aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKalle Valo <kvalo@codeaurora.org>2018-03-20 06:01:22 -0400
committerKalle Valo <kvalo@codeaurora.org>2018-03-20 06:01:22 -0400
commit15eb5e3e601773bbb6f18eea4018b5cfe937a71a (patch)
tree463e9d95df7b48889ccb96ef069bf7f4bbc7eb9a
parent1259055170287a350cad453e9eac139c81609860 (diff)
parent9f4ef1d70f05ebb7f0755545c05ea383be0eeb0f (diff)
Merge tag 'iwlwifi-for-kalle-2018-03-19' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes
Fourth batch of iwlwifi fixes intended for 4.16: * a couple of fixes for channel-switch; * a few fixes for the aggregation handling code;
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mvm.h3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c21
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.c53
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/time-event.c15
5 files changed, 52 insertions, 45 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index d09afb4acaeb..7152fdc00fb1 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -3494,6 +3494,7 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
3494 ret = 0; 3494 ret = 0;
3495 goto out; 3495 goto out;
3496 case NL80211_IFTYPE_STATION: 3496 case NL80211_IFTYPE_STATION:
3497 mvmvif->csa_bcn_pending = false;
3497 break; 3498 break;
3498 case NL80211_IFTYPE_MONITOR: 3499 case NL80211_IFTYPE_MONITOR:
3499 /* always disable PS when a monitor interface is active */ 3500 /* always disable PS when a monitor interface is active */
@@ -3537,7 +3538,7 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
3537 } 3538 }
3538 3539
3539 if (switching_chanctx && vif->type == NL80211_IFTYPE_STATION) { 3540 if (switching_chanctx && vif->type == NL80211_IFTYPE_STATION) {
3540 u32 duration = 2 * vif->bss_conf.beacon_int; 3541 u32 duration = 3 * vif->bss_conf.beacon_int;
3541 3542
3542 /* iwl_mvm_protect_session() reads directly from the 3543 /* iwl_mvm_protect_session() reads directly from the
3543 * device (the system time), so make sure it is 3544 * device (the system time), so make sure it is
@@ -3550,6 +3551,7 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
3550 /* Protect the session to make sure we hear the first 3551 /* Protect the session to make sure we hear the first
3551 * beacon on the new channel. 3552 * beacon on the new channel.
3552 */ 3553 */
3554 mvmvif->csa_bcn_pending = true;
3553 iwl_mvm_protect_session(mvm, vif, duration, duration, 3555 iwl_mvm_protect_session(mvm, vif, duration, duration,
3554 vif->bss_conf.beacon_int / 2, 3556 vif->bss_conf.beacon_int / 2,
3555 true); 3557 true);
@@ -3988,6 +3990,7 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw,
3988 if (vif->type == NL80211_IFTYPE_STATION) { 3990 if (vif->type == NL80211_IFTYPE_STATION) {
3989 struct iwl_mvm_sta *mvmsta; 3991 struct iwl_mvm_sta *mvmsta;
3990 3992
3993 mvmvif->csa_bcn_pending = false;
3991 mvmsta = iwl_mvm_sta_from_staid_protected(mvm, 3994 mvmsta = iwl_mvm_sta_from_staid_protected(mvm,
3992 mvmvif->ap_sta_id); 3995 mvmvif->ap_sta_id);
3993 3996
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 89ff02d7c876..625b238a3f0a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -438,6 +438,9 @@ struct iwl_mvm_vif {
438 bool csa_failed; 438 bool csa_failed;
439 u16 csa_target_freq; 439 u16 csa_target_freq;
440 440
441 /* Indicates that we are waiting for a beacon on a new channel */
442 bool csa_bcn_pending;
443
441 /* TCP Checksum Offload */ 444 /* TCP Checksum Offload */
442 netdev_features_t features; 445 netdev_features_t features;
443}; 446};
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
index 305cd56bf746..7f5434b34d0d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
@@ -8,6 +8,7 @@
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
10 * Copyright(c) 2017 Intel Deutschland GmbH 10 * Copyright(c) 2017 Intel Deutschland GmbH
11 * Copyright(c) 2018 Intel Corporation
11 * 12 *
12 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of version 2 of the GNU General Public License as 14 * it under the terms of version 2 of the GNU General Public License as
@@ -18,11 +19,6 @@
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details. 20 * General Public License for more details.
20 * 21 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
24 * USA
25 *
26 * The full GNU General Public License is included in this distribution 22 * The full GNU General Public License is included in this distribution
27 * in the file called COPYING. 23 * in the file called COPYING.
28 * 24 *
@@ -34,6 +30,7 @@
34 * 30 *
35 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
36 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
33 * Copyright(c) 2018 Intel Corporation
37 * All rights reserved. 34 * All rights reserved.
38 * 35 *
39 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -286,6 +283,20 @@ void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
286 return; 283 return;
287 284
288 ctxt->ref--; 285 ctxt->ref--;
286
287 /*
288 * Move unused phy's to a default channel. When the phy is moved the,
289 * fw will cleanup immediate quiet bit if it was previously set,
290 * otherwise we might not be able to reuse this phy.
291 */
292 if (ctxt->ref == 0) {
293 struct ieee80211_channel *chan;
294 struct cfg80211_chan_def chandef;
295
296 chan = &mvm->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[0];
297 cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
298 iwl_mvm_phy_ctxt_changed(mvm, ctxt, &chandef, 1, 1);
299 }
289} 300}
290 301
291static void iwl_mvm_binding_iterator(void *_data, u8 *mac, 302static void iwl_mvm_binding_iterator(void *_data, u8 *mac,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 5be4bae5b70d..80067eb9ea05 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -1695,7 +1695,8 @@ int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm,
1695 u32 qmask, enum nl80211_iftype iftype, 1695 u32 qmask, enum nl80211_iftype iftype,
1696 enum iwl_sta_type type) 1696 enum iwl_sta_type type)
1697{ 1697{
1698 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { 1698 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) ||
1699 sta->sta_id == IWL_MVM_INVALID_STA) {
1699 sta->sta_id = iwl_mvm_find_free_sta_id(mvm, iftype); 1700 sta->sta_id = iwl_mvm_find_free_sta_id(mvm, iftype);
1700 if (WARN_ON_ONCE(sta->sta_id == IWL_MVM_INVALID_STA)) 1701 if (WARN_ON_ONCE(sta->sta_id == IWL_MVM_INVALID_STA))
1701 return -ENOSPC; 1702 return -ENOSPC;
@@ -2478,28 +2479,12 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
2478 2479
2479 /* 2480 /*
2480 * Note the possible cases: 2481 * Note the possible cases:
2481 * 1. In DQA mode with an enabled TXQ - TXQ needs to become agg'ed 2482 * 1. An enabled TXQ - TXQ needs to become agg'ed
2482 * 2. Non-DQA mode: the TXQ hasn't yet been enabled, so find a free 2483 * 2. The TXQ hasn't yet been enabled, so find a free one and mark
2483 * one and mark it as reserved 2484 * it as reserved
2484 * 3. In DQA mode, but no traffic yet on this TID: same treatment as in
2485 * non-DQA mode, since the TXQ hasn't yet been allocated
2486 * Don't support case 3 for new TX path as it is not expected to happen
2487 * and aggregation will be offloaded soon anyway
2488 */ 2485 */
2489 txq_id = mvmsta->tid_data[tid].txq_id; 2486 txq_id = mvmsta->tid_data[tid].txq_id;
2490 if (iwl_mvm_has_new_tx_api(mvm)) { 2487 if (txq_id == IWL_MVM_INVALID_QUEUE) {
2491 if (txq_id == IWL_MVM_INVALID_QUEUE) {
2492 ret = -ENXIO;
2493 goto release_locks;
2494 }
2495 } else if (unlikely(mvm->queue_info[txq_id].status ==
2496 IWL_MVM_QUEUE_SHARED)) {
2497 ret = -ENXIO;
2498 IWL_DEBUG_TX_QUEUES(mvm,
2499 "Can't start tid %d agg on shared queue!\n",
2500 tid);
2501 goto release_locks;
2502 } else if (mvm->queue_info[txq_id].status != IWL_MVM_QUEUE_READY) {
2503 txq_id = iwl_mvm_find_free_queue(mvm, mvmsta->sta_id, 2488 txq_id = iwl_mvm_find_free_queue(mvm, mvmsta->sta_id,
2504 IWL_MVM_DQA_MIN_DATA_QUEUE, 2489 IWL_MVM_DQA_MIN_DATA_QUEUE,
2505 IWL_MVM_DQA_MAX_DATA_QUEUE); 2490 IWL_MVM_DQA_MAX_DATA_QUEUE);
@@ -2508,16 +2493,16 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
2508 IWL_ERR(mvm, "Failed to allocate agg queue\n"); 2493 IWL_ERR(mvm, "Failed to allocate agg queue\n");
2509 goto release_locks; 2494 goto release_locks;
2510 } 2495 }
2511 /*
2512 * TXQ shouldn't be in inactive mode for non-DQA, so getting
2513 * an inactive queue from iwl_mvm_find_free_queue() is
2514 * certainly a bug
2515 */
2516 WARN_ON(mvm->queue_info[txq_id].status ==
2517 IWL_MVM_QUEUE_INACTIVE);
2518 2496
2519 /* TXQ hasn't yet been enabled, so mark it only as reserved */ 2497 /* TXQ hasn't yet been enabled, so mark it only as reserved */
2520 mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_RESERVED; 2498 mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_RESERVED;
2499 } else if (unlikely(mvm->queue_info[txq_id].status ==
2500 IWL_MVM_QUEUE_SHARED)) {
2501 ret = -ENXIO;
2502 IWL_DEBUG_TX_QUEUES(mvm,
2503 "Can't start tid %d agg on shared queue!\n",
2504 tid);
2505 goto release_locks;
2521 } 2506 }
2522 2507
2523 spin_unlock(&mvm->queue_info_lock); 2508 spin_unlock(&mvm->queue_info_lock);
@@ -2696,8 +2681,10 @@ out:
2696 2681
2697static void iwl_mvm_unreserve_agg_queue(struct iwl_mvm *mvm, 2682static void iwl_mvm_unreserve_agg_queue(struct iwl_mvm *mvm,
2698 struct iwl_mvm_sta *mvmsta, 2683 struct iwl_mvm_sta *mvmsta,
2699 u16 txq_id) 2684 struct iwl_mvm_tid_data *tid_data)
2700{ 2685{
2686 u16 txq_id = tid_data->txq_id;
2687
2701 if (iwl_mvm_has_new_tx_api(mvm)) 2688 if (iwl_mvm_has_new_tx_api(mvm))
2702 return; 2689 return;
2703 2690
@@ -2709,8 +2696,10 @@ static void iwl_mvm_unreserve_agg_queue(struct iwl_mvm *mvm,
2709 * allocated through iwl_mvm_enable_txq, so we can just mark it back as 2696 * allocated through iwl_mvm_enable_txq, so we can just mark it back as
2710 * free. 2697 * free.
2711 */ 2698 */
2712 if (mvm->queue_info[txq_id].status == IWL_MVM_QUEUE_RESERVED) 2699 if (mvm->queue_info[txq_id].status == IWL_MVM_QUEUE_RESERVED) {
2713 mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_FREE; 2700 mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_FREE;
2701 tid_data->txq_id = IWL_MVM_INVALID_QUEUE;
2702 }
2714 2703
2715 spin_unlock_bh(&mvm->queue_info_lock); 2704 spin_unlock_bh(&mvm->queue_info_lock);
2716} 2705}
@@ -2741,7 +2730,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
2741 2730
2742 mvmsta->agg_tids &= ~BIT(tid); 2731 mvmsta->agg_tids &= ~BIT(tid);
2743 2732
2744 iwl_mvm_unreserve_agg_queue(mvm, mvmsta, txq_id); 2733 iwl_mvm_unreserve_agg_queue(mvm, mvmsta, tid_data);
2745 2734
2746 switch (tid_data->state) { 2735 switch (tid_data->state) {
2747 case IWL_AGG_ON: 2736 case IWL_AGG_ON:
@@ -2808,7 +2797,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
2808 mvmsta->agg_tids &= ~BIT(tid); 2797 mvmsta->agg_tids &= ~BIT(tid);
2809 spin_unlock_bh(&mvmsta->lock); 2798 spin_unlock_bh(&mvmsta->lock);
2810 2799
2811 iwl_mvm_unreserve_agg_queue(mvm, mvmsta, txq_id); 2800 iwl_mvm_unreserve_agg_queue(mvm, mvmsta, tid_data);
2812 2801
2813 if (old_state >= IWL_AGG_ON) { 2802 if (old_state >= IWL_AGG_ON) {
2814 iwl_mvm_drain_sta(mvm, mvmsta, true); 2803 iwl_mvm_drain_sta(mvm, mvmsta, true);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
index acb217e666db..cd91bc44259c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
@@ -8,6 +8,7 @@
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2017 Intel Deutschland GmbH 10 * Copyright(c) 2017 Intel Deutschland GmbH
11 * Copyright(c) 2018 Intel Corporation
11 * 12 *
12 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of version 2 of the GNU General Public License as 14 * it under the terms of version 2 of the GNU General Public License as
@@ -18,11 +19,6 @@
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details. 20 * General Public License for more details.
20 * 21 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
24 * USA
25 *
26 * The full GNU General Public License is included in this distribution 22 * The full GNU General Public License is included in this distribution
27 * in the file called COPYING. 23 * in the file called COPYING.
28 * 24 *
@@ -35,6 +31,7 @@
35 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
36 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
37 * Copyright(c) 2017 Intel Deutschland GmbH 33 * Copyright(c) 2017 Intel Deutschland GmbH
34 * Copyright(c) 2018 Intel Corporation
38 * All rights reserved. 35 * All rights reserved.
39 * 36 *
40 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -198,9 +195,13 @@ static bool iwl_mvm_te_check_disconnect(struct iwl_mvm *mvm,
198 struct ieee80211_vif *vif, 195 struct ieee80211_vif *vif,
199 const char *errmsg) 196 const char *errmsg)
200{ 197{
198 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
199
201 if (vif->type != NL80211_IFTYPE_STATION) 200 if (vif->type != NL80211_IFTYPE_STATION)
202 return false; 201 return false;
203 if (vif->bss_conf.assoc && vif->bss_conf.dtim_period) 202
203 if (!mvmvif->csa_bcn_pending && vif->bss_conf.assoc &&
204 vif->bss_conf.dtim_period)
204 return false; 205 return false;
205 if (errmsg) 206 if (errmsg)
206 IWL_ERR(mvm, "%s\n", errmsg); 207 IWL_ERR(mvm, "%s\n", errmsg);
@@ -344,7 +345,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
344 * and know the dtim period. 345 * and know the dtim period.
345 */ 346 */
346 iwl_mvm_te_check_disconnect(mvm, te_data->vif, 347 iwl_mvm_te_check_disconnect(mvm, te_data->vif,
347 "No association and the time event is over already..."); 348 "No beacon heard and the time event is over already...");
348 break; 349 break;
349 default: 350 default:
350 break; 351 break;