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:
commit
197b9c152b
@ -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));
|
||||
|
@ -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[] =
|
||||
|
@ -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);
|
||||
|
@ -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__ */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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__ */
|
||||
|
@ -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__ */
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
/*****************************************************
|
||||
|
@ -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 */
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 *)¬if,
|
||||
sizeof(notif));
|
||||
iwl_mvm_sync_rx_queues_internal(mvm, IWL_MVM_RXQ_NSSN_SYNC, false,
|
||||
¬if, 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);
|
||||
|
@ -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, ¶ms);
|
||||
|
||||
iwl_mvm_scan_6ghz_passive_scan(mvm, ¶ms, vif);
|
||||
|
||||
uid = iwl_mvm_build_scan_cmd(mvm, vif, &hcmd, ¶ms,
|
||||
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));
|
||||
|
||||
|
@ -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 *)¬if, sizeof(notif));
|
||||
|
||||
iwl_mvm_sync_rx_queues_internal(mvm, IWL_MVM_RXQ_NOTIF_DEL_BA, true,
|
||||
¬if, sizeof(notif));
|
||||
};
|
||||
|
||||
static void iwl_mvm_free_reorder(struct iwl_mvm *mvm,
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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++) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user