Commit 15eb5e3e authored by Kalle Valo's avatar Kalle Valo

Merge tag 'iwlwifi-for-kalle-2018-03-19' of...

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;
parents 12590551 9f4ef1d7
...@@ -3494,6 +3494,7 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm, ...@@ -3494,6 +3494,7 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
ret = 0; ret = 0;
goto out; goto out;
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
mvmvif->csa_bcn_pending = false;
break; break;
case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_MONITOR:
/* always disable PS when a monitor interface is active */ /* 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,7 +3538,7 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
} }
if (switching_chanctx && vif->type == NL80211_IFTYPE_STATION) { if (switching_chanctx && vif->type == NL80211_IFTYPE_STATION) {
u32 duration = 2 * vif->bss_conf.beacon_int; u32 duration = 3 * vif->bss_conf.beacon_int;
/* iwl_mvm_protect_session() reads directly from the /* iwl_mvm_protect_session() reads directly from the
* device (the system time), so make sure it is * 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,6 +3551,7 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
/* Protect the session to make sure we hear the first /* Protect the session to make sure we hear the first
* beacon on the new channel. * beacon on the new channel.
*/ */
mvmvif->csa_bcn_pending = true;
iwl_mvm_protect_session(mvm, vif, duration, duration, iwl_mvm_protect_session(mvm, vif, duration, duration,
vif->bss_conf.beacon_int / 2, vif->bss_conf.beacon_int / 2,
true); true);
...@@ -3988,6 +3990,7 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw, ...@@ -3988,6 +3990,7 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw,
if (vif->type == NL80211_IFTYPE_STATION) { if (vif->type == NL80211_IFTYPE_STATION) {
struct iwl_mvm_sta *mvmsta; struct iwl_mvm_sta *mvmsta;
mvmvif->csa_bcn_pending = false;
mvmsta = iwl_mvm_sta_from_staid_protected(mvm, mvmsta = iwl_mvm_sta_from_staid_protected(mvm,
mvmvif->ap_sta_id); mvmvif->ap_sta_id);
......
...@@ -438,6 +438,9 @@ struct iwl_mvm_vif { ...@@ -438,6 +438,9 @@ struct iwl_mvm_vif {
bool csa_failed; bool csa_failed;
u16 csa_target_freq; u16 csa_target_freq;
/* Indicates that we are waiting for a beacon on a new channel */
bool csa_bcn_pending;
/* TCP Checksum Offload */ /* TCP Checksum Offload */
netdev_features_t features; netdev_features_t features;
}; };
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
* Copyright(c) 2017 Intel Deutschland GmbH * Copyright(c) 2017 Intel Deutschland GmbH
* Copyright(c) 2018 Intel Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as * it under the terms of version 2 of the GNU General Public License as
...@@ -18,11 +19,6 @@ ...@@ -18,11 +19,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
* USA
*
* The full GNU General Public License is included in this distribution * The full GNU General Public License is included in this distribution
* in the file called COPYING. * in the file called COPYING.
* *
...@@ -34,6 +30,7 @@ ...@@ -34,6 +30,7 @@
* *
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
* Copyright(c) 2018 Intel Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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,6 +283,20 @@ void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
return; return;
ctxt->ref--; ctxt->ref--;
/*
* Move unused phy's to a default channel. When the phy is moved the,
* fw will cleanup immediate quiet bit if it was previously set,
* otherwise we might not be able to reuse this phy.
*/
if (ctxt->ref == 0) {
struct ieee80211_channel *chan;
struct cfg80211_chan_def chandef;
chan = &mvm->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[0];
cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
iwl_mvm_phy_ctxt_changed(mvm, ctxt, &chandef, 1, 1);
}
} }
static void iwl_mvm_binding_iterator(void *_data, u8 *mac, static void iwl_mvm_binding_iterator(void *_data, u8 *mac,
......
...@@ -1695,7 +1695,8 @@ int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, ...@@ -1695,7 +1695,8 @@ int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm,
u32 qmask, enum nl80211_iftype iftype, u32 qmask, enum nl80211_iftype iftype,
enum iwl_sta_type type) enum iwl_sta_type type)
{ {
if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) ||
sta->sta_id == IWL_MVM_INVALID_STA) {
sta->sta_id = iwl_mvm_find_free_sta_id(mvm, iftype); sta->sta_id = iwl_mvm_find_free_sta_id(mvm, iftype);
if (WARN_ON_ONCE(sta->sta_id == IWL_MVM_INVALID_STA)) if (WARN_ON_ONCE(sta->sta_id == IWL_MVM_INVALID_STA))
return -ENOSPC; return -ENOSPC;
...@@ -2478,28 +2479,12 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ...@@ -2478,28 +2479,12 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
/* /*
* Note the possible cases: * Note the possible cases:
* 1. In DQA mode with an enabled TXQ - TXQ needs to become agg'ed * 1. An enabled TXQ - TXQ needs to become agg'ed
* 2. Non-DQA mode: the TXQ hasn't yet been enabled, so find a free * 2. The TXQ hasn't yet been enabled, so find a free one and mark
* one and mark it as reserved * it as reserved
* 3. In DQA mode, but no traffic yet on this TID: same treatment as in
* non-DQA mode, since the TXQ hasn't yet been allocated
* Don't support case 3 for new TX path as it is not expected to happen
* and aggregation will be offloaded soon anyway
*/ */
txq_id = mvmsta->tid_data[tid].txq_id; txq_id = mvmsta->tid_data[tid].txq_id;
if (iwl_mvm_has_new_tx_api(mvm)) { if (txq_id == IWL_MVM_INVALID_QUEUE) {
if (txq_id == IWL_MVM_INVALID_QUEUE) {
ret = -ENXIO;
goto release_locks;
}
} else if (unlikely(mvm->queue_info[txq_id].status ==
IWL_MVM_QUEUE_SHARED)) {
ret = -ENXIO;
IWL_DEBUG_TX_QUEUES(mvm,
"Can't start tid %d agg on shared queue!\n",
tid);
goto release_locks;
} else if (mvm->queue_info[txq_id].status != IWL_MVM_QUEUE_READY) {
txq_id = iwl_mvm_find_free_queue(mvm, mvmsta->sta_id, txq_id = iwl_mvm_find_free_queue(mvm, mvmsta->sta_id,
IWL_MVM_DQA_MIN_DATA_QUEUE, IWL_MVM_DQA_MIN_DATA_QUEUE,
IWL_MVM_DQA_MAX_DATA_QUEUE); 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,16 +2493,16 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
IWL_ERR(mvm, "Failed to allocate agg queue\n"); IWL_ERR(mvm, "Failed to allocate agg queue\n");
goto release_locks; goto release_locks;
} }
/*
* TXQ shouldn't be in inactive mode for non-DQA, so getting
* an inactive queue from iwl_mvm_find_free_queue() is
* certainly a bug
*/
WARN_ON(mvm->queue_info[txq_id].status ==
IWL_MVM_QUEUE_INACTIVE);
/* TXQ hasn't yet been enabled, so mark it only as reserved */ /* TXQ hasn't yet been enabled, so mark it only as reserved */
mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_RESERVED; mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_RESERVED;
} else if (unlikely(mvm->queue_info[txq_id].status ==
IWL_MVM_QUEUE_SHARED)) {
ret = -ENXIO;
IWL_DEBUG_TX_QUEUES(mvm,
"Can't start tid %d agg on shared queue!\n",
tid);
goto release_locks;
} }
spin_unlock(&mvm->queue_info_lock); spin_unlock(&mvm->queue_info_lock);
...@@ -2696,8 +2681,10 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ...@@ -2696,8 +2681,10 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
static void iwl_mvm_unreserve_agg_queue(struct iwl_mvm *mvm, static void iwl_mvm_unreserve_agg_queue(struct iwl_mvm *mvm,
struct iwl_mvm_sta *mvmsta, struct iwl_mvm_sta *mvmsta,
u16 txq_id) struct iwl_mvm_tid_data *tid_data)
{ {
u16 txq_id = tid_data->txq_id;
if (iwl_mvm_has_new_tx_api(mvm)) if (iwl_mvm_has_new_tx_api(mvm))
return; return;
...@@ -2709,8 +2696,10 @@ static void iwl_mvm_unreserve_agg_queue(struct iwl_mvm *mvm, ...@@ -2709,8 +2696,10 @@ static void iwl_mvm_unreserve_agg_queue(struct iwl_mvm *mvm,
* allocated through iwl_mvm_enable_txq, so we can just mark it back as * allocated through iwl_mvm_enable_txq, so we can just mark it back as
* free. * free.
*/ */
if (mvm->queue_info[txq_id].status == IWL_MVM_QUEUE_RESERVED) if (mvm->queue_info[txq_id].status == IWL_MVM_QUEUE_RESERVED) {
mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_FREE; mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_FREE;
tid_data->txq_id = IWL_MVM_INVALID_QUEUE;
}
spin_unlock_bh(&mvm->queue_info_lock); spin_unlock_bh(&mvm->queue_info_lock);
} }
...@@ -2741,7 +2730,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ...@@ -2741,7 +2730,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
mvmsta->agg_tids &= ~BIT(tid); mvmsta->agg_tids &= ~BIT(tid);
iwl_mvm_unreserve_agg_queue(mvm, mvmsta, txq_id); iwl_mvm_unreserve_agg_queue(mvm, mvmsta, tid_data);
switch (tid_data->state) { switch (tid_data->state) {
case IWL_AGG_ON: case IWL_AGG_ON:
...@@ -2808,7 +2797,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ...@@ -2808,7 +2797,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
mvmsta->agg_tids &= ~BIT(tid); mvmsta->agg_tids &= ~BIT(tid);
spin_unlock_bh(&mvmsta->lock); spin_unlock_bh(&mvmsta->lock);
iwl_mvm_unreserve_agg_queue(mvm, mvmsta, txq_id); iwl_mvm_unreserve_agg_queue(mvm, mvmsta, tid_data);
if (old_state >= IWL_AGG_ON) { if (old_state >= IWL_AGG_ON) {
iwl_mvm_drain_sta(mvm, mvmsta, true); iwl_mvm_drain_sta(mvm, mvmsta, true);
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2017 Intel Deutschland GmbH * Copyright(c) 2017 Intel Deutschland GmbH
* Copyright(c) 2018 Intel Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as * it under the terms of version 2 of the GNU General Public License as
...@@ -18,11 +19,6 @@ ...@@ -18,11 +19,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
* USA
*
* The full GNU General Public License is included in this distribution * The full GNU General Public License is included in this distribution
* in the file called COPYING. * in the file called COPYING.
* *
...@@ -35,6 +31,7 @@ ...@@ -35,6 +31,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2017 Intel Deutschland GmbH * Copyright(c) 2017 Intel Deutschland GmbH
* Copyright(c) 2018 Intel Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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,9 +195,13 @@ static bool iwl_mvm_te_check_disconnect(struct iwl_mvm *mvm,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
const char *errmsg) const char *errmsg)
{ {
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
if (vif->type != NL80211_IFTYPE_STATION) if (vif->type != NL80211_IFTYPE_STATION)
return false; return false;
if (vif->bss_conf.assoc && vif->bss_conf.dtim_period)
if (!mvmvif->csa_bcn_pending && vif->bss_conf.assoc &&
vif->bss_conf.dtim_period)
return false; return false;
if (errmsg) if (errmsg)
IWL_ERR(mvm, "%s\n", errmsg); IWL_ERR(mvm, "%s\n", errmsg);
...@@ -344,7 +345,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm, ...@@ -344,7 +345,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
* and know the dtim period. * and know the dtim period.
*/ */
iwl_mvm_te_check_disconnect(mvm, te_data->vif, iwl_mvm_te_check_disconnect(mvm, te_data->vif,
"No association and the time event is over already..."); "No beacon heard and the time event is over already...");
break; break;
default: default:
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment