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 IWL_BIOS_TABLE_LOADER_DATA(wbem, u32); 42 IWL_BIOS_TABLE_LOADER_DATA(dsbr, u32); 43 44 45 static const struct dmi_system_id dmi_ppag_approved_list[] = { 46 { .ident = "HP", 47 .matches = { 48 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 49 }, 50 }, 51 { .ident = "SAMSUNG", 52 .matches = { 53 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"), 54 }, 55 }, 56 { .ident = "MSFT", 57 .matches = { 58 DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), 59 }, 60 }, 61 { .ident = "ASUS", 62 .matches = { 63 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 64 }, 65 }, 66 { .ident = "GOOGLE-HP", 67 .matches = { 68 DMI_MATCH(DMI_SYS_VENDOR, "Google"), 69 DMI_MATCH(DMI_BOARD_VENDOR, "HP"), 70 }, 71 }, 72 { .ident = "GOOGLE-ASUS", 73 .matches = { 74 DMI_MATCH(DMI_SYS_VENDOR, "Google"), 75 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek COMPUTER INC."), 76 }, 77 }, 78 { .ident = "GOOGLE-SAMSUNG", 79 .matches = { 80 DMI_MATCH(DMI_SYS_VENDOR, "Google"), 81 DMI_MATCH(DMI_BOARD_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"), 82 }, 83 }, 84 { .ident = "DELL", 85 .matches = { 86 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 87 }, 88 }, 89 { .ident = "DELL", 90 .matches = { 91 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), 92 }, 93 }, 94 { .ident = "RAZER", 95 .matches = { 96 DMI_MATCH(DMI_SYS_VENDOR, "Razer"), 97 }, 98 }, 99 { .ident = "Honor", 100 .matches = { 101 DMI_MATCH(DMI_SYS_VENDOR, "HONOR"), 102 }, 103 }, 104 { .ident = "WIKO", 105 .matches = { 106 DMI_MATCH(DMI_SYS_VENDOR, "WIKO"), 107 }, 108 }, 109 {} 110 }; 111 112 static const struct dmi_system_id dmi_tas_approved_list[] = { 113 { .ident = "HP", 114 .matches = { 115 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 116 }, 117 }, 118 { .ident = "SAMSUNG", 119 .matches = { 120 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"), 121 }, 122 }, 123 { .ident = "LENOVO", 124 .matches = { 125 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 126 }, 127 }, 128 { .ident = "DELL", 129 .matches = { 130 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 131 }, 132 }, 133 { .ident = "MSFT", 134 .matches = { 135 DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), 136 }, 137 }, 138 { .ident = "Acer", 139 .matches = { 140 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 141 }, 142 }, 143 { .ident = "ASUS", 144 .matches = { 145 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 146 }, 147 }, 148 { .ident = "GOOGLE-HP", 149 .matches = { 150 DMI_MATCH(DMI_SYS_VENDOR, "Google"), 151 DMI_MATCH(DMI_BOARD_VENDOR, "HP"), 152 }, 153 }, 154 { .ident = "MSI", 155 .matches = { 156 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."), 157 }, 158 }, 159 { .ident = "Honor", 160 .matches = { 161 DMI_MATCH(DMI_SYS_VENDOR, "HONOR"), 162 }, 163 }, 164 /* keep last */ 165 {} 166 }; 167 168 bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt) 169 { 170 /* 171 * The PER_CHAIN_LIMIT_OFFSET_CMD command is not supported on 172 * earlier firmware versions. Unfortunately, we don't have a 173 * TLV API flag to rely on, so rely on the major version which 174 * is in the first byte of ucode_ver. This was implemented 175 * initially on version 38 and then backported to 17. It was 176 * also backported to 29, but only for 7265D devices. The 177 * intention was to have it in 36 as well, but not all 8000 178 * family got this feature enabled. The 8000 family is the 179 * only one using version 36, so skip this version entirely. 180 */ 181 return IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) >= 38 || 182 (IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 17 && 183 fwrt->trans->hw_rev != CSR_HW_REV_TYPE_3160) || 184 (IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 29 && 185 ((fwrt->trans->hw_rev & CSR_HW_REV_TYPE_MSK) == 186 CSR_HW_REV_TYPE_7265D)); 187 } 188 IWL_EXPORT_SYMBOL(iwl_sar_geo_support); 189 190 int iwl_sar_geo_fill_table(struct iwl_fw_runtime *fwrt, 191 struct iwl_per_chain_offset *table, 192 u32 n_bands, u32 n_profiles) 193 { 194 int i, j; 195 196 if (!fwrt->geo_enabled) 197 return -ENODATA; 198 199 if (!iwl_sar_geo_support(fwrt)) 200 return -EOPNOTSUPP; 201 202 for (i = 0; i < n_profiles; i++) { 203 for (j = 0; j < n_bands; j++) { 204 struct iwl_per_chain_offset *chain = 205 &table[i * n_bands + j]; 206 207 chain->max_tx_power = 208 cpu_to_le16(fwrt->geo_profiles[i].bands[j].max); 209 chain->chain_a = 210 fwrt->geo_profiles[i].bands[j].chains[0]; 211 chain->chain_b = 212 fwrt->geo_profiles[i].bands[j].chains[1]; 213 IWL_DEBUG_RADIO(fwrt, 214 "SAR geographic profile[%d] Band[%d]: chain A = %d chain B = %d max_tx_power = %d\n", 215 i, j, 216 fwrt->geo_profiles[i].bands[j].chains[0], 217 fwrt->geo_profiles[i].bands[j].chains[1], 218 fwrt->geo_profiles[i].bands[j].max); 219 } 220 } 221 222 return 0; 223 } 224 IWL_EXPORT_SYMBOL(iwl_sar_geo_fill_table); 225 226 static int iwl_sar_fill_table(struct iwl_fw_runtime *fwrt, 227 __le16 *per_chain, u32 n_subbands, 228 int prof_a, int prof_b) 229 { 230 int profs[BIOS_SAR_NUM_CHAINS] = { prof_a, prof_b }; 231 int i, j; 232 233 for (i = 0; i < BIOS_SAR_NUM_CHAINS; i++) { 234 struct iwl_sar_profile *prof; 235 236 /* don't allow SAR to be disabled (profile 0 means disable) */ 237 if (profs[i] == 0) 238 return -EPERM; 239 240 /* we are off by one, so allow up to BIOS_SAR_MAX_PROFILE_NUM */ 241 if (profs[i] > BIOS_SAR_MAX_PROFILE_NUM) 242 return -EINVAL; 243 244 /* profiles go from 1 to 4, so decrement to access the array */ 245 prof = &fwrt->sar_profiles[profs[i] - 1]; 246 247 /* if the profile is disabled, do nothing */ 248 if (!prof->enabled) { 249 IWL_DEBUG_RADIO(fwrt, "SAR profile %d is disabled.\n", 250 profs[i]); 251 /* 252 * if one of the profiles is disabled, we 253 * ignore all of them and return 1 to 254 * differentiate disabled from other failures. 255 */ 256 return 1; 257 } 258 259 IWL_DEBUG_INFO(fwrt, 260 "SAR EWRD: chain %d profile index %d\n", 261 i, profs[i]); 262 IWL_DEBUG_RADIO(fwrt, " Chain[%d]:\n", i); 263 for (j = 0; j < n_subbands; j++) { 264 per_chain[i * n_subbands + j] = 265 cpu_to_le16(prof->chains[i].subbands[j]); 266 IWL_DEBUG_RADIO(fwrt, " Band[%d] = %d * .125dBm\n", 267 j, prof->chains[i].subbands[j]); 268 } 269 } 270 271 return 0; 272 } 273 274 int iwl_sar_fill_profile(struct iwl_fw_runtime *fwrt, 275 __le16 *per_chain, u32 n_tables, u32 n_subbands, 276 int prof_a, int prof_b) 277 { 278 int i, ret = 0; 279 280 for (i = 0; i < n_tables; i++) { 281 ret = iwl_sar_fill_table(fwrt, 282 &per_chain[i * n_subbands * BIOS_SAR_NUM_CHAINS], 283 n_subbands, prof_a, prof_b); 284 if (ret) 285 break; 286 } 287 288 return ret; 289 } 290 IWL_EXPORT_SYMBOL(iwl_sar_fill_profile); 291 292 static bool iwl_ppag_value_valid(struct iwl_fw_runtime *fwrt, int chain, 293 int subband) 294 { 295 s8 ppag_val = fwrt->ppag_chains[chain].subbands[subband]; 296 297 if ((subband == 0 && 298 (ppag_val > IWL_PPAG_MAX_LB || ppag_val < IWL_PPAG_MIN_LB)) || 299 (subband != 0 && 300 (ppag_val > IWL_PPAG_MAX_HB || ppag_val < IWL_PPAG_MIN_HB))) { 301 IWL_DEBUG_RADIO(fwrt, "Invalid PPAG value: %d\n", ppag_val); 302 return false; 303 } 304 return true; 305 } 306 307 int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt, 308 union iwl_ppag_table_cmd *cmd, int *cmd_size) 309 { 310 u8 cmd_ver; 311 int i, j, num_sub_bands; 312 s8 *gain; 313 bool send_ppag_always; 314 315 /* many firmware images for JF lie about this */ 316 if (CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id) == 317 CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_JF)) 318 return -EOPNOTSUPP; 319 320 if (!fw_has_capa(&fwrt->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_PPAG)) { 321 IWL_DEBUG_RADIO(fwrt, 322 "PPAG capability not supported by FW, command not sent.\n"); 323 return -EINVAL; 324 } 325 326 cmd_ver = iwl_fw_lookup_cmd_ver(fwrt->fw, 327 WIDE_ID(PHY_OPS_GROUP, 328 PER_PLATFORM_ANT_GAIN_CMD), 1); 329 /* 330 * Starting from ver 4, driver needs to send the PPAG CMD regardless 331 * if PPAG is enabled/disabled or valid/invalid. 332 */ 333 send_ppag_always = cmd_ver > 3; 334 335 /* Don't send PPAG if it is disabled */ 336 if (!send_ppag_always && !fwrt->ppag_flags) { 337 IWL_DEBUG_RADIO(fwrt, "PPAG not enabled, command not sent.\n"); 338 return -EINVAL; 339 } 340 341 /* The 'flags' field is the same in v1 and in v2 so we can just 342 * use v1 to access it. 343 */ 344 cmd->v1.flags = cpu_to_le32(fwrt->ppag_flags); 345 346 IWL_DEBUG_RADIO(fwrt, "PPAG cmd ver is %d\n", cmd_ver); 347 if (cmd_ver == 1) { 348 num_sub_bands = IWL_NUM_SUB_BANDS_V1; 349 gain = cmd->v1.gain[0]; 350 *cmd_size = sizeof(cmd->v1); 351 if (fwrt->ppag_ver >= 1) { 352 /* in this case FW supports revision 0 */ 353 IWL_DEBUG_RADIO(fwrt, 354 "PPAG table rev is %d, send truncated table\n", 355 fwrt->ppag_ver); 356 } 357 } else if (cmd_ver >= 2 && cmd_ver <= 6) { 358 num_sub_bands = IWL_NUM_SUB_BANDS_V2; 359 gain = cmd->v2.gain[0]; 360 *cmd_size = sizeof(cmd->v2); 361 if (fwrt->ppag_ver == 0) { 362 /* in this case FW supports revisions 1,2 or 3 */ 363 IWL_DEBUG_RADIO(fwrt, 364 "PPAG table rev is 0, send padded table\n"); 365 } 366 } else { 367 IWL_DEBUG_RADIO(fwrt, "Unsupported PPAG command version\n"); 368 return -EINVAL; 369 } 370 371 /* ppag mode */ 372 IWL_DEBUG_RADIO(fwrt, 373 "PPAG MODE bits were read from bios: %d\n", 374 le32_to_cpu(cmd->v1.flags)); 375 376 if (cmd_ver == 5) 377 cmd->v1.flags &= cpu_to_le32(IWL_PPAG_CMD_V5_MASK); 378 else if (cmd_ver < 5) 379 cmd->v1.flags &= cpu_to_le32(IWL_PPAG_CMD_V4_MASK); 380 381 if ((cmd_ver == 1 && 382 !fw_has_capa(&fwrt->fw->ucode_capa, 383 IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT)) || 384 (cmd_ver == 2 && fwrt->ppag_ver >= 2)) { 385 cmd->v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK); 386 IWL_DEBUG_RADIO(fwrt, "masking ppag China bit\n"); 387 } else { 388 IWL_DEBUG_RADIO(fwrt, "isn't masking ppag China bit\n"); 389 } 390 391 IWL_DEBUG_RADIO(fwrt, 392 "PPAG MODE bits going to be sent: %d\n", 393 le32_to_cpu(cmd->v1.flags)); 394 395 for (i = 0; i < IWL_NUM_CHAIN_LIMITS; i++) { 396 for (j = 0; j < num_sub_bands; j++) { 397 if (!send_ppag_always && 398 !iwl_ppag_value_valid(fwrt, i, j)) 399 return -EINVAL; 400 401 gain[i * num_sub_bands + j] = 402 fwrt->ppag_chains[i].subbands[j]; 403 IWL_DEBUG_RADIO(fwrt, 404 "PPAG table: chain[%d] band[%d]: gain = %d\n", 405 i, j, gain[i * num_sub_bands + j]); 406 } 407 } 408 409 return 0; 410 } 411 IWL_EXPORT_SYMBOL(iwl_fill_ppag_table); 412 413 bool iwl_is_ppag_approved(struct iwl_fw_runtime *fwrt) 414 { 415 if (!dmi_check_system(dmi_ppag_approved_list)) { 416 IWL_DEBUG_RADIO(fwrt, 417 "System vendor '%s' is not in the approved list, disabling PPAG.\n", 418 dmi_get_system_info(DMI_SYS_VENDOR) ?: "<unknown>"); 419 fwrt->ppag_flags = 0; 420 return false; 421 } 422 423 return true; 424 } 425 IWL_EXPORT_SYMBOL(iwl_is_ppag_approved); 426 427 bool iwl_is_tas_approved(void) 428 { 429 return dmi_check_system(dmi_tas_approved_list); 430 } 431 IWL_EXPORT_SYMBOL(iwl_is_tas_approved); 432 433 struct iwl_tas_selection_data 434 iwl_parse_tas_selection(const u32 tas_selection_in, const u8 tbl_rev) 435 { 436 struct iwl_tas_selection_data tas_selection_out = {}; 437 u8 override_iec = u32_get_bits(tas_selection_in, 438 IWL_WTAS_OVERRIDE_IEC_MSK); 439 u8 canada_tas_uhb = u32_get_bits(tas_selection_in, 440 IWL_WTAS_CANADA_UHB_MSK); 441 u8 enabled_iec = u32_get_bits(tas_selection_in, 442 IWL_WTAS_ENABLE_IEC_MSK); 443 u8 usa_tas_uhb = u32_get_bits(tas_selection_in, 444 IWL_WTAS_USA_UHB_MSK); 445 446 if (tbl_rev > 0) { 447 tas_selection_out.usa_tas_uhb_allowed = usa_tas_uhb; 448 tas_selection_out.override_tas_iec = override_iec; 449 tas_selection_out.enable_tas_iec = enabled_iec; 450 } 451 452 if (tbl_rev > 1) 453 tas_selection_out.canada_tas_uhb_allowed = canada_tas_uhb; 454 455 return tas_selection_out; 456 } 457 IWL_EXPORT_SYMBOL(iwl_parse_tas_selection); 458 459 bool iwl_add_mcc_to_tas_block_list(u16 *list, u8 *size, u16 mcc) 460 { 461 for (int i = 0; i < *size; i++) { 462 if (list[i] == mcc) 463 return true; 464 } 465 466 /* Verify that there is room for another country 467 * If *size == IWL_WTAS_BLACK_LIST_MAX, then the table is full. 468 */ 469 if (*size >= IWL_WTAS_BLACK_LIST_MAX) 470 return false; 471 472 list[*size++] = mcc; 473 return true; 474 } 475 IWL_EXPORT_SYMBOL(iwl_add_mcc_to_tas_block_list); 476 477 __le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt) 478 { 479 int ret; 480 u32 val; 481 __le32 config_bitmap = 0; 482 483 switch (CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id)) { 484 case IWL_CFG_RF_TYPE_HR1: 485 case IWL_CFG_RF_TYPE_HR2: 486 case IWL_CFG_RF_TYPE_JF1: 487 case IWL_CFG_RF_TYPE_JF2: 488 ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_INDONESIA_5G2, 489 &val); 490 491 if (!ret && val == DSM_VALUE_INDONESIA_ENABLE) 492 config_bitmap |= 493 cpu_to_le32(LARI_CONFIG_ENABLE_5G2_IN_INDONESIA_MSK); 494 break; 495 default: 496 break; 497 } 498 499 ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_DISABLE_SRD, &val); 500 if (!ret) { 501 if (val == DSM_VALUE_SRD_PASSIVE) 502 config_bitmap |= 503 cpu_to_le32(LARI_CONFIG_CHANGE_ETSI_TO_PASSIVE_MSK); 504 else if (val == DSM_VALUE_SRD_DISABLE) 505 config_bitmap |= 506 cpu_to_le32(LARI_CONFIG_CHANGE_ETSI_TO_DISABLED_MSK); 507 } 508 509 if (fw_has_capa(&fwrt->fw->ucode_capa, 510 IWL_UCODE_TLV_CAPA_CHINA_22_REG_SUPPORT)) { 511 ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_REGULATORY_CONFIG, 512 &val); 513 /* 514 * China 2022 enable if the BIOS object does not exist or 515 * if it is enabled in BIOS. 516 */ 517 if (ret < 0 || val & DSM_MASK_CHINA_22_REG) 518 config_bitmap |= 519 cpu_to_le32(LARI_CONFIG_ENABLE_CHINA_22_REG_SUPPORT_MSK); 520 } 521 522 return config_bitmap; 523 } 524 IWL_EXPORT_SYMBOL(iwl_get_lari_config_bitmap); 525 526 static size_t iwl_get_lari_config_cmd_size(u8 cmd_ver) 527 { 528 size_t cmd_size; 529 530 switch (cmd_ver) { 531 case 12: 532 case 11: 533 cmd_size = sizeof(struct iwl_lari_config_change_cmd); 534 break; 535 case 10: 536 cmd_size = sizeof(struct iwl_lari_config_change_cmd_v10); 537 break; 538 case 9: 539 case 8: 540 case 7: 541 cmd_size = sizeof(struct iwl_lari_config_change_cmd_v7); 542 break; 543 case 6: 544 cmd_size = sizeof(struct iwl_lari_config_change_cmd_v6); 545 break; 546 case 5: 547 cmd_size = sizeof(struct iwl_lari_config_change_cmd_v5); 548 break; 549 case 4: 550 cmd_size = sizeof(struct iwl_lari_config_change_cmd_v4); 551 break; 552 case 3: 553 cmd_size = sizeof(struct iwl_lari_config_change_cmd_v3); 554 break; 555 case 2: 556 cmd_size = sizeof(struct iwl_lari_config_change_cmd_v2); 557 break; 558 default: 559 cmd_size = sizeof(struct iwl_lari_config_change_cmd_v1); 560 break; 561 } 562 return cmd_size; 563 } 564 565 int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt, 566 struct iwl_lari_config_change_cmd *cmd, 567 size_t *cmd_size) 568 { 569 int ret; 570 u32 value; 571 u8 cmd_ver = iwl_fw_lookup_cmd_ver(fwrt->fw, 572 WIDE_ID(REGULATORY_AND_NVM_GROUP, 573 LARI_CONFIG_CHANGE), 1); 574 575 if (WARN_ONCE(cmd_ver > 12, 576 "Don't add newer versions to this function\n")) 577 return -EINVAL; 578 579 memset(cmd, 0, sizeof(*cmd)); 580 *cmd_size = iwl_get_lari_config_cmd_size(cmd_ver); 581 582 cmd->config_bitmap = iwl_get_lari_config_bitmap(fwrt); 583 584 ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_11AX_ENABLEMENT, &value); 585 if (!ret) 586 cmd->oem_11ax_allow_bitmap = cpu_to_le32(value); 587 588 ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_UNII4_CHAN, &value); 589 if (!ret) { 590 value &= DSM_UNII4_ALLOW_BITMAP; 591 592 /* Since version 9, bits 4 and 5 are supported 593 * regardless of this capability. 594 */ 595 if (cmd_ver < 9 && 596 !fw_has_capa(&fwrt->fw->ucode_capa, 597 IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_5G9_FOR_CA)) 598 value &= ~(DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK | 599 DSM_VALUE_UNII4_CANADA_EN_MSK); 600 601 cmd->oem_unii4_allow_bitmap = cpu_to_le32(value); 602 } 603 604 ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ACTIVATE_CHANNEL, &value); 605 if (!ret) { 606 if (cmd_ver < 8) 607 value &= ~ACTIVATE_5G2_IN_WW_MASK; 608 609 /* Since version 12, bits 5 and 6 are supported 610 * regardless of this capability. 611 */ 612 if (cmd_ver < 12 && 613 !fw_has_capa(&fwrt->fw->ucode_capa, 614 IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_UNII4_US_CA)) 615 value &= CHAN_STATE_ACTIVE_BITMAP_CMD_V11; 616 617 cmd->chan_state_active_bitmap = cpu_to_le32(value); 618 } 619 620 ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_6E, &value); 621 if (!ret) 622 cmd->oem_uhb_allow_bitmap = cpu_to_le32(value); 623 624 ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_FORCE_DISABLE_CHANNELS, &value); 625 if (!ret) 626 cmd->force_disable_channels_bitmap = cpu_to_le32(value); 627 628 ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENERGY_DETECTION_THRESHOLD, 629 &value); 630 if (!ret) 631 cmd->edt_bitmap = cpu_to_le32(value); 632 633 ret = iwl_bios_get_wbem(fwrt, &value); 634 if (!ret) 635 cmd->oem_320mhz_allow_bitmap = cpu_to_le32(value); 636 637 ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_11BE, &value); 638 if (!ret) 639 cmd->oem_11be_allow_bitmap = cpu_to_le32(value); 640 641 if (cmd->config_bitmap || 642 cmd->oem_uhb_allow_bitmap || 643 cmd->oem_11ax_allow_bitmap || 644 cmd->oem_unii4_allow_bitmap || 645 cmd->chan_state_active_bitmap || 646 cmd->force_disable_channels_bitmap || 647 cmd->edt_bitmap || 648 cmd->oem_320mhz_allow_bitmap || 649 cmd->oem_11be_allow_bitmap) { 650 IWL_DEBUG_RADIO(fwrt, 651 "sending LARI_CONFIG_CHANGE, config_bitmap=0x%x, oem_11ax_allow_bitmap=0x%x\n", 652 le32_to_cpu(cmd->config_bitmap), 653 le32_to_cpu(cmd->oem_11ax_allow_bitmap)); 654 IWL_DEBUG_RADIO(fwrt, 655 "sending LARI_CONFIG_CHANGE, oem_unii4_allow_bitmap=0x%x, chan_state_active_bitmap=0x%x, cmd_ver=%d\n", 656 le32_to_cpu(cmd->oem_unii4_allow_bitmap), 657 le32_to_cpu(cmd->chan_state_active_bitmap), 658 cmd_ver); 659 IWL_DEBUG_RADIO(fwrt, 660 "sending LARI_CONFIG_CHANGE, oem_uhb_allow_bitmap=0x%x, force_disable_channels_bitmap=0x%x\n", 661 le32_to_cpu(cmd->oem_uhb_allow_bitmap), 662 le32_to_cpu(cmd->force_disable_channels_bitmap)); 663 IWL_DEBUG_RADIO(fwrt, 664 "sending LARI_CONFIG_CHANGE, edt_bitmap=0x%x, oem_320mhz_allow_bitmap=0x%x\n", 665 le32_to_cpu(cmd->edt_bitmap), 666 le32_to_cpu(cmd->oem_320mhz_allow_bitmap)); 667 IWL_DEBUG_RADIO(fwrt, 668 "sending LARI_CONFIG_CHANGE, oem_11be_allow_bitmap=0x%x\n", 669 le32_to_cpu(cmd->oem_11be_allow_bitmap)); 670 } else { 671 return 1; 672 } 673 674 return 0; 675 } 676 IWL_EXPORT_SYMBOL(iwl_fill_lari_config); 677 678 int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func, 679 u32 *value) 680 { 681 GET_BIOS_TABLE(dsm, fwrt, func, value); 682 } 683 IWL_EXPORT_SYMBOL(iwl_bios_get_dsm); 684 685 bool iwl_puncturing_is_allowed_in_bios(u32 puncturing, u16 mcc) 686 { 687 /* Some kind of regulatory mess means we need to currently disallow 688 * puncturing in the US and Canada unless enabled in BIOS. 689 */ 690 switch (mcc) { 691 case IWL_MCC_US: 692 return puncturing & IWL_UEFI_CNV_PUNCTURING_USA_EN_MSK; 693 case IWL_MCC_CANADA: 694 return puncturing & IWL_UEFI_CNV_PUNCTURING_CANADA_EN_MSK; 695 default: 696 return true; 697 } 698 } 699 IWL_EXPORT_SYMBOL(iwl_puncturing_is_allowed_in_bios); 700 701 bool iwl_rfi_is_enabled_in_bios(struct iwl_fw_runtime *fwrt) 702 { 703 /* default behaviour is disabled */ 704 u32 value = 0; 705 int ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_RFI_CONFIG, &value); 706 707 if (ret < 0) { 708 IWL_DEBUG_RADIO(fwrt, "Failed to get DSM RFI, ret=%d\n", ret); 709 return false; 710 } 711 712 value &= DSM_VALUE_RFI_DISABLE; 713 /* RFI BIOS CONFIG value can be 0 or 3 only. 714 * i.e 0 means DDR and DLVR enabled. 3 means DDR and DLVR disabled. 715 * 1 and 2 are invalid BIOS configurations, So, it's not possible to 716 * disable ddr/dlvr separately. 717 */ 718 if (!value) { 719 IWL_DEBUG_RADIO(fwrt, "DSM RFI is evaluated to enable\n"); 720 return true; 721 } else if (value == DSM_VALUE_RFI_DISABLE) { 722 IWL_DEBUG_RADIO(fwrt, "DSM RFI is evaluated to disable\n"); 723 } else { 724 IWL_DEBUG_RADIO(fwrt, 725 "DSM RFI got invalid value, value=%d\n", value); 726 } 727 728 return false; 729 } 730 IWL_EXPORT_SYMBOL(iwl_rfi_is_enabled_in_bios); 731