@@ -257,7 +257,42 @@ static const struct rtw89_regd rtw89_regd_map[] = {
257
257
COUNTRY_REGD ("PS" , RTW89_ETSI , RTW89_ETSI , RTW89_NA ),
258
258
};
259
259
260
- static const struct rtw89_regd * rtw89_regd_find_reg_by_name (char * alpha2 )
260
+ static const char rtw89_alpha2_list_eu [][3 ] = {
261
+ "AT" ,
262
+ "BE" ,
263
+ "CY" ,
264
+ "CZ" ,
265
+ "DK" ,
266
+ "EE" ,
267
+ "FI" ,
268
+ "FR" ,
269
+ "DE" ,
270
+ "GR" ,
271
+ "HU" ,
272
+ "IS" ,
273
+ "IE" ,
274
+ "IT" ,
275
+ "LV" ,
276
+ "LI" ,
277
+ "LT" ,
278
+ "LU" ,
279
+ "MT" ,
280
+ "MC" ,
281
+ "NL" ,
282
+ "NO" ,
283
+ "PL" ,
284
+ "PT" ,
285
+ "SK" ,
286
+ "SI" ,
287
+ "ES" ,
288
+ "SE" ,
289
+ "CH" ,
290
+ "BG" ,
291
+ "HR" ,
292
+ "RO" ,
293
+ };
294
+
295
+ static const struct rtw89_regd * rtw89_regd_find_reg_by_name (const char * alpha2 )
261
296
{
262
297
u32 i ;
263
298
@@ -274,6 +309,24 @@ static bool rtw89_regd_is_ww(const struct rtw89_regd *regd)
274
309
return regd == & rtw89_ww_regd ;
275
310
}
276
311
312
+ static u8 rtw89_regd_get_index (const struct rtw89_regd * regd )
313
+ {
314
+ BUILD_BUG_ON (ARRAY_SIZE (rtw89_regd_map ) > RTW89_REGD_MAX_COUNTRY_NUM );
315
+
316
+ if (rtw89_regd_is_ww (regd ))
317
+ return RTW89_REGD_MAX_COUNTRY_NUM ;
318
+
319
+ return regd - rtw89_regd_map ;
320
+ }
321
+
322
+ static u8 rtw89_regd_get_index_by_name (const char * alpha2 )
323
+ {
324
+ const struct rtw89_regd * regd ;
325
+
326
+ regd = rtw89_regd_find_reg_by_name (alpha2 );
327
+ return rtw89_regd_get_index (regd );
328
+ }
329
+
277
330
#define rtw89_debug_regd (_dev , _regd , _desc , _argv ...) \
278
331
do { \
279
332
typeof(_regd) __r = _regd; \
@@ -335,6 +388,77 @@ static void rtw89_regd_setup_unii4(struct rtw89_dev *rtwdev,
335
388
sband -> n_channels -= 3 ;
336
389
}
337
390
391
+ static void __rtw89_regd_setup_policy_6ghz (struct rtw89_dev * rtwdev , bool block ,
392
+ const char * alpha2 )
393
+ {
394
+ struct rtw89_regulatory_info * regulatory = & rtwdev -> regulatory ;
395
+ u8 index ;
396
+
397
+ index = rtw89_regd_get_index_by_name (alpha2 );
398
+ if (index == RTW89_REGD_MAX_COUNTRY_NUM ) {
399
+ rtw89_debug (rtwdev , RTW89_DBG_REGD , "%s: unknown alpha2 %c%c\n" ,
400
+ __func__ , alpha2 [0 ], alpha2 [1 ]);
401
+ return ;
402
+ }
403
+
404
+ if (block )
405
+ set_bit (index , regulatory -> block_6ghz );
406
+ else
407
+ clear_bit (index , regulatory -> block_6ghz );
408
+ }
409
+
410
+ static void rtw89_regd_setup_policy_6ghz (struct rtw89_dev * rtwdev )
411
+ {
412
+ struct rtw89_regulatory_info * regulatory = & rtwdev -> regulatory ;
413
+ const struct rtw89_acpi_country_code * country ;
414
+ const struct rtw89_acpi_policy_6ghz * ptr ;
415
+ struct rtw89_acpi_dsm_result res = {};
416
+ bool to_block ;
417
+ int i , j ;
418
+ int ret ;
419
+
420
+ ret = rtw89_acpi_evaluate_dsm (rtwdev , RTW89_ACPI_DSM_FUNC_6G_BP , & res );
421
+ if (ret ) {
422
+ rtw89_debug (rtwdev , RTW89_DBG_REGD ,
423
+ "acpi: cannot eval policy 6ghz: %d\n" , ret );
424
+ return ;
425
+ }
426
+
427
+ ptr = res .u .policy_6ghz ;
428
+
429
+ switch (ptr -> policy_mode ) {
430
+ case RTW89_ACPI_POLICY_BLOCK :
431
+ to_block = true;
432
+ break ;
433
+ case RTW89_ACPI_POLICY_ALLOW :
434
+ to_block = false;
435
+ /* only below list is allowed; block all first */
436
+ bitmap_fill (regulatory -> block_6ghz , RTW89_REGD_MAX_COUNTRY_NUM );
437
+ break ;
438
+ default :
439
+ rtw89_debug (rtwdev , RTW89_DBG_REGD ,
440
+ "%s: unknown policy mode: %d\n" , __func__ ,
441
+ ptr -> policy_mode );
442
+ goto out ;
443
+ }
444
+
445
+ for (i = 0 ; i < ptr -> country_count ; i ++ ) {
446
+ country = & ptr -> country_list [i ];
447
+ if (memcmp ("EU" , country -> alpha2 , 2 ) != 0 ) {
448
+ __rtw89_regd_setup_policy_6ghz (rtwdev , to_block ,
449
+ country -> alpha2 );
450
+ continue ;
451
+ }
452
+
453
+ for (j = 0 ; j < ARRAY_SIZE (rtw89_alpha2_list_eu ); j ++ )
454
+ __rtw89_regd_setup_policy_6ghz (rtwdev , to_block ,
455
+ rtw89_alpha2_list_eu [j ]);
456
+ }
457
+
458
+ out :
459
+ kfree (ptr );
460
+ }
461
+
338
462
static void rtw89_regd_setup_6ghz (struct rtw89_dev * rtwdev , struct wiphy * wiphy )
339
463
{
340
464
const struct rtw89_chip_info * chip = rtwdev -> chip ;
@@ -375,8 +499,10 @@ static void rtw89_regd_setup_6ghz(struct rtw89_dev *rtwdev, struct wiphy *wiphy)
375
499
rtw89_debug (rtwdev , RTW89_DBG_REGD , "regd: allow 6ghz: %d\n" ,
376
500
regd_allow_6ghz );
377
501
378
- if (regd_allow_6ghz )
502
+ if (regd_allow_6ghz ) {
503
+ rtw89_regd_setup_policy_6ghz (rtwdev );
379
504
return ;
505
+ }
380
506
381
507
sband = wiphy -> bands [NL80211_BAND_6GHZ ];
382
508
if (!sband )
@@ -436,6 +562,33 @@ int rtw89_regd_init(struct rtw89_dev *rtwdev,
436
562
return 0 ;
437
563
}
438
564
565
+ static void rtw89_regd_apply_policy_6ghz (struct rtw89_dev * rtwdev ,
566
+ struct wiphy * wiphy )
567
+ {
568
+ struct rtw89_regulatory_info * regulatory = & rtwdev -> regulatory ;
569
+ const struct rtw89_regd * regd = regulatory -> regd ;
570
+ struct ieee80211_supported_band * sband ;
571
+ u8 index ;
572
+ int i ;
573
+
574
+ index = rtw89_regd_get_index (regd );
575
+ if (index == RTW89_REGD_MAX_COUNTRY_NUM )
576
+ return ;
577
+
578
+ if (!test_bit (index , regulatory -> block_6ghz ))
579
+ return ;
580
+
581
+ rtw89_debug (rtwdev , RTW89_DBG_REGD , "%c%c 6 GHz is blocked by policy\n" ,
582
+ regd -> alpha2 [0 ], regd -> alpha2 [1 ]);
583
+
584
+ sband = wiphy -> bands [NL80211_BAND_6GHZ ];
585
+ if (!sband )
586
+ return ;
587
+
588
+ for (i = 0 ; i < sband -> n_channels ; i ++ )
589
+ sband -> channels [i ].flags |= IEEE80211_CHAN_DISABLED ;
590
+ }
591
+
439
592
static void rtw89_regd_notifier_apply (struct rtw89_dev * rtwdev ,
440
593
struct wiphy * wiphy ,
441
594
struct regulatory_request * request )
@@ -450,6 +603,8 @@ static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev,
450
603
wiphy -> regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE ;
451
604
else
452
605
wiphy -> regulatory_flags &= ~REGULATORY_COUNTRY_IE_IGNORE ;
606
+
607
+ rtw89_regd_apply_policy_6ghz (rtwdev , wiphy );
453
608
}
454
609
455
610
void rtw89_regd_notifier (struct wiphy * wiphy , struct regulatory_request * request )
0 commit comments