blob: c4d110d1422ea7b6be739b133648f5fa123f88a8 [file] [log] [blame]
developer9237f442024-06-14 17:13:04 +08001From 9b5284be6784cf32222425a9cbbd9622db38aafd Mon Sep 17 00:00:00 2001
developer66e89bc2024-04-23 14:50:01 +08002From: Shayne Chen <shayne.chen@mediatek.com>
3Date: Thu, 23 Nov 2023 18:22:11 +0800
developer9237f442024-06-14 17:13:04 +08004Subject: [PATCH 089/116] wifi: mt76: mt7996: support multi-link vif links and
developer66e89bc2024-04-23 14:50:01 +08005 MLO bss callbacks
6
7Rework add/remove interface functions to add/remove bss_conf functions,
8and also switch to callbacks for MLO bss.
9This is a preliminary patch to add MLO support for mt7996 chipsets.
10
11Co-developed-by: Bo Jiao <Bo.Jiao@mediatek.com>
12Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
13Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
14---
15 mt7996/main.c | 298 +++++++++++++++++++++++++++++++++++++++---------
16 mt7996/mcu.c | 29 +++--
17 mt7996/mt7996.h | 9 ++
18 3 files changed, 270 insertions(+), 66 deletions(-)
19
20diff --git a/mt7996/main.c b/mt7996/main.c
developer9237f442024-06-14 17:13:04 +080021index 4e5ba58..9fbb86c 100644
developer66e89bc2024-04-23 14:50:01 +080022--- a/mt7996/main.c
23+++ b/mt7996/main.c
24@@ -205,6 +205,38 @@ static int get_omac_idx(enum nl80211_iftype type, u64 mask)
25 return -1;
26 }
27
28+static int get_own_mld_idx(u64 mask, bool group_mld)
29+{
30+ u8 start, end;
31+ int i;
32+
33+ if (group_mld) {
34+ start = 0;
35+ end = 15;
36+ } else {
37+ start = 16;
38+ end = 63;
39+ }
40+
41+ i = get_free_idx(mask, start, end);
42+ if (i)
43+ return i - 1;
44+
45+ return -1;
46+}
47+
48+static int get_mld_remap_idx(u64 mask)
49+{
50+ u8 start = 0, end = 15;
51+ int i;
52+
53+ i = get_free_idx(mask, start, end);
54+ if (i)
55+ return i - 1;
56+
57+ return -1;
58+}
59+
60 static void mt7996_init_bitrate_mask(struct mt7996_bss_conf *mconf)
61 {
62 int i;
63@@ -223,48 +255,108 @@ static void mt7996_init_bitrate_mask(struct mt7996_bss_conf *mconf)
64 }
65 }
66
67-static int mt7996_add_interface(struct ieee80211_hw *hw,
68- struct ieee80211_vif *vif)
69+static void mt7996_remove_bss_conf(struct ieee80211_vif *vif,
70+ struct ieee80211_bss_conf *conf,
71+ struct mt7996_bss_conf *mconf)
72 {
73- struct ieee80211_bss_conf *conf = &vif->bss_conf;
74+ struct mt7996_phy *phy = mconf->phy;
75+ struct mt7996_dev *dev = phy->dev;
76 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
77- struct mt7996_bss_conf *mconf = &mvif->deflink;
78- struct mt7996_link_sta *mlink = &mvif->sta.deflink;
79- struct mt7996_dev *dev = mt7996_hw_dev(hw);
80- struct mt7996_phy *phy = mt7996_hw_phy(hw);
81+ u8 link_id = conf->link_id;
82+ struct mt7996_link_sta *mlink =
83+ mlink_dereference_protected(&mvif->sta, link_id);
84+
85+ if (!mlink)
86+ return;
87+
88+ mt7996_mcu_add_sta(dev, conf, mconf, NULL, mlink, false, false);
89+ mt7996_mcu_add_bss_info(phy, conf, mconf, mlink, false);
90+ mt7996_mcu_add_dev_info(phy, conf, mconf, false);
91+
92+ rcu_assign_pointer(dev->mt76.wcid[mlink->wcid.idx], NULL);
93+ rcu_assign_pointer(mvif->link[link_id], NULL);
94+ rcu_assign_pointer(mvif->sta.link[link_id], NULL);
95+
96+ dev->mt76.vif_mask &= ~BIT_ULL(mconf->mt76.idx);
97+ dev->mld_id_mask &= ~BIT_ULL(mconf->own_mld_id);
98+ phy->omac_mask &= ~BIT_ULL(mconf->mt76.omac_idx);
99+
100+ spin_lock_bh(&dev->mt76.sta_poll_lock);
101+ if (!list_empty(&mlink->wcid.poll_list))
102+ list_del_init(&mlink->wcid.poll_list);
103+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
104+
105+ mt76_wcid_cleanup(&dev->mt76, &mlink->wcid);
106+
107+ if (mlink != &mvif->sta.deflink)
108+ kfree(mlink);
109+
110+ if (mconf != &mvif->deflink)
111+ kfree(mconf);
112+}
113+
114+static int mt7996_add_bss_conf(struct mt7996_phy *phy,
115+ struct ieee80211_vif *vif,
116+ struct ieee80211_bss_conf *conf)
117+{
118+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
119+ struct mt7996_dev *dev = phy->dev;
120+ struct mt7996_bss_conf *mconf;
121+ struct mt7996_link_sta *mlink;
122 struct mt76_txq *mtxq;
123 u8 band_idx = phy->mt76->band_idx;
124- int idx, ret = 0;
125-
126- mutex_lock(&dev->mt76.mutex);
127+ u8 link_id = conf->link_id;
128+ int idx, ret;
129
130- if (vif->type == NL80211_IFTYPE_MONITOR &&
131- is_zero_ether_addr(vif->addr))
132- phy->monitor_vif = vif;
133+ if (conf != &vif->bss_conf) {
134+ mconf = kzalloc(sizeof(*mconf), GFP_KERNEL);
135+ if (!mconf)
136+ return -ENOMEM;
137+ } else {
138+ mconf = &mvif->deflink;
139+ }
140
141 mconf->mt76.idx = __ffs64(~dev->mt76.vif_mask);
142 if (mconf->mt76.idx >= mt7996_max_interface_num(dev)) {
143 ret = -ENOSPC;
144- goto out;
145+ goto error;
146 }
147
148 idx = get_omac_idx(vif->type, phy->omac_mask);
149 if (idx < 0) {
150 ret = -ENOSPC;
151- goto out;
152+ goto error;
153+ }
154+
155+ mconf->own_mld_id = get_own_mld_idx(dev->mld_id_mask, false);
156+ if (mconf->own_mld_id < 0) {
157+ ret = -ENOSPC;
158+ goto error;
159 }
160+
161 mconf->mt76.omac_idx = idx;
162 mconf->vif = mvif;
163 mconf->phy = phy;
164 mconf->mt76.band_idx = band_idx;
165 mconf->mt76.wmm_idx = vif->type != NL80211_IFTYPE_AP;
166- mvif->dev = dev;
167+ mconf->link_id = link_id;
168
169 ret = mt7996_mcu_add_dev_info(phy, conf, mconf, true);
170 if (ret)
171- goto out;
172+ goto error;
173+
174+ if (ieee80211_vif_is_mld(vif)) {
175+ mlink = kzalloc(sizeof(*mlink), GFP_KERNEL);
176+ if (!mlink) {
177+ ret = -ENOMEM;
178+ goto error;
179+ }
180+ } else {
181+ mlink = &mvif->sta.deflink;
182+ }
183
184 dev->mt76.vif_mask |= BIT_ULL(mconf->mt76.idx);
185+ dev->mld_id_mask |= BIT_ULL(mconf->own_mld_id);
186 phy->omac_mask |= BIT_ULL(mconf->mt76.omac_idx);
187
188 idx = MT7996_WTBL_RESERVED - mconf->mt76.idx;
189@@ -275,6 +367,9 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
190 mlink->wcid.phy_idx = band_idx;
191 mlink->wcid.hw_key_idx = -1;
192 mlink->wcid.tx_info |= MT_WCID_TX_INFO_SET;
193+ mlink->wcid.def_wcid = &mvif->sta.deflink.wcid;
194+ mlink->wcid.link_id = link_id;
195+ mlink->wcid.link_valid = ieee80211_vif_is_mld(vif);
196 mlink->sta = &mvif->sta;
197 mlink->sta->vif = mvif;
198 mt76_wcid_init(&mlink->wcid);
199@@ -296,7 +391,6 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
200 mconf->mt76.basic_rates_idx = MT7996_BASIC_RATES_TBL + 4;
201 else
202 mconf->mt76.basic_rates_idx = MT7996_BASIC_RATES_TBL;
203-
204 mt7996_init_bitrate_mask(mconf);
205
206 mt7996_mcu_add_bss_info(phy, conf, mconf, mlink, true);
207@@ -306,10 +400,32 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
208 if (vif->type != NL80211_IFTYPE_STATION)
209 mt7996_mcu_add_sta(dev, conf, mconf, NULL, mlink, true, true);
210 rcu_assign_pointer(dev->mt76.wcid[idx], &mlink->wcid);
211- rcu_assign_pointer(mvif->link[0], mconf);
212- rcu_assign_pointer(mvif->sta.link[0], mlink);
213+ rcu_assign_pointer(mvif->link[link_id], mconf);
214+ rcu_assign_pointer(mvif->sta.link[link_id], mlink);
215
216-out:
217+ return 0;
218+error:
219+ mt7996_remove_bss_conf(vif, conf, mconf);
220+ return ret;
221+}
222+
223+static int mt7996_add_interface(struct ieee80211_hw *hw,
224+ struct ieee80211_vif *vif)
225+{
226+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
227+ struct mt7996_dev *dev = mt7996_hw_dev(hw);
228+ struct mt7996_phy *phy = mt7996_hw_phy(hw);
229+ int ret = 0;
230+
231+ mutex_lock(&dev->mt76.mutex);
232+ if (vif->type == NL80211_IFTYPE_MONITOR &&
233+ is_zero_ether_addr(vif->addr))
234+ phy->monitor_vif = vif;
235+
236+ mvif->dev = dev;
237+ mvif->sta.vif = mvif;
238+
239+ ret = mt7996_add_bss_conf(phy, vif, &vif->bss_conf);
240 mutex_unlock(&dev->mt76.mutex);
241
242 return ret;
243@@ -321,38 +437,23 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw,
244 struct ieee80211_bss_conf *conf;
245 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
246 struct mt7996_bss_conf *mconf;
247- struct mt7996_link_sta *mlink = &mvif->sta.deflink;
248 struct mt7996_dev *dev = mt7996_hw_dev(hw);
249 struct mt7996_phy *phy = mt7996_hw_phy(hw);
250- int idx = mlink->wcid.idx;
251
252 cancel_delayed_work_sync(&phy->scan_work);
253
254 mutex_lock(&dev->mt76.mutex);
255
256- conf = link_conf_dereference_protected(vif, 0);
257- mconf = mconf_dereference_protected(mvif, 0);
258- mt7996_mcu_add_sta(dev, conf, mconf, NULL, mlink, false, false);
259- mt7996_mcu_add_bss_info(phy, conf, mconf, mlink, false);
260+ if (test_bit(MT76_SCANNING, &phy->mt76->state))
261+ mt7996_scan_complete(phy, true);
262
263 if (vif == phy->monitor_vif)
264 phy->monitor_vif = NULL;
265
266- mt7996_mcu_add_dev_info(phy, conf, mconf, false);
267-
268- rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
269-
270- dev->mt76.vif_mask &= ~BIT_ULL(mconf->mt76.idx);
271- phy->omac_mask &= ~BIT_ULL(mconf->mt76.omac_idx);
272-
273- spin_lock_bh(&dev->mt76.sta_poll_lock);
274- if (!list_empty(&mlink->wcid.poll_list))
275- list_del_init(&mlink->wcid.poll_list);
276- spin_unlock_bh(&dev->mt76.sta_poll_lock);
277+ conf = link_conf_dereference_protected(vif, 0);
278+ mconf = mconf_dereference_protected(mvif, 0);
279
280- mt76_wcid_cleanup(&dev->mt76, &mlink->wcid);
281- rcu_assign_pointer(mvif->link[0], NULL);
282- rcu_assign_pointer(mvif->sta.link[0], NULL);
283+ mt7996_remove_bss_conf(vif, conf, mconf);
284
285 mutex_unlock(&dev->mt76.mutex);
286 }
287@@ -716,10 +817,31 @@ mt7996_update_mu_group(struct ieee80211_hw *hw, struct ieee80211_bss_conf *conf,
288 mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS3(band), mu[3]);
289 }
290
291-static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
292- struct ieee80211_vif *vif,
293- struct ieee80211_bss_conf *info,
294- u64 changed)
295+static void mt7996_vif_cfg_changed(struct ieee80211_hw *hw,
296+ struct ieee80211_vif *vif, u64 changed)
297+{
298+ struct mt7996_phy *phy = mt7996_hw_phy(hw);
299+ struct mt7996_dev *dev = mt7996_hw_dev(hw);
300+
301+ mutex_lock(&dev->mt76.mutex);
302+
303+ if (changed & BSS_CHANGED_ASSOC && vif->cfg.assoc) {
304+ struct ieee80211_bss_conf *conf = &vif->bss_conf;
305+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
306+ struct mt7996_bss_conf *mconf = mconf_dereference_protected(mvif, 0);
307+ struct mt7996_link_sta *mlink = mlink_dereference_protected(&mvif->sta, 0);
308+
309+ mt7996_mcu_add_bss_info(phy, conf, mconf, mlink, true);
310+ mt7996_mcu_add_sta(dev, conf, mconf, NULL, mlink, true, false);
311+ }
312+
313+ mutex_unlock(&dev->mt76.mutex);
314+}
315+
316+static void mt7996_link_info_changed(struct ieee80211_hw *hw,
317+ struct ieee80211_vif *vif,
318+ struct ieee80211_bss_conf *info,
319+ u64 changed)
320 {
321 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
322 struct mt7996_bss_conf *mconf;
323@@ -735,7 +857,6 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
324 * and then peer references bss_info_rfch to set bandwidth cap.
325 */
326 if ((changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid)) ||
327- (changed & BSS_CHANGED_ASSOC && vif->cfg.assoc) ||
328 (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon)) {
329 mt7996_mcu_add_bss_info(phy, info, mconf, mlink, true);
330 mt7996_mcu_add_sta(dev, info, mconf, NULL, mlink, true,
331@@ -1078,7 +1199,7 @@ mt7996_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
332 u64 ret;
333
334 mutex_lock(&dev->mt76.mutex);
335- mconf = mconf_dereference_protected(mvif, 0);
336+ mconf = mconf_dereference_protected(mvif, mvif->master_link_id);
337 ret = __mt7996_get_tsf(hw, mconf);
338 mutex_unlock(&dev->mt76.mutex);
339
340@@ -1101,7 +1222,7 @@ mt7996_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
341
342 mutex_lock(&dev->mt76.mutex);
343
344- mconf = mconf_dereference_protected(mvif, 0);
345+ mconf = mconf_dereference_protected(mvif, mvif->master_link_id);
346 n = mconf->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0
347 : mconf->mt76.omac_idx;
348 mt76_wr(dev, MT_LPON_UTTR0(phy->mt76->band_idx), tsf.t32[0]);
349@@ -1129,7 +1250,7 @@ mt7996_offset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
350
351 mutex_lock(&dev->mt76.mutex);
352
353- mconf = mconf_dereference_protected(mvif, 0);
354+ mconf = mconf_dereference_protected(mvif, mvif->master_link_id);
355 n = mconf->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0
356 : mconf->mt76.omac_idx;
357 mt76_wr(dev, MT_LPON_UTTR0(phy->mt76->band_idx), tsf.t32[0]);
358@@ -1304,7 +1425,7 @@ mt7996_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
359 u32 changed = IEEE80211_RC_SUPP_RATES_CHANGED;
360
361 mutex_lock(&dev->mt76.mutex);
362- mconf = mconf_dereference_protected(mvif, 0);
363+ mconf = mconf_dereference_protected(mvif, mvif->master_link_id);
364 mconf->bitrate_mask = *mask;
365 mutex_unlock(&dev->mt76.mutex);
366
367@@ -1524,7 +1645,7 @@ void mt7996_get_et_stats(struct ieee80211_hw *hw,
368 int i, ei = 0;
369
370 mutex_lock(&dev->mt76.mutex);
371- mconf = mconf_dereference_protected(mvif, 0);
372+ mconf = mconf_dereference_protected(mvif, mvif->master_link_id);
373 wi.idx = mconf->mt76.idx,
374
375 mt7996_mac_update_stats(phy);
376@@ -1897,6 +2018,8 @@ mt7996_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
377 struct mt7996_phy *phy = ctx->phy;
378 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
379 struct mt7996_bss_conf *mconf;
380+ u8 link_id = link_conf->link_id;
381+ int ret;
382
383 wiphy_info(hw->wiphy, "Assign VIF (addr: %pM, type: %d, link_id: %d) to channel context: %d MHz\n",
384 vif->addr, vif->type, link_conf->link_id,
385@@ -1904,10 +2027,24 @@ mt7996_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
386
387 mutex_lock(&phy->dev->mt76.mutex);
388
389- mconf = mconf_dereference_protected(mvif, 0);
390+ /* remove first */
391+ if (rcu_access_pointer(mvif->link[link_id]))
392+ mt7996_remove_bss_conf(vif, link_conf,
393+ mconf_dereference_protected(mvif, link_id));
394+
395+ ret = mt7996_add_bss_conf(phy, vif, link_conf);
396+ if (ret) {
397+ mutex_unlock(&phy->dev->mt76.mutex);
398+ return ret;
399+ }
400+
401+ mconf = mconf_dereference_protected(mvif, link_id);
402 mconf->chanctx = ctx;
403 ctx->nbss_assigned++;
404
405+ if (mt7996_hw_phy(hw) == phy)
406+ mvif->master_link_id = link_id;
407+
408 mutex_unlock(&phy->dev->mt76.mutex);
409
410 return 0;
411@@ -1933,7 +2070,7 @@ mt7996_unassign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
412 if (test_bit(MT76_SCANNING, &phy->mt76->state))
413 mt7996_scan_complete(phy, true);
414
415- mconf = mconf_dereference_protected(mvif, 0);
416+ mconf = mconf_dereference_protected(mvif, link_conf->link_id);
417 mconf->chanctx = NULL;
418 ctx->nbss_assigned--;
419
420@@ -1973,6 +2110,57 @@ mt7996_switch_vif_chanctx(struct ieee80211_hw *hw,
421 return mt7996_set_channel(phy, &new_ctx->chandef);
422 }
423
424+static int
425+mt7996_change_vif_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
426+ u16 old_links, u16 new_links,
427+ struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS])
428+{
429+ struct mt7996_dev *dev = mt7996_hw_dev(hw);
430+ struct mt7996_phy *phy = mt7996_hw_phy(hw);
431+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
432+ unsigned long rem = old_links & ~new_links;
433+ unsigned int link_id;
434+ int ret = 0;
435+
436+ if (old_links == new_links)
437+ return 0;
438+
439+ mutex_lock(&dev->mt76.mutex);
440+
441+ /* check if there's legacy bss needed to be removed */
442+ if (rcu_access_pointer(mvif->link[0]) == &mvif->deflink)
443+ rem |= BIT(0);
444+ /* remove first */
445+ for_each_set_bit(link_id, &rem, IEEE80211_MLD_MAX_NUM_LINKS) {
446+ struct mt7996_bss_conf *mconf =
447+ mconf_dereference_protected(mvif, link_id);
448+
449+ if (!mconf)
450+ continue;
451+
452+ mt7996_remove_bss_conf(vif, old[link_id], mconf);
453+ }
454+
455+ if (!old_links) {
456+ mvif->group_mld_id = get_own_mld_idx(dev->mld_id_mask, true);
457+ dev->mld_id_mask |= BIT_ULL(mvif->group_mld_id);
458+
459+ mvif->mld_remap_id = get_mld_remap_idx(dev->mld_remap_id_mask);
460+ dev->mld_remap_id_mask |= BIT_ULL(mvif->mld_remap_id);
461+ }
462+
463+ /* fallback to non-MLO interface */
464+ if (!new_links) {
465+ ret = mt7996_add_bss_conf(phy, vif, &vif->bss_conf);
466+ dev->mld_id_mask &= ~BIT_ULL(mvif->group_mld_id);
467+ dev->mld_remap_id_mask &= ~BIT_ULL(mvif->mld_remap_id);
468+ }
469+
470+ mutex_unlock(&dev->mt76.mutex);
471+
472+ return ret;
473+}
474+
475 const struct ieee80211_ops mt7996_ops = {
476 .tx = mt7996_tx,
477 .start = mt7996_start,
478@@ -1982,7 +2170,8 @@ const struct ieee80211_ops mt7996_ops = {
479 .config = mt7996_config,
480 .conf_tx = mt7996_conf_tx,
481 .configure_filter = mt7996_configure_filter,
482- .bss_info_changed = mt7996_bss_info_changed,
483+ .vif_cfg_changed = mt7996_vif_cfg_changed,
484+ .link_info_changed = mt7996_link_info_changed,
485 .sta_state = mt76_sta_state,
486 .sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,
487 .sta_rc_update = mt7996_sta_rc_update,
488@@ -2028,4 +2217,5 @@ const struct ieee80211_ops mt7996_ops = {
489 .assign_vif_chanctx = mt7996_assign_vif_chanctx,
490 .unassign_vif_chanctx = mt7996_unassign_vif_chanctx,
491 .switch_vif_chanctx = mt7996_switch_vif_chanctx,
492+ .change_vif_links = mt7996_change_vif_links,
493 };
494diff --git a/mt7996/mcu.c b/mt7996/mcu.c
developer9237f442024-06-14 17:13:04 +0800495index cab4a0a..2a17299 100644
developer66e89bc2024-04-23 14:50:01 +0800496--- a/mt7996/mcu.c
497+++ b/mt7996/mcu.c
498@@ -1047,15 +1047,23 @@ static void
499 mt7996_mcu_bss_mld_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
500 struct mt7996_bss_conf *mconf)
501 {
502+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
503 struct bss_mld_tlv *mld;
504 struct tlv *tlv;
505
506 tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_MLD, sizeof(*mld));
507-
508 mld = (struct bss_mld_tlv *)tlv;
509- mld->group_mld_id = 0xff;
510- mld->own_mld_id = mconf->mt76.idx;
511- mld->remap_idx = 0xff;
512+
513+ if (ieee80211_vif_is_mld(vif)) {
514+ mld->group_mld_id = mvif->group_mld_id;
515+ mld->remap_idx = mvif->mld_remap_id;
516+ memcpy(mld->mac_addr, vif->addr, ETH_ALEN);
517+ } else {
518+ mld->group_mld_id = 0xff;
519+ mld->remap_idx = 0xff;
520+ }
521+
522+ mld->own_mld_id = mconf->own_mld_id;
523 }
524
525 static void
526@@ -1136,13 +1144,11 @@ mt7996_mcu_bss_ifs_timing_tlv(struct sk_buff *skb, struct mt7996_phy *phy)
527 }
528
529 static int
530-mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
531- struct ieee80211_bss_conf *conf,
532- struct mt7996_bss_conf *mconf,
533- struct ieee80211_sta *sta,
534- struct mt76_phy *phy, u16 wlan_idx,
535- bool enable)
536+mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, struct ieee80211_bss_conf *conf,
537+ struct mt7996_bss_conf *mconf, struct ieee80211_sta *sta,
538+ u16 wlan_idx, bool enable)
539 {
540+ struct mt76_phy *phy = mconf->phy->mt76;
541 struct ieee80211_vif *vif = conf->vif;
542 struct cfg80211_chan_def *chandef = &phy->chandef;
543 struct mt76_connac_bss_basic_tlv *bss;
544@@ -1254,8 +1260,7 @@ int mt7996_mcu_add_bss_info(struct mt7996_phy *phy,
545 return PTR_ERR(skb);
546
547 /* bss_basic must be first */
548- mt7996_mcu_bss_basic_tlv(skb, conf, mconf, NULL, phy->mt76,
549- mlink->wcid.idx, enable);
550+ mt7996_mcu_bss_basic_tlv(skb, conf, mconf, NULL, mlink->wcid.idx, enable);
551 mt7996_mcu_bss_sec_tlv(skb, mconf);
552
553 if (vif->type == NL80211_IFTYPE_MONITOR)
554diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
developer9237f442024-06-14 17:13:04 +0800555index 3701720..ed8c82e 100644
developer66e89bc2024-04-23 14:50:01 +0800556--- a/mt7996/mt7996.h
557+++ b/mt7996/mt7996.h
558@@ -340,6 +340,9 @@ struct mt7996_bss_conf {
559 struct cfg80211_bitrate_mask bitrate_mask;
560
561 struct mt7996_chanctx *chanctx;
562+
563+ u8 link_id;
564+ u8 own_mld_id;
565 };
566
567 struct mt7996_vif {
568@@ -348,6 +351,10 @@ struct mt7996_vif {
569
570 struct mt7996_sta sta;
571 struct mt7996_dev *dev;
572+
573+ u8 master_link_id;
574+ u8 group_mld_id;
575+ u8 mld_remap_id;
576 };
577
578 /* crash-dump */
579@@ -549,6 +556,8 @@ struct mt7996_dev {
580 u16 chainmask;
581 u8 chainshift[__MT_MAX_BAND];
582 u32 hif_idx;
583+ u64 mld_id_mask;
584+ u64 mld_remap_id_mask;
585
586 struct work_struct init_work;
587 struct work_struct rc_work;
588--
developer9237f442024-06-14 17:13:04 +08005892.18.0
developer66e89bc2024-04-23 14:50:01 +0800590