]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: mac80211: support initialising current S1G short beacon index
authorLachlan Hodges <lachlan.hodges@morsemicro.com>
Thu, 17 Jul 2025 07:42:04 +0000 (17:42 +1000)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 18 Jul 2025 12:14:44 +0000 (14:14 +0200)
Introduce the sb_count variable which tracks the number of
beacon intervals until the next long beacon. To initialise this
value, we find the current short beacon index into this period
which represents the number of short beacons left to send before
the next long beacon. We use the same TSF value used to initialise
the DTIM count to ensure the short beacon count and DTIM count
are in sync as its common for the long beacon period and DTIM period
to be equivalent.

Signed-off-by: Lachlan Hodges <lachlan.hodges@morsemicro.com>
Link: https://patch.msgid.link/20250717074205.312577-4-lachlan.hodges@morsemicro.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/cfg.c
net/mac80211/debugfs_netdev.c
net/mac80211/ieee80211_i.h
net/mac80211/mesh.c
net/mac80211/util.c

index 2f97e2d5bb8bc17afe6b2dd20ebf7d0d466c1dc5..4f20d57ab913aa33d2d47470830f5e2f3bd11708 100644 (file)
@@ -1382,6 +1382,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
        struct ieee80211_link_data *link;
        struct ieee80211_bss_conf *link_conf;
        struct ieee80211_chan_req chanreq = { .oper = params->chandef };
+       u64 tsf;
 
        lockdep_assert_wiphy(local->hw.wiphy);
 
@@ -1603,7 +1604,12 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
                goto error;
        }
 
-       ieee80211_recalc_dtim(local, sdata);
+       tsf = drv_get_tsf(local, sdata);
+       ieee80211_recalc_dtim(sdata, tsf);
+
+       if (link->u.ap.s1g_short_beacon)
+               ieee80211_recalc_sb_count(sdata, tsf);
+
        ieee80211_vif_cfg_change_notify(sdata, BSS_CHANGED_SSID);
        ieee80211_link_info_change_notify(sdata, link, changed);
 
index 54c479910d054be014affaea27197003d6cf01c0..1dac78271045a9f9f6201e791d3471f2f8df83d1 100644 (file)
@@ -704,7 +704,7 @@ static ssize_t ieee80211_if_parse_tsf(
                }
        }
 
-       ieee80211_recalc_dtim(local, sdata);
+       ieee80211_recalc_dtim(sdata, drv_get_tsf(local, sdata));
        return buflen;
 }
 IEEE80211_IF_FILE_RW(tsf);
index 61cd1cc098ac1041550e984f198d9c3b8307570f..8afa2404eaa8e3383c0021fd95861024af44e18e 100644 (file)
@@ -314,6 +314,7 @@ struct ps_data {
        atomic_t num_sta_ps; /* number of stations in PS mode */
        int dtim_count;
        bool dtim_bc_mc;
+       int sb_count; /* num short beacons til next long beacon */
 };
 
 struct ieee80211_if_ap {
@@ -2774,9 +2775,8 @@ void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy,
                                       struct wiphy_work *work);
 int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
                              struct cfg80211_csa_settings *csa_settings);
-
-void ieee80211_recalc_dtim(struct ieee80211_local *local,
-                          struct ieee80211_sub_if_data *sdata);
+void ieee80211_recalc_sb_count(struct ieee80211_sub_if_data *sdata, u64 tsf);
+void ieee80211_recalc_dtim(struct ieee80211_sub_if_data *sdata, u64 tsf);
 int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
                                 const struct cfg80211_chan_def *chandef,
                                 enum ieee80211_chanctx_mode chanmode,
index d00d9d413c5cff9b04cd7b3340a8b438b8edb89e..a4a715f6f1c32fd49f47e1b2da0d61b6b5abe294 100644 (file)
@@ -1202,7 +1202,7 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
                return -ENOMEM;
        }
 
-       ieee80211_recalc_dtim(local, sdata);
+       ieee80211_recalc_dtim(sdata, drv_get_tsf(local, sdata));
        ieee80211_link_info_change_notify(sdata, &sdata->deflink, changed);
 
        netif_carrier_on(sdata->dev);
index 0d85a382746faf0c75a19e3221bedd8e1221460c..32f1bc5908c571416df905bdda1ba54dd7b41f33 100644 (file)
@@ -3913,10 +3913,8 @@ int ieee80211_parse_p2p_noa(const struct ieee80211_p2p_noa_attr *attr,
 }
 EXPORT_SYMBOL(ieee80211_parse_p2p_noa);
 
-void ieee80211_recalc_dtim(struct ieee80211_local *local,
-                          struct ieee80211_sub_if_data *sdata)
+void ieee80211_recalc_dtim(struct ieee80211_sub_if_data *sdata, u64 tsf)
 {
-       u64 tsf = drv_get_tsf(local, sdata);
        u64 dtim_count = 0;
        u32 beacon_int = sdata->vif.bss_conf.beacon_int * 1024;
        u8 dtim_period = sdata->vif.bss_conf.dtim_period;
@@ -3954,6 +3952,33 @@ void ieee80211_recalc_dtim(struct ieee80211_local *local,
        ps->dtim_count = dtim_count;
 }
 
+/*
+ * Given a long beacon period, calculate the current index into
+ * that period to determine the number of TSBTTs until the next TBTT.
+ * It is completely valid to have a short beacon period that differs
+ * from the dtim period (i.e a TBTT thats not a DTIM).
+ */
+void ieee80211_recalc_sb_count(struct ieee80211_sub_if_data *sdata, u64 tsf)
+{
+       u32 sb_idx;
+       struct ps_data *ps = &sdata->bss->ps;
+       u8 lb_period = sdata->vif.bss_conf.s1g_long_beacon_period;
+       u32 beacon_int = sdata->vif.bss_conf.beacon_int * 1024;
+
+       /* No mesh / IBSS support for short beaconing */
+       if (tsf == -1ULL || !lb_period ||
+           (sdata->vif.type != NL80211_IFTYPE_AP &&
+            sdata->vif.type != NL80211_IFTYPE_AP_VLAN))
+               return;
+
+       /* find the current TSBTT index in our lb_period */
+       do_div(tsf, beacon_int);
+       sb_idx = do_div(tsf, lb_period);
+
+       /* num TSBTTs until the next TBTT */
+       ps->sb_count = sb_idx ? lb_period - sb_idx : 0;
+}
+
 static u8 ieee80211_chanctx_radar_detect(struct ieee80211_local *local,
                                         struct ieee80211_chanctx *ctx)
 {