blob: 9600fe8a4d078326007ddef686421ce46b7590ca [file] [log] [blame]
From 5b96ef6f679b62a82fec6ca5ea1be7591c75a98b Mon Sep 17 00:00:00 2001
From: Shayne Chen <shayne.chen@mediatek.com>
Date: Thu, 23 Nov 2023 18:22:11 +0800
Subject: [PATCH 105/120] wifi: mt76: mt7996: support multi-link vif links and
MLO bss callbacks
Rework add/remove interface functions to add/remove bss_conf functions,
and also switch to callbacks for MLO bss.
This is a preliminary patch to add MLO support for mt7996 chipsets.
Co-developed-by: Bo Jiao <Bo.Jiao@mediatek.com>
Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
---
mt7996/main.c | 298 +++++++++++++++++++++++++++++++++++++++---------
mt7996/mcu.c | 29 +++--
mt7996/mt7996.h | 9 ++
3 files changed, 270 insertions(+), 66 deletions(-)
diff --git a/mt7996/main.c b/mt7996/main.c
index 798beebb5..0ad3e3a6f 100644
--- a/mt7996/main.c
+++ b/mt7996/main.c
@@ -204,6 +204,38 @@ static int get_omac_idx(enum nl80211_iftype type, u64 mask)
return -1;
}
+static int get_own_mld_idx(u64 mask, bool group_mld)
+{
+ u8 start, end;
+ int i;
+
+ if (group_mld) {
+ start = 0;
+ end = 15;
+ } else {
+ start = 16;
+ end = 63;
+ }
+
+ i = get_free_idx(mask, start, end);
+ if (i)
+ return i - 1;
+
+ return -1;
+}
+
+static int get_mld_remap_idx(u64 mask)
+{
+ u8 start = 0, end = 15;
+ int i;
+
+ i = get_free_idx(mask, start, end);
+ if (i)
+ return i - 1;
+
+ return -1;
+}
+
static void mt7996_init_bitrate_mask(struct mt7996_bss_conf *mconf)
{
int i;
@@ -222,48 +254,108 @@ static void mt7996_init_bitrate_mask(struct mt7996_bss_conf *mconf)
}
}
-static int mt7996_add_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+static void mt7996_remove_bss_conf(struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *conf,
+ struct mt7996_bss_conf *mconf)
{
- struct ieee80211_bss_conf *conf = &vif->bss_conf;
+ struct mt7996_phy *phy = mconf->phy;
+ struct mt7996_dev *dev = phy->dev;
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
- struct mt7996_bss_conf *mconf = &mvif->deflink;
- struct mt7996_link_sta *mlink = &mvif->sta.deflink;
- struct mt7996_dev *dev = mt7996_hw_dev(hw);
- struct mt7996_phy *phy = mt7996_hw_phy(hw);
+ u8 link_id = conf->link_id;
+ struct mt7996_link_sta *mlink =
+ mlink_dereference_protected(&mvif->sta, link_id);
+
+ if (!mlink)
+ return;
+
+ mt7996_mcu_add_sta(dev, conf, mconf, NULL, mlink, false, false);
+ mt7996_mcu_add_bss_info(phy, conf, mconf, mlink, false);
+ mt7996_mcu_add_dev_info(phy, conf, mconf, false);
+
+ rcu_assign_pointer(dev->mt76.wcid[mlink->wcid.idx], NULL);
+ rcu_assign_pointer(mvif->link[link_id], NULL);
+ rcu_assign_pointer(mvif->sta.link[link_id], NULL);
+
+ dev->mt76.vif_mask &= ~BIT_ULL(mconf->mt76.idx);
+ dev->mld_id_mask &= ~BIT_ULL(mconf->own_mld_id);
+ phy->omac_mask &= ~BIT_ULL(mconf->mt76.omac_idx);
+
+ spin_lock_bh(&dev->mt76.sta_poll_lock);
+ if (!list_empty(&mlink->wcid.poll_list))
+ list_del_init(&mlink->wcid.poll_list);
+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
+
+ mt76_wcid_cleanup(&dev->mt76, &mlink->wcid);
+
+ if (mlink != &mvif->sta.deflink)
+ kfree(mlink);
+
+ if (mconf != &mvif->deflink)
+ kfree(mconf);
+}
+
+static int mt7996_add_bss_conf(struct mt7996_phy *phy,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *conf)
+{
+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+ struct mt7996_dev *dev = phy->dev;
+ struct mt7996_bss_conf *mconf;
+ struct mt7996_link_sta *mlink;
struct mt76_txq *mtxq;
u8 band_idx = phy->mt76->band_idx;
- int idx, ret = 0;
-
- mutex_lock(&dev->mt76.mutex);
+ u8 link_id = conf->link_id;
+ int idx, ret;
- if (vif->type == NL80211_IFTYPE_MONITOR &&
- is_zero_ether_addr(vif->addr))
- phy->monitor_vif = vif;
+ if (conf != &vif->bss_conf) {
+ mconf = kzalloc(sizeof(*mconf), GFP_KERNEL);
+ if (!mconf)
+ return -ENOMEM;
+ } else {
+ mconf = &mvif->deflink;
+ }
mconf->mt76.idx = __ffs64(~dev->mt76.vif_mask);
if (mconf->mt76.idx >= mt7996_max_interface_num(dev)) {
ret = -ENOSPC;
- goto out;
+ goto error;
}
idx = get_omac_idx(vif->type, phy->omac_mask);
if (idx < 0) {
ret = -ENOSPC;
- goto out;
+ goto error;
+ }
+
+ mconf->own_mld_id = get_own_mld_idx(dev->mld_id_mask, false);
+ if (mconf->own_mld_id < 0) {
+ ret = -ENOSPC;
+ goto error;
}
+
mconf->mt76.omac_idx = idx;
mconf->vif = mvif;
mconf->phy = phy;
mconf->mt76.band_idx = band_idx;
mconf->mt76.wmm_idx = vif->type != NL80211_IFTYPE_AP;
- mvif->dev = dev;
+ mconf->link_id = link_id;
ret = mt7996_mcu_add_dev_info(phy, conf, mconf, true);
if (ret)
- goto out;
+ goto error;
+
+ if (ieee80211_vif_is_mld(vif)) {
+ mlink = kzalloc(sizeof(*mlink), GFP_KERNEL);
+ if (!mlink) {
+ ret = -ENOMEM;
+ goto error;
+ }
+ } else {
+ mlink = &mvif->sta.deflink;
+ }
dev->mt76.vif_mask |= BIT_ULL(mconf->mt76.idx);
+ dev->mld_id_mask |= BIT_ULL(mconf->own_mld_id);
phy->omac_mask |= BIT_ULL(mconf->mt76.omac_idx);
idx = MT7996_WTBL_RESERVED - mconf->mt76.idx;
@@ -274,6 +366,9 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
mlink->wcid.phy_idx = band_idx;
mlink->wcid.hw_key_idx = -1;
mlink->wcid.tx_info |= MT_WCID_TX_INFO_SET;
+ mlink->wcid.def_wcid = &mvif->sta.deflink.wcid;
+ mlink->wcid.link_id = link_id;
+ mlink->wcid.link_valid = ieee80211_vif_is_mld(vif);
mlink->sta = &mvif->sta;
mlink->sta->vif = mvif;
mt76_wcid_init(&mlink->wcid);
@@ -295,7 +390,6 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
mconf->mt76.basic_rates_idx = MT7996_BASIC_RATES_TBL + 4;
else
mconf->mt76.basic_rates_idx = MT7996_BASIC_RATES_TBL;
-
mt7996_init_bitrate_mask(mconf);
mt7996_mcu_add_bss_info(phy, conf, mconf, mlink, true);
@@ -305,10 +399,32 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
if (vif->type != NL80211_IFTYPE_STATION)
mt7996_mcu_add_sta(dev, conf, mconf, NULL, mlink, true, true);
rcu_assign_pointer(dev->mt76.wcid[idx], &mlink->wcid);
- rcu_assign_pointer(mvif->link[0], mconf);
- rcu_assign_pointer(mvif->sta.link[0], mlink);
+ rcu_assign_pointer(mvif->link[link_id], mconf);
+ rcu_assign_pointer(mvif->sta.link[link_id], mlink);
-out:
+ return 0;
+error:
+ mt7996_remove_bss_conf(vif, conf, mconf);
+ return ret;
+}
+
+static int mt7996_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+ struct mt7996_dev *dev = mt7996_hw_dev(hw);
+ struct mt7996_phy *phy = mt7996_hw_phy(hw);
+ int ret = 0;
+
+ mutex_lock(&dev->mt76.mutex);
+ if (vif->type == NL80211_IFTYPE_MONITOR &&
+ is_zero_ether_addr(vif->addr))
+ phy->monitor_vif = vif;
+
+ mvif->dev = dev;
+ mvif->sta.vif = mvif;
+
+ ret = mt7996_add_bss_conf(phy, vif, &vif->bss_conf);
mutex_unlock(&dev->mt76.mutex);
return ret;
@@ -320,38 +436,23 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *conf;
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
struct mt7996_bss_conf *mconf;
- struct mt7996_link_sta *mlink = &mvif->sta.deflink;
struct mt7996_dev *dev = mt7996_hw_dev(hw);
struct mt7996_phy *phy = mt7996_hw_phy(hw);
- int idx = mlink->wcid.idx;
cancel_delayed_work_sync(&phy->scan_work);
mutex_lock(&dev->mt76.mutex);
- conf = link_conf_dereference_protected(vif, 0);
- mconf = mconf_dereference_protected(mvif, 0);
- mt7996_mcu_add_sta(dev, conf, mconf, NULL, mlink, false, false);
- mt7996_mcu_add_bss_info(phy, conf, mconf, mlink, false);
+ if (test_bit(MT76_SCANNING, &phy->mt76->state))
+ mt7996_scan_complete(phy, true);
if (vif == phy->monitor_vif)
phy->monitor_vif = NULL;
- mt7996_mcu_add_dev_info(phy, conf, mconf, false);
-
- rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
-
- dev->mt76.vif_mask &= ~BIT_ULL(mconf->mt76.idx);
- phy->omac_mask &= ~BIT_ULL(mconf->mt76.omac_idx);
-
- spin_lock_bh(&dev->mt76.sta_poll_lock);
- if (!list_empty(&mlink->wcid.poll_list))
- list_del_init(&mlink->wcid.poll_list);
- spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ conf = link_conf_dereference_protected(vif, 0);
+ mconf = mconf_dereference_protected(mvif, 0);
- mt76_wcid_cleanup(&dev->mt76, &mlink->wcid);
- rcu_assign_pointer(mvif->link[0], NULL);
- rcu_assign_pointer(mvif->sta.link[0], NULL);
+ mt7996_remove_bss_conf(vif, conf, mconf);
mutex_unlock(&dev->mt76.mutex);
}
@@ -714,10 +815,31 @@ mt7996_update_mu_group(struct ieee80211_hw *hw, struct ieee80211_bss_conf *conf,
mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS3(band), mu[3]);
}
-static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *info,
- u64 changed)
+static void mt7996_vif_cfg_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, u64 changed)
+{
+ struct mt7996_phy *phy = mt7996_hw_phy(hw);
+ struct mt7996_dev *dev = mt7996_hw_dev(hw);
+
+ mutex_lock(&dev->mt76.mutex);
+
+ if (changed & BSS_CHANGED_ASSOC && vif->cfg.assoc) {
+ struct ieee80211_bss_conf *conf = &vif->bss_conf;
+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+ struct mt7996_bss_conf *mconf = mconf_dereference_protected(mvif, 0);
+ struct mt7996_link_sta *mlink = mlink_dereference_protected(&mvif->sta, 0);
+
+ mt7996_mcu_add_bss_info(phy, conf, mconf, mlink, true);
+ mt7996_mcu_add_sta(dev, conf, mconf, NULL, mlink, true, false);
+ }
+
+ mutex_unlock(&dev->mt76.mutex);
+}
+
+static void mt7996_link_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *info,
+ u64 changed)
{
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
struct mt7996_bss_conf *mconf;
@@ -733,7 +855,6 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
* and then peer references bss_info_rfch to set bandwidth cap.
*/
if ((changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid)) ||
- (changed & BSS_CHANGED_ASSOC && vif->cfg.assoc) ||
(changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon)) {
mt7996_mcu_add_bss_info(phy, info, mconf, mlink, true);
mt7996_mcu_add_sta(dev, info, mconf, NULL, mlink, true,
@@ -1076,7 +1197,7 @@ mt7996_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
u64 ret;
mutex_lock(&dev->mt76.mutex);
- mconf = mconf_dereference_protected(mvif, 0);
+ mconf = mconf_dereference_protected(mvif, mvif->master_link_id);
ret = __mt7996_get_tsf(hw, mconf);
mutex_unlock(&dev->mt76.mutex);
@@ -1099,7 +1220,7 @@ mt7996_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
mutex_lock(&dev->mt76.mutex);
- mconf = mconf_dereference_protected(mvif, 0);
+ mconf = mconf_dereference_protected(mvif, mvif->master_link_id);
n = mconf->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0
: mconf->mt76.omac_idx;
mt76_wr(dev, MT_LPON_UTTR0(phy->mt76->band_idx), tsf.t32[0]);
@@ -1127,7 +1248,7 @@ mt7996_offset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
mutex_lock(&dev->mt76.mutex);
- mconf = mconf_dereference_protected(mvif, 0);
+ mconf = mconf_dereference_protected(mvif, mvif->master_link_id);
n = mconf->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0
: mconf->mt76.omac_idx;
mt76_wr(dev, MT_LPON_UTTR0(phy->mt76->band_idx), tsf.t32[0]);
@@ -1302,7 +1423,7 @@ mt7996_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u32 changed = IEEE80211_RC_SUPP_RATES_CHANGED;
mutex_lock(&dev->mt76.mutex);
- mconf = mconf_dereference_protected(mvif, 0);
+ mconf = mconf_dereference_protected(mvif, mvif->master_link_id);
mconf->bitrate_mask = *mask;
mutex_unlock(&dev->mt76.mutex);
@@ -1522,7 +1643,7 @@ void mt7996_get_et_stats(struct ieee80211_hw *hw,
int i, ei = 0;
mutex_lock(&dev->mt76.mutex);
- mconf = mconf_dereference_protected(mvif, 0);
+ mconf = mconf_dereference_protected(mvif, mvif->master_link_id);
wi.idx = mconf->mt76.idx,
mt7996_mac_update_stats(phy);
@@ -1890,6 +2011,8 @@ mt7996_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct mt7996_phy *phy = ctx->phy;
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
struct mt7996_bss_conf *mconf;
+ u8 link_id = link_conf->link_id;
+ int ret;
wiphy_info(hw->wiphy, "Assign VIF (addr: %pM, type: %d, link_id: %d) to channel context: %d MHz\n",
vif->addr, vif->type, link_conf->link_id,
@@ -1897,10 +2020,24 @@ mt7996_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
mutex_lock(&phy->dev->mt76.mutex);
- mconf = mconf_dereference_protected(mvif, 0);
+ /* remove first */
+ if (rcu_access_pointer(mvif->link[link_id]))
+ mt7996_remove_bss_conf(vif, link_conf,
+ mconf_dereference_protected(mvif, link_id));
+
+ ret = mt7996_add_bss_conf(phy, vif, link_conf);
+ if (ret) {
+ mutex_unlock(&phy->dev->mt76.mutex);
+ return ret;
+ }
+
+ mconf = mconf_dereference_protected(mvif, link_id);
mconf->chanctx = ctx;
ctx->nbss_assigned++;
+ if (mt7996_hw_phy(hw) == phy)
+ mvif->master_link_id = link_id;
+
mutex_unlock(&phy->dev->mt76.mutex);
return 0;
@@ -1926,7 +2063,7 @@ mt7996_unassign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
if (test_bit(MT76_SCANNING, &phy->mt76->state))
mt7996_scan_complete(phy, true);
- mconf = mconf_dereference_protected(mvif, 0);
+ mconf = mconf_dereference_protected(mvif, link_conf->link_id);
mconf->chanctx = NULL;
ctx->nbss_assigned--;
@@ -1960,6 +2097,57 @@ mt7996_switch_vif_chanctx(struct ieee80211_hw *hw,
return mt7996_set_channel(phy, &new_ctx->chandef);
}
+static int
+mt7996_change_vif_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ u16 old_links, u16 new_links,
+ struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS])
+{
+ struct mt7996_dev *dev = mt7996_hw_dev(hw);
+ struct mt7996_phy *phy = mt7996_hw_phy(hw);
+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+ unsigned long rem = old_links & ~new_links;
+ unsigned int link_id;
+ int ret = 0;
+
+ if (old_links == new_links)
+ return 0;
+
+ mutex_lock(&dev->mt76.mutex);
+
+ /* check if there's legacy bss needed to be removed */
+ if (rcu_access_pointer(mvif->link[0]) == &mvif->deflink)
+ rem |= BIT(0);
+ /* remove first */
+ for_each_set_bit(link_id, &rem, IEEE80211_MLD_MAX_NUM_LINKS) {
+ struct mt7996_bss_conf *mconf =
+ mconf_dereference_protected(mvif, link_id);
+
+ if (!mconf)
+ continue;
+
+ mt7996_remove_bss_conf(vif, old[link_id], mconf);
+ }
+
+ if (!old_links) {
+ mvif->group_mld_id = get_own_mld_idx(dev->mld_id_mask, true);
+ dev->mld_id_mask |= BIT_ULL(mvif->group_mld_id);
+
+ mvif->mld_remap_id = get_mld_remap_idx(dev->mld_remap_id_mask);
+ dev->mld_remap_id_mask |= BIT_ULL(mvif->mld_remap_id);
+ }
+
+ /* fallback to non-MLO interface */
+ if (!new_links) {
+ ret = mt7996_add_bss_conf(phy, vif, &vif->bss_conf);
+ dev->mld_id_mask &= ~BIT_ULL(mvif->group_mld_id);
+ dev->mld_remap_id_mask &= ~BIT_ULL(mvif->mld_remap_id);
+ }
+
+ mutex_unlock(&dev->mt76.mutex);
+
+ return ret;
+}
+
const struct ieee80211_ops mt7996_ops = {
.tx = mt7996_tx,
.start = mt7996_start,
@@ -1969,7 +2157,8 @@ const struct ieee80211_ops mt7996_ops = {
.config = mt7996_config,
.conf_tx = mt7996_conf_tx,
.configure_filter = mt7996_configure_filter,
- .bss_info_changed = mt7996_bss_info_changed,
+ .vif_cfg_changed = mt7996_vif_cfg_changed,
+ .link_info_changed = mt7996_link_info_changed,
.sta_state = mt76_sta_state,
.sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,
.sta_rc_update = mt7996_sta_rc_update,
@@ -2015,4 +2204,5 @@ const struct ieee80211_ops mt7996_ops = {
.assign_vif_chanctx = mt7996_assign_vif_chanctx,
.unassign_vif_chanctx = mt7996_unassign_vif_chanctx,
.switch_vif_chanctx = mt7996_switch_vif_chanctx,
+ .change_vif_links = mt7996_change_vif_links,
};
diff --git a/mt7996/mcu.c b/mt7996/mcu.c
index 8ef8506e1..a27769426 100644
--- a/mt7996/mcu.c
+++ b/mt7996/mcu.c
@@ -1045,15 +1045,23 @@ static void
mt7996_mcu_bss_mld_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
struct mt7996_bss_conf *mconf)
{
+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
struct bss_mld_tlv *mld;
struct tlv *tlv;
tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_MLD, sizeof(*mld));
-
mld = (struct bss_mld_tlv *)tlv;
- mld->group_mld_id = 0xff;
- mld->own_mld_id = mconf->mt76.idx;
- mld->remap_idx = 0xff;
+
+ if (ieee80211_vif_is_mld(vif)) {
+ mld->group_mld_id = mvif->group_mld_id;
+ mld->remap_idx = mvif->mld_remap_id;
+ memcpy(mld->mac_addr, vif->addr, ETH_ALEN);
+ } else {
+ mld->group_mld_id = 0xff;
+ mld->remap_idx = 0xff;
+ }
+
+ mld->own_mld_id = mconf->own_mld_id;
}
static void
@@ -1134,13 +1142,11 @@ mt7996_mcu_bss_ifs_timing_tlv(struct sk_buff *skb, struct mt7996_phy *phy)
}
static int
-mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
- struct ieee80211_bss_conf *conf,
- struct mt7996_bss_conf *mconf,
- struct ieee80211_sta *sta,
- struct mt76_phy *phy, u16 wlan_idx,
- bool enable)
+mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, struct ieee80211_bss_conf *conf,
+ struct mt7996_bss_conf *mconf, struct ieee80211_sta *sta,
+ u16 wlan_idx, bool enable)
{
+ struct mt76_phy *phy = mconf->phy->mt76;
struct ieee80211_vif *vif = conf->vif;
struct cfg80211_chan_def *chandef = &phy->chandef;
struct mt76_connac_bss_basic_tlv *bss;
@@ -1252,8 +1258,7 @@ int mt7996_mcu_add_bss_info(struct mt7996_phy *phy,
return PTR_ERR(skb);
/* bss_basic must be first */
- mt7996_mcu_bss_basic_tlv(skb, conf, mconf, NULL, phy->mt76,
- mlink->wcid.idx, enable);
+ mt7996_mcu_bss_basic_tlv(skb, conf, mconf, NULL, mlink->wcid.idx, enable);
mt7996_mcu_bss_sec_tlv(skb, mconf);
if (vif->type == NL80211_IFTYPE_MONITOR)
diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
index 724829ec1..15912e8e8 100644
--- a/mt7996/mt7996.h
+++ b/mt7996/mt7996.h
@@ -341,6 +341,9 @@ struct mt7996_bss_conf {
struct cfg80211_bitrate_mask bitrate_mask;
struct mt7996_chanctx *chanctx;
+
+ u8 link_id;
+ u8 own_mld_id;
};
struct mt7996_vif {
@@ -349,6 +352,10 @@ struct mt7996_vif {
struct mt7996_sta sta;
struct mt7996_dev *dev;
+
+ u8 master_link_id;
+ u8 group_mld_id;
+ u8 mld_remap_id;
};
/* crash-dump */
@@ -547,6 +554,8 @@ struct mt7996_dev {
u16 chainmask;
u8 chainshift[__MT_MAX_BAND];
u32 hif_idx;
+ u64 mld_id_mask;
+ u64 mld_remap_id_mask;
struct work_struct init_work;
struct work_struct rc_work;
--
2.39.2