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 <pagadala.yesu.anjaneyulu@intel.com>
Link: https://patch.msgid.link/20260714165826.c73d2fbebbfe.I93af7c456f04ef10d03646a43aaeb1858ecdc36d@changeid
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
This commit is contained in:
Pagadala Yesu Anjaneyulu 2026-07-14 17:02:15 +03:00 committed by Miri Korenblit
parent 678148622f
commit 974cbad4c8
9 changed files with 88 additions and 34 deletions

View File

@ -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 <linux/uuid.h>
#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:

View File

@ -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 */

View File

@ -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,

View File

@ -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);

View File

@ -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.

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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",