mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 21:38:24 +02:00
wifi: iwlwifi: updates - 2026-07-23
This comtains the usual features, fixes and cleanups. Notably: - Small fixes of bugs reported by LLMs - LARI command version 14 and 15 - MCC command version 10 - Support for core 107 -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQQM3A3Pv7vbm9vtjWbacY7uyt+OfQUCamJQLQAKCRDacY7uyt+O fc/cAQCHQ7F7RCO8iB5u+kFc71+0UpDpK8bYVN1lwvL26/7WkQD/YcRZ9L01EOJl DZQAP0WwHoHzK6DuPQoxnr88iiUYnAs= =PyTI -----END PGP SIGNATURE----- Merge tag 'iwlwifi-next-2026-07-23' of https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next Miri Korenblit says: ==================== wifi: iwlwifi: updates - 2026-07-23 This comtains the usual features, fixes and cleanups. Notably: - Small fixes of bugs reported by LLMs - LARI command version 14 and 15 - MCC command version 10 - Support for core 107 ==================== Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
commit
905b418df8
|
|
@ -10,7 +10,7 @@
|
|||
#include "fw/api/txq.h"
|
||||
|
||||
/* Highest firmware core release supported */
|
||||
#define IWL_BZ_UCODE_CORE_MAX 106
|
||||
#define IWL_BZ_UCODE_CORE_MAX 107
|
||||
|
||||
/* Lowest firmware core release supported */
|
||||
#define IWL_BZ_UCODE_CORE_MIN 102
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#include "fw/api/txq.h"
|
||||
|
||||
/* Highest firmware core release supported */
|
||||
#define IWL_DR_UCODE_CORE_MAX 106
|
||||
#define IWL_DR_UCODE_CORE_MAX 107
|
||||
|
||||
/* Lowest firmware core release supported */
|
||||
#define IWL_DR_UCODE_CORE_MIN 102
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include "fw/api/txq.h"
|
||||
|
||||
/* Highest firmware core release supported */
|
||||
#define IWL_SC_UCODE_CORE_MAX 106
|
||||
#define IWL_SC_UCODE_CORE_MAX 107
|
||||
|
||||
/* Lowest firmware core release supported */
|
||||
#define IWL_SC_UCODE_CORE_MIN 102
|
||||
|
|
|
|||
|
|
@ -1511,10 +1511,10 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
|||
priv->workqueue = NULL;
|
||||
out_uninit_drv:
|
||||
iwl_uninit_drv(priv);
|
||||
out_free_eeprom_blob:
|
||||
kfree(priv->eeprom_blob);
|
||||
out_free_eeprom:
|
||||
kfree(priv->nvm_data);
|
||||
out_free_eeprom_blob:
|
||||
kfree(priv->eeprom_blob);
|
||||
out_leave_trans:
|
||||
iwl_trans_op_mode_leave(priv->trans);
|
||||
out_free_hw:
|
||||
|
|
|
|||
|
|
@ -604,8 +604,10 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
|
|||
}
|
||||
|
||||
ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
iwlagn_dealloc_agg_txq(priv, txq_id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
spin_lock_bh(&priv->sta_lock);
|
||||
tid_data = &priv->tid_data[sta_id][tid];
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
@ -181,6 +181,7 @@ static int iwl_acpi_load_dsm_values(struct iwl_fw_runtime *fwrt)
|
|||
|
||||
fwrt->dsm_revision = ACPI_DSM_REV;
|
||||
fwrt->dsm_source = BIOS_SOURCE_ACPI;
|
||||
fwrt->dsm_values[DSM_FUNC_QUERY] = (u32)query_func_val;
|
||||
|
||||
IWL_DEBUG_RADIO(fwrt, "ACPI DSM validity bitmap 0x%x\n",
|
||||
(u32)query_func_val);
|
||||
|
|
@ -246,7 +247,7 @@ int iwl_acpi_get_dsm(struct iwl_fw_runtime *fwrt,
|
|||
BUILD_BUG_ON(ARRAY_SIZE(fwrt->dsm_values) != DSM_FUNC_NUM_FUNCS);
|
||||
BUILD_BUG_ON(BITS_PER_TYPE(fwrt->dsm_funcs_valid) < DSM_FUNC_NUM_FUNCS);
|
||||
|
||||
if (WARN_ON(func >= ARRAY_SIZE(fwrt->dsm_values) || !func))
|
||||
if (WARN_ON(func >= ARRAY_SIZE(fwrt->dsm_values)))
|
||||
return -EINVAL;
|
||||
|
||||
if (!(fwrt->dsm_funcs_valid & BIT(func))) {
|
||||
|
|
@ -1193,6 +1194,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:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018-2023, 2025 Intel Corporation
|
||||
* Copyright (C) 2018-2023, 2025-2026 Intel Corporation
|
||||
*/
|
||||
#ifndef __iwl_fw_acpi__
|
||||
#define __iwl_fw_acpi__
|
||||
|
|
@ -111,9 +111,6 @@
|
|||
#define ACPI_PPAG_WIFI_DATA_SIZE_V3 ((ACPI_PPAG_NUM_CHAINS * \
|
||||
ACPI_PPAG_NUM_BANDS_V3) + 2)
|
||||
|
||||
#define IWL_SAR_ENABLE_MSK BIT(0)
|
||||
#define IWL_REDUCE_POWER_FLAGS_POS 1
|
||||
|
||||
/* The Inidcator whether UEFI WIFI GUID tables are locked is read from ACPI */
|
||||
#define UEFI_WIFI_GUID_UNLOCKED 0
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
@ -46,6 +46,11 @@ enum iwl_regulatory_and_nvm_subcmd_ids {
|
|||
*/
|
||||
MCC_ALLOWED_AP_TYPE_CMD = 0x5,
|
||||
|
||||
/**
|
||||
* @LARI_CONFIG_EXTENSION: &struct iwl_lari_config_extension_cmd
|
||||
*/
|
||||
LARI_CONFIG_EXTENSION = 0x8,
|
||||
|
||||
/**
|
||||
* @PNVM_INIT_COMPLETE_NTFY: &struct iwl_pnvm_init_complete_ntfy
|
||||
*/
|
||||
|
|
@ -433,7 +438,10 @@ struct iwl_mcc_chub_notif {
|
|||
__le16 mcc;
|
||||
u8 source_id;
|
||||
u8 reserved1;
|
||||
} __packed; /* LAR_MCC_NOTIFY_S */
|
||||
} __packed;
|
||||
/* LAR_MCC_NOTIFY_S_VER_1
|
||||
* LAR_MCC_NOTIFY_S_VER_2
|
||||
*/
|
||||
|
||||
enum iwl_mcc_update_status {
|
||||
MCC_RESP_NEW_CHAN_PROFILE,
|
||||
|
|
@ -541,6 +549,27 @@ struct iwl_bios_config_hdr {
|
|||
u8 reserved[2];
|
||||
} __packed; /* BIOS_CONFIG_HDR_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_lari_config_extension_cmd - extend LARI configuration
|
||||
*
|
||||
* LARI_CONFIG_CHANGE's version must remain stable for frozen firmware.
|
||||
* Because the driver might not know this version but still load that
|
||||
* frozen FW and then send some default old version of LARI, causing the FW to
|
||||
* assert about the bad size of it. To handle this, we do the following:
|
||||
* 1. For newer firmware: increase the LARI_CONFIG_CHANGE version to support the
|
||||
* new firmware API with extra UHB bits.
|
||||
* 2. For frozen firmware: add a special alternative API that doesn't require
|
||||
* modifying the frozen LARI_CONFIG_CHANGE's version.
|
||||
* @dsm_table_hdr: BIOS DSM table source and revision
|
||||
* @oem_uhb_allow_extension_bitmap: extension bitmap for OEM UHB config
|
||||
* @reserved: reserved
|
||||
*/
|
||||
struct iwl_lari_config_extension_cmd {
|
||||
struct iwl_bios_config_hdr dsm_table_hdr;
|
||||
__le32 oem_uhb_allow_extension_bitmap;
|
||||
__le32 reserved[10];
|
||||
} __packed; /* LARI_CONFIG_EXTENSION_CMD_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct bios_value_u32 - BIOS configuration.
|
||||
* @hdr: bios config header
|
||||
|
|
@ -689,6 +718,14 @@ 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
|
||||
* @oem_supported_dsm_bitmap: DSM function 0 bitmap describing supported
|
||||
* DSM function indices
|
||||
*/
|
||||
struct iwl_lari_config_change_cmd {
|
||||
__le32 config_bitmap;
|
||||
|
|
@ -706,9 +743,19 @@ 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];
|
||||
/* since version 15 */
|
||||
__le32 oem_supported_dsm_bitmap;
|
||||
} __packed;
|
||||
/* LARI_CHANGE_CONF_CMD_S_VER_12
|
||||
* LARI_CHANGE_CONF_CMD_S_VER_13
|
||||
* LARI_CHANGE_CONF_CMD_S_VER_14
|
||||
* LARI_CHANGE_CONF_CMD_S_VER_15
|
||||
*/
|
||||
|
||||
/* Activate UNII-1 (5.2GHz) for World Wide */
|
||||
|
|
|
|||
|
|
@ -369,7 +369,7 @@ static void iwl_fwrt_dump_fseq_regs(struct iwl_fw_runtime *fwrt)
|
|||
void iwl_fwrt_dump_error_logs(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
struct iwl_pc_data *pc_data;
|
||||
u8 count;
|
||||
u32 count;
|
||||
|
||||
if (!iwl_trans_device_enabled(fwrt->trans)) {
|
||||
IWL_ERR(fwrt,
|
||||
|
|
|
|||
|
|
@ -352,7 +352,7 @@ struct iwl_fw_ini_error_dump_register {
|
|||
* struct iwl_fw_ini_dump_cfg_name - configuration name
|
||||
* @image_type: image type the configuration is related to
|
||||
* @cfg_name_len: length of the configuration name
|
||||
* @cfg_name: name of the configuraiton
|
||||
* @cfg_name: name of the configuration
|
||||
*/
|
||||
struct iwl_fw_ini_dump_cfg_name {
|
||||
__le32 image_type;
|
||||
|
|
|
|||
|
|
@ -448,8 +448,9 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t;
|
|||
* @IWL_UCODE_TLV_CAPA_EXT_FSEQ_IMAGE_SUPPORT: external FSEQ image support
|
||||
* @IWL_UCODE_TLV_CAPA_RESET_DURING_ASSERT: FW reset handshake is needed
|
||||
* during assert handling even if the dump isn't split
|
||||
* @IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE: Firmware has capability of
|
||||
* handling raw DSM table data.
|
||||
* @IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE: Firmware can handle raw DSM
|
||||
* table data. For LARI_CONFIG_CHANGE command version 13 and above, this
|
||||
* capability is obsolete since raw DSM values are accepted by default.
|
||||
* @IWL_UCODE_TLV_CAPA_NAN_SYNC_SUPPORT: Supports NAN synchronization
|
||||
*
|
||||
* @NUM_IWL_UCODE_TLV_CAPA: number of bits used
|
||||
|
|
|
|||
|
|
@ -205,6 +205,12 @@ static int iwl_pnvm_parse(struct iwl_trans *trans, const u8 *data,
|
|||
IWL_DEBUG_FW(trans,
|
||||
"Got IWL_UCODE_TLV_PNVM_SKU len %d\n",
|
||||
tlv_len);
|
||||
if (tlv_len < sizeof(*tlv_sku_id)) {
|
||||
IWL_ERR(trans, "invalid PNVM SKU TLV len: %u\n",
|
||||
tlv_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
IWL_DEBUG_FW(trans, "sku_id 0x%0x 0x%0x 0x%0x\n",
|
||||
le32_to_cpu(tlv_sku_id->data[0]),
|
||||
le32_to_cpu(tlv_sku_id->data[1]),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2023-2025 Intel Corporation
|
||||
* Copyright (C) 2023-2026 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __fw_regulatory_h__
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
#define BIOS_GEO_MIN_PROFILE_NUM 3
|
||||
|
||||
#define IWL_SAR_ENABLE_MSK BIT(0)
|
||||
#define IWL_REDUCE_POWER_FLAGS_POS 1
|
||||
|
||||
/* PPAG gain value bounds in 1/8 dBm */
|
||||
#define IWL_PPAG_MIN_LB -16
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
@ -248,6 +248,12 @@ int iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
|
|||
IWL_DEBUG_FW(trans,
|
||||
"Got IWL_UCODE_TLV_PNVM_SKU len %d\n",
|
||||
tlv_len);
|
||||
if (tlv_len < sizeof(*tlv_sku_id)) {
|
||||
IWL_ERR(trans, "invalid PNVM SKU TLV len: %u\n",
|
||||
tlv_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
IWL_DEBUG_FW(trans, "sku_id 0x%0x 0x%0x 0x%0x\n",
|
||||
le32_to_cpu(tlv_sku_id->data[0]),
|
||||
le32_to_cpu(tlv_sku_id->data[1]),
|
||||
|
|
@ -884,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);
|
||||
|
|
@ -919,7 +927,7 @@ static int iwl_uefi_load_dsm_values(struct iwl_fw_runtime *fwrt)
|
|||
*/
|
||||
fwrt->dsm_funcs_valid |= BIT(DSM_FUNC_QUERY);
|
||||
|
||||
for (int func = 1; func < ARRAY_SIZE(fwrt->dsm_values); func++) {
|
||||
for (int func = 0; func < ARRAY_SIZE(fwrt->dsm_values); func++) {
|
||||
if (!(fwrt->dsm_funcs_valid & BIT(func))) {
|
||||
IWL_DEBUG_RADIO(fwrt, "DSM func %d not in 0x%x\n",
|
||||
func, fwrt->dsm_funcs_valid);
|
||||
|
|
@ -970,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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2018-2025 Intel Corporation
|
||||
* Copyright (C) 2018-2026 Intel Corporation
|
||||
*/
|
||||
#include <linux/firmware.h>
|
||||
#include "iwl-drv.h"
|
||||
|
|
@ -611,6 +611,9 @@ static int iwl_dbg_tlv_alloc_fragments(struct iwl_fw_runtime *fwrt,
|
|||
cpu_to_le32(IWL_FW_INI_LOCATION_DRAM_PATH))
|
||||
return 0;
|
||||
|
||||
if (!fw_mon_cfg->req_size)
|
||||
return -EIO;
|
||||
|
||||
num_frags = le32_to_cpu(fw_mon_cfg->max_frags_num);
|
||||
if (fwrt->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) {
|
||||
if (alloc_id != IWL_FW_INI_ALLOCATION_ID_DBGC1)
|
||||
|
|
@ -621,6 +624,9 @@ static int iwl_dbg_tlv_alloc_fragments(struct iwl_fw_runtime *fwrt,
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
if (!num_frags)
|
||||
return -EIO;
|
||||
|
||||
remain_pages = DIV_ROUND_UP(le32_to_cpu(fw_mon_cfg->req_size),
|
||||
PAGE_SIZE);
|
||||
num_frags = min_t(u32, num_frags, BUF_ALLOC_MAX_NUM_FRAGS);
|
||||
|
|
|
|||
|
|
@ -225,6 +225,18 @@ enum iwl_reg_capa_flags_v5 {
|
|||
REG_CAPA_V5_11BN_DISABLED = BIT(17),
|
||||
}; /* GEO_CHANNEL_CAPABILITIES_API_S_VER_4, 5 */
|
||||
|
||||
/**
|
||||
* enum iwl_reg_capa_flags_v6 - global capability flags,
|
||||
* applicable from MCC response version 10 onwards.
|
||||
* Response v6 includes all members of iwl_reg_capa_flags_v5; only v6-specific
|
||||
* additions are listed here.
|
||||
* @REG_CAPA_V6_EHT_PUNCTURING_ENABLED: EHT puncturing is enabled for this
|
||||
* regulatory domain.
|
||||
*/
|
||||
enum iwl_reg_capa_flags_v6 {
|
||||
REG_CAPA_V6_EHT_PUNCTURING_ENABLED = BIT(18),
|
||||
}; /* GEO_CHANNEL_CAPABILITIES_API_S_VER_6 */
|
||||
|
||||
/*
|
||||
* API v2 for reg_capa_flags is relevant from version 6 and onwards of the
|
||||
* MCC update command response.
|
||||
|
|
@ -236,6 +248,11 @@ enum iwl_reg_capa_flags_v5 {
|
|||
*/
|
||||
#define REG_CAPA_V4_RESP_VER 8
|
||||
|
||||
/* API v6 for reg_capa_flags is relevant from version 10 and onwards of the
|
||||
* MCC update command response.
|
||||
*/
|
||||
#define REG_CAPA_V6_RESP_VER 10
|
||||
|
||||
static inline void iwl_nvm_print_channel_flags(struct device *dev, u32 level,
|
||||
int chan, u32 flags)
|
||||
{
|
||||
|
|
@ -697,7 +714,8 @@ static const struct ieee80211_sband_iftype_data iwl_iftype_cap[] = {
|
|||
.mac.mac_cap = {
|
||||
[0] = IEEE80211_UHR_MAC_CAP0_NPCA_SUPP |
|
||||
IEEE80211_UHR_MAC_CAP0_DPS_SUPP,
|
||||
[1] = IEEE80211_UHR_MAC_CAP1_DUO_SUPP,
|
||||
[1] = IEEE80211_UHR_MAC_CAP1_DUO_SUPP |
|
||||
IEEE80211_UHR_MAC_CAP1_DBE_SUPP,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -1687,6 +1705,13 @@ static struct iwl_reg_capa iwl_get_reg_capa(u32 flags, u8 resp_ver)
|
|||
{
|
||||
struct iwl_reg_capa reg_capa = {};
|
||||
|
||||
if (resp_ver >= REG_CAPA_V6_RESP_VER) {
|
||||
if (flags & REG_CAPA_V6_EHT_PUNCTURING_ENABLED)
|
||||
reg_capa.puncturing_status = IWL_PUNCTURING_STATUS_ENABLED;
|
||||
else
|
||||
reg_capa.puncturing_status = IWL_PUNCTURING_STATUS_DISABLED;
|
||||
}
|
||||
|
||||
if (resp_ver >= REG_CAPA_V4_RESP_VER) {
|
||||
reg_capa.allow_40mhz = true;
|
||||
reg_capa.allow_80mhz = flags & REG_CAPA_V5_80MHZ_ALLOWED;
|
||||
|
|
@ -1713,7 +1738,8 @@ static struct iwl_reg_capa iwl_get_reg_capa(u32 flags, u8 resp_ver)
|
|||
struct ieee80211_regdomain *
|
||||
iwl_parse_nvm_mcc_info(struct iwl_trans *trans,
|
||||
int num_of_ch, __le32 *channels, u16 fw_mcc,
|
||||
u16 geo_info, u32 cap, u8 resp_ver)
|
||||
u16 geo_info, u32 cap, u8 resp_ver,
|
||||
enum iwl_puncturing_status *puncturing_status)
|
||||
{
|
||||
const struct iwl_rf_cfg *cfg = trans->cfg;
|
||||
struct device *dev = trans->dev;
|
||||
|
|
@ -1776,6 +1802,9 @@ iwl_parse_nvm_mcc_info(struct iwl_trans *trans,
|
|||
/* parse regulatory capability flags */
|
||||
reg_capa = iwl_get_reg_capa(cap, resp_ver);
|
||||
|
||||
if (puncturing_status)
|
||||
*puncturing_status = reg_capa.puncturing_status;
|
||||
|
||||
for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
|
||||
enum nl80211_band band =
|
||||
iwl_nl80211_band_from_channel_idx(ch_idx);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2005-2015, 2018-2025 Intel Corporation
|
||||
* Copyright (C) 2005-2015, 2018-2026 Intel Corporation
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
#ifndef __iwl_nvm_parse_h__
|
||||
|
|
@ -21,6 +21,19 @@ enum iwl_nvm_sbands_flags {
|
|||
IWL_NVM_SBANDS_FLAGS_NO_WIDE_IN_5GHZ = BIT(1),
|
||||
};
|
||||
|
||||
/**
|
||||
* enum iwl_puncturing_status - EHT puncturing status from MCC capabilities
|
||||
* @IWL_PUNCTURING_STATUS_UNKNOWN: puncturing status is not provided by FW
|
||||
* or is not initialized yet
|
||||
* @IWL_PUNCTURING_STATUS_ENABLED: puncturing is enabled for the current MCC
|
||||
* @IWL_PUNCTURING_STATUS_DISABLED: puncturing is disabled for the current MCC
|
||||
*/
|
||||
enum iwl_puncturing_status {
|
||||
IWL_PUNCTURING_STATUS_UNKNOWN,
|
||||
IWL_PUNCTURING_STATUS_ENABLED,
|
||||
IWL_PUNCTURING_STATUS_DISABLED,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_reg_capa - struct for global regulatory capabilities, Used for
|
||||
* handling the different APIs of reg_capa_flags.
|
||||
|
|
@ -36,6 +49,8 @@ enum iwl_nvm_sbands_flags {
|
|||
* @disable_11ax: 11ax is forbidden for this regulatory domain.
|
||||
* @disable_11be: 11be is forbidden for this regulatory domain.
|
||||
* @disable_11bn: UHR/11bn is not allowed for this regulatory domain
|
||||
* @puncturing_status: EHT puncturing status for the current MCC.
|
||||
* See &enum iwl_puncturing_status.
|
||||
*/
|
||||
struct iwl_reg_capa {
|
||||
bool allow_40mhz;
|
||||
|
|
@ -45,6 +60,7 @@ struct iwl_reg_capa {
|
|||
bool disable_11ax;
|
||||
bool disable_11be;
|
||||
bool disable_11bn;
|
||||
enum iwl_puncturing_status puncturing_status;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -131,11 +147,13 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg,
|
|||
* @geo_info: geo info value
|
||||
* @cap: capability
|
||||
* @resp_ver: FW response version
|
||||
* @puncturing_status: FW puncturing status for current MCC, when available
|
||||
*/
|
||||
struct ieee80211_regdomain *
|
||||
iwl_parse_nvm_mcc_info(struct iwl_trans *trans,
|
||||
int num_of_ch, __le32 *channels, u16 fw_mcc,
|
||||
u16 geo_info, u32 cap, u8 resp_ver);
|
||||
u16 geo_info, u32 cap, u8 resp_ver,
|
||||
enum iwl_puncturing_status *puncturing_status);
|
||||
|
||||
/**
|
||||
* struct iwl_nvm_section - describes an NVM section in memory.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2024 Intel Corporation
|
||||
* Copyright (C) 2026 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/etherdevice.h>
|
||||
|
|
@ -457,7 +458,7 @@ static int iwl_mei_send_sap_msg_payload(struct mei_cl_device *cldev,
|
|||
notif_q = &dir->q_ctrl_blk[SAP_QUEUE_IDX_NOTIF];
|
||||
q_head = mei->shared_mem.q_head[SAP_DIRECTION_HOST_TO_ME][SAP_QUEUE_IDX_NOTIF];
|
||||
q_sz = mei->shared_mem.q_size[SAP_DIRECTION_HOST_TO_ME][SAP_QUEUE_IDX_NOTIF];
|
||||
ret = iwl_mei_write_cyclic_buf(q_head, notif_q, q_head, hdr, q_sz);
|
||||
ret = iwl_mei_write_cyclic_buf(cldev, notif_q, q_head, hdr, q_sz);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
|
@ -1040,11 +1041,14 @@ static void iwl_mei_read_from_q(const u8 *q_head, u32 q_sz,
|
|||
u32 rd = *_rd;
|
||||
|
||||
if (rd + len <= q_sz) {
|
||||
memcpy(buf, q_head + rd, len);
|
||||
if (buf)
|
||||
memcpy(buf, q_head + rd, len);
|
||||
rd += len;
|
||||
} else {
|
||||
memcpy(buf, q_head + rd, q_sz - rd);
|
||||
memcpy(buf + q_sz - rd, q_head, len - (q_sz - rd));
|
||||
if (buf) {
|
||||
memcpy(buf, q_head + rd, q_sz - rd);
|
||||
memcpy(buf + q_sz - rd, q_head, len - (q_sz - rd));
|
||||
}
|
||||
rd = len - (q_sz - rd);
|
||||
}
|
||||
|
||||
|
|
@ -1085,24 +1089,29 @@ static void iwl_mei_handle_sap_data(struct mei_cl_device *cldev,
|
|||
break;
|
||||
}
|
||||
|
||||
valid_rx_sz -= len;
|
||||
|
||||
if (len < sizeof(*ethhdr)) {
|
||||
dev_err(&cldev->dev,
|
||||
"Data len is smaller than an ethernet header? len = %d\n",
|
||||
len);
|
||||
iwl_mei_read_from_q(q_head, q_sz, &rd, wr, NULL, len);
|
||||
continue;
|
||||
}
|
||||
|
||||
valid_rx_sz -= len;
|
||||
|
||||
if (le16_to_cpu(hdr.type) != SAP_MSG_DATA_PACKET) {
|
||||
dev_err(&cldev->dev, "Unsupported Rx data: type %d, len %d\n",
|
||||
le16_to_cpu(hdr.type), len);
|
||||
iwl_mei_read_from_q(q_head, q_sz, &rd, wr, NULL, len);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We need enough room for the WiFi header + SNAP + IV */
|
||||
skb = netdev_alloc_skb(netdev, len + QOS_HDR_IV_SNAP_LEN);
|
||||
if (!skb)
|
||||
if (!skb) {
|
||||
iwl_mei_read_from_q(q_head, q_sz, &rd, wr, NULL, len);
|
||||
continue;
|
||||
}
|
||||
|
||||
skb_reserve(skb, QOS_HDR_IV_SNAP_LEN);
|
||||
ethhdr = skb_push(skb, sizeof(*ethhdr));
|
||||
|
|
@ -1147,6 +1156,11 @@ static void iwl_mei_handle_sap_rx_cmd(struct mei_cl_device *cldev,
|
|||
iwl_mei_read_from_q(q_head, q_sz, &rd, wr, hdr, sizeof(*hdr));
|
||||
valid_rx_sz -= sizeof(*hdr);
|
||||
len = le16_to_cpu(hdr->len);
|
||||
if (len + sizeof(*hdr) > PAGE_SIZE) {
|
||||
dev_err(&cldev->dev,
|
||||
"SAP message is too big: %u\n", len);
|
||||
break;
|
||||
}
|
||||
|
||||
if (valid_rx_sz < len)
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -200,11 +200,11 @@ iwl_mld_reorder(struct iwl_mld *mld, struct napi_struct *napi,
|
|||
struct iwl_mld_baid_data *baid_data;
|
||||
struct iwl_mld_reorder_buffer *buffer;
|
||||
struct iwl_mld_reorder_buf_entry *entries;
|
||||
struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(sta);
|
||||
struct iwl_mld_link_sta *mld_link_sta;
|
||||
u32 reorder = le32_to_cpu(desc->reorder_data);
|
||||
bool amsdu, last_subframe, is_old_sn, is_dup;
|
||||
u8 tid = ieee80211_get_tid(hdr);
|
||||
struct iwl_mld_sta *mld_sta;
|
||||
u8 baid;
|
||||
u16 nssn, sn;
|
||||
u32 sta_mask = 0;
|
||||
|
|
@ -228,10 +228,13 @@ iwl_mld_reorder(struct iwl_mld *mld, struct napi_struct *napi,
|
|||
return IWL_MLD_PASS_SKB;
|
||||
|
||||
/* no sta yet */
|
||||
if (WARN_ONCE(!sta,
|
||||
"Got valid BAID without a valid station assigned\n"))
|
||||
if (IWL_FW_CHECK(mld, !sta,
|
||||
"Got valid BAID without a valid station assigned - %d\n",
|
||||
baid))
|
||||
return IWL_MLD_PASS_SKB;
|
||||
|
||||
mld_sta = iwl_mld_sta_from_mac80211(sta);
|
||||
|
||||
/* not a data packet */
|
||||
if (!ieee80211_is_data_qos(hdr->frame_control) ||
|
||||
is_multicast_ether_addr(hdr->addr1))
|
||||
|
|
|
|||
|
|
@ -59,6 +59,30 @@ struct iwl_mld_suspend_key_iter_data {
|
|||
__le32 bigtk_cipher;
|
||||
};
|
||||
|
||||
struct iwl_mld_wake_pkt_iter_data {
|
||||
bool multicast;
|
||||
u32 ivlen;
|
||||
u32 icvlen;
|
||||
};
|
||||
|
||||
static void
|
||||
iwl_mld_wake_pkt_key_iter(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key, void *_data)
|
||||
{
|
||||
struct iwl_mld_wake_pkt_iter_data *data = _data;
|
||||
bool is_group_key = !sta;
|
||||
|
||||
/* ignore anything that is not a PTK / GTK */
|
||||
if (key->keyidx > 3)
|
||||
return;
|
||||
if (is_group_key != data->multicast)
|
||||
return;
|
||||
|
||||
data->ivlen = key->iv_len;
|
||||
data->icvlen = key->icv_len;
|
||||
}
|
||||
|
||||
struct iwl_mld_mcast_key_data {
|
||||
u8 key[WOWLAN_KEY_MAX_SIZE];
|
||||
u8 len;
|
||||
|
|
@ -573,18 +597,42 @@ iwl_mld_convert_wowlan_notif_v5(const struct iwl_wowlan_info_notif_v5 *notif_v5,
|
|||
}
|
||||
}
|
||||
|
||||
static bool iwl_mld_validate_wowlan_notif_size(struct iwl_mld *mld,
|
||||
u32 len,
|
||||
u32 expected_len,
|
||||
u8 num_mlo_keys,
|
||||
static bool iwl_mld_validate_wowlan_notif_size(struct iwl_mld *mld, u32 len,
|
||||
const void *notif_data,
|
||||
int version)
|
||||
{
|
||||
u32 len_with_mlo_keys;
|
||||
u32 expected_len;
|
||||
u8 num_mlo_keys;
|
||||
|
||||
if (IWL_FW_CHECK(mld, len < expected_len,
|
||||
"Invalid wowlan_info_notif v%d (expected=%u got=%u)\n",
|
||||
version, expected_len, len))
|
||||
/* Extract num_mlo_keys from the void pointer based on version */
|
||||
if (version == 5) {
|
||||
const struct iwl_wowlan_info_notif_v5 *notif_v5 = notif_data;
|
||||
|
||||
expected_len = sizeof(*notif_v5);
|
||||
|
||||
if (IWL_FW_CHECK(mld, len < expected_len,
|
||||
"Invalid wowlan_info_notif v5 (expected=%u got=%u)\n",
|
||||
expected_len, len))
|
||||
return false;
|
||||
|
||||
num_mlo_keys = notif_v5->num_mlo_link_keys;
|
||||
} else if (version == 6) {
|
||||
const struct iwl_wowlan_info_notif *notif = notif_data;
|
||||
|
||||
expected_len = sizeof(*notif);
|
||||
|
||||
if (IWL_FW_CHECK(mld, len < expected_len,
|
||||
"Invalid wowlan_info_notif v6 (expected=%u got=%u)\n",
|
||||
expected_len, len))
|
||||
return false;
|
||||
|
||||
num_mlo_keys = notif->num_mlo_link_keys;
|
||||
} else {
|
||||
IWL_WARN(mld, "Unsupported wowlan_info_notif version %d\n",
|
||||
version);
|
||||
return false;
|
||||
}
|
||||
|
||||
len_with_mlo_keys = expected_len +
|
||||
(num_mlo_keys * sizeof(struct iwl_wowlan_mlo_gtk));
|
||||
|
|
@ -616,16 +664,14 @@ iwl_mld_handle_wowlan_info_notif(struct iwl_mld *mld,
|
|||
|
||||
if (wowlan_info_ver == 5) {
|
||||
/* v5 format - validate before conversion */
|
||||
const struct iwl_wowlan_info_notif_v5 *notif_v5 = (void *)pkt->data;
|
||||
const struct iwl_wowlan_info_notif_v5 *_notif =
|
||||
(void *)pkt->data;
|
||||
|
||||
if (!iwl_mld_validate_wowlan_notif_size(mld, len,
|
||||
sizeof(*notif_v5),
|
||||
notif_v5->num_mlo_link_keys,
|
||||
5))
|
||||
if (!iwl_mld_validate_wowlan_notif_size(mld, len, _notif, 5))
|
||||
return true;
|
||||
|
||||
converted_notif = kzalloc_flex(*converted_notif, mlo_gtks,
|
||||
notif_v5->num_mlo_link_keys,
|
||||
_notif->num_mlo_link_keys,
|
||||
GFP_ATOMIC);
|
||||
if (!converted_notif) {
|
||||
IWL_ERR(mld,
|
||||
|
|
@ -633,15 +679,12 @@ iwl_mld_handle_wowlan_info_notif(struct iwl_mld *mld,
|
|||
return true;
|
||||
}
|
||||
|
||||
iwl_mld_convert_wowlan_notif_v5(notif_v5,
|
||||
converted_notif);
|
||||
iwl_mld_convert_wowlan_notif_v5(_notif, converted_notif);
|
||||
notif = converted_notif;
|
||||
} else if (wowlan_info_ver == 6) {
|
||||
notif = (void *)pkt->data;
|
||||
if (!iwl_mld_validate_wowlan_notif_size(mld, len,
|
||||
sizeof(*notif),
|
||||
notif->num_mlo_link_keys,
|
||||
6))
|
||||
|
||||
if (!iwl_mld_validate_wowlan_notif_size(mld, len, notif, 6))
|
||||
return true;
|
||||
} else {
|
||||
/* smaller versions are not supported */
|
||||
|
|
@ -686,7 +729,7 @@ iwl_mld_handle_wake_pkt_notif(struct iwl_mld *mld,
|
|||
{
|
||||
const struct iwl_wowlan_wake_pkt_notif *notif = (void *)pkt->data;
|
||||
u32 actual_size, len = iwl_rx_packet_payload_len(pkt);
|
||||
u32 expected_size = le32_to_cpu(notif->wake_packet_length);
|
||||
u32 expected_size;
|
||||
|
||||
if (IWL_FW_CHECK(mld, len < sizeof(*notif),
|
||||
"Invalid WoWLAN wake packet notification (expected size=%zu got=%u)\n",
|
||||
|
|
@ -699,6 +742,7 @@ iwl_mld_handle_wake_pkt_notif(struct iwl_mld *mld,
|
|||
wowlan_status->wakeup_reasons))
|
||||
return true;
|
||||
|
||||
expected_size = le32_to_cpu(notif->wake_packet_length);
|
||||
actual_size = len - offsetof(struct iwl_wowlan_wake_pkt_notif,
|
||||
wake_packet);
|
||||
|
||||
|
|
@ -723,11 +767,17 @@ iwl_mld_set_wake_packet(struct iwl_mld *mld,
|
|||
struct cfg80211_wowlan_wakeup *wakeup,
|
||||
struct sk_buff **_pkt)
|
||||
{
|
||||
int pkt_bufsize = wowlan_status->wake_packet_bufsize;
|
||||
int expected_pktlen = wowlan_status->wake_packet_length;
|
||||
u32 pkt_bufsize = wowlan_status->wake_packet_bufsize;
|
||||
u32 expected_pktlen = wowlan_status->wake_packet_length;
|
||||
const u8 *pktdata = wowlan_status->wake_packet;
|
||||
const struct ieee80211_hdr *hdr = (const void *)pktdata;
|
||||
int truncated = expected_pktlen - pkt_bufsize;
|
||||
u32 truncated;
|
||||
|
||||
if (IWL_FW_CHECK(mld, pkt_bufsize < sizeof(*hdr),
|
||||
"pkt_bufsize is too short: %u\n", pkt_bufsize))
|
||||
return;
|
||||
|
||||
truncated = expected_pktlen - pkt_bufsize;
|
||||
|
||||
if (ieee80211_is_data(hdr->frame_control)) {
|
||||
int hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
|
|
@ -738,9 +788,18 @@ iwl_mld_set_wake_packet(struct iwl_mld *mld,
|
|||
if (!pkt)
|
||||
return;
|
||||
|
||||
skb_put_data(pkt, pktdata, hdrlen);
|
||||
pktdata += hdrlen;
|
||||
pkt_bufsize -= hdrlen;
|
||||
if (ieee80211_has_protected(hdr->frame_control)) {
|
||||
struct iwl_mld_wake_pkt_iter_data iter_data = {
|
||||
.multicast =
|
||||
is_multicast_ether_addr(hdr->addr1),
|
||||
};
|
||||
|
||||
ieee80211_iter_keys(mld->hw, vif,
|
||||
iwl_mld_wake_pkt_key_iter,
|
||||
&iter_data);
|
||||
ivlen = iter_data.ivlen;
|
||||
icvlen += iter_data.icvlen;
|
||||
}
|
||||
|
||||
/* if truncated, FCS/ICV is (partially) gone */
|
||||
if (truncated >= icvlen) {
|
||||
|
|
@ -751,6 +810,13 @@ iwl_mld_set_wake_packet(struct iwl_mld *mld,
|
|||
truncated = 0;
|
||||
}
|
||||
|
||||
if (IWL_FW_CHECK(mld, pkt_bufsize <= hdrlen + ivlen + icvlen,
|
||||
"pkt_bufsize is too small %u\n", pkt_bufsize))
|
||||
return;
|
||||
|
||||
skb_put_data(pkt, pktdata, hdrlen);
|
||||
pktdata += hdrlen;
|
||||
pkt_bufsize -= hdrlen;
|
||||
pkt_bufsize -= ivlen + icvlen;
|
||||
pktdata += ivlen;
|
||||
|
||||
|
|
@ -772,6 +838,11 @@ iwl_mld_set_wake_packet(struct iwl_mld *mld,
|
|||
fcslen -= truncated;
|
||||
truncated = 0;
|
||||
}
|
||||
|
||||
if (IWL_FW_CHECK(mld, pkt_bufsize <= fcslen,
|
||||
"pkt_bufsize is too small %u\n", pkt_bufsize))
|
||||
return;
|
||||
|
||||
pkt_bufsize -= fcslen;
|
||||
wakeup->packet = wowlan_status->wake_packet;
|
||||
wakeup->packet_present_len = pkt_bufsize;
|
||||
|
|
@ -1449,8 +1520,16 @@ static bool iwl_mld_handle_d3_notif(struct iwl_notif_wait_data *notif_wait,
|
|||
}
|
||||
case WIDE_ID(PROT_OFFLOAD_GROUP, D3_END_NOTIFICATION): {
|
||||
struct iwl_d3_end_notif *notif = (void *)pkt->data;
|
||||
u32 len = iwl_rx_packet_payload_len(pkt);
|
||||
|
||||
if (IWL_FW_CHECK(mld, len < sizeof(*notif),
|
||||
"Invalid D3_END notification (expected=%zu got=%u)\n",
|
||||
sizeof(*notif), len)) {
|
||||
resume_data->notif_handling_err = true;
|
||||
} else {
|
||||
resume_data->d3_end_flags = le32_to_cpu(notif->flags);
|
||||
}
|
||||
|
||||
resume_data->d3_end_flags = le32_to_cpu(notif->flags);
|
||||
resume_data->notifs_received |= IWL_D3_NOTIF_D3_END_NOTIF;
|
||||
break;
|
||||
}
|
||||
|
|
@ -2140,6 +2219,9 @@ int iwl_mld_wowlan_resume(struct iwl_mld *mld)
|
|||
ret = iwl_mld_wait_d3_notif(mld, &resume_data, true);
|
||||
if (ret) {
|
||||
IWL_ERR(mld, "Couldn't get the d3 notifs %d\n", ret);
|
||||
|
||||
if (bss_vif->cfg.assoc)
|
||||
ieee80211_resume_disconnect(bss_vif);
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -459,3 +459,24 @@ void iwl_mld_ftm_restart_cleanup(struct iwl_mld *mld)
|
|||
mld->ftm_initiator.req, GFP_KERNEL);
|
||||
iwl_mld_ftm_reset(mld);
|
||||
}
|
||||
|
||||
void iwl_mld_ftm_abort(struct iwl_mld *mld, struct cfg80211_pmsr_request *req)
|
||||
{
|
||||
struct iwl_tof_range_abort_cmd cmd = {
|
||||
.request_id = req->cookie,
|
||||
};
|
||||
|
||||
lockdep_assert_wiphy(mld->wiphy);
|
||||
|
||||
if (req != mld->ftm_initiator.req)
|
||||
return;
|
||||
|
||||
if (iwl_mld_send_cmd_pdu(mld, WIDE_ID(LOCATION_GROUP,
|
||||
TOF_RANGE_ABORT_CMD),
|
||||
&cmd))
|
||||
IWL_ERR(mld, "failed to abort FTM process\n");
|
||||
|
||||
iwl_mld_cancel_notifications_of_object(mld, IWL_MLD_OBJECT_TYPE_FTM_REQ,
|
||||
mld->ftm_initiator.req->cookie);
|
||||
iwl_mld_ftm_reset(mld);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,5 +25,6 @@ int iwl_mld_ftm_start(struct iwl_mld *mld, struct ieee80211_vif *vif,
|
|||
void iwl_mld_handle_ftm_resp_notif(struct iwl_mld *mld,
|
||||
struct iwl_rx_packet *pkt);
|
||||
void iwl_mld_ftm_restart_cleanup(struct iwl_mld *mld);
|
||||
void iwl_mld_ftm_abort(struct iwl_mld *mld, struct cfg80211_pmsr_request *req);
|
||||
|
||||
#endif /* __iwl_mld_ftm_initiator_h__ */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2024-2025 Intel Corporation
|
||||
* Copyright (C) 2024-2026 Intel Corporation
|
||||
*/
|
||||
#ifndef __iwl_mld_hcmd_h__
|
||||
#define __iwl_mld_hcmd_h__
|
||||
|
|
@ -42,7 +42,12 @@ __iwl_mld_send_cmd_with_flags_pdu(struct iwl_mld *mld, u32 id,
|
|||
|
||||
#define _iwl_mld_send_cmd_with_flags_pdu(mld, id, flags, data, len, \
|
||||
ignored...) \
|
||||
__iwl_mld_send_cmd_with_flags_pdu(mld, id, flags, data, len)
|
||||
({ \
|
||||
BUILD_BUG_ON(__builtin_constant_p(len) && \
|
||||
(u16)(len) > IWL_MAX_CMD_PAYLOAD_SIZE); \
|
||||
__iwl_mld_send_cmd_with_flags_pdu(mld, id, flags, \
|
||||
data, len); \
|
||||
})
|
||||
#define iwl_mld_send_cmd_with_flags_pdu(mld, id, flags, data, len...) \
|
||||
_iwl_mld_send_cmd_with_flags_pdu(mld, id, flags, data, ##len, \
|
||||
sizeof(*(data)))
|
||||
|
|
|
|||
|
|
@ -543,8 +543,7 @@ iwl_mld_mac80211_tx(struct ieee80211_hw *hw,
|
|||
iwl_mld_tx_skb(mld, skb, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
iwl_mld_restart_cleanup(struct iwl_mld *mld)
|
||||
void iwl_mld_restart_cleanup(struct iwl_mld *mld)
|
||||
{
|
||||
iwl_cleanup_mld(mld);
|
||||
|
||||
|
|
@ -1281,11 +1280,13 @@ void iwl_mld_unassign_vif_chanctx(struct ieee80211_hw *hw,
|
|||
iwl_mld_tlc_update_phy(mld, vif, link);
|
||||
|
||||
/* in the non-MLO case, remove/re-add the link to clean up FW state.
|
||||
* In MLO, it'll be done in drv_change_vif_link
|
||||
* In MLO, it'll be done in drv_change_vif_link.
|
||||
* Do not do so during restart or in case the device is dead.
|
||||
*/
|
||||
if (!ieee80211_vif_is_mld(vif) && !mld_vif->ap_sta &&
|
||||
!WARN_ON_ONCE(vif->cfg.assoc) &&
|
||||
vif->type != NL80211_IFTYPE_AP && !mld->fw_status.in_hw_restart) {
|
||||
vif->type != NL80211_IFTYPE_AP && !mld->fw_status.in_hw_restart &&
|
||||
!iwl_trans_is_dead(mld->trans)) {
|
||||
iwl_mld_remove_link(mld, link);
|
||||
iwl_mld_add_link(mld, link);
|
||||
}
|
||||
|
|
@ -2853,6 +2854,15 @@ static int iwl_mld_start_pmsr(struct ieee80211_hw *hw,
|
|||
return iwl_mld_ftm_start(mld, vif, request);
|
||||
}
|
||||
|
||||
static void iwl_mld_abort_pmsr(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct cfg80211_pmsr_request *request)
|
||||
{
|
||||
struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);
|
||||
|
||||
iwl_mld_ftm_abort(mld, request);
|
||||
}
|
||||
|
||||
static enum ieee80211_neg_ttlm_res
|
||||
iwl_mld_can_neg_ttlm(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_neg_ttlm *neg_ttlm)
|
||||
|
|
@ -2974,6 +2984,7 @@ const struct ieee80211_ops iwl_mld_hw_ops = {
|
|||
.prep_add_interface = iwl_mld_prep_add_interface,
|
||||
.set_hw_timestamp = iwl_mld_set_hw_timestamp,
|
||||
.start_pmsr = iwl_mld_start_pmsr,
|
||||
.abort_pmsr = iwl_mld_abort_pmsr,
|
||||
.can_neg_ttlm = iwl_mld_can_neg_ttlm,
|
||||
.start_nan = iwl_mld_start_nan,
|
||||
.stop_nan = iwl_mld_stop_nan,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2024 Intel Corporation
|
||||
* Copyright (C) 2026 Intel Corporation
|
||||
*/
|
||||
#ifndef __iwl_mld_mac80211_h__
|
||||
#define __iwl_mld_mac80211_h__
|
||||
|
|
@ -9,5 +10,6 @@
|
|||
|
||||
int iwl_mld_register_hw(struct iwl_mld *mld);
|
||||
void iwl_mld_recalc_multicast_filter(struct iwl_mld *mld);
|
||||
void iwl_mld_restart_cleanup(struct iwl_mld *mld);
|
||||
|
||||
#endif /* __iwl_mld_mac80211_h__ */
|
||||
|
|
|
|||
|
|
@ -95,6 +95,8 @@ iwl_mld_get_regdomain(struct iwl_mld *mld,
|
|||
struct iwl_mcc_update_resp_v8 *resp;
|
||||
u8 resp_ver = iwl_fw_lookup_notif_ver(mld->fw, IWL_ALWAYS_LONG_GROUP,
|
||||
MCC_UPDATE_CMD, 0);
|
||||
enum iwl_puncturing_status puncturing_status;
|
||||
u16 mcc;
|
||||
|
||||
IWL_DEBUG_LAR(mld, "Getting regdomain data for %s from FW\n", alpha2);
|
||||
|
||||
|
|
@ -116,12 +118,13 @@ iwl_mld_get_regdomain(struct iwl_mld *mld,
|
|||
}
|
||||
IWL_DEBUG_LAR(mld, "MCC update response version: %d\n", resp_ver);
|
||||
|
||||
mcc = le16_to_cpu(resp->mcc);
|
||||
regd = iwl_parse_nvm_mcc_info(mld->trans,
|
||||
__le32_to_cpu(resp->n_channels),
|
||||
resp->channels,
|
||||
__le16_to_cpu(resp->mcc),
|
||||
resp->channels, mcc,
|
||||
__le16_to_cpu(resp->geo_info),
|
||||
le32_to_cpu(resp->cap), resp_ver);
|
||||
le32_to_cpu(resp->cap), resp_ver,
|
||||
&puncturing_status);
|
||||
|
||||
if (IS_ERR(regd)) {
|
||||
IWL_DEBUG_LAR(mld, "Could not get parse update from FW %ld\n",
|
||||
|
|
@ -135,18 +138,25 @@ iwl_mld_get_regdomain(struct iwl_mld *mld,
|
|||
|
||||
mld->mcc_src = resp->source_id;
|
||||
|
||||
if (puncturing_status == IWL_PUNCTURING_STATUS_ENABLED)
|
||||
__clear_bit(IEEE80211_HW_DISALLOW_PUNCTURING,
|
||||
mld->hw->flags);
|
||||
else if (puncturing_status == IWL_PUNCTURING_STATUS_DISABLED)
|
||||
ieee80211_hw_set(mld->hw, DISALLOW_PUNCTURING);
|
||||
|
||||
if (resp_ver >= 10)
|
||||
goto out;
|
||||
|
||||
/* 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,
|
||||
le16_to_cpu(resp->mcc)))
|
||||
if (!iwl_puncturing_is_allowed_in_bios(mld->fwrt.bios_puncturing,
|
||||
mcc))
|
||||
ieee80211_hw_set(mld->hw, DISALLOW_PUNCTURING);
|
||||
else
|
||||
__clear_bit(IEEE80211_HW_DISALLOW_PUNCTURING,
|
||||
mld->hw->flags);
|
||||
} else if (CSR_HW_RFID_TYPE(mld->trans->info.hw_rf_id) ==
|
||||
IWL_CFG_RF_TYPE_WH) {
|
||||
u16 mcc = le16_to_cpu(resp->mcc);
|
||||
|
||||
IWL_CFG_RF_TYPE_WH) {
|
||||
if (mcc == IWL_MCC_US || mcc == IWL_MCC_CANADA)
|
||||
ieee80211_hw_set(mld->hw, DISALLOW_PUNCTURING);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -212,6 +212,7 @@ static const struct iwl_hcmd_names iwl_mld_reg_and_nvm_names[] = {
|
|||
HCMD_NAME(TAS_CONFIG),
|
||||
HCMD_NAME(SAR_OFFSET_MAPPING_TABLE_CMD),
|
||||
HCMD_NAME(MCC_ALLOWED_AP_TYPE_CMD),
|
||||
HCMD_NAME(PNVM_INIT_COMPLETE_NTFY),
|
||||
};
|
||||
|
||||
/* Please keep this array *SORTED* by hex value.
|
||||
|
|
@ -418,8 +419,6 @@ iwl_op_mode_mld_start(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg,
|
|||
iwl_mld_construct_fw_runtime(mld, trans, fw, dbgfs_dir);
|
||||
|
||||
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_mld_hw_set_regulatory(mld);
|
||||
|
||||
|
|
@ -446,6 +445,8 @@ iwl_op_mode_mld_start(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg,
|
|||
}
|
||||
|
||||
if (ret) {
|
||||
/* wiphy memory is about to be freed, we should cancel any pending work */
|
||||
wiphy_work_cancel(mld->wiphy, &mld->async_handlers_wk);
|
||||
wiphy_unlock(mld->wiphy);
|
||||
rtnl_unlock();
|
||||
goto err;
|
||||
|
|
@ -511,6 +512,7 @@ iwl_op_mode_mld_stop(struct iwl_op_mode *op_mode)
|
|||
iwl_mld_thermal_exit(mld);
|
||||
|
||||
wiphy_lock(mld->wiphy);
|
||||
wiphy_work_cancel(mld->wiphy, &mld->async_handlers_wk);
|
||||
iwl_mld_low_latency_stop(mld);
|
||||
iwl_mld_deinit_time_sync(mld);
|
||||
wiphy_unlock(mld->wiphy);
|
||||
|
|
@ -745,6 +747,7 @@ static void iwl_mld_device_powered_off(struct iwl_op_mode *op_mode)
|
|||
|
||||
wiphy_lock(mld->wiphy);
|
||||
iwl_mld_stop_fw(mld);
|
||||
iwl_mld_restart_cleanup(mld);
|
||||
mld->fw_status.in_d3 = false;
|
||||
wiphy_unlock(mld->wiphy);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -298,7 +298,8 @@ CMD_VERSIONS(channel_survey_notif,
|
|||
CMD_VERSIONS(mfuart_notif,
|
||||
CMD_VER_ENTRY(2, iwl_mfuart_load_notif))
|
||||
CMD_VERSIONS(update_mcc,
|
||||
CMD_VER_ENTRY(1, iwl_mcc_chub_notif))
|
||||
CMD_VER_ENTRY(1, iwl_mcc_chub_notif)
|
||||
CMD_VER_ENTRY(2, iwl_mcc_chub_notif))
|
||||
CMD_VERSIONS(session_prot_notif,
|
||||
CMD_VER_ENTRY(3, iwl_session_prot_notif))
|
||||
CMD_VERSIONS(missed_beacon_notif,
|
||||
|
|
@ -517,7 +518,7 @@ iwl_mld_notif_is_valid(struct iwl_mld *mld, struct iwl_rx_packet *pkt,
|
|||
handler->cmd_id, notif_ver,
|
||||
handler->sizes[handler->n_sizes - 1].ver);
|
||||
|
||||
return size < handler->sizes[handler->n_sizes - 1].size;
|
||||
return false;
|
||||
}
|
||||
|
||||
struct iwl_async_handler_entry {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,26 @@
|
|||
#include "mld.h"
|
||||
#include "hcmd.h"
|
||||
|
||||
static ssize_t iwl_mld_get_lari_config_cmd_size(u8 cmd_ver)
|
||||
{
|
||||
switch (cmd_ver) {
|
||||
case 15:
|
||||
return sizeof(struct iwl_lari_config_change_cmd);
|
||||
case 14:
|
||||
return offsetof(struct iwl_lari_config_change_cmd,
|
||||
oem_supported_dsm_bitmap);
|
||||
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;
|
||||
|
|
@ -67,6 +87,9 @@ void iwl_mld_get_bios_tables(struct iwl_mld *mld)
|
|||
iwl_uefi_get_uneb_table(mld->trans, &mld->fwrt);
|
||||
|
||||
iwl_bios_get_phy_filters(&mld->fwrt);
|
||||
|
||||
iwl_uefi_get_sgom_table(mld->trans, &mld->fwrt);
|
||||
iwl_uefi_get_puncturing(&mld->fwrt);
|
||||
}
|
||||
|
||||
static int iwl_mld_geo_sar_init(struct iwl_mld *mld)
|
||||
|
|
@ -325,11 +348,23 @@ void iwl_mld_configure_lari(struct iwl_mld *mld)
|
|||
struct iwl_lari_config_change_cmd cmd = {
|
||||
.config_bitmap = iwl_mld_get_lari_config_bitmap(fwrt),
|
||||
};
|
||||
bool has_raw_dsm_capa = fw_has_capa(&fwrt->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE);
|
||||
u8 cmd_ver = iwl_fw_lookup_cmd_ver(mld->fw,
|
||||
WIDE_ID(REGULATORY_AND_NVM_GROUP,
|
||||
LARI_CONFIG_CHANGE), 12);
|
||||
/*
|
||||
* For LARI_CONFIG_CHANGE command version 13 and above, firmware accepts
|
||||
* raw DSM values by default and this TLV is no longer needed.
|
||||
*/
|
||||
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)
|
||||
|
|
@ -371,8 +406,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)
|
||||
|
|
@ -386,8 +424,21 @@ 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);
|
||||
|
||||
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_QUERY, &value);
|
||||
if (!ret)
|
||||
cmd.oem_supported_dsm_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 &&
|
||||
|
|
@ -396,7 +447,9 @@ 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 &&
|
||||
!cmd.oem_supported_dsm_bitmap)
|
||||
return;
|
||||
|
||||
cmd.bios_hdr.table_source = fwrt->dsm_source;
|
||||
|
|
@ -414,6 +467,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),
|
||||
|
|
@ -427,22 +483,16 @@ 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));
|
||||
IWL_DEBUG_RADIO(mld,
|
||||
"sending LARI_CONFIG_CHANGE, oem_supported_dsm_bitmap=0x%x\n",
|
||||
le32_to_cpu(cmd.oem_supported_dsm_bitmap));
|
||||
|
||||
if (iwl_fw_lookup_cmd_ver(mld->fw,
|
||||
WIDE_ID(REGULATORY_AND_NVM_GROUP,
|
||||
LARI_CONFIG_CHANGE), 12) == 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",
|
||||
|
|
@ -488,6 +538,8 @@ void iwl_mld_init_ap_type_tables(struct iwl_mld *mld)
|
|||
if (ret)
|
||||
IWL_ERR(mld, "failed to send MCC_ALLOWED_AP_TYPE_CMD (%d)\n",
|
||||
ret);
|
||||
else
|
||||
IWL_DEBUG_RADIO(mld, "MCC_ALLOWED_AP_TYPE_CMD sent to FW\n");
|
||||
}
|
||||
|
||||
void iwl_mld_init_tas(struct iwl_mld *mld)
|
||||
|
|
|
|||
|
|
@ -1681,7 +1681,8 @@ iwl_mld_scan_send_abort_cmd_status(struct iwl_mld *mld, int uid, u32 *status)
|
|||
static int
|
||||
iwl_mld_scan_abort(struct iwl_mld *mld, int type, int uid, bool *wait)
|
||||
{
|
||||
enum iwl_umac_scan_abort_status status;
|
||||
enum iwl_umac_scan_abort_status status =
|
||||
IWL_UMAC_SCAN_ABORT_STATUS_NOT_FOUND;
|
||||
int ret;
|
||||
|
||||
*wait = true;
|
||||
|
|
|
|||
|
|
@ -355,10 +355,9 @@ static void iwl_mld_fill_pkt_ext(struct iwl_mld *mld,
|
|||
|
||||
for (int i = 0; i < MAX_HE_SUPP_NSS; i++) {
|
||||
for (int bw = 0;
|
||||
bw < ARRAY_SIZE(*pkt_ext->pkt_ext_qam_th[i]);
|
||||
bw < ARRAY_SIZE(pkt_ext->pkt_ext_qam_th[i]);
|
||||
bw++) {
|
||||
u8 *qam_th =
|
||||
&pkt_ext->pkt_ext_qam_th[i][bw][0];
|
||||
u8 *qam_th = pkt_ext->pkt_ext_qam_th[i][bw];
|
||||
|
||||
IWL_DEBUG_HT(mld,
|
||||
"PPE table: nss[%d] bw[%d] PPET8 = %d, PPET16 = %d\n",
|
||||
|
|
|
|||
|
|
@ -1517,12 +1517,48 @@ static int iwl_mvm_fill_lari_config(struct iwl_fw_runtime *fwrt,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void iwl_mvm_send_lari_cfg_extension(struct iwl_mvm *mvm)
|
||||
{
|
||||
struct iwl_fw_runtime *fwrt = &mvm->fwrt;
|
||||
struct iwl_lari_config_extension_cmd cmd = {};
|
||||
u32 cmd_id = WIDE_ID(REGULATORY_AND_NVM_GROUP,
|
||||
LARI_CONFIG_EXTENSION);
|
||||
u32 value;
|
||||
int ret;
|
||||
|
||||
if (iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, 0) < 1)
|
||||
return;
|
||||
|
||||
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_REGULATORY_CONFIG, &value);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
cmd.dsm_table_hdr.table_source = fwrt->dsm_source;
|
||||
cmd.dsm_table_hdr.table_revision = fwrt->dsm_revision;
|
||||
cmd.oem_uhb_allow_extension_bitmap = cpu_to_le32(value);
|
||||
|
||||
IWL_DEBUG_RADIO(mvm,
|
||||
"sending LARI_CONFIG_EXTENSION, oem_uhb_allow_extension_bitmap=0x%x\n",
|
||||
le32_to_cpu(cmd.oem_uhb_allow_extension_bitmap));
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(cmd), &cmd);
|
||||
if (ret < 0)
|
||||
IWL_DEBUG_RADIO(mvm,
|
||||
"Failed to send LARI_CONFIG_EXTENSION (%d)\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm)
|
||||
{
|
||||
struct iwl_lari_config_change_cmd cmd;
|
||||
size_t cmd_size;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* LARI_CONFIG_CHANGE triggers a profile update, so send
|
||||
* LARI_CONFIG_EXTENSION first to make sure its data is applied
|
||||
* in the same update.
|
||||
*/
|
||||
iwl_mvm_send_lari_cfg_extension(mvm);
|
||||
ret = iwl_mvm_fill_lari_config(&mvm->fwrt, &cmd, &cmd_size);
|
||||
if (!ret) {
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm,
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ struct ieee80211_regdomain *iwl_mvm_get_regdomain(struct wiphy *wiphy,
|
|||
resp->channels,
|
||||
__le16_to_cpu(resp->mcc),
|
||||
__le16_to_cpu(resp->geo_info),
|
||||
le32_to_cpu(resp->cap), resp_ver);
|
||||
le32_to_cpu(resp->cap), resp_ver, NULL);
|
||||
/* Store the return source id */
|
||||
src_id = resp->source_id;
|
||||
if (IS_ERR_OR_NULL(regd)) {
|
||||
|
|
@ -1127,7 +1127,7 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
|
|||
RCU_INIT_POINTER(mvmvif->deflink.probe_resp_data, NULL);
|
||||
}
|
||||
|
||||
static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
|
||||
void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
|
||||
{
|
||||
iwl_mvm_stop_device(mvm);
|
||||
|
||||
|
|
@ -2350,10 +2350,9 @@ int iwl_mvm_set_sta_pkt_ext(struct iwl_mvm *mvm,
|
|||
int bw;
|
||||
|
||||
for (bw = 0;
|
||||
bw < ARRAY_SIZE(*pkt_ext->pkt_ext_qam_th[i]);
|
||||
bw < ARRAY_SIZE(pkt_ext->pkt_ext_qam_th[i]);
|
||||
bw++) {
|
||||
u8 *qam_th =
|
||||
&pkt_ext->pkt_ext_qam_th[i][bw][0];
|
||||
u8 *qam_th = pkt_ext->pkt_ext_qam_th[i][bw];
|
||||
|
||||
IWL_DEBUG_HT(mvm,
|
||||
"PPE table: nss[%d] bw[%d] PPET8 = %d, PPET16 = %d\n",
|
||||
|
|
|
|||
|
|
@ -1657,6 +1657,7 @@ void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags,
|
|||
u8 iwl_mvm_rate_idx_to_fw_idx(const struct iwl_fw *fw, int rate_idx);
|
||||
u8 iwl_mvm_mac80211_ac_to_ucode_ac(enum ieee80211_ac_numbers ac);
|
||||
bool iwl_mvm_is_nic_ack_enabled(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
||||
void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm);
|
||||
|
||||
static inline void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
|
||||
{
|
||||
|
|
@ -1672,14 +1673,24 @@ u32 iwl_mvm_get_systime(struct iwl_mvm *mvm);
|
|||
/* Tx / Host Commands */
|
||||
int iwl_mvm_send_cmd(struct iwl_mvm *mvm,
|
||||
struct iwl_host_cmd *cmd);
|
||||
int iwl_mvm_send_cmd_pdu(struct iwl_mvm *mvm, u32 id,
|
||||
u32 flags, u16 len, const void *data);
|
||||
int _iwl_mvm_send_cmd_pdu(struct iwl_mvm *mvm, u32 id,
|
||||
u32 flags, u16 len, const void *data);
|
||||
#define iwl_mvm_send_cmd_pdu(mvm, id, flags, len, data) ({ \
|
||||
BUILD_BUG_ON(__builtin_constant_p(len) && \
|
||||
(u16)(len) > IWL_MAX_CMD_PAYLOAD_SIZE); \
|
||||
_iwl_mvm_send_cmd_pdu(mvm, id, flags, len, data); \
|
||||
})
|
||||
int iwl_mvm_send_cmd_status(struct iwl_mvm *mvm,
|
||||
struct iwl_host_cmd *cmd,
|
||||
u32 *status);
|
||||
int iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u32 id,
|
||||
u16 len, const void *data,
|
||||
u32 *status);
|
||||
int _iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u32 id,
|
||||
u16 len, const void *data,
|
||||
u32 *status);
|
||||
#define iwl_mvm_send_cmd_pdu_status(mvm, id, len, data, status) ({ \
|
||||
BUILD_BUG_ON(__builtin_constant_p(len) && \
|
||||
(u16)(len) > IWL_MAX_CMD_PAYLOAD_SIZE); \
|
||||
_iwl_mvm_send_cmd_pdu_status(mvm, id, len, data, status); \
|
||||
})
|
||||
int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
struct ieee80211_sta *sta);
|
||||
int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb);
|
||||
|
|
@ -2392,14 +2403,12 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
|
|||
bool sync,
|
||||
const void *data, u32 size);
|
||||
struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm);
|
||||
struct ieee80211_vif *iwl_mvm_get_vif_by_macid(struct iwl_mvm *mvm, u32 macid);
|
||||
bool iwl_mvm_is_vif_assoc(struct iwl_mvm *mvm);
|
||||
|
||||
#define MVM_TCM_PERIOD_MSEC 500
|
||||
#define MVM_TCM_PERIOD (HZ * MVM_TCM_PERIOD_MSEC / 1000)
|
||||
#define MVM_LL_PERIOD (10 * HZ)
|
||||
void iwl_mvm_tcm_work(struct work_struct *work);
|
||||
void iwl_mvm_recalc_tcm(struct iwl_mvm *mvm);
|
||||
void iwl_mvm_pause_tcm(struct iwl_mvm *mvm, bool with_cancel);
|
||||
void iwl_mvm_resume_tcm(struct iwl_mvm *mvm);
|
||||
void iwl_mvm_tcm_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
||||
|
|
|
|||
|
|
@ -155,8 +155,8 @@ static void iwl_mvm_rx_monitor_notif(struct iwl_mvm *mvm,
|
|||
if (notif->type != cpu_to_le32(IWL_DP_MON_NOTIF_TYPE_EXT_CCA))
|
||||
return;
|
||||
|
||||
/* FIXME: should fetch the link and not the vif */
|
||||
vif = iwl_mvm_get_vif_by_macid(mvm, notif->link_id);
|
||||
/* mac_id = link_id since we don't support MLO */
|
||||
vif = iwl_mvm_rcu_dereference_vif_id(mvm, notif->link_id, false);
|
||||
if (!vif || vif->type != NL80211_IFTYPE_STATION)
|
||||
return;
|
||||
|
||||
|
|
@ -707,6 +707,7 @@ static const struct iwl_hcmd_names iwl_mvm_regulatory_and_nvm_names[] = {
|
|||
HCMD_NAME(NVM_ACCESS_COMPLETE),
|
||||
HCMD_NAME(NVM_GET_INFO),
|
||||
HCMD_NAME(TAS_CONFIG),
|
||||
HCMD_NAME(LARI_CONFIG_EXTENSION),
|
||||
};
|
||||
|
||||
/* Please keep this array *SORTED* by hex value.
|
||||
|
|
@ -954,7 +955,7 @@ static void iwl_mvm_frob_txf_key_iter(struct ieee80211_hw *hw,
|
|||
}
|
||||
match++;
|
||||
if (match == keylen) {
|
||||
memset(txf->buf + i - keylen, 0xAA, keylen);
|
||||
memset(txf->buf + i + 1 - keylen, 0xAA, keylen);
|
||||
match = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1535,6 +1536,7 @@ void iwl_mvm_stop_device(struct iwl_mvm *mvm)
|
|||
iwl_fw_cancel_timestamp(&mvm->fwrt);
|
||||
|
||||
clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status);
|
||||
mvm->sf_state = SF_UNINIT;
|
||||
|
||||
iwl_mvm_pause_tcm(mvm, false);
|
||||
|
||||
|
|
@ -2090,7 +2092,7 @@ static void iwl_op_mode_mvm_device_powered_off(struct iwl_op_mode *op_mode)
|
|||
|
||||
mutex_lock(&mvm->mutex);
|
||||
clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);
|
||||
iwl_mvm_stop_device(mvm);
|
||||
iwl_mvm_restart_cleanup(mvm);
|
||||
mvm->fast_resume = false;
|
||||
mutex_unlock(&mvm->mutex);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
* Copyright (C) 2026 Intel Corporation
|
||||
*/
|
||||
#ifndef __TIME_SYNC_H__
|
||||
#define __TIME_SYNC_H__
|
||||
|
|
@ -19,6 +20,9 @@ int iwl_mvm_time_sync_config(struct iwl_mvm *mvm, const u8 *addr,
|
|||
static inline
|
||||
bool iwl_mvm_time_sync_frame(struct iwl_mvm *mvm, struct sk_buff *skb, u8 *addr)
|
||||
{
|
||||
if (!mvm->time_sync.active)
|
||||
return false;
|
||||
|
||||
if (ether_addr_equal(mvm->time_sync.peer_addr, addr) &&
|
||||
(ieee80211_is_timing_measurement(skb) || ieee80211_is_ftm(skb))) {
|
||||
skb_queue_tail(&mvm->time_sync.frame_list, skb);
|
||||
|
|
|
|||
|
|
@ -73,8 +73,8 @@ int iwl_mvm_send_cmd(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int iwl_mvm_send_cmd_pdu(struct iwl_mvm *mvm, u32 id,
|
||||
u32 flags, u16 len, const void *data)
|
||||
int _iwl_mvm_send_cmd_pdu(struct iwl_mvm *mvm, u32 id,
|
||||
u32 flags, u16 len, const void *data)
|
||||
{
|
||||
struct iwl_host_cmd cmd = {
|
||||
.id = id,
|
||||
|
|
@ -137,8 +137,8 @@ int iwl_mvm_send_cmd_status(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd,
|
|||
/*
|
||||
* We assume that the caller set the status to the sucess value
|
||||
*/
|
||||
int iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u32 id, u16 len,
|
||||
const void *data, u32 *status)
|
||||
int _iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u32 id, u16 len,
|
||||
const void *data, u32 *status)
|
||||
{
|
||||
struct iwl_host_cmd cmd = {
|
||||
.id = id,
|
||||
|
|
@ -689,36 +689,6 @@ struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm)
|
|||
return bss_iter_data.vif;
|
||||
}
|
||||
|
||||
struct iwl_bss_find_iter_data {
|
||||
struct ieee80211_vif *vif;
|
||||
u32 macid;
|
||||
};
|
||||
|
||||
static void iwl_mvm_bss_find_iface_iterator(void *_data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_bss_find_iter_data *data = _data;
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
|
||||
if (mvmvif->id == data->macid)
|
||||
data->vif = vif;
|
||||
}
|
||||
|
||||
struct ieee80211_vif *iwl_mvm_get_vif_by_macid(struct iwl_mvm *mvm, u32 macid)
|
||||
{
|
||||
struct iwl_bss_find_iter_data data = {
|
||||
.macid = macid,
|
||||
};
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
ieee80211_iterate_active_interfaces_atomic(
|
||||
mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mvm_bss_find_iface_iterator, &data);
|
||||
|
||||
return data.vif;
|
||||
}
|
||||
|
||||
struct iwl_sta_iter_data {
|
||||
bool assoc;
|
||||
};
|
||||
|
|
@ -1055,7 +1025,7 @@ static unsigned long iwl_mvm_calc_tcm_stats(struct iwl_mvm *mvm,
|
|||
/*
|
||||
* If the current load isn't low we need to force re-evaluation
|
||||
* in the TCM period, so that we can return to low load if there
|
||||
* was no traffic at all (and thus iwl_mvm_recalc_tcm didn't get
|
||||
* was no traffic at all (and thus iwl_mvm_tcm_work() didn't get
|
||||
* triggered by traffic).
|
||||
*/
|
||||
if (load != IWL_MVM_TRAFFIC_LOW)
|
||||
|
|
@ -1081,8 +1051,11 @@ static unsigned long iwl_mvm_calc_tcm_stats(struct iwl_mvm *mvm,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void iwl_mvm_recalc_tcm(struct iwl_mvm *mvm)
|
||||
void iwl_mvm_tcm_work(struct work_struct *work)
|
||||
{
|
||||
struct delayed_work *delayed_work = to_delayed_work(work);
|
||||
struct iwl_mvm *mvm = container_of(delayed_work, struct iwl_mvm,
|
||||
tcm.work);
|
||||
unsigned long ts = jiffies;
|
||||
bool handle_uapsd =
|
||||
time_after(ts, mvm->tcm.uapsd_nonagg_ts +
|
||||
|
|
@ -1119,15 +1092,6 @@ void iwl_mvm_recalc_tcm(struct iwl_mvm *mvm)
|
|||
iwl_mvm_tcm_results(mvm);
|
||||
}
|
||||
|
||||
void iwl_mvm_tcm_work(struct work_struct *work)
|
||||
{
|
||||
struct delayed_work *delayed_work = to_delayed_work(work);
|
||||
struct iwl_mvm *mvm = container_of(delayed_work, struct iwl_mvm,
|
||||
tcm.work);
|
||||
|
||||
iwl_mvm_recalc_tcm(mvm);
|
||||
}
|
||||
|
||||
void iwl_mvm_pause_tcm(struct iwl_mvm *mvm, bool with_cancel)
|
||||
{
|
||||
spin_lock_bh(&mvm->tcm.lock);
|
||||
|
|
|
|||
|
|
@ -548,6 +548,7 @@ VISIBLE_IF_IWLWIFI_KUNIT const struct pci_device_id iwl_hw_card_ids[] = {
|
|||
{IWL_PCI_DEVICE(0xD340, PCI_ANY_ID, iwl_sc_mac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x6E70, PCI_ANY_ID, iwl_sc_mac_cfg)},
|
||||
{IWL_PCI_DEVICE(0xD240, PCI_ANY_ID, iwl_sc_mac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x9327, PCI_ANY_ID, iwl_sc_mac_cfg)},
|
||||
#endif /* CONFIG_IWLMVM || CONFIG_IWLMLD */
|
||||
|
||||
{0}
|
||||
|
|
|
|||
|
|
@ -773,6 +773,8 @@ int iwl_txq_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb,
|
|||
|
||||
tfd = iwl_txq_gen2_build_tfd(trans, txq, dev_cmd, skb, out_meta);
|
||||
if (!tfd) {
|
||||
txq->entries[idx].skb = NULL;
|
||||
txq->entries[idx].cmd = NULL;
|
||||
spin_unlock(&txq->lock);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2003-2014, 2018-2021, 2023-2025 Intel Corporation
|
||||
* Copyright (C) 2003-2014, 2018-2021, 2023-2026 Intel Corporation
|
||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
|
|
@ -1149,10 +1149,17 @@ bool iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
|
|||
unsigned int wdg_timeout)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
struct iwl_txq *txq = trans_pcie->txqs.txq[txq_id];
|
||||
struct iwl_txq *txq;
|
||||
int fifo = -1;
|
||||
bool scd_bug = false;
|
||||
|
||||
if (WARN_ONCE(txq_id < 0 ||
|
||||
txq_id >= trans->mac_cfg->base->num_of_queues,
|
||||
"queue %d out of range", txq_id))
|
||||
return false;
|
||||
|
||||
txq = trans_pcie->txqs.txq[txq_id];
|
||||
|
||||
if (test_and_set_bit(txq_id, trans_pcie->txqs.queue_used))
|
||||
WARN_ONCE(1, "queue %d already used - expect issues", txq_id);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user