--- 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. @@ -116,6 +117,9 @@ static const struct ieee80211_regdomain static bool dynamic_country_user_possible(struct ath_regulatory *reg) { + if (IS_ENABLED(CONFIG_ATH_USER_REGD)) + return true; + if (IS_ENABLED(CONFIG_ATH_REG_DYNAMIC_USER_CERT_TESTING)) return true; @@ -188,6 +192,8 @@ static bool dynamic_country_user_possibl static bool ath_reg_dyn_country_user_allow(struct ath_regulatory *reg) { + if (IS_ENABLED(CONFIG_ATH_USER_REGD)) + return true; if (!IS_ENABLED(CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS)) return false; if (!dynamic_country_user_possible(reg)) @@ -345,6 +351,9 @@ ath_reg_apply_beaconing_flags(struct wip struct ieee80211_channel *ch; unsigned int i; + if (IS_ENABLED(CONFIG_ATH_USER_REGD)) + return; + for (band = 0; band < NUM_NL80211_BANDS; band++) { if (!wiphy->bands[band]) continue; @@ -379,6 +388,9 @@ ath_reg_apply_ir_flags(struct wiphy *wip { struct ieee80211_supported_band *sband; + if (IS_ENABLED(CONFIG_ATH_USER_REGD)) + return; + sband = wiphy->bands[NL80211_BAND_2GHZ]; if (!sband) return; @@ -408,6 +420,9 @@ static void ath_reg_apply_radar_flags(st struct ieee80211_channel *ch; unsigned int i; + if (IS_ENABLED(CONFIG_ATH_USER_REGD)) + return; + if (!wiphy->bands[NL80211_BAND_5GHZ]) return; @@ -640,6 +655,10 @@ ath_regd_init_wiphy(struct ath_regulator const struct ieee80211_regdomain *regd; wiphy->reg_notifier = reg_notifier; + + if (IS_ENABLED(CONFIG_ATH_USER_REGD)) + return 0; + wiphy->regulatory_flags |= REGULATORY_STRICT_REG | REGULATORY_CUSTOM_REG; --- a/drivers/net/wireless/ath/Kconfig +++ b/drivers/net/wireless/ath/Kconfig @@ -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 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -44,7 +44,8 @@ static struct reg_dmn_pair_mapping *ath_ 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) @@ -62,57 +63,56 @@ static struct reg_dmn_pair_mapping *ath_ #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 bool dynamic_country_user_possible(struct ath_regulatory *reg) --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -3370,6 +3370,8 @@ void regulatory_hint_country_ie(struct w 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; @@ -3621,6 +3623,7 @@ static bool is_wiphy_all_set_reg_flag(en 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. --- 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 regDo {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 al {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 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -115,6 +115,16 @@ static const struct ieee80211_regdomain ) }; +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(CONFIG_ATH_USER_REGD)) @@ -123,6 +133,9 @@ static bool dynamic_country_user_possibl if (IS_ENABLED(CONFIG_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: @@ -208,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)); @@ -659,6 +667,9 @@ ath_regd_init_wiphy(struct ath_regulator if (IS_ENABLED(CONFIG_ATH_USER_REGD)) return 0; + if (is_default_regd(reg)) + return 0; + wiphy->regulatory_flags |= REGULATORY_STRICT_REG | REGULATORY_CUSTOM_REG; --- linux-6.3/drivers/net/wireless/ath/ath9k/init.c.orig 2023-04-23 21:02:52.000000000 +0200 +++ linux-6.3/drivers/net/wireless/ath/ath9k/init.c 2023-05-28 12:29:58.335041933 +0200 @@ -1108,7 +1108,7 @@ } /* Handle world regulatory */ - if (!ath_is_world_regd(reg)) { + if (!IS_ENABLED(CONFIG_ATH_USER_REGD) && !ath_is_world_regd(reg)) { error = regulatory_hint(hw->wiphy, reg->alpha2); if (error) goto debug_cleanup; --- linux-6.3/drivers/net/wireless/ath/ath10k/mac.c.orig 2023-04-23 21:02:52.000000000 +0200 +++ linux-6.3/drivers/net/wireless/ath/ath10k/mac.c 2023-05-28 12:29:12.823062813 +0200 @@ -10278,7 +10278,7 @@ ar->hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_AP_VLAN); } - if (!ath_is_world_regd(&ar->ath_common.reg_world_copy) && + if (!IS_ENABLED(CONFIG_ATH_USER_REGD) && !ath_is_world_regd(&ar->ath_common.reg_world_copy) && !ath_is_world_regd(&ar->ath_common.regulatory)) { ret = regulatory_hint(ar->hw->wiphy, ar->ath_common.regulatory.alpha2);