Skip to content

Commit b13f43a

Browse files
egrumbachlucacoelho
authored andcommitted
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>
1 parent d1b275f commit b13f43a

File tree

6 files changed

+49
-15
lines changed

6 files changed

+49
-15
lines changed

drivers/net/wireless/intel/iwlwifi/fw/api/txq.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@
6868
* @IWL_MVM_DQA_CMD_QUEUE: a queue reserved for sending HCMDs to the FW
6969
* @IWL_MVM_DQA_AUX_QUEUE: a queue reserved for aux frames
7070
* @IWL_MVM_DQA_P2P_DEVICE_QUEUE: a queue reserved for P2P device frames
71+
* @IWL_MVM_DQA_INJECT_MONITOR_QUEUE: a queue reserved for injection using
72+
* monitor mode. Note this queue is the same as the queue for P2P device
73+
* but we can't have active monitor mode along with P2P device anyway.
7174
* @IWL_MVM_DQA_GCAST_QUEUE: a queue reserved for P2P GO/SoftAP GCAST frames
7275
* @IWL_MVM_DQA_BSS_CLIENT_QUEUE: a queue reserved for BSS activity, to ensure
7376
* that we are never left without the possibility to connect to an AP.
@@ -87,6 +90,7 @@ enum iwl_mvm_dqa_txq {
8790
IWL_MVM_DQA_CMD_QUEUE = 0,
8891
IWL_MVM_DQA_AUX_QUEUE = 1,
8992
IWL_MVM_DQA_P2P_DEVICE_QUEUE = 2,
93+
IWL_MVM_DQA_INJECT_MONITOR_QUEUE = 2,
9094
IWL_MVM_DQA_GCAST_QUEUE = 3,
9195
IWL_MVM_DQA_BSS_CLIENT_QUEUE = 4,
9296
IWL_MVM_DQA_MIN_MGMT_QUEUE = 5,

drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,7 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
787787
u32 action)
788788
{
789789
struct iwl_mac_ctx_cmd cmd = {};
790-
u32 tfd_queue_msk = 0;
790+
u32 tfd_queue_msk = BIT(mvm->snif_queue);
791791
int ret;
792792

793793
WARN_ON(vif->type != NL80211_IFTYPE_MONITOR);

drivers/net/wireless/intel/iwlwifi/mvm/mvm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,7 @@ struct iwl_mvm {
972972

973973
/* Tx queues */
974974
u16 aux_queue;
975+
u16 snif_queue;
975976
u16 probe_queue;
976977
u16 p2p_dev_queue;
977978

drivers/net/wireless/intel/iwlwifi/mvm/ops.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
624624
mvm->fw_restart = iwlwifi_mod_params.fw_restart ? -1 : 0;
625625

626626
mvm->aux_queue = IWL_MVM_DQA_AUX_QUEUE;
627+
mvm->snif_queue = IWL_MVM_DQA_INJECT_MONITOR_QUEUE;
627628
mvm->probe_queue = IWL_MVM_DQA_AP_PROBE_RESP_QUEUE;
628629
mvm->p2p_dev_queue = IWL_MVM_DQA_P2P_DEVICE_QUEUE;
629630

drivers/net/wireless/intel/iwlwifi/mvm/sta.c

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1709,29 +1709,29 @@ void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta)
17091709
sta->sta_id = IWL_MVM_INVALID_STA;
17101710
}
17111711

1712-
static void iwl_mvm_enable_aux_queue(struct iwl_mvm *mvm)
1712+
static void iwl_mvm_enable_aux_snif_queue(struct iwl_mvm *mvm, u16 *queue,
1713+
u8 sta_id, u8 fifo)
17131714
{
17141715
unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ?
17151716
mvm->cfg->base_params->wd_timeout :
17161717
IWL_WATCHDOG_DISABLED;
17171718

17181719
if (iwl_mvm_has_new_tx_api(mvm)) {
1719-
int queue = iwl_mvm_tvqm_enable_txq(mvm, mvm->aux_queue,
1720-
mvm->aux_sta.sta_id,
1721-
IWL_MAX_TID_COUNT,
1722-
wdg_timeout);
1723-
mvm->aux_queue = queue;
1720+
int tvqm_queue =
1721+
iwl_mvm_tvqm_enable_txq(mvm, *queue, sta_id,
1722+
IWL_MAX_TID_COUNT,
1723+
wdg_timeout);
1724+
*queue = tvqm_queue;
17241725
} else {
17251726
struct iwl_trans_txq_scd_cfg cfg = {
1726-
.fifo = IWL_MVM_TX_FIFO_MCAST,
1727-
.sta_id = mvm->aux_sta.sta_id,
1727+
.fifo = fifo,
1728+
.sta_id = sta_id,
17281729
.tid = IWL_MAX_TID_COUNT,
17291730
.aggregate = false,
17301731
.frame_limit = IWL_FRAME_LIMIT,
17311732
};
17321733

1733-
iwl_mvm_enable_txq(mvm, mvm->aux_queue, mvm->aux_queue, 0, &cfg,
1734-
wdg_timeout);
1734+
iwl_mvm_enable_txq(mvm, *queue, *queue, 0, &cfg, wdg_timeout);
17351735
}
17361736
}
17371737

@@ -1750,7 +1750,9 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
17501750

17511751
/* Map Aux queue to fifo - needs to happen before adding Aux station */
17521752
if (!iwl_mvm_has_new_tx_api(mvm))
1753-
iwl_mvm_enable_aux_queue(mvm);
1753+
iwl_mvm_enable_aux_snif_queue(mvm, &mvm->aux_queue,
1754+
mvm->aux_sta.sta_id,
1755+
IWL_MVM_TX_FIFO_MCAST);
17541756

17551757
ret = iwl_mvm_add_int_sta_common(mvm, &mvm->aux_sta, NULL,
17561758
MAC_INDEX_AUX, 0);
@@ -1764,18 +1766,41 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
17641766
* to firmware so enable queue here - after the station was added
17651767
*/
17661768
if (iwl_mvm_has_new_tx_api(mvm))
1767-
iwl_mvm_enable_aux_queue(mvm);
1769+
iwl_mvm_enable_aux_snif_queue(mvm, &mvm->aux_queue,
1770+
mvm->aux_sta.sta_id,
1771+
IWL_MVM_TX_FIFO_MCAST);
17681772

17691773
return 0;
17701774
}
17711775

17721776
int iwl_mvm_add_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
17731777
{
17741778
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1779+
int ret;
17751780

17761781
lockdep_assert_held(&mvm->mutex);
1777-
return iwl_mvm_add_int_sta_common(mvm, &mvm->snif_sta, vif->addr,
1782+
1783+
/* Map snif queue to fifo - must happen before adding snif station */
1784+
if (!iwl_mvm_has_new_tx_api(mvm))
1785+
iwl_mvm_enable_aux_snif_queue(mvm, &mvm->snif_queue,
1786+
mvm->snif_sta.sta_id,
1787+
IWL_MVM_TX_FIFO_BE);
1788+
1789+
ret = iwl_mvm_add_int_sta_common(mvm, &mvm->snif_sta, vif->addr,
17781790
mvmvif->id, 0);
1791+
if (ret)
1792+
return ret;
1793+
1794+
/*
1795+
* For 22000 firmware and on we cannot add queue to a station unknown
1796+
* to firmware so enable queue here - after the station was added
1797+
*/
1798+
if (iwl_mvm_has_new_tx_api(mvm))
1799+
iwl_mvm_enable_aux_snif_queue(mvm, &mvm->snif_queue,
1800+
mvm->snif_sta.sta_id,
1801+
IWL_MVM_TX_FIFO_BE);
1802+
1803+
return 0;
17791804
}
17801805

17811806
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)
17841809

17851810
lockdep_assert_held(&mvm->mutex);
17861811

1812+
iwl_mvm_disable_txq(mvm, mvm->snif_queue, mvm->snif_queue,
1813+
IWL_MAX_TID_COUNT, 0);
17871814
ret = iwl_mvm_rm_sta_common(mvm, mvm->snif_sta.sta_id);
17881815
if (ret)
17891816
IWL_WARN(mvm, "Failed sending remove station\n");

drivers/net/wireless/intel/iwlwifi/mvm/tx.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,8 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
657657
if (ap_sta_id != IWL_MVM_INVALID_STA)
658658
sta_id = ap_sta_id;
659659
} else if (info.control.vif->type == NL80211_IFTYPE_MONITOR) {
660-
queue = mvm->aux_queue;
660+
queue = mvm->snif_queue;
661+
sta_id = mvm->snif_sta.sta_id;
661662
}
662663
}
663664

0 commit comments

Comments
 (0)