iwlwifi patches for v5.13

* Add support for new FTM FW APIs;
 * Some CSA fixes;
 * Support for new HW family and other HW detection fixes;
 * Robustness improvement in the HW detection code;
 * One fix in PMF;
 * Some new regulatory features;
 * Support for passive scan in 6GHz;
 * Some improvements in the sync queue implementation;
 * Support for new devices;
 * Support for a new FW API command version;
 * Some locking fixes;
 * Bump the FW API version support for AX devices;
 * Some other small fixes, clean-ups and improvements.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEF3LNfgb2BPWm68smoUecoho8xfoFAmB2tukACgkQoUecoho8
 xfob8w/+Oih7yNEBrz/nwDRmZmHgjM2+XZjOucwLBbwBbv9SnGtpohBa4Fuy/Ekw
 Gi6dGWBBn4U8QxRGVG3UMztlZSVpeWuqbqLyG0VyST66rCncLK0quxV2y4jt06mH
 BJ/hcPpYmUzRInegFhfEgAXKoy06/CsHyjiX23ZKVCSONRxZstJ9wcSwmzknpDM6
 eADa5za9Yynndlp0yHpOtOKpt2YMogmWhKyhiq54hPsbJsnblxHYuGCO1g4aYiQV
 YMMO+gM91Ux5sBmcGJMlzfBbzmJ/ieQ+u/mNaPb77sNglB5xS7diNE2LlsFxmeWS
 SafQWhezbs+EdjSHlKXBw61ZStlrIMKVAHY4yYcJwrwpRot0C7JymvpJ6lDRYLz1
 Hw+diqQcQqpTA9vFsHhtdqZwgpg55b+QU+P07WNlXehheenfg7f0vDYaVgiIl3j/
 K+eZXo9DWX5Bf1SgriBnnDQd4XA2KYg9ViEswJ/AUHl3GtHwLdwOa3fB+GLCKFgX
 PlYAxJitYeVf5kDDVdxnP+DXOZO4HGD6WwFl5GU3nTdT3Fg4ZJ6/UCsG4hINjNiK
 OAO3b6N2xExHanVjCZwuMLG27fxXwnbZBtg5XGrjznLZrMaiQL/A81DEvVXCVBFq
 1i/37EYdZpca5IRRXBw0V84q4z/kIekpPCCLAOawmEcj6XOZBRQ=
 =dm69
 -----END PGP SIGNATURE-----

Merge tag 'iwlwifi-next-for-kalle-2021-04-12-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next

iwlwifi patches for v5.13

* Add support for new FTM FW APIs;
* Some CSA fixes;
* Support for new HW family and other HW detection fixes;
* Robustness improvement in the HW detection code;
* One fix in PMF;
* Some new regulatory features;
* Support for passive scan in 6GHz;
* Some improvements in the sync queue implementation;
* Support for new devices;
* Support for a new FW API command version;
* Some locking fixes;
* Bump the FW API version support for AX devices;
* Some other small fixes, clean-ups and improvements.

# gpg: Signature made Wed 14 Apr 2021 12:33:29 PM EEST using RSA key ID 1A3CC5FA
# gpg: Good signature from "Luciano Roth Coelho (Luca) <luca@coelho.fi>"
# gpg:                 aka "Luciano Roth Coelho (Intel) <luciano.coelho@intel.com>"
This commit is contained in:
Kalle Valo 2021-04-17 11:38:01 +03:00
commit 197b9c152b
44 changed files with 1111 additions and 550 deletions

View File

@ -9,7 +9,7 @@
#include "iwl-prph.h"
/* Highest firmware API version supported */
#define IWL_22000_UCODE_API_MAX 62
#define IWL_22000_UCODE_API_MAX 63
/* Lowest firmware API version supported */
#define IWL_22000_UCODE_API_MIN 39
@ -48,6 +48,10 @@
#define IWL_MA_A_GF4_A_FW_PRE "iwlwifi-ma-a0-gf4-a0-"
#define IWL_MA_A_MR_A_FW_PRE "iwlwifi-ma-a0-mr-a0-"
#define IWL_SNJ_A_MR_A_FW_PRE "iwlwifi-SoSnj-a0-mr-a0-"
#define IWL_BZ_A_HR_B_FW_PRE "iwlwifi-bz-a0-hr-b0-"
#define IWL_BZ_A_GF_A_FW_PRE "iwlwifi-bz-a0-gf-a0-"
#define IWL_BZ_A_GF4_A_FW_PRE "iwlwifi-bz-a0-gf4-a0-"
#define IWL_BZ_A_MR_A_FW_PRE "iwlwifi-bz-a0-mr-a0-"
#define IWL_QU_B_HR_B_MODULE_FIRMWARE(api) \
IWL_QU_B_HR_B_FW_PRE __stringify(api) ".ucode"
@ -91,6 +95,14 @@
IWL_MA_A_MR_A_FW_PRE __stringify(api) ".ucode"
#define IWL_SNJ_A_MR_A_MODULE_FIRMWARE(api) \
IWL_SNJ_A_MR_A_FW_PRE __stringify(api) ".ucode"
#define IWL_BZ_A_HR_B_MODULE_FIRMWARE(api) \
IWL_BZ_A_HR_B_FW_PRE __stringify(api) ".ucode"
#define IWL_BZ_A_GF_A_MODULE_FIRMWARE(api) \
IWL_BZ_A_GF_A_FW_PRE __stringify(api) ".ucode"
#define IWL_BZ_A_GF4_A_MODULE_FIRMWARE(api) \
IWL_BZ_A_GF4_A_FW_PRE __stringify(api) ".ucode"
#define IWL_BZ_A_MR_A_MODULE_FIRMWARE(api) \
IWL_BZ_A_MR_A_FW_PRE __stringify(api) ".ucode"
static const struct iwl_base_params iwl_22000_base_params = {
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
@ -357,13 +369,27 @@ const struct iwl_cfg_trans_params iwl_ma_trans_cfg = {
.umac_prph_offset = 0x300000
};
const struct iwl_cfg_trans_params iwl_bz_trans_cfg = {
.device_family = IWL_DEVICE_FAMILY_AX210,
.base_params = &iwl_ax210_base_params,
.mq_rx_supported = true,
.use_tfh = true,
.rf_id = true,
.gen2 = true,
.integrated = true,
.umac_prph_offset = 0x300000,
.xtal_latency = 12000,
.low_latency_xtal = true,
.ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US,
};
const char iwl_ax101_name[] = "Intel(R) Wi-Fi 6 AX101";
const char iwl_ax200_name[] = "Intel(R) Wi-Fi 6 AX200 160MHz";
const char iwl_ax201_name[] = "Intel(R) Wi-Fi 6 AX201 160MHz";
const char iwl_ax203_name[] = "Intel(R) Wi-Fi 6 AX203";
const char iwl_ax211_name[] = "Intel(R) Wi-Fi 6 AX211 160MHz";
const char iwl_ax411_name[] = "Intel(R) Wi-Fi 6 AX411 160MHz";
const char iwl_ma_name[] = "Intel(R) Wi-Fi 6";
const char iwl_ax211_name[] = "Intel(R) Wi-Fi 6E AX211 160MHz";
const char iwl_ax221_name[] = "Intel(R) Wi-Fi 6E AX221 160MHz";
const char iwl_ax411_name[] = "Intel(R) Wi-Fi 6E AX411 160MHz";
const char iwl_ax200_killer_1650w_name[] =
"Killer(R) Wi-Fi 6 AX1650w 160MHz Wireless Network Adapter (200D2W)";
@ -373,6 +399,10 @@ const char iwl_ax201_killer_1650s_name[] =
"Killer(R) Wi-Fi 6 AX1650s 160MHz Wireless Network Adapter (201D2W)";
const char iwl_ax201_killer_1650i_name[] =
"Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW)";
const char iwl_ax210_killer_1675w_name[] =
"Killer(R) Wi-Fi 6E AX1675w 160MHz Wireless Network Adapter (210D2W)";
const char iwl_ax210_killer_1675x_name[] =
"Killer(R) Wi-Fi 6E AX1675x 160MHz Wireless Network Adapter (210NGW)";
const struct iwl_cfg iwl_qu_b0_hr1_b0 = {
.fw_name_pre = IWL_QU_B_HR_B_FW_PRE,
@ -578,7 +608,7 @@ const struct iwl_cfg iwl_qnj_b0_hr_b0_cfg = {
.num_rbds = IWL_NUM_RBDS_22000_HE,
};
const struct iwl_cfg iwlax210_2ax_cfg_so_jf_a0 = {
const struct iwl_cfg iwlax210_2ax_cfg_so_jf_b0 = {
.name = "Intel(R) Wireless-AC 9560 160MHz",
.fw_name_pre = IWL_SO_A_JF_B_FW_PRE,
IWL_DEVICE_AX210,
@ -719,6 +749,34 @@ const struct iwl_cfg iwl_cfg_quz_a0_hr_b0 = {
.num_rbds = IWL_NUM_RBDS_22000_HE,
};
const struct iwl_cfg iwl_cfg_bz_a0_hr_b0 = {
.fw_name_pre = IWL_BZ_A_HR_B_FW_PRE,
.uhb_supported = true,
IWL_DEVICE_AX210,
.num_rbds = IWL_NUM_RBDS_AX210_HE,
};
const struct iwl_cfg iwl_cfg_bz_a0_gf_a0 = {
.fw_name_pre = IWL_BZ_A_GF_A_FW_PRE,
.uhb_supported = true,
IWL_DEVICE_AX210,
.num_rbds = IWL_NUM_RBDS_AX210_HE,
};
const struct iwl_cfg iwl_cfg_bz_a0_gf4_a0 = {
.fw_name_pre = IWL_BZ_A_GF4_A_FW_PRE,
.uhb_supported = true,
IWL_DEVICE_AX210,
.num_rbds = IWL_NUM_RBDS_AX210_HE,
};
const struct iwl_cfg iwl_cfg_bz_a0_mr_a0 = {
.fw_name_pre = IWL_BZ_A_MR_A_FW_PRE,
.uhb_supported = true,
IWL_DEVICE_AX210,
.num_rbds = IWL_NUM_RBDS_AX210_HE,
};
MODULE_FIRMWARE(IWL_QU_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QNJ_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
@ -740,3 +798,7 @@ MODULE_FIRMWARE(IWL_MA_A_GF_A_FW_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_MA_A_GF4_A_FW_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_MA_A_MR_A_FW_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_SNJ_A_MR_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_BZ_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_BZ_A_GF_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_BZ_A_GF4_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_BZ_A_MR_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));

View File

@ -168,7 +168,7 @@ const char iwl9462_160_name[] = "Intel(R) Wireless-AC 9462 160MHz";
const char iwl9560_160_name[] = "Intel(R) Wireless-AC 9560 160MHz";
const char iwl9260_killer_1550_name[] =
"Killer (R) Wireless-AC 1550 Wireless Network Adapter (9260NGW)";
"Killer (R) Wireless-AC 1550 Wireless Network Adapter (9260NGW) 160MHz";
const char iwl9560_killer_1550i_name[] =
"Killer (R) Wireless-AC 1550i Wireless Network Adapter (9560NGW)";
const char iwl9560_killer_1550s_name[] =

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2017 Intel Deutschland GmbH
* Copyright (C) 2019-2020 Intel Corporation
* Copyright (C) 2019-2021 Intel Corporation
*/
#include <linux/uuid.h>
#include "iwl-drv.h"
@ -181,14 +181,13 @@ union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev,
/*
* We need at least two packages, one for the revision and one
* for the data itself. Also check that the revision is valid
* (i.e. it is an integer smaller than 2, as we currently support only
* 2 revisions).
* (i.e. it is an integer (each caller has to check by itself
* if the returned revision is supported)).
*/
if (data->type != ACPI_TYPE_PACKAGE ||
data->package.count < 2 ||
data->package.elements[0].type != ACPI_TYPE_INTEGER ||
data->package.elements[0].integer.value > 1) {
IWL_DEBUG_DEV_RADIO(dev, "Unsupported packages structure\n");
data->package.elements[0].type != ACPI_TYPE_INTEGER) {
IWL_DEBUG_DEV_RADIO(dev, "Invalid packages structure\n");
return ERR_PTR(-EINVAL);
}
@ -696,3 +695,70 @@ int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt,
return 0;
}
IWL_EXPORT_SYMBOL(iwl_sar_geo_init);
static u32 iwl_acpi_eval_dsm_func(struct device *dev, enum iwl_dsm_funcs_rev_0 eval_func)
{
union acpi_object *obj;
u32 ret;
obj = iwl_acpi_get_dsm_object(dev, 0,
eval_func, NULL,
&iwl_guid);
if (IS_ERR(obj)) {
IWL_DEBUG_DEV_RADIO(dev,
"ACPI: DSM func '%d': Got Error in obj = %ld\n",
eval_func,
PTR_ERR(obj));
return 0;
}
if (obj->type != ACPI_TYPE_INTEGER) {
IWL_DEBUG_DEV_RADIO(dev,
"ACPI: DSM func '%d' did not return a valid object, type=%d\n",
eval_func,
obj->type);
ret = 0;
goto out;
}
ret = obj->integer.value;
IWL_DEBUG_DEV_RADIO(dev,
"ACPI: DSM method evaluated: func='%d', ret=%d\n",
eval_func,
ret);
out:
ACPI_FREE(obj);
return ret;
}
__le32 iwl_acpi_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt)
{
u32 ret;
__le32 config_bitmap = 0;
/*
** Evaluate func 'DSM_FUNC_ENABLE_INDONESIA_5G2'
*/
ret = iwl_acpi_eval_dsm_func(fwrt->dev, DSM_FUNC_ENABLE_INDONESIA_5G2);
if (ret == DSM_VALUE_INDONESIA_ENABLE)
config_bitmap |=
cpu_to_le32(LARI_CONFIG_ENABLE_5G2_IN_INDONESIA_MSK);
/*
** Evaluate func 'DSM_FUNC_DISABLE_SRD'
*/
ret = iwl_acpi_eval_dsm_func(fwrt->dev, DSM_FUNC_DISABLE_SRD);
if (ret == DSM_VALUE_SRD_PASSIVE)
config_bitmap |=
cpu_to_le32(LARI_CONFIG_CHANGE_ETSI_TO_PASSIVE_MSK);
else if (ret == DSM_VALUE_SRD_DISABLE)
config_bitmap |=
cpu_to_le32(LARI_CONFIG_CHANGE_ETSI_TO_DISABLED_MSK);
return config_bitmap;
}
IWL_EXPORT_SYMBOL(iwl_acpi_get_lari_config_bitmap);

View File

@ -53,8 +53,8 @@
#define ACPI_WGDS_TABLE_SIZE 3
#define ACPI_PPAG_WIFI_DATA_SIZE ((IWL_NUM_CHAIN_LIMITS * \
IWL_NUM_SUB_BANDS) + 2)
#define ACPI_PPAG_WIFI_DATA_SIZE_V1 ((IWL_NUM_CHAIN_LIMITS * \
IWL_NUM_SUB_BANDS_V1) + 2)
#define ACPI_PPAG_WIFI_DATA_SIZE_V2 ((IWL_NUM_CHAIN_LIMITS * \
IWL_NUM_SUB_BANDS_V2) + 2)
@ -77,6 +77,7 @@ enum iwl_dsm_funcs_rev_0 {
DSM_FUNC_QUERY = 0,
DSM_FUNC_DISABLE_SRD = 1,
DSM_FUNC_ENABLE_INDONESIA_5G2 = 2,
DSM_FUNC_11AX_ENABLEMENT = 6,
};
enum iwl_dsm_values_srd {
@ -160,6 +161,8 @@ int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt,
int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt, __le32 *block_list_array,
int *block_list_size);
__le32 iwl_acpi_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt);
#else /* CONFIG_ACPI */
static inline void *iwl_acpi_get_object(struct device *dev, acpi_string method)
@ -235,5 +238,11 @@ static inline int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt,
{
return -ENOENT;
}
static inline __le32 iwl_acpi_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt)
{
return 0;
}
#endif /* CONFIG_ACPI */
#endif /* __iwl_fw_acpi__ */

View File

@ -147,6 +147,10 @@ enum iwl_tof_mcsi_enable {
* @IWL_TOF_RESPONDER_CMD_VALID_RETRY_ON_ALGO_FAIL: retry on algorithm failure
* is valid
* @IWL_TOF_RESPONDER_CMD_VALID_STA_ID: station ID is valid
* @IWL_TOF_RESPONDER_CMD_VALID_NDP_SUPPORT: enable/disable NDP ranging support
* is valid
* @IWL_TOF_RESPONDER_CMD_VALID_NDP_PARAMS: NDP parameters are valid
* @IWL_TOF_RESPONDER_CMD_VALID_LMR_FEEDBACK: LMR feedback support is valid
*/
enum iwl_tof_responder_cmd_valid_field {
IWL_TOF_RESPONDER_CMD_VALID_CHAN_INFO = BIT(0),
@ -162,6 +166,9 @@ enum iwl_tof_responder_cmd_valid_field {
IWL_TOF_RESPONDER_CMD_VALID_FAST_ALGO_SUPPORT = BIT(10),
IWL_TOF_RESPONDER_CMD_VALID_RETRY_ON_ALGO_FAIL = BIT(11),
IWL_TOF_RESPONDER_CMD_VALID_STA_ID = BIT(12),
IWL_TOF_RESPONDER_CMD_VALID_NDP_SUPPORT = BIT(22),
IWL_TOF_RESPONDER_CMD_VALID_NDP_PARAMS = BIT(23),
IWL_TOF_RESPONDER_CMD_VALID_LMR_FEEDBACK = BIT(24),
};
/**
@ -176,6 +183,9 @@ enum iwl_tof_responder_cmd_valid_field {
* @IWL_TOF_RESPONDER_FLAGS_FAST_ALGO_SUPPORT: fast algorithm support
* @IWL_TOF_RESPONDER_FLAGS_RETRY_ON_ALGO_FAIL: retry on algorithm fail
* @IWL_TOF_RESPONDER_FLAGS_FTM_TX_ANT: TX antenna mask
* @IWL_TOF_RESPONDER_FLAGS_NDP_SUPPORT: support NDP ranging
* @IWL_TOF_RESPONDER_FLAGS_LMR_FEEDBACK: request for LMR feedback if the
* initiator supports it
*/
enum iwl_tof_responder_cfg_flags {
IWL_TOF_RESPONDER_FLAGS_NON_ASAP_SUPPORT = BIT(0),
@ -188,6 +198,8 @@ enum iwl_tof_responder_cfg_flags {
IWL_TOF_RESPONDER_FLAGS_FAST_ALGO_SUPPORT = BIT(9),
IWL_TOF_RESPONDER_FLAGS_RETRY_ON_ALGO_FAIL = BIT(10),
IWL_TOF_RESPONDER_FLAGS_FTM_TX_ANT = RATE_MCS_ANT_ABC_MSK,
IWL_TOF_RESPONDER_FLAGS_NDP_SUPPORT = BIT(24),
IWL_TOF_RESPONDER_FLAGS_LMR_FEEDBACK = BIT(25),
};
/**
@ -226,7 +238,7 @@ struct iwl_tof_responder_config_cmd_v6 {
} __packed; /* TOF_RESPONDER_CONFIG_CMD_API_S_VER_6 */
/**
* struct iwl_tof_responder_config_cmd - ToF AP mode (for debug)
* struct iwl_tof_responder_config_cmd_v7 - ToF AP mode (for debug)
* @cmd_valid_fields: &iwl_tof_responder_cmd_valid_field
* @responder_cfg_flags: &iwl_tof_responder_cfg_flags
* @format_bw: bits 0 - 3: &enum iwl_location_frame_format.
@ -245,7 +257,7 @@ struct iwl_tof_responder_config_cmd_v6 {
* @bssid: Current AP BSSID
* @reserved2: reserved
*/
struct iwl_tof_responder_config_cmd {
struct iwl_tof_responder_config_cmd_v7 {
__le32 cmd_valid_fields;
__le32 responder_cfg_flags;
u8 format_bw;
@ -259,7 +271,56 @@ struct iwl_tof_responder_config_cmd {
__le16 specific_calib;
u8 bssid[ETH_ALEN];
__le16 reserved2;
} __packed; /* TOF_RESPONDER_CONFIG_CMD_API_S_VER_6 */
} __packed; /* TOF_RESPONDER_CONFIG_CMD_API_S_VER_7 */
#define IWL_RESPONDER_STS_POS 3
#define IWL_RESPONDER_TOTAL_LTF_POS 6
/**
* struct iwl_tof_responder_config_cmd_v8 - ToF AP mode (for debug)
* @cmd_valid_fields: &iwl_tof_responder_cmd_valid_field
* @responder_cfg_flags: &iwl_tof_responder_cfg_flags
* @format_bw: bits 0 - 3: &enum iwl_location_frame_format.
* bits 4 - 7: &enum iwl_location_bw.
* @rate: current AP rate
* @channel_num: current AP Channel
* @ctrl_ch_position: coding of the control channel position relative to
* the center frequency, see iwl_mvm_get_ctrl_pos()
* @sta_id: index of the AP STA when in AP mode
* @reserved1: reserved
* @toa_offset: Artificial addition [pSec] for the ToA - to be used for debug
* purposes, simulating station movement by adding various values
* to this field
* @common_calib: XVT: common calibration value
* @specific_calib: XVT: specific calibration value
* @bssid: Current AP BSSID
* @r2i_ndp_params: parameters for R2I NDP.
* bits 0 - 2: max number of LTF repetitions
* bits 3 - 5: max number of spatial streams (supported values are < 2)
* bits 6 - 7: max number of total LTFs
* (&enum ieee80211_range_params_max_total_ltf)
* @i2r_ndp_params: parameters for I2R NDP.
* bits 0 - 2: max number of LTF repetitions
* bits 3 - 5: max number of spatial streams
* bits 6 - 7: max number of total LTFs
* (&enum ieee80211_range_params_max_total_ltf)
*/
struct iwl_tof_responder_config_cmd_v8 {
__le32 cmd_valid_fields;
__le32 responder_cfg_flags;
u8 format_bw;
u8 rate;
u8 channel_num;
u8 ctrl_ch_position;
u8 sta_id;
u8 reserved1;
__le16 toa_offset;
__le16 common_calib;
__le16 specific_calib;
u8 bssid[ETH_ALEN];
u8 r2i_ndp_params;
u8 i2r_ndp_params;
} __packed; /* TOF_RESPONDER_CONFIG_CMD_API_S_VER_8 */
#define IWL_LCI_CIVIC_IE_MAX_SIZE 400
@ -422,10 +483,12 @@ struct iwl_tof_range_req_ap_entry_v2 {
* driver.
* @IWL_INITIATOR_AP_FLAGS_NON_TB: Use non trigger based flow
* @IWL_INITIATOR_AP_FLAGS_TB: Use trigger based flow
* @IWL_INITIATOR_AP_FLAGS_SECURED: request secured measurement
* @IWL_INITIATOR_AP_FLAGS_SECURED: request secure LTF measurement
* @IWL_INITIATOR_AP_FLAGS_LMR_FEEDBACK: Send LMR feedback
* @IWL_INITIATOR_AP_FLAGS_USE_CALIB: Use calibration values from the request
* instead of fw internal values.
* @IWL_INITIATOR_AP_FLAGS_PMF: request to protect the negotiation and LMR
* frames with protected management frames.
*/
enum iwl_initiator_ap_flags {
IWL_INITIATOR_AP_FLAGS_ASAP = BIT(1),
@ -440,6 +503,7 @@ enum iwl_initiator_ap_flags {
IWL_INITIATOR_AP_FLAGS_SECURED = BIT(11),
IWL_INITIATOR_AP_FLAGS_LMR_FEEDBACK = BIT(12),
IWL_INITIATOR_AP_FLAGS_USE_CALIB = BIT(13),
IWL_INITIATOR_AP_FLAGS_PMF = BIT(14),
};
/**
@ -657,6 +721,79 @@ struct iwl_tof_range_req_ap_entry_v7 {
u8 tx_pn[IEEE80211_CCMP_PN_LEN];
} __packed; /* LOCATION_RANGE_REQ_AP_ENTRY_CMD_API_S_VER_7 */
#define IWL_LOCATION_MAX_STS_POS 3
/**
* struct iwl_tof_range_req_ap_entry_v8 - AP configuration parameters
* @initiator_ap_flags: see &enum iwl_initiator_ap_flags.
* @channel_num: AP Channel number
* @format_bw: bits 0 - 3: &enum iwl_location_frame_format.
* bits 4 - 7: &enum iwl_location_bw.
* @ctrl_ch_position: Coding of the control channel position relative to the
* center frequency, see iwl_mvm_get_ctrl_pos().
* @ftmr_max_retries: Max number of retries to send the FTMR in case of no
* reply from the AP.
* @bssid: AP's BSSID
* @burst_period: Recommended value to be sent to the AP. Measurement
* periodicity In units of 100ms. ignored if num_of_bursts_exp = 0
* @samples_per_burst: the number of FTMs pairs in single Burst (1-31);
* @num_of_bursts: Recommended value to be sent to the AP. 2s Exponent of
* the number of measurement iterations (min 2^0 = 1, max 2^14)
* @sta_id: the station id of the AP. Only relevant when associated to the AP,
* otherwise should be set to &IWL_MVM_INVALID_STA.
* @cipher: pairwise cipher suite for secured measurement.
* &enum iwl_location_cipher.
* @hltk: HLTK to be used for secured 11az measurement
* @tk: TK to be used for secured 11az measurement
* @calib: An array of calibration values per FTM rx bandwidth.
* If &IWL_INITIATOR_AP_FLAGS_USE_CALIB is set, the fw will use the
* calibration value that corresponds to the rx bandwidth of the FTM
* frame.
* @beacon_interval: beacon interval of the AP in TUs. Only required if
* &IWL_INITIATOR_AP_FLAGS_TB is set.
* @rx_pn: the next expected PN for protected management frames Rx. LE byte
* order. Only valid if &IWL_INITIATOR_AP_FLAGS_SECURED is set and sta_id
* is set to &IWL_MVM_INVALID_STA.
* @tx_pn: the next PN to use for protected management frames Tx. LE byte
* order. Only valid if &IWL_INITIATOR_AP_FLAGS_SECURED is set and sta_id
* is set to &IWL_MVM_INVALID_STA.
* @r2i_ndp_params: parameters for R2I NDP ranging negotiation.
* bits 0 - 2: max LTF repetitions
* bits 3 - 5: max number of spatial streams
* bits 6 - 7: reserved
* @i2r_ndp_params: parameters for I2R NDP ranging negotiation.
* bits 0 - 2: max LTF repetitions
* bits 3 - 5: max number of spatial streams (supported values are < 2)
* bits 6 - 7: reserved
* @r2i_max_total_ltf: R2I Max Total LTFs for NDP ranging negotiation.
* One of &enum ieee80211_range_params_max_total_ltf.
* @i2r_max_total_ltf: I2R Max Total LTFs for NDP ranging negotiation.
* One of &enum ieee80211_range_params_max_total_ltf.
*/
struct iwl_tof_range_req_ap_entry_v8 {
__le32 initiator_ap_flags;
u8 channel_num;
u8 format_bw;
u8 ctrl_ch_position;
u8 ftmr_max_retries;
u8 bssid[ETH_ALEN];
__le16 burst_period;
u8 samples_per_burst;
u8 num_of_bursts;
u8 sta_id;
u8 cipher;
u8 hltk[HLTK_11AZ_LEN];
u8 tk[TK_11AZ_LEN];
__le16 calib[IWL_TOF_BW_NUM];
__le16 beacon_interval;
u8 rx_pn[IEEE80211_CCMP_PN_LEN];
u8 tx_pn[IEEE80211_CCMP_PN_LEN];
u8 r2i_ndp_params;
u8 i2r_ndp_params;
u8 r2i_max_total_ltf;
u8 i2r_max_total_ltf;
} __packed; /* LOCATION_RANGE_REQ_AP_ENTRY_CMD_API_S_VER_8 */
/**
* enum iwl_tof_response_mode
* @IWL_MVM_TOF_RESPONSE_ASAP: report each AP measurement separately as soon as
@ -878,6 +1015,34 @@ struct iwl_tof_range_req_cmd_v11 {
struct iwl_tof_range_req_ap_entry_v7 ap[IWL_MVM_TOF_MAX_APS];
} __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_11 */
/**
* struct iwl_tof_range_req_cmd_v12 - start measurement cmd
* @initiator_flags: see flags @ iwl_tof_initiator_flags
* @request_id: A Token incremented per request. The same Token will be
* sent back in the range response
* @num_of_ap: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS)
* @range_req_bssid: ranging request BSSID
* @macaddr_mask: Bits set to 0 shall be copied from the MAC address template.
* Bits set to 1 shall be randomized by the UMAC
* @macaddr_template: MAC address template to use for non-randomized bits
* @req_timeout_ms: Requested timeout of the response in units of milliseconds.
* This is the session time for completing the measurement.
* @tsf_mac_id: report the measurement start time for each ap in terms of the
* TSF of this mac id. 0xff to disable TSF reporting.
* @ap: per-AP request data, see &struct iwl_tof_range_req_ap_entry_v2.
*/
struct iwl_tof_range_req_cmd_v12 {
__le32 initiator_flags;
u8 request_id;
u8 num_of_ap;
u8 range_req_bssid[ETH_ALEN];
u8 macaddr_mask[ETH_ALEN];
u8 macaddr_template[ETH_ALEN];
__le32 req_timeout_ms;
__le32 tsf_mac_id;
struct iwl_tof_range_req_ap_entry_v8 ap[IWL_MVM_TOF_MAX_APS];
} __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_12 */
/*
* enum iwl_tof_range_request_status - status of the sent request
* @IWL_TOF_RANGE_REQUEST_STATUS_SUCCESSFUL - FW successfully received the

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2012-2014, 2018-2020 Intel Corporation
* Copyright (C) 2012-2014, 2018-2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@ -414,6 +414,9 @@ enum iwl_lari_config_masks {
LARI_CONFIG_ENABLE_5G2_IN_INDONESIA_MSK = BIT(3),
};
#define IWL_11AX_UKRAINE_MASK 3
#define IWL_11AX_UKRAINE_SHIFT 8
/**
* struct iwl_lari_config_change_cmd_v1 - change LARI configuration
* @config_bitmap: bit map of the config commands. each bit will trigger a
@ -434,6 +437,21 @@ struct iwl_lari_config_change_cmd_v2 {
__le32 oem_uhb_allow_bitmap;
} __packed; /* LARI_CHANGE_CONF_CMD_S_VER_2 */
/**
* struct iwl_lari_config_change_cmd_v3 - change LARI configuration
* @config_bitmap: bit map of the config commands. each bit will trigger a
* different predefined FW config operation
* @oem_uhb_allow_bitmap: bitmap of UHB enabled MCC sets
* @oem_11ax_allow_bitmap: bitmap of 11ax allowed MCCs.
* For each supported country, a pair of regulatory override bit and 11ax mode exist
* in the bit field.
*/
struct iwl_lari_config_change_cmd_v3 {
__le32 config_bitmap;
__le32 oem_uhb_allow_bitmap;
__le32 oem_11ax_allow_bitmap;
} __packed; /* LARI_CHANGE_CONF_CMD_S_VER_3 */
/**
* struct iwl_pnvm_init_complete_ntfy - PNVM initialization complete
* @status: PNVM image loading status

View File

@ -274,7 +274,7 @@ enum iwl_dev_tx_power_cmd_mode {
#define IWL_NUM_CHAIN_TABLES 1
#define IWL_NUM_CHAIN_TABLES_V2 2
#define IWL_NUM_CHAIN_LIMITS 2
#define IWL_NUM_SUB_BANDS 5
#define IWL_NUM_SUB_BANDS_V1 5
#define IWL_NUM_SUB_BANDS_V2 11
/**
@ -300,7 +300,7 @@ struct iwl_dev_tx_power_common {
* @per_chain: per chain restrictions
*/
struct iwl_dev_tx_power_cmd_v3 {
__le16 per_chain[IWL_NUM_CHAIN_TABLES][IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS];
__le16 per_chain[IWL_NUM_CHAIN_TABLES][IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V1];
} __packed; /* TX_REDUCED_POWER_API_S_VER_3 */
#define IWL_DEV_MAX_TX_POWER 0x7FFF
@ -313,7 +313,7 @@ struct iwl_dev_tx_power_cmd_v3 {
* @reserved: reserved (padding)
*/
struct iwl_dev_tx_power_cmd_v4 {
__le16 per_chain[IWL_NUM_CHAIN_TABLES][IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS];
__le16 per_chain[IWL_NUM_CHAIN_TABLES][IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V1];
u8 enable_ack_reduction;
u8 reserved[3];
} __packed; /* TX_REDUCED_POWER_API_S_VER_4 */
@ -332,7 +332,7 @@ struct iwl_dev_tx_power_cmd_v4 {
* BIOS values. relevant if setMode is IWL_TX_POWER_MODE_SET_SAR_TIMER
*/
struct iwl_dev_tx_power_cmd_v5 {
__le16 per_chain[IWL_NUM_CHAIN_TABLES][IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS];
__le16 per_chain[IWL_NUM_CHAIN_TABLES][IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V1];
u8 enable_ack_reduction;
u8 per_chain_restriction_changed;
u8 reserved[2];
@ -454,21 +454,23 @@ struct iwl_geo_tx_power_profiles_resp {
/**
* union iwl_ppag_table_cmd - union for all versions of PPAG command
* @v1: version 1, table revision = 0
* @v2: version 2, table revision = 1
* @v1: version 1
* @v2: version 2
*
* @enabled: 1 if PPAG is enabled, 0 otherwise
* @flags: bit 0 - indicates enablement of PPAG for ETSI
* bit 1 - indicates enablement of PPAG for CHINA BIOS
* bit 1 can be used only in v3 (identical to v2)
* @gain: table of antenna gain values per chain and sub-band
* @reserved: reserved
*/
union iwl_ppag_table_cmd {
struct {
__le32 enabled;
s8 gain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS];
__le32 flags;
s8 gain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V1];
s8 reserved[2];
} v1;
struct {
__le32 enabled;
__le32 flags;
s8 gain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V2];
s8 reserved[2];
} v2;

View File

@ -779,36 +779,6 @@ struct iwl_rxq_sync_notification {
u8 payload[];
} __packed; /* MULTI_QUEUE_DRV_SYNC_HDR_CMD_API_S_VER_1 */
/**
* enum iwl_mvm_rxq_notif_type - Internal message identifier
*
* @IWL_MVM_RXQ_EMPTY: empty sync notification
* @IWL_MVM_RXQ_NOTIF_DEL_BA: notify RSS queues of delBA
* @IWL_MVM_RXQ_NSSN_SYNC: notify all the RSS queues with the new NSSN
*/
enum iwl_mvm_rxq_notif_type {
IWL_MVM_RXQ_EMPTY,
IWL_MVM_RXQ_NOTIF_DEL_BA,
IWL_MVM_RXQ_NSSN_SYNC,
};
/**
* struct iwl_mvm_internal_rxq_notif - Internal representation of the data sent
* in &iwl_rxq_sync_cmd. Should be DWORD aligned.
* FW is agnostic to the payload, so there are no endianity requirements.
*
* @type: value from &iwl_mvm_rxq_notif_type
* @sync: ctrl path is waiting for all notifications to be received
* @cookie: internal cookie to identify old notifications
* @data: payload
*/
struct iwl_mvm_internal_rxq_notif {
u16 type;
u16 sync;
u32 cookie;
u8 data[];
} __packed;
/**
* enum iwl_mvm_pm_event - type of station PM event
* @IWL_MVM_PM_EVENT_AWAKE: station woke up

View File

@ -634,6 +634,12 @@ enum iwl_umac_scan_general_flags2 {
* @IWL_UMAC_SCAN_GEN_FLAGS_V2_TRIGGER_UHB_SCAN: at the end of 2.4GHz and
* 5.2Ghz bands scan, trigger scan on 6GHz band to discover
* the reported collocated APs
* @IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN: at the end of 2.4GHz and 5GHz
* bands scan, if not APs were discovered, allow scan to conitnue and scan
* 6GHz PSC channels in order to discover country information.
* @IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN_FILTER_IN: in case
* &IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN is enabled and scan is
* activated over 6GHz PSC channels, filter in beacons and probe responses.
*/
enum iwl_umac_scan_general_flags_v2 {
IWL_UMAC_SCAN_GEN_FLAGS_V2_PERIODIC = BIT(0),
@ -649,6 +655,8 @@ enum iwl_umac_scan_general_flags_v2 {
IWL_UMAC_SCAN_GEN_FLAGS_V2_MULTI_SSID = BIT(10),
IWL_UMAC_SCAN_GEN_FLAGS_V2_FORCE_PASSIVE = BIT(11),
IWL_UMAC_SCAN_GEN_FLAGS_V2_TRIGGER_UHB_SCAN = BIT(12),
IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN = BIT(13),
IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN_FILTER_IN = BIT(14),
};
/**

View File

@ -2559,7 +2559,9 @@ int iwl_fw_dbg_ini_collect(struct iwl_fw_runtime *fwrt,
fwrt->dump.wks[idx].dump_data = *dump_data;
IWL_WARN(fwrt, "WRT: Collecting data: ini trigger %d fired.\n", tp_id);
IWL_WARN(fwrt,
"WRT: Collecting data: ini trigger %d fired (delay=%dms).\n",
tp_id, (u32)(delay / USEC_PER_MSEC));
schedule_delayed_work(&fwrt->dump.wks[idx].wk, usecs_to_jiffies(delay));

View File

@ -362,6 +362,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t;
* @IWL_UCODE_TLV_CAPA_PROTECTED_TWT: Supports protection of TWT action frames
* @IWL_UCODE_TLV_CAPA_FW_RESET_HANDSHAKE: Supports the firmware handshake in
* reset flow
* @IWL_UCODE_TLV_CAPA_PASSIVE_6GHZ_SCAN: Support for passive scan on 6GHz PSC
* channels even when these are not enabled.
*
* @NUM_IWL_UCODE_TLV_CAPA: number of bits used
*/
@ -408,6 +410,7 @@ enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD = (__force iwl_ucode_tlv_capa_t)54,
IWL_UCODE_TLV_CAPA_PROTECTED_TWT = (__force iwl_ucode_tlv_capa_t)56,
IWL_UCODE_TLV_CAPA_FW_RESET_HANDSHAKE = (__force iwl_ucode_tlv_capa_t)57,
IWL_UCODE_TLV_CAPA_PASSIVE_6GHZ_SCAN = (__force iwl_ucode_tlv_capa_t)58,
/* set 2 */
IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64,

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2005-2014, 2018-2020 Intel Corporation
* Copyright (C) 2005-2014, 2018-2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016 Intel Deutschland GmbH
*/
@ -116,6 +116,9 @@ struct fw_img {
#define PAGING_CMD_NUM_OF_PAGES_IN_LAST_GRP_POS 0
#define PAGING_TLV_SECURE_MASK 1
/* FW MSB Mask for regions/cache_control */
#define FW_ADDR_CACHE_CONTROL 0xC0000000UL
/**
* struct iwl_fw_paging
* @fw_paging_phys: page phy pointer

View File

@ -10,6 +10,8 @@
#include "fw/api/soc.h"
#include "fw/api/commands.h"
#include "fw/api/rx.h"
#include "fw/api/datapath.h"
void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
const struct iwl_fw *fw,
@ -95,3 +97,60 @@ int iwl_set_soc_latency(struct iwl_fw_runtime *fwrt)
return ret;
}
IWL_EXPORT_SYMBOL(iwl_set_soc_latency);
int iwl_configure_rxq(struct iwl_fw_runtime *fwrt)
{
int i, num_queues, size, ret;
struct iwl_rfh_queue_config *cmd;
struct iwl_host_cmd hcmd = {
.id = WIDE_ID(DATA_PATH_GROUP, RFH_QUEUE_CONFIG_CMD),
.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
};
/*
* The default queue is configured via context info, so if we
* have a single queue, there's nothing to do here.
*/
if (fwrt->trans->num_rx_queues == 1)
return 0;
if (fwrt->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_22000)
return 0;
/* skip the default queue */
num_queues = fwrt->trans->num_rx_queues - 1;
size = struct_size(cmd, data, num_queues);
cmd = kzalloc(size, GFP_KERNEL);
if (!cmd)
return -ENOMEM;
cmd->num_queues = num_queues;
for (i = 0; i < num_queues; i++) {
struct iwl_trans_rxq_dma_data data;
cmd->data[i].q_num = i + 1;
iwl_trans_get_rxq_dma_data(fwrt->trans, i + 1, &data);
cmd->data[i].fr_bd_cb = cpu_to_le64(data.fr_bd_cb);
cmd->data[i].urbd_stts_wrptr =
cpu_to_le64(data.urbd_stts_wrptr);
cmd->data[i].ur_bd_cb = cpu_to_le64(data.ur_bd_cb);
cmd->data[i].fr_bd_wid = cpu_to_le32(data.fr_bd_wid);
}
hcmd.data[0] = cmd;
hcmd.len[0] = size;
ret = iwl_trans_send_cmd(fwrt->trans, &hcmd);
kfree(cmd);
if (ret)
IWL_ERR(fwrt, "Failed to configure RX queues: %d\n", ret);
return ret;
}
IWL_EXPORT_SYMBOL(iwl_configure_rxq);

View File

@ -190,5 +190,6 @@ void iwl_free_fw_paging(struct iwl_fw_runtime *fwrt);
void iwl_get_shared_mem_conf(struct iwl_fw_runtime *fwrt);
int iwl_set_soc_latency(struct iwl_fw_runtime *fwrt);
int iwl_configure_rxq(struct iwl_fw_runtime *fwrt);
#endif /* __iwl_fw_runtime_h__ */

View File

@ -416,6 +416,7 @@ struct iwl_cfg {
#define IWL_CFG_MAC_TYPE_SNJ 0x42
#define IWL_CFG_MAC_TYPE_SOF 0x43
#define IWL_CFG_MAC_TYPE_MA 0x44
#define IWL_CFG_MAC_TYPE_BZ 0x46
#define IWL_CFG_RF_TYPE_TH 0x105
#define IWL_CFG_RF_TYPE_TH1 0x108
@ -477,6 +478,7 @@ extern const struct iwl_cfg_trans_params iwl_snj_trans_cfg;
extern const struct iwl_cfg_trans_params iwl_so_trans_cfg;
extern const struct iwl_cfg_trans_params iwl_so_long_latency_trans_cfg;
extern const struct iwl_cfg_trans_params iwl_ma_trans_cfg;
extern const struct iwl_cfg_trans_params iwl_bz_trans_cfg;
extern const char iwl9162_name[];
extern const char iwl9260_name[];
extern const char iwl9260_1_name[];
@ -501,8 +503,10 @@ extern const char iwl_ax200_killer_1650w_name[];
extern const char iwl_ax200_killer_1650x_name[];
extern const char iwl_ax201_killer_1650s_name[];
extern const char iwl_ax201_killer_1650i_name[];
extern const char iwl_ma_name[];
extern const char iwl_ax210_killer_1675w_name[];
extern const char iwl_ax210_killer_1675x_name[];
extern const char iwl_ax211_name[];
extern const char iwl_ax221_name[];
extern const char iwl_ax411_name[];
#if IS_ENABLED(CONFIG_IWLDVM)
extern const struct iwl_cfg iwl5300_agn_cfg;
@ -594,7 +598,7 @@ extern const struct iwl_cfg killer1650i_2ax_cfg_qu_c0_hr_b0;
extern const struct iwl_cfg killer1650x_2ax_cfg;
extern const struct iwl_cfg killer1650w_2ax_cfg;
extern const struct iwl_cfg iwl_qnj_b0_hr_b0_cfg;
extern const struct iwl_cfg iwlax210_2ax_cfg_so_jf_a0;
extern const struct iwl_cfg iwlax210_2ax_cfg_so_jf_b0;
extern const struct iwl_cfg iwlax210_2ax_cfg_so_hr_a0;
extern const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0;
extern const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0_long;
@ -612,6 +616,10 @@ extern const struct iwl_cfg iwl_cfg_ma_a0_mr_a0;
extern const struct iwl_cfg iwl_cfg_snj_a0_mr_a0;
extern const struct iwl_cfg iwl_cfg_so_a0_hr_a0;
extern const struct iwl_cfg iwl_cfg_quz_a0_hr_b0;
extern const struct iwl_cfg iwl_cfg_bz_a0_hr_b0;
extern const struct iwl_cfg iwl_cfg_bz_a0_gf_a0;
extern const struct iwl_cfg iwl_cfg_bz_a0_gf4_a0;
extern const struct iwl_cfg iwl_cfg_bz_a0_mr_a0;
#endif /* CONFIG_IWLMVM */
#endif /* __IWL_CONFIG_H__ */

View File

@ -578,6 +578,9 @@ enum msix_fh_int_causes {
MSIX_FH_INT_CAUSES_FH_ERR = BIT(21),
};
/* The low 16 bits are for rx data queue indication */
#define MSIX_FH_INT_CAUSES_DATA_QUEUE 0xffff
/*
* Causes for the HW register interrupts
*/

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2018-2020 Intel Corporation
* Copyright (C) 2018-2021 Intel Corporation
*/
#include <linux/firmware.h>
#include "iwl-drv.h"
@ -426,7 +426,8 @@ void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans)
const struct firmware *fw;
int res;
if (!iwlwifi_mod_params.enable_ini)
if (!iwlwifi_mod_params.enable_ini ||
trans->trans_cfg->device_family <= IWL_DEVICE_FAMILY_9000)
return;
res = firmware_request_nowarn(&fw, "iwl-debug-yoyo.bin", dev);

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2005-2014, 2018-2020 Intel Corporation
* Copyright (C) 2005-2014, 2018-2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@ -550,8 +550,6 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv,
return 0;
}
#define FW_ADDR_CACHE_CONTROL 0xC0000000
static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
const struct firmware *ucode_raw,
struct iwl_firmware_pieces *pieces,

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2005-2014, 2018-2020 Intel Corporation
* Copyright (C) 2005-2014, 2018-2021 Intel Corporation
* Copyright (C) 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015 Intel Deutschland GmbH
*/
@ -176,6 +176,8 @@ iwl_op_mode_hw_rf_kill(struct iwl_op_mode *op_mode, bool state)
static inline void iwl_op_mode_free_skb(struct iwl_op_mode *op_mode,
struct sk_buff *skb)
{
if (WARN_ON_ONCE(!op_mode))
return;
op_mode->ops->free_skb(op_mode, skb);
}

View File

@ -2,7 +2,7 @@
/*
* Copyright (C) 2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
* Copyright (C) 2019-2020 Intel Corporation
* Copyright (C) 2019-2021 Intel Corporation
*/
#include <linux/kernel.h>
#include <linux/bsearch.h>
@ -21,7 +21,6 @@ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
const struct iwl_cfg_trans_params *cfg_trans)
{
struct iwl_trans *trans;
int txcmd_size, txcmd_align;
#ifdef CONFIG_LOCKDEP
static struct lock_class_key __key;
#endif
@ -31,23 +30,6 @@ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
return NULL;
trans->trans_cfg = cfg_trans;
if (!cfg_trans->gen2) {
txcmd_size = sizeof(struct iwl_tx_cmd);
txcmd_align = sizeof(void *);
} else if (cfg_trans->device_family < IWL_DEVICE_FAMILY_AX210) {
txcmd_size = sizeof(struct iwl_tx_cmd_gen2);
txcmd_align = 64;
} else {
txcmd_size = sizeof(struct iwl_tx_cmd_gen3);
txcmd_align = 128;
}
txcmd_size += sizeof(struct iwl_cmd_header);
txcmd_size += 36; /* biggest possible 802.11 header */
/* Ensure device TX cmd cannot reach/cross a page boundary in gen2 */
if (WARN_ON(cfg_trans->gen2 && txcmd_size >= txcmd_align))
return ERR_PTR(-EINVAL);
#ifdef CONFIG_LOCKDEP
lockdep_init_map(&trans->sync_cmd_lockdep_map, "sync_cmd_lockdep_map",
@ -58,22 +40,7 @@ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
trans->ops = ops;
trans->num_rx_queues = 1;
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
trans->txqs.bc_tbl_size = sizeof(struct iwl_gen3_bc_tbl);
else
trans->txqs.bc_tbl_size = sizeof(struct iwlagn_scd_bc_tbl);
/*
* For gen2 devices, we use a single allocation for each byte-count
* table, but they're pretty small (1k) so use a DMA pool that we
* allocate here.
*/
if (trans->trans_cfg->gen2) {
trans->txqs.bc_pool = dmam_pool_create("iwlwifi:bc", dev,
trans->txqs.bc_tbl_size,
256, 0);
if (!trans->txqs.bc_pool)
return NULL;
}
WARN_ON(!ops->wait_txq_empty && !ops->wait_tx_queues_empty);
if (trans->trans_cfg->use_tfh) {
trans->txqs.tfd.addr_size = 64;
@ -86,6 +53,52 @@ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
}
trans->max_skb_frags = IWL_TRANS_MAX_FRAGS(trans);
return trans;
}
int iwl_trans_init(struct iwl_trans *trans)
{
int txcmd_size, txcmd_align;
if (!trans->trans_cfg->gen2) {
txcmd_size = sizeof(struct iwl_tx_cmd);
txcmd_align = sizeof(void *);
} else if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) {
txcmd_size = sizeof(struct iwl_tx_cmd_gen2);
txcmd_align = 64;
} else {
txcmd_size = sizeof(struct iwl_tx_cmd_gen3);
txcmd_align = 128;
}
txcmd_size += sizeof(struct iwl_cmd_header);
txcmd_size += 36; /* biggest possible 802.11 header */
/* Ensure device TX cmd cannot reach/cross a page boundary in gen2 */
if (WARN_ON(trans->trans_cfg->gen2 && txcmd_size >= txcmd_align))
return -EINVAL;
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
trans->txqs.bc_tbl_size = sizeof(struct iwl_gen3_bc_tbl);
else
trans->txqs.bc_tbl_size = sizeof(struct iwlagn_scd_bc_tbl);
/*
* For gen2 devices, we use a single allocation for each byte-count
* table, but they're pretty small (1k) so use a DMA pool that we
* allocate here.
*/
if (trans->trans_cfg->gen2) {
trans->txqs.bc_pool = dmam_pool_create("iwlwifi:bc", trans->dev,
trans->txqs.bc_tbl_size,
256, 0);
if (!trans->txqs.bc_pool)
return -ENOMEM;
}
/* Some things must not change even if the config does */
WARN_ON(trans->txqs.tfd.addr_size !=
(trans->trans_cfg->use_tfh ? 64 : 36));
snprintf(trans->dev_cmd_pool_name, sizeof(trans->dev_cmd_pool_name),
"iwl_cmd_pool:%s", dev_name(trans->dev));
trans->dev_cmd_pool =
@ -93,36 +106,36 @@ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
txcmd_size, txcmd_align,
SLAB_HWCACHE_ALIGN, NULL);
if (!trans->dev_cmd_pool)
return NULL;
WARN_ON(!ops->wait_txq_empty && !ops->wait_tx_queues_empty);
return -ENOMEM;
trans->txqs.tso_hdr_page = alloc_percpu(struct iwl_tso_hdr_page);
if (!trans->txqs.tso_hdr_page) {
kmem_cache_destroy(trans->dev_cmd_pool);
return NULL;
return -ENOMEM;
}
/* Initialize the wait queue for commands */
init_waitqueue_head(&trans->wait_command_queue);
return trans;
return 0;
}
void iwl_trans_free(struct iwl_trans *trans)
{
int i;
for_each_possible_cpu(i) {
struct iwl_tso_hdr_page *p =
per_cpu_ptr(trans->txqs.tso_hdr_page, i);
if (trans->txqs.tso_hdr_page) {
for_each_possible_cpu(i) {
struct iwl_tso_hdr_page *p =
per_cpu_ptr(trans->txqs.tso_hdr_page, i);
if (p->page)
__free_page(p->page);
if (p && p->page)
__free_page(p->page);
}
free_percpu(trans->txqs.tso_hdr_page);
}
free_percpu(trans->txqs.tso_hdr_page);
kmem_cache_destroy(trans->dev_cmd_pool);
}

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2005-2014, 2018-2020 Intel Corporation
* Copyright (C) 2005-2014, 2018-2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@ -1267,7 +1267,8 @@ static inline int iwl_trans_wait_tx_queues_empty(struct iwl_trans *trans,
if (WARN_ON_ONCE(!trans->ops->wait_tx_queues_empty))
return -ENOTSUPP;
if (WARN_ON_ONCE(trans->state != IWL_TRANS_FW_ALIVE)) {
/* No need to wait if the firmware is not alive */
if (trans->state != IWL_TRANS_FW_ALIVE) {
IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
return -EIO;
}
@ -1438,6 +1439,7 @@ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
struct device *dev,
const struct iwl_trans_ops *ops,
const struct iwl_cfg_trans_params *cfg_trans);
int iwl_trans_init(struct iwl_trans *trans);
void iwl_trans_free(struct iwl_trans *trans);
/*****************************************************

View File

@ -93,6 +93,15 @@
#define IWL_MVM_ENABLE_EBS 1
#define IWL_MVM_FTM_INITIATOR_ALGO IWL_TOF_ALGO_TYPE_MAX_LIKE
#define IWL_MVM_FTM_INITIATOR_DYNACK true
#define IWL_MVM_FTM_R2I_MAX_REP 7
#define IWL_MVM_FTM_I2R_MAX_REP 7
#define IWL_MVM_FTM_R2I_MAX_STS 1
#define IWL_MVM_FTM_I2R_MAX_STS 1
#define IWL_MVM_FTM_R2I_MAX_TOTAL_LTF 3
#define IWL_MVM_FTM_I2R_MAX_TOTAL_LTF 3
#define IWL_MVM_FTM_INITIATOR_SECURE_LTF false
#define IWL_MVM_FTM_RESP_NDP_SUPPORT true
#define IWL_MVM_FTM_RESP_LMR_FEEDBACK_SUPPORT true
#define IWL_MVM_D3_DEBUG false
#define IWL_MVM_USE_TWT true
#define IWL_MVM_AMPDU_CONSEC_DROPS_DELBA 10
@ -108,5 +117,7 @@
#define IWL_MVM_FTM_INITIATOR_SMOOTH_OVERSHOOT 20016
#define IWL_MVM_FTM_INITIATOR_SMOOTH_AGE_SEC 2
#define IWL_MVM_DISABLE_AP_FILS false
#define IWL_MVM_6GHZ_PASSIVE_SCAN_TIMEOUT 3000 /* in seconds */
#define IWL_MVM_6GHZ_PASSIVE_SCAN_ASSOC_TIMEOUT 60 /* in seconds */
#endif /* __MVM_CONSTANTS_H */

View File

@ -2028,6 +2028,8 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
mutex_lock(&mvm->mutex);
mvm->last_reset_or_resume_time_jiffies = jiffies;
/* get the BSS vif pointer again */
vif = iwl_mvm_get_bss_vif(mvm);
if (IS_ERR_OR_NULL(vif))

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2012-2014, 2018-2020 Intel Corporation
* Copyright (C) 2012-2014, 2018-2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@ -1210,10 +1210,10 @@ static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm *mvm, char *bin, int len)
IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE))
return -EINVAL;
rcu_read_lock();
mutex_lock(&mvm->mutex);
for (i = 0; i < NUM_MAC_INDEX_DRIVER; i++) {
vif = iwl_mvm_rcu_dereference_vif_id(mvm, i, true);
vif = iwl_mvm_rcu_dereference_vif_id(mvm, i, false);
if (!vif)
continue;
@ -1253,18 +1253,16 @@ static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm *mvm, char *bin, int len)
&beacon_cmd.tim_size,
beacon->data, beacon->len);
mutex_lock(&mvm->mutex);
iwl_mvm_mac_ctxt_send_beacon_cmd(mvm, beacon, &beacon_cmd,
sizeof(beacon_cmd));
mutex_unlock(&mvm->mutex);
dev_kfree_skb(beacon);
rcu_read_unlock();
return 0;
out_err:
rcu_read_unlock();
mutex_unlock(&mvm->mutex);
return -EINVAL;
}

View File

@ -490,6 +490,15 @@ iwl_mvm_ftm_put_target(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
if (vif->bss_conf.assoc &&
!memcmp(peer->addr, vif->bss_conf.bssid, ETH_ALEN)) {
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct ieee80211_sta *sta;
rcu_read_lock();
sta = rcu_dereference(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id]);
if (sta->mfp)
FTM_PUT_FLAG(PMF);
rcu_read_unlock();
target->sta_id = mvmvif->ap_sta_id;
} else {
@ -684,6 +693,19 @@ iwl_mvm_ftm_set_secured_ranging(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
}
}
static int
iwl_mvm_ftm_put_target_v7(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
struct cfg80211_pmsr_request_peer *peer,
struct iwl_tof_range_req_ap_entry_v7 *target)
{
int err = iwl_mvm_ftm_put_target(mvm, vif, peer, (void *)target);
if (err)
return err;
iwl_mvm_ftm_set_secured_ranging(mvm, vif, target);
return err;
}
static int iwl_mvm_ftm_start_v11(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct cfg80211_pmsr_request *req)
@ -704,11 +726,67 @@ static int iwl_mvm_ftm_start_v11(struct iwl_mvm *mvm,
struct cfg80211_pmsr_request_peer *peer = &req->peers[i];
struct iwl_tof_range_req_ap_entry_v7 *target = &cmd.ap[i];
err = iwl_mvm_ftm_put_target(mvm, vif, peer, (void *)target);
err = iwl_mvm_ftm_put_target_v7(mvm, vif, peer, target);
if (err)
return err;
}
return iwl_mvm_ftm_send_cmd(mvm, &hcmd);
}
static void
iwl_mvm_ftm_set_ndp_params(struct iwl_mvm *mvm,
struct iwl_tof_range_req_ap_entry_v8 *target)
{
/* Only 2 STS are supported on Tx */
u32 i2r_max_sts = IWL_MVM_FTM_I2R_MAX_STS > 1 ? 1 :
IWL_MVM_FTM_I2R_MAX_STS;
target->r2i_ndp_params = IWL_MVM_FTM_R2I_MAX_REP |
(IWL_MVM_FTM_R2I_MAX_STS << IWL_LOCATION_MAX_STS_POS);
target->i2r_ndp_params = IWL_MVM_FTM_I2R_MAX_REP |
(i2r_max_sts << IWL_LOCATION_MAX_STS_POS);
target->r2i_max_total_ltf = IWL_MVM_FTM_R2I_MAX_TOTAL_LTF;
target->i2r_max_total_ltf = IWL_MVM_FTM_I2R_MAX_TOTAL_LTF;
}
static int iwl_mvm_ftm_start_v12(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct cfg80211_pmsr_request *req)
{
struct iwl_tof_range_req_cmd_v12 cmd;
struct iwl_host_cmd hcmd = {
.id = iwl_cmd_id(TOF_RANGE_REQ_CMD, LOCATION_GROUP, 0),
.dataflags[0] = IWL_HCMD_DFL_DUP,
.data[0] = &cmd,
.len[0] = sizeof(cmd),
};
u8 i;
int err;
iwl_mvm_ftm_cmd_common(mvm, vif, (void *)&cmd, req);
for (i = 0; i < cmd.num_of_ap; i++) {
struct cfg80211_pmsr_request_peer *peer = &req->peers[i];
struct iwl_tof_range_req_ap_entry_v8 *target = &cmd.ap[i];
u32 flags;
err = iwl_mvm_ftm_put_target_v7(mvm, vif, peer, (void *)target);
if (err)
return err;
iwl_mvm_ftm_set_secured_ranging(mvm, vif, target);
iwl_mvm_ftm_set_ndp_params(mvm, target);
/*
* If secure LTF is turned off, replace the flag with PMF only
*/
flags = le32_to_cpu(target->initiator_ap_flags);
if ((flags & IWL_INITIATOR_AP_FLAGS_SECURED) &&
!IWL_MVM_FTM_INITIATOR_SECURE_LTF) {
flags &= ~IWL_INITIATOR_AP_FLAGS_SECURED;
flags |= IWL_INITIATOR_AP_FLAGS_PMF;
target->initiator_ap_flags = cpu_to_le32(flags);
}
}
return iwl_mvm_ftm_send_cmd(mvm, &hcmd);
@ -732,6 +810,9 @@ int iwl_mvm_ftm_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
IWL_FW_CMD_VER_UNKNOWN);
switch (cmd_ver) {
case 12:
err = iwl_mvm_ftm_start_v12(mvm, vif, req);
break;
case 11:
err = iwl_mvm_ftm_start_v11(mvm, vif, req);
break;

View File

@ -75,6 +75,24 @@ static int iwl_mvm_ftm_responder_set_bw_v2(struct cfg80211_chan_def *chandef,
return 0;
}
static void
iwl_mvm_ftm_responder_set_ndp(struct iwl_mvm *mvm,
struct iwl_tof_responder_config_cmd_v8 *cmd)
{
/* Up to 2 R2I STS are allowed on the responder */
u32 r2i_max_sts = IWL_MVM_FTM_R2I_MAX_STS < 2 ?
IWL_MVM_FTM_R2I_MAX_STS : 1;
cmd->r2i_ndp_params = IWL_MVM_FTM_R2I_MAX_REP |
(r2i_max_sts << IWL_RESPONDER_STS_POS) |
(IWL_MVM_FTM_R2I_MAX_TOTAL_LTF << IWL_RESPONDER_TOTAL_LTF_POS);
cmd->i2r_ndp_params = IWL_MVM_FTM_I2R_MAX_REP |
(IWL_MVM_FTM_I2R_MAX_STS << IWL_RESPONDER_STS_POS) |
(IWL_MVM_FTM_I2R_MAX_TOTAL_LTF << IWL_RESPONDER_TOTAL_LTF_POS);
cmd->cmd_valid_fields |=
cpu_to_le32(IWL_TOF_RESPONDER_CMD_VALID_NDP_PARAMS);
}
static int
iwl_mvm_ftm_responder_cmd(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
@ -82,11 +100,11 @@ iwl_mvm_ftm_responder_cmd(struct iwl_mvm *mvm,
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
/*
* The command structure is the same for versions 6 and 7, (only the
* The command structure is the same for versions 6, 7 and 8 (only the
* field interpretation is different), so the same struct can be use
* for all cases.
*/
struct iwl_tof_responder_config_cmd cmd = {
struct iwl_tof_responder_config_cmd_v8 cmd = {
.channel_num = chandef->chan->hw_value,
.cmd_valid_fields =
cpu_to_le32(IWL_TOF_RESPONDER_CMD_VALID_CHAN_INFO |
@ -100,7 +118,10 @@ iwl_mvm_ftm_responder_cmd(struct iwl_mvm *mvm,
lockdep_assert_held(&mvm->mutex);
if (cmd_ver == 7)
if (cmd_ver == 8)
iwl_mvm_ftm_responder_set_ndp(mvm, &cmd);
if (cmd_ver >= 7)
err = iwl_mvm_ftm_responder_set_bw_v2(chandef, &cmd.format_bw,
&cmd.ctrl_ch_position);
else

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2012-2014, 2018-2020 Intel Corporation
* Copyright (C) 2012-2014, 2018-2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@ -29,6 +29,9 @@
#define UCODE_VALID_OK cpu_to_le32(0x1)
#define IWL_PPAG_MASK 3
#define IWL_PPAG_ETSI_MASK BIT(0)
struct iwl_mvm_alive_data {
bool valid;
u32 scd_base_addr;
@ -70,56 +73,6 @@ static int iwl_send_rss_cfg_cmd(struct iwl_mvm *mvm)
return iwl_mvm_send_cmd_pdu(mvm, RSS_CONFIG_CMD, 0, sizeof(cmd), &cmd);
}
static int iwl_configure_rxq(struct iwl_mvm *mvm)
{
int i, num_queues, size, ret;
struct iwl_rfh_queue_config *cmd;
struct iwl_host_cmd hcmd = {
.id = WIDE_ID(DATA_PATH_GROUP, RFH_QUEUE_CONFIG_CMD),
.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
};
/*
* The default queue is configured via context info, so if we
* have a single queue, there's nothing to do here.
*/
if (mvm->trans->num_rx_queues == 1)
return 0;
/* skip the default queue */
num_queues = mvm->trans->num_rx_queues - 1;
size = struct_size(cmd, data, num_queues);
cmd = kzalloc(size, GFP_KERNEL);
if (!cmd)
return -ENOMEM;
cmd->num_queues = num_queues;
for (i = 0; i < num_queues; i++) {
struct iwl_trans_rxq_dma_data data;
cmd->data[i].q_num = i + 1;
iwl_trans_get_rxq_dma_data(mvm->trans, i + 1, &data);
cmd->data[i].fr_bd_cb = cpu_to_le64(data.fr_bd_cb);
cmd->data[i].urbd_stts_wrptr =
cpu_to_le64(data.urbd_stts_wrptr);
cmd->data[i].ur_bd_cb = cpu_to_le64(data.ur_bd_cb);
cmd->data[i].fr_bd_wid = cpu_to_le32(data.fr_bd_wid);
}
hcmd.data[0] = cmd;
hcmd.len[0] = size;
ret = iwl_mvm_send_cmd(mvm, &hcmd);
kfree(cmd);
return ret;
}
static int iwl_mvm_send_dqa_cmd(struct iwl_mvm *mvm)
{
struct iwl_dqa_enable_cmd dqa_cmd = {
@ -233,7 +186,8 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
mvm->trans->dbg.lmac_error_event_table[1] =
le32_to_cpu(lmac2->dbg_ptrs.error_event_table_ptr);
umac_error_table = le32_to_cpu(umac->dbg_ptrs.error_info_addr);
umac_error_table = le32_to_cpu(umac->dbg_ptrs.error_info_addr) &
~FW_ADDR_CACHE_CONTROL;
if (umac_error_table) {
if (umac_error_table >=
@ -773,16 +727,16 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
} else if (fw_has_api(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_API_REDUCE_TX_POWER)) {
len = sizeof(cmd.v5);
n_subbands = IWL_NUM_SUB_BANDS;
n_subbands = IWL_NUM_SUB_BANDS_V1;
per_chain = cmd.v5.per_chain[0][0];
} else if (fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_TX_POWER_ACK)) {
len = sizeof(cmd.v4);
n_subbands = IWL_NUM_SUB_BANDS;
n_subbands = IWL_NUM_SUB_BANDS_V1;
per_chain = cmd.v4.per_chain[0][0];
} else {
len = sizeof(cmd.v3);
n_subbands = IWL_NUM_SUB_BANDS;
n_subbands = IWL_NUM_SUB_BANDS_V1;
per_chain = cmd.v3.per_chain[0][0];
}
@ -909,46 +863,50 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
static int iwl_mvm_get_ppag_table(struct iwl_mvm *mvm)
{
union acpi_object *wifi_pkg, *data, *enabled;
union acpi_object *wifi_pkg, *data, *flags;
int i, j, ret, tbl_rev, num_sub_bands;
int idx = 2;
s8 *gain;
/*
* The 'enabled' field is the same in v1 and v2 so we can just
* The 'flags' field is the same in v1 and in v2 so we can just
* use v1 to access it.
*/
mvm->fwrt.ppag_table.v1.enabled = cpu_to_le32(0);
mvm->fwrt.ppag_table.v1.flags = cpu_to_le32(0);
data = iwl_acpi_get_object(mvm->dev, ACPI_PPAG_METHOD);
if (IS_ERR(data))
return PTR_ERR(data);
/* try to read ppag table revision 1 */
/* try to read ppag table rev 2 or 1 (both have the same data size) */
wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data,
ACPI_PPAG_WIFI_DATA_SIZE_V2, &tbl_rev);
if (!IS_ERR(wifi_pkg)) {
if (tbl_rev != 1) {
if (tbl_rev == 1 || tbl_rev == 2) {
num_sub_bands = IWL_NUM_SUB_BANDS_V2;
gain = mvm->fwrt.ppag_table.v2.gain[0];
mvm->fwrt.ppag_ver = tbl_rev;
IWL_DEBUG_RADIO(mvm,
"Reading PPAG table v2 (tbl_rev=%d)\n",
tbl_rev);
goto read_table;
} else {
ret = -EINVAL;
goto out_free;
}
num_sub_bands = IWL_NUM_SUB_BANDS_V2;
gain = mvm->fwrt.ppag_table.v2.gain[0];
mvm->fwrt.ppag_ver = 2;
IWL_DEBUG_RADIO(mvm, "Reading PPAG table v2 (tbl_rev=1)\n");
goto read_table;
}
/* try to read ppag table revision 0 */
wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data,
ACPI_PPAG_WIFI_DATA_SIZE, &tbl_rev);
ACPI_PPAG_WIFI_DATA_SIZE_V1, &tbl_rev);
if (!IS_ERR(wifi_pkg)) {
if (tbl_rev != 0) {
ret = -EINVAL;
goto out_free;
}
num_sub_bands = IWL_NUM_SUB_BANDS;
num_sub_bands = IWL_NUM_SUB_BANDS_V1;
gain = mvm->fwrt.ppag_table.v1.gain[0];
mvm->fwrt.ppag_ver = 1;
mvm->fwrt.ppag_ver = 0;
IWL_DEBUG_RADIO(mvm, "Reading PPAG table v1 (tbl_rev=0)\n");
goto read_table;
}
@ -956,15 +914,17 @@ static int iwl_mvm_get_ppag_table(struct iwl_mvm *mvm)
goto out_free;
read_table:
enabled = &wifi_pkg->package.elements[1];
if (enabled->type != ACPI_TYPE_INTEGER ||
(enabled->integer.value != 0 && enabled->integer.value != 1)) {
flags = &wifi_pkg->package.elements[1];
if (flags->type != ACPI_TYPE_INTEGER) {
ret = -EINVAL;
goto out_free;
}
mvm->fwrt.ppag_table.v1.enabled = cpu_to_le32(enabled->integer.value);
if (!mvm->fwrt.ppag_table.v1.enabled) {
mvm->fwrt.ppag_table.v1.flags = cpu_to_le32(flags->integer.value &
IWL_PPAG_MASK);
if (!mvm->fwrt.ppag_table.v1.flags) {
ret = 0;
goto out_free;
}
@ -992,12 +952,13 @@ read_table:
(j != 0 &&
(gain[i * num_sub_bands + j] > ACPI_PPAG_MAX_HB ||
gain[i * num_sub_bands + j] < ACPI_PPAG_MIN_HB))) {
mvm->fwrt.ppag_table.v1.enabled = cpu_to_le32(0);
mvm->fwrt.ppag_table.v1.flags = cpu_to_le32(0);
ret = -EINVAL;
goto out_free;
}
}
}
ret = 0;
out_free:
kfree(data);
@ -1015,7 +976,7 @@ int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm)
"PPAG capability not supported by FW, command not sent.\n");
return 0;
}
if (!mvm->fwrt.ppag_table.v1.enabled) {
if (!mvm->fwrt.ppag_table.v1.flags) {
IWL_DEBUG_RADIO(mvm, "PPAG not enabled, command not sent.\n");
return 0;
}
@ -1024,20 +985,28 @@ int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm)
PER_PLATFORM_ANT_GAIN_CMD,
IWL_FW_CMD_VER_UNKNOWN);
if (cmd_ver == 1) {
num_sub_bands = IWL_NUM_SUB_BANDS;
num_sub_bands = IWL_NUM_SUB_BANDS_V1;
gain = mvm->fwrt.ppag_table.v1.gain[0];
cmd_size = sizeof(mvm->fwrt.ppag_table.v1);
if (mvm->fwrt.ppag_ver == 2) {
if (mvm->fwrt.ppag_ver == 1 || mvm->fwrt.ppag_ver == 2) {
IWL_DEBUG_RADIO(mvm,
"PPAG table is v2 but FW supports v1, sending truncated table\n");
"PPAG table rev is %d but FW supports v1, sending truncated table\n",
mvm->fwrt.ppag_ver);
mvm->fwrt.ppag_table.v1.flags &=
cpu_to_le32(IWL_PPAG_ETSI_MASK);
}
} else if (cmd_ver == 2) {
} else if (cmd_ver == 2 || cmd_ver == 3) {
num_sub_bands = IWL_NUM_SUB_BANDS_V2;
gain = mvm->fwrt.ppag_table.v2.gain[0];
cmd_size = sizeof(mvm->fwrt.ppag_table.v2);
if (mvm->fwrt.ppag_ver == 1) {
if (mvm->fwrt.ppag_ver == 0) {
IWL_DEBUG_RADIO(mvm,
"PPAG table is v1 but FW supports v2, sending padded table\n");
} else if (cmd_ver == 2 && mvm->fwrt.ppag_ver == 2) {
IWL_DEBUG_RADIO(mvm,
"PPAG table is v3 but FW supports v2, sending partial bitmap.\n");
mvm->fwrt.ppag_table.v1.flags &=
cpu_to_le32(IWL_PPAG_ETSI_MASK);
}
} else {
IWL_DEBUG_RADIO(mvm, "Unsupported PPAG command version\n");
@ -1102,7 +1071,7 @@ static int iwl_mvm_ppag_init(struct iwl_mvm *mvm)
IWL_DEBUG_RADIO(mvm,
"System vendor '%s' is not in the approved list, disabling PPAG.\n",
dmi_get_system_info(DMI_SYS_VENDOR));
mvm->fwrt.ppag_table.v1.enabled = cpu_to_le32(0);
mvm->fwrt.ppag_table.v1.flags = cpu_to_le32(0);
return 0;
}
@ -1144,33 +1113,6 @@ static void iwl_mvm_tas_init(struct iwl_mvm *mvm)
IWL_DEBUG_RADIO(mvm, "failed to send TAS_CONFIG (%d)\n", ret);
}
static u8 iwl_mvm_eval_dsm_indonesia_5g2(struct iwl_mvm *mvm)
{
u8 value;
int ret = iwl_acpi_get_dsm_u8((&mvm->fwrt)->dev, 0,
DSM_FUNC_ENABLE_INDONESIA_5G2,
&iwl_guid, &value);
if (ret < 0)
IWL_DEBUG_RADIO(mvm,
"Failed to evaluate DSM function ENABLE_INDONESIA_5G2, ret=%d\n",
ret);
else if (value >= DSM_VALUE_INDONESIA_MAX)
IWL_DEBUG_RADIO(mvm,
"DSM function ENABLE_INDONESIA_5G2 return invalid value, value=%d\n",
value);
else if (value == DSM_VALUE_INDONESIA_ENABLE) {
IWL_DEBUG_RADIO(mvm,
"Evaluated DSM function ENABLE_INDONESIA_5G2: Enabling 5g2\n");
return DSM_VALUE_INDONESIA_ENABLE;
}
/* default behaviour is disabled */
return DSM_VALUE_INDONESIA_DISABLE;
}
static u8 iwl_mvm_eval_dsm_rfi(struct iwl_mvm *mvm)
{
u8 value;
@ -1195,64 +1137,27 @@ static u8 iwl_mvm_eval_dsm_rfi(struct iwl_mvm *mvm)
return DSM_VALUE_RFI_DISABLE;
}
static u8 iwl_mvm_eval_dsm_disable_srd(struct iwl_mvm *mvm)
{
u8 value;
int ret = iwl_acpi_get_dsm_u8((&mvm->fwrt)->dev, 0,
DSM_FUNC_DISABLE_SRD,
&iwl_guid, &value);
if (ret < 0)
IWL_DEBUG_RADIO(mvm,
"Failed to evaluate DSM function DISABLE_SRD, ret=%d\n",
ret);
else if (value >= DSM_VALUE_SRD_MAX)
IWL_DEBUG_RADIO(mvm,
"DSM function DISABLE_SRD return invalid value, value=%d\n",
value);
else if (value == DSM_VALUE_SRD_PASSIVE) {
IWL_DEBUG_RADIO(mvm,
"Evaluated DSM function DISABLE_SRD: setting SRD to passive\n");
return DSM_VALUE_SRD_PASSIVE;
} else if (value == DSM_VALUE_SRD_DISABLE) {
IWL_DEBUG_RADIO(mvm,
"Evaluated DSM function DISABLE_SRD: disabling SRD\n");
return DSM_VALUE_SRD_DISABLE;
}
/* default behaviour is active */
return DSM_VALUE_SRD_ACTIVE;
}
static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm)
{
u8 ret;
int cmd_ret;
struct iwl_lari_config_change_cmd_v2 cmd = {};
struct iwl_lari_config_change_cmd_v3 cmd = {};
if (iwl_mvm_eval_dsm_indonesia_5g2(mvm) == DSM_VALUE_INDONESIA_ENABLE)
cmd.config_bitmap |=
cpu_to_le32(LARI_CONFIG_ENABLE_5G2_IN_INDONESIA_MSK);
ret = iwl_mvm_eval_dsm_disable_srd(mvm);
if (ret == DSM_VALUE_SRD_PASSIVE)
cmd.config_bitmap |=
cpu_to_le32(LARI_CONFIG_CHANGE_ETSI_TO_PASSIVE_MSK);
else if (ret == DSM_VALUE_SRD_DISABLE)
cmd.config_bitmap |=
cpu_to_le32(LARI_CONFIG_CHANGE_ETSI_TO_DISABLED_MSK);
cmd.config_bitmap = iwl_acpi_get_lari_config_bitmap(&mvm->fwrt);
/* apply more config masks here */
if (cmd.config_bitmap) {
size_t cmd_size = iwl_fw_lookup_cmd_ver(mvm->fw,
REGULATORY_AND_NVM_GROUP,
LARI_CONFIG_CHANGE, 1) == 2 ?
sizeof(struct iwl_lari_config_change_cmd_v2) :
sizeof(struct iwl_lari_config_change_cmd_v1);
size_t cmd_size;
u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw,
REGULATORY_AND_NVM_GROUP,
LARI_CONFIG_CHANGE, 1);
if (cmd_ver == 3)
cmd_size = sizeof(struct iwl_lari_config_change_cmd_v3);
else if (cmd_ver == 2)
cmd_size = sizeof(struct iwl_lari_config_change_cmd_v2);
else
cmd_size = sizeof(struct iwl_lari_config_change_cmd_v1);
IWL_DEBUG_RADIO(mvm,
"sending LARI_CONFIG_CHANGE, config_bitmap=0x%x\n",
le32_to_cpu(cmd.config_bitmap));
@ -1485,14 +1390,9 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
}
/* Init RSS configuration */
if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) {
ret = iwl_configure_rxq(mvm);
if (ret) {
IWL_ERR(mvm, "Failed to configure RX queues: %d\n",
ret);
goto error;
}
}
ret = iwl_configure_rxq(&mvm->fwrt);
if (ret)
goto error;
if (iwl_mvm_has_new_rx_api(mvm)) {
ret = iwl_send_rss_cfg_cmd(mvm);

View File

@ -1099,6 +1099,8 @@ int __iwl_mvm_mac_start(struct iwl_mvm *mvm)
iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_PERIODIC,
NULL);
mvm->last_reset_or_resume_time_jiffies = jiffies;
if (ret && test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
/* Something went wrong - we need to finish some cleanup
* that normally iwl_mvm_mac_restart_complete() below
@ -4610,6 +4612,16 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
break;
case NL80211_IFTYPE_STATION:
/*
* We haven't configured the firmware to be associated yet since
* we don't know the dtim period. In this case, the firmware can't
* track the beacons.
*/
if (!vif->bss_conf.assoc || !vif->bss_conf.dtim_period) {
ret = -EBUSY;
goto out_unlock;
}
if (chsw->delay > IWL_MAX_CSA_BLOCK_TX)
schedule_delayed_work(&mvmvif->csa_work, 0);
@ -5134,28 +5146,50 @@ static void iwl_mvm_mac_event_callback(struct ieee80211_hw *hw,
}
void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
struct iwl_mvm_internal_rxq_notif *notif,
u32 size)
enum iwl_mvm_rxq_notif_type type,
bool sync,
const void *data, u32 size)
{
u32 qmask = BIT(mvm->trans->num_rx_queues) - 1;
struct {
struct iwl_rxq_sync_cmd cmd;
struct iwl_mvm_internal_rxq_notif notif;
} __packed cmd = {
.cmd.rxq_mask = cpu_to_le32(BIT(mvm->trans->num_rx_queues) - 1),
.cmd.count =
cpu_to_le32(sizeof(struct iwl_mvm_internal_rxq_notif) +
size),
.notif.type = type,
.notif.sync = sync,
};
struct iwl_host_cmd hcmd = {
.id = WIDE_ID(DATA_PATH_GROUP, TRIGGER_RX_QUEUES_NOTIF_CMD),
.data[0] = &cmd,
.len[0] = sizeof(cmd),
.data[1] = data,
.len[1] = size,
.flags = sync ? 0 : CMD_ASYNC,
};
int ret;
/* size must be a multiple of DWORD */
if (WARN_ON(cmd.cmd.count & cpu_to_le32(3)))
return;
if (!iwl_mvm_has_new_rx_api(mvm))
return;
if (notif->sync) {
notif->cookie = mvm->queue_sync_cookie;
if (sync) {
cmd.notif.cookie = mvm->queue_sync_cookie;
mvm->queue_sync_state = (1 << mvm->trans->num_rx_queues) - 1;
}
ret = iwl_mvm_notify_rx_queue(mvm, qmask, notif, size, !notif->sync);
ret = iwl_mvm_send_cmd(mvm, &hcmd);
if (ret) {
IWL_ERR(mvm, "Failed to trigger RX queues sync (%d)\n", ret);
goto out;
}
if (notif->sync) {
if (sync) {
lockdep_assert_held(&mvm->mutex);
ret = wait_event_timeout(mvm->rx_sync_waitq,
READ_ONCE(mvm->queue_sync_state) == 0 ||
@ -5167,21 +5201,18 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
}
out:
mvm->queue_sync_state = 0;
if (notif->sync)
if (sync) {
mvm->queue_sync_state = 0;
mvm->queue_sync_cookie++;
}
}
static void iwl_mvm_sync_rx_queues(struct ieee80211_hw *hw)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
struct iwl_mvm_internal_rxq_notif data = {
.type = IWL_MVM_RXQ_EMPTY,
.sync = 1,
};
mutex_lock(&mvm->mutex);
iwl_mvm_sync_rx_queues_internal(mvm, &data, sizeof(data));
iwl_mvm_sync_rx_queues_internal(mvm, IWL_MVM_RXQ_EMPTY, true, NULL, 0);
mutex_unlock(&mvm->mutex);
}

View File

@ -591,7 +591,6 @@ struct iwl_mvm_tcm {
enum iwl_mvm_traffic_load global_load;
bool low_latency[NUM_MAC_INDEX_DRIVER];
bool change[NUM_MAC_INDEX_DRIVER];
bool global_change;
} result;
};
@ -1096,6 +1095,9 @@ struct iwl_mvm {
/* sniffer data to include in radiotap */
__le16 cur_aid;
u8 cur_bssid[ETH_ALEN];
unsigned long last_6ghz_passive_scan_jiffies;
unsigned long last_reset_or_resume_time_jiffies;
};
/* Extract MVM priv from op_mode and _hw */
@ -1570,9 +1572,6 @@ void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi,
struct iwl_rx_cmd_buffer *rxb, int queue);
void iwl_mvm_rx_bar_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi,
struct iwl_rx_cmd_buffer *rxb, int queue);
int iwl_mvm_notify_rx_queue(struct iwl_mvm *mvm, u32 rxq_mask,
const struct iwl_mvm_internal_rxq_notif *notif,
u32 notif_size, bool async);
void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct napi_struct *napi,
struct iwl_rx_cmd_buffer *rxb, int queue);
void iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
@ -2001,8 +2000,9 @@ void iwl_mvm_rx_tdls_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
void iwl_mvm_tdls_ch_switch_work(struct work_struct *work);
void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
struct iwl_mvm_internal_rxq_notif *notif,
u32 size);
enum iwl_mvm_rxq_notif_type type,
bool sync,
const void *data, u32 size);
void iwl_mvm_reorder_timer_expired(struct timer_list *t);
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);

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2017 Intel Deutschland GmbH
* Copyright (C) 2018-2020 Intel Corporation
* Copyright (C) 2018-2021 Intel Corporation
*/
#include "rs.h"
#include "fw-api.h"
@ -72,19 +72,15 @@ static u16 rs_fw_get_config_flags(struct iwl_mvm *mvm,
bool vht_ena = vht_cap->vht_supported;
u16 flags = 0;
/* get STBC flags */
if (mvm->cfg->ht_params->stbc &&
(num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1)) {
if (he_cap->has_he) {
if (he_cap->he_cap_elem.phy_cap_info[2] &
IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ)
flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK;
if (he_cap->he_cap_elem.phy_cap_info[7] &
IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ)
flags |= IWL_TLC_MNG_CFG_FLAGS_HE_STBC_160MHZ_MSK;
} else if ((ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) ||
(vht_ena &&
(vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK)))
if (he_cap->has_he && he_cap->he_cap_elem.phy_cap_info[2] &
IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ)
flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK;
else if (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK)
flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK;
else if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC)
flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK;
}

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/******************************************************************************
*
* Copyright(c) 2005 - 2014, 2018 - 2020 Intel Corporation. All rights reserved.
* Copyright(c) 2005 - 2014, 2018 - 2021 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
*
@ -1926,9 +1926,7 @@ static bool rs_tpc_allowed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
if (is_ht(rate))
return index == IWL_RATE_MCS_7_INDEX;
if (is_vht(rate))
return index == IWL_RATE_MCS_7_INDEX ||
index == IWL_RATE_MCS_8_INDEX ||
index == IWL_RATE_MCS_9_INDEX;
return index == IWL_RATE_MCS_9_INDEX;
WARN_ON_ONCE(1);
return false;

View File

@ -527,37 +527,6 @@ static bool iwl_mvm_is_dup(struct ieee80211_sta *sta, int queue,
return false;
}
int iwl_mvm_notify_rx_queue(struct iwl_mvm *mvm, u32 rxq_mask,
const struct iwl_mvm_internal_rxq_notif *notif,
u32 notif_size, bool async)
{
u8 buf[sizeof(struct iwl_rxq_sync_cmd) +
sizeof(struct iwl_mvm_rss_sync_notif)];
struct iwl_rxq_sync_cmd *cmd = (void *)buf;
u32 data_size = sizeof(*cmd) + notif_size;
int ret;
/*
* size must be a multiple of DWORD
* Ensure we don't overflow buf
*/
if (WARN_ON(notif_size & 3 ||
notif_size > sizeof(struct iwl_mvm_rss_sync_notif)))
return -EINVAL;
cmd->rxq_mask = cpu_to_le32(rxq_mask);
cmd->count = cpu_to_le32(notif_size);
cmd->flags = 0;
memcpy(cmd->payload, notif, notif_size);
ret = iwl_mvm_send_cmd_pdu(mvm,
WIDE_ID(DATA_PATH_GROUP,
TRIGGER_RX_QUEUES_NOTIF_CMD),
async ? CMD_ASYNC : 0, data_size, cmd);
return ret;
}
/*
* Returns true if sn2 - buffer_size < sn1 < sn2.
* To be used only in order to compare reorder buffer head with NSSN.
@ -573,15 +542,13 @@ static bool iwl_mvm_is_sn_less(u16 sn1, u16 sn2, u16 buffer_size)
static void iwl_mvm_sync_nssn(struct iwl_mvm *mvm, u8 baid, u16 nssn)
{
if (IWL_MVM_USE_NSSN_SYNC) {
struct iwl_mvm_rss_sync_notif notif = {
.metadata.type = IWL_MVM_RXQ_NSSN_SYNC,
.metadata.sync = 0,
.nssn_sync.baid = baid,
.nssn_sync.nssn = nssn,
struct iwl_mvm_nssn_sync_data notif = {
.baid = baid,
.nssn = nssn,
};
iwl_mvm_sync_rx_queues_internal(mvm, (void *)&notif,
sizeof(notif));
iwl_mvm_sync_rx_queues_internal(mvm, IWL_MVM_RXQ_NSSN_SYNC, false,
&notif, sizeof(notif));
}
}
@ -830,8 +797,7 @@ void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct napi_struct *napi,
"invalid notification size %d (%d)",
len, (int)(sizeof(*notif) + sizeof(*internal_notif))))
return;
/* remove only the firmware header, we want all of our payload below */
len -= sizeof(*notif);
len -= sizeof(*notif) + sizeof(*internal_notif);
if (internal_notif->sync &&
mvm->queue_sync_cookie != internal_notif->cookie) {
@ -841,21 +807,19 @@ void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct napi_struct *napi,
switch (internal_notif->type) {
case IWL_MVM_RXQ_EMPTY:
WARN_ONCE(len != sizeof(*internal_notif),
"invalid empty notification size %d (%d)",
len, (int)sizeof(*internal_notif));
WARN_ONCE(len, "invalid empty notification size %d", len);
break;
case IWL_MVM_RXQ_NOTIF_DEL_BA:
if (WARN_ONCE(len != sizeof(struct iwl_mvm_rss_sync_notif),
if (WARN_ONCE(len != sizeof(struct iwl_mvm_delba_data),
"invalid delba notification size %d (%d)",
len, (int)sizeof(struct iwl_mvm_rss_sync_notif)))
len, (int)sizeof(struct iwl_mvm_delba_data)))
break;
iwl_mvm_del_ba(mvm, queue, (void *)internal_notif->data);
break;
case IWL_MVM_RXQ_NSSN_SYNC:
if (WARN_ONCE(len != sizeof(struct iwl_mvm_rss_sync_notif),
if (WARN_ONCE(len != sizeof(struct iwl_mvm_nssn_sync_data),
"invalid nssn sync notification size %d (%d)",
len, (int)sizeof(struct iwl_mvm_rss_sync_notif)))
len, (int)sizeof(struct iwl_mvm_nssn_sync_data)))
break;
iwl_mvm_nssn_sync(mvm, napi, queue,
(void *)internal_notif->data);

View File

@ -43,6 +43,9 @@
/* adaptive dwell number of APs override for social channels */
#define IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS 2
/* minimal number of 2GHz and 5GHz channels in the regular scan request */
#define IWL_MVM_6GHZ_PASSIVE_SCAN_MIN_CHANS 4
struct iwl_mvm_scan_timing_params {
u32 suspend_time;
u32 max_out_time;
@ -94,6 +97,7 @@ struct iwl_mvm_scan_params {
struct cfg80211_scan_6ghz_params *scan_6ghz_params;
u32 n_6ghz_params;
bool scan_6ghz;
bool enable_6ghz_passive;
};
static inline void *iwl_mvm_get_scan_req_umac_data(struct iwl_mvm *mvm)
@ -1873,6 +1877,98 @@ static u8 iwl_mvm_scan_umac_chan_flags_v2(struct iwl_mvm *mvm,
return flags;
}
static void iwl_mvm_scan_6ghz_passive_scan(struct iwl_mvm *mvm,
struct iwl_mvm_scan_params *params,
struct ieee80211_vif *vif)
{
struct ieee80211_supported_band *sband =
&mvm->nvm_data->bands[NL80211_BAND_6GHZ];
u32 n_disabled, i;
params->enable_6ghz_passive = false;
if (params->scan_6ghz)
return;
if (!fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_PASSIVE_6GHZ_SCAN)) {
IWL_DEBUG_SCAN(mvm,
"6GHz passive scan: Not supported by FW\n");
return;
}
/* 6GHz passive scan allowed only on station interface */
if (vif->type != NL80211_IFTYPE_STATION) {
IWL_DEBUG_SCAN(mvm,
"6GHz passive scan: not station interface\n");
return;
}
/*
* 6GHz passive scan is allowed while associated in a defined time
* interval following HW reset or resume flow
*/
if (vif->bss_conf.assoc &&
(time_before(mvm->last_reset_or_resume_time_jiffies +
(IWL_MVM_6GHZ_PASSIVE_SCAN_ASSOC_TIMEOUT * HZ),
jiffies))) {
IWL_DEBUG_SCAN(mvm, "6GHz passive scan: associated\n");
return;
}
/* No need for 6GHz passive scan if not enough time elapsed */
if (time_after(mvm->last_6ghz_passive_scan_jiffies +
(IWL_MVM_6GHZ_PASSIVE_SCAN_TIMEOUT * HZ), jiffies)) {
IWL_DEBUG_SCAN(mvm,
"6GHz passive scan: timeout did not expire\n");
return;
}
/* not enough channels in the regular scan request */
if (params->n_channels < IWL_MVM_6GHZ_PASSIVE_SCAN_MIN_CHANS) {
IWL_DEBUG_SCAN(mvm,
"6GHz passive scan: not enough channels\n");
return;
}
for (i = 0; i < params->n_ssids; i++) {
if (!params->ssids[i].ssid_len)
break;
}
/* not a wildcard scan, so cannot enable passive 6GHz scan */
if (i == params->n_ssids) {
IWL_DEBUG_SCAN(mvm,
"6GHz passive scan: no wildcard SSID\n");
return;
}
if (!sband || !sband->n_channels) {
IWL_DEBUG_SCAN(mvm,
"6GHz passive scan: no 6GHz channels\n");
return;
}
for (i = 0, n_disabled = 0; i < sband->n_channels; i++) {
if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED))
n_disabled++;
}
/*
* Not all the 6GHz channels are disabled, so no need for 6GHz passive
* scan
*/
if (n_disabled != sband->n_channels) {
IWL_DEBUG_SCAN(mvm,
"6GHz passive scan: 6GHz channels enabled\n");
return;
}
/* all conditions to enable 6ghz passive scan are satisfied */
IWL_DEBUG_SCAN(mvm, "6GHz passive scan: can be enabled\n");
params->enable_6ghz_passive = true;
}
static u16 iwl_mvm_scan_umac_flags_v2(struct iwl_mvm *mvm,
struct iwl_mvm_scan_params *params,
struct ieee80211_vif *vif,
@ -1911,6 +2007,9 @@ static u16 iwl_mvm_scan_umac_flags_v2(struct iwl_mvm *mvm,
params->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ)
flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_TRIGGER_UHB_SCAN;
if (params->enable_6ghz_passive)
flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN;
return flags;
}
@ -2183,6 +2282,30 @@ iwl_mvm_scan_umac_fill_ch_p_v6(struct iwl_mvm *mvm,
params->n_channels,
channel_cfg_flags,
vif->type);
if (params->enable_6ghz_passive) {
struct ieee80211_supported_band *sband =
&mvm->nvm_data->bands[NL80211_BAND_6GHZ];
u32 i;
for (i = 0; i < sband->n_channels; i++) {
struct ieee80211_channel *channel =
&sband->channels[i];
struct iwl_scan_channel_cfg_umac *cfg =
&cp->channel_config[cp->count];
if (!cfg80211_channel_is_psc(channel))
continue;
cfg->flags = 0;
cfg->v2.channel_num = channel->hw_value;
cfg->v2.band = PHY_BAND_6;
cfg->v2.iter_count = 1;
cfg->v2.iter_interval = 0;
cp->count++;
}
}
}
static int iwl_mvm_scan_umac_v12(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
@ -2500,6 +2623,8 @@ int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
iwl_mvm_build_scan_probe(mvm, vif, ies, &params);
iwl_mvm_scan_6ghz_passive_scan(mvm, &params, vif);
uid = iwl_mvm_build_scan_cmd(mvm, vif, &hcmd, &params,
IWL_MVM_SCAN_REGULAR);
@ -2524,6 +2649,9 @@ int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
mvm->scan_status |= IWL_MVM_SCAN_REGULAR;
mvm->scan_vif = iwl_mvm_vif_from_mac80211(vif);
if (params.enable_6ghz_passive)
mvm->last_6ghz_passive_scan_jiffies = jiffies;
schedule_delayed_work(&mvm->scan_timeout_dwork,
msecs_to_jiffies(SCAN_TIMEOUT));

View File

@ -2441,12 +2441,12 @@ int iwl_mvm_rm_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
static void iwl_mvm_sync_rxq_del_ba(struct iwl_mvm *mvm, u8 baid)
{
struct iwl_mvm_rss_sync_notif notif = {
.metadata.type = IWL_MVM_RXQ_NOTIF_DEL_BA,
.metadata.sync = 1,
.delba.baid = baid,
struct iwl_mvm_delba_data notif = {
.baid = baid,
};
iwl_mvm_sync_rx_queues_internal(mvm, (void *)&notif, sizeof(notif));
iwl_mvm_sync_rx_queues_internal(mvm, IWL_MVM_RXQ_NOTIF_DEL_BA, true,
&notif, sizeof(notif));
};
static void iwl_mvm_free_reorder(struct iwl_mvm *mvm,

View File

@ -281,6 +281,36 @@ struct iwl_mvm_key_pn {
} ____cacheline_aligned_in_smp q[];
};
/**
* enum iwl_mvm_rxq_notif_type - Internal message identifier
*
* @IWL_MVM_RXQ_EMPTY: empty sync notification
* @IWL_MVM_RXQ_NOTIF_DEL_BA: notify RSS queues of delBA
* @IWL_MVM_RXQ_NSSN_SYNC: notify all the RSS queues with the new NSSN
*/
enum iwl_mvm_rxq_notif_type {
IWL_MVM_RXQ_EMPTY,
IWL_MVM_RXQ_NOTIF_DEL_BA,
IWL_MVM_RXQ_NSSN_SYNC,
};
/**
* struct iwl_mvm_internal_rxq_notif - Internal representation of the data sent
* in &iwl_rxq_sync_cmd. Should be DWORD aligned.
* FW is agnostic to the payload, so there are no endianity requirements.
*
* @type: value from &iwl_mvm_rxq_notif_type
* @sync: ctrl path is waiting for all notifications to be received
* @cookie: internal cookie to identify old notifications
* @data: payload
*/
struct iwl_mvm_internal_rxq_notif {
u16 type;
u16 sync;
u32 cookie;
u8 data[];
} __packed;
struct iwl_mvm_delba_data {
u32 baid;
} __packed;
@ -290,14 +320,6 @@ struct iwl_mvm_nssn_sync_data {
u32 nssn;
} __packed;
struct iwl_mvm_rss_sync_notif {
struct iwl_mvm_internal_rxq_notif metadata;
union {
struct iwl_mvm_delba_data delba;
struct iwl_mvm_nssn_sync_data nssn_sync;
};
} __packed;
/**
* struct iwl_mvm_rxq_dup_data - per station per rx queue data
* @last_seq: last sequence per tid for duplicate packet detection

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2012-2014, 2018-2020 Intel Corporation
* Copyright (C) 2012-2014, 2018-2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2017 Intel Deutschland GmbH
*/
@ -151,6 +151,16 @@ static bool iwl_mvm_te_check_disconnect(struct iwl_mvm *mvm,
if (errmsg)
IWL_ERR(mvm, "%s\n", errmsg);
if (mvmvif->csa_bcn_pending) {
struct iwl_mvm_sta *mvmsta;
rcu_read_lock();
mvmsta = iwl_mvm_sta_from_staid_rcu(mvm, mvmvif->ap_sta_id);
if (!WARN_ON(!mvmsta))
iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false);
rcu_read_unlock();
}
iwl_mvm_connection_loss(mvm, vif, errmsg);
return true;
}
@ -284,6 +294,17 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
iwl_mvm_roc_finished(mvm);
break;
case NL80211_IFTYPE_STATION:
/*
* If we are switching channel, don't disconnect
* if the time event is already done. Beacons can
* be delayed a bit after the switch.
*/
if (te_data->id == TE_CHANNEL_SWITCH_PERIOD) {
IWL_DEBUG_TE(mvm,
"No beacon heard and the CS time event is over, don't disconnect\n");
break;
}
/*
* By now, we should have finished association
* and know the dtim period.
@ -713,8 +734,8 @@ void iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
IWL_DEBUG_TE(mvm, "Removing TE 0x%x\n", le32_to_cpu(time_cmd.id));
ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, 0,
sizeof(time_cmd), &time_cmd);
if (WARN_ON(ret))
return;
if (ret)
IWL_ERR(mvm, "Couldn't remove the time event\n");
}
/*

View File

@ -1030,15 +1030,9 @@ iwl_mvm_tcm_load(struct iwl_mvm *mvm, u32 airtime, unsigned long elapsed)
return IWL_MVM_TRAFFIC_LOW;
}
struct iwl_mvm_tcm_iter_data {
struct iwl_mvm *mvm;
bool any_sent;
};
static void iwl_mvm_tcm_iter(void *_data, u8 *mac, struct ieee80211_vif *vif)
{
struct iwl_mvm_tcm_iter_data *data = _data;
struct iwl_mvm *mvm = data->mvm;
struct iwl_mvm *mvm = _data;
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
bool low_latency, prev = mvmvif->low_latency & LOW_LATENCY_TRAFFIC;
@ -1060,22 +1054,15 @@ static void iwl_mvm_tcm_iter(void *_data, u8 *mac, struct ieee80211_vif *vif)
} else {
iwl_mvm_update_quotas(mvm, false, NULL);
}
data->any_sent = true;
}
static void iwl_mvm_tcm_results(struct iwl_mvm *mvm)
{
struct iwl_mvm_tcm_iter_data data = {
.mvm = mvm,
.any_sent = false,
};
mutex_lock(&mvm->mutex);
ieee80211_iterate_active_interfaces(
mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_tcm_iter, &data);
iwl_mvm_tcm_iter, mvm);
if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN))
iwl_mvm_config_scan(mvm);
@ -1257,7 +1244,6 @@ static unsigned long iwl_mvm_calc_tcm_stats(struct iwl_mvm *mvm,
}
load = iwl_mvm_tcm_load(mvm, total_airtime, elapsed);
mvm->tcm.result.global_change = load != mvm->tcm.result.global_load;
mvm->tcm.result.global_load = load;
for (i = 0; i < NUM_NL80211_BANDS; i++) {

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2005-2014, 2018-2020 Intel Corporation
* Copyright (C) 2005-2014, 2018-2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@ -17,10 +17,20 @@
#include "iwl-prph.h"
#include "internal.h"
#define TRANS_CFG_MARKER BIT(0)
#define _IS_A(cfg, _struct) __builtin_types_compatible_p(typeof(cfg), \
struct _struct)
extern int _invalid_type;
#define _TRANS_CFG_MARKER(cfg) \
(__builtin_choose_expr(_IS_A(cfg, iwl_cfg_trans_params), \
TRANS_CFG_MARKER, \
__builtin_choose_expr(_IS_A(cfg, iwl_cfg), 0, _invalid_type)))
#define _ASSIGN_CFG(cfg) (_TRANS_CFG_MARKER(cfg) + (kernel_ulong_t)&(cfg))
#define IWL_PCI_DEVICE(dev, subdev, cfg) \
.vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \
.subvendor = PCI_ANY_ID, .subdevice = (subdev), \
.driver_data = (kernel_ulong_t)&(cfg)
.driver_data = _ASSIGN_CFG(cfg)
/* Hardware specific file defines the PCI IDs table for that hardware module */
static const struct pci_device_id iwl_hw_card_ids[] = {
@ -490,6 +500,8 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x2729, PCI_ANY_ID, iwl_ma_trans_cfg)},
{IWL_PCI_DEVICE(0x7E40, PCI_ANY_ID, iwl_ma_trans_cfg)},
/* Bz devices */
{IWL_PCI_DEVICE(0x2727, PCI_ANY_ID, iwl_bz_trans_cfg)},
#endif /* CONFIG_IWLMVM */
{0}
@ -607,6 +619,8 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
IWL_DEV_INFO(0x2725, 0x4020, iwlax210_2ax_cfg_ty_gf_a0, NULL),
IWL_DEV_INFO(0x2725, 0x6020, iwlax210_2ax_cfg_ty_gf_a0, NULL),
IWL_DEV_INFO(0x2725, 0x6024, iwlax210_2ax_cfg_ty_gf_a0, NULL),
IWL_DEV_INFO(0x2725, 0x1673, iwlax210_2ax_cfg_ty_gf_a0, iwl_ax210_killer_1675w_name),
IWL_DEV_INFO(0x2725, 0x1674, iwlax210_2ax_cfg_ty_gf_a0, iwl_ax210_killer_1675x_name),
IWL_DEV_INFO(0x7A70, 0x0090, iwlax211_2ax_cfg_so_gf_a0_long, NULL),
IWL_DEV_INFO(0x7A70, 0x0098, iwlax211_2ax_cfg_so_gf_a0_long, NULL),
IWL_DEV_INFO(0x7A70, 0x00B0, iwlax411_2ax_cfg_so_gf4_a0_long, NULL),
@ -1014,12 +1028,12 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
IWL_CFG_MAC_TYPE_MA, IWL_CFG_ANY,
IWL_CFG_RF_TYPE_MR, IWL_CFG_ANY,
IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB,
iwl_cfg_ma_a0_mr_a0, iwl_ma_name),
iwl_cfg_ma_a0_mr_a0, iwl_ax221_name),
_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
IWL_CFG_MAC_TYPE_SNJ, IWL_CFG_ANY,
IWL_CFG_RF_TYPE_MR, IWL_CFG_ANY,
IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB,
iwl_cfg_snj_a0_mr_a0, iwl_ma_name),
iwl_cfg_snj_a0_mr_a0, iwl_ax221_name),
/* So with Hr */
_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
@ -1067,6 +1081,35 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB,
iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_name),
/* Bz */
_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY,
IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY,
IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB,
iwl_cfg_bz_a0_hr_b0, iwl_ax201_name),
_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY,
IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY,
IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB,
iwl_cfg_bz_a0_gf_a0, iwl_ax211_name),
_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY,
IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY,
IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_CDB,
iwl_cfg_bz_a0_gf4_a0, iwl_ax211_name),
_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY,
IWL_CFG_RF_TYPE_MR, IWL_CFG_ANY,
IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB,
iwl_cfg_bz_a0_mr_a0, iwl_ax211_name),
/* So with GF */
_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY,
IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY,
IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB,
iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_name)
#endif /* CONFIG_IWLMVM */
};
@ -1075,19 +1118,22 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
const struct iwl_cfg_trans_params *trans =
(struct iwl_cfg_trans_params *)(ent->driver_data);
const struct iwl_cfg_trans_params *trans;
const struct iwl_cfg *cfg_7265d __maybe_unused = NULL;
struct iwl_trans *iwl_trans;
struct iwl_trans_pcie *trans_pcie;
int i, ret;
const struct iwl_cfg *cfg;
trans = (void *)(ent->driver_data & ~TRANS_CFG_MARKER);
/*
* This is needed for backwards compatibility with the old
* tables, so we don't need to change all the config structs
* at the same time. The cfg is used to compare with the old
* full cfg structs.
*/
const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
cfg = (void *)(ent->driver_data & ~TRANS_CFG_MARKER);
/* make sure trans is the first element in iwl_cfg */
BUILD_BUG_ON(offsetof(struct iwl_cfg, trans));
@ -1165,7 +1211,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
iwl_trans->cfg = &iwlax210_2ax_cfg_ty_gf_a0;
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) {
iwl_trans->cfg = &iwlax210_2ax_cfg_so_jf_a0;
iwl_trans->cfg = &iwlax210_2ax_cfg_so_jf_b0;
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF)) {
iwl_trans->cfg = &iwlax211_2ax_cfg_so_gf_a0;
@ -1202,11 +1248,19 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
#endif
/*
* If we didn't set the cfg yet, assume the trans is actually
* a full cfg from the old tables.
* If we didn't set the cfg yet, the PCI ID table entry should have
* been a full config - if yes, use it, otherwise fail.
*/
if (!iwl_trans->cfg)
if (!iwl_trans->cfg) {
if (ent->driver_data & TRANS_CFG_MARKER) {
pr_err("No config found for PCI dev %04x/%04x, rev=0x%x, rfid=0x%x\n",
pdev->device, pdev->subsystem_device,
iwl_trans->hw_rev, iwl_trans->hw_rf_id);
ret = -EINVAL;
goto out_free_trans;
}
iwl_trans->cfg = cfg;
}
/* if we don't have a name yet, copy name from the old cfg */
if (!iwl_trans->name)
@ -1222,6 +1276,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
trans_pcie->num_rx_bufs = RX_QUEUE_SIZE;
}
ret = iwl_trans_init(iwl_trans);
if (ret)
goto out_free_trans;
pci_set_drvdata(pdev, iwl_trans);
iwl_trans->drv = iwl_drv_start(iwl_trans);

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2003-2014, 2018-2020 Intel Corporation
* Copyright (C) 2003-2014, 2018-2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@ -1023,6 +1023,9 @@ static int iwl_pcie_napi_poll(struct napi_struct *napi, int budget)
ret = iwl_pcie_rx_handle(trans, rxq->id, budget);
IWL_DEBUG_ISR(trans, "[%d] handled %d, budget %d\n",
rxq->id, ret, budget);
if (ret < budget) {
spin_lock(&trans_pcie->irq_lock);
if (test_bit(STATUS_INT_ENABLED, &trans->status))
@ -1046,33 +1049,19 @@ static int iwl_pcie_napi_poll_msix(struct napi_struct *napi, int budget)
trans = trans_pcie->trans;
ret = iwl_pcie_rx_handle(trans, rxq->id, budget);
IWL_DEBUG_ISR(trans, "[%d] handled %d, budget %d\n", rxq->id, ret,
budget);
if (ret < budget) {
int irq_line = rxq->id;
/* FIRST_RSS is shared with line 0 */
if (trans_pcie->shared_vec_mask & IWL_SHARED_IRQ_FIRST_RSS &&
rxq->id == 1)
irq_line = 0;
spin_lock(&trans_pcie->irq_lock);
iwl_pcie_clear_irq(trans, rxq->id);
spin_unlock(&trans_pcie->irq_lock);
napi_complete_done(&rxq->napi, ret);
}
return ret;
}
static int iwl_pcie_napi_poll_msix_shared(struct napi_struct *napi, int budget)
{
struct iwl_rxq *rxq = container_of(napi, struct iwl_rxq, napi);
struct iwl_trans_pcie *trans_pcie;
struct iwl_trans *trans;
int ret;
trans_pcie = container_of(napi->dev, struct iwl_trans_pcie, napi_dev);
trans = trans_pcie->trans;
ret = iwl_pcie_rx_handle(trans, rxq->id, budget);
if (ret < budget) {
spin_lock(&trans_pcie->irq_lock);
iwl_pcie_clear_irq(trans, 0);
iwl_pcie_clear_irq(trans, irq_line);
spin_unlock(&trans_pcie->irq_lock);
napi_complete_done(&rxq->napi, ret);
@ -1134,18 +1123,9 @@ static int _iwl_pcie_rx_init(struct iwl_trans *trans)
if (!rxq->napi.poll) {
int (*poll)(struct napi_struct *, int) = iwl_pcie_napi_poll;
if (trans_pcie->msix_enabled) {
if (trans_pcie->msix_enabled)
poll = iwl_pcie_napi_poll_msix;
if (trans_pcie->shared_vec_mask & IWL_SHARED_IRQ_NON_RX &&
i == 0)
poll = iwl_pcie_napi_poll_msix_shared;
if (trans_pcie->shared_vec_mask & IWL_SHARED_IRQ_FIRST_RSS &&
i == 1)
poll = iwl_pcie_napi_poll_msix_shared;
}
netif_napi_add(&trans_pcie->napi_dev, &rxq->napi,
poll, NAPI_POLL_WEIGHT);
napi_enable(&rxq->napi);
@ -1659,10 +1639,13 @@ irqreturn_t iwl_pcie_irq_rx_msix_handler(int irq, void *dev_id)
if (WARN_ON(entry->entry >= trans->num_rx_queues))
return IRQ_NONE;
if (WARN_ONCE(!rxq, "Got MSI-X interrupt before we have Rx queues"))
if (WARN_ONCE(!rxq,
"[%d] Got MSI-X interrupt before we have Rx queues",
entry->entry))
return IRQ_NONE;
lock_map_acquire(&trans->sync_cmd_lockdep_map);
IWL_DEBUG_ISR(trans, "[%d] Got interrupt\n", entry->entry);
local_bh_disable();
if (napi_schedule_prep(&rxq->napi))
@ -2194,9 +2177,16 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
struct iwl_trans_pcie *trans_pcie = iwl_pcie_get_trans_pcie(entry);
struct iwl_trans *trans = trans_pcie->trans;
struct isr_statistics *isr_stats = &trans_pcie->isr_stats;
u32 inta_fh_msk = ~MSIX_FH_INT_CAUSES_DATA_QUEUE;
u32 inta_fh, inta_hw;
bool polling = false;
if (trans_pcie->shared_vec_mask & IWL_SHARED_IRQ_NON_RX)
inta_fh_msk |= MSIX_FH_INT_CAUSES_Q0;
if (trans_pcie->shared_vec_mask & IWL_SHARED_IRQ_FIRST_RSS)
inta_fh_msk |= MSIX_FH_INT_CAUSES_Q1;
lock_map_acquire(&trans->sync_cmd_lockdep_map);
spin_lock_bh(&trans_pcie->irq_lock);
@ -2205,7 +2195,7 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
/*
* Clear causes registers to avoid being handling the same cause.
*/
iwl_write32(trans, CSR_MSIX_FH_INT_CAUSES_AD, inta_fh);
iwl_write32(trans, CSR_MSIX_FH_INT_CAUSES_AD, inta_fh & inta_fh_msk);
iwl_write32(trans, CSR_MSIX_HW_INT_CAUSES_AD, inta_hw);
spin_unlock_bh(&trans_pcie->irq_lock);
@ -2219,8 +2209,8 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
if (iwl_have_debug_level(IWL_DL_ISR)) {
IWL_DEBUG_ISR(trans,
"ISR inta_fh 0x%08x, enabled (sw) 0x%08x (hw) 0x%08x\n",
inta_fh, trans_pcie->fh_mask,
"ISR[%d] inta_fh 0x%08x, enabled (sw) 0x%08x (hw) 0x%08x\n",
entry->entry, inta_fh, trans_pcie->fh_mask,
iwl_read32(trans, CSR_MSIX_FH_INT_MASK_AD));
if (inta_fh & ~trans_pcie->fh_mask)
IWL_DEBUG_ISR(trans,
@ -2275,8 +2265,8 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
/* After checking FH register check HW register */
if (iwl_have_debug_level(IWL_DL_ISR)) {
IWL_DEBUG_ISR(trans,
"ISR inta_hw 0x%08x, enabled (sw) 0x%08x (hw) 0x%08x\n",
inta_hw, trans_pcie->hw_mask,
"ISR[%d] inta_hw 0x%08x, enabled (sw) 0x%08x (hw) 0x%08x\n",
entry->entry, inta_hw, trans_pcie->hw_mask,
iwl_read32(trans, CSR_MSIX_HW_INT_MASK_AD));
if (inta_hw & ~trans_pcie->hw_mask)
IWL_DEBUG_ISR(trans,

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2017 Intel Deutschland GmbH
* Copyright (C) 2018-2020 Intel Corporation
* Copyright (C) 2018-2021 Intel Corporation
*/
#include "iwl-trans.h"
#include "iwl-prph.h"
@ -108,8 +108,8 @@ static void iwl_trans_pcie_fw_reset_handshake(struct iwl_trans *trans)
ret = wait_event_timeout(trans_pcie->fw_reset_waitq,
trans_pcie->fw_reset_done, FW_RESET_TIMEOUT);
if (!ret)
IWL_ERR(trans,
"firmware didn't ACK the reset - continue anyway\n");
IWL_INFO(trans,
"firmware didn't ACK the reset - continue anyway\n");
}
void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
@ -143,7 +143,7 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
IWL_DEBUG_INFO(trans,
"DEVICE_ENABLED bit was set and is now cleared\n");
iwl_txq_gen2_tx_stop(trans);
iwl_txq_gen2_tx_free(trans);
iwl_pcie_rx_stop(trans);
}

View File

@ -1604,6 +1604,11 @@ iwl_pcie_set_interrupt_capa(struct pci_dev *pdev,
} else {
trans_pcie->trans->num_rx_queues = num_irqs - 1;
}
IWL_DEBUG_INFO(trans,
"MSI-X enabled with rx queues %d, vec mask 0x%x\n",
trans_pcie->trans->num_rx_queues, trans_pcie->shared_vec_mask);
WARN_ON(trans_pcie->trans->num_rx_queues > IWL_MAX_RX_HW_QUEUES);
trans_pcie->alloc_vecs = num_irqs;

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2003-2014, 2018-2020 Intel Corporation
* Copyright (C) 2003-2014, 2018-2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@ -181,16 +181,20 @@ static void iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
lockdep_assert_held(&trans_pcie->reg_lock);
if (!trans->trans_cfg->base_params->apmg_wake_up_wa)
return;
if (WARN_ON(!trans_pcie->cmd_hold_nic_awake))
spin_lock(&trans_pcie->reg_lock);
if (WARN_ON(!trans_pcie->cmd_hold_nic_awake)) {
spin_unlock(&trans_pcie->reg_lock);
return;
}
trans_pcie->cmd_hold_nic_awake = false;
__iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
spin_unlock(&trans_pcie->reg_lock);
}
/*
@ -198,7 +202,6 @@ static void iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans)
*/
static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_txq *txq = trans->txqs.txq[txq_id];
if (!txq) {
@ -222,12 +225,9 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id)
iwl_txq_free_tfd(trans, txq);
txq->read_ptr = iwl_txq_inc_wrap(trans, txq->read_ptr);
if (txq->read_ptr == txq->write_ptr) {
spin_lock(&trans_pcie->reg_lock);
if (txq_id == trans->txqs.cmd.q_id)
iwl_pcie_clear_cmd_in_flight(trans);
spin_unlock(&trans_pcie->reg_lock);
}
if (txq->read_ptr == txq->write_ptr &&
txq_id == trans->txqs.cmd.q_id)
iwl_pcie_clear_cmd_in_flight(trans);
}
while (!skb_queue_empty(&txq->overflow_q)) {
@ -629,38 +629,30 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans,
const struct iwl_host_cmd *cmd)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
int ret;
lockdep_assert_held(&trans_pcie->reg_lock);
/* Make sure the NIC is still alive in the bus */
if (test_bit(STATUS_TRANS_DEAD, &trans->status))
return -ENODEV;
if (!trans->trans_cfg->base_params->apmg_wake_up_wa)
return 0;
/*
* wake up the NIC to make sure that the firmware will see the host
* command - we will let the NIC sleep once all the host commands
* returned. This needs to be done only on NICs that have
* apmg_wake_up_wa set.
* apmg_wake_up_wa set (see above.)
*/
if (trans->trans_cfg->base_params->apmg_wake_up_wa &&
!trans_pcie->cmd_hold_nic_awake) {
__iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
if (!iwl_trans_grab_nic_access(trans))
return -EIO;
ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
(CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP),
15000);
if (ret < 0) {
__iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
IWL_ERR(trans, "Failed to wake NIC for hcmd\n");
return -EIO;
}
trans_pcie->cmd_hold_nic_awake = true;
}
/*
* In iwl_trans_grab_nic_access(), we've acquired the reg_lock.
* There, we also returned immediately if cmd_hold_nic_awake is
* already true, so it's OK to unconditionally set it to true.
*/
trans_pcie->cmd_hold_nic_awake = true;
spin_unlock_bh(&trans_pcie->reg_lock);
return 0;
}
@ -674,7 +666,6 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans,
*/
static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_txq *txq = trans->txqs.txq[txq_id];
int nfreed = 0;
u16 r;
@ -705,12 +696,8 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
}
}
if (txq->read_ptr == txq->write_ptr) {
/* BHs are also disabled due to txq->lock */
spin_lock(&trans_pcie->reg_lock);
if (txq->read_ptr == txq->write_ptr)
iwl_pcie_clear_cmd_in_flight(trans);
spin_unlock(&trans_pcie->reg_lock);
}
iwl_txq_progress(txq);
}
@ -914,7 +901,6 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id,
int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
struct iwl_host_cmd *cmd)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_txq *txq = trans->txqs.txq[trans->txqs.cmd.q_id];
struct iwl_device_cmd *out_cmd;
struct iwl_cmd_meta *out_meta;
@ -1161,19 +1147,16 @@ int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
if (txq->read_ptr == txq->write_ptr && txq->wd_timeout)
mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);
spin_lock(&trans_pcie->reg_lock);
ret = iwl_pcie_set_cmd_in_flight(trans, cmd);
if (ret < 0) {
idx = ret;
goto unlock_reg;
goto out;
}
/* Increment and update queue's write index */
txq->write_ptr = iwl_txq_inc_wrap(trans, txq->write_ptr);
iwl_pcie_txq_inc_wr_ptr(trans, txq);
unlock_reg:
spin_unlock(&trans_pcie->reg_lock);
out:
spin_unlock_irqrestore(&txq->lock, flags);
free_dup_buf:
@ -1367,7 +1350,6 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb,
/* this is the data left for this subframe */
unsigned int data_left =
min_t(unsigned int, mss, total_len);
struct sk_buff *csum_skb = NULL;
unsigned int hdr_tb_len;
dma_addr_t hdr_tb_phys;
u8 *subf_hdrs_start = hdr_page->pos;
@ -1398,10 +1380,8 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb,
hdr_tb_len = hdr_page->pos - start_hdr;
hdr_tb_phys = dma_map_single(trans->dev, start_hdr,
hdr_tb_len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(trans->dev, hdr_tb_phys))) {
dev_kfree_skb(csum_skb);
if (unlikely(dma_mapping_error(trans->dev, hdr_tb_phys)))
return -EINVAL;
}
iwl_pcie_txq_build_tfd(trans, txq, hdr_tb_phys,
hdr_tb_len, false);
trace_iwlwifi_dev_tx_tb(trans->dev, skb, start_hdr,
@ -1420,10 +1400,8 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb,
tb_phys = dma_map_single(trans->dev, tso.data,
size, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(trans->dev, tb_phys))) {
dev_kfree_skb(csum_skb);
if (unlikely(dma_mapping_error(trans->dev, tb_phys)))
return -EINVAL;
}
iwl_pcie_txq_build_tfd(trans, txq, tb_phys,
size, false);

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*/
#include <net/tso.h>
#include <linux/tcp.h>
@ -13,30 +13,6 @@
#include "iwl-scd.h"
#include <linux/dmapool.h>
/*
* iwl_txq_gen2_tx_stop - Stop all Tx DMA channels
*/
void iwl_txq_gen2_tx_stop(struct iwl_trans *trans)
{
int txq_id;
/*
* This function can be called before the op_mode disabled the
* queues. This happens when we have an rfkill interrupt.
* Since we stop Tx altogether - mark the queues as stopped.
*/
memset(trans->txqs.queue_stopped, 0,
sizeof(trans->txqs.queue_stopped));
memset(trans->txqs.queue_used, 0, sizeof(trans->txqs.queue_used));
/* Unmap DMA from host system and free skb's */
for (txq_id = 0; txq_id < ARRAY_SIZE(trans->txqs.txq); txq_id++) {
if (!trans->txqs.txq[txq_id])
continue;
iwl_txq_gen2_unmap(trans, txq_id);
}
}
/*
* iwl_txq_update_byte_tbl - Set up entry in Tx byte-count array
*/
@ -399,7 +375,6 @@ static int iwl_txq_gen2_build_amsdu(struct iwl_trans *trans,
while (total_len) {
/* this is the data left for this subframe */
unsigned int data_left = min_t(unsigned int, mss, total_len);
struct sk_buff *csum_skb = NULL;
unsigned int tb_len;
dma_addr_t tb_phys;
u8 *subf_hdrs_start = hdr_page->pos;
@ -430,10 +405,8 @@ static int iwl_txq_gen2_build_amsdu(struct iwl_trans *trans,
tb_len = hdr_page->pos - start_hdr;
tb_phys = dma_map_single(trans->dev, start_hdr,
tb_len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(trans->dev, tb_phys))) {
dev_kfree_skb(csum_skb);
if (unlikely(dma_mapping_error(trans->dev, tb_phys)))
goto out_err;
}
/*
* No need for _with_wa, this is from the TSO page and
* we leave some space at the end of it so can't hit
@ -458,10 +431,8 @@ static int iwl_txq_gen2_build_amsdu(struct iwl_trans *trans,
ret = iwl_txq_gen2_set_tb_with_wa(trans, skb, tfd,
tb_phys, tso.data,
tb_len, NULL);
if (ret) {
dev_kfree_skb(csum_skb);
if (ret)
goto out_err;
}
data_left -= tb_len;
tso_build_data(skb, &tso, tb_len);
@ -1189,6 +1160,12 @@ static int iwl_txq_alloc_response(struct iwl_trans *trans, struct iwl_txq *txq,
goto error_free_resp;
}
if (WARN_ONCE(trans->txqs.txq[qid],
"queue %d already allocated\n", qid)) {
ret = -EIO;
goto error_free_resp;
}
txq->id = qid;
trans->txqs.txq[qid] = txq;
wr_ptr &= (trans->trans_cfg->base_params->max_tfd_queue_size - 1);

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*/
#ifndef __iwl_trans_queue_tx_h__
#define __iwl_trans_queue_tx_h__
@ -123,7 +123,6 @@ int iwl_txq_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb,
void iwl_txq_dyn_free(struct iwl_trans *trans, int queue);
void iwl_txq_gen2_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq);
void iwl_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq);
void iwl_txq_gen2_tx_stop(struct iwl_trans *trans);
void iwl_txq_gen2_tx_free(struct iwl_trans *trans);
int iwl_txq_init(struct iwl_trans *trans, struct iwl_txq *txq, int slots_num,
bool cmd_queue);