summaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorSara Sharon <sara.sharon@intel.com>2019-02-06 06:17:10 -0500
committerJohannes Berg <johannes.berg@intel.com>2019-02-22 07:43:53 -0500
commitb9cc81d827ed13502ca9c8523361be26ca1d7220 (patch)
tree557b5204ff9b7cfea170afa9379fbdb1ecb4230b /net/mac80211/mlme.c
parentee145775c1eb84bb76e71639425ec44c654fb868 (diff)
mac80211: abort CSA if beacon does not include CSA IEs
In case we receive a beacon without CSA IE while we are in the middle of channel switch - abort the operation. Signed-off-by: Sara Sharon <sara.sharon@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c43
1 files changed, 37 insertions, 6 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 1b4938d100d5..28a275ec6700 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1259,6 +1259,32 @@ static void ieee80211_chswitch_timer(struct timer_list *t)
1259} 1259}
1260 1260
1261static void 1261static void
1262ieee80211_sta_abort_chanswitch(struct ieee80211_sub_if_data *sdata)
1263{
1264 struct ieee80211_local *local = sdata->local;
1265
1266 if (!local->ops->abort_channel_switch)
1267 return;
1268
1269 mutex_lock(&local->mtx);
1270
1271 mutex_lock(&local->chanctx_mtx);
1272 ieee80211_vif_unreserve_chanctx(sdata);
1273 mutex_unlock(&local->chanctx_mtx);
1274
1275 if (sdata->csa_block_tx)
1276 ieee80211_wake_vif_queues(local, sdata,
1277 IEEE80211_QUEUE_STOP_REASON_CSA);
1278
1279 sdata->csa_block_tx = false;
1280 sdata->vif.csa_active = false;
1281
1282 mutex_unlock(&local->mtx);
1283
1284 drv_abort_channel_switch(sdata);
1285}
1286
1287static void
1262ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, 1288ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1263 u64 timestamp, u32 device_timestamp, 1289 u64 timestamp, u32 device_timestamp,
1264 struct ieee802_11_elems *elems, 1290 struct ieee802_11_elems *elems,
@@ -1282,19 +1308,24 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1282 if (local->scanning) 1308 if (local->scanning)
1283 return; 1309 return;
1284 1310
1285 /* disregard subsequent announcements if we are already processing */
1286 if (sdata->vif.csa_active)
1287 return;
1288
1289 current_band = cbss->channel->band; 1311 current_band = cbss->channel->band;
1290 res = ieee80211_parse_ch_switch_ie(sdata, elems, current_band, 1312 res = ieee80211_parse_ch_switch_ie(sdata, elems, current_band,
1291 ifmgd->flags, 1313 ifmgd->flags,
1292 ifmgd->associated->bssid, &csa_ie); 1314 ifmgd->associated->bssid, &csa_ie);
1293 if (res < 0) 1315 if (res < 0) {
1294 ieee80211_queue_work(&local->hw, 1316 ieee80211_queue_work(&local->hw,
1295 &ifmgd->csa_connection_drop_work); 1317 &ifmgd->csa_connection_drop_work);
1296 if (res)
1297 return; 1318 return;
1319 }
1320
1321 if (res && beacon && sdata->vif.csa_active &&
1322 !ifmgd->csa_waiting_bcn) {
1323 ieee80211_sta_abort_chanswitch(sdata);
1324 return;
1325 } else if (sdata->vif.csa_active || res) {
1326 /* disregard subsequent announcements if already processing */
1327 return;
1328 }
1298 1329
1299 if (!cfg80211_chandef_usable(local->hw.wiphy, &csa_ie.chandef, 1330 if (!cfg80211_chandef_usable(local->hw.wiphy, &csa_ie.chandef,
1300 IEEE80211_CHAN_DISABLED)) { 1331 IEEE80211_CHAN_DISABLED)) {