1 | // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause |
2 | /* Copyright(c) 2019-2020 Realtek Corporation |
3 | */ |
4 | |
5 | #include "acpi.h" |
6 | #include "debug.h" |
7 | #include "ps.h" |
8 | #include "util.h" |
9 | |
10 | #define COUNTRY_REGD(_alpha2, _txpwr_regd...) \ |
11 | {.alpha2 = (_alpha2), \ |
12 | .txpwr_regd = {_txpwr_regd}, \ |
13 | } |
14 | |
15 | static const struct rtw89_regd rtw89_ww_regd = |
16 | COUNTRY_REGD("00" , RTW89_WW, RTW89_WW, RTW89_WW); |
17 | |
18 | static const struct rtw89_regd rtw89_regd_map[] = { |
19 | COUNTRY_REGD("AR" , RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC), |
20 | COUNTRY_REGD("BO" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
21 | COUNTRY_REGD("BR" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
22 | COUNTRY_REGD("CL" , RTW89_CHILE, RTW89_CHILE, RTW89_CHILE), |
23 | COUNTRY_REGD("CO" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
24 | COUNTRY_REGD("CR" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
25 | COUNTRY_REGD("EC" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
26 | COUNTRY_REGD("SV" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
27 | COUNTRY_REGD("GT" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
28 | COUNTRY_REGD("HN" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
29 | COUNTRY_REGD("MX" , RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC), |
30 | COUNTRY_REGD("NI" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
31 | COUNTRY_REGD("PA" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
32 | COUNTRY_REGD("PY" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
33 | COUNTRY_REGD("PE" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
34 | COUNTRY_REGD("US" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
35 | COUNTRY_REGD("UY" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
36 | COUNTRY_REGD("VE" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
37 | COUNTRY_REGD("PR" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
38 | COUNTRY_REGD("DO" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
39 | COUNTRY_REGD("AT" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
40 | COUNTRY_REGD("BE" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
41 | COUNTRY_REGD("CY" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
42 | COUNTRY_REGD("CZ" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
43 | COUNTRY_REGD("DK" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
44 | COUNTRY_REGD("EE" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
45 | COUNTRY_REGD("FI" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
46 | COUNTRY_REGD("FR" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
47 | COUNTRY_REGD("DE" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
48 | COUNTRY_REGD("GR" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
49 | COUNTRY_REGD("HU" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
50 | COUNTRY_REGD("IS" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
51 | COUNTRY_REGD("IE" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
52 | COUNTRY_REGD("IT" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
53 | COUNTRY_REGD("LV" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
54 | COUNTRY_REGD("LI" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
55 | COUNTRY_REGD("LT" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
56 | COUNTRY_REGD("LU" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
57 | COUNTRY_REGD("MT" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
58 | COUNTRY_REGD("MC" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
59 | COUNTRY_REGD("NL" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
60 | COUNTRY_REGD("NO" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
61 | COUNTRY_REGD("PL" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
62 | COUNTRY_REGD("PT" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
63 | COUNTRY_REGD("SK" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
64 | COUNTRY_REGD("SI" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
65 | COUNTRY_REGD("ES" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
66 | COUNTRY_REGD("SE" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
67 | COUNTRY_REGD("CH" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
68 | COUNTRY_REGD("GB" , RTW89_UK, RTW89_UK, RTW89_UK), |
69 | COUNTRY_REGD("AL" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
70 | COUNTRY_REGD("AZ" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
71 | COUNTRY_REGD("BH" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
72 | COUNTRY_REGD("BA" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
73 | COUNTRY_REGD("BG" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
74 | COUNTRY_REGD("HR" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
75 | COUNTRY_REGD("EG" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
76 | COUNTRY_REGD("GH" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
77 | COUNTRY_REGD("IQ" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
78 | COUNTRY_REGD("IL" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
79 | COUNTRY_REGD("JO" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
80 | COUNTRY_REGD("KZ" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
81 | COUNTRY_REGD("KE" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
82 | COUNTRY_REGD("KW" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
83 | COUNTRY_REGD("KG" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
84 | COUNTRY_REGD("LB" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
85 | COUNTRY_REGD("LS" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
86 | COUNTRY_REGD("MK" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
87 | COUNTRY_REGD("MA" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
88 | COUNTRY_REGD("MZ" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
89 | COUNTRY_REGD("NA" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
90 | COUNTRY_REGD("NG" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
91 | COUNTRY_REGD("OM" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
92 | COUNTRY_REGD("QA" , RTW89_QATAR, RTW89_QATAR, RTW89_QATAR), |
93 | COUNTRY_REGD("RO" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
94 | COUNTRY_REGD("RU" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
95 | COUNTRY_REGD("SA" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
96 | COUNTRY_REGD("SN" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
97 | COUNTRY_REGD("RS" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
98 | COUNTRY_REGD("ME" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
99 | COUNTRY_REGD("ZA" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
100 | COUNTRY_REGD("TR" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
101 | COUNTRY_REGD("UA" , RTW89_UKRAINE, RTW89_UKRAINE, RTW89_UKRAINE), |
102 | COUNTRY_REGD("AE" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
103 | COUNTRY_REGD("YE" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
104 | COUNTRY_REGD("ZW" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
105 | COUNTRY_REGD("BD" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
106 | COUNTRY_REGD("KH" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
107 | COUNTRY_REGD("CN" , RTW89_CN, RTW89_CN, RTW89_CN), |
108 | COUNTRY_REGD("HK" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
109 | COUNTRY_REGD("IN" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
110 | COUNTRY_REGD("ID" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
111 | COUNTRY_REGD("KR" , RTW89_KCC, RTW89_KCC, RTW89_KCC), |
112 | COUNTRY_REGD("MY" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
113 | COUNTRY_REGD("PK" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
114 | COUNTRY_REGD("PH" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
115 | COUNTRY_REGD("SG" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
116 | COUNTRY_REGD("LK" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
117 | COUNTRY_REGD("TW" , RTW89_FCC, RTW89_FCC, RTW89_ETSI), |
118 | COUNTRY_REGD("TH" , RTW89_ETSI, RTW89_ETSI, RTW89_THAILAND), |
119 | COUNTRY_REGD("VN" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
120 | COUNTRY_REGD("AU" , RTW89_ACMA, RTW89_ACMA, RTW89_ACMA), |
121 | COUNTRY_REGD("NZ" , RTW89_ACMA, RTW89_ACMA, RTW89_ACMA), |
122 | COUNTRY_REGD("PG" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
123 | COUNTRY_REGD("CA" , RTW89_IC, RTW89_IC, RTW89_IC), |
124 | COUNTRY_REGD("JP" , RTW89_MKK, RTW89_MKK, RTW89_MKK), |
125 | COUNTRY_REGD("JM" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
126 | COUNTRY_REGD("AN" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
127 | COUNTRY_REGD("TT" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
128 | COUNTRY_REGD("TN" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
129 | COUNTRY_REGD("AF" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
130 | COUNTRY_REGD("DZ" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
131 | COUNTRY_REGD("AS" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
132 | COUNTRY_REGD("AD" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
133 | COUNTRY_REGD("AO" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
134 | COUNTRY_REGD("AI" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
135 | COUNTRY_REGD("AQ" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
136 | COUNTRY_REGD("AG" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
137 | COUNTRY_REGD("AM" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
138 | COUNTRY_REGD("AW" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
139 | COUNTRY_REGD("BS" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
140 | COUNTRY_REGD("BB" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
141 | COUNTRY_REGD("BY" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
142 | COUNTRY_REGD("BZ" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
143 | COUNTRY_REGD("BJ" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
144 | COUNTRY_REGD("BM" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
145 | COUNTRY_REGD("BT" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
146 | COUNTRY_REGD("BW" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
147 | COUNTRY_REGD("BV" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
148 | COUNTRY_REGD("IO" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
149 | COUNTRY_REGD("VG" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
150 | COUNTRY_REGD("BN" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
151 | COUNTRY_REGD("BF" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
152 | COUNTRY_REGD("MM" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
153 | COUNTRY_REGD("BI" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
154 | COUNTRY_REGD("CM" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
155 | COUNTRY_REGD("CV" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
156 | COUNTRY_REGD("KY" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
157 | COUNTRY_REGD("CF" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
158 | COUNTRY_REGD("TD" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
159 | COUNTRY_REGD("CX" , RTW89_ACMA, RTW89_ACMA, RTW89_NA), |
160 | COUNTRY_REGD("CC" , RTW89_ACMA, RTW89_ACMA, RTW89_NA), |
161 | COUNTRY_REGD("KM" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
162 | COUNTRY_REGD("CG" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
163 | COUNTRY_REGD("CD" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
164 | COUNTRY_REGD("CK" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
165 | COUNTRY_REGD("CI" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
166 | COUNTRY_REGD("DJ" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
167 | COUNTRY_REGD("DM" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
168 | COUNTRY_REGD("GQ" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
169 | COUNTRY_REGD("ER" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
170 | COUNTRY_REGD("ET" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
171 | COUNTRY_REGD("FK" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
172 | COUNTRY_REGD("FO" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
173 | COUNTRY_REGD("FJ" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
174 | COUNTRY_REGD("GF" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
175 | COUNTRY_REGD("PF" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
176 | COUNTRY_REGD("TF" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
177 | COUNTRY_REGD("GA" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
178 | COUNTRY_REGD("GM" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
179 | COUNTRY_REGD("GE" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
180 | COUNTRY_REGD("GI" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
181 | COUNTRY_REGD("GL" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
182 | COUNTRY_REGD("GD" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
183 | COUNTRY_REGD("GP" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
184 | COUNTRY_REGD("GU" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
185 | COUNTRY_REGD("GG" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
186 | COUNTRY_REGD("GN" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
187 | COUNTRY_REGD("GW" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
188 | COUNTRY_REGD("GY" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
189 | COUNTRY_REGD("HT" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
190 | COUNTRY_REGD("HM" , RTW89_ACMA, RTW89_ACMA, RTW89_NA), |
191 | COUNTRY_REGD("VA" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
192 | COUNTRY_REGD("IM" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
193 | COUNTRY_REGD("JE" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
194 | COUNTRY_REGD("KI" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
195 | COUNTRY_REGD("XK" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
196 | COUNTRY_REGD("LA" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
197 | COUNTRY_REGD("LR" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
198 | COUNTRY_REGD("LY" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
199 | COUNTRY_REGD("MO" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
200 | COUNTRY_REGD("MG" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
201 | COUNTRY_REGD("MW" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
202 | COUNTRY_REGD("MV" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
203 | COUNTRY_REGD("ML" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
204 | COUNTRY_REGD("MH" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
205 | COUNTRY_REGD("MQ" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
206 | COUNTRY_REGD("MR" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
207 | COUNTRY_REGD("MU" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
208 | COUNTRY_REGD("YT" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
209 | COUNTRY_REGD("FM" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
210 | COUNTRY_REGD("MD" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
211 | COUNTRY_REGD("MN" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
212 | COUNTRY_REGD("MS" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
213 | COUNTRY_REGD("NR" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
214 | COUNTRY_REGD("NP" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
215 | COUNTRY_REGD("NC" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
216 | COUNTRY_REGD("NE" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
217 | COUNTRY_REGD("NU" , RTW89_ACMA, RTW89_ACMA, RTW89_NA), |
218 | COUNTRY_REGD("NF" , RTW89_ACMA, RTW89_ACMA, RTW89_NA), |
219 | COUNTRY_REGD("MP" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
220 | COUNTRY_REGD("PW" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
221 | COUNTRY_REGD("RE" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
222 | COUNTRY_REGD("RW" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
223 | COUNTRY_REGD("SH" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
224 | COUNTRY_REGD("KN" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
225 | COUNTRY_REGD("LC" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
226 | COUNTRY_REGD("MF" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
227 | COUNTRY_REGD("SX" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
228 | COUNTRY_REGD("PM" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
229 | COUNTRY_REGD("VC" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
230 | COUNTRY_REGD("WS" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
231 | COUNTRY_REGD("SM" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
232 | COUNTRY_REGD("ST" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
233 | COUNTRY_REGD("SC" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
234 | COUNTRY_REGD("SL" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
235 | COUNTRY_REGD("SB" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
236 | COUNTRY_REGD("SO" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
237 | COUNTRY_REGD("GS" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
238 | COUNTRY_REGD("SR" , RTW89_FCC, RTW89_FCC, RTW89_FCC), |
239 | COUNTRY_REGD("SJ" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
240 | COUNTRY_REGD("SZ" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
241 | COUNTRY_REGD("TJ" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
242 | COUNTRY_REGD("TZ" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
243 | COUNTRY_REGD("TG" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
244 | COUNTRY_REGD("TK" , RTW89_ACMA, RTW89_ACMA, RTW89_NA), |
245 | COUNTRY_REGD("TO" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
246 | COUNTRY_REGD("TM" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
247 | COUNTRY_REGD("TC" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
248 | COUNTRY_REGD("TV" , RTW89_ETSI, RTW89_NA, RTW89_NA), |
249 | COUNTRY_REGD("UG" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
250 | COUNTRY_REGD("VI" , RTW89_FCC, RTW89_FCC, RTW89_NA), |
251 | COUNTRY_REGD("UZ" , RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), |
252 | COUNTRY_REGD("VU" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
253 | COUNTRY_REGD("WF" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
254 | COUNTRY_REGD("EH" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
255 | COUNTRY_REGD("ZM" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
256 | COUNTRY_REGD("IR" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
257 | COUNTRY_REGD("PS" , RTW89_ETSI, RTW89_ETSI, RTW89_NA), |
258 | }; |
259 | |
260 | static const char rtw89_alpha2_list_eu[][3] = { |
261 | "AT" , |
262 | "BE" , |
263 | "CY" , |
264 | "CZ" , |
265 | "DK" , |
266 | "EE" , |
267 | "FI" , |
268 | "FR" , |
269 | "DE" , |
270 | "GR" , |
271 | "HU" , |
272 | "IS" , |
273 | "IE" , |
274 | "IT" , |
275 | "LV" , |
276 | "LI" , |
277 | "LT" , |
278 | "LU" , |
279 | "MT" , |
280 | "MC" , |
281 | "NL" , |
282 | "NO" , |
283 | "PL" , |
284 | "PT" , |
285 | "SK" , |
286 | "SI" , |
287 | "ES" , |
288 | "SE" , |
289 | "CH" , |
290 | "BG" , |
291 | "HR" , |
292 | "RO" , |
293 | }; |
294 | |
295 | static const struct rtw89_regd *rtw89_regd_find_reg_by_name(const char *alpha2) |
296 | { |
297 | u32 i; |
298 | |
299 | for (i = 0; i < ARRAY_SIZE(rtw89_regd_map); i++) { |
300 | if (!memcmp(p: rtw89_regd_map[i].alpha2, q: alpha2, size: 2)) |
301 | return &rtw89_regd_map[i]; |
302 | } |
303 | |
304 | return &rtw89_ww_regd; |
305 | } |
306 | |
307 | static bool rtw89_regd_is_ww(const struct rtw89_regd *regd) |
308 | { |
309 | return regd == &rtw89_ww_regd; |
310 | } |
311 | |
312 | static u8 rtw89_regd_get_index(const struct rtw89_regd *regd) |
313 | { |
314 | BUILD_BUG_ON(ARRAY_SIZE(rtw89_regd_map) > RTW89_REGD_MAX_COUNTRY_NUM); |
315 | |
316 | if (rtw89_regd_is_ww(regd)) |
317 | return RTW89_REGD_MAX_COUNTRY_NUM; |
318 | |
319 | return regd - rtw89_regd_map; |
320 | } |
321 | |
322 | static u8 rtw89_regd_get_index_by_name(const char *alpha2) |
323 | { |
324 | const struct rtw89_regd *regd; |
325 | |
326 | regd = rtw89_regd_find_reg_by_name(alpha2); |
327 | return rtw89_regd_get_index(regd); |
328 | } |
329 | |
330 | #define rtw89_debug_regd(_dev, _regd, _desc, _argv...) \ |
331 | do { \ |
332 | typeof(_regd) __r = _regd; \ |
333 | rtw89_debug(_dev, RTW89_DBG_REGD, _desc \ |
334 | ": %c%c: mapping txregd to {2g: %d, 5g: %d, 6g: %d}\n", \ |
335 | ##_argv, __r->alpha2[0], __r->alpha2[1], \ |
336 | __r->txpwr_regd[RTW89_BAND_2G], \ |
337 | __r->txpwr_regd[RTW89_BAND_5G], \ |
338 | __r->txpwr_regd[RTW89_BAND_6G]); \ |
339 | } while (0) |
340 | |
341 | static void rtw89_regd_setup_unii4(struct rtw89_dev *rtwdev, |
342 | struct wiphy *wiphy) |
343 | { |
344 | const struct rtw89_chip_info *chip = rtwdev->chip; |
345 | bool regd_allow_unii_4 = chip->support_unii4; |
346 | struct ieee80211_supported_band *sband; |
347 | struct rtw89_acpi_dsm_result res = {}; |
348 | int ret; |
349 | u8 val; |
350 | |
351 | if (!chip->support_unii4) |
352 | goto bottom; |
353 | |
354 | ret = rtw89_acpi_evaluate_dsm(rtwdev, func: RTW89_ACPI_DSM_FUNC_59G_EN, res: &res); |
355 | if (ret) { |
356 | rtw89_debug(rtwdev, mask: RTW89_DBG_REGD, |
357 | fmt: "acpi: cannot eval unii 4: %d\n" , ret); |
358 | goto bottom; |
359 | } |
360 | |
361 | val = res.u.value; |
362 | |
363 | rtw89_debug(rtwdev, mask: RTW89_DBG_REGD, |
364 | fmt: "acpi: eval if allow unii 4: %d\n" , val); |
365 | |
366 | switch (val) { |
367 | case 0: |
368 | regd_allow_unii_4 = false; |
369 | break; |
370 | case 1: |
371 | regd_allow_unii_4 = true; |
372 | break; |
373 | default: |
374 | break; |
375 | } |
376 | |
377 | bottom: |
378 | rtw89_debug(rtwdev, mask: RTW89_DBG_REGD, fmt: "regd: allow unii 4: %d\n" , |
379 | regd_allow_unii_4); |
380 | |
381 | if (regd_allow_unii_4) |
382 | return; |
383 | |
384 | sband = wiphy->bands[NL80211_BAND_5GHZ]; |
385 | if (!sband) |
386 | return; |
387 | |
388 | sband->n_channels -= 3; |
389 | } |
390 | |
391 | static void __rtw89_regd_setup_policy_6ghz(struct rtw89_dev *rtwdev, bool block, |
392 | const char *alpha2) |
393 | { |
394 | struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; |
395 | u8 index; |
396 | |
397 | index = rtw89_regd_get_index_by_name(alpha2); |
398 | if (index == RTW89_REGD_MAX_COUNTRY_NUM) { |
399 | rtw89_debug(rtwdev, mask: RTW89_DBG_REGD, fmt: "%s: unknown alpha2 %c%c\n" , |
400 | __func__, alpha2[0], alpha2[1]); |
401 | return; |
402 | } |
403 | |
404 | if (block) |
405 | set_bit(nr: index, addr: regulatory->block_6ghz); |
406 | else |
407 | clear_bit(nr: index, addr: regulatory->block_6ghz); |
408 | } |
409 | |
410 | static void rtw89_regd_setup_policy_6ghz(struct rtw89_dev *rtwdev) |
411 | { |
412 | struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; |
413 | const struct rtw89_acpi_country_code *country; |
414 | const struct rtw89_acpi_policy_6ghz *ptr; |
415 | struct rtw89_acpi_dsm_result res = {}; |
416 | bool to_block; |
417 | int i, j; |
418 | int ret; |
419 | |
420 | ret = rtw89_acpi_evaluate_dsm(rtwdev, func: RTW89_ACPI_DSM_FUNC_6G_BP, res: &res); |
421 | if (ret) { |
422 | rtw89_debug(rtwdev, mask: RTW89_DBG_REGD, |
423 | fmt: "acpi: cannot eval policy 6ghz: %d\n" , ret); |
424 | return; |
425 | } |
426 | |
427 | ptr = res.u.policy_6ghz; |
428 | |
429 | switch (ptr->policy_mode) { |
430 | case RTW89_ACPI_POLICY_BLOCK: |
431 | to_block = true; |
432 | break; |
433 | case RTW89_ACPI_POLICY_ALLOW: |
434 | to_block = false; |
435 | /* only below list is allowed; block all first */ |
436 | bitmap_fill(dst: regulatory->block_6ghz, RTW89_REGD_MAX_COUNTRY_NUM); |
437 | break; |
438 | default: |
439 | rtw89_debug(rtwdev, mask: RTW89_DBG_REGD, |
440 | fmt: "%s: unknown policy mode: %d\n" , __func__, |
441 | ptr->policy_mode); |
442 | goto out; |
443 | } |
444 | |
445 | for (i = 0; i < ptr->country_count; i++) { |
446 | country = &ptr->country_list[i]; |
447 | if (memcmp(p: "EU" , q: country->alpha2, size: 2) != 0) { |
448 | __rtw89_regd_setup_policy_6ghz(rtwdev, block: to_block, |
449 | alpha2: country->alpha2); |
450 | continue; |
451 | } |
452 | |
453 | for (j = 0; j < ARRAY_SIZE(rtw89_alpha2_list_eu); j++) |
454 | __rtw89_regd_setup_policy_6ghz(rtwdev, block: to_block, |
455 | alpha2: rtw89_alpha2_list_eu[j]); |
456 | } |
457 | |
458 | out: |
459 | kfree(objp: ptr); |
460 | } |
461 | |
462 | static void rtw89_regd_setup_6ghz(struct rtw89_dev *rtwdev, struct wiphy *wiphy) |
463 | { |
464 | const struct rtw89_chip_info *chip = rtwdev->chip; |
465 | bool chip_support_6ghz = chip->support_bands & BIT(NL80211_BAND_6GHZ); |
466 | bool regd_allow_6ghz = chip_support_6ghz; |
467 | struct ieee80211_supported_band *sband; |
468 | struct rtw89_acpi_dsm_result res = {}; |
469 | int ret; |
470 | u8 val; |
471 | |
472 | if (!chip_support_6ghz) |
473 | goto bottom; |
474 | |
475 | ret = rtw89_acpi_evaluate_dsm(rtwdev, func: RTW89_ACPI_DSM_FUNC_6G_DIS, res: &res); |
476 | if (ret) { |
477 | rtw89_debug(rtwdev, mask: RTW89_DBG_REGD, |
478 | fmt: "acpi: cannot eval 6ghz: %d\n" , ret); |
479 | goto bottom; |
480 | } |
481 | |
482 | val = res.u.value; |
483 | |
484 | rtw89_debug(rtwdev, mask: RTW89_DBG_REGD, |
485 | fmt: "acpi: eval if disallow 6ghz: %d\n" , val); |
486 | |
487 | switch (val) { |
488 | case 0: |
489 | regd_allow_6ghz = true; |
490 | break; |
491 | case 1: |
492 | regd_allow_6ghz = false; |
493 | break; |
494 | default: |
495 | break; |
496 | } |
497 | |
498 | bottom: |
499 | rtw89_debug(rtwdev, mask: RTW89_DBG_REGD, fmt: "regd: allow 6ghz: %d\n" , |
500 | regd_allow_6ghz); |
501 | |
502 | if (regd_allow_6ghz) { |
503 | rtw89_regd_setup_policy_6ghz(rtwdev); |
504 | return; |
505 | } |
506 | |
507 | sband = wiphy->bands[NL80211_BAND_6GHZ]; |
508 | if (!sband) |
509 | return; |
510 | |
511 | wiphy->bands[NL80211_BAND_6GHZ] = NULL; |
512 | kfree(objp: (__force void *)sband->iftype_data); |
513 | kfree(objp: sband); |
514 | } |
515 | |
516 | int rtw89_regd_setup(struct rtw89_dev *rtwdev) |
517 | { |
518 | struct wiphy *wiphy = rtwdev->hw->wiphy; |
519 | |
520 | if (!wiphy) |
521 | return -EINVAL; |
522 | |
523 | rtw89_regd_setup_unii4(rtwdev, wiphy); |
524 | rtw89_regd_setup_6ghz(rtwdev, wiphy); |
525 | |
526 | wiphy->reg_notifier = rtw89_regd_notifier; |
527 | return 0; |
528 | } |
529 | |
530 | int rtw89_regd_init(struct rtw89_dev *rtwdev, |
531 | void (*reg_notifier)(struct wiphy *wiphy, |
532 | struct regulatory_request *request)) |
533 | { |
534 | struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; |
535 | const struct rtw89_regd *chip_regd; |
536 | struct wiphy *wiphy = rtwdev->hw->wiphy; |
537 | int ret; |
538 | |
539 | regulatory->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; |
540 | |
541 | if (!wiphy) |
542 | return -EINVAL; |
543 | |
544 | chip_regd = rtw89_regd_find_reg_by_name(alpha2: rtwdev->efuse.country_code); |
545 | if (!rtw89_regd_is_ww(regd: chip_regd)) { |
546 | rtwdev->regulatory.regd = chip_regd; |
547 | /* Ignore country ie if there is a country domain programmed in chip */ |
548 | wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; |
549 | wiphy->regulatory_flags |= REGULATORY_STRICT_REG; |
550 | |
551 | ret = regulatory_hint(wiphy: rtwdev->hw->wiphy, |
552 | alpha2: rtwdev->regulatory.regd->alpha2); |
553 | if (ret) |
554 | rtw89_warn(rtwdev, "failed to hint regulatory:%d\n" , ret); |
555 | |
556 | rtw89_debug_regd(rtwdev, chip_regd, "efuse country code" ); |
557 | return 0; |
558 | } |
559 | |
560 | rtw89_debug_regd(rtwdev, rtwdev->regulatory.regd, |
561 | "worldwide roaming chip, follow the setting of stack" ); |
562 | return 0; |
563 | } |
564 | |
565 | static void rtw89_regd_apply_policy_6ghz(struct rtw89_dev *rtwdev, |
566 | struct wiphy *wiphy) |
567 | { |
568 | struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; |
569 | const struct rtw89_regd *regd = regulatory->regd; |
570 | struct ieee80211_supported_band *sband; |
571 | u8 index; |
572 | int i; |
573 | |
574 | index = rtw89_regd_get_index(regd); |
575 | if (index == RTW89_REGD_MAX_COUNTRY_NUM) |
576 | return; |
577 | |
578 | if (!test_bit(index, regulatory->block_6ghz)) |
579 | return; |
580 | |
581 | rtw89_debug(rtwdev, mask: RTW89_DBG_REGD, fmt: "%c%c 6 GHz is blocked by policy\n" , |
582 | regd->alpha2[0], regd->alpha2[1]); |
583 | |
584 | sband = wiphy->bands[NL80211_BAND_6GHZ]; |
585 | if (!sband) |
586 | return; |
587 | |
588 | for (i = 0; i < sband->n_channels; i++) |
589 | sband->channels[i].flags |= IEEE80211_CHAN_DISABLED; |
590 | } |
591 | |
592 | static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev, |
593 | struct wiphy *wiphy, |
594 | struct regulatory_request *request) |
595 | { |
596 | rtwdev->regulatory.regd = rtw89_regd_find_reg_by_name(alpha2: request->alpha2); |
597 | /* This notification might be set from the system of distros, |
598 | * and it does not expect the regulatory will be modified by |
599 | * connecting to an AP (i.e. country ie). |
600 | */ |
601 | if (request->initiator == NL80211_REGDOM_SET_BY_USER && |
602 | !rtw89_regd_is_ww(regd: rtwdev->regulatory.regd)) |
603 | wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; |
604 | else |
605 | wiphy->regulatory_flags &= ~REGULATORY_COUNTRY_IE_IGNORE; |
606 | |
607 | rtw89_regd_apply_policy_6ghz(rtwdev, wiphy); |
608 | } |
609 | |
610 | void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request) |
611 | { |
612 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); |
613 | struct rtw89_dev *rtwdev = hw->priv; |
614 | |
615 | mutex_lock(&rtwdev->mutex); |
616 | rtw89_leave_ps_mode(rtwdev); |
617 | |
618 | if (wiphy->regd) { |
619 | rtw89_debug(rtwdev, mask: RTW89_DBG_REGD, |
620 | fmt: "There is a country domain programmed in chip, ignore notifications\n" ); |
621 | goto exit; |
622 | } |
623 | rtw89_regd_notifier_apply(rtwdev, wiphy, request); |
624 | rtw89_debug_regd(rtwdev, rtwdev->regulatory.regd, |
625 | "get from initiator %d, alpha2" , |
626 | request->initiator); |
627 | |
628 | rtw89_core_set_chip_txpwr(rtwdev); |
629 | |
630 | exit: |
631 | mutex_unlock(lock: &rtwdev->mutex); |
632 | } |
633 | |
634 | static void __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev) |
635 | { |
636 | struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; |
637 | enum rtw89_reg_6ghz_power sel; |
638 | const struct rtw89_chan *chan; |
639 | struct rtw89_vif *rtwvif; |
640 | int count = 0; |
641 | |
642 | rtw89_for_each_rtwvif(rtwdev, rtwvif) { |
643 | chan = rtw89_chan_get(rtwdev, idx: rtwvif->sub_entity_idx); |
644 | if (chan->band_type != RTW89_BAND_6G) |
645 | continue; |
646 | |
647 | if (count != 0 && rtwvif->reg_6ghz_power == sel) |
648 | continue; |
649 | |
650 | sel = rtwvif->reg_6ghz_power; |
651 | count++; |
652 | } |
653 | |
654 | if (count != 1) |
655 | sel = RTW89_REG_6GHZ_POWER_DFLT; |
656 | |
657 | if (regulatory->reg_6ghz_power == sel) |
658 | return; |
659 | |
660 | rtw89_debug(rtwdev, mask: RTW89_DBG_REGD, |
661 | fmt: "recalc 6 GHz reg power type to %d\n" , sel); |
662 | |
663 | regulatory->reg_6ghz_power = sel; |
664 | |
665 | rtw89_core_set_chip_txpwr(rtwdev); |
666 | } |
667 | |
668 | void rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev, |
669 | struct rtw89_vif *rtwvif, bool active) |
670 | { |
671 | struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); |
672 | |
673 | lockdep_assert_held(&rtwdev->mutex); |
674 | |
675 | if (active) { |
676 | switch (vif->bss_conf.power_type) { |
677 | case IEEE80211_REG_VLP_AP: |
678 | rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_VLP; |
679 | break; |
680 | case IEEE80211_REG_LPI_AP: |
681 | rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_LPI; |
682 | break; |
683 | case IEEE80211_REG_SP_AP: |
684 | rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_STD; |
685 | break; |
686 | default: |
687 | rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; |
688 | break; |
689 | } |
690 | } else { |
691 | rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; |
692 | } |
693 | |
694 | __rtw89_reg_6ghz_power_recalc(rtwdev); |
695 | } |
696 | |