Commit 2964b57f authored by Johannes Berg's avatar Johannes Berg

wifi: iwlwifi: mvm: fix flushing during quiet CSA

If, for any reason, we're going to attempt to flush the queues
while quiet CSA is happening, this cannot succeed. This could
be the case if for example mac80211 were to flush after TXing
e.g. a deauth frame due to disconnecting during the CSA.

In this case, drop the frames instead, the firmware won't let
us do any transmissions and may also become unhappy if we're
not going to disconnect quickly enough.

Currently this doesn't happen as mac80211 stops queues, but
we'll want to let mac80211 know not to stop queues for proper
multi-link support during CSA, so we need to handle this case.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarMiri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240311081938.d5d629f32ea8.I86d9b849d92273542bfc2d9c671b66179e7ebb72@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent d90ab6e3
......@@ -1437,6 +1437,7 @@ int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw,
u8 ap_sta_id = mvmvif->link[link_id]->ap_sta_id;
mvmvif->csa_bcn_pending = false;
mvmvif->csa_blocks_tx = false;
mvmsta = iwl_mvm_sta_from_staid_protected(mvm, ap_sta_id);
if (WARN_ON(!mvmsta)) {
......@@ -5426,6 +5427,7 @@ int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
mutex_lock(&mvm->mutex);
mvmvif->csa_failed = false;
mvmvif->csa_blocks_tx = false;
IWL_DEBUG_MAC80211(mvm, "pre CSA to freq %d\n",
chsw->chandef.center_freq1);
......@@ -5464,6 +5466,8 @@ int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
break;
case NL80211_IFTYPE_STATION:
mvmvif->csa_blocks_tx = chsw->block_tx;
/*
* In the new flow FW is in charge of timing the switch so there
* is no need for all of this
......@@ -5628,8 +5632,8 @@ static void iwl_mvm_flush_no_vif(struct iwl_mvm *mvm, u32 queues, bool drop)
void iwl_mvm_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u32 queues, bool drop)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
struct iwl_mvm_vif *mvmvif;
struct iwl_mvm_sta *mvmsta;
struct ieee80211_sta *sta;
bool ap_sta_done = false;
......@@ -5641,11 +5645,22 @@ void iwl_mvm_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
return;
}
if (!drop && hweight16(vif->active_links) <= 1) {
int link_id = vif->active_links ? __ffs(vif->active_links) : 0;
struct ieee80211_bss_conf *link_conf;
link_conf = wiphy_dereference(hw->wiphy,
vif->link_conf[link_id]);
if (WARN_ON(!link_conf))
return;
if (link_conf->csa_active && mvmvif->csa_blocks_tx)
drop = true;
}
/* Make sure we're done with the deferred traffic before flushing */
flush_work(&mvm->add_stream_wk);
mutex_lock(&mvm->mutex);
mvmvif = iwl_mvm_vif_from_mac80211(vif);
/* flush the AP-station and all TDLS peers */
for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
......
......@@ -370,6 +370,7 @@ struct iwl_mvm_vif_link_info {
* @csa_countdown: indicates that CSA countdown may be started
* @csa_failed: CSA failed to schedule time event, report an error later
* @csa_bcn_pending: indicates that we are waiting for a beacon on a new channel
* @csa_blocks_tx: CSA is blocking TX
* @features: hw features active for this vif
* @ap_beacon_time: AP beacon time for synchronisation (on older FW)
* @bf_enabled: indicates if beacon filtering is enabled
......@@ -445,6 +446,7 @@ struct iwl_mvm_vif {
bool csa_countdown;
bool csa_failed;
bool csa_bcn_pending;
bool csa_blocks_tx;
u16 csa_target_freq;
u16 csa_count;
u16 csa_misbehave;
......
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