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