hostapd puts NL80211_ATTR_HE_OBSS_PD into NL80211_CMD_SET_BEACON as well as NL80211_CMD_START_AP, but cfg80211 parses it only when the AP starts. A change of the spatial reuse parameters therefore reaches the beacon but not the driver, and the only way to apply it is to restart the AP, which disconnects all stations. Parse the attribute in the AP update path and apply it in ieee80211_change_beacon() when it differs from the current settings. Assisted-by: LLM Signed-off-by: John Macias --- Tested on OpenWrt (backports 7.2) with hostapd changing he_spr_sr_control and he_spr_non_srg_obss_pd_max_offset at runtime (SET + UPDATE_BEACON): - ath11k (IPQ8074): without the patch the driver is never called; with it, ath11k reprograms the OBSS PD threshold on every change. - ath12k (IPQ5332 + QCN6432, and QCN9274): toggling non-SRG OBSS PD at runtime turns the firmware's spatial reuse on and off (htt_stats OBSS_PD_STATS: 0 -> 74 -> 0 non-SRG opportunities in 15 s runs). include/net/cfg80211.h | 3 +++ net/mac80211/cfg.c | 7 +++++++ net/wireless/nl80211.c | 7 +++++++ 3 files changed, 17 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index f773856c1..e373fb32d 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1668,12 +1668,15 @@ struct cfg80211_ap_settings { * @fils_discovery: FILS discovery transmission parameters * @unsol_bcast_probe_resp: Unsolicited broadcast probe response parameters * @s1g_short_beacon: S1G short beacon data + * @he_obss_pd: OBSS Packet Detection settings, applied if @he_obss_pd.enable + * is set */ struct cfg80211_ap_update { struct cfg80211_beacon_data beacon; struct cfg80211_fils_discovery fils_discovery; struct cfg80211_unsol_bcast_probe_resp unsol_bcast_probe_resp; struct cfg80211_s1g_short_beacon s1g_short_beacon; + struct ieee80211_he_obss_pd he_obss_pd; }; /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 9608c07bc..619052ebd 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2118,6 +2118,13 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev, changed |= BSS_CHANGED_HE_BSS_COLOR; } + if (params->he_obss_pd.enable && link_conf->he_support && + memcmp(¶ms->he_obss_pd, &link_conf->he_obss_pd, + sizeof(params->he_obss_pd))) { + link_conf->he_obss_pd = params->he_obss_pd; + changed |= BSS_CHANGED_HE_OBSS_PD; + } + ieee80211_link_info_change_notify(sdata, link, changed); return 0; } diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d790e204a..38a707aca 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -7708,6 +7708,13 @@ static int nl80211_parse_ap_update(struct cfg80211_registered_device *rdev, return err; } + attr = attrs[NL80211_ATTR_HE_OBSS_PD]; + if (attr) { + err = nl80211_parse_he_obss_pd(attr, ¶ms->he_obss_pd); + if (err) + return err; + } + return 0; } -- 2.47.3