mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 02:24:24 +02:00
iwlwifi features, notably
- cleanup of unsupported APIs - add a API range per RF - transport layer cleanups - a few small fixes -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQQM3A3Pv7vbm9vtjWbacY7uyt+OfQUCaHYfNAAKCRDacY7uyt+O fRaKAQC66tvpxblh3WLvh3U2e/DAqzfHrAlvm7AmOCUbXU21gQEA8bm78T1DihDJ cSu29gkfN37ly8+Oz+dph82mAOGCrgg= =wf7j -----END PGP SIGNATURE----- Merge tag 'iwlwifi-next-2025-07-15' of https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next Miri Korenblit says: ==================== iwlwifi features, notably - cleanup of unsupported APIs - add a API range per RF - transport layer cleanups - a few small fixes ==================== Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
commit
003322be55
|
|
@ -22,6 +22,7 @@ iwlwifi-$(CONFIG_IWLMVM) += cfg/7000.o cfg/8000.o
|
|||
# MAC configurations
|
||||
iwlwifi-$(CONFIG_IWLMVM) += cfg/9000.o cfg/22000.o
|
||||
iwlwifi-$(CONFIG_IWLMVM) += cfg/ax210.o
|
||||
iwlwifi-$(CONFIG_IWLMVM) += cfg/bz.o cfg/sc.o
|
||||
iwlwifi-$(CONFIG_IWLMLD) += cfg/bz.o cfg/sc.o cfg/dr.o
|
||||
# RF configurations
|
||||
iwlwifi-$(CONFIG_IWLMVM) += cfg/rf-jf.o cfg/rf-hr.o cfg/rf-gf.o
|
||||
|
|
|
|||
|
|
@ -19,26 +19,8 @@
|
|||
#define IWL_22000_SMEM_OFFSET 0x400000
|
||||
#define IWL_22000_SMEM_LEN 0xD0000
|
||||
|
||||
#define IWL_QU_B_HR_B_FW_PRE "iwlwifi-Qu-b0-hr-b0"
|
||||
#define IWL_QU_C_HR_B_FW_PRE "iwlwifi-Qu-c0-hr-b0"
|
||||
#define IWL_QU_B_JF_B_FW_PRE "iwlwifi-Qu-b0-jf-b0"
|
||||
#define IWL_QU_C_JF_B_FW_PRE "iwlwifi-Qu-c0-jf-b0"
|
||||
#define IWL_QUZ_A_HR_B_FW_PRE "iwlwifi-QuZ-a0-hr-b0"
|
||||
#define IWL_QUZ_A_JF_B_FW_PRE "iwlwifi-QuZ-a0-jf-b0"
|
||||
#define IWL_CC_A_FW_PRE "iwlwifi-cc-a0"
|
||||
|
||||
#define IWL_QU_B_HR_B_MODULE_FIRMWARE(api) \
|
||||
IWL_QU_B_HR_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_QUZ_A_HR_B_MODULE_FIRMWARE(api) \
|
||||
IWL_QUZ_A_HR_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_QUZ_A_JF_B_MODULE_FIRMWARE(api) \
|
||||
IWL_QUZ_A_JF_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_QU_C_HR_B_MODULE_FIRMWARE(api) \
|
||||
IWL_QU_C_HR_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \
|
||||
IWL_QU_B_JF_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_QU_C_JF_B_MODULE_FIRMWARE(api) \
|
||||
IWL_QU_C_JF_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_CC_A_MODULE_FIRMWARE(api) \
|
||||
IWL_CC_A_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
|
|
@ -132,10 +114,4 @@ const char iwl_ax201_killer_1650s_name[] =
|
|||
const char iwl_ax201_killer_1650i_name[] =
|
||||
"Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW)";
|
||||
|
||||
MODULE_FIRMWARE(IWL_QU_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_QU_C_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_QUZ_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_QUZ_A_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_CC_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
|
||||
|
|
|
|||
|
|
@ -13,33 +13,12 @@
|
|||
#define IWL_AX210_UCODE_API_MAX 89
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_AX210_UCODE_API_MIN 77
|
||||
#define IWL_AX210_UCODE_API_MIN 89
|
||||
|
||||
/* Memory offsets and lengths */
|
||||
#define IWL_AX210_SMEM_OFFSET 0x400000
|
||||
#define IWL_AX210_SMEM_LEN 0xD0000
|
||||
|
||||
#define IWL_SO_A_JF_B_FW_PRE "iwlwifi-so-a0-jf-b0"
|
||||
#define IWL_SO_A_HR_B_FW_PRE "iwlwifi-so-a0-hr-b0"
|
||||
#define IWL_SO_A_GF_A_FW_PRE "iwlwifi-so-a0-gf-a0"
|
||||
#define IWL_TY_A_GF_A_FW_PRE "iwlwifi-ty-a0-gf-a0"
|
||||
#define IWL_SO_A_GF4_A_FW_PRE "iwlwifi-so-a0-gf4-a0"
|
||||
#define IWL_MA_A_HR_B_FW_PRE "iwlwifi-ma-a0-hr-b0"
|
||||
#define IWL_MA_A_GF_A_FW_PRE "iwlwifi-ma-a0-gf-a0"
|
||||
#define IWL_MA_A_GF4_A_FW_PRE "iwlwifi-ma-a0-gf4-a0"
|
||||
#define IWL_MA_B_HR_B_FW_PRE "iwlwifi-ma-b0-hr-b0"
|
||||
#define IWL_MA_B_GF_A_FW_PRE "iwlwifi-ma-b0-gf-a0"
|
||||
#define IWL_MA_B_GF4_A_FW_PRE "iwlwifi-ma-b0-gf4-a0"
|
||||
|
||||
#define IWL_SO_A_JF_B_MODULE_FIRMWARE(api) \
|
||||
IWL_SO_A_JF_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_SO_A_HR_B_MODULE_FIRMWARE(api) \
|
||||
IWL_SO_A_HR_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_MA_A_HR_B_FW_MODULE_FIRMWARE(api) \
|
||||
IWL_MA_A_HR_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_MA_B_HR_B_FW_MODULE_FIRMWARE(api) \
|
||||
IWL_MA_B_HR_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
static const struct iwl_family_base_params iwl_ax210_base = {
|
||||
.num_of_queues = 512,
|
||||
.max_tfd_queue_size = 65536,
|
||||
|
|
@ -143,14 +122,3 @@ const struct iwl_mac_cfg iwl_ma_mac_cfg = {
|
|||
.integrated = true,
|
||||
.umac_prph_offset = 0x300000
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL_SO_A_JF_B_MODULE_FIRMWARE(IWL_AX210_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_SO_A_HR_B_MODULE_FIRMWARE(IWL_AX210_UCODE_API_MAX));
|
||||
IWL_FW_AND_PNVM(IWL_SO_A_GF_A_FW_PRE, IWL_AX210_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_TY_A_GF_A_FW_PRE, IWL_AX210_UCODE_API_MAX);
|
||||
MODULE_FIRMWARE(IWL_MA_A_HR_B_FW_MODULE_FIRMWARE(IWL_AX210_UCODE_API_MAX));
|
||||
IWL_FW_AND_PNVM(IWL_MA_A_GF_A_FW_PRE, IWL_AX210_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_MA_A_GF4_A_FW_PRE, IWL_AX210_UCODE_API_MAX);
|
||||
MODULE_FIRMWARE(IWL_MA_B_HR_B_FW_MODULE_FIRMWARE(IWL_AX210_UCODE_API_MAX));
|
||||
IWL_FW_AND_PNVM(IWL_MA_B_GF_A_FW_PRE, IWL_AX210_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_MA_B_GF4_A_FW_PRE, IWL_AX210_UCODE_API_MAX);
|
||||
|
|
|
|||
|
|
@ -19,18 +19,12 @@
|
|||
#define IWL_BZ_SMEM_OFFSET 0x400000
|
||||
#define IWL_BZ_SMEM_LEN 0xD0000
|
||||
|
||||
#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_FM_B_FW_PRE "iwlwifi-bz-a0-fm-b0"
|
||||
#define IWL_BZ_A_FM_C_FW_PRE "iwlwifi-bz-a0-fm-c0"
|
||||
#define IWL_BZ_A_FM4_B_FW_PRE "iwlwifi-bz-a0-fm4-b0"
|
||||
#define IWL_GL_B_FM_B_FW_PRE "iwlwifi-gl-b0-fm-b0"
|
||||
#define IWL_GL_C_FM_C_FW_PRE "iwlwifi-gl-c0-fm-c0"
|
||||
|
||||
#define IWL_BZ_A_HR_B_MODULE_FIRMWARE(api) \
|
||||
IWL_BZ_A_HR_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
static const struct iwl_family_base_params iwl_bz_base = {
|
||||
.num_of_queues = 512,
|
||||
.max_tfd_queue_size = 65536,
|
||||
|
|
@ -107,9 +101,6 @@ const struct iwl_mac_cfg iwl_gl_mac_cfg = {
|
|||
.low_latency_xtal = true,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL_BZ_A_HR_B_MODULE_FIRMWARE(IWL_BZ_UCODE_API_MAX));
|
||||
IWL_FW_AND_PNVM(IWL_BZ_A_GF_A_FW_PRE, IWL_BZ_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_BZ_A_GF4_A_FW_PRE, IWL_BZ_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_BZ_A_FM_B_FW_PRE, IWL_BZ_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_BZ_A_FM_C_FW_PRE, IWL_BZ_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_BZ_A_FM4_B_FW_PRE, IWL_BZ_UCODE_API_MAX);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,24 @@
|
|||
*/
|
||||
#include "iwl-config.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL_GF_UCODE_API_MAX 100
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_GF_UCODE_API_MIN 98
|
||||
|
||||
#define IWL_SO_A_GF_A_FW_PRE "iwlwifi-so-a0-gf-a0"
|
||||
#define IWL_TY_A_GF_A_FW_PRE "iwlwifi-ty-a0-gf-a0"
|
||||
#define IWL_MA_A_GF_A_FW_PRE "iwlwifi-ma-a0-gf-a0"
|
||||
#define IWL_MA_B_GF_A_FW_PRE "iwlwifi-ma-b0-gf-a0"
|
||||
#define IWL_SO_A_GF4_A_FW_PRE "iwlwifi-so-a0-gf4-a0"
|
||||
#define IWL_MA_A_GF4_A_FW_PRE "iwlwifi-ma-a0-gf4-a0"
|
||||
#define IWL_MA_B_GF4_A_FW_PRE "iwlwifi-ma-b0-gf4-a0"
|
||||
#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_SC_A_GF_A_FW_PRE "iwlwifi-sc-a0-gf-a0"
|
||||
#define IWL_SC_A_GF4_A_FW_PRE "iwlwifi-sc-a0-gf4-a0"
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL_GF_NVM_VERSION 0x0a1d
|
||||
|
||||
|
|
@ -22,6 +40,8 @@ const struct iwl_rf_cfg iwl_rf_gf = {
|
|||
.nvm_ver = IWL_GF_NVM_VERSION,
|
||||
.nvm_type = IWL_NVM_EXT,
|
||||
.num_rbds = IWL_NUM_RBDS_HE,
|
||||
.ucode_api_min = IWL_GF_UCODE_API_MIN,
|
||||
.ucode_api_max = IWL_GF_UCODE_API_MAX,
|
||||
};
|
||||
|
||||
const char iwl_ax210_killer_1675w_name[] =
|
||||
|
|
@ -40,3 +60,14 @@ const char iwl_ax411_killer_1690i_name[] =
|
|||
const char iwl_ax210_name[] = "Intel(R) Wi-Fi 6E AX210 160MHz";
|
||||
const char iwl_ax211_name[] = "Intel(R) Wi-Fi 6E AX211 160MHz";
|
||||
const char iwl_ax411_name[] = "Intel(R) Wi-Fi 6E AX411 160MHz";
|
||||
|
||||
IWL_FW_AND_PNVM(IWL_SO_A_GF_A_FW_PRE, IWL_GF_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_TY_A_GF_A_FW_PRE, IWL_GF_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_MA_A_GF_A_FW_PRE, IWL_GF_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_MA_B_GF_A_FW_PRE, IWL_GF_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_MA_A_GF4_A_FW_PRE, IWL_GF_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_MA_B_GF4_A_FW_PRE, IWL_GF_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_BZ_A_GF_A_FW_PRE, IWL_GF_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_BZ_A_GF4_A_FW_PRE, IWL_GF_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_SC_A_GF_A_FW_PRE, IWL_GF_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_SC_A_GF4_A_FW_PRE, IWL_GF_UCODE_API_MAX);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,41 @@
|
|||
*/
|
||||
#include "iwl-config.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL_HR_UCODE_API_MAX 100
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_HR_UCODE_API_MIN 98
|
||||
|
||||
#define IWL_QU_B_HR_B_FW_PRE "iwlwifi-Qu-b0-hr-b0"
|
||||
#define IWL_QU_C_HR_B_FW_PRE "iwlwifi-Qu-c0-hr-b0"
|
||||
#define IWL_QUZ_A_HR_B_FW_PRE "iwlwifi-QuZ-a0-hr-b0"
|
||||
#define IWL_SO_A_HR_B_FW_PRE "iwlwifi-so-a0-hr-b0"
|
||||
#define IWL_MA_A_HR_B_FW_PRE "iwlwifi-ma-a0-hr-b0"
|
||||
#define IWL_MA_B_HR_B_FW_PRE "iwlwifi-ma-b0-hr-b0"
|
||||
#define IWL_BZ_A_HR_B_FW_PRE "iwlwifi-bz-a0-hr-b0"
|
||||
#define IWL_SC_A_HR_A_FW_PRE "iwlwifi-sc-a0-hr-b0"
|
||||
#define IWL_SC_A_HR_B_FW_PRE "iwlwifi-sc-a0-hr-b0"
|
||||
|
||||
#define IWL_QU_B_HR_B_MODULE_FIRMWARE(api) \
|
||||
IWL_QU_B_HR_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_QUZ_A_HR_B_MODULE_FIRMWARE(api) \
|
||||
IWL_QUZ_A_HR_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_QU_C_HR_B_MODULE_FIRMWARE(api) \
|
||||
IWL_QU_C_HR_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_SO_A_HR_B_MODULE_FIRMWARE(api) \
|
||||
IWL_SO_A_HR_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_MA_A_HR_B_FW_MODULE_FIRMWARE(api) \
|
||||
IWL_MA_A_HR_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_MA_B_HR_B_FW_MODULE_FIRMWARE(api) \
|
||||
IWL_MA_B_HR_B_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_SC_A_HR_A_FW_MODULE_FIRMWARE(api) \
|
||||
IWL_SC_A_HR_A_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_SC_A_HR_B_FW_MODULE_FIRMWARE(api) \
|
||||
IWL_SC_A_HR_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL_HR_NVM_VERSION 0x0a1d
|
||||
|
||||
|
|
@ -20,7 +55,9 @@
|
|||
}, \
|
||||
.num_rbds = IWL_NUM_RBDS_HE, \
|
||||
.nvm_ver = IWL_HR_NVM_VERSION, \
|
||||
.nvm_type = IWL_NVM_EXT
|
||||
.nvm_type = IWL_NVM_EXT, \
|
||||
.ucode_api_min = IWL_HR_UCODE_API_MIN, \
|
||||
.ucode_api_max = IWL_HR_UCODE_API_MAX
|
||||
|
||||
const struct iwl_rf_cfg iwl_rf_hr1 = {
|
||||
IWL_DEVICE_HR,
|
||||
|
|
@ -40,3 +77,13 @@ 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";
|
||||
|
||||
MODULE_FIRMWARE(IWL_QU_B_HR_B_MODULE_FIRMWARE(IWL_HR_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_HR_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_QUZ_A_HR_B_MODULE_FIRMWARE(IWL_HR_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_SO_A_HR_B_MODULE_FIRMWARE(IWL_HR_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_MA_A_HR_B_FW_MODULE_FIRMWARE(IWL_HR_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_MA_B_HR_B_FW_MODULE_FIRMWARE(IWL_HR_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_BZ_A_HR_B_MODULE_FIRMWARE(IWL_HR_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_SC_A_HR_A_FW_MODULE_FIRMWARE(IWL_HR_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_SC_A_HR_B_FW_MODULE_FIRMWARE(IWL_HR_UCODE_API_MAX));
|
||||
|
|
|
|||
|
|
@ -5,6 +5,26 @@
|
|||
*/
|
||||
#include "iwl-config.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL_JF_UCODE_API_MAX 77
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_JF_UCODE_API_MIN 77
|
||||
|
||||
#define IWL_QU_B_JF_B_FW_PRE "iwlwifi-Qu-b0-jf-b0"
|
||||
#define IWL_QU_C_JF_B_FW_PRE "iwlwifi-Qu-c0-jf-b0"
|
||||
#define IWL_QUZ_A_JF_B_FW_PRE "iwlwifi-QuZ-a0-jf-b0"
|
||||
#define IWL_SO_A_JF_B_FW_PRE "iwlwifi-so-a0-jf-b0"
|
||||
|
||||
#define IWL_QUZ_A_JF_B_MODULE_FIRMWARE(api) \
|
||||
IWL_QUZ_A_JF_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \
|
||||
IWL_QU_B_JF_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_QU_C_JF_B_MODULE_FIRMWARE(api) \
|
||||
IWL_QU_C_JF_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_SO_A_JF_B_MODULE_FIRMWARE(api) \
|
||||
IWL_SO_A_JF_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL_JF_NVM_VERSION 0x0a1d
|
||||
|
||||
|
|
@ -56,7 +76,9 @@ static const struct iwl_tt_params iwl_jf_tt_params = {
|
|||
BIT(NL80211_BAND_5GHZ), \
|
||||
}, \
|
||||
.nvm_ver = IWL_JF_NVM_VERSION, \
|
||||
.nvm_type = IWL_NVM_EXT
|
||||
.nvm_type = IWL_NVM_EXT, \
|
||||
.ucode_api_min = IWL_JF_UCODE_API_MIN, \
|
||||
.ucode_api_max = IWL_JF_UCODE_API_MAX
|
||||
|
||||
const struct iwl_rf_cfg iwl_rf_jf = {
|
||||
IWL_DEVICE_JF,
|
||||
|
|
@ -82,3 +104,8 @@ const char iwl9560_killer_1550i_name[] =
|
|||
"Killer(R) Wireless-AC 1550i Wireless Network Adapter (9560NGW) 160MHz";
|
||||
const char iwl9560_killer_1550s_name[] =
|
||||
"Killer(R) Wireless-AC 1550s Wireless Network Adapter (9560D2W) 160MHz";
|
||||
|
||||
MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_JF_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_QU_C_JF_B_MODULE_FIRMWARE(IWL_JF_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_QUZ_A_JF_B_MODULE_FIRMWARE(IWL_JF_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_SO_A_JF_B_MODULE_FIRMWARE(IWL_JF_UCODE_API_MAX));
|
||||
|
|
|
|||
|
|
@ -24,21 +24,12 @@
|
|||
|
||||
#define IWL_SC_A_FM_B_FW_PRE "iwlwifi-sc-a0-fm-b0"
|
||||
#define IWL_SC_A_FM_C_FW_PRE "iwlwifi-sc-a0-fm-c0"
|
||||
#define IWL_SC_A_HR_A_FW_PRE "iwlwifi-sc-a0-hr-b0"
|
||||
#define IWL_SC_A_HR_B_FW_PRE "iwlwifi-sc-a0-hr-b0"
|
||||
#define IWL_SC_A_GF_A_FW_PRE "iwlwifi-sc-a0-gf-a0"
|
||||
#define IWL_SC_A_GF4_A_FW_PRE "iwlwifi-sc-a0-gf4-a0"
|
||||
#define IWL_SC_A_WH_A_FW_PRE "iwlwifi-sc-a0-wh-a0"
|
||||
#define IWL_SC2_A_FM_C_FW_PRE "iwlwifi-sc2-a0-fm-c0"
|
||||
#define IWL_SC2_A_WH_A_FW_PRE "iwlwifi-sc2-a0-wh-a0"
|
||||
#define IWL_SC2F_A_FM_C_FW_PRE "iwlwifi-sc2f-a0-fm-c0"
|
||||
#define IWL_SC2F_A_WH_A_FW_PRE "iwlwifi-sc2f-a0-wh-a0"
|
||||
|
||||
#define IWL_SC_A_HR_A_FW_MODULE_FIRMWARE(api) \
|
||||
IWL_SC_A_HR_A_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_SC_A_HR_B_FW_MODULE_FIRMWARE(api) \
|
||||
IWL_SC_A_HR_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
static const struct iwl_family_base_params iwl_sc_base = {
|
||||
.num_of_queues = 512,
|
||||
.max_tfd_queue_size = 65536,
|
||||
|
|
@ -107,10 +98,6 @@ const struct iwl_mac_cfg iwl_sc_mac_cfg = {
|
|||
|
||||
IWL_FW_AND_PNVM(IWL_SC_A_FM_B_FW_PRE, IWL_SC_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_SC_A_FM_C_FW_PRE, IWL_SC_UCODE_API_MAX);
|
||||
MODULE_FIRMWARE(IWL_SC_A_HR_A_FW_MODULE_FIRMWARE(IWL_SC_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_SC_A_HR_B_FW_MODULE_FIRMWARE(IWL_SC_UCODE_API_MAX));
|
||||
IWL_FW_AND_PNVM(IWL_SC_A_GF_A_FW_PRE, IWL_SC_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_SC_A_GF4_A_FW_PRE, IWL_SC_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_SC_A_WH_A_FW_PRE, IWL_SC_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_SC2_A_FM_C_FW_PRE, IWL_SC_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_SC2_A_WH_A_FW_PRE, IWL_SC_UCODE_API_MAX);
|
||||
|
|
|
|||
|
|
@ -679,11 +679,11 @@ static int iwl_eeprom_acquire_semaphore(struct iwl_trans *trans)
|
|||
ret = iwl_poll_bits(trans, CSR_HW_IF_CONFIG_REG,
|
||||
CSR_HW_IF_CONFIG_REG_EEPROM_OWN_SEM,
|
||||
IWL_EEPROM_SEM_TIMEOUT);
|
||||
if (ret >= 0) {
|
||||
if (!ret) {
|
||||
IWL_DEBUG_EEPROM(trans->dev,
|
||||
"Acquired semaphore after %d tries.\n",
|
||||
count+1);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -799,7 +799,7 @@ static int iwl_read_otp_word(struct iwl_trans *trans, u16 addr,
|
|||
ret = iwl_poll_bits(trans, CSR_EEPROM_REG,
|
||||
CSR_EEPROM_REG_READ_VALID_MSK,
|
||||
IWL_EEPROM_ACCESS_TIMEOUT);
|
||||
if (ret < 0) {
|
||||
if (ret) {
|
||||
IWL_ERR(trans, "Time out reading OTP[%d]\n", addr);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -941,14 +941,14 @@ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size)
|
|||
return -ENOMEM;
|
||||
|
||||
ret = iwl_eeprom_verify_signature(trans, nvm_is_otp);
|
||||
if (ret < 0) {
|
||||
if (ret) {
|
||||
IWL_ERR(trans, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
/* Make sure driver (instead of uCode) is allowed to read EEPROM */
|
||||
ret = iwl_eeprom_acquire_semaphore(trans);
|
||||
if (ret < 0) {
|
||||
if (ret) {
|
||||
IWL_ERR(trans, "Failed to acquire EEPROM semaphore.\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
|
@ -994,7 +994,7 @@ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size)
|
|||
ret = iwl_poll_bits(trans, CSR_EEPROM_REG,
|
||||
CSR_EEPROM_REG_READ_VALID_MSK,
|
||||
IWL_EEPROM_ACCESS_TIMEOUT);
|
||||
if (ret < 0) {
|
||||
if (ret) {
|
||||
IWL_ERR(trans,
|
||||
"Time out reading EEPROM[%d]\n", addr);
|
||||
goto err_unlock;
|
||||
|
|
|
|||
|
|
@ -82,21 +82,6 @@ struct iwl_alive_ntf_v3 {
|
|||
struct iwl_umac_alive umac_data;
|
||||
} __packed; /* UCODE_ALIVE_NTFY_API_S_VER_3 */
|
||||
|
||||
struct iwl_alive_ntf_v4 {
|
||||
__le16 status;
|
||||
__le16 flags;
|
||||
struct iwl_lmac_alive lmac_data[2];
|
||||
struct iwl_umac_alive umac_data;
|
||||
} __packed; /* UCODE_ALIVE_NTFY_API_S_VER_4 */
|
||||
|
||||
struct iwl_alive_ntf_v5 {
|
||||
__le16 status;
|
||||
__le16 flags;
|
||||
struct iwl_lmac_alive lmac_data[2];
|
||||
struct iwl_umac_alive umac_data;
|
||||
struct iwl_sku_id sku_id;
|
||||
} __packed; /* UCODE_ALIVE_NTFY_API_S_VER_5 */
|
||||
|
||||
struct iwl_imr_alive_info {
|
||||
__le64 base_addr;
|
||||
__le32 size;
|
||||
|
|
|
|||
|
|
@ -573,9 +573,8 @@ enum iwl_legacy_cmds {
|
|||
WOWLAN_KEK_KCK_MATERIAL = 0xe4,
|
||||
|
||||
/**
|
||||
* @WOWLAN_GET_STATUSES: response in &struct iwl_wowlan_status_v6,
|
||||
* &struct iwl_wowlan_status_v7, &struct iwl_wowlan_status_v9 or
|
||||
* &struct iwl_wowlan_status_v12
|
||||
* @WOWLAN_GET_STATUSES: response in &struct iwl_wowlan_status_v6 or
|
||||
* &struct iwl_wowlan_status_v7
|
||||
*/
|
||||
WOWLAN_GET_STATUSES = 0xe5,
|
||||
|
||||
|
|
|
|||
|
|
@ -456,11 +456,6 @@ struct iwl_wowlan_rsc_tsc_params_cmd_ver_2 {
|
|||
union iwl_all_tsc_rsc all_tsc_rsc;
|
||||
} __packed; /* ALL_TSC_RSC_API_S_VER_2 */
|
||||
|
||||
struct iwl_wowlan_rsc_tsc_params_cmd_v4 {
|
||||
struct iwl_wowlan_rsc_tsc_params_cmd_ver_2 params;
|
||||
__le32 sta_id;
|
||||
} __packed; /* ALL_TSC_RSC_API_S_VER_4 */
|
||||
|
||||
struct iwl_wowlan_rsc_tsc_params_cmd {
|
||||
__le64 ucast_rsc[IWL_MAX_TID_COUNT];
|
||||
__le64 mcast_rsc[WOWLAN_GTK_KEYS_NUM][IWL_MAX_TID_COUNT];
|
||||
|
|
@ -719,82 +714,6 @@ struct iwl_wowlan_status_v7 {
|
|||
u8 wake_packet[]; /* can be truncated from _length to _bufsize */
|
||||
} __packed; /* WOWLAN_STATUSES_API_S_VER_7 */
|
||||
|
||||
/**
|
||||
* struct iwl_wowlan_status_v9 - WoWLAN status (versions 9 and 10)
|
||||
* @gtk: GTK data
|
||||
* @igtk: IGTK data
|
||||
* @replay_ctr: GTK rekey replay counter
|
||||
* @pattern_number: number of the matched pattern
|
||||
* @non_qos_seq_ctr: non-QoS sequence counter to use next.
|
||||
* Reserved if the struct has version >= 10.
|
||||
* @qos_seq_ctr: QoS sequence counters to use next
|
||||
* @wakeup_reasons: wakeup reasons, see &enum iwl_wowlan_wakeup_reason
|
||||
* @num_of_gtk_rekeys: number of GTK rekeys
|
||||
* @transmitted_ndps: number of transmitted neighbor discovery packets
|
||||
* @received_beacons: number of received beacons
|
||||
* @wake_packet_length: wakeup packet length
|
||||
* @wake_packet_bufsize: wakeup packet buffer size
|
||||
* @tid_tear_down: bit mask of tids whose BA sessions were closed
|
||||
* in suspend state
|
||||
* @reserved: unused
|
||||
* @wake_packet: wakeup packet
|
||||
*/
|
||||
struct iwl_wowlan_status_v9 {
|
||||
struct iwl_wowlan_gtk_status_v2 gtk[WOWLAN_GTK_KEYS_NUM];
|
||||
struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM];
|
||||
__le64 replay_ctr;
|
||||
__le16 pattern_number;
|
||||
__le16 non_qos_seq_ctr;
|
||||
__le16 qos_seq_ctr[8];
|
||||
__le32 wakeup_reasons;
|
||||
__le32 num_of_gtk_rekeys;
|
||||
__le32 transmitted_ndps;
|
||||
__le32 received_beacons;
|
||||
__le32 wake_packet_length;
|
||||
__le32 wake_packet_bufsize;
|
||||
u8 tid_tear_down;
|
||||
u8 reserved[3];
|
||||
u8 wake_packet[]; /* can be truncated from _length to _bufsize */
|
||||
} __packed; /* WOWLAN_STATUSES_RSP_API_S_VER_9 */
|
||||
|
||||
/**
|
||||
* struct iwl_wowlan_status_v12 - WoWLAN status
|
||||
* @gtk: GTK data
|
||||
* @igtk: IGTK data
|
||||
* @replay_ctr: GTK rekey replay counter
|
||||
* @pattern_number: number of the matched pattern
|
||||
* @non_qos_seq_ctr: non-QoS sequence counter to use next.
|
||||
* Reserved if the struct has version >= 10.
|
||||
* @qos_seq_ctr: QoS sequence counters to use next
|
||||
* @wakeup_reasons: wakeup reasons, see &enum iwl_wowlan_wakeup_reason
|
||||
* @num_of_gtk_rekeys: number of GTK rekeys
|
||||
* @transmitted_ndps: number of transmitted neighbor discovery packets
|
||||
* @received_beacons: number of received beacons
|
||||
* @wake_packet_length: wakeup packet length
|
||||
* @wake_packet_bufsize: wakeup packet buffer size
|
||||
* @tid_tear_down: bit mask of tids whose BA sessions were closed
|
||||
* in suspend state
|
||||
* @reserved: unused
|
||||
* @wake_packet: wakeup packet
|
||||
*/
|
||||
struct iwl_wowlan_status_v12 {
|
||||
struct iwl_wowlan_gtk_status_v3 gtk[WOWLAN_GTK_KEYS_NUM];
|
||||
struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM];
|
||||
__le64 replay_ctr;
|
||||
__le16 pattern_number;
|
||||
__le16 non_qos_seq_ctr;
|
||||
__le16 qos_seq_ctr[8];
|
||||
__le32 wakeup_reasons;
|
||||
__le32 num_of_gtk_rekeys;
|
||||
__le32 transmitted_ndps;
|
||||
__le32 received_beacons;
|
||||
__le32 wake_packet_length;
|
||||
__le32 wake_packet_bufsize;
|
||||
u8 tid_tear_down;
|
||||
u8 reserved[3];
|
||||
u8 wake_packet[]; /* can be truncated from _length to _bufsize */
|
||||
} __packed; /* WOWLAN_STATUSES_RSP_API_S_VER_12 */
|
||||
|
||||
/**
|
||||
* struct iwl_wowlan_info_notif_v1 - WoWLAN information notification
|
||||
* @gtk: GTK data
|
||||
|
|
@ -832,39 +751,6 @@ struct iwl_wowlan_info_notif_v1 {
|
|||
u8 reserved2[2];
|
||||
} __packed; /* WOWLAN_INFO_NTFY_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_wowlan_info_notif_v2 - WoWLAN information notification
|
||||
* @gtk: GTK data
|
||||
* @igtk: IGTK data
|
||||
* @replay_ctr: GTK rekey replay counter
|
||||
* @pattern_number: number of the matched patterns
|
||||
* @reserved1: reserved
|
||||
* @qos_seq_ctr: QoS sequence counters to use next
|
||||
* @wakeup_reasons: wakeup reasons, see &enum iwl_wowlan_wakeup_reason
|
||||
* @num_of_gtk_rekeys: number of GTK rekeys
|
||||
* @transmitted_ndps: number of transmitted neighbor discovery packets
|
||||
* @received_beacons: number of received beacons
|
||||
* @tid_tear_down: bit mask of tids whose BA sessions were closed
|
||||
* in suspend state
|
||||
* @station_id: station id
|
||||
* @reserved2: reserved
|
||||
*/
|
||||
struct iwl_wowlan_info_notif_v2 {
|
||||
struct iwl_wowlan_gtk_status_v3 gtk[WOWLAN_GTK_KEYS_NUM];
|
||||
struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM];
|
||||
__le64 replay_ctr;
|
||||
__le16 pattern_number;
|
||||
__le16 reserved1;
|
||||
__le16 qos_seq_ctr[8];
|
||||
__le32 wakeup_reasons;
|
||||
__le32 num_of_gtk_rekeys;
|
||||
__le32 transmitted_ndps;
|
||||
__le32 received_beacons;
|
||||
u8 tid_tear_down;
|
||||
u8 station_id;
|
||||
u8 reserved2[2];
|
||||
} __packed; /* WOWLAN_INFO_NTFY_API_S_VER_2 */
|
||||
|
||||
/* MAX MLO keys of non-active links that can arrive in the notification */
|
||||
#define WOWLAN_MAX_MLO_KEYS 18
|
||||
|
||||
|
|
|
|||
|
|
@ -124,6 +124,11 @@ enum iwl_data_path_subcmd_ids {
|
|||
*/
|
||||
TLC_MNG_UPDATE_NOTIF = 0xF7,
|
||||
|
||||
/**
|
||||
* @BEACON_FILTER_IN_NOTIF: &struct iwl_beacon_filter_notif
|
||||
*/
|
||||
BEACON_FILTER_IN_NOTIF = 0xF8,
|
||||
|
||||
/**
|
||||
* @STA_PM_NOTIF: &struct iwl_mvm_pm_state_notification
|
||||
*/
|
||||
|
|
@ -695,12 +700,23 @@ struct iwl_sec_key_cmd {
|
|||
} __packed; /* SEC_KEY_CMD_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_omi_send_status_notif - OMI status notification
|
||||
* struct iwl_omi_send_status_notif_v1 - OMI status notification
|
||||
* @success: indicates that the OMI was sent successfully
|
||||
* (currently always set)
|
||||
*/
|
||||
struct iwl_omi_send_status_notif {
|
||||
struct iwl_omi_send_status_notif_v1 {
|
||||
__le32 success;
|
||||
} __packed; /* OMI_SEND_STATUS_NTFY_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_omi_send_status_notif - OMI status notification
|
||||
* @success: indicates that the OMI was sent successfully
|
||||
* (currently always set)
|
||||
* @sta_id: sta_id to which the OMI was sent
|
||||
*/
|
||||
struct iwl_omi_send_status_notif {
|
||||
__le32 success;
|
||||
__le32 sta_id;
|
||||
} __packed; /* OMI_SEND_STATUS_NTFY_API_S_VER_2 */
|
||||
|
||||
#endif /* __iwl_fw_api_datapath_h__ */
|
||||
|
|
|
|||
|
|
@ -787,6 +787,7 @@ struct iwl_lari_config_change_cmd {
|
|||
/* Activate UNII-1 (5.2GHz) for World Wide */
|
||||
#define ACTIVATE_5G2_IN_WW_MASK BIT(4)
|
||||
#define CHAN_STATE_ACTIVE_BITMAP_CMD_V11 0x1F
|
||||
#define CHAN_STATE_ACTIVE_BITMAP_CMD_V12 0x7F
|
||||
|
||||
/**
|
||||
* struct iwl_pnvm_init_complete_ntfy - PNVM initialization complete
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* Copyright (C) 2012-2014 Intel Corporation
|
||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2021-2024 Intel Corporation
|
||||
* Copyright (C) 2021-2025 Intel Corporation
|
||||
*/
|
||||
#ifndef __iwl_fw_api_offload_h__
|
||||
#define __iwl_fw_api_offload_h__
|
||||
|
|
@ -19,7 +19,7 @@ enum iwl_prot_offload_subcmd_ids {
|
|||
|
||||
/**
|
||||
* @WOWLAN_INFO_NOTIFICATION: Notification in
|
||||
* &struct iwl_wowlan_info_notif_v1, &struct iwl_wowlan_info_notif_v2,
|
||||
* &struct iwl_wowlan_info_notif_v1, iwl_wowlan_info_notif_v3,
|
||||
* or &struct iwl_wowlan_info_notif
|
||||
*/
|
||||
WOWLAN_INFO_NOTIFICATION = 0xFD,
|
||||
|
|
|
|||
|
|
@ -255,19 +255,6 @@ struct iwl_uapsd_misbehaving_ap_notif {
|
|||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_reduce_tx_power_cmd - TX power reduction command
|
||||
* REDUCE_TX_POWER_CMD = 0x9f
|
||||
* @flags: (reserved for future implementation)
|
||||
* @mac_context_id: id of the mac ctx for which we are reducing TX power.
|
||||
* @pwr_restriction: TX power restriction in dBms.
|
||||
*/
|
||||
struct iwl_reduce_tx_power_cmd {
|
||||
u8 flags;
|
||||
u8 mac_context_id;
|
||||
__le16 pwr_restriction;
|
||||
} __packed; /* TX_REDUCED_POWER_API_S_VER_1 */
|
||||
|
||||
enum iwl_dev_tx_power_cmd_mode {
|
||||
IWL_TX_POWER_MODE_SET_LINK = 0,
|
||||
IWL_TX_POWER_MODE_SET_DEVICE = 1,
|
||||
|
|
@ -341,50 +328,6 @@ struct iwl_dev_tx_power_cmd_v5 {
|
|||
__le32 timer_period;
|
||||
} __packed; /* TX_REDUCED_POWER_API_S_VER_5 */
|
||||
|
||||
/**
|
||||
* struct iwl_dev_tx_power_cmd_v6 - TX power reduction command version 6
|
||||
* @per_chain: per chain restrictions
|
||||
* @enable_ack_reduction: enable or disable close range ack TX power
|
||||
* reduction.
|
||||
* @per_chain_restriction_changed: is per_chain_restriction has changed
|
||||
* from last command. used if set_mode is
|
||||
* IWL_TX_POWER_MODE_SET_SAR_TIMER.
|
||||
* note: if not changed, the command is used for keep alive only.
|
||||
* @reserved: reserved (padding)
|
||||
* @timer_period: timer in milliseconds. if expires FW will change to default
|
||||
* BIOS values. relevant if setMode is IWL_TX_POWER_MODE_SET_SAR_TIMER
|
||||
*/
|
||||
struct iwl_dev_tx_power_cmd_v6 {
|
||||
__le16 per_chain[IWL_NUM_CHAIN_TABLES_V2][IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V2];
|
||||
u8 enable_ack_reduction;
|
||||
u8 per_chain_restriction_changed;
|
||||
u8 reserved[2];
|
||||
__le32 timer_period;
|
||||
} __packed; /* TX_REDUCED_POWER_API_S_VER_6 */
|
||||
|
||||
/**
|
||||
* struct iwl_dev_tx_power_cmd_v7 - TX power reduction command version 7
|
||||
* @per_chain: per chain restrictions
|
||||
* @enable_ack_reduction: enable or disable close range ack TX power
|
||||
* reduction.
|
||||
* @per_chain_restriction_changed: is per_chain_restriction has changed
|
||||
* from last command. used if set_mode is
|
||||
* IWL_TX_POWER_MODE_SET_SAR_TIMER.
|
||||
* note: if not changed, the command is used for keep alive only.
|
||||
* @reserved: reserved (padding)
|
||||
* @timer_period: timer in milliseconds. if expires FW will change to default
|
||||
* BIOS values. relevant if setMode is IWL_TX_POWER_MODE_SET_SAR_TIMER
|
||||
* @flags: reduce power flags.
|
||||
*/
|
||||
struct iwl_dev_tx_power_cmd_v7 {
|
||||
__le16 per_chain[IWL_NUM_CHAIN_TABLES_V2][IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V2];
|
||||
u8 enable_ack_reduction;
|
||||
u8 per_chain_restriction_changed;
|
||||
u8 reserved[2];
|
||||
__le32 timer_period;
|
||||
__le32 flags;
|
||||
} __packed; /* TX_REDUCED_POWER_API_S_VER_7 */
|
||||
|
||||
/**
|
||||
* struct iwl_dev_tx_power_cmd_v8 - TX power reduction command version 8
|
||||
* @per_chain: per chain restrictions
|
||||
|
|
@ -429,8 +372,6 @@ struct iwl_dev_tx_power_cmd_per_band {
|
|||
* @v3: version 3 part of the command
|
||||
* @v4: version 4 part of the command
|
||||
* @v5: version 5 part of the command
|
||||
* @v6: version 6 part of the command
|
||||
* @v7: version 7 part of the command
|
||||
* @v8: version 8 part of the command
|
||||
*/
|
||||
struct iwl_dev_tx_power_cmd_v3_v8 {
|
||||
|
|
@ -440,8 +381,6 @@ struct iwl_dev_tx_power_cmd_v3_v8 {
|
|||
struct iwl_dev_tx_power_cmd_v3 v3;
|
||||
struct iwl_dev_tx_power_cmd_v4 v4;
|
||||
struct iwl_dev_tx_power_cmd_v5 v5;
|
||||
struct iwl_dev_tx_power_cmd_v6 v6;
|
||||
struct iwl_dev_tx_power_cmd_v7 v7;
|
||||
struct iwl_dev_tx_power_cmd_v8 v8;
|
||||
};
|
||||
};
|
||||
|
|
@ -632,8 +571,7 @@ enum iwl_ppag_flags {
|
|||
/**
|
||||
* union iwl_ppag_table_cmd - union for all versions of PPAG command
|
||||
* @v1: command version 1 structure.
|
||||
* @v2: command version from 2 to 6 are same structure as v2.
|
||||
* but has a different format of the flags bitmap
|
||||
* @v2: command version 5 structure.
|
||||
* @v3: command version 7 structure.
|
||||
* @v1.flags: values from &enum iwl_ppag_flags
|
||||
* @v1.gain: table of antenna gain values per chain and sub-band
|
||||
|
|
@ -654,9 +592,7 @@ union iwl_ppag_table_cmd {
|
|||
__le32 flags;
|
||||
s8 gain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V2];
|
||||
s8 reserved[2];
|
||||
} __packed v2; /* PER_PLAT_ANTENNA_GAIN_CMD_API_S_VER_2, VER3, VER4,
|
||||
* VER5, VER6
|
||||
*/
|
||||
} __packed v2; /* PER_PLAT_ANTENNA_GAIN_CMD_API_S_VER_5 */
|
||||
struct {
|
||||
struct bios_value_u32 ppag_config_info;
|
||||
s8 gain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V2];
|
||||
|
|
@ -664,20 +600,11 @@ union iwl_ppag_table_cmd {
|
|||
} __packed v3; /* PER_PLAT_ANTENNA_GAIN_CMD_API_S_VER_7 */
|
||||
} __packed;
|
||||
|
||||
#define IWL_PPAG_CMD_V4_MASK (IWL_PPAG_ETSI_MASK | IWL_PPAG_CHINA_MASK)
|
||||
#define IWL_PPAG_CMD_V5_MASK (IWL_PPAG_CMD_V4_MASK | \
|
||||
#define IWL_PPAG_CMD_V1_MASK (IWL_PPAG_ETSI_MASK | IWL_PPAG_CHINA_MASK)
|
||||
#define IWL_PPAG_CMD_V5_MASK (IWL_PPAG_CMD_V1_MASK | \
|
||||
IWL_PPAG_ETSI_LPI_UHB_MASK | \
|
||||
IWL_PPAG_USA_LPI_UHB_MASK)
|
||||
|
||||
#define IWL_PPAG_CMD_V6_MASK (IWL_PPAG_CMD_V5_MASK | \
|
||||
IWL_PPAG_ETSI_VLP_UHB_MASK | \
|
||||
IWL_PPAG_ETSI_SP_UHB_MASK | \
|
||||
IWL_PPAG_USA_VLP_UHB_MASK | \
|
||||
IWL_PPAG_USA_SP_UHB_MASK | \
|
||||
IWL_PPAG_CANADA_LPI_UHB_MASK | \
|
||||
IWL_PPAG_CANADA_VLP_UHB_MASK | \
|
||||
IWL_PPAG_CANADA_SP_UHB_MASK)
|
||||
|
||||
#define MCC_TO_SAR_OFFSET_TABLE_ROW_SIZE 26
|
||||
#define MCC_TO_SAR_OFFSET_TABLE_COL_SIZE 13
|
||||
|
||||
|
|
|
|||
|
|
@ -194,7 +194,9 @@ enum iwl_rx_mpdu_amsdu_info {
|
|||
};
|
||||
|
||||
enum iwl_rx_mpdu_mac_phy_band {
|
||||
/* whether or not this is MAC or LINK depends on the API */
|
||||
IWL_RX_MPDU_MAC_PHY_BAND_MAC_MASK = 0x0f,
|
||||
IWL_RX_MPDU_MAC_PHY_BAND_LINK_MASK = 0x0f,
|
||||
IWL_RX_MPDU_MAC_PHY_BAND_PHY_MASK = 0x30,
|
||||
IWL_RX_MPDU_MAC_PHY_BAND_BAND_MASK = 0xc0,
|
||||
};
|
||||
|
|
@ -671,7 +673,7 @@ struct iwl_rx_mpdu_desc {
|
|||
*/
|
||||
__le16 phy_info;
|
||||
/**
|
||||
* @mac_phy_band: MAC ID, PHY ID, band;
|
||||
* @mac_phy_band: MAC/link ID, PHY ID, band;
|
||||
* see &enum iwl_rx_mpdu_mac_phy_band
|
||||
*/
|
||||
u8 mac_phy_band;
|
||||
|
|
@ -1019,4 +1021,24 @@ struct iwl_rfh_queue_config {
|
|||
struct iwl_rfh_queue_data data[];
|
||||
} __packed; /* RFH_QUEUE_CONFIG_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_beacon_filter_notif_v1 - beacon filter notification
|
||||
* @average_energy: average energy for the received beacon
|
||||
* @mac_id: MAC ID the beacon was received for
|
||||
*/
|
||||
struct iwl_beacon_filter_notif_v1 {
|
||||
__le32 average_energy;
|
||||
__le32 mac_id;
|
||||
} __packed; /* BEACON_FILTER_IN_NTFY_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_beacon_filter_notif - beacon filter notification
|
||||
* @average_energy: average energy for the received beacon
|
||||
* @link_id: link ID the beacon was received for
|
||||
*/
|
||||
struct iwl_beacon_filter_notif {
|
||||
__le32 average_energy;
|
||||
__le32 link_id;
|
||||
} __packed; /* BEACON_FILTER_IN_NTFY_API_S_VER_2 */
|
||||
|
||||
#endif /* __iwl_fw_api_rx_h__ */
|
||||
|
|
|
|||
|
|
@ -2978,7 +2978,7 @@ IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect_desc);
|
|||
int iwl_fw_dbg_error_collect(struct iwl_fw_runtime *fwrt,
|
||||
enum iwl_fw_dbg_trigger trig_type)
|
||||
{
|
||||
if (!test_bit(STATUS_DEVICE_ENABLED, &fwrt->trans->status))
|
||||
if (!iwl_trans_device_enabled(fwrt->trans))
|
||||
return -EIO;
|
||||
|
||||
if (iwl_trans_dbg_ini_valid(fwrt->trans)) {
|
||||
|
|
@ -3180,13 +3180,13 @@ static void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt, u8 wk_idx)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (!test_bit(STATUS_DEVICE_ENABLED, &fwrt->trans->status)) {
|
||||
if (!iwl_trans_device_enabled(fwrt->trans)) {
|
||||
IWL_ERR(fwrt, "Device is not enabled - cannot dump error\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* there's no point in fw dump if the bus is dead */
|
||||
if (test_bit(STATUS_TRANS_DEAD, &fwrt->trans->status)) {
|
||||
if (iwl_trans_is_dead(fwrt->trans)) {
|
||||
IWL_ERR(fwrt, "Skip fw error dump since bus is dead\n");
|
||||
goto out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -389,6 +389,12 @@ static int iwl_dbgfs_fw_info_seq_show(struct seq_file *seq, void *v)
|
|||
" %d: %d\n",
|
||||
IWL_UCODE_TLV_CAPA_CHINA_22_REG_SUPPORT,
|
||||
has_capa);
|
||||
has_capa = fw_has_capa(&fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE) ? 1 : 0;
|
||||
seq_printf(seq,
|
||||
" %d: %d\n",
|
||||
IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE,
|
||||
has_capa);
|
||||
seq_puts(seq, "fw_api_ver:\n");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ static void iwl_fwrt_dump_lmac_error_log(struct iwl_fw_runtime *fwrt, u8 lmac_nu
|
|||
IWL_ERR(trans, "HW error, resetting before reading\n");
|
||||
|
||||
/* reset the device */
|
||||
err = iwl_trans_sw_reset(trans, true);
|
||||
err = iwl_trans_sw_reset(trans);
|
||||
if (err)
|
||||
return;
|
||||
|
||||
|
|
@ -490,7 +490,7 @@ void iwl_fwrt_dump_error_logs(struct iwl_fw_runtime *fwrt)
|
|||
struct iwl_pc_data *pc_data;
|
||||
u8 count;
|
||||
|
||||
if (!test_bit(STATUS_DEVICE_ENABLED, &fwrt->trans->status)) {
|
||||
if (!iwl_trans_device_enabled(fwrt->trans)) {
|
||||
IWL_ERR(fwrt,
|
||||
"DEVICE_ENABLED bit is not set. Aborting dump.\n");
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -407,6 +407,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t;
|
|||
* for CA from BIOS.
|
||||
* @IWL_UCODE_TLV_CAPA_UHB_CANADA_TAS_SUPPORT: supports %TAS_UHB_ALLOWED_CANADA
|
||||
* @IWL_UCODE_TLV_CAPA_EXT_FSEQ_IMAGE_SUPPORT: external FSEQ image support
|
||||
* @IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE: Firmware has capability of
|
||||
* handling raw DSM table data.
|
||||
*
|
||||
* @NUM_IWL_UCODE_TLV_CAPA: number of bits used
|
||||
*/
|
||||
|
|
@ -517,6 +519,7 @@ enum iwl_ucode_tlv_capa {
|
|||
* during assert handling even if the dump isn't split
|
||||
*/
|
||||
IWL_UCODE_TLV_CAPA_RESET_DURING_ASSERT = (__force iwl_ucode_tlv_capa_t)(4 * 32 + 0),
|
||||
IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE = (__force iwl_ucode_tlv_capa_t)(4 * 32 + 1),
|
||||
NUM_IWL_UCODE_TLV_CAPA
|
||||
/*
|
||||
* This construction make both sparse (which cannot increment the previous
|
||||
|
|
|
|||
|
|
@ -344,18 +344,18 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
|
|||
num_sub_bands = IWL_NUM_SUB_BANDS_V1;
|
||||
gain = cmd->v1.gain[0];
|
||||
*cmd_size = sizeof(cmd->v1);
|
||||
cmd->v1.flags = cpu_to_le32(fwrt->ppag_flags);
|
||||
cmd->v1.flags = cpu_to_le32(fwrt->ppag_flags & IWL_PPAG_CMD_V1_MASK);
|
||||
if (fwrt->ppag_bios_rev >= 1) {
|
||||
/* in this case FW supports revision 0 */
|
||||
IWL_DEBUG_RADIO(fwrt,
|
||||
"PPAG table rev is %d, send truncated table\n",
|
||||
fwrt->ppag_bios_rev);
|
||||
}
|
||||
} else if (cmd_ver >= 2 && cmd_ver <= 6) {
|
||||
} else if (cmd_ver == 5) {
|
||||
num_sub_bands = IWL_NUM_SUB_BANDS_V2;
|
||||
gain = cmd->v2.gain[0];
|
||||
*cmd_size = sizeof(cmd->v2);
|
||||
cmd->v2.flags = cpu_to_le32(fwrt->ppag_flags);
|
||||
cmd->v2.flags = cpu_to_le32(fwrt->ppag_flags & IWL_PPAG_CMD_V5_MASK);
|
||||
if (fwrt->ppag_bios_rev == 0) {
|
||||
/* in this case FW supports revisions 1,2 or 3 */
|
||||
IWL_DEBUG_RADIO(fwrt,
|
||||
|
|
@ -378,17 +378,9 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
|
|||
"PPAG MODE bits were read from bios: %d\n",
|
||||
fwrt->ppag_flags);
|
||||
|
||||
if (cmd_ver == 6)
|
||||
cmd->v1.flags &= cpu_to_le32(IWL_PPAG_CMD_V6_MASK);
|
||||
else if (cmd_ver == 5)
|
||||
cmd->v1.flags &= cpu_to_le32(IWL_PPAG_CMD_V5_MASK);
|
||||
else if (cmd_ver < 5)
|
||||
cmd->v1.flags &= cpu_to_le32(IWL_PPAG_CMD_V4_MASK);
|
||||
|
||||
if ((cmd_ver == 1 &&
|
||||
!fw_has_capa(&fwrt->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT)) ||
|
||||
(cmd_ver == 2 && fwrt->ppag_bios_rev >= 2)) {
|
||||
if (cmd_ver == 1 &&
|
||||
!fw_has_capa(&fwrt->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT)) {
|
||||
cmd->v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK);
|
||||
IWL_DEBUG_RADIO(fwrt, "masking ppag China bit\n");
|
||||
} else {
|
||||
|
|
@ -579,6 +571,8 @@ int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt,
|
|||
{
|
||||
int ret;
|
||||
u32 value;
|
||||
bool has_raw_dsm_capa = fw_has_capa(&fwrt->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE);
|
||||
u8 cmd_ver = iwl_fw_lookup_cmd_ver(fwrt->fw,
|
||||
WIDE_ID(REGULATORY_AND_NVM_GROUP,
|
||||
LARI_CONFIG_CHANGE), 1);
|
||||
|
|
@ -593,17 +587,22 @@ int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt,
|
|||
cmd->config_bitmap = iwl_get_lari_config_bitmap(fwrt);
|
||||
|
||||
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_11AX_ENABLEMENT, &value);
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
if (!has_raw_dsm_capa)
|
||||
value &= DSM_11AX_ALLOW_BITMAP;
|
||||
cmd->oem_11ax_allow_bitmap = cpu_to_le32(value);
|
||||
}
|
||||
|
||||
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_UNII4_CHAN, &value);
|
||||
if (!ret) {
|
||||
value &= DSM_UNII4_ALLOW_BITMAP;
|
||||
if (!has_raw_dsm_capa)
|
||||
value &= DSM_UNII4_ALLOW_BITMAP;
|
||||
|
||||
/* Since version 9, bits 4 and 5 are supported
|
||||
* regardless of this capability.
|
||||
* regardless of this capability, By pass this masking
|
||||
* if firmware has capability of accepting raw DSM table.
|
||||
*/
|
||||
if (cmd_ver < 9 &&
|
||||
if (!has_raw_dsm_capa && cmd_ver < 9 &&
|
||||
!fw_has_capa(&fwrt->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_5G9_FOR_CA))
|
||||
value &= ~(DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK |
|
||||
|
|
@ -614,13 +613,17 @@ int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt,
|
|||
|
||||
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ACTIVATE_CHANNEL, &value);
|
||||
if (!ret) {
|
||||
if (cmd_ver < 8)
|
||||
if (!has_raw_dsm_capa)
|
||||
value &= CHAN_STATE_ACTIVE_BITMAP_CMD_V12;
|
||||
|
||||
if (!has_raw_dsm_capa && cmd_ver < 8)
|
||||
value &= ~ACTIVATE_5G2_IN_WW_MASK;
|
||||
|
||||
/* Since version 12, bits 5 and 6 are supported
|
||||
* regardless of this capability.
|
||||
* regardless of this capability, By pass this masking
|
||||
* if firmware has capability of accepting raw DSM table.
|
||||
*/
|
||||
if (cmd_ver < 12 &&
|
||||
if (!has_raw_dsm_capa && cmd_ver < 12 &&
|
||||
!fw_has_capa(&fwrt->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_UNII4_US_CA))
|
||||
value &= CHAN_STATE_ACTIVE_BITMAP_CMD_V11;
|
||||
|
|
@ -633,13 +636,19 @@ int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt,
|
|||
cmd->oem_uhb_allow_bitmap = cpu_to_le32(value);
|
||||
|
||||
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_FORCE_DISABLE_CHANNELS, &value);
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
if (!has_raw_dsm_capa)
|
||||
value &= DSM_FORCE_DISABLE_CHANNELS_ALLOWED_BITMAP;
|
||||
cmd->force_disable_channels_bitmap = cpu_to_le32(value);
|
||||
}
|
||||
|
||||
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENERGY_DETECTION_THRESHOLD,
|
||||
&value);
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
if (!has_raw_dsm_capa)
|
||||
value &= DSM_EDT_ALLOWED_BITMAP;
|
||||
cmd->edt_bitmap = cpu_to_le32(value);
|
||||
}
|
||||
|
||||
ret = iwl_bios_get_wbem(fwrt, &value);
|
||||
if (!ret)
|
||||
|
|
|
|||
|
|
@ -159,6 +159,10 @@ enum iwl_dsm_unii4_bitmap {
|
|||
DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK |\
|
||||
DSM_VALUE_UNII4_CANADA_EN_MSK)
|
||||
|
||||
#define DSM_11AX_ALLOW_BITMAP 0xF
|
||||
#define DSM_EDT_ALLOWED_BITMAP 0x7ffff0
|
||||
#define DSM_FORCE_DISABLE_CHANNELS_ALLOWED_BITMAP 0x7FF
|
||||
|
||||
enum iwl_dsm_values_rfi {
|
||||
DSM_VALUE_RFI_DLVR_DISABLE = BIT(0),
|
||||
DSM_VALUE_RFI_DDR_DISABLE = BIT(1),
|
||||
|
|
|
|||
|
|
@ -301,13 +301,17 @@ static void iwl_get_ucode_api_versions(struct iwl_trans *trans,
|
|||
const struct iwl_family_base_params *base = trans->mac_cfg->base;
|
||||
const struct iwl_rf_cfg *cfg = trans->cfg;
|
||||
|
||||
if (!base->ucode_api_max) {
|
||||
/* if the MAC doesn't have range or if its range it higher than the RF's */
|
||||
if (!base->ucode_api_max ||
|
||||
(cfg->ucode_api_max && base->ucode_api_min > cfg->ucode_api_max)) {
|
||||
*api_min = cfg->ucode_api_min;
|
||||
*api_max = cfg->ucode_api_max;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cfg->ucode_api_max) {
|
||||
/* if the RF doesn't have range or if its range it higher than the MAC's */
|
||||
if (!cfg->ucode_api_max ||
|
||||
(base->ucode_api_max && cfg->ucode_api_min > base->ucode_api_max)) {
|
||||
*api_min = base->ucode_api_min;
|
||||
*api_max = base->ucode_api_max;
|
||||
return;
|
||||
|
|
@ -1541,7 +1545,7 @@ _iwl_op_mode_start(struct iwl_drv *drv, struct iwlwifi_opmode_table *op)
|
|||
if (!IS_ERR(op_mode))
|
||||
return op_mode;
|
||||
|
||||
if (test_bit(STATUS_TRANS_DEAD, &drv->trans->status))
|
||||
if (iwl_trans_is_dead(drv->trans))
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ int iwl_poll_bits_mask(struct iwl_trans *trans, u32 addr,
|
|||
|
||||
do {
|
||||
if ((iwl_read32(trans, addr) & mask) == (bits & mask))
|
||||
return t;
|
||||
return 0;
|
||||
udelay(IWL_POLL_INTERVAL);
|
||||
t += IWL_POLL_INTERVAL;
|
||||
} while (t < timeout);
|
||||
|
|
|
|||
|
|
@ -663,6 +663,8 @@ static const struct ieee80211_sband_iftype_data iwl_he_eht_capa[] = {
|
|||
.phy_cap_info[9] =
|
||||
IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |
|
||||
IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB |
|
||||
IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU |
|
||||
IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU |
|
||||
(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_RESERVED <<
|
||||
IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_POS),
|
||||
.phy_cap_info[10] =
|
||||
|
|
@ -691,44 +693,26 @@ static const struct ieee80211_sband_iftype_data iwl_he_eht_capa[] = {
|
|||
.has_eht = true,
|
||||
.eht_cap_elem = {
|
||||
.mac_cap_info[0] =
|
||||
IEEE80211_EHT_MAC_CAP0_EPCS_PRIO_ACCESS |
|
||||
IEEE80211_EHT_MAC_CAP0_OM_CONTROL |
|
||||
IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE1 |
|
||||
IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE2 |
|
||||
IEEE80211_EHT_MAC_CAP0_SCS_TRAFFIC_DESC,
|
||||
.mac_cap_info[1] =
|
||||
IEEE80211_EHT_MAC_CAP1_UNSOL_EPCS_PRIO_ACCESS,
|
||||
IEEE80211_EHT_MAC_CAP0_OM_CONTROL,
|
||||
.phy_cap_info[0] =
|
||||
IEEE80211_EHT_PHY_CAP0_242_TONE_RU_GT20MHZ |
|
||||
IEEE80211_EHT_PHY_CAP0_NDP_4_EHT_LFT_32_GI |
|
||||
IEEE80211_EHT_PHY_CAP0_PARTIAL_BW_UL_MU_MIMO |
|
||||
IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE |
|
||||
IEEE80211_EHT_PHY_CAP0_BEAMFORMEE_SS_80MHZ_MASK,
|
||||
.phy_cap_info[1] =
|
||||
IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_80MHZ_MASK |
|
||||
IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_160MHZ_MASK,
|
||||
.phy_cap_info[3] =
|
||||
IEEE80211_EHT_PHY_CAP3_NG_16_SU_FEEDBACK |
|
||||
IEEE80211_EHT_PHY_CAP3_NG_16_MU_FEEDBACK |
|
||||
IEEE80211_EHT_PHY_CAP3_CODEBOOK_4_2_SU_FDBK |
|
||||
IEEE80211_EHT_PHY_CAP3_CODEBOOK_7_5_MU_FDBK |
|
||||
IEEE80211_EHT_PHY_CAP3_TRIG_SU_BF_FDBK |
|
||||
IEEE80211_EHT_PHY_CAP3_TRIG_MU_BF_PART_BW_FDBK |
|
||||
IEEE80211_EHT_PHY_CAP3_TRIG_CQI_FDBK,
|
||||
IEEE80211_EHT_PHY_CAP3_TRIG_SU_BF_FDBK,
|
||||
|
||||
.phy_cap_info[4] =
|
||||
IEEE80211_EHT_PHY_CAP4_PART_BW_DL_MU_MIMO |
|
||||
IEEE80211_EHT_PHY_CAP4_POWER_BOOST_FACT_SUPP |
|
||||
IEEE80211_EHT_PHY_CAP4_EHT_MU_PPDU_4_EHT_LTF_08_GI,
|
||||
.phy_cap_info[5] =
|
||||
FIELD_PREP_CONST(IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_MASK,
|
||||
IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_16US) |
|
||||
IEEE80211_EHT_PHY_CAP5_NON_TRIG_CQI_FEEDBACK |
|
||||
IEEE80211_EHT_PHY_CAP5_TX_LESS_242_TONE_RU_SUPP |
|
||||
IEEE80211_EHT_PHY_CAP5_RX_LESS_242_TONE_RU_SUPP,
|
||||
.phy_cap_info[6] =
|
||||
IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_MASK |
|
||||
IEEE80211_EHT_PHY_CAP6_EHT_DUP_6GHZ_SUPP,
|
||||
IEEE80211_EHT_PHY_CAP5_RX_LESS_242_TONE_RU_SUPP |
|
||||
IEEE80211_EHT_PHY_CAP5_SUPP_EXTRA_EHT_LTF,
|
||||
.phy_cap_info[8] =
|
||||
IEEE80211_EHT_PHY_CAP8_RX_1024QAM_WIDER_BW_DL_OFDMA |
|
||||
IEEE80211_EHT_PHY_CAP8_RX_4096QAM_WIDER_BW_DL_OFDMA,
|
||||
|
|
@ -796,6 +780,7 @@ static const struct ieee80211_sband_iftype_data iwl_he_eht_capa[] = {
|
|||
IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI |
|
||||
IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_242,
|
||||
.phy_cap_info[9] =
|
||||
IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU |
|
||||
IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_RESERVED
|
||||
<< IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_POS,
|
||||
},
|
||||
|
|
@ -822,9 +807,7 @@ static const struct ieee80211_sband_iftype_data iwl_he_eht_capa[] = {
|
|||
.has_eht = true,
|
||||
.eht_cap_elem = {
|
||||
.mac_cap_info[0] =
|
||||
IEEE80211_EHT_MAC_CAP0_OM_CONTROL |
|
||||
IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE1 |
|
||||
IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE2,
|
||||
IEEE80211_EHT_MAC_CAP0_OM_CONTROL,
|
||||
.phy_cap_info[0] =
|
||||
IEEE80211_EHT_PHY_CAP0_242_TONE_RU_GT20MHZ |
|
||||
IEEE80211_EHT_PHY_CAP0_NDP_4_EHT_LFT_32_GI,
|
||||
|
|
@ -1039,48 +1022,17 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans,
|
|||
cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << 2);
|
||||
}
|
||||
|
||||
/* prior RFs don't have HE, HR RF doesn't have this, later have it */
|
||||
if (CSR_HW_RFID_TYPE(trans->info.hw_rf_id) == IWL_CFG_RF_TYPE_HR1 ||
|
||||
CSR_HW_RFID_TYPE(trans->info.hw_rf_id) == IWL_CFG_RF_TYPE_HR2)
|
||||
iftype_data->he_cap.he_cap_elem.phy_cap_info[9] &=
|
||||
~(IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU |
|
||||
IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU);
|
||||
|
||||
if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210 && !is_ap)
|
||||
iftype_data->he_cap.he_cap_elem.phy_cap_info[2] |=
|
||||
IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO;
|
||||
|
||||
switch (CSR_HW_RFID_TYPE(trans->info.hw_rf_id)) {
|
||||
case IWL_CFG_RF_TYPE_GF:
|
||||
case IWL_CFG_RF_TYPE_FM:
|
||||
case IWL_CFG_RF_TYPE_WH:
|
||||
case IWL_CFG_RF_TYPE_PE:
|
||||
iftype_data->he_cap.he_cap_elem.phy_cap_info[9] |=
|
||||
IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU;
|
||||
if (!is_ap)
|
||||
iftype_data->he_cap.he_cap_elem.phy_cap_info[9] |=
|
||||
IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU;
|
||||
break;
|
||||
}
|
||||
|
||||
if (CSR_HW_REV_TYPE(trans->info.hw_rev) == IWL_CFG_MAC_TYPE_GL &&
|
||||
iftype_data->eht_cap.has_eht) {
|
||||
iftype_data->eht_cap.eht_cap_elem.mac_cap_info[0] &=
|
||||
~(IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE1 |
|
||||
IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE2);
|
||||
iftype_data->eht_cap.eht_cap_elem.phy_cap_info[3] &=
|
||||
~(IEEE80211_EHT_PHY_CAP0_PARTIAL_BW_UL_MU_MIMO |
|
||||
IEEE80211_EHT_PHY_CAP3_NG_16_SU_FEEDBACK |
|
||||
IEEE80211_EHT_PHY_CAP3_NG_16_MU_FEEDBACK |
|
||||
IEEE80211_EHT_PHY_CAP3_CODEBOOK_4_2_SU_FDBK |
|
||||
IEEE80211_EHT_PHY_CAP3_CODEBOOK_7_5_MU_FDBK |
|
||||
IEEE80211_EHT_PHY_CAP3_TRIG_MU_BF_PART_BW_FDBK |
|
||||
IEEE80211_EHT_PHY_CAP3_TRIG_CQI_FDBK);
|
||||
iftype_data->eht_cap.eht_cap_elem.phy_cap_info[4] &=
|
||||
~(IEEE80211_EHT_PHY_CAP4_PART_BW_DL_MU_MIMO |
|
||||
IEEE80211_EHT_PHY_CAP4_POWER_BOOST_FACT_SUPP);
|
||||
iftype_data->eht_cap.eht_cap_elem.phy_cap_info[5] &=
|
||||
~IEEE80211_EHT_PHY_CAP5_NON_TRIG_CQI_FEEDBACK;
|
||||
iftype_data->eht_cap.eht_cap_elem.phy_cap_info[6] &=
|
||||
~(IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_MASK |
|
||||
IEEE80211_EHT_PHY_CAP6_EHT_DUP_6GHZ_SUPP);
|
||||
iftype_data->eht_cap.eht_cap_elem.phy_cap_info[5] |=
|
||||
IEEE80211_EHT_PHY_CAP5_SUPP_EXTRA_EHT_LTF;
|
||||
}
|
||||
|
||||
if (fw_has_capa(&fw->ucode_capa, IWL_UCODE_TLV_CAPA_BROADCAST_TWT))
|
||||
iftype_data->he_cap.he_cap_elem.mac_cap_info[2] |=
|
||||
IEEE80211_HE_MAC_CAP2_BCAST_TWT;
|
||||
|
|
|
|||
|
|
@ -419,7 +419,10 @@ void iwl_trans_op_mode_leave(struct iwl_trans *trans)
|
|||
{
|
||||
might_sleep();
|
||||
|
||||
iwl_trans_pcie_op_mode_leave(trans);
|
||||
if (trans->mac_cfg->gen2)
|
||||
iwl_trans_pcie_gen2_op_mode_leave(trans);
|
||||
else
|
||||
iwl_trans_pcie_op_mode_leave(trans);
|
||||
|
||||
cancel_delayed_work_sync(&trans->restart.wk);
|
||||
|
||||
|
|
@ -495,9 +498,9 @@ void iwl_trans_set_pmi(struct iwl_trans *trans, bool state)
|
|||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_trans_set_pmi);
|
||||
|
||||
int iwl_trans_sw_reset(struct iwl_trans *trans, bool retake_ownership)
|
||||
int iwl_trans_sw_reset(struct iwl_trans *trans)
|
||||
{
|
||||
return iwl_trans_pcie_sw_reset(trans, retake_ownership);
|
||||
return iwl_trans_pcie_sw_reset(trans, true);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_trans_sw_reset);
|
||||
|
||||
|
|
|
|||
|
|
@ -1096,7 +1096,7 @@ static inline u32 iwl_trans_write_mem32(struct iwl_trans *trans, u32 addr,
|
|||
|
||||
void iwl_trans_set_pmi(struct iwl_trans *trans, bool state);
|
||||
|
||||
int iwl_trans_sw_reset(struct iwl_trans *trans, bool retake_ownership);
|
||||
int iwl_trans_sw_reset(struct iwl_trans *trans);
|
||||
|
||||
void iwl_trans_set_bits_mask(struct iwl_trans *trans, u32 reg,
|
||||
u32 mask, u32 value);
|
||||
|
|
@ -1230,6 +1230,21 @@ static inline u16 iwl_trans_get_num_rbds(struct iwl_trans *trans)
|
|||
return result;
|
||||
}
|
||||
|
||||
static inline void iwl_trans_suppress_cmd_error_once(struct iwl_trans *trans)
|
||||
{
|
||||
set_bit(STATUS_SUPPRESS_CMD_ERROR_ONCE, &trans->status);
|
||||
}
|
||||
|
||||
static inline bool iwl_trans_device_enabled(struct iwl_trans *trans)
|
||||
{
|
||||
return test_bit(STATUS_DEVICE_ENABLED, &trans->status);
|
||||
}
|
||||
|
||||
static inline bool iwl_trans_is_dead(struct iwl_trans *trans)
|
||||
{
|
||||
return test_bit(STATUS_TRANS_DEAD, &trans->status);
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* PCIe handling
|
||||
*****************************************************/
|
||||
|
|
|
|||
|
|
@ -294,9 +294,20 @@ int iwl_mld_start_ap_ibss(struct ieee80211_hw *hw,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
mld_vif->ap_ibss_active = true;
|
||||
|
||||
if (vif->p2p && mld->p2p_device_vif) {
|
||||
ret = iwl_mld_mac_fw_action(mld, mld->p2p_device_vif,
|
||||
FW_CTXT_ACTION_MODIFY);
|
||||
if (ret) {
|
||||
mld_vif->ap_ibss_active = false;
|
||||
goto rm_mcast;
|
||||
}
|
||||
}
|
||||
|
||||
ret = iwl_mld_add_bcast_sta(mld, vif, link);
|
||||
if (ret)
|
||||
goto rm_mcast;
|
||||
goto update_p2p_dev;
|
||||
|
||||
/* Those keys were configured by the upper layers before starting the
|
||||
* AP. Now that it is started and the bcast and mcast sta were added to
|
||||
|
|
@ -310,12 +321,6 @@ int iwl_mld_start_ap_ibss(struct ieee80211_hw *hw,
|
|||
iwl_mld_vif_update_low_latency(mld, vif, true,
|
||||
LOW_LATENCY_VIF_TYPE);
|
||||
|
||||
mld_vif->ap_ibss_active = true;
|
||||
|
||||
if (vif->p2p && mld->p2p_device_vif)
|
||||
return iwl_mld_mac_fw_action(mld, mld->p2p_device_vif,
|
||||
FW_CTXT_ACTION_MODIFY);
|
||||
|
||||
/* When the channel context was added, the link is not yet active, so
|
||||
* min_def is always used. Update the PHY again here in case def should
|
||||
* actually be used.
|
||||
|
|
@ -326,6 +331,11 @@ int iwl_mld_start_ap_ibss(struct ieee80211_hw *hw,
|
|||
return 0;
|
||||
rm_bcast:
|
||||
iwl_mld_remove_bcast_sta(mld, vif, link);
|
||||
update_p2p_dev:
|
||||
mld_vif->ap_ibss_active = false;
|
||||
if (vif->p2p && mld->p2p_device_vif)
|
||||
iwl_mld_mac_fw_action(mld, mld->p2p_device_vif,
|
||||
FW_CTXT_ACTION_MODIFY);
|
||||
rm_mcast:
|
||||
iwl_mld_remove_mcast_sta(mld, vif, link);
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -24,13 +24,17 @@ int iwl_mld_send_bt_init_conf(struct iwl_mld *mld)
|
|||
void iwl_mld_handle_bt_coex_notif(struct iwl_mld *mld,
|
||||
struct iwl_rx_packet *pkt)
|
||||
{
|
||||
const struct iwl_bt_coex_profile_notif *notif = (const void *)pkt->data;
|
||||
const struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data;
|
||||
const struct iwl_bt_coex_profile_notif zero_notif = {};
|
||||
/* zeroed structure means that BT is OFF */
|
||||
bool bt_is_active = memcmp(notif, &zero_notif, sizeof(*notif));
|
||||
|
||||
mld->last_bt_notif = *notif;
|
||||
if (bt_is_active == mld->bt_is_active)
|
||||
return;
|
||||
|
||||
IWL_DEBUG_INFO(mld, "BT was turned %s\n", bt_is_active ? "ON" : "OFF");
|
||||
|
||||
mld->bt_is_active = bt_is_active;
|
||||
|
||||
iwl_mld_emlsr_check_bt(mld);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -646,51 +646,6 @@ iwl_mld_set_key_rx_seq(struct ieee80211_key_conf *key,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
iwl_mld_d3_update_mcast_key(struct iwl_mld *mld,
|
||||
struct ieee80211_vif *vif,
|
||||
struct iwl_mld_wowlan_status *wowlan_status,
|
||||
struct ieee80211_key_conf *key,
|
||||
struct iwl_mld_mcast_key_data *key_data)
|
||||
{
|
||||
if (key->keyidx != key_data->id &&
|
||||
(key->keyidx < 4 || key->keyidx > 5)) {
|
||||
IWL_ERR(mld,
|
||||
"Unexpected keyId mismatch. Old keyId:%d, New keyId:%d\n",
|
||||
key->keyidx, key_data->id);
|
||||
return;
|
||||
}
|
||||
|
||||
/* All installed keys are sent by the FW, even weren't
|
||||
* rekeyed during D3.
|
||||
* We remove an existing key if it has the same index as
|
||||
* a new key and a rekey has occurred during d3
|
||||
*/
|
||||
if (wowlan_status->num_of_gtk_rekeys && key_data->len) {
|
||||
if (key->keyidx == 4 || key->keyidx == 5) {
|
||||
struct iwl_mld_vif *mld_vif =
|
||||
iwl_mld_vif_from_mac80211(vif);
|
||||
struct iwl_mld_link *mld_link;
|
||||
int link_id = vif->active_links ?
|
||||
__ffs(vif->active_links) : 0;
|
||||
|
||||
mld_link = iwl_mld_link_dereference_check(mld_vif,
|
||||
link_id);
|
||||
if (WARN_ON(!mld_link))
|
||||
return;
|
||||
|
||||
if (mld_link->igtk == key)
|
||||
mld_link->igtk = NULL;
|
||||
mld->num_igtks--;
|
||||
}
|
||||
|
||||
ieee80211_remove_key(key);
|
||||
return;
|
||||
}
|
||||
|
||||
iwl_mld_set_key_rx_seq(key, key_data);
|
||||
}
|
||||
|
||||
static void
|
||||
iwl_mld_update_ptk_rx_seq(struct iwl_mld *mld,
|
||||
struct iwl_mld_wowlan_status *wowlan_status,
|
||||
|
|
@ -759,8 +714,7 @@ iwl_mld_resume_keys_iter(struct ieee80211_hw *hw,
|
|||
|
||||
data->gtk_cipher = key->cipher;
|
||||
status_idx = key->keyidx == wowlan_status->gtk[1].id;
|
||||
iwl_mld_d3_update_mcast_key(data->mld, vif, wowlan_status, key,
|
||||
&wowlan_status->gtk[status_idx]);
|
||||
iwl_mld_set_key_rx_seq(key, &wowlan_status->gtk[status_idx]);
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_BIP_GMAC_128:
|
||||
case WLAN_CIPHER_SUITE_BIP_GMAC_256:
|
||||
|
|
@ -772,9 +726,8 @@ iwl_mld_resume_keys_iter(struct ieee80211_hw *hw,
|
|||
return;
|
||||
|
||||
data->igtk_cipher = key->cipher;
|
||||
iwl_mld_d3_update_mcast_key(data->mld, vif,
|
||||
wowlan_status,
|
||||
key, &wowlan_status->igtk);
|
||||
if (key->keyidx == wowlan_status->igtk.id)
|
||||
iwl_mld_set_key_rx_seq(key, &wowlan_status->igtk);
|
||||
}
|
||||
if (key->keyidx == 6 || key->keyidx == 7) {
|
||||
if (WARN_ON(data->bigtk_cipher &&
|
||||
|
|
@ -783,9 +736,7 @@ iwl_mld_resume_keys_iter(struct ieee80211_hw *hw,
|
|||
|
||||
data->bigtk_cipher = key->cipher;
|
||||
status_idx = key->keyidx == wowlan_status->bigtk[1].id;
|
||||
iwl_mld_d3_update_mcast_key(data->mld, vif,
|
||||
wowlan_status, key,
|
||||
&wowlan_status->bigtk[status_idx]);
|
||||
iwl_mld_set_key_rx_seq(key, &wowlan_status->bigtk[status_idx]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -795,7 +746,7 @@ iwl_mld_resume_keys_iter(struct ieee80211_hw *hw,
|
|||
data->num_keys++;
|
||||
}
|
||||
|
||||
static bool
|
||||
static void
|
||||
iwl_mld_add_mcast_rekey(struct ieee80211_vif *vif,
|
||||
struct iwl_mld *mld,
|
||||
struct iwl_mld_mcast_key_data *key_data,
|
||||
|
|
@ -822,7 +773,7 @@ iwl_mld_add_mcast_rekey(struct ieee80211_vif *vif,
|
|||
BUILD_BUG_ON(sizeof(conf.key) < sizeof(key_data->key));
|
||||
|
||||
if (!key_data->len)
|
||||
return true;
|
||||
return;
|
||||
|
||||
switch (cipher) {
|
||||
case WLAN_CIPHER_SUITE_CCMP:
|
||||
|
|
@ -854,7 +805,7 @@ iwl_mld_add_mcast_rekey(struct ieee80211_vif *vif,
|
|||
memcpy(conf.conf.key, key_data->key, conf.conf.keylen);
|
||||
key_config = ieee80211_gtk_rekey_add(vif, &conf.conf, link_id);
|
||||
if (IS_ERR(key_config))
|
||||
return false;
|
||||
return;
|
||||
|
||||
iwl_mld_set_key_rx_seq(key_config, key_data);
|
||||
|
||||
|
|
@ -862,10 +813,25 @@ iwl_mld_add_mcast_rekey(struct ieee80211_vif *vif,
|
|||
if (key_config->keyidx == 4 || key_config->keyidx == 5) {
|
||||
struct iwl_mld_link *mld_link =
|
||||
iwl_mld_link_from_mac80211(link_conf);
|
||||
mld_link->igtk = key_config;
|
||||
mld->num_igtks++;
|
||||
|
||||
/* If we had more than one rekey, mac80211 will tell us to
|
||||
* remove the old and add the new so we will update the IGTK in
|
||||
* drv_set_key
|
||||
*/
|
||||
if (mld_link->igtk && mld_link->igtk != key_config) {
|
||||
/* mark the old IGTK as not in FW */
|
||||
mld_link->igtk->hw_key_idx = STA_KEY_IDX_INVALID;
|
||||
mld_link->igtk = key_config;
|
||||
}
|
||||
}
|
||||
|
||||
/* Also keep track of the new BIGTK */
|
||||
if ((key_config->keyidx == 6 || key_config->keyidx == 7) &&
|
||||
vif->type == NL80211_IFTYPE_STATION) {
|
||||
struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
|
||||
|
||||
rcu_assign_pointer(mld_vif->bigtks[key_config->keyidx - 6], key_config);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -877,23 +843,20 @@ iwl_mld_add_all_rekeys(struct ieee80211_vif *vif,
|
|||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(wowlan_status->gtk); i++)
|
||||
if (!iwl_mld_add_mcast_rekey(vif, key_iter_data->mld,
|
||||
&wowlan_status->gtk[i],
|
||||
link_conf,
|
||||
key_iter_data->gtk_cipher))
|
||||
return;
|
||||
iwl_mld_add_mcast_rekey(vif, key_iter_data->mld,
|
||||
&wowlan_status->gtk[i],
|
||||
link_conf,
|
||||
key_iter_data->gtk_cipher);
|
||||
|
||||
if (!iwl_mld_add_mcast_rekey(vif, key_iter_data->mld,
|
||||
&wowlan_status->igtk,
|
||||
link_conf, key_iter_data->igtk_cipher))
|
||||
return;
|
||||
iwl_mld_add_mcast_rekey(vif, key_iter_data->mld,
|
||||
&wowlan_status->igtk,
|
||||
link_conf, key_iter_data->igtk_cipher);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(wowlan_status->bigtk); i++)
|
||||
if (!iwl_mld_add_mcast_rekey(vif, key_iter_data->mld,
|
||||
&wowlan_status->bigtk[i],
|
||||
link_conf,
|
||||
key_iter_data->bigtk_cipher))
|
||||
return;
|
||||
iwl_mld_add_mcast_rekey(vif, key_iter_data->mld,
|
||||
&wowlan_status->bigtk[i],
|
||||
link_conf,
|
||||
key_iter_data->bigtk_cipher);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -1851,6 +1814,7 @@ int iwl_mld_wowlan_resume(struct iwl_mld *mld)
|
|||
goto err;
|
||||
}
|
||||
|
||||
mld->fw_status.resuming = true;
|
||||
mld->fw_status.in_d3 = false;
|
||||
mld->scan.last_start_time_jiffies = jiffies;
|
||||
|
||||
|
|
@ -1926,6 +1890,8 @@ int iwl_mld_wowlan_resume(struct iwl_mld *mld)
|
|||
mld->fw_status.in_hw_restart = true;
|
||||
ret = 1;
|
||||
out:
|
||||
mld->fw_status.resuming = false;
|
||||
|
||||
if (resume_data.wowlan_status) {
|
||||
kfree(resume_data.wowlan_status->wake_packet);
|
||||
kfree(resume_data.wowlan_status);
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mld *mld, char *buf,
|
|||
|
||||
if (count == 6 && !strcmp(buf, "nolog\n")) {
|
||||
mld->fw_status.do_not_dump_once = true;
|
||||
set_bit(STATUS_SUPPRESS_CMD_ERROR_ONCE, &mld->trans->status);
|
||||
iwl_trans_suppress_cmd_error_once(mld->trans);
|
||||
}
|
||||
|
||||
/* take the return value to make compiler happy - it will
|
||||
|
|
|
|||
|
|
@ -129,6 +129,12 @@ static int iwl_mld_add_key_to_fw(struct iwl_mld *mld, u32 sta_mask,
|
|||
bool tkip = key->cipher == WLAN_CIPHER_SUITE_TKIP;
|
||||
int max_key_len = sizeof(cmd.u.add.key);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
/* If there was a rekey in wowlan, FW already has the key */
|
||||
if (mld->fw_status.resuming)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if (WARN_ON(!sta_mask))
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -160,6 +166,12 @@ static void iwl_mld_remove_key_from_fw(struct iwl_mld *mld, u32 sta_mask,
|
|||
.u.remove.key_flags = cpu_to_le32(key_flags),
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
/* If there was a rekey in wowlan, FW already removed the key */
|
||||
if (mld->fw_status.resuming)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (WARN_ON(!sta_mask))
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -649,11 +649,39 @@ void iwl_mld_omi_ap_changed_bw(struct iwl_mld *mld,
|
|||
void iwl_mld_handle_omi_status_notif(struct iwl_mld *mld,
|
||||
struct iwl_rx_packet *pkt)
|
||||
{
|
||||
int ver = iwl_fw_lookup_notif_ver(mld->fw, DATA_PATH_GROUP,
|
||||
OMI_SEND_STATUS_NOTIF, 1);
|
||||
struct ieee80211_link_sta *link_sta;
|
||||
struct iwl_mld_link *mld_link;
|
||||
struct ieee80211_vif *vif;
|
||||
|
||||
vif = iwl_mld_get_omi_bw_reduction_pointers(mld, &link_sta, &mld_link);
|
||||
if (ver == 2) {
|
||||
const struct iwl_omi_send_status_notif *notif =
|
||||
(const void *)pkt->data;
|
||||
u32 sta_id = le32_to_cpu(notif->sta_id);
|
||||
struct iwl_mld_vif *mld_vif;
|
||||
|
||||
if (IWL_FW_CHECK(mld, sta_id >= mld->fw->ucode_capa.num_stations,
|
||||
"Invalid station %d\n", sta_id))
|
||||
return;
|
||||
|
||||
link_sta = wiphy_dereference(mld->wiphy,
|
||||
mld->fw_id_to_link_sta[sta_id]);
|
||||
if (IWL_FW_CHECK(mld, !link_sta, "Station does not exist\n"))
|
||||
return;
|
||||
|
||||
vif = iwl_mld_sta_from_mac80211(link_sta->sta)->vif;
|
||||
mld_vif = iwl_mld_vif_from_mac80211(vif);
|
||||
|
||||
mld_link = iwl_mld_link_dereference_check(mld_vif,
|
||||
link_sta->link_id);
|
||||
if (WARN(!mld_link, "Link %d does not exist\n",
|
||||
link_sta->link_id))
|
||||
return;
|
||||
} else {
|
||||
vif = iwl_mld_get_omi_bw_reduction_pointers(mld, &link_sta,
|
||||
&mld_link);
|
||||
}
|
||||
if (IWL_FW_CHECK(mld, !vif, "unexpected OMI notification\n"))
|
||||
return;
|
||||
|
||||
|
|
@ -783,6 +811,7 @@ iwl_mld_init_link(struct iwl_mld *mld, struct ieee80211_bss_conf *link,
|
|||
{
|
||||
mld_link->vif = link->vif;
|
||||
mld_link->link_id = link->link_id;
|
||||
mld_link->average_beacon_energy = 0;
|
||||
|
||||
iwl_mld_init_internal_sta(&mld_link->bcast_sta);
|
||||
iwl_mld_init_internal_sta(&mld_link->mcast_sta);
|
||||
|
|
@ -1216,3 +1245,22 @@ unsigned int iwl_mld_get_link_grade(struct iwl_mld *mld,
|
|||
return grade;
|
||||
}
|
||||
EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_mld_get_link_grade);
|
||||
|
||||
void iwl_mld_handle_beacon_filter_notif(struct iwl_mld *mld,
|
||||
struct iwl_rx_packet *pkt)
|
||||
{
|
||||
const struct iwl_beacon_filter_notif *notif = (const void *)pkt->data;
|
||||
u32 link_id = le32_to_cpu(notif->link_id);
|
||||
struct ieee80211_bss_conf *link_conf =
|
||||
iwl_mld_fw_id_to_link_conf(mld, link_id);
|
||||
struct iwl_mld_link *mld_link;
|
||||
|
||||
if (IWL_FW_CHECK(mld, !link_conf, "invalid link ID %d\n", link_id))
|
||||
return;
|
||||
|
||||
mld_link = iwl_mld_link_from_mac80211(link_conf);
|
||||
if (WARN_ON_ONCE(!mld_link))
|
||||
return;
|
||||
|
||||
mld_link->average_beacon_energy = le32_to_cpu(notif->average_energy);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ struct iwl_probe_resp_data {
|
|||
* @mcast_sta: station used for multicast packets. Used in AP, GO and IBSS.
|
||||
* @mon_sta: station used for TX injection in monitor interface.
|
||||
* @link_id: over the air link ID
|
||||
* @average_beacon_energy: average beacon energy for beacons received during
|
||||
* client connections
|
||||
* @ap_early_keys: The firmware cannot install keys before bcast/mcast STAs,
|
||||
* but higher layers work differently, so we store the keys here for
|
||||
* later installation.
|
||||
|
|
@ -85,6 +87,7 @@ struct iwl_mld_link {
|
|||
|
||||
/* we can only have 2 GTK + 2 IGTK + 2 BIGTK active at a time */
|
||||
struct ieee80211_key_conf *ap_early_keys[6];
|
||||
u32 average_beacon_energy;
|
||||
bool silent_deactivation;
|
||||
struct iwl_probe_resp_data __rcu *probe_resp_data;
|
||||
};
|
||||
|
|
@ -150,4 +153,7 @@ void iwl_mld_omi_ap_changed_bw(struct iwl_mld *mld,
|
|||
struct ieee80211_bss_conf *link_conf,
|
||||
enum ieee80211_sta_rx_bandwidth bw);
|
||||
|
||||
void iwl_mld_handle_beacon_filter_notif(struct iwl_mld *mld,
|
||||
struct iwl_rx_packet *pkt);
|
||||
|
||||
#endif /* __iwl_mld_link_h__ */
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
/* It is the caller's responsibility to free the pointer returned here */
|
||||
static struct iwl_mcc_update_resp_v8 *
|
||||
iwl_mld_parse_mcc_update_resp_v8(const struct iwl_rx_packet *pkt)
|
||||
iwl_mld_copy_mcc_resp(const struct iwl_rx_packet *pkt)
|
||||
{
|
||||
const struct iwl_mcc_update_resp_v8 *mcc_resp_v8 = (const void *)pkt->data;
|
||||
int n_channels = __le32_to_cpu(mcc_resp_v8->n_channels);
|
||||
|
|
@ -32,43 +32,11 @@ iwl_mld_parse_mcc_update_resp_v8(const struct iwl_rx_packet *pkt)
|
|||
return resp_cp;
|
||||
}
|
||||
|
||||
/* It is the caller's responsibility to free the pointer returned here */
|
||||
static struct iwl_mcc_update_resp_v8 *
|
||||
iwl_mld_parse_mcc_update_resp_v5_v6(const struct iwl_rx_packet *pkt)
|
||||
{
|
||||
const struct iwl_mcc_update_resp_v4 *mcc_resp_v4 = (const void *)pkt->data;
|
||||
struct iwl_mcc_update_resp_v8 *resp_cp;
|
||||
int n_channels = __le32_to_cpu(mcc_resp_v4->n_channels);
|
||||
int resp_len;
|
||||
|
||||
if (iwl_rx_packet_payload_len(pkt) !=
|
||||
struct_size(mcc_resp_v4, channels, n_channels))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
resp_len = struct_size(resp_cp, channels, n_channels);
|
||||
resp_cp = kzalloc(resp_len, GFP_KERNEL);
|
||||
if (!resp_cp)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
resp_cp->status = mcc_resp_v4->status;
|
||||
resp_cp->mcc = mcc_resp_v4->mcc;
|
||||
resp_cp->cap = cpu_to_le32(le16_to_cpu(mcc_resp_v4->cap));
|
||||
resp_cp->source_id = mcc_resp_v4->source_id;
|
||||
resp_cp->geo_info = mcc_resp_v4->geo_info;
|
||||
resp_cp->n_channels = mcc_resp_v4->n_channels;
|
||||
memcpy(resp_cp->channels, mcc_resp_v4->channels,
|
||||
n_channels * sizeof(__le32));
|
||||
|
||||
return resp_cp;
|
||||
}
|
||||
|
||||
/* It is the caller's responsibility to free the pointer returned here */
|
||||
static struct iwl_mcc_update_resp_v8 *
|
||||
iwl_mld_update_mcc(struct iwl_mld *mld, const char *alpha2,
|
||||
enum iwl_mcc_source src_id)
|
||||
{
|
||||
int resp_ver = iwl_fw_lookup_notif_ver(mld->fw, LONG_GROUP,
|
||||
MCC_UPDATE_CMD, 0);
|
||||
struct iwl_mcc_update_cmd mcc_update_cmd = {
|
||||
.mcc = cpu_to_le16(alpha2[0] << 8 | alpha2[1]),
|
||||
.source_id = (u8)src_id,
|
||||
|
|
@ -93,23 +61,7 @@ iwl_mld_update_mcc(struct iwl_mld *mld, const char *alpha2,
|
|||
|
||||
pkt = cmd.resp_pkt;
|
||||
|
||||
/* For Wifi-7 radios, we get version 8
|
||||
* For Wifi-6E radios, we get version 6
|
||||
* For Wifi-6 radios, we get version 5, but 5, 6, and 4 are compatible.
|
||||
*/
|
||||
switch (resp_ver) {
|
||||
case 5:
|
||||
case 6:
|
||||
resp_cp = iwl_mld_parse_mcc_update_resp_v5_v6(pkt);
|
||||
break;
|
||||
case 8:
|
||||
resp_cp = iwl_mld_parse_mcc_update_resp_v8(pkt);
|
||||
break;
|
||||
default:
|
||||
IWL_FW_CHECK_FAILED(mld, "Unknown MCC_UPDATE_CMD version %d\n", resp_ver);
|
||||
resp_cp = ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
resp_cp = iwl_mld_copy_mcc_resp(pkt);
|
||||
if (IS_ERR(resp_cp))
|
||||
goto exit;
|
||||
|
||||
|
|
@ -177,11 +129,15 @@ iwl_mld_get_regdomain(struct iwl_mld *mld,
|
|||
|
||||
mld->mcc_src = resp->source_id;
|
||||
|
||||
if (!iwl_puncturing_is_allowed_in_bios(mld->bios_enable_puncturing,
|
||||
le16_to_cpu(resp->mcc)))
|
||||
ieee80211_hw_set(mld->hw, DISALLOW_PUNCTURING);
|
||||
else
|
||||
__clear_bit(IEEE80211_HW_DISALLOW_PUNCTURING, mld->hw->flags);
|
||||
/* FM is the earliest supported and later always do puncturing */
|
||||
if (CSR_HW_RFID_TYPE(mld->trans->info.hw_rf_id) == IWL_CFG_RF_TYPE_FM) {
|
||||
if (!iwl_puncturing_is_allowed_in_bios(mld->bios_enable_puncturing,
|
||||
le16_to_cpu(resp->mcc)))
|
||||
ieee80211_hw_set(mld->hw, DISALLOW_PUNCTURING);
|
||||
else
|
||||
__clear_bit(IEEE80211_HW_DISALLOW_PUNCTURING,
|
||||
mld->hw->flags);
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(resp);
|
||||
|
|
|
|||
|
|
@ -255,6 +255,7 @@ static const struct iwl_hcmd_names iwl_mld_data_path_names[] = {
|
|||
HCMD_NAME(ESR_MODE_NOTIF),
|
||||
HCMD_NAME(MONITOR_NOTIF),
|
||||
HCMD_NAME(TLC_MNG_UPDATE_NOTIF),
|
||||
HCMD_NAME(BEACON_FILTER_IN_NOTIF),
|
||||
HCMD_NAME(MU_GROUP_MGMT_NOTIF),
|
||||
};
|
||||
|
||||
|
|
@ -630,7 +631,7 @@ iwl_mld_nic_error(struct iwl_op_mode *op_mode,
|
|||
enum iwl_fw_error_type type)
|
||||
{
|
||||
struct iwl_mld *mld = IWL_OP_MODE_GET_MLD(op_mode);
|
||||
bool trans_dead = test_bit(STATUS_TRANS_DEAD, &mld->trans->status);
|
||||
bool trans_dead = iwl_trans_is_dead(mld->trans);
|
||||
|
||||
if (type == IWL_ERR_TYPE_CMD_QUEUE_FULL)
|
||||
IWL_ERR(mld, "Command queue full!\n");
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@
|
|||
* cleanup using iwl_mld_free_internal_sta
|
||||
* @netdetect: indicates the FW is in suspend mode with netdetect configured
|
||||
* @p2p_device_vif: points to the p2p device vif if exists
|
||||
* @bt_is_active: indicates that BT is active
|
||||
* @dev: pointer to device struct. For printing purposes
|
||||
* @trans: pointer to the transport layer
|
||||
* @cfg: pointer to the device configuration
|
||||
|
|
@ -149,6 +150,7 @@
|
|||
* @running: true if the firmware is running
|
||||
* @do_not_dump_once: true if firmware dump must be prevented once
|
||||
* @in_d3: indicates FW is in suspend mode and should be resumed
|
||||
* @resuming: indicates the driver is resuming from wowlan
|
||||
* @in_hw_restart: indicates that we are currently in restart flow.
|
||||
* rather than restarted. Should be unset upon restart.
|
||||
* @radio_kill: bitmap of radio kill status
|
||||
|
|
@ -188,7 +190,6 @@
|
|||
* @ptp_data: data of the PTP clock
|
||||
* @time_sync: time sync data.
|
||||
* @ftm_initiator: FTM initiator data
|
||||
* @last_bt_notif: last received BT Coex notif
|
||||
*/
|
||||
struct iwl_mld {
|
||||
/* Add here fields that need clean up on restart */
|
||||
|
|
@ -213,7 +214,7 @@ struct iwl_mld {
|
|||
bool netdetect;
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
struct ieee80211_vif *p2p_device_vif;
|
||||
struct iwl_bt_coex_profile_notif last_bt_notif;
|
||||
bool bt_is_active;
|
||||
);
|
||||
struct ieee80211_link_sta __rcu *fw_id_to_link_sta[IWL_STATION_COUNT_MAX];
|
||||
/* And here fields that survive a fw restart */
|
||||
|
|
@ -237,6 +238,7 @@ struct iwl_mld {
|
|||
do_not_dump_once:1,
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
in_d3:1,
|
||||
resuming:1,
|
||||
#endif
|
||||
in_hw_restart:1;
|
||||
|
||||
|
|
|
|||
|
|
@ -689,42 +689,6 @@ s8 iwl_mld_get_emlsr_rssi_thresh(struct iwl_mld *mld,
|
|||
#undef RSSI_THRESHOLD
|
||||
}
|
||||
|
||||
#define IWL_MLD_BT_COEX_DISABLE_EMLSR_RSSI_THRESH -69
|
||||
#define IWL_MLD_BT_COEX_ENABLE_EMLSR_RSSI_THRESH -63
|
||||
#define IWL_MLD_BT_COEX_WIFI_LOSS_THRESH 7
|
||||
|
||||
VISIBLE_IF_IWLWIFI_KUNIT
|
||||
bool
|
||||
iwl_mld_bt_allows_emlsr(struct iwl_mld *mld, struct ieee80211_bss_conf *link,
|
||||
bool check_entry)
|
||||
{
|
||||
int bt_penalty, rssi_thresh;
|
||||
s32 link_rssi;
|
||||
|
||||
if (WARN_ON_ONCE(!link->bss))
|
||||
return false;
|
||||
|
||||
link_rssi = MBM_TO_DBM(link->bss->signal);
|
||||
rssi_thresh = check_entry ?
|
||||
IWL_MLD_BT_COEX_ENABLE_EMLSR_RSSI_THRESH :
|
||||
IWL_MLD_BT_COEX_DISABLE_EMLSR_RSSI_THRESH;
|
||||
/* No valid RSSI - force to take low rssi */
|
||||
if (!link_rssi)
|
||||
link_rssi = rssi_thresh - 1;
|
||||
|
||||
if (link_rssi > rssi_thresh)
|
||||
bt_penalty = max(mld->last_bt_notif.wifi_loss_mid_high_rssi[PHY_BAND_24][0],
|
||||
mld->last_bt_notif.wifi_loss_mid_high_rssi[PHY_BAND_24][1]);
|
||||
else
|
||||
bt_penalty = max(mld->last_bt_notif.wifi_loss_low_rssi[PHY_BAND_24][0],
|
||||
mld->last_bt_notif.wifi_loss_low_rssi[PHY_BAND_24][1]);
|
||||
|
||||
IWL_DEBUG_EHT(mld, "BT penalty for link-id %0X is %d\n",
|
||||
link->link_id, bt_penalty);
|
||||
return bt_penalty < IWL_MLD_BT_COEX_WIFI_LOSS_THRESH;
|
||||
}
|
||||
EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_mld_bt_allows_emlsr);
|
||||
|
||||
static u32
|
||||
iwl_mld_emlsr_disallowed_with_link(struct iwl_mld *mld,
|
||||
struct ieee80211_vif *vif,
|
||||
|
|
@ -739,8 +703,7 @@ iwl_mld_emlsr_disallowed_with_link(struct iwl_mld *mld,
|
|||
if (WARN_ON_ONCE(!conf))
|
||||
return IWL_MLD_EMLSR_EXIT_INVALID;
|
||||
|
||||
if (link->chandef->chan->band == NL80211_BAND_2GHZ &&
|
||||
!iwl_mld_bt_allows_emlsr(mld, conf, true))
|
||||
if (link->chandef->chan->band == NL80211_BAND_2GHZ && mld->bt_is_active)
|
||||
ret |= IWL_MLD_EMLSR_EXIT_BT_COEX;
|
||||
|
||||
if (link->signal <
|
||||
|
|
@ -1078,41 +1041,30 @@ static void iwl_mld_emlsr_check_bt_iter(void *_data, u8 *mac,
|
|||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
|
||||
const struct iwl_bt_coex_profile_notif zero_notif = {};
|
||||
struct iwl_mld *mld = mld_vif->mld;
|
||||
struct ieee80211_bss_conf *link;
|
||||
unsigned int link_id;
|
||||
const struct iwl_bt_coex_profile_notif *notif = &mld->last_bt_notif;
|
||||
|
||||
if (!iwl_mld_vif_has_emlsr_cap(vif))
|
||||
return;
|
||||
|
||||
/* zeroed structure means that BT is OFF */
|
||||
if (!memcmp(notif, &zero_notif, sizeof(*notif))) {
|
||||
if (!mld->bt_is_active) {
|
||||
iwl_mld_retry_emlsr(mld, vif);
|
||||
return;
|
||||
}
|
||||
|
||||
for_each_vif_active_link(vif, link, link_id) {
|
||||
bool emlsr_active, emlsr_allowed;
|
||||
/* BT is turned ON but we are not in EMLSR, nothing to do */
|
||||
if (!iwl_mld_emlsr_active(vif))
|
||||
return;
|
||||
|
||||
/* In EMLSR and BT is turned ON */
|
||||
|
||||
for_each_vif_active_link(vif, link, link_id) {
|
||||
if (WARN_ON(!link->chanreq.oper.chan))
|
||||
continue;
|
||||
|
||||
if (link->chanreq.oper.chan->band != NL80211_BAND_2GHZ)
|
||||
continue;
|
||||
|
||||
emlsr_active = iwl_mld_emlsr_active(vif);
|
||||
emlsr_allowed = iwl_mld_bt_allows_emlsr(mld, link,
|
||||
!emlsr_active);
|
||||
if (emlsr_allowed && !emlsr_active) {
|
||||
iwl_mld_retry_emlsr(mld, vif);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!emlsr_allowed && emlsr_active) {
|
||||
iwl_mld_exit_emlsr(mld, vif,
|
||||
IWL_MLD_EMLSR_EXIT_BT_COEX,
|
||||
if (link->chanreq.oper.chan->band == NL80211_BAND_2GHZ) {
|
||||
iwl_mld_exit_emlsr(mld, vif, IWL_MLD_EMLSR_EXIT_BT_COEX,
|
||||
iwl_mld_get_primary_link(vif));
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,10 +163,6 @@ void iwl_mld_emlsr_block_tmp_non_bss(struct iwl_mld *mld);
|
|||
u32 iwl_mld_emlsr_pair_state(struct ieee80211_vif *vif,
|
||||
struct iwl_mld_link_sel_data *a,
|
||||
struct iwl_mld_link_sel_data *b);
|
||||
|
||||
bool iwl_mld_bt_allows_emlsr(struct iwl_mld *mld,
|
||||
struct ieee80211_bss_conf *link,
|
||||
bool entry_criteria);
|
||||
#endif
|
||||
|
||||
void iwl_mld_start_ignoring_tpt_updates(struct iwl_mld *mld);
|
||||
|
|
|
|||
|
|
@ -349,8 +349,10 @@ CMD_VERSIONS(time_msmt_notif,
|
|||
CMD_VERSIONS(time_sync_confirm_notif,
|
||||
CMD_VER_ENTRY(1, iwl_time_msmt_cfm_notify))
|
||||
CMD_VERSIONS(omi_status_notif,
|
||||
CMD_VER_ENTRY(1, iwl_omi_send_status_notif))
|
||||
CMD_VERSIONS(ftm_resp_notif, CMD_VER_ENTRY(9, iwl_tof_range_rsp_ntfy))
|
||||
CMD_VER_ENTRY(1, iwl_omi_send_status_notif_v1)
|
||||
CMD_VER_ENTRY(2, iwl_omi_send_status_notif))
|
||||
CMD_VERSIONS(ftm_resp_notif, CMD_VER_ENTRY(10, iwl_tof_range_rsp_ntfy))
|
||||
CMD_VERSIONS(beacon_filter_notif, CMD_VER_ENTRY(2, iwl_beacon_filter_notif))
|
||||
|
||||
DEFINE_SIMPLE_CANCELLATION(session_prot, iwl_session_prot_notif, mac_link_id)
|
||||
DEFINE_SIMPLE_CANCELLATION(tlc, iwl_tlc_update_notif, sta_id)
|
||||
|
|
@ -368,6 +370,7 @@ DEFINE_SIMPLE_CANCELLATION(uapsd_misbehaving_ap, iwl_uapsd_misbehaving_ap_notif,
|
|||
mac_id)
|
||||
#define iwl_mld_cancel_omi_status_notif iwl_mld_always_cancel
|
||||
DEFINE_SIMPLE_CANCELLATION(ftm_resp, iwl_tof_range_rsp_ntfy, request_id)
|
||||
DEFINE_SIMPLE_CANCELLATION(beacon_filter, iwl_beacon_filter_notif, link_id)
|
||||
|
||||
/**
|
||||
* DOC: Handlers for fw notifications
|
||||
|
|
@ -460,6 +463,8 @@ const struct iwl_rx_handler iwl_mld_rx_handlers[] = {
|
|||
time_sync_confirm_notif, RX_HANDLER_ASYNC)
|
||||
RX_HANDLER_OF_LINK(DATA_PATH_GROUP, OMI_SEND_STATUS_NOTIF,
|
||||
omi_status_notif)
|
||||
RX_HANDLER_OF_LINK(DATA_PATH_GROUP, BEACON_FILTER_IN_NOTIF,
|
||||
beacon_filter_notif)
|
||||
RX_HANDLER_OF_FTM_REQ(LOCATION_GROUP, TOF_RANGE_RESPONSE_NOTIF,
|
||||
ftm_resp_notif)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -377,23 +377,15 @@ int iwl_mld_set_tx_power(struct iwl_mld *mld,
|
|||
u16 u_tx_power = tx_power == IWL_DEFAULT_MAX_TX_POWER ?
|
||||
IWL_DEV_MAX_TX_POWER : 8 * tx_power;
|
||||
struct iwl_dev_tx_power_cmd cmd = {
|
||||
/* Those fields sit on the same place for v9 and v10 */
|
||||
.common.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_LINK),
|
||||
.common.pwr_restriction = cpu_to_le16(u_tx_power),
|
||||
};
|
||||
u8 cmd_ver = iwl_fw_lookup_cmd_ver(mld->fw, cmd_id,
|
||||
IWL_FW_CMD_VER_UNKNOWN);
|
||||
int len = sizeof(cmd.common);
|
||||
int len = sizeof(cmd.common) + sizeof(cmd.v10);
|
||||
|
||||
if (WARN_ON(!mld_link))
|
||||
return -ENODEV;
|
||||
|
||||
cmd.common.link_id = cpu_to_le32(mld_link->fw_id);
|
||||
|
||||
if (cmd_ver == 10)
|
||||
len += sizeof(cmd.v10);
|
||||
else if (cmd_ver == 9)
|
||||
len += sizeof(cmd.v9);
|
||||
|
||||
return iwl_mld_send_cmd_pdu(mld, cmd_id, &cmd, len);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,40 +71,17 @@ void iwl_mld_get_bios_tables(struct iwl_mld *mld)
|
|||
static int iwl_mld_geo_sar_init(struct iwl_mld *mld)
|
||||
{
|
||||
u32 cmd_id = WIDE_ID(PHY_OPS_GROUP, PER_CHAIN_LIMIT_OFFSET_CMD);
|
||||
union iwl_geo_tx_power_profiles_cmd cmd;
|
||||
u16 len;
|
||||
u32 n_bands;
|
||||
__le32 sk = cpu_to_le32(0);
|
||||
int ret;
|
||||
u8 cmd_ver = iwl_fw_lookup_cmd_ver(mld->fw, cmd_id,
|
||||
IWL_FW_CMD_VER_UNKNOWN);
|
||||
|
||||
BUILD_BUG_ON(offsetof(struct iwl_geo_tx_power_profiles_cmd_v4, ops) !=
|
||||
offsetof(struct iwl_geo_tx_power_profiles_cmd_v5, ops));
|
||||
|
||||
cmd.v4.ops = cpu_to_le32(IWL_PER_CHAIN_OFFSET_SET_TABLES);
|
||||
|
||||
/* Only set to South Korea if the table revision is 1 */
|
||||
if (mld->fwrt.geo_rev == 1)
|
||||
sk = cpu_to_le32(1);
|
||||
__le32 sk = cpu_to_le32(mld->fwrt.geo_rev == 1 ? 1 : 0);
|
||||
union iwl_geo_tx_power_profiles_cmd cmd = {
|
||||
.v5.ops = cpu_to_le32(IWL_PER_CHAIN_OFFSET_SET_TABLES),
|
||||
.v5.table_revision = sk,
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (cmd_ver == 5) {
|
||||
len = sizeof(cmd.v5);
|
||||
n_bands = ARRAY_SIZE(cmd.v5.table[0]);
|
||||
cmd.v5.table_revision = sk;
|
||||
} else if (cmd_ver == 4) {
|
||||
len = sizeof(cmd.v4);
|
||||
n_bands = ARRAY_SIZE(cmd.v4.table[0]);
|
||||
cmd.v4.table_revision = sk;
|
||||
} else {
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
BUILD_BUG_ON(offsetof(struct iwl_geo_tx_power_profiles_cmd_v4, table) !=
|
||||
offsetof(struct iwl_geo_tx_power_profiles_cmd_v5, table));
|
||||
/* the table is at the same position for all versions, so set use v4 */
|
||||
ret = iwl_sar_geo_fill_table(&mld->fwrt, &cmd.v4.table[0][0],
|
||||
n_bands, BIOS_GEO_MAX_PROFILE_NUM);
|
||||
ret = iwl_sar_geo_fill_table(&mld->fwrt, &cmd.v5.table[0][0],
|
||||
ARRAY_SIZE(cmd.v5.table[0]),
|
||||
BIOS_GEO_MAX_PROFILE_NUM);
|
||||
|
||||
/* It is a valid scenario to not support SAR, or miss wgds table,
|
||||
* but in that case there is no need to send the command.
|
||||
|
|
@ -112,7 +89,7 @@ static int iwl_mld_geo_sar_init(struct iwl_mld *mld)
|
|||
if (ret)
|
||||
return 0;
|
||||
|
||||
return iwl_mld_send_cmd_pdu(mld, cmd_id, &cmd, len);
|
||||
return iwl_mld_send_cmd_pdu(mld, cmd_id, &cmd, sizeof(cmd.v5));
|
||||
}
|
||||
|
||||
int iwl_mld_config_sar_profile(struct iwl_mld *mld, int prof_a, int prof_b)
|
||||
|
|
@ -120,37 +97,20 @@ int iwl_mld_config_sar_profile(struct iwl_mld *mld, int prof_a, int prof_b)
|
|||
u32 cmd_id = REDUCE_TX_POWER_CMD;
|
||||
struct iwl_dev_tx_power_cmd cmd = {
|
||||
.common.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_CHAINS),
|
||||
.v10.flags = cpu_to_le32(mld->fwrt.reduced_power_flags),
|
||||
};
|
||||
__le16 *per_chain;
|
||||
int ret;
|
||||
u16 len = sizeof(cmd.common);
|
||||
u32 n_subbands;
|
||||
u8 cmd_ver = iwl_fw_lookup_cmd_ver(mld->fw, cmd_id,
|
||||
IWL_FW_CMD_VER_UNKNOWN);
|
||||
|
||||
if (cmd_ver == 10) {
|
||||
len += sizeof(cmd.v10);
|
||||
n_subbands = IWL_NUM_SUB_BANDS_V2;
|
||||
per_chain = &cmd.v10.per_chain[0][0][0];
|
||||
cmd.v10.flags =
|
||||
cpu_to_le32(mld->fwrt.reduced_power_flags);
|
||||
} else if (cmd_ver == 9) {
|
||||
len += sizeof(cmd.v9);
|
||||
n_subbands = IWL_NUM_SUB_BANDS_V1;
|
||||
per_chain = &cmd.v9.per_chain[0][0];
|
||||
} else {
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* TODO: CDB - support IWL_NUM_CHAIN_TABLES_V2 */
|
||||
ret = iwl_sar_fill_profile(&mld->fwrt, per_chain,
|
||||
IWL_NUM_CHAIN_TABLES,
|
||||
n_subbands, prof_a, prof_b);
|
||||
ret = iwl_sar_fill_profile(&mld->fwrt, &cmd.v10.per_chain[0][0][0],
|
||||
IWL_NUM_CHAIN_TABLES, IWL_NUM_SUB_BANDS_V2,
|
||||
prof_a, prof_b);
|
||||
/* return on error or if the profile is disabled (positive number) */
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return iwl_mld_send_cmd_pdu(mld, cmd_id, &cmd, len);
|
||||
return iwl_mld_send_cmd_pdu(mld, cmd_id, &cmd,
|
||||
sizeof(cmd.common) + sizeof(cmd.v10));
|
||||
}
|
||||
|
||||
int iwl_mld_init_sar(struct iwl_mld *mld)
|
||||
|
|
@ -238,34 +198,50 @@ void iwl_mld_configure_lari(struct iwl_mld *mld)
|
|||
struct iwl_lari_config_change_cmd cmd = {
|
||||
.config_bitmap = iwl_get_lari_config_bitmap(fwrt),
|
||||
};
|
||||
bool has_raw_dsm_capa = fw_has_capa(&fwrt->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE);
|
||||
int ret;
|
||||
u32 value;
|
||||
|
||||
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_11AX_ENABLEMENT, &value);
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
if (!has_raw_dsm_capa)
|
||||
value &= DSM_11AX_ALLOW_BITMAP;
|
||||
cmd.oem_11ax_allow_bitmap = cpu_to_le32(value);
|
||||
}
|
||||
|
||||
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_UNII4_CHAN, &value);
|
||||
if (!ret)
|
||||
cmd.oem_unii4_allow_bitmap =
|
||||
cpu_to_le32(value &= DSM_UNII4_ALLOW_BITMAP);
|
||||
if (!ret) {
|
||||
if (!has_raw_dsm_capa)
|
||||
value &= DSM_UNII4_ALLOW_BITMAP;
|
||||
cmd.oem_unii4_allow_bitmap = cpu_to_le32(value);
|
||||
}
|
||||
|
||||
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ACTIVATE_CHANNEL, &value);
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
if (!has_raw_dsm_capa)
|
||||
value &= CHAN_STATE_ACTIVE_BITMAP_CMD_V12;
|
||||
cmd.chan_state_active_bitmap = cpu_to_le32(value);
|
||||
}
|
||||
|
||||
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_6E, &value);
|
||||
if (!ret)
|
||||
cmd.oem_uhb_allow_bitmap = cpu_to_le32(value);
|
||||
|
||||
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_FORCE_DISABLE_CHANNELS, &value);
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
if (!has_raw_dsm_capa)
|
||||
value &= DSM_FORCE_DISABLE_CHANNELS_ALLOWED_BITMAP;
|
||||
cmd.force_disable_channels_bitmap = cpu_to_le32(value);
|
||||
}
|
||||
|
||||
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENERGY_DETECTION_THRESHOLD,
|
||||
&value);
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
if (!has_raw_dsm_capa)
|
||||
value &= DSM_EDT_ALLOWED_BITMAP;
|
||||
cmd.edt_bitmap = cpu_to_le32(value);
|
||||
}
|
||||
|
||||
ret = iwl_bios_get_wbem(fwrt, &value);
|
||||
if (!ret)
|
||||
|
|
|
|||
|
|
@ -143,7 +143,55 @@ void iwl_mld_pass_packet_to_mac80211(struct iwl_mld *mld,
|
|||
}
|
||||
EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_mld_pass_packet_to_mac80211);
|
||||
|
||||
static void iwl_mld_fill_signal(struct iwl_mld *mld,
|
||||
static bool iwl_mld_used_average_energy(struct iwl_mld *mld, int link_id,
|
||||
struct ieee80211_hdr *hdr,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct ieee80211_bss_conf *link_conf;
|
||||
struct iwl_mld_link *mld_link;
|
||||
|
||||
if (unlikely(!hdr || link_id < 0))
|
||||
return false;
|
||||
|
||||
if (likely(!ieee80211_is_beacon(hdr->frame_control)))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* if link ID is >= valid ones then that means the RX
|
||||
* was on the AUX link and no correction is needed
|
||||
*/
|
||||
if (link_id >= mld->fw->ucode_capa.num_links)
|
||||
return false;
|
||||
|
||||
/* for the link conf lookup */
|
||||
guard(rcu)();
|
||||
|
||||
link_conf = rcu_dereference(mld->fw_id_to_bss_conf[link_id]);
|
||||
if (!link_conf)
|
||||
return false;
|
||||
|
||||
mld_link = iwl_mld_link_from_mac80211(link_conf);
|
||||
if (!mld_link)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* If we know the link by link ID then the frame was
|
||||
* received for the link, so by filtering it means it
|
||||
* was from the AP the link is connected to.
|
||||
*/
|
||||
|
||||
/* skip also in case we don't have it (yet) */
|
||||
if (!mld_link->average_beacon_energy)
|
||||
return false;
|
||||
|
||||
IWL_DEBUG_STATS(mld, "energy override by average %d\n",
|
||||
mld_link->average_beacon_energy);
|
||||
rx_status->signal = -mld_link->average_beacon_energy;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void iwl_mld_fill_signal(struct iwl_mld *mld, int link_id,
|
||||
struct ieee80211_hdr *hdr,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
struct iwl_mld_rx_phy_data *phy_data)
|
||||
{
|
||||
|
|
@ -159,9 +207,11 @@ static void iwl_mld_fill_signal(struct iwl_mld *mld,
|
|||
IWL_DEBUG_STATS(mld, "energy in A %d B %d, and max %d\n",
|
||||
energy_a, energy_b, max_energy);
|
||||
|
||||
if (iwl_mld_used_average_energy(mld, link_id, hdr, rx_status))
|
||||
return;
|
||||
|
||||
rx_status->signal = max_energy;
|
||||
rx_status->chains =
|
||||
(rate_n_flags & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS;
|
||||
rx_status->chains = u32_get_bits(rate_n_flags, RATE_MCS_ANT_AB_MSK);
|
||||
rx_status->chain_signal[0] = energy_a;
|
||||
rx_status->chain_signal[1] = energy_b;
|
||||
}
|
||||
|
|
@ -1160,7 +1210,10 @@ static void iwl_mld_add_rtap_sniffer_config(struct iwl_mld *mld,
|
|||
}
|
||||
#endif
|
||||
|
||||
static void iwl_mld_rx_fill_status(struct iwl_mld *mld, struct sk_buff *skb,
|
||||
/* Note: hdr can be NULL */
|
||||
static void iwl_mld_rx_fill_status(struct iwl_mld *mld, int link_id,
|
||||
struct ieee80211_hdr *hdr,
|
||||
struct sk_buff *skb,
|
||||
struct iwl_mld_rx_phy_data *phy_data,
|
||||
int queue)
|
||||
{
|
||||
|
|
@ -1182,7 +1235,7 @@ static void iwl_mld_rx_fill_status(struct iwl_mld *mld, struct sk_buff *skb,
|
|||
phy_data->phy_info & IWL_RX_MPDU_PHY_SHORT_PREAMBLE)
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_SHORTPRE;
|
||||
|
||||
iwl_mld_fill_signal(mld, rx_status, phy_data);
|
||||
iwl_mld_fill_signal(mld, link_id, hdr, rx_status, phy_data);
|
||||
|
||||
/* This may be overridden by iwl_mld_rx_he() to HE_RU */
|
||||
switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) {
|
||||
|
|
@ -1733,7 +1786,7 @@ void iwl_mld_rx_mpdu(struct iwl_mld *mld, struct napi_struct *napi,
|
|||
struct sk_buff *skb;
|
||||
size_t mpdu_desc_size = sizeof(*mpdu_desc);
|
||||
bool drop = false;
|
||||
u8 crypto_len = 0, band;
|
||||
u8 crypto_len = 0, band, link_id;
|
||||
u32 pkt_len = iwl_rx_packet_payload_len(pkt);
|
||||
u32 mpdu_len;
|
||||
enum iwl_mld_reorder_result reorder_res;
|
||||
|
|
@ -1822,7 +1875,10 @@ void iwl_mld_rx_mpdu(struct iwl_mld *mld, struct napi_struct *napi,
|
|||
SCHED_SCAN_PASS_ALL_STATE_FOUND;
|
||||
}
|
||||
|
||||
iwl_mld_rx_fill_status(mld, skb, &phy_data, queue);
|
||||
link_id = u8_get_bits(mpdu_desc->mac_phy_band,
|
||||
IWL_RX_MPDU_MAC_PHY_BAND_LINK_MASK);
|
||||
|
||||
iwl_mld_rx_fill_status(mld, link_id, hdr, skb, &phy_data, queue);
|
||||
|
||||
if (iwl_mld_rx_crypto(mld, sta, hdr, rx_status, mpdu_desc, queue,
|
||||
le32_to_cpu(pkt->len_n_flags), &crypto_len))
|
||||
|
|
@ -2035,7 +2091,8 @@ void iwl_mld_rx_monitor_no_data(struct iwl_mld *mld, struct napi_struct *napi,
|
|||
rx_status->freq = ieee80211_channel_to_frequency(channel,
|
||||
rx_status->band);
|
||||
|
||||
iwl_mld_rx_fill_status(mld, skb, &phy_data, queue);
|
||||
/* link ID is ignored for NULL header */
|
||||
iwl_mld_rx_fill_status(mld, -1, NULL, skb, &phy_data, queue);
|
||||
|
||||
/* No more radiotap info should be added after this point.
|
||||
* Mark it as mac header for upper layers to know where
|
||||
|
|
|
|||
|
|
@ -359,7 +359,7 @@ iwl_mld_scan_fits(struct iwl_mld *mld, int n_ssids,
|
|||
struct ieee80211_scan_ies *ies, int n_channels)
|
||||
{
|
||||
return ((n_ssids <= PROBE_OPTION_MAX) &&
|
||||
(n_channels <= mld->fw->ucode_capa.n_scan_channels) &
|
||||
(n_channels <= mld->fw->ucode_capa.n_scan_channels) &&
|
||||
(ies->common_ie_len + ies->len[NL80211_BAND_2GHZ] +
|
||||
ies->len[NL80211_BAND_5GHZ] + ies->len[NL80211_BAND_6GHZ] <=
|
||||
iwl_mld_scan_max_template_size()));
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
iwlmld-tests-y += module.o hcmd.o utils.o link.o rx.o agg.o link-selection.o emlsr_with_bt.o
|
||||
iwlmld-tests-y += module.o hcmd.o utils.o link.o rx.o agg.o link-selection.o
|
||||
|
||||
ccflags-y += -I$(src)/../
|
||||
obj-$(CONFIG_IWLWIFI_KUNIT_TESTS) += iwlmld-tests.o
|
||||
|
|
|
|||
|
|
@ -1,140 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* KUnit tests for link selection functions
|
||||
*
|
||||
* Copyright (C) 2025 Intel Corporation
|
||||
*/
|
||||
#include <kunit/static_stub.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "mld.h"
|
||||
#include "mlo.h"
|
||||
|
||||
static const struct emlsr_with_bt_test_case {
|
||||
const char *desc;
|
||||
struct {
|
||||
struct iwl_bt_coex_profile_notif notif;
|
||||
s32 signal;
|
||||
bool check_entry;
|
||||
} input;
|
||||
bool emlsr_allowed;
|
||||
} emlsr_with_bt_cases[] = {
|
||||
{
|
||||
.desc = "BT penalty(exit) with low rssi 4.5: emlsr allowed",
|
||||
.input = {
|
||||
.notif.wifi_loss_low_rssi[1] = {4, 5},
|
||||
.notif.wifi_loss_mid_high_rssi[1] = {7, 9},
|
||||
.signal = -69,
|
||||
.check_entry = false,
|
||||
},
|
||||
.emlsr_allowed = true,
|
||||
},
|
||||
{
|
||||
.desc = "BT penalty(exit) from high rssi 5: emlsr allowed",
|
||||
.input = {
|
||||
.notif.wifi_loss_low_rssi[1] = {7, 9},
|
||||
.notif.wifi_loss_mid_high_rssi[1] = {5, 5},
|
||||
.signal = -68,
|
||||
.check_entry = false,
|
||||
},
|
||||
.emlsr_allowed = true,
|
||||
},
|
||||
{
|
||||
.desc = "BT penalty(exit) with low rssi 8: emlsr not allowed",
|
||||
.input = {
|
||||
.notif.wifi_loss_low_rssi[1] = {7, 9},
|
||||
.notif.wifi_loss_mid_high_rssi[1] = {4, 5},
|
||||
.signal = -69,
|
||||
.check_entry = false,
|
||||
},
|
||||
.emlsr_allowed = false,
|
||||
},
|
||||
{
|
||||
.desc = "BT penalty(exit) from high rssi 9: emlsr not allowed",
|
||||
.input = {
|
||||
.notif.wifi_loss_low_rssi[1] = {4, 5},
|
||||
.notif.wifi_loss_mid_high_rssi[1] = {9, 9},
|
||||
.signal = -68,
|
||||
.check_entry = false,
|
||||
},
|
||||
.emlsr_allowed = false,
|
||||
},
|
||||
{
|
||||
.desc = "BT penalty(entry) with low rssi 4.5: emlsr allowed",
|
||||
.input = {
|
||||
.notif.wifi_loss_low_rssi[1] = {4, 5},
|
||||
.notif.wifi_loss_mid_high_rssi[1] = {7, 9},
|
||||
.signal = -63,
|
||||
.check_entry = true,
|
||||
},
|
||||
.emlsr_allowed = true,
|
||||
},
|
||||
{
|
||||
.desc = "BT penalty(entry) from high rssi 5: emlsr allowed",
|
||||
.input = {
|
||||
.notif.wifi_loss_low_rssi[1] = {7, 9},
|
||||
.notif.wifi_loss_mid_high_rssi[1] = {5, 5},
|
||||
.signal = -62,
|
||||
.check_entry = false,
|
||||
},
|
||||
.emlsr_allowed = true,
|
||||
},
|
||||
{
|
||||
.desc = "BT penalty(entry) with low rssi 8: emlsr not allowed",
|
||||
.input = {
|
||||
.notif.wifi_loss_low_rssi[1] = {7, 9},
|
||||
.notif.wifi_loss_mid_high_rssi[1] = {4, 5},
|
||||
.signal = -63,
|
||||
.check_entry = false,
|
||||
},
|
||||
.emlsr_allowed = true,
|
||||
},
|
||||
{
|
||||
.desc = "BT penalty(entry) from high rssi 9: emlsr not allowed",
|
||||
.input = {
|
||||
.notif.wifi_loss_low_rssi[1] = {4, 5},
|
||||
.notif.wifi_loss_mid_high_rssi[1] = {9, 9},
|
||||
.signal = -62,
|
||||
.check_entry = true,
|
||||
},
|
||||
.emlsr_allowed = false,
|
||||
},
|
||||
};
|
||||
|
||||
KUNIT_ARRAY_PARAM_DESC(emlsr_with_bt, emlsr_with_bt_cases, desc);
|
||||
|
||||
static void test_emlsr_with_bt(struct kunit *test)
|
||||
{
|
||||
struct iwl_mld *mld = test->priv;
|
||||
const struct emlsr_with_bt_test_case *test_param =
|
||||
(const void *)(test->param_value);
|
||||
struct ieee80211_vif *vif =
|
||||
iwlmld_kunit_add_vif(true, NL80211_IFTYPE_STATION);
|
||||
struct ieee80211_bss_conf *link = iwlmld_kunit_add_link(vif, 1);
|
||||
bool actual_value = false;
|
||||
|
||||
KUNIT_ALLOC_AND_ASSERT(test, link->bss);
|
||||
|
||||
/* Extract test case parameters */
|
||||
link->bss->signal = DBM_TO_MBM(test_param->input.signal);
|
||||
memcpy(&mld->last_bt_notif, &test_param->input.notif,
|
||||
sizeof(struct iwl_bt_coex_profile_notif));
|
||||
|
||||
actual_value = iwl_mld_bt_allows_emlsr(mld, link,
|
||||
test_param->input.check_entry);
|
||||
/* Assert that the returned value matches the expected emlsr_allowed */
|
||||
KUNIT_EXPECT_EQ(test, actual_value, test_param->emlsr_allowed);
|
||||
}
|
||||
|
||||
static struct kunit_case emlsr_with_bt_test_cases[] = {
|
||||
KUNIT_CASE_PARAM(test_emlsr_with_bt, emlsr_with_bt_gen_params),
|
||||
{},
|
||||
};
|
||||
|
||||
static struct kunit_suite emlsr_with_bt = {
|
||||
.name = "iwlmld-emlsr-with-bt-tests",
|
||||
.test_cases = emlsr_with_bt_test_cases,
|
||||
.init = iwlmld_kunit_test_init,
|
||||
};
|
||||
|
||||
kunit_test_suite(emlsr_with_bt);
|
||||
|
|
@ -287,7 +287,6 @@ static void test_iwl_mld_link_pair_allows_emlsr(struct kunit *test)
|
|||
const struct link_pair_case *params = test->param_value;
|
||||
struct iwl_mld *mld = test->priv;
|
||||
struct ieee80211_vif *vif;
|
||||
struct ieee80211_bss_conf *link;
|
||||
/* link A is the primary and link B is the secondary */
|
||||
struct iwl_mld_link_sel_data a = {
|
||||
.chandef = params->chandef_a,
|
||||
|
|
@ -311,11 +310,6 @@ static void test_iwl_mld_link_pair_allows_emlsr(struct kunit *test)
|
|||
|
||||
wiphy_lock(mld->wiphy);
|
||||
|
||||
link = wiphy_dereference(mld->wiphy, vif->link_conf[a.link_id]);
|
||||
KUNIT_ALLOC_AND_ASSERT(test, link->bss);
|
||||
link = wiphy_dereference(mld->wiphy, vif->link_conf[b.link_id]);
|
||||
KUNIT_ALLOC_AND_ASSERT(test, link->bss);
|
||||
|
||||
/* Simulate channel load */
|
||||
if (params->primary_link_active) {
|
||||
struct iwl_mld_phy *phy =
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
|
|||
}
|
||||
|
||||
struct wowlan_key_rsc_tsc_data {
|
||||
struct iwl_wowlan_rsc_tsc_params_cmd_v4 *rsc_tsc;
|
||||
struct iwl_wowlan_rsc_tsc_params_cmd_ver_2 *rsc_tsc;
|
||||
bool have_rsc_tsc;
|
||||
};
|
||||
|
||||
|
|
@ -236,16 +236,16 @@ static void iwl_mvm_wowlan_get_rsc_tsc_data(struct ieee80211_hw *hw,
|
|||
u64 pn64;
|
||||
|
||||
tkip_sc =
|
||||
data->rsc_tsc->params.all_tsc_rsc.tkip.unicast_rsc;
|
||||
data->rsc_tsc->all_tsc_rsc.tkip.unicast_rsc;
|
||||
tkip_tx_sc =
|
||||
&data->rsc_tsc->params.all_tsc_rsc.tkip.tsc;
|
||||
&data->rsc_tsc->all_tsc_rsc.tkip.tsc;
|
||||
|
||||
pn64 = atomic64_read(&key->tx_pn);
|
||||
tkip_tx_sc->iv16 = cpu_to_le16(TKIP_PN_TO_IV16(pn64));
|
||||
tkip_tx_sc->iv32 = cpu_to_le32(TKIP_PN_TO_IV32(pn64));
|
||||
} else {
|
||||
tkip_sc =
|
||||
data->rsc_tsc->params.all_tsc_rsc.tkip.multicast_rsc;
|
||||
data->rsc_tsc->all_tsc_rsc.tkip.multicast_rsc;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -269,15 +269,15 @@ static void iwl_mvm_wowlan_get_rsc_tsc_data(struct ieee80211_hw *hw,
|
|||
u64 pn64;
|
||||
|
||||
aes_sc =
|
||||
data->rsc_tsc->params.all_tsc_rsc.aes.unicast_rsc;
|
||||
data->rsc_tsc->all_tsc_rsc.aes.unicast_rsc;
|
||||
aes_tx_sc =
|
||||
&data->rsc_tsc->params.all_tsc_rsc.aes.tsc;
|
||||
&data->rsc_tsc->all_tsc_rsc.aes.tsc;
|
||||
|
||||
pn64 = atomic64_read(&key->tx_pn);
|
||||
aes_tx_sc->pn = cpu_to_le64(pn64);
|
||||
} else {
|
||||
aes_sc =
|
||||
data->rsc_tsc->params.all_tsc_rsc.aes.multicast_rsc;
|
||||
data->rsc_tsc->all_tsc_rsc.aes.multicast_rsc;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -480,30 +480,21 @@ static int iwl_mvm_wowlan_config_rsc_tsc(struct iwl_mvm *mvm,
|
|||
else
|
||||
ret = 0;
|
||||
kfree(data.rsc);
|
||||
} else if (ver == 4 || ver == 2 || ver == IWL_FW_CMD_VER_UNKNOWN) {
|
||||
} else if (ver == 2 || ver == IWL_FW_CMD_VER_UNKNOWN) {
|
||||
struct wowlan_key_rsc_tsc_data data = {};
|
||||
int size;
|
||||
|
||||
data.rsc_tsc = kzalloc(sizeof(*data.rsc_tsc), GFP_KERNEL);
|
||||
if (!data.rsc_tsc)
|
||||
return -ENOMEM;
|
||||
|
||||
if (ver == 4) {
|
||||
size = sizeof(*data.rsc_tsc);
|
||||
data.rsc_tsc->sta_id =
|
||||
cpu_to_le32(mvm_link->ap_sta_id);
|
||||
} else {
|
||||
/* ver == 2 || ver == IWL_FW_CMD_VER_UNKNOWN */
|
||||
size = sizeof(data.rsc_tsc->params);
|
||||
}
|
||||
|
||||
ieee80211_iter_keys(mvm->hw, vif,
|
||||
iwl_mvm_wowlan_get_rsc_tsc_data,
|
||||
&data);
|
||||
|
||||
if (data.have_rsc_tsc)
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_TSC_RSC_PARAM,
|
||||
CMD_ASYNC, size,
|
||||
CMD_ASYNC,
|
||||
sizeof(data.rsc_tsc),
|
||||
data.rsc_tsc);
|
||||
else
|
||||
ret = 0;
|
||||
|
|
@ -1689,7 +1680,7 @@ static void iwl_mvm_set_aes_ptk_rx_seq(struct iwl_mvm *mvm,
|
|||
}
|
||||
|
||||
static void iwl_mvm_convert_key_counters(struct iwl_wowlan_status_data *status,
|
||||
union iwl_all_tsc_rsc *sc)
|
||||
union iwl_all_tsc_rsc *sc, u8 key_idx)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -1704,7 +1695,7 @@ static void iwl_mvm_convert_key_counters(struct iwl_wowlan_status_data *status,
|
|||
&status->gtk_seq[0].aes.seq[i]);
|
||||
}
|
||||
status->gtk_seq[0].valid = true;
|
||||
status->gtk_seq[0].key_id = -1;
|
||||
status->gtk_seq[0].key_id = key_idx;
|
||||
|
||||
/* PTK TX counter */
|
||||
status->ptk.tkip.tx_pn = (u64)le16_to_cpu(sc->tkip.tsc.iv16) |
|
||||
|
|
@ -1795,23 +1786,7 @@ static void iwl_mvm_set_key_rx_seq(struct ieee80211_key_conf *key,
|
|||
if (!status->gtk_seq[i].valid)
|
||||
continue;
|
||||
|
||||
/* Handle the case where we know the key ID */
|
||||
if (status->gtk_seq[i].key_id == key->keyidx) {
|
||||
s8 new_key_id = -1;
|
||||
|
||||
if (status->num_of_gtk_rekeys)
|
||||
new_key_id = status->gtk[0].flags &
|
||||
IWL_WOWLAN_GTK_IDX_MASK;
|
||||
|
||||
/* Don't install a new key's value to an old key */
|
||||
if (new_key_id != key->keyidx)
|
||||
iwl_mvm_set_key_rx_seq_idx(key, status, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* handle the case where we didn't, last key only */
|
||||
if (status->gtk_seq[i].key_id == -1 &&
|
||||
(!status->num_of_gtk_rekeys))
|
||||
if (status->gtk_seq[i].key_id == key->keyidx)
|
||||
iwl_mvm_set_key_rx_seq_idx(key, status, i);
|
||||
}
|
||||
}
|
||||
|
|
@ -1901,17 +1876,10 @@ iwl_mvm_d3_update_igtk_bigtk(struct iwl_wowlan_status_data *status,
|
|||
struct ieee80211_key_conf *key,
|
||||
struct iwl_multicast_key_data *key_data)
|
||||
{
|
||||
if (status->num_of_gtk_rekeys && key_data->len) {
|
||||
/* remove rekeyed key */
|
||||
ieee80211_remove_key(key);
|
||||
} else {
|
||||
struct ieee80211_key_seq seq;
|
||||
struct ieee80211_key_seq seq;
|
||||
|
||||
iwl_mvm_d3_set_igtk_bigtk_ipn(key_data,
|
||||
&seq,
|
||||
key->cipher);
|
||||
ieee80211_set_key_rx_seq(key, 0, &seq);
|
||||
}
|
||||
iwl_mvm_d3_set_igtk_bigtk_ipn(key_data, &seq, key->cipher);
|
||||
ieee80211_set_key_rx_seq(key, 0, &seq);
|
||||
}
|
||||
|
||||
static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
|
||||
|
|
@ -1952,18 +1920,13 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
|
|||
return;
|
||||
}
|
||||
keyidx = key->keyidx;
|
||||
/* The current key is always sent by the FW, even if it wasn't
|
||||
* rekeyed during D3.
|
||||
* We remove an existing key if it has the same index as
|
||||
* a new key
|
||||
/*
|
||||
* Update the seq even if there was a rekey. If there was a
|
||||
* rekey, we will update again after replacing the key
|
||||
*/
|
||||
if (status->num_of_gtk_rekeys &&
|
||||
((status->gtk[0].len && keyidx == status->gtk[0].id) ||
|
||||
(status->gtk[1].len && keyidx == status->gtk[1].id))) {
|
||||
ieee80211_remove_key(key);
|
||||
} else {
|
||||
iwl_mvm_set_key_rx_seq(key, data->status);
|
||||
}
|
||||
if ((status->gtk[0].len && keyidx == status->gtk[0].id) ||
|
||||
(status->gtk[1].len && keyidx == status->gtk[1].id))
|
||||
iwl_mvm_set_key_rx_seq(key, status);
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_BIP_GMAC_128:
|
||||
case WLAN_CIPHER_SUITE_BIP_GMAC_256:
|
||||
|
|
@ -2027,8 +1990,12 @@ static bool iwl_mvm_gtk_rekey(struct iwl_wowlan_status_data *status,
|
|||
sizeof(status->gtk[i].key));
|
||||
|
||||
key = ieee80211_gtk_rekey_add(vif, conf, link_id);
|
||||
if (IS_ERR(key))
|
||||
if (IS_ERR(key)) {
|
||||
/* FW may send also the old keys */
|
||||
if (PTR_ERR(key) == -EALREADY)
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(status->gtk_seq); j++) {
|
||||
if (!status->gtk_seq[j].valid ||
|
||||
|
|
@ -2048,14 +2015,16 @@ iwl_mvm_d3_igtk_bigtk_rekey_add(struct iwl_wowlan_status_data *status,
|
|||
struct ieee80211_vif *vif, u32 cipher,
|
||||
struct iwl_multicast_key_data *key_data)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
DEFINE_RAW_FLEX(struct ieee80211_key_conf, conf, key,
|
||||
WOWLAN_KEY_MAX_SIZE);
|
||||
struct ieee80211_key_conf *key_config;
|
||||
struct ieee80211_key_seq seq;
|
||||
int link_id = vif->active_links ? __ffs(vif->active_links) : -1;
|
||||
s8 keyidx = key_data->id;
|
||||
|
||||
conf->cipher = cipher;
|
||||
conf->keyidx = key_data->id;
|
||||
conf->keyidx = keyidx;
|
||||
|
||||
if (!key_data->len)
|
||||
return true;
|
||||
|
|
@ -2082,19 +2051,26 @@ iwl_mvm_d3_igtk_bigtk_rekey_add(struct iwl_wowlan_status_data *status,
|
|||
memcpy(conf->key, key_data->key, conf->keylen);
|
||||
|
||||
key_config = ieee80211_gtk_rekey_add(vif, conf, link_id);
|
||||
if (IS_ERR(key_config))
|
||||
return false;
|
||||
if (IS_ERR(key_config)) {
|
||||
/* FW may send also the old keys */
|
||||
return PTR_ERR(key_config) == -EALREADY;
|
||||
}
|
||||
ieee80211_set_key_rx_seq(key_config, 0, &seq);
|
||||
|
||||
if (key_config->keyidx == 4 || key_config->keyidx == 5) {
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
if (keyidx == 4 || keyidx == 5) {
|
||||
struct iwl_mvm_vif_link_info *mvm_link;
|
||||
|
||||
link_id = link_id < 0 ? 0 : link_id;
|
||||
mvm_link = mvmvif->link[link_id];
|
||||
if (mvm_link->igtk)
|
||||
mvm_link->igtk->hw_key_idx = STA_KEY_IDX_INVALID;
|
||||
mvm_link->igtk = key_config;
|
||||
}
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION && (keyidx == 6 || keyidx == 7))
|
||||
rcu_assign_pointer(mvmvif->bcn_prot.keys[keyidx - 6],
|
||||
key_config);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -2210,6 +2186,7 @@ static void iwl_mvm_convert_gtk_v2(struct iwl_wowlan_status_data *status,
|
|||
|
||||
status->gtk[0].len = data->key_len;
|
||||
status->gtk[0].flags = data->key_flags;
|
||||
status->gtk[0].id = status->gtk[0].flags & IWL_WOWLAN_GTK_IDX_MASK;
|
||||
|
||||
memcpy(status->gtk[0].key, data->key, sizeof(data->key));
|
||||
|
||||
|
|
@ -2380,8 +2357,8 @@ iwl_mvm_parse_wowlan_info_notif_v3(struct iwl_mvm *mvm,
|
|||
}
|
||||
|
||||
static void
|
||||
iwl_mvm_parse_wowlan_info_notif_v2(struct iwl_mvm *mvm,
|
||||
struct iwl_wowlan_info_notif_v2 *data,
|
||||
iwl_mvm_parse_wowlan_info_notif_v1(struct iwl_mvm *mvm,
|
||||
struct iwl_wowlan_info_notif_v1 *data,
|
||||
struct iwl_wowlan_status_data *status,
|
||||
u32 len)
|
||||
{
|
||||
|
|
@ -2466,8 +2443,6 @@ iwl_mvm_parse_wowlan_status_common_ ## _ver(struct iwl_mvm *mvm, \
|
|||
|
||||
iwl_mvm_parse_wowlan_status_common(v6)
|
||||
iwl_mvm_parse_wowlan_status_common(v7)
|
||||
iwl_mvm_parse_wowlan_status_common(v9)
|
||||
iwl_mvm_parse_wowlan_status_common(v12)
|
||||
|
||||
static struct iwl_wowlan_status_data *
|
||||
iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id)
|
||||
|
|
@ -2523,7 +2498,8 @@ iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id)
|
|||
v6->gtk.tkip_mic_key,
|
||||
sizeof(v6->gtk.tkip_mic_key));
|
||||
|
||||
iwl_mvm_convert_key_counters(status, &v6->gtk.rsc.all_tsc_rsc);
|
||||
iwl_mvm_convert_key_counters(status, &v6->gtk.rsc.all_tsc_rsc,
|
||||
v6->gtk.key_index);
|
||||
|
||||
/* hardcode the key length to 16 since v6 only supports 16 */
|
||||
status->gtk[0].len = 16;
|
||||
|
|
@ -2534,6 +2510,7 @@ iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id)
|
|||
* currently used key.
|
||||
*/
|
||||
status->gtk[0].flags = v6->gtk.key_index | BIT(7);
|
||||
status->gtk[0].id = v6->gtk.key_index;
|
||||
} else if (notif_ver == 7) {
|
||||
struct iwl_wowlan_status_v7 *v7 = (void *)cmd.resp_pkt->data;
|
||||
|
||||
|
|
@ -2541,36 +2518,10 @@ iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id)
|
|||
if (!status)
|
||||
goto out_free_resp;
|
||||
|
||||
iwl_mvm_convert_key_counters(status, &v7->gtk[0].rsc.all_tsc_rsc);
|
||||
iwl_mvm_convert_key_counters(status, &v7->gtk[0].rsc.all_tsc_rsc,
|
||||
v7->gtk[0].key_flags & IWL_WOWLAN_GTK_IDX_MASK);
|
||||
iwl_mvm_convert_gtk_v2(status, &v7->gtk[0]);
|
||||
iwl_mvm_convert_igtk(status, &v7->igtk[0]);
|
||||
} else if (notif_ver == 9 || notif_ver == 10 || notif_ver == 11) {
|
||||
struct iwl_wowlan_status_v9 *v9 = (void *)cmd.resp_pkt->data;
|
||||
|
||||
/* these three command versions have same layout and size, the
|
||||
* difference is only in a few not used (reserved) fields.
|
||||
*/
|
||||
status = iwl_mvm_parse_wowlan_status_common_v9(mvm, v9, len);
|
||||
if (!status)
|
||||
goto out_free_resp;
|
||||
|
||||
iwl_mvm_convert_key_counters(status, &v9->gtk[0].rsc.all_tsc_rsc);
|
||||
iwl_mvm_convert_gtk_v2(status, &v9->gtk[0]);
|
||||
iwl_mvm_convert_igtk(status, &v9->igtk[0]);
|
||||
|
||||
status->tid_tear_down = v9->tid_tear_down;
|
||||
} else if (notif_ver == 12) {
|
||||
struct iwl_wowlan_status_v12 *v12 = (void *)cmd.resp_pkt->data;
|
||||
|
||||
status = iwl_mvm_parse_wowlan_status_common_v12(mvm, v12, len);
|
||||
if (!status)
|
||||
goto out_free_resp;
|
||||
|
||||
iwl_mvm_convert_key_counters_v5(status, &v12->gtk[0].sc);
|
||||
iwl_mvm_convert_gtk_v3(status, v12->gtk);
|
||||
iwl_mvm_convert_igtk(status, &v12->igtk[0]);
|
||||
|
||||
status->tid_tear_down = v12->tid_tear_down;
|
||||
} else {
|
||||
IWL_ERR(mvm,
|
||||
"Firmware advertises unknown WoWLAN status response %d!\n",
|
||||
|
|
@ -3097,29 +3048,11 @@ static bool iwl_mvm_wait_d3_notif(struct iwl_notif_wait_data *notif_wait,
|
|||
break;
|
||||
}
|
||||
|
||||
if (wowlan_info_ver < 2) {
|
||||
if (wowlan_info_ver == 1) {
|
||||
struct iwl_wowlan_info_notif_v1 *notif_v1 =
|
||||
(void *)pkt->data;
|
||||
struct iwl_wowlan_info_notif_v2 *notif_v2;
|
||||
|
||||
notif_v2 = kmemdup(notif_v1, sizeof(*notif_v2), GFP_ATOMIC);
|
||||
|
||||
if (!notif_v2)
|
||||
return false;
|
||||
|
||||
notif_v2->tid_tear_down = notif_v1->tid_tear_down;
|
||||
notif_v2->station_id = notif_v1->station_id;
|
||||
memset_after(notif_v2, 0, station_id);
|
||||
iwl_mvm_parse_wowlan_info_notif_v2(mvm, notif_v2,
|
||||
d3_data->status,
|
||||
len);
|
||||
kfree(notif_v2);
|
||||
|
||||
} else if (wowlan_info_ver == 2) {
|
||||
struct iwl_wowlan_info_notif_v2 *notif_v2 =
|
||||
(void *)pkt->data;
|
||||
|
||||
iwl_mvm_parse_wowlan_info_notif_v2(mvm, notif_v2,
|
||||
iwl_mvm_parse_wowlan_info_notif_v1(mvm, notif_v1,
|
||||
d3_data->status,
|
||||
len);
|
||||
} else if (wowlan_info_ver == 3) {
|
||||
|
|
|
|||
|
|
@ -1134,7 +1134,7 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf,
|
|||
|
||||
if (count == 6 && !strcmp(buf, "nolog\n")) {
|
||||
set_bit(IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE, &mvm->status);
|
||||
set_bit(STATUS_SUPPRESS_CMD_ERROR_ONCE, &mvm->trans->status);
|
||||
iwl_trans_suppress_cmd_error_once(mvm->trans);
|
||||
}
|
||||
|
||||
/* take the return value to make compiler happy - it will fail anyway */
|
||||
|
|
|
|||
|
|
@ -121,6 +121,22 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
|
|||
return false;
|
||||
|
||||
palive = (void *)pkt->data;
|
||||
|
||||
umac = &palive->umac_data;
|
||||
lmac1 = &palive->lmac_data[0];
|
||||
lmac2 = &palive->lmac_data[1];
|
||||
status = le16_to_cpu(palive->status);
|
||||
|
||||
BUILD_BUG_ON(sizeof(palive->sku_id.data) !=
|
||||
sizeof(alive_data->sku_id));
|
||||
memcpy(alive_data->sku_id, palive->sku_id.data,
|
||||
sizeof(palive->sku_id.data));
|
||||
|
||||
IWL_DEBUG_FW(mvm, "Got sku_id: 0x0%x 0x0%x 0x0%x\n",
|
||||
le32_to_cpu(alive_data->sku_id[0]),
|
||||
le32_to_cpu(alive_data->sku_id[1]),
|
||||
le32_to_cpu(alive_data->sku_id[2]));
|
||||
|
||||
mvm->trans->dbg.imr_data.imr_enable =
|
||||
le32_to_cpu(palive->imr.enabled);
|
||||
mvm->trans->dbg.imr_data.imr_size =
|
||||
|
|
@ -168,40 +184,6 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
|
|||
IWL_DEBUG_FW(mvm, "platform id: 0x%llx\n",
|
||||
palive_v8->platform_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (version >= 5) {
|
||||
struct iwl_alive_ntf_v5 *palive;
|
||||
|
||||
if (pkt_len < sizeof(*palive))
|
||||
return false;
|
||||
|
||||
palive = (void *)pkt->data;
|
||||
umac = &palive->umac_data;
|
||||
lmac1 = &palive->lmac_data[0];
|
||||
lmac2 = &palive->lmac_data[1];
|
||||
status = le16_to_cpu(palive->status);
|
||||
|
||||
BUILD_BUG_ON(sizeof(palive->sku_id.data) !=
|
||||
sizeof(alive_data->sku_id));
|
||||
memcpy(alive_data->sku_id, palive->sku_id.data,
|
||||
sizeof(palive->sku_id.data));
|
||||
|
||||
IWL_DEBUG_FW(mvm, "Got sku_id: 0x0%x 0x0%x 0x0%x\n",
|
||||
le32_to_cpu(alive_data->sku_id[0]),
|
||||
le32_to_cpu(alive_data->sku_id[1]),
|
||||
le32_to_cpu(alive_data->sku_id[2]));
|
||||
} else if (iwl_rx_packet_payload_len(pkt) == sizeof(struct iwl_alive_ntf_v4)) {
|
||||
struct iwl_alive_ntf_v4 *palive;
|
||||
|
||||
if (pkt_len < sizeof(*palive))
|
||||
return false;
|
||||
|
||||
palive = (void *)pkt->data;
|
||||
umac = &palive->umac_data;
|
||||
lmac1 = &palive->lmac_data[0];
|
||||
lmac2 = &palive->lmac_data[1];
|
||||
status = le16_to_cpu(palive->status);
|
||||
} else if (iwl_rx_packet_payload_len(pkt) ==
|
||||
sizeof(struct iwl_alive_ntf_v3)) {
|
||||
struct iwl_alive_ntf_v3 *palive3;
|
||||
|
|
@ -888,17 +870,11 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
|
|||
len = sizeof(cmd_v9_v10.v9);
|
||||
n_subbands = IWL_NUM_SUB_BANDS_V1;
|
||||
per_chain = &cmd_v9_v10.v9.per_chain[0][0];
|
||||
} else if (cmd_ver >= 7) {
|
||||
len = sizeof(cmd.v7);
|
||||
} else if (cmd_ver == 8) {
|
||||
len = sizeof(cmd.v8);
|
||||
n_subbands = IWL_NUM_SUB_BANDS_V2;
|
||||
per_chain = cmd.v7.per_chain[0][0];
|
||||
cmd.v7.flags = cpu_to_le32(mvm->fwrt.reduced_power_flags);
|
||||
if (cmd_ver == 8)
|
||||
len = sizeof(cmd.v8);
|
||||
} else if (cmd_ver == 6) {
|
||||
len = sizeof(cmd.v6);
|
||||
n_subbands = IWL_NUM_SUB_BANDS_V2;
|
||||
per_chain = cmd.v6.per_chain[0][0];
|
||||
per_chain = cmd.v8.per_chain[0][0];
|
||||
cmd.v8.flags = cpu_to_le32(mvm->fwrt.reduced_power_flags);
|
||||
} else if (fw_has_api(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_API_REDUCE_TX_POWER)) {
|
||||
len = sizeof(cmd.v5);
|
||||
|
|
@ -1462,9 +1438,6 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
|||
RCU_INIT_POINTER(mvm->fw_id_to_link_sta[i], NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < IWL_FW_MAX_LINK_ID + 1; i++)
|
||||
RCU_INIT_POINTER(mvm->link_id_to_link_conf[i], NULL);
|
||||
|
||||
mvm->tdls_cs.peer.sta_id = IWL_INVALID_STA;
|
||||
|
||||
/* reset quota debouncing buffer - 0xff will yield invalid data */
|
||||
|
|
|
|||
|
|
@ -18,8 +18,7 @@
|
|||
HOW(EXIT_COEX) \
|
||||
HOW(EXIT_BANDWIDTH) \
|
||||
HOW(EXIT_CSA) \
|
||||
HOW(EXIT_LINK_USAGE) \
|
||||
HOW(EXIT_FAIL_ENTRY)
|
||||
HOW(EXIT_LINK_USAGE)
|
||||
|
||||
static const char *const iwl_mvm_esr_states_names[] = {
|
||||
#define NAME_ENTRY(x) [ilog2(IWL_MVM_ESR_##x)] = #x,
|
||||
|
|
@ -50,20 +49,6 @@ static void iwl_mvm_print_esr_state(struct iwl_mvm *mvm, u32 mask)
|
|||
#undef NAME_PR
|
||||
}
|
||||
|
||||
static u32 iwl_mvm_get_free_fw_link_id(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_vif *mvm_vif)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mvm->link_id_to_link_conf); i++)
|
||||
if (!rcu_access_pointer(mvm->link_id_to_link_conf[i]))
|
||||
return i;
|
||||
|
||||
return IWL_MVM_FW_LINK_ID_INVALID;
|
||||
}
|
||||
|
||||
static int iwl_mvm_link_cmd_send(struct iwl_mvm *mvm,
|
||||
struct iwl_link_config_cmd *cmd,
|
||||
enum iwl_ctxt_action action)
|
||||
|
|
@ -80,25 +65,15 @@ static int iwl_mvm_link_cmd_send(struct iwl_mvm *mvm,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int iwl_mvm_set_link_mapping(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *link_conf)
|
||||
void iwl_mvm_set_link_fw_id(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *link_conf)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_mvm_vif_link_info *link_info =
|
||||
mvmvif->link[link_conf->link_id];
|
||||
|
||||
if (link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID) {
|
||||
link_info->fw_link_id = iwl_mvm_get_free_fw_link_id(mvm,
|
||||
mvmvif);
|
||||
if (link_info->fw_link_id >=
|
||||
ARRAY_SIZE(mvm->link_id_to_link_conf))
|
||||
return -EINVAL;
|
||||
|
||||
rcu_assign_pointer(mvm->link_id_to_link_conf[link_info->fw_link_id],
|
||||
link_conf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID)
|
||||
link_info->fw_link_id = mvmvif->id;
|
||||
}
|
||||
|
||||
int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
|
|
@ -110,14 +85,11 @@ int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||
struct iwl_link_config_cmd cmd = {};
|
||||
unsigned int cmd_id = WIDE_ID(MAC_CONF_GROUP, LINK_CONFIG_CMD);
|
||||
u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, 1);
|
||||
int ret;
|
||||
|
||||
if (WARN_ON_ONCE(!link_info))
|
||||
return -EINVAL;
|
||||
|
||||
ret = iwl_mvm_set_link_mapping(mvm, vif, link_conf);
|
||||
if (ret)
|
||||
return ret;
|
||||
iwl_mvm_set_link_fw_id(mvm, vif, link_conf);
|
||||
|
||||
/* Update SF - Disable if needed. if this fails, SF might still be on
|
||||
* while many macs are bound, which is forbidden - so fail the binding.
|
||||
|
|
@ -374,24 +346,6 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int iwl_mvm_unset_link_mapping(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *link_conf)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_mvm_vif_link_info *link_info =
|
||||
mvmvif->link[link_conf->link_id];
|
||||
|
||||
/* mac80211 thought we have the link, but it was never configured */
|
||||
if (WARN_ON(!link_info ||
|
||||
link_info->fw_link_id >=
|
||||
ARRAY_SIZE(mvm->link_id_to_link_conf)))
|
||||
return -EINVAL;
|
||||
|
||||
RCU_INIT_POINTER(mvm->link_id_to_link_conf[link_info->fw_link_id],
|
||||
NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iwl_mvm_remove_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *link_conf)
|
||||
{
|
||||
|
|
@ -401,10 +355,6 @@ int iwl_mvm_remove_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||
struct iwl_link_config_cmd cmd = {};
|
||||
int ret;
|
||||
|
||||
ret = iwl_mvm_unset_link_mapping(mvm, vif, link_conf);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
cmd.link_id = cpu_to_le32(link_info->fw_link_id);
|
||||
link_info->fw_link_id = IWL_MVM_FW_LINK_ID_INVALID;
|
||||
cmd.spec_link_id = link_conf->link_id;
|
||||
|
|
|
|||
|
|
@ -1586,7 +1586,7 @@ iwl_mvm_handle_missed_beacons_notif(struct iwl_mvm *mvm,
|
|||
u32 id = le32_to_cpu(mb->link_id);
|
||||
union iwl_dbg_tlv_tp_data tp_data = { .fw_pkt = pkt };
|
||||
u32 mac_type;
|
||||
int link_id = -1;
|
||||
int link_id;
|
||||
u8 notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
|
||||
MISSED_BEACONS_NOTIFICATION,
|
||||
0);
|
||||
|
|
@ -1602,20 +1602,6 @@ iwl_mvm_handle_missed_beacons_notif(struct iwl_mvm *mvm,
|
|||
if (new_notif_ver)
|
||||
notif_ver = new_notif_ver;
|
||||
|
||||
/* before version four the ID in the notification refers to mac ID */
|
||||
if (notif_ver < 4) {
|
||||
vif = iwl_mvm_rcu_dereference_vif_id(mvm, id, false);
|
||||
bss_conf = &vif->bss_conf;
|
||||
} else {
|
||||
bss_conf = iwl_mvm_rcu_fw_link_id_to_link_conf(mvm, id, false);
|
||||
|
||||
if (!bss_conf)
|
||||
return;
|
||||
|
||||
vif = bss_conf->vif;
|
||||
link_id = bss_conf->link_id;
|
||||
}
|
||||
|
||||
IWL_DEBUG_INFO(mvm,
|
||||
"missed bcn %s_id=%u, consecutive=%u (%u)\n",
|
||||
notif_ver < 4 ? "mac" : "link",
|
||||
|
|
@ -1623,9 +1609,16 @@ iwl_mvm_handle_missed_beacons_notif(struct iwl_mvm *mvm,
|
|||
le32_to_cpu(mb->consec_missed_beacons),
|
||||
le32_to_cpu(mb->consec_missed_beacons_since_last_rx));
|
||||
|
||||
/*
|
||||
* starting from version 4 the ID is link ID, but driver
|
||||
* uses link ID == MAC ID, so always treat as MAC ID
|
||||
*/
|
||||
vif = iwl_mvm_rcu_dereference_vif_id(mvm, id, false);
|
||||
if (!vif)
|
||||
return;
|
||||
|
||||
bss_conf = &vif->bss_conf;
|
||||
link_id = bss_conf->link_id;
|
||||
mac_type = iwl_mvm_get_mac_type(vif);
|
||||
|
||||
IWL_DEBUG_INFO(mvm, "missed beacon mac_type=%u,\n", mac_type);
|
||||
|
|
@ -1875,16 +1868,15 @@ void iwl_mvm_channel_switch_start_notif(struct iwl_mvm *mvm,
|
|||
} else {
|
||||
struct iwl_channel_switch_start_notif *notif = (void *)pkt->data;
|
||||
u32 link_id = le32_to_cpu(notif->link_id);
|
||||
struct ieee80211_bss_conf *bss_conf =
|
||||
iwl_mvm_rcu_fw_link_id_to_link_conf(mvm, link_id, true);
|
||||
|
||||
if (!bss_conf)
|
||||
/* we use link ID == MAC ID */
|
||||
vif = iwl_mvm_rcu_dereference_vif_id(mvm, link_id, true);
|
||||
if (!vif)
|
||||
goto out_unlock;
|
||||
|
||||
id = link_id;
|
||||
mac_link_id = bss_conf->link_id;
|
||||
vif = bss_conf->vif;
|
||||
csa_active = bss_conf->csa_active;
|
||||
mac_link_id = vif->bss_conf.link_id;
|
||||
csa_active = vif->bss_conf.csa_active;
|
||||
}
|
||||
|
||||
mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
|
|
|
|||
|
|
@ -165,12 +165,6 @@ struct ieee80211_regdomain *iwl_mvm_get_regdomain(struct wiphy *wiphy,
|
|||
mvm->lar_regdom_set = true;
|
||||
mvm->mcc_src = src_id;
|
||||
|
||||
if (!iwl_puncturing_is_allowed_in_bios(mvm->bios_enable_puncturing,
|
||||
le16_to_cpu(resp->mcc)))
|
||||
ieee80211_hw_set(mvm->hw, DISALLOW_PUNCTURING);
|
||||
else
|
||||
__clear_bit(IEEE80211_HW_DISALLOW_PUNCTURING, mvm->hw->flags);
|
||||
|
||||
iwl_mei_set_country_code(__le16_to_cpu(resp->mcc));
|
||||
|
||||
out:
|
||||
|
|
@ -1521,10 +1515,6 @@ int iwl_mvm_set_tx_power(struct iwl_mvm *mvm,
|
|||
len = sizeof(cmd_v9_v10.v9);
|
||||
else if (cmd_ver == 8)
|
||||
len = sizeof(cmd.v8);
|
||||
else if (cmd_ver == 7)
|
||||
len = sizeof(cmd.v7);
|
||||
else if (cmd_ver == 6)
|
||||
len = sizeof(cmd.v6);
|
||||
else if (fw_has_api(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_API_REDUCE_TX_POWER))
|
||||
len = sizeof(cmd.v5);
|
||||
|
|
@ -1775,6 +1765,8 @@ void iwl_mvm_mac_init_mvmvif(struct iwl_mvm *mvm, struct iwl_mvm_vif *mvmvif)
|
|||
if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
|
||||
return;
|
||||
|
||||
mvmvif->deflink.average_beacon_energy = 0;
|
||||
|
||||
INIT_DELAYED_WORK(&mvmvif->csa_work,
|
||||
iwl_mvm_channel_switch_disconnect_wk);
|
||||
|
||||
|
|
@ -1812,9 +1804,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
|
|||
|
||||
vif->driver_flags = IEEE80211_VIF_REMOVE_AP_AFTER_DISASSOC;
|
||||
|
||||
ret = iwl_mvm_set_link_mapping(mvm, vif, &vif->bss_conf);
|
||||
if (ret)
|
||||
goto out;
|
||||
iwl_mvm_set_link_fw_id(mvm, vif, &vif->bss_conf);
|
||||
|
||||
/*
|
||||
* Not much to do here. The stack will not allow interface
|
||||
|
|
@ -2015,7 +2005,6 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
|
|||
mvm->monitor_on = false;
|
||||
|
||||
out:
|
||||
iwl_mvm_unset_link_mapping(mvm, vif, &vif->bss_conf);
|
||||
if (vif->type == NL80211_IFTYPE_AP ||
|
||||
vif->type == NL80211_IFTYPE_ADHOC) {
|
||||
iwl_mvm_dealloc_int_sta(mvm, &mvmvif->deflink.mcast_sta);
|
||||
|
|
@ -4618,6 +4607,10 @@ int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|||
{
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
|
||||
/* When resuming from wowlan, FW already knows about the newest keys */
|
||||
if (test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status))
|
||||
return 0;
|
||||
|
||||
guard(mvm)(mvm);
|
||||
return __iwl_mvm_mac_set_key(hw, cmd, vif, sta, key);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -304,6 +304,8 @@ struct iwl_probe_resp_data {
|
|||
* @mcast_sta: multicast station
|
||||
* @phy_ctxt: phy context allocated to this link, if any
|
||||
* @bf_data: beacon filtering data
|
||||
* @average_beacon_energy: average beacon energy for beacons received during
|
||||
* client connections
|
||||
*/
|
||||
struct iwl_mvm_vif_link_info {
|
||||
u8 bssid[ETH_ALEN];
|
||||
|
|
@ -342,6 +344,7 @@ struct iwl_mvm_vif_link_info {
|
|||
u16 mgmt_queue;
|
||||
|
||||
struct iwl_mvm_link_bf_data bf_data;
|
||||
u32 average_beacon_energy;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -374,7 +377,6 @@ struct iwl_mvm_vif_link_info {
|
|||
* preventing the enablement of EMLSR
|
||||
* @IWL_MVM_ESR_EXIT_CSA: CSA happened, so exit EMLSR
|
||||
* @IWL_MVM_ESR_EXIT_LINK_USAGE: Exit EMLSR due to low tpt on secondary link
|
||||
* @IWL_MVM_ESR_EXIT_FAIL_ENTRY: Exit EMLSR due to entry failure
|
||||
*/
|
||||
enum iwl_mvm_esr_state {
|
||||
IWL_MVM_ESR_BLOCKED_PREVENTION = 0x1,
|
||||
|
|
@ -390,7 +392,6 @@ enum iwl_mvm_esr_state {
|
|||
IWL_MVM_ESR_EXIT_BANDWIDTH = 0x80000,
|
||||
IWL_MVM_ESR_EXIT_CSA = 0x100000,
|
||||
IWL_MVM_ESR_EXIT_LINK_USAGE = 0x200000,
|
||||
IWL_MVM_ESR_EXIT_FAIL_ENTRY = 0x400000,
|
||||
};
|
||||
|
||||
#define IWL_MVM_BLOCK_ESR_REASONS 0xffff
|
||||
|
|
@ -1179,8 +1180,6 @@ struct iwl_mvm {
|
|||
|
||||
struct ieee80211_vif __rcu *vif_id_to_mac[NUM_MAC_INDEX_DRIVER];
|
||||
|
||||
struct ieee80211_bss_conf __rcu *link_id_to_link_conf[IWL_FW_MAX_LINK_ID + 1];
|
||||
|
||||
u8 *error_recovery_buf;
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_LEDS
|
||||
|
|
@ -1372,7 +1371,6 @@ struct iwl_mvm {
|
|||
struct iwl_mvm_acs_survey *acs_survey;
|
||||
|
||||
bool statistics_clear;
|
||||
u32 bios_enable_puncturing;
|
||||
};
|
||||
|
||||
/* Extract MVM priv from op_mode and _hw */
|
||||
|
|
@ -1488,20 +1486,6 @@ iwl_mvm_rcu_dereference_vif_id(struct iwl_mvm *mvm, u8 vif_id, bool rcu)
|
|||
lockdep_is_held(&mvm->mutex));
|
||||
}
|
||||
|
||||
static inline struct ieee80211_bss_conf *
|
||||
iwl_mvm_rcu_fw_link_id_to_link_conf(struct iwl_mvm *mvm, u8 link_id, bool rcu)
|
||||
{
|
||||
if (IWL_FW_CHECK(mvm, link_id >= ARRAY_SIZE(mvm->link_id_to_link_conf),
|
||||
"erroneous FW link ID: %d\n", link_id))
|
||||
return NULL;
|
||||
|
||||
if (rcu)
|
||||
return rcu_dereference(mvm->link_id_to_link_conf[link_id]);
|
||||
|
||||
return rcu_dereference_protected(mvm->link_id_to_link_conf[link_id],
|
||||
lockdep_is_held(&mvm->mutex));
|
||||
}
|
||||
|
||||
static inline bool iwl_mvm_is_adaptive_dwell_supported(struct iwl_mvm *mvm)
|
||||
{
|
||||
return fw_has_api(&mvm->fw->ucode_capa,
|
||||
|
|
@ -2093,6 +2077,9 @@ void iwl_mvm_channel_switch_start_notif(struct iwl_mvm *mvm,
|
|||
struct iwl_rx_cmd_buffer *rxb);
|
||||
void iwl_mvm_channel_switch_error_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb);
|
||||
void iwl_mvm_rx_beacon_filter_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb);
|
||||
|
||||
/* Bindings */
|
||||
int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
||||
int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
||||
|
|
@ -2100,15 +2087,13 @@ u32 iwl_mvm_get_lmac_id(struct iwl_mvm *mvm, enum nl80211_band band);
|
|||
|
||||
/* Links */
|
||||
void iwl_mvm_init_link(struct iwl_mvm_vif_link_info *link);
|
||||
int iwl_mvm_set_link_mapping(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *link_conf);
|
||||
void iwl_mvm_set_link_fw_id(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *link_conf);
|
||||
int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *link_conf);
|
||||
int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *link_conf,
|
||||
u32 changes, bool active);
|
||||
int iwl_mvm_unset_link_mapping(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *link_conf);
|
||||
int iwl_mvm_remove_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *link_conf);
|
||||
int iwl_mvm_disable_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
|
|
|
|||
|
|
@ -161,43 +161,6 @@ static void iwl_mvm_rx_esr_mode_notif(struct iwl_mvm *mvm,
|
|||
iwl_mvm_get_primary_link(vif));
|
||||
}
|
||||
|
||||
static void iwl_mvm_rx_esr_trans_fail_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb)
|
||||
{
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
struct iwl_esr_trans_fail_notif *notif = (void *)pkt->data;
|
||||
struct ieee80211_vif *vif = iwl_mvm_get_bss_vif(mvm);
|
||||
u8 fw_link_id = le32_to_cpu(notif->link_id);
|
||||
struct ieee80211_bss_conf *bss_conf;
|
||||
|
||||
if (IS_ERR_OR_NULL(vif))
|
||||
return;
|
||||
|
||||
IWL_DEBUG_INFO(mvm, "Failed to %s eSR on link %d, reason %d\n",
|
||||
le32_to_cpu(notif->activation) ? "enter" : "exit",
|
||||
le32_to_cpu(notif->link_id),
|
||||
le32_to_cpu(notif->err_code));
|
||||
|
||||
/* we couldn't go back to single link, disconnect */
|
||||
if (!le32_to_cpu(notif->activation)) {
|
||||
iwl_mvm_connection_loss(mvm, vif, "emlsr exit failed");
|
||||
return;
|
||||
}
|
||||
|
||||
bss_conf = iwl_mvm_rcu_fw_link_id_to_link_conf(mvm, fw_link_id, false);
|
||||
if (IWL_FW_CHECK(mvm, !bss_conf,
|
||||
"FW reported failure to activate EMLSR on a non-existing link: %d\n",
|
||||
fw_link_id))
|
||||
return;
|
||||
|
||||
/*
|
||||
* We failed to activate the second link and enter EMLSR, we need to go
|
||||
* back to single link.
|
||||
*/
|
||||
iwl_mvm_exit_esr(mvm, vif, IWL_MVM_ESR_EXIT_FAIL_ENTRY,
|
||||
bss_conf->link_id);
|
||||
}
|
||||
|
||||
static void iwl_mvm_rx_monitor_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb)
|
||||
{
|
||||
|
|
@ -526,10 +489,11 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
|
|||
RX_HANDLER_GRP(SCAN_GROUP, CHANNEL_SURVEY_NOTIF,
|
||||
iwl_mvm_rx_channel_survey_notif, RX_HANDLER_ASYNC_LOCKED,
|
||||
struct iwl_umac_scan_channel_survey_notif),
|
||||
RX_HANDLER_GRP(MAC_CONF_GROUP, EMLSR_TRANS_FAIL_NOTIF,
|
||||
iwl_mvm_rx_esr_trans_fail_notif,
|
||||
RX_HANDLER_ASYNC_LOCKED_WIPHY,
|
||||
struct iwl_esr_trans_fail_notif),
|
||||
RX_HANDLER_GRP(DATA_PATH_GROUP, BEACON_FILTER_IN_NOTIF,
|
||||
iwl_mvm_rx_beacon_filter_notif,
|
||||
RX_HANDLER_ASYNC_LOCKED,
|
||||
/* same size as v1 */
|
||||
struct iwl_beacon_filter_notif),
|
||||
};
|
||||
#undef RX_HANDLER
|
||||
#undef RX_HANDLER_GRP
|
||||
|
|
@ -660,7 +624,6 @@ static const struct iwl_hcmd_names iwl_mvm_mac_conf_names[] = {
|
|||
HCMD_NAME(STA_REMOVE_CMD),
|
||||
HCMD_NAME(STA_DISABLE_TX_CMD),
|
||||
HCMD_NAME(ROC_CMD),
|
||||
HCMD_NAME(EMLSR_TRANS_FAIL_NOTIF),
|
||||
HCMD_NAME(ROC_NOTIF),
|
||||
HCMD_NAME(CHANNEL_SWITCH_ERROR_NOTIF),
|
||||
HCMD_NAME(MISSED_VAP_NOTIF),
|
||||
|
|
@ -701,6 +664,7 @@ static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = {
|
|||
HCMD_NAME(ESR_MODE_NOTIF),
|
||||
HCMD_NAME(MONITOR_NOTIF),
|
||||
HCMD_NAME(THERMAL_DUAL_CHAIN_REQUEST),
|
||||
HCMD_NAME(BEACON_FILTER_IN_NOTIF),
|
||||
HCMD_NAME(STA_PM_NOTIF),
|
||||
HCMD_NAME(MU_GROUP_MGMT_NOTIF),
|
||||
HCMD_NAME(RX_QUEUES_NOTIFICATION),
|
||||
|
|
@ -1397,8 +1361,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg,
|
|||
}
|
||||
}
|
||||
|
||||
mvm->bios_enable_puncturing = iwl_uefi_get_puncturing(&mvm->fwrt);
|
||||
|
||||
if (iwl_mvm_has_new_tx_api(mvm)) {
|
||||
/*
|
||||
* If we have the new TX/queue allocation API initialize them
|
||||
|
|
@ -2055,7 +2017,7 @@ static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode,
|
|||
|
||||
if (type == IWL_ERR_TYPE_CMD_QUEUE_FULL)
|
||||
IWL_ERR(mvm, "Command queue full!\n");
|
||||
else if (!test_bit(STATUS_TRANS_DEAD, &mvm->trans->status) &&
|
||||
else if (!iwl_trans_is_dead(mvm->trans) &&
|
||||
!test_and_clear_bit(IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE,
|
||||
&mvm->status))
|
||||
iwl_mvm_dump_nic_error_log(mvm);
|
||||
|
|
@ -2157,6 +2119,17 @@ static void iwl_op_mode_mvm_time_point(struct iwl_op_mode *op_mode,
|
|||
iwl_dbg_tlv_time_point(&mvm->fwrt, tp_id, tp_data);
|
||||
}
|
||||
|
||||
static void iwl_mvm_dump(struct iwl_op_mode *op_mode)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
|
||||
struct iwl_fw_runtime *fwrt = &mvm->fwrt;
|
||||
|
||||
if (!iwl_trans_fw_running(fwrt->trans))
|
||||
return;
|
||||
|
||||
iwl_dbg_tlv_time_point(fwrt, IWL_FW_INI_TIME_POINT_USER_TRIGGER, NULL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static void iwl_op_mode_mvm_device_powered_off(struct iwl_op_mode *op_mode)
|
||||
{
|
||||
|
|
@ -2219,4 +2192,5 @@ static const struct iwl_op_mode_ops iwl_mvm_ops_mq = {
|
|||
IWL_MVM_COMMON_OPS,
|
||||
.rx = iwl_mvm_rx_mq,
|
||||
.rx_rss = iwl_mvm_rx_mq_rss,
|
||||
.dump = iwl_mvm_dump,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -877,28 +877,28 @@ iwl_mvm_stat_iterator_all_links(struct iwl_mvm *mvm,
|
|||
u32 rx_bytes[MAC_INDEX_AUX] = {};
|
||||
int fw_link_id;
|
||||
|
||||
for (fw_link_id = 0; fw_link_id < ARRAY_SIZE(mvm->link_id_to_link_conf);
|
||||
/* driver uses link ID == MAC ID */
|
||||
for (fw_link_id = 0; fw_link_id < ARRAY_SIZE(mvm->vif_id_to_mac);
|
||||
fw_link_id++) {
|
||||
struct iwl_stats_ntfy_per_link *link_stats;
|
||||
struct ieee80211_bss_conf *bss_conf;
|
||||
struct iwl_mvm_vif *mvmvif;
|
||||
struct iwl_mvm_vif_link_info *link_info;
|
||||
struct iwl_mvm_vif *mvmvif;
|
||||
struct ieee80211_vif *vif;
|
||||
int link_id;
|
||||
int sig;
|
||||
|
||||
bss_conf = iwl_mvm_rcu_fw_link_id_to_link_conf(mvm, fw_link_id,
|
||||
false);
|
||||
if (!bss_conf)
|
||||
vif = iwl_mvm_rcu_dereference_vif_id(mvm, fw_link_id, false);
|
||||
if (!vif)
|
||||
continue;
|
||||
|
||||
if (bss_conf->vif->type != NL80211_IFTYPE_STATION)
|
||||
if (vif->type != NL80211_IFTYPE_STATION)
|
||||
continue;
|
||||
|
||||
link_id = bss_conf->link_id;
|
||||
link_id = vif->bss_conf.link_id;
|
||||
if (link_id >= ARRAY_SIZE(mvmvif->link))
|
||||
continue;
|
||||
|
||||
mvmvif = iwl_mvm_vif_from_mac80211(bss_conf->vif);
|
||||
mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
link_info = mvmvif->link[link_id];
|
||||
if (!link_info)
|
||||
continue;
|
||||
|
|
@ -916,8 +916,7 @@ iwl_mvm_stat_iterator_all_links(struct iwl_mvm *mvm,
|
|||
|
||||
if (link_info->phy_ctxt &&
|
||||
link_info->phy_ctxt->channel->band == NL80211_BAND_2GHZ)
|
||||
iwl_mvm_bt_coex_update_link_esr(mvm, bss_conf->vif,
|
||||
link_id);
|
||||
iwl_mvm_bt_coex_update_link_esr(mvm, vif, link_id);
|
||||
|
||||
/* make sure that beacon statistics don't go backwards with TCM
|
||||
* request to clear statistics
|
||||
|
|
@ -927,8 +926,7 @@ iwl_mvm_stat_iterator_all_links(struct iwl_mvm *mvm,
|
|||
mvmvif->link[link_id]->beacon_stats.num_beacons;
|
||||
|
||||
sig = -le32_to_cpu(link_stats->beacon_filter_average_energy);
|
||||
iwl_mvm_update_link_sig(bss_conf->vif, sig, link_info,
|
||||
bss_conf);
|
||||
iwl_mvm_update_link_sig(vif, sig, link_info, &vif->bss_conf);
|
||||
|
||||
if (WARN_ONCE(mvmvif->id >= MAC_INDEX_AUX,
|
||||
"invalid mvmvif id: %d", mvmvif->id))
|
||||
|
|
|
|||
|
|
@ -246,13 +246,62 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm,
|
|||
ieee80211_rx_napi(mvm->hw, sta, skb, napi);
|
||||
}
|
||||
|
||||
static bool iwl_mvm_used_average_energy(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_mpdu_desc *desc,
|
||||
struct ieee80211_hdr *hdr,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct iwl_mvm_vif *mvm_vif;
|
||||
struct ieee80211_vif *vif;
|
||||
u32 id;
|
||||
|
||||
if (unlikely(!hdr || !desc))
|
||||
return false;
|
||||
|
||||
if (likely(!ieee80211_is_beacon(hdr->frame_control)))
|
||||
return false;
|
||||
|
||||
/* for the link conf lookup */
|
||||
guard(rcu)();
|
||||
|
||||
/* MAC or link ID depending on FW, but driver has them equal */
|
||||
id = u8_get_bits(desc->mac_phy_band,
|
||||
IWL_RX_MPDU_MAC_PHY_BAND_MAC_MASK);
|
||||
|
||||
/* >= means AUX MAC/link ID, no energy correction needed then */
|
||||
if (id >= ARRAY_SIZE(mvm->vif_id_to_mac))
|
||||
return false;
|
||||
|
||||
vif = iwl_mvm_rcu_dereference_vif_id(mvm, id, true);
|
||||
if (!vif)
|
||||
return false;
|
||||
|
||||
mvm_vif = iwl_mvm_vif_from_mac80211(vif);
|
||||
|
||||
/*
|
||||
* If we know the MAC by MAC or link ID then the frame was
|
||||
* received for the link, so by filtering it means it was
|
||||
* from the AP the link is connected to.
|
||||
*/
|
||||
|
||||
/* skip also in case we don't have it (yet) */
|
||||
if (!mvm_vif->deflink.average_beacon_energy)
|
||||
return false;
|
||||
|
||||
IWL_DEBUG_STATS(mvm, "energy override by average %d\n",
|
||||
mvm_vif->deflink.average_beacon_energy);
|
||||
rx_status->signal = -mvm_vif->deflink.average_beacon_energy;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_mpdu_desc *desc,
|
||||
struct ieee80211_hdr *hdr,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
u32 rate_n_flags, int energy_a,
|
||||
int energy_b)
|
||||
{
|
||||
int max_energy;
|
||||
u32 rate_flags = rate_n_flags;
|
||||
|
||||
energy_a = energy_a ? -energy_a : S8_MIN;
|
||||
energy_b = energy_b ? -energy_b : S8_MIN;
|
||||
|
|
@ -261,9 +310,11 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
|
|||
IWL_DEBUG_STATS(mvm, "energy In A %d B %d, and max %d\n",
|
||||
energy_a, energy_b, max_energy);
|
||||
|
||||
if (iwl_mvm_used_average_energy(mvm, desc, hdr, rx_status))
|
||||
return;
|
||||
|
||||
rx_status->signal = max_energy;
|
||||
rx_status->chains =
|
||||
(rate_flags & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS;
|
||||
rx_status->chains = u32_get_bits(rate_n_flags, RATE_MCS_ANT_AB_MSK);
|
||||
rx_status->chain_signal[0] = energy_a;
|
||||
rx_status->chain_signal[1] = energy_b;
|
||||
}
|
||||
|
|
@ -1906,8 +1957,11 @@ static void iwl_mvm_rx_get_sta_block_tx(void *data, struct ieee80211_sta *sta)
|
|||
/*
|
||||
* Note: requires also rx_status->band to be prefilled, as well
|
||||
* as phy_data (apart from phy_data->info_type)
|
||||
* Note: desc/hdr may be NULL
|
||||
*/
|
||||
static void iwl_mvm_rx_fill_status(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_mpdu_desc *desc,
|
||||
struct ieee80211_hdr *hdr,
|
||||
struct sk_buff *skb,
|
||||
struct iwl_mvm_rx_phy_data *phy_data,
|
||||
int queue)
|
||||
|
|
@ -1962,7 +2016,7 @@ static void iwl_mvm_rx_fill_status(struct iwl_mvm *mvm,
|
|||
|
||||
rx_status->freq = ieee80211_channel_to_frequency(phy_data->channel,
|
||||
rx_status->band);
|
||||
iwl_mvm_get_signal_strength(mvm, rx_status, rate_n_flags,
|
||||
iwl_mvm_get_signal_strength(mvm, desc, hdr, rx_status, rate_n_flags,
|
||||
phy_data->energy_a, phy_data->energy_b);
|
||||
|
||||
/* using TLV format and must be after all fixed len fields */
|
||||
|
|
@ -2215,7 +2269,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
|
|||
goto out;
|
||||
}
|
||||
|
||||
iwl_mvm_rx_fill_status(mvm, skb, &phy_data, queue);
|
||||
iwl_mvm_rx_fill_status(mvm, desc, hdr, skb, &phy_data, queue);
|
||||
|
||||
if (sta) {
|
||||
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
|
|
@ -2445,7 +2499,7 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi,
|
|||
rx_status->band = phy_data.channel > 14 ? NL80211_BAND_5GHZ :
|
||||
NL80211_BAND_2GHZ;
|
||||
|
||||
iwl_mvm_rx_fill_status(mvm, skb, &phy_data, queue);
|
||||
iwl_mvm_rx_fill_status(mvm, NULL, NULL, skb, &phy_data, queue);
|
||||
|
||||
/* no more radio tap info should be put after this point.
|
||||
*
|
||||
|
|
@ -2548,3 +2602,28 @@ void iwl_mvm_rx_bar_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi,
|
|||
out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
void iwl_mvm_rx_beacon_filter_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb)
|
||||
{
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
/* MAC or link ID in v1/v2, but driver has the IDs equal */
|
||||
struct iwl_beacon_filter_notif *notif = (void *)pkt->data;
|
||||
u32 id = le32_to_cpu(notif->link_id);
|
||||
struct iwl_mvm_vif *mvm_vif;
|
||||
struct ieee80211_vif *vif;
|
||||
|
||||
/* >= means AUX MAC/link ID, no energy correction needed then */
|
||||
if (IWL_FW_CHECK(mvm, id >= ARRAY_SIZE(mvm->vif_id_to_mac),
|
||||
"invalid link ID %d\n", id))
|
||||
return;
|
||||
|
||||
vif = iwl_mvm_rcu_dereference_vif_id(mvm, id, false);
|
||||
if (!vif)
|
||||
return;
|
||||
|
||||
mvm_vif = iwl_mvm_vif_from_mac80211(vif);
|
||||
|
||||
mvm_vif->deflink.average_beacon_energy =
|
||||
le32_to_cpu(notif->average_energy);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -836,7 +836,7 @@ static inline bool iwl_mvm_scan_fits(struct iwl_mvm *mvm, int n_ssids,
|
|||
int n_channels)
|
||||
{
|
||||
return ((n_ssids <= PROBE_OPTION_MAX) &&
|
||||
(n_channels <= mvm->fw->ucode_capa.n_scan_channels) &
|
||||
(n_channels <= mvm->fw->ucode_capa.n_scan_channels) &&
|
||||
(ies->common_ie_len +
|
||||
ies->len[NL80211_BAND_2GHZ] + ies->len[NL80211_BAND_5GHZ] +
|
||||
ies->len[NL80211_BAND_6GHZ] <=
|
||||
|
|
@ -3547,7 +3547,7 @@ int iwl_mvm_scan_stop(struct iwl_mvm *mvm, int type, bool notify)
|
|||
if (!(mvm->scan_status & type))
|
||||
return 0;
|
||||
|
||||
if (!test_bit(STATUS_DEVICE_ENABLED, &mvm->trans->status)) {
|
||||
if (!iwl_trans_device_enabled(mvm->trans)) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -958,40 +958,19 @@ void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm,
|
|||
{
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
struct iwl_session_prot_notif *notif = (void *)pkt->data;
|
||||
unsigned int ver =
|
||||
iwl_fw_lookup_notif_ver(mvm->fw, MAC_CONF_GROUP,
|
||||
SESSION_PROTECTION_NOTIF, 2);
|
||||
int id = le32_to_cpu(notif->mac_link_id);
|
||||
struct ieee80211_vif *vif;
|
||||
struct iwl_mvm_vif *mvmvif;
|
||||
unsigned int notif_link_id;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
if (ver <= 2) {
|
||||
vif = iwl_mvm_rcu_dereference_vif_id(mvm, id, true);
|
||||
} else {
|
||||
struct ieee80211_bss_conf *link_conf =
|
||||
iwl_mvm_rcu_fw_link_id_to_link_conf(mvm, id, true);
|
||||
|
||||
if (!link_conf)
|
||||
goto out_unlock;
|
||||
|
||||
notif_link_id = link_conf->link_id;
|
||||
vif = link_conf->vif;
|
||||
}
|
||||
|
||||
/* note we use link ID == MAC ID */
|
||||
vif = iwl_mvm_rcu_dereference_vif_id(mvm, id, true);
|
||||
if (!vif)
|
||||
goto out_unlock;
|
||||
|
||||
mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
|
||||
if (WARN(ver > 2 && mvmvif->time_event_data.link_id >= 0 &&
|
||||
mvmvif->time_event_data.link_id != notif_link_id,
|
||||
"SESSION_PROTECTION_NOTIF was received for link %u, while the current time event is on link %u\n",
|
||||
notif_link_id, mvmvif->time_event_data.link_id))
|
||||
goto out_unlock;
|
||||
|
||||
/* The vif is not a P2P_DEVICE, maintain its time_event_data */
|
||||
if (vif->type != NL80211_IFTYPE_P2P_DEVICE) {
|
||||
struct iwl_mvm_time_event_data *te_data =
|
||||
|
|
|
|||
|
|
@ -501,7 +501,7 @@ VISIBLE_IF_IWLWIFI_KUNIT const struct pci_device_id iwl_hw_card_ids[] = {
|
|||
{IWL_PCI_DEVICE(0x2729, PCI_ANY_ID, iwl_ma_mac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x7E40, PCI_ANY_ID, iwl_ma_mac_cfg)},
|
||||
#endif /* CONFIG_IWLMVM */
|
||||
#if IS_ENABLED(CONFIG_IWLMLD)
|
||||
#if IS_ENABLED(CONFIG_IWLMVM) || IS_ENABLED(CONFIG_IWLMLD)
|
||||
/* Bz devices */
|
||||
{IWL_PCI_DEVICE(0x272b, PCI_ANY_ID, iwl_gl_mac_cfg)},
|
||||
{IWL_PCI_DEVICE(0xA840, 0x0000, iwl_bz_mac_cfg)},
|
||||
|
|
@ -546,7 +546,7 @@ VISIBLE_IF_IWLWIFI_KUNIT const struct pci_device_id iwl_hw_card_ids[] = {
|
|||
{IWL_PCI_DEVICE(0xD340, PCI_ANY_ID, iwl_sc_mac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x6E70, PCI_ANY_ID, iwl_sc_mac_cfg)},
|
||||
{IWL_PCI_DEVICE(0xD240, PCI_ANY_ID, iwl_sc_mac_cfg)},
|
||||
#endif /* CONFIG_IWLMLD */
|
||||
#endif /* CONFIG_IWLMVM || CONFIG_IWLMLD */
|
||||
|
||||
{0}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1091,6 +1091,7 @@ int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
|
|||
void iwl_trans_pcie_stop_device(struct iwl_trans *trans);
|
||||
|
||||
/* common functions that are used by gen2 transport */
|
||||
void iwl_trans_pcie_gen2_op_mode_leave(struct iwl_trans *trans);
|
||||
int iwl_pcie_gen2_apm_init(struct iwl_trans *trans);
|
||||
void iwl_pcie_apm_config(struct iwl_trans *trans);
|
||||
int iwl_pcie_prepare_card_hw(struct iwl_trans *trans);
|
||||
|
|
|
|||
|
|
@ -630,3 +630,23 @@ int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans,
|
|||
mutex_unlock(&trans_pcie->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void iwl_trans_pcie_gen2_op_mode_leave(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
mutex_lock(&trans_pcie->mutex);
|
||||
|
||||
/* disable interrupts - don't enable HW RF kill interrupt */
|
||||
iwl_disable_interrupts(trans);
|
||||
|
||||
iwl_pcie_gen2_apm_stop(trans, true);
|
||||
|
||||
iwl_disable_interrupts(trans);
|
||||
|
||||
iwl_pcie_disable_ict(trans);
|
||||
|
||||
mutex_unlock(&trans_pcie->mutex);
|
||||
|
||||
iwl_pcie_synchronize_irqs(trans);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -392,7 +392,7 @@ void iwl_pcie_apm_stop_master(struct iwl_trans *trans)
|
|||
CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
if (ret)
|
||||
IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n");
|
||||
|
||||
IWL_DEBUG_INFO(trans, "stop master\n");
|
||||
|
|
@ -495,10 +495,10 @@ static int iwl_pcie_set_hw_ready(struct iwl_trans *trans)
|
|||
CSR_HW_IF_CONFIG_REG_PCI_OWN_SET,
|
||||
HW_READY_TIMEOUT);
|
||||
|
||||
if (ret >= 0)
|
||||
if (!ret)
|
||||
iwl_set_bit(trans, CSR_MBOX_SET_REG, CSR_MBOX_SET_REG_OS_ALIVE);
|
||||
|
||||
IWL_DEBUG_INFO(trans, "hardware%s ready\n", ret < 0 ? " not" : "");
|
||||
IWL_DEBUG_INFO(trans, "hardware%s ready\n", ret ? " not" : "");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -512,7 +512,7 @@ int iwl_pcie_prepare_card_hw(struct iwl_trans *trans)
|
|||
|
||||
ret = iwl_pcie_set_hw_ready(trans);
|
||||
/* If the card is ready, exit 0 */
|
||||
if (ret >= 0) {
|
||||
if (!ret) {
|
||||
trans->csme_own = false;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -530,7 +530,7 @@ int iwl_pcie_prepare_card_hw(struct iwl_trans *trans)
|
|||
|
||||
do {
|
||||
ret = iwl_pcie_set_hw_ready(trans);
|
||||
if (ret >= 0) {
|
||||
if (!ret) {
|
||||
trans->csme_own = false;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2353,7 +2353,7 @@ bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent)
|
|||
* and do not save/restore SRAM when power cycling.
|
||||
*/
|
||||
ret = iwl_poll_bits_mask(trans, CSR_GP_CNTRL, poll, mask, 15000);
|
||||
if (unlikely(ret < 0)) {
|
||||
if (unlikely(ret)) {
|
||||
u32 cntrl = iwl_read32(trans, CSR_GP_CNTRL);
|
||||
|
||||
if (silent) {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "iwl-op-mode.h"
|
||||
#include "internal.h"
|
||||
#include "fw/api/tx.h"
|
||||
#include "fw/dbg.h"
|
||||
#include "pcie/utils.h"
|
||||
|
||||
/*************** DMA-QUEUE-GENERAL-FUNCTIONS *****
|
||||
|
|
@ -591,7 +592,7 @@ static void iwl_pcie_tx_stop_fh(struct iwl_trans *trans)
|
|||
|
||||
/* Wait for DMA channels to be idle */
|
||||
ret = iwl_poll_bits(trans, FH_TSSR_TX_STATUS_REG, mask, 5000);
|
||||
if (ret < 0)
|
||||
if (ret)
|
||||
IWL_ERR(trans,
|
||||
"Failing on timeout while stopping DMA channel %d [0x%08x]\n",
|
||||
ch, iwl_read32(trans, FH_TSSR_TX_STATUS_REG));
|
||||
|
|
@ -1638,13 +1639,11 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
|
|||
/* If a Tx command is being handled and it isn't in the actual
|
||||
* command queue then there a command routing bug has been introduced
|
||||
* in the queue management code. */
|
||||
if (WARN(txq_id != trans->conf.cmd_queue,
|
||||
"wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n",
|
||||
txq_id, trans->conf.cmd_queue, sequence, txq->read_ptr,
|
||||
txq->write_ptr)) {
|
||||
iwl_print_hex_error(trans, pkt, 32);
|
||||
if (IWL_FW_CHECK(trans, txq_id != trans->conf.cmd_queue,
|
||||
"wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d pkt=%*phN\n",
|
||||
txq_id, trans->conf.cmd_queue, sequence, txq->read_ptr,
|
||||
txq->write_ptr, 32, pkt))
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_bh(&txq->lock);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
#ifndef __iwl_pcie_utils_h__
|
||||
#define __iwl_pcie_utils_h__
|
||||
|
||||
#include "iwl-io.h"
|
||||
|
||||
void iwl_trans_pcie_dump_regs(struct iwl_trans *trans, struct pci_dev *pdev);
|
||||
|
||||
static inline void _iwl_trans_set_bits_mask(struct iwl_trans *trans,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user