Commit f84eaa10 authored by Johannes Berg's avatar Johannes Berg

mac80211: ignore CSA to same channel

If the AP is confused and starts doing a CSA to the same channel,
just ignore that request instead of trying to act it out since it
was likely sent in error anyway.

In the case of the bug I was investigating the GO was misbehaving
and sending out a beacon with CSA IEs still included after having
actually done the channel switch.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 496fcc29
...@@ -464,6 +464,7 @@ struct ieee80211_if_managed { ...@@ -464,6 +464,7 @@ struct ieee80211_if_managed {
unsigned int flags; unsigned int flags;
bool csa_waiting_bcn; bool csa_waiting_bcn;
bool csa_ignored_same_chan;
bool beacon_crc_valid; bool beacon_crc_valid;
u32 beacon_crc; u32 beacon_crc;
......
...@@ -1150,6 +1150,17 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, ...@@ -1150,6 +1150,17 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
return; return;
} }
if (cfg80211_chandef_identical(&csa_ie.chandef,
&sdata->vif.bss_conf.chandef)) {
if (ifmgd->csa_ignored_same_chan)
return;
sdata_info(sdata,
"AP %pM tries to chanswitch to same channel, ignore\n",
ifmgd->associated->bssid);
ifmgd->csa_ignored_same_chan = true;
return;
}
mutex_lock(&local->mtx); mutex_lock(&local->mtx);
mutex_lock(&local->chanctx_mtx); mutex_lock(&local->chanctx_mtx);
conf = rcu_dereference_protected(sdata->vif.chanctx_conf, conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
...@@ -1210,6 +1221,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, ...@@ -1210,6 +1221,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
sdata->vif.csa_active = true; sdata->vif.csa_active = true;
sdata->csa_chandef = csa_ie.chandef; sdata->csa_chandef = csa_ie.chandef;
sdata->csa_block_tx = csa_ie.mode; sdata->csa_block_tx = csa_ie.mode;
ifmgd->csa_ignored_same_chan = false;
if (sdata->csa_block_tx) if (sdata->csa_block_tx)
ieee80211_stop_vif_queues(local, sdata, ieee80211_stop_vif_queues(local, sdata,
...@@ -2090,6 +2102,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, ...@@ -2090,6 +2102,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
sdata->vif.csa_active = false; sdata->vif.csa_active = false;
ifmgd->csa_waiting_bcn = false; ifmgd->csa_waiting_bcn = false;
ifmgd->csa_ignored_same_chan = false;
if (sdata->csa_block_tx) { if (sdata->csa_block_tx) {
ieee80211_wake_vif_queues(local, sdata, ieee80211_wake_vif_queues(local, sdata,
IEEE80211_QUEUE_STOP_REASON_CSA); IEEE80211_QUEUE_STOP_REASON_CSA);
......
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