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