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:
Johannes Berg 2025-07-15 13:20:51 +02:00
commit 003322be55
66 changed files with 793 additions and 1218 deletions

View File

@ -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

View File

@ -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));

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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));

View File

@ -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));

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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

View File

@ -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__ */

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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__ */

View File

@ -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;
}

View File

@ -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");
}

View File

@ -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;

View File

@ -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

View File

@ -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)

View File

@ -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),

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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
*****************************************************/

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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__ */

View File

@ -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);

View File

@ -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");

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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)
};

View File

@ -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);
}

View File

@ -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)

View File

@ -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

View File

@ -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()));

View File

@ -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

View File

@ -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);

View File

@ -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 =

View File

@ -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) {

View File

@ -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 */

View File

@ -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 */

View File

@ -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;

View File

@ -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);

View File

@ -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);
}

View File

@ -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,

View File

@ -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,
};

View File

@ -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))

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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 =

View File

@ -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}
};

View File

@ -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);

View File

@ -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);
}

View File

@ -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) {

View File

@ -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);

View File

@ -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,