mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
wifi: iwlwifi-next : updates - 2026-06-03
This pull request contains iwlwifi features and cleanups. Notably:
- Bump max core version for BZ/SC/DR to 106.
- Add KUnit tests for link grading, RSSI adjustment, and beacon
handling;
- Drop core101 support and remove TLC config v4/v5 compatibility code.
- Fixes:
Fix PCIe write pointer detection
Fix STEP_URM register address
Remove unneeded WoWLAN warning
reduce NIC wakeups during dump.
Revert MODULE_FIRMWARE relocation change
-----BEGIN PGP SIGNATURE-----
iHUEABYIAB0WIQQM3A3Pv7vbm9vtjWbacY7uyt+OfQUCaiA4nQAKCRDacY7uyt+O
fcECAQC8YSlz1duQiMiuLTQ1WJ55yG8hncvPlgvUwEUHD8E/wgEAgjHPS566XWfU
/H4pc3CEZT+w8LRHhvvJiYWXpmmnvgs=
=+5Cu
-----END PGP SIGNATURE-----
Merge tag 'iwlwifi-next-2026-06-03' of https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
Miri Korenblit says:
====================
wifi: iwlwifi-next : updates - 2026-06-03
This pull request contains iwlwifi features and cleanups. Notably:
- Bump max core version for BZ/SC/DR to 106.
- Add KUnit tests for link grading, RSSI adjustment, and beacon
handling;
- Drop core101 support and remove TLC config v4/v5 compatibility code.
- Fixes:
Fix PCIe write pointer detection
Fix STEP_URM register address
Remove unneeded WoWLAN warning
reduce NIC wakeups during dump.
Revert MODULE_FIRMWARE relocation change
====================
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
commit
a26c2a22e7
|
|
@ -10,10 +10,16 @@
|
|||
#include "fw/api/txq.h"
|
||||
|
||||
/* Highest firmware core release supported */
|
||||
#define IWL_BZ_UCODE_CORE_MAX 105
|
||||
#define IWL_BZ_UCODE_CORE_MAX 106
|
||||
|
||||
/* Lowest firmware core release supported */
|
||||
#define IWL_BZ_UCODE_CORE_MIN 101
|
||||
#define IWL_BZ_UCODE_CORE_MIN 102
|
||||
|
||||
#define IWL_BZ_A_FM_B_FW_PRE "iwlwifi-bz-a0-fm-b0"
|
||||
#define IWL_BZ_A_FM_C_FW_PRE "iwlwifi-bz-a0-fm-c0"
|
||||
#define IWL_BZ_A_FM4_B_FW_PRE "iwlwifi-bz-a0-fm4-b0"
|
||||
#define IWL_GL_B_FM_B_FW_PRE "iwlwifi-gl-b0-fm-b0"
|
||||
#define IWL_GL_C_FM_C_FW_PRE "iwlwifi-gl-c0-fm-c0"
|
||||
|
||||
static const struct iwl_family_base_params iwl_bz_base = {
|
||||
.num_of_queues = 512,
|
||||
|
|
@ -85,3 +91,9 @@ const struct iwl_mac_cfg iwl_gl_mac_cfg = {
|
|||
.xtal_latency = 12000,
|
||||
.low_latency_xtal = true,
|
||||
};
|
||||
|
||||
IWL_CORE_FW(IWL_BZ_A_FM_B_FW_PRE, IWL_BZ_UCODE_CORE_MAX);
|
||||
IWL_CORE_FW(IWL_BZ_A_FM_C_FW_PRE, IWL_BZ_UCODE_CORE_MAX);
|
||||
IWL_CORE_FW(IWL_BZ_A_FM4_B_FW_PRE, IWL_BZ_UCODE_CORE_MAX);
|
||||
IWL_CORE_FW(IWL_GL_B_FM_B_FW_PRE, IWL_BZ_UCODE_CORE_MAX);
|
||||
IWL_CORE_FW(IWL_GL_C_FM_C_FW_PRE, IWL_BZ_UCODE_CORE_MAX);
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@
|
|||
#include "fw/api/txq.h"
|
||||
|
||||
/* Highest firmware core release supported */
|
||||
#define IWL_DR_UCODE_CORE_MAX 105
|
||||
#define IWL_DR_UCODE_CORE_MAX 106
|
||||
|
||||
/* Lowest firmware core release supported */
|
||||
#define IWL_DR_UCODE_CORE_MIN 101
|
||||
#define IWL_DR_UCODE_CORE_MIN 102
|
||||
|
||||
#define IWL_DR_A_PE_A_FW_PRE "iwlwifi-dr-a0-pe-a0"
|
||||
|
||||
|
|
|
|||
|
|
@ -5,12 +5,6 @@
|
|||
*/
|
||||
#include "iwl-config.h"
|
||||
|
||||
#define IWL_BZ_A_FM_B_FW_PRE "iwlwifi-bz-a0-fm-b0"
|
||||
#define IWL_BZ_A_FM_C_FW_PRE "iwlwifi-bz-a0-fm-c0"
|
||||
#define IWL_BZ_A_FM4_B_FW_PRE "iwlwifi-bz-a0-fm4-b0"
|
||||
#define IWL_GL_B_FM_B_FW_PRE "iwlwifi-gl-b0-fm-b0"
|
||||
#define IWL_GL_C_FM_C_FW_PRE "iwlwifi-gl-c0-fm-c0"
|
||||
|
||||
#define IWL_DEVICE_FM \
|
||||
.ht_params = { \
|
||||
.stbc = true, \
|
||||
|
|
@ -54,9 +48,3 @@ const char iwl_be201_name[] = "Intel(R) Wi-Fi 7 BE201 320MHz";
|
|||
const char iwl_be200_name[] = "Intel(R) Wi-Fi 7 BE200 320MHz";
|
||||
const char iwl_be202_name[] = "Intel(R) Wi-Fi 7 BE202 160MHz";
|
||||
const char iwl_be401_name[] = "Intel(R) Wi-Fi 7 BE401 320MHz";
|
||||
|
||||
IWL_CORE_FW(IWL_BZ_A_FM_B_FW_PRE, IWL_BZ_UCODE_CORE_MAX);
|
||||
IWL_CORE_FW(IWL_BZ_A_FM_C_FW_PRE, IWL_BZ_UCODE_CORE_MAX);
|
||||
IWL_CORE_FW(IWL_BZ_A_FM4_B_FW_PRE, IWL_BZ_UCODE_CORE_MAX);
|
||||
IWL_CORE_FW(IWL_GL_B_FM_B_FW_PRE, IWL_BZ_UCODE_CORE_MAX);
|
||||
IWL_CORE_FW(IWL_GL_C_FM_C_FW_PRE, IWL_BZ_UCODE_CORE_MAX);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2015-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018-2025 Intel Corporation
|
||||
* Copyright (C) 2018-2026 Intel Corporation
|
||||
*/
|
||||
#include "iwl-config.h"
|
||||
|
||||
|
|
@ -60,6 +60,7 @@ const char iwl_ax411_killer_1690i_name[] =
|
|||
|
||||
const char iwl_ax210_name[] = "Intel(R) Wi-Fi 6E AX210 160MHz";
|
||||
const char iwl_ax211_name[] = "Intel(R) Wi-Fi 6E AX211 160MHz";
|
||||
const char iwl_ax231_name[] = "Intel(R) Wi-Fi 6 AX231";
|
||||
const char iwl_ax411_name[] = "Intel(R) Wi-Fi 6E AX411 160MHz";
|
||||
|
||||
MODULE_FIRMWARE(IWL_BZ_A_GF_A_MODULE_FIRMWARE(IWL_GF_UCODE_API_MAX));
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@
|
|||
#include "fw/api/txq.h"
|
||||
|
||||
/* Highest firmware core release supported */
|
||||
#define IWL_SC_UCODE_CORE_MAX 105
|
||||
#define IWL_SC_UCODE_CORE_MAX 106
|
||||
|
||||
/* Lowest firmware core release supported */
|
||||
#define IWL_SC_UCODE_CORE_MIN 101
|
||||
#define IWL_SC_UCODE_CORE_MIN 102
|
||||
|
||||
#define IWL_SC_A_FM_B_FW_PRE "iwlwifi-sc-a0-fm-b0"
|
||||
#define IWL_SC_A_FM_C_FW_PRE "iwlwifi-sc-a0-fm-c0"
|
||||
|
|
|
|||
|
|
@ -466,8 +466,8 @@ enum iwl_legacy_cmds {
|
|||
MCC_CHUB_UPDATE_CMD = 0xc9,
|
||||
|
||||
/**
|
||||
* @MARKER_CMD: trace marker command, uses &struct iwl_mvm_marker
|
||||
* with &struct iwl_mvm_marker_rsp
|
||||
* @MARKER_CMD: trace marker command, uses &struct iwl_marker
|
||||
* with &struct iwl_marker_rsp
|
||||
*/
|
||||
MARKER_CMD = 0xcb,
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2012-2014, 2018-2019, 2023-2024 Intel Corporation
|
||||
* Copyright (C) 2026 Intel Corporation
|
||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
|
|
@ -99,14 +100,4 @@ struct iwl_phy_cfg_cmd_v3 {
|
|||
struct iwl_phy_specific_cfg phy_specific_cfg;
|
||||
} __packed; /* PHY_CONFIGURATION_CMD_API_S_VER_3 */
|
||||
|
||||
/*
|
||||
* enum iwl_dc2dc_config_id - flag ids
|
||||
*
|
||||
* Ids of dc2dc configuration flags
|
||||
*/
|
||||
enum iwl_dc2dc_config_id {
|
||||
DCDC_LOW_POWER_MODE_MSK_SET = 0x1, /* not used */
|
||||
DCDC_FREQ_TUNE_SET = 0x2,
|
||||
}; /* MARKER_ID_API_E_VER_1 */
|
||||
|
||||
#endif /* __iwl_fw_api_config_h__ */
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ enum iwl_data_path_subcmd_ids {
|
|||
|
||||
/**
|
||||
* @TLC_MNG_CONFIG_CMD: &struct iwl_tlc_config_cmd_v4 or
|
||||
* &struct iwl_tlc_config_cmd_v5 or &struct iwl_tlc_config_cmd.
|
||||
* &struct iwl_tlc_config_cmd.
|
||||
*/
|
||||
TLC_MNG_CONFIG_CMD = 0xF,
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2005-2014, 2018-2025 Intel Corporation
|
||||
* Copyright (C) 2005-2014, 2018-2026 Intel Corporation
|
||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
|
|
@ -262,20 +262,20 @@ struct iwl_mfu_assert_dump_notif {
|
|||
} __packed; /* MFU_DUMP_ASSERT_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* enum iwl_mvm_marker_id - marker ids
|
||||
* enum iwl_marker_id - marker ids
|
||||
*
|
||||
* The ids for different type of markers to insert into the usniffer logs
|
||||
*
|
||||
* @MARKER_ID_TX_FRAME_LATENCY: TX latency marker
|
||||
* @MARKER_ID_SYNC_CLOCK: sync FW time and systime
|
||||
*/
|
||||
enum iwl_mvm_marker_id {
|
||||
enum iwl_marker_id {
|
||||
MARKER_ID_TX_FRAME_LATENCY = 1,
|
||||
MARKER_ID_SYNC_CLOCK = 2,
|
||||
}; /* MARKER_ID_API_E_VER_2 */
|
||||
|
||||
/**
|
||||
* struct iwl_mvm_marker - mark info into the usniffer logs
|
||||
* struct iwl_marker - mark info into the usniffer logs
|
||||
*
|
||||
* (MARKER_CMD = 0xcb)
|
||||
*
|
||||
|
|
@ -284,12 +284,12 @@ enum iwl_mvm_marker_id {
|
|||
* In the command response the ucode will return the GP2 time.
|
||||
*
|
||||
* @dw_len: The amount of dwords following this byte including this byte.
|
||||
* @marker_id: A unique marker id (iwl_mvm_marker_id).
|
||||
* @marker_id: A unique marker id (iwl_marker_id).
|
||||
* @reserved: reserved.
|
||||
* @timestamp: in milliseconds since 1970-01-01 00:00:00 UTC
|
||||
* @metadata: additional meta data that will be written to the unsiffer log
|
||||
*/
|
||||
struct iwl_mvm_marker {
|
||||
struct iwl_marker {
|
||||
u8 dw_len;
|
||||
u8 marker_id;
|
||||
__le16 reserved;
|
||||
|
|
@ -298,11 +298,11 @@ struct iwl_mvm_marker {
|
|||
} __packed; /* MARKER_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_mvm_marker_rsp - Response to marker cmd
|
||||
* struct iwl_marker_rsp - Response to marker cmd
|
||||
*
|
||||
* @gp2: The gp2 clock value in the FW
|
||||
*/
|
||||
struct iwl_mvm_marker_rsp {
|
||||
struct iwl_marker_rsp {
|
||||
__le32 gp2;
|
||||
} __packed;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2012-2014, 2018-2022, 2024-2025 Intel Corporation
|
||||
* Copyright (C) 2012-2014, 2018-2022, 2024-2026 Intel Corporation
|
||||
* Copyright (C) 2017 Intel Deutschland GmbH
|
||||
*/
|
||||
#ifndef __iwl_fw_api_rs_h__
|
||||
|
|
@ -206,37 +206,6 @@ struct iwl_tlc_config_cmd_v4 {
|
|||
__le16 max_tx_op;
|
||||
} __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_4 */
|
||||
|
||||
/**
|
||||
* struct iwl_tlc_config_cmd_v5 - TLC configuration
|
||||
* @sta_id: station id
|
||||
* @reserved1: reserved
|
||||
* @max_ch_width: max supported channel width from &enum iwl_tlc_mng_cfg_cw
|
||||
* @mode: &enum iwl_tlc_mng_cfg_mode
|
||||
* @chains: bitmask of &enum iwl_tlc_mng_cfg_chains
|
||||
* @sgi_ch_width_supp: bitmap of SGI support per channel width
|
||||
* use BIT(&enum iwl_tlc_mng_cfg_cw)
|
||||
* @flags: bitmask of &enum iwl_tlc_mng_cfg_flags
|
||||
* @non_ht_rates: bitmap of supported legacy rates
|
||||
* @ht_rates: bitmap of &enum iwl_tlc_mng_ht_rates, per <nss, channel-width>
|
||||
* pair (0 - 80mhz width and below, 1 - 160mhz, 2 - 320mhz).
|
||||
* @max_mpdu_len: max MPDU length, in bytes
|
||||
* @max_tx_op: max TXOP in uSecs for all AC (BK, BE, VO, VI),
|
||||
* set zero for no limit.
|
||||
*/
|
||||
struct iwl_tlc_config_cmd_v5 {
|
||||
u8 sta_id;
|
||||
u8 reserved1[3];
|
||||
u8 max_ch_width;
|
||||
u8 mode;
|
||||
u8 chains;
|
||||
u8 sgi_ch_width_supp;
|
||||
__le16 flags;
|
||||
__le16 non_ht_rates;
|
||||
__le32 ht_rates[IWL_TLC_NSS_MAX][IWL_TLC_MCS_PER_BW_NUM_V4];
|
||||
__le16 max_mpdu_len;
|
||||
__le16 max_tx_op;
|
||||
} __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_5 */
|
||||
|
||||
/**
|
||||
* struct iwl_tlc_config_cmd - TLC configuration
|
||||
* @sta_mask: station mask (in NAN we can have multiple logical stations of
|
||||
|
|
@ -889,7 +858,6 @@ struct iwl_lq_cmd {
|
|||
__le32 ss_params;
|
||||
}; /* LINK_QUALITY_CMD_API_S_VER_1 */
|
||||
|
||||
u8 iwl_fw_rate_idx_to_plcp(int idx);
|
||||
const struct iwl_rate_mcs_info *iwl_rate_mcs(int idx);
|
||||
const char *iwl_rs_pretty_ant(u8 ant);
|
||||
const char *iwl_rs_pretty_bw(int bw);
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ static int iwl_dump_ini_prph_mac_iter_common(struct iwl_fw_runtime *fwrt,
|
|||
range->internal_base_addr = cpu_to_le32(addr);
|
||||
range->range_data_size = size;
|
||||
for (i = 0; i < le32_to_cpu(size); i += 4)
|
||||
*val++ = cpu_to_le32(iwl_read_prph(fwrt->trans, addr + i));
|
||||
*val++ = cpu_to_le32(iwl_trans_read_prph(fwrt->trans, addr + i));
|
||||
|
||||
return sizeof(*range) + le32_to_cpu(range->range_data_size);
|
||||
}
|
||||
|
|
@ -158,9 +158,6 @@ static int iwl_dump_ini_prph_phy_iter_common(struct iwl_fw_runtime *fwrt,
|
|||
indirect_wr_addr += le32_to_cpu(offset);
|
||||
indirect_rd_addr += le32_to_cpu(offset);
|
||||
|
||||
if (!iwl_trans_grab_nic_access(fwrt->trans))
|
||||
return -EBUSY;
|
||||
|
||||
dphy_addr = (offset) ? WFPM_LMAC2_PS_CTL_RW : WFPM_LMAC1_PS_CTL_RW;
|
||||
dphy_state = iwl_read_umac_prph_no_grab(fwrt->trans, dphy_addr);
|
||||
|
||||
|
|
@ -194,7 +191,6 @@ static int iwl_dump_ini_prph_phy_iter_common(struct iwl_fw_runtime *fwrt,
|
|||
*val++ = cpu_to_le32(prph_val);
|
||||
}
|
||||
|
||||
iwl_trans_release_nic_access(fwrt->trans);
|
||||
return sizeof(*range) + le32_to_cpu(range->range_data_size);
|
||||
}
|
||||
|
||||
|
|
@ -283,8 +279,8 @@ static int iwl_dump_ini_dev_mem_iter(struct iwl_fw_runtime *fwrt,
|
|||
|
||||
range->internal_base_addr = cpu_to_le32(addr);
|
||||
range->range_data_size = reg->dev_addr.size;
|
||||
iwl_trans_read_mem_bytes(fwrt->trans, addr, range->data,
|
||||
le32_to_cpu(reg->dev_addr.size));
|
||||
iwl_trans_read_mem_bytes_no_grab(fwrt->trans, addr, range->data,
|
||||
le32_to_cpu(reg->dev_addr.size));
|
||||
|
||||
if (reg->sub_type == IWL_FW_INI_REGION_DEVICE_MEMORY_SUBTYPE_HW_SMEM &&
|
||||
fwrt->sanitize_ops && fwrt->sanitize_ops->frob_txf)
|
||||
|
|
@ -368,8 +364,8 @@ static int iwl_dump_ini_mon_smem_iter(struct iwl_fw_runtime *fwrt,
|
|||
|
||||
range->internal_base_addr = cpu_to_le32(addr);
|
||||
range->range_data_size = reg->internal_buffer.size;
|
||||
iwl_trans_read_mem_bytes(fwrt->trans, addr, range->data,
|
||||
le32_to_cpu(reg->internal_buffer.size));
|
||||
iwl_trans_read_mem_bytes_no_grab(fwrt->trans, addr, range->data,
|
||||
le32_to_cpu(reg->internal_buffer.size));
|
||||
|
||||
return sizeof(*range) + le32_to_cpu(range->range_data_size);
|
||||
}
|
||||
|
|
@ -443,9 +439,6 @@ static int iwl_dump_ini_txf_iter(struct iwl_fw_runtime *fwrt,
|
|||
if (!iwl_ini_txf_iter(fwrt, reg_data, idx))
|
||||
return -EIO;
|
||||
|
||||
if (!iwl_trans_grab_nic_access(fwrt->trans))
|
||||
return -EBUSY;
|
||||
|
||||
range->fifo_hdr.fifo_num = cpu_to_le32(iter->fifo);
|
||||
range->fifo_hdr.num_of_registers = cpu_to_le32(registers_num);
|
||||
range->range_data_size = cpu_to_le32(iter->fifo_size + registers_size);
|
||||
|
|
@ -489,8 +482,6 @@ static int iwl_dump_ini_txf_iter(struct iwl_fw_runtime *fwrt,
|
|||
reg_dump, iter->fifo_size);
|
||||
|
||||
out:
|
||||
iwl_trans_release_nic_access(fwrt->trans);
|
||||
|
||||
return sizeof(*range) + le32_to_cpu(range->range_data_size);
|
||||
}
|
||||
|
||||
|
|
@ -511,9 +502,6 @@ iwl_dump_ini_prph_snps_dphyip_iter(struct iwl_fw_runtime *fwrt,
|
|||
range->internal_base_addr = cpu_to_le32(addr);
|
||||
range->range_data_size = reg->dev_addr.size;
|
||||
|
||||
if (!iwl_trans_grab_nic_access(fwrt->trans))
|
||||
return -EBUSY;
|
||||
|
||||
indirect_rd_wr_addr += le32_to_cpu(offset);
|
||||
|
||||
dphy_addr = offset ? WFPM_LMAC2_PS_CTL_RW : WFPM_LMAC1_PS_CTL_RW;
|
||||
|
|
@ -537,7 +525,6 @@ iwl_dump_ini_prph_snps_dphyip_iter(struct iwl_fw_runtime *fwrt,
|
|||
DPHYIP_INDIRECT_RD_SHIFT);
|
||||
}
|
||||
|
||||
iwl_trans_release_nic_access(fwrt->trans);
|
||||
return sizeof(*range) + le32_to_cpu(range->range_data_size);
|
||||
}
|
||||
|
||||
|
|
@ -626,9 +613,6 @@ static int iwl_dump_ini_rxf_iter(struct iwl_fw_runtime *fwrt,
|
|||
if (!rxf_data.size)
|
||||
return -EIO;
|
||||
|
||||
if (!iwl_trans_grab_nic_access(fwrt->trans))
|
||||
return -EBUSY;
|
||||
|
||||
range->fifo_hdr.fifo_num = cpu_to_le32(rxf_data.fifo_num);
|
||||
range->fifo_hdr.num_of_registers = cpu_to_le32(registers_num);
|
||||
range->range_data_size = cpu_to_le32(rxf_data.size + registers_size);
|
||||
|
|
@ -668,8 +652,6 @@ static int iwl_dump_ini_rxf_iter(struct iwl_fw_runtime *fwrt,
|
|||
*data++ = cpu_to_le32(iwl_trans_read_prph(fwrt->trans, addr));
|
||||
|
||||
out:
|
||||
iwl_trans_release_nic_access(fwrt->trans);
|
||||
|
||||
return sizeof(*range) + le32_to_cpu(range->range_data_size);
|
||||
}
|
||||
|
||||
|
|
@ -686,8 +668,8 @@ iwl_dump_ini_err_table_iter(struct iwl_fw_runtime *fwrt,
|
|||
|
||||
range->internal_base_addr = cpu_to_le32(addr);
|
||||
range->range_data_size = err_table->size;
|
||||
iwl_trans_read_mem_bytes(fwrt->trans, addr, range->data,
|
||||
le32_to_cpu(err_table->size));
|
||||
iwl_trans_read_mem_bytes_no_grab(fwrt->trans, addr, range->data,
|
||||
le32_to_cpu(err_table->size));
|
||||
|
||||
return sizeof(*range) + le32_to_cpu(range->range_data_size);
|
||||
}
|
||||
|
|
@ -707,8 +689,8 @@ iwl_dump_ini_special_mem_iter(struct iwl_fw_runtime *fwrt,
|
|||
|
||||
range->internal_base_addr = cpu_to_le32(addr);
|
||||
range->range_data_size = special_mem->size;
|
||||
iwl_trans_read_mem_bytes(fwrt->trans, addr, range->data,
|
||||
le32_to_cpu(special_mem->size));
|
||||
iwl_trans_read_mem_bytes_no_grab(fwrt->trans, addr, range->data,
|
||||
le32_to_cpu(special_mem->size));
|
||||
|
||||
return sizeof(*range) + le32_to_cpu(range->range_data_size);
|
||||
}
|
||||
|
|
@ -724,9 +706,6 @@ iwl_dump_ini_dbgi_sram_iter(struct iwl_fw_runtime *fwrt,
|
|||
u32 prph_data;
|
||||
int i;
|
||||
|
||||
if (!iwl_trans_grab_nic_access(fwrt->trans))
|
||||
return -EBUSY;
|
||||
|
||||
range->range_data_size = reg->dev_addr.size;
|
||||
for (i = 0; i < (le32_to_cpu(reg->dev_addr.size) / 4); i++) {
|
||||
prph_data =
|
||||
|
|
@ -734,13 +713,11 @@ iwl_dump_ini_dbgi_sram_iter(struct iwl_fw_runtime *fwrt,
|
|||
(i % 2) ?
|
||||
DBGI_SRAM_TARGET_ACCESS_RDATA_MSB :
|
||||
DBGI_SRAM_TARGET_ACCESS_RDATA_LSB);
|
||||
if (iwl_trans_is_hw_error_value(prph_data)) {
|
||||
iwl_trans_release_nic_access(fwrt->trans);
|
||||
if (iwl_trans_is_hw_error_value(prph_data))
|
||||
return -EBUSY;
|
||||
}
|
||||
*val++ = cpu_to_le32(prph_data);
|
||||
}
|
||||
iwl_trans_release_nic_access(fwrt->trans);
|
||||
|
||||
return sizeof(*range) + le32_to_cpu(range->range_data_size);
|
||||
}
|
||||
|
||||
|
|
@ -787,8 +764,8 @@ static int iwl_dump_ini_imr_iter(struct iwl_fw_runtime *fwrt,
|
|||
fwrt->trans->dbg.imr_data.imr_curr_addr = imr_curr_addr + size_to_dump;
|
||||
fwrt->trans->dbg.imr_data.imr2sram_remainbyte -= size_to_dump;
|
||||
|
||||
iwl_trans_read_mem_bytes(fwrt->trans, sram_addr, range->data,
|
||||
size_to_dump);
|
||||
iwl_trans_read_mem_bytes_no_grab(fwrt->trans, sram_addr, range->data,
|
||||
size_to_dump);
|
||||
return sizeof(*range) + le32_to_cpu(range->range_data_size);
|
||||
}
|
||||
|
||||
|
|
@ -842,11 +819,6 @@ iwl_dump_ini_mon_fill_header(struct iwl_fw_runtime *fwrt, u32 alloc_id,
|
|||
struct iwl_fw_ini_monitor_dump *data,
|
||||
const struct iwl_fw_mon_regs *addrs)
|
||||
{
|
||||
if (!iwl_trans_grab_nic_access(fwrt->trans)) {
|
||||
IWL_ERR(fwrt, "Failed to get monitor header\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data->write_ptr = iwl_get_mon_reg(fwrt, alloc_id,
|
||||
&addrs->write_ptr);
|
||||
if (fwrt->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
|
||||
|
|
@ -859,8 +831,6 @@ iwl_dump_ini_mon_fill_header(struct iwl_fw_runtime *fwrt, u32 alloc_id,
|
|||
data->cur_frag = iwl_get_mon_reg(fwrt, alloc_id,
|
||||
&addrs->cur_frag);
|
||||
|
||||
iwl_trans_release_nic_access(fwrt->trans);
|
||||
|
||||
data->header.version = cpu_to_le32(IWL_INI_DUMP_VER);
|
||||
|
||||
return data->data;
|
||||
|
|
@ -1266,6 +1236,7 @@ iwl_dump_ini_imr_get_size(struct iwl_fw_runtime *fwrt,
|
|||
* the first range or NULL if failed to fill headers.
|
||||
* @fill_range: copies a given memory range into the dump.
|
||||
* Returns the size of the range or negative error value otherwise.
|
||||
* @requires_nic_access: indicates to dump only if NIC access was acquired
|
||||
*/
|
||||
struct iwl_dump_ini_mem_ops {
|
||||
u32 (*get_num_of_ranges)(struct iwl_fw_runtime *fwrt,
|
||||
|
|
@ -1278,6 +1249,7 @@ struct iwl_dump_ini_mem_ops {
|
|||
int (*fill_range)(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_dump_ini_region_data *reg_data,
|
||||
void *range, int idx);
|
||||
bool requires_nic_access;
|
||||
};
|
||||
|
||||
struct iwl_fw_ini_dump_entry {
|
||||
|
|
@ -1374,7 +1346,8 @@ static void iwl_dump_ini_mem_prep(struct iwl_fw_runtime *fwrt,
|
|||
}
|
||||
|
||||
static u32 iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_ini_dump_entry *entry)
|
||||
struct iwl_fw_ini_dump_entry *entry,
|
||||
bool have_nic_access)
|
||||
{
|
||||
struct iwl_dump_ini_region_data *reg_data = &entry->reg_data;
|
||||
struct iwl_fw_ini_region_tlv *reg = (void *)reg_data->reg_tlv->data;
|
||||
|
|
@ -1388,6 +1361,9 @@ static u32 iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt,
|
|||
u32 free_size;
|
||||
u64 header_size;
|
||||
|
||||
if (!have_nic_access && ops->requires_nic_access)
|
||||
goto out_err;
|
||||
|
||||
tlv = (void *)entry->data;
|
||||
header = (void *)tlv->data;
|
||||
|
||||
|
|
@ -1541,36 +1517,42 @@ static const struct iwl_dump_ini_mem_ops iwl_dump_ini_region_ops[] = {
|
|||
.get_size = iwl_dump_ini_mon_smem_get_size,
|
||||
.fill_mem_hdr = iwl_dump_ini_mon_smem_fill_header,
|
||||
.fill_range = iwl_dump_ini_mon_smem_iter,
|
||||
.requires_nic_access = true,
|
||||
},
|
||||
[IWL_FW_INI_REGION_DRAM_BUFFER] = {
|
||||
.get_num_of_ranges = iwl_dump_ini_mon_dram_ranges,
|
||||
.get_size = iwl_dump_ini_mon_dram_get_size,
|
||||
.fill_mem_hdr = iwl_dump_ini_mon_dram_fill_header,
|
||||
.fill_range = iwl_dump_ini_mon_dram_iter,
|
||||
.requires_nic_access = true,
|
||||
},
|
||||
[IWL_FW_INI_REGION_TXF] = {
|
||||
.get_num_of_ranges = iwl_dump_ini_txf_ranges,
|
||||
.get_size = iwl_dump_ini_txf_get_size,
|
||||
.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
|
||||
.fill_range = iwl_dump_ini_txf_iter,
|
||||
.requires_nic_access = true,
|
||||
},
|
||||
[IWL_FW_INI_REGION_RXF] = {
|
||||
.get_num_of_ranges = iwl_dump_ini_single_range,
|
||||
.get_size = iwl_dump_ini_rxf_get_size,
|
||||
.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
|
||||
.fill_range = iwl_dump_ini_rxf_iter,
|
||||
.requires_nic_access = true,
|
||||
},
|
||||
[IWL_FW_INI_REGION_LMAC_ERROR_TABLE] = {
|
||||
.get_num_of_ranges = iwl_dump_ini_single_range,
|
||||
.get_size = iwl_dump_ini_err_table_get_size,
|
||||
.fill_mem_hdr = iwl_dump_ini_err_table_fill_header,
|
||||
.fill_range = iwl_dump_ini_err_table_iter,
|
||||
.requires_nic_access = true,
|
||||
},
|
||||
[IWL_FW_INI_REGION_UMAC_ERROR_TABLE] = {
|
||||
.get_num_of_ranges = iwl_dump_ini_single_range,
|
||||
.get_size = iwl_dump_ini_err_table_get_size,
|
||||
.fill_mem_hdr = iwl_dump_ini_err_table_fill_header,
|
||||
.fill_range = iwl_dump_ini_err_table_iter,
|
||||
.requires_nic_access = true,
|
||||
},
|
||||
[IWL_FW_INI_REGION_RSP_OR_NOTIF] = {
|
||||
.get_num_of_ranges = iwl_dump_ini_single_range,
|
||||
|
|
@ -1583,30 +1565,35 @@ static const struct iwl_dump_ini_mem_ops iwl_dump_ini_region_ops[] = {
|
|||
.get_size = iwl_dump_ini_mem_get_size,
|
||||
.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
|
||||
.fill_range = iwl_dump_ini_dev_mem_iter,
|
||||
.requires_nic_access = true,
|
||||
},
|
||||
[IWL_FW_INI_REGION_PERIPHERY_MAC] = {
|
||||
.get_num_of_ranges = iwl_dump_ini_mem_ranges,
|
||||
.get_size = iwl_dump_ini_mem_get_size,
|
||||
.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
|
||||
.fill_range = iwl_dump_ini_prph_mac_iter,
|
||||
.requires_nic_access = true,
|
||||
},
|
||||
[IWL_FW_INI_REGION_PERIPHERY_PHY] = {
|
||||
.get_num_of_ranges = iwl_dump_ini_mem_ranges,
|
||||
.get_size = iwl_dump_ini_mem_get_size,
|
||||
.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
|
||||
.fill_range = iwl_dump_ini_prph_phy_iter,
|
||||
.requires_nic_access = true,
|
||||
},
|
||||
[IWL_FW_INI_REGION_PERIPHERY_MAC_RANGE] = {
|
||||
.get_num_of_ranges = iwl_dump_ini_mem_block_ranges,
|
||||
.get_size = iwl_dump_ini_mem_block_get_size,
|
||||
.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
|
||||
.fill_range = iwl_dump_ini_prph_mac_block_iter,
|
||||
.requires_nic_access = true,
|
||||
},
|
||||
[IWL_FW_INI_REGION_PERIPHERY_PHY_RANGE] = {
|
||||
.get_num_of_ranges = iwl_dump_ini_mem_block_ranges,
|
||||
.get_size = iwl_dump_ini_mem_block_get_size,
|
||||
.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
|
||||
.fill_range = iwl_dump_ini_prph_phy_block_iter,
|
||||
.requires_nic_access = true,
|
||||
},
|
||||
[IWL_FW_INI_REGION_PERIPHERY_AUX] = {},
|
||||
[IWL_FW_INI_REGION_PAGING] = {
|
||||
|
|
@ -1626,6 +1613,7 @@ static const struct iwl_dump_ini_mem_ops iwl_dump_ini_region_ops[] = {
|
|||
.get_size = iwl_dump_ini_imr_get_size,
|
||||
.fill_mem_hdr = iwl_dump_ini_imr_fill_header,
|
||||
.fill_range = iwl_dump_ini_imr_iter,
|
||||
.requires_nic_access = true,
|
||||
},
|
||||
[IWL_FW_INI_REGION_PCI_IOSF_CONFIG] = {
|
||||
.get_num_of_ranges = iwl_dump_ini_mem_ranges,
|
||||
|
|
@ -1638,18 +1626,21 @@ static const struct iwl_dump_ini_mem_ops iwl_dump_ini_region_ops[] = {
|
|||
.get_size = iwl_dump_ini_special_mem_get_size,
|
||||
.fill_mem_hdr = iwl_dump_ini_special_mem_fill_header,
|
||||
.fill_range = iwl_dump_ini_special_mem_iter,
|
||||
.requires_nic_access = true,
|
||||
},
|
||||
[IWL_FW_INI_REGION_DBGI_SRAM] = {
|
||||
.get_num_of_ranges = iwl_dump_ini_mem_ranges,
|
||||
.get_size = iwl_dump_ini_mon_dbgi_get_size,
|
||||
.fill_mem_hdr = iwl_dump_ini_mon_dbgi_fill_header,
|
||||
.fill_range = iwl_dump_ini_dbgi_sram_iter,
|
||||
.requires_nic_access = true,
|
||||
},
|
||||
[IWL_FW_INI_REGION_PERIPHERY_SNPS_DPHYIP] = {
|
||||
.get_num_of_ranges = iwl_dump_ini_mem_ranges,
|
||||
.get_size = iwl_dump_ini_mem_get_size,
|
||||
.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
|
||||
.fill_range = iwl_dump_ini_prph_snps_dphyip_iter,
|
||||
.requires_nic_access = true,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -1733,8 +1724,11 @@ iwl_dump_ini_dump_entries(struct iwl_fw_runtime *fwrt,
|
|||
enum iwl_dump_ini_region_selector which)
|
||||
{
|
||||
struct iwl_fw_ini_dump_entry *entry, *tmp;
|
||||
bool have_nic_access;
|
||||
u32 size = 0;
|
||||
|
||||
have_nic_access = iwl_trans_grab_nic_access(fwrt->trans);
|
||||
|
||||
list_for_each_entry_safe(entry, tmp, list, list) {
|
||||
u32 dp = entry->region_dump_policy;
|
||||
|
||||
|
|
@ -1751,9 +1745,15 @@ iwl_dump_ini_dump_entries(struct iwl_fw_runtime *fwrt,
|
|||
break;
|
||||
}
|
||||
|
||||
size += iwl_dump_ini_mem(fwrt, entry);
|
||||
size += iwl_dump_ini_mem(fwrt, entry, have_nic_access);
|
||||
|
||||
if (have_nic_access)
|
||||
iwl_trans_resched_with_nic_access(fwrt->trans);
|
||||
}
|
||||
|
||||
if (have_nic_access)
|
||||
iwl_trans_release_nic_access(fwrt->trans);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
|
@ -2383,8 +2383,8 @@ static int iwl_fw_dbg_restart_recording(struct iwl_trans *trans,
|
|||
|
||||
int iwl_fw_send_timestamp_marker_cmd(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
struct iwl_mvm_marker marker = {
|
||||
.dw_len = sizeof(struct iwl_mvm_marker) / 4,
|
||||
struct iwl_marker marker = {
|
||||
.dw_len = sizeof(struct iwl_marker) / 4,
|
||||
.marker_id = MARKER_ID_SYNC_CLOCK,
|
||||
};
|
||||
struct iwl_host_cmd hcmd = {
|
||||
|
|
@ -2392,7 +2392,7 @@ int iwl_fw_send_timestamp_marker_cmd(struct iwl_fw_runtime *fwrt)
|
|||
.id = WIDE_ID(LONG_GROUP, MARKER_CMD),
|
||||
.dataflags = {},
|
||||
};
|
||||
struct iwl_mvm_marker_rsp *resp;
|
||||
struct iwl_marker_rsp *resp;
|
||||
int cmd_ver = iwl_fw_lookup_cmd_ver(fwrt->fw,
|
||||
WIDE_ID(LONG_GROUP, MARKER_CMD),
|
||||
IWL_FW_CMD_VER_UNKNOWN);
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ enum iwl_ucode_tlv_type {
|
|||
IWL_UCODE_TLV_FW_NUM_LINKS = IWL_UCODE_TLV_CONST_BASE + 1,
|
||||
IWL_UCODE_TLV_FW_NUM_BEACONS = IWL_UCODE_TLV_CONST_BASE + 2,
|
||||
IWL_UCODE_TLV_FW_NUM_MCAST_KEY_ENTRIES = IWL_UCODE_TLV_CONST_BASE + 3,
|
||||
IWL_UCODE_TLV_FW_NAN_MAX_CHAN_SWITCH_TIME = IWL_UCODE_TLV_CONST_BASE + 4,
|
||||
|
||||
IWL_UCODE_TLV_TYPE_DEBUG_INFO = IWL_UCODE_TLV_DEBUG_BASE + 0,
|
||||
IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION = IWL_UCODE_TLV_DEBUG_BASE + 1,
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ struct iwl_ucode_capabilities {
|
|||
u32 num_links;
|
||||
u32 num_beacons;
|
||||
u32 num_mcast_key_entries;
|
||||
u16 nan_max_chan_switch_time;
|
||||
DECLARE_BITMAP(_api, NUM_IWL_UCODE_TLV_API);
|
||||
DECLARE_BITMAP(_capa, NUM_IWL_UCODE_TLV_CAPA);
|
||||
|
||||
|
|
|
|||
|
|
@ -8,27 +8,6 @@
|
|||
#include "iwl-drv.h"
|
||||
#include "iwl-config.h"
|
||||
|
||||
#define IWL_DECLARE_RATE_INFO(r) \
|
||||
[IWL_RATE_##r##M_INDEX] = IWL_RATE_##r##M_PLCP
|
||||
|
||||
/*
|
||||
* Translate from fw_rate_index (IWL_RATE_XXM_INDEX) to PLCP
|
||||
* */
|
||||
static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = {
|
||||
IWL_DECLARE_RATE_INFO(1),
|
||||
IWL_DECLARE_RATE_INFO(2),
|
||||
IWL_DECLARE_RATE_INFO(5),
|
||||
IWL_DECLARE_RATE_INFO(11),
|
||||
IWL_DECLARE_RATE_INFO(6),
|
||||
IWL_DECLARE_RATE_INFO(9),
|
||||
IWL_DECLARE_RATE_INFO(12),
|
||||
IWL_DECLARE_RATE_INFO(18),
|
||||
IWL_DECLARE_RATE_INFO(24),
|
||||
IWL_DECLARE_RATE_INFO(36),
|
||||
IWL_DECLARE_RATE_INFO(48),
|
||||
IWL_DECLARE_RATE_INFO(54),
|
||||
};
|
||||
|
||||
/* mbps, mcs */
|
||||
static const struct iwl_rate_mcs_info rate_mcs[IWL_RATE_COUNT] = {
|
||||
{ "1", "BPSK DSSS"},
|
||||
|
|
@ -61,12 +40,6 @@ static const char * const pretty_bw[] = {
|
|||
"320Mhz",
|
||||
};
|
||||
|
||||
u8 iwl_fw_rate_idx_to_plcp(int idx)
|
||||
{
|
||||
return fw_rate_idx_to_plcp[idx];
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fw_rate_idx_to_plcp);
|
||||
|
||||
const struct iwl_rate_mcs_info *iwl_rate_mcs(int idx)
|
||||
{
|
||||
return &rate_mcs[idx];
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2005-2014, 2018-2021 Intel Corporation
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018-2025 Intel Corporation
|
||||
* Copyright (C) 2018-2026 Intel Corporation
|
||||
*/
|
||||
#ifndef __IWL_CONFIG_H__
|
||||
#define __IWL_CONFIG_H__
|
||||
|
|
@ -372,7 +372,7 @@ struct iwl_mac_cfg {
|
|||
};
|
||||
|
||||
/*
|
||||
* These sizes were picked according to 8 MSDUs inside 64/256/612 A-MSDUs
|
||||
* These sizes were picked according to 8 MSDUs inside 64/256/512 A-MSDUs
|
||||
* in an A-MPDU, with additional overhead to account for processing time.
|
||||
* They will be doubled for MACs starting from So/Ty that don't support
|
||||
* putting multiple frames into a single buffer.
|
||||
|
|
@ -669,6 +669,7 @@ extern const char iwl_ax411_killer_1690s_name[];
|
|||
extern const char iwl_ax411_killer_1690i_name[];
|
||||
extern const char iwl_ax210_name[];
|
||||
extern const char iwl_ax211_name[];
|
||||
extern const char iwl_ax231_name[];
|
||||
extern const char iwl_ax411_name[];
|
||||
extern const char iwl_killer_be1750s_name[];
|
||||
extern const char iwl_killer_be1750i_name[];
|
||||
|
|
@ -740,6 +741,7 @@ extern const struct iwl_rf_cfg iwl_rf_hr;
|
|||
extern const struct iwl_rf_cfg iwl_rf_hr_80mhz;
|
||||
|
||||
extern const struct iwl_rf_cfg iwl_rf_gf;
|
||||
#define iwl_rf_ot iwl_rf_hr_80mhz
|
||||
#endif /* CONFIG_IWLMVM */
|
||||
|
||||
#if IS_ENABLED(CONFIG_IWLMLD)
|
||||
|
|
|
|||
|
|
@ -1337,6 +1337,12 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
|||
capa->num_mcast_key_entries =
|
||||
le32_to_cpup((const __le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_FW_NAN_MAX_CHAN_SWITCH_TIME:
|
||||
if (tlv_len != sizeof(u32))
|
||||
goto invalid_tlv_len;
|
||||
capa->nan_max_chan_switch_time =
|
||||
le32_to_cpup((const __le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_UMAC_DEBUG_ADDRS: {
|
||||
const struct iwl_umac_debug_addrs *dbg_ptrs =
|
||||
(const void *)tlv_data;
|
||||
|
|
|
|||
|
|
@ -385,7 +385,8 @@ enum {
|
|||
#define CNVI_SCU_REG_FOR_ECO_1_WIAMT_KNOWN BIT(4)
|
||||
#define CNVI_SCU_REG_FOR_ECO_1_WIAMT_PRESENT BIT(5)
|
||||
|
||||
#define CNVI_PMU_STEP_FLOW 0xA2D588
|
||||
#define CNVI_PMU_STEP_FLOW_BZ 0xA2D588
|
||||
#define CNVI_PMU_STEP_FLOW_SC 0xA2D688
|
||||
#define CNVI_PMU_STEP_FLOW_FORCE_URM BIT(2)
|
||||
|
||||
#define PREG_AUX_BUS_WPROT_0 0xA04CC0
|
||||
|
|
|
|||
|
|
@ -558,6 +558,11 @@ bool iwl_trans_grab_nic_access(struct iwl_trans *trans)
|
|||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_trans_grab_nic_access);
|
||||
|
||||
void iwl_trans_resched_with_nic_access(struct iwl_trans *trans)
|
||||
{
|
||||
iwl_trans_pcie_resched_with_nic_access(trans);
|
||||
}
|
||||
|
||||
void __releases(nic_access)
|
||||
iwl_trans_release_nic_access(struct iwl_trans *trans)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -161,6 +161,10 @@ struct iwl_device_tx_cmd {
|
|||
|
||||
#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd))
|
||||
|
||||
/* Maximum payload size for a non-NOCOPY host command (excluding the header) */
|
||||
#define IWL_MAX_CMD_PAYLOAD_SIZE \
|
||||
(TFD_MAX_PAYLOAD_SIZE - sizeof(struct iwl_cmd_header_wide))
|
||||
|
||||
/*
|
||||
* number of transfer buffers (fragments) per transmit frame descriptor;
|
||||
* this is just the driver's idea, the hardware supports 20
|
||||
|
|
@ -981,6 +985,17 @@ void iwl_trans_set_bits_mask(struct iwl_trans *trans, u32 reg,
|
|||
|
||||
bool iwl_trans_grab_nic_access(struct iwl_trans *trans);
|
||||
|
||||
/**
|
||||
* iwl_trans_resched_with_nic_access - reschedule while holding NIC access
|
||||
* @trans: the transport pointer
|
||||
*
|
||||
* This can be called while holding NIC access, during periods where
|
||||
* the lock itself isn't interesting, the NIC should remain active,
|
||||
* but a lot of processing is happening and the CPU may need to be
|
||||
* released. In practice, this is only during FW dump.
|
||||
*/
|
||||
void iwl_trans_resched_with_nic_access(struct iwl_trans *trans);
|
||||
|
||||
void __releases(nic_access)
|
||||
iwl_trans_release_nic_access(struct iwl_trans *trans);
|
||||
|
||||
|
|
|
|||
|
|
@ -2066,8 +2066,11 @@ int iwl_mld_wowlan_suspend(struct iwl_mld *mld, struct cfg80211_wowlan *wowlan)
|
|||
|
||||
if (!bss_vif->cfg.assoc) {
|
||||
int ret;
|
||||
/* If we're not associated, this must be netdetect */
|
||||
if (WARN_ON(!wowlan->nd_config))
|
||||
/*
|
||||
* If not associated we can only do netdetect, if
|
||||
* that's not enabled then just suspend normally.
|
||||
*/
|
||||
if (!wowlan->nd_config)
|
||||
return 1;
|
||||
|
||||
ret = iwl_mld_netdetect_config(mld, bss_vif, wowlan);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
* Copyright (C) 2024-2026 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <kunit/static_stub.h>
|
||||
|
||||
#include "constants.h"
|
||||
#include "link.h"
|
||||
#include "iface.h"
|
||||
|
|
@ -1024,7 +1026,7 @@ iwl_mld_get_avail_chan_load(struct iwl_mld *mld,
|
|||
return MAX_CHAN_LOAD - iwl_mld_get_chan_load(mld, link_conf);
|
||||
}
|
||||
|
||||
static s8
|
||||
VISIBLE_IF_IWLWIFI_KUNIT s8
|
||||
iwl_mld_get_dup_beacon_rssi_adjust(struct iwl_mld *mld,
|
||||
struct ieee80211_bss_conf *link_conf)
|
||||
{
|
||||
|
|
@ -1032,6 +1034,9 @@ iwl_mld_get_dup_beacon_rssi_adjust(struct iwl_mld *mld,
|
|||
const struct cfg80211_bss_ies *beacon_ies;
|
||||
const struct element *elem;
|
||||
|
||||
KUNIT_STATIC_STUB_REDIRECT(iwl_mld_get_dup_beacon_rssi_adjust,
|
||||
mld, link_conf);
|
||||
|
||||
/* Duplicated beacon feature is only specific to 6 GHz */
|
||||
if (WARN_ONCE(link_conf->chanreq.oper.chan->band != NL80211_BAND_6GHZ,
|
||||
"Unexpected band %d\n",
|
||||
|
|
@ -1077,6 +1082,7 @@ iwl_mld_get_dup_beacon_rssi_adjust(struct iwl_mld *mld,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_mld_get_dup_beacon_rssi_adjust);
|
||||
|
||||
static s8 iwl_mld_get_primary_psd(const struct ieee80211_parsed_tpe_psd *psd,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
|
|
@ -1097,7 +1103,8 @@ static s8 iwl_mld_get_primary_psd(const struct ieee80211_parsed_tpe_psd *psd,
|
|||
return psd->power[primary_idx] / 2;
|
||||
}
|
||||
|
||||
static s8 iwl_mld_get_psd_eirp_rssi_adjust(struct ieee80211_bss_conf *link_conf)
|
||||
VISIBLE_IF_IWLWIFI_KUNIT s8
|
||||
iwl_mld_get_psd_eirp_rssi_adjust(struct ieee80211_bss_conf *link_conf)
|
||||
{
|
||||
const struct ieee80211_parsed_tpe *tpe = &link_conf->tpe;
|
||||
s8 psd_20mhz, psd_oper, psd_local, psd_reg, psd_boost;
|
||||
|
|
@ -1107,6 +1114,9 @@ static s8 iwl_mld_get_psd_eirp_rssi_adjust(struct ieee80211_bss_conf *link_conf)
|
|||
int bw_mhz, num_subchans;
|
||||
u8 bw_index;
|
||||
|
||||
KUNIT_STATIC_STUB_REDIRECT(iwl_mld_get_psd_eirp_rssi_adjust,
|
||||
link_conf);
|
||||
|
||||
/* PSD/EIRP adjustment is only specific to 6 GHz */
|
||||
if (WARN_ONCE(link_conf->chanreq.oper.chan->band != NL80211_BAND_6GHZ,
|
||||
"PSD/EIRP adjustment called for non-6 GHz band %d\n",
|
||||
|
|
@ -1216,6 +1226,7 @@ static s8 iwl_mld_get_psd_eirp_rssi_adjust(struct ieee80211_bss_conf *link_conf)
|
|||
|
||||
return adjustment;
|
||||
}
|
||||
EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_mld_get_psd_eirp_rssi_adjust);
|
||||
|
||||
/* This function calculates the grade of a link. Returns 0 in error case */
|
||||
unsigned int iwl_mld_get_link_grade(struct iwl_mld *mld,
|
||||
|
|
|
|||
|
|
@ -142,6 +142,12 @@ int iwl_mld_link_set_associated(struct iwl_mld *mld, struct ieee80211_vif *vif,
|
|||
unsigned int iwl_mld_get_link_grade(struct iwl_mld *mld,
|
||||
struct ieee80211_bss_conf *link_conf);
|
||||
|
||||
#if IS_ENABLED(CONFIG_IWLWIFI_KUNIT_TESTS)
|
||||
s8 iwl_mld_get_dup_beacon_rssi_adjust(struct iwl_mld *mld,
|
||||
struct ieee80211_bss_conf *link_conf);
|
||||
s8 iwl_mld_get_psd_eirp_rssi_adjust(struct ieee80211_bss_conf *link_conf);
|
||||
#endif
|
||||
|
||||
unsigned int iwl_mld_get_chan_load(struct iwl_mld *mld,
|
||||
struct ieee80211_bss_conf *link_conf);
|
||||
|
||||
|
|
|
|||
|
|
@ -291,8 +291,13 @@ static void iwl_mld_hw_set_nan(struct iwl_mld *mld)
|
|||
NAN_DEV_CAPA_NUM_RX_ANT_POS) &
|
||||
NAN_DEV_CAPA_NUM_RX_ANT_MASK);
|
||||
|
||||
/* Maximal channel switch time is 4 msec */
|
||||
hw->wiphy->nan_capa.max_channel_switch_time = 4 * USEC_PER_MSEC;
|
||||
/* Maximal channel switch time - use FW TLV value if available */
|
||||
if (mld->fw->ucode_capa.nan_max_chan_switch_time)
|
||||
hw->wiphy->nan_capa.max_channel_switch_time =
|
||||
mld->fw->ucode_capa.nan_max_chan_switch_time;
|
||||
else
|
||||
hw->wiphy->nan_capa.max_channel_switch_time =
|
||||
4 * USEC_PER_MSEC;
|
||||
|
||||
hw->wiphy->nan_capa.phy.ht = mld->nvm_data->nan_phy_capa.ht;
|
||||
hw->wiphy->nan_capa.phy.vht = mld->nvm_data->nan_phy_capa.vht;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ bool iwl_mld_nan_supported(struct iwl_mld *mld)
|
|||
iwl_fw_lookup_cmd_ver(fw, WIDE_ID(MAC_CONF_GROUP, NAN_PEER_CMD), 0) >= 1 &&
|
||||
iwl_fw_lookup_cmd_ver(fw, WIDE_ID(MAC_CONF_GROUP, STA_CONFIG_CMD), 0) >= 3 &&
|
||||
iwl_fw_lookup_cmd_ver(fw, WIDE_ID(MAC_CONF_GROUP, MAC_CONFIG_CMD), 0) >= 4 &&
|
||||
iwl_fw_lookup_cmd_ver(fw, WIDE_ID(DATA_PATH_GROUP, TLC_MNG_CONFIG_CMD), 0) >= 6)
|
||||
iwl_fw_lookup_cmd_ver(fw, WIDE_ID(DATA_PATH_GROUP, TLC_MNG_CONFIG_CMD), 0) >= 6 &&
|
||||
mld->nvm_data->nan_phy_capa.ht.ht_supported)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
#include <linux/crc32.h>
|
||||
|
||||
|
|
@ -237,6 +237,12 @@ iwl_mld_scan_type iwl_mld_get_scan_type(struct iwl_mld *mld,
|
|||
vif->type != NL80211_IFTYPE_P2P_DEVICE)
|
||||
return IWL_SCAN_TYPE_FRAGMENTED;
|
||||
|
||||
/* While associated to MLD AP with active EMLSR, set all scan
|
||||
* operations as fast-balance scans.
|
||||
*/
|
||||
if (iwl_mld_emlsr_active(vif))
|
||||
return IWL_SCAN_TYPE_FAST_BALANCE;
|
||||
|
||||
/* In case of DCM with P2P GO set all scan requests as
|
||||
* fast-balance scan
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -538,6 +538,12 @@ int iwl_mld_add_modify_sta_cmd(struct iwl_mld *mld,
|
|||
break;
|
||||
}
|
||||
|
||||
/* In NAN, there is no association request so no initial SMPS info */
|
||||
if (mld_sta->vif->type == NL80211_IFTYPE_NAN_DATA) {
|
||||
cmd.mimo = cpu_to_le32(1);
|
||||
cmd.mimo_protection = cpu_to_le32(0);
|
||||
}
|
||||
|
||||
iwl_mld_fill_ampdu_size_and_dens(link_sta, is_6ghz,
|
||||
&cmd.tx_ampdu_max_size,
|
||||
&cmd.tx_ampdu_spacing);
|
||||
|
|
|
|||
|
|
@ -13,24 +13,39 @@
|
|||
#include "phy.h"
|
||||
#include "mlo.h"
|
||||
|
||||
struct link_grading_input {
|
||||
u8 link_id;
|
||||
const struct cfg80211_chan_def *chandef;
|
||||
bool active;
|
||||
s32 signal;
|
||||
bool has_chan_util_elem;
|
||||
u8 chan_util;
|
||||
u8 chan_load_by_us;
|
||||
s8 dup_beacon_adj;
|
||||
s8 psd_eirp_adj;
|
||||
u16 punctured;
|
||||
};
|
||||
|
||||
static const struct link_grading_test_case {
|
||||
const char *desc;
|
||||
struct {
|
||||
struct {
|
||||
u8 link_id;
|
||||
const struct cfg80211_chan_def *chandef;
|
||||
bool active;
|
||||
s32 signal;
|
||||
bool has_chan_util_elem;
|
||||
u8 chan_util; /* 0-255 , used only if has_chan_util_elem is true */
|
||||
u8 chan_load_by_us; /* 0-100, used only if active is true */;
|
||||
} link;
|
||||
} input;
|
||||
struct link_grading_input link;
|
||||
unsigned int expected_grade;
|
||||
} link_grading_cases[] = {
|
||||
/* Per-bandwidth grading table tests */
|
||||
{
|
||||
.desc = "channel util of 128 (50%)",
|
||||
.input.link = {
|
||||
.desc = "20 MHz grading table: -75 dBm",
|
||||
.link = {
|
||||
.link_id = 0,
|
||||
.chandef = &chandef_2ghz_20mhz,
|
||||
.active = false,
|
||||
.signal = -75,
|
||||
},
|
||||
/* 137 * 0.7 (default 2.4GHz channel load 30%) */
|
||||
.expected_grade = 96,
|
||||
},
|
||||
{
|
||||
.desc = "20 MHz with channel util 128 (50%): -70 dBm",
|
||||
.link = {
|
||||
.link_id = 0,
|
||||
.chandef = &chandef_2ghz_20mhz,
|
||||
.active = false,
|
||||
|
|
@ -41,8 +56,8 @@ static const struct link_grading_test_case {
|
|||
.expected_grade = 86,
|
||||
},
|
||||
{
|
||||
.desc = "channel util of 180 (70%)",
|
||||
.input.link = {
|
||||
.desc = "20 MHz with channel util 180 (70%): -70 dBm",
|
||||
.link = {
|
||||
.link_id = 0,
|
||||
.chandef = &chandef_2ghz_20mhz,
|
||||
.active = false,
|
||||
|
|
@ -53,32 +68,222 @@ static const struct link_grading_test_case {
|
|||
.expected_grade = 51,
|
||||
},
|
||||
{
|
||||
.desc = "channel util of 180 (70%), channel load by us of 10%",
|
||||
.input.link = {
|
||||
.desc = "20 MHz active link with chan load by us 10%: -70 dBm",
|
||||
.link = {
|
||||
.link_id = 0,
|
||||
.chandef = &chandef_2ghz_20mhz,
|
||||
.active = true,
|
||||
.signal = -70,
|
||||
.has_chan_util_elem = true,
|
||||
.chan_util = 180,
|
||||
.active = true,
|
||||
.chan_load_by_us = 10,
|
||||
},
|
||||
.expected_grade = 67,
|
||||
},
|
||||
{
|
||||
.desc = "no channel util element",
|
||||
.input.link = {
|
||||
{
|
||||
.desc = "40 MHz grading table: -80 dBm",
|
||||
.link = {
|
||||
.link_id = 0,
|
||||
.chandef = &chandef_2ghz_20mhz,
|
||||
.signal = -70,
|
||||
.active = true,
|
||||
.chandef = &chandef_5ghz_40mhz,
|
||||
.active = false,
|
||||
.signal = -80,
|
||||
},
|
||||
.expected_grade = 120,
|
||||
/* 206 * 0.85 (default 5GHz channel load 15%) */
|
||||
.expected_grade = 175,
|
||||
},
|
||||
{
|
||||
.desc = "80 MHz grading table: -70 dBm",
|
||||
.link = {
|
||||
.link_id = 0,
|
||||
.chandef = &chandef_5ghz_80mhz,
|
||||
.active = false,
|
||||
.signal = -70,
|
||||
},
|
||||
/* 548 * 0.85 (default 5GHz channel load 15%) */
|
||||
.expected_grade = 466,
|
||||
},
|
||||
{
|
||||
.desc = "160 MHz grading table: -65 dBm",
|
||||
.link = {
|
||||
.link_id = 0,
|
||||
.chandef = &chandef_5ghz_160mhz,
|
||||
.active = false,
|
||||
.signal = -65,
|
||||
},
|
||||
/* 1240 * 0.85 (default 5GHz channel load 15%) */
|
||||
.expected_grade = 1055,
|
||||
},
|
||||
{
|
||||
.desc = "320 MHz grading table: -60 dBm",
|
||||
.link = {
|
||||
.link_id = 0,
|
||||
.chandef = &chandef_6ghz_320mhz,
|
||||
.active = false,
|
||||
.signal = -60,
|
||||
},
|
||||
/* 3680 at -56 dBm (-60 + 4 dBm 6 GHz) */
|
||||
.expected_grade = 3680,
|
||||
},
|
||||
/* 6 GHz RSSI adjustment integration tests */
|
||||
{
|
||||
.desc = "6 GHz 160 MHz with fixed +4 dBm adjustment",
|
||||
.link = {
|
||||
.link_id = 0,
|
||||
.chandef = &chandef_6ghz_160mhz,
|
||||
.active = false,
|
||||
.signal = -69,
|
||||
},
|
||||
/* -69 + 4 dBm = -65, grade 1240 */
|
||||
.expected_grade = 1240,
|
||||
},
|
||||
{
|
||||
.desc = "6 GHz 80 MHz with fixed +4 dBm adjustment",
|
||||
.link = {
|
||||
.link_id = 0,
|
||||
.chandef = &chandef_6ghz_80mhz,
|
||||
.active = false,
|
||||
.signal = -74,
|
||||
},
|
||||
/* -74 + 4 dBm = -70, grade 548 */
|
||||
.expected_grade = 548,
|
||||
},
|
||||
{
|
||||
.desc = "6 GHz 40 MHz with fixed +4 dBm adjustment",
|
||||
.link = {
|
||||
.link_id = 0,
|
||||
.chandef = &chandef_6ghz_40mhz,
|
||||
.active = false,
|
||||
.signal = -84,
|
||||
},
|
||||
/* -84 + 4 dBm = -80, grade 206 */
|
||||
.expected_grade = 206,
|
||||
},
|
||||
{
|
||||
.desc = "6 GHz 20 MHz with fixed +4 dBm adjustment",
|
||||
.link = {
|
||||
.link_id = 0,
|
||||
.chandef = &chandef_6ghz_20mhz,
|
||||
.active = false,
|
||||
.signal = -79,
|
||||
},
|
||||
.expected_grade = 137,
|
||||
},
|
||||
/* Duplicated beacon RSSI adjustment tests */
|
||||
{
|
||||
.desc = "6 GHz 40 MHz dup beacon: -81 dBm + 3 dBm = -78 dBm",
|
||||
.link = {
|
||||
.link_id = 0,
|
||||
.chandef = &chandef_6ghz_40mhz,
|
||||
.active = false,
|
||||
.signal = -81,
|
||||
.dup_beacon_adj = 3,
|
||||
},
|
||||
.expected_grade = 206,
|
||||
},
|
||||
{
|
||||
.desc = "6 GHz 80 MHz dup beacon: -73 dBm + 6 dBm = -67 dBm",
|
||||
.link = {
|
||||
.link_id = 0,
|
||||
.chandef = &chandef_6ghz_80mhz,
|
||||
.active = false,
|
||||
.signal = -73,
|
||||
.dup_beacon_adj = 6,
|
||||
},
|
||||
.expected_grade = 620,
|
||||
},
|
||||
{
|
||||
.desc = "6 GHz 160 MHz dup beacon: -74 dBm + 9 dBm = -65 dBm",
|
||||
.link = {
|
||||
.link_id = 0,
|
||||
.chandef = &chandef_6ghz_160mhz,
|
||||
.active = false,
|
||||
.signal = -74,
|
||||
.dup_beacon_adj = 9,
|
||||
},
|
||||
.expected_grade = 1240,
|
||||
},
|
||||
{
|
||||
.desc = "6 GHz 320 MHz dup beacon: -72 dBm + 12 dBm = -60 dBm",
|
||||
.link = {
|
||||
.link_id = 0,
|
||||
.chandef = &chandef_6ghz_320mhz,
|
||||
.active = false,
|
||||
.signal = -72,
|
||||
.dup_beacon_adj = 12,
|
||||
},
|
||||
.expected_grade = 3296,
|
||||
},
|
||||
/* PSD/EIRP RSSI adjustment tests */
|
||||
{
|
||||
.desc = "6 GHz 80 MHz PSD/EIRP: -77 dBm + 3 dBm = -74 dBm",
|
||||
.link = {
|
||||
.link_id = 0,
|
||||
.chandef = &chandef_6ghz_80mhz,
|
||||
.active = false,
|
||||
.signal = -77,
|
||||
.psd_eirp_adj = 3,
|
||||
},
|
||||
/* -77 + 3 dBm = -74, grade 412; fallback +4: -73 -> 548 */
|
||||
.expected_grade = 412,
|
||||
},
|
||||
{
|
||||
.desc = "6 GHz 160 MHz PSD/EIRP: -70 dBm + 3 dBm = -67 dBm",
|
||||
.link = {
|
||||
.link_id = 0,
|
||||
.chandef = &chandef_6ghz_160mhz,
|
||||
.active = false,
|
||||
.signal = -70,
|
||||
.psd_eirp_adj = 3,
|
||||
},
|
||||
/* -70 + 3 dBm = -67, grade 1096; fallback +4: -66 -> 1240 */
|
||||
.expected_grade = 1096,
|
||||
},
|
||||
/* Puncturing penalty tests */
|
||||
{
|
||||
.desc = "80 MHz with 20 MHz punctured: 3 active subchannels",
|
||||
.link = {
|
||||
.link_id = 0,
|
||||
.chandef = &chandef_5ghz_80mhz,
|
||||
.active = false,
|
||||
.signal = -70,
|
||||
.punctured = 0x2,
|
||||
},
|
||||
/* 548 * 0.85 (5GHz load) * 3/4 (puncturing) */
|
||||
.expected_grade = 349,
|
||||
},
|
||||
{
|
||||
.desc = "160 MHz with 40 MHz punctured: 6 active subchannels",
|
||||
.link = {
|
||||
.link_id = 0,
|
||||
.chandef = &chandef_5ghz_160mhz,
|
||||
.active = false,
|
||||
.signal = -65,
|
||||
.punctured = 0xC,
|
||||
},
|
||||
/* 1240 * 0.85 (5GHz load) * 6/8 (puncturing) */
|
||||
.expected_grade = 791,
|
||||
},
|
||||
};
|
||||
|
||||
KUNIT_ARRAY_PARAM_DESC(link_grading, link_grading_cases, desc);
|
||||
|
||||
static s8 fake_dup_beacon_rssi_adjust(struct iwl_mld *mld,
|
||||
struct ieee80211_bss_conf *link_conf)
|
||||
{
|
||||
const struct link_grading_test_case *params =
|
||||
kunit_get_current_test()->param_value;
|
||||
|
||||
return params->link.dup_beacon_adj;
|
||||
}
|
||||
|
||||
static s8 fake_psd_eirp_rssi_adjust(struct ieee80211_bss_conf *link_conf)
|
||||
{
|
||||
const struct link_grading_test_case *params =
|
||||
kunit_get_current_test()->param_value;
|
||||
|
||||
return params->link.psd_eirp_adj;
|
||||
}
|
||||
|
||||
static void setup_link(struct ieee80211_bss_conf *link)
|
||||
{
|
||||
struct kunit *test = kunit_get_current_test();
|
||||
|
|
@ -88,14 +293,14 @@ static void setup_link(struct ieee80211_bss_conf *link)
|
|||
|
||||
KUNIT_ALLOC_AND_ASSERT(test, link->bss);
|
||||
|
||||
link->bss->signal = DBM_TO_MBM(test_param->input.link.signal);
|
||||
link->bss->signal = DBM_TO_MBM(test_param->link.signal);
|
||||
|
||||
link->chanreq.oper = *test_param->input.link.chandef;
|
||||
link->chanreq.oper = *test_param->link.chandef;
|
||||
|
||||
if (test_param->input.link.has_chan_util_elem) {
|
||||
if (test_param->link.has_chan_util_elem) {
|
||||
struct cfg80211_bss_ies *ies;
|
||||
struct ieee80211_bss_load_elem bss_load = {
|
||||
.channel_util = test_param->input.link.chan_util,
|
||||
.channel_util = test_param->link.chan_util,
|
||||
};
|
||||
struct element *elem =
|
||||
iwlmld_kunit_gen_element(WLAN_EID_QBSS_LOAD,
|
||||
|
|
@ -110,7 +315,10 @@ static void setup_link(struct ieee80211_bss_conf *link)
|
|||
rcu_assign_pointer(link->bss->ies, ies);
|
||||
}
|
||||
|
||||
if (test_param->input.link.active) {
|
||||
if (test_param->link.punctured)
|
||||
link->chanreq.oper.punctured = test_param->link.punctured;
|
||||
|
||||
if (test_param->link.active) {
|
||||
struct ieee80211_chanctx_conf *chan_ctx =
|
||||
wiphy_dereference(mld->wiphy, link->chanctx_conf);
|
||||
struct iwl_mld_phy *phy;
|
||||
|
|
@ -119,7 +327,7 @@ static void setup_link(struct ieee80211_bss_conf *link)
|
|||
|
||||
phy = iwl_mld_phy_from_mac80211(chan_ctx);
|
||||
|
||||
phy->channel_load_by_us = test_param->input.link.chan_load_by_us;
|
||||
phy->channel_load_by_us = test_param->link.chan_load_by_us;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -131,12 +339,11 @@ static void test_link_grading(struct kunit *test)
|
|||
struct ieee80211_vif *vif;
|
||||
struct ieee80211_bss_conf *link;
|
||||
unsigned int actual_grade;
|
||||
/* Extract test case parameters */
|
||||
u8 link_id = test_param->input.link.link_id;
|
||||
bool active = test_param->input.link.active;
|
||||
u8 link_id = test_param->link.link_id;
|
||||
bool active = test_param->link.active;
|
||||
u16 valid_links;
|
||||
struct iwl_mld_kunit_link assoc_link = {
|
||||
.chandef = test_param->input.link.chandef,
|
||||
.chandef = test_param->link.chandef,
|
||||
};
|
||||
|
||||
/* If the link is not active, use a different link as the assoc link */
|
||||
|
|
@ -150,6 +357,11 @@ static void test_link_grading(struct kunit *test)
|
|||
|
||||
vif = iwlmld_kunit_setup_mlo_assoc(valid_links, &assoc_link);
|
||||
|
||||
kunit_activate_static_stub(test, iwl_mld_get_dup_beacon_rssi_adjust,
|
||||
fake_dup_beacon_rssi_adjust);
|
||||
kunit_activate_static_stub(test, iwl_mld_get_psd_eirp_rssi_adjust,
|
||||
fake_psd_eirp_rssi_adjust);
|
||||
|
||||
wiphy_lock(mld->wiphy);
|
||||
link = wiphy_dereference(mld->wiphy, vif->link_conf[link_id]);
|
||||
KUNIT_ASSERT_NOT_NULL(test, link);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* KUnit tests for channel helper functions
|
||||
* KUnit tests for link helper functions
|
||||
*
|
||||
* Copyright (C) 2024-2025 Intel Corporation
|
||||
* Copyright (C) 2024-2026 Intel Corporation
|
||||
*/
|
||||
#include <kunit/static_stub.h>
|
||||
|
||||
|
|
@ -96,8 +96,478 @@ static void test_missed_beacon(struct kunit *test)
|
|||
/* TODO: add test cases for esr and check */
|
||||
}
|
||||
|
||||
struct dup_beacon_test_case {
|
||||
const char *desc;
|
||||
enum nl80211_chan_width bandwidth;
|
||||
bool has_he_oper;
|
||||
bool dup_beacon_bit;
|
||||
s8 expected_adj;
|
||||
};
|
||||
|
||||
static const struct dup_beacon_test_case dup_beacon_cases[] = {
|
||||
{
|
||||
.desc = "20 MHz - no duplication",
|
||||
.bandwidth = NL80211_CHAN_WIDTH_20,
|
||||
.has_he_oper = true,
|
||||
.dup_beacon_bit = true,
|
||||
.expected_adj = 0,
|
||||
},
|
||||
{
|
||||
.desc = "40 MHz with duplication - 3 dB",
|
||||
.bandwidth = NL80211_CHAN_WIDTH_40,
|
||||
.has_he_oper = true,
|
||||
.dup_beacon_bit = true,
|
||||
.expected_adj = 3,
|
||||
},
|
||||
{
|
||||
.desc = "80 MHz with duplication - 6 dB",
|
||||
.bandwidth = NL80211_CHAN_WIDTH_80,
|
||||
.has_he_oper = true,
|
||||
.dup_beacon_bit = true,
|
||||
.expected_adj = 6,
|
||||
},
|
||||
{
|
||||
.desc = "160 MHz with duplication - 9 dB",
|
||||
.bandwidth = NL80211_CHAN_WIDTH_160,
|
||||
.has_he_oper = true,
|
||||
.dup_beacon_bit = true,
|
||||
.expected_adj = 9,
|
||||
},
|
||||
{
|
||||
.desc = "320 MHz with duplication - 12 dB",
|
||||
.bandwidth = NL80211_CHAN_WIDTH_320,
|
||||
.has_he_oper = true,
|
||||
.dup_beacon_bit = true,
|
||||
.expected_adj = 12,
|
||||
},
|
||||
{
|
||||
.desc = "80 MHz without dup bit - no adjustment",
|
||||
.bandwidth = NL80211_CHAN_WIDTH_80,
|
||||
.has_he_oper = true,
|
||||
.dup_beacon_bit = false,
|
||||
.expected_adj = 0,
|
||||
},
|
||||
{
|
||||
.desc = "80 MHz without HE oper - no adjustment",
|
||||
.bandwidth = NL80211_CHAN_WIDTH_80,
|
||||
.has_he_oper = false,
|
||||
.dup_beacon_bit = true,
|
||||
.expected_adj = 0,
|
||||
},
|
||||
};
|
||||
|
||||
KUNIT_ARRAY_PARAM_DESC(test_dup_beacon_rssi_adjust, dup_beacon_cases, desc);
|
||||
|
||||
struct psd_eirp_test_case {
|
||||
const char *desc;
|
||||
const struct cfg80211_chan_def *chandef;
|
||||
enum ieee80211_ap_reg_power power_type;
|
||||
struct {
|
||||
s8 psd_20;
|
||||
s8 psd_oper;
|
||||
s8 eirp_20;
|
||||
s8 eirp_oper;
|
||||
} local, reg;
|
||||
s8 expected_adj;
|
||||
struct {
|
||||
bool no_psd_data;
|
||||
bool no_eirp_data;
|
||||
bool no_reg_psd_data;
|
||||
bool has_partial_psd;
|
||||
u8 psd_partial_count;
|
||||
bool non_uniform_psd;
|
||||
bool has_unusable_channels;
|
||||
} flags;
|
||||
};
|
||||
|
||||
static const struct psd_eirp_test_case psd_eirp_cases[] = {
|
||||
{
|
||||
.desc = "20 MHz VLP baseline - no boost expected",
|
||||
.chandef = &chandef_6ghz_20mhz,
|
||||
.power_type = IEEE80211_REG_VLP_AP,
|
||||
.local = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 40,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 40,
|
||||
},
|
||||
.expected_adj = 0,
|
||||
},
|
||||
{
|
||||
.desc = "40 MHz VLP - power limit prevents boost",
|
||||
.chandef = &chandef_6ghz_40mhz,
|
||||
.power_type = IEEE80211_REG_VLP_AP,
|
||||
.local = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 46,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 46,
|
||||
},
|
||||
.expected_adj = 0,
|
||||
},
|
||||
{
|
||||
.desc = "80 MHz LPI - power limit caps the boost",
|
||||
.chandef = &chandef_6ghz_80mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 52,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 52,
|
||||
},
|
||||
.expected_adj = 3,
|
||||
},
|
||||
{
|
||||
.desc = "160 MHz LPI - power limit caps the boost",
|
||||
.chandef = &chandef_6ghz_160mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 58,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 58,
|
||||
},
|
||||
.expected_adj = 3,
|
||||
},
|
||||
{
|
||||
.desc = "320 MHz SP - power limit caps the boost",
|
||||
.chandef = &chandef_6ghz_320mhz_pri0,
|
||||
.power_type = IEEE80211_REG_SP_AP,
|
||||
.local = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 63,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 63,
|
||||
},
|
||||
.expected_adj = 3,
|
||||
},
|
||||
{
|
||||
.desc = "80 MHz - EIRP prevents boost",
|
||||
.chandef = &chandef_6ghz_80mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 20,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 20,
|
||||
},
|
||||
.expected_adj = 0,
|
||||
},
|
||||
{
|
||||
.desc = "40 MHz - regulatory TPE sets lower limits",
|
||||
.chandef = &chandef_6ghz_40mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = 30, .psd_oper = 30,
|
||||
.eirp_20 = 50, .eirp_oper = 56,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 46,
|
||||
},
|
||||
.expected_adj = 3,
|
||||
},
|
||||
{
|
||||
.desc = "80 MHz - PSD missing, use EIRP only",
|
||||
.chandef = &chandef_6ghz_80mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = S8_MAX, .psd_oper = S8_MAX,
|
||||
.eirp_20 = 40, .eirp_oper = 52,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = S8_MAX, .psd_oper = S8_MAX,
|
||||
.eirp_20 = 40, .eirp_oper = 52,
|
||||
},
|
||||
.expected_adj = 0,
|
||||
.flags.no_psd_data = true,
|
||||
},
|
||||
{
|
||||
.desc = "80 MHz - single PSD source available",
|
||||
.chandef = &chandef_6ghz_80mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 52,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 52,
|
||||
},
|
||||
.expected_adj = 3,
|
||||
.flags.no_reg_psd_data = true,
|
||||
},
|
||||
{
|
||||
.desc = "80 MHz - partial PSD data present",
|
||||
.chandef = &chandef_6ghz_80mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = 24, .psd_oper = 24,
|
||||
.eirp_20 = 40, .eirp_oper = 56,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 24, .psd_oper = 24,
|
||||
.eirp_20 = 40, .eirp_oper = 56,
|
||||
},
|
||||
.expected_adj = 0,
|
||||
.flags.has_partial_psd = true,
|
||||
.flags.psd_partial_count = 2,
|
||||
},
|
||||
{
|
||||
.desc = "160 MHz - different PSD per sub-channel",
|
||||
.chandef = &chandef_6ghz_160mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = 8, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 58,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 8, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 58,
|
||||
},
|
||||
.expected_adj = 11,
|
||||
.flags.non_uniform_psd = true,
|
||||
},
|
||||
{
|
||||
.desc = "80 MHz - EIRP missing, use PSD only",
|
||||
.chandef = &chandef_6ghz_80mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = S8_MAX, .eirp_oper = S8_MAX,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = S8_MAX, .eirp_oper = S8_MAX,
|
||||
},
|
||||
.expected_adj = 3,
|
||||
.flags.no_eirp_data = true,
|
||||
},
|
||||
{
|
||||
.desc = "80 MHz - skip unusable channels in average",
|
||||
.chandef = &chandef_6ghz_80mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 52,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 52,
|
||||
},
|
||||
.expected_adj = 3,
|
||||
.flags.has_unusable_channels = true,
|
||||
},
|
||||
{
|
||||
.desc = "40 MHz - no negative adjustment",
|
||||
.chandef = &chandef_6ghz_40mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 18,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 18,
|
||||
},
|
||||
.expected_adj = 0,
|
||||
},
|
||||
};
|
||||
|
||||
KUNIT_ARRAY_PARAM_DESC(test_psd_eirp_rssi_adjust, psd_eirp_cases, desc);
|
||||
|
||||
static void setup_psd(struct ieee80211_bss_conf *link_conf,
|
||||
const struct psd_eirp_test_case *params,
|
||||
int num_subchannels)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (params->flags.no_psd_data) {
|
||||
link_conf->tpe.psd_local[0].valid = false;
|
||||
link_conf->tpe.psd_reg_client[0].valid = false;
|
||||
link_conf->tpe.psd_local[0].count = 0;
|
||||
link_conf->tpe.psd_reg_client[0].count = 0;
|
||||
} else if (params->flags.no_reg_psd_data) {
|
||||
link_conf->tpe.psd_local[0].valid = true;
|
||||
link_conf->tpe.psd_local[0].count = num_subchannels;
|
||||
link_conf->tpe.psd_reg_client[0].valid = false;
|
||||
link_conf->tpe.psd_reg_client[0].count = 0;
|
||||
} else if (params->flags.has_partial_psd) {
|
||||
link_conf->tpe.psd_local[0].valid = true;
|
||||
link_conf->tpe.psd_local[0].count =
|
||||
params->flags.psd_partial_count;
|
||||
link_conf->tpe.psd_reg_client[0].valid = true;
|
||||
link_conf->tpe.psd_reg_client[0].count =
|
||||
params->flags.psd_partial_count;
|
||||
} else {
|
||||
link_conf->tpe.psd_local[0].valid = true;
|
||||
link_conf->tpe.psd_local[0].count = num_subchannels;
|
||||
link_conf->tpe.psd_reg_client[0].valid = true;
|
||||
link_conf->tpe.psd_reg_client[0].count = num_subchannels;
|
||||
}
|
||||
|
||||
/* TPE element stores PSD limit as value * 2 */
|
||||
if (params->flags.non_uniform_psd) {
|
||||
/* PSD varies per sub-channel: 10/12/10/8 dBm pattern */
|
||||
static const s8 psd_values[] = {20, 24, 20, 16, 20, 24, 20, 16,
|
||||
20, 24, 20, 16, 20, 24, 20};
|
||||
/* Set primary channel (index 0) explicitly */
|
||||
link_conf->tpe.psd_local[0].power[0] =
|
||||
params->local.psd_20 * 2;
|
||||
link_conf->tpe.psd_reg_client[0].power[0] =
|
||||
params->reg.psd_20 * 2;
|
||||
/* Set remaining subchannels with pattern */
|
||||
for (i = 1; i < num_subchannels; i++) {
|
||||
link_conf->tpe.psd_local[0].power[i] =
|
||||
psd_values[i - 1];
|
||||
link_conf->tpe.psd_reg_client[0].power[i] =
|
||||
psd_values[i - 1];
|
||||
}
|
||||
} else if (params->flags.no_psd_data) {
|
||||
for (i = 0; i < num_subchannels; i++) {
|
||||
link_conf->tpe.psd_local[0].power[i] = S8_MAX;
|
||||
link_conf->tpe.psd_reg_client[0].power[i] = S8_MAX;
|
||||
}
|
||||
} else if (params->flags.has_unusable_channels) {
|
||||
/* Alternate usable/unusable channels for S8_MIN test */
|
||||
/* Set primary channel (index 0) explicitly */
|
||||
link_conf->tpe.psd_local[0].power[0] =
|
||||
params->local.psd_20 * 2;
|
||||
link_conf->tpe.psd_reg_client[0].power[0] =
|
||||
params->reg.psd_20 * 2;
|
||||
/* Alternate usable/unusable for remaining subchannels */
|
||||
for (i = 1; i < num_subchannels; i++) {
|
||||
if (i % 2 == 0) {
|
||||
link_conf->tpe.psd_local[0].power[i] =
|
||||
params->local.psd_oper * 2;
|
||||
link_conf->tpe.psd_reg_client[0].power[i] =
|
||||
params->reg.psd_oper * 2;
|
||||
} else {
|
||||
link_conf->tpe.psd_local[0].power[i] = S8_MIN;
|
||||
link_conf->tpe.psd_reg_client[0].power[i] =
|
||||
S8_MIN;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Set primary channel (index 0) separately */
|
||||
link_conf->tpe.psd_local[0].power[0] =
|
||||
params->local.psd_20 * 2;
|
||||
link_conf->tpe.psd_reg_client[0].power[0] =
|
||||
params->reg.psd_20 * 2;
|
||||
/* Set remaining subchannels */
|
||||
for (i = 1; i < num_subchannels; i++) {
|
||||
link_conf->tpe.psd_local[0].power[i] =
|
||||
params->local.psd_oper * 2;
|
||||
link_conf->tpe.psd_reg_client[0].power[i] =
|
||||
params->reg.psd_oper * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_eirp(struct ieee80211_bss_conf *link_conf,
|
||||
const struct psd_eirp_test_case *params,
|
||||
int num_subchannels)
|
||||
{
|
||||
int i;
|
||||
int count = ilog2(num_subchannels) + 1;
|
||||
|
||||
link_conf->tpe.max_local[0].valid = !params->flags.no_eirp_data;
|
||||
link_conf->tpe.max_reg_client[0].valid = !params->flags.no_eirp_data;
|
||||
|
||||
if (params->flags.no_eirp_data) {
|
||||
link_conf->tpe.max_local[0].count = 0;
|
||||
link_conf->tpe.max_reg_client[0].count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
link_conf->tpe.max_local[0].count = count;
|
||||
link_conf->tpe.max_reg_client[0].count = count;
|
||||
|
||||
/* TPE element stores EIRP limit as value * 2 */
|
||||
link_conf->tpe.max_local[0].power[0] = params->local.eirp_20 * 2;
|
||||
link_conf->tpe.max_reg_client[0].power[0] = params->reg.eirp_20 * 2;
|
||||
for (i = 1; i < count; i++) {
|
||||
link_conf->tpe.max_local[0].power[i] =
|
||||
params->local.eirp_oper * 2;
|
||||
link_conf->tpe.max_reg_client[0].power[i] =
|
||||
params->reg.eirp_oper * 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_dup_beacon_rssi_adjust(struct kunit *test)
|
||||
{
|
||||
const struct dup_beacon_test_case *params = test->param_value;
|
||||
struct iwl_mld *mld = test->priv;
|
||||
struct ieee80211_bss_conf *link_conf;
|
||||
struct cfg80211_bss *bss;
|
||||
struct element *he_elem = NULL;
|
||||
s8 result;
|
||||
|
||||
KUNIT_ALLOC_AND_ASSERT(test, link_conf);
|
||||
KUNIT_ALLOC_AND_ASSERT(test, bss);
|
||||
link_conf->bss = bss;
|
||||
|
||||
link_conf->chanreq.oper.chan = &chan_6ghz;
|
||||
link_conf->chanreq.oper.width = params->bandwidth;
|
||||
|
||||
if (params->has_he_oper) {
|
||||
struct ieee80211_he_6ghz_oper he_6ghz = {};
|
||||
|
||||
if (params->dup_beacon_bit)
|
||||
he_6ghz.control =
|
||||
IEEE80211_HE_6GHZ_OPER_CTRL_DUP_BEACON;
|
||||
he_elem = iwlmld_kunit_create_he_6ghz_oper(he_6ghz);
|
||||
}
|
||||
|
||||
rcu_assign_pointer(bss->beacon_ies,
|
||||
iwlmld_kunit_create_bss_ies(he_elem));
|
||||
|
||||
guard(wiphy)(mld->wiphy);
|
||||
result = iwl_mld_get_dup_beacon_rssi_adjust(mld, link_conf);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, result, params->expected_adj);
|
||||
}
|
||||
|
||||
static void test_psd_eirp_rssi_adjust(struct kunit *test)
|
||||
{
|
||||
const struct psd_eirp_test_case *params = test->param_value;
|
||||
struct ieee80211_bss_conf *link_conf;
|
||||
int num_subchannels;
|
||||
s8 result;
|
||||
|
||||
KUNIT_ALLOC_AND_ASSERT(test, link_conf);
|
||||
|
||||
link_conf->power_type = params->power_type;
|
||||
link_conf->chanreq.oper = *params->chandef;
|
||||
num_subchannels =
|
||||
nl80211_chan_width_to_mhz(params->chandef->width) / 20;
|
||||
|
||||
setup_psd(link_conf, params, num_subchannels);
|
||||
setup_eirp(link_conf, params, num_subchannels);
|
||||
|
||||
result = iwl_mld_get_psd_eirp_rssi_adjust(link_conf);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, result, params->expected_adj);
|
||||
}
|
||||
|
||||
static struct kunit_case link_cases[] = {
|
||||
KUNIT_CASE_PARAM(test_missed_beacon, test_missed_beacon_gen_params),
|
||||
KUNIT_CASE_PARAM(test_dup_beacon_rssi_adjust,
|
||||
test_dup_beacon_rssi_adjust_gen_params),
|
||||
KUNIT_CASE_PARAM(test_psd_eirp_rssi_adjust,
|
||||
test_psd_eirp_rssi_adjust_gen_params),
|
||||
{},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -439,6 +439,66 @@ struct ieee80211_vif *iwlmld_kunit_assoc_emlsr(struct iwl_mld_kunit_link *link1,
|
|||
return vif;
|
||||
}
|
||||
|
||||
struct element *
|
||||
iwlmld_kunit_create_he_6ghz_oper(struct ieee80211_he_6ghz_oper he_6ghz)
|
||||
{
|
||||
struct kunit *test = kunit_get_current_test();
|
||||
u8 *data;
|
||||
size_t data_len;
|
||||
size_t offset = 0;
|
||||
__le32 he_oper_params;
|
||||
__le16 he_mcs_nss_set = 0;
|
||||
|
||||
/* Build HE Operation IE with 6 GHz info using raw buffer.
|
||||
* Cannot use struct embedding because ieee80211_he_operation
|
||||
* has a flexible array member (optional[]).
|
||||
*
|
||||
* Layout:
|
||||
* 1 byte: ext_id (WLAN_EID_EXT_HE_OPERATION)
|
||||
* he_oper_params: he_oper_params (from ieee80211_he_operation)
|
||||
* he_mcs_nss_set: he_mcs_nss_set (from ieee80211_he_operation)
|
||||
* he_6ghz: ieee80211_he_6ghz_oper (goes into optional[])
|
||||
*/
|
||||
data_len = 1 + sizeof(he_oper_params) + sizeof(he_mcs_nss_set) +
|
||||
sizeof(struct ieee80211_he_6ghz_oper);
|
||||
|
||||
data = kunit_kzalloc(test, data_len, GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, data);
|
||||
|
||||
data[offset++] = WLAN_EID_EXT_HE_OPERATION;
|
||||
|
||||
he_oper_params = cpu_to_le32(IEEE80211_HE_OPERATION_6GHZ_OP_INFO);
|
||||
memcpy(&data[offset], &he_oper_params, sizeof(he_oper_params));
|
||||
offset += sizeof(he_oper_params);
|
||||
|
||||
memcpy(&data[offset], &he_mcs_nss_set, sizeof(he_mcs_nss_set));
|
||||
offset += sizeof(he_mcs_nss_set);
|
||||
|
||||
memcpy(&data[offset], &he_6ghz, sizeof(he_6ghz));
|
||||
|
||||
return iwlmld_kunit_gen_element(WLAN_EID_EXTENSION, data, data_len);
|
||||
}
|
||||
|
||||
struct cfg80211_bss_ies *iwlmld_kunit_create_bss_ies(struct element *elem)
|
||||
{
|
||||
struct kunit *test = kunit_get_current_test();
|
||||
struct cfg80211_bss_ies *ies;
|
||||
size_t ies_len = 0;
|
||||
|
||||
if (elem)
|
||||
ies_len = sizeof(*elem) + elem->datalen;
|
||||
|
||||
ies = kunit_kzalloc(test, sizeof(*ies) + ies_len, GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, ies);
|
||||
|
||||
ies->len = ies_len;
|
||||
|
||||
if (elem)
|
||||
memcpy(ies->data, elem, ies_len);
|
||||
|
||||
return ies;
|
||||
}
|
||||
|
||||
struct element *iwlmld_kunit_gen_element(u8 id, const void *data, size_t len)
|
||||
{
|
||||
struct kunit *test = kunit_get_current_test();
|
||||
|
|
|
|||
|
|
@ -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_kunit_utils_h__
|
||||
|
|
@ -77,6 +77,8 @@ CHANNEL(chan_6ghz_221, NL80211_BAND_6GHZ, 7055);
|
|||
NL80211_CHAN_WIDTH_160) \
|
||||
CHANDEF(chandef_6ghz_320mhz, chan_6ghz, 6105, \
|
||||
NL80211_CHAN_WIDTH_320) \
|
||||
CHANDEF(chandef_6ghz_320mhz_pri0, chan_6ghz, 6265, \
|
||||
NL80211_CHAN_WIDTH_320) \
|
||||
CHANDEF(chandef_6ghz_221_160mhz, chan_6ghz_221, 6985, \
|
||||
NL80211_CHAN_WIDTH_160) \
|
||||
/* Feel free to add more */
|
||||
|
|
@ -121,6 +123,11 @@ iwlmld_kunit_assoc_emlsr(struct iwl_mld_kunit_link *link1,
|
|||
|
||||
struct element *iwlmld_kunit_gen_element(u8 id, const void *data, size_t len);
|
||||
|
||||
struct element *
|
||||
iwlmld_kunit_create_he_6ghz_oper(struct ieee80211_he_6ghz_oper he_6ghz);
|
||||
|
||||
struct cfg80211_bss_ies *iwlmld_kunit_create_bss_ies(struct element *elem);
|
||||
|
||||
/**
|
||||
* iwlmld_kunit_get_phy_of_link - Get the phy of a link
|
||||
*
|
||||
|
|
|
|||
|
|
@ -467,65 +467,6 @@ iwl_mld_fill_supp_rates(struct iwl_mld *mld,
|
|||
}
|
||||
}
|
||||
|
||||
static int iwl_mld_convert_tlc_cmd_to_v5(struct iwl_tlc_config_cmd *cmd,
|
||||
struct iwl_tlc_config_cmd_v5 *cmd_v5)
|
||||
{
|
||||
if (WARN_ON_ONCE(hweight32(le32_to_cpu(cmd->sta_mask)) != 1))
|
||||
return -EINVAL;
|
||||
|
||||
/* Convert sta_mask to sta_id */
|
||||
cmd_v5->sta_id = __ffs(le32_to_cpu(cmd->sta_mask));
|
||||
|
||||
/* Copy all the rest */
|
||||
cmd_v5->max_ch_width = cmd->max_ch_width;
|
||||
cmd_v5->mode = cmd->mode;
|
||||
cmd_v5->chains = cmd->chains;
|
||||
cmd_v5->sgi_ch_width_supp = cmd->sgi_ch_width_supp;
|
||||
cmd_v5->flags = cmd->flags;
|
||||
cmd_v5->non_ht_rates = cmd->non_ht_rates;
|
||||
|
||||
BUILD_BUG_ON(sizeof(cmd_v5->ht_rates) != sizeof(cmd->ht_rates));
|
||||
memcpy(cmd_v5->ht_rates, cmd->ht_rates, sizeof(cmd->ht_rates));
|
||||
|
||||
cmd_v5->max_mpdu_len = cmd->max_mpdu_len;
|
||||
cmd_v5->max_tx_op = cmd->max_tx_op;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_mld_convert_tlc_cmd_to_v4(struct iwl_tlc_config_cmd *cmd,
|
||||
struct iwl_tlc_config_cmd_v4 *cmd_v4)
|
||||
{
|
||||
if (WARN_ON_ONCE(hweight32(le32_to_cpu(cmd->sta_mask)) != 1))
|
||||
return -EINVAL;
|
||||
|
||||
/* Convert sta_mask to sta_id */
|
||||
cmd_v4->sta_id = __ffs(le32_to_cpu(cmd->sta_mask));
|
||||
|
||||
/* Copy everything until ht_rates */
|
||||
cmd_v4->max_ch_width = cmd->max_ch_width;
|
||||
cmd_v4->mode = cmd->mode;
|
||||
cmd_v4->chains = cmd->chains;
|
||||
cmd_v4->sgi_ch_width_supp = cmd->sgi_ch_width_supp;
|
||||
cmd_v4->flags = cmd->flags;
|
||||
cmd_v4->non_ht_rates = cmd->non_ht_rates;
|
||||
|
||||
/* Convert ht_rates from __le32 to __le16 */
|
||||
BUILD_BUG_ON(ARRAY_SIZE(cmd_v4->ht_rates) != ARRAY_SIZE(cmd->ht_rates));
|
||||
BUILD_BUG_ON(ARRAY_SIZE(cmd_v4->ht_rates[0]) != ARRAY_SIZE(cmd->ht_rates[0]));
|
||||
|
||||
for (int nss = 0; nss < ARRAY_SIZE(cmd->ht_rates); nss++)
|
||||
for (int bw = 0; bw < ARRAY_SIZE(cmd->ht_rates[nss]); bw++)
|
||||
cmd_v4->ht_rates[nss][bw] =
|
||||
cpu_to_le16(le32_to_cpu(cmd->ht_rates[nss][bw]));
|
||||
|
||||
/* Copy the rest */
|
||||
cmd_v4->max_mpdu_len = cmd->max_mpdu_len;
|
||||
cmd_v4->max_tx_op = cmd->max_tx_op;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void iwl_mld_send_tlc_cmd(struct iwl_mld *mld,
|
||||
struct ieee80211_vif *vif,
|
||||
struct iwl_mld_sta *mld_sta,
|
||||
|
|
@ -544,8 +485,6 @@ static void iwl_mld_send_tlc_cmd(struct iwl_mld *mld,
|
|||
};
|
||||
u32 cmd_id = WIDE_ID(DATA_PATH_GROUP, TLC_MNG_CONFIG_CMD);
|
||||
u8 cmd_ver = iwl_fw_lookup_cmd_ver(mld->fw, cmd_id, 0);
|
||||
struct iwl_tlc_config_cmd_v5 cmd_v5 = {};
|
||||
struct iwl_tlc_config_cmd_v4 cmd_v4 = {};
|
||||
void *cmd_ptr;
|
||||
u8 cmd_size;
|
||||
int ret;
|
||||
|
|
@ -558,19 +497,6 @@ static void iwl_mld_send_tlc_cmd(struct iwl_mld *mld,
|
|||
if (cmd_ver == 6) {
|
||||
cmd_ptr = &cmd;
|
||||
cmd_size = sizeof(cmd);
|
||||
} else if (cmd_ver == 5) {
|
||||
/* TODO: remove support once FW moves to version 6 */
|
||||
ret = iwl_mld_convert_tlc_cmd_to_v5(&cmd, &cmd_v5);
|
||||
if (ret)
|
||||
return;
|
||||
cmd_ptr = &cmd_v5;
|
||||
cmd_size = sizeof(cmd_v5);
|
||||
} else if (cmd_ver == 4) {
|
||||
ret = iwl_mld_convert_tlc_cmd_to_v4(&cmd, &cmd_v4);
|
||||
if (ret)
|
||||
return;
|
||||
cmd_ptr = &cmd_v4;
|
||||
cmd_size = sizeof(cmd_v4);
|
||||
} else {
|
||||
IWL_ERR(mld, "Unsupported TLC config cmd version %d\n",
|
||||
cmd_ver);
|
||||
|
|
|
|||
|
|
@ -563,7 +563,8 @@ iwl_mld_fill_tx_cmd(struct iwl_mld *mld, struct sk_buff *skb,
|
|||
* - when no sta is given.
|
||||
* - frames that are sent to an NMI sta, which is only used for management.
|
||||
*/
|
||||
if (unlikely(!sta || mld_sta->vif->type == NL80211_IFTYPE_NAN ||
|
||||
if (unlikely(!sta ||
|
||||
(mld_sta && mld_sta->vif->type == NL80211_IFTYPE_NAN) ||
|
||||
info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT)) {
|
||||
flags |= IWL_TX_FLAGS_CMD_RATE;
|
||||
rate_n_flags = iwl_mld_get_tx_rate_n_flags(mld, info, sta,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2014, 2020 Intel Corporation
|
||||
* Copyright (C) 2016 Intel Deutschland GmbH
|
||||
* Copyright (C) 2022, 2024 Intel Corporation
|
||||
* Copyright (C) 2022, 2024, 2026 Intel Corporation
|
||||
*/
|
||||
#include <net/mac80211.h>
|
||||
#include "fw-api.h"
|
||||
|
|
@ -76,6 +76,9 @@ static void iwl_mvm_iface_iterator(void *_data, u8 *mac,
|
|||
if (vif == data->ignore_vif)
|
||||
return;
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_P2P_DEVICE && !mvmvif->p2p_in_binding)
|
||||
return;
|
||||
|
||||
if (mvmvif->deflink.phy_ctxt != data->phyctxt)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -935,9 +935,9 @@ u16 iwl_mvm_mac_ctxt_get_beacon_flags(const struct iwl_fw *fw, u8 rate_idx)
|
|||
: IWL_MAC_BEACON_CCK_V1;
|
||||
|
||||
if (iwl_fw_lookup_cmd_ver(fw, TX_CMD, 0) > 8)
|
||||
flags |= iwl_mvm_mac80211_idx_to_hwrate(fw, rate_idx);
|
||||
flags |= iwl_mvm_rate_idx_to_fw_idx(fw, rate_idx);
|
||||
else
|
||||
flags |= iwl_fw_rate_idx_to_plcp(rate_idx);
|
||||
flags |= iwl_mvm_rate_idx_to_plcp(rate_idx);
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
|
@ -998,7 +998,7 @@ static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm,
|
|||
else
|
||||
rate_n_flags |= RATE_MCS_MOD_TYPE_LEGACY_OFDM;
|
||||
|
||||
rate_n_flags |= iwl_mvm_mac80211_idx_to_hwrate(mvm->fw, rate);
|
||||
rate_n_flags |= iwl_mvm_rate_idx_to_fw_idx(mvm->fw, rate);
|
||||
|
||||
tx_params->rate_n_flags = iwl_mvm_v3_rate_to_fw(rate_n_flags,
|
||||
mvm->fw_rates_ver);
|
||||
|
|
|
|||
|
|
@ -1104,6 +1104,7 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
|
|||
spin_unlock_bh(&mvm->time_event_lock);
|
||||
|
||||
mvmvif->roc_activity = ROC_NUM_ACTIVITIES;
|
||||
mvmvif->p2p_in_binding = false;
|
||||
|
||||
mvmvif->bf_enabled = false;
|
||||
mvmvif->ba_enabled = false;
|
||||
|
|
@ -4634,6 +4635,7 @@ static int iwl_mvm_add_aux_sta_for_hs20(struct iwl_mvm *mvm, u32 lmac_id)
|
|||
|
||||
static int iwl_mvm_roc_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
|
@ -4642,10 +4644,18 @@ static int iwl_mvm_roc_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
|||
if (WARN(ret, "Failed binding P2P_DEVICE\n"))
|
||||
return ret;
|
||||
|
||||
mvmvif->p2p_in_binding = true;
|
||||
|
||||
/* The station and queue allocation must be done only after the binding
|
||||
* is done, as otherwise the FW might incorrectly configure its state.
|
||||
*/
|
||||
return iwl_mvm_add_p2p_bcast_sta(mvm, vif);
|
||||
ret = iwl_mvm_add_p2p_bcast_sta(mvm, vif);
|
||||
if (ret) {
|
||||
iwl_mvm_binding_remove_vif(mvm, vif);
|
||||
mvmvif->p2p_in_binding = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iwl_mvm_roc(struct ieee80211_hw *hw,
|
||||
|
|
|
|||
|
|
@ -383,6 +383,8 @@ struct iwl_mvm_vif_link_info {
|
|||
* @pm_enabled: indicates powersave is enabled
|
||||
* @roc_activity: currently running ROC activity for this vif (or
|
||||
* ROC_NUM_ACTIVITIES if no activity is running).
|
||||
* @p2p_in_binding: indicates that this P2P-Device interface should be
|
||||
* added to the binding, i.e. is running ROC right now
|
||||
* @session_prot_connection_loss: the connection was lost due to session
|
||||
* protection ending without receiving a beacon, so we need to now
|
||||
* protect the deauth separately
|
||||
|
|
@ -492,6 +494,7 @@ struct iwl_mvm_vif {
|
|||
struct iwl_mvm_time_event_data time_event_data;
|
||||
struct iwl_mvm_time_event_data hs_time_event_data;
|
||||
enum iwl_roc_activity roc_activity;
|
||||
bool p2p_in_binding;
|
||||
|
||||
/* TCP Checksum Offload */
|
||||
netdev_features_t features;
|
||||
|
|
@ -1646,6 +1649,7 @@ int __iwl_mvm_mac_start(struct iwl_mvm *mvm);
|
|||
int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm);
|
||||
|
||||
/* Utils */
|
||||
u8 iwl_mvm_rate_idx_to_plcp(int idx);
|
||||
int iwl_mvm_legacy_hw_idx_to_mac80211_idx(u32 rate_n_flags,
|
||||
enum nl80211_band band);
|
||||
int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags,
|
||||
|
|
@ -1653,7 +1657,7 @@ int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags,
|
|||
void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags,
|
||||
enum nl80211_band band,
|
||||
struct ieee80211_tx_rate *r);
|
||||
u8 iwl_mvm_mac80211_idx_to_hwrate(const struct iwl_fw *fw, int rate_idx);
|
||||
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);
|
||||
|
||||
|
|
@ -1669,16 +1673,16 @@ void iwl_mvm_get_sync_time(struct iwl_mvm *mvm, int clock_type, u32 *gp2,
|
|||
u32 iwl_mvm_get_systime(struct iwl_mvm *mvm);
|
||||
|
||||
/* Tx / Host Commands */
|
||||
int __must_check iwl_mvm_send_cmd(struct iwl_mvm *mvm,
|
||||
struct iwl_host_cmd *cmd);
|
||||
int __must_check iwl_mvm_send_cmd_pdu(struct iwl_mvm *mvm, u32 id,
|
||||
u32 flags, u16 len, const void *data);
|
||||
int __must_check iwl_mvm_send_cmd_status(struct iwl_mvm *mvm,
|
||||
struct iwl_host_cmd *cmd,
|
||||
u32 *status);
|
||||
int __must_check iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u32 id,
|
||||
u16 len, const void *data,
|
||||
u32 *status);
|
||||
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_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_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);
|
||||
|
|
|
|||
|
|
@ -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) 2017 Intel Deutschland GmbH
|
||||
*/
|
||||
|
|
@ -88,6 +88,7 @@ static void iwl_mvm_cleanup_roc(struct iwl_mvm *mvm)
|
|||
} else {
|
||||
iwl_mvm_rm_p2p_bcast_sta(mvm, vif);
|
||||
iwl_mvm_binding_remove_vif(mvm, vif);
|
||||
mvmvif->p2p_in_binding = false;
|
||||
}
|
||||
|
||||
/* Do not remove the PHY context as removing and adding
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
@ -268,7 +268,6 @@ static u32 iwl_mvm_convert_rate_idx(struct iwl_mvm *mvm,
|
|||
int rate_idx)
|
||||
{
|
||||
u32 rate_flags = 0;
|
||||
u8 rate_plcp;
|
||||
bool is_cck;
|
||||
|
||||
/* if the rate isn't a well known legacy rate, take the lowest one */
|
||||
|
|
@ -277,8 +276,9 @@ static u32 iwl_mvm_convert_rate_idx(struct iwl_mvm *mvm,
|
|||
info,
|
||||
info->control.vif);
|
||||
|
||||
/* Get PLCP rate for tx_cmd->rate_n_flags */
|
||||
rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(mvm->fw, rate_idx);
|
||||
/* Get FW rate for tx_cmd->rate_n_flags */
|
||||
rate_flags |= iwl_mvm_rate_idx_to_fw_idx(mvm->fw, rate_idx);
|
||||
|
||||
is_cck = (rate_idx >= IWL_FIRST_CCK_RATE) &&
|
||||
(rate_idx <= IWL_LAST_CCK_RATE);
|
||||
|
||||
|
|
@ -288,7 +288,7 @@ static u32 iwl_mvm_convert_rate_idx(struct iwl_mvm *mvm,
|
|||
else
|
||||
rate_flags |= RATE_MCS_MOD_TYPE_CCK;
|
||||
|
||||
return (u32)rate_plcp | rate_flags;
|
||||
return rate_flags;
|
||||
}
|
||||
|
||||
static u32 iwl_mvm_get_inject_tx_rate(struct iwl_mvm *mvm,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,30 @@
|
|||
#include "fw/api/rs.h"
|
||||
#include "fw/img.h"
|
||||
|
||||
#define IWL_DECLARE_RATE_INFO(r) \
|
||||
[IWL_RATE_##r##M_INDEX] = IWL_RATE_##r##M_PLCP
|
||||
|
||||
/* Translate from fw_rate_index (IWL_RATE_XXM_INDEX) to PLCP */
|
||||
static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = {
|
||||
IWL_DECLARE_RATE_INFO(1),
|
||||
IWL_DECLARE_RATE_INFO(2),
|
||||
IWL_DECLARE_RATE_INFO(5),
|
||||
IWL_DECLARE_RATE_INFO(11),
|
||||
IWL_DECLARE_RATE_INFO(6),
|
||||
IWL_DECLARE_RATE_INFO(9),
|
||||
IWL_DECLARE_RATE_INFO(12),
|
||||
IWL_DECLARE_RATE_INFO(18),
|
||||
IWL_DECLARE_RATE_INFO(24),
|
||||
IWL_DECLARE_RATE_INFO(36),
|
||||
IWL_DECLARE_RATE_INFO(48),
|
||||
IWL_DECLARE_RATE_INFO(54),
|
||||
};
|
||||
|
||||
u8 iwl_mvm_rate_idx_to_plcp(int idx)
|
||||
{
|
||||
return fw_rate_idx_to_plcp[idx];
|
||||
}
|
||||
|
||||
/*
|
||||
* Will return 0 even if the cmd failed when RFKILL is asserted unless
|
||||
* CMD_WANT_SKB is set in cmd->flags.
|
||||
|
|
@ -151,13 +175,13 @@ int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags,
|
|||
if (band != NL80211_BAND_2GHZ)
|
||||
band_offset = IWL_FIRST_OFDM_RATE;
|
||||
for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++)
|
||||
if (iwl_fw_rate_idx_to_plcp(idx) == rate)
|
||||
if (iwl_mvm_rate_idx_to_plcp(idx) == rate)
|
||||
return idx - band_offset;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
u8 iwl_mvm_mac80211_idx_to_hwrate(const struct iwl_fw *fw, int rate_idx)
|
||||
u8 iwl_mvm_rate_idx_to_fw_idx(const struct iwl_fw *fw, int rate_idx)
|
||||
{
|
||||
return rate_idx >= IWL_FIRST_OFDM_RATE ?
|
||||
rate_idx - IWL_FIRST_OFDM_RATE :
|
||||
|
|
@ -1243,7 +1267,7 @@ static u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags)
|
|||
int last = ofdm ? IWL_RATE_COUNT_LEGACY : IWL_FIRST_OFDM_RATE;
|
||||
|
||||
for (idx = offset; idx < last; idx++)
|
||||
if (iwl_fw_rate_idx_to_plcp(idx) == rate)
|
||||
if (iwl_mvm_rate_idx_to_plcp(idx) == rate)
|
||||
return idx - offset;
|
||||
return IWL_RATE_INVALID;
|
||||
}
|
||||
|
|
@ -1353,7 +1377,7 @@ __le32 iwl_mvm_v3_rate_to_fw(u32 rate, u8 rate_ver)
|
|||
rate_idx = u32_get_bits(rate, RATE_LEGACY_RATE_MSK);
|
||||
if (!(result & RATE_MCS_CCK_MSK_V1))
|
||||
rate_idx += IWL_FIRST_OFDM_RATE;
|
||||
result |= u32_encode_bits(iwl_fw_rate_idx_to_plcp(rate_idx),
|
||||
result |= u32_encode_bits(iwl_mvm_rate_idx_to_plcp(rate_idx),
|
||||
RATE_LEGACY_RATE_MSK_V1);
|
||||
break;
|
||||
case RATE_MCS_MOD_TYPE_HT:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2005-2014, 2018-2025 Intel Corporation
|
||||
* Copyright (C) 2005-2014, 2018-2026 Intel Corporation
|
||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
|
|
@ -1016,6 +1016,7 @@ VISIBLE_IF_IWLWIFI_KUNIT const struct iwl_dev_info iwl_dev_info_table[] = {
|
|||
|
||||
/* GF RF */
|
||||
IWL_DEV_INFO(iwl_rf_gf, iwl_ax211_name, RF_TYPE(GF)),
|
||||
IWL_DEV_INFO(iwl_rf_ot, iwl_ax231_name, RF_TYPE(GF), SUBDEV(0x0294)),
|
||||
IWL_DEV_INFO(iwl_rf_gf, iwl_ax411_name, RF_TYPE(GF), CDB),
|
||||
IWL_DEV_INFO(iwl_rf_gf, iwl_ax210_name, DEVICE(0x2725)),
|
||||
|
||||
|
|
|
|||
|
|
@ -1203,6 +1203,7 @@ void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg,
|
|||
int iwl_trans_pcie_read_config32(struct iwl_trans *trans, u32 ofs,
|
||||
u32 *val);
|
||||
bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans);
|
||||
void iwl_trans_pcie_resched_with_nic_access(struct iwl_trans *trans);
|
||||
void __releases(nic_access_nobh)
|
||||
iwl_trans_pcie_release_nic_access(struct iwl_trans *trans);
|
||||
void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans, u8 max_power);
|
||||
|
|
|
|||
|
|
@ -376,6 +376,7 @@ static void iwl_pcie_get_rf_name(struct iwl_trans *trans)
|
|||
void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
u32 step_reg;
|
||||
|
||||
iwl_pcie_reset_ict(trans);
|
||||
|
||||
|
|
@ -404,10 +405,13 @@ void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans)
|
|||
iwl_pcie_get_rf_name(trans);
|
||||
mutex_unlock(&trans_pcie->mutex);
|
||||
|
||||
if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
|
||||
trans->step_urm = !!(iwl_read_prph(trans,
|
||||
CNVI_PMU_STEP_FLOW) &
|
||||
CNVI_PMU_STEP_FLOW_FORCE_URM);
|
||||
if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_BZ)
|
||||
return;
|
||||
|
||||
step_reg = trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_SC ?
|
||||
CNVI_PMU_STEP_FLOW_SC : CNVI_PMU_STEP_FLOW_BZ;
|
||||
trans->step_urm = !!(iwl_read_prph(trans, step_reg) &
|
||||
CNVI_PMU_STEP_FLOW_FORCE_URM);
|
||||
}
|
||||
|
||||
static bool iwl_pcie_set_ltr(struct iwl_trans *trans)
|
||||
|
|
|
|||
|
|
@ -521,7 +521,6 @@ static int iwl_pcie_nic_init(struct iwl_trans *trans)
|
|||
|
||||
#define HW_READY_TIMEOUT (50)
|
||||
|
||||
/* Note: returns poll_bit return value, which is >= 0 if success */
|
||||
static int iwl_pcie_set_hw_ready(struct iwl_trans *trans)
|
||||
{
|
||||
int ret;
|
||||
|
|
@ -2424,7 +2423,7 @@ bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans)
|
|||
return false;
|
||||
}
|
||||
|
||||
static void iwl_trans_pcie_resched_with_nic_access(struct iwl_trans *trans)
|
||||
void iwl_trans_pcie_resched_with_nic_access(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
|
|
@ -2591,7 +2590,7 @@ int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans, int txq_idx)
|
|||
struct iwl_txq *txq;
|
||||
unsigned long now = jiffies;
|
||||
bool overflow_tx;
|
||||
u8 wr_ptr;
|
||||
int wr_ptr;
|
||||
|
||||
/* Make sure the NIC is still alive in the bus */
|
||||
if (test_bit(STATUS_TRANS_DEAD, &trans->status))
|
||||
|
|
@ -2614,7 +2613,7 @@ int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans, int txq_idx)
|
|||
overflow_tx) &&
|
||||
!time_after(jiffies,
|
||||
now + msecs_to_jiffies(IWL_FLUSH_WAIT_MS))) {
|
||||
u8 write_ptr = READ_ONCE(txq->write_ptr);
|
||||
int write_ptr = READ_ONCE(txq->write_ptr);
|
||||
|
||||
/*
|
||||
* If write pointer moved during the wait, warn only
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user