Skip to content

Commit

Permalink
wifi: mac80211: fix advertised TTLM scheduling
Browse files Browse the repository at this point in the history
Handle a case of time overflow, where the switch time might
be smaller than the partial TSF in the beacon.
Additionally, apply advertised TTLM earlier in order to be
ready on time on the newly activated links.

Fixes: 702e804 ("wifi: mac80211: support handling of advertised TID-to-link mapping")
Signed-off-by: Ayala Beker <[email protected]>
Reviewed-by: Johannes Berg <[email protected]>
Signed-off-by: Miri Korenblit <[email protected]>
Link: https://msgid.link/20231220133549.15079c34e5c8.I0dd50bcceff5953080cdd7aee5118b72c78c6507@changeid
Signed-off-by: Johannes Berg <[email protected]>
  • Loading branch information
AyalaBkr authored and jmberg-intel committed Dec 21, 2023
1 parent acc44cb commit b1a23f8
Showing 1 changed file with 40 additions and 9 deletions.
49 changes: 40 additions & 9 deletions net/mac80211/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -5964,6 +5967,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) {
Expand Down Expand Up @@ -6058,25 +6068,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.
*/
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
*/
st_us = ieee80211_tu_to_usec(ttlm_info.switch_time);
if (st_us > ts_l26)
delay = st_us - ts_l26;
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;
}
}
Expand Down

0 comments on commit b1a23f8

Please sign in to comment.