diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 17b6eb426356..9af283b1c3b5 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1739,6 +1739,8 @@ struct ieee80211_vif_cfg { * @cfg: vif configuration, see &struct ieee80211_vif_cfg * @bss_conf: BSS configuration for this interface, either our own * or the BSS we're associated to + * @link_conf: in case of MLD, the per-link BSS configuration, + * indexed by link ID * @addr: address of this interface * @p2p: indicates whether this AP or STA interface is a p2p * interface, i.e. a GO or p2p-sta respectively @@ -1773,6 +1775,7 @@ struct ieee80211_vif { enum nl80211_iftype type; struct ieee80211_vif_cfg cfg; struct ieee80211_bss_conf bss_conf; + struct ieee80211_bss_conf *link_conf[IEEE80211_MLD_MAX_NUM_LINKS]; u8 addr[ETH_ALEN] __aligned(2); bool p2p; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 20153957cdee..397b111f006d 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1031,6 +1031,7 @@ struct ieee80211_sub_if_data { } u; struct ieee80211_link_data deflink; + struct ieee80211_link_data *link[IEEE80211_MLD_MAX_NUM_LINKS]; #ifdef CONFIG_MAC80211_DEBUGFS struct { diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 978dfa48e098..04ee525394e9 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1012,6 +1012,23 @@ static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata) sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE; } +static void ieee80211_sdata_init(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata) +{ + sdata->local = local; + + /* + * Initialize the default link, so we can use link_id 0 for non-MLD, + * and that continues to work for non-MLD-aware drivers that use just + * vif.bss_conf instead of vif.link_conf. + * + * Note that we never change this, so if link ID 0 isn't used in an + * MLD connection, we get a separate allocation for it. + */ + sdata->vif.link_conf[0] = &sdata->vif.bss_conf; + sdata->link[0] = &sdata->deflink; +} + int ieee80211_add_virtual_monitor(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata; @@ -1031,12 +1048,13 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local) return -ENOMEM; /* set up data */ - sdata->local = local; sdata->vif.type = NL80211_IFTYPE_MONITOR; snprintf(sdata->name, IFNAMSIZ, "%s-monitor", wiphy_name(local->hw.wiphy)); sdata->wdev.iftype = NL80211_IFTYPE_MONITOR; + ieee80211_sdata_init(local, sdata); + ieee80211_set_default_queues(sdata); ret = drv_add_interface(local, sdata); @@ -2074,7 +2092,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, /* initialise type-independent data */ sdata->wdev.wiphy = local->hw.wiphy; - sdata->local = local; + + ieee80211_sdata_init(local, sdata); ieee80211_init_frag_cache(&sdata->frags);