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