| From 429745cbf1435d31a656d4d912b7ea1cdd271be2 Mon Sep 17 00:00:00 2001 |
| From: Shayne Chen <shayne.chen@mediatek.com> |
| Date: Tue, 12 Mar 2024 11:26:07 +0800 |
| Subject: [PATCH 02/61] sync backports patches/ath |
| |
| --- |
| drivers/net/wireless/ath/Kconfig | 5 +- |
| drivers/net/wireless/ath/Makefile | 2 +- |
| drivers/net/wireless/ath/ath.h | 17 ++--- |
| drivers/net/wireless/ath/ath5k/ani.c | 2 +- |
| drivers/net/wireless/ath/ath5k/base.c | 4 +- |
| drivers/net/wireless/ath/ath5k/mac80211-ops.c | 2 +- |
| drivers/net/wireless/ath/ath5k/pci.c | 26 ++++++- |
| drivers/net/wireless/ath/ath9k/link.c | 2 +- |
| drivers/net/wireless/ath/ath9k/main.c | 4 +- |
| drivers/net/wireless/ath/hw.c | 2 +- |
| drivers/net/wireless/ath/regd.c | 72 +++++++++++++------ |
| drivers/net/wireless/ath/regd_common.h | 3 + |
| local-symbols | 1 + |
| net/wireless/reg.c | 3 + |
| 14 files changed, 102 insertions(+), 43 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 e9d95c7..888c5e2 100644 |
| --- a/drivers/net/wireless/ath/ath.h |
| +++ b/drivers/net/wireless/ath/ath.h |
| @@ -43,10 +43,12 @@ struct ath_ani { |
| }; |
| |
| struct ath_cycle_counters { |
| - u32 cycles; |
| - u32 rx_busy; |
| - u32 rx_frame; |
| - u32 tx_frame; |
| + struct_group(cnts, |
| + u32 cycles; |
| + u32 rx_busy; |
| + u32 rx_frame; |
| + u32 tx_frame; |
| + ); |
| }; |
| |
| enum ath_device_state { |
| @@ -319,14 +321,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/ani.c b/drivers/net/wireless/ath/ath5k/ani.c |
| index 11fd1ca..897cfd9 100644 |
| --- a/drivers/net/wireless/ath/ath5k/ani.c |
| +++ b/drivers/net/wireless/ath/ath5k/ani.c |
| @@ -379,7 +379,7 @@ ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as) |
| spin_lock_bh(&common->cc_lock); |
| |
| ath_hw_cycle_counters_update(common); |
| - memcpy(&as->last_cc, &common->cc_ani, sizeof(as->last_cc)); |
| + memcpy(&as->last_cc.cnts, &common->cc_ani.cnts, sizeof(as->last_cc.cnts)); |
| |
| /* clears common->cc_ani */ |
| listen = ath_hw_get_listen_time(common); |
| diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c |
| index 7ec5d9a..bad83fd 100644 |
| --- a/drivers/net/wireless/ath/ath5k/base.c |
| +++ b/drivers/net/wireless/ath/ath5k/base.c |
| @@ -2985,8 +2985,8 @@ ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan, |
| memset(&ah->survey, 0, sizeof(ah->survey)); |
| spin_lock_bh(&common->cc_lock); |
| ath_hw_cycle_counters_update(common); |
| - memset(&common->cc_survey, 0, sizeof(common->cc_survey)); |
| - memset(&common->cc_ani, 0, sizeof(common->cc_ani)); |
| + memset(&common->cc_survey.cnts, 0, sizeof(common->cc_survey.cnts)); |
| + memset(&common->cc_ani.cnts, 0, sizeof(common->cc_ani.cnts)); |
| spin_unlock_bh(&common->cc_lock); |
| |
| /* |
| diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c |
| index eea4bda..da9dc62 100644 |
| --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c |
| +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c |
| @@ -664,7 +664,7 @@ ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey) |
| ah->survey.time_rx += cc->rx_frame / div; |
| ah->survey.time_tx += cc->tx_frame / div; |
| } |
| - memset(cc, 0, sizeof(*cc)); |
| + memset(&cc->cnts, 0, sizeof(cc->cnts)); |
| spin_unlock_bh(&common->cc_lock); |
| |
| memcpy(survey, &ah->survey, sizeof(*survey)); |
| diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c |
| index b51fce5..c4315dd 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 = 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/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c |
| index d1e5767..7f18d71 100644 |
| --- a/drivers/net/wireless/ath/ath9k/link.c |
| +++ b/drivers/net/wireless/ath/ath9k/link.c |
| @@ -536,7 +536,7 @@ int ath_update_survey_stats(struct ath_softc *sc) |
| if (cc->cycles > 0) |
| ret = cc->rx_busy * 100 / cc->cycles; |
| |
| - memset(cc, 0, sizeof(*cc)); |
| + memset(&cc->cnts, 0, sizeof(cc->cnts)); |
| |
| ath_update_survey_nf(sc, pos); |
| |
| diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c |
| index 34d11b0..6d120df 100644 |
| --- a/drivers/net/wireless/ath/ath9k/main.c |
| +++ b/drivers/net/wireless/ath/ath9k/main.c |
| @@ -135,8 +135,8 @@ void ath9k_ps_wakeup(struct ath_softc *sc) |
| if (power_mode != ATH9K_PM_AWAKE) { |
| spin_lock(&common->cc_lock); |
| ath_hw_cycle_counters_update(common); |
| - memset(&common->cc_survey, 0, sizeof(common->cc_survey)); |
| - memset(&common->cc_ani, 0, sizeof(common->cc_ani)); |
| + memset(&common->cc_survey.cnts, 0, sizeof(common->cc_survey.cnts)); |
| + memset(&common->cc_ani.cnts, 0, sizeof(common->cc_ani.cnts)); |
| spin_unlock(&common->cc_lock); |
| } |
| |
| diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c |
| index 8595557..be8bfed 100644 |
| --- a/drivers/net/wireless/ath/hw.c |
| +++ b/drivers/net/wireless/ath/hw.c |
| @@ -183,7 +183,7 @@ int32_t ath_hw_get_listen_time(struct ath_common *common) |
| listen_time = (cc->cycles - cc->rx_frame - cc->tx_frame) / |
| (common->clockrate * 1000); |
| |
| - memset(cc, 0, sizeof(*cc)); |
| + memset(&cc->cnts, 0, sizeof(cc->cnts)); |
| |
| return listen_time; |
| } |
| 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 0743888..b200b00 100644 |
| --- a/local-symbols |
| +++ b/local-symbols |
| @@ -101,6 +101,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 233ebab..2c0c1f1 100644 |
| --- a/net/wireless/reg.c |
| +++ b/net/wireless/reg.c |
| @@ -3365,6 +3365,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; |
| @@ -3616,6 +3618,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 |
| |