From f8e7ec408c357d6438abd980f700353a7efcac7e Mon Sep 17 00:00:00 2001 From: Maharaja Kennadyrajan Date: Tue, 12 Jan 2021 18:11:33 +0530 Subject: [PATCH] mac80211: Add support for beacon tx mode User can configure the beacon tx mode while bring-up the AP via hostapd configuration. Use the below configuration in the hostapd to configure the beacon tx mode. "beacon_tx_mode=N", where N = 0 for STAGGERED beacon mode and N = 1 for BURST beacon mode. Signed-off-by: Maharaja Kennadyrajan --- include/net/cfg80211.h | 2 +- include/net/mac80211.h | 1 + include/uapi/linux/nl80211.h | 2 ++ net/mac80211/cfg.c | 1 + net/wireless/nl80211.c | 7 ++++++- 5 files changed, 11 insertions(+), 2 deletions(-) --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1233,6 +1233,7 @@ enum cfg80211_ap_settings_flags { * @he_bss_color: BSS Color settings * @he_oper: HE operation IE (or %NULL if HE isn't enabled) * @multiple_bssid: AP settings for multiple bssid + * @beacon_tx_mode: Beacon Tx Mode setting */ struct cfg80211_ap_settings { struct cfg80211_chan_def chandef; @@ -1264,6 +1265,7 @@ struct cfg80211_ap_settings { struct ieee80211_he_obss_pd he_obss_pd; struct cfg80211_he_bss_color he_bss_color; struct ieee80211_multiple_bssid multiple_bssid; + enum nl80211_beacon_tx_mode beacon_tx_mode; }; /** @@ -2132,6 +2134,7 @@ struct mesh_config { * to operate on DFS channels. * @control_port_over_nl80211: TRUE if userspace expects to exchange control * port frames over NL80211 instead of the network interface. + * @beacon_tx_mode: Beacon Tx Mode setting. * * These parameters are fixed when the mesh is created. */ @@ -2155,6 +2158,7 @@ struct mesh_setup { struct cfg80211_bitrate_mask beacon_rate; bool userspace_handles_dfs; bool control_port_over_nl80211; + enum nl80211_beacon_tx_mode beacon_tx_mode; }; /** --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -647,6 +647,7 @@ struct ieee80211_fils_discovery { * to driver when rate control is offloaded to firmware. * @nss_ap_isolate: Used for notifying the NSS host about AP isolate feature * @multiple_bssid: the multiple bssid settings of the AP. + * @beacon_tx_mode: Beacon Tx Mode setting. */ struct ieee80211_bss_conf { const u8 *bssid; @@ -719,6 +720,7 @@ struct ieee80211_bss_conf { struct cfg80211_bitrate_mask beacon_tx_rate; bool nss_ap_isolate; struct ieee80211_multiple_bssid multiple_bssid; + enum nl80211_beacon_tx_mode beacon_tx_mode; }; /** --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -2636,7 +2636,9 @@ enum nl80211_commands { * The last additional RNR group, if present, points to information * for co-located APs and neighbor APs in ESS to be added in all * EMA beacons. - * + * @NL80211_ATTR_BEACON_TX_MODE: used to configure the beacon tx mode as + * staggered mode = 1 or burst mode = 2 in %NL80211_CMD_START_AP or + * %NL80211_CMD_JOIN_MESH from user-space. * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -3150,6 +3152,8 @@ enum nl80211_attrs { NL80211_ATTR_RNR_OFFSETS, + NL80211_ATTR_BEACON_TX_MODE, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -7412,4 +7416,12 @@ enum nl80211_sar_specs_attrs { NL80211_SAR_ATTR_SPECS_MAX = __NL80211_SAR_ATTR_SPECS_LAST - 1, }; +/** + * enum nl80211_beacon_tx_mode - Beacon Tx Mode enum. + * Used to configure beacon staggered mode or beacon burst mode. + */ +enum nl80211_beacon_tx_mode { + NL80211_BEACON_STAGGERED_MODE = 1, + NL80211_BEACON_BURST_MODE = 2, +}; #endif /* __LINUX_NL80211_H */ --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1228,6 +1228,7 @@ static int ieee80211_start_ap(struct wip prev_beacon_int = sdata->vif.bss_conf.beacon_int; sdata->vif.bss_conf.beacon_int = params->beacon_interval; + sdata->vif.bss_conf.beacon_tx_mode = params->beacon_tx_mode; if (params->he_cap && params->he_oper) { sdata->vif.bss_conf.he_support = true; @@ -2256,6 +2257,7 @@ static int copy_mesh_setup(struct ieee80 sdata->vif.bss_conf.beacon_int = setup->beacon_interval; sdata->vif.bss_conf.dtim_period = setup->dtim_period; + sdata->vif.bss_conf.beacon_tx_mode = setup->beacon_tx_mode; sdata->beacon_rate_set = false; if (wiphy_ext_feature_isset(sdata->local->hw.wiphy, --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -794,6 +794,8 @@ static const struct nla_policy nl80211_p [NL80211_ATTR_COLOR_CHANGE_ANNOUNCEMENT_COLOR] = { .type = NLA_U8 }, [NL80211_ATTR_COLOR_CHANGE_ANNOUNCEMENT_IES] = NLA_POLICY_NESTED(nl80211_policy), [NL80211_ATTR_RNR_OFFSETS] = NLA_POLICY_NESTED(nl80211_rnr_ies_policy), + [NL80211_ATTR_BEACON_TX_MODE] = NLA_POLICY_RANGE(NLA_U32, 1, 2), + }; /* policy for the key attributes */ @@ -5437,6 +5439,9 @@ static int nl80211_start_ap(struct sk_bu nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]); params.dtim_period = nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]); + if (info->attrs[NL80211_ATTR_BEACON_TX_MODE]) + params.beacon_tx_mode = + nla_get_u32(info->attrs[NL80211_ATTR_BEACON_TX_MODE]); err = cfg80211_validate_beacon_int(rdev, dev->ieee80211_ptr->iftype, params.beacon_interval); @@ -12024,6 +12029,10 @@ static int nl80211_join_mesh(struct sk_b return -EINVAL; } + if (info->attrs[NL80211_ATTR_BEACON_TX_MODE]) + setup.beacon_tx_mode = + nla_get_u32(info->attrs[NL80211_ATTR_BEACON_TX_MODE]); + if (info->attrs[NL80211_ATTR_MESH_SETUP]) { /* parse additional setup parameters if given */ err = nl80211_parse_mesh_setup(info, &setup);