[PATCH 4/5] wifi: mt76: mt7921: add auto regdomain switch support
Sean Wang
sean.wang at kernel.org
Mon Feb 23 15:45:26 PST 2026
Hi, JB
On Mon, Feb 23, 2026 at 1:40 AM JB Tsai <jb.tsai at mediatek.com> wrote:
>
> Implement 802.11d-based automatic regulatory domain switching to
> dynamically determine the regulatory domain at runtime.
>
> Signed-off-by: JB Tsai <jb.tsai at mediatek.com>
> ---
> .../wireless/mediatek/mt76/mt76_connac_mcu.h | 3 +-
> .../net/wireless/mediatek/mt76/mt7921/mac.c | 3 +
> .../net/wireless/mediatek/mt76/mt7921/main.c | 12 ++-
> .../net/wireless/mediatek/mt76/mt7921/mcu.c | 3 +-
> .../net/wireless/mediatek/mt76/mt7921/regd.c | 81 +++++++++++++++++--
> .../net/wireless/mediatek/mt76/mt7921/regd.h | 2 +
> 6 files changed, 93 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
> index f44977f9093d..263778be4a34 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
> @@ -1586,7 +1586,7 @@ struct mt76_connac_hw_scan_done {
> u8 pno_enabled;
> u8 pad2[3];
> u8 sparse_channel_valid_num;
> - u8 pad3[3];
> + u8 alpha2[3];
> u8 channel_num[MT76_CONNAC_SCAN_DONE_EVENT_MAX_CHANNEL_NUM];
> /* idle format for channel_idle_time
> * 0: first bytes: idle time(ms) 2nd byte: dwell time(ms)
> @@ -1599,6 +1599,7 @@ struct mt76_connac_hw_scan_done {
> u8 mdrdy_count[MT76_CONNAC_SCAN_DONE_EVENT_MAX_CHANNEL_NUM];
> __le32 beacon_2g_num;
> __le32 beacon_5g_num;
> + __le16 channel_scan_time[MT76_CONNAC_SCAN_DONE_EVENT_MAX_CHANNEL_NUM];
> } __packed;
>
> struct mt76_connac_sched_scan_req {
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
> index 03b4960db73f..bcca4b17e8f2 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
> @@ -7,6 +7,7 @@
> #include "mt7921.h"
> #include "../dma.h"
> #include "../mt76_connac2_mac.h"
> +#include "regd.h"
> #include "mcu.h"
>
> #define MT_WTBL_TXRX_CAP_RATE_OFFSET 7
> @@ -697,6 +698,8 @@ void mt7921_mac_reset_work(struct work_struct *work)
> IEEE80211_IFACE_ITER_RESUME_ALL,
> mt7921_vif_connect_iter, NULL);
> mt76_connac_power_save_sched(&dev->mt76.phy, pm);
> +
> + mt7921_regd_change(&dev->phy, "00");
> }
>
> void mt7921_coredump_work(struct work_struct *work)
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
> index 00ca3d3f3ef0..dfe8cbd7dfa5 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
> @@ -1027,8 +1027,16 @@ void mt7921_scan_work(struct work_struct *work)
> rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
> if (rxd->eid == MCU_EVENT_SCHED_SCAN_DONE) {
> ieee80211_sched_scan_results(phy->mt76->hw);
> - } else if (test_and_clear_bit(MT76_HW_SCANNING,
> - &phy->mt76->state)) {
> + } else if (rxd->eid == MCU_EVENT_SCAN_DONE) {
> + struct mt76_connac_hw_scan_done *event = NULL;
> +
> + skb_pull(skb, sizeof(*rxd));
> + event = (struct mt76_connac_hw_scan_done *)skb->data;
> + mt7921_regd_change(phy, event->alpha2);
Because this changes the firmware/driver ABI, we need to consider
backward compatibility. Will the driver still behave correctly with
older firmware?
For example, on older firmware the scan-done event doesn’t populate
alpha2 (it would effectively be coming from the old pad3 field and may
contain undefined bytes).
> + }
> +
> + if (test_and_clear_bit(MT76_HW_SCANNING,
> + &phy->mt76->state)) {
> struct cfg80211_scan_info info = {
More information about the Linux-mediatek
mailing list