aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c5
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c15
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c65
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c19
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c34
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c33
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c1
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c15
12 files changed, 134 insertions, 63 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index 822f1a00efbb..319387263e12 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -1068,7 +1068,10 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success)
1068 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 1068 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
1069 return; 1069 return;
1070 1070
1071 if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) 1071 if (!test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
1072 return;
1073
1074 if (ctx->vif)
1072 ieee80211_chswitch_done(ctx->vif, is_success); 1075 ieee80211_chswitch_done(ctx->vif, is_success);
1073} 1076}
1074 1077
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index 3952ddf2ddb2..1531a4fc0960 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -758,7 +758,7 @@ int iwl_alive_start(struct iwl_priv *priv)
758 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); 758 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
759 if (ret) 759 if (ret)
760 return ret; 760 return ret;
761 } else { 761 } else if (priv->lib->bt_params) {
762 /* 762 /*
763 * default is 2-wire BT coexexistence support 763 * default is 2-wire BT coexexistence support
764 */ 764 */
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 7e5e5c2f9f87..83da884cf303 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -134,7 +134,7 @@ struct wowlan_key_data {
134 struct iwl_wowlan_rsc_tsc_params_cmd *rsc_tsc; 134 struct iwl_wowlan_rsc_tsc_params_cmd *rsc_tsc;
135 struct iwl_wowlan_tkip_params_cmd *tkip; 135 struct iwl_wowlan_tkip_params_cmd *tkip;
136 bool error, use_rsc_tsc, use_tkip; 136 bool error, use_rsc_tsc, use_tkip;
137 int gtk_key_idx; 137 int wep_key_idx;
138}; 138};
139 139
140static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw, 140static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
@@ -188,8 +188,8 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
188 wkc.wep_key.key_offset = 0; 188 wkc.wep_key.key_offset = 0;
189 } else { 189 } else {
190 /* others start at 1 */ 190 /* others start at 1 */
191 data->gtk_key_idx++; 191 data->wep_key_idx++;
192 wkc.wep_key.key_offset = data->gtk_key_idx; 192 wkc.wep_key.key_offset = data->wep_key_idx;
193 } 193 }
194 194
195 ret = iwl_mvm_send_cmd_pdu(mvm, WEP_KEY, CMD_SYNC, 195 ret = iwl_mvm_send_cmd_pdu(mvm, WEP_KEY, CMD_SYNC,
@@ -316,8 +316,13 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
316 mvm->ptk_ivlen = key->iv_len; 316 mvm->ptk_ivlen = key->iv_len;
317 mvm->ptk_icvlen = key->icv_len; 317 mvm->ptk_icvlen = key->icv_len;
318 } else { 318 } else {
319 data->gtk_key_idx++; 319 /*
320 key->hw_key_idx = data->gtk_key_idx; 320 * firmware only supports TSC/RSC for a single key,
321 * so if there are multiple keep overwriting them
322 * with new ones -- this relies on mac80211 doing
323 * list_add_tail().
324 */
325 key->hw_key_idx = 1;
321 mvm->gtk_ivlen = key->iv_len; 326 mvm->gtk_ivlen = key->iv_len;
322 mvm->gtk_icvlen = key->icv_len; 327 mvm->gtk_icvlen = key->icv_len;
323 } 328 }
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index e56ed2a84888..c24a744910ac 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -988,7 +988,11 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
988 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 988 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
989 char buf[100]; 989 char buf[100];
990 990
991 if (!dbgfs_dir) 991 /*
992 * Check if debugfs directory already exist before creating it.
993 * This may happen when, for example, resetting hw or suspend-resume
994 */
995 if (!dbgfs_dir || mvmvif->dbgfs_dir)
992 return; 996 return;
993 997
994 mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir); 998 mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir);
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index b60d14151721..365095a0c3b3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -69,7 +69,6 @@
69/* Scan Commands, Responses, Notifications */ 69/* Scan Commands, Responses, Notifications */
70 70
71/* Masks for iwl_scan_channel.type flags */ 71/* Masks for iwl_scan_channel.type flags */
72#define SCAN_CHANNEL_TYPE_PASSIVE 0
73#define SCAN_CHANNEL_TYPE_ACTIVE BIT(0) 72#define SCAN_CHANNEL_TYPE_ACTIVE BIT(0)
74#define SCAN_CHANNEL_NARROW_BAND BIT(22) 73#define SCAN_CHANNEL_NARROW_BAND BIT(22)
75 74
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index e08683b20531..f19baf0dea6b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -257,7 +257,11 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
257 if (ret) 257 if (ret)
258 return ret; 258 return ret;
259 259
260 return ieee80211_register_hw(mvm->hw); 260 ret = ieee80211_register_hw(mvm->hw);
261 if (ret)
262 iwl_mvm_leds_exit(mvm);
263
264 return ret;
261} 265}
262 266
263static void iwl_mvm_mac_tx(struct ieee80211_hw *hw, 267static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
@@ -385,6 +389,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
385 ieee80211_wake_queues(mvm->hw); 389 ieee80211_wake_queues(mvm->hw);
386 390
387 mvm->vif_count = 0; 391 mvm->vif_count = 0;
392 mvm->rx_ba_sessions = 0;
388} 393}
389 394
390static int iwl_mvm_mac_start(struct ieee80211_hw *hw) 395static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
@@ -507,6 +512,27 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
507 goto out_unlock; 512 goto out_unlock;
508 513
509 /* 514 /*
515 * TODO: remove this temporary code.
516 * Currently MVM FW supports power management only on single MAC.
517 * If new interface added, disable PM on existing interface.
518 * P2P device is a special case, since it is handled by FW similary to
519 * scan. If P2P deviced is added, PM remains enabled on existing
520 * interface.
521 * Note: the method below does not count the new interface being added
522 * at this moment.
523 */
524 if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
525 mvm->vif_count++;
526 if (mvm->vif_count > 1) {
527 IWL_DEBUG_MAC80211(mvm,
528 "Disable power on existing interfaces\n");
529 ieee80211_iterate_active_interfaces_atomic(
530 mvm->hw,
531 IEEE80211_IFACE_ITER_NORMAL,
532 iwl_mvm_pm_disable_iterator, mvm);
533 }
534
535 /*
510 * The AP binding flow can be done only after the beacon 536 * The AP binding flow can be done only after the beacon
511 * template is configured (which happens only in the mac80211 537 * template is configured (which happens only in the mac80211
512 * start_ap() flow), and adding the broadcast station can happen 538 * start_ap() flow), and adding the broadcast station can happen
@@ -529,27 +555,6 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
529 goto out_unlock; 555 goto out_unlock;
530 } 556 }
531 557
532 /*
533 * TODO: remove this temporary code.
534 * Currently MVM FW supports power management only on single MAC.
535 * If new interface added, disable PM on existing interface.
536 * P2P device is a special case, since it is handled by FW similary to
537 * scan. If P2P deviced is added, PM remains enabled on existing
538 * interface.
539 * Note: the method below does not count the new interface being added
540 * at this moment.
541 */
542 if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
543 mvm->vif_count++;
544 if (mvm->vif_count > 1) {
545 IWL_DEBUG_MAC80211(mvm,
546 "Disable power on existing interfaces\n");
547 ieee80211_iterate_active_interfaces_atomic(
548 mvm->hw,
549 IEEE80211_IFACE_ITER_NORMAL,
550 iwl_mvm_pm_disable_iterator, mvm);
551 }
552
553 ret = iwl_mvm_mac_ctxt_add(mvm, vif); 558 ret = iwl_mvm_mac_ctxt_add(mvm, vif);
554 if (ret) 559 if (ret)
555 goto out_release; 560 goto out_release;
@@ -1006,6 +1011,21 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
1006 mutex_lock(&mvm->mutex); 1011 mutex_lock(&mvm->mutex);
1007 if (old_state == IEEE80211_STA_NOTEXIST && 1012 if (old_state == IEEE80211_STA_NOTEXIST &&
1008 new_state == IEEE80211_STA_NONE) { 1013 new_state == IEEE80211_STA_NONE) {
1014 /*
1015 * Firmware bug - it'll crash if the beacon interval is less
1016 * than 16. We can't avoid connecting at all, so refuse the
1017 * station state change, this will cause mac80211 to abandon
1018 * attempts to connect to this AP, and eventually wpa_s will
1019 * blacklist the AP...
1020 */
1021 if (vif->type == NL80211_IFTYPE_STATION &&
1022 vif->bss_conf.beacon_int < 16) {
1023 IWL_ERR(mvm,
1024 "AP %pM beacon interval is %d, refusing due to firmware bug!\n",
1025 sta->addr, vif->bss_conf.beacon_int);
1026 ret = -EINVAL;
1027 goto out_unlock;
1028 }
1009 ret = iwl_mvm_add_sta(mvm, vif, sta); 1029 ret = iwl_mvm_add_sta(mvm, vif, sta);
1010 } else if (old_state == IEEE80211_STA_NONE && 1030 } else if (old_state == IEEE80211_STA_NONE &&
1011 new_state == IEEE80211_STA_AUTH) { 1031 new_state == IEEE80211_STA_AUTH) {
@@ -1038,6 +1058,7 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
1038 } else { 1058 } else {
1039 ret = -EIO; 1059 ret = -EIO;
1040 } 1060 }
1061 out_unlock:
1041 mutex_unlock(&mvm->mutex); 1062 mutex_unlock(&mvm->mutex);
1042 1063
1043 return ret; 1064 return ret;
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index d40d7db185d6..420e82d379d9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -419,6 +419,7 @@ struct iwl_mvm {
419 struct work_struct sta_drained_wk; 419 struct work_struct sta_drained_wk;
420 unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)]; 420 unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)];
421 atomic_t pending_frames[IWL_MVM_STATION_COUNT]; 421 atomic_t pending_frames[IWL_MVM_STATION_COUNT];
422 u8 rx_ba_sessions;
422 423
423 /* configured by mac80211 */ 424 /* configured by mac80211 */
424 u32 rts_threshold; 425 u32 rts_threshold;
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 2157b0f8ced5..acdff6b67e04 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -137,8 +137,8 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd,
137{ 137{
138 int fw_idx, req_idx; 138 int fw_idx, req_idx;
139 139
140 fw_idx = 0; 140 for (req_idx = req->n_ssids - 1, fw_idx = 0; req_idx > 0;
141 for (req_idx = req->n_ssids - 1; req_idx > 0; req_idx--) { 141 req_idx--, fw_idx++) {
142 cmd->direct_scan[fw_idx].id = WLAN_EID_SSID; 142 cmd->direct_scan[fw_idx].id = WLAN_EID_SSID;
143 cmd->direct_scan[fw_idx].len = req->ssids[req_idx].ssid_len; 143 cmd->direct_scan[fw_idx].len = req->ssids[req_idx].ssid_len;
144 memcpy(cmd->direct_scan[fw_idx].ssid, 144 memcpy(cmd->direct_scan[fw_idx].ssid,
@@ -153,7 +153,9 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd,
153 * just to notify that this scan is active and not passive. 153 * just to notify that this scan is active and not passive.
154 * In order to notify the FW of the number of SSIDs we wish to scan (including 154 * In order to notify the FW of the number of SSIDs we wish to scan (including
155 * the zero-length one), we need to set the corresponding bits in chan->type, 155 * the zero-length one), we need to set the corresponding bits in chan->type,
156 * one for each SSID, and set the active bit (first). 156 * one for each SSID, and set the active bit (first). The first SSID is already
157 * included in the probe template, so we need to set only req->n_ssids - 1 bits
158 * in addition to the first bit.
157 */ 159 */
158static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) 160static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids)
159{ 161{
@@ -176,19 +178,12 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
176 struct iwl_scan_channel *chan = (struct iwl_scan_channel *) 178 struct iwl_scan_channel *chan = (struct iwl_scan_channel *)
177 (cmd->data + le16_to_cpu(cmd->tx_cmd.len)); 179 (cmd->data + le16_to_cpu(cmd->tx_cmd.len));
178 int i; 180 int i;
179 __le32 chan_type_value;
180
181 if (req->n_ssids > 0)
182 chan_type_value = cpu_to_le32(BIT(req->n_ssids + 1) - 1);
183 else
184 chan_type_value = SCAN_CHANNEL_TYPE_PASSIVE;
185 181
186 for (i = 0; i < cmd->channel_count; i++) { 182 for (i = 0; i < cmd->channel_count; i++) {
187 chan->channel = cpu_to_le16(req->channels[i]->hw_value); 183 chan->channel = cpu_to_le16(req->channels[i]->hw_value);
184 chan->type = cpu_to_le32(BIT(req->n_ssids) - 1);
188 if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) 185 if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN)
189 chan->type = SCAN_CHANNEL_TYPE_PASSIVE; 186 chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE);
190 else
191 chan->type = chan_type_value;
192 chan->active_dwell = cpu_to_le16(active_dwell); 187 chan->active_dwell = cpu_to_le16(active_dwell);
193 chan->passive_dwell = cpu_to_le16(passive_dwell); 188 chan->passive_dwell = cpu_to_le16(passive_dwell);
194 chan->iteration_count = cpu_to_le16(1); 189 chan->iteration_count = cpu_to_le16(1);
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 62fe5209093b..563f559b902d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -608,6 +608,8 @@ int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta)
608 return ret; 608 return ret;
609} 609}
610 610
611#define IWL_MAX_RX_BA_SESSIONS 16
612
611int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 613int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
612 int tid, u16 ssn, bool start) 614 int tid, u16 ssn, bool start)
613{ 615{
@@ -618,11 +620,20 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
618 620
619 lockdep_assert_held(&mvm->mutex); 621 lockdep_assert_held(&mvm->mutex);
620 622
623 if (start && mvm->rx_ba_sessions >= IWL_MAX_RX_BA_SESSIONS) {
624 IWL_WARN(mvm, "Not enough RX BA SESSIONS\n");
625 return -ENOSPC;
626 }
627
621 cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color); 628 cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
622 cmd.sta_id = mvm_sta->sta_id; 629 cmd.sta_id = mvm_sta->sta_id;
623 cmd.add_modify = STA_MODE_MODIFY; 630 cmd.add_modify = STA_MODE_MODIFY;
624 cmd.add_immediate_ba_tid = (u8) tid; 631 if (start) {
625 cmd.add_immediate_ba_ssn = cpu_to_le16(ssn); 632 cmd.add_immediate_ba_tid = (u8) tid;
633 cmd.add_immediate_ba_ssn = cpu_to_le16(ssn);
634 } else {
635 cmd.remove_immediate_ba_tid = (u8) tid;
636 }
626 cmd.modify_mask = start ? STA_MODIFY_ADD_BA_TID : 637 cmd.modify_mask = start ? STA_MODIFY_ADD_BA_TID :
627 STA_MODIFY_REMOVE_BA_TID; 638 STA_MODIFY_REMOVE_BA_TID;
628 639
@@ -648,6 +659,14 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
648 break; 659 break;
649 } 660 }
650 661
662 if (!ret) {
663 if (start)
664 mvm->rx_ba_sessions++;
665 else if (mvm->rx_ba_sessions > 0)
666 /* check that restart flow didn't zero the counter */
667 mvm->rx_ba_sessions--;
668 }
669
651 return ret; 670 return ret;
652} 671}
653 672
@@ -896,6 +915,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
896 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 915 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
897 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; 916 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
898 u16 txq_id; 917 u16 txq_id;
918 enum iwl_mvm_agg_state old_state;
899 919
900 /* 920 /*
901 * First set the agg state to OFF to avoid calling 921 * First set the agg state to OFF to avoid calling
@@ -905,13 +925,17 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
905 txq_id = tid_data->txq_id; 925 txq_id = tid_data->txq_id;
906 IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n", 926 IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n",
907 mvmsta->sta_id, tid, txq_id, tid_data->state); 927 mvmsta->sta_id, tid, txq_id, tid_data->state);
928 old_state = tid_data->state;
908 tid_data->state = IWL_AGG_OFF; 929 tid_data->state = IWL_AGG_OFF;
909 spin_unlock_bh(&mvmsta->lock); 930 spin_unlock_bh(&mvmsta->lock);
910 931
911 if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true)) 932 if (old_state >= IWL_AGG_ON) {
912 IWL_ERR(mvm, "Couldn't flush the AGG queue\n"); 933 if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true))
934 IWL_ERR(mvm, "Couldn't flush the AGG queue\n");
935
936 iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
937 }
913 938
914 iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
915 mvm->queue_to_mac80211[tid_data->txq_id] = 939 mvm->queue_to_mac80211[tid_data->txq_id] =
916 IWL_INVALID_MAC80211_QUEUE; 940 IWL_INVALID_MAC80211_QUEUE;
917 941
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index ad9bbca99213..7fd6fbfbc1b3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -138,6 +138,20 @@ static void iwl_mvm_roc_finished(struct iwl_mvm *mvm)
138 schedule_work(&mvm->roc_done_wk); 138 schedule_work(&mvm->roc_done_wk);
139} 139}
140 140
141static bool iwl_mvm_te_check_disconnect(struct iwl_mvm *mvm,
142 struct ieee80211_vif *vif,
143 const char *errmsg)
144{
145 if (vif->type != NL80211_IFTYPE_STATION)
146 return false;
147 if (vif->bss_conf.assoc && vif->bss_conf.dtim_period)
148 return false;
149 if (errmsg)
150 IWL_ERR(mvm, "%s\n", errmsg);
151 ieee80211_connection_loss(vif);
152 return true;
153}
154
141/* 155/*
142 * Handles a FW notification for an event that is known to the driver. 156 * Handles a FW notification for an event that is known to the driver.
143 * 157 *
@@ -163,8 +177,13 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
163 * P2P Device discoveribility, while there are other higher priority 177 * P2P Device discoveribility, while there are other higher priority
164 * events in the system). 178 * events in the system).
165 */ 179 */
166 WARN_ONCE(!le32_to_cpu(notif->status), 180 if (WARN_ONCE(!le32_to_cpu(notif->status),
167 "Failed to schedule time event\n"); 181 "Failed to schedule time event\n")) {
182 if (iwl_mvm_te_check_disconnect(mvm, te_data->vif, NULL)) {
183 iwl_mvm_te_clear_data(mvm, te_data);
184 return;
185 }
186 }
168 187
169 if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_END) { 188 if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_END) {
170 IWL_DEBUG_TE(mvm, 189 IWL_DEBUG_TE(mvm,
@@ -180,14 +199,8 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
180 * By now, we should have finished association 199 * By now, we should have finished association
181 * and know the dtim period. 200 * and know the dtim period.
182 */ 201 */
183 if (te_data->vif->type == NL80211_IFTYPE_STATION && 202 iwl_mvm_te_check_disconnect(mvm, te_data->vif,
184 (!te_data->vif->bss_conf.assoc || 203 "No assocation and the time event is over already...");
185 !te_data->vif->bss_conf.dtim_period)) {
186 IWL_ERR(mvm,
187 "No assocation and the time event is over already...\n");
188 ieee80211_connection_loss(te_data->vif);
189 }
190
191 iwl_mvm_te_clear_data(mvm, te_data); 204 iwl_mvm_te_clear_data(mvm, te_data);
192 } else if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_START) { 205 } else if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_START) {
193 te_data->running = true; 206 te_data->running = true;
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index 81f3ea5b09a4..ff13458efc27 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -130,6 +130,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
130 {IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */ 130 {IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */
131 {IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */ 131 {IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */
132 {IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */ 132 {IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */
133 {IWL_PCI_DEVICE(0x423C, 0x1326, iwl5150_abg_cfg)}, /* Half Mini Card */
133 134
134 {IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */ 135 {IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */
135 {IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */ 136 {IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 826c15602c46..390e2f058aff 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -670,6 +670,11 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
670 return err; 670 return err;
671 } 671 }
672 672
673 /* Reset the entire device */
674 iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
675
676 usleep_range(10, 15);
677
673 iwl_pcie_apm_init(trans); 678 iwl_pcie_apm_init(trans);
674 679
675 /* From now on, the op_mode will be kept updated about RF kill state */ 680 /* From now on, the op_mode will be kept updated about RF kill state */
@@ -1497,16 +1502,16 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
1497 spin_lock_init(&trans_pcie->reg_lock); 1502 spin_lock_init(&trans_pcie->reg_lock);
1498 init_waitqueue_head(&trans_pcie->ucode_write_waitq); 1503 init_waitqueue_head(&trans_pcie->ucode_write_waitq);
1499 1504
1500 /* W/A - seems to solve weird behavior. We need to remove this if we
1501 * don't want to stay in L1 all the time. This wastes a lot of power */
1502 pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
1503 PCIE_LINK_STATE_CLKPM);
1504
1505 if (pci_enable_device(pdev)) { 1505 if (pci_enable_device(pdev)) {
1506 err = -ENODEV; 1506 err = -ENODEV;
1507 goto out_no_pci; 1507 goto out_no_pci;
1508 } 1508 }
1509 1509
1510 /* W/A - seems to solve weird behavior. We need to remove this if we
1511 * don't want to stay in L1 all the time. This wastes a lot of power */
1512 pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
1513 PCIE_LINK_STATE_CLKPM);
1514
1510 pci_set_master(pdev); 1515 pci_set_master(pdev);
1511 1516
1512 err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); 1517 err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36));