aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r--net/mac80211/tx.c58
1 files changed, 36 insertions, 22 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 263dea5a5cbb..0d1a42d4b6de 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2417,10 +2417,9 @@ static void ieee80211_update_csa(struct ieee80211_sub_if_data *sdata,
2417 struct beacon_data *beacon) 2417 struct beacon_data *beacon)
2418{ 2418{
2419 struct probe_resp *resp; 2419 struct probe_resp *resp;
2420 int counter_offset_beacon = sdata->csa_counter_offset_beacon;
2421 int counter_offset_presp = sdata->csa_counter_offset_presp;
2422 u8 *beacon_data; 2420 u8 *beacon_data;
2423 size_t beacon_data_len; 2421 size_t beacon_data_len;
2422 int i;
2424 2423
2425 switch (sdata->vif.type) { 2424 switch (sdata->vif.type) {
2426 case NL80211_IFTYPE_AP: 2425 case NL80211_IFTYPE_AP:
@@ -2438,32 +2437,47 @@ static void ieee80211_update_csa(struct ieee80211_sub_if_data *sdata,
2438 default: 2437 default:
2439 return; 2438 return;
2440 } 2439 }
2441 if (WARN_ON(counter_offset_beacon >= beacon_data_len))
2442 return;
2443 2440
2444 /* Warn if the driver did not check for/react to csa 2441 for (i = 0; i < IEEE80211_MAX_CSA_COUNTERS_NUM; ++i) {
2445 * completeness. A beacon with CSA counter set to 0 should 2442 u16 counter_offset_beacon =
2446 * never occur, because a counter of 1 means switch just 2443 sdata->csa_counter_offset_beacon[i];
2447 * before the next beacon. 2444 u16 counter_offset_presp = sdata->csa_counter_offset_presp[i];
2448 */
2449 if (WARN_ON(beacon_data[counter_offset_beacon] == 1))
2450 return;
2451 2445
2452 sdata->csa_current_counter--; 2446 if (counter_offset_beacon) {
2453 beacon_data[counter_offset_beacon] = sdata->csa_current_counter; 2447 if (WARN_ON(counter_offset_beacon >= beacon_data_len))
2448 return;
2454 2449
2455 if (sdata->vif.type == NL80211_IFTYPE_AP && counter_offset_presp) { 2450 /* Warn if the driver did not check for/react to csa
2456 rcu_read_lock(); 2451 * completeness. A beacon with CSA counter set to 0
2457 resp = rcu_dereference(sdata->u.ap.probe_resp); 2452 * should never occur, because a counter of 1 means
2453 * switch just before the next beacon.
2454 */
2455 if (WARN_ON(beacon_data[counter_offset_beacon] == 1))
2456 return;
2458 2457
2459 /* if nl80211 accepted the offset, this should not happen. */ 2458 beacon_data[counter_offset_beacon] =
2460 if (WARN_ON(!resp)) { 2459 sdata->csa_current_counter - 1;
2460 }
2461
2462 if (sdata->vif.type == NL80211_IFTYPE_AP &&
2463 counter_offset_presp) {
2464 rcu_read_lock();
2465 resp = rcu_dereference(sdata->u.ap.probe_resp);
2466
2467 /* If nl80211 accepted the offset, this should
2468 * not happen.
2469 */
2470 if (WARN_ON(!resp)) {
2471 rcu_read_unlock();
2472 return;
2473 }
2474 resp->data[counter_offset_presp] =
2475 sdata->csa_current_counter - 1;
2461 rcu_read_unlock(); 2476 rcu_read_unlock();
2462 return;
2463 } 2477 }
2464 resp->data[counter_offset_presp] = sdata->csa_current_counter;
2465 rcu_read_unlock();
2466 } 2478 }
2479
2480 sdata->csa_current_counter--;
2467} 2481}
2468 2482
2469bool ieee80211_csa_is_complete(struct ieee80211_vif *vif) 2483bool ieee80211_csa_is_complete(struct ieee80211_vif *vif)
@@ -2472,7 +2486,7 @@ bool ieee80211_csa_is_complete(struct ieee80211_vif *vif)
2472 struct beacon_data *beacon = NULL; 2486 struct beacon_data *beacon = NULL;
2473 u8 *beacon_data; 2487 u8 *beacon_data;
2474 size_t beacon_data_len; 2488 size_t beacon_data_len;
2475 int counter_beacon = sdata->csa_counter_offset_beacon; 2489 int counter_beacon = sdata->csa_counter_offset_beacon[0];
2476 int ret = false; 2490 int ret = false;
2477 2491
2478 if (!ieee80211_sdata_running(sdata)) 2492 if (!ieee80211_sdata_running(sdata))