Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next

Conflicts:
drivers/net/wireless/iwlwifi/mvm/mac80211.c

+578 -309
+18
drivers/net/wireless/iwlwifi/dvm/commands.h
··· 3897 3897 __le64 replay_ctr; 3898 3898 } __packed; 3899 3899 3900 + #define RF_KILL_INDICATOR_FOR_WOWLAN 0x87 3901 + 3902 + /* 3903 + * REPLY_WOWLAN_GET_STATUS = 0xe5 3904 + */ 3905 + struct iwlagn_wowlan_status { 3906 + __le64 replay_ctr; 3907 + __le32 rekey_status; 3908 + __le32 wakeup_reason; 3909 + u8 pattern_number; 3910 + u8 reserved1; 3911 + __le16 qos_seq_ctr[8]; 3912 + __le16 non_qos_seq_ctr; 3913 + __le16 reserved2; 3914 + union iwlagn_all_tsc_rsc tsc_rsc; 3915 + __le16 reserved3; 3916 + } __packed; 3917 + 3900 3918 /* 3901 3919 * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification) 3902 3920 */
+138 -35
drivers/net/wireless/iwlwifi/dvm/mac80211.c
··· 441 441 return ret; 442 442 } 443 443 444 + struct iwl_resume_data { 445 + struct iwl_priv *priv; 446 + struct iwlagn_wowlan_status *cmd; 447 + bool valid; 448 + }; 449 + 450 + static bool iwl_resume_status_fn(struct iwl_notif_wait_data *notif_wait, 451 + struct iwl_rx_packet *pkt, void *data) 452 + { 453 + struct iwl_resume_data *resume_data = data; 454 + struct iwl_priv *priv = resume_data->priv; 455 + u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 456 + 457 + if (len - 4 != sizeof(*resume_data->cmd)) { 458 + IWL_ERR(priv, "rx wrong size data\n"); 459 + return true; 460 + } 461 + memcpy(resume_data->cmd, pkt->data, sizeof(*resume_data->cmd)); 462 + resume_data->valid = true; 463 + 464 + return true; 465 + } 466 + 444 467 static int iwlagn_mac_resume(struct ieee80211_hw *hw) 445 468 { 446 469 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 447 470 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 448 471 struct ieee80211_vif *vif; 449 - unsigned long flags; 450 - u32 base, status = 0xffffffff; 451 - int ret = -EIO; 472 + u32 base; 473 + int ret; 474 + enum iwl_d3_status d3_status; 475 + struct error_table_start { 476 + /* cf. struct iwl_error_event_table */ 477 + u32 valid; 478 + u32 error_id; 479 + } err_info; 480 + struct iwl_notification_wait status_wait; 481 + static const u8 status_cmd[] = { 482 + REPLY_WOWLAN_GET_STATUS, 483 + }; 484 + struct iwlagn_wowlan_status status_data = {}; 485 + struct iwl_resume_data resume_data = { 486 + .priv = priv, 487 + .cmd = &status_data, 488 + .valid = false, 489 + }; 490 + struct cfg80211_wowlan_wakeup wakeup = { 491 + .pattern_idx = -1, 492 + }; 493 + #ifdef CONFIG_IWLWIFI_DEBUGFS 494 + const struct fw_img *img; 495 + #endif 452 496 453 497 IWL_DEBUG_MAC80211(priv, "enter\n"); 454 498 mutex_lock(&priv->mutex); 455 499 456 - iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_CLR, 457 - CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); 458 - 459 - base = priv->device_pointers.error_event_table; 460 - if (iwlagn_hw_valid_rtc_data_addr(base)) { 461 - if (iwl_trans_grab_nic_access(priv->trans, true, &flags)) { 462 - iwl_write32(priv->trans, HBUS_TARG_MEM_RADDR, base); 463 - status = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT); 464 - iwl_trans_release_nic_access(priv->trans, &flags); 465 - ret = 0; 466 - } 467 - 468 - #ifdef CONFIG_IWLWIFI_DEBUGFS 469 - if (ret == 0) { 470 - const struct fw_img *img; 471 - 472 - img = &(priv->fw->img[IWL_UCODE_WOWLAN]); 473 - if (!priv->wowlan_sram) { 474 - priv->wowlan_sram = 475 - kzalloc(img->sec[IWL_UCODE_SECTION_DATA].len, 476 - GFP_KERNEL); 477 - } 478 - 479 - if (priv->wowlan_sram) 480 - iwl_trans_read_mem( 481 - priv->trans, 0x800000, 482 - priv->wowlan_sram, 483 - img->sec[IWL_UCODE_SECTION_DATA].len / 4); 484 - } 485 - #endif 486 - } 487 - 488 500 /* we'll clear ctx->vif during iwlagn_prepare_restart() */ 489 501 vif = ctx->vif; 502 + 503 + ret = iwl_trans_d3_resume(priv->trans, &d3_status); 504 + if (ret) 505 + goto out_unlock; 506 + 507 + if (d3_status != IWL_D3_STATUS_ALIVE) { 508 + IWL_INFO(priv, "Device was reset during suspend\n"); 509 + goto out_unlock; 510 + } 511 + 512 + base = priv->device_pointers.error_event_table; 513 + if (!iwlagn_hw_valid_rtc_data_addr(base)) { 514 + IWL_WARN(priv, "Invalid error table during resume!\n"); 515 + goto out_unlock; 516 + } 517 + 518 + iwl_trans_read_mem_bytes(priv->trans, base, 519 + &err_info, sizeof(err_info)); 520 + 521 + if (err_info.valid) { 522 + IWL_INFO(priv, "error table is valid (%d, 0x%x)\n", 523 + err_info.valid, err_info.error_id); 524 + if (err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN) { 525 + wakeup.rfkill_release = true; 526 + ieee80211_report_wowlan_wakeup(vif, &wakeup, 527 + GFP_KERNEL); 528 + } 529 + goto out_unlock; 530 + } 531 + 532 + #ifdef CONFIG_IWLWIFI_DEBUGFS 533 + img = &priv->fw->img[IWL_UCODE_WOWLAN]; 534 + if (!priv->wowlan_sram) 535 + priv->wowlan_sram = 536 + kzalloc(img->sec[IWL_UCODE_SECTION_DATA].len, 537 + GFP_KERNEL); 538 + 539 + if (priv->wowlan_sram) 540 + iwl_trans_read_mem(priv->trans, 0x800000, 541 + priv->wowlan_sram, 542 + img->sec[IWL_UCODE_SECTION_DATA].len / 4); 543 + #endif 544 + 545 + /* 546 + * This is very strange. The GET_STATUS command is sent but the device 547 + * doesn't reply properly, it seems it doesn't close the RBD so one is 548 + * always left open ... As a result, we need to send another command 549 + * and have to reset the driver afterwards. As we need to switch to 550 + * runtime firmware again that'll happen. 551 + */ 552 + 553 + iwl_init_notification_wait(&priv->notif_wait, &status_wait, status_cmd, 554 + ARRAY_SIZE(status_cmd), iwl_resume_status_fn, 555 + &resume_data); 556 + 557 + iwl_dvm_send_cmd_pdu(priv, REPLY_WOWLAN_GET_STATUS, CMD_ASYNC, 0, NULL); 558 + iwl_dvm_send_cmd_pdu(priv, REPLY_ECHO, CMD_ASYNC, 0, NULL); 559 + /* an RBD is left open in the firmware now! */ 560 + 561 + ret = iwl_wait_notification(&priv->notif_wait, &status_wait, HZ/5); 562 + if (ret) 563 + goto out_unlock; 564 + 565 + if (resume_data.valid && priv->contexts[IWL_RXON_CTX_BSS].vif) { 566 + u32 reasons = le32_to_cpu(status_data.wakeup_reason); 567 + struct cfg80211_wowlan_wakeup *wakeup_report; 568 + 569 + IWL_INFO(priv, "WoWLAN wakeup reason(s): 0x%.8x\n", reasons); 570 + 571 + if (reasons) { 572 + if (reasons & IWLAGN_WOWLAN_WAKEUP_MAGIC_PACKET) 573 + wakeup.magic_pkt = true; 574 + if (reasons & IWLAGN_WOWLAN_WAKEUP_PATTERN_MATCH) 575 + wakeup.pattern_idx = status_data.pattern_number; 576 + if (reasons & (IWLAGN_WOWLAN_WAKEUP_BEACON_MISS | 577 + IWLAGN_WOWLAN_WAKEUP_LINK_CHANGE)) 578 + wakeup.disconnect = true; 579 + if (reasons & IWLAGN_WOWLAN_WAKEUP_GTK_REKEY_FAIL) 580 + wakeup.gtk_rekey_failure = true; 581 + if (reasons & IWLAGN_WOWLAN_WAKEUP_EAP_IDENT_REQ) 582 + wakeup.eap_identity_req = true; 583 + if (reasons & IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE) 584 + wakeup.four_way_handshake = true; 585 + wakeup_report = &wakeup; 586 + } else { 587 + wakeup_report = NULL; 588 + } 589 + 590 + ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL); 591 + } 490 592 491 593 priv->wowlan = false; 492 594 ··· 598 496 iwl_connection_init_rx_config(priv, ctx); 599 497 iwlagn_set_rxon_chain(priv, ctx); 600 498 499 + out_unlock: 601 500 mutex_unlock(&priv->mutex); 602 501 IWL_DEBUG_MAC80211(priv, "leave\n"); 603 502
+1 -1
drivers/net/wireless/iwlwifi/dvm/rx.c
··· 790 790 791 791 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); 792 792 793 - ieee80211_rx(priv->hw, skb); 793 + ieee80211_rx_ni(priv->hw, skb); 794 794 } 795 795 796 796 static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
+2 -3
drivers/net/wireless/iwlwifi/dvm/rxon.c
··· 1545 1545 bss_conf->bssid); 1546 1546 } 1547 1547 1548 - if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_ADHOC && 1549 - priv->beacon_ctx) { 1548 + if (changes & BSS_CHANGED_BEACON && priv->beacon_ctx == ctx) { 1550 1549 if (iwlagn_update_beacon(priv, vif)) 1551 - IWL_ERR(priv, "Error sending IBSS beacon\n"); 1550 + IWL_ERR(priv, "Error updating beacon\n"); 1552 1551 } 1553 1552 1554 1553 mutex_unlock(&priv->mutex);
+2 -2
drivers/net/wireless/iwlwifi/dvm/sta.c
··· 77 77 IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n", 78 78 sta_id); 79 79 80 - spin_lock(&priv->sta_lock); 80 + spin_lock_bh(&priv->sta_lock); 81 81 82 82 switch (add_sta_resp->status) { 83 83 case ADD_STA_SUCCESS_MSK: ··· 119 119 priv->stations[sta_id].sta.mode == 120 120 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", 121 121 addsta->sta.addr); 122 - spin_unlock(&priv->sta_lock); 122 + spin_unlock_bh(&priv->sta_lock); 123 123 124 124 return ret; 125 125 }
+8 -8
drivers/net/wireless/iwlwifi/dvm/tx.c
··· 1117 1117 sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >> 1118 1118 IWLAGN_TX_RES_RA_POS; 1119 1119 1120 - spin_lock(&priv->sta_lock); 1120 + spin_lock_bh(&priv->sta_lock); 1121 1121 1122 1122 if (is_agg) 1123 1123 iwl_rx_reply_tx_agg(priv, tx_resp); ··· 1239 1239 le16_to_cpu(tx_resp->seq_ctl)); 1240 1240 1241 1241 iwl_check_abort_status(priv, tx_resp->frame_count, status); 1242 - spin_unlock(&priv->sta_lock); 1242 + spin_unlock_bh(&priv->sta_lock); 1243 1243 1244 1244 while (!skb_queue_empty(&skbs)) { 1245 1245 skb = __skb_dequeue(&skbs); 1246 - ieee80211_tx_status(priv->hw, skb); 1246 + ieee80211_tx_status_ni(priv->hw, skb); 1247 1247 } 1248 1248 1249 1249 if (is_offchannel_skb) ··· 1290 1290 tid = ba_resp->tid; 1291 1291 agg = &priv->tid_data[sta_id][tid].agg; 1292 1292 1293 - spin_lock(&priv->sta_lock); 1293 + spin_lock_bh(&priv->sta_lock); 1294 1294 1295 1295 if (unlikely(!agg->wait_for_ba)) { 1296 1296 if (unlikely(ba_resp->bitmap)) 1297 1297 IWL_ERR(priv, "Received BA when not expected\n"); 1298 - spin_unlock(&priv->sta_lock); 1298 + spin_unlock_bh(&priv->sta_lock); 1299 1299 return 0; 1300 1300 } 1301 1301 ··· 1309 1309 IWL_DEBUG_TX_QUEUES(priv, 1310 1310 "Bad queue mapping txq_id=%d, agg_txq[sta:%d,tid:%d]=%d\n", 1311 1311 scd_flow, sta_id, tid, agg->txq_id); 1312 - spin_unlock(&priv->sta_lock); 1312 + spin_unlock_bh(&priv->sta_lock); 1313 1313 return 0; 1314 1314 } 1315 1315 ··· 1378 1378 } 1379 1379 } 1380 1380 1381 - spin_unlock(&priv->sta_lock); 1381 + spin_unlock_bh(&priv->sta_lock); 1382 1382 1383 1383 while (!skb_queue_empty(&reclaimed_skbs)) { 1384 1384 skb = __skb_dequeue(&reclaimed_skbs); 1385 - ieee80211_tx_status(priv->hw, skb); 1385 + ieee80211_tx_status_ni(priv->hw, skb); 1386 1386 } 1387 1387 1388 1388 return 0;
+6 -4
drivers/net/wireless/iwlwifi/iwl-op-mode.h
··· 113 113 * May sleep 114 114 * @rx: Rx notification to the op_mode. rxb is the Rx buffer itself. Cmd is the 115 115 * HCMD the this Rx responds to. 116 - * Must be atomic and called with BH disabled. 116 + * This callback may sleep, it is called from a threaded IRQ handler. 117 117 * @queue_full: notifies that a HW queue is full. 118 118 * Must be atomic and called with BH disabled. 119 119 * @queue_not_full: notifies that a HW queue is not full any more. 120 120 * Must be atomic and called with BH disabled. 121 121 * @hw_rf_kill:notifies of a change in the HW rf kill switch. True means that 122 - * the radio is killed. Must be atomic. 122 + * the radio is killed. May sleep. 123 123 * @free_skb: allows the transport layer to free skbs that haven't been 124 124 * reclaimed by the op_mode. This can happen when the driver is freed and 125 125 * there are Tx packets pending in the transport layer. ··· 130 130 * called with BH disabled. 131 131 * @nic_config: configure NIC, called before firmware is started. 132 132 * May sleep 133 - * @wimax_active: invoked when WiMax becomes active. Must be atomic and called 134 - * with BH disabled. 133 + * @wimax_active: invoked when WiMax becomes active. May sleep 135 134 */ 136 135 struct iwl_op_mode_ops { 137 136 struct iwl_op_mode *(*start)(struct iwl_trans *trans, ··· 177 178 struct iwl_rx_cmd_buffer *rxb, 178 179 struct iwl_device_cmd *cmd) 179 180 { 181 + might_sleep(); 180 182 return op_mode->ops->rx(op_mode, rxb, cmd); 181 183 } 182 184 ··· 196 196 static inline void iwl_op_mode_hw_rf_kill(struct iwl_op_mode *op_mode, 197 197 bool state) 198 198 { 199 + might_sleep(); 199 200 op_mode->ops->hw_rf_kill(op_mode, state); 200 201 } 201 202 ··· 224 223 225 224 static inline void iwl_op_mode_wimax_active(struct iwl_op_mode *op_mode) 226 225 { 226 + might_sleep(); 227 227 op_mode->ops->wimax_active(op_mode); 228 228 } 229 229
+27 -2
drivers/net/wireless/iwlwifi/iwl-trans.h
··· 65 65 66 66 #include <linux/ieee80211.h> 67 67 #include <linux/mm.h> /* for page_address */ 68 + #include <linux/lockdep.h> 68 69 69 70 #include "iwl-debug.h" 70 71 #include "iwl-config.h" ··· 527 526 528 527 struct dentry *dbgfs_dir; 529 528 529 + #ifdef CONFIG_LOCKDEP 530 + struct lockdep_map sync_cmd_lockdep_map; 531 + #endif 532 + 530 533 /* pointer to trans specific struct */ 531 534 /*Ensure that this pointer will always be aligned to sizeof pointer */ 532 535 char trans_specific[0] __aligned(sizeof(void *)); ··· 607 602 } 608 603 609 604 static inline int iwl_trans_send_cmd(struct iwl_trans *trans, 610 - struct iwl_host_cmd *cmd) 605 + struct iwl_host_cmd *cmd) 611 606 { 607 + int ret; 608 + 612 609 WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, 613 610 "%s bad state = %d", __func__, trans->state); 614 611 615 - return trans->ops->send_cmd(trans, cmd); 612 + if (!(cmd->flags & CMD_ASYNC)) 613 + lock_map_acquire_read(&trans->sync_cmd_lockdep_map); 614 + 615 + ret = trans->ops->send_cmd(trans, cmd); 616 + 617 + if (!(cmd->flags & CMD_ASYNC)) 618 + lock_map_release(&trans->sync_cmd_lockdep_map); 619 + 620 + return ret; 616 621 } 617 622 618 623 static inline struct iwl_device_cmd * ··· 805 790 ******************************************************/ 806 791 int __must_check iwl_pci_register_driver(void); 807 792 void iwl_pci_unregister_driver(void); 793 + 794 + static inline void trans_lockdep_init(struct iwl_trans *trans) 795 + { 796 + #ifdef CONFIG_LOCKDEP 797 + static struct lock_class_key __key; 798 + 799 + lockdep_init_map(&trans->sync_cmd_lockdep_map, "sync_cmd_lockdep_map", 800 + &__key, 0); 801 + #endif 802 + } 808 803 809 804 #endif /* __iwl_trans_h__ */
+144 -30
drivers/net/wireless/iwlwifi/mvm/d3.c
··· 97 97 struct inet6_ifaddr *ifa; 98 98 int idx = 0; 99 99 100 - read_lock(&idev->lock); 100 + read_lock_bh(&idev->lock); 101 101 list_for_each_entry(ifa, &idev->addr_list, if_list) { 102 102 mvmvif->target_ipv6_addrs[idx] = ifa->addr; 103 103 idx++; 104 104 if (idx >= IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS) 105 105 break; 106 106 } 107 - read_unlock(&idev->lock); 107 + read_unlock_bh(&idev->lock); 108 108 109 109 mvmvif->num_target_ipv6_addrs = idx; 110 110 } ··· 490 490 return -EIO; 491 491 } 492 492 493 - ret = iwl_mvm_sta_add_to_fw(mvm, ap_sta); 493 + ret = iwl_mvm_sta_send_to_fw(mvm, ap_sta, false); 494 494 if (ret) 495 495 return ret; 496 496 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], ap_sta); ··· 763 763 return ret; 764 764 } 765 765 766 + static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, 767 + struct ieee80211_vif *vif) 768 + { 769 + u32 base = mvm->error_event_table; 770 + struct error_table_start { 771 + /* cf. struct iwl_error_event_table */ 772 + u32 valid; 773 + u32 error_id; 774 + } err_info; 775 + struct cfg80211_wowlan_wakeup wakeup = { 776 + .pattern_idx = -1, 777 + }; 778 + struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup; 779 + struct iwl_host_cmd cmd = { 780 + .id = WOWLAN_GET_STATUSES, 781 + .flags = CMD_SYNC | CMD_WANT_SKB, 782 + }; 783 + struct iwl_wowlan_status *status; 784 + u32 reasons; 785 + int ret, len; 786 + bool pkt8023 = false; 787 + struct sk_buff *pkt = NULL; 788 + 789 + iwl_trans_read_mem_bytes(mvm->trans, base, 790 + &err_info, sizeof(err_info)); 791 + 792 + if (err_info.valid) { 793 + IWL_INFO(mvm, "error table is valid (%d)\n", 794 + err_info.valid); 795 + if (err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN) { 796 + wakeup.rfkill_release = true; 797 + ieee80211_report_wowlan_wakeup(vif, &wakeup, 798 + GFP_KERNEL); 799 + } 800 + return; 801 + } 802 + 803 + /* only for tracing for now */ 804 + ret = iwl_mvm_send_cmd_pdu(mvm, OFFLOADS_QUERY_CMD, CMD_SYNC, 0, NULL); 805 + if (ret) 806 + IWL_ERR(mvm, "failed to query offload statistics (%d)\n", ret); 807 + 808 + ret = iwl_mvm_send_cmd(mvm, &cmd); 809 + if (ret) { 810 + IWL_ERR(mvm, "failed to query status (%d)\n", ret); 811 + return; 812 + } 813 + 814 + /* RF-kill already asserted again... */ 815 + if (!cmd.resp_pkt) 816 + return; 817 + 818 + len = le32_to_cpu(cmd.resp_pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 819 + if (len - sizeof(struct iwl_cmd_header) < sizeof(*status)) { 820 + IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); 821 + goto out; 822 + } 823 + 824 + status = (void *)cmd.resp_pkt->data; 825 + 826 + if (len - sizeof(struct iwl_cmd_header) != 827 + sizeof(*status) + le32_to_cpu(status->wake_packet_bufsize)) { 828 + IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); 829 + goto out; 830 + } 831 + 832 + reasons = le32_to_cpu(status->wakeup_reasons); 833 + 834 + if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) { 835 + wakeup_report = NULL; 836 + goto report; 837 + } 838 + 839 + if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) { 840 + wakeup.magic_pkt = true; 841 + pkt8023 = true; 842 + } 843 + 844 + if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) { 845 + wakeup.pattern_idx = 846 + le16_to_cpu(status->pattern_number); 847 + pkt8023 = true; 848 + } 849 + 850 + if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON | 851 + IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH)) 852 + wakeup.disconnect = true; 853 + 854 + if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) { 855 + wakeup.gtk_rekey_failure = true; 856 + pkt8023 = true; 857 + } 858 + 859 + if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) { 860 + wakeup.rfkill_release = true; 861 + pkt8023 = true; 862 + } 863 + 864 + if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) { 865 + wakeup.eap_identity_req = true; 866 + pkt8023 = true; 867 + } 868 + 869 + if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) { 870 + wakeup.four_way_handshake = true; 871 + pkt8023 = true; 872 + } 873 + 874 + if (status->wake_packet_bufsize) { 875 + u32 pktsize = le32_to_cpu(status->wake_packet_bufsize); 876 + u32 pktlen = le32_to_cpu(status->wake_packet_length); 877 + 878 + if (pkt8023) { 879 + pkt = alloc_skb(pktsize, GFP_KERNEL); 880 + if (!pkt) 881 + goto report; 882 + memcpy(skb_put(pkt, pktsize), status->wake_packet, 883 + pktsize); 884 + if (ieee80211_data_to_8023(pkt, vif->addr, vif->type)) 885 + goto report; 886 + wakeup.packet = pkt->data; 887 + wakeup.packet_present_len = pkt->len; 888 + wakeup.packet_len = pkt->len - (pktlen - pktsize); 889 + wakeup.packet_80211 = false; 890 + } else { 891 + wakeup.packet = status->wake_packet; 892 + wakeup.packet_present_len = pktsize; 893 + wakeup.packet_len = pktlen; 894 + wakeup.packet_80211 = true; 895 + } 896 + } 897 + 898 + report: 899 + ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL); 900 + kfree_skb(pkt); 901 + 902 + out: 903 + iwl_free_resp(&cmd); 904 + } 905 + 766 906 int iwl_mvm_resume(struct ieee80211_hw *hw) 767 907 { 768 908 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); ··· 910 770 .mvm = mvm, 911 771 }; 912 772 struct ieee80211_vif *vif = NULL; 913 - u32 base; 914 773 int ret; 915 774 enum iwl_d3_status d3_status; 916 - struct error_table_start { 917 - /* cf. struct iwl_error_event_table */ 918 - u32 valid; 919 - u32 error_id; 920 - } err_info; 921 775 922 776 mutex_lock(&mvm->mutex); 923 777 ··· 934 800 goto out_unlock; 935 801 } 936 802 937 - base = mvm->error_event_table; 938 - 939 - iwl_trans_read_mem_bytes(mvm->trans, base, 940 - &err_info, sizeof(err_info)); 941 - 942 - if (err_info.valid) { 943 - IWL_INFO(mvm, "error table is valid (%d)\n", 944 - err_info.valid); 945 - if (err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN) 946 - IWL_ERR(mvm, "this was due to RF-kill\n"); 947 - goto out_unlock; 948 - } 949 - 950 - /* TODO: get status and whatever else ... */ 951 - ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_GET_STATUSES, CMD_SYNC, 0, NULL); 952 - if (ret) 953 - IWL_ERR(mvm, "failed to query status (%d)\n", ret); 954 - 955 - ret = iwl_mvm_send_cmd_pdu(mvm, OFFLOADS_QUERY_CMD, CMD_SYNC, 0, NULL); 956 - if (ret) 957 - IWL_ERR(mvm, "failed to query offloads (%d)\n", ret); 803 + iwl_mvm_query_wakeup_reasons(mvm, vif); 958 804 959 805 out_unlock: 960 806 mutex_unlock(&mvm->mutex);
+3
drivers/net/wireless/iwlwifi/mvm/fw-api.h
··· 633 633 __le32 phy; 634 634 } __packed; /* BINDING_CMD_API_S_VER_1 */ 635 635 636 + /* The maximal number of fragments in the FW's schedule session */ 637 + #define IWL_MVM_MAX_QUOTA 128 638 + 636 639 /** 637 640 * struct iwl_time_quota_data - configuration of time quota per binding 638 641 * @id_and_color: ID and color of the relevant Binding
-4
drivers/net/wireless/iwlwifi/mvm/fw.c
··· 621 621 (flags & CT_KILL_CARD_DISABLED) ? 622 622 "Reached" : "Not reached"); 623 623 624 - if (flags & CARD_DISABLED_MSK) 625 - iwl_write32(mvm->trans, CSR_UCODE_DRV_GP1_SET, 626 - CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); 627 - 628 624 return 0; 629 625 } 630 626
+5 -1
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
··· 584 584 struct ieee80211_vif *vif, 585 585 struct iwl_mac_data_sta *ctxt_sta) 586 586 { 587 - ctxt_sta->is_assoc = cpu_to_le32(vif->bss_conf.assoc ? 1 : 0); 587 + /* We need the dtim_period to set the MAC as associated */ 588 + if (vif->bss_conf.assoc && vif->bss_conf.dtim_period) 589 + ctxt_sta->is_assoc = cpu_to_le32(1); 590 + else 591 + ctxt_sta->is_assoc = cpu_to_le32(0); 588 592 589 593 ctxt_sta->bi = cpu_to_le32(vif->bss_conf.beacon_int); 590 594 ctxt_sta->bi_reciprocal =
+12 -5
drivers/net/wireless/iwlwifi/mvm/mac80211.c
··· 474 474 if (mvm->vif_count > 1) { 475 475 IWL_DEBUG_MAC80211(mvm, 476 476 "Disable power on existing interfaces\n"); 477 - ieee80211_iterate_active_interfaces( 477 + ieee80211_iterate_active_interfaces_atomic( 478 478 mvm->hw, 479 479 IEEE80211_IFACE_ITER_NORMAL, 480 480 iwl_mvm_pm_disable_iterator, mvm); ··· 670 670 IWL_ERR(mvm, "failed to update quotas\n"); 671 671 return; 672 672 } 673 - iwl_mvm_remove_time_event(mvm, mvmvif, 674 - &mvmvif->time_event_data); 675 673 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { 676 674 /* remove AP station now that the MAC is unassoc */ 677 675 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); ··· 681 683 if (ret) 682 684 IWL_ERR(mvm, "failed to update quotas\n"); 683 685 } 686 + } else if (changes & BSS_CHANGED_DTIM_PERIOD) { 687 + /* 688 + * We received a beacon _after_ association so 689 + * remove the session protection. 690 + */ 691 + iwl_mvm_remove_time_event(mvm, mvmvif, 692 + &mvmvif->time_event_data); 684 693 } else if (changes & BSS_CHANGED_PS) { 685 694 /* 686 695 * TODO: remove this temporary code. ··· 926 921 ret = 0; 927 922 } else if (old_state == IEEE80211_STA_AUTH && 928 923 new_state == IEEE80211_STA_ASSOC) { 929 - iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band); 930 - ret = 0; 924 + ret = iwl_mvm_update_sta(mvm, vif, sta); 925 + if (ret == 0) 926 + iwl_mvm_rs_rate_init(mvm, sta, 927 + mvmvif->phy_ctxt->channel->band); 931 928 } else if (old_state == IEEE80211_STA_ASSOC && 932 929 new_state == IEEE80211_STA_AUTHORIZED) { 933 930 ret = 0;
+20 -17
drivers/net/wireless/iwlwifi/mvm/ops.c
··· 536 536 537 537 for (i = 0; i < ARRAY_SIZE(iwl_mvm_rx_handlers); i++) { 538 538 const struct iwl_rx_handlers *rx_h = &iwl_mvm_rx_handlers[i]; 539 - if (rx_h->cmd_id == pkt->hdr.cmd) { 540 - struct iwl_async_handler_entry *entry; 541 - if (!rx_h->async) 542 - return rx_h->fn(mvm, rxb, cmd); 539 + struct iwl_async_handler_entry *entry; 543 540 544 - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 545 - /* we can't do much... */ 546 - if (!entry) 547 - return 0; 541 + if (rx_h->cmd_id != pkt->hdr.cmd) 542 + continue; 548 543 549 - entry->rxb._page = rxb_steal_page(rxb); 550 - entry->rxb._offset = rxb->_offset; 551 - entry->rxb._rx_page_order = rxb->_rx_page_order; 552 - entry->fn = rx_h->fn; 553 - spin_lock(&mvm->async_handlers_lock); 554 - list_add_tail(&entry->list, &mvm->async_handlers_list); 555 - spin_unlock(&mvm->async_handlers_lock); 556 - schedule_work(&mvm->async_handlers_wk); 557 - } 544 + if (!rx_h->async) 545 + return rx_h->fn(mvm, rxb, cmd); 546 + 547 + entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 548 + /* we can't do much... */ 549 + if (!entry) 550 + return 0; 551 + 552 + entry->rxb._page = rxb_steal_page(rxb); 553 + entry->rxb._offset = rxb->_offset; 554 + entry->rxb._rx_page_order = rxb->_rx_page_order; 555 + entry->fn = rx_h->fn; 556 + spin_lock(&mvm->async_handlers_lock); 557 + list_add_tail(&entry->list, &mvm->async_handlers_list); 558 + spin_unlock(&mvm->async_handlers_lock); 559 + schedule_work(&mvm->async_handlers_wk); 560 + break; 558 561 } 559 562 560 563 return 0;
+1 -1
drivers/net/wireless/iwlwifi/mvm/power.c
··· 194 194 cmd.id_and_color, iwlmvm_mod_params.power_scheme, 195 195 le16_to_cpu(cmd.flags)); 196 196 197 - return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, 197 + return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC, 198 198 sizeof(cmd), &cmd); 199 199 } 200 200
+24 -5
drivers/net/wireless/iwlwifi/mvm/quota.c
··· 131 131 int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif) 132 132 { 133 133 struct iwl_time_quota_cmd cmd; 134 - int i, idx, ret; 134 + int i, idx, ret, num_active_bindings, quota, quota_rem; 135 135 struct iwl_mvm_quota_iterator_data data = { 136 136 .n_interfaces = {}, 137 137 .colors = { -1, -1, -1, -1 }, ··· 156 156 iwl_mvm_quota_iterator(&data, newvif->addr, newvif); 157 157 } 158 158 159 + /* 160 + * The FW's scheduling session consists of 161 + * IWL_MVM_MAX_QUOTA fragments. Divide these fragments 162 + * equally between all the bindings that require quota 163 + */ 164 + num_active_bindings = 0; 165 + for (i = 0; i < MAX_BINDINGS; i++) { 166 + cmd.quotas[i].id_and_color = cpu_to_le32(FW_CTXT_INVALID); 167 + if (data.n_interfaces[i] > 0) 168 + num_active_bindings++; 169 + } 170 + 171 + if (!num_active_bindings) 172 + goto send_cmd; 173 + 174 + quota = IWL_MVM_MAX_QUOTA / num_active_bindings; 175 + quota_rem = IWL_MVM_MAX_QUOTA % num_active_bindings; 176 + 159 177 for (idx = 0, i = 0; i < MAX_BINDINGS; i++) { 160 178 if (data.n_interfaces[i] <= 0) 161 179 continue; 162 180 163 181 cmd.quotas[idx].id_and_color = 164 182 cpu_to_le32(FW_CMD_ID_AND_COLOR(i, data.colors[i])); 165 - cmd.quotas[idx].quota = cpu_to_le32(100); 166 - cmd.quotas[idx].max_duration = cpu_to_le32(1000); 183 + cmd.quotas[idx].quota = cpu_to_le32(quota); 184 + cmd.quotas[idx].max_duration = cpu_to_le32(IWL_MVM_MAX_QUOTA); 167 185 idx++; 168 186 } 169 187 170 - for (i = idx; i < MAX_BINDINGS; i++) 171 - cmd.quotas[i].id_and_color = cpu_to_le32(FW_CTXT_INVALID); 188 + /* Give the remainder of the session to the first binding */ 189 + le32_add_cpu(&cmd.quotas[0].quota, quota_rem); 172 190 191 + send_cmd: 173 192 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, CMD_SYNC, 174 193 sizeof(cmd), &cmd); 175 194 if (ret)
+1 -1
drivers/net/wireless/iwlwifi/mvm/rx.c
··· 121 121 122 122 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); 123 123 124 - ieee80211_rx(mvm->hw, skb); 124 + ieee80211_rx_ni(mvm->hw, skb); 125 125 } 126 126 127 127 /*
+32 -8
drivers/net/wireless/iwlwifi/mvm/sta.c
··· 81 81 return IWL_MVM_STATION_COUNT; 82 82 } 83 83 84 - /* add a NEW station to fw */ 85 - int iwl_mvm_sta_add_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta) 84 + /* send station add/update command to firmware */ 85 + int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 86 + bool update) 86 87 { 87 88 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 88 89 struct iwl_mvm_add_sta_cmd add_sta_cmd; ··· 95 94 96 95 add_sta_cmd.sta_id = mvm_sta->sta_id; 97 96 add_sta_cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color); 98 - add_sta_cmd.tfd_queue_msk = cpu_to_le32(mvm_sta->tfd_queue_msk); 99 - memcpy(&add_sta_cmd.addr, sta->addr, ETH_ALEN); 97 + if (!update) { 98 + add_sta_cmd.tfd_queue_msk = cpu_to_le32(mvm_sta->tfd_queue_msk); 99 + memcpy(&add_sta_cmd.addr, sta->addr, ETH_ALEN); 100 + } 101 + add_sta_cmd.add_modify = update ? 1 : 0; 100 102 101 103 /* STA_FLG_FAT_EN_MSK ? */ 102 104 /* STA_FLG_MIMO_EN_MSK ? */ ··· 185 181 /* for HW restart - need to reset the seq_number etc... */ 186 182 memset(mvm_sta->tid_data, 0, sizeof(mvm_sta->tid_data)); 187 183 188 - ret = iwl_mvm_sta_add_to_fw(mvm, sta); 184 + ret = iwl_mvm_sta_send_to_fw(mvm, sta, false); 189 185 if (ret) 190 186 return ret; 191 187 ··· 197 193 rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], sta); 198 194 199 195 return 0; 196 + } 197 + 198 + int iwl_mvm_update_sta(struct iwl_mvm *mvm, 199 + struct ieee80211_vif *vif, 200 + struct ieee80211_sta *sta) 201 + { 202 + return iwl_mvm_sta_send_to_fw(mvm, sta, true); 200 203 } 201 204 202 205 int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, ··· 1127 1116 if (WARN_ON_ONCE(mvm_sta->vif != vif)) 1128 1117 return -EINVAL; 1129 1118 1130 - key_flags = cpu_to_le16(keyconf->keyidx & STA_KEY_FLG_KEYID_MSK); 1119 + key_flags = cpu_to_le16((keyconf->keyidx << STA_KEY_FLG_KEYID_POS) & 1120 + STA_KEY_FLG_KEYID_MSK); 1131 1121 key_flags |= cpu_to_le16(STA_KEY_FLG_NO_ENC | STA_KEY_FLG_WEP_KEY_MAP); 1132 1122 key_flags |= cpu_to_le16(STA_KEY_NOT_VALID); 1133 1123 ··· 1166 1154 struct ieee80211_sta *sta, u32 iv32, 1167 1155 u16 *phase1key) 1168 1156 { 1169 - struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 1157 + struct iwl_mvm_sta *mvm_sta; 1170 1158 u8 sta_id = iwl_mvm_get_key_sta_id(vif, sta); 1171 1159 1172 - if (sta_id == IWL_INVALID_STATION) 1160 + if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION)) 1173 1161 return; 1174 1162 1163 + rcu_read_lock(); 1164 + 1165 + if (!sta) { 1166 + sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); 1167 + if (WARN_ON(IS_ERR_OR_NULL(sta))) { 1168 + rcu_read_unlock(); 1169 + return; 1170 + } 1171 + } 1172 + 1173 + mvm_sta = (void *)sta->drv_priv; 1175 1174 iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id, 1176 1175 iv32, phase1key, CMD_ASYNC); 1176 + rcu_read_unlock(); 1177 1177 } 1178 1178 1179 1179 void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, int sta_id)
+5 -1
drivers/net/wireless/iwlwifi/mvm/sta.h
··· 309 309 u32 tfd_queue_msk; 310 310 }; 311 311 312 - int iwl_mvm_sta_add_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta); 312 + int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 313 + bool update); 313 314 int iwl_mvm_add_sta(struct iwl_mvm *mvm, 314 315 struct ieee80211_vif *vif, 315 316 struct ieee80211_sta *sta); 317 + int iwl_mvm_update_sta(struct iwl_mvm *mvm, 318 + struct ieee80211_vif *vif, 319 + struct ieee80211_sta *sta); 316 320 int iwl_mvm_rm_sta(struct iwl_mvm *mvm, 317 321 struct ieee80211_vif *vif, 318 322 struct ieee80211_sta *sta);
+89 -147
drivers/net/wireless/iwlwifi/mvm/time-event.c
··· 76 76 #define TU_TO_JIFFIES(_tu) (usecs_to_jiffies((_tu) * 1024)) 77 77 #define MSEC_TO_TU(_msec) (_msec*1000/1024) 78 78 79 + /* For ROC use a TE type which has priority high enough to be scheduled when 80 + * there is a concurrent BSS or GO/AP. Currently, use a TE type that has 81 + * priority similar to the TE priority used for action scans by the FW. 82 + * TODO: This needs to be changed, based on the reason for the ROC, i.e., use 83 + * TE_P2P_DEVICE_DISCOVERABLE for remain on channel without mgmt skb, and use 84 + * TE_P2P_DEVICE_ACTION_SCAN 85 + */ 86 + #define IWL_MVM_ROC_TE_TYPE TE_P2P_DEVICE_ACTION_SCAN 87 + 79 88 void iwl_mvm_te_clear_data(struct iwl_mvm *mvm, 80 89 struct iwl_mvm_time_event_data *te_data) 81 90 { ··· 184 175 */ 185 176 if (te_data->vif->type == NL80211_IFTYPE_STATION && 186 177 (!te_data->vif->bss_conf.assoc || 187 - !te_data->vif->bss_conf.dtim_period)) 178 + !te_data->vif->bss_conf.dtim_period)) { 188 179 IWL_ERR(mvm, 189 180 "No assocation and the time event is over already...\n"); 181 + ieee80211_connection_loss(te_data->vif); 182 + } 190 183 191 184 iwl_mvm_te_clear_data(mvm, te_data); 192 185 } else if (le32_to_cpu(notif->action) == TE_NOTIF_HOST_START) { ··· 230 219 return 0; 231 220 } 232 221 233 - static bool iwl_mvm_time_event_notif(struct iwl_notif_wait_data *notif_wait, 234 - struct iwl_rx_packet *pkt, void *data) 222 + static bool iwl_mvm_time_event_response(struct iwl_notif_wait_data *notif_wait, 223 + struct iwl_rx_packet *pkt, void *data) 235 224 { 236 225 struct iwl_mvm *mvm = 237 226 container_of(notif_wait, struct iwl_mvm, notif_wait); 238 227 struct iwl_mvm_time_event_data *te_data = data; 239 - struct ieee80211_vif *vif = te_data->vif; 240 - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 241 - struct iwl_time_event_notif *notif; 242 228 struct iwl_time_event_resp *resp; 229 + int resp_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 243 230 244 - u32 mac_id_n_color = FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color); 245 - 246 - /* until we do something else */ 247 - WARN_ON(te_data->id != TE_BSS_STA_AGGRESSIVE_ASSOC); 248 - 249 - switch (pkt->hdr.cmd) { 250 - case TIME_EVENT_CMD: 251 - resp = (void *)pkt->data; 252 - /* TODO: I can't check that since the fw is buggy - it doesn't 253 - * put the right values when we remove a TE. We can be here 254 - * when we remove a TE because the remove TE command is sent in 255 - * ASYNC... 256 - * WARN_ON(mac_id_n_color != le32_to_cpu(resp->id_and_color)); 257 - */ 258 - te_data->uid = le32_to_cpu(resp->unique_id); 259 - IWL_DEBUG_TE(mvm, "Got response - UID = 0x%x\n", te_data->uid); 260 - return false; 261 - 262 - case TIME_EVENT_NOTIFICATION: 263 - notif = (void *)pkt->data; 264 - WARN_ON(le32_to_cpu(notif->status) != 1); 265 - WARN_ON(mac_id_n_color != le32_to_cpu(notif->id_and_color)); 266 - /* check if this is our Time Event that is starting */ 267 - if (le32_to_cpu(notif->unique_id) != te_data->uid) 268 - return false; 269 - IWL_DEBUG_TE(mvm, "Event %d is starting - time is %d\n", 270 - te_data->uid, le32_to_cpu(notif->timestamp)); 271 - 272 - WARN_ONCE(!le32_to_cpu(notif->status), 273 - "Failed to schedule protected session TE\n"); 274 - 275 - te_data->running = true; 276 - te_data->end_jiffies = jiffies + 277 - TU_TO_JIFFIES(te_data->duration); 231 + if (WARN_ON(pkt->hdr.cmd != TIME_EVENT_CMD)) 278 232 return true; 279 233 280 - default: 281 - WARN_ON(1); 282 - return false; 283 - }; 234 + if (WARN_ON_ONCE(resp_len != sizeof(pkt->hdr) + sizeof(*resp))) { 235 + IWL_ERR(mvm, "Invalid TIME_EVENT_CMD response\n"); 236 + return true; 237 + } 238 + 239 + resp = (void *)pkt->data; 240 + te_data->uid = le32_to_cpu(resp->unique_id); 241 + IWL_DEBUG_TE(mvm, "TIME_EVENT_CMD response - UID = 0x%x\n", 242 + te_data->uid); 243 + return true; 244 + } 245 + 246 + static int iwl_mvm_time_event_send_add(struct iwl_mvm *mvm, 247 + struct ieee80211_vif *vif, 248 + struct iwl_mvm_time_event_data *te_data, 249 + struct iwl_time_event_cmd *te_cmd) 250 + { 251 + static const u8 time_event_response[] = { TIME_EVENT_CMD }; 252 + struct iwl_notification_wait wait_time_event; 253 + int ret; 254 + 255 + lockdep_assert_held(&mvm->mutex); 256 + 257 + spin_lock_bh(&mvm->time_event_lock); 258 + if (WARN_ON(te_data->id != TE_MAX)) { 259 + spin_unlock_bh(&mvm->time_event_lock); 260 + return -EIO; 261 + } 262 + te_data->vif = vif; 263 + te_data->duration = le32_to_cpu(te_cmd->duration); 264 + te_data->id = le32_to_cpu(te_cmd->id); 265 + list_add_tail(&te_data->list, &mvm->time_event_list); 266 + spin_unlock_bh(&mvm->time_event_lock); 267 + 268 + /* 269 + * Use a notification wait, which really just processes the 270 + * command response and doesn't wait for anything, in order 271 + * to be able to process the response and get the UID inside 272 + * the RX path. Using CMD_WANT_SKB doesn't work because it 273 + * stores the buffer and then wakes up this thread, by which 274 + * time another notification (that the time event started) 275 + * might already be processed unsuccessfully. 276 + */ 277 + iwl_init_notification_wait(&mvm->notif_wait, &wait_time_event, 278 + time_event_response, 279 + ARRAY_SIZE(time_event_response), 280 + iwl_mvm_time_event_response, te_data); 281 + 282 + ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_SYNC, 283 + sizeof(*te_cmd), te_cmd); 284 + if (ret) { 285 + IWL_ERR(mvm, "Couldn't send TIME_EVENT_CMD: %d\n", ret); 286 + iwl_remove_notification(&mvm->notif_wait, &wait_time_event); 287 + goto out_clear_te; 288 + } 289 + 290 + /* No need to wait for anything, so just pass 1 (0 isn't valid) */ 291 + ret = iwl_wait_notification(&mvm->notif_wait, &wait_time_event, 1); 292 + /* should never fail */ 293 + WARN_ON_ONCE(ret); 294 + 295 + if (ret) { 296 + out_clear_te: 297 + spin_lock_bh(&mvm->time_event_lock); 298 + iwl_mvm_te_clear_data(mvm, te_data); 299 + spin_unlock_bh(&mvm->time_event_lock); 300 + } 301 + return ret; 284 302 } 285 303 286 304 void iwl_mvm_protect_session(struct iwl_mvm *mvm, ··· 318 278 { 319 279 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 320 280 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; 321 - static const u8 time_event_notif[] = { TIME_EVENT_CMD, 322 - TIME_EVENT_NOTIFICATION }; 323 - struct iwl_notification_wait wait_time_event; 324 281 struct iwl_time_event_cmd time_cmd = {}; 325 - int ret; 326 282 327 283 lockdep_assert_held(&mvm->mutex); 328 284 ··· 345 309 iwl_mvm_stop_session_protection(mvm, vif); 346 310 } 347 311 348 - iwl_init_notification_wait(&mvm->notif_wait, &wait_time_event, 349 - time_event_notif, 350 - ARRAY_SIZE(time_event_notif), 351 - iwl_mvm_time_event_notif, 352 - &mvmvif->time_event_data); 353 - 354 312 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD); 355 313 time_cmd.id_and_color = 356 314 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)); ··· 352 322 353 323 time_cmd.apply_time = 354 324 cpu_to_le32(iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG)); 325 + 355 326 time_cmd.dep_policy = TE_INDEPENDENT; 356 327 time_cmd.is_present = cpu_to_le32(1); 357 328 time_cmd.max_frags = cpu_to_le32(TE_FRAG_NONE); ··· 364 333 time_cmd.repeat = cpu_to_le32(1); 365 334 time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_START | TE_NOTIF_HOST_END); 366 335 367 - te_data->vif = vif; 368 - te_data->duration = duration; 369 - 370 - spin_lock_bh(&mvm->time_event_lock); 371 - te_data->id = le32_to_cpu(time_cmd.id); 372 - list_add_tail(&te_data->list, &mvm->time_event_list); 373 - spin_unlock_bh(&mvm->time_event_lock); 374 - 375 - ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_SYNC, 376 - sizeof(time_cmd), &time_cmd); 377 - if (ret) { 378 - IWL_ERR(mvm, "Couldn't send TIME_EVENT_CMD: %d\n", ret); 379 - goto out_remove_notif; 380 - } 381 - 382 - ret = iwl_wait_notification(&mvm->notif_wait, &wait_time_event, 1 * HZ); 383 - if (ret) { 384 - IWL_ERR(mvm, "%s - failed on timeout\n", __func__); 385 - spin_lock_bh(&mvm->time_event_lock); 386 - iwl_mvm_te_clear_data(mvm, te_data); 387 - spin_unlock_bh(&mvm->time_event_lock); 388 - } 389 - 390 - return; 391 - 392 - out_remove_notif: 393 - iwl_remove_notification(&mvm->notif_wait, &wait_time_event); 336 + iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); 394 337 } 395 338 396 339 /* ··· 429 424 iwl_mvm_remove_time_event(mvm, mvmvif, te_data); 430 425 } 431 426 432 - static bool iwl_mvm_roc_te_notif(struct iwl_notif_wait_data *notif_wait, 433 - struct iwl_rx_packet *pkt, void *data) 434 - { 435 - struct iwl_mvm *mvm = 436 - container_of(notif_wait, struct iwl_mvm, notif_wait); 437 - struct iwl_mvm_time_event_data *te_data = data; 438 - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); 439 - struct iwl_time_event_resp *resp; 440 - 441 - u32 mac_id_n_color = FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color); 442 - 443 - /* until we do something else */ 444 - WARN_ON(te_data->id != TE_P2P_DEVICE_DISCOVERABLE); 445 - 446 - switch (pkt->hdr.cmd) { 447 - case TIME_EVENT_CMD: 448 - resp = (void *)pkt->data; 449 - WARN_ON(mac_id_n_color != le32_to_cpu(resp->id_and_color)); 450 - te_data->uid = le32_to_cpu(resp->unique_id); 451 - IWL_DEBUG_TE(mvm, "Got response - UID = 0x%x\n", te_data->uid); 452 - return true; 453 - 454 - default: 455 - WARN_ON(1); 456 - return false; 457 - }; 458 - } 459 - 460 427 int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 461 428 int duration) 462 429 { 463 430 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 464 431 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; 465 - static const u8 roc_te_notif[] = { TIME_EVENT_CMD }; 466 - struct iwl_notification_wait wait_time_event; 467 432 struct iwl_time_event_cmd time_cmd = {}; 468 - int ret; 469 433 470 434 lockdep_assert_held(&mvm->mutex); 471 435 if (te_data->running) { ··· 448 474 */ 449 475 flush_work(&mvm->roc_done_wk); 450 476 451 - iwl_init_notification_wait(&mvm->notif_wait, &wait_time_event, 452 - roc_te_notif, 453 - ARRAY_SIZE(roc_te_notif), 454 - iwl_mvm_roc_te_notif, 455 - &mvmvif->time_event_data); 456 - 457 477 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD); 458 478 time_cmd.id_and_color = 459 479 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)); 460 - time_cmd.id = cpu_to_le32(TE_P2P_DEVICE_DISCOVERABLE); 480 + time_cmd.id = cpu_to_le32(IWL_MVM_ROC_TE_TYPE); 461 481 462 482 time_cmd.apply_time = cpu_to_le32(0); 463 483 time_cmd.dep_policy = cpu_to_le32(TE_INDEPENDENT); ··· 460 492 time_cmd.interval = cpu_to_le32(1); 461 493 462 494 /* 463 - * TE_P2P_DEVICE_DISCOVERABLE can have lower priority than other events 495 + * IWL_MVM_ROC_TE_TYPE can have lower priority than other events 464 496 * that are being scheduled by the driver/fw, and thus it might not be 465 497 * scheduled. To improve the chances of it being scheduled, allow it to 466 498 * be fragmented. ··· 473 505 time_cmd.repeat = cpu_to_le32(1); 474 506 time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_START | TE_NOTIF_HOST_END); 475 507 476 - /* Push the te data to the tracked te list */ 477 - te_data->vif = vif; 478 - te_data->duration = MSEC_TO_TU(duration); 479 - 480 - spin_lock_bh(&mvm->time_event_lock); 481 - te_data->id = le32_to_cpu(time_cmd.id); 482 - list_add_tail(&te_data->list, &mvm->time_event_list); 483 - spin_unlock_bh(&mvm->time_event_lock); 484 - 485 - ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_SYNC, 486 - sizeof(time_cmd), &time_cmd); 487 - if (ret) { 488 - IWL_ERR(mvm, "Couldn't send TIME_EVENT_CMD: %d\n", ret); 489 - goto out_remove_notif; 490 - } 491 - 492 - ret = iwl_wait_notification(&mvm->notif_wait, &wait_time_event, 1 * HZ); 493 - if (ret) { 494 - IWL_ERR(mvm, "%s - failed on timeout\n", __func__); 495 - iwl_mvm_te_clear_data(mvm, te_data); 496 - } 497 - 498 - return ret; 499 - 500 - out_remove_notif: 501 - iwl_remove_notification(&mvm->notif_wait, &wait_time_event); 502 - return ret; 508 + return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); 503 509 } 504 510 505 511 void iwl_mvm_stop_p2p_roc(struct iwl_mvm *mvm)
+6 -6
drivers/net/wireless/iwlwifi/mvm/tx.c
··· 620 620 seq_ctl = le16_to_cpu(hdr->seq_ctrl); 621 621 } 622 622 623 - ieee80211_tx_status(mvm->hw, skb); 623 + ieee80211_tx_status_ni(mvm->hw, skb); 624 624 } 625 625 626 626 if (txq_id >= IWL_FIRST_AMPDU_QUEUE) { ··· 663 663 struct iwl_mvm_tid_data *tid_data = 664 664 &mvmsta->tid_data[tid]; 665 665 666 - spin_lock(&mvmsta->lock); 666 + spin_lock_bh(&mvmsta->lock); 667 667 tid_data->next_reclaimed = next_reclaimed; 668 668 IWL_DEBUG_TX_REPLY(mvm, "Next reclaimed packet:%d\n", 669 669 next_reclaimed); 670 670 iwl_mvm_check_ratid_empty(mvm, sta, tid); 671 - spin_unlock(&mvmsta->lock); 671 + spin_unlock_bh(&mvmsta->lock); 672 672 } 673 673 674 674 #ifdef CONFIG_PM_SLEEP ··· 832 832 return 0; 833 833 } 834 834 835 - spin_lock(&mvmsta->lock); 835 + spin_lock_bh(&mvmsta->lock); 836 836 837 837 __skb_queue_head_init(&reclaimed_skbs); 838 838 ··· 886 886 } 887 887 } 888 888 889 - spin_unlock(&mvmsta->lock); 889 + spin_unlock_bh(&mvmsta->lock); 890 890 891 891 rcu_read_unlock(); 892 892 893 893 while (!skb_queue_empty(&reclaimed_skbs)) { 894 894 skb = __skb_dequeue(&reclaimed_skbs); 895 - ieee80211_tx_status(mvm->hw, skb); 895 + ieee80211_tx_status_ni(mvm->hw, skb); 896 896 } 897 897 898 898 return 0;
+1 -2
drivers/net/wireless/iwlwifi/pcie/internal.h
··· 249 249 int ict_index; 250 250 u32 inta; 251 251 bool use_ict; 252 - struct tasklet_struct irq_tasklet; 253 252 struct isr_statistics isr_stats; 254 253 255 254 spinlock_t irq_lock; ··· 329 330 * RX 330 331 ******************************************************/ 331 332 int iwl_pcie_rx_init(struct iwl_trans *trans); 332 - void iwl_pcie_tasklet(struct iwl_trans *trans); 333 + irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id); 333 334 int iwl_pcie_rx_stop(struct iwl_trans *trans); 334 335 void iwl_pcie_rx_free(struct iwl_trans *trans); 335 336
+25 -15
drivers/net/wireless/iwlwifi/pcie/rx.c
··· 81 81 * 'processed' and 'read' driver indexes as well) 82 82 * + A received packet is processed and handed to the kernel network stack, 83 83 * detached from the iwl->rxq. The driver 'processed' index is updated. 84 - * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free 85 - * list. If there are no allocated buffers in iwl->rxq->rx_free, the READ 86 - * INDEX is not incremented and iwl->status(RX_STALLED) is set. If there 87 - * were enough free buffers and RX_STALLED is set it is cleared. 84 + * + The Host/Firmware iwl->rxq is replenished at irq thread time from the 85 + * rx_free list. If there are no allocated buffers in iwl->rxq->rx_free, 86 + * the READ INDEX is not incremented and iwl->status(RX_STALLED) is set. 87 + * If there were enough free buffers and RX_STALLED is set it is cleared. 88 88 * 89 89 * 90 90 * Driver sequence: ··· 214 214 /* 215 215 * If the device isn't enabled - not need to try to add buffers... 216 216 * This can happen when we stop the device and still have an interrupt 217 - * pending. We stop the APM before we sync the interrupts / tasklets 218 - * because we have to (see comment there). On the other hand, since 219 - * the APM is stopped, we cannot access the HW (in particular not prph). 217 + * pending. We stop the APM before we sync the interrupts because we 218 + * have to (see comment there). On the other hand, since the APM is 219 + * stopped, we cannot access the HW (in particular not prph). 220 220 * So don't try to restock if the APM has been already stopped. 221 221 */ 222 222 if (!test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status)) ··· 796 796 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); 797 797 wake_up(&trans_pcie->wait_command_queue); 798 798 799 + local_bh_disable(); 799 800 iwl_op_mode_nic_error(trans->op_mode); 801 + local_bh_enable(); 800 802 } 801 803 802 - void iwl_pcie_tasklet(struct iwl_trans *trans) 804 + irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) 803 805 { 806 + struct iwl_trans *trans = dev_id; 804 807 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 805 808 struct isr_statistics *isr_stats = &trans_pcie->isr_stats; 806 809 u32 inta = 0; ··· 813 810 #ifdef CONFIG_IWLWIFI_DEBUG 814 811 u32 inta_mask; 815 812 #endif 813 + 814 + lock_map_acquire(&trans->sync_cmd_lockdep_map); 816 815 817 816 spin_lock_irqsave(&trans_pcie->irq_lock, flags); 818 817 ··· 860 855 861 856 handled |= CSR_INT_BIT_HW_ERR; 862 857 863 - return; 858 + goto out; 864 859 } 865 860 866 861 #ifdef CONFIG_IWLWIFI_DEBUG ··· 1010 1005 /* Re-enable RF_KILL if it occurred */ 1011 1006 else if (handled & CSR_INT_BIT_RF_KILL) 1012 1007 iwl_enable_rfkill_int(trans); 1008 + 1009 + out: 1010 + lock_map_release(&trans->sync_cmd_lockdep_map); 1011 + return IRQ_HANDLED; 1013 1012 } 1014 1013 1015 1014 /****************************************************************************** ··· 1136 1127 1137 1128 /* Disable (but don't clear!) interrupts here to avoid 1138 1129 * back-to-back ISRs and sporadic interrupts from our NIC. 1139 - * If we have something to service, the tasklet will re-enable ints. 1130 + * If we have something to service, the irq thread will re-enable ints. 1140 1131 * If we *don't* have something, we'll re-enable before leaving here. */ 1141 1132 inta_mask = iwl_read32(trans, CSR_INT_MASK); 1142 1133 iwl_write32(trans, CSR_INT_MASK, 0x00000000); ··· 1176 1167 #endif 1177 1168 1178 1169 trans_pcie->inta |= inta; 1179 - /* iwl_pcie_tasklet() will service interrupts and re-enable them */ 1170 + /* the thread will service interrupts and re-enable them */ 1180 1171 if (likely(inta)) 1181 - tasklet_schedule(&trans_pcie->irq_tasklet); 1172 + return IRQ_WAKE_THREAD; 1182 1173 else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && 1183 1174 !trans_pcie->inta) 1184 1175 iwl_enable_interrupts(trans); ··· 1286 1277 trans_pcie->inta |= inta; 1287 1278 1288 1279 /* iwl_pcie_tasklet() will service interrupts and re-enable them */ 1289 - if (likely(inta)) 1290 - tasklet_schedule(&trans_pcie->irq_tasklet); 1291 - else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && 1280 + if (likely(inta)) { 1281 + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 1282 + return IRQ_WAKE_THREAD; 1283 + } else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && 1292 1284 !trans_pcie->inta) { 1293 1285 /* Allow interrupt if was disabled by this handler and 1294 1286 * no tasklet was schedules, We should not enable interrupt,
+4 -7
drivers/net/wireless/iwlwifi/pcie/trans.c
··· 760 760 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 761 761 762 762 synchronize_irq(trans_pcie->pci_dev->irq); 763 - tasklet_kill(&trans_pcie->irq_tasklet); 764 763 765 764 iwl_pcie_tx_free(trans); 766 765 iwl_pcie_rx_free(trans); ··· 1479 1480 1480 1481 trans->ops = &trans_ops_pcie; 1481 1482 trans->cfg = cfg; 1483 + trans_lockdep_init(trans); 1482 1484 trans_pcie->trans = trans; 1483 1485 spin_lock_init(&trans_pcie->irq_lock); 1484 1486 spin_lock_init(&trans_pcie->reg_lock); ··· 1567 1567 1568 1568 trans_pcie->inta_mask = CSR_INI_SET_MASK; 1569 1569 1570 - tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long)) 1571 - iwl_pcie_tasklet, (unsigned long)trans); 1572 - 1573 1570 if (iwl_pcie_alloc_ict(trans)) 1574 1571 goto out_free_cmd_pool; 1575 1572 1576 - err = request_irq(pdev->irq, iwl_pcie_isr_ict, 1577 - IRQF_SHARED, DRV_NAME, trans); 1578 - if (err) { 1573 + if (request_threaded_irq(pdev->irq, iwl_pcie_isr_ict, 1574 + iwl_pcie_irq_handler, 1575 + IRQF_SHARED, DRV_NAME, trans)) { 1579 1576 IWL_ERR(trans, "Error allocating IRQ %d\n", pdev->irq); 1580 1577 goto out_free_ict; 1581 1578 }
+4 -4
drivers/net/wireless/iwlwifi/pcie/tx.c
··· 926 926 if (WARN_ON(txq_id == trans_pcie->cmd_queue)) 927 927 return; 928 928 929 - spin_lock(&txq->lock); 929 + spin_lock_bh(&txq->lock); 930 930 931 931 if (txq->q.read_ptr == tfd_num) 932 932 goto out; ··· 970 970 if (iwl_queue_space(&txq->q) > txq->q.low_mark) 971 971 iwl_wake_queue(trans, txq); 972 972 out: 973 - spin_unlock(&txq->lock); 973 + spin_unlock_bh(&txq->lock); 974 974 } 975 975 976 976 /* ··· 1371 1371 return; 1372 1372 } 1373 1373 1374 - spin_lock(&txq->lock); 1374 + spin_lock_bh(&txq->lock); 1375 1375 1376 1376 cmd_index = get_cmd_index(&txq->q, index); 1377 1377 cmd = txq->entries[cmd_index].cmd; ··· 1405 1405 1406 1406 meta->flags = 0; 1407 1407 1408 - spin_unlock(&txq->lock); 1408 + spin_unlock_bh(&txq->lock); 1409 1409 } 1410 1410 1411 1411 #define HOST_COMPLETE_TIMEOUT (2 * HZ)