|
5 | 5 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
6 | 6 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
|
7 | 7 | * Copyright 2013-2014 Intel Mobile Communications GmbH
|
8 |
| - * Copyright (C) 2018-2024 Intel Corporation |
| 8 | + * Copyright (C) 2018-2025 Intel Corporation |
9 | 9 | *
|
10 | 10 | * Transmit and frame generation functions.
|
11 | 11 | */
|
@@ -5016,12 +5016,25 @@ static void ieee80211_set_beacon_cntdwn(struct ieee80211_sub_if_data *sdata,
|
5016 | 5016 | }
|
5017 | 5017 | }
|
5018 | 5018 |
|
5019 |
| -static u8 __ieee80211_beacon_update_cntdwn(struct beacon_data *beacon) |
| 5019 | +static u8 __ieee80211_beacon_update_cntdwn(struct ieee80211_link_data *link, |
| 5020 | + struct beacon_data *beacon) |
5020 | 5021 | {
|
5021 |
| - beacon->cntdwn_current_counter--; |
| 5022 | + if (beacon->cntdwn_current_counter == 1) { |
| 5023 | + /* |
| 5024 | + * Channel switch handling is done by a worker thread while |
| 5025 | + * beacons get pulled from hardware timers. It's therefore |
| 5026 | + * possible that software threads are slow enough to not be |
| 5027 | + * able to complete CSA handling in a single beacon interval, |
| 5028 | + * in which case we get here. There isn't much to do about |
| 5029 | + * it, other than letting the user know that the AP isn't |
| 5030 | + * behaving correctly. |
| 5031 | + */ |
| 5032 | + link_err_once(link, |
| 5033 | + "beacon TX faster than countdown (channel/color switch) completion\n"); |
| 5034 | + return 0; |
| 5035 | + } |
5022 | 5036 |
|
5023 |
| - /* the counter should never reach 0 */ |
5024 |
| - WARN_ON_ONCE(!beacon->cntdwn_current_counter); |
| 5037 | + beacon->cntdwn_current_counter--; |
5025 | 5038 |
|
5026 | 5039 | return beacon->cntdwn_current_counter;
|
5027 | 5040 | }
|
@@ -5052,7 +5065,7 @@ u8 ieee80211_beacon_update_cntdwn(struct ieee80211_vif *vif, unsigned int link_i
|
5052 | 5065 | if (!beacon)
|
5053 | 5066 | goto unlock;
|
5054 | 5067 |
|
5055 |
| - count = __ieee80211_beacon_update_cntdwn(beacon); |
| 5068 | + count = __ieee80211_beacon_update_cntdwn(link, beacon); |
5056 | 5069 |
|
5057 | 5070 | unlock:
|
5058 | 5071 | rcu_read_unlock();
|
@@ -5450,7 +5463,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
|
5450 | 5463 |
|
5451 | 5464 | if (beacon->cntdwn_counter_offsets[0]) {
|
5452 | 5465 | if (!is_template)
|
5453 |
| - __ieee80211_beacon_update_cntdwn(beacon); |
| 5466 | + __ieee80211_beacon_update_cntdwn(link, beacon); |
5454 | 5467 |
|
5455 | 5468 | ieee80211_set_beacon_cntdwn(sdata, beacon, link);
|
5456 | 5469 | }
|
@@ -5482,7 +5495,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
|
5482 | 5495 | * for now we leave it consistent with overall
|
5483 | 5496 | * mac80211's behavior.
|
5484 | 5497 | */
|
5485 |
| - __ieee80211_beacon_update_cntdwn(beacon); |
| 5498 | + __ieee80211_beacon_update_cntdwn(link, beacon); |
5486 | 5499 |
|
5487 | 5500 | ieee80211_set_beacon_cntdwn(sdata, beacon, link);
|
5488 | 5501 | }
|
|
0 commit comments