diff options
author | Kalle Valo <kvalo@codeaurora.org> | 2018-03-20 06:01:22 -0400 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2018-03-20 06:01:22 -0400 |
commit | 15eb5e3e601773bbb6f18eea4018b5cfe937a71a (patch) | |
tree | 463e9d95df7b48889ccb96ef069bf7f4bbc7eb9a | |
parent | 1259055170287a350cad453e9eac139c81609860 (diff) | |
parent | 9f4ef1d70f05ebb7f0755545c05ea383be0eeb0f (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.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c | 21 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 53 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/time-event.c | 15 |
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 | ||
291 | static void iwl_mvm_binding_iterator(void *_data, u8 *mac, | 302 | static 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 | ||
2697 | static void iwl_mvm_unreserve_agg_queue(struct iwl_mvm *mvm, | 2682 | static 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; |