10
10
#include "ps.h"
11
11
#include "util.h"
12
12
13
+ static void rtw89_swap_chanctx (struct rtw89_dev * rtwdev ,
14
+ enum rtw89_chanctx_idx idx1 ,
15
+ enum rtw89_chanctx_idx idx2 );
16
+
13
17
static enum rtw89_subband rtw89_get_subband_type (enum rtw89_band band ,
14
18
u8 center_chan )
15
19
{
@@ -226,11 +230,15 @@ static void rtw89_config_default_chandef(struct rtw89_dev *rtwdev)
226
230
void rtw89_entity_init (struct rtw89_dev * rtwdev )
227
231
{
228
232
struct rtw89_hal * hal = & rtwdev -> hal ;
233
+ struct rtw89_entity_mgnt * mgnt = & hal -> entity_mgnt ;
229
234
230
235
hal -> entity_pause = false;
231
236
bitmap_zero (hal -> entity_map , NUM_OF_RTW89_CHANCTX );
232
237
bitmap_zero (hal -> changes , NUM_OF_RTW89_CHANCTX_CHANGES );
233
238
atomic_set (& hal -> roc_chanctx_idx , RTW89_CHANCTX_IDLE );
239
+
240
+ INIT_LIST_HEAD (& mgnt -> active_list );
241
+
234
242
rtw89_config_default_chandef (rtwdev );
235
243
}
236
244
@@ -272,6 +280,71 @@ static void rtw89_entity_calculate_weight(struct rtw89_dev *rtwdev,
272
280
}
273
281
}
274
282
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
+
275
348
enum rtw89_entity_mode rtw89_entity_recalc (struct rtw89_dev * rtwdev )
276
349
{
277
350
DECLARE_BITMAP (recalc_map , NUM_OF_RTW89_CHANCTX ) = {};
@@ -327,6 +400,8 @@ enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
327
400
rtw89_assign_entity_chan (rtwdev , idx , & chan );
328
401
}
329
402
403
+ rtw89_entity_recalc_mgnt_roles (rtwdev );
404
+
330
405
if (hal -> entity_pause )
331
406
return rtw89_get_entity_mode (rtwdev );
332
407
@@ -716,6 +791,7 @@ struct rtw89_mcc_fill_role_selector {
716
791
};
717
792
718
793
static_assert ((u8 )NUM_OF_RTW89_CHANCTX >= NUM_OF_RTW89_MCC_ROLES );
794
+ static_assert (RTW89_MAX_INTERFACE_NUM >= NUM_OF_RTW89_MCC_ROLES );
719
795
720
796
static int rtw89_mcc_fill_role_iterator (struct rtw89_dev * rtwdev ,
721
797
struct rtw89_mcc_role * mcc_role ,
@@ -745,29 +821,26 @@ static int rtw89_mcc_fill_role_iterator(struct rtw89_dev *rtwdev,
745
821
746
822
static int rtw89_mcc_fill_all_roles (struct rtw89_dev * rtwdev )
747
823
{
824
+ struct rtw89_hal * hal = & rtwdev -> hal ;
825
+ struct rtw89_entity_mgnt * mgnt = & hal -> entity_mgnt ;
748
826
struct rtw89_mcc_fill_role_selector sel = {};
749
827
struct rtw89_vif_link * rtwvif_link ;
750
828
struct rtw89_vif * rtwvif ;
751
829
int ret ;
830
+ int i ;
752
831
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 ;
756
836
757
837
rtwvif_link = rtw89_vif_get_link_inst (rtwvif , 0 );
758
838
if (unlikely (!rtwvif_link )) {
759
839
rtw89_err (rtwdev , "mcc fill roles: find no link on HW-0\n" );
760
840
continue ;
761
841
}
762
842
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 ;
771
844
}
772
845
773
846
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,
2501
2574
struct ieee80211_chanctx_conf * ctx )
2502
2575
{
2503
2576
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 ;
2504
2580
struct rtw89_entity_weight w = {};
2505
2581
2506
2582
rtwvif_link -> chanctx_idx = cfg -> idx ;
2507
2583
rtwvif_link -> chanctx_assigned = true;
2508
2584
cfg -> ref_count ++ ;
2509
2585
2586
+ if (list_empty (& rtwvif -> mgnt_entry ))
2587
+ list_add_tail (& rtwvif -> mgnt_entry , & mgnt -> active_list );
2588
+
2510
2589
if (cfg -> idx == RTW89_CHANCTX_0 )
2511
2590
goto out ;
2512
2591
@@ -2526,6 +2605,7 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
2526
2605
struct ieee80211_chanctx_conf * ctx )
2527
2606
{
2528
2607
struct rtw89_chanctx_cfg * cfg = (struct rtw89_chanctx_cfg * )ctx -> drv_priv ;
2608
+ struct rtw89_vif * rtwvif = rtwvif_link -> rtwvif ;
2529
2609
struct rtw89_hal * hal = & rtwdev -> hal ;
2530
2610
enum rtw89_chanctx_idx roll ;
2531
2611
enum rtw89_entity_mode cur ;
@@ -2536,6 +2616,9 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
2536
2616
rtwvif_link -> chanctx_assigned = false;
2537
2617
cfg -> ref_count -- ;
2538
2618
2619
+ if (!rtw89_vif_is_active_role (rtwvif ))
2620
+ list_del_init (& rtwvif -> mgnt_entry );
2621
+
2539
2622
if (cfg -> ref_count != 0 )
2540
2623
goto out ;
2541
2624
0 commit comments