From b8a08a51577d9cc3e5b9982f9359179deb7d8b36 Mon Sep 17 00:00:00 2001
From: Shayne Chen <shayne.chen@mediatek.com>
Date: Thu, 16 Mar 2023 12:35:19 +0800
Subject: [PATCH 02/70] sync backport patches/ath

---
 drivers/net/wireless/ath/Kconfig       |  5 +-
 drivers/net/wireless/ath/Makefile      |  2 +-
 drivers/net/wireless/ath/ath.h         |  7 ---
 drivers/net/wireless/ath/ath5k/pci.c   | 26 +++++++++-
 drivers/net/wireless/ath/regd.c        | 72 ++++++++++++++++++--------
 drivers/net/wireless/ath/regd_common.h |  3 ++
 local-symbols                          |  1 +
 net/wireless/reg.c                     |  3 ++
 8 files changed, 88 insertions(+), 31 deletions(-)

diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index 9ef8d46..bd576b4 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: ISC
 config ATH_COMMON
-	tristate
+	tristate "ath.ko"
 	depends on m
 
 config WLAN_VENDOR_ATH
@@ -24,6 +24,9 @@ config WLAN_VENDOR_ATH
 
 if WLAN_VENDOR_ATH
 
+config ATH_USER_REGD
+	bool "Do not enforce EEPROM regulatory restrictions"
+
 config ATH_DEBUG
 	bool "Atheros wireless debugging"
 	help
diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile
index 7432d87..adea25c 100644
--- a/drivers/net/wireless/ath/Makefile
+++ b/drivers/net/wireless/ath/Makefile
@@ -16,10 +16,10 @@ ath-objs :=	main.o \
 		regd.o \
 		hw.o \
 		key.o \
+		debug.o \
 		dfs_pattern_detector.o \
 		dfs_pri_detector.o
 
-ath-$(CPTCFG_ATH_DEBUG) += debug.o
 ath-$(CPTCFG_ATH_TRACEPOINTS) += trace.o
 
 CFLAGS_trace.o := -I$(src)
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 8b2ef78..cfe535a 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -317,14 +317,7 @@ void _ath_dbg(struct ath_common *common, enum ATH_DEBUG dbg_mask,
 #endif /* CPTCFG_ATH_DEBUG */
 
 /** Returns string describing opmode, or NULL if unknown mode. */
-#ifdef CPTCFG_ATH_DEBUG
 const char *ath_opmode_to_string(enum nl80211_iftype opmode);
-#else
-static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode)
-{
-	return "UNKNOWN";
-}
-#endif
 
 extern const char *ath_bus_type_strings[];
 static inline const char *ath_bus_type_to_string(enum ath_bus_type bustype)
diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c
index 86b8cb9..6c724fa 100644
--- a/drivers/net/wireless/ath/ath5k/pci.c
+++ b/drivers/net/wireless/ath/ath5k/pci.c
@@ -20,6 +20,7 @@
 #include <linux/pci.h>
 #include <linux/etherdevice.h>
 #include <linux/module.h>
+#include <linux/ath5k_platform.h>
 #include "../ath.h"
 #include "ath5k.h"
 #include "debug.h"
@@ -71,7 +72,7 @@ static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz)
 }
 
 /*
- * Read from eeprom
+ * Read from eeprom or platform_data
  */
 static bool
 ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data)
@@ -79,6 +80,19 @@ ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data)
 	struct ath5k_hw *ah = (struct ath5k_hw *) common->ah;
 	u32 status, timeout;
 
+	struct ath5k_platform_data *pdata = NULL;
+
+	if (ah->pdev)
+		pdata = ah->pdev->dev.platform_data;
+
+	if (pdata && pdata->eeprom_data && pdata->eeprom_data[61] == AR5K_EEPROM_MAGIC_VALUE) {
+		if (offset >= ATH5K_PLAT_EEP_MAX_WORDS)
+			return false;
+
+		*data = pdata->eeprom_data[offset];
+		return true;
+	}
+
 	/*
 	 * Initialize EEPROM access
 	 */
@@ -122,6 +136,16 @@ static int ath5k_pci_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
 	u16 data;
 	int octet;
 
+	struct ath5k_platform_data *pdata = NULL;
+
+	if (ah->pdev)
+		pdata = ah->pdev->dev.platform_data;
+
+	if (pdata && pdata->macaddr) {
+		memcpy(mac, pdata->macaddr, ETH_ALEN);
+		return 0;
+	}
+
 	AR5K_EEPROM_READ(0x20, data);
 
 	for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index 2afdebf..3ba9fc3 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -24,6 +24,7 @@
 #include "regd_common.h"
 
 static int __ath_regd_init(struct ath_regulatory *reg);
+static struct reg_dmn_pair_mapping *ath_get_regpair(int regdmn);
 
 /*
  * This is a set of common rules used by our world regulatory domains.
@@ -43,7 +44,8 @@ static int __ath_regd_init(struct ath_regulatory *reg);
 					 NL80211_RRF_NO_OFDM)
 
 /* We allow IBSS on these on a case by case basis by regulatory domain */
-#define ATH_5GHZ_5150_5350	REG_RULE(5150-10, 5350+10, 80, 0, 30,\
+#define ATH_5GHZ_5150_5350	REG_RULE(5150-10, 5240+10, 80, 0, 30, 0),\
+				REG_RULE(5260-10, 5350+10, 80, 0, 30,\
 					 NL80211_RRF_NO_IR)
 #define ATH_5GHZ_5470_5850	REG_RULE(5470-10, 5850+10, 80, 0, 30,\
 					 NL80211_RRF_NO_IR)
@@ -61,64 +63,79 @@ static int __ath_regd_init(struct ath_regulatory *reg);
 #define ATH_5GHZ_NO_MIDBAND	ATH_5GHZ_5150_5350, \
 				ATH_5GHZ_5725_5850
 
+#define REGD_RULES(...) \
+	.reg_rules = { __VA_ARGS__ }, \
+	.n_reg_rules = ARRAY_SIZE(((struct ieee80211_reg_rule[]) { __VA_ARGS__ }))
+
 /* Can be used for:
  * 0x60, 0x61, 0x62 */
 static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = {
-	.n_reg_rules = 5,
 	.alpha2 =  "99",
-	.reg_rules = {
+	REGD_RULES(
 		ATH_2GHZ_ALL,
 		ATH_5GHZ_ALL,
-	}
+	)
 };
 
 /* Can be used by 0x63 and 0x65 */
 static const struct ieee80211_regdomain ath_world_regdom_63_65 = {
-	.n_reg_rules = 4,
 	.alpha2 =  "99",
-	.reg_rules = {
+	REGD_RULES(
 		ATH_2GHZ_CH01_11,
 		ATH_2GHZ_CH12_13,
 		ATH_5GHZ_NO_MIDBAND,
-	}
+	)
 };
 
 /* Can be used by 0x64 only */
 static const struct ieee80211_regdomain ath_world_regdom_64 = {
-	.n_reg_rules = 3,
 	.alpha2 =  "99",
-	.reg_rules = {
+	REGD_RULES(
 		ATH_2GHZ_CH01_11,
 		ATH_5GHZ_NO_MIDBAND,
-	}
+	)
 };
 
 /* Can be used by 0x66 and 0x69 */
 static const struct ieee80211_regdomain ath_world_regdom_66_69 = {
-	.n_reg_rules = 3,
 	.alpha2 =  "99",
-	.reg_rules = {
+	REGD_RULES(
 		ATH_2GHZ_CH01_11,
 		ATH_5GHZ_ALL,
-	}
+	)
 };
 
 /* Can be used by 0x67, 0x68, 0x6A and 0x6C */
 static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = {
-	.n_reg_rules = 4,
 	.alpha2 =  "99",
-	.reg_rules = {
+	REGD_RULES(
 		ATH_2GHZ_CH01_11,
 		ATH_2GHZ_CH12_13,
 		ATH_5GHZ_ALL,
-	}
+	)
 };
 
+static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
+{
+	return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
+}
+
+static bool is_default_regd(struct ath_regulatory *reg)
+{
+	return ath_regd_get_eepromRD(reg) == CTRY_DEFAULT;
+}
+
 static bool dynamic_country_user_possible(struct ath_regulatory *reg)
 {
+	if (IS_ENABLED(CPTCFG_ATH_USER_REGD))
+		return true;
+
 	if (IS_ENABLED(CPTCFG_ATH_REG_DYNAMIC_USER_CERT_TESTING))
 		return true;
 
+	if (is_default_regd(reg))
+		return true;
+
 	switch (reg->country_code) {
 	case CTRY_UNITED_STATES:
 	case CTRY_JAPAN1:
@@ -188,6 +205,8 @@ static bool dynamic_country_user_possible(struct ath_regulatory *reg)
 
 static bool ath_reg_dyn_country_user_allow(struct ath_regulatory *reg)
 {
+	if (IS_ENABLED(CPTCFG_ATH_USER_REGD))
+		return true;
 	if (!IS_ENABLED(CPTCFG_ATH_REG_DYNAMIC_USER_REG_HINTS))
 		return false;
 	if (!dynamic_country_user_possible(reg))
@@ -202,11 +221,6 @@ static inline bool is_wwr_sku(u16 regd)
 		(regd == WORLD));
 }
 
-static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
-{
-	return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
-}
-
 bool ath_is_world_regd(struct ath_regulatory *reg)
 {
 	return is_wwr_sku(ath_regd_get_eepromRD(reg));
@@ -345,6 +359,9 @@ ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
 	struct ieee80211_channel *ch;
 	unsigned int i;
 
+	if (IS_ENABLED(CPTCFG_ATH_USER_REGD))
+		return;
+
 	for (band = 0; band < NUM_NL80211_BANDS; band++) {
 		if (!wiphy->bands[band])
 			continue;
@@ -379,6 +396,9 @@ ath_reg_apply_ir_flags(struct wiphy *wiphy,
 {
 	struct ieee80211_supported_band *sband;
 
+	if (IS_ENABLED(CPTCFG_ATH_USER_REGD))
+		return;
+
 	sband = wiphy->bands[NL80211_BAND_2GHZ];
 	if (!sband)
 		return;
@@ -408,6 +428,9 @@ static void ath_reg_apply_radar_flags(struct wiphy *wiphy,
 	struct ieee80211_channel *ch;
 	unsigned int i;
 
+	if (IS_ENABLED(CPTCFG_ATH_USER_REGD))
+		return;
+
 	if (!wiphy->bands[NL80211_BAND_5GHZ])
 		return;
 
@@ -640,6 +663,13 @@ ath_regd_init_wiphy(struct ath_regulatory *reg,
 	const struct ieee80211_regdomain *regd;
 
 	wiphy->reg_notifier = reg_notifier;
+
+	if (IS_ENABLED(CPTCFG_ATH_USER_REGD))
+		return 0;
+
+	if (is_default_regd(reg))
+		return 0;
+
 	wiphy->regulatory_flags |= REGULATORY_STRICT_REG |
 				   REGULATORY_CUSTOM_REG;
 
diff --git a/drivers/net/wireless/ath/regd_common.h b/drivers/net/wireless/ath/regd_common.h
index cdb1e9a..2574f80 100644
--- a/drivers/net/wireless/ath/regd_common.h
+++ b/drivers/net/wireless/ath/regd_common.h
@@ -32,6 +32,7 @@ enum EnumRd {
 	FCC2_WORLD = 0x21,
 	FCC2_ETSIC = 0x22,
 	FCC6_WORLD = 0x23,
+	FCC3_FCCA_2 = 0x2A,
 	FRANCE_RES = 0x31,
 	FCC3_FCCA = 0x3A,
 	FCC3_WORLD = 0x3B,
@@ -173,6 +174,7 @@ static struct reg_dmn_pair_mapping regDomainPairs[] = {
 	{FCC2_WORLD, CTL_FCC, CTL_ETSI},
 	{FCC2_ETSIC, CTL_FCC, CTL_ETSI},
 	{FCC3_FCCA, CTL_FCC, CTL_FCC},
+	{FCC3_FCCA_2, CTL_FCC, CTL_FCC},
 	{FCC3_WORLD, CTL_FCC, CTL_ETSI},
 	{FCC3_ETSIC, CTL_FCC, CTL_ETSI},
 	{FCC4_FCCA, CTL_FCC, CTL_FCC},
@@ -486,6 +488,7 @@ static struct country_code_to_enum_rd allCountries[] = {
 	{CTRY_UAE, NULL1_WORLD, "AE"},
 	{CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"},
 	{CTRY_UNITED_STATES, FCC3_FCCA, "US"},
+	{CTRY_UNITED_STATES, FCC3_FCCA_2, "US"},
 	{CTRY_UNITED_STATES2, FCC3_FCCA, "US"},
 	{CTRY_UNITED_STATES3, FCC3_FCCA, "US"},
 	/* This "PS" is for US public safety actually... to support this we
diff --git a/local-symbols b/local-symbols
index dcecb87..c750661 100644
--- a/local-symbols
+++ b/local-symbols
@@ -104,6 +104,7 @@ ADM8211=
 ATH_COMMON=
 WLAN_VENDOR_ATH=
 ATH_DEBUG=
+ATH_USER_REGD=
 ATH_TRACEPOINTS=
 ATH_REG_DYNAMIC_USER_REG_HINTS=
 ATH_REG_DYNAMIC_USER_CERT_TESTING=
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index a8704fa..46ecfb2 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -3335,6 +3335,8 @@ void regulatory_hint_country_ie(struct wiphy *wiphy, enum nl80211_band band,
 	enum environment_cap env = ENVIRON_ANY;
 	struct regulatory_request *request = NULL, *lr;
 
+	return;
+
 	/* IE len must be evenly divisible by 2 */
 	if (country_ie_len & 0x01)
 		return;
@@ -3586,6 +3588,7 @@ static bool is_wiphy_all_set_reg_flag(enum ieee80211_regulatory_flags flag)
 
 void regulatory_hint_disconnect(void)
 {
+	return;
 	/* Restore of regulatory settings is not required when wiphy(s)
 	 * ignore IE from connected access point but clearance of beacon hints
 	 * is required when wiphy(s) supports beacon hints.
-- 
2.39.2

