The current code keeps a separate instance for the ww reg domain outside the static map, and treats rtw89_regd_get_index() returning RTW89_REGD_MAX_COUNTRY_NUM as the index for the ww domain. This conflates the "not found" sentinel with a real index and causes the block_* bitmap lookups to skip ww entirely, explicitly blocking 6GHz on the ww domain rather than deferring to the kernel regulatory policy. Fold the standalone rtw89_ww_regd into rtw89_regd_map[0] and drop the special case in rtw89_regd_get_index() that returned RTW89_REGD_MAX_COUNTRY_NUM for ww. rtw89_regd_find_reg_by_name() now returns NULL on miss, and its callers either translate that into the RTW89_REGD_MAX_COUNTRY_NUM sentinel (rtw89_regd_get_index_by_name()) or fall back to the ww entry explicitly (rtw89_regd_notifier_apply()). With ww living at a real index, the block-list checks apply and 6GHz is no longer unconditionally blocked for ww. Signed-off-by: Matthew Leach --- drivers/net/wireless/realtek/rtw89/regd.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c index 28466cb35ea2..698b8b7f6129 100644 --- a/drivers/net/wireless/realtek/rtw89/regd.c +++ b/drivers/net/wireless/realtek/rtw89/regd.c @@ -21,10 +21,8 @@ void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request static_assert(BITS_PER_TYPE(unsigned long) >= NUM_OF_RTW89_REGD_FUNC); -static const struct rtw89_regd rtw89_ww_regd = - COUNTRY_REGD("00", RTW89_WW, RTW89_WW, RTW89_WW, 0x0); - static const struct rtw89_regd rtw89_regd_map[] = { + COUNTRY_REGD("00", RTW89_WW, RTW89_WW, RTW89_WW, 0x0), COUNTRY_REGD("AR", RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC, 0x0), COUNTRY_REGD("BO", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0), COUNTRY_REGD("BR", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0), @@ -316,12 +314,13 @@ static const struct rtw89_regd *rtw89_regd_find_reg_by_name(struct rtw89_dev *rt return ®d_ctrl->map[i]; } - return &rtw89_ww_regd; + return NULL; } static bool rtw89_regd_is_ww(const struct rtw89_regd *regd) { - return regd == &rtw89_ww_regd; + /* Index 0 in the static map contains the WW domain entry. */ + return regd == &rtw89_regd_map[0]; } static u8 rtw89_regd_get_index(struct rtw89_dev *rtwdev, const struct rtw89_regd *regd) @@ -331,9 +330,6 @@ static u8 rtw89_regd_get_index(struct rtw89_dev *rtwdev, const struct rtw89_regd BUILD_BUG_ON(ARRAY_SIZE(rtw89_regd_map) > RTW89_REGD_MAX_COUNTRY_NUM); - if (rtw89_regd_is_ww(regd)) - return RTW89_REGD_MAX_COUNTRY_NUM; - return regd - regd_ctrl->map; } @@ -342,6 +338,10 @@ static u8 rtw89_regd_get_index_by_name(struct rtw89_dev *rtwdev, const char *alp const struct rtw89_regd *regd; regd = rtw89_regd_find_reg_by_name(rtwdev, alpha2); + + if (!regd) + return RTW89_REGD_MAX_COUNTRY_NUM; + return rtw89_regd_get_index(rtwdev, regd); } @@ -721,7 +721,7 @@ int rtw89_regd_init_hint(struct rtw89_dev *rtwdev) return -EINVAL; chip_regd = rtw89_regd_find_reg_by_name(rtwdev, rtwdev->efuse.country_code); - if (!rtw89_regd_is_ww(chip_regd)) { + if (chip_regd && !rtw89_regd_is_ww(chip_regd)) { rtwdev->regulatory.regd = chip_regd; rtwdev->regulatory.programmed = true; @@ -859,7 +859,15 @@ static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev, struct wiphy *wiphy, struct regulatory_request *request) { - rtwdev->regulatory.regd = rtw89_regd_find_reg_by_name(rtwdev, request->alpha2); + const struct rtw89_regd *regd = rtw89_regd_find_reg_by_name(rtwdev, request->alpha2); + + if (!regd) { + /* Fallback to WW domain if name not found. */ + regd = &rtw89_regd_map[0]; + } + + rtwdev->regulatory.regd = regd; + /* This notification might be set from the system of distros, * and it does not expect the regulatory will be modified by * connecting to an AP (i.e. country ie). --- base-commit: 8cd9520d35a6c38db6567e97dd93b1f11f185dc6 change-id: 20260616-rtw89-6ghz-regd-fixes-d8f816880bd0 Best regards, -- Matt