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
rtw89_regd_find_reg_by_name(const char * alpha2)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(rtw89_regd_map[i].alpha2, alpha2, 2))
301 return &rtw89_regd_map[i];
302 }
303
304 return &rtw89_ww_regd;
305 }
306
rtw89_regd_is_ww(const struct rtw89_regd * regd)307 static bool rtw89_regd_is_ww(const struct rtw89_regd *regd)
308 {
309 return regd == &rtw89_ww_regd;
310 }
311
rtw89_regd_get_index(const struct rtw89_regd * regd)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
rtw89_regd_get_index_by_name(const char * alpha2)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
rtw89_regd_setup_unii4(struct rtw89_dev * rtwdev,struct wiphy * wiphy)341 static void rtw89_regd_setup_unii4(struct rtw89_dev *rtwdev,
342 struct wiphy *wiphy)
343 {
344 struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
345 const struct rtw89_chip_info *chip = rtwdev->chip;
346 struct ieee80211_supported_band *sband;
347 struct rtw89_acpi_dsm_result res = {};
348 bool enable_by_fcc;
349 bool enable_by_ic;
350 int ret;
351 u8 val;
352 int i;
353
354 sband = wiphy->bands[NL80211_BAND_5GHZ];
355 if (!sband)
356 return;
357
358 if (!chip->support_unii4) {
359 sband->n_channels -= RTW89_5GHZ_UNII4_CHANNEL_NUM;
360 return;
361 }
362
363 bitmap_fill(regulatory->block_unii4, RTW89_REGD_MAX_COUNTRY_NUM);
364
365 ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_UNII4_SUP, &res);
366 if (ret) {
367 rtw89_debug(rtwdev, RTW89_DBG_REGD,
368 "acpi: cannot eval unii 4: %d\n", ret);
369 enable_by_fcc = true;
370 enable_by_ic = false;
371 goto bottom;
372 }
373
374 val = res.u.value;
375 enable_by_fcc = u8_get_bits(val, RTW89_ACPI_CONF_UNII4_FCC);
376 enable_by_ic = u8_get_bits(val, RTW89_ACPI_CONF_UNII4_IC);
377
378 rtw89_debug(rtwdev, RTW89_DBG_REGD,
379 "acpi: eval if allow unii-4: 0x%x\n", val);
380
381 bottom:
382 for (i = 0; i < ARRAY_SIZE(rtw89_regd_map); i++) {
383 const struct rtw89_regd *regd = &rtw89_regd_map[i];
384
385 switch (regd->txpwr_regd[RTW89_BAND_5G]) {
386 case RTW89_FCC:
387 if (enable_by_fcc)
388 clear_bit(i, regulatory->block_unii4);
389 break;
390 case RTW89_IC:
391 if (enable_by_ic)
392 clear_bit(i, regulatory->block_unii4);
393 break;
394 default:
395 break;
396 }
397 }
398 }
399
__rtw89_regd_setup_policy_6ghz(struct rtw89_dev * rtwdev,bool block,const char * alpha2)400 static void __rtw89_regd_setup_policy_6ghz(struct rtw89_dev *rtwdev, bool block,
401 const char *alpha2)
402 {
403 struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
404 u8 index;
405
406 index = rtw89_regd_get_index_by_name(alpha2);
407 if (index == RTW89_REGD_MAX_COUNTRY_NUM) {
408 rtw89_debug(rtwdev, RTW89_DBG_REGD, "%s: unknown alpha2 %c%c\n",
409 __func__, alpha2[0], alpha2[1]);
410 return;
411 }
412
413 if (block)
414 set_bit(index, regulatory->block_6ghz);
415 else
416 clear_bit(index, regulatory->block_6ghz);
417 }
418
rtw89_regd_setup_policy_6ghz(struct rtw89_dev * rtwdev)419 static void rtw89_regd_setup_policy_6ghz(struct rtw89_dev *rtwdev)
420 {
421 struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
422 const struct rtw89_acpi_country_code *country;
423 const struct rtw89_acpi_policy_6ghz *ptr;
424 struct rtw89_acpi_dsm_result res = {};
425 bool to_block;
426 int i, j;
427 int ret;
428
429 ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_6G_BP, &res);
430 if (ret) {
431 rtw89_debug(rtwdev, RTW89_DBG_REGD,
432 "acpi: cannot eval policy 6ghz: %d\n", ret);
433 return;
434 }
435
436 ptr = res.u.policy_6ghz;
437
438 switch (ptr->policy_mode) {
439 case RTW89_ACPI_POLICY_BLOCK:
440 to_block = true;
441 break;
442 case RTW89_ACPI_POLICY_ALLOW:
443 to_block = false;
444 /* only below list is allowed; block all first */
445 bitmap_fill(regulatory->block_6ghz, RTW89_REGD_MAX_COUNTRY_NUM);
446 break;
447 default:
448 rtw89_debug(rtwdev, RTW89_DBG_REGD,
449 "%s: unknown policy mode: %d\n", __func__,
450 ptr->policy_mode);
451 goto out;
452 }
453
454 for (i = 0; i < ptr->country_count; i++) {
455 country = &ptr->country_list[i];
456 if (memcmp("EU", country->alpha2, 2) != 0) {
457 __rtw89_regd_setup_policy_6ghz(rtwdev, to_block,
458 country->alpha2);
459 continue;
460 }
461
462 for (j = 0; j < ARRAY_SIZE(rtw89_alpha2_list_eu); j++)
463 __rtw89_regd_setup_policy_6ghz(rtwdev, to_block,
464 rtw89_alpha2_list_eu[j]);
465 }
466
467 out:
468 kfree(ptr);
469 }
470
rtw89_regd_setup_policy_6ghz_sp(struct rtw89_dev * rtwdev)471 static void rtw89_regd_setup_policy_6ghz_sp(struct rtw89_dev *rtwdev)
472 {
473 struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
474 const struct rtw89_acpi_policy_6ghz_sp *ptr;
475 struct rtw89_acpi_dsm_result res = {};
476 bool enable_by_us;
477 int ret;
478 int i;
479
480 ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP, &res);
481 if (ret) {
482 rtw89_debug(rtwdev, RTW89_DBG_REGD,
483 "acpi: cannot eval policy 6ghz-sp: %d\n", ret);
484 return;
485 }
486
487 ptr = res.u.policy_6ghz_sp;
488
489 switch (ptr->override) {
490 default:
491 rtw89_debug(rtwdev, RTW89_DBG_REGD,
492 "%s: unknown override case: %d\n", __func__,
493 ptr->override);
494 fallthrough;
495 case 0:
496 goto out;
497 case 1:
498 break;
499 }
500
501 bitmap_fill(regulatory->block_6ghz_sp, RTW89_REGD_MAX_COUNTRY_NUM);
502
503 enable_by_us = u8_get_bits(ptr->conf, RTW89_ACPI_CONF_6GHZ_SP_US);
504
505 for (i = 0; i < ARRAY_SIZE(rtw89_regd_map); i++) {
506 const struct rtw89_regd *tmp = &rtw89_regd_map[i];
507
508 if (enable_by_us && memcmp(tmp->alpha2, "US", 2) == 0)
509 clear_bit(i, regulatory->block_6ghz_sp);
510 }
511
512 out:
513 kfree(ptr);
514 }
515
rtw89_regd_setup_6ghz(struct rtw89_dev * rtwdev,struct wiphy * wiphy)516 static void rtw89_regd_setup_6ghz(struct rtw89_dev *rtwdev, struct wiphy *wiphy)
517 {
518 const struct rtw89_chip_info *chip = rtwdev->chip;
519 bool chip_support_6ghz = chip->support_bands & BIT(NL80211_BAND_6GHZ);
520 bool regd_allow_6ghz = chip_support_6ghz;
521 struct ieee80211_supported_band *sband;
522 struct rtw89_acpi_dsm_result res = {};
523 int ret;
524 u8 val;
525
526 if (!chip_support_6ghz)
527 goto bottom;
528
529 ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_6G_DIS, &res);
530 if (ret) {
531 rtw89_debug(rtwdev, RTW89_DBG_REGD,
532 "acpi: cannot eval 6ghz: %d\n", ret);
533 goto bottom;
534 }
535
536 val = res.u.value;
537
538 rtw89_debug(rtwdev, RTW89_DBG_REGD,
539 "acpi: eval if disallow 6ghz: %d\n", val);
540
541 switch (val) {
542 case 0:
543 regd_allow_6ghz = true;
544 break;
545 case 1:
546 regd_allow_6ghz = false;
547 break;
548 default:
549 break;
550 }
551
552 bottom:
553 rtw89_debug(rtwdev, RTW89_DBG_REGD, "regd: allow 6ghz: %d\n",
554 regd_allow_6ghz);
555
556 if (regd_allow_6ghz) {
557 rtw89_regd_setup_policy_6ghz(rtwdev);
558 rtw89_regd_setup_policy_6ghz_sp(rtwdev);
559 return;
560 }
561
562 sband = wiphy->bands[NL80211_BAND_6GHZ];
563 if (!sband)
564 return;
565
566 wiphy->bands[NL80211_BAND_6GHZ] = NULL;
567 kfree((__force void *)sband->iftype_data);
568 kfree(sband);
569 }
570
rtw89_regd_setup(struct rtw89_dev * rtwdev)571 int rtw89_regd_setup(struct rtw89_dev *rtwdev)
572 {
573 struct wiphy *wiphy = rtwdev->hw->wiphy;
574
575 if (!wiphy)
576 return -EINVAL;
577
578 rtw89_regd_setup_unii4(rtwdev, wiphy);
579 rtw89_regd_setup_6ghz(rtwdev, wiphy);
580
581 wiphy->reg_notifier = rtw89_regd_notifier;
582 return 0;
583 }
584
rtw89_regd_init(struct rtw89_dev * rtwdev,void (* reg_notifier)(struct wiphy * wiphy,struct regulatory_request * request))585 int rtw89_regd_init(struct rtw89_dev *rtwdev,
586 void (*reg_notifier)(struct wiphy *wiphy,
587 struct regulatory_request *request))
588 {
589 struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
590 const struct rtw89_regd *chip_regd;
591 struct wiphy *wiphy = rtwdev->hw->wiphy;
592 int ret;
593
594 regulatory->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
595
596 if (!wiphy)
597 return -EINVAL;
598
599 chip_regd = rtw89_regd_find_reg_by_name(rtwdev->efuse.country_code);
600 if (!rtw89_regd_is_ww(chip_regd)) {
601 rtwdev->regulatory.regd = chip_regd;
602 /* Ignore country ie if there is a country domain programmed in chip */
603 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
604 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
605
606 ret = regulatory_hint(rtwdev->hw->wiphy,
607 rtwdev->regulatory.regd->alpha2);
608 if (ret)
609 rtw89_warn(rtwdev, "failed to hint regulatory:%d\n", ret);
610
611 rtw89_debug_regd(rtwdev, chip_regd, "efuse country code");
612 return 0;
613 }
614
615 rtw89_debug_regd(rtwdev, rtwdev->regulatory.regd,
616 "worldwide roaming chip, follow the setting of stack");
617 return 0;
618 }
619
rtw89_regd_apply_policy_unii4(struct rtw89_dev * rtwdev,struct wiphy * wiphy)620 static void rtw89_regd_apply_policy_unii4(struct rtw89_dev *rtwdev,
621 struct wiphy *wiphy)
622 {
623 struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
624 const struct rtw89_chip_info *chip = rtwdev->chip;
625 const struct rtw89_regd *regd = regulatory->regd;
626 struct ieee80211_supported_band *sband;
627 u8 index;
628 int i;
629
630 sband = wiphy->bands[NL80211_BAND_5GHZ];
631 if (!sband)
632 return;
633
634 if (!chip->support_unii4)
635 return;
636
637 index = rtw89_regd_get_index(regd);
638 if (index != RTW89_REGD_MAX_COUNTRY_NUM &&
639 !test_bit(index, regulatory->block_unii4))
640 return;
641
642 rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c unii-4 is blocked by policy\n",
643 regd->alpha2[0], regd->alpha2[1]);
644
645 for (i = RTW89_5GHZ_UNII4_START_INDEX; i < sband->n_channels; i++)
646 sband->channels[i].flags |= IEEE80211_CHAN_DISABLED;
647 }
648
regd_is_6ghz_blocked(struct rtw89_dev * rtwdev)649 static bool regd_is_6ghz_blocked(struct rtw89_dev *rtwdev)
650 {
651 struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
652 const struct rtw89_regd *regd = regulatory->regd;
653 u8 index;
654
655 index = rtw89_regd_get_index(regd);
656 if (index != RTW89_REGD_MAX_COUNTRY_NUM &&
657 !test_bit(index, regulatory->block_6ghz))
658 return false;
659
660 rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c 6 GHz is blocked by policy\n",
661 regd->alpha2[0], regd->alpha2[1]);
662 return true;
663 }
664
regd_is_6ghz_not_applicable(struct rtw89_dev * rtwdev)665 static bool regd_is_6ghz_not_applicable(struct rtw89_dev *rtwdev)
666 {
667 struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
668 const struct rtw89_regd *regd = regulatory->regd;
669
670 if (regd->txpwr_regd[RTW89_BAND_6G] != RTW89_NA)
671 return false;
672
673 rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c 6 GHz is N/A in regd map\n",
674 regd->alpha2[0], regd->alpha2[1]);
675 return true;
676 }
677
rtw89_regd_apply_policy_6ghz(struct rtw89_dev * rtwdev,struct wiphy * wiphy)678 static void rtw89_regd_apply_policy_6ghz(struct rtw89_dev *rtwdev,
679 struct wiphy *wiphy)
680 {
681 struct ieee80211_supported_band *sband;
682 int i;
683
684 if (!regd_is_6ghz_blocked(rtwdev) &&
685 !regd_is_6ghz_not_applicable(rtwdev))
686 return;
687
688 sband = wiphy->bands[NL80211_BAND_6GHZ];
689 if (!sband)
690 return;
691
692 for (i = 0; i < sband->n_channels; i++)
693 sband->channels[i].flags |= IEEE80211_CHAN_DISABLED;
694 }
695
rtw89_regd_notifier_apply(struct rtw89_dev * rtwdev,struct wiphy * wiphy,struct regulatory_request * request)696 static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev,
697 struct wiphy *wiphy,
698 struct regulatory_request *request)
699 {
700 rtwdev->regulatory.regd = rtw89_regd_find_reg_by_name(request->alpha2);
701 /* This notification might be set from the system of distros,
702 * and it does not expect the regulatory will be modified by
703 * connecting to an AP (i.e. country ie).
704 */
705 if (request->initiator == NL80211_REGDOM_SET_BY_USER &&
706 !rtw89_regd_is_ww(rtwdev->regulatory.regd))
707 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
708 else
709 wiphy->regulatory_flags &= ~REGULATORY_COUNTRY_IE_IGNORE;
710
711 rtw89_regd_apply_policy_unii4(rtwdev, wiphy);
712 rtw89_regd_apply_policy_6ghz(rtwdev, wiphy);
713 }
714
rtw89_regd_notifier(struct wiphy * wiphy,struct regulatory_request * request)715 void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request)
716 {
717 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
718 struct rtw89_dev *rtwdev = hw->priv;
719
720 mutex_lock(&rtwdev->mutex);
721 rtw89_leave_ps_mode(rtwdev);
722
723 if (wiphy->regd) {
724 rtw89_debug(rtwdev, RTW89_DBG_REGD,
725 "There is a country domain programmed in chip, ignore notifications\n");
726 goto exit;
727 }
728 rtw89_regd_notifier_apply(rtwdev, wiphy, request);
729 rtw89_debug_regd(rtwdev, rtwdev->regulatory.regd,
730 "get from initiator %d, alpha2",
731 request->initiator);
732
733 rtw89_core_set_chip_txpwr(rtwdev);
734
735 exit:
736 mutex_unlock(&rtwdev->mutex);
737 }
738
739 /* Maximum Transmit Power field (@raw) can be EIRP or PSD.
740 * Both units are 0.5 dB-based. Return a constraint in dB.
741 */
tpe_get_constraint(s8 raw)742 static s8 tpe_get_constraint(s8 raw)
743 {
744 const u8 hw_deviation = 3; /* unit: 0.5 dB */
745 const u8 antenna_gain = 10; /* unit: 0.5 dB */
746 const u8 array_gain = 6; /* unit: 0.5 dB */
747 const u8 offset = hw_deviation + antenna_gain + array_gain;
748
749 return (raw - offset) / 2;
750 }
751
tpe_intersect_constraint(struct rtw89_reg_6ghz_tpe * tpe,s8 cstr)752 static void tpe_intersect_constraint(struct rtw89_reg_6ghz_tpe *tpe, s8 cstr)
753 {
754 if (tpe->valid) {
755 tpe->constraint = min(tpe->constraint, cstr);
756 return;
757 }
758
759 tpe->constraint = cstr;
760 tpe->valid = true;
761 }
762
tpe_deal_with_eirp(struct rtw89_reg_6ghz_tpe * tpe,const struct ieee80211_parsed_tpe_eirp * eirp)763 static void tpe_deal_with_eirp(struct rtw89_reg_6ghz_tpe *tpe,
764 const struct ieee80211_parsed_tpe_eirp *eirp)
765 {
766 unsigned int i;
767 s8 cstr;
768
769 if (!eirp->valid)
770 return;
771
772 for (i = 0; i < eirp->count; i++) {
773 cstr = tpe_get_constraint(eirp->power[i]);
774 tpe_intersect_constraint(tpe, cstr);
775 }
776 }
777
tpe_convert_psd_to_eirp(s8 psd)778 static s8 tpe_convert_psd_to_eirp(s8 psd)
779 {
780 static const unsigned int mlog20 = 1301;
781
782 return psd + 10 * mlog20 / 1000;
783 }
784
tpe_deal_with_psd(struct rtw89_reg_6ghz_tpe * tpe,const struct ieee80211_parsed_tpe_psd * psd)785 static void tpe_deal_with_psd(struct rtw89_reg_6ghz_tpe *tpe,
786 const struct ieee80211_parsed_tpe_psd *psd)
787 {
788 unsigned int i;
789 s8 cstr_psd;
790 s8 cstr;
791
792 if (!psd->valid)
793 return;
794
795 for (i = 0; i < psd->count; i++) {
796 cstr_psd = tpe_get_constraint(psd->power[i]);
797 cstr = tpe_convert_psd_to_eirp(cstr_psd);
798 tpe_intersect_constraint(tpe, cstr);
799 }
800 }
801
rtw89_calculate_tpe(struct rtw89_dev * rtwdev,struct rtw89_reg_6ghz_tpe * result_tpe,const struct ieee80211_parsed_tpe * parsed_tpe)802 static void rtw89_calculate_tpe(struct rtw89_dev *rtwdev,
803 struct rtw89_reg_6ghz_tpe *result_tpe,
804 const struct ieee80211_parsed_tpe *parsed_tpe)
805 {
806 static const u8 category = IEEE80211_TPE_CAT_6GHZ_DEFAULT;
807
808 tpe_deal_with_eirp(result_tpe, &parsed_tpe->max_local[category]);
809 tpe_deal_with_eirp(result_tpe, &parsed_tpe->max_reg_client[category]);
810 tpe_deal_with_psd(result_tpe, &parsed_tpe->psd_local[category]);
811 tpe_deal_with_psd(result_tpe, &parsed_tpe->psd_reg_client[category]);
812 }
813
__rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev * rtwdev)814 static bool __rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev *rtwdev)
815 {
816 struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
817 struct rtw89_reg_6ghz_tpe new = {};
818 struct rtw89_vif_link *rtwvif_link;
819 struct rtw89_vif *rtwvif;
820 unsigned int link_id;
821 bool changed = false;
822
823 rtw89_for_each_rtwvif(rtwdev, rtwvif) {
824 const struct rtw89_reg_6ghz_tpe *tmp;
825 const struct rtw89_chan *chan;
826
827 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
828 chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
829 if (chan->band_type != RTW89_BAND_6G)
830 continue;
831
832 tmp = &rtwvif_link->reg_6ghz_tpe;
833 if (!tmp->valid)
834 continue;
835
836 tpe_intersect_constraint(&new, tmp->constraint);
837 }
838 }
839
840 if (memcmp(®ulatory->reg_6ghz_tpe, &new,
841 sizeof(regulatory->reg_6ghz_tpe)) != 0)
842 changed = true;
843
844 if (changed) {
845 if (new.valid)
846 rtw89_debug(rtwdev, RTW89_DBG_REGD,
847 "recalc 6 GHz reg TPE to %d dBm\n",
848 new.constraint);
849 else
850 rtw89_debug(rtwdev, RTW89_DBG_REGD,
851 "recalc 6 GHz reg TPE to none\n");
852
853 regulatory->reg_6ghz_tpe = new;
854 }
855
856 return changed;
857 }
858
rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev * rtwdev,struct rtw89_vif_link * rtwvif_link,bool active,unsigned int * changed)859 static int rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev *rtwdev,
860 struct rtw89_vif_link *rtwvif_link, bool active,
861 unsigned int *changed)
862 {
863 struct rtw89_reg_6ghz_tpe *tpe = &rtwvif_link->reg_6ghz_tpe;
864 struct ieee80211_bss_conf *bss_conf;
865
866 memset(tpe, 0, sizeof(*tpe));
867
868 if (!active || rtwvif_link->reg_6ghz_power != RTW89_REG_6GHZ_POWER_STD)
869 goto bottom;
870
871 rcu_read_lock();
872
873 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
874 rtw89_calculate_tpe(rtwdev, tpe, &bss_conf->tpe);
875
876 rcu_read_unlock();
877
878 if (!tpe->valid)
879 goto bottom;
880
881 if (tpe->constraint < RTW89_MIN_VALID_POWER_CONSTRAINT) {
882 rtw89_err(rtwdev,
883 "%s: constraint %d dBm is less than min valid val\n",
884 __func__, tpe->constraint);
885
886 tpe->valid = false;
887 return -EINVAL;
888 }
889
890 bottom:
891 *changed += __rtw89_reg_6ghz_tpe_recalc(rtwdev);
892 return 0;
893 }
894
__rtw89_reg_6ghz_power_recalc(struct rtw89_dev * rtwdev)895 static bool __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev)
896 {
897 struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
898 const struct rtw89_regd *regd = regulatory->regd;
899 enum rtw89_reg_6ghz_power sel;
900 const struct rtw89_chan *chan;
901 struct rtw89_vif_link *rtwvif_link;
902 struct rtw89_vif *rtwvif;
903 unsigned int link_id;
904 int count = 0;
905 u8 index;
906
907 rtw89_for_each_rtwvif(rtwdev, rtwvif) {
908 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
909 chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
910 if (chan->band_type != RTW89_BAND_6G)
911 continue;
912
913 if (count != 0 && rtwvif_link->reg_6ghz_power == sel)
914 continue;
915
916 sel = rtwvif_link->reg_6ghz_power;
917 count++;
918 }
919 }
920
921 if (count != 1)
922 sel = RTW89_REG_6GHZ_POWER_DFLT;
923
924 if (sel == RTW89_REG_6GHZ_POWER_STD) {
925 index = rtw89_regd_get_index(regd);
926 if (index == RTW89_REGD_MAX_COUNTRY_NUM ||
927 test_bit(index, regulatory->block_6ghz_sp)) {
928 rtw89_debug(rtwdev, RTW89_DBG_REGD,
929 "%c%c 6 GHz SP is blocked by policy\n",
930 regd->alpha2[0], regd->alpha2[1]);
931 sel = RTW89_REG_6GHZ_POWER_DFLT;
932 }
933 }
934
935 if (regulatory->reg_6ghz_power == sel)
936 return false;
937
938 rtw89_debug(rtwdev, RTW89_DBG_REGD,
939 "recalc 6 GHz reg power type to %d\n", sel);
940
941 regulatory->reg_6ghz_power = sel;
942 return true;
943 }
944
rtw89_reg_6ghz_power_recalc(struct rtw89_dev * rtwdev,struct rtw89_vif_link * rtwvif_link,bool active,unsigned int * changed)945 static int rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev,
946 struct rtw89_vif_link *rtwvif_link, bool active,
947 unsigned int *changed)
948 {
949 struct ieee80211_bss_conf *bss_conf;
950
951 rcu_read_lock();
952
953 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
954
955 if (active) {
956 switch (bss_conf->power_type) {
957 case IEEE80211_REG_VLP_AP:
958 rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_VLP;
959 break;
960 case IEEE80211_REG_LPI_AP:
961 rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_LPI;
962 break;
963 case IEEE80211_REG_SP_AP:
964 rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_STD;
965 break;
966 default:
967 rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
968 break;
969 }
970 } else {
971 rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
972 }
973
974 rcu_read_unlock();
975
976 *changed += __rtw89_reg_6ghz_power_recalc(rtwdev);
977 return 0;
978 }
979
rtw89_reg_6ghz_recalc(struct rtw89_dev * rtwdev,struct rtw89_vif_link * rtwvif_link,bool active)980 int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
981 bool active)
982 {
983 unsigned int changed = 0;
984 int ret;
985
986 lockdep_assert_held(&rtwdev->mutex);
987
988 /* The result of reg_6ghz_tpe may depend on reg_6ghz_power type,
989 * so must do reg_6ghz_tpe_recalc() after reg_6ghz_power_recalc().
990 */
991
992 ret = rtw89_reg_6ghz_power_recalc(rtwdev, rtwvif_link, active, &changed);
993 if (ret)
994 return ret;
995
996 ret = rtw89_reg_6ghz_tpe_recalc(rtwdev, rtwvif_link, active, &changed);
997 if (ret)
998 return ret;
999
1000 if (changed)
1001 rtw89_core_set_chip_txpwr(rtwdev);
1002
1003 return 0;
1004 }
1005