diff options
Diffstat (limited to 'package/kernel/mac80211/patches/subsys/323-mac80211-MBSSID-support-in-interface-handling.patch')
-rw-r--r-- | package/kernel/mac80211/patches/subsys/323-mac80211-MBSSID-support-in-interface-handling.patch | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/subsys/323-mac80211-MBSSID-support-in-interface-handling.patch b/package/kernel/mac80211/patches/subsys/323-mac80211-MBSSID-support-in-interface-handling.patch new file mode 100644 index 0000000000..a135e3d1b5 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/323-mac80211-MBSSID-support-in-interface-handling.patch @@ -0,0 +1,144 @@ +From: John Crispin <john@phrozen.org> +Date: Wed, 15 Sep 2021 19:54:35 -0700 +Subject: [PATCH] mac80211: MBSSID support in interface handling + +Configure multiple BSSID and enhanced multi-BSSID advertisement (EMA) +parameters in mac80211 for AP mode. + +For each interface, 'mbssid_tx_vif' points to the transmitting interface of +the MBSSID set. The pointer is set to NULL if MBSSID is disabled. + +Function ieee80211_stop() is modified to always bring down all the +non-transmitting interfaces first and the transmitting interface last. + +Signed-off-by: John Crispin <john@phrozen.org> +Co-developed-by: Aloka Dixit <alokad@codeaurora.org> +Signed-off-by: Aloka Dixit <alokad@codeaurora.org> +Link: https://lore.kernel.org/r/20210916025437.29138-3-alokad@codeaurora.org +[slightly change logic to be more obvious] +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -1719,6 +1719,7 @@ enum ieee80211_offload_flags { + * write-protected by sdata_lock and local->mtx so holding either is fine + * for read access. + * @color_change_color: the bss color that will be used after the change. ++ * @mbssid_tx_vif: Pointer to the transmitting interface if MBSSID is enabled. + */ + struct ieee80211_vif { + enum nl80211_iftype type; +@@ -1750,6 +1751,8 @@ struct ieee80211_vif { + bool color_change_active; + u8 color_change_color; + ++ struct ieee80211_vif *mbssid_tx_vif; ++ + /* must be last */ + u8 drv_priv[] __aligned(sizeof(void *)); + }; +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -112,6 +112,36 @@ static int ieee80211_set_mon_options(str + return 0; + } + ++static int ieee80211_set_ap_mbssid_options(struct ieee80211_sub_if_data *sdata, ++ struct cfg80211_mbssid_config params) ++{ ++ struct ieee80211_sub_if_data *tx_sdata; ++ ++ sdata->vif.mbssid_tx_vif = NULL; ++ sdata->vif.bss_conf.bssid_index = 0; ++ sdata->vif.bss_conf.nontransmitted = false; ++ sdata->vif.bss_conf.ema_ap = false; ++ ++ if (sdata->vif.type != NL80211_IFTYPE_AP || !params.tx_wdev) ++ return -EINVAL; ++ ++ tx_sdata = IEEE80211_WDEV_TO_SUB_IF(params.tx_wdev); ++ if (!tx_sdata) ++ return -EINVAL; ++ ++ if (tx_sdata == sdata) { ++ sdata->vif.mbssid_tx_vif = &sdata->vif; ++ } else { ++ sdata->vif.mbssid_tx_vif = &tx_sdata->vif; ++ sdata->vif.bss_conf.nontransmitted = true; ++ sdata->vif.bss_conf.bssid_index = params.index; ++ } ++ if (params.ema) ++ sdata->vif.bss_conf.ema_ap = true; ++ ++ return 0; ++} ++ + static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy, + const char *name, + unsigned char name_assign_type, +@@ -1107,6 +1137,14 @@ static int ieee80211_start_ap(struct wip + changed |= BSS_CHANGED_HE_BSS_COLOR; + } + ++ if (sdata->vif.type == NL80211_IFTYPE_AP && ++ params->mbssid_config.tx_wdev) { ++ err = ieee80211_set_ap_mbssid_options(sdata, ++ params->mbssid_config); ++ if (err) ++ return err; ++ } ++ + mutex_lock(&local->mtx); + err = ieee80211_vif_use_channel(sdata, ¶ms->chandef, + IEEE80211_CHANCTX_SHARED); +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -632,17 +632,46 @@ static void ieee80211_do_stop(struct iee + ieee80211_add_virtual_monitor(local); + } + ++static void ieee80211_stop_mbssid(struct ieee80211_sub_if_data *sdata) ++{ ++ struct ieee80211_sub_if_data *tx_sdata, *non_tx_sdata, *tmp_sdata; ++ struct ieee80211_vif *tx_vif = sdata->vif.mbssid_tx_vif; ++ ++ if (!tx_vif) ++ return; ++ ++ tx_sdata = vif_to_sdata(tx_vif); ++ sdata->vif.mbssid_tx_vif = NULL; ++ ++ list_for_each_entry_safe(non_tx_sdata, tmp_sdata, ++ &tx_sdata->local->interfaces, list) { ++ if (non_tx_sdata != sdata && non_tx_sdata != tx_sdata && ++ non_tx_sdata->vif.mbssid_tx_vif == tx_vif && ++ ieee80211_sdata_running(non_tx_sdata)) { ++ non_tx_sdata->vif.mbssid_tx_vif = NULL; ++ dev_close(non_tx_sdata->wdev.netdev); ++ } ++ } ++ ++ if (sdata != tx_sdata && ieee80211_sdata_running(tx_sdata)) { ++ tx_sdata->vif.mbssid_tx_vif = NULL; ++ dev_close(tx_sdata->wdev.netdev); ++ } ++} ++ + static int ieee80211_stop(struct net_device *dev) + { + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + +- /* close all dependent VLAN interfaces before locking wiphy */ ++ /* close dependent VLAN and MBSSID interfaces before locking wiphy */ + if (sdata->vif.type == NL80211_IFTYPE_AP) { + struct ieee80211_sub_if_data *vlan, *tmpsdata; + + list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, + u.vlan.list) + dev_close(vlan->dev); ++ ++ ieee80211_stop_mbssid(sdata); + } + + wiphy_lock(sdata->local->hw.wiphy); |