Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Copyright (c) 2008-2009 Atheros Communications Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Permission to use, copy, modify, and/or distribute this software for any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * purpose with or without fee is hereby granted, provided that the above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * copyright notice and this permission notice appear in all copies.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <net/cfg80211.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <net/mac80211.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include "regd.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include "regd_common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) static int __ath_regd_init(struct ath_regulatory *reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * This is a set of common rules used by our world regulatory domains.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * We have 12 world regulatory domains. To save space we consolidate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * the regulatory domains in 5 structures by frequency and change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * the flags on our reg_notifier() on a case by case basis.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) /* Only these channels all allow active scan on all world regulatory domains */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define ATH_2GHZ_CH01_11	REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) /* We enable active scan on these a case by case basis by regulatory domain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define ATH_2GHZ_CH12_13	REG_RULE(2467-10, 2472+10, 40, 0, 20,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 					 NL80211_RRF_NO_IR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define ATH_2GHZ_CH14		REG_RULE(2484-10, 2484+10, 40, 0, 20,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 					 NL80211_RRF_NO_IR | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 					 NL80211_RRF_NO_OFDM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) /* We allow IBSS on these on a case by case basis by regulatory domain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define ATH_5GHZ_5150_5350	REG_RULE(5150-10, 5350+10, 80, 0, 30,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 					 NL80211_RRF_NO_IR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define ATH_5GHZ_5470_5850	REG_RULE(5470-10, 5850+10, 80, 0, 30,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 					 NL80211_RRF_NO_IR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define ATH_5GHZ_5725_5850	REG_RULE(5725-10, 5850+10, 80, 0, 30,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 					 NL80211_RRF_NO_IR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define ATH_2GHZ_ALL		ATH_2GHZ_CH01_11, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 				ATH_2GHZ_CH12_13, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 				ATH_2GHZ_CH14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define ATH_5GHZ_ALL		ATH_5GHZ_5150_5350, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 				ATH_5GHZ_5470_5850
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) /* This one skips what we call "mid band" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define ATH_5GHZ_NO_MIDBAND	ATH_5GHZ_5150_5350, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 				ATH_5GHZ_5725_5850
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) /* Can be used for:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  * 0x60, 0x61, 0x62 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	.n_reg_rules = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	.alpha2 =  "99",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	.reg_rules = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		ATH_2GHZ_ALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		ATH_5GHZ_ALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) /* Can be used by 0x63 and 0x65 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) static const struct ieee80211_regdomain ath_world_regdom_63_65 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	.n_reg_rules = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	.alpha2 =  "99",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	.reg_rules = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		ATH_2GHZ_CH01_11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		ATH_2GHZ_CH12_13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		ATH_5GHZ_NO_MIDBAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) /* Can be used by 0x64 only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) static const struct ieee80211_regdomain ath_world_regdom_64 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	.n_reg_rules = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	.alpha2 =  "99",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	.reg_rules = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		ATH_2GHZ_CH01_11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		ATH_5GHZ_NO_MIDBAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) /* Can be used by 0x66 and 0x69 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) static const struct ieee80211_regdomain ath_world_regdom_66_69 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	.n_reg_rules = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	.alpha2 =  "99",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	.reg_rules = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		ATH_2GHZ_CH01_11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		ATH_5GHZ_ALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* Can be used by 0x67, 0x68, 0x6A and 0x6C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	.n_reg_rules = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	.alpha2 =  "99",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	.reg_rules = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		ATH_2GHZ_CH01_11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		ATH_2GHZ_CH12_13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		ATH_5GHZ_ALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static bool dynamic_country_user_possible(struct ath_regulatory *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	if (IS_ENABLED(CONFIG_ATH_REG_DYNAMIC_USER_CERT_TESTING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	switch (reg->country_code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	case CTRY_UNITED_STATES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	case CTRY_JAPAN1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	case CTRY_JAPAN2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	case CTRY_JAPAN3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	case CTRY_JAPAN4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	case CTRY_JAPAN5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	case CTRY_JAPAN6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	case CTRY_JAPAN7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	case CTRY_JAPAN8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	case CTRY_JAPAN9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	case CTRY_JAPAN10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	case CTRY_JAPAN11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	case CTRY_JAPAN12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	case CTRY_JAPAN13:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	case CTRY_JAPAN14:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	case CTRY_JAPAN15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	case CTRY_JAPAN16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	case CTRY_JAPAN17:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	case CTRY_JAPAN18:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	case CTRY_JAPAN19:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	case CTRY_JAPAN20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	case CTRY_JAPAN21:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	case CTRY_JAPAN22:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	case CTRY_JAPAN23:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	case CTRY_JAPAN24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	case CTRY_JAPAN25:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	case CTRY_JAPAN26:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	case CTRY_JAPAN27:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	case CTRY_JAPAN28:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	case CTRY_JAPAN29:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	case CTRY_JAPAN30:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	case CTRY_JAPAN31:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	case CTRY_JAPAN32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	case CTRY_JAPAN33:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	case CTRY_JAPAN34:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	case CTRY_JAPAN35:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	case CTRY_JAPAN36:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	case CTRY_JAPAN37:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	case CTRY_JAPAN38:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	case CTRY_JAPAN39:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	case CTRY_JAPAN40:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	case CTRY_JAPAN41:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	case CTRY_JAPAN42:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	case CTRY_JAPAN43:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	case CTRY_JAPAN44:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	case CTRY_JAPAN45:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	case CTRY_JAPAN46:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	case CTRY_JAPAN47:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	case CTRY_JAPAN48:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	case CTRY_JAPAN49:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	case CTRY_JAPAN50:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	case CTRY_JAPAN51:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	case CTRY_JAPAN52:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	case CTRY_JAPAN53:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	case CTRY_JAPAN54:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	case CTRY_JAPAN55:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	case CTRY_JAPAN56:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	case CTRY_JAPAN57:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	case CTRY_JAPAN58:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	case CTRY_JAPAN59:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static bool ath_reg_dyn_country_user_allow(struct ath_regulatory *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	if (!IS_ENABLED(CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	if (!dynamic_country_user_possible(reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static inline bool is_wwr_sku(u16 regd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		(((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		(regd == WORLD));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) bool ath_is_world_regd(struct ath_regulatory *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	return is_wwr_sku(ath_regd_get_eepromRD(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) EXPORT_SYMBOL(ath_is_world_regd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static const struct ieee80211_regdomain *ath_default_world_regdomain(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	/* this is the most restrictive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	return &ath_world_regdom_64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static const struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	switch (reg->regpair->reg_domain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	case 0x60:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	case 0x61:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	case 0x62:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		return &ath_world_regdom_60_61_62;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	case 0x63:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	case 0x65:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		return &ath_world_regdom_63_65;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	case 0x64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		return &ath_world_regdom_64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	case 0x66:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	case 0x69:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		return &ath_world_regdom_66_69;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	case 0x67:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	case 0x68:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	case 0x6A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	case 0x6C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		return &ath_world_regdom_67_68_6A_6C;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		return ath_default_world_regdomain();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) bool ath_is_49ghz_allowed(u16 regdomain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	/* possibly more */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	return regdomain == MKK9_MKKC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) EXPORT_SYMBOL(ath_is_49ghz_allowed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* Frequency is one where radar detection is required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static bool ath_is_radar_freq(u16 center_freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 			      struct ath_regulatory *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	if (reg->country_code == CTRY_INDIA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		return (center_freq >= 5500 && center_freq <= 5700);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	return (center_freq >= 5260 && center_freq <= 5700);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static void ath_force_clear_no_ir_chan(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 				       struct ieee80211_channel *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	const struct ieee80211_reg_rule *reg_rule;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	if (IS_ERR(reg_rule))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	if (!(reg_rule->flags & NL80211_RRF_NO_IR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		if (ch->flags & IEEE80211_CHAN_NO_IR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 			ch->flags &= ~IEEE80211_CHAN_NO_IR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static void ath_force_clear_no_ir_freq(struct wiphy *wiphy, u16 center_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	struct ieee80211_channel *ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	ch = ieee80211_get_channel(wiphy, center_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	if (!ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	ath_force_clear_no_ir_chan(wiphy, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static void ath_force_no_ir_chan(struct ieee80211_channel *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	ch->flags |= IEEE80211_CHAN_NO_IR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static void ath_force_no_ir_freq(struct wiphy *wiphy, u16 center_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	struct ieee80211_channel *ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	ch = ieee80211_get_channel(wiphy, center_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	if (!ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	ath_force_no_ir_chan(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) __ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 				struct ath_regulatory *reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 				enum nl80211_reg_initiator initiator,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 				struct ieee80211_channel *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	if (ath_is_radar_freq(ch->center_freq, reg) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	    (ch->flags & IEEE80211_CHAN_RADAR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	switch (initiator) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		ath_force_clear_no_ir_chan(wiphy, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	case NL80211_REGDOM_SET_BY_USER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		if (ath_reg_dyn_country_user_allow(reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 			ath_force_clear_no_ir_chan(wiphy, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		if (ch->beacon_found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 			ch->flags &= ~IEEE80211_CHAN_NO_IR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)  * These exception rules do not apply radar frequencies.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)  * - We enable initiating radiation if the country IE says its fine:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)  * - If no country IE has been processed and a we determine we have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)  *   received a beacon on a channel we can enable initiating radiation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 			      struct ath_regulatory *reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 			      enum nl80211_reg_initiator initiator)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	enum nl80211_band band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	struct ieee80211_supported_band *sband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	struct ieee80211_channel *ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	for (band = 0; band < NUM_NL80211_BANDS; band++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		if (!wiphy->bands[band])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		sband = wiphy->bands[band];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		for (i = 0; i < sband->n_channels; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 			ch = &sband->channels[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 			__ath_reg_apply_beaconing_flags(wiphy, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 							initiator, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)  * ath_reg_apply_ir_flags()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)  * @wiphy: the wiphy to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)  * @initiator: the regulatory hint initiator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)  * If no country IE has been received always enable passive scan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)  * and no-ibss on these channels. This is only done for specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)  * regulatory SKUs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)  * If a country IE has been received check its rule for this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)  * channel first before enabling active scan. The passive scan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)  * would have been enforced by the initial processing of our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)  * custom regulatory domain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) ath_reg_apply_ir_flags(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		       struct ath_regulatory *reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		       enum nl80211_reg_initiator initiator)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	struct ieee80211_supported_band *sband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	sband = wiphy->bands[NL80211_BAND_2GHZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	if (!sband)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	switch(initiator) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		ath_force_clear_no_ir_freq(wiphy, 2467);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		ath_force_clear_no_ir_freq(wiphy, 2472);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	case NL80211_REGDOM_SET_BY_USER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		if (!ath_reg_dyn_country_user_allow(reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		ath_force_clear_no_ir_freq(wiphy, 2467);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		ath_force_clear_no_ir_freq(wiphy, 2472);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		ath_force_no_ir_freq(wiphy, 2467);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		ath_force_no_ir_freq(wiphy, 2472);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /* Always apply Radar/DFS rules on freq range 5500 MHz - 5700 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static void ath_reg_apply_radar_flags(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 				      struct ath_regulatory *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	struct ieee80211_supported_band *sband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	struct ieee80211_channel *ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	if (!wiphy->bands[NL80211_BAND_5GHZ])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	sband = wiphy->bands[NL80211_BAND_5GHZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	for (i = 0; i < sband->n_channels; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		ch = &sband->channels[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		if (!ath_is_radar_freq(ch->center_freq, reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		/* We always enable radar detection/DFS on this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		 * frequency range. Additionally we also apply on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		 * this frequency range:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		 * - If STA mode does not yet have DFS supports disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		 *   active scanning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		 * - If adhoc mode does not support DFS yet then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		 *   disable adhoc in the frequency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		 * - If AP mode does not yet support radar detection/DFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		 *   do not allow AP mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		if (!(ch->flags & IEEE80211_CHAN_DISABLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 			ch->flags |= IEEE80211_CHAN_RADAR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 				     IEEE80211_CHAN_NO_IR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static void ath_reg_apply_world_flags(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 				      enum nl80211_reg_initiator initiator,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 				      struct ath_regulatory *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	switch (reg->regpair->reg_domain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	case 0x60:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	case 0x63:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	case 0x66:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	case 0x67:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	case 0x6C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		ath_reg_apply_beaconing_flags(wiphy, reg, initiator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	case 0x68:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		ath_reg_apply_beaconing_flags(wiphy, reg, initiator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		ath_reg_apply_ir_flags(wiphy, reg, initiator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		if (ath_reg_dyn_country_user_allow(reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 			ath_reg_apply_beaconing_flags(wiphy, reg, initiator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) u16 ath_regd_find_country_by_name(char *alpha2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		if (!memcmp(allCountries[i].isoName, alpha2, 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 			return allCountries[i].countryCode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) EXPORT_SYMBOL(ath_regd_find_country_by_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static int __ath_reg_dyn_country(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 				 struct ath_regulatory *reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 				 struct regulatory_request *request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	u16 country_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	    !ath_is_world_regd(reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	country_code = ath_regd_find_country_by_name(request->alpha2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	if (country_code == (u16) -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	reg->current_rd = COUNTRY_ERD_FLAG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	reg->current_rd |= country_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	__ath_regd_init(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	ath_reg_apply_world_flags(wiphy, request->initiator, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) static void ath_reg_dyn_country(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 				struct ath_regulatory *reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 				struct regulatory_request *request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	if (__ath_reg_dyn_country(wiphy, reg, request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	printk(KERN_DEBUG "ath: regdomain 0x%0x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 			  "dynamically updated by %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	       reg->current_rd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	       reg_initiator_name(request->initiator));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) void ath_reg_notifier_apply(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 			    struct regulatory_request *request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 			    struct ath_regulatory *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	struct ath_common *common = container_of(reg, struct ath_common,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 						 regulatory);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	/* We always apply this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	ath_reg_apply_radar_flags(wiphy, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	 * This would happen when we have sent a custom regulatory request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	 * a world regulatory domain and the scheduler hasn't yet processed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	 * any pending requests in the queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	if (!request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	reg->region = request->dfs_region;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	switch (request->initiator) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	case NL80211_REGDOM_SET_BY_CORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		 * If common->reg_world_copy is world roaming it means we *were*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		 * world roaming... so we now have to restore that data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		if (!ath_is_world_regd(&common->reg_world_copy))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		memcpy(reg, &common->reg_world_copy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 		       sizeof(struct ath_regulatory));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	case NL80211_REGDOM_SET_BY_DRIVER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	case NL80211_REGDOM_SET_BY_USER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		if (ath_reg_dyn_country_user_allow(reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 			ath_reg_dyn_country(wiphy, reg, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		ath_reg_dyn_country(wiphy, reg, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) EXPORT_SYMBOL(ath_reg_notifier_apply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	u16 rd = ath_regd_get_eepromRD(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	if (rd & COUNTRY_ERD_FLAG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		/* EEPROM value is a country code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		u16 cc = rd & ~COUNTRY_ERD_FLAG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 		       "ath: EEPROM indicates we should expect "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 			"a country code\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		for (i = 0; i < ARRAY_SIZE(allCountries); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 			if (allCountries[i].countryCode == cc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 				return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 		/* EEPROM value is a regpair value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		if (rd != CTRY_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 			printk(KERN_DEBUG "ath: EEPROM indicates we "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 			       "should expect a direct regpair map\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 			if (regDomainPairs[i].reg_domain == rd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 				return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		 "ath: invalid regulatory domain/country code 0x%x\n", rd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) /* EEPROM country code to regpair mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) static struct country_code_to_enum_rd*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) ath_regd_find_country(u16 countryCode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 		if (allCountries[i].countryCode == countryCode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 			return &allCountries[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) /* EEPROM rd code to regpair mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static struct country_code_to_enum_rd*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) ath_regd_find_country_by_rd(int regdmn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 		if (allCountries[i].regDmnEnum == regdmn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 			return &allCountries[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /* Returns the map of the EEPROM set RD to a country code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) static u16 ath_regd_get_default_country(u16 rd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	if (rd & COUNTRY_ERD_FLAG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 		struct country_code_to_enum_rd *country = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 		u16 cc = rd & ~COUNTRY_ERD_FLAG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 		country = ath_regd_find_country(cc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		if (country != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 			return cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	return CTRY_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) static struct reg_dmn_pair_mapping*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) ath_get_regpair(int regdmn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	if (regdmn == NO_ENUMRD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 		if (regDomainPairs[i].reg_domain == regdmn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 			return &regDomainPairs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) ath_regd_init_wiphy(struct ath_regulatory *reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 		    struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 		    void (*reg_notifier)(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 					 struct regulatory_request *request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	const struct ieee80211_regdomain *regd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	wiphy->reg_notifier = reg_notifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	wiphy->regulatory_flags |= REGULATORY_STRICT_REG |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 				   REGULATORY_CUSTOM_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	if (ath_is_world_regd(reg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		 * Anything applied here (prior to wiphy registration) gets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 		 * saved on the wiphy orig_* parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 		regd = ath_world_regdomain(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 		wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_FOLLOW_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 		 * This gets applied in the case of the absence of CRDA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 		 * it's our own custom world regulatory domain, similar to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 		 * cfg80211's but we enable passive scanning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 		regd = ath_default_world_regdomain();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	wiphy_apply_custom_regulatory(wiphy, regd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	ath_reg_apply_radar_flags(wiphy, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)  * Some users have reported their EEPROM programmed with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)  * 0x8000 set, this is not a supported regulatory domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)  * but since we have more than one user with it we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)  * a solution for them. We default to 0x64, which is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)  * default Atheros world regulatory domain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static void ath_regd_sanitize(struct ath_regulatory *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	if (reg->current_rd != COUNTRY_ERD_FLAG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	printk(KERN_DEBUG "ath: EEPROM regdomain sanitized\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	reg->current_rd = 0x64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) static int __ath_regd_init(struct ath_regulatory *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	struct country_code_to_enum_rd *country = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	u16 regdmn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	if (!reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	ath_regd_sanitize(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	printk(KERN_DEBUG "ath: EEPROM regdomain: 0x%0x\n", reg->current_rd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	if (!ath_regd_is_eeprom_valid(reg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 		pr_err("Invalid EEPROM contents\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	regdmn = ath_regd_get_eepromRD(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	reg->country_code = ath_regd_get_default_country(regdmn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	if (reg->country_code == CTRY_DEFAULT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	    regdmn == CTRY_DEFAULT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 		printk(KERN_DEBUG "ath: EEPROM indicates default "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 		       "country code should be used\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 		reg->country_code = CTRY_UNITED_STATES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	if (reg->country_code == CTRY_DEFAULT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 		country = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 		printk(KERN_DEBUG "ath: doing EEPROM country->regdmn "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 		       "map search\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 		country = ath_regd_find_country(reg->country_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 		if (country == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 			printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 				"ath: no valid country maps found for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 				"country code: 0x%0x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 				reg->country_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 			regdmn = country->regDmnEnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 			printk(KERN_DEBUG "ath: country maps to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 			       "regdmn code: 0x%0x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 			       regdmn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	reg->regpair = ath_get_regpair(regdmn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	if (!reg->regpair) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 		printk(KERN_DEBUG "ath: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 			"No regulatory domain pair found, cannot continue\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	if (!country)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 		country = ath_regd_find_country_by_rd(regdmn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	if (country) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 		reg->alpha2[0] = country->isoName[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 		reg->alpha2[1] = country->isoName[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 		reg->alpha2[0] = '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 		reg->alpha2[1] = '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	printk(KERN_DEBUG "ath: Country alpha2 being used: %c%c\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 		reg->alpha2[0], reg->alpha2[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	printk(KERN_DEBUG "ath: Regpair used: 0x%0x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 		reg->regpair->reg_domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) ath_regd_init(struct ath_regulatory *reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	      struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 	      void (*reg_notifier)(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 				   struct regulatory_request *request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 	struct ath_common *common = container_of(reg, struct ath_common,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 						 regulatory);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 	r = __ath_regd_init(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 	if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 	if (ath_is_world_regd(reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 		memcpy(&common->reg_world_copy, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 		       sizeof(struct ath_regulatory));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 	ath_regd_init_wiphy(reg, wiphy, reg_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) EXPORT_SYMBOL(ath_regd_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) u32 ath_regd_get_band_ctl(struct ath_regulatory *reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 			  enum nl80211_band band)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 	if (!reg->regpair ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 	    (reg->country_code == CTRY_DEFAULT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 	     is_wwr_sku(ath_regd_get_eepromRD(reg)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 		return SD_NO_CTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 	if (ath_regd_get_eepromRD(reg) == CTRY_DEFAULT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 		switch (reg->region) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 		case NL80211_DFS_FCC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 			return CTL_FCC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 		case NL80211_DFS_ETSI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 			return CTL_ETSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 		case NL80211_DFS_JP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 			return CTL_MKK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 	switch (band) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 	case NL80211_BAND_2GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 		return reg->regpair->reg_2ghz_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 	case NL80211_BAND_5GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 		return reg->regpair->reg_5ghz_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 		return NO_CTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) EXPORT_SYMBOL(ath_regd_get_band_ctl);