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 /* Ignore country ie if there is a country domain programmed in chip */ 727 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; 728 wiphy->regulatory_flags |= REGULATORY_STRICT_REG; 729 730 ret = regulatory_hint(rtwdev->hw->wiphy, 731 rtwdev->regulatory.regd->alpha2); 732 if (ret) 733 rtw89_warn(rtwdev, "failed to hint regulatory:%d\n", ret); 734 735 rtw89_debug_regd(rtwdev, chip_regd, "efuse country code"); 736 return 0; 737 } 738 739 rtw89_debug_regd(rtwdev, rtwdev->regulatory.regd, 740 "worldwide roaming chip, follow the setting of stack"); 741 return 0; 742 } 743 744 static void rtw89_regd_apply_policy_unii4(struct rtw89_dev *rtwdev, 745 struct wiphy *wiphy) 746 { 747 struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; 748 const struct rtw89_chip_info *chip = rtwdev->chip; 749 const struct rtw89_regd *regd = regulatory->regd; 750 struct ieee80211_supported_band *sband; 751 u8 index; 752 int i; 753 754 sband = wiphy->bands[NL80211_BAND_5GHZ]; 755 if (!sband) 756 return; 757 758 if (!chip->support_unii4) 759 return; 760 761 index = rtw89_regd_get_index(rtwdev, regd); 762 if (index != RTW89_REGD_MAX_COUNTRY_NUM && 763 !test_bit(index, regulatory->block_unii4)) 764 return; 765 766 rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c unii-4 is blocked by policy\n", 767 regd->alpha2[0], regd->alpha2[1]); 768 769 for (i = RTW89_5GHZ_UNII4_START_INDEX; i < sband->n_channels; i++) 770 sband->channels[i].flags |= IEEE80211_CHAN_DISABLED; 771 } 772 773 static bool regd_is_6ghz_blocked(struct rtw89_dev *rtwdev) 774 { 775 struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; 776 const struct rtw89_regd *regd = regulatory->regd; 777 u8 index; 778 779 index = rtw89_regd_get_index(rtwdev, regd); 780 if (index != RTW89_REGD_MAX_COUNTRY_NUM && 781 !test_bit(index, regulatory->block_6ghz)) 782 return false; 783 784 rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c 6 GHz is blocked by policy\n", 785 regd->alpha2[0], regd->alpha2[1]); 786 return true; 787 } 788 789 static bool regd_is_6ghz_not_applicable(struct rtw89_dev *rtwdev) 790 { 791 struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; 792 const struct rtw89_regd *regd = regulatory->regd; 793 794 if (regd->txpwr_regd[RTW89_BAND_6G] != RTW89_NA) 795 return false; 796 797 rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c 6 GHz is N/A in regd map\n", 798 regd->alpha2[0], regd->alpha2[1]); 799 return true; 800 } 801 802 static void rtw89_regd_apply_policy_6ghz(struct rtw89_dev *rtwdev, 803 struct wiphy *wiphy) 804 { 805 struct ieee80211_supported_band *sband; 806 int i; 807 808 if (!regd_is_6ghz_blocked(rtwdev) && 809 !regd_is_6ghz_not_applicable(rtwdev)) 810 return; 811 812 sband = wiphy->bands[NL80211_BAND_6GHZ]; 813 if (!sband) 814 return; 815 816 for (i = 0; i < sband->n_channels; i++) 817 sband->channels[i].flags |= IEEE80211_CHAN_DISABLED; 818 } 819 820 static void rtw89_regd_apply_policy_tas(struct rtw89_dev *rtwdev) 821 { 822 struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; 823 const struct rtw89_regd *regd = regulatory->regd; 824 struct rtw89_tas_info *tas = &rtwdev->tas; 825 u8 tas_country; 826 827 if (!tas->enable) 828 return; 829 830 if (memcmp("US", regd->alpha2, 2) == 0) 831 tas_country = RTW89_ACPI_CONF_TAS_US; 832 else if (memcmp("CA", regd->alpha2, 2) == 0) 833 tas_country = RTW89_ACPI_CONF_TAS_CA; 834 else if (memcmp("KR", regd->alpha2, 2) == 0) 835 tas_country = RTW89_ACPI_CONF_TAS_KR; 836 else 837 tas_country = RTW89_ACPI_CONF_TAS_OTHERS; 838 839 tas->block_regd = !(tas->enabled_countries & tas_country && 840 test_bit(RTW89_REGD_FUNC_TAS, regd->func_bitmap)); 841 } 842 843 static void rtw89_regd_apply_policy_ant_gain(struct rtw89_dev *rtwdev) 844 { 845 struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; 846 struct rtw89_ant_gain_info *ant_gain = &rtwdev->ant_gain; 847 const struct rtw89_chip_info *chip = rtwdev->chip; 848 const struct rtw89_regd *regd = regulatory->regd; 849 850 if (!chip->support_ant_gain) 851 return; 852 853 ant_gain->block_country = !test_bit(RTW89_REGD_FUNC_DAG, regd->func_bitmap); 854 } 855 856 static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev, 857 struct wiphy *wiphy, 858 struct regulatory_request *request) 859 { 860 rtwdev->regulatory.regd = rtw89_regd_find_reg_by_name(rtwdev, request->alpha2); 861 /* This notification might be set from the system of distros, 862 * and it does not expect the regulatory will be modified by 863 * connecting to an AP (i.e. country ie). 864 */ 865 if (request->initiator == NL80211_REGDOM_SET_BY_USER && 866 !rtw89_regd_is_ww(rtwdev->regulatory.regd)) 867 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; 868 else 869 wiphy->regulatory_flags &= ~REGULATORY_COUNTRY_IE_IGNORE; 870 871 rtw89_regd_apply_policy_unii4(rtwdev, wiphy); 872 rtw89_regd_apply_policy_6ghz(rtwdev, wiphy); 873 rtw89_regd_apply_policy_tas(rtwdev); 874 rtw89_regd_apply_policy_ant_gain(rtwdev); 875 } 876 877 static 878 void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request) 879 { 880 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 881 struct rtw89_dev *rtwdev = hw->priv; 882 883 wiphy_lock(wiphy); 884 rtw89_leave_ps_mode(rtwdev); 885 886 if (wiphy->regd) { 887 rtw89_debug(rtwdev, RTW89_DBG_REGD, 888 "There is a country domain programmed in chip, ignore notifications\n"); 889 goto exit; 890 } 891 rtw89_regd_notifier_apply(rtwdev, wiphy, request); 892 rtw89_debug_regd(rtwdev, rtwdev->regulatory.regd, 893 "get from initiator %d, alpha2", 894 request->initiator); 895 896 rtw89_core_set_chip_txpwr(rtwdev); 897 898 exit: 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