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