xref: /freebsd/sys/contrib/dev/rtw89/regd.c (revision 354a030185c650d1465ed2035a83636b8f825d72)
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 static
11 void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request);
12 
13 #define COUNTRY_REGD(_alpha2, _rule_2ghz, _rule_5ghz, _rule_6ghz, _fmap) \
14 	{							\
15 		.alpha2 = _alpha2,				\
16 		.txpwr_regd[RTW89_BAND_2G] = _rule_2ghz,	\
17 		.txpwr_regd[RTW89_BAND_5G] = _rule_5ghz,	\
18 		.txpwr_regd[RTW89_BAND_6G] = _rule_6ghz,	\
19 		.func_bitmap = { _fmap, },	\
20 	}
21 
22 static_assert(BITS_PER_TYPE(unsigned long) >= NUM_OF_RTW89_REGD_FUNC);
23 
24 static const struct rtw89_regd rtw89_ww_regd =
25 	COUNTRY_REGD("00", RTW89_WW, RTW89_WW, RTW89_WW, 0x0);
26 
27 static const struct rtw89_regd rtw89_regd_map[] = {
28 	COUNTRY_REGD("AR", RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC, 0x0),
29 	COUNTRY_REGD("BO", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
30 	COUNTRY_REGD("BR", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
31 	COUNTRY_REGD("CL", RTW89_CHILE, RTW89_CHILE, RTW89_CHILE, 0x0),
32 	COUNTRY_REGD("CO", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
33 	COUNTRY_REGD("CR", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
34 	COUNTRY_REGD("EC", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
35 	COUNTRY_REGD("SV", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
36 	COUNTRY_REGD("GT", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
37 	COUNTRY_REGD("HN", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
38 	COUNTRY_REGD("MX", RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC, 0x0),
39 	COUNTRY_REGD("NI", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
40 	COUNTRY_REGD("PA", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
41 	COUNTRY_REGD("PY", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
42 	COUNTRY_REGD("PE", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
43 	COUNTRY_REGD("US", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x1),
44 	COUNTRY_REGD("UY", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
45 	COUNTRY_REGD("VE", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
46 	COUNTRY_REGD("PR", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
47 	COUNTRY_REGD("DO", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
48 	COUNTRY_REGD("AT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
49 	COUNTRY_REGD("BE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
50 	COUNTRY_REGD("CY", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
51 	COUNTRY_REGD("CZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
52 	COUNTRY_REGD("DK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
53 	COUNTRY_REGD("EE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
54 	COUNTRY_REGD("FI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
55 	COUNTRY_REGD("FR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
56 	COUNTRY_REGD("DE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
57 	COUNTRY_REGD("GR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
58 	COUNTRY_REGD("HU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
59 	COUNTRY_REGD("IS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
60 	COUNTRY_REGD("IE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
61 	COUNTRY_REGD("IT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
62 	COUNTRY_REGD("LV", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
63 	COUNTRY_REGD("LI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
64 	COUNTRY_REGD("LT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
65 	COUNTRY_REGD("LU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
66 	COUNTRY_REGD("MT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
67 	COUNTRY_REGD("MC", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
68 	COUNTRY_REGD("NL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
69 	COUNTRY_REGD("NO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
70 	COUNTRY_REGD("PL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
71 	COUNTRY_REGD("PT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
72 	COUNTRY_REGD("SK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
73 	COUNTRY_REGD("SI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
74 	COUNTRY_REGD("ES", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
75 	COUNTRY_REGD("SE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
76 	COUNTRY_REGD("CH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
77 	COUNTRY_REGD("GB", RTW89_UK, RTW89_UK, RTW89_UK, 0x0),
78 	COUNTRY_REGD("AL", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
79 	COUNTRY_REGD("AZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
80 	COUNTRY_REGD("BH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
81 	COUNTRY_REGD("BA", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
82 	COUNTRY_REGD("BG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
83 	COUNTRY_REGD("HR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
84 	COUNTRY_REGD("EG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
85 	COUNTRY_REGD("GH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
86 	COUNTRY_REGD("IQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
87 	COUNTRY_REGD("IL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
88 	COUNTRY_REGD("JO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
89 	COUNTRY_REGD("KZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
90 	COUNTRY_REGD("KE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
91 	COUNTRY_REGD("KW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
92 	COUNTRY_REGD("KG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
93 	COUNTRY_REGD("LB", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
94 	COUNTRY_REGD("LS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
95 	COUNTRY_REGD("MK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
96 	COUNTRY_REGD("MA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
97 	COUNTRY_REGD("MZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
98 	COUNTRY_REGD("NA", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
99 	COUNTRY_REGD("NG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
100 	COUNTRY_REGD("OM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
101 	COUNTRY_REGD("QA", RTW89_QATAR, RTW89_QATAR, RTW89_QATAR, 0x0),
102 	COUNTRY_REGD("RO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
103 	COUNTRY_REGD("RU", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
104 	COUNTRY_REGD("SA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
105 	COUNTRY_REGD("SN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
106 	COUNTRY_REGD("RS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
107 	COUNTRY_REGD("ME", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
108 	COUNTRY_REGD("ZA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
109 	COUNTRY_REGD("TR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
110 	COUNTRY_REGD("UA", RTW89_UKRAINE, RTW89_UKRAINE, RTW89_UKRAINE, 0x0),
111 	COUNTRY_REGD("AE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
112 	COUNTRY_REGD("YE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
113 	COUNTRY_REGD("ZW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
114 	COUNTRY_REGD("BD", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
115 	COUNTRY_REGD("KH", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
116 	COUNTRY_REGD("CN", RTW89_CN, RTW89_CN, RTW89_CN, 0x0),
117 	COUNTRY_REGD("HK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
118 	COUNTRY_REGD("IN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
119 	COUNTRY_REGD("ID", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
120 	COUNTRY_REGD("KR", RTW89_KCC, RTW89_KCC, RTW89_KCC, 0x1),
121 	COUNTRY_REGD("MY", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
122 	COUNTRY_REGD("PK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
123 	COUNTRY_REGD("PH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
124 	COUNTRY_REGD("SG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
125 	COUNTRY_REGD("LK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
126 	COUNTRY_REGD("TW", RTW89_FCC, RTW89_FCC, RTW89_ETSI, 0x0),
127 	COUNTRY_REGD("TH", RTW89_THAILAND, RTW89_THAILAND, RTW89_THAILAND, 0x0),
128 	COUNTRY_REGD("VN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
129 	COUNTRY_REGD("AU", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA, 0x0),
130 	COUNTRY_REGD("NZ", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA, 0x0),
131 	COUNTRY_REGD("PG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
132 	COUNTRY_REGD("CA", RTW89_IC, RTW89_IC, RTW89_IC, 0x1),
133 	COUNTRY_REGD("JP", RTW89_MKK, RTW89_MKK, RTW89_MKK, 0x0),
134 	COUNTRY_REGD("JM", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
135 	COUNTRY_REGD("AN", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
136 	COUNTRY_REGD("TT", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
137 	COUNTRY_REGD("TN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
138 	COUNTRY_REGD("AF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
139 	COUNTRY_REGD("DZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
140 	COUNTRY_REGD("AS", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
141 	COUNTRY_REGD("AD", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
142 	COUNTRY_REGD("AO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
143 	COUNTRY_REGD("AI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
144 	COUNTRY_REGD("AQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
145 	COUNTRY_REGD("AG", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
146 	COUNTRY_REGD("AM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
147 	COUNTRY_REGD("AW", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
148 	COUNTRY_REGD("BS", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
149 	COUNTRY_REGD("BB", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
150 	COUNTRY_REGD("BY", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
151 	COUNTRY_REGD("BZ", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
152 	COUNTRY_REGD("BJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
153 	COUNTRY_REGD("BM", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
154 	COUNTRY_REGD("BT", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
155 	COUNTRY_REGD("BW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
156 	COUNTRY_REGD("BV", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
157 	COUNTRY_REGD("IO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
158 	COUNTRY_REGD("VG", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
159 	COUNTRY_REGD("BN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
160 	COUNTRY_REGD("BF", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
161 	COUNTRY_REGD("MM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
162 	COUNTRY_REGD("BI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
163 	COUNTRY_REGD("CM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
164 	COUNTRY_REGD("CV", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
165 	COUNTRY_REGD("KY", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
166 	COUNTRY_REGD("CF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
167 	COUNTRY_REGD("TD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
168 	COUNTRY_REGD("CX", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0),
169 	COUNTRY_REGD("CC", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0),
170 	COUNTRY_REGD("KM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
171 	COUNTRY_REGD("CG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
172 	COUNTRY_REGD("CD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
173 	COUNTRY_REGD("CK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
174 	COUNTRY_REGD("CI", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
175 	COUNTRY_REGD("DJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
176 	COUNTRY_REGD("DM", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
177 	COUNTRY_REGD("GQ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
178 	COUNTRY_REGD("ER", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
179 	COUNTRY_REGD("ET", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
180 	COUNTRY_REGD("FK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
181 	COUNTRY_REGD("FO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
182 	COUNTRY_REGD("FJ", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
183 	COUNTRY_REGD("GF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
184 	COUNTRY_REGD("PF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
185 	COUNTRY_REGD("TF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
186 	COUNTRY_REGD("GA", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
187 	COUNTRY_REGD("GM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
188 	COUNTRY_REGD("GE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
189 	COUNTRY_REGD("GI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
190 	COUNTRY_REGD("GL", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
191 	COUNTRY_REGD("GD", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
192 	COUNTRY_REGD("GP", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
193 	COUNTRY_REGD("GU", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
194 	COUNTRY_REGD("GG", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
195 	COUNTRY_REGD("GN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
196 	COUNTRY_REGD("GW", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
197 	COUNTRY_REGD("GY", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
198 	COUNTRY_REGD("HT", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
199 	COUNTRY_REGD("HM", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0),
200 	COUNTRY_REGD("VA", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
201 	COUNTRY_REGD("IM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
202 	COUNTRY_REGD("JE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
203 	COUNTRY_REGD("KI", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
204 	COUNTRY_REGD("XK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
205 	COUNTRY_REGD("LA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
206 	COUNTRY_REGD("LR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
207 	COUNTRY_REGD("LY", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
208 	COUNTRY_REGD("MO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
209 	COUNTRY_REGD("MG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
210 	COUNTRY_REGD("MW", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
211 	COUNTRY_REGD("MV", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
212 	COUNTRY_REGD("ML", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
213 	COUNTRY_REGD("MH", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
214 	COUNTRY_REGD("MQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
215 	COUNTRY_REGD("MR", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
216 	COUNTRY_REGD("MU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
217 	COUNTRY_REGD("YT", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
218 	COUNTRY_REGD("FM", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
219 	COUNTRY_REGD("MD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
220 	COUNTRY_REGD("MN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
221 	COUNTRY_REGD("MS", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
222 	COUNTRY_REGD("NR", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
223 	COUNTRY_REGD("NP", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
224 	COUNTRY_REGD("NC", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
225 	COUNTRY_REGD("NE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
226 	COUNTRY_REGD("NU", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0),
227 	COUNTRY_REGD("NF", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0),
228 	COUNTRY_REGD("MP", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
229 	COUNTRY_REGD("PW", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
230 	COUNTRY_REGD("RE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
231 	COUNTRY_REGD("RW", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
232 	COUNTRY_REGD("SH", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
233 	COUNTRY_REGD("KN", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
234 	COUNTRY_REGD("LC", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
235 	COUNTRY_REGD("MF", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
236 	COUNTRY_REGD("SX", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
237 	COUNTRY_REGD("PM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
238 	COUNTRY_REGD("VC", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
239 	COUNTRY_REGD("WS", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
240 	COUNTRY_REGD("SM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
241 	COUNTRY_REGD("ST", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
242 	COUNTRY_REGD("SC", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
243 	COUNTRY_REGD("SL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
244 	COUNTRY_REGD("SB", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
245 	COUNTRY_REGD("SO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
246 	COUNTRY_REGD("GS", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
247 	COUNTRY_REGD("SR", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
248 	COUNTRY_REGD("SJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
249 	COUNTRY_REGD("SZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
250 	COUNTRY_REGD("TJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
251 	COUNTRY_REGD("TZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
252 	COUNTRY_REGD("TG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
253 	COUNTRY_REGD("TK", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0),
254 	COUNTRY_REGD("TO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
255 	COUNTRY_REGD("TM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
256 	COUNTRY_REGD("TC", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
257 	COUNTRY_REGD("TV", RTW89_ETSI, RTW89_NA, RTW89_NA, 0x0),
258 	COUNTRY_REGD("UG", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
259 	COUNTRY_REGD("VI", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
260 	COUNTRY_REGD("UZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
261 	COUNTRY_REGD("VU", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
262 	COUNTRY_REGD("WF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
263 	COUNTRY_REGD("EH", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
264 	COUNTRY_REGD("ZM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
265 	COUNTRY_REGD("CU", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
266 	COUNTRY_REGD("IR", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
267 	COUNTRY_REGD("SY", RTW89_ETSI, RTW89_NA, RTW89_NA, 0x0),
268 	COUNTRY_REGD("SD", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
269 	COUNTRY_REGD("PS", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
270 };
271 
272 static const char rtw89_alpha2_list_eu[][3] = {
273 	"AT",
274 	"BE",
275 	"CY",
276 	"CZ",
277 	"DK",
278 	"EE",
279 	"FI",
280 	"FR",
281 	"DE",
282 	"GR",
283 	"HU",
284 	"IS",
285 	"IE",
286 	"IT",
287 	"LV",
288 	"LI",
289 	"LT",
290 	"LU",
291 	"MT",
292 	"MC",
293 	"NL",
294 	"NO",
295 	"PL",
296 	"PT",
297 	"SK",
298 	"SI",
299 	"ES",
300 	"SE",
301 	"CH",
302 	"BG",
303 	"HR",
304 	"RO",
305 };
306 
rtw89_regd_find_reg_by_name(struct rtw89_dev * rtwdev,const char * alpha2)307 static const struct rtw89_regd *rtw89_regd_find_reg_by_name(struct rtw89_dev *rtwdev,
308 							    const char *alpha2)
309 {
310 	struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
311 	const struct rtw89_regd_ctrl *regd_ctrl = &regulatory->ctrl;
312 	u32 i;
313 
314 	for (i = 0; i < regd_ctrl->nr; i++) {
315 		if (!memcmp(regd_ctrl->map[i].alpha2, alpha2, 2))
316 			return &regd_ctrl->map[i];
317 	}
318 
319 	return &rtw89_ww_regd;
320 }
321 
rtw89_regd_is_ww(const struct rtw89_regd * regd)322 static bool rtw89_regd_is_ww(const struct rtw89_regd *regd)
323 {
324 	return regd == &rtw89_ww_regd;
325 }
326 
rtw89_regd_get_index(struct rtw89_dev * rtwdev,const struct rtw89_regd * regd)327 static u8 rtw89_regd_get_index(struct rtw89_dev *rtwdev, const struct rtw89_regd *regd)
328 {
329 	struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
330 	const struct rtw89_regd_ctrl *regd_ctrl = &regulatory->ctrl;
331 
332 	BUILD_BUG_ON(ARRAY_SIZE(rtw89_regd_map) > RTW89_REGD_MAX_COUNTRY_NUM);
333 
334 	if (rtw89_regd_is_ww(regd))
335 		return RTW89_REGD_MAX_COUNTRY_NUM;
336 
337 	return regd - regd_ctrl->map;
338 }
339 
rtw89_regd_get_index_by_name(struct rtw89_dev * rtwdev,const char * alpha2)340 static u8 rtw89_regd_get_index_by_name(struct rtw89_dev *rtwdev, const char *alpha2)
341 {
342 	const struct rtw89_regd *regd;
343 
344 	regd = rtw89_regd_find_reg_by_name(rtwdev, alpha2);
345 	return rtw89_regd_get_index(rtwdev, regd);
346 }
347 
348 #define rtw89_debug_regd(_dev, _regd, _desc, _argv...) \
349 do { \
350 	typeof(_regd) __r = _regd; \
351 	rtw89_debug(_dev, RTW89_DBG_REGD, _desc \
352 		    ": %c%c: mapping txregd to {2g: %d, 5g: %d, 6g: %d}\n", \
353 		    ##_argv, __r->alpha2[0], __r->alpha2[1], \
354 		    __r->txpwr_regd[RTW89_BAND_2G], \
355 		    __r->txpwr_regd[RTW89_BAND_5G], \
356 		    __r->txpwr_regd[RTW89_BAND_6G]); \
357 } while (0)
358 
rtw89_regd_setup_unii4(struct rtw89_dev * rtwdev,struct wiphy * wiphy)359 static void rtw89_regd_setup_unii4(struct rtw89_dev *rtwdev,
360 				   struct wiphy *wiphy)
361 {
362 	struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
363 	const struct rtw89_chip_info *chip = rtwdev->chip;
364 	struct ieee80211_supported_band *sband;
365 	struct rtw89_acpi_dsm_result res = {};
366 	bool enable;
367 	u8 index;
368 	int ret;
369 	u8 val;
370 
371 	sband = wiphy->bands[NL80211_BAND_5GHZ];
372 	if (!sband)
373 		return;
374 
375 	if (!chip->support_unii4) {
376 		sband->n_channels -= RTW89_5GHZ_UNII4_CHANNEL_NUM;
377 		return;
378 	}
379 
380 	bitmap_fill(regulatory->block_unii4, RTW89_REGD_MAX_COUNTRY_NUM);
381 
382 	ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_UNII4_SUP, &res);
383 	if (ret) {
384 		rtw89_debug(rtwdev, RTW89_DBG_REGD,
385 			    "acpi: cannot eval unii 4: %d\n", ret);
386 		val = u8_encode_bits(1, RTW89_ACPI_CONF_UNII4_US);
387 		goto bottom;
388 	}
389 
390 	val = res.u.value;
391 
392 	rtw89_debug(rtwdev, RTW89_DBG_REGD,
393 		    "acpi: eval if allow unii-4: 0x%x\n", val);
394 
395 bottom:
396 	index = rtw89_regd_get_index_by_name(rtwdev, "US");
397 	enable = u8_get_bits(val, RTW89_ACPI_CONF_UNII4_US);
398 	if (enable && index != RTW89_REGD_MAX_COUNTRY_NUM)
399 		clear_bit(index, regulatory->block_unii4);
400 
401 	index = rtw89_regd_get_index_by_name(rtwdev, "CA");
402 	enable = u8_get_bits(val, RTW89_ACPI_CONF_UNII4_CA);
403 	if (enable && index != RTW89_REGD_MAX_COUNTRY_NUM)
404 		clear_bit(index, regulatory->block_unii4);
405 }
406 
__rtw89_regd_setup_policy_6ghz(struct rtw89_dev * rtwdev,bool block,const char * alpha2)407 static void __rtw89_regd_setup_policy_6ghz(struct rtw89_dev *rtwdev, bool block,
408 					   const char *alpha2)
409 {
410 	struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
411 	u8 index;
412 
413 	index = rtw89_regd_get_index_by_name(rtwdev, alpha2);
414 	if (index == RTW89_REGD_MAX_COUNTRY_NUM) {
415 		rtw89_debug(rtwdev, RTW89_DBG_REGD, "%s: unknown alpha2 %c%c\n",
416 			    __func__, alpha2[0], alpha2[1]);
417 		return;
418 	}
419 
420 	if (block)
421 		set_bit(index, regulatory->block_6ghz);
422 	else
423 		clear_bit(index, regulatory->block_6ghz);
424 }
425 
rtw89_regd_setup_policy_6ghz(struct rtw89_dev * rtwdev)426 static void rtw89_regd_setup_policy_6ghz(struct rtw89_dev *rtwdev)
427 {
428 	struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
429 	const struct rtw89_acpi_country_code *country;
430 	const struct rtw89_acpi_policy_6ghz *ptr;
431 	struct rtw89_acpi_dsm_result res = {};
432 	bool to_block;
433 	int i, j;
434 	int ret;
435 
436 	ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_6G_BP, &res);
437 	if (ret) {
438 		rtw89_debug(rtwdev, RTW89_DBG_REGD,
439 			    "acpi: cannot eval policy 6ghz: %d\n", ret);
440 		return;
441 	}
442 
443 	ptr = res.u.policy_6ghz;
444 
445 	switch (ptr->policy_mode) {
446 	case RTW89_ACPI_POLICY_BLOCK:
447 		to_block = true;
448 		break;
449 	case RTW89_ACPI_POLICY_ALLOW:
450 		to_block = false;
451 		/* only below list is allowed; block all first */
452 		bitmap_fill(regulatory->block_6ghz, RTW89_REGD_MAX_COUNTRY_NUM);
453 		break;
454 	default:
455 		rtw89_debug(rtwdev, RTW89_DBG_REGD,
456 			    "%s: unknown policy mode: %d\n", __func__,
457 			    ptr->policy_mode);
458 		goto out;
459 	}
460 
461 	for (i = 0; i < ptr->country_count; i++) {
462 		country = &ptr->country_list[i];
463 		if (memcmp("EU", country->alpha2, 2) != 0) {
464 			__rtw89_regd_setup_policy_6ghz(rtwdev, to_block,
465 						       country->alpha2);
466 			continue;
467 		}
468 
469 		for (j = 0; j < ARRAY_SIZE(rtw89_alpha2_list_eu); j++)
470 			__rtw89_regd_setup_policy_6ghz(rtwdev, to_block,
471 						       rtw89_alpha2_list_eu[j]);
472 	}
473 
474 out:
475 	kfree(ptr);
476 }
477 
rtw89_regd_setup_policy_6ghz_sp(struct rtw89_dev * rtwdev)478 static void rtw89_regd_setup_policy_6ghz_sp(struct rtw89_dev *rtwdev)
479 {
480 	struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
481 	const struct rtw89_acpi_policy_6ghz_sp *ptr;
482 	struct rtw89_acpi_dsm_result res = {};
483 	bool enable;
484 	u8 index;
485 	int ret;
486 
487 	ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP, &res);
488 	if (ret) {
489 		rtw89_debug(rtwdev, RTW89_DBG_REGD,
490 			    "acpi: cannot eval policy 6ghz-sp: %d\n", ret);
491 		return;
492 	}
493 
494 	ptr = res.u.policy_6ghz_sp;
495 
496 	switch (ptr->override) {
497 	default:
498 		rtw89_debug(rtwdev, RTW89_DBG_REGD,
499 			    "%s: unknown override case: %d\n", __func__,
500 			    ptr->override);
501 		fallthrough;
502 	case 0:
503 		goto out;
504 	case 1:
505 		break;
506 	}
507 
508 	bitmap_fill(regulatory->block_6ghz_sp, RTW89_REGD_MAX_COUNTRY_NUM);
509 
510 	index = rtw89_regd_get_index_by_name(rtwdev, "US");
511 	enable = u8_get_bits(ptr->conf, RTW89_ACPI_CONF_6GHZ_SP_US);
512 	if (enable && index != RTW89_REGD_MAX_COUNTRY_NUM)
513 		clear_bit(index, regulatory->block_6ghz_sp);
514 
515 	index = rtw89_regd_get_index_by_name(rtwdev, "CA");
516 	enable = u8_get_bits(ptr->conf, RTW89_ACPI_CONF_6GHZ_SP_CA);
517 	if (enable && index != RTW89_REGD_MAX_COUNTRY_NUM)
518 		clear_bit(index, regulatory->block_6ghz_sp);
519 
520 out:
521 	kfree(ptr);
522 }
523 
rtw89_regd_setup_policy_6ghz_vlp(struct rtw89_dev * rtwdev)524 static void rtw89_regd_setup_policy_6ghz_vlp(struct rtw89_dev *rtwdev)
525 {
526 	struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
527 	const struct rtw89_acpi_policy_6ghz_vlp *ptr = NULL;
528 	struct rtw89_acpi_dsm_result res = {};
529 	bool enable;
530 	u8 index;
531 	int ret;
532 	u8 val;
533 
534 	/* By default, allow 6 GHz VLP on all countries except US and CA. */
535 	val = ~(RTW89_ACPI_CONF_6GHZ_VLP_US | RTW89_ACPI_CONF_6GHZ_VLP_CA);
536 
537 	ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_6GHZ_VLP_SUP, &res);
538 	if (ret) {
539 		rtw89_debug(rtwdev, RTW89_DBG_REGD,
540 			    "acpi: cannot eval policy 6ghz-vlp: %d\n", ret);
541 		goto bottom;
542 	}
543 
544 	ptr = res.u.policy_6ghz_vlp;
545 
546 	switch (ptr->override) {
547 	default:
548 		rtw89_debug(rtwdev, RTW89_DBG_REGD,
549 			    "%s: unknown override case: %d\n", __func__,
550 			    ptr->override);
551 		fallthrough;
552 	case 0:
553 		break;
554 	case 1:
555 		val = ptr->conf;
556 		break;
557 	}
558 
559 bottom:
560 	index = rtw89_regd_get_index_by_name(rtwdev, "US");
561 	enable = u8_get_bits(val, RTW89_ACPI_CONF_6GHZ_VLP_US);
562 	if (!enable && index != RTW89_REGD_MAX_COUNTRY_NUM)
563 		set_bit(index, regulatory->block_6ghz_vlp);
564 
565 	index = rtw89_regd_get_index_by_name(rtwdev, "CA");
566 	enable = u8_get_bits(val, RTW89_ACPI_CONF_6GHZ_VLP_CA);
567 	if (!enable && index != RTW89_REGD_MAX_COUNTRY_NUM)
568 		set_bit(index, regulatory->block_6ghz_vlp);
569 
570 	kfree(ptr);
571 }
572 
rtw89_regd_setup_6ghz(struct rtw89_dev * rtwdev,struct wiphy * wiphy)573 static void rtw89_regd_setup_6ghz(struct rtw89_dev *rtwdev, struct wiphy *wiphy)
574 {
575 	const struct rtw89_chip_info *chip = rtwdev->chip;
576 	bool chip_support_6ghz = chip->support_bands & BIT(NL80211_BAND_6GHZ);
577 	bool regd_allow_6ghz = chip_support_6ghz;
578 	struct ieee80211_supported_band *sband;
579 	struct rtw89_acpi_dsm_result res = {};
580 	int ret;
581 	u8 val;
582 
583 	if (!chip_support_6ghz)
584 		goto bottom;
585 
586 	ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_6G_DIS, &res);
587 	if (ret) {
588 		rtw89_debug(rtwdev, RTW89_DBG_REGD,
589 			    "acpi: cannot eval 6ghz: %d\n", ret);
590 		goto bottom;
591 	}
592 
593 	val = res.u.value;
594 
595 	rtw89_debug(rtwdev, RTW89_DBG_REGD,
596 		    "acpi: eval if disallow 6ghz: %d\n", val);
597 
598 	switch (val) {
599 	case 0:
600 		regd_allow_6ghz = true;
601 		break;
602 	case 1:
603 		regd_allow_6ghz = false;
604 		break;
605 	default:
606 		break;
607 	}
608 
609 bottom:
610 	rtw89_debug(rtwdev, RTW89_DBG_REGD, "regd: allow 6ghz: %d\n",
611 		    regd_allow_6ghz);
612 
613 	if (regd_allow_6ghz) {
614 		rtw89_regd_setup_policy_6ghz(rtwdev);
615 		rtw89_regd_setup_policy_6ghz_sp(rtwdev);
616 		rtw89_regd_setup_policy_6ghz_vlp(rtwdev);
617 		return;
618 	}
619 
620 	sband = wiphy->bands[NL80211_BAND_6GHZ];
621 	if (!sband)
622 		return;
623 
624 	wiphy->bands[NL80211_BAND_6GHZ] = NULL;
625 	kfree((__force void *)sband->iftype_data);
626 	kfree(sband);
627 }
628 
629 #define RTW89_DEF_REGD_STR(regd) \
630 	[RTW89_ ## regd] = #regd
631 
632 static const char * const rtw89_regd_string[] = {
633 	RTW89_DEF_REGD_STR(WW),
634 	RTW89_DEF_REGD_STR(ETSI),
635 	RTW89_DEF_REGD_STR(FCC),
636 	RTW89_DEF_REGD_STR(MKK),
637 	RTW89_DEF_REGD_STR(NA),
638 	RTW89_DEF_REGD_STR(IC),
639 	RTW89_DEF_REGD_STR(KCC),
640 	RTW89_DEF_REGD_STR(ACMA),
641 	RTW89_DEF_REGD_STR(NCC),
642 	RTW89_DEF_REGD_STR(MEXICO),
643 	RTW89_DEF_REGD_STR(CHILE),
644 	RTW89_DEF_REGD_STR(UKRAINE),
645 	RTW89_DEF_REGD_STR(CN),
646 	RTW89_DEF_REGD_STR(QATAR),
647 	RTW89_DEF_REGD_STR(UK),
648 	RTW89_DEF_REGD_STR(THAILAND),
649 };
650 
651 static_assert(ARRAY_SIZE(rtw89_regd_string) == RTW89_REGD_NUM);
652 
rtw89_regd_get_string(enum rtw89_regulation_type regd)653 const char *rtw89_regd_get_string(enum rtw89_regulation_type regd)
654 {
655 	if (regd < 0 || regd >= RTW89_REGD_NUM)
656 		return "(unknown)";
657 
658 	return rtw89_regd_string[regd];
659 }
660 
rtw89_regd_setup_reg_rules(struct rtw89_dev * rtwdev)661 static void rtw89_regd_setup_reg_rules(struct rtw89_dev *rtwdev)
662 {
663 	struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
664 	const struct rtw89_acpi_policy_reg_rules *ptr;
665 	struct rtw89_acpi_dsm_result res = {};
666 	int ret;
667 
668 	regulatory->txpwr_uk_follow_etsi = true;
669 
670 	ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_REG_RULES_EN, &res);
671 	if (ret) {
672 		rtw89_debug(rtwdev, RTW89_DBG_REGD,
673 			    "acpi: cannot eval policy reg-rules: %d\n", ret);
674 		return;
675 	}
676 
677 	ptr = res.u.policy_reg_rules;
678 
679 	regulatory->txpwr_uk_follow_etsi =
680 		!u8_get_bits(ptr->conf, RTW89_ACPI_CONF_REG_RULE_REGD_UK);
681 
682 	kfree(ptr);
683 }
684 
rtw89_regd_setup(struct rtw89_dev * rtwdev)685 int rtw89_regd_setup(struct rtw89_dev *rtwdev)
686 {
687 	struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
688 	struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
689 	const struct rtw89_regd_data *regd_data = elm_info->regd;
690 	struct wiphy *wiphy = rtwdev->hw->wiphy;
691 
692 	if (regd_data) {
693 		regulatory->ctrl.nr = regd_data->nr;
694 		regulatory->ctrl.map = regd_data->map;
695 	} else {
696 		regulatory->ctrl.nr = ARRAY_SIZE(rtw89_regd_map);
697 		regulatory->ctrl.map = rtw89_regd_map;
698 	}
699 
700 	regulatory->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
701 
702 	rtw89_regd_setup_reg_rules(rtwdev);
703 
704 	if (!wiphy)
705 		return -EINVAL;
706 
707 	rtw89_regd_setup_unii4(rtwdev, wiphy);
708 	rtw89_regd_setup_6ghz(rtwdev, wiphy);
709 
710 	wiphy->reg_notifier = rtw89_regd_notifier;
711 	return 0;
712 }
713 
rtw89_regd_init_hint(struct rtw89_dev * rtwdev)714 int rtw89_regd_init_hint(struct rtw89_dev *rtwdev)
715 {
716 	const struct rtw89_regd *chip_regd;
717 	struct wiphy *wiphy = rtwdev->hw->wiphy;
718 	int ret;
719 
720 	if (!wiphy)
721 		return -EINVAL;
722 
723 	chip_regd = rtw89_regd_find_reg_by_name(rtwdev, rtwdev->efuse.country_code);
724 #if defined(__FreeBSD__)
725 	rtwdev->regulatory.regd = chip_regd;
726 #endif
727 	if (!rtw89_regd_is_ww(chip_regd)) {
728 #if defined(__linux__)
729 		rtwdev->regulatory.regd = chip_regd;
730 #endif
731 		/* Ignore country ie if there is a country domain programmed in chip */
732 		wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
733 		wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
734 
735 		ret = regulatory_hint(rtwdev->hw->wiphy,
736 				      rtwdev->regulatory.regd->alpha2);
737 		if (ret)
738 			rtw89_warn(rtwdev, "failed to hint regulatory:%d\n", ret);
739 
740 		rtw89_debug_regd(rtwdev, chip_regd, "efuse country code");
741 		return 0;
742 	}
743 
744 	rtw89_debug_regd(rtwdev, rtwdev->regulatory.regd,
745 			 "worldwide roaming chip, follow the setting of stack");
746 	return 0;
747 }
748 
rtw89_regd_apply_policy_unii4(struct rtw89_dev * rtwdev,struct wiphy * wiphy)749 static void rtw89_regd_apply_policy_unii4(struct rtw89_dev *rtwdev,
750 					  struct wiphy *wiphy)
751 {
752 	struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
753 	const struct rtw89_chip_info *chip = rtwdev->chip;
754 	const struct rtw89_regd *regd = regulatory->regd;
755 	struct ieee80211_supported_band *sband;
756 	u8 index;
757 	int i;
758 
759 	sband = wiphy->bands[NL80211_BAND_5GHZ];
760 	if (!sband)
761 		return;
762 
763 	if (!chip->support_unii4)
764 		return;
765 
766 	index = rtw89_regd_get_index(rtwdev, regd);
767 	if (index != RTW89_REGD_MAX_COUNTRY_NUM &&
768 	    !test_bit(index, regulatory->block_unii4))
769 		return;
770 
771 	rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c unii-4 is blocked by policy\n",
772 		    regd->alpha2[0], regd->alpha2[1]);
773 
774 	for (i = RTW89_5GHZ_UNII4_START_INDEX; i < sband->n_channels; i++)
775 		sband->channels[i].flags |= IEEE80211_CHAN_DISABLED;
776 }
777 
regd_is_6ghz_blocked(struct rtw89_dev * rtwdev)778 static bool regd_is_6ghz_blocked(struct rtw89_dev *rtwdev)
779 {
780 	struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
781 	const struct rtw89_regd *regd = regulatory->regd;
782 	u8 index;
783 
784 	index = rtw89_regd_get_index(rtwdev, regd);
785 	if (index != RTW89_REGD_MAX_COUNTRY_NUM &&
786 	    !test_bit(index, regulatory->block_6ghz))
787 		return false;
788 
789 	rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c 6 GHz is blocked by policy\n",
790 		    regd->alpha2[0], regd->alpha2[1]);
791 	return true;
792 }
793 
regd_is_6ghz_not_applicable(struct rtw89_dev * rtwdev)794 static bool regd_is_6ghz_not_applicable(struct rtw89_dev *rtwdev)
795 {
796 	struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
797 	const struct rtw89_regd *regd = regulatory->regd;
798 
799 	if (regd->txpwr_regd[RTW89_BAND_6G] != RTW89_NA)
800 		return false;
801 
802 	rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c 6 GHz is N/A in regd map\n",
803 		    regd->alpha2[0], regd->alpha2[1]);
804 	return true;
805 }
806 
rtw89_regd_apply_policy_6ghz(struct rtw89_dev * rtwdev,struct wiphy * wiphy)807 static void rtw89_regd_apply_policy_6ghz(struct rtw89_dev *rtwdev,
808 					 struct wiphy *wiphy)
809 {
810 	struct ieee80211_supported_band *sband;
811 	int i;
812 
813 	if (!regd_is_6ghz_blocked(rtwdev) &&
814 	    !regd_is_6ghz_not_applicable(rtwdev))
815 		return;
816 
817 	sband = wiphy->bands[NL80211_BAND_6GHZ];
818 	if (!sband)
819 		return;
820 
821 	for (i = 0; i < sband->n_channels; i++)
822 		sband->channels[i].flags |= IEEE80211_CHAN_DISABLED;
823 }
824 
rtw89_regd_apply_policy_tas(struct rtw89_dev * rtwdev)825 static void rtw89_regd_apply_policy_tas(struct rtw89_dev *rtwdev)
826 {
827 	struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
828 	const struct rtw89_regd *regd = regulatory->regd;
829 	struct rtw89_tas_info *tas = &rtwdev->tas;
830 	u8 tas_country;
831 
832 	if (!tas->enable)
833 		return;
834 
835 	if (memcmp("US", regd->alpha2, 2) == 0)
836 		tas_country = RTW89_ACPI_CONF_TAS_US;
837 	else if (memcmp("CA", regd->alpha2, 2) == 0)
838 		tas_country = RTW89_ACPI_CONF_TAS_CA;
839 	else if (memcmp("KR", regd->alpha2, 2) == 0)
840 		tas_country = RTW89_ACPI_CONF_TAS_KR;
841 	else
842 		tas_country = RTW89_ACPI_CONF_TAS_OTHERS;
843 
844 	tas->block_regd = !(tas->enabled_countries & tas_country &&
845 			    test_bit(RTW89_REGD_FUNC_TAS, regd->func_bitmap));
846 }
847 
rtw89_regd_apply_policy_ant_gain(struct rtw89_dev * rtwdev)848 static void rtw89_regd_apply_policy_ant_gain(struct rtw89_dev *rtwdev)
849 {
850 	struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
851 	struct rtw89_ant_gain_info *ant_gain = &rtwdev->ant_gain;
852 	const struct rtw89_chip_info *chip = rtwdev->chip;
853 	const struct rtw89_regd *regd = regulatory->regd;
854 
855 	if (!chip->support_ant_gain)
856 		return;
857 
858 	ant_gain->block_country = !test_bit(RTW89_REGD_FUNC_DAG, regd->func_bitmap);
859 }
860 
rtw89_regd_notifier_apply(struct rtw89_dev * rtwdev,struct wiphy * wiphy,struct regulatory_request * request)861 static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev,
862 				      struct wiphy *wiphy,
863 				      struct regulatory_request *request)
864 {
865 	rtwdev->regulatory.regd = rtw89_regd_find_reg_by_name(rtwdev, request->alpha2);
866 	/* This notification might be set from the system of distros,
867 	 * and it does not expect the regulatory will be modified by
868 	 * connecting to an AP (i.e. country ie).
869 	 */
870 	if (request->initiator == NL80211_REGDOM_SET_BY_USER &&
871 	    !rtw89_regd_is_ww(rtwdev->regulatory.regd))
872 		wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
873 	else
874 		wiphy->regulatory_flags &= ~REGULATORY_COUNTRY_IE_IGNORE;
875 
876 	rtw89_regd_apply_policy_unii4(rtwdev, wiphy);
877 	rtw89_regd_apply_policy_6ghz(rtwdev, wiphy);
878 	rtw89_regd_apply_policy_tas(rtwdev);
879 	rtw89_regd_apply_policy_ant_gain(rtwdev);
880 }
881 
882 static
rtw89_regd_notifier(struct wiphy * wiphy,struct regulatory_request * request)883 void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request)
884 {
885 	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
886 	struct rtw89_dev *rtwdev = hw->priv;
887 
888 	wiphy_lock(wiphy);
889 	rtw89_leave_ps_mode(rtwdev);
890 
891 	if (wiphy->regd) {
892 		rtw89_debug(rtwdev, RTW89_DBG_REGD,
893 			    "There is a country domain programmed in chip, ignore notifications\n");
894 		goto exit;
895 	}
896 	rtw89_regd_notifier_apply(rtwdev, wiphy, request);
897 	rtw89_debug_regd(rtwdev, rtwdev->regulatory.regd,
898 			 "get from initiator %d, alpha2",
899 			 request->initiator);
900 
901 	rtw89_core_set_chip_txpwr(rtwdev);
902 
903 exit:
904 	wiphy_unlock(wiphy);
905 }
906 
907 /* Maximum Transmit Power field (@raw) can be EIRP or PSD.
908  * Both units are 0.5 dB-based. Return a constraint in dB.
909  */
tpe_get_constraint(s8 raw)910 static s8 tpe_get_constraint(s8 raw)
911 {
912 	const u8 hw_deviation = 3; /* unit: 0.5 dB */
913 	const u8 antenna_gain = 10; /* unit: 0.5 dB */
914 	const u8 array_gain = 6; /* unit: 0.5 dB */
915 	const u8 offset = hw_deviation + antenna_gain + array_gain;
916 
917 	return (raw - offset) / 2;
918 }
919 
tpe_intersect_constraint(struct rtw89_reg_6ghz_tpe * tpe,s8 cstr)920 static void tpe_intersect_constraint(struct rtw89_reg_6ghz_tpe *tpe, s8 cstr)
921 {
922 	if (tpe->valid) {
923 		tpe->constraint = min(tpe->constraint, cstr);
924 		return;
925 	}
926 
927 	tpe->constraint = cstr;
928 	tpe->valid = true;
929 }
930 
tpe_deal_with_eirp(struct rtw89_reg_6ghz_tpe * tpe,const struct ieee80211_parsed_tpe_eirp * eirp)931 static void tpe_deal_with_eirp(struct rtw89_reg_6ghz_tpe *tpe,
932 			       const struct ieee80211_parsed_tpe_eirp *eirp)
933 {
934 	unsigned int i;
935 	s8 cstr;
936 
937 	if (!eirp->valid)
938 		return;
939 
940 	for (i = 0; i < eirp->count; i++) {
941 		cstr = tpe_get_constraint(eirp->power[i]);
942 		tpe_intersect_constraint(tpe, cstr);
943 	}
944 }
945 
tpe_convert_psd_to_eirp(s8 psd)946 static s8 tpe_convert_psd_to_eirp(s8 psd)
947 {
948 	static const unsigned int mlog20 = 1301;
949 
950 	return psd + 10 * mlog20 / 1000;
951 }
952 
tpe_deal_with_psd(struct rtw89_reg_6ghz_tpe * tpe,const struct ieee80211_parsed_tpe_psd * psd)953 static void tpe_deal_with_psd(struct rtw89_reg_6ghz_tpe *tpe,
954 			      const struct ieee80211_parsed_tpe_psd *psd)
955 {
956 	unsigned int i;
957 	s8 cstr_psd;
958 	s8 cstr;
959 
960 	if (!psd->valid)
961 		return;
962 
963 	for (i = 0; i < psd->count; i++) {
964 		cstr_psd = tpe_get_constraint(psd->power[i]);
965 		cstr = tpe_convert_psd_to_eirp(cstr_psd);
966 		tpe_intersect_constraint(tpe, cstr);
967 	}
968 }
969 
rtw89_calculate_tpe(struct rtw89_dev * rtwdev,struct rtw89_reg_6ghz_tpe * result_tpe,const struct ieee80211_parsed_tpe * parsed_tpe)970 static void rtw89_calculate_tpe(struct rtw89_dev *rtwdev,
971 				struct rtw89_reg_6ghz_tpe *result_tpe,
972 				const struct ieee80211_parsed_tpe *parsed_tpe)
973 {
974 	static const u8 category = IEEE80211_TPE_CAT_6GHZ_DEFAULT;
975 
976 	tpe_deal_with_eirp(result_tpe, &parsed_tpe->max_local[category]);
977 	tpe_deal_with_eirp(result_tpe, &parsed_tpe->max_reg_client[category]);
978 	tpe_deal_with_psd(result_tpe, &parsed_tpe->psd_local[category]);
979 	tpe_deal_with_psd(result_tpe, &parsed_tpe->psd_reg_client[category]);
980 }
981 
__rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev * rtwdev)982 static bool __rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev *rtwdev)
983 {
984 	struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
985 	struct rtw89_reg_6ghz_tpe new = {};
986 	struct rtw89_vif_link *rtwvif_link;
987 	struct rtw89_vif *rtwvif;
988 	unsigned int link_id;
989 	bool changed = false;
990 
991 	rtw89_for_each_rtwvif(rtwdev, rtwvif) {
992 		const struct rtw89_reg_6ghz_tpe *tmp;
993 		const struct rtw89_chan *chan;
994 
995 		rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
996 			chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
997 			if (chan->band_type != RTW89_BAND_6G)
998 				continue;
999 
1000 			tmp = &rtwvif_link->reg_6ghz_tpe;
1001 			if (!tmp->valid)
1002 				continue;
1003 
1004 			tpe_intersect_constraint(&new, tmp->constraint);
1005 		}
1006 	}
1007 
1008 	if (memcmp(&regulatory->reg_6ghz_tpe, &new,
1009 		   sizeof(regulatory->reg_6ghz_tpe)) != 0)
1010 		changed = true;
1011 
1012 	if (changed) {
1013 		if (new.valid)
1014 			rtw89_debug(rtwdev, RTW89_DBG_REGD,
1015 				    "recalc 6 GHz reg TPE to %d dBm\n",
1016 				    new.constraint);
1017 		else
1018 			rtw89_debug(rtwdev, RTW89_DBG_REGD,
1019 				    "recalc 6 GHz reg TPE to none\n");
1020 
1021 		regulatory->reg_6ghz_tpe = new;
1022 	}
1023 
1024 	return changed;
1025 }
1026 
rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev * rtwdev,struct rtw89_vif_link * rtwvif_link,bool active,unsigned int * changed)1027 static int rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev *rtwdev,
1028 				     struct rtw89_vif_link *rtwvif_link, bool active,
1029 				     unsigned int *changed)
1030 {
1031 	struct rtw89_reg_6ghz_tpe *tpe = &rtwvif_link->reg_6ghz_tpe;
1032 	struct ieee80211_bss_conf *bss_conf;
1033 
1034 	memset(tpe, 0, sizeof(*tpe));
1035 
1036 	if (!active || rtwvif_link->reg_6ghz_power != RTW89_REG_6GHZ_POWER_STD)
1037 		goto bottom;
1038 
1039 	rcu_read_lock();
1040 
1041 	bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
1042 	rtw89_calculate_tpe(rtwdev, tpe, &bss_conf->tpe);
1043 
1044 	rcu_read_unlock();
1045 
1046 	if (!tpe->valid)
1047 		goto bottom;
1048 
1049 	if (tpe->constraint < RTW89_MIN_VALID_POWER_CONSTRAINT) {
1050 		rtw89_err(rtwdev,
1051 			  "%s: constraint %d dBm is less than min valid val\n",
1052 			  __func__, tpe->constraint);
1053 
1054 		tpe->valid = false;
1055 		return -EINVAL;
1056 	}
1057 
1058 bottom:
1059 	*changed += __rtw89_reg_6ghz_tpe_recalc(rtwdev);
1060 	return 0;
1061 }
1062 
__rtw89_reg_6ghz_power_recalc(struct rtw89_dev * rtwdev)1063 static bool __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev)
1064 {
1065 	struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
1066 	const struct rtw89_regd *regd = regulatory->regd;
1067 	enum rtw89_reg_6ghz_power sel;
1068 	const struct rtw89_chan *chan;
1069 	struct rtw89_vif_link *rtwvif_link;
1070 	struct rtw89_vif *rtwvif;
1071 	unsigned int link_id;
1072 	int count = 0;
1073 	u8 index;
1074 
1075 	rtw89_for_each_rtwvif(rtwdev, rtwvif) {
1076 		rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
1077 			chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
1078 			if (chan->band_type != RTW89_BAND_6G)
1079 				continue;
1080 
1081 			if (count != 0 && rtwvif_link->reg_6ghz_power == sel)
1082 				continue;
1083 
1084 			sel = rtwvif_link->reg_6ghz_power;
1085 			count++;
1086 		}
1087 	}
1088 
1089 	if (count != 1)
1090 		sel = RTW89_REG_6GHZ_POWER_DFLT;
1091 
1092 	if (sel == RTW89_REG_6GHZ_POWER_STD) {
1093 		index = rtw89_regd_get_index(rtwdev, regd);
1094 		if (index == RTW89_REGD_MAX_COUNTRY_NUM ||
1095 		    test_bit(index, regulatory->block_6ghz_sp)) {
1096 			rtw89_debug(rtwdev, RTW89_DBG_REGD,
1097 				    "%c%c 6 GHz SP is blocked by policy\n",
1098 				    regd->alpha2[0], regd->alpha2[1]);
1099 			sel = RTW89_REG_6GHZ_POWER_DFLT;
1100 		}
1101 	}
1102 
1103 	if (regulatory->reg_6ghz_power == sel)
1104 		return false;
1105 
1106 	rtw89_debug(rtwdev, RTW89_DBG_REGD,
1107 		    "recalc 6 GHz reg power type to %d\n", sel);
1108 
1109 	regulatory->reg_6ghz_power = sel;
1110 	return true;
1111 }
1112 
rtw89_reg_6ghz_power_recalc(struct rtw89_dev * rtwdev,struct rtw89_vif_link * rtwvif_link,bool active,unsigned int * changed)1113 static int rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev,
1114 				       struct rtw89_vif_link *rtwvif_link, bool active,
1115 				       unsigned int *changed)
1116 {
1117 	struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
1118 	const struct rtw89_regd *regd = regulatory->regd;
1119 	bool blocked[NUM_OF_RTW89_REG_6GHZ_POWER] = {};
1120 	u8 index = rtw89_regd_get_index(rtwdev, regd);
1121 	struct ieee80211_bss_conf *bss_conf;
1122 	bool dflt = false;
1123 
1124 	if (index == RTW89_REGD_MAX_COUNTRY_NUM ||
1125 	    test_bit(index, regulatory->block_6ghz_vlp))
1126 		blocked[RTW89_REG_6GHZ_POWER_VLP] = true;
1127 
1128 	rcu_read_lock();
1129 
1130 	bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
1131 
1132 	if (active) {
1133 		switch (bss_conf->power_type) {
1134 		case IEEE80211_REG_VLP_AP:
1135 			rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_VLP;
1136 			break;
1137 		case IEEE80211_REG_LPI_AP:
1138 			rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_LPI;
1139 			break;
1140 		case IEEE80211_REG_SP_AP:
1141 			rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_STD;
1142 			break;
1143 		default:
1144 			rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
1145 			dflt = true;
1146 			break;
1147 		}
1148 	} else {
1149 		rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
1150 	}
1151 
1152 	rcu_read_unlock();
1153 
1154 	if (!dflt && blocked[rtwvif_link->reg_6ghz_power]) {
1155 		rtw89_debug(rtwdev, RTW89_DBG_REGD,
1156 			    "%c%c 6 GHz power type-%u is blocked by policy\n",
1157 			    regd->alpha2[0], regd->alpha2[1],
1158 			    rtwvif_link->reg_6ghz_power);
1159 		return -EINVAL;
1160 	}
1161 
1162 	*changed += __rtw89_reg_6ghz_power_recalc(rtwdev);
1163 	return 0;
1164 }
1165 
rtw89_reg_6ghz_recalc(struct rtw89_dev * rtwdev,struct rtw89_vif_link * rtwvif_link,bool active)1166 int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
1167 			  bool active)
1168 {
1169 	unsigned int changed = 0;
1170 	int ret;
1171 
1172 	lockdep_assert_wiphy(rtwdev->hw->wiphy);
1173 
1174 	/* The result of reg_6ghz_tpe may depend on reg_6ghz_power type,
1175 	 * so must do reg_6ghz_tpe_recalc() after reg_6ghz_power_recalc().
1176 	 */
1177 
1178 	ret = rtw89_reg_6ghz_power_recalc(rtwdev, rtwvif_link, active, &changed);
1179 	if (ret)
1180 		return ret;
1181 
1182 	ret = rtw89_reg_6ghz_tpe_recalc(rtwdev, rtwvif_link, active, &changed);
1183 	if (ret)
1184 		return ret;
1185 
1186 	if (changed)
1187 		rtw89_core_set_chip_txpwr(rtwdev);
1188 
1189 	return 0;
1190 }
1191