aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-02-12 12:51:08 -0500
committerJohn W. Linville <linville@tuxdriver.com>2013-02-12 12:51:08 -0500
commit5171f7a0b79dfbc61a6e12f20f6eef6d7dd5b2a8 (patch)
tree50e48f8b65bc10fd7b8959735cb599884a161d1b
parentc88d0dc1cc0182358ce1ae6f457dace34539eb12 (diff)
parent36eed56a8f7e1bd7fb5014ea0e702708e1702f30 (diff)
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
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/commands.h18
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c161
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rxon.c5
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/sta.c4
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-op-mode.h10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h29
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c174
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c17
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c41
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c29
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c40
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.h6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c232
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c12
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h3
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c40
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c11
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c8
25 files changed, 572 insertions, 303 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h
index 8bce4b0148e0..02c9ebb3b340 100644
--- a/drivers/net/wireless/iwlwifi/dvm/commands.h
+++ b/drivers/net/wireless/iwlwifi/dvm/commands.h
@@ -3897,6 +3897,24 @@ struct iwlagn_wowlan_kek_kck_material_cmd {
3897 __le64 replay_ctr; 3897 __le64 replay_ctr;
3898} __packed; 3898} __packed;
3899 3899
3900#define RF_KILL_INDICATOR_FOR_WOWLAN 0x87
3901
3902/*
3903 * REPLY_WOWLAN_GET_STATUS = 0xe5
3904 */
3905struct 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 * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification) 3919 * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification)
3902 */ 3920 */
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index 0fccf725a2e6..323e4a33fcac 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -441,52 +441,154 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
441 return ret; 441 return ret;
442} 442}
443 443
444struct iwl_resume_data {
445 struct iwl_priv *priv;
446 struct iwlagn_wowlan_status *cmd;
447 bool valid;
448};
449
450static 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
444static int iwlagn_mac_resume(struct ieee80211_hw *hw) 467static int iwlagn_mac_resume(struct ieee80211_hw *hw)
445{ 468{
446 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 469 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
447 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 470 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
448 struct ieee80211_vif *vif; 471 struct ieee80211_vif *vif;
449 unsigned long flags; 472 u32 base;
450 u32 base, status = 0xffffffff; 473 int ret;
451 int ret = -EIO; 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 IWL_DEBUG_MAC80211(priv, "enter\n"); 497 IWL_DEBUG_MAC80211(priv, "enter\n");
454 mutex_lock(&priv->mutex); 498 mutex_lock(&priv->mutex);
455 499
456 iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_CLR, 500 /* we'll clear ctx->vif during iwlagn_prepare_restart() */
457 CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); 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 }
458 511
459 base = priv->device_pointers.error_event_table; 512 base = priv->device_pointers.error_event_table;
460 if (iwlagn_hw_valid_rtc_data_addr(base)) { 513 if (!iwlagn_hw_valid_rtc_data_addr(base)) {
461 if (iwl_trans_grab_nic_access(priv->trans, true, &flags)) { 514 IWL_WARN(priv, "Invalid error table during resume!\n");
462 iwl_write32(priv->trans, HBUS_TARG_MEM_RADDR, base); 515 goto out_unlock;
463 status = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT); 516 }
464 iwl_trans_release_nic_access(priv->trans, &flags); 517
465 ret = 0; 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);
466 } 528 }
529 goto out_unlock;
530 }
467 531
468#ifdef CONFIG_IWLWIFI_DEBUGFS 532#ifdef CONFIG_IWLWIFI_DEBUGFS
469 if (ret == 0) { 533 img = &priv->fw->img[IWL_UCODE_WOWLAN];
470 const struct fw_img *img; 534 if (!priv->wowlan_sram)
471 535 priv->wowlan_sram =
472 img = &(priv->fw->img[IWL_UCODE_WOWLAN]); 536 kzalloc(img->sec[IWL_UCODE_SECTION_DATA].len,
473 if (!priv->wowlan_sram) { 537 GFP_KERNEL);
474 priv->wowlan_sram = 538
475 kzalloc(img->sec[IWL_UCODE_SECTION_DATA].len, 539 if (priv->wowlan_sram)
476 GFP_KERNEL); 540 iwl_trans_read_mem(priv->trans, 0x800000,
477 } 541 priv->wowlan_sram,
542 img->sec[IWL_UCODE_SECTION_DATA].len / 4);
543#endif
478 544
479 if (priv->wowlan_sram) 545 /*
480 iwl_trans_read_mem( 546 * This is very strange. The GET_STATUS command is sent but the device
481 priv->trans, 0x800000, 547 * doesn't reply properly, it seems it doesn't close the RBD so one is
482 priv->wowlan_sram, 548 * always left open ... As a result, we need to send another command
483 img->sec[IWL_UCODE_SECTION_DATA].len / 4); 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;
484 } 588 }
485#endif
486 }
487 589
488 /* we'll clear ctx->vif during iwlagn_prepare_restart() */ 590 ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL);
489 vif = ctx->vif; 591 }
490 592
491 priv->wowlan = false; 593 priv->wowlan = false;
492 594
@@ -496,6 +598,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
496 iwl_connection_init_rx_config(priv, ctx); 598 iwl_connection_init_rx_config(priv, ctx);
497 iwlagn_set_rxon_chain(priv, ctx); 599 iwlagn_set_rxon_chain(priv, ctx);
498 600
601 out_unlock:
499 mutex_unlock(&priv->mutex); 602 mutex_unlock(&priv->mutex);
500 IWL_DEBUG_MAC80211(priv, "leave\n"); 603 IWL_DEBUG_MAC80211(priv, "leave\n");
501 604
diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c
index e8d5b90abf5c..a4eed2055fdb 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rx.c
@@ -790,7 +790,7 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
790 790
791 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); 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
796static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) 796static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c
index 9fabd26997ca..23be948cf162 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rxon.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c
@@ -1545,10 +1545,9 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
1545 bss_conf->bssid); 1545 bss_conf->bssid);
1546 } 1546 }
1547 1547
1548 if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_ADHOC && 1548 if (changes & BSS_CHANGED_BEACON && priv->beacon_ctx == ctx) {
1549 priv->beacon_ctx) {
1550 if (iwlagn_update_beacon(priv, vif)) 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 mutex_unlock(&priv->mutex); 1553 mutex_unlock(&priv->mutex);
diff --git a/drivers/net/wireless/iwlwifi/dvm/sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c
index ab768045696b..2d33760a9dc2 100644
--- a/drivers/net/wireless/iwlwifi/dvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/dvm/sta.c
@@ -77,7 +77,7 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv,
77 IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n", 77 IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n",
78 sta_id); 78 sta_id);
79 79
80 spin_lock(&priv->sta_lock); 80 spin_lock_bh(&priv->sta_lock);
81 81
82 switch (add_sta_resp->status) { 82 switch (add_sta_resp->status) {
83 case ADD_STA_SUCCESS_MSK: 83 case ADD_STA_SUCCESS_MSK:
@@ -119,7 +119,7 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv,
119 priv->stations[sta_id].sta.mode == 119 priv->stations[sta_id].sta.mode ==
120 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", 120 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
121 addsta->sta.addr); 121 addsta->sta.addr);
122 spin_unlock(&priv->sta_lock); 122 spin_unlock_bh(&priv->sta_lock);
123 123
124 return ret; 124 return ret;
125} 125}
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index 7b0550d35a91..4ece5ea81b86 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -1117,7 +1117,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
1117 sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >> 1117 sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >>
1118 IWLAGN_TX_RES_RA_POS; 1118 IWLAGN_TX_RES_RA_POS;
1119 1119
1120 spin_lock(&priv->sta_lock); 1120 spin_lock_bh(&priv->sta_lock);
1121 1121
1122 if (is_agg) 1122 if (is_agg)
1123 iwl_rx_reply_tx_agg(priv, tx_resp); 1123 iwl_rx_reply_tx_agg(priv, tx_resp);
@@ -1239,11 +1239,11 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
1239 le16_to_cpu(tx_resp->seq_ctl)); 1239 le16_to_cpu(tx_resp->seq_ctl));
1240 1240
1241 iwl_check_abort_status(priv, tx_resp->frame_count, status); 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 while (!skb_queue_empty(&skbs)) { 1244 while (!skb_queue_empty(&skbs)) {
1245 skb = __skb_dequeue(&skbs); 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 if (is_offchannel_skb) 1249 if (is_offchannel_skb)
@@ -1290,12 +1290,12 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
1290 tid = ba_resp->tid; 1290 tid = ba_resp->tid;
1291 agg = &priv->tid_data[sta_id][tid].agg; 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 if (unlikely(!agg->wait_for_ba)) { 1295 if (unlikely(!agg->wait_for_ba)) {
1296 if (unlikely(ba_resp->bitmap)) 1296 if (unlikely(ba_resp->bitmap))
1297 IWL_ERR(priv, "Received BA when not expected\n"); 1297 IWL_ERR(priv, "Received BA when not expected\n");
1298 spin_unlock(&priv->sta_lock); 1298 spin_unlock_bh(&priv->sta_lock);
1299 return 0; 1299 return 0;
1300 } 1300 }
1301 1301
@@ -1309,7 +1309,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
1309 IWL_DEBUG_TX_QUEUES(priv, 1309 IWL_DEBUG_TX_QUEUES(priv,
1310 "Bad queue mapping txq_id=%d, agg_txq[sta:%d,tid:%d]=%d\n", 1310 "Bad queue mapping txq_id=%d, agg_txq[sta:%d,tid:%d]=%d\n",
1311 scd_flow, sta_id, tid, agg->txq_id); 1311 scd_flow, sta_id, tid, agg->txq_id);
1312 spin_unlock(&priv->sta_lock); 1312 spin_unlock_bh(&priv->sta_lock);
1313 return 0; 1313 return 0;
1314 } 1314 }
1315 1315
@@ -1378,11 +1378,11 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
1378 } 1378 }
1379 } 1379 }
1380 1380
1381 spin_unlock(&priv->sta_lock); 1381 spin_unlock_bh(&priv->sta_lock);
1382 1382
1383 while (!skb_queue_empty(&reclaimed_skbs)) { 1383 while (!skb_queue_empty(&reclaimed_skbs)) {
1384 skb = __skb_dequeue(&reclaimed_skbs); 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 return 0; 1388 return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
index dc792584f401..4a680019e117 100644
--- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h
+++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
@@ -113,13 +113,13 @@ struct iwl_cfg;
113 * May sleep 113 * May sleep
114 * @rx: Rx notification to the op_mode. rxb is the Rx buffer itself. Cmd is the 114 * @rx: Rx notification to the op_mode. rxb is the Rx buffer itself. Cmd is the
115 * HCMD the this Rx responds to. 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 * @queue_full: notifies that a HW queue is full. 117 * @queue_full: notifies that a HW queue is full.
118 * Must be atomic and called with BH disabled. 118 * Must be atomic and called with BH disabled.
119 * @queue_not_full: notifies that a HW queue is not full any more. 119 * @queue_not_full: notifies that a HW queue is not full any more.
120 * Must be atomic and called with BH disabled. 120 * Must be atomic and called with BH disabled.
121 * @hw_rf_kill:notifies of a change in the HW rf kill switch. True means that 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 * @free_skb: allows the transport layer to free skbs that haven't been 123 * @free_skb: allows the transport layer to free skbs that haven't been
124 * reclaimed by the op_mode. This can happen when the driver is freed and 124 * reclaimed by the op_mode. This can happen when the driver is freed and
125 * there are Tx packets pending in the transport layer. 125 * there are Tx packets pending in the transport layer.
@@ -130,8 +130,7 @@ struct iwl_cfg;
130 * called with BH disabled. 130 * called with BH disabled.
131 * @nic_config: configure NIC, called before firmware is started. 131 * @nic_config: configure NIC, called before firmware is started.
132 * May sleep 132 * May sleep
133 * @wimax_active: invoked when WiMax becomes active. Must be atomic and called 133 * @wimax_active: invoked when WiMax becomes active. May sleep
134 * with BH disabled.
135 */ 134 */
136struct iwl_op_mode_ops { 135struct iwl_op_mode_ops {
137 struct iwl_op_mode *(*start)(struct iwl_trans *trans, 136 struct iwl_op_mode *(*start)(struct iwl_trans *trans,
@@ -178,6 +177,7 @@ static inline int iwl_op_mode_rx(struct iwl_op_mode *op_mode,
178 struct iwl_rx_cmd_buffer *rxb, 177 struct iwl_rx_cmd_buffer *rxb,
179 struct iwl_device_cmd *cmd) 178 struct iwl_device_cmd *cmd)
180{ 179{
180 might_sleep();
181 return op_mode->ops->rx(op_mode, rxb, cmd); 181 return op_mode->ops->rx(op_mode, rxb, cmd);
182} 182}
183 183
@@ -196,6 +196,7 @@ static inline void iwl_op_mode_queue_not_full(struct iwl_op_mode *op_mode,
196static inline void iwl_op_mode_hw_rf_kill(struct iwl_op_mode *op_mode, 196static inline void iwl_op_mode_hw_rf_kill(struct iwl_op_mode *op_mode,
197 bool state) 197 bool state)
198{ 198{
199 might_sleep();
199 op_mode->ops->hw_rf_kill(op_mode, state); 200 op_mode->ops->hw_rf_kill(op_mode, state);
200} 201}
201 202
@@ -223,6 +224,7 @@ static inline void iwl_op_mode_nic_config(struct iwl_op_mode *op_mode)
223 224
224static inline void iwl_op_mode_wimax_active(struct iwl_op_mode *op_mode) 225static inline void iwl_op_mode_wimax_active(struct iwl_op_mode *op_mode)
225{ 226{
227 might_sleep();
226 op_mode->ops->wimax_active(op_mode); 228 op_mode->ops->wimax_active(op_mode);
227} 229}
228 230
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 0a3d4df5f434..8c7bec6b9a0b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -65,6 +65,7 @@
65 65
66#include <linux/ieee80211.h> 66#include <linux/ieee80211.h>
67#include <linux/mm.h> /* for page_address */ 67#include <linux/mm.h> /* for page_address */
68#include <linux/lockdep.h>
68 69
69#include "iwl-debug.h" 70#include "iwl-debug.h"
70#include "iwl-config.h" 71#include "iwl-config.h"
@@ -526,6 +527,10 @@ struct iwl_trans {
526 527
527 struct dentry *dbgfs_dir; 528 struct dentry *dbgfs_dir;
528 529
530#ifdef CONFIG_LOCKDEP
531 struct lockdep_map sync_cmd_lockdep_map;
532#endif
533
529 /* pointer to trans specific struct */ 534 /* pointer to trans specific struct */
530 /*Ensure that this pointer will always be aligned to sizeof pointer */ 535 /*Ensure that this pointer will always be aligned to sizeof pointer */
531 char trans_specific[0] __aligned(sizeof(void *)); 536 char trans_specific[0] __aligned(sizeof(void *));
@@ -602,12 +607,22 @@ static inline int iwl_trans_d3_resume(struct iwl_trans *trans,
602} 607}
603 608
604static inline int iwl_trans_send_cmd(struct iwl_trans *trans, 609static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
605 struct iwl_host_cmd *cmd) 610 struct iwl_host_cmd *cmd)
606{ 611{
612 int ret;
613
607 WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, 614 WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
608 "%s bad state = %d", __func__, trans->state); 615 "%s bad state = %d", __func__, trans->state);
609 616
610 return trans->ops->send_cmd(trans, cmd); 617 if (!(cmd->flags & CMD_ASYNC))
618 lock_map_acquire_read(&trans->sync_cmd_lockdep_map);
619
620 ret = trans->ops->send_cmd(trans, cmd);
621
622 if (!(cmd->flags & CMD_ASYNC))
623 lock_map_release(&trans->sync_cmd_lockdep_map);
624
625 return ret;
611} 626}
612 627
613static inline struct iwl_device_cmd * 628static inline struct iwl_device_cmd *
@@ -791,4 +806,14 @@ iwl_trans_release_nic_access(struct iwl_trans *trans, unsigned long *flags)
791int __must_check iwl_pci_register_driver(void); 806int __must_check iwl_pci_register_driver(void);
792void iwl_pci_unregister_driver(void); 807void iwl_pci_unregister_driver(void);
793 808
809static inline void trans_lockdep_init(struct iwl_trans *trans)
810{
811#ifdef CONFIG_LOCKDEP
812 static struct lock_class_key __key;
813
814 lockdep_init_map(&trans->sync_cmd_lockdep_map, "sync_cmd_lockdep_map",
815 &__key, 0);
816#endif
817}
818
794#endif /* __iwl_trans_h__ */ 819#endif /* __iwl_trans_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 9a95c374990d..c64d864799cd 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -97,14 +97,14 @@ void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw,
97 struct inet6_ifaddr *ifa; 97 struct inet6_ifaddr *ifa;
98 int idx = 0; 98 int idx = 0;
99 99
100 read_lock(&idev->lock); 100 read_lock_bh(&idev->lock);
101 list_for_each_entry(ifa, &idev->addr_list, if_list) { 101 list_for_each_entry(ifa, &idev->addr_list, if_list) {
102 mvmvif->target_ipv6_addrs[idx] = ifa->addr; 102 mvmvif->target_ipv6_addrs[idx] = ifa->addr;
103 idx++; 103 idx++;
104 if (idx >= IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS) 104 if (idx >= IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS)
105 break; 105 break;
106 } 106 }
107 read_unlock(&idev->lock); 107 read_unlock_bh(&idev->lock);
108 108
109 mvmvif->num_target_ipv6_addrs = idx; 109 mvmvif->num_target_ipv6_addrs = idx;
110} 110}
@@ -490,7 +490,7 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
490 return -EIO; 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 if (ret) 494 if (ret)
495 return ret; 495 return ret;
496 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], ap_sta); 496 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], ap_sta);
@@ -763,6 +763,146 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
763 return ret; 763 return ret;
764} 764}
765 765
766static 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
766int iwl_mvm_resume(struct ieee80211_hw *hw) 906int iwl_mvm_resume(struct ieee80211_hw *hw)
767{ 907{
768 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 908 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
@@ -770,14 +910,8 @@ int iwl_mvm_resume(struct ieee80211_hw *hw)
770 .mvm = mvm, 910 .mvm = mvm,
771 }; 911 };
772 struct ieee80211_vif *vif = NULL; 912 struct ieee80211_vif *vif = NULL;
773 u32 base;
774 int ret; 913 int ret;
775 enum iwl_d3_status d3_status; 914 enum iwl_d3_status d3_status;
776 struct error_table_start {
777 /* cf. struct iwl_error_event_table */
778 u32 valid;
779 u32 error_id;
780 } err_info;
781 915
782 mutex_lock(&mvm->mutex); 916 mutex_lock(&mvm->mutex);
783 917
@@ -800,27 +934,7 @@ int iwl_mvm_resume(struct ieee80211_hw *hw)
800 goto out_unlock; 934 goto out_unlock;
801 } 935 }
802 936
803 base = mvm->error_event_table; 937 iwl_mvm_query_wakeup_reasons(mvm, vif);
804
805 iwl_trans_read_mem_bytes(mvm->trans, base,
806 &err_info, sizeof(err_info));
807
808 if (err_info.valid) {
809 IWL_INFO(mvm, "error table is valid (%d)\n",
810 err_info.valid);
811 if (err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN)
812 IWL_ERR(mvm, "this was due to RF-kill\n");
813 goto out_unlock;
814 }
815
816 /* TODO: get status and whatever else ... */
817 ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_GET_STATUSES, CMD_SYNC, 0, NULL);
818 if (ret)
819 IWL_ERR(mvm, "failed to query status (%d)\n", ret);
820
821 ret = iwl_mvm_send_cmd_pdu(mvm, OFFLOADS_QUERY_CMD, CMD_SYNC, 0, NULL);
822 if (ret)
823 IWL_ERR(mvm, "failed to query offloads (%d)\n", ret);
824 938
825 out_unlock: 939 out_unlock:
826 mutex_unlock(&mvm->mutex); 940 mutex_unlock(&mvm->mutex);
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 9fd49db32a32..23eebda848b0 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -633,6 +633,9 @@ struct iwl_binding_cmd {
633 __le32 phy; 633 __le32 phy;
634} __packed; /* BINDING_CMD_API_S_VER_1 */ 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 * struct iwl_time_quota_data - configuration of time quota per binding 640 * struct iwl_time_quota_data - configuration of time quota per binding
638 * @id_and_color: ID and color of the relevant Binding 641 * @id_and_color: ID and color of the relevant Binding
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index 90473c2ba1c7..d3d959db03a9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -621,10 +621,6 @@ int iwl_mvm_rx_card_state_notif(struct iwl_mvm *mvm,
621 (flags & CT_KILL_CARD_DISABLED) ? 621 (flags & CT_KILL_CARD_DISABLED) ?
622 "Reached" : "Not reached"); 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 return 0; 624 return 0;
629} 625}
630 626
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index c08a17a3cab9..0854dc338881 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -584,7 +584,11 @@ static void iwl_mvm_mac_ctxt_cmd_fill_sta(struct iwl_mvm *mvm,
584 struct ieee80211_vif *vif, 584 struct ieee80211_vif *vif,
585 struct iwl_mac_data_sta *ctxt_sta) 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 ctxt_sta->bi = cpu_to_le32(vif->bss_conf.beacon_int); 593 ctxt_sta->bi = cpu_to_le32(vif->bss_conf.beacon_int);
590 ctxt_sta->bi_reciprocal = 594 ctxt_sta->bi_reciprocal =
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index bbb8a5b35662..e27eb9724112 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -474,7 +474,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
474 if (mvm->vif_count > 1) { 474 if (mvm->vif_count > 1) {
475 IWL_DEBUG_MAC80211(mvm, 475 IWL_DEBUG_MAC80211(mvm,
476 "Disable power on existing interfaces\n"); 476 "Disable power on existing interfaces\n");
477 ieee80211_iterate_active_interfaces( 477 ieee80211_iterate_active_interfaces_atomic(
478 mvm->hw, 478 mvm->hw,
479 IEEE80211_IFACE_ITER_NORMAL, 479 IEEE80211_IFACE_ITER_NORMAL,
480 iwl_mvm_pm_disable_iterator, mvm); 480 iwl_mvm_pm_disable_iterator, mvm);
@@ -670,8 +670,6 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
670 IWL_ERR(mvm, "failed to update quotas\n"); 670 IWL_ERR(mvm, "failed to update quotas\n");
671 return; 671 return;
672 } 672 }
673 iwl_mvm_remove_time_event(mvm, mvmvif,
674 &mvmvif->time_event_data);
675 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { 673 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
676 /* remove AP station now that the MAC is unassoc */ 674 /* remove AP station now that the MAC is unassoc */
677 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); 675 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id);
@@ -683,6 +681,13 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
683 if (ret) 681 if (ret)
684 IWL_ERR(mvm, "failed to update quotas\n"); 682 IWL_ERR(mvm, "failed to update quotas\n");
685 } 683 }
684 } else if (changes & BSS_CHANGED_DTIM_PERIOD) {
685 /*
686 * We received a beacon _after_ association so
687 * remove the session protection.
688 */
689 iwl_mvm_remove_time_event(mvm, mvmvif,
690 &mvmvif->time_event_data);
686 } else if (changes & BSS_CHANGED_PS) { 691 } else if (changes & BSS_CHANGED_PS) {
687 /* 692 /*
688 * TODO: remove this temporary code. 693 * TODO: remove this temporary code.
@@ -921,8 +926,10 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
921 ret = 0; 926 ret = 0;
922 } else if (old_state == IEEE80211_STA_AUTH && 927 } else if (old_state == IEEE80211_STA_AUTH &&
923 new_state == IEEE80211_STA_ASSOC) { 928 new_state == IEEE80211_STA_ASSOC) {
924 iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band); 929 ret = iwl_mvm_update_sta(mvm, vif, sta);
925 ret = 0; 930 if (ret == 0)
931 iwl_mvm_rs_rate_init(mvm, sta,
932 mvmvif->phy_ctxt->channel->band);
926 } else if (old_state == IEEE80211_STA_ASSOC && 933 } else if (old_state == IEEE80211_STA_ASSOC &&
927 new_state == IEEE80211_STA_AUTHORIZED) { 934 new_state == IEEE80211_STA_AUTHORIZED) {
928 ret = 0; 935 ret = 0;
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 983dca3f888a..aa59adf87db3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -536,25 +536,28 @@ static int iwl_mvm_rx_dispatch(struct iwl_op_mode *op_mode,
536 536
537 for (i = 0; i < ARRAY_SIZE(iwl_mvm_rx_handlers); i++) { 537 for (i = 0; i < ARRAY_SIZE(iwl_mvm_rx_handlers); i++) {
538 const struct iwl_rx_handlers *rx_h = &iwl_mvm_rx_handlers[i]; 538 const struct iwl_rx_handlers *rx_h = &iwl_mvm_rx_handlers[i];
539 if (rx_h->cmd_id == pkt->hdr.cmd) { 539 struct iwl_async_handler_entry *entry;
540 struct iwl_async_handler_entry *entry; 540
541 if (!rx_h->async) 541 if (rx_h->cmd_id != pkt->hdr.cmd)
542 return rx_h->fn(mvm, rxb, cmd); 542 continue;
543 543
544 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 544 if (!rx_h->async)
545 /* we can't do much... */ 545 return rx_h->fn(mvm, rxb, cmd);
546 if (!entry) 546
547 return 0; 547 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
548 548 /* we can't do much... */
549 entry->rxb._page = rxb_steal_page(rxb); 549 if (!entry)
550 entry->rxb._offset = rxb->_offset; 550 return 0;
551 entry->rxb._rx_page_order = rxb->_rx_page_order; 551
552 entry->fn = rx_h->fn; 552 entry->rxb._page = rxb_steal_page(rxb);
553 spin_lock(&mvm->async_handlers_lock); 553 entry->rxb._offset = rxb->_offset;
554 list_add_tail(&entry->list, &mvm->async_handlers_list); 554 entry->rxb._rx_page_order = rxb->_rx_page_order;
555 spin_unlock(&mvm->async_handlers_lock); 555 entry->fn = rx_h->fn;
556 schedule_work(&mvm->async_handlers_wk); 556 spin_lock(&mvm->async_handlers_lock);
557 } 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 return 0; 563 return 0;
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index 63628739cf4a..5a92a4978795 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -194,7 +194,7 @@ int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
194 cmd.id_and_color, iwlmvm_mod_params.power_scheme, 194 cmd.id_and_color, iwlmvm_mod_params.power_scheme,
195 le16_to_cpu(cmd.flags)); 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 sizeof(cmd), &cmd); 198 sizeof(cmd), &cmd);
199} 199}
200 200
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c
index 2d4611a563c5..925628468146 100644
--- a/drivers/net/wireless/iwlwifi/mvm/quota.c
+++ b/drivers/net/wireless/iwlwifi/mvm/quota.c
@@ -131,7 +131,7 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
131int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif) 131int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
132{ 132{
133 struct iwl_time_quota_cmd cmd; 133 struct iwl_time_quota_cmd cmd;
134 int i, idx, ret; 134 int i, idx, ret, num_active_bindings, quota, quota_rem;
135 struct iwl_mvm_quota_iterator_data data = { 135 struct iwl_mvm_quota_iterator_data data = {
136 .n_interfaces = {}, 136 .n_interfaces = {},
137 .colors = { -1, -1, -1, -1 }, 137 .colors = { -1, -1, -1, -1 },
@@ -156,20 +156,39 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
156 iwl_mvm_quota_iterator(&data, newvif->addr, newvif); 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 for (idx = 0, i = 0; i < MAX_BINDINGS; i++) { 177 for (idx = 0, i = 0; i < MAX_BINDINGS; i++) {
160 if (data.n_interfaces[i] <= 0) 178 if (data.n_interfaces[i] <= 0)
161 continue; 179 continue;
162 180
163 cmd.quotas[idx].id_and_color = 181 cmd.quotas[idx].id_and_color =
164 cpu_to_le32(FW_CMD_ID_AND_COLOR(i, data.colors[i])); 182 cpu_to_le32(FW_CMD_ID_AND_COLOR(i, data.colors[i]));
165 cmd.quotas[idx].quota = cpu_to_le32(100); 183 cmd.quotas[idx].quota = cpu_to_le32(quota);
166 cmd.quotas[idx].max_duration = cpu_to_le32(1000); 184 cmd.quotas[idx].max_duration = cpu_to_le32(IWL_MVM_MAX_QUOTA);
167 idx++; 185 idx++;
168 } 186 }
169 187
170 for (i = idx; i < MAX_BINDINGS; i++) 188 /* Give the remainder of the session to the first binding */
171 cmd.quotas[i].id_and_color = cpu_to_le32(FW_CTXT_INVALID); 189 le32_add_cpu(&cmd.quotas[0].quota, quota_rem);
172 190
191send_cmd:
173 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, CMD_SYNC, 192 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, CMD_SYNC,
174 sizeof(cmd), &cmd); 193 sizeof(cmd), &cmd);
175 if (ret) 194 if (ret)
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index 52da375e5740..3f3ce91ad5c2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -121,7 +121,7 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm,
121 121
122 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); 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/*
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 69603c3b2b39..a1eb692d7fad 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -81,8 +81,9 @@ static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm)
81 return IWL_MVM_STATION_COUNT; 81 return IWL_MVM_STATION_COUNT;
82} 82}
83 83
84/* add a NEW station to fw */ 84/* send station add/update command to firmware */
85int iwl_mvm_sta_add_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta) 85int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
86 bool update)
86{ 87{
87 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 88 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
88 struct iwl_mvm_add_sta_cmd add_sta_cmd; 89 struct iwl_mvm_add_sta_cmd add_sta_cmd;
@@ -94,8 +95,11 @@ int iwl_mvm_sta_add_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta)
94 95
95 add_sta_cmd.sta_id = mvm_sta->sta_id; 96 add_sta_cmd.sta_id = mvm_sta->sta_id;
96 add_sta_cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color); 97 add_sta_cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
97 add_sta_cmd.tfd_queue_msk = cpu_to_le32(mvm_sta->tfd_queue_msk); 98 if (!update) {
98 memcpy(&add_sta_cmd.addr, sta->addr, ETH_ALEN); 99 add_sta_cmd.tfd_queue_msk = cpu_to_le32(mvm_sta->tfd_queue_msk);
100 memcpy(&add_sta_cmd.addr, sta->addr, ETH_ALEN);
101 }
102 add_sta_cmd.add_modify = update ? 1 : 0;
99 103
100 /* STA_FLG_FAT_EN_MSK ? */ 104 /* STA_FLG_FAT_EN_MSK ? */
101 /* STA_FLG_MIMO_EN_MSK ? */ 105 /* STA_FLG_MIMO_EN_MSK ? */
@@ -181,7 +185,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
181 /* for HW restart - need to reset the seq_number etc... */ 185 /* for HW restart - need to reset the seq_number etc... */
182 memset(mvm_sta->tid_data, 0, sizeof(mvm_sta->tid_data)); 186 memset(mvm_sta->tid_data, 0, sizeof(mvm_sta->tid_data));
183 187
184 ret = iwl_mvm_sta_add_to_fw(mvm, sta); 188 ret = iwl_mvm_sta_send_to_fw(mvm, sta, false);
185 if (ret) 189 if (ret)
186 return ret; 190 return ret;
187 191
@@ -195,6 +199,13 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
195 return 0; 199 return 0;
196} 200}
197 201
202int iwl_mvm_update_sta(struct iwl_mvm *mvm,
203 struct ieee80211_vif *vif,
204 struct ieee80211_sta *sta)
205{
206 return iwl_mvm_sta_send_to_fw(mvm, sta, true);
207}
208
198int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, 209int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
199 bool drain) 210 bool drain)
200{ 211{
@@ -1116,7 +1127,8 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
1116 if (WARN_ON_ONCE(mvm_sta->vif != vif)) 1127 if (WARN_ON_ONCE(mvm_sta->vif != vif))
1117 return -EINVAL; 1128 return -EINVAL;
1118 1129
1119 key_flags = cpu_to_le16(keyconf->keyidx & STA_KEY_FLG_KEYID_MSK); 1130 key_flags = cpu_to_le16((keyconf->keyidx << STA_KEY_FLG_KEYID_POS) &
1131 STA_KEY_FLG_KEYID_MSK);
1120 key_flags |= cpu_to_le16(STA_KEY_FLG_NO_ENC | STA_KEY_FLG_WEP_KEY_MAP); 1132 key_flags |= cpu_to_le16(STA_KEY_FLG_NO_ENC | STA_KEY_FLG_WEP_KEY_MAP);
1121 key_flags |= cpu_to_le16(STA_KEY_NOT_VALID); 1133 key_flags |= cpu_to_le16(STA_KEY_NOT_VALID);
1122 1134
@@ -1154,14 +1166,26 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
1154 struct ieee80211_sta *sta, u32 iv32, 1166 struct ieee80211_sta *sta, u32 iv32,
1155 u16 *phase1key) 1167 u16 *phase1key)
1156{ 1168{
1157 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 1169 struct iwl_mvm_sta *mvm_sta;
1158 u8 sta_id = iwl_mvm_get_key_sta_id(vif, sta); 1170 u8 sta_id = iwl_mvm_get_key_sta_id(vif, sta);
1159 1171
1160 if (sta_id == IWL_INVALID_STATION) 1172 if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION))
1161 return; 1173 return;
1162 1174
1175 rcu_read_lock();
1176
1177 if (!sta) {
1178 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
1179 if (WARN_ON(IS_ERR_OR_NULL(sta))) {
1180 rcu_read_unlock();
1181 return;
1182 }
1183 }
1184
1185 mvm_sta = (void *)sta->drv_priv;
1163 iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id, 1186 iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id,
1164 iv32, phase1key, CMD_ASYNC); 1187 iv32, phase1key, CMD_ASYNC);
1188 rcu_read_unlock();
1165} 1189}
1166 1190
1167void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, int sta_id) 1191void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, int sta_id)
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h
index 1bf301097984..bdd7c5ed8222 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.h
@@ -309,10 +309,14 @@ struct iwl_mvm_int_sta {
309 u32 tfd_queue_msk; 309 u32 tfd_queue_msk;
310}; 310};
311 311
312int iwl_mvm_sta_add_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta); 312int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
313 bool update);
313int iwl_mvm_add_sta(struct iwl_mvm *mvm, 314int iwl_mvm_add_sta(struct iwl_mvm *mvm,
314 struct ieee80211_vif *vif, 315 struct ieee80211_vif *vif,
315 struct ieee80211_sta *sta); 316 struct ieee80211_sta *sta);
317int iwl_mvm_update_sta(struct iwl_mvm *mvm,
318 struct ieee80211_vif *vif,
319 struct ieee80211_sta *sta);
316int iwl_mvm_rm_sta(struct iwl_mvm *mvm, 320int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
317 struct ieee80211_vif *vif, 321 struct ieee80211_vif *vif,
318 struct ieee80211_sta *sta); 322 struct ieee80211_sta *sta);
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index b9f076f4f17c..c09b71f23759 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -76,6 +76,15 @@
76#define TU_TO_JIFFIES(_tu) (usecs_to_jiffies((_tu) * 1024)) 76#define TU_TO_JIFFIES(_tu) (usecs_to_jiffies((_tu) * 1024))
77#define MSEC_TO_TU(_msec) (_msec*1000/1024) 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
79void iwl_mvm_te_clear_data(struct iwl_mvm *mvm, 88void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
80 struct iwl_mvm_time_event_data *te_data) 89 struct iwl_mvm_time_event_data *te_data)
81{ 90{
@@ -175,9 +184,11 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
175 */ 184 */
176 if (te_data->vif->type == NL80211_IFTYPE_STATION && 185 if (te_data->vif->type == NL80211_IFTYPE_STATION &&
177 (!te_data->vif->bss_conf.assoc || 186 (!te_data->vif->bss_conf.assoc ||
178 !te_data->vif->bss_conf.dtim_period)) 187 !te_data->vif->bss_conf.dtim_period)) {
179 IWL_ERR(mvm, 188 IWL_ERR(mvm,
180 "No assocation and the time event is over already...\n"); 189 "No assocation and the time event is over already...\n");
190 ieee80211_connection_loss(te_data->vif);
191 }
181 192
182 iwl_mvm_te_clear_data(mvm, te_data); 193 iwl_mvm_te_clear_data(mvm, te_data);
183 } else if (le32_to_cpu(notif->action) == TE_NOTIF_HOST_START) { 194 } else if (le32_to_cpu(notif->action) == TE_NOTIF_HOST_START) {
@@ -219,57 +230,86 @@ int iwl_mvm_rx_time_event_notif(struct iwl_mvm *mvm,
219 return 0; 230 return 0;
220} 231}
221 232
222static bool iwl_mvm_time_event_notif(struct iwl_notif_wait_data *notif_wait, 233static bool iwl_mvm_time_event_response(struct iwl_notif_wait_data *notif_wait,
223 struct iwl_rx_packet *pkt, void *data) 234 struct iwl_rx_packet *pkt, void *data)
224{ 235{
225 struct iwl_mvm *mvm = 236 struct iwl_mvm *mvm =
226 container_of(notif_wait, struct iwl_mvm, notif_wait); 237 container_of(notif_wait, struct iwl_mvm, notif_wait);
227 struct iwl_mvm_time_event_data *te_data = data; 238 struct iwl_mvm_time_event_data *te_data = data;
228 struct ieee80211_vif *vif = te_data->vif;
229 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
230 struct iwl_time_event_notif *notif;
231 struct iwl_time_event_resp *resp; 239 struct iwl_time_event_resp *resp;
240 int resp_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
232 241
233 u32 mac_id_n_color = FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color); 242 if (WARN_ON(pkt->hdr.cmd != TIME_EVENT_CMD))
243 return true;
234 244
235 /* until we do something else */ 245 if (WARN_ON_ONCE(resp_len != sizeof(pkt->hdr) + sizeof(*resp))) {
236 WARN_ON(te_data->id != TE_BSS_STA_AGGRESSIVE_ASSOC); 246 IWL_ERR(mvm, "Invalid TIME_EVENT_CMD response\n");
247 return true;
248 }
237 249
238 switch (pkt->hdr.cmd) { 250 resp = (void *)pkt->data;
239 case TIME_EVENT_CMD: 251 te_data->uid = le32_to_cpu(resp->unique_id);
240 resp = (void *)pkt->data; 252 IWL_DEBUG_TE(mvm, "TIME_EVENT_CMD response - UID = 0x%x\n",
241 /* TODO: I can't check that since the fw is buggy - it doesn't 253 te_data->uid);
242 * put the right values when we remove a TE. We can be here 254 return true;
243 * when we remove a TE because the remove TE command is sent in 255}
244 * ASYNC...
245 * WARN_ON(mac_id_n_color != le32_to_cpu(resp->id_and_color));
246 */
247 te_data->uid = le32_to_cpu(resp->unique_id);
248 IWL_DEBUG_TE(mvm, "Got response - UID = 0x%x\n", te_data->uid);
249 return false;
250
251 case TIME_EVENT_NOTIFICATION:
252 notif = (void *)pkt->data;
253 WARN_ON(le32_to_cpu(notif->status) != 1);
254 WARN_ON(mac_id_n_color != le32_to_cpu(notif->id_and_color));
255 /* check if this is our Time Event that is starting */
256 if (le32_to_cpu(notif->unique_id) != te_data->uid)
257 return false;
258 IWL_DEBUG_TE(mvm, "Event %d is starting - time is %d\n",
259 te_data->uid, le32_to_cpu(notif->timestamp));
260
261 WARN_ONCE(!le32_to_cpu(notif->status),
262 "Failed to schedule protected session TE\n");
263 256
264 te_data->running = true; 257static int iwl_mvm_time_event_send_add(struct iwl_mvm *mvm,
265 te_data->end_jiffies = jiffies + 258 struct ieee80211_vif *vif,
266 TU_TO_JIFFIES(te_data->duration); 259 struct iwl_mvm_time_event_data *te_data,
267 return true; 260 struct iwl_time_event_cmd *te_cmd)
261{
262 static const u8 time_event_response[] = { TIME_EVENT_CMD };
263 struct iwl_notification_wait wait_time_event;
264 int ret;
265
266 lockdep_assert_held(&mvm->mutex);
267
268 spin_lock_bh(&mvm->time_event_lock);
269 if (WARN_ON(te_data->id != TE_MAX)) {
270 spin_unlock_bh(&mvm->time_event_lock);
271 return -EIO;
272 }
273 te_data->vif = vif;
274 te_data->duration = le32_to_cpu(te_cmd->duration);
275 te_data->id = le32_to_cpu(te_cmd->id);
276 list_add_tail(&te_data->list, &mvm->time_event_list);
277 spin_unlock_bh(&mvm->time_event_lock);
278
279 /*
280 * Use a notification wait, which really just processes the
281 * command response and doesn't wait for anything, in order
282 * to be able to process the response and get the UID inside
283 * the RX path. Using CMD_WANT_SKB doesn't work because it
284 * stores the buffer and then wakes up this thread, by which
285 * time another notification (that the time event started)
286 * might already be processed unsuccessfully.
287 */
288 iwl_init_notification_wait(&mvm->notif_wait, &wait_time_event,
289 time_event_response,
290 ARRAY_SIZE(time_event_response),
291 iwl_mvm_time_event_response, te_data);
268 292
269 default: 293 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_SYNC,
270 WARN_ON(1); 294 sizeof(*te_cmd), te_cmd);
271 return false; 295 if (ret) {
272 }; 296 IWL_ERR(mvm, "Couldn't send TIME_EVENT_CMD: %d\n", ret);
297 iwl_remove_notification(&mvm->notif_wait, &wait_time_event);
298 goto out_clear_te;
299 }
300
301 /* No need to wait for anything, so just pass 1 (0 isn't valid) */
302 ret = iwl_wait_notification(&mvm->notif_wait, &wait_time_event, 1);
303 /* should never fail */
304 WARN_ON_ONCE(ret);
305
306 if (ret) {
307 out_clear_te:
308 spin_lock_bh(&mvm->time_event_lock);
309 iwl_mvm_te_clear_data(mvm, te_data);
310 spin_unlock_bh(&mvm->time_event_lock);
311 }
312 return ret;
273} 313}
274 314
275void iwl_mvm_protect_session(struct iwl_mvm *mvm, 315void iwl_mvm_protect_session(struct iwl_mvm *mvm,
@@ -278,11 +318,7 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
278{ 318{
279 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 319 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
280 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; 320 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
281 static const u8 time_event_notif[] = { TIME_EVENT_CMD,
282 TIME_EVENT_NOTIFICATION };
283 struct iwl_notification_wait wait_time_event;
284 struct iwl_time_event_cmd time_cmd = {}; 321 struct iwl_time_event_cmd time_cmd = {};
285 int ret;
286 322
287 lockdep_assert_held(&mvm->mutex); 323 lockdep_assert_held(&mvm->mutex);
288 324
@@ -309,12 +345,6 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
309 iwl_mvm_stop_session_protection(mvm, vif); 345 iwl_mvm_stop_session_protection(mvm, vif);
310 } 346 }
311 347
312 iwl_init_notification_wait(&mvm->notif_wait, &wait_time_event,
313 time_event_notif,
314 ARRAY_SIZE(time_event_notif),
315 iwl_mvm_time_event_notif,
316 &mvmvif->time_event_data);
317
318 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD); 348 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
319 time_cmd.id_and_color = 349 time_cmd.id_and_color =
320 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)); 350 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
@@ -322,6 +352,7 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
322 352
323 time_cmd.apply_time = 353 time_cmd.apply_time =
324 cpu_to_le32(iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG)); 354 cpu_to_le32(iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG));
355
325 time_cmd.dep_policy = TE_INDEPENDENT; 356 time_cmd.dep_policy = TE_INDEPENDENT;
326 time_cmd.is_present = cpu_to_le32(1); 357 time_cmd.is_present = cpu_to_le32(1);
327 time_cmd.max_frags = cpu_to_le32(TE_FRAG_NONE); 358 time_cmd.max_frags = cpu_to_le32(TE_FRAG_NONE);
@@ -333,33 +364,7 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
333 time_cmd.repeat = cpu_to_le32(1); 364 time_cmd.repeat = cpu_to_le32(1);
334 time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_START | TE_NOTIF_HOST_END); 365 time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_START | TE_NOTIF_HOST_END);
335 366
336 te_data->vif = vif; 367 iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
337 te_data->duration = duration;
338
339 spin_lock_bh(&mvm->time_event_lock);
340 te_data->id = le32_to_cpu(time_cmd.id);
341 list_add_tail(&te_data->list, &mvm->time_event_list);
342 spin_unlock_bh(&mvm->time_event_lock);
343
344 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_SYNC,
345 sizeof(time_cmd), &time_cmd);
346 if (ret) {
347 IWL_ERR(mvm, "Couldn't send TIME_EVENT_CMD: %d\n", ret);
348 goto out_remove_notif;
349 }
350
351 ret = iwl_wait_notification(&mvm->notif_wait, &wait_time_event, 1 * HZ);
352 if (ret) {
353 IWL_ERR(mvm, "%s - failed on timeout\n", __func__);
354 spin_lock_bh(&mvm->time_event_lock);
355 iwl_mvm_te_clear_data(mvm, te_data);
356 spin_unlock_bh(&mvm->time_event_lock);
357 }
358
359 return;
360
361out_remove_notif:
362 iwl_remove_notification(&mvm->notif_wait, &wait_time_event);
363} 368}
364 369
365/* 370/*
@@ -424,43 +429,12 @@ void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm,
424 iwl_mvm_remove_time_event(mvm, mvmvif, te_data); 429 iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
425} 430}
426 431
427static bool iwl_mvm_roc_te_notif(struct iwl_notif_wait_data *notif_wait,
428 struct iwl_rx_packet *pkt, void *data)
429{
430 struct iwl_mvm *mvm =
431 container_of(notif_wait, struct iwl_mvm, notif_wait);
432 struct iwl_mvm_time_event_data *te_data = data;
433 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
434 struct iwl_time_event_resp *resp;
435
436 u32 mac_id_n_color = FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color);
437
438 /* until we do something else */
439 WARN_ON(te_data->id != TE_P2P_DEVICE_DISCOVERABLE);
440
441 switch (pkt->hdr.cmd) {
442 case TIME_EVENT_CMD:
443 resp = (void *)pkt->data;
444 WARN_ON(mac_id_n_color != le32_to_cpu(resp->id_and_color));
445 te_data->uid = le32_to_cpu(resp->unique_id);
446 IWL_DEBUG_TE(mvm, "Got response - UID = 0x%x\n", te_data->uid);
447 return true;
448
449 default:
450 WARN_ON(1);
451 return false;
452 };
453}
454
455int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 432int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
456 int duration) 433 int duration)
457{ 434{
458 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 435 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
459 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; 436 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
460 static const u8 roc_te_notif[] = { TIME_EVENT_CMD };
461 struct iwl_notification_wait wait_time_event;
462 struct iwl_time_event_cmd time_cmd = {}; 437 struct iwl_time_event_cmd time_cmd = {};
463 int ret;
464 438
465 lockdep_assert_held(&mvm->mutex); 439 lockdep_assert_held(&mvm->mutex);
466 if (te_data->running) { 440 if (te_data->running) {
@@ -474,16 +448,10 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
474 */ 448 */
475 flush_work(&mvm->roc_done_wk); 449 flush_work(&mvm->roc_done_wk);
476 450
477 iwl_init_notification_wait(&mvm->notif_wait, &wait_time_event,
478 roc_te_notif,
479 ARRAY_SIZE(roc_te_notif),
480 iwl_mvm_roc_te_notif,
481 &mvmvif->time_event_data);
482
483 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD); 451 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
484 time_cmd.id_and_color = 452 time_cmd.id_and_color =
485 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)); 453 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
486 time_cmd.id = cpu_to_le32(TE_P2P_DEVICE_DISCOVERABLE); 454 time_cmd.id = cpu_to_le32(IWL_MVM_ROC_TE_TYPE);
487 455
488 time_cmd.apply_time = cpu_to_le32(0); 456 time_cmd.apply_time = cpu_to_le32(0);
489 time_cmd.dep_policy = cpu_to_le32(TE_INDEPENDENT); 457 time_cmd.dep_policy = cpu_to_le32(TE_INDEPENDENT);
@@ -492,7 +460,7 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
492 time_cmd.interval = cpu_to_le32(1); 460 time_cmd.interval = cpu_to_le32(1);
493 461
494 /* 462 /*
495 * TE_P2P_DEVICE_DISCOVERABLE can have lower priority than other events 463 * IWL_MVM_ROC_TE_TYPE can have lower priority than other events
496 * that are being scheduled by the driver/fw, and thus it might not be 464 * that are being scheduled by the driver/fw, and thus it might not be
497 * scheduled. To improve the chances of it being scheduled, allow it to 465 * scheduled. To improve the chances of it being scheduled, allow it to
498 * be fragmented. 466 * be fragmented.
@@ -505,33 +473,7 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
505 time_cmd.repeat = cpu_to_le32(1); 473 time_cmd.repeat = cpu_to_le32(1);
506 time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_START | TE_NOTIF_HOST_END); 474 time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_START | TE_NOTIF_HOST_END);
507 475
508 /* Push the te data to the tracked te list */ 476 return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
509 te_data->vif = vif;
510 te_data->duration = MSEC_TO_TU(duration);
511
512 spin_lock_bh(&mvm->time_event_lock);
513 te_data->id = le32_to_cpu(time_cmd.id);
514 list_add_tail(&te_data->list, &mvm->time_event_list);
515 spin_unlock_bh(&mvm->time_event_lock);
516
517 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_SYNC,
518 sizeof(time_cmd), &time_cmd);
519 if (ret) {
520 IWL_ERR(mvm, "Couldn't send TIME_EVENT_CMD: %d\n", ret);
521 goto out_remove_notif;
522 }
523
524 ret = iwl_wait_notification(&mvm->notif_wait, &wait_time_event, 1 * HZ);
525 if (ret) {
526 IWL_ERR(mvm, "%s - failed on timeout\n", __func__);
527 iwl_mvm_te_clear_data(mvm, te_data);
528 }
529
530 return ret;
531
532out_remove_notif:
533 iwl_remove_notification(&mvm->notif_wait, &wait_time_event);
534 return ret;
535} 477}
536 478
537void iwl_mvm_stop_p2p_roc(struct iwl_mvm *mvm) 479void iwl_mvm_stop_p2p_roc(struct iwl_mvm *mvm)
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index cada8efe0cca..6b67ce3f679c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -620,7 +620,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
620 seq_ctl = le16_to_cpu(hdr->seq_ctrl); 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 if (txq_id >= IWL_FIRST_AMPDU_QUEUE) { 626 if (txq_id >= IWL_FIRST_AMPDU_QUEUE) {
@@ -663,12 +663,12 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
663 struct iwl_mvm_tid_data *tid_data = 663 struct iwl_mvm_tid_data *tid_data =
664 &mvmsta->tid_data[tid]; 664 &mvmsta->tid_data[tid];
665 665
666 spin_lock(&mvmsta->lock); 666 spin_lock_bh(&mvmsta->lock);
667 tid_data->next_reclaimed = next_reclaimed; 667 tid_data->next_reclaimed = next_reclaimed;
668 IWL_DEBUG_TX_REPLY(mvm, "Next reclaimed packet:%d\n", 668 IWL_DEBUG_TX_REPLY(mvm, "Next reclaimed packet:%d\n",
669 next_reclaimed); 669 next_reclaimed);
670 iwl_mvm_check_ratid_empty(mvm, sta, tid); 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#ifdef CONFIG_PM_SLEEP 674#ifdef CONFIG_PM_SLEEP
@@ -832,7 +832,7 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
832 return 0; 832 return 0;
833 } 833 }
834 834
835 spin_lock(&mvmsta->lock); 835 spin_lock_bh(&mvmsta->lock);
836 836
837 __skb_queue_head_init(&reclaimed_skbs); 837 __skb_queue_head_init(&reclaimed_skbs);
838 838
@@ -886,13 +886,13 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
886 } 886 }
887 } 887 }
888 888
889 spin_unlock(&mvmsta->lock); 889 spin_unlock_bh(&mvmsta->lock);
890 890
891 rcu_read_unlock(); 891 rcu_read_unlock();
892 892
893 while (!skb_queue_empty(&reclaimed_skbs)) { 893 while (!skb_queue_empty(&reclaimed_skbs)) {
894 skb = __skb_dequeue(&reclaimed_skbs); 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 return 0; 898 return 0;
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index 5f6bb4e09d42..aa2a39a637dd 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -249,7 +249,6 @@ struct iwl_trans_pcie {
249 int ict_index; 249 int ict_index;
250 u32 inta; 250 u32 inta;
251 bool use_ict; 251 bool use_ict;
252 struct tasklet_struct irq_tasklet;
253 struct isr_statistics isr_stats; 252 struct isr_statistics isr_stats;
254 253
255 spinlock_t irq_lock; 254 spinlock_t irq_lock;
@@ -330,7 +329,7 @@ void iwl_trans_pcie_free(struct iwl_trans *trans);
330* RX 329* RX
331******************************************************/ 330******************************************************/
332int iwl_pcie_rx_init(struct iwl_trans *trans); 331int iwl_pcie_rx_init(struct iwl_trans *trans);
333void iwl_pcie_tasklet(struct iwl_trans *trans); 332irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id);
334int iwl_pcie_rx_stop(struct iwl_trans *trans); 333int iwl_pcie_rx_stop(struct iwl_trans *trans);
335void iwl_pcie_rx_free(struct iwl_trans *trans); 334void iwl_pcie_rx_free(struct iwl_trans *trans);
336 335
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index a9ca1d35fa93..b0ae06d2456f 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -81,10 +81,10 @@
81 * 'processed' and 'read' driver indexes as well) 81 * 'processed' and 'read' driver indexes as well)
82 * + A received packet is processed and handed to the kernel network stack, 82 * + A received packet is processed and handed to the kernel network stack,
83 * detached from the iwl->rxq. The driver 'processed' index is updated. 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 84 * + The Host/Firmware iwl->rxq is replenished at irq thread time from the
85 * list. If there are no allocated buffers in iwl->rxq->rx_free, the READ 85 * rx_free list. If there are no allocated buffers in iwl->rxq->rx_free,
86 * INDEX is not incremented and iwl->status(RX_STALLED) is set. If there 86 * the READ INDEX is not incremented and iwl->status(RX_STALLED) is set.
87 * were enough free buffers and RX_STALLED is set it is cleared. 87 * If there were enough free buffers and RX_STALLED is set it is cleared.
88 * 88 *
89 * 89 *
90 * Driver sequence: 90 * Driver sequence:
@@ -214,9 +214,9 @@ static void iwl_pcie_rxq_restock(struct iwl_trans *trans)
214 /* 214 /*
215 * If the device isn't enabled - not need to try to add buffers... 215 * If the device isn't enabled - not need to try to add buffers...
216 * This can happen when we stop the device and still have an interrupt 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 217 * pending. We stop the APM before we sync the interrupts because we
218 * because we have to (see comment there). On the other hand, since 218 * have to (see comment there). On the other hand, since the APM is
219 * the APM is stopped, we cannot access the HW (in particular not prph). 219 * stopped, we cannot access the HW (in particular not prph).
220 * So don't try to restock if the APM has been already stopped. 220 * So don't try to restock if the APM has been already stopped.
221 */ 221 */
222 if (!test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status)) 222 if (!test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status))
@@ -796,11 +796,14 @@ static void iwl_pcie_irq_handle_error(struct iwl_trans *trans)
796 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); 796 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
797 wake_up(&trans_pcie->wait_command_queue); 797 wake_up(&trans_pcie->wait_command_queue);
798 798
799 local_bh_disable();
799 iwl_op_mode_nic_error(trans->op_mode); 800 iwl_op_mode_nic_error(trans->op_mode);
801 local_bh_enable();
800} 802}
801 803
802void iwl_pcie_tasklet(struct iwl_trans *trans) 804irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id)
803{ 805{
806 struct iwl_trans *trans = dev_id;
804 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 807 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
805 struct isr_statistics *isr_stats = &trans_pcie->isr_stats; 808 struct isr_statistics *isr_stats = &trans_pcie->isr_stats;
806 u32 inta = 0; 809 u32 inta = 0;
@@ -811,6 +814,8 @@ void iwl_pcie_tasklet(struct iwl_trans *trans)
811 u32 inta_mask; 814 u32 inta_mask;
812#endif 815#endif
813 816
817 lock_map_acquire(&trans->sync_cmd_lockdep_map);
818
814 spin_lock_irqsave(&trans_pcie->irq_lock, flags); 819 spin_lock_irqsave(&trans_pcie->irq_lock, flags);
815 820
816 /* Ack/clear/reset pending uCode interrupts. 821 /* Ack/clear/reset pending uCode interrupts.
@@ -855,7 +860,7 @@ void iwl_pcie_tasklet(struct iwl_trans *trans)
855 860
856 handled |= CSR_INT_BIT_HW_ERR; 861 handled |= CSR_INT_BIT_HW_ERR;
857 862
858 return; 863 goto out;
859 } 864 }
860 865
861#ifdef CONFIG_IWLWIFI_DEBUG 866#ifdef CONFIG_IWLWIFI_DEBUG
@@ -1005,6 +1010,10 @@ void iwl_pcie_tasklet(struct iwl_trans *trans)
1005 /* Re-enable RF_KILL if it occurred */ 1010 /* Re-enable RF_KILL if it occurred */
1006 else if (handled & CSR_INT_BIT_RF_KILL) 1011 else if (handled & CSR_INT_BIT_RF_KILL)
1007 iwl_enable_rfkill_int(trans); 1012 iwl_enable_rfkill_int(trans);
1013
1014out:
1015 lock_map_release(&trans->sync_cmd_lockdep_map);
1016 return IRQ_HANDLED;
1008} 1017}
1009 1018
1010/****************************************************************************** 1019/******************************************************************************
@@ -1127,7 +1136,7 @@ static irqreturn_t iwl_pcie_isr(int irq, void *data)
1127 1136
1128 /* Disable (but don't clear!) interrupts here to avoid 1137 /* Disable (but don't clear!) interrupts here to avoid
1129 * back-to-back ISRs and sporadic interrupts from our NIC. 1138 * back-to-back ISRs and sporadic interrupts from our NIC.
1130 * If we have something to service, the tasklet will re-enable ints. 1139 * If we have something to service, the irq thread will re-enable ints.
1131 * If we *don't* have something, we'll re-enable before leaving here. */ 1140 * If we *don't* have something, we'll re-enable before leaving here. */
1132 inta_mask = iwl_read32(trans, CSR_INT_MASK); 1141 inta_mask = iwl_read32(trans, CSR_INT_MASK);
1133 iwl_write32(trans, CSR_INT_MASK, 0x00000000); 1142 iwl_write32(trans, CSR_INT_MASK, 0x00000000);
@@ -1167,9 +1176,9 @@ static irqreturn_t iwl_pcie_isr(int irq, void *data)
1167#endif 1176#endif
1168 1177
1169 trans_pcie->inta |= inta; 1178 trans_pcie->inta |= inta;
1170 /* iwl_pcie_tasklet() will service interrupts and re-enable them */ 1179 /* the thread will service interrupts and re-enable them */
1171 if (likely(inta)) 1180 if (likely(inta))
1172 tasklet_schedule(&trans_pcie->irq_tasklet); 1181 return IRQ_WAKE_THREAD;
1173 else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && 1182 else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
1174 !trans_pcie->inta) 1183 !trans_pcie->inta)
1175 iwl_enable_interrupts(trans); 1184 iwl_enable_interrupts(trans);
@@ -1277,9 +1286,10 @@ irqreturn_t iwl_pcie_isr_ict(int irq, void *data)
1277 trans_pcie->inta |= inta; 1286 trans_pcie->inta |= inta;
1278 1287
1279 /* iwl_pcie_tasklet() will service interrupts and re-enable them */ 1288 /* iwl_pcie_tasklet() will service interrupts and re-enable them */
1280 if (likely(inta)) 1289 if (likely(inta)) {
1281 tasklet_schedule(&trans_pcie->irq_tasklet); 1290 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
1282 else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && 1291 return IRQ_WAKE_THREAD;
1292 } else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
1283 !trans_pcie->inta) { 1293 !trans_pcie->inta) {
1284 /* Allow interrupt if was disabled by this handler and 1294 /* Allow interrupt if was disabled by this handler and
1285 * no tasklet was schedules, We should not enable interrupt, 1295 * no tasklet was schedules, We should not enable interrupt,
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 56d4f72500bc..17bedc50e753 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -760,7 +760,6 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
760 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 760 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
761 761
762 synchronize_irq(trans_pcie->pci_dev->irq); 762 synchronize_irq(trans_pcie->pci_dev->irq);
763 tasklet_kill(&trans_pcie->irq_tasklet);
764 763
765 iwl_pcie_tx_free(trans); 764 iwl_pcie_tx_free(trans);
766 iwl_pcie_rx_free(trans); 765 iwl_pcie_rx_free(trans);
@@ -1480,6 +1479,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
1480 1479
1481 trans->ops = &trans_ops_pcie; 1480 trans->ops = &trans_ops_pcie;
1482 trans->cfg = cfg; 1481 trans->cfg = cfg;
1482 trans_lockdep_init(trans);
1483 trans_pcie->trans = trans; 1483 trans_pcie->trans = trans;
1484 spin_lock_init(&trans_pcie->irq_lock); 1484 spin_lock_init(&trans_pcie->irq_lock);
1485 spin_lock_init(&trans_pcie->reg_lock); 1485 spin_lock_init(&trans_pcie->reg_lock);
@@ -1567,15 +1567,12 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
1567 1567
1568 trans_pcie->inta_mask = CSR_INI_SET_MASK; 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 if (iwl_pcie_alloc_ict(trans)) 1570 if (iwl_pcie_alloc_ict(trans))
1574 goto out_free_cmd_pool; 1571 goto out_free_cmd_pool;
1575 1572
1576 err = request_irq(pdev->irq, iwl_pcie_isr_ict, 1573 if (request_threaded_irq(pdev->irq, iwl_pcie_isr_ict,
1577 IRQF_SHARED, DRV_NAME, trans); 1574 iwl_pcie_irq_handler,
1578 if (err) { 1575 IRQF_SHARED, DRV_NAME, trans)) {
1579 IWL_ERR(trans, "Error allocating IRQ %d\n", pdev->irq); 1576 IWL_ERR(trans, "Error allocating IRQ %d\n", pdev->irq);
1580 goto out_free_ict; 1577 goto out_free_ict;
1581 } 1578 }
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 041127ad372a..8e9e3212fe78 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -926,7 +926,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
926 if (WARN_ON(txq_id == trans_pcie->cmd_queue)) 926 if (WARN_ON(txq_id == trans_pcie->cmd_queue))
927 return; 927 return;
928 928
929 spin_lock(&txq->lock); 929 spin_lock_bh(&txq->lock);
930 930
931 if (txq->q.read_ptr == tfd_num) 931 if (txq->q.read_ptr == tfd_num)
932 goto out; 932 goto out;
@@ -970,7 +970,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
970 if (iwl_queue_space(&txq->q) > txq->q.low_mark) 970 if (iwl_queue_space(&txq->q) > txq->q.low_mark)
971 iwl_wake_queue(trans, txq); 971 iwl_wake_queue(trans, txq);
972out: 972out:
973 spin_unlock(&txq->lock); 973 spin_unlock_bh(&txq->lock);
974} 974}
975 975
976/* 976/*
@@ -1371,7 +1371,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
1371 return; 1371 return;
1372 } 1372 }
1373 1373
1374 spin_lock(&txq->lock); 1374 spin_lock_bh(&txq->lock);
1375 1375
1376 cmd_index = get_cmd_index(&txq->q, index); 1376 cmd_index = get_cmd_index(&txq->q, index);
1377 cmd = txq->entries[cmd_index].cmd; 1377 cmd = txq->entries[cmd_index].cmd;
@@ -1405,7 +1405,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
1405 1405
1406 meta->flags = 0; 1406 meta->flags = 0;
1407 1407
1408 spin_unlock(&txq->lock); 1408 spin_unlock_bh(&txq->lock);
1409} 1409}
1410 1410
1411#define HOST_COMPLETE_TIMEOUT (2 * HZ) 1411#define HOST_COMPLETE_TIMEOUT (2 * HZ)