Commit 3bc62aa4 authored by Ming Yen Hsieh's avatar Ming Yen Hsieh Committed by Felix Fietkau
Browse files

wifi: mt76: mt7925: add auto regdomain switch support



Implement 802.11d-based automatic regulatory domain switching to
dynamically determine the regulatory domain at runtime.

Signed-off-by: default avatarMing Yen Hsieh <mingyen.hsieh@mediatek.com>
Link: https://patch.msgid.link/20251031090352.1400079-6-mingyen.hsieh@mediatek.com


Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 6338709a
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -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);
+2 −3
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
#include <linux/timekeeping.h>
#include "mt7925.h"
#include "../dma.h"
#include "regd.h"
#include "mac.h"
#include "mcu.h"

@@ -1329,9 +1330,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)
+1 −22
Original line number Diff line number Diff line
@@ -1313,20 +1313,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;
@@ -1335,7 +1321,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;
@@ -1366,13 +1351,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:
+1 −0
Original line number Diff line number Diff line
@@ -755,6 +755,7 @@ static int mt7925_load_clc(struct mt792x_dev *dev, const char *fw_name)
		}
	}

	ret = mt7925_regd_init(phy);
out:
	release_firmware(fw);

+61 −0
Original line number Diff line number Diff line
@@ -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;
}
Loading