diff options
author | David S. Miller <davem@davemloft.net> | 2024-01-02 12:46:10 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2024-01-02 12:46:10 +0000 |
commit | a27359abc820c619c67e91241e75d045decbfdc2 (patch) | |
tree | a82f9249942b066d243e5f3ce62d7d6066013ff5 /net/mac80211/mlme.c | |
parent | 8146c3f9e69543c9b5a0d72b4fe3509655363ed9 (diff) | |
parent | 968509128207f122d7177ffb6ff51c9c6fa7e13d (diff) |
Merge tag 'wireless-next-2023-12-22' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next
Kalle Valo says:
====================
wireless-next patches for v6.8
The third "new features" pull request for v6.8. This is a smaller one
to clear up our tree before the break and nothing really noteworthy
this time.
Major changes:
stack
* cfg80211: introduce cfg80211_ssid_eq() for SSID matching
* cfg80211: support P2P operation on DFS channels
* mac80211: allow 64-bit radiotap timestamps
iwlwifi
* AX210: allow concurrent P2P operation on DFS channels
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 61 |
1 files changed, 52 insertions, 9 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 40a4fbfff530..967282baf0e2 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -43,6 +43,9 @@ #define IEEE80211_ASSOC_TIMEOUT_SHORT (HZ / 10) #define IEEE80211_ASSOC_MAX_TRIES 3 +#define IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS msecs_to_jiffies(100) +#define IEEE80211_ADV_TTLM_ST_UNDERFLOW 0xff00 + static int max_nullfunc_tries = 2; module_param(max_nullfunc_tries, int, 0644); MODULE_PARM_DESC(max_nullfunc_tries, @@ -598,6 +601,7 @@ static int ieee80211_config_bw(struct ieee80211_link_data *link, return ret; } + cfg80211_schedule_channels_check(&sdata->wdev); return 0; } @@ -5381,6 +5385,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, assoc_data->ap_addr, tu, ms); assoc_data->timeout = jiffies + msecs_to_jiffies(ms); assoc_data->timeout_started = true; + assoc_data->comeback = true; if (ms > IEEE80211_ASSOC_TIMEOUT) run_again(sdata, assoc_data->timeout); goto notify_driver; @@ -5964,6 +5969,13 @@ ieee80211_parse_adv_t2l(struct ieee80211_sub_if_data *sdata, pos++; ttlm_info->switch_time = get_unaligned_le16(pos); + + /* Since ttlm_info->switch_time == 0 means no switch time, bump it + * by 1. + */ + if (!ttlm_info->switch_time) + ttlm_info->switch_time = 1; + pos += 2; if (control & IEEE80211_TTLM_CONTROL_EXPECTED_DUR_PRESENT) { @@ -6058,25 +6070,46 @@ static void ieee80211_process_adv_ttlm(struct ieee80211_sub_if_data *sdata, } if (ttlm_info.switch_time) { - u32 st_us, delay = 0; - u32 ts_l26 = beacon_ts & GENMASK(25, 0); + u16 beacon_ts_tu, st_tu, delay; + u32 delay_jiffies; + u64 mask; /* The t2l map switch time is indicated with a partial - * TSF value, convert it to TSF and calc the delay - * to the start time. + * TSF value (bits 10 to 25), get the partial beacon TS + * as well, and calc the delay to the start time. + */ + mask = GENMASK_ULL(25, 10); + beacon_ts_tu = (beacon_ts & mask) >> 10; + st_tu = ttlm_info.switch_time; + delay = st_tu - beacon_ts_tu; + + /* + * If the switch time is far in the future, then it + * could also be the previous switch still being + * announced. + * We can simply ignore it for now, if it is a future + * switch the AP will continue to announce it anyway. */ - st_us = ieee80211_tu_to_usec(ttlm_info.switch_time); - if (st_us > ts_l26) - delay = st_us - ts_l26; + if (delay > IEEE80211_ADV_TTLM_ST_UNDERFLOW) + return; + + delay_jiffies = TU_TO_JIFFIES(delay); + + /* Link switching can take time, so schedule it + * 100ms before to be ready on time + */ + if (delay_jiffies > IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS) + delay_jiffies -= + IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS; else - continue; + delay_jiffies = 0; sdata->u.mgd.ttlm_info = ttlm_info; wiphy_delayed_work_cancel(sdata->local->hw.wiphy, &sdata->u.mgd.ttlm_work); wiphy_delayed_work_queue(sdata->local->hw.wiphy, &sdata->u.mgd.ttlm_work, - usecs_to_jiffies(delay)); + delay_jiffies); return; } } @@ -6720,8 +6753,18 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) } ifmgd->auth_data->timeout_started = true; } else if (ifmgd->assoc_data && + !ifmgd->assoc_data->comeback && (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))) { + /* + * Update association timeout based on the TX status + * for the (Re)Association Request frame. Skip this if + * we have already processed a (Re)Association Response + * frame that indicated need for association comeback + * at a specific time in the future. This could happen + * if the TX status information is delayed enough for + * the response to be received and processed first. + */ if (status_acked) { ifmgd->assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT_SHORT; |