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