Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH] wifi: rtw89: regd: fix ww domain blocking on 6GHz
@ 2026-06-17 10:13 Matthew Leach
  2026-06-18  3:45 ` Zong-Zhe Yang
  0 siblings, 1 reply; 2+ messages in thread
From: Matthew Leach @ 2026-06-17 10:13 UTC (permalink / raw)
  To: Ping-Ke Shih; +Cc: linux-wireless, linux-kernel, kernel, Matthew Leach

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 <matthew.leach@collabora.com>
---
 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 &regd_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


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* RE: [PATCH] wifi: rtw89: regd: fix ww domain blocking on 6GHz
  2026-06-17 10:13 [PATCH] wifi: rtw89: regd: fix ww domain blocking on 6GHz Matthew Leach
@ 2026-06-18  3:45 ` Zong-Zhe Yang
  0 siblings, 0 replies; 2+ messages in thread
From: Zong-Zhe Yang @ 2026-06-18  3:45 UTC (permalink / raw)
  To: Matthew Leach, Ping-Ke Shih
  Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org,
	kernel@collabora.com

Matthew Leach <matthew.leach@collabora.com> wrote:
> 
> 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

We ensure regd_map size <= RTW89_REGD_MAX_COUNTRY_NUM.
And we treat "not found" as WW-like case.

> block_* bitmap lookups to skip ww entirely, explicitly blocking 6GHz on
> the ww domain rather than deferring to the kernel regulatory policy.

In fact, we meant to block 6GHz on WW for now.
And I didn't see wireless-regdb enables 6GHz on WW either.

> 
> 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

A big problem here:
Note that regd_map will be generated/updated based on certification document
provided by our RF team, but it won't include WW. (no so-called WW certification)

There are two kinds of chipsets:
1. regd_map is loaded from built-in array
2. regd_map is loaded from fw element

For case 2, regd_map[0] won't stand for WW.
So, your fallback won't work correctly.

> 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 <matthew.leach@collabora.com>
> ---
>  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 &regd_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
> 


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-06-18  3:45 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-17 10:13 [PATCH] wifi: rtw89: regd: fix ww domain blocking on 6GHz Matthew Leach
2026-06-18  3:45 ` Zong-Zhe Yang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox