summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2017-11-19 10:35:14 +0200
committerLuca Coelho <luciano.coelho@intel.com>2017-11-25 17:06:42 +0200
commitb13f43a48571f0cd0fda271b5046b65f1f268db5 (patch)
treed052b5cbbf2eea95ffd83182ffd79d06f5d012e7 /drivers/net/wireless/intel/iwlwifi/mvm/sta.c
parentd1b275ffec459c5ae12b5c7086c84175696e5a9f (diff)
iwlwifi: mvm: fix packet injection
We need to have a station and a queue for the monitor interface to be able to inject traffic. We used to have this traffic routed to the auxiliary queue, but this queue isn't scheduled for the station we had linked to the monitor vif. Allocate a new queue, link it to the monitor vif's station and make that queue use the BE fifo. This fixes https://bugzilla.kernel.org/show_bug.cgi?id=196715 Cc: stable@vger.kernel.org Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/sta.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.c53
1 files changed, 40 insertions, 13 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index c19f98489d4e..1add5615fc3a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -1709,29 +1709,29 @@ void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta)
sta->sta_id = IWL_MVM_INVALID_STA;
}
-static void iwl_mvm_enable_aux_queue(struct iwl_mvm *mvm)
+static void iwl_mvm_enable_aux_snif_queue(struct iwl_mvm *mvm, u16 *queue,
+ u8 sta_id, u8 fifo)
{
unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ?
mvm->cfg->base_params->wd_timeout :
IWL_WATCHDOG_DISABLED;
if (iwl_mvm_has_new_tx_api(mvm)) {
- int queue = iwl_mvm_tvqm_enable_txq(mvm, mvm->aux_queue,
- mvm->aux_sta.sta_id,
- IWL_MAX_TID_COUNT,
- wdg_timeout);
- mvm->aux_queue = queue;
+ int tvqm_queue =
+ iwl_mvm_tvqm_enable_txq(mvm, *queue, sta_id,
+ IWL_MAX_TID_COUNT,
+ wdg_timeout);
+ *queue = tvqm_queue;
} else {
struct iwl_trans_txq_scd_cfg cfg = {
- .fifo = IWL_MVM_TX_FIFO_MCAST,
- .sta_id = mvm->aux_sta.sta_id,
+ .fifo = fifo,
+ .sta_id = sta_id,
.tid = IWL_MAX_TID_COUNT,
.aggregate = false,
.frame_limit = IWL_FRAME_LIMIT,
};
- iwl_mvm_enable_txq(mvm, mvm->aux_queue, mvm->aux_queue, 0, &cfg,
- wdg_timeout);
+ iwl_mvm_enable_txq(mvm, *queue, *queue, 0, &cfg, wdg_timeout);
}
}
@@ -1750,7 +1750,9 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
/* Map Aux queue to fifo - needs to happen before adding Aux station */
if (!iwl_mvm_has_new_tx_api(mvm))
- iwl_mvm_enable_aux_queue(mvm);
+ iwl_mvm_enable_aux_snif_queue(mvm, &mvm->aux_queue,
+ mvm->aux_sta.sta_id,
+ IWL_MVM_TX_FIFO_MCAST);
ret = iwl_mvm_add_int_sta_common(mvm, &mvm->aux_sta, NULL,
MAC_INDEX_AUX, 0);
@@ -1764,7 +1766,9 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
* to firmware so enable queue here - after the station was added
*/
if (iwl_mvm_has_new_tx_api(mvm))
- iwl_mvm_enable_aux_queue(mvm);
+ iwl_mvm_enable_aux_snif_queue(mvm, &mvm->aux_queue,
+ mvm->aux_sta.sta_id,
+ IWL_MVM_TX_FIFO_MCAST);
return 0;
}
@@ -1772,10 +1776,31 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
int iwl_mvm_add_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ int ret;
lockdep_assert_held(&mvm->mutex);
- return iwl_mvm_add_int_sta_common(mvm, &mvm->snif_sta, vif->addr,
+
+ /* Map snif queue to fifo - must happen before adding snif station */
+ if (!iwl_mvm_has_new_tx_api(mvm))
+ iwl_mvm_enable_aux_snif_queue(mvm, &mvm->snif_queue,
+ mvm->snif_sta.sta_id,
+ IWL_MVM_TX_FIFO_BE);
+
+ ret = iwl_mvm_add_int_sta_common(mvm, &mvm->snif_sta, vif->addr,
mvmvif->id, 0);
+ if (ret)
+ return ret;
+
+ /*
+ * For 22000 firmware and on we cannot add queue to a station unknown
+ * to firmware so enable queue here - after the station was added
+ */
+ if (iwl_mvm_has_new_tx_api(mvm))
+ iwl_mvm_enable_aux_snif_queue(mvm, &mvm->snif_queue,
+ mvm->snif_sta.sta_id,
+ IWL_MVM_TX_FIFO_BE);
+
+ return 0;
}
int iwl_mvm_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
@@ -1784,6 +1809,8 @@ int iwl_mvm_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
lockdep_assert_held(&mvm->mutex);
+ iwl_mvm_disable_txq(mvm, mvm->snif_queue, mvm->snif_queue,
+ IWL_MAX_TID_COUNT, 0);
ret = iwl_mvm_rm_sta_common(mvm, mvm->snif_sta.sta_id);
if (ret)
IWL_WARN(mvm, "Failed sending remove station\n");