1 | // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause |
2 | /* Copyright(c) 2018-2019 Realtek Corporation |
3 | */ |
4 | |
5 | #include "main.h" |
6 | #include "regd.h" |
7 | #include "debug.h" |
8 | #include "phy.h" |
9 | |
10 | #define COUNTRY_REGD_ENT(_alpha2, _regd_2g, _regd_5g) \ |
11 | {.alpha2 = (_alpha2), \ |
12 | .txpwr_regd_2g = (_regd_2g), \ |
13 | .txpwr_regd_5g = (_regd_5g), \ |
14 | } |
15 | |
16 | #define rtw_dbg_regd_dump(_dev, _msg, _args...) \ |
17 | do { \ |
18 | struct rtw_dev *__d = (_dev); \ |
19 | const struct rtw_regd *__r = &__d->regd; \ |
20 | rtw_dbg(__d, RTW_DBG_REGD, _msg \ |
21 | "apply alpha2 %c%c, regd {%d, %d}, dfs_region %d\n",\ |
22 | ##_args, \ |
23 | __r->regulatory->alpha2[0], \ |
24 | __r->regulatory->alpha2[1], \ |
25 | __r->regulatory->txpwr_regd_2g, \ |
26 | __r->regulatory->txpwr_regd_5g, \ |
27 | __r->dfs_region); \ |
28 | } while (0) |
29 | |
30 | /* If country code is not correctly defined in efuse, |
31 | * use worldwide country code and txpwr regd. |
32 | */ |
33 | static const struct rtw_regulatory rtw_reg_ww = |
34 | COUNTRY_REGD_ENT("00" , RTW_REGD_WW, RTW_REGD_WW); |
35 | |
36 | static const struct rtw_regulatory rtw_reg_map[] = { |
37 | COUNTRY_REGD_ENT("AD" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
38 | COUNTRY_REGD_ENT("AE" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
39 | COUNTRY_REGD_ENT("AF" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
40 | COUNTRY_REGD_ENT("AG" , RTW_REGD_FCC, RTW_REGD_FCC), |
41 | COUNTRY_REGD_ENT("AI" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
42 | COUNTRY_REGD_ENT("AL" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
43 | COUNTRY_REGD_ENT("AM" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
44 | COUNTRY_REGD_ENT("AN" , RTW_REGD_FCC, RTW_REGD_FCC), |
45 | COUNTRY_REGD_ENT("AO" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
46 | COUNTRY_REGD_ENT("AQ" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
47 | COUNTRY_REGD_ENT("AR" , RTW_REGD_MEXICO, RTW_REGD_MEXICO), |
48 | COUNTRY_REGD_ENT("AS" , RTW_REGD_FCC, RTW_REGD_FCC), |
49 | COUNTRY_REGD_ENT("AT" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
50 | COUNTRY_REGD_ENT("AU" , RTW_REGD_ACMA, RTW_REGD_ACMA), |
51 | COUNTRY_REGD_ENT("AW" , RTW_REGD_FCC, RTW_REGD_FCC), |
52 | COUNTRY_REGD_ENT("AZ" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
53 | COUNTRY_REGD_ENT("BA" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
54 | COUNTRY_REGD_ENT("BB" , RTW_REGD_FCC, RTW_REGD_FCC), |
55 | COUNTRY_REGD_ENT("BD" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
56 | COUNTRY_REGD_ENT("BE" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
57 | COUNTRY_REGD_ENT("BF" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
58 | COUNTRY_REGD_ENT("BG" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
59 | COUNTRY_REGD_ENT("BH" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
60 | COUNTRY_REGD_ENT("BI" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
61 | COUNTRY_REGD_ENT("BJ" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
62 | COUNTRY_REGD_ENT("BM" , RTW_REGD_FCC, RTW_REGD_FCC), |
63 | COUNTRY_REGD_ENT("BN" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
64 | COUNTRY_REGD_ENT("BO" , RTW_REGD_FCC, RTW_REGD_FCC), |
65 | COUNTRY_REGD_ENT("BR" , RTW_REGD_FCC, RTW_REGD_FCC), |
66 | COUNTRY_REGD_ENT("BS" , RTW_REGD_FCC, RTW_REGD_FCC), |
67 | COUNTRY_REGD_ENT("BT" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
68 | COUNTRY_REGD_ENT("BV" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
69 | COUNTRY_REGD_ENT("BW" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
70 | COUNTRY_REGD_ENT("BY" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
71 | COUNTRY_REGD_ENT("BZ" , RTW_REGD_FCC, RTW_REGD_FCC), |
72 | COUNTRY_REGD_ENT("CA" , RTW_REGD_IC, RTW_REGD_IC), |
73 | COUNTRY_REGD_ENT("CC" , RTW_REGD_ACMA, RTW_REGD_ACMA), |
74 | COUNTRY_REGD_ENT("CD" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
75 | COUNTRY_REGD_ENT("CF" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
76 | COUNTRY_REGD_ENT("CG" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
77 | COUNTRY_REGD_ENT("CH" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
78 | COUNTRY_REGD_ENT("CI" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
79 | COUNTRY_REGD_ENT("CK" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
80 | COUNTRY_REGD_ENT("CL" , RTW_REGD_CHILE, RTW_REGD_CHILE), |
81 | COUNTRY_REGD_ENT("CM" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
82 | COUNTRY_REGD_ENT("CN" , RTW_REGD_CN, RTW_REGD_CN), |
83 | COUNTRY_REGD_ENT("CO" , RTW_REGD_FCC, RTW_REGD_FCC), |
84 | COUNTRY_REGD_ENT("CR" , RTW_REGD_FCC, RTW_REGD_FCC), |
85 | COUNTRY_REGD_ENT("CV" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
86 | COUNTRY_REGD_ENT("CX" , RTW_REGD_ACMA, RTW_REGD_ACMA), |
87 | COUNTRY_REGD_ENT("CY" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
88 | COUNTRY_REGD_ENT("CZ" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
89 | COUNTRY_REGD_ENT("DE" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
90 | COUNTRY_REGD_ENT("DJ" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
91 | COUNTRY_REGD_ENT("DK" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
92 | COUNTRY_REGD_ENT("DM" , RTW_REGD_FCC, RTW_REGD_FCC), |
93 | COUNTRY_REGD_ENT("DO" , RTW_REGD_FCC, RTW_REGD_FCC), |
94 | COUNTRY_REGD_ENT("DZ" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
95 | COUNTRY_REGD_ENT("EC" , RTW_REGD_FCC, RTW_REGD_FCC), |
96 | COUNTRY_REGD_ENT("EE" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
97 | COUNTRY_REGD_ENT("EG" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
98 | COUNTRY_REGD_ENT("EH" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
99 | COUNTRY_REGD_ENT("ER" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
100 | COUNTRY_REGD_ENT("ES" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
101 | COUNTRY_REGD_ENT("ET" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
102 | COUNTRY_REGD_ENT("FI" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
103 | COUNTRY_REGD_ENT("FJ" , RTW_REGD_FCC, RTW_REGD_FCC), |
104 | COUNTRY_REGD_ENT("FK" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
105 | COUNTRY_REGD_ENT("FM" , RTW_REGD_FCC, RTW_REGD_FCC), |
106 | COUNTRY_REGD_ENT("FO" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
107 | COUNTRY_REGD_ENT("FR" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
108 | COUNTRY_REGD_ENT("GA" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
109 | COUNTRY_REGD_ENT("GB" , RTW_REGD_UK, RTW_REGD_UK), |
110 | COUNTRY_REGD_ENT("GD" , RTW_REGD_FCC, RTW_REGD_FCC), |
111 | COUNTRY_REGD_ENT("GE" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
112 | COUNTRY_REGD_ENT("GF" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
113 | COUNTRY_REGD_ENT("GG" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
114 | COUNTRY_REGD_ENT("GH" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
115 | COUNTRY_REGD_ENT("GI" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
116 | COUNTRY_REGD_ENT("GL" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
117 | COUNTRY_REGD_ENT("GM" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
118 | COUNTRY_REGD_ENT("GN" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
119 | COUNTRY_REGD_ENT("GP" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
120 | COUNTRY_REGD_ENT("GQ" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
121 | COUNTRY_REGD_ENT("GR" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
122 | COUNTRY_REGD_ENT("GS" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
123 | COUNTRY_REGD_ENT("GT" , RTW_REGD_FCC, RTW_REGD_FCC), |
124 | COUNTRY_REGD_ENT("GU" , RTW_REGD_FCC, RTW_REGD_FCC), |
125 | COUNTRY_REGD_ENT("GW" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
126 | COUNTRY_REGD_ENT("GY" , RTW_REGD_FCC, RTW_REGD_FCC), |
127 | COUNTRY_REGD_ENT("HK" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
128 | COUNTRY_REGD_ENT("HM" , RTW_REGD_ACMA, RTW_REGD_ACMA), |
129 | COUNTRY_REGD_ENT("HN" , RTW_REGD_FCC, RTW_REGD_FCC), |
130 | COUNTRY_REGD_ENT("HR" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
131 | COUNTRY_REGD_ENT("HT" , RTW_REGD_FCC, RTW_REGD_FCC), |
132 | COUNTRY_REGD_ENT("HU" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
133 | COUNTRY_REGD_ENT("ID" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
134 | COUNTRY_REGD_ENT("IE" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
135 | COUNTRY_REGD_ENT("IL" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
136 | COUNTRY_REGD_ENT("IM" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
137 | COUNTRY_REGD_ENT("IN" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
138 | COUNTRY_REGD_ENT("IO" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
139 | COUNTRY_REGD_ENT("IQ" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
140 | COUNTRY_REGD_ENT("IR" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
141 | COUNTRY_REGD_ENT("IS" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
142 | COUNTRY_REGD_ENT("IT" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
143 | COUNTRY_REGD_ENT("JE" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
144 | COUNTRY_REGD_ENT("JM" , RTW_REGD_FCC, RTW_REGD_FCC), |
145 | COUNTRY_REGD_ENT("JO" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
146 | COUNTRY_REGD_ENT("JP" , RTW_REGD_MKK, RTW_REGD_MKK), |
147 | COUNTRY_REGD_ENT("KE" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
148 | COUNTRY_REGD_ENT("KG" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
149 | COUNTRY_REGD_ENT("KH" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
150 | COUNTRY_REGD_ENT("KI" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
151 | COUNTRY_REGD_ENT("KM" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
152 | COUNTRY_REGD_ENT("KN" , RTW_REGD_FCC, RTW_REGD_FCC), |
153 | COUNTRY_REGD_ENT("KR" , RTW_REGD_KCC, RTW_REGD_KCC), |
154 | COUNTRY_REGD_ENT("KW" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
155 | COUNTRY_REGD_ENT("KY" , RTW_REGD_FCC, RTW_REGD_FCC), |
156 | COUNTRY_REGD_ENT("KZ" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
157 | COUNTRY_REGD_ENT("LA" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
158 | COUNTRY_REGD_ENT("LB" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
159 | COUNTRY_REGD_ENT("LC" , RTW_REGD_FCC, RTW_REGD_FCC), |
160 | COUNTRY_REGD_ENT("LI" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
161 | COUNTRY_REGD_ENT("LK" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
162 | COUNTRY_REGD_ENT("LR" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
163 | COUNTRY_REGD_ENT("LS" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
164 | COUNTRY_REGD_ENT("LT" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
165 | COUNTRY_REGD_ENT("LU" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
166 | COUNTRY_REGD_ENT("LV" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
167 | COUNTRY_REGD_ENT("LY" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
168 | COUNTRY_REGD_ENT("MA" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
169 | COUNTRY_REGD_ENT("MC" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
170 | COUNTRY_REGD_ENT("MD" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
171 | COUNTRY_REGD_ENT("ME" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
172 | COUNTRY_REGD_ENT("MF" , RTW_REGD_FCC, RTW_REGD_FCC), |
173 | COUNTRY_REGD_ENT("MG" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
174 | COUNTRY_REGD_ENT("MH" , RTW_REGD_FCC, RTW_REGD_FCC), |
175 | COUNTRY_REGD_ENT("MK" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
176 | COUNTRY_REGD_ENT("ML" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
177 | COUNTRY_REGD_ENT("MM" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
178 | COUNTRY_REGD_ENT("MN" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
179 | COUNTRY_REGD_ENT("MO" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
180 | COUNTRY_REGD_ENT("MP" , RTW_REGD_FCC, RTW_REGD_FCC), |
181 | COUNTRY_REGD_ENT("MQ" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
182 | COUNTRY_REGD_ENT("MR" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
183 | COUNTRY_REGD_ENT("MS" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
184 | COUNTRY_REGD_ENT("MT" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
185 | COUNTRY_REGD_ENT("MU" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
186 | COUNTRY_REGD_ENT("MV" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
187 | COUNTRY_REGD_ENT("MW" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
188 | COUNTRY_REGD_ENT("MX" , RTW_REGD_MEXICO, RTW_REGD_MEXICO), |
189 | COUNTRY_REGD_ENT("MY" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
190 | COUNTRY_REGD_ENT("MZ" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
191 | COUNTRY_REGD_ENT("NA" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
192 | COUNTRY_REGD_ENT("NC" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
193 | COUNTRY_REGD_ENT("NE" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
194 | COUNTRY_REGD_ENT("NF" , RTW_REGD_ACMA, RTW_REGD_ACMA), |
195 | COUNTRY_REGD_ENT("NG" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
196 | COUNTRY_REGD_ENT("NI" , RTW_REGD_FCC, RTW_REGD_FCC), |
197 | COUNTRY_REGD_ENT("NL" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
198 | COUNTRY_REGD_ENT("NO" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
199 | COUNTRY_REGD_ENT("NP" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
200 | COUNTRY_REGD_ENT("NR" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
201 | COUNTRY_REGD_ENT("NU" , RTW_REGD_ACMA, RTW_REGD_ACMA), |
202 | COUNTRY_REGD_ENT("NZ" , RTW_REGD_ACMA, RTW_REGD_ACMA), |
203 | COUNTRY_REGD_ENT("OM" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
204 | COUNTRY_REGD_ENT("PA" , RTW_REGD_FCC, RTW_REGD_FCC), |
205 | COUNTRY_REGD_ENT("PE" , RTW_REGD_FCC, RTW_REGD_FCC), |
206 | COUNTRY_REGD_ENT("PF" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
207 | COUNTRY_REGD_ENT("PG" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
208 | COUNTRY_REGD_ENT("PH" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
209 | COUNTRY_REGD_ENT("PK" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
210 | COUNTRY_REGD_ENT("PL" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
211 | COUNTRY_REGD_ENT("PM" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
212 | COUNTRY_REGD_ENT("PR" , RTW_REGD_FCC, RTW_REGD_FCC), |
213 | COUNTRY_REGD_ENT("PS" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
214 | COUNTRY_REGD_ENT("PT" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
215 | COUNTRY_REGD_ENT("PW" , RTW_REGD_FCC, RTW_REGD_FCC), |
216 | COUNTRY_REGD_ENT("PY" , RTW_REGD_FCC, RTW_REGD_FCC), |
217 | COUNTRY_REGD_ENT("QA" , RTW_REGD_QATAR, RTW_REGD_QATAR), |
218 | COUNTRY_REGD_ENT("RE" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
219 | COUNTRY_REGD_ENT("RO" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
220 | COUNTRY_REGD_ENT("RS" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
221 | COUNTRY_REGD_ENT("RU" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
222 | COUNTRY_REGD_ENT("RW" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
223 | COUNTRY_REGD_ENT("SA" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
224 | COUNTRY_REGD_ENT("SB" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
225 | COUNTRY_REGD_ENT("SC" , RTW_REGD_FCC, RTW_REGD_FCC), |
226 | COUNTRY_REGD_ENT("SE" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
227 | COUNTRY_REGD_ENT("SG" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
228 | COUNTRY_REGD_ENT("SH" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
229 | COUNTRY_REGD_ENT("SI" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
230 | COUNTRY_REGD_ENT("SJ" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
231 | COUNTRY_REGD_ENT("SK" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
232 | COUNTRY_REGD_ENT("SL" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
233 | COUNTRY_REGD_ENT("SM" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
234 | COUNTRY_REGD_ENT("SN" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
235 | COUNTRY_REGD_ENT("SO" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
236 | COUNTRY_REGD_ENT("SR" , RTW_REGD_FCC, RTW_REGD_FCC), |
237 | COUNTRY_REGD_ENT("ST" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
238 | COUNTRY_REGD_ENT("SV" , RTW_REGD_FCC, RTW_REGD_FCC), |
239 | COUNTRY_REGD_ENT("SX" , RTW_REGD_FCC, RTW_REGD_FCC), |
240 | COUNTRY_REGD_ENT("SZ" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
241 | COUNTRY_REGD_ENT("TC" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
242 | COUNTRY_REGD_ENT("TD" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
243 | COUNTRY_REGD_ENT("TF" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
244 | COUNTRY_REGD_ENT("TG" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
245 | COUNTRY_REGD_ENT("TH" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
246 | COUNTRY_REGD_ENT("TJ" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
247 | COUNTRY_REGD_ENT("TK" , RTW_REGD_ACMA, RTW_REGD_ACMA), |
248 | COUNTRY_REGD_ENT("TM" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
249 | COUNTRY_REGD_ENT("TN" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
250 | COUNTRY_REGD_ENT("TO" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
251 | COUNTRY_REGD_ENT("TR" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
252 | COUNTRY_REGD_ENT("TT" , RTW_REGD_FCC, RTW_REGD_FCC), |
253 | COUNTRY_REGD_ENT("TV" , RTW_REGD_ETSI, RTW_REGD_WW), |
254 | COUNTRY_REGD_ENT("TW" , RTW_REGD_FCC, RTW_REGD_FCC), |
255 | COUNTRY_REGD_ENT("TZ" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
256 | COUNTRY_REGD_ENT("UA" , RTW_REGD_UKRAINE, RTW_REGD_UKRAINE), |
257 | COUNTRY_REGD_ENT("UG" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
258 | COUNTRY_REGD_ENT("US" , RTW_REGD_FCC, RTW_REGD_FCC), |
259 | COUNTRY_REGD_ENT("UY" , RTW_REGD_FCC, RTW_REGD_FCC), |
260 | COUNTRY_REGD_ENT("UZ" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
261 | COUNTRY_REGD_ENT("VA" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
262 | COUNTRY_REGD_ENT("VC" , RTW_REGD_FCC, RTW_REGD_FCC), |
263 | COUNTRY_REGD_ENT("VE" , RTW_REGD_FCC, RTW_REGD_FCC), |
264 | COUNTRY_REGD_ENT("VG" , RTW_REGD_FCC, RTW_REGD_FCC), |
265 | COUNTRY_REGD_ENT("VI" , RTW_REGD_FCC, RTW_REGD_FCC), |
266 | COUNTRY_REGD_ENT("VN" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
267 | COUNTRY_REGD_ENT("VU" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
268 | COUNTRY_REGD_ENT("WF" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
269 | COUNTRY_REGD_ENT("WS" , RTW_REGD_FCC, RTW_REGD_FCC), |
270 | COUNTRY_REGD_ENT("XK" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
271 | COUNTRY_REGD_ENT("YE" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
272 | COUNTRY_REGD_ENT("YT" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
273 | COUNTRY_REGD_ENT("ZA" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
274 | COUNTRY_REGD_ENT("ZM" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
275 | COUNTRY_REGD_ENT("ZW" , RTW_REGD_ETSI, RTW_REGD_ETSI), |
276 | }; |
277 | |
278 | static void rtw_regd_apply_hw_cap_flags(struct wiphy *wiphy) |
279 | { |
280 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); |
281 | struct ieee80211_supported_band *sband; |
282 | struct ieee80211_channel *ch; |
283 | struct rtw_dev *rtwdev = hw->priv; |
284 | struct rtw_efuse *efuse = &rtwdev->efuse; |
285 | int i; |
286 | |
287 | if (efuse->hw_cap.bw & BIT(RTW_CHANNEL_WIDTH_80)) |
288 | return; |
289 | |
290 | sband = wiphy->bands[NL80211_BAND_2GHZ]; |
291 | if (!sband) |
292 | goto out_5g; |
293 | |
294 | for (i = 0; i < sband->n_channels; i++) { |
295 | ch = &sband->channels[i]; |
296 | ch->flags |= IEEE80211_CHAN_NO_80MHZ; |
297 | } |
298 | |
299 | out_5g: |
300 | sband = wiphy->bands[NL80211_BAND_5GHZ]; |
301 | if (!sband) |
302 | return; |
303 | |
304 | for (i = 0; i < sband->n_channels; i++) { |
305 | ch = &sband->channels[i]; |
306 | ch->flags |= IEEE80211_CHAN_NO_80MHZ; |
307 | } |
308 | } |
309 | |
310 | static bool rtw_reg_is_ww(const struct rtw_regulatory *reg) |
311 | { |
312 | return reg == &rtw_reg_ww; |
313 | } |
314 | |
315 | static bool rtw_reg_match(const struct rtw_regulatory *reg, const char *alpha2) |
316 | { |
317 | return memcmp(p: reg->alpha2, q: alpha2, size: 2) == 0; |
318 | } |
319 | |
320 | static const struct rtw_regulatory *rtw_reg_find_by_name(const char *alpha2) |
321 | { |
322 | unsigned int i; |
323 | |
324 | for (i = 0; i < ARRAY_SIZE(rtw_reg_map); i++) { |
325 | if (rtw_reg_match(reg: &rtw_reg_map[i], alpha2)) |
326 | return &rtw_reg_map[i]; |
327 | } |
328 | |
329 | return &rtw_reg_ww; |
330 | } |
331 | |
332 | static |
333 | void rtw_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request); |
334 | |
335 | /* call this before ieee80211_register_hw() */ |
336 | int rtw_regd_init(struct rtw_dev *rtwdev) |
337 | { |
338 | struct wiphy *wiphy = rtwdev->hw->wiphy; |
339 | const struct rtw_regulatory *chip_reg; |
340 | |
341 | if (!wiphy) |
342 | return -EINVAL; |
343 | |
344 | wiphy->reg_notifier = rtw_regd_notifier; |
345 | |
346 | chip_reg = rtw_reg_find_by_name(alpha2: rtwdev->efuse.country_code); |
347 | if (!rtw_reg_is_ww(reg: chip_reg)) { |
348 | rtwdev->regd.state = RTW_REGD_STATE_PROGRAMMED; |
349 | |
350 | /* Set REGULATORY_STRICT_REG before ieee80211_register_hw(), |
351 | * stack will wait for regulatory_hint() and consider it |
352 | * as the superset for our regulatory rule. |
353 | */ |
354 | wiphy->regulatory_flags |= REGULATORY_STRICT_REG; |
355 | wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; |
356 | } else { |
357 | rtwdev->regd.state = RTW_REGD_STATE_WORLDWIDE; |
358 | } |
359 | |
360 | rtwdev->regd.regulatory = &rtw_reg_ww; |
361 | rtwdev->regd.dfs_region = NL80211_DFS_UNSET; |
362 | rtw_dbg_regd_dump(rtwdev, "regd init state %d: " , rtwdev->regd.state); |
363 | |
364 | rtw_regd_apply_hw_cap_flags(wiphy); |
365 | return 0; |
366 | } |
367 | |
368 | /* call this after ieee80211_register_hw() */ |
369 | int rtw_regd_hint(struct rtw_dev *rtwdev) |
370 | { |
371 | struct wiphy *wiphy = rtwdev->hw->wiphy; |
372 | int ret; |
373 | |
374 | if (!wiphy) |
375 | return -EINVAL; |
376 | |
377 | if (rtwdev->regd.state == RTW_REGD_STATE_PROGRAMMED) { |
378 | rtw_dbg(rtwdev, mask: RTW_DBG_REGD, |
379 | fmt: "country domain %c%c is PGed on efuse" , |
380 | rtwdev->efuse.country_code[0], |
381 | rtwdev->efuse.country_code[1]); |
382 | |
383 | ret = regulatory_hint(wiphy, alpha2: rtwdev->efuse.country_code); |
384 | if (ret) { |
385 | rtw_warn(rtwdev, |
386 | "failed to hint regulatory: %d\n" , ret); |
387 | return ret; |
388 | } |
389 | } |
390 | |
391 | return 0; |
392 | } |
393 | |
394 | static bool rtw_regd_mgmt_worldwide(struct rtw_dev *rtwdev, |
395 | struct rtw_regd *next_regd, |
396 | struct regulatory_request *request) |
397 | { |
398 | struct wiphy *wiphy = rtwdev->hw->wiphy; |
399 | |
400 | next_regd->state = RTW_REGD_STATE_WORLDWIDE; |
401 | |
402 | if (request->initiator == NL80211_REGDOM_SET_BY_USER && |
403 | !rtw_reg_is_ww(reg: next_regd->regulatory)) { |
404 | next_regd->state = RTW_REGD_STATE_SETTING; |
405 | wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; |
406 | } |
407 | |
408 | return true; |
409 | } |
410 | |
411 | static bool rtw_regd_mgmt_programmed(struct rtw_dev *rtwdev, |
412 | struct rtw_regd *next_regd, |
413 | struct regulatory_request *request) |
414 | { |
415 | if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER && |
416 | rtw_reg_match(reg: next_regd->regulatory, alpha2: rtwdev->efuse.country_code)) { |
417 | next_regd->state = RTW_REGD_STATE_PROGRAMMED; |
418 | return true; |
419 | } |
420 | |
421 | return false; |
422 | } |
423 | |
424 | static bool rtw_regd_mgmt_setting(struct rtw_dev *rtwdev, |
425 | struct rtw_regd *next_regd, |
426 | struct regulatory_request *request) |
427 | { |
428 | struct wiphy *wiphy = rtwdev->hw->wiphy; |
429 | |
430 | if (request->initiator != NL80211_REGDOM_SET_BY_USER) |
431 | return false; |
432 | |
433 | next_regd->state = RTW_REGD_STATE_SETTING; |
434 | |
435 | if (rtw_reg_is_ww(reg: next_regd->regulatory)) { |
436 | next_regd->state = RTW_REGD_STATE_WORLDWIDE; |
437 | wiphy->regulatory_flags &= ~REGULATORY_COUNTRY_IE_IGNORE; |
438 | } |
439 | |
440 | return true; |
441 | } |
442 | |
443 | static bool (*const rtw_regd_handler[RTW_REGD_STATE_NR]) |
444 | (struct rtw_dev *, struct rtw_regd *, struct regulatory_request *) = { |
445 | [RTW_REGD_STATE_WORLDWIDE] = rtw_regd_mgmt_worldwide, |
446 | [RTW_REGD_STATE_PROGRAMMED] = rtw_regd_mgmt_programmed, |
447 | [RTW_REGD_STATE_SETTING] = rtw_regd_mgmt_setting, |
448 | }; |
449 | |
450 | static bool rtw_regd_state_hdl(struct rtw_dev *rtwdev, |
451 | struct rtw_regd *next_regd, |
452 | struct regulatory_request *request) |
453 | { |
454 | next_regd->regulatory = rtw_reg_find_by_name(alpha2: request->alpha2); |
455 | next_regd->dfs_region = request->dfs_region; |
456 | return rtw_regd_handler[rtwdev->regd.state](rtwdev, next_regd, request); |
457 | } |
458 | |
459 | static |
460 | void rtw_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request) |
461 | { |
462 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); |
463 | struct rtw_dev *rtwdev = hw->priv; |
464 | struct rtw_hal *hal = &rtwdev->hal; |
465 | struct rtw_regd next_regd = {0}; |
466 | bool hdl; |
467 | |
468 | hdl = rtw_regd_state_hdl(rtwdev, next_regd: &next_regd, request); |
469 | if (!hdl) { |
470 | rtw_dbg(rtwdev, mask: RTW_DBG_REGD, |
471 | fmt: "regd state %d: ignore request %c%c of initiator %d\n" , |
472 | rtwdev->regd.state, |
473 | request->alpha2[0], |
474 | request->alpha2[1], |
475 | request->initiator); |
476 | return; |
477 | } |
478 | |
479 | rtw_dbg(rtwdev, mask: RTW_DBG_REGD, fmt: "regd state: %d -> %d\n" , |
480 | rtwdev->regd.state, next_regd.state); |
481 | |
482 | mutex_lock(&rtwdev->mutex); |
483 | rtwdev->regd = next_regd; |
484 | rtw_dbg_regd_dump(rtwdev, "get alpha2 %c%c from initiator %d: " , |
485 | request->alpha2[0], |
486 | request->alpha2[1], |
487 | request->initiator); |
488 | |
489 | rtw_phy_adaptivity_set_mode(rtwdev); |
490 | rtw_phy_set_tx_power_level(rtwdev, channel: hal->current_channel); |
491 | mutex_unlock(lock: &rtwdev->mutex); |
492 | } |
493 | |
494 | u8 rtw_regd_get(struct rtw_dev *rtwdev) |
495 | { |
496 | struct rtw_hal *hal = &rtwdev->hal; |
497 | u8 band = hal->current_band_type; |
498 | |
499 | return band == RTW_BAND_2G ? |
500 | rtwdev->regd.regulatory->txpwr_regd_2g : |
501 | rtwdev->regd.regulatory->txpwr_regd_5g; |
502 | } |
503 | EXPORT_SYMBOL(rtw_regd_get); |
504 | |
505 | bool rtw_regd_srrc(struct rtw_dev *rtwdev) |
506 | { |
507 | struct rtw_regd *regd = &rtwdev->regd; |
508 | |
509 | return rtw_reg_match(reg: regd->regulatory, alpha2: "CN" ); |
510 | } |
511 | EXPORT_SYMBOL(rtw_regd_srrc); |
512 | |
513 | struct rtw_regd_alternative_t { |
514 | bool set; |
515 | u8 alt; |
516 | }; |
517 | |
518 | #define DECL_REGD_ALT(_regd, _regd_alt) \ |
519 | [(_regd)] = {.set = true, .alt = (_regd_alt)} |
520 | |
521 | static const struct rtw_regd_alternative_t |
522 | rtw_regd_alt[RTW_REGD_MAX] = { |
523 | DECL_REGD_ALT(RTW_REGD_IC, RTW_REGD_FCC), |
524 | DECL_REGD_ALT(RTW_REGD_KCC, RTW_REGD_ETSI), |
525 | DECL_REGD_ALT(RTW_REGD_ACMA, RTW_REGD_ETSI), |
526 | DECL_REGD_ALT(RTW_REGD_CHILE, RTW_REGD_FCC), |
527 | DECL_REGD_ALT(RTW_REGD_UKRAINE, RTW_REGD_ETSI), |
528 | DECL_REGD_ALT(RTW_REGD_MEXICO, RTW_REGD_FCC), |
529 | DECL_REGD_ALT(RTW_REGD_CN, RTW_REGD_ETSI), |
530 | DECL_REGD_ALT(RTW_REGD_QATAR, RTW_REGD_ETSI), |
531 | DECL_REGD_ALT(RTW_REGD_UK, RTW_REGD_ETSI), |
532 | }; |
533 | |
534 | bool rtw_regd_has_alt(u8 regd, u8 *regd_alt) |
535 | { |
536 | if (!rtw_regd_alt[regd].set) |
537 | return false; |
538 | |
539 | *regd_alt = rtw_regd_alt[regd].alt; |
540 | return true; |
541 | } |
542 | |