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