From 974cbad4c86d6442d9e08710322b924e4ae79023 Mon Sep 17 00:00:00 2001 From: Pagadala Yesu Anjaneyulu Date: Tue, 14 Jul 2026 17:02:15 +0300 Subject: [PATCH] wifi: iwlwifi: regulatory: add LARI_CONFIG_CHANGE command v14 support Add support for LARI_CONFIG_CHANGE version 14 and populate the newly added BIOS-related fields in the command payload. Extend the version 14 command layout with UHB extension, puncturing and WBEM metadata fields, update command-size handling for version negotiation, and wire the new data into the LARI configuration flow. Track WBEM and puncturing source/revision in fw runtime, set them when loading ACPI or UEFI tables, and pass the headers to firmware. Update send conditions, debug traces, and related documentation/comments to match the new format. Signed-off-by: Pagadala Yesu Anjaneyulu Link: https://patch.msgid.link/20260714165826.c73d2fbebbfe.I93af7c456f04ef10d03646a43aaeb1858ecdc36d@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 4 +- .../wireless/intel/iwlwifi/fw/api/nvm-reg.h | 15 ++++- .../net/wireless/intel/iwlwifi/fw/runtime.h | 13 +++- drivers/net/wireless/intel/iwlwifi/fw/uefi.c | 20 ++++--- drivers/net/wireless/intel/iwlwifi/fw/uefi.h | 4 +- drivers/net/wireless/intel/iwlwifi/mld/mcc.c | 2 +- drivers/net/wireless/intel/iwlwifi/mld/mld.c | 2 +- drivers/net/wireless/intel/iwlwifi/mld/mld.h | 2 - .../wireless/intel/iwlwifi/mld/regulatory.c | 60 ++++++++++++++----- 9 files changed, 88 insertions(+), 34 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c index bf0f851a9075..9f2f4a6af1ca 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2019-2025 Intel Corporation + * Copyright (C) 2019-2026 Intel Corporation */ #include #include "iwl-drv.h" @@ -1188,6 +1188,8 @@ int iwl_acpi_get_wbem(struct iwl_fw_runtime *fwrt, u32 *value) *value = wifi_pkg->package.elements[1].integer.value & IWL_ACPI_WBEM_REV0_MASK; + fwrt->wbem_source = BIOS_SOURCE_ACPI; + fwrt->wbem_revision = tbl_rev; IWL_DEBUG_RADIO(fwrt, "Loaded WBEM config from ACPI\n"); ret = 0; out_free: diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h index 443a9a416325..d8ec9934a9b6 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018-2025 Intel Corporation + * Copyright (C) 2012-2014, 2018-2026 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -662,6 +662,12 @@ struct iwl_lari_config_change_cmd_v8 { * get the data from the BIOS. * @oem_unii9_enable: UNII-9 enablement as read from the BIOS * @bios_hdr: bios config header + * @oem_uhb_allow_extension_bitmap: DSM Function 4 data as an extension of UHB + * enabled MCC sets + * @bios_wcpe_hdr: puncturing config header + * @wcpe_bitmap: bitmap of puncturing enablement per MCC + * @bios_wbem_hdr: 320 MHz per-MCC WBEM config header + * @reserved: reserved */ struct iwl_lari_config_change_cmd { __le32 config_bitmap; @@ -679,9 +685,16 @@ struct iwl_lari_config_change_cmd { __le32 oem_unii9_enable; /* since version 13 */ struct iwl_bios_config_hdr bios_hdr; + /* All the below are since version 14 */ + __le32 oem_uhb_allow_extension_bitmap; + struct iwl_bios_config_hdr bios_wcpe_hdr; + __le32 wcpe_bitmap; + struct iwl_bios_config_hdr bios_wbem_hdr; + __le32 reserved[10]; } __packed; /* LARI_CHANGE_CONF_CMD_S_VER_12 * LARI_CHANGE_CONF_CMD_S_VER_13 + * LARI_CHANGE_CONF_CMD_S_VER_14 */ /* Activate UNII-1 (5.2GHz) for World Wide */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index d80ae610e56c..ac01ac0092ee 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2018-2025 Intel Corporation + * Copyright (C) 2018-2026 Intel Corporation */ #ifndef __iwl_fw_runtime_h__ #define __iwl_fw_runtime_h__ @@ -144,6 +144,11 @@ struct iwl_txf_iter_data { * @tpc_enabled: TPC enabled * @dsm_source: one of &enum bios_source. UEFI, ACPI or NONE * @dsm_revision: the revision of the DSM table + * @wbem_source: one of &enum bios_source for the WBEM table + * @wbem_revision: the revision of the WBEM table + * @puncturing_source: one of &enum bios_source for the puncturing table + * @puncturing_revision: the revision of the puncturing table + * @bios_puncturing: per-country puncturing enablement bitmap from BIOS */ struct iwl_fw_runtime { struct iwl_trans *trans; @@ -226,6 +231,12 @@ struct iwl_fw_runtime { u32 dsm_funcs_valid; u32 dsm_values[DSM_FUNC_NUM_FUNCS]; #endif + + enum bios_source wbem_source; + u8 wbem_revision; + enum bios_source puncturing_source; + u8 puncturing_revision; + u32 bios_puncturing; }; void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans, diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c index 4cd36b42262c..01e495e24ebc 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright(c) 2021-2025 Intel Corporation + * Copyright(c) 2021-2026 Intel Corporation */ #include "iwl-drv.h" @@ -890,6 +890,8 @@ int iwl_uefi_get_wbem(struct iwl_fw_runtime *fwrt, u32 *value) goto out; } *value = data->wbem_320mhz_per_mcc & IWL_UEFI_WBEM_REV0_MASK; + fwrt->wbem_source = BIOS_SOURCE_UEFI; + fwrt->wbem_revision = data->revision; IWL_DEBUG_RADIO(fwrt, "Loaded WBEM config from UEFI\n"); out: kfree(data); @@ -976,29 +978,29 @@ int iwl_uefi_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func, int iwl_uefi_get_puncturing(struct iwl_fw_runtime *fwrt) { struct uefi_cnv_var_puncturing_data *data; - /* default value is not enabled if there is any issue in reading - * uefi variable or revision is not supported - */ - int puncturing = 0; + int ret = 0; data = iwl_uefi_get_verified_variable(fwrt->trans, IWL_UEFI_PUNCTURING_NAME, "UefiCnvWlanPuncturing", sizeof(*data), NULL); if (IS_ERR(data)) - return puncturing; + return -EINVAL; if (data->revision != IWL_UEFI_PUNCTURING_REVISION) { IWL_DEBUG_RADIO(fwrt, "Unsupported UEFI PUNCTURING rev:%d\n", data->revision); + ret = -EINVAL; } else { - puncturing = data->puncturing & IWL_UEFI_PUNCTURING_REV0_MASK; + fwrt->puncturing_source = BIOS_SOURCE_UEFI; + fwrt->puncturing_revision = data->revision; + fwrt->bios_puncturing = data->puncturing; IWL_DEBUG_RADIO(fwrt, "Loaded puncturing bits from UEFI: %d\n", - puncturing); + fwrt->bios_puncturing); } kfree(data); - return puncturing; + return ret; } IWL_EXPORT_SYMBOL(iwl_uefi_get_puncturing); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h index 474f06db4d43..386ca3744408 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright(c) 2021-2025 Intel Corporation + * Copyright(c) 2021-2026 Intel Corporation */ #ifndef __iwl_fw_uefi__ #define __iwl_fw_uefi__ @@ -275,8 +275,6 @@ enum iwl_uefi_cnv_puncturing_flags { IWL_UEFI_CNV_PUNCTURING_CANADA_EN_MSK = BIT(1), }; -#define IWL_UEFI_PUNCTURING_REV0_MASK (IWL_UEFI_CNV_PUNCTURING_USA_EN_MSK | \ - IWL_UEFI_CNV_PUNCTURING_CANADA_EN_MSK) /** * struct uefi_cnv_var_puncturing_data - controlling channel * puncturing for few countries. diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mcc.c b/drivers/net/wireless/intel/iwlwifi/mld/mcc.c index 8502129abe49..7649ae794dfd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mcc.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mcc.c @@ -131,7 +131,7 @@ iwl_mld_get_regdomain(struct iwl_mld *mld, /* FM follows BIOS/MCC policy, WH disallows puncturing only in US/CA. */ if (CSR_HW_RFID_TYPE(mld->trans->info.hw_rf_id) == IWL_CFG_RF_TYPE_FM) { - if (!iwl_puncturing_is_allowed_in_bios(mld->bios_enable_puncturing, + if (!iwl_puncturing_is_allowed_in_bios(mld->fwrt.bios_puncturing, le16_to_cpu(resp->mcc))) ieee80211_hw_set(mld->hw, DISALLOW_PUNCTURING); else diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mld.c b/drivers/net/wireless/intel/iwlwifi/mld/mld.c index 5a6c9ab20fd6..99506f354bfa 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mld.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mld.c @@ -419,7 +419,7 @@ iwl_op_mode_mld_start(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg, iwl_mld_get_bios_tables(mld); iwl_uefi_get_sgom_table(trans, &mld->fwrt); - mld->bios_enable_puncturing = iwl_uefi_get_puncturing(&mld->fwrt); + iwl_uefi_get_puncturing(&mld->fwrt); iwl_mld_hw_set_regulatory(mld); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mld.h b/drivers/net/wireless/intel/iwlwifi/mld/mld.h index 922aa3dbff54..37f41b504b54 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mld.h +++ b/drivers/net/wireless/intel/iwlwifi/mld/mld.h @@ -172,7 +172,6 @@ * @debug_max_sleep: maximum sleep time in D3 (for debug purposes) * @led: the led device * @mcc_src: the source id of the MCC, comes from the firmware - * @bios_enable_puncturing: is puncturing enabled by bios * @fw_id_to_ba: maps a fw (BA) id to a corresponding Block Ack session data. * @num_rx_ba_sessions: tracks the number of active Rx Block Ack (BA) sessions. * the driver ensures that new BA sessions are blocked once the maximum @@ -279,7 +278,6 @@ struct iwl_mld { struct led_classdev led; #endif enum iwl_mcc_source mcc_src; - bool bios_enable_puncturing; struct iwl_mld_baid_data __rcu *fw_id_to_ba[IWL_MAX_BAID]; u8 num_rx_ba_sessions; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c b/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c index 858635607f5d..4a93ccbef495 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c @@ -13,6 +13,23 @@ #include "mld.h" #include "hcmd.h" +static ssize_t iwl_mld_get_lari_config_cmd_size(u8 cmd_ver) +{ + switch (cmd_ver) { + case 14: + return sizeof(struct iwl_lari_config_change_cmd); + case 13: + return offsetof(struct iwl_lari_config_change_cmd, + oem_uhb_allow_extension_bitmap); + case 12: + return offsetof(struct iwl_lari_config_change_cmd, + oem_11bn_allow_bitmap); + default: + WARN(true, "unsupported version: %d", cmd_ver); + return -EINVAL; + } +} + void iwl_mld_get_bios_tables(struct iwl_mld *mld) { int ret; @@ -335,9 +352,13 @@ void iwl_mld_configure_lari(struct iwl_mld *mld) bool has_raw_dsm_capa = cmd_ver >= 13 || fw_has_capa(&fwrt->fw->ucode_capa, IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE); + ssize_t cmd_len = iwl_mld_get_lari_config_cmd_size(cmd_ver); int ret; u32 value; + if (cmd_len < 0) + return; + ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_11AX_ENABLEMENT, &value); if (!ret) { if (!has_raw_dsm_capa) @@ -379,8 +400,11 @@ void iwl_mld_configure_lari(struct iwl_mld *mld) } ret = iwl_bios_get_wbem(fwrt, &value); - if (!ret) + if (!ret) { cmd.oem_320mhz_allow_bitmap = cpu_to_le32(value); + cmd.bios_wbem_hdr.table_source = fwrt->wbem_source; + cmd.bios_wbem_hdr.table_revision = fwrt->wbem_revision; + } ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_11BE, &value); if (!ret) @@ -394,8 +418,17 @@ void iwl_mld_configure_lari(struct iwl_mld *mld) if (!ret) cmd.oem_unii9_enable = cpu_to_le32(value); + ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_REGULATORY_CONFIG, &value); + if (!ret) + cmd.oem_uhb_allow_extension_bitmap = cpu_to_le32(value); + + cmd.bios_wcpe_hdr.table_source = fwrt->puncturing_source; + cmd.bios_wcpe_hdr.table_revision = fwrt->puncturing_revision; + cmd.wcpe_bitmap = cpu_to_le32(fwrt->bios_puncturing); + if (!cmd.config_bitmap && !cmd.oem_uhb_allow_bitmap && + !cmd.oem_uhb_allow_extension_bitmap && !cmd.oem_11ax_allow_bitmap && !cmd.oem_unii4_allow_bitmap && !cmd.chan_state_active_bitmap && @@ -404,7 +437,8 @@ void iwl_mld_configure_lari(struct iwl_mld *mld) !cmd.oem_320mhz_allow_bitmap && !cmd.oem_11be_allow_bitmap && !cmd.oem_11bn_allow_bitmap && - !cmd.oem_unii9_enable) + !cmd.oem_unii9_enable && + !cmd.wcpe_bitmap) return; cmd.bios_hdr.table_source = fwrt->dsm_source; @@ -422,6 +456,9 @@ void iwl_mld_configure_lari(struct iwl_mld *mld) "sending LARI_CONFIG_CHANGE, oem_uhb_allow_bitmap=0x%x, force_disable_channels_bitmap=0x%x\n", le32_to_cpu(cmd.oem_uhb_allow_bitmap), le32_to_cpu(cmd.force_disable_channels_bitmap)); + IWL_DEBUG_RADIO(mld, + "sending LARI_CONFIG_CHANGE, oem_uhb_allow_extension_bitmap=0x%x\n", + le32_to_cpu(cmd.oem_uhb_allow_extension_bitmap)); IWL_DEBUG_RADIO(mld, "sending LARI_CONFIG_CHANGE, edt_bitmap=0x%x, oem_320mhz_allow_bitmap=0x%x\n", le32_to_cpu(cmd.edt_bitmap), @@ -435,20 +472,13 @@ void iwl_mld_configure_lari(struct iwl_mld *mld) IWL_DEBUG_RADIO(mld, "sending LARI_CONFIG_CHANGE, oem_unii9_enable=0x%x\n", le32_to_cpu(cmd.oem_unii9_enable)); + IWL_DEBUG_RADIO(mld, + "sending LARI_CONFIG_CHANGE, wcpe_bitmap=0x%x\n", + le32_to_cpu(cmd.wcpe_bitmap)); - if (cmd_ver == 12) { - int cmd_size = offsetof(typeof(cmd), oem_11bn_allow_bitmap); - - ret = iwl_mld_send_cmd_pdu(mld, - WIDE_ID(REGULATORY_AND_NVM_GROUP, - LARI_CONFIG_CHANGE), - &cmd, cmd_size); - } else { - ret = iwl_mld_send_cmd_pdu(mld, - WIDE_ID(REGULATORY_AND_NVM_GROUP, - LARI_CONFIG_CHANGE), - &cmd); - } + ret = iwl_mld_send_cmd_pdu(mld, + WIDE_ID(REGULATORY_AND_NVM_GROUP, + LARI_CONFIG_CHANGE), &cmd, cmd_len); if (ret) IWL_DEBUG_RADIO(mld, "Failed to send LARI_CONFIG_CHANGE (%d)\n",