[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