Skip to content

Commit 68ec751

Browse files
Zong-Zhe YangPing-Ke Shih
authored andcommitted
wifi: rtw89: chan: manage active interfaces
To set channel well for combination of MCC (multi-channel concurrency) and impending MLO support, we need a method to manage relation between active interfaces and channel contexts. If an interface owns at least one active link, we call it an active interface. We add a list to manage active ones. Basically, the list follows the active order except for the below case. To be compatible with legacy behavior, the first interface that owns the first channel context will put at the first entry in the list when recalculating. Besides, MCC can also select and fill roles based on the above active list. Signed-off-by: Zong-Zhe Yang <[email protected]> Signed-off-by: Ping-Ke Shih <[email protected]> Link: https://patch.msgid.link/[email protected]
1 parent c39eed4 commit 68ec751

File tree

4 files changed

+108
-13
lines changed

4 files changed

+108
-13
lines changed

drivers/net/wireless/realtek/rtw89/chan.c

Lines changed: 94 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
#include "ps.h"
1111
#include "util.h"
1212

13+
static void rtw89_swap_chanctx(struct rtw89_dev *rtwdev,
14+
enum rtw89_chanctx_idx idx1,
15+
enum rtw89_chanctx_idx idx2);
16+
1317
static enum rtw89_subband rtw89_get_subband_type(enum rtw89_band band,
1418
u8 center_chan)
1519
{
@@ -226,11 +230,15 @@ static void rtw89_config_default_chandef(struct rtw89_dev *rtwdev)
226230
void rtw89_entity_init(struct rtw89_dev *rtwdev)
227231
{
228232
struct rtw89_hal *hal = &rtwdev->hal;
233+
struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
229234

230235
hal->entity_pause = false;
231236
bitmap_zero(hal->entity_map, NUM_OF_RTW89_CHANCTX);
232237
bitmap_zero(hal->changes, NUM_OF_RTW89_CHANCTX_CHANGES);
233238
atomic_set(&hal->roc_chanctx_idx, RTW89_CHANCTX_IDLE);
239+
240+
INIT_LIST_HEAD(&mgnt->active_list);
241+
234242
rtw89_config_default_chandef(rtwdev);
235243
}
236244

@@ -272,6 +280,71 @@ static void rtw89_entity_calculate_weight(struct rtw89_dev *rtwdev,
272280
}
273281
}
274282

283+
static void rtw89_normalize_link_chanctx(struct rtw89_dev *rtwdev,
284+
struct rtw89_vif_link *rtwvif_link)
285+
{
286+
struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
287+
struct rtw89_vif_link *cur;
288+
289+
if (unlikely(!rtwvif_link->chanctx_assigned))
290+
return;
291+
292+
cur = rtw89_vif_get_link_inst(rtwvif, 0);
293+
if (!cur || !cur->chanctx_assigned)
294+
return;
295+
296+
if (cur == rtwvif_link)
297+
return;
298+
299+
rtw89_swap_chanctx(rtwdev, rtwvif_link->chanctx_idx, cur->chanctx_idx);
300+
}
301+
302+
static void rtw89_entity_recalc_mgnt_roles(struct rtw89_dev *rtwdev)
303+
{
304+
struct rtw89_hal *hal = &rtwdev->hal;
305+
struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
306+
struct rtw89_vif_link *link;
307+
struct rtw89_vif *role;
308+
u8 pos = 0;
309+
int i;
310+
311+
lockdep_assert_held(&rtwdev->mutex);
312+
313+
for (i = 0; i < RTW89_MAX_INTERFACE_NUM; i++)
314+
mgnt->active_roles[i] = NULL;
315+
316+
/* To be consistent with legacy behavior, expect the first active role
317+
* which uses RTW89_CHANCTX_0 to put at position 0, and make its first
318+
* link instance take RTW89_CHANCTX_0. (normalizing)
319+
*/
320+
list_for_each_entry(role, &mgnt->active_list, mgnt_entry) {
321+
for (i = 0; i < role->links_inst_valid_num; i++) {
322+
link = rtw89_vif_get_link_inst(role, i);
323+
if (!link || !link->chanctx_assigned)
324+
continue;
325+
326+
if (link->chanctx_idx == RTW89_CHANCTX_0) {
327+
rtw89_normalize_link_chanctx(rtwdev, link);
328+
329+
list_del(&role->mgnt_entry);
330+
list_add(&role->mgnt_entry, &mgnt->active_list);
331+
break;
332+
}
333+
}
334+
}
335+
336+
list_for_each_entry(role, &mgnt->active_list, mgnt_entry) {
337+
if (unlikely(pos >= RTW89_MAX_INTERFACE_NUM)) {
338+
rtw89_warn(rtwdev,
339+
"%s: active roles are over max iface num\n",
340+
__func__);
341+
break;
342+
}
343+
344+
mgnt->active_roles[pos++] = role;
345+
}
346+
}
347+
275348
enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
276349
{
277350
DECLARE_BITMAP(recalc_map, NUM_OF_RTW89_CHANCTX) = {};
@@ -327,6 +400,8 @@ enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
327400
rtw89_assign_entity_chan(rtwdev, idx, &chan);
328401
}
329402

403+
rtw89_entity_recalc_mgnt_roles(rtwdev);
404+
330405
if (hal->entity_pause)
331406
return rtw89_get_entity_mode(rtwdev);
332407

@@ -716,6 +791,7 @@ struct rtw89_mcc_fill_role_selector {
716791
};
717792

718793
static_assert((u8)NUM_OF_RTW89_CHANCTX >= NUM_OF_RTW89_MCC_ROLES);
794+
static_assert(RTW89_MAX_INTERFACE_NUM >= NUM_OF_RTW89_MCC_ROLES);
719795

720796
static int rtw89_mcc_fill_role_iterator(struct rtw89_dev *rtwdev,
721797
struct rtw89_mcc_role *mcc_role,
@@ -745,29 +821,26 @@ static int rtw89_mcc_fill_role_iterator(struct rtw89_dev *rtwdev,
745821

746822
static int rtw89_mcc_fill_all_roles(struct rtw89_dev *rtwdev)
747823
{
824+
struct rtw89_hal *hal = &rtwdev->hal;
825+
struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
748826
struct rtw89_mcc_fill_role_selector sel = {};
749827
struct rtw89_vif_link *rtwvif_link;
750828
struct rtw89_vif *rtwvif;
751829
int ret;
830+
int i;
752831

753-
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
754-
if (!rtw89_vif_is_active_role(rtwvif))
755-
continue;
832+
for (i = 0; i < NUM_OF_RTW89_MCC_ROLES; i++) {
833+
rtwvif = mgnt->active_roles[i];
834+
if (!rtwvif)
835+
break;
756836

757837
rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
758838
if (unlikely(!rtwvif_link)) {
759839
rtw89_err(rtwdev, "mcc fill roles: find no link on HW-0\n");
760840
continue;
761841
}
762842

763-
if (sel.bind_vif[rtwvif_link->chanctx_idx]) {
764-
rtw89_warn(rtwdev,
765-
"MCC skip extra vif <macid %d> on chanctx[%d]\n",
766-
rtwvif_link->mac_id, rtwvif_link->chanctx_idx);
767-
continue;
768-
}
769-
770-
sel.bind_vif[rtwvif_link->chanctx_idx] = rtwvif_link;
843+
sel.bind_vif[i] = rtwvif_link;
771844
}
772845

773846
ret = rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_fill_role_iterator, &sel);
@@ -2501,12 +2574,18 @@ int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
25012574
struct ieee80211_chanctx_conf *ctx)
25022575
{
25032576
struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
2577+
struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
2578+
struct rtw89_hal *hal = &rtwdev->hal;
2579+
struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
25042580
struct rtw89_entity_weight w = {};
25052581

25062582
rtwvif_link->chanctx_idx = cfg->idx;
25072583
rtwvif_link->chanctx_assigned = true;
25082584
cfg->ref_count++;
25092585

2586+
if (list_empty(&rtwvif->mgnt_entry))
2587+
list_add_tail(&rtwvif->mgnt_entry, &mgnt->active_list);
2588+
25102589
if (cfg->idx == RTW89_CHANCTX_0)
25112590
goto out;
25122591

@@ -2526,6 +2605,7 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
25262605
struct ieee80211_chanctx_conf *ctx)
25272606
{
25282607
struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
2608+
struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
25292609
struct rtw89_hal *hal = &rtwdev->hal;
25302610
enum rtw89_chanctx_idx roll;
25312611
enum rtw89_entity_mode cur;
@@ -2536,6 +2616,9 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
25362616
rtwvif_link->chanctx_assigned = false;
25372617
cfg->ref_count--;
25382618

2619+
if (!rtw89_vif_is_active_role(rtwvif))
2620+
list_del_init(&rtwvif->mgnt_entry);
2621+
25392622
if (cfg->ref_count != 0)
25402623
goto out;
25412624

drivers/net/wireless/realtek/rtw89/core.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,13 +192,13 @@ static const struct ieee80211_iface_combination rtw89_iface_combs[] = {
192192
{
193193
.limits = rtw89_iface_limits,
194194
.n_limits = ARRAY_SIZE(rtw89_iface_limits),
195-
.max_interfaces = 2,
195+
.max_interfaces = RTW89_MAX_INTERFACE_NUM,
196196
.num_different_channels = 1,
197197
},
198198
{
199199
.limits = rtw89_iface_limits_mcc,
200200
.n_limits = ARRAY_SIZE(rtw89_iface_limits_mcc),
201-
.max_interfaces = 2,
201+
.max_interfaces = RTW89_MAX_INTERFACE_NUM,
202202
.num_different_channels = 2,
203203
},
204204
};

drivers/net/wireless/realtek/rtw89/core.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4635,6 +4635,14 @@ enum rtw89_entity_mode {
46354635
RTW89_ENTITY_MODE_UNHANDLED = -ESRCH,
46364636
};
46374637

4638+
#define RTW89_MAX_INTERFACE_NUM 2
4639+
4640+
/* only valid when running with chanctx_ops */
4641+
struct rtw89_entity_mgnt {
4642+
struct list_head active_list;
4643+
struct rtw89_vif *active_roles[RTW89_MAX_INTERFACE_NUM];
4644+
};
4645+
46384646
struct rtw89_chanctx {
46394647
struct cfg80211_chan_def chandef;
46404648
struct rtw89_chan chan;
@@ -4682,6 +4690,7 @@ struct rtw89_hal {
46824690
bool entity_active[RTW89_PHY_MAX];
46834691
bool entity_pause;
46844692
enum rtw89_entity_mode entity_mode;
4693+
struct rtw89_entity_mgnt entity_mgnt;
46854694

46864695
struct rtw89_edcca_bak edcca_bak;
46874696
u32 disabled_dm_bitmap; /* bitmap of enum rtw89_dm_type */
@@ -5636,6 +5645,7 @@ struct rtw89_dev {
56365645
struct rtw89_vif {
56375646
struct rtw89_dev *rtwdev;
56385647
struct list_head list;
5648+
struct list_head mgnt_entry;
56395649

56405650
u8 mac_addr[ETH_ALEN];
56415651
__be32 ip_addr;

drivers/net/wireless/realtek/rtw89/mac80211.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
192192
if (!rtw89_rtwvif_in_list(rtwdev, rtwvif))
193193
list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list);
194194

195+
INIT_LIST_HEAD(&rtwvif->mgnt_entry);
196+
195197
ether_addr_copy(rtwvif->mac_addr, vif->addr);
196198

197199
rtwvif->offchan = false;

0 commit comments

Comments
 (0)