From: Ming Yen Hsieh Move regd logic to regd.c and regd.h files Signed-off-by: Ming Yen Hsieh --- .../wireless/mediatek/mt76/mt7925/Makefile | 2 +- .../net/wireless/mediatek/mt76/mt7925/init.c | 146 +---------------- .../net/wireless/mediatek/mt76/mt7925/main.c | 1 + .../wireless/mediatek/mt76/mt7925/mt7925.h | 2 - .../net/wireless/mediatek/mt76/mt7925/pci.c | 1 + .../net/wireless/mediatek/mt76/mt7925/regd.c | 149 ++++++++++++++++++ .../net/wireless/mediatek/mt76/mt7925/regd.h | 14 ++ 7 files changed, 167 insertions(+), 148 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/mt7925/regd.c create mode 100644 drivers/net/wireless/mediatek/mt76/mt7925/regd.h diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/Makefile b/drivers/net/wireless/mediatek/mt76/mt7925/Makefile index 5d769de979c0..8f1078ce3231 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/Makefile +++ b/drivers/net/wireless/mediatek/mt76/mt7925/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_MT7925_COMMON) += mt7925-common.o obj-$(CONFIG_MT7925E) += mt7925e.o obj-$(CONFIG_MT7925U) += mt7925u.o -mt7925-common-y := mac.o mcu.o main.o init.o debugfs.o +mt7925-common-y := mac.o mcu.o regd.o main.o init.o debugfs.o mt7925-common-$(CONFIG_NL80211_TESTMODE) += testmode.o mt7925e-y := pci.o pci_mac.o pci_mcu.o mt7925u-y := usb.o diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/init.c b/drivers/net/wireless/mediatek/mt76/mt7925/init.c index ea397ad48c30..741e38b29b77 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/init.c @@ -7,6 +7,7 @@ #include #include #include "mt7925.h" +#include "regd.h" #include "mac.h" #include "mcu.h" @@ -60,151 +61,6 @@ static int mt7925_thermal_init(struct mt792x_phy *phy) return PTR_ERR_OR_ZERO(hwmon); } -void mt7925_regd_be_ctrl(struct mt792x_dev *dev, u8 *alpha2) -{ - struct mt792x_phy *phy = &dev->phy; - struct mt7925_clc_rule_v2 *rule; - struct mt7925_clc *clc; - bool old = dev->has_eht, new = true; - u32 mtcl_conf = mt792x_acpi_get_mtcl_conf(&dev->phy, alpha2); - u8 *pos; - - if (mtcl_conf != MT792X_ACPI_MTCL_INVALID && - (((mtcl_conf >> 4) & 0x3) == 0)) { - new = false; - goto out; - } - - if (!phy->clc[MT792x_CLC_BE_CTRL]) - goto out; - - clc = (struct mt7925_clc *)phy->clc[MT792x_CLC_BE_CTRL]; - pos = clc->data; - - while (1) { - rule = (struct mt7925_clc_rule_v2 *)pos; - - if (rule->alpha2[0] == alpha2[0] && - rule->alpha2[1] == alpha2[1]) { - new = false; - break; - } - - /* Check the last one */ - if (rule->flag & BIT(0)) - break; - - pos += sizeof(*rule); - } - -out: - if (old == new) - return; - - dev->has_eht = new; - mt7925_set_stream_he_eht_caps(phy); -} - -static void -mt7925_regd_channel_update(struct wiphy *wiphy, struct mt792x_dev *dev) -{ -#define IS_UNII_INVALID(idx, sfreq, efreq, cfreq) \ - (!(dev->phy.clc_chan_conf & BIT(idx)) && (cfreq) >= (sfreq) && (cfreq) <= (efreq)) -#define MT7925_UNII_59G_IS_VALID 0x1 -#define MT7925_UNII_6G_IS_VALID 0x1e - struct ieee80211_supported_band *sband; - struct mt76_dev *mdev = &dev->mt76; - struct ieee80211_channel *ch; - u32 mtcl_conf = mt792x_acpi_get_mtcl_conf(&dev->phy, mdev->alpha2); - int i; - - if (mtcl_conf != MT792X_ACPI_MTCL_INVALID) { - if ((mtcl_conf & 0x3) == 0) - dev->phy.clc_chan_conf &= ~MT7925_UNII_59G_IS_VALID; - if (((mtcl_conf >> 2) & 0x3) == 0) - dev->phy.clc_chan_conf &= ~MT7925_UNII_6G_IS_VALID; - } - - sband = wiphy->bands[NL80211_BAND_5GHZ]; - if (!sband) - return; - - for (i = 0; i < sband->n_channels; i++) { - ch = &sband->channels[i]; - - /* UNII-4 */ - if (IS_UNII_INVALID(0, 5845, 5925, ch->center_freq)) - ch->flags |= IEEE80211_CHAN_DISABLED; - } - - sband = wiphy->bands[NL80211_BAND_6GHZ]; - if (!sband) - return; - - for (i = 0; i < sband->n_channels; i++) { - ch = &sband->channels[i]; - - /* UNII-5/6/7/8 */ - if (IS_UNII_INVALID(1, 5925, 6425, ch->center_freq) || - IS_UNII_INVALID(2, 6425, 6525, ch->center_freq) || - IS_UNII_INVALID(3, 6525, 6875, ch->center_freq) || - IS_UNII_INVALID(4, 6875, 7125, ch->center_freq)) - ch->flags |= IEEE80211_CHAN_DISABLED; - } -} - -void mt7925_regd_update(struct mt792x_dev *dev) -{ - struct mt76_dev *mdev = &dev->mt76; - struct ieee80211_hw *hw = mdev->hw; - struct wiphy *wiphy = hw->wiphy; - - if (!dev->regd_change) - return; - - mt7925_mcu_set_clc(dev, mdev->alpha2, dev->country_ie_env); - mt7925_regd_channel_update(wiphy, dev); - mt7925_mcu_set_channel_domain(hw->priv); - mt7925_set_tx_sar_pwr(hw, NULL); - dev->regd_change = false; -} -EXPORT_SYMBOL_GPL(mt7925_regd_update); - -static void -mt7925_regd_notifier(struct wiphy *wiphy, - struct regulatory_request *req) -{ - struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); - struct mt792x_dev *dev = mt792x_hw_dev(hw); - struct mt76_dev *mdev = &dev->mt76; - struct mt76_connac_pm *pm = &dev->pm; - - /* allow world regdom at the first boot only */ - if (!memcmp(req->alpha2, "00", 2) && - mdev->alpha2[0] && mdev->alpha2[1]) - return; - - /* do not need to update the same country twice */ - if (!memcmp(req->alpha2, mdev->alpha2, 2) && - dev->country_ie_env == req->country_ie_env) - return; - - memcpy(mdev->alpha2, req->alpha2, 2); - mdev->region = req->dfs_region; - dev->country_ie_env = req->country_ie_env; - dev->regd_change = true; - - if (pm->suspended) - return; - - dev->regd_in_progress = true; - mt792x_mutex_acquire(dev); - mt7925_regd_update(dev); - mt792x_mutex_release(dev); - dev->regd_in_progress = false; - wake_up(&dev->wait); -} - static void mt7925_mac_init_basic_rates(struct mt792x_dev *dev) { int i; diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c index 23746627f68f..f9993f191448 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c @@ -8,6 +8,7 @@ #include #include #include "mt7925.h" +#include "regd.h" #include "mcu.h" #include "mac.h" diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h b/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h index 6df39ce6eb4a..5030d7714bcf 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h @@ -263,8 +263,6 @@ int mt7925_mcu_chip_config(struct mt792x_dev *dev, const char *cmd); int mt7925_mcu_set_rxfilter(struct mt792x_dev *dev, u32 fif, u8 bit_op, u32 bit_map); -void mt7925_regd_be_ctrl(struct mt792x_dev *dev, u8 *alpha2); -void mt7925_regd_update(struct mt792x_dev *dev); int mt7925_mac_init(struct mt792x_dev *dev); int mt7925_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c index 1de5e41a4061..c10f14386571 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c @@ -8,6 +8,7 @@ #include "mt7925.h" #include "mac.h" #include "mcu.h" +#include "regd.h" #include "../dma.h" static const struct pci_device_id mt7925_pci_device_table[] = { diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/regd.c b/drivers/net/wireless/mediatek/mt76/mt7925/regd.c new file mode 100644 index 000000000000..8d7ce274adcd --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt7925/regd.c @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* Copyright (C) 2025 MediaTek Inc. */ + +#include "mt7925.h" +#include "regd.h" +#include "mcu.h" + +void mt7925_regd_be_ctrl(struct mt792x_dev *dev, u8 *alpha2) +{ + struct mt792x_phy *phy = &dev->phy; + struct mt7925_clc_rule_v2 *rule; + struct mt7925_clc *clc; + bool old = dev->has_eht, new = true; + u32 mtcl_conf = mt792x_acpi_get_mtcl_conf(&dev->phy, alpha2); + u8 *pos; + + if (mtcl_conf != MT792X_ACPI_MTCL_INVALID && + (((mtcl_conf >> 4) & 0x3) == 0)) { + new = false; + goto out; + } + + if (!phy->clc[MT792x_CLC_BE_CTRL]) + goto out; + + clc = (struct mt7925_clc *)phy->clc[MT792x_CLC_BE_CTRL]; + pos = clc->data; + + while (1) { + rule = (struct mt7925_clc_rule_v2 *)pos; + + if (rule->alpha2[0] == alpha2[0] && + rule->alpha2[1] == alpha2[1]) { + new = false; + break; + } + + /* Check the last one */ + if (rule->flag & BIT(0)) + break; + + pos += sizeof(*rule); + } + +out: + if (old == new) + return; + + dev->has_eht = new; + mt7925_set_stream_he_eht_caps(phy); +} + +static void +mt7925_regd_channel_update(struct wiphy *wiphy, struct mt792x_dev *dev) +{ +#define IS_UNII_INVALID(idx, sfreq, efreq, cfreq) \ + (!(dev->phy.clc_chan_conf & BIT(idx)) && (cfreq) >= (sfreq) && (cfreq) <= (efreq)) +#define MT7925_UNII_59G_IS_VALID 0x1 +#define MT7925_UNII_6G_IS_VALID 0x1e + struct ieee80211_supported_band *sband; + struct mt76_dev *mdev = &dev->mt76; + struct ieee80211_channel *ch; + u32 mtcl_conf = mt792x_acpi_get_mtcl_conf(&dev->phy, mdev->alpha2); + int i; + + if (mtcl_conf != MT792X_ACPI_MTCL_INVALID) { + if ((mtcl_conf & 0x3) == 0) + dev->phy.clc_chan_conf &= ~MT7925_UNII_59G_IS_VALID; + if (((mtcl_conf >> 2) & 0x3) == 0) + dev->phy.clc_chan_conf &= ~MT7925_UNII_6G_IS_VALID; + } + + sband = wiphy->bands[NL80211_BAND_5GHZ]; + if (!sband) + return; + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + + /* UNII-4 */ + if (IS_UNII_INVALID(0, 5845, 5925, ch->center_freq)) + ch->flags |= IEEE80211_CHAN_DISABLED; + } + + sband = wiphy->bands[NL80211_BAND_6GHZ]; + if (!sband) + return; + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + + /* UNII-5/6/7/8 */ + if (IS_UNII_INVALID(1, 5925, 6425, ch->center_freq) || + IS_UNII_INVALID(2, 6425, 6525, ch->center_freq) || + IS_UNII_INVALID(3, 6525, 6875, ch->center_freq) || + IS_UNII_INVALID(4, 6875, 7125, ch->center_freq)) + ch->flags |= IEEE80211_CHAN_DISABLED; + } +} + +void mt7925_regd_update(struct mt792x_dev *dev) +{ + struct mt76_dev *mdev = &dev->mt76; + struct ieee80211_hw *hw = mdev->hw; + struct wiphy *wiphy = hw->wiphy; + + if (!dev->regd_change) + return; + + mt7925_mcu_set_clc(dev, mdev->alpha2, dev->country_ie_env); + mt7925_regd_channel_update(wiphy, dev); + mt7925_mcu_set_channel_domain(hw->priv); + mt7925_set_tx_sar_pwr(hw, NULL); + dev->regd_change = false; +} +EXPORT_SYMBOL_GPL(mt7925_regd_update); + +void mt7925_regd_notifier(struct wiphy *wiphy, struct regulatory_request *req) +{ + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct mt792x_dev *dev = mt792x_hw_dev(hw); + struct mt76_dev *mdev = &dev->mt76; + struct mt76_connac_pm *pm = &dev->pm; + + /* allow world regdom at the first boot only */ + if (!memcmp(req->alpha2, "00", 2) && + mdev->alpha2[0] && mdev->alpha2[1]) + return; + + /* do not need to update the same country twice */ + if (!memcmp(req->alpha2, mdev->alpha2, 2) && + dev->country_ie_env == req->country_ie_env) + return; + + memcpy(mdev->alpha2, req->alpha2, 2); + mdev->region = req->dfs_region; + dev->country_ie_env = req->country_ie_env; + dev->regd_change = true; + + if (pm->suspended) + return; + + dev->regd_in_progress = true; + mt792x_mutex_acquire(dev); + mt7925_regd_update(dev); + mt792x_mutex_release(dev); + dev->regd_in_progress = false; + wake_up(&dev->wait); +} diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/regd.h b/drivers/net/wireless/mediatek/mt76/mt7925/regd.h new file mode 100644 index 000000000000..a504e71472fd --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt7925/regd.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* Copyright (C) 2025 MediaTek Inc. */ + +#ifndef __MT7925_REGD_H +#define __MT7925_REGD_H + +#include "mt7925.h" + +void mt7925_regd_be_ctrl(struct mt792x_dev *dev, u8 *alpha2); +void mt7925_regd_update(struct mt792x_dev *dev); +void mt7925_regd_notifier(struct wiphy *wiphy, struct regulatory_request *req); + +#endif + -- 2.34.1 From: Ming Yen Hsieh Move the disable_clc module parameter to regd.c and introduce mt7925_regd_clc_supported() to centralize CLC support checks. Signed-off-by: Ming Yen Hsieh --- drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 11 +++++------ drivers/net/wireless/mediatek/mt76/mt7925/regd.c | 13 +++++++++++++ drivers/net/wireless/mediatek/mt76/mt7925/regd.h | 1 + 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c index 25d26baebb17..08013fcf2cdf 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c @@ -4,16 +4,13 @@ #include #include #include "mt7925.h" +#include "regd.h" #include "mcu.h" #include "mac.h" #define MT_STA_BFER BIT(0) #define MT_STA_BFEE BIT(1) -static bool mt7925_disable_clc; -module_param_named(disable_clc, mt7925_disable_clc, bool, 0644); -MODULE_PARM_DESC(disable_clc, "disable CLC support"); - int mt7925_mcu_parse_response(struct mt76_dev *mdev, int cmd, struct sk_buff *skb, int seq) { @@ -741,8 +738,7 @@ static int mt7925_load_clc(struct mt792x_dev *dev, const char *fw_name) int ret, i, len, offset = 0; dev->phy.clc_chan_conf = 0xff; - if (mt7925_disable_clc || - mt76_is_usb(&dev->mt76)) + if (!mt7925_regd_clc_supported(dev)) return 0; if (mt76_is_mmio(&dev->mt76)) { @@ -3436,6 +3432,9 @@ int mt7925_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2, struct mt792x_phy *phy = (struct mt792x_phy *)&dev->phy; int i, ret; + if (!ARRAY_SIZE(phy->clc)) + return -ESRCH; + /* submit all clc config */ for (i = 0; i < ARRAY_SIZE(phy->clc); i++) { if (i == MT792x_CLC_BE_CTRL) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/regd.c b/drivers/net/wireless/mediatek/mt76/mt7925/regd.c index 8d7ce274adcd..9e7b468a8228 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/regd.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/regd.c @@ -5,6 +5,19 @@ #include "regd.h" #include "mcu.h" +static bool mt7925_disable_clc; +module_param_named(disable_clc, mt7925_disable_clc, bool, 0644); +MODULE_PARM_DESC(disable_clc, "disable CLC support"); + +bool mt7925_regd_clc_supported(struct mt792x_dev *dev) +{ + if (mt7925_disable_clc || + mt76_is_usb(&dev->mt76)) + return false; + + return true; +} + void mt7925_regd_be_ctrl(struct mt792x_dev *dev, u8 *alpha2) { struct mt792x_phy *phy = &dev->phy; diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/regd.h b/drivers/net/wireless/mediatek/mt76/mt7925/regd.h index a504e71472fd..5977e068c1c6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/regd.h +++ b/drivers/net/wireless/mediatek/mt76/mt7925/regd.h @@ -9,6 +9,7 @@ void mt7925_regd_be_ctrl(struct mt792x_dev *dev, u8 *alpha2); void mt7925_regd_update(struct mt792x_dev *dev); void mt7925_regd_notifier(struct wiphy *wiphy, struct regulatory_request *req); +bool mt7925_regd_clc_supported(struct mt792x_dev *dev); #endif -- 2.34.1 From: Ming Yen Hsieh Rename mt7925_regd_update() to mt7925_mcu_regd_update() to centralize regd updates with error handling. Signed-off-by: Ming Yen Hsieh --- .../net/wireless/mediatek/mt76/mt7925/pci.c | 3 +- .../net/wireless/mediatek/mt76/mt7925/regd.c | 49 +++++++++++++------ .../net/wireless/mediatek/mt76/mt7925/regd.h | 4 +- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c index c10f14386571..96bd3eb21133 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c @@ -6,6 +6,7 @@ #include #include "mt7925.h" +#include "regd.h" #include "mac.h" #include "mcu.h" #include "regd.h" @@ -585,7 +586,7 @@ static int _mt7925_pci_resume(struct device *device, bool restore) if (!pm->ds_enable) mt7925_mcu_set_deep_sleep(dev, false); - mt7925_regd_update(dev); + mt7925_mcu_regd_update(dev, mdev->alpha2, dev->country_ie_env); failed: pm->suspended = false; diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/regd.c b/drivers/net/wireless/mediatek/mt76/mt7925/regd.c index 9e7b468a8228..b36c6a6f5da6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/regd.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/regd.c @@ -111,29 +111,49 @@ mt7925_regd_channel_update(struct wiphy *wiphy, struct mt792x_dev *dev) } } -void mt7925_regd_update(struct mt792x_dev *dev) +int mt7925_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2, + enum environment_cap country_ie_env) { - struct mt76_dev *mdev = &dev->mt76; - struct ieee80211_hw *hw = mdev->hw; + struct ieee80211_hw *hw = mt76_hw(dev); struct wiphy *wiphy = hw->wiphy; + int ret = 0; + + dev->regd_in_progress = true; + mt792x_mutex_acquire(dev); if (!dev->regd_change) - return; + goto err; + + ret = mt7925_mcu_set_clc(dev, alpha2, country_ie_env); + if (ret < 0) + goto err; - mt7925_mcu_set_clc(dev, mdev->alpha2, dev->country_ie_env); mt7925_regd_channel_update(wiphy, dev); - mt7925_mcu_set_channel_domain(hw->priv); - mt7925_set_tx_sar_pwr(hw, NULL); + + ret = mt7925_mcu_set_channel_domain(hw->priv); + if (ret < 0) + goto err; + + ret = mt7925_set_tx_sar_pwr(hw, NULL); + if (ret < 0) + goto err; + +err: + mt792x_mutex_release(dev); dev->regd_change = false; + dev->regd_in_progress = false; + wake_up(&dev->wait); + + return ret; } -EXPORT_SYMBOL_GPL(mt7925_regd_update); +EXPORT_SYMBOL_GPL(mt7925_mcu_regd_update); void mt7925_regd_notifier(struct wiphy *wiphy, struct regulatory_request *req) { struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct mt792x_dev *dev = mt792x_hw_dev(hw); - struct mt76_dev *mdev = &dev->mt76; struct mt76_connac_pm *pm = &dev->pm; + struct mt76_dev *mdev = &dev->mt76; /* allow world regdom at the first boot only */ if (!memcmp(req->alpha2, "00", 2) && @@ -148,15 +168,14 @@ void mt7925_regd_notifier(struct wiphy *wiphy, struct regulatory_request *req) memcpy(mdev->alpha2, req->alpha2, 2); mdev->region = req->dfs_region; dev->country_ie_env = req->country_ie_env; + dev->regd_change = true; if (pm->suspended) + /* postpone the mcu update to resume */ return; - dev->regd_in_progress = true; - mt792x_mutex_acquire(dev); - mt7925_regd_update(dev); - mt792x_mutex_release(dev); - dev->regd_in_progress = false; - wake_up(&dev->wait); + mt7925_mcu_regd_update(dev, req->alpha2, + req->country_ie_env); + return; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/regd.h b/drivers/net/wireless/mediatek/mt76/mt7925/regd.h index 5977e068c1c6..edcda72b12b0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/regd.h +++ b/drivers/net/wireless/mediatek/mt76/mt7925/regd.h @@ -6,8 +6,10 @@ #include "mt7925.h" +int mt7925_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2, + enum environment_cap country_ie_env); + void mt7925_regd_be_ctrl(struct mt792x_dev *dev, u8 *alpha2); -void mt7925_regd_update(struct mt792x_dev *dev); void mt7925_regd_notifier(struct wiphy *wiphy, struct regulatory_request *req); bool mt7925_regd_clc_supported(struct mt792x_dev *dev); -- 2.34.1 From: Ming Yen Hsieh Move EHT flag handling into mt7925_regd_channel_update() to ensure correct channel capability reporting. Signed-off-by: Ming Yen Hsieh --- .../net/wireless/mediatek/mt76/mt7925/main.c | 2 -- .../net/wireless/mediatek/mt76/mt7925/regd.c | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c index f9993f191448..92d7a6eb4179 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c @@ -1376,8 +1376,6 @@ void mt7925_scan_work(struct work_struct *work) if (!is_valid_alpha2(evt->alpha2)) break; - mt7925_regd_be_ctrl(phy->dev, evt->alpha2); - if (mdev->alpha2[0] != '0' && mdev->alpha2[1] != '0') break; diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/regd.c b/drivers/net/wireless/mediatek/mt76/mt7925/regd.c index b36c6a6f5da6..12d8aac16e34 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/regd.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/regd.c @@ -83,6 +83,17 @@ mt7925_regd_channel_update(struct wiphy *wiphy, struct mt792x_dev *dev) dev->phy.clc_chan_conf &= ~MT7925_UNII_6G_IS_VALID; } + sband = wiphy->bands[NL80211_BAND_2GHZ]; + if (!sband) + return; + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + + if (!dev->has_eht) + ch->flags |= IEEE80211_CHAN_NO_EHT; + } + sband = wiphy->bands[NL80211_BAND_5GHZ]; if (!sband) return; @@ -93,6 +104,9 @@ mt7925_regd_channel_update(struct wiphy *wiphy, struct mt792x_dev *dev) /* UNII-4 */ if (IS_UNII_INVALID(0, 5845, 5925, ch->center_freq)) ch->flags |= IEEE80211_CHAN_DISABLED; + + if (!dev->has_eht) + ch->flags |= IEEE80211_CHAN_NO_EHT; } sband = wiphy->bands[NL80211_BAND_6GHZ]; @@ -108,6 +122,9 @@ mt7925_regd_channel_update(struct wiphy *wiphy, struct mt792x_dev *dev) IS_UNII_INVALID(3, 6525, 6875, ch->center_freq) || IS_UNII_INVALID(4, 6875, 7125, ch->center_freq)) ch->flags |= IEEE80211_CHAN_DISABLED; + + if (!dev->has_eht) + ch->flags |= IEEE80211_CHAN_NO_EHT; } } @@ -128,6 +145,7 @@ int mt7925_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2, if (ret < 0) goto err; + mt7925_regd_be_ctrl(dev, alpha2); mt7925_regd_channel_update(wiphy, dev); ret = mt7925_mcu_set_channel_domain(hw->priv); -- 2.34.1 From: Ming Yen Hsieh Implement 802.11d-based automatic regulatory domain switching to dynamically determine the regulatory domain at runtime. Signed-off-by: Ming Yen Hsieh --- .../net/wireless/mediatek/mt76/mt7925/init.c | 2 - .../net/wireless/mediatek/mt76/mt7925/mac.c | 5 +- .../net/wireless/mediatek/mt76/mt7925/main.c | 23 +------ .../net/wireless/mediatek/mt76/mt7925/mcu.c | 1 + .../net/wireless/mediatek/mt76/mt7925/regd.c | 61 +++++++++++++++++++ .../net/wireless/mediatek/mt76/mt7925/regd.h | 2 + drivers/net/wireless/mediatek/mt76/mt792x.h | 1 + 7 files changed, 68 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/init.c b/drivers/net/wireless/mediatek/mt76/mt7925/init.c index 741e38b29b77..36f7e98f256c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/init.c @@ -91,8 +91,6 @@ int mt7925_mac_init(struct mt792x_dev *dev) mt7925_mac_init_basic_rates(dev); - memzero_explicit(&dev->mt76.alpha2, sizeof(dev->mt76.alpha2)); - return 0; } EXPORT_SYMBOL_GPL(mt7925_mac_init); diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c index 643ab03ee28e..fa75fb5879ba 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c @@ -6,6 +6,7 @@ #include #include "mt7925.h" #include "../dma.h" +#include "regd.h" #include "mac.h" #include "mcu.h" @@ -1332,9 +1333,7 @@ void mt7925_mac_reset_work(struct work_struct *work) mt7925_vif_connect_iter, NULL); mt76_connac_power_save_sched(&dev->mt76.phy, pm); - mt792x_mutex_acquire(dev); - mt7925_mcu_set_clc(dev, "00", ENVIRON_INDOOR); - mt792x_mutex_release(dev); + mt7925_regd_change(&dev->phy, "00"); } void mt7925_coredump_work(struct work_struct *work) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c index 92d7a6eb4179..62e9c2655749 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c @@ -1320,20 +1320,6 @@ void mt7925_mlo_pm_work(struct work_struct *work) mt7925_mlo_pm_iter, dev); } -static bool is_valid_alpha2(const char *alpha2) -{ - if (!alpha2) - return false; - - if (alpha2[0] == '0' && alpha2[1] == '0') - return true; - - if (isalpha(alpha2[0]) && isalpha(alpha2[1])) - return true; - - return false; -} - void mt7925_scan_work(struct work_struct *work) { struct mt792x_phy *phy; @@ -1342,7 +1328,6 @@ void mt7925_scan_work(struct work_struct *work) scan_work.work); while (true) { - struct mt76_dev *mdev = &phy->dev->mt76; struct sk_buff *skb; struct tlv *tlv; int tlv_len; @@ -1373,13 +1358,7 @@ void mt7925_scan_work(struct work_struct *work) case UNI_EVENT_SCAN_DONE_CHNLINFO: evt = (struct mt7925_mcu_scan_chinfo_event *)tlv->data; - if (!is_valid_alpha2(evt->alpha2)) - break; - - if (mdev->alpha2[0] != '0' && mdev->alpha2[1] != '0') - break; - - mt7925_mcu_set_clc(phy->dev, evt->alpha2, ENVIRON_INDOOR); + mt7925_regd_change(phy, evt->alpha2); break; case UNI_EVENT_SCAN_DONE_NLO: diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c index 08013fcf2cdf..fe1a7e386fc7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c @@ -808,6 +808,7 @@ static int mt7925_load_clc(struct mt792x_dev *dev, const char *fw_name) } } + ret = mt7925_regd_init(phy); out: release_firmware(fw); diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/regd.c b/drivers/net/wireless/mediatek/mt76/mt7925/regd.c index 12d8aac16e34..4565e1132b36 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/regd.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/regd.c @@ -197,3 +197,64 @@ void mt7925_regd_notifier(struct wiphy *wiphy, struct regulatory_request *req) req->country_ie_env); return; } + +static bool +mt7925_regd_is_valid_alpha2(const char *alpha2) +{ + if (!alpha2) + return false; + + if (alpha2[0] == '0' && alpha2[1] == '0') + return true; + + if (isalpha(alpha2[0]) && isalpha(alpha2[1])) + return true; + + return false; +} + +int mt7925_regd_change(struct mt792x_phy *phy, char *alpha2) +{ + struct wiphy *wiphy = phy->mt76->hw->wiphy; + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct mt792x_dev *dev = mt792x_hw_dev(hw); + struct mt76_dev *mdev = &dev->mt76; + + if (dev->hw_full_reset) + return 0; + + if (!mt7925_regd_is_valid_alpha2(alpha2) || + !mt7925_regd_clc_supported(dev)) + return -EINVAL; + + if (mdev->alpha2[0] != '0' && mdev->alpha2[1] != '0') + return 0; + + /* do not need to update the same country twice */ + if (!memcmp(alpha2, mdev->alpha2, 2)) + return 0; + + if (phy->chip_cap & MT792x_CHIP_CAP_11D_EN) { + return regulatory_hint(wiphy, alpha2); + } else { + return mt7925_mcu_set_clc(dev, alpha2, ENVIRON_INDOOR); + } +} +EXPORT_SYMBOL_GPL(mt7925_regd_change); + +int mt7925_regd_init(struct mt792x_phy *phy) +{ + struct wiphy *wiphy = phy->mt76->hw->wiphy; + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct mt792x_dev *dev = mt792x_hw_dev(hw); + struct mt76_dev *mdev = &dev->mt76; + + if (phy->chip_cap & MT792x_CHIP_CAP_11D_EN) { + wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE | + REGULATORY_DISABLE_BEACON_HINTS; + } else { + memzero_explicit(&mdev->alpha2, sizeof(mdev->alpha2)); + } + + return 0; +} diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/regd.h b/drivers/net/wireless/mediatek/mt76/mt7925/regd.h index edcda72b12b0..0767f078862e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/regd.h +++ b/drivers/net/wireless/mediatek/mt76/mt7925/regd.h @@ -12,6 +12,8 @@ int mt7925_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2, void mt7925_regd_be_ctrl(struct mt792x_dev *dev, u8 *alpha2); void mt7925_regd_notifier(struct wiphy *wiphy, struct regulatory_request *req); bool mt7925_regd_clc_supported(struct mt792x_dev *dev); +int mt7925_regd_change(struct mt792x_phy *phy, char *alpha2); +int mt7925_regd_init(struct mt792x_phy *phy); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt792x.h b/drivers/net/wireless/mediatek/mt76/mt792x.h index da7831f9efec..ed2606e9251a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt792x.h +++ b/drivers/net/wireless/mediatek/mt76/mt792x.h @@ -28,6 +28,7 @@ #define MT792x_CHIP_CAP_CLC_EVT_EN BIT(0) #define MT792x_CHIP_CAP_RSSI_NOTIFY_EVT_EN BIT(1) #define MT792x_CHIP_CAP_WF_RF_PIN_CTRL_EVT_EN BIT(3) +#define MT792x_CHIP_CAP_11D_EN BIT(4) #define MT792x_CHIP_CAP_MLO_EN BIT(8) #define MT792x_CHIP_CAP_MLO_EML_EN BIT(9) -- 2.34.1 From: Ming Yen Hsieh Add regd_user flag to block automatic regulatory domain updates if set by user. Signed-off-by: Ming Yen Hsieh --- drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 1 + drivers/net/wireless/mediatek/mt76/mt7925/regd.c | 7 ++++++- drivers/net/wireless/mediatek/mt76/mt792x.h | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c index fe1a7e386fc7..ac3049360bab 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c @@ -738,6 +738,7 @@ static int mt7925_load_clc(struct mt792x_dev *dev, const char *fw_name) int ret, i, len, offset = 0; dev->phy.clc_chan_conf = 0xff; + dev->regd_user = false; if (!mt7925_regd_clc_supported(dev)) return 0; diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/regd.c b/drivers/net/wireless/mediatek/mt76/mt7925/regd.c index 4565e1132b36..292087e882d1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/regd.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/regd.c @@ -173,6 +173,10 @@ void mt7925_regd_notifier(struct wiphy *wiphy, struct regulatory_request *req) struct mt76_connac_pm *pm = &dev->pm; struct mt76_dev *mdev = &dev->mt76; + if (req->initiator == NL80211_REGDOM_SET_BY_USER && + !dev->regd_user) + dev->regd_user = true; + /* allow world regdom at the first boot only */ if (!memcmp(req->alpha2, "00", 2) && mdev->alpha2[0] && mdev->alpha2[1]) @@ -224,7 +228,8 @@ int mt7925_regd_change(struct mt792x_phy *phy, char *alpha2) return 0; if (!mt7925_regd_is_valid_alpha2(alpha2) || - !mt7925_regd_clc_supported(dev)) + !mt7925_regd_clc_supported(dev) || + dev->regd_user) return -EINVAL; if (mdev->alpha2[0] != '0' && mdev->alpha2[1] != '0') diff --git a/drivers/net/wireless/mediatek/mt76/mt792x.h b/drivers/net/wireless/mediatek/mt76/mt792x.h index ed2606e9251a..8388638ed550 100644 --- a/drivers/net/wireless/mediatek/mt76/mt792x.h +++ b/drivers/net/wireless/mediatek/mt76/mt792x.h @@ -231,6 +231,7 @@ struct mt792x_dev { bool hw_init_done:1; bool fw_assert:1; bool has_eht:1; + bool regd_user:1; bool regd_in_progress:1; bool aspm_supported:1; bool hif_idle:1; -- 2.34.1