1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 /* 3 * Copyright (C) 2023 Intel Corporation 4 */ 5 #include <linux/dmi.h> 6 #include "iwl-drv.h" 7 #include "iwl-debug.h" 8 #include "regulatory.h" 9 #include "fw/runtime.h" 10 #include "fw/uefi.h" 11 12 #define GET_BIOS_TABLE(__name, ...) \ 13 do { \ 14 int ret = -ENOENT; \ 15 if (fwrt->uefi_tables_lock_status > UEFI_WIFI_GUID_UNLOCKED) \ 16 ret = iwl_uefi_get_ ## __name(__VA_ARGS__); \ 17 if (ret < 0) \ 18 ret = iwl_acpi_get_ ## __name(__VA_ARGS__); \ 19 return ret; \ 20 } while (0) 21 22 #define IWL_BIOS_TABLE_LOADER(__name) \ 23 int iwl_bios_get_ ## __name(struct iwl_fw_runtime *fwrt) \ 24 {GET_BIOS_TABLE(__name, fwrt); } \ 25 IWL_EXPORT_SYMBOL(iwl_bios_get_ ## __name) 26 27 #define IWL_BIOS_TABLE_LOADER_DATA(__name, data_type) \ 28 int iwl_bios_get_ ## __name(struct iwl_fw_runtime *fwrt, \ 29 data_type * data) \ 30 {GET_BIOS_TABLE(__name, fwrt, data); } \ 31 IWL_EXPORT_SYMBOL(iwl_bios_get_ ## __name) 32 33 IWL_BIOS_TABLE_LOADER(wrds_table); 34 IWL_BIOS_TABLE_LOADER(ewrd_table); 35 IWL_BIOS_TABLE_LOADER(wgds_table); 36 IWL_BIOS_TABLE_LOADER(ppag_table); 37 IWL_BIOS_TABLE_LOADER_DATA(tas_table, struct iwl_tas_data); 38 IWL_BIOS_TABLE_LOADER_DATA(pwr_limit, u64); 39 IWL_BIOS_TABLE_LOADER_DATA(mcc, char); 40 IWL_BIOS_TABLE_LOADER_DATA(eckv, u32); 41 42 43 static const struct dmi_system_id dmi_ppag_approved_list[] = { 44 { .ident = "HP", 45 .matches = { 46 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 47 }, 48 }, 49 { .ident = "SAMSUNG", 50 .matches = { 51 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"), 52 }, 53 }, 54 { .ident = "MSFT", 55 .matches = { 56 DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), 57 }, 58 }, 59 { .ident = "ASUS", 60 .matches = { 61 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 62 }, 63 }, 64 { .ident = "GOOGLE-HP", 65 .matches = { 66 DMI_MATCH(DMI_SYS_VENDOR, "Google"), 67 DMI_MATCH(DMI_BOARD_VENDOR, "HP"), 68 }, 69 }, 70 { .ident = "GOOGLE-ASUS", 71 .matches = { 72 DMI_MATCH(DMI_SYS_VENDOR, "Google"), 73 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek COMPUTER INC."), 74 }, 75 }, 76 { .ident = "GOOGLE-SAMSUNG", 77 .matches = { 78 DMI_MATCH(DMI_SYS_VENDOR, "Google"), 79 DMI_MATCH(DMI_BOARD_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"), 80 }, 81 }, 82 { .ident = "DELL", 83 .matches = { 84 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 85 }, 86 }, 87 { .ident = "DELL", 88 .matches = { 89 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), 90 }, 91 }, 92 { .ident = "RAZER", 93 .matches = { 94 DMI_MATCH(DMI_SYS_VENDOR, "Razer"), 95 }, 96 }, 97 { .ident = "Honor", 98 .matches = { 99 DMI_MATCH(DMI_SYS_VENDOR, "HONOR"), 100 }, 101 }, 102 {} 103 }; 104 105 static const struct dmi_system_id dmi_tas_approved_list[] = { 106 { .ident = "HP", 107 .matches = { 108 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 109 }, 110 }, 111 { .ident = "SAMSUNG", 112 .matches = { 113 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"), 114 }, 115 }, 116 { .ident = "LENOVO", 117 .matches = { 118 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 119 }, 120 }, 121 { .ident = "DELL", 122 .matches = { 123 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 124 }, 125 }, 126 { .ident = "MSFT", 127 .matches = { 128 DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), 129 }, 130 }, 131 { .ident = "Acer", 132 .matches = { 133 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 134 }, 135 }, 136 { .ident = "ASUS", 137 .matches = { 138 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 139 }, 140 }, 141 { .ident = "GOOGLE-HP", 142 .matches = { 143 DMI_MATCH(DMI_SYS_VENDOR, "Google"), 144 DMI_MATCH(DMI_BOARD_VENDOR, "HP"), 145 }, 146 }, 147 { .ident = "MSI", 148 .matches = { 149 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."), 150 }, 151 }, 152 { .ident = "Honor", 153 .matches = { 154 DMI_MATCH(DMI_SYS_VENDOR, "HONOR"), 155 }, 156 }, 157 /* keep last */ 158 {} 159 }; 160 161 bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt) 162 { 163 /* 164 * The PER_CHAIN_LIMIT_OFFSET_CMD command is not supported on 165 * earlier firmware versions. Unfortunately, we don't have a 166 * TLV API flag to rely on, so rely on the major version which 167 * is in the first byte of ucode_ver. This was implemented 168 * initially on version 38 and then backported to 17. It was 169 * also backported to 29, but only for 7265D devices. The 170 * intention was to have it in 36 as well, but not all 8000 171 * family got this feature enabled. The 8000 family is the 172 * only one using version 36, so skip this version entirely. 173 */ 174 return IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) >= 38 || 175 (IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 17 && 176 fwrt->trans->hw_rev != CSR_HW_REV_TYPE_3160) || 177 (IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 29 && 178 ((fwrt->trans->hw_rev & CSR_HW_REV_TYPE_MSK) == 179 CSR_HW_REV_TYPE_7265D)); 180 } 181 IWL_EXPORT_SYMBOL(iwl_sar_geo_support); 182 183 int iwl_sar_geo_fill_table(struct iwl_fw_runtime *fwrt, 184 struct iwl_per_chain_offset *table, 185 u32 n_bands, u32 n_profiles) 186 { 187 int i, j; 188 189 if (!fwrt->geo_enabled) 190 return -ENODATA; 191 192 if (!iwl_sar_geo_support(fwrt)) 193 return -EOPNOTSUPP; 194 195 for (i = 0; i < n_profiles; i++) { 196 for (j = 0; j < n_bands; j++) { 197 struct iwl_per_chain_offset *chain = 198 &table[i * n_bands + j]; 199 200 chain->max_tx_power = 201 cpu_to_le16(fwrt->geo_profiles[i].bands[j].max); 202 chain->chain_a = 203 fwrt->geo_profiles[i].bands[j].chains[0]; 204 chain->chain_b = 205 fwrt->geo_profiles[i].bands[j].chains[1]; 206 IWL_DEBUG_RADIO(fwrt, 207 "SAR geographic profile[%d] Band[%d]: chain A = %d chain B = %d max_tx_power = %d\n", 208 i, j, 209 fwrt->geo_profiles[i].bands[j].chains[0], 210 fwrt->geo_profiles[i].bands[j].chains[1], 211 fwrt->geo_profiles[i].bands[j].max); 212 } 213 } 214 215 return 0; 216 } 217 IWL_EXPORT_SYMBOL(iwl_sar_geo_fill_table); 218 219 static int iwl_sar_fill_table(struct iwl_fw_runtime *fwrt, 220 __le16 *per_chain, u32 n_subbands, 221 int prof_a, int prof_b) 222 { 223 int profs[BIOS_SAR_NUM_CHAINS] = { prof_a, prof_b }; 224 int i, j; 225 226 for (i = 0; i < BIOS_SAR_NUM_CHAINS; i++) { 227 struct iwl_sar_profile *prof; 228 229 /* don't allow SAR to be disabled (profile 0 means disable) */ 230 if (profs[i] == 0) 231 return -EPERM; 232 233 /* we are off by one, so allow up to BIOS_SAR_MAX_PROFILE_NUM */ 234 if (profs[i] > BIOS_SAR_MAX_PROFILE_NUM) 235 return -EINVAL; 236 237 /* profiles go from 1 to 4, so decrement to access the array */ 238 prof = &fwrt->sar_profiles[profs[i] - 1]; 239 240 /* if the profile is disabled, do nothing */ 241 if (!prof->enabled) { 242 IWL_DEBUG_RADIO(fwrt, "SAR profile %d is disabled.\n", 243 profs[i]); 244 /* 245 * if one of the profiles is disabled, we 246 * ignore all of them and return 1 to 247 * differentiate disabled from other failures. 248 */ 249 return 1; 250 } 251 252 IWL_DEBUG_INFO(fwrt, 253 "SAR EWRD: chain %d profile index %d\n", 254 i, profs[i]); 255 IWL_DEBUG_RADIO(fwrt, " Chain[%d]:\n", i); 256 for (j = 0; j < n_subbands; j++) { 257 per_chain[i * n_subbands + j] = 258 cpu_to_le16(prof->chains[i].subbands[j]); 259 IWL_DEBUG_RADIO(fwrt, " Band[%d] = %d * .125dBm\n", 260 j, prof->chains[i].subbands[j]); 261 } 262 } 263 264 return 0; 265 } 266 267 int iwl_sar_fill_profile(struct iwl_fw_runtime *fwrt, 268 __le16 *per_chain, u32 n_tables, u32 n_subbands, 269 int prof_a, int prof_b) 270 { 271 int i, ret = 0; 272 273 for (i = 0; i < n_tables; i++) { 274 ret = iwl_sar_fill_table(fwrt, 275 &per_chain[i * n_subbands * BIOS_SAR_NUM_CHAINS], 276 n_subbands, prof_a, prof_b); 277 if (ret) 278 break; 279 } 280 281 return ret; 282 } 283 IWL_EXPORT_SYMBOL(iwl_sar_fill_profile); 284 285 static bool iwl_ppag_value_valid(struct iwl_fw_runtime *fwrt, int chain, 286 int subband) 287 { 288 s8 ppag_val = fwrt->ppag_chains[chain].subbands[subband]; 289 290 if ((subband == 0 && 291 (ppag_val > IWL_PPAG_MAX_LB || ppag_val < IWL_PPAG_MIN_LB)) || 292 (subband != 0 && 293 (ppag_val > IWL_PPAG_MAX_HB || ppag_val < IWL_PPAG_MIN_HB))) { 294 IWL_DEBUG_RADIO(fwrt, "Invalid PPAG value: %d\n", ppag_val); 295 return false; 296 } 297 return true; 298 } 299 300 int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt, 301 union iwl_ppag_table_cmd *cmd, int *cmd_size) 302 { 303 u8 cmd_ver; 304 int i, j, num_sub_bands; 305 s8 *gain; 306 bool send_ppag_always; 307 308 /* many firmware images for JF lie about this */ 309 if (CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id) == 310 CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_JF)) 311 return -EOPNOTSUPP; 312 313 if (!fw_has_capa(&fwrt->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_PPAG)) { 314 IWL_DEBUG_RADIO(fwrt, 315 "PPAG capability not supported by FW, command not sent.\n"); 316 return -EINVAL; 317 } 318 319 cmd_ver = iwl_fw_lookup_cmd_ver(fwrt->fw, 320 WIDE_ID(PHY_OPS_GROUP, 321 PER_PLATFORM_ANT_GAIN_CMD), 1); 322 /* 323 * Starting from ver 4, driver needs to send the PPAG CMD regardless 324 * if PPAG is enabled/disabled or valid/invalid. 325 */ 326 send_ppag_always = cmd_ver > 3; 327 328 /* Don't send PPAG if it is disabled */ 329 if (!send_ppag_always && !fwrt->ppag_flags) { 330 IWL_DEBUG_RADIO(fwrt, "PPAG not enabled, command not sent.\n"); 331 return -EINVAL; 332 } 333 334 /* The 'flags' field is the same in v1 and in v2 so we can just 335 * use v1 to access it. 336 */ 337 cmd->v1.flags = cpu_to_le32(fwrt->ppag_flags); 338 339 IWL_DEBUG_RADIO(fwrt, "PPAG cmd ver is %d\n", cmd_ver); 340 if (cmd_ver == 1) { 341 num_sub_bands = IWL_NUM_SUB_BANDS_V1; 342 gain = cmd->v1.gain[0]; 343 *cmd_size = sizeof(cmd->v1); 344 if (fwrt->ppag_ver >= 1) { 345 /* in this case FW supports revision 0 */ 346 IWL_DEBUG_RADIO(fwrt, 347 "PPAG table rev is %d, send truncated table\n", 348 fwrt->ppag_ver); 349 } 350 } else if (cmd_ver >= 2 && cmd_ver <= 5) { 351 num_sub_bands = IWL_NUM_SUB_BANDS_V2; 352 gain = cmd->v2.gain[0]; 353 *cmd_size = sizeof(cmd->v2); 354 if (fwrt->ppag_ver == 0) { 355 /* in this case FW supports revisions 1,2 or 3 */ 356 IWL_DEBUG_RADIO(fwrt, 357 "PPAG table rev is 0, send padded table\n"); 358 } 359 } else { 360 IWL_DEBUG_RADIO(fwrt, "Unsupported PPAG command version\n"); 361 return -EINVAL; 362 } 363 364 /* ppag mode */ 365 IWL_DEBUG_RADIO(fwrt, 366 "PPAG MODE bits were read from bios: %d\n", 367 le32_to_cpu(cmd->v1.flags)); 368 369 if (cmd_ver == 5) 370 cmd->v1.flags &= cpu_to_le32(IWL_PPAG_CMD_V5_MASK); 371 else if (cmd_ver < 5) 372 cmd->v1.flags &= cpu_to_le32(IWL_PPAG_CMD_V4_MASK); 373 374 if ((cmd_ver == 1 && 375 !fw_has_capa(&fwrt->fw->ucode_capa, 376 IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT)) || 377 (cmd_ver == 2 && fwrt->ppag_ver >= 2)) { 378 cmd->v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK); 379 IWL_DEBUG_RADIO(fwrt, "masking ppag China bit\n"); 380 } else { 381 IWL_DEBUG_RADIO(fwrt, "isn't masking ppag China bit\n"); 382 } 383 384 IWL_DEBUG_RADIO(fwrt, 385 "PPAG MODE bits going to be sent: %d\n", 386 le32_to_cpu(cmd->v1.flags)); 387 388 for (i = 0; i < IWL_NUM_CHAIN_LIMITS; i++) { 389 for (j = 0; j < num_sub_bands; j++) { 390 if (!send_ppag_always && 391 !iwl_ppag_value_valid(fwrt, i, j)) 392 return -EINVAL; 393 394 gain[i * num_sub_bands + j] = 395 fwrt->ppag_chains[i].subbands[j]; 396 IWL_DEBUG_RADIO(fwrt, 397 "PPAG table: chain[%d] band[%d]: gain = %d\n", 398 i, j, gain[i * num_sub_bands + j]); 399 } 400 } 401 402 return 0; 403 } 404 IWL_EXPORT_SYMBOL(iwl_fill_ppag_table); 405 406 bool iwl_is_ppag_approved(struct iwl_fw_runtime *fwrt) 407 { 408 if (!dmi_check_system(dmi_ppag_approved_list)) { 409 IWL_DEBUG_RADIO(fwrt, 410 "System vendor '%s' is not in the approved list, disabling PPAG.\n", 411 dmi_get_system_info(DMI_SYS_VENDOR) ?: "<unknown>"); 412 fwrt->ppag_flags = 0; 413 return false; 414 } 415 416 return true; 417 } 418 IWL_EXPORT_SYMBOL(iwl_is_ppag_approved); 419 420 bool iwl_is_tas_approved(void) 421 { 422 return dmi_check_system(dmi_tas_approved_list); 423 } 424 IWL_EXPORT_SYMBOL(iwl_is_tas_approved); 425 426 int iwl_parse_tas_selection(struct iwl_fw_runtime *fwrt, 427 struct iwl_tas_data *tas_data, 428 const u32 tas_selection) 429 { 430 u8 override_iec = u32_get_bits(tas_selection, 431 IWL_WTAS_OVERRIDE_IEC_MSK); 432 u8 enabled_iec = u32_get_bits(tas_selection, IWL_WTAS_ENABLE_IEC_MSK); 433 u8 usa_tas_uhb = u32_get_bits(tas_selection, IWL_WTAS_USA_UHB_MSK); 434 int enabled = tas_selection & IWL_WTAS_ENABLED_MSK; 435 436 IWL_DEBUG_RADIO(fwrt, "TAS selection as read from BIOS: 0x%x\n", 437 tas_selection); 438 439 tas_data->usa_tas_uhb_allowed = usa_tas_uhb; 440 tas_data->override_tas_iec = override_iec; 441 tas_data->enable_tas_iec = enabled_iec; 442 443 return enabled; 444 } 445 446 __le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt) 447 { 448 int ret; 449 u32 val; 450 __le32 config_bitmap = 0; 451 452 switch (CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id)) { 453 case IWL_CFG_RF_TYPE_HR1: 454 case IWL_CFG_RF_TYPE_HR2: 455 case IWL_CFG_RF_TYPE_JF1: 456 case IWL_CFG_RF_TYPE_JF2: 457 ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_INDONESIA_5G2, 458 &val); 459 460 if (!ret && val == DSM_VALUE_INDONESIA_ENABLE) 461 config_bitmap |= 462 cpu_to_le32(LARI_CONFIG_ENABLE_5G2_IN_INDONESIA_MSK); 463 break; 464 default: 465 break; 466 } 467 468 ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_DISABLE_SRD, &val); 469 if (!ret) { 470 if (val == DSM_VALUE_SRD_PASSIVE) 471 config_bitmap |= 472 cpu_to_le32(LARI_CONFIG_CHANGE_ETSI_TO_PASSIVE_MSK); 473 else if (val == DSM_VALUE_SRD_DISABLE) 474 config_bitmap |= 475 cpu_to_le32(LARI_CONFIG_CHANGE_ETSI_TO_DISABLED_MSK); 476 } 477 478 if (fw_has_capa(&fwrt->fw->ucode_capa, 479 IWL_UCODE_TLV_CAPA_CHINA_22_REG_SUPPORT)) { 480 ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_REGULATORY_CONFIG, 481 &val); 482 /* 483 * China 2022 enable if the BIOS object does not exist or 484 * if it is enabled in BIOS. 485 */ 486 if (ret < 0 || val & DSM_MASK_CHINA_22_REG) 487 config_bitmap |= 488 cpu_to_le32(LARI_CONFIG_ENABLE_CHINA_22_REG_SUPPORT_MSK); 489 } 490 491 return config_bitmap; 492 } 493 IWL_EXPORT_SYMBOL(iwl_get_lari_config_bitmap); 494 495 int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func, 496 u32 *value) 497 { 498 GET_BIOS_TABLE(dsm, fwrt, func, value); 499 } 500 IWL_EXPORT_SYMBOL(iwl_bios_get_dsm); 501