diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi')
162 files changed, 6550 insertions, 5645 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/Makefile b/drivers/net/wireless/intel/iwlwifi/Makefile index 9546ceeaf5e3..3f476e333726 100644 --- a/drivers/net/wireless/intel/iwlwifi/Makefile +++ b/drivers/net/wireless/intel/iwlwifi/Makefile @@ -8,12 +8,23 @@ iwlwifi-objs += iwl-nvm-utils.o iwlwifi-objs += iwl-utils.o iwlwifi-objs += iwl-phy-db.o iwl-nvm-parse.o iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o -iwlwifi-objs += pcie/ctxt-info.o pcie/ctxt-info-gen3.o +iwlwifi-objs += pcie/ctxt-info.o pcie/ctxt-info-v2.o iwlwifi-objs += pcie/trans-gen2.o pcie/tx-gen2.o -iwlwifi-$(CONFIG_IWLDVM) += cfg/1000.o cfg/2000.o cfg/5000.o cfg/6000.o -iwlwifi-$(CONFIG_IWLMVM) += cfg/7000.o cfg/8000.o cfg/9000.o cfg/22000.o + +CFLAGS_pcie/drv.o += -Wno-override-init + +# combined MAC/RF configurations +iwlwifi-$(CONFIG_IWLDVM) += cfg/1000.o cfg/2000.o +iwlwifi-$(CONFIG_IWLDVM) += cfg/5000.o cfg/6000.o +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_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 +iwlwifi-$(CONFIG_IWLMLD) += cfg/rf-fm.o cfg/rf-wh.o cfg/rf-pe.o + iwlwifi-objs += iwl-dbg-tlv.o iwlwifi-objs += iwl-trans.o diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c index f172ffd2a841..c029e595e7c2 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2018 - 2020, 2023 Intel Corporation + * Copyright(c) 2018 - 2020, 2023, 2025 Intel Corporation *****************************************************************************/ #include <linux/module.h> @@ -29,7 +29,7 @@ #define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE "-" __stringify(api) ".ucode" -static const struct iwl_base_params iwl1000_base_params = { +static const struct iwl_family_base_params iwl1000_base = { .num_of_queues = IWLAGN_NUM_QUEUES, .max_tfd_queue_size = 256, .eeprom_size = OTP_LOW_IMAGE_SIZE_2K, @@ -42,12 +42,6 @@ static const struct iwl_base_params iwl1000_base_params = { .scd_chain_ext_wa = true, }; -static const struct iwl_ht_params iwl1000_ht_params = { - .ht_greenfield_support = true, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .ht40_bands = BIT(NL80211_BAND_2GHZ), -}; - static const struct iwl_eeprom_params iwl1000_eeprom_params = { .regulatory_bands = { EEPROM_REG_BAND_1_CHANNELS, @@ -60,54 +54,67 @@ static const struct iwl_eeprom_params iwl1000_eeprom_params = { } }; +const struct iwl_mac_cfg iwl1000_mac_cfg = { + .device_family = IWL_DEVICE_FAMILY_1000, + .base = &iwl1000_base, +}; + #define IWL_DEVICE_1000 \ .fw_name_pre = IWL1000_FW_PRE, \ .ucode_api_max = IWL1000_UCODE_API_MAX, \ .ucode_api_min = IWL1000_UCODE_API_MIN, \ - .trans.device_family = IWL_DEVICE_FAMILY_1000, \ .max_inst_size = IWLAGN_RTC_INST_SIZE, \ .max_data_size = IWLAGN_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_1000_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ - .trans.base_params = &iwl1000_base_params, \ .eeprom_params = &iwl1000_eeprom_params, \ .led_mode = IWL_LED_BLINK -const struct iwl_cfg iwl1000_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN", +const struct iwl_rf_cfg iwl1000_bgn_cfg = { IWL_DEVICE_1000, - .ht_params = &iwl1000_ht_params, + .ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(NL80211_BAND_2GHZ), + }, }; -const struct iwl_cfg iwl1000_bg_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 1000 BG", +const char iwl1000_bgn_name[] = "Intel(R) Centrino(R) Wireless-N 1000 BGN"; + +const struct iwl_rf_cfg iwl1000_bg_cfg = { IWL_DEVICE_1000, }; +const char iwl1000_bg_name[] = "Intel(R) Centrino(R) Wireless-N 1000 BG"; + #define IWL_DEVICE_100 \ .fw_name_pre = IWL100_FW_PRE, \ .ucode_api_max = IWL100_UCODE_API_MAX, \ .ucode_api_min = IWL100_UCODE_API_MIN, \ - .trans.device_family = IWL_DEVICE_FAMILY_100, \ .max_inst_size = IWLAGN_RTC_INST_SIZE, \ .max_data_size = IWLAGN_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_1000_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ - .trans.base_params = &iwl1000_base_params, \ .eeprom_params = &iwl1000_eeprom_params, \ .led_mode = IWL_LED_RF_STATE, \ .rx_with_siso_diversity = true -const struct iwl_cfg iwl100_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 100 BGN", +const struct iwl_rf_cfg iwl100_bgn_cfg = { IWL_DEVICE_100, - .ht_params = &iwl1000_ht_params, + .ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(NL80211_BAND_2GHZ), + }, }; -const struct iwl_cfg iwl100_bg_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 100 BG", +const char iwl100_bgn_name[] = "Intel(R) Centrino(R) Wireless-N 100 BGN"; + +const struct iwl_rf_cfg iwl100_bg_cfg = { IWL_DEVICE_100, }; +const char iwl100_bg_name[] = "Intel(R) Centrino(R) Wireless-N 100 BG"; + MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_MAX)); diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c index 6f3f26da0ad5..47554a5f406e 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2018 - 2020, 2023 Intel Corporation + * Copyright(c) 2018 - 2020, 2023, 2025 Intel Corporation *****************************************************************************/ #include <linux/module.h> @@ -40,7 +40,7 @@ #define IWL135_FW_PRE "iwlwifi-135" #define IWL135_MODULE_FIRMWARE(api) IWL135_FW_PRE "-" __stringify(api) ".ucode" -static const struct iwl_base_params iwl2000_base_params = { +static const struct iwl_family_base_params iwl2000_base = { .eeprom_size = OTP_LOW_IMAGE_SIZE_2K, .num_of_queues = IWLAGN_NUM_QUEUES, .max_tfd_queue_size = 256, @@ -54,7 +54,7 @@ static const struct iwl_base_params iwl2000_base_params = { }; -static const struct iwl_base_params iwl2030_base_params = { +static const struct iwl_family_base_params iwl2030_base = { .eeprom_size = OTP_LOW_IMAGE_SIZE_2K, .num_of_queues = IWLAGN_NUM_QUEUES, .max_tfd_queue_size = 256, @@ -67,12 +67,6 @@ static const struct iwl_base_params iwl2030_base_params = { .scd_chain_ext_wa = true, }; -static const struct iwl_ht_params iwl2000_ht_params = { - .ht_greenfield_support = true, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .ht40_bands = BIT(NL80211_BAND_2GHZ), -}; - static const struct iwl_eeprom_params iwl20x0_eeprom_params = { .regulatory_bands = { EEPROM_REG_BAND_1_CHANNELS, @@ -86,97 +80,119 @@ static const struct iwl_eeprom_params iwl20x0_eeprom_params = { .enhanced_txpower = true, }; +const struct iwl_mac_cfg iwl2000_mac_cfg = { + .device_family = IWL_DEVICE_FAMILY_2000, + .base = &iwl2000_base, +}; + #define IWL_DEVICE_2000 \ .fw_name_pre = IWL2000_FW_PRE, \ .ucode_api_max = IWL2000_UCODE_API_MAX, \ .ucode_api_min = IWL2000_UCODE_API_MIN, \ - .trans.device_family = IWL_DEVICE_FAMILY_2000, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ - .trans.base_params = &iwl2000_base_params, \ .eeprom_params = &iwl20x0_eeprom_params, \ .led_mode = IWL_LED_RF_STATE -const struct iwl_cfg iwl2000_2bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 2200 BGN", +const struct iwl_rf_cfg iwl2000_2bgn_cfg = { IWL_DEVICE_2000, - .ht_params = &iwl2000_ht_params, + .ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(NL80211_BAND_2GHZ), + }, }; -const struct iwl_cfg iwl2000_2bgn_d_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 2200D BGN", - IWL_DEVICE_2000, - .ht_params = &iwl2000_ht_params, +const char iwl2000_2bgn_name[] = "Intel(R) Centrino(R) Wireless-N 2200 BGN"; +const char iwl2000_2bgn_d_name[] = "Intel(R) Centrino(R) Wireless-N 2200D BGN"; + +const struct iwl_mac_cfg iwl2030_mac_cfg = { + .device_family = IWL_DEVICE_FAMILY_2030, + .base = &iwl2030_base, }; #define IWL_DEVICE_2030 \ .fw_name_pre = IWL2030_FW_PRE, \ .ucode_api_max = IWL2030_UCODE_API_MAX, \ .ucode_api_min = IWL2030_UCODE_API_MIN, \ - .trans.device_family = IWL_DEVICE_FAMILY_2030, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ - .trans.base_params = &iwl2030_base_params, \ .eeprom_params = &iwl20x0_eeprom_params, \ .led_mode = IWL_LED_RF_STATE -const struct iwl_cfg iwl2030_2bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN", +const struct iwl_rf_cfg iwl2030_2bgn_cfg = { IWL_DEVICE_2030, - .ht_params = &iwl2000_ht_params, + .ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(NL80211_BAND_2GHZ), + }, +}; + +const char iwl2030_2bgn_name[] = "Intel(R) Centrino(R) Wireless-N 2230 BGN"; + +const struct iwl_mac_cfg iwl105_mac_cfg = { + .device_family = IWL_DEVICE_FAMILY_105, + .base = &iwl2000_base, }; #define IWL_DEVICE_105 \ .fw_name_pre = IWL105_FW_PRE, \ .ucode_api_max = IWL105_UCODE_API_MAX, \ .ucode_api_min = IWL105_UCODE_API_MIN, \ - .trans.device_family = IWL_DEVICE_FAMILY_105, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ - .trans.base_params = &iwl2000_base_params, \ .eeprom_params = &iwl20x0_eeprom_params, \ .led_mode = IWL_LED_RF_STATE, \ .rx_with_siso_diversity = true -const struct iwl_cfg iwl105_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 105 BGN", +const struct iwl_rf_cfg iwl105_bgn_cfg = { IWL_DEVICE_105, - .ht_params = &iwl2000_ht_params, + .ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(NL80211_BAND_2GHZ), + }, }; -const struct iwl_cfg iwl105_bgn_d_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 105D BGN", - IWL_DEVICE_105, - .ht_params = &iwl2000_ht_params, +const char iwl105_bgn_name[] = "Intel(R) Centrino(R) Wireless-N 105 BGN"; +const char iwl105_bgn_d_name[] = "Intel(R) Centrino(R) Wireless-N 105D BGN"; + +const struct iwl_mac_cfg iwl135_mac_cfg = { + .device_family = IWL_DEVICE_FAMILY_135, + .base = &iwl2030_base, }; #define IWL_DEVICE_135 \ .fw_name_pre = IWL135_FW_PRE, \ .ucode_api_max = IWL135_UCODE_API_MAX, \ .ucode_api_min = IWL135_UCODE_API_MIN, \ - .trans.device_family = IWL_DEVICE_FAMILY_135, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ - .trans.base_params = &iwl2030_base_params, \ .eeprom_params = &iwl20x0_eeprom_params, \ .led_mode = IWL_LED_RF_STATE, \ .rx_with_siso_diversity = true -const struct iwl_cfg iwl135_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 135 BGN", +const struct iwl_rf_cfg iwl135_bgn_cfg = { IWL_DEVICE_135, - .ht_params = &iwl2000_ht_params, + .ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(NL80211_BAND_2GHZ), + }, }; +const char iwl135_bgn_name[] = "Intel(R) Centrino(R) Wireless-N 135 BGN"; + MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX)); MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_MAX)); diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 130b9a8aa7eb..52e0beebf9ce 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* * Copyright (C) 2015-2017 Intel Deutschland GmbH - * Copyright (C) 2018-2024 Intel Corporation + * Copyright (C) 2018-2025 Intel Corporation */ #include <linux/module.h> #include <linux/stringify.h> @@ -15,14 +15,7 @@ /* Lowest firmware API version supported */ #define IWL_22000_UCODE_API_MIN 77 -/* NVM versions */ -#define IWL_22000_NVM_VERSION 0x0a1d - /* Memory offsets and lengths */ -#define IWL_22000_DCCM_OFFSET 0x800000 /* LMAC1 */ -#define IWL_22000_DCCM_LEN 0x10000 /* LMAC1 */ -#define IWL_22000_DCCM2_OFFSET 0x880000 -#define IWL_22000_DCCM2_LEN 0x8000 #define IWL_22000_SMEM_OFFSET 0x400000 #define IWL_22000_SMEM_LEN 0xD0000 @@ -44,11 +37,12 @@ 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" -static const struct iwl_base_params iwl_22000_base_params = { - .eeprom_size = OTP_LOW_IMAGE_SIZE_32K, +static const struct iwl_family_base_params iwl_22000_base = { .num_of_queues = 512, .max_tfd_queue_size = 256, .shadow_ram_support = true, @@ -57,155 +51,78 @@ static const struct iwl_base_params iwl_22000_base_params = { .max_event_log_size = 512, .shadow_reg_enable = true, .pcie_l1_allowed = true, -}; - -const struct iwl_ht_params iwl_22000_ht_params = { - .stbc = true, - .ldpc = true, - .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ) | - BIT(NL80211_BAND_6GHZ), -}; - -#define IWL_DEVICE_22000_COMMON \ - .ucode_api_min = IWL_22000_UCODE_API_MIN, \ - .led_mode = IWL_LED_RF_STATE, \ - .nvm_hw_section_num = 10, \ - .non_shared_ant = ANT_B, \ - .dccm_offset = IWL_22000_DCCM_OFFSET, \ - .dccm_len = IWL_22000_DCCM_LEN, \ - .dccm2_offset = IWL_22000_DCCM2_OFFSET, \ - .dccm2_len = IWL_22000_DCCM2_LEN, \ - .smem_offset = IWL_22000_SMEM_OFFSET, \ - .smem_len = IWL_22000_SMEM_LEN, \ - .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \ - .apmg_not_supported = true, \ - .trans.mq_rx_supported = true, \ - .vht_mu_mimo_supported = true, \ - .mac_addr_from_csr = 0x380, \ - .ht_params = &iwl_22000_ht_params, \ - .nvm_ver = IWL_22000_NVM_VERSION, \ - .trans.rf_id = true, \ - .trans.gen2 = true, \ - .nvm_type = IWL_NVM_EXT, \ - .dbgc_supported = true, \ - .min_umac_error_event_table = 0x400000, \ - .d3_debug_data_base_addr = 0x401000, \ - .d3_debug_data_length = 60 * 1024, \ - .mon_smem_regs = { \ - .write_ptr = { \ - .addr = LDBG_M2S_BUF_WPTR, \ - .mask = LDBG_M2S_BUF_WPTR_VAL_MSK, \ - }, \ - .cycle_cnt = { \ - .addr = LDBG_M2S_BUF_WRAP_CNT, \ - .mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK, \ - }, \ - } - -#define IWL_DEVICE_22500 \ - IWL_DEVICE_22000_COMMON, \ - .ucode_api_max = IWL_22000_UCODE_API_MAX, \ - .trans.device_family = IWL_DEVICE_FAMILY_22000, \ - .trans.base_params = &iwl_22000_base_params, \ - .gp2_reg_addr = 0xa02c68, \ - .mon_dram_regs = { \ - .write_ptr = { \ - .addr = MON_BUFF_WRPTR_VER2, \ - .mask = 0xffffffff, \ - }, \ - .cycle_cnt = { \ - .addr = MON_BUFF_CYCLE_CNT_VER2, \ - .mask = 0xffffffff, \ - }, \ - } - -const struct iwl_cfg_trans_params iwl_qu_trans_cfg = { + .smem_offset = IWL_22000_SMEM_OFFSET, + .smem_len = IWL_22000_SMEM_LEN, + .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, + .apmg_not_supported = true, + .mac_addr_from_csr = 0x380, + .min_umac_error_event_table = 0x400000, + .d3_debug_data_base_addr = 0x401000, + .d3_debug_data_length = 60 * 1024, + .mon_smem_regs = { + .write_ptr = { + .addr = LDBG_M2S_BUF_WPTR, + .mask = LDBG_M2S_BUF_WPTR_VAL_MSK, + }, + .cycle_cnt = { + .addr = LDBG_M2S_BUF_WRAP_CNT, + .mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK, + }, + }, + .gp2_reg_addr = 0xa02c68, + .mon_dram_regs = { + .write_ptr = { + .addr = MON_BUFF_WRPTR_VER2, + .mask = 0xffffffff, + }, + .cycle_cnt = { + .addr = MON_BUFF_CYCLE_CNT_VER2, + .mask = 0xffffffff, + }, + }, + .ucode_api_min = IWL_22000_UCODE_API_MIN, + .ucode_api_max = IWL_22000_UCODE_API_MAX, +}; + +const struct iwl_mac_cfg iwl_qu_mac_cfg = { .mq_rx_supported = true, - .rf_id = true, .gen2 = true, .device_family = IWL_DEVICE_FAMILY_22000, - .base_params = &iwl_22000_base_params, + .base = &iwl_22000_base, .integrated = true, .xtal_latency = 500, .ltr_delay = IWL_CFG_TRANS_LTR_DELAY_200US, }; -const struct iwl_cfg_trans_params iwl_qu_medium_latency_trans_cfg = { +const struct iwl_mac_cfg iwl_qu_medium_latency_mac_cfg = { .mq_rx_supported = true, - .rf_id = true, .gen2 = true, .device_family = IWL_DEVICE_FAMILY_22000, - .base_params = &iwl_22000_base_params, + .base = &iwl_22000_base, .integrated = true, .xtal_latency = 1820, .ltr_delay = IWL_CFG_TRANS_LTR_DELAY_1820US, }; -const struct iwl_cfg_trans_params iwl_qu_long_latency_trans_cfg = { +const struct iwl_mac_cfg iwl_qu_long_latency_mac_cfg = { .mq_rx_supported = true, - .rf_id = true, .gen2 = true, .device_family = IWL_DEVICE_FAMILY_22000, - .base_params = &iwl_22000_base_params, + .base = &iwl_22000_base, .integrated = true, .xtal_latency = 12000, .low_latency_xtal = true, .ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US, }; -/* - * If the device doesn't support HE, no need to have that many buffers. - * 22000 devices can split multiple frames into a single RB, so fewer are - * needed; AX210 cannot (but use smaller RBs by default) - these sizes - * were picked according to 8 MSDUs inside 256 A-MSDUs in an A-MPDU, with - * additional overhead to account for processing time. - */ -#define IWL_NUM_RBDS_NON_HE 512 -#define IWL_NUM_RBDS_22000_HE 2048 - -/* - * All JF radio modules are part of the 9000 series, but the MAC part - * looks more like 22000. That's why this device is here, but called - * 9560 nevertheless. - */ -const struct iwl_cfg iwl9560_qu_b0_jf_b0_cfg = { - .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, - IWL_DEVICE_22500, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - -const struct iwl_cfg iwl9560_qu_c0_jf_b0_cfg = { - .fw_name_pre = IWL_QU_C_JF_B_FW_PRE, - IWL_DEVICE_22500, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - -const struct iwl_cfg iwl9560_quz_a0_jf_b0_cfg = { - .fw_name_pre = IWL_QUZ_A_JF_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - -const struct iwl_cfg_trans_params iwl_ax200_trans_cfg = { +const struct iwl_mac_cfg iwl_ax200_mac_cfg = { .device_family = IWL_DEVICE_FAMILY_22000, - .base_params = &iwl_22000_base_params, + .base = &iwl_22000_base, .mq_rx_supported = true, - .rf_id = true, .gen2 = true, .bisr_workaround = 1, }; -const char iwl_ax101_name[] = "Intel(R) Wi-Fi 6 AX101"; -const char iwl_ax200_name[] = "Intel(R) Wi-Fi 6 AX200 160MHz"; -const char iwl_ax201_name[] = "Intel(R) Wi-Fi 6 AX201 160MHz"; -const char iwl_ax203_name[] = "Intel(R) Wi-Fi 6 AX203"; - const char iwl_ax200_killer_1650w_name[] = "Killer(R) Wi-Fi 6 AX1650w 160MHz Wireless Network Adapter (200D2W)"; const char iwl_ax200_killer_1650x_name[] = @@ -215,213 +132,10 @@ 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)"; -const struct iwl_cfg iwl_qu_b0_hr1_b0 = { - .fw_name_pre = IWL_QU_B_HR_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .tx_with_siso_diversity = true, - .num_rbds = IWL_NUM_RBDS_22000_HE, -}; - -const struct iwl_cfg iwl_qu_b0_hr_b0 = { - .fw_name_pre = IWL_QU_B_HR_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .num_rbds = IWL_NUM_RBDS_22000_HE, -}; - -const struct iwl_cfg iwl_ax201_cfg_qu_hr = { - .name = "Intel(R) Wi-Fi 6 AX201 160MHz", - .fw_name_pre = IWL_QU_B_HR_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .num_rbds = IWL_NUM_RBDS_22000_HE, -}; - -const struct iwl_cfg iwl_qu_c0_hr1_b0 = { - .fw_name_pre = IWL_QU_C_HR_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .tx_with_siso_diversity = true, - .num_rbds = IWL_NUM_RBDS_22000_HE, -}; - -const struct iwl_cfg iwl_qu_c0_hr_b0 = { - .fw_name_pre = IWL_QU_C_HR_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .num_rbds = IWL_NUM_RBDS_22000_HE, -}; - -const struct iwl_cfg iwl_ax201_cfg_qu_c0_hr_b0 = { - .name = "Intel(R) Wi-Fi 6 AX201 160MHz", - .fw_name_pre = IWL_QU_C_HR_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .num_rbds = IWL_NUM_RBDS_22000_HE, -}; - -const struct iwl_cfg iwl_quz_a0_hr1_b0 = { - .fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .tx_with_siso_diversity = true, - .num_rbds = IWL_NUM_RBDS_22000_HE, -}; - -const struct iwl_cfg iwl_ax201_cfg_quz_hr = { - .name = "Intel(R) Wi-Fi 6 AX201 160MHz", - .fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .num_rbds = IWL_NUM_RBDS_22000_HE, -}; - -const struct iwl_cfg iwl_ax1650s_cfg_quz_hr = { - .name = "Killer(R) Wi-Fi 6 AX1650s 160MHz Wireless Network Adapter (201D2W)", - .fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .num_rbds = IWL_NUM_RBDS_22000_HE, -}; - -const struct iwl_cfg iwl_ax1650i_cfg_quz_hr = { - .name = "Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW)", - .fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .num_rbds = IWL_NUM_RBDS_22000_HE, -}; - -const struct iwl_cfg iwl_ax200_cfg_cc = { - .fw_name_pre = IWL_CC_A_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .num_rbds = IWL_NUM_RBDS_22000_HE, -}; - -const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0 = { - .name = "Killer(R) Wi-Fi 6 AX1650s 160MHz Wireless Network Adapter (201NGW)", - .fw_name_pre = IWL_QU_B_HR_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .num_rbds = IWL_NUM_RBDS_22000_HE, -}; - -const struct iwl_cfg killer1650i_2ax_cfg_qu_b0_hr_b0 = { - .name = "Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201D2W)", - .fw_name_pre = IWL_QU_B_HR_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .num_rbds = IWL_NUM_RBDS_22000_HE, -}; - -const struct iwl_cfg killer1650s_2ax_cfg_qu_c0_hr_b0 = { - .name = "Killer(R) Wi-Fi 6 AX1650s 160MHz Wireless Network Adapter (201NGW)", - .fw_name_pre = IWL_QU_C_HR_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .num_rbds = IWL_NUM_RBDS_22000_HE, -}; - -const struct iwl_cfg killer1650i_2ax_cfg_qu_c0_hr_b0 = { - .name = "Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201D2W)", - .fw_name_pre = IWL_QU_C_HR_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .num_rbds = IWL_NUM_RBDS_22000_HE, -}; - -const struct iwl_cfg iwl_cfg_quz_a0_hr_b0 = { - .fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE, - IWL_DEVICE_22500, - /* - * This device doesn't support receiving BlockAck with a large bitmap - * so we need to restrict the size of transmitted aggregation to the - * HT size; mac80211 would otherwise pick the HE max (256) by default. - */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .num_rbds = IWL_NUM_RBDS_22000_HE, -}; - 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)); diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/5000.c b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c index de7ede59a994..aaae3b1f5433 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/5000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2018 - 2020, 2023 Intel Corporation + * Copyright(c) 2018 - 2020, 2023, 2025 Intel Corporation *****************************************************************************/ #include <linux/module.h> @@ -30,7 +30,7 @@ #define IWL5150_FW_PRE "iwlwifi-5150" #define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE "-" __stringify(api) ".ucode" -static const struct iwl_base_params iwl5000_base_params = { +static const struct iwl_family_base_params iwl5000_base = { .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, .num_of_queues = IWLAGN_NUM_QUEUES, .max_tfd_queue_size = 256, @@ -41,11 +41,6 @@ static const struct iwl_base_params iwl5000_base_params = { .scd_chain_ext_wa = true, }; -static const struct iwl_ht_params iwl5000_ht_params = { - .ht_greenfield_support = true, - .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), -}; - static const struct iwl_eeprom_params iwl5000_eeprom_params = { .regulatory_bands = { EEPROM_REG_BAND_1_CHANNELS, @@ -58,93 +53,107 @@ static const struct iwl_eeprom_params iwl5000_eeprom_params = { }, }; +const struct iwl_mac_cfg iwl5000_mac_cfg = { + .device_family = IWL_DEVICE_FAMILY_5000, + .base = &iwl5000_base, +}; + #define IWL_DEVICE_5000 \ .fw_name_pre = IWL5000_FW_PRE, \ .ucode_api_max = IWL5000_UCODE_API_MAX, \ .ucode_api_min = IWL5000_UCODE_API_MIN, \ - .trans.device_family = IWL_DEVICE_FAMILY_5000, \ .max_inst_size = IWLAGN_RTC_INST_SIZE, \ .max_data_size = IWLAGN_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_5000_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_5000_TX_POWER_VERSION, \ - .trans.base_params = &iwl5000_base_params, \ .eeprom_params = &iwl5000_eeprom_params, \ .led_mode = IWL_LED_BLINK -const struct iwl_cfg iwl5300_agn_cfg = { - .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", +const struct iwl_rf_cfg iwl5300_agn_cfg = { IWL_DEVICE_5000, /* at least EEPROM 0x11A has wrong info */ .valid_tx_ant = ANT_ABC, /* .cfg overwrite */ .valid_rx_ant = ANT_ABC, /* .cfg overwrite */ - .ht_params = &iwl5000_ht_params, + .ht_params = { + .ht_greenfield_support = true, + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, }; -const struct iwl_cfg iwl5100_bgn_cfg = { - .name = "Intel(R) WiFi Link 5100 BGN", - IWL_DEVICE_5000, - .valid_tx_ant = ANT_B, /* .cfg overwrite */ - .valid_rx_ant = ANT_AB, /* .cfg overwrite */ - .ht_params = &iwl5000_ht_params, -}; +const char iwl5300_agn_name[] = "Intel(R) Ultimate N WiFi Link 5300 AGN"; -const struct iwl_cfg iwl5100_abg_cfg = { - .name = "Intel(R) WiFi Link 5100 ABG", +const struct iwl_rf_cfg iwl5100_n_cfg = { IWL_DEVICE_5000, .valid_tx_ant = ANT_B, /* .cfg overwrite */ .valid_rx_ant = ANT_AB, /* .cfg overwrite */ + .ht_params = { + .ht_greenfield_support = true, + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, }; -const struct iwl_cfg iwl5100_agn_cfg = { - .name = "Intel(R) WiFi Link 5100 AGN", +const char iwl5100_bgn_name[] = "Intel(R) WiFi Link 5100 BGN"; + +const struct iwl_rf_cfg iwl5100_abg_cfg = { IWL_DEVICE_5000, .valid_tx_ant = ANT_B, /* .cfg overwrite */ .valid_rx_ant = ANT_AB, /* .cfg overwrite */ - .ht_params = &iwl5000_ht_params, }; -const struct iwl_cfg iwl5350_agn_cfg = { - .name = "Intel(R) WiMAX/WiFi Link 5350 AGN", +const char iwl5100_abg_name[] = "Intel(R) WiFi Link 5100 ABG"; +const char iwl5100_agn_name[] = "Intel(R) WiFi Link 5100 AGN"; + +const struct iwl_rf_cfg iwl5350_agn_cfg = { .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, - .trans.device_family = IWL_DEVICE_FAMILY_5000, .max_inst_size = IWLAGN_RTC_INST_SIZE, .max_data_size = IWLAGN_RTC_DATA_SIZE, .nvm_ver = EEPROM_5050_EEPROM_VERSION, .nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, - .trans.base_params = &iwl5000_base_params, .eeprom_params = &iwl5000_eeprom_params, - .ht_params = &iwl5000_ht_params, + .ht_params = { + .ht_greenfield_support = true, + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, .led_mode = IWL_LED_BLINK, .internal_wimax_coex = true, }; +const char iwl5350_agn_name[] = "Intel(R) WiMAX/WiFi Link 5350 AGN"; + +const struct iwl_mac_cfg iwl5150_mac_cfg = { + .device_family = IWL_DEVICE_FAMILY_5150, + .base = &iwl5000_base, +}; + #define IWL_DEVICE_5150 \ .fw_name_pre = IWL5150_FW_PRE, \ .ucode_api_max = IWL5150_UCODE_API_MAX, \ .ucode_api_min = IWL5150_UCODE_API_MIN, \ - .trans.device_family = IWL_DEVICE_FAMILY_5150, \ .max_inst_size = IWLAGN_RTC_INST_SIZE, \ .max_data_size = IWLAGN_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_5050_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ - .trans.base_params = &iwl5000_base_params, \ .eeprom_params = &iwl5000_eeprom_params, \ .led_mode = IWL_LED_BLINK, \ .internal_wimax_coex = true -const struct iwl_cfg iwl5150_agn_cfg = { - .name = "Intel(R) WiMAX/WiFi Link 5150 AGN", +const struct iwl_rf_cfg iwl5150_agn_cfg = { IWL_DEVICE_5150, - .ht_params = &iwl5000_ht_params, - + .ht_params = { + .ht_greenfield_support = true, + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, }; -const struct iwl_cfg iwl5150_abg_cfg = { - .name = "Intel(R) WiMAX/WiFi Link 5150 ABG", +const char iwl5150_agn_name[] = "Intel(R) WiMAX/WiFi Link 5150 AGN"; + +const struct iwl_rf_cfg iwl5150_abg_cfg = { IWL_DEVICE_5150, }; +const char iwl5150_abg_name[] = "Intel(R) WiMAX/WiFi Link 5150 ABG"; + MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX)); diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c index f013cf420569..ab13394896e0 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2018 - 2020, 2023 Intel Corporation + * Copyright(c) 2018 - 2020, 2023, 2025 Intel Corporation *****************************************************************************/ #include <linux/module.h> @@ -49,7 +49,7 @@ #define IWL6030_FW_PRE "iwlwifi-6000g2b" #define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE "-" __stringify(api) ".ucode" -static const struct iwl_base_params iwl6000_base_params = { +static const struct iwl_family_base_params iwl6000_base = { .eeprom_size = OTP_LOW_IMAGE_SIZE_2K, .num_of_queues = IWLAGN_NUM_QUEUES, .max_tfd_queue_size = 256, @@ -62,7 +62,7 @@ static const struct iwl_base_params iwl6000_base_params = { .scd_chain_ext_wa = true, }; -static const struct iwl_base_params iwl6050_base_params = { +static const struct iwl_family_base_params iwl6050_base = { .eeprom_size = OTP_LOW_IMAGE_SIZE_2K, .num_of_queues = IWLAGN_NUM_QUEUES, .max_tfd_queue_size = 256, @@ -75,7 +75,7 @@ static const struct iwl_base_params iwl6050_base_params = { .scd_chain_ext_wa = true, }; -static const struct iwl_base_params iwl6000_g2_base_params = { +static const struct iwl_family_base_params iwl6000_g2_base = { .eeprom_size = OTP_LOW_IMAGE_SIZE_2K, .num_of_queues = IWLAGN_NUM_QUEUES, .max_tfd_queue_size = 256, @@ -88,12 +88,6 @@ static const struct iwl_base_params iwl6000_g2_base_params = { .scd_chain_ext_wa = true, }; -static const struct iwl_ht_params iwl6000_ht_params = { - .ht_greenfield_support = true, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), -}; - static const struct iwl_eeprom_params iwl6000_eeprom_params = { .regulatory_bands = { EEPROM_REG_BAND_1_CHANNELS, @@ -107,141 +101,126 @@ static const struct iwl_eeprom_params iwl6000_eeprom_params = { .enhanced_txpower = true, }; +const struct iwl_mac_cfg iwl6005_mac_cfg = { + .device_family = IWL_DEVICE_FAMILY_6005, + .base = &iwl6000_g2_base, +}; + #define IWL_DEVICE_6005 \ .fw_name_pre = IWL6005_FW_PRE, \ .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ - .trans.device_family = IWL_DEVICE_FAMILY_6005, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_6005_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ - .trans.base_params = &iwl6000_g2_base_params, \ .eeprom_params = &iwl6000_eeprom_params, \ .led_mode = IWL_LED_RF_STATE -const struct iwl_cfg iwl6005_2agn_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN", - IWL_DEVICE_6005, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl6005_2abg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG", - IWL_DEVICE_6005, -}; - -const struct iwl_cfg iwl6005_2bg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6205 BG", +const struct iwl_rf_cfg iwl6005_n_cfg = { IWL_DEVICE_6005, + .ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, }; -const struct iwl_cfg iwl6005_2agn_sff_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6205S AGN", - IWL_DEVICE_6005, - .ht_params = &iwl6000_ht_params, -}; +const char iwl6005_2agn_name[] = "Intel(R) Centrino(R) Advanced-N 6205 AGN"; +const char iwl6005_2agn_sff_name[] = "Intel(R) Centrino(R) Advanced-N 6205S AGN"; +const char iwl6005_2agn_d_name[] = "Intel(R) Centrino(R) Advanced-N 6205D AGN"; +const char iwl6005_2agn_mow1_name[] = "Intel(R) Centrino(R) Advanced-N 6206 AGN"; +const char iwl6005_2agn_mow2_name[] = "Intel(R) Centrino(R) Advanced-N 6207 AGN"; -const struct iwl_cfg iwl6005_2agn_d_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6205D AGN", +const struct iwl_rf_cfg iwl6005_non_n_cfg = { IWL_DEVICE_6005, - .ht_params = &iwl6000_ht_params, }; -const struct iwl_cfg iwl6005_2agn_mow1_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6206 AGN", - IWL_DEVICE_6005, - .ht_params = &iwl6000_ht_params, -}; +const char iwl6005_2abg_name[] = "Intel(R) Centrino(R) Advanced-N 6205 ABG"; +const char iwl6005_2bg_name[] = "Intel(R) Centrino(R) Advanced-N 6205 BG"; -const struct iwl_cfg iwl6005_2agn_mow2_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6207 AGN", - IWL_DEVICE_6005, - .ht_params = &iwl6000_ht_params, +const struct iwl_mac_cfg iwl6030_mac_cfg = { + .device_family = IWL_DEVICE_FAMILY_6030, + .base = &iwl6000_g2_base, }; #define IWL_DEVICE_6030 \ .fw_name_pre = IWL6030_FW_PRE, \ .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ - .trans.device_family = IWL_DEVICE_FAMILY_6030, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_6030_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ - .trans.base_params = &iwl6000_g2_base_params, \ .eeprom_params = &iwl6000_eeprom_params, \ .led_mode = IWL_LED_RF_STATE -const struct iwl_cfg iwl6030_2agn_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", +const struct iwl_rf_cfg iwl6030_n_cfg = { IWL_DEVICE_6030, - .ht_params = &iwl6000_ht_params, + .ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, }; -const struct iwl_cfg iwl6030_2abg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG", - IWL_DEVICE_6030, -}; +const char iwl6030_2agn_name[] = "Intel(R) Centrino(R) Advanced-N 6230 AGN"; +const char iwl6030_2bgn_name[] = "Intel(R) Centrino(R) Advanced-N 6230 BGN"; +const char iwl1030_bgn_name[] = "Intel(R) Centrino(R) Wireless-N 1030 BGN"; +const char iwl1030_bg_name[] = "Intel(R) Centrino(R) Wireless-N 1030 BG"; -const struct iwl_cfg iwl6030_2bgn_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN", +const struct iwl_rf_cfg iwl6030_non_n_cfg = { IWL_DEVICE_6030, - .ht_params = &iwl6000_ht_params, }; -const struct iwl_cfg iwl6030_2bg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6230 BG", - IWL_DEVICE_6030, -}; +const char iwl6030_2abg_name[] = "Intel(R) Centrino(R) Advanced-N 6230 ABG"; +const char iwl6030_2bg_name[] = "Intel(R) Centrino(R) Advanced-N 6230 BG"; #define IWL_DEVICE_6035 \ .fw_name_pre = IWL6030_FW_PRE, \ .ucode_api_max = IWL6035_UCODE_API_MAX, \ .ucode_api_min = IWL6035_UCODE_API_MIN, \ - .trans.device_family = IWL_DEVICE_FAMILY_6030, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_6030_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ - .trans.base_params = &iwl6000_g2_base_params, \ .eeprom_params = &iwl6000_eeprom_params, \ .led_mode = IWL_LED_RF_STATE -const struct iwl_cfg iwl6035_2agn_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", +const struct iwl_rf_cfg iwl6035_2agn_cfg = { IWL_DEVICE_6035, - .ht_params = &iwl6000_ht_params, + .ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, }; -const struct iwl_cfg iwl6035_2agn_sff_cfg = { - .name = "Intel(R) Centrino(R) Ultimate-N 6235 AGN", - IWL_DEVICE_6035, - .ht_params = &iwl6000_ht_params, -}; +const char iwl6035_2agn_name[] = "Intel(R) Centrino(R) Advanced-N 6235 AGN"; +const char iwl6035_2agn_sff_name[] = "Intel(R) Centrino(R) Ultimate-N 6235 AGN"; -const struct iwl_cfg iwl1030_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", +const struct iwl_rf_cfg iwl130_bgn_cfg = { IWL_DEVICE_6030, - .ht_params = &iwl6000_ht_params, + .ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, + .rx_with_siso_diversity = true, }; -const struct iwl_cfg iwl1030_bg_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 1030 BG", - IWL_DEVICE_6030, -}; +const char iwl130_bgn_name[] = "Intel(R) Centrino(R) Wireless-N 130 BGN"; -const struct iwl_cfg iwl130_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 130 BGN", +const struct iwl_rf_cfg iwl130_bg_cfg = { IWL_DEVICE_6030, - .ht_params = &iwl6000_ht_params, .rx_with_siso_diversity = true, }; -const struct iwl_cfg iwl130_bg_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 130 BG", - IWL_DEVICE_6030, - .rx_with_siso_diversity = true, +const char iwl130_bg_name[] = "Intel(R) Centrino(R) Wireless-N 130 BG"; + +const struct iwl_mac_cfg iwl6000i_mac_cfg = { + .device_family = IWL_DEVICE_FAMILY_6000i, + .base = &iwl6000_base, }; /* @@ -251,101 +230,127 @@ const struct iwl_cfg iwl130_bg_cfg = { .fw_name_pre = IWL6000_FW_PRE, \ .ucode_api_max = IWL6000_UCODE_API_MAX, \ .ucode_api_min = IWL6000_UCODE_API_MIN, \ - .trans.device_family = IWL_DEVICE_FAMILY_6000i, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ .valid_tx_ant = ANT_BC, /* .cfg overwrite */ \ .valid_rx_ant = ANT_BC, /* .cfg overwrite */ \ .nvm_ver = EEPROM_6000_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ - .trans.base_params = &iwl6000_base_params, \ .eeprom_params = &iwl6000_eeprom_params, \ .led_mode = IWL_LED_BLINK -const struct iwl_cfg iwl6000i_2agn_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN", +const struct iwl_rf_cfg iwl6000i_2agn_cfg = { IWL_DEVICE_6000i, - .ht_params = &iwl6000_ht_params, + .ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, }; -const struct iwl_cfg iwl6000i_2abg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG", +const char iwl6000i_2agn_name[] = "Intel(R) Centrino(R) Advanced-N 6200 AGN"; + +const struct iwl_rf_cfg iwl6000i_non_n_cfg = { IWL_DEVICE_6000i, }; -const struct iwl_cfg iwl6000i_2bg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6200 BG", - IWL_DEVICE_6000i, +const char iwl6000i_2abg_name[] = "Intel(R) Centrino(R) Advanced-N 6200 ABG"; +const char iwl6000i_2bg_name[] = "Intel(R) Centrino(R) Advanced-N 6200 BG"; + +const struct iwl_mac_cfg iwl6050_mac_cfg = { + .device_family = IWL_DEVICE_FAMILY_6050, + .base = &iwl6050_base, }; #define IWL_DEVICE_6050 \ .fw_name_pre = IWL6050_FW_PRE, \ .ucode_api_max = IWL6050_UCODE_API_MAX, \ .ucode_api_min = IWL6050_UCODE_API_MIN, \ - .trans.device_family = IWL_DEVICE_FAMILY_6050, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ .valid_tx_ant = ANT_AB, /* .cfg overwrite */ \ .valid_rx_ant = ANT_AB, /* .cfg overwrite */ \ .nvm_ver = EEPROM_6050_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ - .trans.base_params = &iwl6050_base_params, \ .eeprom_params = &iwl6000_eeprom_params, \ .led_mode = IWL_LED_BLINK, \ .internal_wimax_coex = true -const struct iwl_cfg iwl6050_2agn_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN", +const struct iwl_rf_cfg iwl6050_2agn_cfg = { IWL_DEVICE_6050, - .ht_params = &iwl6000_ht_params, + .ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, }; -const struct iwl_cfg iwl6050_2abg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG", +const char iwl6050_2agn_name[] = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN"; + +const struct iwl_rf_cfg iwl6050_2abg_cfg = { IWL_DEVICE_6050, }; +const char iwl6050_2abg_name[] = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG"; + +const struct iwl_mac_cfg iwl6150_mac_cfg = { + .device_family = IWL_DEVICE_FAMILY_6150, + .base = &iwl6050_base, +}; + #define IWL_DEVICE_6150 \ .fw_name_pre = IWL6050_FW_PRE, \ .ucode_api_max = IWL6050_UCODE_API_MAX, \ .ucode_api_min = IWL6050_UCODE_API_MIN, \ - .trans.device_family = IWL_DEVICE_FAMILY_6150, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_6150_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_6150_TX_POWER_VERSION, \ - .trans.base_params = &iwl6050_base_params, \ .eeprom_params = &iwl6000_eeprom_params, \ .led_mode = IWL_LED_BLINK, \ .internal_wimax_coex = true -const struct iwl_cfg iwl6150_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN", +const struct iwl_rf_cfg iwl6150_bgn_cfg = { IWL_DEVICE_6150, - .ht_params = &iwl6000_ht_params, + .ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, }; -const struct iwl_cfg iwl6150_bg_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG", +const char iwl6150_bgn_name[] = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN"; + +const struct iwl_rf_cfg iwl6150_bg_cfg = { IWL_DEVICE_6150, }; -const struct iwl_cfg iwl6000_3agn_cfg = { - .name = "Intel(R) Centrino(R) Ultimate-N 6300 AGN", +const char iwl6150_bg_name[] = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG"; + +const struct iwl_mac_cfg iwl6000_mac_cfg = { + .device_family = IWL_DEVICE_FAMILY_6000, + .base = &iwl6000_base, +}; + +const struct iwl_rf_cfg iwl6000_3agn_cfg = { .fw_name_pre = IWL6000_FW_PRE, .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, - .trans.device_family = IWL_DEVICE_FAMILY_6000, .max_inst_size = IWL60_RTC_INST_SIZE, .max_data_size = IWL60_RTC_DATA_SIZE, .nvm_ver = EEPROM_6000_EEPROM_VERSION, .nvm_calib_ver = EEPROM_6000_TX_POWER_VERSION, - .trans.base_params = &iwl6000_base_params, .eeprom_params = &iwl6000_eeprom_params, - .ht_params = &iwl6000_ht_params, + .ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, .led_mode = IWL_LED_BLINK, }; +const char iwl6000_3agn_name[] = "Intel(R) Centrino(R) Ultimate-N 6300 AGN"; + MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c index 4e2afdedf4c6..f987ad3192c1 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2020, 2023 Intel Corporation + * Copyright (C) 2012-2014, 2018-2020, 2023, 2025 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH * Copyright (C) 2015 Intel Deutschland GmbH */ @@ -49,7 +49,7 @@ #define IWL7265D_FW_PRE "iwlwifi-7265D" #define IWL7265D_MODULE_FIRMWARE(api) IWL7265D_FW_PRE "-" __stringify(api) ".ucode" -static const struct iwl_base_params iwl7000_base_params = { +static const struct iwl_family_base_params iwl7000_base = { .eeprom_size = OTP_LOW_IMAGE_SIZE_16K, .num_of_queues = 31, .max_tfd_queue_size = 256, @@ -60,6 +60,7 @@ static const struct iwl_base_params iwl7000_base_params = { .shadow_reg_enable = true, .pcie_l1_allowed = true, .apmg_wake_up_wa = true, + .nvm_hw_section_num = 0, }; static const struct iwl_tt_params iwl7000_high_temp_tt_params = { @@ -84,16 +85,13 @@ static const struct iwl_tt_params iwl7000_high_temp_tt_params = { .support_tx_backoff = true, }; -static const struct iwl_ht_params iwl7000_ht_params = { - .stbc = true, - .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), +const struct iwl_mac_cfg iwl7000_mac_cfg = { + .device_family = IWL_DEVICE_FAMILY_7000, + .base = &iwl7000_base, }; #define IWL_DEVICE_7000_COMMON \ - .trans.device_family = IWL_DEVICE_FAMILY_7000, \ - .trans.base_params = &iwl7000_base_params, \ .led_mode = IWL_LED_RF_STATE, \ - .nvm_hw_section_num = 0, \ .non_shared_ant = ANT_A, \ .dccm_offset = IWL7000_DCCM_OFFSET @@ -117,77 +115,52 @@ static const struct iwl_ht_params iwl7000_ht_params = { .ucode_api_max = IWL7265D_UCODE_API_MAX, \ .ucode_api_min = IWL7265D_UCODE_API_MIN -const struct iwl_cfg iwl7260_2ac_cfg = { - .name = "Intel(R) Dual Band Wireless AC 7260", +const char iwl7260_2ac_name[] = "Intel(R) Dual Band Wireless AC 7260"; +const char iwl7260_2n_name[] = "Intel(R) Dual Band Wireless N 7260"; +const char iwl7260_n_name[] = "Intel(R) Wireless N 7260"; +const char iwl3160_2ac_name[] = "Intel(R) Dual Band Wireless AC 3160"; +const char iwl3160_2n_name[] = "Intel(R) Dual Band Wireless N 3160"; +const char iwl3160_n_name[] = "Intel(R) Wireless N 3160"; +const char iwl3165_2ac_name[] = "Intel(R) Dual Band Wireless-AC 3165"; +const char iwl3168_2ac_name[] = "Intel(R) Dual Band Wireless-AC 3168"; +const char iwl7265_2ac_name[] = "Intel(R) Dual Band Wireless-AC 7265"; +const char iwl7265_2n_name[] = "Intel(R) Dual Band Wireless-N 7265"; +const char iwl7265_n_name[] = "Intel(R) Wireless-N 7265"; + +const struct iwl_rf_cfg iwl7260_cfg = { .fw_name_pre = IWL7260_FW_PRE, IWL_DEVICE_7000, - .ht_params = &iwl7000_ht_params, + .ht_params = { + .stbc = true, + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, .nvm_ver = IWL7260_NVM_VERSION, .host_interrupt_operation_mode = true, .lp_xtal_workaround = true, .dccm_len = IWL7260_DCCM_LEN, }; -const struct iwl_cfg iwl7260_2ac_cfg_high_temp = { - .name = "Intel(R) Dual Band Wireless AC 7260", +const struct iwl_rf_cfg iwl7260_high_temp_cfg = { .fw_name_pre = IWL7260_FW_PRE, IWL_DEVICE_7000, - .ht_params = &iwl7000_ht_params, + .ht_params = { + .stbc = true, + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, .nvm_ver = IWL7260_NVM_VERSION, - .high_temp = true, .host_interrupt_operation_mode = true, .lp_xtal_workaround = true, .dccm_len = IWL7260_DCCM_LEN, .thermal_params = &iwl7000_high_temp_tt_params, }; -const struct iwl_cfg iwl7260_2n_cfg = { - .name = "Intel(R) Dual Band Wireless N 7260", - .fw_name_pre = IWL7260_FW_PRE, - IWL_DEVICE_7000, - .ht_params = &iwl7000_ht_params, - .nvm_ver = IWL7260_NVM_VERSION, - .host_interrupt_operation_mode = true, - .lp_xtal_workaround = true, - .dccm_len = IWL7260_DCCM_LEN, -}; - -const struct iwl_cfg iwl7260_n_cfg = { - .name = "Intel(R) Wireless N 7260", - .fw_name_pre = IWL7260_FW_PRE, - IWL_DEVICE_7000, - .ht_params = &iwl7000_ht_params, - .nvm_ver = IWL7260_NVM_VERSION, - .host_interrupt_operation_mode = true, - .lp_xtal_workaround = true, - .dccm_len = IWL7260_DCCM_LEN, -}; - -const struct iwl_cfg iwl3160_2ac_cfg = { - .name = "Intel(R) Dual Band Wireless AC 3160", +const struct iwl_rf_cfg iwl3160_cfg = { .fw_name_pre = IWL3160_FW_PRE, IWL_DEVICE_7000, - .ht_params = &iwl7000_ht_params, - .nvm_ver = IWL3160_NVM_VERSION, - .host_interrupt_operation_mode = true, - .dccm_len = IWL3160_DCCM_LEN, -}; - -const struct iwl_cfg iwl3160_2n_cfg = { - .name = "Intel(R) Dual Band Wireless N 3160", - .fw_name_pre = IWL3160_FW_PRE, - IWL_DEVICE_7000, - .ht_params = &iwl7000_ht_params, - .nvm_ver = IWL3160_NVM_VERSION, - .host_interrupt_operation_mode = true, - .dccm_len = IWL3160_DCCM_LEN, -}; - -const struct iwl_cfg iwl3160_n_cfg = { - .name = "Intel(R) Wireless N 3160", - .fw_name_pre = IWL3160_FW_PRE, - IWL_DEVICE_7000, - .ht_params = &iwl7000_ht_params, + .ht_params = { + .stbc = true, + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, .nvm_ver = IWL3160_NVM_VERSION, .host_interrupt_operation_mode = true, .dccm_len = IWL3160_DCCM_LEN, @@ -204,88 +177,52 @@ static const struct iwl_pwr_tx_backoff iwl7265_pwr_tx_backoffs[] = { {0}, }; -static const struct iwl_ht_params iwl7265_ht_params = { - .stbc = true, - .ldpc = true, - .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), -}; - -const struct iwl_cfg iwl3165_2ac_cfg = { - .name = "Intel(R) Dual Band Wireless AC 3165", +const struct iwl_rf_cfg iwl3165_2ac_cfg = { .fw_name_pre = IWL7265D_FW_PRE, IWL_DEVICE_7005D, - .ht_params = &iwl7000_ht_params, + .ht_params = { + .stbc = true, + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, .nvm_ver = IWL3165_NVM_VERSION, .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, .dccm_len = IWL7265_DCCM_LEN, }; -const struct iwl_cfg iwl3168_2ac_cfg = { - .name = "Intel(R) Dual Band Wireless AC 3168", +const struct iwl_rf_cfg iwl3168_2ac_cfg = { .fw_name_pre = IWL3168_FW_PRE, IWL_DEVICE_3008, - .ht_params = &iwl7000_ht_params, + .ht_params = { + .stbc = true, + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, .nvm_ver = IWL3168_NVM_VERSION, .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, .dccm_len = IWL7265_DCCM_LEN, .nvm_type = IWL_NVM_SDP, }; -const struct iwl_cfg iwl7265_2ac_cfg = { - .name = "Intel(R) Dual Band Wireless AC 7265", - .fw_name_pre = IWL7265_FW_PRE, - IWL_DEVICE_7005, - .ht_params = &iwl7265_ht_params, - .nvm_ver = IWL7265_NVM_VERSION, - .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, - .dccm_len = IWL7265_DCCM_LEN, -}; - -const struct iwl_cfg iwl7265_2n_cfg = { - .name = "Intel(R) Dual Band Wireless N 7265", - .fw_name_pre = IWL7265_FW_PRE, - IWL_DEVICE_7005, - .ht_params = &iwl7265_ht_params, - .nvm_ver = IWL7265_NVM_VERSION, - .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, - .dccm_len = IWL7265_DCCM_LEN, -}; - -const struct iwl_cfg iwl7265_n_cfg = { - .name = "Intel(R) Wireless N 7265", +const struct iwl_rf_cfg iwl7265_cfg = { .fw_name_pre = IWL7265_FW_PRE, IWL_DEVICE_7005, - .ht_params = &iwl7265_ht_params, + .ht_params = { + .stbc = true, + .ldpc = true, + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, .nvm_ver = IWL7265_NVM_VERSION, .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, .dccm_len = IWL7265_DCCM_LEN, }; -const struct iwl_cfg iwl7265d_2ac_cfg = { - .name = "Intel(R) Dual Band Wireless AC 7265", - .fw_name_pre = IWL7265D_FW_PRE, - IWL_DEVICE_7005D, - .ht_params = &iwl7265_ht_params, - .nvm_ver = IWL7265D_NVM_VERSION, - .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, - .dccm_len = IWL7265_DCCM_LEN, -}; - -const struct iwl_cfg iwl7265d_2n_cfg = { - .name = "Intel(R) Dual Band Wireless N 7265", +const struct iwl_rf_cfg iwl7265d_cfg = { .fw_name_pre = IWL7265D_FW_PRE, IWL_DEVICE_7005D, - .ht_params = &iwl7265_ht_params, - .nvm_ver = IWL7265D_NVM_VERSION, - .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, - .dccm_len = IWL7265_DCCM_LEN, -}; - -const struct iwl_cfg iwl7265d_n_cfg = { - .name = "Intel(R) Wireless N 7265", - .fw_name_pre = IWL7265D_FW_PRE, - IWL_DEVICE_7005D, - .ht_params = &iwl7265_ht_params, + .ht_params = { + .stbc = true, + .ldpc = true, + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, .nvm_ver = IWL7265D_NVM_VERSION, .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, .dccm_len = IWL7265_DCCM_LEN, diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c index d09cf8d7dc01..b56574006ee0 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2014, 2018-2020, 2023 Intel Corporation + * Copyright (C) 2014, 2018-2020, 2023, 2025 Intel Corporation * Copyright (C) 2014-2015 Intel Mobile Communications GmbH * Copyright (C) 2016 Intel Deutschland GmbH */ @@ -35,9 +35,7 @@ #define IWL8265_MODULE_FIRMWARE(api) \ IWL8265_FW_PRE "-" __stringify(api) ".ucode" -#define DEFAULT_NVM_FILE_FAMILY_8000C "nvmData-8000C" - -static const struct iwl_base_params iwl8000_base_params = { +static const struct iwl_family_base_params iwl8000_base = { .eeprom_size = OTP_LOW_IMAGE_SIZE_32K, .num_of_queues = 31, .max_tfd_queue_size = 256, @@ -47,12 +45,12 @@ static const struct iwl_base_params iwl8000_base_params = { .max_event_log_size = 512, .shadow_reg_enable = true, .pcie_l1_allowed = true, -}; - -static const struct iwl_ht_params iwl8000_ht_params = { - .stbc = true, - .ldpc = true, - .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + .nvm_hw_section_num = 10, + .features = NETIF_F_RXCSUM, + .smem_offset = IWL8260_SMEM_OFFSET, + .smem_len = IWL8260_SMEM_LEN, + .apmg_not_supported = true, + .min_umac_error_event_table = 0x800000, }; static const struct iwl_tt_params iwl8000_tt_params = { @@ -76,30 +74,20 @@ static const struct iwl_tt_params iwl8000_tt_params = { .support_tx_backoff = true, }; +const struct iwl_mac_cfg iwl8000_mac_cfg = { + .device_family = IWL_DEVICE_FAMILY_8000, + .base = &iwl8000_base, +}; + #define IWL_DEVICE_8000_COMMON \ - .trans.device_family = IWL_DEVICE_FAMILY_8000, \ - .trans.base_params = &iwl8000_base_params, \ .led_mode = IWL_LED_RF_STATE, \ - .nvm_hw_section_num = 10, \ - .features = NETIF_F_RXCSUM, \ .non_shared_ant = ANT_A, \ .dccm_offset = IWL8260_DCCM_OFFSET, \ .dccm_len = IWL8260_DCCM_LEN, \ .dccm2_offset = IWL8260_DCCM2_OFFSET, \ .dccm2_len = IWL8260_DCCM2_LEN, \ - .smem_offset = IWL8260_SMEM_OFFSET, \ - .smem_len = IWL8260_SMEM_LEN, \ - .default_nvm_file_C_step = DEFAULT_NVM_FILE_FAMILY_8000C, \ .thermal_params = &iwl8000_tt_params, \ - .apmg_not_supported = true, \ - .nvm_type = IWL_NVM_EXT, \ - .dbgc_supported = true, \ - .min_umac_error_event_table = 0x800000 - -#define IWL_DEVICE_8000 \ - IWL_DEVICE_8000_COMMON, \ - .ucode_api_max = IWL8000_UCODE_API_MAX, \ - .ucode_api_min = IWL8000_UCODE_API_MIN \ + .nvm_type = IWL_NVM_EXT #define IWL_DEVICE_8260 \ IWL_DEVICE_8000_COMMON, \ @@ -111,47 +99,39 @@ static const struct iwl_tt_params iwl8000_tt_params = { .ucode_api_max = IWL8265_UCODE_API_MAX, \ .ucode_api_min = IWL8265_UCODE_API_MIN \ -const struct iwl_cfg iwl8260_2n_cfg = { - .name = "Intel(R) Dual Band Wireless N 8260", - .fw_name_pre = IWL8000_FW_PRE, - IWL_DEVICE_8260, - .ht_params = &iwl8000_ht_params, - .nvm_ver = IWL8000_NVM_VERSION, -}; +const char iwl8260_2n_name[] = "Intel(R) Dual Band Wireless-N 8260"; +const char iwl8260_2ac_name[] = "Intel(R) Dual Band Wireless-AC 8260"; +const char iwl8265_2ac_name[] = "Intel(R) Dual Band Wireless-AC 8265"; +const char iwl8275_2ac_name[] = "Intel(R) Dual Band Wireless-AC 8275"; +const char iwl4165_2ac_name[] = "Intel(R) Dual Band Wireless-AC 4165"; -const struct iwl_cfg iwl8260_2ac_cfg = { - .name = "Intel(R) Dual Band Wireless AC 8260", +const char iwl_killer_1435i_name[] = + "Killer(R) Wireless-AC 1435i Wireless Network Adapter (8265D2W)"; +const char iwl_killer_1434_kix_name[] = + "Killer(R) Wireless-AC 1435-KIX Wireless Network Adapter (8265NGW)"; + +const struct iwl_rf_cfg iwl8260_cfg = { .fw_name_pre = IWL8000_FW_PRE, IWL_DEVICE_8260, - .ht_params = &iwl8000_ht_params, + .ht_params = { + .stbc = true, + .ldpc = true, + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, .nvm_ver = IWL8000_NVM_VERSION, }; -const struct iwl_cfg iwl8265_2ac_cfg = { - .name = "Intel(R) Dual Band Wireless AC 8265", +const struct iwl_rf_cfg iwl8265_cfg = { .fw_name_pre = IWL8265_FW_PRE, IWL_DEVICE_8265, - .ht_params = &iwl8000_ht_params, - .nvm_ver = IWL8000_NVM_VERSION, - .vht_mu_mimo_supported = true, -}; - -const struct iwl_cfg iwl8275_2ac_cfg = { - .name = "Intel(R) Dual Band Wireless AC 8275", - .fw_name_pre = IWL8265_FW_PRE, - IWL_DEVICE_8265, - .ht_params = &iwl8000_ht_params, + .ht_params = { + .stbc = true, + .ldpc = true, + .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), + }, .nvm_ver = IWL8000_NVM_VERSION, .vht_mu_mimo_supported = true, }; -const struct iwl_cfg iwl4165_2ac_cfg = { - .name = "Intel(R) Dual Band Wireless AC 4165", - .fw_name_pre = IWL8000_FW_PRE, - IWL_DEVICE_8000, - .ht_params = &iwl8000_ht_params, - .nvm_ver = IWL8000_NVM_VERSION, -}; - MODULE_FIRMWARE(IWL8000_MODULE_FIRMWARE(IWL8000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL8265_MODULE_FIRMWARE(IWL8265_UCODE_API_MAX)); diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c index 0130d9a9b78b..ac1fa291cf2f 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* * Copyright (C) 2015-2017 Intel Deutschland GmbH - * Copyright (C) 2018-2021, 2023 Intel Corporation + * Copyright (C) 2018-2021, 2023, 2025 Intel Corporation */ #include <linux/module.h> #include <linux/stringify.h> @@ -15,14 +15,7 @@ /* Lowest firmware API version supported */ #define IWL9000_UCODE_API_MIN 30 -/* NVM versions */ -#define IWL9000_NVM_VERSION 0x0a1d - /* Memory offsets and lengths */ -#define IWL9000_DCCM_OFFSET 0x800000 -#define IWL9000_DCCM_LEN 0x18000 -#define IWL9000_DCCM2_OFFSET 0x880000 -#define IWL9000_DCCM2_LEN 0x8000 #define IWL9000_SMEM_OFFSET 0x400000 #define IWL9000_SMEM_LEN 0x68000 @@ -33,7 +26,7 @@ #define IWL9260_MODULE_FIRMWARE(api) \ IWL9260_FW_PRE "-" __stringify(api) ".ucode" -static const struct iwl_base_params iwl9000_base_params = { +static const struct iwl_family_base_params iwl9000_base = { .eeprom_size = OTP_LOW_IMAGE_SIZE_32K, .num_of_queues = 31, .max_tfd_queue_size = 256, @@ -43,150 +36,69 @@ static const struct iwl_base_params iwl9000_base_params = { .max_event_log_size = 512, .shadow_reg_enable = true, .pcie_l1_allowed = true, -}; - -static const struct iwl_ht_params iwl9000_ht_params = { - .stbc = true, - .ldpc = true, - .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ), -}; - -static const struct iwl_tt_params iwl9000_tt_params = { - .ct_kill_entry = 115, - .ct_kill_exit = 93, - .ct_kill_duration = 5, - .dynamic_smps_entry = 111, - .dynamic_smps_exit = 107, - .tx_protection_entry = 112, - .tx_protection_exit = 105, - .tx_backoff = { - {.temperature = 110, .backoff = 200}, - {.temperature = 111, .backoff = 600}, - {.temperature = 112, .backoff = 1200}, - {.temperature = 113, .backoff = 2000}, - {.temperature = 114, .backoff = 4000}, + .smem_offset = IWL9000_SMEM_OFFSET, + .smem_len = IWL9000_SMEM_LEN, + .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, + .apmg_not_supported = true, + .mac_addr_from_csr = 0x380, + .min_umac_error_event_table = 0x800000, + .d3_debug_data_base_addr = 0x401000, + .d3_debug_data_length = 92 * 1024, + .nvm_hw_section_num = 10, + .mon_smem_regs = { + .write_ptr = { + .addr = LDBG_M2S_BUF_WPTR, + .mask = LDBG_M2S_BUF_WPTR_VAL_MSK, + }, + .cycle_cnt = { + .addr = LDBG_M2S_BUF_WRAP_CNT, + .mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK, + }, + }, + .mon_dram_regs = { + .write_ptr = { + .addr = MON_BUFF_WRPTR_VER2, + .mask = 0xffffffff, + }, + .cycle_cnt = { + .addr = MON_BUFF_CYCLE_CNT_VER2, + .mask = 0xffffffff, + }, }, - .support_ct_kill = true, - .support_dynamic_smps = true, - .support_tx_protection = true, - .support_tx_backoff = true, + .ucode_api_max = IWL9000_UCODE_API_MAX, + .ucode_api_min = IWL9000_UCODE_API_MIN, }; -#define IWL_DEVICE_9000 \ - .ucode_api_max = IWL9000_UCODE_API_MAX, \ - .ucode_api_min = IWL9000_UCODE_API_MIN, \ - .led_mode = IWL_LED_RF_STATE, \ - .nvm_hw_section_num = 10, \ - .non_shared_ant = ANT_B, \ - .dccm_offset = IWL9000_DCCM_OFFSET, \ - .dccm_len = IWL9000_DCCM_LEN, \ - .dccm2_offset = IWL9000_DCCM2_OFFSET, \ - .dccm2_len = IWL9000_DCCM2_LEN, \ - .smem_offset = IWL9000_SMEM_OFFSET, \ - .smem_len = IWL9000_SMEM_LEN, \ - .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \ - .thermal_params = &iwl9000_tt_params, \ - .apmg_not_supported = true, \ - .num_rbds = 512, \ - .vht_mu_mimo_supported = true, \ - .mac_addr_from_csr = 0x380, \ - .nvm_type = IWL_NVM_EXT, \ - .dbgc_supported = true, \ - .min_umac_error_event_table = 0x800000, \ - .d3_debug_data_base_addr = 0x401000, \ - .d3_debug_data_length = 92 * 1024, \ - .ht_params = &iwl9000_ht_params, \ - .nvm_ver = IWL9000_NVM_VERSION, \ - .mon_smem_regs = { \ - .write_ptr = { \ - .addr = LDBG_M2S_BUF_WPTR, \ - .mask = LDBG_M2S_BUF_WPTR_VAL_MSK, \ - }, \ - .cycle_cnt = { \ - .addr = LDBG_M2S_BUF_WRAP_CNT, \ - .mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK, \ - }, \ - }, \ - .mon_dram_regs = { \ - .write_ptr = { \ - .addr = MON_BUFF_WRPTR_VER2, \ - .mask = 0xffffffff, \ - }, \ - .cycle_cnt = { \ - .addr = MON_BUFF_CYCLE_CNT_VER2, \ - .mask = 0xffffffff, \ - }, \ - } - -const struct iwl_cfg_trans_params iwl9000_trans_cfg = { +const struct iwl_mac_cfg iwl9000_mac_cfg = { .device_family = IWL_DEVICE_FAMILY_9000, - .base_params = &iwl9000_base_params, + .base = &iwl9000_base, .mq_rx_supported = true, - .rf_id = true, }; -const struct iwl_cfg_trans_params iwl9560_trans_cfg = { +const struct iwl_mac_cfg iwl9560_mac_cfg = { .device_family = IWL_DEVICE_FAMILY_9000, - .base_params = &iwl9000_base_params, + .base = &iwl9000_base, .mq_rx_supported = true, - .rf_id = true, .integrated = true, .xtal_latency = 650, }; -const struct iwl_cfg_trans_params iwl9560_long_latency_trans_cfg = { +const struct iwl_mac_cfg iwl9560_long_latency_mac_cfg = { .device_family = IWL_DEVICE_FAMILY_9000, - .base_params = &iwl9000_base_params, + .base = &iwl9000_base, .mq_rx_supported = true, - .rf_id = true, .integrated = true, .xtal_latency = 2820, }; -const struct iwl_cfg_trans_params iwl9560_shared_clk_trans_cfg = { +const struct iwl_mac_cfg iwl9560_shared_clk_mac_cfg = { .device_family = IWL_DEVICE_FAMILY_9000, - .base_params = &iwl9000_base_params, + .base = &iwl9000_base, .mq_rx_supported = true, - .rf_id = true, .integrated = true, .xtal_latency = 670, .extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK }; -const char iwl9162_name[] = "Intel(R) Wireless-AC 9162"; -const char iwl9260_name[] = "Intel(R) Wireless-AC 9260"; -const char iwl9260_1_name[] = "Intel(R) Wireless-AC 9260-1"; -const char iwl9270_name[] = "Intel(R) Wireless-AC 9270"; -const char iwl9461_name[] = "Intel(R) Wireless-AC 9461"; -const char iwl9462_name[] = "Intel(R) Wireless-AC 9462"; -const char iwl9560_name[] = "Intel(R) Wireless-AC 9560"; -const char iwl9162_160_name[] = "Intel(R) Wireless-AC 9162 160MHz"; -const char iwl9260_160_name[] = "Intel(R) Wireless-AC 9260 160MHz"; -const char iwl9270_160_name[] = "Intel(R) Wireless-AC 9270 160MHz"; -const char iwl9461_160_name[] = "Intel(R) Wireless-AC 9461 160MHz"; -const char iwl9462_160_name[] = "Intel(R) Wireless-AC 9462 160MHz"; -const char iwl9560_160_name[] = "Intel(R) Wireless-AC 9560 160MHz"; - -const char iwl9260_killer_1550_name[] = - "Killer (R) Wireless-AC 1550 Wireless Network Adapter (9260NGW) 160MHz"; -const char iwl9560_killer_1550i_name[] = - "Killer (R) Wireless-AC 1550i Wireless Network Adapter (9560NGW)"; -const char iwl9560_killer_1550i_160_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 (9560NGW)"; -const char iwl9560_killer_1550s_160_name[] = - "Killer(R) Wireless-AC 1550s Wireless Network Adapter (9560D2W) 160MHz"; - -const struct iwl_cfg iwl9260_2ac_cfg = { - .fw_name_pre = IWL9260_FW_PRE, - IWL_DEVICE_9000, -}; - -const struct iwl_cfg iwl9560_2ac_cfg_soc = { - .fw_name_pre = IWL9000_FW_PRE, - IWL_DEVICE_9000, -}; - MODULE_FIRMWARE(IWL9000_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL9260_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/ax210.c b/drivers/net/wireless/intel/iwlwifi/cfg/ax210.c index e87b57b9e2c0..3bf9fdbe01c6 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/ax210.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/ax210.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* * Copyright (C) 2015-2017 Intel Deutschland GmbH - * Copyright (C) 2018-2024 Intel Corporation + * Copyright (C) 2018-2025 Intel Corporation */ #include <linux/module.h> #include <linux/stringify.h> @@ -15,14 +15,7 @@ /* Lowest firmware API version supported */ #define IWL_AX210_UCODE_API_MIN 77 -/* NVM versions */ -#define IWL_AX210_NVM_VERSION 0x0a1d - /* Memory offsets and lengths */ -#define IWL_AX210_DCCM_OFFSET 0x800000 /* LMAC1 */ -#define IWL_AX210_DCCM_LEN 0x10000 /* LMAC1 */ -#define IWL_AX210_DCCM2_OFFSET 0x880000 -#define IWL_AX210_DCCM2_LEN 0x8000 #define IWL_AX210_SMEM_OFFSET 0x400000 #define IWL_AX210_SMEM_LEN 0xD0000 @@ -47,8 +40,7 @@ #define IWL_MA_B_HR_B_FW_MODULE_FIRMWARE(api) \ IWL_MA_B_HR_B_FW_PRE "-" __stringify(api) ".ucode" -static const struct iwl_base_params iwl_ax210_base_params = { - .eeprom_size = OTP_LOW_IMAGE_SIZE_32K, +static const struct iwl_family_base_params iwl_ax210_base = { .num_of_queues = 512, .max_tfd_queue_size = 65536, .shadow_ram_support = true, @@ -57,74 +49,60 @@ static const struct iwl_base_params iwl_ax210_base_params = { .max_event_log_size = 512, .shadow_reg_enable = true, .pcie_l1_allowed = true, + .smem_offset = IWL_AX210_SMEM_OFFSET, + .smem_len = IWL_AX210_SMEM_LEN, + .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, + .apmg_not_supported = true, + .mac_addr_from_csr = 0x380, + .min_umac_error_event_table = 0x400000, + .d3_debug_data_base_addr = 0x401000, + .d3_debug_data_length = 60 * 1024, + .mon_smem_regs = { + .write_ptr = { + .addr = LDBG_M2S_BUF_WPTR, + .mask = LDBG_M2S_BUF_WPTR_VAL_MSK, + }, + .cycle_cnt = { + .addr = LDBG_M2S_BUF_WRAP_CNT, + .mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK, + }, + }, + .min_txq_size = 128, + .gp2_reg_addr = 0xd02c68, + .min_ba_txq_size = IWL_DEFAULT_QUEUE_SIZE_HE, + .mon_dram_regs = { + .write_ptr = { + .addr = DBGC_CUR_DBGBUF_STATUS, + .mask = DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK, + }, + .cycle_cnt = { + .addr = DBGC_DBGBUF_WRAP_AROUND, + .mask = 0xffffffff, + }, + .cur_frag = { + .addr = DBGC_CUR_DBGBUF_STATUS, + .mask = DBGC_CUR_DBGBUF_STATUS_IDX_MSK, + }, + }, + .ucode_api_min = IWL_AX210_UCODE_API_MIN, + .ucode_api_max = IWL_AX210_UCODE_API_MAX, }; -#define IWL_DEVICE_AX210_COMMON \ - .ucode_api_min = IWL_AX210_UCODE_API_MIN, \ - .led_mode = IWL_LED_RF_STATE, \ - .nvm_hw_section_num = 10, \ - .non_shared_ant = ANT_B, \ - .dccm_offset = IWL_AX210_DCCM_OFFSET, \ - .dccm_len = IWL_AX210_DCCM_LEN, \ - .dccm2_offset = IWL_AX210_DCCM2_OFFSET, \ - .dccm2_len = IWL_AX210_DCCM2_LEN, \ - .smem_offset = IWL_AX210_SMEM_OFFSET, \ - .smem_len = IWL_AX210_SMEM_LEN, \ - .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \ - .apmg_not_supported = true, \ - .trans.mq_rx_supported = true, \ - .vht_mu_mimo_supported = true, \ - .mac_addr_from_csr = 0x380, \ - .ht_params = &iwl_22000_ht_params, \ - .nvm_ver = IWL_AX210_NVM_VERSION, \ - .trans.rf_id = true, \ - .trans.gen2 = true, \ - .nvm_type = IWL_NVM_EXT, \ - .dbgc_supported = true, \ - .min_umac_error_event_table = 0x400000, \ - .d3_debug_data_base_addr = 0x401000, \ - .d3_debug_data_length = 60 * 1024, \ - .mon_smem_regs = { \ - .write_ptr = { \ - .addr = LDBG_M2S_BUF_WPTR, \ - .mask = LDBG_M2S_BUF_WPTR_VAL_MSK, \ - }, \ - .cycle_cnt = { \ - .addr = LDBG_M2S_BUF_WRAP_CNT, \ - .mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK, \ - }, \ - } - -#define IWL_DEVICE_AX210 \ - IWL_DEVICE_AX210_COMMON, \ - .ucode_api_max = IWL_AX210_UCODE_API_MAX, \ - .trans.umac_prph_offset = 0x300000, \ - .trans.device_family = IWL_DEVICE_FAMILY_AX210, \ - .trans.base_params = &iwl_ax210_base_params, \ - .min_txq_size = 128, \ - .gp2_reg_addr = 0xd02c68, \ - .min_ba_txq_size = IWL_DEFAULT_QUEUE_SIZE_HE, \ - .mon_dram_regs = { \ - .write_ptr = { \ - .addr = DBGC_CUR_DBGBUF_STATUS, \ - .mask = DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK, \ - }, \ - .cycle_cnt = { \ - .addr = DBGC_DBGBUF_WRAP_AROUND, \ - .mask = 0xffffffff, \ - }, \ - .cur_frag = { \ - .addr = DBGC_CUR_DBGBUF_STATUS, \ - .mask = DBGC_CUR_DBGBUF_STATUS_IDX_MSK, \ - }, \ - } +const struct iwl_mac_cfg iwl_ty_mac_cfg = { + .mq_rx_supported = true, + .gen2 = true, + .device_family = IWL_DEVICE_FAMILY_AX210, + .base = &iwl_ax210_base, + .umac_prph_offset = 0x300000, + /* TODO: the following values need to be checked */ + .xtal_latency = 500, +}; -const struct iwl_cfg_trans_params iwl_so_trans_cfg = { +const struct iwl_mac_cfg iwl_so_mac_cfg = { .mq_rx_supported = true, - .rf_id = true, .gen2 = true, .device_family = IWL_DEVICE_FAMILY_AX210, - .base_params = &iwl_ax210_base_params, + .base = &iwl_ax210_base, .umac_prph_offset = 0x300000, .integrated = true, /* TODO: the following values need to be checked */ @@ -132,12 +110,11 @@ const struct iwl_cfg_trans_params iwl_so_trans_cfg = { .ltr_delay = IWL_CFG_TRANS_LTR_DELAY_200US, }; -const struct iwl_cfg_trans_params iwl_so_long_latency_trans_cfg = { +const struct iwl_mac_cfg iwl_so_long_latency_mac_cfg = { .mq_rx_supported = true, - .rf_id = true, .gen2 = true, .device_family = IWL_DEVICE_FAMILY_AX210, - .base_params = &iwl_ax210_base_params, + .base = &iwl_ax210_base, .umac_prph_offset = 0x300000, .integrated = true, .low_latency_xtal = true, @@ -145,12 +122,11 @@ const struct iwl_cfg_trans_params iwl_so_long_latency_trans_cfg = { .ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US, }; -const struct iwl_cfg_trans_params iwl_so_long_latency_imr_trans_cfg = { +const struct iwl_mac_cfg iwl_so_long_latency_imr_mac_cfg = { .mq_rx_supported = true, - .rf_id = true, .gen2 = true, .device_family = IWL_DEVICE_FAMILY_AX210, - .base_params = &iwl_ax210_base_params, + .base = &iwl_ax210_base, .umac_prph_offset = 0x300000, .integrated = true, .low_latency_xtal = true, @@ -159,107 +135,15 @@ const struct iwl_cfg_trans_params iwl_so_long_latency_imr_trans_cfg = { .imr_enabled = true, }; -/* - * If the device doesn't support HE, no need to have that many buffers. - * AX210 devices can split multiple frames into a single RB, so fewer are - * needed; AX210 cannot (but use smaller RBs by default) - these sizes - * were picked according to 8 MSDUs inside 256 A-MSDUs in an A-MPDU, with - * additional overhead to account for processing time. - */ -#define IWL_NUM_RBDS_NON_HE 512 -#define IWL_NUM_RBDS_AX210_HE 4096 - -const struct iwl_cfg_trans_params iwl_ma_trans_cfg = { +const struct iwl_mac_cfg iwl_ma_mac_cfg = { .device_family = IWL_DEVICE_FAMILY_AX210, - .base_params = &iwl_ax210_base_params, + .base = &iwl_ax210_base, .mq_rx_supported = true, - .rf_id = true, .gen2 = true, .integrated = true, .umac_prph_offset = 0x300000 }; -const char iwl_ax211_name[] = "Intel(R) Wi-Fi 6E AX211 160MHz"; -const char iwl_ax231_name[] = "Intel(R) Wi-Fi 6E AX231 160MHz"; -const char iwl_ax411_name[] = "Intel(R) Wi-Fi 6E AX411 160MHz"; - -const char iwl_ax210_killer_1675w_name[] = - "Killer(R) Wi-Fi 6E AX1675w 160MHz Wireless Network Adapter (210D2W)"; -const char iwl_ax210_killer_1675x_name[] = - "Killer(R) Wi-Fi 6E AX1675x 160MHz Wireless Network Adapter (210NGW)"; -const char iwl_ax211_killer_1675s_name[] = - "Killer(R) Wi-Fi 6E AX1675s 160MHz Wireless Network Adapter (211NGW)"; -const char iwl_ax211_killer_1675i_name[] = - "Killer(R) Wi-Fi 6E AX1675i 160MHz Wireless Network Adapter (211NGW)"; -const char iwl_ax411_killer_1690s_name[] = - "Killer(R) Wi-Fi 6E AX1690s 160MHz Wireless Network Adapter (411D2W)"; -const char iwl_ax411_killer_1690i_name[] = - "Killer(R) Wi-Fi 6E AX1690i 160MHz Wireless Network Adapter (411NGW)"; - -const struct iwl_cfg iwlax210_2ax_cfg_so_jf_b0 = { - .name = "Intel(R) Wireless-AC 9560 160MHz", - .fw_name_pre = IWL_SO_A_JF_B_FW_PRE, - IWL_DEVICE_AX210, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - -const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0 = { - .name = iwl_ax211_name, - .fw_name_pre = IWL_SO_A_GF_A_FW_PRE, - .uhb_supported = true, - IWL_DEVICE_AX210, - .num_rbds = IWL_NUM_RBDS_AX210_HE, -}; - -const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0_long = { - .name = iwl_ax211_name, - .fw_name_pre = IWL_SO_A_GF_A_FW_PRE, - .uhb_supported = true, - IWL_DEVICE_AX210, - .num_rbds = IWL_NUM_RBDS_AX210_HE, - .trans.xtal_latency = 12000, - .trans.low_latency_xtal = true, -}; - -const struct iwl_cfg iwlax210_2ax_cfg_ty_gf_a0 = { - .name = "Intel(R) Wi-Fi 6 AX210 160MHz", - .fw_name_pre = IWL_TY_A_GF_A_FW_PRE, - .uhb_supported = true, - IWL_DEVICE_AX210, - .num_rbds = IWL_NUM_RBDS_AX210_HE, -}; - -const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0 = { - .name = iwl_ax411_name, - .fw_name_pre = IWL_SO_A_GF4_A_FW_PRE, - .uhb_supported = true, - IWL_DEVICE_AX210, - .num_rbds = IWL_NUM_RBDS_AX210_HE, -}; - -const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0_long = { - .name = iwl_ax411_name, - .fw_name_pre = IWL_SO_A_GF4_A_FW_PRE, - .uhb_supported = true, - IWL_DEVICE_AX210, - .num_rbds = IWL_NUM_RBDS_AX210_HE, - .trans.xtal_latency = 12000, - .trans.low_latency_xtal = true, -}; - -const struct iwl_cfg iwl_cfg_ma = { - .fw_name_mac = "ma", - .uhb_supported = true, - IWL_DEVICE_AX210, - .num_rbds = IWL_NUM_RBDS_AX210_HE, -}; - -const struct iwl_cfg iwl_cfg_so_a0_hr_a0 = { - .fw_name_pre = IWL_SO_A_HR_B_FW_PRE, - IWL_DEVICE_AX210, - .num_rbds = IWL_NUM_RBDS_AX210_HE, -}; - 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); diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/bz.c b/drivers/net/wireless/intel/iwlwifi/cfg/bz.c index f055255a7c93..05e45fff8b36 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/bz.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/bz.c @@ -10,19 +10,12 @@ #include "fw/api/txq.h" /* Highest firmware API version supported */ -#define IWL_BZ_UCODE_API_MAX 98 +#define IWL_BZ_UCODE_API_MAX 99 /* Lowest firmware API version supported */ #define IWL_BZ_UCODE_API_MIN 93 -/* NVM versions */ -#define IWL_BZ_NVM_VERSION 0x0a1d - /* Memory offsets and lengths */ -#define IWL_BZ_DCCM_OFFSET 0x800000 /* LMAC1 */ -#define IWL_BZ_DCCM_LEN 0x10000 /* LMAC1 */ -#define IWL_BZ_DCCM2_OFFSET 0x880000 -#define IWL_BZ_DCCM2_LEN 0x8000 #define IWL_BZ_SMEM_OFFSET 0x400000 #define IWL_BZ_SMEM_LEN 0xD0000 @@ -38,13 +31,7 @@ #define IWL_BZ_A_HR_B_MODULE_FIRMWARE(api) \ IWL_BZ_A_HR_B_FW_PRE "-" __stringify(api) ".ucode" -#if !IS_ENABLED(CONFIG_IWLMVM) -const char iwl_ax211_name[] = "Intel(R) Wi-Fi 6E AX211 160MHz"; -const char iwl_ax201_name[] = "Intel(R) Wi-Fi 6 AX201 160MHz"; -#endif - -static const struct iwl_base_params iwl_bz_base_params = { - .eeprom_size = OTP_LOW_IMAGE_SIZE_32K, +static const struct iwl_family_base_params iwl_bz_base = { .num_of_queues = 512, .max_tfd_queue_size = 65536, .shadow_ram_support = true, @@ -53,91 +40,55 @@ static const struct iwl_base_params iwl_bz_base_params = { .max_event_log_size = 512, .shadow_reg_enable = true, .pcie_l1_allowed = true, + .smem_offset = IWL_BZ_SMEM_OFFSET, + .smem_len = IWL_BZ_SMEM_LEN, + .apmg_not_supported = true, + .mac_addr_from_csr = 0x30, + .min_umac_error_event_table = 0xD0000, + .d3_debug_data_base_addr = 0x401000, + .d3_debug_data_length = 60 * 1024, + .mon_smem_regs = { + .write_ptr = { + .addr = LDBG_M2S_BUF_WPTR, + .mask = LDBG_M2S_BUF_WPTR_VAL_MSK, + }, + .cycle_cnt = { + .addr = LDBG_M2S_BUF_WRAP_CNT, + .mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK, + }, + }, + .min_txq_size = 128, + .gp2_reg_addr = 0xd02c68, + .min_ba_txq_size = IWL_DEFAULT_QUEUE_SIZE_EHT, + .mon_dram_regs = { + .write_ptr = { + .addr = DBGC_CUR_DBGBUF_STATUS, + .mask = DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK, + }, + .cycle_cnt = { + .addr = DBGC_DBGBUF_WRAP_AROUND, + .mask = 0xffffffff, + }, + .cur_frag = { + .addr = DBGC_CUR_DBGBUF_STATUS, + .mask = DBGC_CUR_DBGBUF_STATUS_IDX_MSK, + }, + }, + .mon_dbgi_regs = { + .write_ptr = { + .addr = DBGI_SRAM_FIFO_POINTERS, + .mask = DBGI_SRAM_FIFO_POINTERS_WR_PTR_MSK, + }, + }, + .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, + .ucode_api_max = IWL_BZ_UCODE_API_MAX, + .ucode_api_min = IWL_BZ_UCODE_API_MIN, }; -const struct iwl_ht_params iwl_bz_ht_params = { - .stbc = true, - .ldpc = true, - .ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ) | - BIT(NL80211_BAND_6GHZ), -}; - -#define IWL_DEVICE_BZ_COMMON \ - .ucode_api_max = IWL_BZ_UCODE_API_MAX, \ - .ucode_api_min = IWL_BZ_UCODE_API_MIN, \ - .led_mode = IWL_LED_RF_STATE, \ - .nvm_hw_section_num = 10, \ - .non_shared_ant = ANT_B, \ - .dccm_offset = IWL_BZ_DCCM_OFFSET, \ - .dccm_len = IWL_BZ_DCCM_LEN, \ - .dccm2_offset = IWL_BZ_DCCM2_OFFSET, \ - .dccm2_len = IWL_BZ_DCCM2_LEN, \ - .smem_offset = IWL_BZ_SMEM_OFFSET, \ - .smem_len = IWL_BZ_SMEM_LEN, \ - .apmg_not_supported = true, \ - .trans.mq_rx_supported = true, \ - .vht_mu_mimo_supported = true, \ - .mac_addr_from_csr = 0x30, \ - .nvm_ver = IWL_BZ_NVM_VERSION, \ - .trans.rf_id = true, \ - .trans.gen2 = true, \ - .nvm_type = IWL_NVM_EXT, \ - .dbgc_supported = true, \ - .min_umac_error_event_table = 0xD0000, \ - .d3_debug_data_base_addr = 0x401000, \ - .d3_debug_data_length = 60 * 1024, \ - .mon_smem_regs = { \ - .write_ptr = { \ - .addr = LDBG_M2S_BUF_WPTR, \ - .mask = LDBG_M2S_BUF_WPTR_VAL_MSK, \ - }, \ - .cycle_cnt = { \ - .addr = LDBG_M2S_BUF_WRAP_CNT, \ - .mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK, \ - }, \ - }, \ - .trans.umac_prph_offset = 0x300000, \ - .trans.device_family = IWL_DEVICE_FAMILY_BZ, \ - .trans.base_params = &iwl_bz_base_params, \ - .min_txq_size = 128, \ - .gp2_reg_addr = 0xd02c68, \ - .min_ba_txq_size = IWL_DEFAULT_QUEUE_SIZE_EHT, \ - .mon_dram_regs = { \ - .write_ptr = { \ - .addr = DBGC_CUR_DBGBUF_STATUS, \ - .mask = DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK, \ - }, \ - .cycle_cnt = { \ - .addr = DBGC_DBGBUF_WRAP_AROUND, \ - .mask = 0xffffffff, \ - }, \ - .cur_frag = { \ - .addr = DBGC_CUR_DBGBUF_STATUS, \ - .mask = DBGC_CUR_DBGBUF_STATUS_IDX_MSK, \ - }, \ - }, \ - .mon_dbgi_regs = { \ - .write_ptr = { \ - .addr = DBGI_SRAM_FIFO_POINTERS, \ - .mask = DBGI_SRAM_FIFO_POINTERS_WR_PTR_MSK, \ - }, \ - } - -#define IWL_DEVICE_BZ \ - IWL_DEVICE_BZ_COMMON, \ - .ht_params = &iwl_bz_ht_params - -/* - * This size was picked according to 8 MSDUs inside 512 A-MSDUs in an - * A-MPDU, with additional overhead to account for processing time. - */ -#define IWL_NUM_RBDS_BZ_EHT (512 * 16) - -const struct iwl_cfg_trans_params iwl_bz_trans_cfg = { +const struct iwl_mac_cfg iwl_bz_mac_cfg = { .device_family = IWL_DEVICE_FAMILY_BZ, - .base_params = &iwl_bz_base_params, + .base = &iwl_bz_base, .mq_rx_supported = true, - .rf_id = true, .gen2 = true, .integrated = true, .umac_prph_offset = 0x300000, @@ -146,38 +97,16 @@ const struct iwl_cfg_trans_params iwl_bz_trans_cfg = { .ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US, }; -const struct iwl_cfg_trans_params iwl_gl_trans_cfg = { +const struct iwl_mac_cfg iwl_gl_mac_cfg = { .device_family = IWL_DEVICE_FAMILY_BZ, - .base_params = &iwl_bz_base_params, + .base = &iwl_bz_base, .mq_rx_supported = true, - .rf_id = true, .gen2 = true, .umac_prph_offset = 0x300000, .xtal_latency = 12000, .low_latency_xtal = true, }; -const char iwl_fm_name[] = "Intel(R) Wi-Fi 7 BE201 320MHz"; -const char iwl_wh_name[] = "Intel(R) Wi-Fi 7 BE211 320MHz"; -const char iwl_gl_name[] = "Intel(R) Wi-Fi 7 BE200 320MHz"; -const char iwl_mtp_name[] = "Intel(R) Wi-Fi 7 BE202 160MHz"; - -const struct iwl_cfg iwl_cfg_bz = { - .fw_name_mac = "bz", - .uhb_supported = true, - IWL_DEVICE_BZ, - .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, - .num_rbds = IWL_NUM_RBDS_BZ_EHT, -}; - -const struct iwl_cfg iwl_cfg_gl = { - .fw_name_mac = "gl", - .uhb_supported = true, - IWL_DEVICE_BZ, - .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, - .num_rbds = IWL_NUM_RBDS_BZ_EHT, -}; - 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); diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/dr.c b/drivers/net/wireless/intel/iwlwifi/cfg/dr.c index 282b9b846c3a..45e55cef42ea 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/dr.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/dr.c @@ -9,35 +9,21 @@ #include "fw/api/txq.h" /* Highest firmware API version supported */ -#define IWL_DR_UCODE_API_MAX 98 +#define IWL_DR_UCODE_API_MAX 99 /* Lowest firmware API version supported */ -#define IWL_DR_UCODE_API_MIN 96 - -/* NVM versions */ -#define IWL_DR_NVM_VERSION 0x0a1d +#define IWL_DR_UCODE_API_MIN 97 /* Memory offsets and lengths */ -#define IWL_DR_DCCM_OFFSET 0x800000 /* LMAC1 */ -#define IWL_DR_DCCM_LEN 0x10000 /* LMAC1 */ -#define IWL_DR_DCCM2_OFFSET 0x880000 -#define IWL_DR_DCCM2_LEN 0x8000 #define IWL_DR_SMEM_OFFSET 0x400000 #define IWL_DR_SMEM_LEN 0xD0000 #define IWL_DR_A_PE_A_FW_PRE "iwlwifi-dr-a0-pe-a0" -#define IWL_BR_A_PET_A_FW_PRE "iwlwifi-br-a0-petc-a0" -#define IWL_BR_A_PE_A_FW_PRE "iwlwifi-br-a0-pe-a0" #define IWL_DR_A_PE_A_FW_MODULE_FIRMWARE(api) \ IWL_DR_A_PE_A_FW_PRE "-" __stringify(api) ".ucode" -#define IWL_BR_A_PET_A_FW_MODULE_FIRMWARE(api) \ - IWL_BR_A_PET_A_FW_PRE "-" __stringify(api) ".ucode" -#define IWL_BR_A_PE_A_FW_MODULE_FIRMWARE(api) \ - IWL_BR_A_PE_A_FW_PRE "-" __stringify(api) ".ucode" -static const struct iwl_base_params iwl_dr_base_params = { - .eeprom_size = OTP_LOW_IMAGE_SIZE_32K, +static const struct iwl_family_base_params iwl_dr_base = { .num_of_queues = 512, .max_tfd_queue_size = 65536, .shadow_ram_support = true, @@ -46,87 +32,55 @@ static const struct iwl_base_params iwl_dr_base_params = { .max_event_log_size = 512, .shadow_reg_enable = true, .pcie_l1_allowed = true, + .smem_offset = IWL_DR_SMEM_OFFSET, + .smem_len = IWL_DR_SMEM_LEN, + .apmg_not_supported = true, + .mac_addr_from_csr = 0x30, + .min_umac_error_event_table = 0xD0000, + .d3_debug_data_base_addr = 0x401000, + .d3_debug_data_length = 60 * 1024, + .mon_smem_regs = { + .write_ptr = { + .addr = LDBG_M2S_BUF_WPTR, + .mask = LDBG_M2S_BUF_WPTR_VAL_MSK, + }, + .cycle_cnt = { + .addr = LDBG_M2S_BUF_WRAP_CNT, + .mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK, + }, + }, + .min_txq_size = 128, + .gp2_reg_addr = 0xd02c68, + .min_ba_txq_size = IWL_DEFAULT_QUEUE_SIZE_EHT, + .mon_dram_regs = { + .write_ptr = { + .addr = DBGC_CUR_DBGBUF_STATUS, + .mask = DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK, + }, + .cycle_cnt = { + .addr = DBGC_DBGBUF_WRAP_AROUND, + .mask = 0xffffffff, + }, + .cur_frag = { + .addr = DBGC_CUR_DBGBUF_STATUS, + .mask = DBGC_CUR_DBGBUF_STATUS_IDX_MSK, + }, + }, + .mon_dbgi_regs = { + .write_ptr = { + .addr = DBGI_SRAM_FIFO_POINTERS, + .mask = DBGI_SRAM_FIFO_POINTERS_WR_PTR_MSK, + }, + }, + .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, + .ucode_api_max = IWL_DR_UCODE_API_MAX, + .ucode_api_min = IWL_DR_UCODE_API_MIN, }; -#define IWL_DEVICE_DR_COMMON \ - .ucode_api_max = IWL_DR_UCODE_API_MAX, \ - .ucode_api_min = IWL_DR_UCODE_API_MIN, \ - .led_mode = IWL_LED_RF_STATE, \ - .nvm_hw_section_num = 10, \ - .non_shared_ant = ANT_B, \ - .dccm_offset = IWL_DR_DCCM_OFFSET, \ - .dccm_len = IWL_DR_DCCM_LEN, \ - .dccm2_offset = IWL_DR_DCCM2_OFFSET, \ - .dccm2_len = IWL_DR_DCCM2_LEN, \ - .smem_offset = IWL_DR_SMEM_OFFSET, \ - .smem_len = IWL_DR_SMEM_LEN, \ - .apmg_not_supported = true, \ - .trans.mq_rx_supported = true, \ - .vht_mu_mimo_supported = true, \ - .mac_addr_from_csr = 0x30, \ - .nvm_ver = IWL_DR_NVM_VERSION, \ - .trans.rf_id = true, \ - .trans.gen2 = true, \ - .nvm_type = IWL_NVM_EXT, \ - .dbgc_supported = true, \ - .min_umac_error_event_table = 0xD0000, \ - .d3_debug_data_base_addr = 0x401000, \ - .d3_debug_data_length = 60 * 1024, \ - .mon_smem_regs = { \ - .write_ptr = { \ - .addr = LDBG_M2S_BUF_WPTR, \ - .mask = LDBG_M2S_BUF_WPTR_VAL_MSK, \ - }, \ - .cycle_cnt = { \ - .addr = LDBG_M2S_BUF_WRAP_CNT, \ - .mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK, \ - }, \ - }, \ - .trans.umac_prph_offset = 0x300000, \ - .trans.device_family = IWL_DEVICE_FAMILY_DR, \ - .trans.base_params = &iwl_dr_base_params, \ - .min_txq_size = 128, \ - .gp2_reg_addr = 0xd02c68, \ - .min_ba_txq_size = IWL_DEFAULT_QUEUE_SIZE_EHT, \ - .mon_dram_regs = { \ - .write_ptr = { \ - .addr = DBGC_CUR_DBGBUF_STATUS, \ - .mask = DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK, \ - }, \ - .cycle_cnt = { \ - .addr = DBGC_DBGBUF_WRAP_AROUND, \ - .mask = 0xffffffff, \ - }, \ - .cur_frag = { \ - .addr = DBGC_CUR_DBGBUF_STATUS, \ - .mask = DBGC_CUR_DBGBUF_STATUS_IDX_MSK, \ - }, \ - }, \ - .mon_dbgi_regs = { \ - .write_ptr = { \ - .addr = DBGI_SRAM_FIFO_POINTERS, \ - .mask = DBGI_SRAM_FIFO_POINTERS_WR_PTR_MSK, \ - }, \ - } - -#define IWL_DEVICE_DR \ - IWL_DEVICE_DR_COMMON, \ - .uhb_supported = true, \ - .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \ - .num_rbds = IWL_NUM_RBDS_DR_EHT, \ - .ht_params = &iwl_bz_ht_params - -/* - * This size was picked according to 8 MSDUs inside 512 A-MSDUs in an - * A-MPDU, with additional overhead to account for processing time. - */ -#define IWL_NUM_RBDS_DR_EHT (512 * 16) - -const struct iwl_cfg_trans_params iwl_dr_trans_cfg = { +const struct iwl_mac_cfg iwl_dr_mac_cfg = { .device_family = IWL_DEVICE_FAMILY_DR, - .base_params = &iwl_dr_base_params, + .base = &iwl_dr_base, .mq_rx_supported = true, - .rf_id = true, .gen2 = true, .integrated = true, .umac_prph_offset = 0x300000, @@ -135,31 +89,5 @@ const struct iwl_cfg_trans_params iwl_dr_trans_cfg = { .ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US, }; -const char iwl_dr_name[] = "Intel(R) TBD Dr device"; - -const struct iwl_cfg iwl_cfg_dr = { - .fw_name_mac = "dr", - IWL_DEVICE_DR, -}; - -const struct iwl_cfg_trans_params iwl_br_trans_cfg = { - .device_family = IWL_DEVICE_FAMILY_DR, - .base_params = &iwl_dr_base_params, - .mq_rx_supported = true, - .rf_id = true, - .gen2 = true, - .umac_prph_offset = 0x300000, - .xtal_latency = 12000, - .low_latency_xtal = true, -}; - -const char iwl_br_name[] = "Intel(R) TBD Br device"; - -const struct iwl_cfg iwl_cfg_br = { - .fw_name_mac = "br", - IWL_DEVICE_DR, -}; - MODULE_FIRMWARE(IWL_DR_A_PE_A_FW_MODULE_FIRMWARE(IWL_DR_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL_BR_A_PET_A_FW_MODULE_FIRMWARE(IWL_DR_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL_BR_A_PE_A_FW_MODULE_FIRMWARE(IWL_DR_UCODE_API_MAX)); + diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/rf-fm.c b/drivers/net/wireless/intel/iwlwifi/cfg/rf-fm.c new file mode 100644 index 000000000000..456a666c8dfd --- /dev/null +++ b/drivers/net/wireless/intel/iwlwifi/cfg/rf-fm.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * Copyright (C) 2015-2017 Intel Deutschland GmbH + * Copyright (C) 2018-2025 Intel Corporation + */ +#include "iwl-config.h" + +/* NVM versions */ +#define IWL_FM_NVM_VERSION 0x0a1d + +#define IWL_DEVICE_FM \ + .ht_params = { \ + .stbc = true, \ + .ldpc = true, \ + .ht40_bands = BIT(NL80211_BAND_2GHZ) | \ + BIT(NL80211_BAND_5GHZ), \ + }, \ + .led_mode = IWL_LED_RF_STATE, \ + .non_shared_ant = ANT_B, \ + .vht_mu_mimo_supported = true, \ + .uhb_supported = true, \ + .num_rbds = IWL_NUM_RBDS_EHT, \ + .nvm_ver = IWL_FM_NVM_VERSION, \ + .nvm_type = IWL_NVM_EXT + +const struct iwl_rf_cfg iwl_rf_fm = { + IWL_DEVICE_FM, +}; + +const struct iwl_rf_cfg iwl_rf_fm_160mhz = { + IWL_DEVICE_FM, + .bw_limit = 160, +}; + +const char iwl_killer_be1750s_name[] = + "Killer(R) Wi-Fi 7 BE1750s 320MHz Wireless Network Adapter (BE201D2W)"; +const char iwl_killer_be1750i_name[] = + "Killer(R) Wi-Fi 7 BE1750i 320MHz Wireless Network Adapter (BE201NGW)"; +const char iwl_killer_be1750w_name[] = + "Killer(TM) Wi-Fi 7 BE1750w 320MHz Wireless Network Adapter (BE200D2W)"; +const char iwl_killer_be1750x_name[] = + "Killer(TM) Wi-Fi 7 BE1750x 320MHz Wireless Network Adapter (BE200NGW)"; +const char iwl_killer_be1790s_name[] = + "Killer(R) Wi-Fi 7 BE1790s 320MHz Wireless Network Adapter (BE401D2W)"; +const char iwl_killer_be1790i_name[] = + "Killer(R) Wi-Fi 7 BE1790i 320MHz Wireless Network Adapter (BE401NGW)"; + +const char iwl_be201_name[] = "Intel(R) Wi-Fi 7 BE201 320MHz"; +const char iwl_be200_name[] = "Intel(R) Wi-Fi 7 BE200 320MHz"; +const char iwl_be202_name[] = "Intel(R) Wi-Fi 7 BE202 160MHz"; +const char iwl_be401_name[] = "Intel(R) Wi-Fi 7 BE401 320MHz"; diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/rf-gf.c b/drivers/net/wireless/intel/iwlwifi/cfg/rf-gf.c new file mode 100644 index 000000000000..f55c286e83be --- /dev/null +++ b/drivers/net/wireless/intel/iwlwifi/cfg/rf-gf.c @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * Copyright (C) 2015-2017 Intel Deutschland GmbH + * Copyright (C) 2018-2025 Intel Corporation + */ +#include "iwl-config.h" + +/* NVM versions */ +#define IWL_GF_NVM_VERSION 0x0a1d + +const struct iwl_rf_cfg iwl_rf_gf = { + .uhb_supported = true, + .led_mode = IWL_LED_RF_STATE, + .non_shared_ant = ANT_B, + .vht_mu_mimo_supported = true, + .ht_params = { + .stbc = true, + .ldpc = true, + .ht40_bands = BIT(NL80211_BAND_2GHZ) | + BIT(NL80211_BAND_5GHZ), + }, + .nvm_ver = IWL_GF_NVM_VERSION, + .nvm_type = IWL_NVM_EXT, + .num_rbds = IWL_NUM_RBDS_HE, +}; + +const char iwl_ax210_killer_1675w_name[] = + "Killer(R) Wi-Fi 6E AX1675w 160MHz Wireless Network Adapter (210D2W)"; +const char iwl_ax210_killer_1675x_name[] = + "Killer(R) Wi-Fi 6E AX1675x 160MHz Wireless Network Adapter (210NGW)"; +const char iwl_ax211_killer_1675s_name[] = + "Killer(R) Wi-Fi 6E AX1675s 160MHz Wireless Network Adapter (211D2W)"; +const char iwl_ax211_killer_1675i_name[] = + "Killer(R) Wi-Fi 6E AX1675i 160MHz Wireless Network Adapter (211NGW)"; +const char iwl_ax411_killer_1690s_name[] = + "Killer(R) Wi-Fi 6E AX1690s 160MHz Wireless Network Adapter (411D2W)"; +const char iwl_ax411_killer_1690i_name[] = + "Killer(R) Wi-Fi 6E AX1690i 160MHz Wireless Network Adapter (411NGW)"; + +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"; diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/rf-hr.c b/drivers/net/wireless/intel/iwlwifi/cfg/rf-hr.c new file mode 100644 index 000000000000..db02664e3917 --- /dev/null +++ b/drivers/net/wireless/intel/iwlwifi/cfg/rf-hr.c @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * Copyright (C) 2015-2017 Intel Deutschland GmbH + * Copyright (C) 2018-2025 Intel Corporation + */ +#include "iwl-config.h" + +/* NVM versions */ +#define IWL_HR_NVM_VERSION 0x0a1d + +#define IWL_DEVICE_HR \ + .led_mode = IWL_LED_RF_STATE, \ + .non_shared_ant = ANT_B, \ + .vht_mu_mimo_supported = true, \ + .ht_params = { \ + .stbc = true, \ + .ldpc = true, \ + .ht40_bands = BIT(NL80211_BAND_2GHZ) | \ + BIT(NL80211_BAND_5GHZ), \ + }, \ + .num_rbds = IWL_NUM_RBDS_HE, \ + .nvm_ver = IWL_HR_NVM_VERSION, \ + .nvm_type = IWL_NVM_EXT + +const struct iwl_rf_cfg iwl_rf_hr1 = { + IWL_DEVICE_HR, + .tx_with_siso_diversity = true, +}; + +const struct iwl_rf_cfg iwl_rf_hr = { + IWL_DEVICE_HR, +}; + +const struct iwl_rf_cfg iwl_rf_hr_80mhz = { + IWL_DEVICE_HR, + .bw_limit = 80, +}; + +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"; diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/rf-jf.c b/drivers/net/wireless/intel/iwlwifi/cfg/rf-jf.c new file mode 100644 index 000000000000..467eaeae6deb --- /dev/null +++ b/drivers/net/wireless/intel/iwlwifi/cfg/rf-jf.c @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * Copyright (C) 2015-2017 Intel Deutschland GmbH + * Copyright (C) 2018-2021, 2023, 2025 Intel Corporation + */ +#include "iwl-config.h" + +/* NVM versions */ +#define IWL_JF_NVM_VERSION 0x0a1d + +/* Memory offsets and lengths */ +#define IWL9000_DCCM_OFFSET 0x800000 +#define IWL9000_DCCM_LEN 0x18000 +#define IWL9000_DCCM2_OFFSET 0x880000 +#define IWL9000_DCCM2_LEN 0x8000 + +static const struct iwl_tt_params iwl_jf_tt_params = { + .ct_kill_entry = 115, + .ct_kill_exit = 93, + .ct_kill_duration = 5, + .dynamic_smps_entry = 111, + .dynamic_smps_exit = 107, + .tx_protection_entry = 112, + .tx_protection_exit = 105, + .tx_backoff = { + {.temperature = 110, .backoff = 200}, + {.temperature = 111, .backoff = 600}, + {.temperature = 112, .backoff = 1200}, + {.temperature = 113, .backoff = 2000}, + {.temperature = 114, .backoff = 4000}, + }, + .support_ct_kill = true, + .support_dynamic_smps = true, + .support_tx_protection = true, + .support_tx_backoff = true, +}; + +/* these values are ignored if not with Pu/Th MAC firmware, due to offload */ +#define IWL_DEVICE_JF_PU \ + .dccm_offset = IWL9000_DCCM_OFFSET, \ + .dccm_len = IWL9000_DCCM_LEN, \ + .dccm2_offset = IWL9000_DCCM2_OFFSET, \ + .dccm2_len = IWL9000_DCCM2_LEN, \ + .thermal_params = &iwl_jf_tt_params + +#define IWL_DEVICE_JF \ + IWL_DEVICE_JF_PU, \ + .led_mode = IWL_LED_RF_STATE, \ + .non_shared_ant = ANT_B, \ + .num_rbds = IWL_NUM_RBDS_NON_HE, \ + .vht_mu_mimo_supported = true, \ + .ht_params = { \ + .stbc = true, \ + .ldpc = true, \ + .ht40_bands = BIT(NL80211_BAND_2GHZ) | \ + BIT(NL80211_BAND_5GHZ), \ + }, \ + .nvm_ver = IWL_JF_NVM_VERSION, \ + .nvm_type = IWL_NVM_EXT + +const struct iwl_rf_cfg iwl_rf_jf = { + IWL_DEVICE_JF, +}; + +const struct iwl_rf_cfg iwl_rf_jf_80mhz = { + IWL_DEVICE_JF, + .bw_limit = 80, +}; + +const char iwl9260_name[] = "Intel(R) Wireless-AC 9260"; +const char iwl9461_name[] = "Intel(R) Wireless-AC 9461"; +const char iwl9462_name[] = "Intel(R) Wireless-AC 9462"; +const char iwl9560_name[] = "Intel(R) Wireless-AC 9560"; +const char iwl9260_160_name[] = "Intel(R) Wireless-AC 9260 160MHz"; +const char iwl9461_160_name[] = "Intel(R) Wireless-AC 9461 160MHz"; +const char iwl9462_160_name[] = "Intel(R) Wireless-AC 9462 160MHz"; +const char iwl9560_160_name[] = "Intel(R) Wireless-AC 9560 160MHz"; + +const char iwl9260_killer_1550_name[] = + "Killer(R) Wireless-AC 1550 Wireless Network Adapter (9260NGW) 160MHz"; +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"; diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/rf-pe.c b/drivers/net/wireless/intel/iwlwifi/cfg/rf-pe.c new file mode 100644 index 000000000000..483f21659eff --- /dev/null +++ b/drivers/net/wireless/intel/iwlwifi/cfg/rf-pe.c @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * Copyright (C) 2025 Intel Corporation + */ +#include "iwl-config.h" + +/* currently iwl_rf_wh/iwl_rf_wh_160mhz are just defines for the FM ones */ + +const char iwl_killer_bn1850w2_name[] = + "Killer(R) Wi-Fi 8 BN1850w2 320MHz Wireless Network Adapter (BN201.D2W)"; +const char iwl_killer_bn1850i_name[] = + "Killer(R) Wi-Fi 8 BN1850i 320MHz Wireless Network Adapter (BN201.NGW)"; + +const char iwl_bn201_name[] = "Intel(R) Wi-Fi 8 BN201"; +const char iwl_be221_name[] = "Intel(R) Wi-Fi 7 BE221"; +const char iwl_be223_name[] = "Intel(R) Wi-Fi 7 BE223"; diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/rf-wh.c b/drivers/net/wireless/intel/iwlwifi/cfg/rf-wh.c new file mode 100644 index 000000000000..97735175cb0e --- /dev/null +++ b/drivers/net/wireless/intel/iwlwifi/cfg/rf-wh.c @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * Copyright (C) 2025 Intel Corporation + */ +#include "iwl-config.h" + +/* currently iwl_rf_wh/iwl_rf_wh_160mhz are just defines for the FM ones */ + +const char iwl_killer_be1775s_name[] = + "Killer(R) Wi-Fi 7 BE1775s 320MHz Wireless Network Adapter (BE211D2W)"; +const char iwl_killer_be1775i_name[] = + "Killer(R) Wi-Fi 7 BE1775i 320MHz Wireless Network Adapter (BE211NGW)"; + +const char iwl_be211_name[] = "Intel(R) Wi-Fi 7 BE211 320MHz"; +const char iwl_be213_name[] = "Intel(R) Wi-Fi 7 BE213 160MHz"; diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/sc.c b/drivers/net/wireless/intel/iwlwifi/cfg/sc.c index 59af36960f9c..b2e4d4035296 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/sc.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/sc.c @@ -10,19 +10,15 @@ #include "fw/api/txq.h" /* Highest firmware API version supported */ -#define IWL_SC_UCODE_API_MAX 98 +#define IWL_SC_UCODE_API_MAX 99 /* Lowest firmware API version supported */ -#define IWL_SC_UCODE_API_MIN 93 +#define IWL_SC_UCODE_API_MIN 97 /* NVM versions */ #define IWL_SC_NVM_VERSION 0x0a1d /* Memory offsets and lengths */ -#define IWL_SC_DCCM_OFFSET 0x800000 /* LMAC1 */ -#define IWL_SC_DCCM_LEN 0x10000 /* LMAC1 */ -#define IWL_SC_DCCM2_OFFSET 0x880000 -#define IWL_SC_DCCM2_LEN 0x8000 #define IWL_SC_SMEM_OFFSET 0x400000 #define IWL_SC_SMEM_LEN 0xD0000 @@ -43,8 +39,7 @@ #define IWL_SC_A_HR_B_FW_MODULE_FIRMWARE(api) \ IWL_SC_A_HR_B_FW_PRE "-" __stringify(api) ".ucode" -static const struct iwl_base_params iwl_sc_base_params = { - .eeprom_size = OTP_LOW_IMAGE_SIZE_32K, +static const struct iwl_family_base_params iwl_sc_base = { .num_of_queues = 512, .max_tfd_queue_size = 65536, .shadow_ram_support = true, @@ -53,87 +48,55 @@ static const struct iwl_base_params iwl_sc_base_params = { .max_event_log_size = 512, .shadow_reg_enable = true, .pcie_l1_allowed = true, + .smem_offset = IWL_SC_SMEM_OFFSET, + .smem_len = IWL_SC_SMEM_LEN, + .apmg_not_supported = true, + .mac_addr_from_csr = 0x30, + .min_umac_error_event_table = 0xD0000, + .d3_debug_data_base_addr = 0x401000, + .d3_debug_data_length = 60 * 1024, + .mon_smem_regs = { + .write_ptr = { + .addr = LDBG_M2S_BUF_WPTR, + .mask = LDBG_M2S_BUF_WPTR_VAL_MSK, + }, + .cycle_cnt = { + .addr = LDBG_M2S_BUF_WRAP_CNT, + .mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK, + }, + }, + .min_txq_size = 128, + .gp2_reg_addr = 0xd02c68, + .min_ba_txq_size = IWL_DEFAULT_QUEUE_SIZE_EHT, + .mon_dram_regs = { + .write_ptr = { + .addr = DBGC_CUR_DBGBUF_STATUS, + .mask = DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK, + }, + .cycle_cnt = { + .addr = DBGC_DBGBUF_WRAP_AROUND, + .mask = 0xffffffff, + }, + .cur_frag = { + .addr = DBGC_CUR_DBGBUF_STATUS, + .mask = DBGC_CUR_DBGBUF_STATUS_IDX_MSK, + }, + }, + .mon_dbgi_regs = { + .write_ptr = { + .addr = DBGI_SRAM_FIFO_POINTERS, + .mask = DBGI_SRAM_FIFO_POINTERS_WR_PTR_MSK, + }, + }, + .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, + .ucode_api_max = IWL_SC_UCODE_API_MAX, + .ucode_api_min = IWL_SC_UCODE_API_MIN, }; -#define IWL_DEVICE_BZ_COMMON \ - .ucode_api_max = IWL_SC_UCODE_API_MAX, \ - .ucode_api_min = IWL_SC_UCODE_API_MIN, \ - .led_mode = IWL_LED_RF_STATE, \ - .nvm_hw_section_num = 10, \ - .non_shared_ant = ANT_B, \ - .dccm_offset = IWL_SC_DCCM_OFFSET, \ - .dccm_len = IWL_SC_DCCM_LEN, \ - .dccm2_offset = IWL_SC_DCCM2_OFFSET, \ - .dccm2_len = IWL_SC_DCCM2_LEN, \ - .smem_offset = IWL_SC_SMEM_OFFSET, \ - .smem_len = IWL_SC_SMEM_LEN, \ - .apmg_not_supported = true, \ - .trans.mq_rx_supported = true, \ - .vht_mu_mimo_supported = true, \ - .mac_addr_from_csr = 0x30, \ - .nvm_ver = IWL_SC_NVM_VERSION, \ - .trans.rf_id = true, \ - .trans.gen2 = true, \ - .nvm_type = IWL_NVM_EXT, \ - .dbgc_supported = true, \ - .min_umac_error_event_table = 0xD0000, \ - .d3_debug_data_base_addr = 0x401000, \ - .d3_debug_data_length = 60 * 1024, \ - .mon_smem_regs = { \ - .write_ptr = { \ - .addr = LDBG_M2S_BUF_WPTR, \ - .mask = LDBG_M2S_BUF_WPTR_VAL_MSK, \ - }, \ - .cycle_cnt = { \ - .addr = LDBG_M2S_BUF_WRAP_CNT, \ - .mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK, \ - }, \ - }, \ - .trans.umac_prph_offset = 0x300000, \ - .trans.device_family = IWL_DEVICE_FAMILY_SC, \ - .trans.base_params = &iwl_sc_base_params, \ - .min_txq_size = 128, \ - .gp2_reg_addr = 0xd02c68, \ - .min_ba_txq_size = IWL_DEFAULT_QUEUE_SIZE_EHT, \ - .mon_dram_regs = { \ - .write_ptr = { \ - .addr = DBGC_CUR_DBGBUF_STATUS, \ - .mask = DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK, \ - }, \ - .cycle_cnt = { \ - .addr = DBGC_DBGBUF_WRAP_AROUND, \ - .mask = 0xffffffff, \ - }, \ - .cur_frag = { \ - .addr = DBGC_CUR_DBGBUF_STATUS, \ - .mask = DBGC_CUR_DBGBUF_STATUS_IDX_MSK, \ - }, \ - }, \ - .mon_dbgi_regs = { \ - .write_ptr = { \ - .addr = DBGI_SRAM_FIFO_POINTERS, \ - .mask = DBGI_SRAM_FIFO_POINTERS_WR_PTR_MSK, \ - }, \ - } - -#define IWL_DEVICE_SC \ - IWL_DEVICE_BZ_COMMON, \ - .uhb_supported = true, \ - .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \ - .num_rbds = IWL_NUM_RBDS_SC_EHT, \ - .ht_params = &iwl_bz_ht_params - -/* - * This size was picked according to 8 MSDUs inside 512 A-MSDUs in an - * A-MPDU, with additional overhead to account for processing time. - */ -#define IWL_NUM_RBDS_SC_EHT (512 * 16) - -const struct iwl_cfg_trans_params iwl_sc_trans_cfg = { +const struct iwl_mac_cfg iwl_sc_mac_cfg = { .device_family = IWL_DEVICE_FAMILY_SC, - .base_params = &iwl_sc_base_params, + .base = &iwl_sc_base, .mq_rx_supported = true, - .rf_id = true, .gen2 = true, .integrated = true, .umac_prph_offset = 0x300000, @@ -142,21 +105,6 @@ const struct iwl_cfg_trans_params iwl_sc_trans_cfg = { .ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US, }; -const struct iwl_cfg iwl_cfg_sc = { - .fw_name_mac = "sc", - IWL_DEVICE_SC, -}; - -const struct iwl_cfg iwl_cfg_sc2 = { - .fw_name_mac = "sc2", - IWL_DEVICE_SC, -}; - -const struct iwl_cfg iwl_cfg_sc2f = { - .fw_name_mac = "sc2f", - IWL_DEVICE_SC, -}; - 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)); diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/agn.h b/drivers/net/wireless/intel/iwlwifi/dvm/agn.h index a13add556a7b..1ebc7effcc2a 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/agn.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/agn.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2005-2014, 2021, 2024 Intel Corporation + * Copyright (C) 2005-2014, 2021, 2024-2025 Intel Corporation */ #ifndef __iwl_agn_h__ #define __iwl_agn_h__ @@ -399,7 +399,7 @@ static inline void iwl_dvm_set_pmi(struct iwl_priv *priv, bool state) * later with iwl_free_nvm_data(). */ struct iwl_nvm_data * -iwl_parse_eeprom_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, +iwl_parse_eeprom_data(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg, const u8 *eeprom, size_t eeprom_size); int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size); diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c index 2ed4b6e798ab..ec94c43ba28c 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. - * Copyright (C) 2018 Intel Corporation + * Copyright (C) 2018, 2025 Intel Corporation *****************************************************************************/ #include <linux/slab.h> @@ -2097,7 +2097,8 @@ static ssize_t iwl_dbgfs_protection_mode_read(struct file *file, char buf[40]; const size_t bufsz = sizeof(buf); - if (priv->cfg->ht_params) + /* HT devices also have at least one HT40 band */ + if (priv->cfg->ht_params.ht40_bands) pos += scnprintf(buf + pos, bufsz - pos, "use %s for aggregation\n", (priv->hw_params.use_rts_for_aggregation) ? @@ -2117,7 +2118,8 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file, int buf_size; int rts; - if (!priv->cfg->ht_params) + /* HT devices also have at least one HT40 band */ + if (!priv->cfg->ht_params.ht40_bands) return -EINVAL; memset(buf, 0, sizeof(buf)); diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/dev.h b/drivers/net/wireless/intel/iwlwifi/dvm/dev.h index 4ac8b862ad41..25b24820466d 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/dev.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/dev.h @@ -2,6 +2,7 @@ /****************************************************************************** * * Copyright(c) 2003 - 2014, 2020, 2023 Intel Corporation. All rights reserved. + * Copyright (C) 2025 Intel Corporation *****************************************************************************/ /* * Please use this file (dev.h) for driver implementation definitions. @@ -627,7 +628,7 @@ struct iwl_priv { struct iwl_trans *trans; struct device *dev; /* for debug prints only */ - const struct iwl_cfg *cfg; + const struct iwl_rf_cfg *cfg; const struct iwl_fw *fw; const struct iwl_dvm_cfg *lib; unsigned long status; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/devices.c b/drivers/net/wireless/intel/iwlwifi/dvm/devices.c index 48a8349680fc..3447ae0b160a 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/devices.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/devices.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. - * Copyright (C) 2019 Intel Corporation + * Copyright (C) 2019, 2025 Intel Corporation *****************************************************************************/ #include <linux/units.h> @@ -481,7 +481,7 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv) /* NIC configuration for 6000 series */ static void iwl6000_nic_config(struct iwl_priv *priv) { - switch (priv->trans->trans_cfg->device_family) { + switch (priv->trans->mac_cfg->device_family) { case IWL_DEVICE_FAMILY_6005: case IWL_DEVICE_FAMILY_6030: case IWL_DEVICE_FAMILY_6000: diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/eeprom.c b/drivers/net/wireless/intel/iwlwifi/dvm/eeprom.c index cdc05f7e75a6..2423125e5284 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/eeprom.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/eeprom.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2005-2014, 2018-2019, 2021, 2024 Intel Corporation + * Copyright (C) 2005-2014, 2018-2019, 2021, 2024-2025 Intel Corporation */ #include <linux/types.h> #include <linux/slab.h> @@ -151,7 +151,7 @@ static u16 iwl_eeprom_query16(const u8 *eeprom, size_t eeprom_size, int offset) { if (WARN_ON(offset + sizeof(u16) > eeprom_size)) return 0; - return le16_to_cpup((__le16 *)(eeprom + offset)); + return le16_to_cpup((const __le16 *)(eeprom + offset)); } static u32 eeprom_indirect_address(const u8 *eeprom, size_t eeprom_size, @@ -204,8 +204,8 @@ static u32 eeprom_indirect_address(const u8 *eeprom, size_t eeprom_size, return (address & ADDRESS_MSK) + (offset << 1); } -static const u8 *iwl_eeprom_query_addr(const u8 *eeprom, size_t eeprom_size, - u32 offset) +static const void *iwl_eeprom_query_addr(const u8 *eeprom, size_t eeprom_size, + u32 offset) { u32 address = eeprom_indirect_address(eeprom, eeprom_size, offset); @@ -218,10 +218,9 @@ static const u8 *iwl_eeprom_query_addr(const u8 *eeprom, size_t eeprom_size, static int iwl_eeprom_read_calib(const u8 *eeprom, size_t eeprom_size, struct iwl_nvm_data *data) { - struct iwl_eeprom_calib_hdr *hdr; + const struct iwl_eeprom_calib_hdr *hdr; - hdr = (void *)iwl_eeprom_query_addr(eeprom, eeprom_size, - EEPROM_CALIB_ALL); + hdr = iwl_eeprom_query_addr(eeprom, eeprom_size, EEPROM_CALIB_ALL); if (!hdr) return -ENODATA; data->calib_version = hdr->version; @@ -295,7 +294,7 @@ struct iwl_eeprom_enhanced_txpwr { } __packed; static s8 iwl_get_max_txpwr_half_dbm(const struct iwl_nvm_data *data, - struct iwl_eeprom_enhanced_txpwr *txp) + const struct iwl_eeprom_enhanced_txpwr *txp) { s8 result = 0; /* (.5 dBm) */ @@ -329,7 +328,7 @@ static s8 iwl_get_max_txpwr_half_dbm(const struct iwl_nvm_data *data, static void iwl_eeprom_enh_txp_read_element(struct iwl_nvm_data *data, - struct iwl_eeprom_enhanced_txpwr *txp, + const struct iwl_eeprom_enhanced_txpwr *txp, int n_channels, s8 max_txpower_avg) { int ch_idx; @@ -360,20 +359,18 @@ static void iwl_eeprom_enhanced_txpower(struct device *dev, const u8 *eeprom, size_t eeprom_size, int n_channels) { - struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; + const struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; int idx, entries; - __le16 *txp_len; + const __le16 *txp_len; s8 max_txp_avg_halfdbm; BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8); /* the length is in 16-bit words, but we want entries */ - txp_len = (__le16 *)iwl_eeprom_query_addr(eeprom, eeprom_size, - EEPROM_TXP_SZ_OFFS); + txp_len = iwl_eeprom_query_addr(eeprom, eeprom_size, EEPROM_TXP_SZ_OFFS); entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN; - txp_array = (void *)iwl_eeprom_query_addr(eeprom, eeprom_size, - EEPROM_TXP_OFFS); + txp_array = iwl_eeprom_query_addr(eeprom, eeprom_size, EEPROM_TXP_OFFS); for (idx = 0; idx < entries; idx++) { txp = &txp_array[idx]; @@ -416,7 +413,7 @@ static void iwl_eeprom_enhanced_txpower(struct device *dev, } } -static void iwl_init_band_reference(const struct iwl_cfg *cfg, +static void iwl_init_band_reference(const struct iwl_rf_cfg *cfg, const u8 *eeprom, size_t eeprom_size, int eeprom_band, int *eeprom_ch_count, const struct iwl_eeprom_channel **ch_info, @@ -426,7 +423,7 @@ static void iwl_init_band_reference(const struct iwl_cfg *cfg, offset |= INDIRECT_ADDRESS | INDIRECT_REGULATORY; - *ch_info = (void *)iwl_eeprom_query_addr(eeprom, eeprom_size, offset); + *ch_info = iwl_eeprom_query_addr(eeprom, eeprom_size, offset); switch (eeprom_band) { case 1: /* 2.4GHz band */ @@ -510,7 +507,7 @@ static void iwl_mod_ht40_chan_info(struct device *dev, #define CHECK_AND_PRINT_I(x) \ ((eeprom_ch_info[ch_idx].flags & EEPROM_CHANNEL_##x) ? # x " " : "") -static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, +static int iwl_init_channel_map(struct device *dev, const struct iwl_rf_cfg *cfg, struct iwl_nvm_data *data, const u8 *eeprom, size_t eeprom_size) { @@ -749,7 +746,7 @@ static int iwl_nvm_is_otp(struct iwl_trans *trans) u32 otpgp; /* OTP only valid for CP/PP and after */ - switch (trans->hw_rev & CSR_HW_REV_TYPE_MSK) { + switch (trans->info.hw_rev & CSR_HW_REV_TYPE_MSK) { case CSR_HW_REV_TYPE_NONE: IWL_ERR(trans, "Unknown hardware type\n"); return -EIO; @@ -784,7 +781,7 @@ static int iwl_init_otp_access(struct iwl_trans *trans) * CSR auto clock gate disable bit - * this is only applicable for HW with OTP shadow RAM */ - if (trans->trans_cfg->base_params->shadow_ram_support) + if (trans->mac_cfg->base->shadow_ram_support) iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG, CSR_RESET_LINK_PWR_MGMT_DISABLED); @@ -905,7 +902,7 @@ static int iwl_find_otp_image(struct iwl_trans *trans, } /* more in the link list, continue */ usedblocks++; - } while (usedblocks <= trans->trans_cfg->base_params->max_ll_items); + } while (usedblocks <= trans->mac_cfg->base->max_ll_items); /* OTP has no valid blocks */ IWL_DEBUG_EEPROM(trans->dev, "OTP has no valid blocks\n"); @@ -938,7 +935,7 @@ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size) if (nvm_is_otp < 0) return nvm_is_otp; - sz = trans->trans_cfg->base_params->eeprom_size; + sz = trans->mac_cfg->base->eeprom_size; IWL_DEBUG_EEPROM(trans->dev, "NVM size = %d\n", sz); e = kmalloc(sz, GFP_KERNEL); @@ -973,7 +970,7 @@ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size) CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); /* traversing the linked list if no shadow ram supported */ - if (!trans->trans_cfg->base_params->shadow_ram_support) { + if (!trans->mac_cfg->base->shadow_ram_support) { ret = iwl_find_otp_image(trans, &validblockaddr); if (ret) goto err_unlock; @@ -1027,7 +1024,7 @@ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size) return ret; } -static void iwl_init_sbands(struct iwl_trans *trans, const struct iwl_cfg *cfg, +static void iwl_init_sbands(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg, struct iwl_nvm_data *data, const u8 *eeprom, size_t eeprom_size) { @@ -1062,7 +1059,7 @@ static void iwl_init_sbands(struct iwl_trans *trans, const struct iwl_cfg *cfg, /* EEPROM data functions */ struct iwl_nvm_data * -iwl_parse_eeprom_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, +iwl_parse_eeprom_data(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg, const u8 *eeprom, size_t eeprom_size) { struct iwl_nvm_data *data; @@ -1098,14 +1095,14 @@ iwl_parse_eeprom_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, EEPROM_RAW_TEMPERATURE); if (!tmp) goto err_free; - data->raw_temperature = *(__le16 *)tmp; + data->raw_temperature = *(const __le16 *)tmp; tmp = iwl_eeprom_query_addr(eeprom, eeprom_size, EEPROM_KELVIN_TEMPERATURE); if (!tmp) goto err_free; - data->kelvin_temperature = *(__le16 *)tmp; - data->kelvin_voltage = *((__le16 *)tmp + 1); + data->kelvin_temperature = *(const __le16 *)tmp; + data->kelvin_voltage = *((const __le16 *)tmp + 1); radio_cfg = iwl_eeprom_query16(eeprom, eeprom_size, EEPROM_RADIO_CONFIG); diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/led.c b/drivers/net/wireless/intel/iwlwifi/dvm/led.c index 5ca85d90a8d6..cec2ebdfd651 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/led.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/led.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. - * Copyright (C) 2019 Intel Corporation + * Copyright (C) 2019, 2025 Intel Corporation *****************************************************************************/ @@ -116,9 +116,9 @@ static int iwl_led_cmd(struct iwl_priv *priv, } led_cmd.on = iwl_blink_compensation(priv, on, - priv->trans->trans_cfg->base_params->led_compensation); + priv->trans->mac_cfg->base->led_compensation); led_cmd.off = iwl_blink_compensation(priv, off, - priv->trans->trans_cfg->base_params->led_compensation); + priv->trans->mac_cfg->base->led_compensation); ret = iwl_send_led_cmd(priv, &led_cmd); if (!ret) { diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c index 56d19a034c24..0771a46bd552 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. - * Copyright(C) 2018 - 2019, 2022 - 2024 Intel Corporation + * Copyright(C) 2018 - 2019, 2022 - 2025 Intel Corporation * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. @@ -96,7 +96,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); ieee80211_hw_set(hw, WANT_MONITOR_VIF); - if (priv->trans->max_skb_frags) + if (priv->trans->info.max_skb_frags) hw->netdev_features = NETIF_F_HIGHDMA | NETIF_F_SG; hw->offchannel_tx_hw_queue = IWL_AUX_QUEUE; @@ -188,7 +188,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, priv->hw->wiphy->bands[NL80211_BAND_5GHZ] = &priv->nvm_data->bands[NL80211_BAND_5GHZ]; - hw->wiphy->hw_version = priv->trans->hw_id; + hw->wiphy->hw_version = priv->trans->info.hw_id; iwl_leds_init(priv); @@ -549,7 +549,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) iwlagn_prepare_restart(priv); - memset((void *)&ctx->active, 0, sizeof(ctx->active)); + memset((void *)(uintptr_t)&ctx->active, 0, sizeof(ctx->active)); iwl_connection_init_rx_config(priv, ctx); iwlagn_set_rxon_chain(priv, ctx); @@ -1091,7 +1091,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, goto done; } - scd_queues = BIT(priv->trans->trans_cfg->base_params->num_of_queues) - 1; + scd_queues = BIT(priv->trans->mac_cfg->base->num_of_queues) - 1; scd_queues &= ~(BIT(IWL_IPAN_CMD_QUEUE_NUM) | BIT(IWL_DEFAULT_CMD_QUEUE_NUM)); diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c index a27a72cc017a..1d619384c629 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Copyright(c) 2003 - 2014, 2018 - 2022 Intel Corporation. All rights reserved. - * Copyright(c) 2024 Intel Corporation. All rights reserved. + * Copyright(c) 2024-2025 Intel Corporation. All rights reserved. * Copyright(c) 2015 Intel Deutschland GmbH * * Portions of this file are derived from the ipw3945 project, as well @@ -824,11 +824,11 @@ int iwl_alive_start(struct iwl_priv *priv) iwlagn_send_tx_ant_config(priv, priv->nvm_data->valid_tx_ant); if (iwl_is_associated_ctx(ctx) && !priv->wowlan) { - struct iwl_rxon_cmd *active_rxon = - (struct iwl_rxon_cmd *)&ctx->active; + struct iwl_rxon_cmd *active = (void *)(uintptr_t)&ctx->active; + /* apply any changes in staging */ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; + active->filter_flags &= ~RXON_FILTER_ASSOC_MSK; } else { struct iwl_rxon_context *tmp; /* Initialize our rx_config data */ @@ -1137,9 +1137,10 @@ static void iwl_uninit_drv(struct iwl_priv *priv) static void iwl_set_hw_params(struct iwl_priv *priv) { - if (priv->cfg->ht_params) + /* there are no devices with HT but without HT40 on all bands */ + if (priv->cfg->ht_params.ht40_bands) priv->hw_params.use_rts_for_aggregation = - priv->cfg->ht_params->use_rts_for_aggregation; + priv->cfg->ht_params.use_rts_for_aggregation; /* Device-specific setup */ priv->lib->set_hw_params(priv); @@ -1173,8 +1174,9 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) { struct iwl_nvm_data *data = priv->nvm_data; + /* all HT devices also have HT40 on at least one band */ if (data->sku_cap_11n_enable && - !priv->cfg->ht_params) { + !priv->cfg->ht_params.ht40_bands) { IWL_ERR(priv, "Invalid 11n configuration\n"); return -EINVAL; } @@ -1224,7 +1226,7 @@ static int iwl_nvm_check_version(struct iwl_nvm_data *data, } static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, - const struct iwl_cfg *cfg, + const struct iwl_rf_cfg *cfg, const struct iwl_fw *fw, struct dentry *dbgfs_dir) { @@ -1233,7 +1235,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, struct iwl_op_mode *op_mode; u16 num_mac; u32 ucode_flags; - struct iwl_trans_config trans_cfg = {}; static const u8 no_reclaim_cmds[] = { REPLY_RX_PHY_CMD, REPLY_RX_MPDU_CMD, @@ -1248,7 +1249,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, ************************/ hw = iwl_alloc_all(); if (!hw) { - pr_err("%s: Cannot allocate network device\n", trans->name); + pr_err("%s: Cannot allocate network device\n", + trans->info.name); err = -ENOMEM; goto out; } @@ -1261,7 +1263,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, priv->cfg = cfg; priv->fw = fw; - switch (priv->trans->trans_cfg->device_family) { + switch (priv->trans->mac_cfg->device_family) { case IWL_DEVICE_FAMILY_1000: case IWL_DEVICE_FAMILY_100: priv->lib = &iwl_dvm_1000_cfg; @@ -1309,52 +1311,50 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, * Populate the state variables that the transport layer needs * to know about. */ - trans_cfg.op_mode = op_mode; - trans_cfg.no_reclaim_cmds = no_reclaim_cmds; - trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); + BUILD_BUG_ON(sizeof(no_reclaim_cmds) > + sizeof(trans->conf.no_reclaim_cmds)); + memcpy(trans->conf.no_reclaim_cmds, no_reclaim_cmds, + sizeof(no_reclaim_cmds)); switch (iwlwifi_mod_params.amsdu_size) { case IWL_AMSDU_DEF: case IWL_AMSDU_4K: - trans_cfg.rx_buf_size = IWL_AMSDU_4K; + trans->conf.rx_buf_size = IWL_AMSDU_4K; break; case IWL_AMSDU_8K: - trans_cfg.rx_buf_size = IWL_AMSDU_8K; + trans->conf.rx_buf_size = IWL_AMSDU_8K; break; case IWL_AMSDU_12K: default: - trans_cfg.rx_buf_size = IWL_AMSDU_4K; + trans->conf.rx_buf_size = IWL_AMSDU_4K; pr_err("Unsupported amsdu_size: %d\n", iwlwifi_mod_params.amsdu_size); } - trans_cfg.command_groups = iwl_dvm_groups; - trans_cfg.command_groups_size = ARRAY_SIZE(iwl_dvm_groups); + trans->conf.command_groups = iwl_dvm_groups; + trans->conf.command_groups_size = ARRAY_SIZE(iwl_dvm_groups); - trans_cfg.cmd_fifo = IWLAGN_CMD_FIFO_NUM; - trans_cfg.cb_data_offs = offsetof(struct ieee80211_tx_info, - driver_data[2]); + trans->conf.cmd_fifo = IWLAGN_CMD_FIFO_NUM; + trans->conf.cb_data_offs = offsetof(struct ieee80211_tx_info, + driver_data[2]); WARN_ON(sizeof(priv->transport_queue_stop) * BITS_PER_BYTE < - priv->trans->trans_cfg->base_params->num_of_queues); + priv->trans->mac_cfg->base->num_of_queues); ucode_flags = fw->ucode_capa.flags; if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) { priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; - trans_cfg.cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; + trans->conf.cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; } else { priv->sta_key_max_num = STA_KEY_MAX_NUM; - trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; + trans->conf.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; } - /* Configure transport layer */ - iwl_trans_configure(priv->trans, &trans_cfg); + trans->conf.rx_mpdu_cmd = REPLY_RX_MPDU_CMD; + trans->conf.rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start); - trans->rx_mpdu_cmd = REPLY_RX_MPDU_CMD; - trans->rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start); - trans->command_groups = trans_cfg.command_groups; - trans->command_groups_size = trans_cfg.command_groups_size; + iwl_trans_op_mode_enter(priv->trans, op_mode); /* At this point both hw and priv are allocated. */ @@ -1378,18 +1378,18 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, * 2. Read REV register ***********************/ IWL_INFO(priv, "Detected %s, REV=0x%X\n", - priv->trans->name, priv->trans->hw_rev); + priv->trans->info.name, priv->trans->info.hw_rev); err = iwl_trans_start_hw(priv->trans); if (err) - goto out_free_hw; + goto out_leave_trans; /* Read the EEPROM */ err = iwl_read_eeprom(priv->trans, &priv->eeprom_blob, &priv->eeprom_blob_size); if (err) { IWL_ERR(priv, "Unable to init EEPROM\n"); - goto out_free_hw; + goto out_leave_trans; } /* Reset chip to save power until we load uCode during "up". */ @@ -1437,10 +1437,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, * packaging bug or due to the eeprom check above */ priv->sta_key_max_num = STA_KEY_MAX_NUM; - trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; - - /* Configure transport layer again*/ - iwl_trans_configure(priv->trans, &trans_cfg); + trans->conf.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; } /******************* @@ -1508,6 +1505,8 @@ out_free_eeprom_blob: kfree(priv->eeprom_blob); out_free_eeprom: kfree(priv->nvm_data); +out_leave_trans: + iwl_trans_op_mode_leave(priv->trans); out_free_hw: ieee80211_free_hw(priv->hw); out: @@ -1992,7 +1991,7 @@ static void iwl_nic_config(struct iwl_op_mode *op_mode) /* SKU Control */ iwl_trans_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP_DASH, - CSR_HW_REV_STEP_DASH(priv->trans->hw_rev)); + CSR_HW_REV_STEP_DASH(priv->trans->info.hw_rev)); /* write radio config values to register */ if (priv->nvm_data->radio_cfg_type <= EEPROM_RF_CONFIG_TYPE_MAX) { diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/power.c b/drivers/net/wireless/intel/iwlwifi/dvm/power.c index 6d16a7105656..6b42d6e5f30f 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/power.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/power.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. - * Copyright (C) 2019 Intel Corporation + * Copyright (C) 2019, 2025 Intel Corporation * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. @@ -64,32 +64,32 @@ struct iwl_power_vec_entry { /* for DTIM period 0 through IWL_DTIM_RANGE_0_MAX */ /* DTIM 0 - 2 */ static const struct iwl_power_vec_entry range_0[IWL_POWER_NUM] = { - {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 1, 2, 2, 0xFF)}, 0}, - {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0}, - {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 2, 2, 2, 0xFF)}, 0}, - {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 2, 4, 4, 0xFF)}, 1}, - {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 2, 4, 6, 0xFF)}, 2} + {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 1, 2, 2, 0xFF), 0}, 0}, + {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF), 0}, 0}, + {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 2, 2, 2, 0xFF), 0}, 0}, + {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 2, 4, 4, 0xFF), 0}, 1}, + {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 2, 4, 6, 0xFF), 0}, 2} }; /* for DTIM period IWL_DTIM_RANGE_0_MAX + 1 through IWL_DTIM_RANGE_1_MAX */ /* DTIM 3 - 10 */ static const struct iwl_power_vec_entry range_1[IWL_POWER_NUM] = { - {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0}, - {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0}, - {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 4, 6, 7, 9)}, 0}, - {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 4, 6, 9, 10)}, 1}, - {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 6, 10, 10)}, 2} + {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4), 0}, 0}, + {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7), 0}, 0}, + {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 4, 6, 7, 9), 0}, 0}, + {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 4, 6, 9, 10), 0}, 1}, + {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 6, 10, 10), 0}, 2} }; /* for DTIM period > IWL_DTIM_RANGE_1_MAX */ /* DTIM 11 - */ static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = { - {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0}, - {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0}, - {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0}, - {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0}, - {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0} + {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF), 0}, 0}, + {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF), 0}, 0}, + {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 7, 9, 9, 0xFF), 0}, 0}, + {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 7, 9, 9, 0xFF), 0}, 0}, + {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF), 0}, 0} }; /* advance power management */ @@ -196,7 +196,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, else cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK; - if (priv->trans->trans_cfg->base_params->shadow_reg_enable) + if (priv->trans->mac_cfg->base->shadow_reg_enable) cmd->flags |= IWL_POWER_SHADOW_REG_ENA; else cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rx.c b/drivers/net/wireless/intel/iwlwifi/dvm/rx.c index 7f67e602940c..5f8b60824043 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/rx.c @@ -3,7 +3,7 @@ * * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2015 Intel Deutschland GmbH - * Copyright(c) 2018, 2020-2021 Intel Corporation + * Copyright(c) 2018, 2020-2021, 2025 Intel Corporation * * Portions of this file are derived from the ipw3945 project, as well * as portionhelp of the ieee80211 subsystem header files. @@ -50,7 +50,7 @@ static void iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb) * See iwlagn_mac_channel_switch. */ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - struct iwl_rxon_cmd *rxon = (void *)&ctx->active; + struct iwl_rxon_cmd *rxon = (void *)(uintptr_t)&ctx->active; if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) return; @@ -643,8 +643,8 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, fraglen = len - hdrlen; if (fraglen) { - int offset = (void *)hdr + hdrlen - - rxb_addr(rxb) + rxb_offset(rxb); + int offset = (u8 *)hdr + hdrlen - + (u8 *)rxb_addr(rxb) + rxb_offset(rxb); skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset, fraglen, rxb->truesize); diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c b/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c index f80cce37e2c0..2d3c1627f283 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /****************************************************************************** * - * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2014, 2025 Intel Corporation. All rights reserved. * Copyright(c) 2015 Intel Deutschland GmbH *****************************************************************************/ @@ -341,7 +341,7 @@ static int iwlagn_rxon_disconn(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { int ret; - struct iwl_rxon_cmd *active = (void *)&ctx->active; + struct iwl_rxon_cmd *active = (void *)(uintptr_t)&ctx->active; if (ctx->ctxid == IWL_RXON_CTX_BSS) { ret = iwlagn_disable_bss(priv, ctx, &ctx->staging); @@ -441,7 +441,7 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { int ret; - struct iwl_rxon_cmd *active = (void *)&ctx->active; + struct iwl_rxon_cmd *active = (void *)(uintptr_t)&ctx->active; /* RXON timing must be before associated RXON */ if (ctx->ctxid == IWL_RXON_CTX_BSS) { @@ -1023,7 +1023,7 @@ static void iwl_calc_basic_rates(struct iwl_priv *priv, int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { /* cast away the const for active_rxon in this function */ - struct iwl_rxon_cmd *active = (void *)&ctx->active; + struct iwl_rxon_cmd *active = (void *)(uintptr_t)&ctx->active; bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); int ret; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c index 111ed1873006..24fefa0e8148 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c @@ -3,7 +3,7 @@ * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. * Copyright (C) 2019 Intel Corporation - * Copyright (C) 2023 Intel Corporation + * Copyright (C) 2023, 2025 Intel Corporation *****************************************************************************/ #include <linux/kernel.h> @@ -463,7 +463,7 @@ static int iwlagn_alloc_agg_txq(struct iwl_priv *priv, int mq) int q; for (q = IWLAGN_FIRST_AMPDU_QUEUE; - q < priv->trans->trans_cfg->base_params->num_of_queues; q++) { + q < priv->trans->mac_cfg->base->num_of_queues; q++) { if (!test_and_set_bit(q, priv->agg_q_alloc)) { priv->queue_to_mac80211[q] = mq; return q; @@ -1277,7 +1277,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, * (in Tx queue's circular buffer) of first TFD/frame in window */ u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); - if (scd_flow >= priv->trans->trans_cfg->base_params->num_of_queues) { + if (scd_flow >= priv->trans->mac_cfg->base->num_of_queues) { IWL_ERR(priv, "BUG_ON scd_flow is bigger than number of queues\n"); return; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c b/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c index bb13ca5d666c..ac90191a3973 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c @@ -3,6 +3,7 @@ * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2015 Intel Deutschland GmbH + * Copyright (C) 2025 Intel Corporation *****************************************************************************/ #include <linux/kernel.h> @@ -222,7 +223,7 @@ static int iwl_alive_notify(struct iwl_priv *priv) int ret; int i; - iwl_trans_fw_alive(priv->trans, 0); + iwl_trans_fw_alive(priv->trans); if (priv->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN && priv->nvm_data->sku_cap_ipan_enable) { @@ -293,15 +294,10 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, { struct iwl_notification_wait alive_wait; struct iwl_alive_data alive_data; - const struct fw_img *fw; int ret; enum iwl_ucode_type old_type; static const u16 alive_cmd[] = { REPLY_ALIVE }; - fw = iwl_get_ucode_image(priv->fw, ucode_type); - if (WARN_ON(!fw)) - return -EINVAL; - old_type = priv->cur_ucode; priv->cur_ucode = ucode_type; priv->ucode_loaded = false; @@ -310,7 +306,7 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, alive_cmd, ARRAY_SIZE(alive_cmd), iwl_alive_fn, &alive_data); - ret = iwl_trans_start_fw(priv->trans, fw, false); + ret = iwl_trans_start_fw(priv->trans, priv->fw, ucode_type, false); if (ret) { priv->cur_ucode = old_type; iwl_remove_notification(&priv->notif_wait, &alive_wait); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c index efa7b673ebc7..bee7d92293b8 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2019-2024 Intel Corporation + * Copyright (C) 2019-2025 Intel Corporation */ #include <linux/uuid.h> #include "iwl-drv.h" @@ -847,12 +847,12 @@ int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt) if (IS_ERR(data)) return PTR_ERR(data); - /* try to read ppag table rev 3, 2 or 1 (all have the same data size) */ + /* try to read ppag table rev 1 to 4 (all have the same data size) */ wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data, ACPI_PPAG_WIFI_DATA_SIZE_V2, &tbl_rev); if (!IS_ERR(wifi_pkg)) { - if (tbl_rev >= 1 && tbl_rev <= 3) { + if (tbl_rev >= 1 && tbl_rev <= 4) { num_sub_bands = IWL_NUM_SUB_BANDS_V2; IWL_DEBUG_RADIO(fwrt, "Reading PPAG table (tbl_rev=%d)\n", @@ -882,7 +882,7 @@ int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt) goto out_free; read_table: - fwrt->ppag_ver = tbl_rev; + fwrt->ppag_bios_rev = tbl_rev; flags = &wifi_pkg->package.elements[1]; if (flags->type != ACPI_TYPE_INTEGER) { @@ -891,7 +891,7 @@ read_table: } fwrt->ppag_flags = iwl_bios_get_ppag_flags(flags->integer.value, - fwrt->ppag_ver); + fwrt->ppag_bios_rev); /* * read, verify gain values and save them into the PPAG table. @@ -912,6 +912,7 @@ read_table: } } + fwrt->ppag_bios_source = BIOS_SOURCE_ACPI; ret = 0; out_free: @@ -919,40 +920,39 @@ out_free: return ret; } -void iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt, - struct iwl_phy_specific_cfg *filters) +int iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt) { + struct iwl_phy_specific_cfg *filters = &fwrt->phy_filters; struct iwl_phy_specific_cfg tmp = {}; - union acpi_object *wifi_pkg, *data; + union acpi_object *wifi_pkg, *data __free(kfree); int tbl_rev, i; data = iwl_acpi_get_object(fwrt->dev, ACPI_WPFC_METHOD); if (IS_ERR(data)) - return; + return PTR_ERR(data); wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data, ACPI_WPFC_WIFI_DATA_SIZE, &tbl_rev); if (IS_ERR(wifi_pkg)) - goto out_free; + return PTR_ERR(wifi_pkg); if (tbl_rev != 0) - goto out_free; + return -EINVAL; BUILD_BUG_ON(ARRAY_SIZE(filters->filter_cfg_chains) != ACPI_WPFC_WIFI_DATA_SIZE - 1); for (i = 0; i < ARRAY_SIZE(filters->filter_cfg_chains); i++) { if (wifi_pkg->package.elements[i + 1].type != ACPI_TYPE_INTEGER) - goto out_free; + return -EINVAL; tmp.filter_cfg_chains[i] = cpu_to_le32(wifi_pkg->package.elements[i + 1].integer.value); } IWL_DEBUG_RADIO(fwrt, "Loaded WPFC filter config from ACPI\n"); *filters = tmp; -out_free: - kfree(data); + return 0; } IWL_EXPORT_SYMBOL(iwl_acpi_get_phy_filters); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h index e50b93472dd2..68d8fb5f6357 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2018-2023 Intel Corporation + * Copyright (C) 2018-2023, 2025 Intel Corporation */ #ifndef __iwl_fw_acpi__ #define __iwl_fw_acpi__ @@ -180,8 +180,7 @@ int iwl_acpi_get_tas_table(struct iwl_fw_runtime *fwrt, int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt); -void iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt, - struct iwl_phy_specific_cfg *filters); +int iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt); void iwl_acpi_get_guid_lock_status(struct iwl_fw_runtime *fwrt); @@ -244,8 +243,10 @@ static inline int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt) return -ENOENT; } -/* macro since the second argument doesn't always exist */ -#define iwl_acpi_get_phy_filters(fwrt, filters) do { } while (0) +static inline int iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt) +{ + return -ENOENT; +} static inline void iwl_acpi_get_guid_lock_status(struct iwl_fw_runtime *fwrt) { diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h b/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h index 42360a8f23aa..3ce477c248ce 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h @@ -112,6 +112,16 @@ struct iwl_alive_ntf_v6 { struct iwl_imr_alive_info imr; } __packed; /* UCODE_ALIVE_NTFY_API_S_VER_6 */ +struct iwl_alive_ntf { + __le16 status; + __le16 flags; + struct iwl_lmac_alive lmac_data[2]; + struct iwl_umac_alive umac_data; + struct iwl_sku_id sku_id; + struct iwl_imr_alive_info imr; + __le64 platform_id; +} __packed; /* UCODE_ALIVE_NTFY_API_S_VER_8 */ + /** * enum iwl_extended_cfg_flags - commands driver may send before * finishing init flow diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h index d43adb6f9220..1c86a858aaab 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH - * Copyright (C) 2018-2022, 2024 Intel Corporation + * Copyright (C) 2018-2022, 2024-2025 Intel Corporation */ #ifndef __iwl_fw_api_commands_h__ #define __iwl_fw_api_commands_h__ @@ -145,8 +145,8 @@ enum iwl_legacy_cmds { REMOVE_STA = 0x19, /** - * @TX_CMD: uses &struct iwl_tx_cmd or &struct iwl_tx_cmd_gen2 or - * &struct iwl_tx_cmd_gen3, + * @TX_CMD: uses &struct iwl_tx_cmd_v6 or &struct iwl_tx_cmd_v9 or + * &struct iwl_tx_cmd, * response in &struct iwl_tx_resp or * &struct iwl_tx_resp_v3 */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h b/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h index c139b965980d..9c88bb280609 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h @@ -98,7 +98,7 @@ enum iwl_data_path_subcmd_ids { /** * @ESR_MODE_NOTIF: notification to recommend/force a wanted esr mode, - * uses &struct iwl_esr_mode_notif + * uses &struct iwl_esr_mode_notif or &struct iwl_esr_mode_notif_v1 */ ESR_MODE_NOTIF = 0xF3, diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h index 4fab6c66994e..3173fa96cb48 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h @@ -527,8 +527,8 @@ enum iwl_fw_ini_time_point { * @IWL_FW_INI_APPLY_POLICY_OVERRIDE_DATA: override trigger data. * Append otherwise * @IWL_FW_INI_APPLY_POLICY_DUMP_COMPLETE_CMD: send cmd once dump collected - * @IWL_FW_INI_APPLY_POLICY_RESET_HANDSHAKE: perform reset handshake and - * split dump to before/after with region marking + * @IWL_FW_INI_APPLY_POLICY_SPLIT_DUMP_RESET: split this dump into regions + * before and after the reset handshake */ enum iwl_fw_ini_trigger_apply_policy { IWL_FW_INI_APPLY_POLICY_MATCH_TIME_POINT = BIT(0), @@ -537,7 +537,7 @@ enum iwl_fw_ini_trigger_apply_policy { IWL_FW_INI_APPLY_POLICY_OVERRIDE_CFG = BIT(9), IWL_FW_INI_APPLY_POLICY_OVERRIDE_DATA = BIT(10), IWL_FW_INI_APPLY_POLICY_DUMP_COMPLETE_CMD = BIT(16), - IWL_FW_INI_APPLY_POLICY_RESET_HANDSHAKE = BIT(17), + IWL_FW_INI_APPLY_POLICY_SPLIT_DUMP_RESET = BIT(17), }; /** @@ -560,7 +560,7 @@ enum iwl_fw_ini_trigger_reset_fw_policy { * @IWL_FW_INI_DEBUG_DUMP_POLICY_MAX_LIMIT_600KB: mini dump only 600KB region dump * @IWL_FW_IWL_DEBUG_DUMP_POLICY_MAX_LIMIT_5MB: mini dump 5MB size dump * @IWL_FW_IWL_DEBUG_DUMP_POLICY_BEFORE_RESET: dump this region before reset - * handshake (if requested by %IWL_FW_INI_APPLY_POLICY_RESET_HANDSHAKE) + * handshake (if requested by %IWL_FW_INI_APPLY_POLICY_SPLIT_DUMP_RESET) */ enum iwl_fw_ini_dump_policy { IWL_FW_INI_DEBUG_DUMP_POLICY_NO_LIMIT = BIT(0), diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h index e1952fc6d149..33541f92c7c7 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h @@ -6,6 +6,11 @@ */ #ifndef __iwl_fw_api_location_h__ #define __iwl_fw_api_location_h__ +#include <linux/ieee80211.h> +#include <linux/if_ether.h> +#include <linux/types.h> +#include <linux/bits.h> +#include "rs.h" /** * enum iwl_location_subcmd_ids - location group command IDs @@ -1609,7 +1614,7 @@ struct iwl_tof_range_rsp_ap_entry_ntfy_v5 { } __packed; /* LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_5 */ /** - * struct iwl_tof_range_rsp_ap_entry_ntfy - AP parameters (response) + * struct iwl_tof_range_rsp_ap_entry_ntfy_v7 - AP parameters (response) * @bssid: BSSID of the AP * @measure_status: current APs measurement status, one of * &enum iwl_tof_entry_status. @@ -1645,7 +1650,7 @@ struct iwl_tof_range_rsp_ap_entry_ntfy_v5 { * @tx_pn: the last PN used for this responder Tx in case PMF is configured in * LE byte order. */ -struct iwl_tof_range_rsp_ap_entry_ntfy { +struct iwl_tof_range_rsp_ap_entry_ntfy_v7 { u8 bssid[ETH_ALEN]; u8 measure_status; u8 measure_bw; @@ -1672,6 +1677,65 @@ struct iwl_tof_range_rsp_ap_entry_ntfy { } __packed; /* LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_6, LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_7 */ +/** + * struct iwl_tof_range_rsp_ap_entry_ntfy - AP parameters (response) + * @bssid: BSSID of the AP + * @measure_status: current APs measurement status, one of + * &enum iwl_tof_entry_status. + * @measure_bw: Current AP Bandwidth: 0 20MHz, 1 40MHz, 2 80MHz + * @rtt: The Round Trip Time that took for the last measurement for + * current AP [pSec] + * @rtt_variance: The Variance of the RTT values measured for current AP + * @rtt_spread: The Difference between the maximum and the minimum RTT + * values measured for current AP in the current session [pSec] + * @rssi: RSSI as uploaded in the Channel Estimation notification + * @rssi_spread: The Difference between the maximum and the minimum RSSI values + * measured for current AP in the current session + * @last_burst: 1 if no more FTM sessions are scheduled for this responder + * @refusal_period: refusal period in case of + * @IWL_TOF_ENTRY_RESPONDER_CANNOT_COLABORATE [sec] + * @timestamp: The GP2 Clock [usec] where Channel Estimation notification was + * uploaded by the LMAC + * @start_tsf: measurement start time in TSF of the mac specified in the range + * request + * @reserved1: reserved, for backwards compatibility + * @t2t3_initiator: as calculated from the algo in the initiator + * @t1t4_responder: as calculated from the algo in the responder + * @common_calib: Calib val that was used in for this AP measurement + * @specific_calib: val that was used in for this AP measurement + * @papd_calib_output: The result of the tof papd calibration that was injected + * into the algorithm. + * @rttConfidence: a value between 0 - 31 that represents the rtt accuracy. + * @reserved: for alignment + * @rx_pn: the last PN used for this responder Rx in case PMF is configured in + * LE byte order. + * @tx_pn: the last PN used for this responder Tx in case PMF is configured in + * LE byte order. + */ +struct iwl_tof_range_rsp_ap_entry_ntfy { + u8 bssid[ETH_ALEN]; + u8 measure_status; + u8 measure_bw; + __le32 rtt; + __le32 rtt_variance; + __le32 rtt_spread; + s8 rssi; + u8 rssi_spread; + u8 last_burst; + u8 refusal_period; + __le32 timestamp; + __le32 start_tsf; + __le32 reserved1[2]; + __le32 t2t3_initiator; + __le32 t1t4_responder; + __le16 common_calib; + __le16 specific_calib; + __le32 papd_calib_output; + u8 rttConfidence; + u8 reserved[3]; + u8 rx_pn[IEEE80211_CCMP_PN_LEN]; + u8 tx_pn[IEEE80211_CCMP_PN_LEN]; +} __packed; /* LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_8 */ /** * enum iwl_tof_response_status - tof response status @@ -1739,6 +1803,24 @@ struct iwl_tof_range_rsp_ntfy_v7 { } __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_7 */ /** + * struct iwl_tof_range_rsp_ntfy_v9 - ranging response notification + * @request_id: A Token ID of the corresponding Range request + * @num_of_aps: Number of APs results + * @last_report: 1 if no more FTM sessions are scheduled, 0 otherwise. + * @reserved: reserved + * @ap: per-AP data + */ +struct iwl_tof_range_rsp_ntfy_v9 { + u8 request_id; + u8 num_of_aps; + u8 last_report; + u8 reserved; + struct iwl_tof_range_rsp_ap_entry_ntfy_v7 ap[IWL_TOF_MAX_APS]; +} __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_8, + * LOCATION_RANGE_RSP_NTFY_API_S_VER_9 + */ + +/** * struct iwl_tof_range_rsp_ntfy - ranging response notification * @request_id: A Token ID of the corresponding Range request * @num_of_aps: Number of APs results @@ -1752,8 +1834,7 @@ struct iwl_tof_range_rsp_ntfy { u8 last_report; u8 reserved; struct iwl_tof_range_rsp_ap_entry_ntfy ap[IWL_TOF_MAX_APS]; -} __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_8, - LOCATION_RANGE_RSP_NTFY_API_S_VER_9 */ +} __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_10 */ #define IWL_MVM_TOF_MCSI_BUF_SIZE (245) /** diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h index b511e3aa6bb2..b9f559dac39f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h @@ -311,8 +311,41 @@ enum iwl_mac_config_filter_flags { }; /* MAC_FILTER_FLAGS_MASK_E_VER_1 */ /** + * struct iwl_mac_wifi_gen_support_v2 - parameters of iwl_mac_config_cmd + * with support up to eht as in version 2 of the command + * + * @he_support: does this MAC support HE + * @he_ap_support: HE AP enabled, "pseudo HE", no trigger frame handling + * @eht_support: does this MAC support EHT. Requires he_support + */ +struct iwl_mac_wifi_gen_support_v2 { + __le16 he_support; + __le16 he_ap_support; + __le32 eht_support; +} __packed; + +/** + * struct iwl_mac_wifi_gen_support - parameters of iwl_mac_config_cmd + * with support up to uhr as in version 3 of the command + * ( MAC_CONTEXT_CONFIG_CMD = 0x8 ) + * + * @he_support: does this MAC support HE + * @he_ap_support: HE AP enabled, "pseudo HE", no trigger frame handling + * @eht_support: does this MAC support EHT. Requires he_support + * @uhr_support: does this MAC support UHR. Requires eht_support + * @reserved: reserved for alignment and to match version 2's size + */ +struct iwl_mac_wifi_gen_support { + u8 he_support; + u8 he_ap_support; + u8 eht_support; + u8 uhr_support; + __le32 reserved; +} __packed; + +/** * struct iwl_mac_config_cmd - command structure to configure MAC contexts in - * MLD API + * MLD API for versions 2 and 3 * ( MAC_CONTEXT_CONFIG_CMD = 0x8 ) * * @id_and_color: ID and color of the MAC @@ -321,9 +354,8 @@ enum iwl_mac_config_filter_flags { * @local_mld_addr: mld address * @reserved_for_local_mld_addr: reserved * @filter_flags: combination of &enum iwl_mac_config_filter_flags - * @he_support: does this MAC support HE - * @he_ap_support: HE AP enabled, "pseudo HE", no trigger frame handling - * @eht_support: does this MAC support EHT. Requires he_support + * @wifi_gen_v2: he/eht parameters as in cmd version 2 + * @wifi_gen: he/eht/uhr parameters as in cmd version 3 * @nic_not_ack_enabled: mark that the NIC doesn't support receiving * ACK-enabled AGG, (i.e. both BACK and non-BACK frames in single AGG). * If the NIC is not ACK_ENABLED it may use the EOF-bit in first non-0 @@ -332,7 +364,6 @@ enum iwl_mac_config_filter_flags { * @p2p_dev: mac data for p2p device */ struct iwl_mac_config_cmd { - /* COMMON_INDEX_HDR_API_S_VER_1 */ __le32 id_and_color; __le32 action; /* MAC_CONTEXT_TYPE_API_E */ @@ -340,16 +371,17 @@ struct iwl_mac_config_cmd { u8 local_mld_addr[6]; __le16 reserved_for_local_mld_addr; __le32 filter_flags; - __le16 he_support; - __le16 he_ap_support; - __le32 eht_support; + union { + struct iwl_mac_wifi_gen_support_v2 wifi_gen_v2; + struct iwl_mac_wifi_gen_support wifi_gen; + }; __le32 nic_not_ack_enabled; /* MAC_CONTEXT_CONFIG_SPECIFIC_DATA_API_U_VER_2 */ union { struct iwl_mac_client_data client; struct iwl_mac_p2p_dev_data p2p_dev; }; -} __packed; /* MAC_CONTEXT_CONFIG_CMD_API_S_VER_2 */ +} __packed; /* MAC_CONTEXT_CONFIG_CMD_API_S_VER_2_VER_3 */ /** * enum iwl_link_ctx_modify_flags - indicate to the fw what fields are being @@ -457,6 +489,24 @@ enum iwl_link_modify_bandwidth { }; /** + * struct iwl_npca_params - NPCA parameters (non-primary channel access) + * + * @switch_delay: after switch, delay TX according to destination AP + * @switch_back_delay: switch back to control channel before OBSS frame end + * @min_dur_threshold: minimum PPDU time to switch to the non-primary + * NPCA channel + * @flags: NPCA flags - bit 0: puncturing allowed, bit 1: new TX allowed + * @reserved: reserved for alignment purposes + */ +struct iwl_npca_params { + u8 switch_delay; + u8 switch_back_delay; + __le16 min_dur_threshold; + __le16 flags; + __le16 reserved; +} __packed; /* NPCA_PARAM_API_S_VER_1 */ + +/** * struct iwl_link_config_cmd - command structure to configure the LINK context * in MLD API * ( LINK_CONFIG_CMD =0x9 ) @@ -513,6 +563,8 @@ enum iwl_link_modify_bandwidth { * IEEE802.11REVme-D5.0 * @ibss_bssid_addr: bssid for ibss * @reserved_for_ibss_bssid_addr: reserved + * @npca_params: NPCA parameters + * @prio_edca_params: priority EDCA parameters for enhanced QoS * @reserved3: reserved for future use */ struct iwl_link_config_cmd { @@ -560,8 +612,10 @@ struct iwl_link_config_cmd { u8 ul_mu_data_disable; u8 ibss_bssid_addr[6]; __le16 reserved_for_ibss_bssid_addr; - __le32 reserved3[8]; -} __packed; /* LINK_CONTEXT_CONFIG_CMD_API_S_VER_1, _VER_2, _VER_3, _VER_4, _VER_5, _VER_6 */ + struct iwl_npca_params npca_params; /* since _VER_7 */ + struct iwl_ac_qos prio_edca_params; /* since _VER_7 */ + __le32 reserved3[4]; +} __packed; /* LINK_CONTEXT_CONFIG_CMD_API_S_VER_1, _VER_2, _VER_3, _VER_4, _VER_5, _VER_6, _VER_7 */ /* Currently FW supports link ids in the range 0-3 and can have * at most two active links for each vif. @@ -589,6 +643,62 @@ enum iwl_fw_sta_type { }; /* STATION_TYPE_E_VER_1 */ /** + * struct iwl_sta_cfg_cmd_v1 - cmd structure to add a peer sta to the uCode's + * station table + * ( STA_CONFIG_CMD = 0xA ) + * + * @sta_id: index of station in uCode's station table + * @link_id: the id of the link that is used to communicate with this sta + * @peer_mld_address: the peers mld address + * @reserved_for_peer_mld_address: reserved + * @peer_link_address: the address of the link that is used to communicate + * with this sta + * @reserved_for_peer_link_address: reserved + * @station_type: type of this station. See &enum iwl_fw_sta_type + * @assoc_id: for GO only + * @beamform_flags: beam forming controls + * @mfp: indicates whether the STA uses management frame protection or not. + * @mimo: indicates whether the sta uses mimo or not + * @mimo_protection: indicates whether the sta uses mimo protection or not + * @ack_enabled: indicates that the AP supports receiving ACK- + * enabled AGG, i.e. both BACK and non-BACK frames in a single AGG + * @trig_rnd_alloc: indicates that trigger based random allocation + * is enabled according to UORA element existence + * @tx_ampdu_spacing: minimum A-MPDU spacing: + * 4 - 2us density, 5 - 4us density, 6 - 8us density, 7 - 16us density + * @tx_ampdu_max_size: maximum A-MPDU length: 0 - 8K, 1 - 16K, 2 - 32K, + * 3 - 64K, 4 - 128K, 5 - 256K, 6 - 512K, 7 - 1024K. + * @sp_length: the size of the SP in actual number of frames + * @uapsd_acs: 4 LS bits are trigger enabled ACs, 4 MS bits are the deliver + * enabled ACs. + * @pkt_ext: optional, exists according to PPE-present bit in the HE/EHT-PHY + * capa + * @htc_flags: which features are supported in HTC + */ +struct iwl_sta_cfg_cmd_v1 { + __le32 sta_id; + __le32 link_id; + u8 peer_mld_address[ETH_ALEN]; + __le16 reserved_for_peer_mld_address; + u8 peer_link_address[ETH_ALEN]; + __le16 reserved_for_peer_link_address; + __le32 station_type; + __le32 assoc_id; + __le32 beamform_flags; + __le32 mfp; + __le32 mimo; + __le32 mimo_protection; + __le32 ack_enabled; + __le32 trig_rnd_alloc; + __le32 tx_ampdu_spacing; + __le32 tx_ampdu_max_size; + __le32 sp_length; + __le32 uapsd_acs; + struct iwl_he_pkt_ext_v2 pkt_ext; + __le32 htc_flags; +} __packed; /* STA_CMD_API_S_VER_1 */ + +/** * struct iwl_sta_cfg_cmd - cmd structure to add a peer sta to the uCode's * station table * ( STA_CONFIG_CMD = 0xA ) @@ -620,6 +730,14 @@ enum iwl_fw_sta_type { * @pkt_ext: optional, exists according to PPE-present bit in the HE/EHT-PHY * capa * @htc_flags: which features are supported in HTC + * @use_ldpc_x2_cw: Indicates whether to use LDPC with double CW + * @use_icf: Indicates whether to use ICF instead of RTS + * @dps_pad_time: DPS (Dynamic Power Save) padding delay resolution to ensure + * proper timing alignment + * @dps_trans_delay: DPS minimal time that takes the peer to return to low power + * @mic_prep_pad_delay: MIC prep time padding + * @mic_compute_pad_delay: MIC compute time padding + * @reserved: Reserved for alignment */ struct iwl_sta_cfg_cmd { __le32 sta_id; @@ -642,7 +760,14 @@ struct iwl_sta_cfg_cmd { __le32 uapsd_acs; struct iwl_he_pkt_ext_v2 pkt_ext; __le32 htc_flags; -} __packed; /* STA_CMD_API_S_VER_1 */ + u8 use_ldpc_x2_cw; + u8 use_icf; + u8 dps_pad_time; + u8 dps_trans_delay; + u8 mic_prep_pad_delay; + u8 mic_compute_pad_delay; + u8 reserved[2]; +} __packed; /* STA_CMD_API_S_VER_2 */ /** * struct iwl_aux_sta_cmd - command for AUX STA configuration @@ -686,9 +811,9 @@ struct iwl_mvm_sta_disable_tx_cmd { /** * enum iwl_mvm_fw_esr_recommendation - FW recommendation code - * @ESR_RECOMMEND_LEAVE: recommendation to leave esr - * @ESR_FORCE_LEAVE: force exiting esr - * @ESR_RECOMMEND_ENTER: recommendation to enter esr + * @ESR_RECOMMEND_LEAVE: recommendation to leave EMLSR + * @ESR_FORCE_LEAVE: force exiting EMLSR + * @ESR_RECOMMEND_ENTER: recommendation to enter EMLSR */ enum iwl_mvm_fw_esr_recommendation { ESR_RECOMMEND_LEAVE, @@ -697,15 +822,46 @@ enum iwl_mvm_fw_esr_recommendation { }; /* ESR_MODE_RECOMMENDATION_CODE_API_E_VER_1 */ /** - * struct iwl_esr_mode_notif - FWs recommendation/force for esr mode + * struct iwl_esr_mode_notif_v1 - FW recommendation/force for EMLSR mode * - * @action: the action to apply on esr state. See &iwl_mvm_fw_esr_recommendation + * @action: the action to apply on EMLSR state. + * See &iwl_mvm_fw_esr_recommendation */ -struct iwl_esr_mode_notif { +struct iwl_esr_mode_notif_v1 { __le32 action; } __packed; /* ESR_MODE_RECOMMENDATION_NTFY_API_S_VER_1 */ /** + * enum iwl_esr_leave_reason - reasons for leaving EMLSR mode + * + * @ESR_LEAVE_REASON_OMI_MU_UL_DISALLOWED: OMI MU UL disallowed + * @ESR_LEAVE_REASON_NO_TRIG_FOR_ESR_STA: No trigger for EMLSR station + * @ESR_LEAVE_REASON_NO_ESR_STA_IN_MU_DL: No EMLSR station in MU DL + * @ESR_LEAVE_REASON_BAD_ACTIV_FRAME_TH: Bad activation frame threshold + * @ESR_LEAVE_REASON_RTS_IN_DUAL_LISTEN: RTS in dual listen + */ +enum iwl_esr_leave_reason { + ESR_LEAVE_REASON_OMI_MU_UL_DISALLOWED = BIT(0), + ESR_LEAVE_REASON_NO_TRIG_FOR_ESR_STA = BIT(1), + ESR_LEAVE_REASON_NO_ESR_STA_IN_MU_DL = BIT(2), + ESR_LEAVE_REASON_BAD_ACTIV_FRAME_TH = BIT(3), + ESR_LEAVE_REASON_RTS_IN_DUAL_LISTEN = BIT(4), +}; + +/** + * struct iwl_esr_mode_notif - FW recommendation/force for EMLSR mode + * + * @action: the action to apply on EMLSR state. + * See &iwl_mvm_fw_esr_recommendation + * @leave_reason_mask: mask for various reasons to leave EMLSR mode. + * See &iwl_esr_leave_reason + */ +struct iwl_esr_mode_notif { + __le32 action; + __le32 leave_reason_mask; +} __packed; /* ESR_MODE_RECOMMENDATION_NTFY_API_S_VER_2 */ + +/** * struct iwl_missed_beacons_notif - sent when by the firmware upon beacon loss * ( MISSED_BEACONS_NOTIF = 0xF6 ) * @link_id: fw link ID diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h b/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h index 26301c0b06a1..2a174c00b712 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018-2022, 2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2022, 2024-2025 Intel Corporation * Copyright (C) 2017 Intel Deutschland GmbH */ #ifndef __iwl_fw_api_mac_h__ @@ -287,9 +287,9 @@ struct iwl_ac_qos { __le16 cw_min; __le16 cw_max; u8 aifsn; - u8 fifos_mask; + u8 fifos_mask; /* not in use since _VER_3 */ __le16 edca_txop; -} __packed; /* AC_QOS_API_S_VER_2 */ +} __packed; /* AC_QOS_API_S_VER_2, _VER_3 */ /** * struct iwl_mac_ctx_cmd - command structure to configure MAC contexts diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h b/drivers/net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h index 4d8a12799c4d..4594a7c94bd6 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018, 2020-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018, 2020-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -146,6 +146,7 @@ struct iwl_phy_context_cmd_v1 { * @sbb_ctrl_channel_loc: location of the control channel * @puncture_mask: bitmap of punctured subchannels * @dsp_cfg_flags: set to 0 + * @secondary_ctrl_chnl_loc: location of secondary control channel * @reserved: reserved to align to 64 bit */ struct iwl_phy_context_cmd { @@ -164,11 +165,13 @@ struct iwl_phy_context_cmd { }; }; __le32 dsp_cfg_flags; - __le32 reserved; + u8 secondary_ctrl_chnl_loc; + u8 reserved[3]; } __packed; /* PHY_CONTEXT_CMD_API_VER_3, * PHY_CONTEXT_CMD_API_VER_4, * PHY_CONTEXT_CMD_API_VER_5, - * PHY_CONTEXT_CMD_API_VER_6 + * PHY_CONTEXT_CMD_API_VER_6, + * PHY_CONTEXT_CMD_API_S_VER_7 */ #endif /* __iwl_fw_api_phy_ctxt_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h index 37ec26596ee7..23140205ccb9 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h @@ -1,12 +1,14 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH */ #ifndef __iwl_fw_api_power_h__ #define __iwl_fw_api_power_h__ +#include "nvm-reg.h" + /* Power Management Commands, Responses, Notifications */ /** @@ -54,7 +56,7 @@ struct iwl_ltr_config_cmd_v1 { * @flags: See &enum iwl_ltr_config_flags * @static_long: static LTR Long register value. * @static_short: static LTR Short register value. - * @ltr_cfg_values: LTR parameters table values (in usec) in folowing order: + * @ltr_cfg_values: LTR parameters table values (in usec) in following order: * TX, RX, Short Idle, Long Idle. Used only if %LTR_CFG_FLAG_UPDATE_VALUES * is set. * @ltr_short_idle_timeout: LTR Short Idle timeout (in usec). Used only if @@ -89,6 +91,7 @@ struct iwl_ltr_config_cmd { * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable. * @POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK: AP/GO's uAPSD misbehaving * detection enablement + * @POWER_FLAGS_ENABLE_SMPS_MSK: SMPS is allowed for this vif */ enum iwl_power_flags { POWER_FLAGS_POWER_SAVE_ENA_MSK = BIT(0), @@ -99,6 +102,7 @@ enum iwl_power_flags { POWER_FLAGS_ADVANCE_PM_ENA_MSK = BIT(9), POWER_FLAGS_LPRX_ENA_MSK = BIT(11), POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK = BIT(12), + POWER_FLAGS_ENABLE_SMPS_MSK = BIT(14), }; #define IWL_POWER_VEC_SIZE 5 @@ -216,7 +220,6 @@ struct iwl_mac_power_cmd { /* CONTEXT_DESC_API_T_VER_1 */ __le32 id_and_color; - /* CLIENT_PM_POWER_TABLE_S_VER_1 */ __le16 flags; __le16 keep_alive_seconds; __le32 rx_data_timeout; @@ -237,7 +240,7 @@ struct iwl_mac_power_cmd { u8 heavy_rx_thld_percentage; u8 limited_ps_threshold; u8 reserved; -} __packed; +} __packed; /* CLIENT_PM_POWER_TABLE_S_VER_1, VER_2 */ /* * struct iwl_uapsd_misbehaving_ap_notif - FW sends this notification when @@ -628,28 +631,37 @@ enum iwl_ppag_flags { /** * union iwl_ppag_table_cmd - union for all versions of PPAG command - * @v1: version 1 - * @v2: version 2 - * version 3, 4, 5 and 6 are the same structure as v2, + * @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 + * @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 * @v1.reserved: reserved * @v2.flags: values from &enum iwl_ppag_flags * @v2.gain: table of antenna gain values per chain and sub-band - * @v2.reserved: reserved + * @v3.ppag_config_info: see @struct bios_value_u32 + * @v3.gain: table of antenna gain values per chain and sub-band + * @v3.reserved: reserved */ union iwl_ppag_table_cmd { struct { __le32 flags; s8 gain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V1]; s8 reserved[2]; - } v1; + } __packed v1; /* PER_PLAT_ANTENNA_GAIN_CMD_API_S_VER_1 */ struct { __le32 flags; s8 gain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V2]; s8 reserved[2]; - } v2; + } __packed v2; /* PER_PLAT_ANTENNA_GAIN_CMD_API_S_VER_2, VER3, VER4, + * VER5, VER6 + */ + struct { + struct bios_value_u32 ppag_config_info; + s8 gain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V2]; + s8 reserved[2]; + } __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) @@ -657,6 +669,15 @@ union iwl_ppag_table_cmd { 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 @@ -690,7 +711,7 @@ struct iwl_sar_offset_mapping_cmd { * Roaming Energy Delta Threshold, otherwise use normal Energy Delta * Threshold. Typical energy threshold is -72dBm. * @bf_temp_threshold: This threshold determines the type of temperature - * filtering (Slow or Fast) that is selected (Units are in Celsuis): + * filtering (Slow or Fast) that is selected (Units are in Celsius): * If the current temperature is above this threshold - Fast filter * will be used, If the current temperature is below this threshold - * Slow filter will be used. @@ -698,12 +719,12 @@ struct iwl_sar_offset_mapping_cmd { * calculated for this and the last passed beacon is greater than this * threshold. Zero value means that the temperature change is ignored for * beacon filtering; beacons will not be forced to be sent to driver - * regardless of whether its temerature has been changed. + * regardless of whether its temperature has been changed. * @bf_temp_slow_filter: Send Beacon to driver if delta in temperature values * calculated for this and the last passed beacon is greater than this * threshold. Zero value means that the temperature change is ignored for * beacon filtering; beacons will not be forced to be sent to driver - * regardless of whether its temerature has been changed. + * regardless of whether its temperature has been changed. * @bf_enable_beacon_filter: 1, beacon filtering is enabled; 0, disabled. * @bf_debug_flag: beacon filtering debug configuration * @bf_escape_timer: Send beacons to to driver if no beacons were passed diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h index c2f806cbab59..3222cbcbe1ab 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h @@ -1,11 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018-2022, 2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2022, 2024-2025 Intel Corporation * Copyright (C) 2017 Intel Deutschland GmbH */ #ifndef __iwl_fw_api_rs_h__ #define __iwl_fw_api_rs_h__ - +#include <linux/bitfield.h> +#include <linux/types.h> +#include <linux/bits.h> #include "mac.h" /** @@ -213,7 +215,8 @@ enum iwl_tlc_update_flags { * @sta_id: station id * @reserved: reserved * @flags: bitmap of notifications reported - * @rate: current initial rate + * @rate: current initial rate, format depends on the notification + * version * @amsdu_size: Max AMSDU size, in bytes * @amsdu_enabled: bitmap for per-TID AMSDU enablement */ @@ -224,7 +227,7 @@ struct iwl_tlc_update_notif { __le32 rate; __le32 amsdu_size; __le32 amsdu_enabled; -} __packed; /* TLC_MNG_UPDATE_NTFY_API_S_VER_2 */ +} __packed; /* TLC_MNG_UPDATE_NTFY_API_S_VER_2, _VER_3, _VER_4 */ /** * enum iwl_tlc_debug_types - debug options @@ -427,6 +430,7 @@ enum { /* Bit 4-5: (0) SISO, (1) MIMO2 (2) MIMO3 */ #define RATE_VHT_MCS_RATE_CODE_MSK 0xf +#define RATE_VHT_MCS_NSS_MSK 0x30 /* * Legacy OFDM rate format for bits 7:0 @@ -541,7 +545,7 @@ enum { #define RATE_MCS_CTS_REQUIRED_POS (31) #define RATE_MCS_CTS_REQUIRED_MSK (0x1 << RATE_MCS_CTS_REQUIRED_POS) -/* rate_n_flags bit field version 2 +/* rate_n_flags bit field version 2 and 3 * * The 32-bit value has different layouts in the low 8 bits depending on the * format. There are three formats, HT, VHT and legacy (11abg, with subformats @@ -553,23 +557,25 @@ enum { * (0) Legacy CCK (1) Legacy OFDM (2) High-throughput (HT) * (3) Very High-throughput (VHT) (4) High-efficiency (HE) * (5) Extremely High-throughput (EHT) + * (6) Ultra High Reliability (UHR) (v3 rate format only) */ #define RATE_MCS_MOD_TYPE_POS 8 #define RATE_MCS_MOD_TYPE_MSK (0x7 << RATE_MCS_MOD_TYPE_POS) -#define RATE_MCS_CCK_MSK (0 << RATE_MCS_MOD_TYPE_POS) -#define RATE_MCS_LEGACY_OFDM_MSK (1 << RATE_MCS_MOD_TYPE_POS) -#define RATE_MCS_HT_MSK (2 << RATE_MCS_MOD_TYPE_POS) -#define RATE_MCS_VHT_MSK (3 << RATE_MCS_MOD_TYPE_POS) -#define RATE_MCS_HE_MSK (4 << RATE_MCS_MOD_TYPE_POS) -#define RATE_MCS_EHT_MSK (5 << RATE_MCS_MOD_TYPE_POS) +#define RATE_MCS_MOD_TYPE_CCK (0 << RATE_MCS_MOD_TYPE_POS) +#define RATE_MCS_MOD_TYPE_LEGACY_OFDM (1 << RATE_MCS_MOD_TYPE_POS) +#define RATE_MCS_MOD_TYPE_HT (2 << RATE_MCS_MOD_TYPE_POS) +#define RATE_MCS_MOD_TYPE_VHT (3 << RATE_MCS_MOD_TYPE_POS) +#define RATE_MCS_MOD_TYPE_HE (4 << RATE_MCS_MOD_TYPE_POS) +#define RATE_MCS_MOD_TYPE_EHT (5 << RATE_MCS_MOD_TYPE_POS) +#define RATE_MCS_MOD_TYPE_UHR (6 << RATE_MCS_MOD_TYPE_POS) /* * Legacy CCK rate format for bits 0:3: * - * (0) 0xa - 1 Mbps - * (1) 0x14 - 2 Mbps - * (2) 0x37 - 5.5 Mbps - * (3) 0x6e - 11 nbps + * (0) 1 Mbps + * (1) 2 Mbps + * (2) 5.5 Mbps + * (3) 11 Mbps * * Legacy OFDM rate format for bis 3:0: * @@ -586,15 +592,19 @@ enum { #define RATE_LEGACY_RATE_MSK 0x7 /* - * HT, VHT, HE, EHT rate format for bits 3:0 - * 3-0: MCS - * + * HT, VHT, HE, EHT, UHR rate format + * Version 2: (not applicable for UHR) + * 3-0: MCS + * 4: NSS==2 indicator + * Version 3: + * 4-0: MCS + * 5: NSS==2 indicator */ #define RATE_HT_MCS_CODE_MSK 0x7 -#define RATE_MCS_NSS_POS 4 -#define RATE_MCS_NSS_MSK (1 << RATE_MCS_NSS_POS) -#define RATE_MCS_CODE_MSK 0xf -#define RATE_HT_MCS_INDEX(r) ((((r) & RATE_MCS_NSS_MSK) >> 1) | \ +#define RATE_MCS_NSS_MSK_V2 0x10 +#define RATE_MCS_NSS_MSK 0x20 +#define RATE_MCS_CODE_MSK 0x1f +#define RATE_HT_MCS_INDEX(r) ((((r) & RATE_MCS_NSS_MSK) >> 2) | \ ((r) & RATE_HT_MCS_CODE_MSK)) /* Bits 7-5: reserved */ @@ -810,11 +820,38 @@ struct iwl_lq_cmd { }; /* LINK_QUALITY_CMD_API_S_VER_1 */ u8 iwl_fw_rate_idx_to_plcp(int idx); -u32 iwl_new_rate_from_v1(u32 rate_v1); const struct iwl_rate_mcs_info *iwl_rate_mcs(int idx); const char *iwl_rs_pretty_ant(u8 ant); const char *iwl_rs_pretty_bw(int bw); int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate); bool iwl_he_is_sgi(u32 rate_n_flags); +static inline u32 iwl_v3_rate_from_v2_v3(__le32 rate, bool fw_v3) +{ + u32 val; + + if (fw_v3) + return le32_to_cpu(rate); + + val = le32_to_cpu(rate) & ~RATE_MCS_NSS_MSK_V2; + val |= u32_encode_bits(le32_get_bits(rate, RATE_MCS_NSS_MSK_V2), + RATE_MCS_NSS_MSK); + + return val; +} + +static inline __le32 iwl_v3_rate_to_v2_v3(u32 rate, bool fw_v3) +{ + __le32 val; + + if (fw_v3) + return cpu_to_le32(rate); + + val = cpu_to_le32(rate & ~RATE_MCS_NSS_MSK); + val |= le32_encode_bits(u32_get_bits(rate, RATE_MCS_NSS_MSK), + RATE_MCS_NSS_MSK_V2); + + return val; +} + #endif /* __iwl_fw_api_rs_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h index 691c879cb90d..7cf6d6ac7430 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH */ @@ -193,10 +193,11 @@ enum iwl_rx_mpdu_amsdu_info { IWL_RX_MPDU_AMSDU_LAST_SUBFRAME = 0x80, }; -#define RX_MPDU_BAND_POS 6 -#define RX_MPDU_BAND_MASK 0xC0 -#define BAND_IN_RX_STATUS(_val) \ - (((_val) & RX_MPDU_BAND_MASK) >> RX_MPDU_BAND_POS) +enum iwl_rx_mpdu_mac_phy_band { + IWL_RX_MPDU_MAC_PHY_BAND_MAC_MASK = 0x0f, + IWL_RX_MPDU_MAC_PHY_BAND_PHY_MASK = 0x30, + IWL_RX_MPDU_MAC_PHY_BAND_BAND_MASK = 0xc0, +}; enum iwl_rx_l3_proto_values { IWL_RX_L3_TYPE_NONE, @@ -639,7 +640,9 @@ struct iwl_rx_mpdu_desc_v3 { */ __le32 reserved[1]; } __packed; /* RX_MPDU_RES_START_API_S_VER_3, - RX_MPDU_RES_START_API_S_VER_5 */ + * RX_MPDU_RES_START_API_S_VER_5, + * RX_MPDU_RES_START_API_S_VER_6 + */ /** * struct iwl_rx_mpdu_desc - RX MPDU descriptor @@ -668,9 +671,10 @@ struct iwl_rx_mpdu_desc { */ __le16 phy_info; /** - * @mac_phy_idx: MAC/PHY index + * @mac_phy_band: MAC ID, PHY ID, band; + * see &enum iwl_rx_mpdu_mac_phy_band */ - u8 mac_phy_idx; + u8 mac_phy_band; /* DW4 */ union { struct { @@ -722,8 +726,10 @@ struct iwl_rx_mpdu_desc { struct iwl_rx_mpdu_desc_v3 v3; }; } __packed; /* RX_MPDU_RES_START_API_S_VER_3, - RX_MPDU_RES_START_API_S_VER_4, - RX_MPDU_RES_START_API_S_VER_5 */ + * RX_MPDU_RES_START_API_S_VER_4, + * RX_MPDU_RES_START_API_S_VER_5, + * RX_MPDU_RES_START_API_S_VER_6 + */ #define IWL_RX_DESC_SIZE_V1 offsetofend(struct iwl_rx_mpdu_desc, v1) @@ -819,7 +825,7 @@ struct iwl_rx_no_data { * 15:8 chain-B, measured at FINA time (FINA_ENERGY), 16:23 channel * @on_air_rise_time: GP2 during on air rise * @fr_time: frame time - * @rate: rate/mcs of frame + * @rate: rate/mcs of frame, format depends on the notification version * @phy_info: &enum iwl_rx_phy_eht_data0 and &enum iwl_rx_phy_info_type * @rx_vec: DW-12:9 raw RX vectors from DSP according to modulation type. * for VHT: OFDM_RX_VECTOR_SIGA1_OUT, OFDM_RX_VECTOR_SIGA2_OUT @@ -835,9 +841,7 @@ struct iwl_rx_no_data_ver_3 { __le32 rate; __le32 phy_info[2]; __le32 rx_vec[4]; -} __packed; /* RX_NO_DATA_NTFY_API_S_VER_1, - RX_NO_DATA_NTFY_API_S_VER_2 - RX_NO_DATA_NTFY_API_S_VER_3 */ +} __packed; /* RX_NO_DATA_NTFY_API_S_VER_3, _VER_4 */ struct iwl_frame_release { u8 baid; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/stats.h b/drivers/net/wireless/intel/iwlwifi/fw/api/stats.h index 0a9f14fb04be..00713a991879 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/stats.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/stats.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018, 2020 - 2021, 2023 - 2024 Intel Corporation + * Copyright (C) 2012-2014, 2018, 2020-2021, 2023-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -584,6 +584,9 @@ struct iwl_stats_ntfy_per_phy { __le32 last_tx_ch_width_indx; } __packed; /* STATISTICS_NTFY_PER_PHY_API_S_VER_1 */ +/* unknown channel load (due to not being active on channel) */ +#define IWL_STATS_UNKNOWN_CHANNEL_LOAD 0xffffffff + /** * struct iwl_stats_ntfy_per_sta * diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tdls.h b/drivers/net/wireless/intel/iwlwifi/fw/api/tdls.h index cfa6532a3cdd..58d5a6ef633e 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/tdls.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tdls.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018, 2024 Intel Corporation + * Copyright (C) 2012-2014, 2018, 2024-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -50,7 +50,7 @@ struct iwl_tdls_channel_switch_timing { */ struct iwl_tdls_channel_switch_frame { __le32 switch_time_offset; - struct iwl_tx_cmd tx_cmd; + struct iwl_tx_cmd_v6 tx_cmd; u8 data[IWL_TDLS_CH_SW_FRAME_MAX_SIZE]; } __packed; /* TDLS_STA_CHANNEL_SWITCH_FRAME_API_S_VER_1 */ @@ -131,7 +131,7 @@ struct iwl_tdls_config_cmd { struct iwl_tdls_sta_info sta_info[IWL_TDLS_STA_COUNT]; __le32 pti_req_data_offset; - struct iwl_tx_cmd pti_req_tx_cmd; + struct iwl_tx_cmd_v6 pti_req_tx_cmd; u8 pti_req_template[]; } __packed; /* TDLS_CONFIG_CMD_API_S_VER_1 */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h index 0a39e4b6eb62..557832563f89 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation * Copyright (C) 2016-2017 Intel Deutschland GmbH */ #ifndef __iwl_fw_api_tx_h__ @@ -151,7 +151,7 @@ enum iwl_tx_cmd_sec_ctrl { #define IWL_LOW_RETRY_LIMIT 7 /** - * enum iwl_tx_offload_assist_flags_pos - set %iwl_tx_cmd offload_assist values + * enum iwl_tx_offload_assist_flags_pos - set %iwl_tx_cmd_v6 offload_assist values * @TX_CMD_OFFLD_IP_HDR: offset to start of IP header (in words) * from mac header end. For normal case it is 4 words for SNAP. * note: tx_cmd, mac header and pad are not counted in the offset. @@ -181,7 +181,7 @@ enum iwl_tx_offload_assist_flags_pos { /* TODO: complete documentation for try_cnt and btkill_cnt */ /** - * struct iwl_tx_cmd - TX command struct to FW + * struct iwl_tx_cmd_v6 - TX command struct to FW * ( TX_CMD = 0x1c ) * @len: in bytes of the payload, see below for details * @offload_assist: TX offload configuration @@ -221,7 +221,7 @@ enum iwl_tx_offload_assist_flags_pos { * After the struct fields the MAC header is placed, plus any padding, * and then the actial payload. */ -struct iwl_tx_cmd { +struct iwl_tx_cmd_v6 { __le16 len; __le16 offload_assist; __le32 tx_flags; @@ -258,7 +258,7 @@ struct iwl_dram_sec_info { } __packed; /* DRAM_SEC_INFO_API_S_VER_1 */ /** - * struct iwl_tx_cmd_gen2 - TX command struct to FW for 22000 devices + * struct iwl_tx_cmd_v9 - TX command struct to FW for 22000 devices * ( TX_CMD = 0x1c ) * @len: in bytes of the payload, see below for details * @offload_assist: TX offload configuration @@ -268,7 +268,7 @@ struct iwl_dram_sec_info { * cleared. Combination of RATE_MCS_* * @hdr: 802.11 header */ -struct iwl_tx_cmd_gen2 { +struct iwl_tx_cmd_v9 { __le16 len; __le16 offload_assist; __le32 flags; @@ -279,18 +279,18 @@ struct iwl_tx_cmd_gen2 { TX_CMD_API_S_VER_9 */ /** - * struct iwl_tx_cmd_gen3 - TX command struct to FW for AX210+ devices + * struct iwl_tx_cmd - TX command struct to FW for AX210+ devices * ( TX_CMD = 0x1c ) * @len: in bytes of the payload, see below for details * @flags: combination of &enum iwl_tx_cmd_flags * @offload_assist: TX offload configuration * @dram_info: FW internal DRAM storage * @rate_n_flags: rate for *all* Tx attempts, if TX_CMD_FLG_STA_RATE_MSK is - * cleared. Combination of RATE_MCS_* + * cleared. Combination of RATE_MCS_*; format depends on version * @reserved: reserved * @hdr: 802.11 header */ -struct iwl_tx_cmd_gen3 { +struct iwl_tx_cmd { __le16 len; __le16 flags; __le32 offload_assist; @@ -298,7 +298,9 @@ struct iwl_tx_cmd_gen3 { __le32 rate_n_flags; u8 reserved[8]; struct ieee80211_hdr hdr[]; -} __packed; /* TX_CMD_API_S_VER_8, TX_CMD_API_S_VER_10 */ +} __packed; /* TX_CMD_API_S_VER_10, + * TX_CMD_API_S_VER_11 + */ /* * TX response related data @@ -549,7 +551,7 @@ struct iwl_tx_resp_v3 { * @failure_rts: num of failures due to unsuccessful RTS * @failure_frame: num failures due to no ACK (unused for agg) * @initial_rate: for non-agg: rate of the successful Tx. For agg: rate of the - * Tx of all the batch. RATE_MCS_* + * Tx of all the batch. RATE_MCS_*; format depends on command version * @wireless_media_time: for non-agg: RTS + CTS + frame tx attempts time + ACK. * for agg: RTS + CTS + aggregation tx time + block-ack time. * in usec. @@ -600,8 +602,10 @@ struct iwl_tx_resp { __le16 reserved2; struct agg_tx_status status; } __packed; /* TX_RSP_API_S_VER_6, - TX_RSP_API_S_VER_7, - TX_RSP_API_S_VER_8 */ + * TX_RSP_API_S_VER_7, + * TX_RSP_API_S_VER_8, + * TX_RSP_API_S_VER_9 + */ /** * struct iwl_mvm_ba_notif - notifies about reception of BA @@ -701,7 +705,8 @@ enum iwl_mvm_ba_resp_flags { * @rts_retry_cnt: RTS retry count * @reserved: reserved (for alignment) * @wireless_time: Wireless-media time - * @tx_rate: the rate the aggregation was sent at + * @tx_rate: the rate the aggregation was sent at. Format depends on command + * version. * @tfd_cnt: number of TFD-Q elements * @ra_tid_cnt: number of RATID-Q elements * @tfd: array of TFD queue status updates. See &iwl_compressed_ba_tfd @@ -730,7 +735,8 @@ struct iwl_compressed_ba_notif { DECLARE_FLEX_ARRAY(struct iwl_compressed_ba_tfd, tfd); }; } __packed; /* COMPRESSED_BA_RES_API_S_VER_4, - COMPRESSED_BA_RES_API_S_VER_5 */ + COMPRESSED_BA_RES_API_S_VER_6, + COMPRESSED_BA_RES_API_S_VER_7 */ /** * struct iwl_mac_beacon_cmd_v6 - beacon template command @@ -742,7 +748,7 @@ struct iwl_compressed_ba_notif { * @frame: the template of the beacon frame */ struct iwl_mac_beacon_cmd_v6 { - struct iwl_tx_cmd tx; + struct iwl_tx_cmd_v6 tx; __le32 template_id; __le32 tim_idx; __le32 tim_size; @@ -761,7 +767,7 @@ struct iwl_mac_beacon_cmd_v6 { * @frame: the template of the beacon frame */ struct iwl_mac_beacon_cmd_v7 { - struct iwl_tx_cmd tx; + struct iwl_tx_cmd_v6 tx; __le32 template_id; __le32 tim_idx; __le32 tim_size; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 03f639fbf9b6..ea739ebe7cb0 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -187,7 +187,7 @@ static void iwl_fw_dump_rxf(struct iwl_fw_runtime *fwrt, /* Pull RXF2 */ iwl_fwrt_dump_rxf(fwrt, dump_data, cfg->rxfifo2_size, RXF_DIFF_FROM_PREV + - fwrt->trans->trans_cfg->umac_prph_offset, 1); + fwrt->trans->mac_cfg->umac_prph_offset, 1); /* Pull LMAC2 RXF1 */ if (fwrt->smem_cfg.num_lmacs > 1) iwl_fwrt_dump_rxf(fwrt, dump_data, @@ -654,10 +654,10 @@ static void iwl_fw_prph_handler(struct iwl_fw_runtime *fwrt, void *ptr, { u32 range_len; - if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + if (fwrt->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { range_len = ARRAY_SIZE(iwl_prph_dump_addr_ax210); handler(fwrt, iwl_prph_dump_addr_ax210, range_len, ptr); - } else if (fwrt->trans->trans_cfg->device_family >= + } else if (fwrt->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { range_len = ARRAY_SIZE(iwl_prph_dump_addr_22000); handler(fwrt, iwl_prph_dump_addr_22000, range_len, ptr); @@ -665,7 +665,7 @@ static void iwl_fw_prph_handler(struct iwl_fw_runtime *fwrt, void *ptr, range_len = ARRAY_SIZE(iwl_prph_dump_addr_comm); handler(fwrt, iwl_prph_dump_addr_comm, range_len, ptr); - if (fwrt->trans->trans_cfg->mq_rx_supported) { + if (fwrt->trans->mac_cfg->mq_rx_supported) { range_len = ARRAY_SIZE(iwl_prph_dump_addr_9000); handler(fwrt, iwl_prph_dump_addr_9000, range_len, ptr); } @@ -809,13 +809,14 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt, const struct iwl_fw_dbg_mem_seg_tlv *fw_mem = fwrt->fw->dbg.mem_tlv; struct iwl_fwrt_shared_mem_cfg *mem_cfg = &fwrt->smem_cfg; u32 file_len, fifo_len = 0, prph_len = 0, radio_len = 0; - u32 smem_len = fwrt->fw->dbg.n_mem_tlv ? 0 : fwrt->trans->cfg->smem_len; + u32 smem_len = fwrt->fw->dbg.n_mem_tlv ? 0 : fwrt->trans->mac_cfg->base->smem_len; u32 sram2_len = fwrt->fw->dbg.n_mem_tlv ? 0 : fwrt->trans->cfg->dccm2_len; int i; /* SRAM - include stack CCM if driver knows the values for it */ - if (!fwrt->trans->cfg->dccm_offset || !fwrt->trans->cfg->dccm_len) { + if (!fwrt->trans->cfg->dccm_offset || + !fwrt->trans->cfg->dccm_len) { const struct fw_img *img; if (fwrt->cur_fw_img >= IWL_UCODE_TYPE_MAX) @@ -838,7 +839,7 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt, iwl_fw_prph_handler(fwrt, &prph_len, iwl_fw_get_prph_len); - if (fwrt->trans->trans_cfg->device_family == + if (fwrt->trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_7000 && iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_RADIO_REG)) radio_len = sizeof(*dump_data) + RADIO_REG_MAX_READ; @@ -876,7 +877,7 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt, if (iwl_fw_dbg_is_d3_debug_enabled(fwrt) && fwrt->dump.d3_debug_data) { file_len += sizeof(*dump_data) + - fwrt->trans->cfg->d3_debug_data_length * 2; + fwrt->trans->mac_cfg->base->d3_debug_data_length * 2; } /* If we only want a monitor dump, reset the file length */ @@ -904,13 +905,14 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt, dump_data->len = cpu_to_le32(sizeof(*dump_info)); dump_info = (void *)dump_data->data; dump_info->hw_type = - cpu_to_le32(CSR_HW_REV_TYPE(fwrt->trans->hw_rev)); + cpu_to_le32(CSR_HW_REV_TYPE(fwrt->trans->info.hw_rev)); dump_info->hw_step = - cpu_to_le32(fwrt->trans->hw_rev_step); + cpu_to_le32(fwrt->trans->info.hw_rev_step); memcpy(dump_info->fw_human_readable, fwrt->fw->human_readable, sizeof(dump_info->fw_human_readable)); - strscpy_pad(dump_info->dev_human_readable, fwrt->trans->name, - sizeof(dump_info->dev_human_readable)); + strscpy_pad(dump_info->dev_human_readable, + fwrt->trans->info.name, + sizeof(dump_info->dev_human_readable)); strscpy_pad(dump_info->bus_human_readable, fwrt->dev->bus->name, sizeof(dump_info->bus_human_readable)); dump_info->num_of_lmacs = fwrt->smem_cfg.num_lmacs; @@ -996,7 +998,7 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt, } iwl_fw_dump_mem(fwrt, &dump_data, smem_len, - fwrt->trans->cfg->smem_offset, + fwrt->trans->mac_cfg->base->smem_offset, IWL_FW_ERROR_DUMP_MEM_SMEM); iwl_fw_dump_mem(fwrt, &dump_data, sram2_len, @@ -1005,8 +1007,8 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt, } if (iwl_fw_dbg_is_d3_debug_enabled(fwrt) && fwrt->dump.d3_debug_data) { - u32 addr = fwrt->trans->cfg->d3_debug_data_base_addr; - size_t data_size = fwrt->trans->cfg->d3_debug_data_length; + u32 addr = fwrt->trans->mac_cfg->base->d3_debug_data_base_addr; + size_t data_size = fwrt->trans->mac_cfg->base->d3_debug_data_length; dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_D3_DEBUG_DATA); dump_data->len = cpu_to_le32(data_size * 2); @@ -1109,7 +1111,7 @@ static int iwl_dump_ini_prph_phy_iter_common(struct iwl_fw_runtime *fwrt, range->internal_base_addr = cpu_to_le32(addr); range->range_data_size = size; - if (fwrt->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) + if (fwrt->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) indirect_wr_addr = WMAL_INDRCT_CMD1; indirect_wr_addr += le32_to_cpu(offset); @@ -1266,7 +1268,7 @@ static int iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt, /* all paged index start from 1 to skip CSS section */ idx++; - if (!fwrt->trans->trans_cfg->gen2) + if (!fwrt->trans->mac_cfg->gen2) return _iwl_dump_ini_paging_iter(fwrt, range_ptr, range_len, idx); range = range_ptr; @@ -1790,7 +1792,7 @@ iwl_dump_ini_mon_fill_header(struct iwl_fw_runtime *fwrt, u32 alloc_id, data->write_ptr = iwl_get_mon_reg(fwrt, alloc_id, &addrs->write_ptr); - if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + if (fwrt->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { u32 wrt_ptr = le32_to_cpu(data->write_ptr); data->write_ptr = cpu_to_le32(wrt_ptr >> 2); @@ -1817,7 +1819,7 @@ iwl_dump_ini_mon_dram_fill_header(struct iwl_fw_runtime *fwrt, u32 alloc_id = le32_to_cpu(reg->dram_alloc_id); return iwl_dump_ini_mon_fill_header(fwrt, alloc_id, mon_dump, - &fwrt->trans->cfg->mon_dram_regs); + &fwrt->trans->mac_cfg->base->mon_dram_regs); } static void * @@ -1830,7 +1832,7 @@ iwl_dump_ini_mon_smem_fill_header(struct iwl_fw_runtime *fwrt, u32 alloc_id = le32_to_cpu(reg->internal_buffer.alloc_id); return iwl_dump_ini_mon_fill_header(fwrt, alloc_id, mon_dump, - &fwrt->trans->cfg->mon_smem_regs); + &fwrt->trans->mac_cfg->base->mon_smem_regs); } static void * @@ -1844,7 +1846,7 @@ iwl_dump_ini_mon_dbgi_fill_header(struct iwl_fw_runtime *fwrt, /* no offset calculation later */ IWL_FW_INI_ALLOCATION_ID_DBGC1, mon_dump, - &fwrt->trans->cfg->mon_dbgi_regs); + &fwrt->trans->mac_cfg->base->mon_dbgi_regs); } static void * @@ -1909,7 +1911,7 @@ iwl_dump_ini_mem_block_ranges(struct iwl_fw_runtime *fwrt, static u32 iwl_dump_ini_paging_ranges(struct iwl_fw_runtime *fwrt, struct iwl_dump_ini_region_data *reg_data) { - if (fwrt->trans->trans_cfg->gen2) { + if (fwrt->trans->mac_cfg->gen2) { if (fwrt->trans->init_dram.paging_cnt) return fwrt->trans->init_dram.paging_cnt - 1; else @@ -2021,7 +2023,7 @@ iwl_dump_ini_paging_get_size(struct iwl_fw_runtime *fwrt, /* start from 1 to skip CSS section */ for (i = 1; i <= iwl_dump_ini_paging_ranges(fwrt, reg_data); i++) { size += range_header_len; - if (fwrt->trans->trans_cfg->gen2) + if (fwrt->trans->mac_cfg->gen2) size += fwrt->trans->init_dram.paging[i].size; else size += fwrt->fw_paging_db[i].fw_paging_size; @@ -2375,7 +2377,7 @@ static u32 iwl_dump_ini_info(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_dump_cfg_name *cfg_name; u32 size = sizeof(*tlv) + sizeof(*dump); u32 num_of_cfg_names = 0; - u32 hw_type; + u32 hw_type, is_cdb, is_jacket; list_for_each_entry(node, &fwrt->trans->dbg.debug_info_tlv_list, list) { size += sizeof(*cfg_name); @@ -2403,33 +2405,24 @@ static u32 iwl_dump_ini_info(struct iwl_fw_runtime *fwrt, dump->ver_type = cpu_to_le32(fwrt->dump.fw_ver.type); dump->ver_subtype = cpu_to_le32(fwrt->dump.fw_ver.subtype); - dump->hw_step = cpu_to_le32(fwrt->trans->hw_rev_step); + dump->hw_step = cpu_to_le32(fwrt->trans->info.hw_rev_step); - /* - * Several HWs all have type == 0x42, so we'll override this value - * according to the detected HW - */ - hw_type = CSR_HW_REV_TYPE(fwrt->trans->hw_rev); - if (hw_type == IWL_AX210_HW_TYPE) { - u32 prph_val = iwl_read_umac_prph(fwrt->trans, WFPM_OTP_CFG1_ADDR); - u32 is_jacket = !!(prph_val & WFPM_OTP_CFG1_IS_JACKET_BIT); - u32 is_cdb = !!(prph_val & WFPM_OTP_CFG1_IS_CDB_BIT); - u32 masked_bits = is_jacket | (is_cdb << 1); + hw_type = CSR_HW_REV_TYPE(fwrt->trans->info.hw_rev); + + is_cdb = CSR_HW_RFID_IS_CDB(fwrt->trans->info.hw_rf_id); + is_jacket = !!(iwl_read_umac_prph(fwrt->trans, WFPM_OTP_CFG1_ADDR) & + WFPM_OTP_CFG1_IS_JACKET_BIT); + + /* Use bits 12 and 13 to indicate jacket/CDB, respectively */ + hw_type |= (is_jacket | (is_cdb << 1)) << IWL_JACKET_CDB_SHIFT; - /* - * The HW type depends on certain bits in this case, so add - * these bits to the HW type. We won't have collisions since we - * add these bits after the highest possible bit in the mask. - */ - hw_type |= masked_bits << IWL_AX210_HW_TYPE_ADDITION_SHIFT; - } dump->hw_type = cpu_to_le32(hw_type); dump->rf_id_flavor = - cpu_to_le32(CSR_HW_RFID_FLAVOR(fwrt->trans->hw_rf_id)); - dump->rf_id_dash = cpu_to_le32(CSR_HW_RFID_DASH(fwrt->trans->hw_rf_id)); - dump->rf_id_step = cpu_to_le32(CSR_HW_RFID_STEP(fwrt->trans->hw_rf_id)); - dump->rf_id_type = cpu_to_le32(CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id)); + cpu_to_le32(CSR_HW_RFID_FLAVOR(fwrt->trans->info.hw_rf_id)); + dump->rf_id_dash = cpu_to_le32(CSR_HW_RFID_DASH(fwrt->trans->info.hw_rf_id)); + dump->rf_id_step = cpu_to_le32(CSR_HW_RFID_STEP(fwrt->trans->info.hw_rf_id)); + dump->rf_id_type = cpu_to_le32(CSR_HW_RFID_TYPE(fwrt->trans->info.hw_rf_id)); dump->lmac_major = cpu_to_le32(fwrt->dump.fw_ver.lmac_major); dump->lmac_minor = cpu_to_le32(fwrt->dump.fw_ver.lmac_minor); @@ -2624,6 +2617,12 @@ enum iwl_dump_ini_region_selector { IWL_INI_DUMP_LATE_REGIONS, }; +static bool iwl_dump_due_to_error(enum iwl_fw_ini_time_point tp_id) +{ + return tp_id == IWL_FW_INI_TIME_POINT_FW_ASSERT || + tp_id == IWL_FW_INI_TIME_POINT_FW_HW_ERROR; +} + static u32 iwl_dump_ini_dump_regions(struct iwl_fw_runtime *fwrt, struct iwl_fwrt_dump_data *dump_data, @@ -2689,8 +2688,7 @@ iwl_dump_ini_dump_regions(struct iwl_fw_runtime *fwrt, * debug data which also need to be collected. */ if (reg_type == IWL_FW_INI_REGION_DRAM_IMR) { - if (tp_id == IWL_FW_INI_TIME_POINT_FW_ASSERT || - tp_id == IWL_FW_INI_TIME_POINT_FW_HW_ERROR) + if (iwl_dump_due_to_error(tp_id)) imr_reg_data->reg_tlv = fwrt->trans->dbg.active_regions[i]; else @@ -2726,8 +2724,8 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt, BUILD_BUG_ON((sizeof(trigger->regions_mask) * BITS_PER_BYTE) < ARRAY_SIZE(fwrt->trans->dbg.active_regions)); - if (trigger->time_point & - cpu_to_le32(IWL_FW_INI_APPLY_POLICY_RESET_HANDSHAKE)) { + if (trigger->apply_policy & + cpu_to_le32(IWL_FW_INI_APPLY_POLICY_SPLIT_DUMP_RESET)) { size += iwl_dump_ini_dump_regions(fwrt, dump_data, list, tp_id, regions_mask, &imr_reg_data, IWL_INI_DUMP_EARLY_REGIONS); @@ -2736,6 +2734,10 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt, regions_mask, &imr_reg_data, IWL_INI_DUMP_LATE_REGIONS); } else { + if (fw_has_capa(&fwrt->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_RESET_DURING_ASSERT) && + iwl_dump_due_to_error(tp_id)) + iwl_trans_pcie_fw_reset_handshake(fwrt->trans); size += iwl_dump_ini_dump_regions(fwrt, dump_data, list, tp_id, regions_mask, &imr_reg_data, IWL_INI_DUMP_ALL_REGIONS); @@ -3282,13 +3284,13 @@ void iwl_fw_error_dump_wk(struct work_struct *work) void iwl_fw_dbg_read_d3_debug_data(struct iwl_fw_runtime *fwrt) { - const struct iwl_cfg *cfg = fwrt->trans->cfg; + const struct iwl_mac_cfg *mac_cfg = fwrt->trans->mac_cfg; if (!iwl_fw_dbg_is_d3_debug_enabled(fwrt)) return; if (!fwrt->dump.d3_debug_data) { - fwrt->dump.d3_debug_data = kmalloc(cfg->d3_debug_data_length, + fwrt->dump.d3_debug_data = kmalloc(mac_cfg->base->d3_debug_data_length, GFP_KERNEL); if (!fwrt->dump.d3_debug_data) { IWL_ERR(fwrt, @@ -3298,15 +3300,15 @@ void iwl_fw_dbg_read_d3_debug_data(struct iwl_fw_runtime *fwrt) } /* if the buffer holds previous debug data it is overwritten */ - iwl_trans_read_mem_bytes(fwrt->trans, cfg->d3_debug_data_base_addr, + iwl_trans_read_mem_bytes(fwrt->trans, mac_cfg->base->d3_debug_data_base_addr, fwrt->dump.d3_debug_data, - cfg->d3_debug_data_length); + mac_cfg->base->d3_debug_data_length); if (fwrt->sanitize_ops && fwrt->sanitize_ops->frob_mem) fwrt->sanitize_ops->frob_mem(fwrt->sanitize_ctx, - cfg->d3_debug_data_base_addr, + mac_cfg->base->d3_debug_data_base_addr, fwrt->dump.d3_debug_data, - cfg->d3_debug_data_length); + mac_cfg->base->d3_debug_data_length); } IWL_EXPORT_SYMBOL(iwl_fw_dbg_read_d3_debug_data); @@ -3341,7 +3343,7 @@ static int iwl_fw_dbg_suspend_resume_hcmd(struct iwl_trans *trans, bool suspend) static void iwl_fw_dbg_stop_recording(struct iwl_trans *trans, struct iwl_fw_dbg_params *params) { - if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000) { + if (trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_7000) { iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100); return; } @@ -3365,7 +3367,7 @@ static int iwl_fw_dbg_restart_recording(struct iwl_trans *trans, if (!params) return -EIO; - if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000) { + if (trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_7000) { iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100); iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1); iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1); @@ -3467,7 +3469,7 @@ void iwl_fw_disable_dbg_asserts(struct iwl_fw_runtime *fwrt) GENMASK(31, IWL_FW_DBG_DOMAIN_POS + 1)); /* supported starting from 9000 devices */ - if (fwrt->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000) + if (fwrt->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_9000) return; if (fwrt->trans->dbg.yoyo_bin_loaded || (preset && preset != 1)) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index 35e30e5db462..8034c9ecba69 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2005-2014, 2018-2019, 2021-2024 Intel Corporation + * Copyright (C) 2005-2014, 2018-2019, 2021-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH */ @@ -201,7 +201,7 @@ static inline bool iwl_fw_dbg_is_d3_debug_enabled(struct iwl_fw_runtime *fwrt) { return fw_has_capa(&fwrt->fw->ucode_capa, IWL_UCODE_TLV_CAPA_D3_DEBUG) && - fwrt->trans->cfg->d3_debug_data_length && fwrt->ops && + fwrt->trans->mac_cfg->base->d3_debug_data_length && fwrt->ops && fwrt->ops->d3_debug_enable && fwrt->ops->d3_debug_enable(fwrt->ops_ctx) && iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_D3_DEBUG_DATA); @@ -210,7 +210,7 @@ static inline bool iwl_fw_dbg_is_d3_debug_enabled(struct iwl_fw_runtime *fwrt) static inline bool iwl_fw_dbg_is_paging_enabled(struct iwl_fw_runtime *fwrt) { return iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_PAGING) && - !fwrt->trans->trans_cfg->gen2 && + !fwrt->trans->mac_cfg->gen2 && fwrt->cur_fw_img < IWL_UCODE_TYPE_MAX && fwrt->fw->img[fwrt->cur_fw_img].paging_mem_size && fwrt->fw_paging_db[0].fw_paging_block; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c index f0c813d675f4..c70f2a20f7d5 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c @@ -311,7 +311,7 @@ static ssize_t iwl_dbgfs_fw_ver_read(struct iwl_fw_runtime *fwrt, pos += scnprintf(pos, endpos - pos, "FW: %s\n", fwrt->fw->human_readable); pos += scnprintf(pos, endpos - pos, "Device: %s\n", - fwrt->trans->name); + fwrt->trans->info.name); pos += scnprintf(pos, endpos - pos, "Bus: %s\n", fwrt->dev->bus->name); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dump.c b/drivers/net/wireless/intel/iwlwifi/fw/dump.c index c7b261c8ec96..3ec42a4ea801 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dump.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dump.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH */ @@ -417,10 +417,10 @@ static void iwl_fwrt_dump_iml_error_log(struct iwl_fw_runtime *fwrt) struct iwl_trans *trans = fwrt->trans; u32 error, data1; - if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { + if (fwrt->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { error = UMAG_SB_CPU_2_STATUS; data1 = UMAG_SB_CPU_1_STATUS; - } else if (fwrt->trans->trans_cfg->device_family >= + } else if (fwrt->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_8000) { error = SB_CPU_2_STATUS; data1 = SB_CPU_1_STATUS; @@ -439,7 +439,7 @@ static void iwl_fwrt_dump_iml_error_log(struct iwl_fw_runtime *fwrt) IWL_ERR(fwrt, "0x%08X | IML/ROM data1\n", iwl_read_umac_prph(trans, data1)); - if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) + if (fwrt->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_22000) IWL_ERR(fwrt, "0x%08X | IML/ROM WFPM_AUTH_KEY_0\n", iwl_read_umac_prph(trans, SB_MODIFY_CFG_FLAG)); } @@ -508,7 +508,7 @@ void iwl_fwrt_dump_error_logs(struct iwl_fw_runtime *fwrt) iwl_fwrt_dump_rcm_error_log(fwrt, 1); iwl_fwrt_dump_iml_error_log(fwrt); iwl_fwrt_dump_fseq_regs(fwrt); - if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { + if (fwrt->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { pc_data = fwrt->trans->dbg.pc_data; if (!iwl_trans_grab_nic_access(fwrt->trans)) @@ -522,7 +522,7 @@ void iwl_fwrt_dump_error_logs(struct iwl_fw_runtime *fwrt) iwl_trans_release_nic_access(fwrt->trans); } - if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { + if (fwrt->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { u32 scratch = iwl_read32(fwrt->trans, CSR_FUNC_SCRATCH); IWL_ERR(fwrt, "Function Scratch status:\n"); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h index 3af275133da0..cf41021d59ad 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2014, 2018-2024 Intel Corporation + * Copyright (C) 2014, 2018-2025 Intel Corporation * Copyright (C) 2014-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -372,10 +372,7 @@ struct iwl_fw_ini_dump_cfg_name { u8 cfg_name[IWL_FW_INI_MAX_CFG_NAME]; } __packed; -/* AX210's HW type */ -#define IWL_AX210_HW_TYPE 0x42 -/* How many bits to roll when adding to the HW type of AX210 HW */ -#define IWL_AX210_HW_TYPE_ADDITION_SHIFT 12 +#define IWL_JACKET_CDB_SHIFT 12 /* struct iwl_fw_ini_dump_info - ini dump information * @version: dump version diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 9860903ecd3f..5a1ec880ed72 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -102,6 +102,7 @@ enum iwl_ucode_tlv_type { IWL_UCODE_TLV_SEC_TABLE_ADDR = 66, IWL_UCODE_TLV_D3_KEK_KCK_ADDR = 67, IWL_UCODE_TLV_CURRENT_PC = 68, + IWL_UCODE_TLV_FSEQ_BIN_VERSION = 72, IWL_UCODE_TLV_FW_NUM_STATIONS = IWL_UCODE_TLV_CONST_BASE + 0, IWL_UCODE_TLV_FW_NUM_LINKS = IWL_UCODE_TLV_CONST_BASE + 1, @@ -402,6 +403,7 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t; * @IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_5G9_FOR_CA: supports (de)activating 5G9 * 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 * * @NUM_IWL_UCODE_TLV_CAPA: number of bits used */ @@ -504,6 +506,14 @@ enum iwl_ucode_tlv_capa { IWL_UCODE_TLV_CAPA_MONITOR_PASSIVE_CHANS = (__force iwl_ucode_tlv_capa_t)122, IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_5G9_FOR_CA = (__force iwl_ucode_tlv_capa_t)123, IWL_UCODE_TLV_CAPA_UHB_CANADA_TAS_SUPPORT = (__force iwl_ucode_tlv_capa_t)124, + IWL_UCODE_TLV_CAPA_EXT_FSEQ_IMAGE_SUPPORT = (__force iwl_ucode_tlv_capa_t)125, + + /* set 4 */ + /** + * @IWL_UCODE_TLV_CAPA_RESET_DURING_ASSERT: FW reset handshake is needed + * 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), NUM_IWL_UCODE_TLV_CAPA /* * This construction make both sparse (which cannot increment the previous @@ -994,6 +1004,10 @@ struct iwl_fw_dump_exclude { __le32 addr, size; }; +struct iwl_fw_fseq_bin_version { + __le32 major, minor; +}; /* FW_TLV_FSEQ_BIN_VERSION_S */ + static inline size_t _iwl_tlv_array_len(const struct iwl_ucode_tlv *tlv, size_t fixed_size, size_t var_size) { @@ -1011,4 +1025,18 @@ static inline size_t _iwl_tlv_array_len(const struct iwl_ucode_tlv *tlv, #define iwl_tlv_array_len_with_size(_tlv_ptr, _struct_ptr, _size) \ _iwl_tlv_array_len((_tlv_ptr), sizeof(*(_struct_ptr)), _size) + +/* external FSEQ file */ +#define IWL_FSEQ_FILE "intel/fseq-%04x-%04x" +#define IWL_FSEQ_MAGIC "INTEL-CNV-FSEQ\n\0" + +struct iwl_fseq_file { + char magic[16]; + char version[16]; + __le32 bt_len; + __le32 wifi_len; + u8 reserved[8]; + u8 data[]; +} __packed; + #endif /* __iwl_fw_file_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/init.c b/drivers/net/wireless/intel/iwlwifi/fw/init.c index de87e0e3e072..d1d8058ad29f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/init.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/init.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2019-2021, 2024 Intel Corporation + * Copyright (C) 2019-2021, 2024-2025 Intel Corporation */ #include "iwl-drv.h" #include "runtime.h" @@ -72,7 +72,7 @@ int iwl_set_soc_latency(struct iwl_fw_runtime *fwrt) * values in VER_1, this is backwards-compatible with VER_2, * as long as we don't set any other bits. */ - if (!fwrt->trans->trans_cfg->integrated) + if (!fwrt->trans->mac_cfg->integrated) cmd.flags = cpu_to_le32(SOC_CONFIG_CMD_FLAGS_DISCRETE); BUILD_BUG_ON(IWL_CFG_TRANS_LTR_DELAY_NONE != @@ -84,17 +84,17 @@ int iwl_set_soc_latency(struct iwl_fw_runtime *fwrt) BUILD_BUG_ON(IWL_CFG_TRANS_LTR_DELAY_1820US != SOC_FLAGS_LTR_APPLY_DELAY_1820); - if (fwrt->trans->trans_cfg->ltr_delay != IWL_CFG_TRANS_LTR_DELAY_NONE && - !WARN_ON(!fwrt->trans->trans_cfg->integrated)) - cmd.flags |= le32_encode_bits(fwrt->trans->trans_cfg->ltr_delay, + if (fwrt->trans->mac_cfg->ltr_delay != IWL_CFG_TRANS_LTR_DELAY_NONE && + !WARN_ON(!fwrt->trans->mac_cfg->integrated)) + cmd.flags |= le32_encode_bits(fwrt->trans->mac_cfg->ltr_delay, SOC_FLAGS_LTR_APPLY_DELAY_MASK); if (iwl_fw_lookup_cmd_ver(fwrt->fw, SCAN_REQ_UMAC, IWL_FW_CMD_VER_UNKNOWN) >= 2 && - fwrt->trans->trans_cfg->low_latency_xtal) + fwrt->trans->mac_cfg->low_latency_xtal) cmd.flags |= cpu_to_le32(SOC_CONFIG_CMD_FLAGS_LOW_LATENCY); - cmd.latency = cpu_to_le32(fwrt->trans->trans_cfg->xtal_latency); + cmd.latency = cpu_to_le32(fwrt->trans->mac_cfg->xtal_latency); ret = iwl_trans_send_cmd(fwrt->trans, &hcmd); if (ret) @@ -116,14 +116,14 @@ int iwl_configure_rxq(struct iwl_fw_runtime *fwrt) * The default queue is configured via context info, so if we * have a single queue, there's nothing to do here. */ - if (fwrt->trans->num_rx_queues == 1) + if (fwrt->trans->info.num_rxqs == 1) return 0; - if (fwrt->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_22000) + if (fwrt->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_22000) return 0; /* skip the default queue */ - num_queues = fwrt->trans->num_rx_queues - 1; + num_queues = fwrt->trans->info.num_rxqs - 1; size = struct_size(cmd, data, num_queues); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/paging.c b/drivers/net/wireless/intel/iwlwifi/fw/paging.c index a7b7cae874a2..826409f6f710 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/paging.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/paging.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2019, 2021 Intel Corporation + * Copyright (C) 2012-2014, 2018-2019, 2021, 2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -267,7 +267,7 @@ int iwl_init_paging(struct iwl_fw_runtime *fwrt, enum iwl_ucode_type type) const struct fw_img *fw = &fwrt->fw->img[type]; int ret; - if (fwrt->trans->trans_cfg->gen2) + if (fwrt->trans->mac_cfg->gen2) return 0; /* diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c index 1195e708caa9..4f3c2f7f4f5b 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright(c) 2020-2024 Intel Corporation + * Copyright(c) 2020-2025 Intel Corporation */ #include "iwl-drv.h" @@ -96,8 +96,8 @@ static int iwl_pnvm_handle_section(struct iwl_trans *trans, const u8 *data, "Got IWL_UCODE_TLV_HW_TYPE mac_type 0x%0x rf_id 0x%0x\n", mac_type, rf_id); - if (mac_type == CSR_HW_REV_TYPE(trans->hw_rev) && - rf_id == CSR_HW_RFID_TYPE(trans->hw_rf_id)) + if (mac_type == CSR_HW_REV_TYPE(trans->info.hw_rev) && + rf_id == CSR_HW_RFID_TYPE(trans->info.hw_rf_id)) hw_match = true; break; case IWL_UCODE_TLV_SEC_RT: { @@ -152,8 +152,8 @@ done: if (!hw_match) { IWL_DEBUG_FW(trans, "HW mismatch, skipping PNVM section (need mac_type 0x%x rf_id 0x%x)\n", - CSR_HW_REV_TYPE(trans->hw_rev), - CSR_HW_RFID_TYPE(trans->hw_rf_id)); + CSR_HW_REV_TYPE(trans->info.hw_rev), + CSR_HW_RFID_TYPE(trans->info.hw_rf_id)); return -ENOENT; } @@ -167,7 +167,8 @@ done: static int iwl_pnvm_parse(struct iwl_trans *trans, const u8 *data, size_t len, - struct iwl_pnvm_image *pnvm_data) + struct iwl_pnvm_image *pnvm_data, + __le32 sku_id[3]) { const struct iwl_ucode_tlv *tlv; @@ -190,23 +191,23 @@ static int iwl_pnvm_parse(struct iwl_trans *trans, const u8 *data, } if (tlv_type == IWL_UCODE_TLV_PNVM_SKU) { - const struct iwl_sku_id *sku_id = + const struct iwl_sku_id *tlv_sku_id = (const void *)(data + sizeof(*tlv)); IWL_DEBUG_FW(trans, "Got IWL_UCODE_TLV_PNVM_SKU len %d\n", tlv_len); IWL_DEBUG_FW(trans, "sku_id 0x%0x 0x%0x 0x%0x\n", - le32_to_cpu(sku_id->data[0]), - le32_to_cpu(sku_id->data[1]), - le32_to_cpu(sku_id->data[2])); + le32_to_cpu(tlv_sku_id->data[0]), + le32_to_cpu(tlv_sku_id->data[1]), + le32_to_cpu(tlv_sku_id->data[2])); data += sizeof(*tlv) + ALIGN(tlv_len, 4); len -= ALIGN(tlv_len, 4); trans->reduced_cap_sku = false; - rf_type = CSR_HW_RFID_TYPE(trans->hw_rf_id); - if ((trans->sku_id[0] & IWL_PNVM_REDUCED_CAP_BIT) && + rf_type = CSR_HW_RFID_TYPE(trans->info.hw_rf_id); + if ((sku_id[0] & cpu_to_le32(IWL_PNVM_REDUCED_CAP_BIT)) && rf_type == IWL_CFG_RF_TYPE_FM) trans->reduced_cap_sku = true; @@ -214,9 +215,9 @@ static int iwl_pnvm_parse(struct iwl_trans *trans, const u8 *data, "Reduced SKU device %d\n", trans->reduced_cap_sku); - if (trans->sku_id[0] == le32_to_cpu(sku_id->data[0]) && - trans->sku_id[1] == le32_to_cpu(sku_id->data[1]) && - trans->sku_id[2] == le32_to_cpu(sku_id->data[2])) { + if (sku_id[0] == tlv_sku_id->data[0] && + sku_id[1] == tlv_sku_id->data[1] && + sku_id[2] == tlv_sku_id->data[2]) { int ret; ret = iwl_pnvm_handle_section(trans, data, len, @@ -263,13 +264,14 @@ static int iwl_pnvm_get_from_fs(struct iwl_trans *trans, u8 **data, size_t *len) return 0; } -static u8 *iwl_get_pnvm_image(struct iwl_trans *trans_p, size_t *len) +static u8 *iwl_get_pnvm_image(struct iwl_trans *trans_p, size_t *len, + __le32 sku_id[3]) { struct pnvm_sku_package *package; u8 *image = NULL; /* Get PNVM from BIOS for non-Intel SKU */ - if (trans_p->sku_id[2]) { + if (sku_id[2]) { package = iwl_uefi_get_pnvm(trans_p, len); if (!IS_ERR_OR_NULL(package)) { if (*len >= sizeof(*package)) { @@ -294,8 +296,10 @@ static u8 *iwl_get_pnvm_image(struct iwl_trans *trans_p, size_t *len) return image; } -static void iwl_pnvm_load_pnvm_to_trans(struct iwl_trans *trans, - const struct iwl_ucode_capabilities *capa) +static void +iwl_pnvm_load_pnvm_to_trans(struct iwl_trans *trans, + const struct iwl_ucode_capabilities *capa, + __le32 sku_id[3]) { struct iwl_pnvm_image *pnvm_data = NULL; u8 *data = NULL; @@ -309,7 +313,7 @@ static void iwl_pnvm_load_pnvm_to_trans(struct iwl_trans *trans, if (trans->pnvm_loaded) goto set; - data = iwl_get_pnvm_image(trans, &length); + data = iwl_get_pnvm_image(trans, &length, sku_id); if (!data) { trans->fail_to_parse_pnvm_image = true; return; @@ -319,7 +323,7 @@ static void iwl_pnvm_load_pnvm_to_trans(struct iwl_trans *trans, if (!pnvm_data) goto free; - ret = iwl_pnvm_parse(trans, data, length, pnvm_data); + ret = iwl_pnvm_parse(trans, data, length, pnvm_data, sku_id); if (ret) { trans->fail_to_parse_pnvm_image = true; goto free; @@ -339,7 +343,8 @@ free: static void iwl_pnvm_load_reduce_power_to_trans(struct iwl_trans *trans, - const struct iwl_ucode_capabilities *capa) + const struct iwl_ucode_capabilities *capa, + __le32 sku_id[3]) { struct iwl_pnvm_image *pnvm_data = NULL; u8 *data = NULL; @@ -362,7 +367,8 @@ iwl_pnvm_load_reduce_power_to_trans(struct iwl_trans *trans, if (!pnvm_data) goto free; - ret = iwl_uefi_reduce_power_parse(trans, data, length, pnvm_data); + ret = iwl_uefi_reduce_power_parse(trans, data, length, pnvm_data, + sku_id); if (ret) { trans->failed_to_load_reduce_power_image = true; goto free; @@ -386,18 +392,19 @@ free: int iwl_pnvm_load(struct iwl_trans *trans, struct iwl_notif_wait_data *notif_wait, - const struct iwl_ucode_capabilities *capa) + const struct iwl_ucode_capabilities *capa, + __le32 sku_id[3]) { struct iwl_notification_wait pnvm_wait; static const u16 ntf_cmds[] = { WIDE_ID(REGULATORY_AND_NVM_GROUP, PNVM_INIT_COMPLETE_NTFY) }; /* if the SKU_ID is empty, there's nothing to do */ - if (!trans->sku_id[0] && !trans->sku_id[1] && !trans->sku_id[2]) + if (!sku_id[0] && !sku_id[1] && !sku_id[2]) return 0; - iwl_pnvm_load_pnvm_to_trans(trans, capa); - iwl_pnvm_load_reduce_power_to_trans(trans, capa); + iwl_pnvm_load_pnvm_to_trans(trans, capa, sku_id); + iwl_pnvm_load_reduce_power_to_trans(trans, capa, sku_id); iwl_init_notification_wait(notif_wait, &pnvm_wait, ntf_cmds, ARRAY_SIZE(ntf_cmds), diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.h b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.h index 1bac3466154c..9540926e8a0f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright(c) 2020-2023 Intel Corporation + * Copyright(c) 2020-2023, 2025 Intel Corporation */ #ifndef __IWL_PNVM_H__ #define __IWL_PNVM_H__ @@ -14,7 +14,8 @@ int iwl_pnvm_load(struct iwl_trans *trans, struct iwl_notif_wait_data *notif_wait, - const struct iwl_ucode_capabilities *capa); + const struct iwl_ucode_capabilities *capa, + __le32 sku_id[3]); static inline void iwl_pnvm_get_fs_name(struct iwl_trans *trans, diff --git a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c index 6adcfa6e214a..74b90bd92c48 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2023 Intel Corporation + * Copyright (C) 2023, 2025 Intel Corporation */ #include <linux/dmi.h> #include "iwl-drv.h" @@ -34,6 +34,7 @@ IWL_BIOS_TABLE_LOADER(wrds_table); IWL_BIOS_TABLE_LOADER(ewrd_table); IWL_BIOS_TABLE_LOADER(wgds_table); IWL_BIOS_TABLE_LOADER(ppag_table); +IWL_BIOS_TABLE_LOADER(phy_filters); IWL_BIOS_TABLE_LOADER_DATA(tas_table, struct iwl_tas_data); IWL_BIOS_TABLE_LOADER_DATA(pwr_limit, u64); IWL_BIOS_TABLE_LOADER_DATA(mcc, char); @@ -180,9 +181,9 @@ bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt) */ return IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) >= 38 || (IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 17 && - fwrt->trans->hw_rev != CSR_HW_REV_TYPE_3160) || + fwrt->trans->info.hw_rev != CSR_HW_REV_TYPE_3160) || (IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 29 && - ((fwrt->trans->hw_rev & CSR_HW_REV_TYPE_MSK) == + ((fwrt->trans->info.hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D)); } IWL_EXPORT_SYMBOL(iwl_sar_geo_support); @@ -313,7 +314,7 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt, bool send_ppag_always; /* many firmware images for JF lie about this */ - if (CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id) == + if (CSR_HW_RFID_TYPE(fwrt->trans->info.hw_rf_id) == CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_JF)) return -EOPNOTSUPP; @@ -338,31 +339,35 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt, return -EINVAL; } - /* The 'flags' field is the same in v1 and in v2 so we can just - * use v1 to access it. - */ - cmd->v1.flags = cpu_to_le32(fwrt->ppag_flags); - IWL_DEBUG_RADIO(fwrt, "PPAG cmd ver is %d\n", cmd_ver); if (cmd_ver == 1) { num_sub_bands = IWL_NUM_SUB_BANDS_V1; gain = cmd->v1.gain[0]; *cmd_size = sizeof(cmd->v1); - if (fwrt->ppag_ver >= 1) { + cmd->v1.flags = cpu_to_le32(fwrt->ppag_flags); + 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_ver); + fwrt->ppag_bios_rev); } } else if (cmd_ver >= 2 && cmd_ver <= 6) { num_sub_bands = IWL_NUM_SUB_BANDS_V2; gain = cmd->v2.gain[0]; *cmd_size = sizeof(cmd->v2); - if (fwrt->ppag_ver == 0) { + cmd->v2.flags = cpu_to_le32(fwrt->ppag_flags); + if (fwrt->ppag_bios_rev == 0) { /* in this case FW supports revisions 1,2 or 3 */ IWL_DEBUG_RADIO(fwrt, "PPAG table rev is 0, send padded table\n"); } + } else if (cmd_ver == 7) { + num_sub_bands = IWL_NUM_SUB_BANDS_V2; + gain = cmd->v3.gain[0]; + *cmd_size = sizeof(cmd->v3); + cmd->v3.ppag_config_info.table_source = fwrt->ppag_bios_source; + cmd->v3.ppag_config_info.table_revision = fwrt->ppag_bios_rev; + cmd->v3.ppag_config_info.value = cpu_to_le32(fwrt->ppag_flags); } else { IWL_DEBUG_RADIO(fwrt, "Unsupported PPAG command version\n"); return -EINVAL; @@ -371,9 +376,11 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt, /* ppag mode */ IWL_DEBUG_RADIO(fwrt, "PPAG MODE bits were read from bios: %d\n", - le32_to_cpu(cmd->v1.flags)); + fwrt->ppag_flags); - if (cmd_ver == 5) + 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); @@ -381,16 +388,20 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt, if ((cmd_ver == 1 && !fw_has_capa(&fwrt->fw->ucode_capa, IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT)) || - (cmd_ver == 2 && fwrt->ppag_ver >= 2)) { + (cmd_ver == 2 && fwrt->ppag_bios_rev >= 2)) { cmd->v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK); IWL_DEBUG_RADIO(fwrt, "masking ppag China bit\n"); } else { IWL_DEBUG_RADIO(fwrt, "isn't masking ppag China bit\n"); } + /* The 'flags' field is the same in v1 and v2 so we can just + * use v1 to access it. + */ IWL_DEBUG_RADIO(fwrt, "PPAG MODE bits going to be sent: %d\n", - le32_to_cpu(cmd->v1.flags)); + (cmd_ver < 7) ? le32_to_cpu(cmd->v1.flags) : + le32_to_cpu(cmd->v3.ppag_config_info.value)); for (i = 0; i < IWL_NUM_CHAIN_LIMITS; i++) { for (j = 0; j < num_sub_bands; j++) { @@ -480,7 +491,7 @@ __le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt) u32 val; __le32 config_bitmap = 0; - switch (CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id)) { + switch (CSR_HW_RFID_TYPE(fwrt->trans->info.hw_rf_id)) { case IWL_CFG_RF_TYPE_HR1: case IWL_CFG_RF_TYPE_HR2: case IWL_CFG_RF_TYPE_JF1: diff --git a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h index 53693314d505..9bed3d573b1e 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2023-2024 Intel Corporation + * Copyright (C) 2023-2025 Intel Corporation */ #ifndef __fw_regulatory_h__ @@ -224,10 +224,14 @@ int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func, u32 *value); static inline u32 iwl_bios_get_ppag_flags(const u32 ppag_modes, - const u8 ppag_ver) + const u8 ppag_bios_rev) { - return ppag_modes & (ppag_ver < 3 ? IWL_PPAG_ETSI_CHINA_MASK : - IWL_PPAG_REV3_MASK); + /* For revision 4 and above driver is pipe */ + if (ppag_bios_rev >= 4) + return ppag_modes; + + return ppag_modes & (ppag_bios_rev < 3 ? IWL_PPAG_ETSI_CHINA_MASK : + IWL_PPAG_REV3_MASK); } bool iwl_puncturing_is_allowed_in_bios(u32 puncturing, u16 mcc); @@ -236,22 +240,25 @@ bool iwl_puncturing_is_allowed_in_bios(u32 puncturing, u16 mcc); #define IWL_DSBR_PERMANENT_URM_MASK BIT(9) int iwl_bios_get_dsbr(struct iwl_fw_runtime *fwrt, u32 *value); +int iwl_bios_get_phy_filters(struct iwl_fw_runtime *fwrt); static inline void iwl_bios_setup_step(struct iwl_trans *trans, struct iwl_fw_runtime *fwrt) { u32 dsbr; - if (!trans->trans_cfg->integrated) + if (!trans->mac_cfg->integrated) return; - if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_BZ) + if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_BZ) return; if (iwl_bios_get_dsbr(fwrt, &dsbr)) dsbr = 0; - trans->dsbr_urm_fw_dependent = !!(dsbr & IWL_DSBR_FW_MODIFIED_URM_MASK); - trans->dsbr_urm_permanent = !!(dsbr & IWL_DSBR_PERMANENT_URM_MASK); + trans->conf.dsbr_urm_fw_dependent = + !!(dsbr & IWL_DSBR_FW_MODIFIED_URM_MASK); + trans->conf.dsbr_urm_permanent = + !!(dsbr & IWL_DSBR_PERMANENT_URM_MASK); } #endif /* __fw_regulatory_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/rs.c b/drivers/net/wireless/intel/iwlwifi/fw/rs.c index 8f99e501629e..746f2acffb8f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/rs.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2021-2022 Intel Corporation + * Copyright (C) 2021-2022, 2025 Intel Corporation */ #include <net/mac80211.h> @@ -91,104 +91,6 @@ const char *iwl_rs_pretty_bw(int bw) } IWL_EXPORT_SYMBOL(iwl_rs_pretty_bw); -static u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags) -{ - int rate = rate_n_flags & RATE_LEGACY_RATE_MSK_V1; - int idx; - bool ofdm = !(rate_n_flags & RATE_MCS_CCK_MSK_V1); - int offset = ofdm ? IWL_FIRST_OFDM_RATE : 0; - int last = ofdm ? IWL_RATE_COUNT_LEGACY : IWL_FIRST_OFDM_RATE; - - for (idx = offset; idx < last; idx++) - if (iwl_fw_rate_idx_to_plcp(idx) == rate) - return idx - offset; - return IWL_RATE_INVALID; -} - -u32 iwl_new_rate_from_v1(u32 rate_v1) -{ - u32 rate_v2 = 0; - u32 dup = 0; - - if (rate_v1 == 0) - return rate_v1; - /* convert rate */ - if (rate_v1 & RATE_MCS_HT_MSK_V1) { - u32 nss = 0; - - rate_v2 |= RATE_MCS_HT_MSK; - rate_v2 |= - rate_v1 & RATE_HT_MCS_RATE_CODE_MSK_V1; - nss = (rate_v1 & RATE_HT_MCS_MIMO2_MSK) >> - RATE_HT_MCS_NSS_POS_V1; - rate_v2 |= nss << RATE_MCS_NSS_POS; - } else if (rate_v1 & RATE_MCS_VHT_MSK_V1 || - rate_v1 & RATE_MCS_HE_MSK_V1) { - rate_v2 |= rate_v1 & RATE_VHT_MCS_RATE_CODE_MSK; - - rate_v2 |= rate_v1 & RATE_MCS_NSS_MSK; - - if (rate_v1 & RATE_MCS_HE_MSK_V1) { - u32 he_type_bits = rate_v1 & RATE_MCS_HE_TYPE_MSK_V1; - u32 he_type = he_type_bits >> RATE_MCS_HE_TYPE_POS_V1; - u32 he_106t = (rate_v1 & RATE_MCS_HE_106T_MSK_V1) >> - RATE_MCS_HE_106T_POS_V1; - u32 he_gi_ltf = (rate_v1 & RATE_MCS_HE_GI_LTF_MSK_V1) >> - RATE_MCS_HE_GI_LTF_POS; - - if ((he_type_bits == RATE_MCS_HE_TYPE_SU || - he_type_bits == RATE_MCS_HE_TYPE_EXT_SU) && - he_gi_ltf == RATE_MCS_HE_SU_4_LTF) - /* the new rate have an additional bit to - * represent the value 4 rather then using SGI - * bit for this purpose - as it was done in the old - * rate */ - he_gi_ltf += (rate_v1 & RATE_MCS_SGI_MSK_V1) >> - RATE_MCS_SGI_POS_V1; - - rate_v2 |= he_gi_ltf << RATE_MCS_HE_GI_LTF_POS; - rate_v2 |= he_type << RATE_MCS_HE_TYPE_POS; - rate_v2 |= he_106t << RATE_MCS_HE_106T_POS; - rate_v2 |= rate_v1 & RATE_HE_DUAL_CARRIER_MODE_MSK; - rate_v2 |= RATE_MCS_HE_MSK; - } else { - rate_v2 |= RATE_MCS_VHT_MSK; - } - /* if legacy format */ - } else { - u32 legacy_rate = iwl_legacy_rate_to_fw_idx(rate_v1); - - if (WARN_ON_ONCE(legacy_rate == IWL_RATE_INVALID)) - legacy_rate = (rate_v1 & RATE_MCS_CCK_MSK_V1) ? - IWL_FIRST_CCK_RATE : IWL_FIRST_OFDM_RATE; - - rate_v2 |= legacy_rate; - if (!(rate_v1 & RATE_MCS_CCK_MSK_V1)) - rate_v2 |= RATE_MCS_LEGACY_OFDM_MSK; - } - - /* convert flags */ - if (rate_v1 & RATE_MCS_LDPC_MSK_V1) - rate_v2 |= RATE_MCS_LDPC_MSK; - rate_v2 |= (rate_v1 & RATE_MCS_CHAN_WIDTH_MSK_V1) | - (rate_v1 & RATE_MCS_ANT_AB_MSK) | - (rate_v1 & RATE_MCS_STBC_MSK) | - (rate_v1 & RATE_MCS_BF_MSK); - - dup = (rate_v1 & RATE_MCS_DUP_MSK_V1) >> RATE_MCS_DUP_POS_V1; - if (dup) { - rate_v2 |= RATE_MCS_DUP_MSK; - rate_v2 |= dup << RATE_MCS_CHAN_WIDTH_POS; - } - - if ((!(rate_v1 & RATE_MCS_HE_MSK_V1)) && - (rate_v1 & RATE_MCS_SGI_MSK_V1)) - rate_v2 |= RATE_MCS_SGI_MSK; - - return rate_v2; -} -IWL_EXPORT_SYMBOL(iwl_new_rate_from_v1); - int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate) { char *type; @@ -197,37 +99,40 @@ int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate) u32 bw = (rate & RATE_MCS_CHAN_WIDTH_MSK) >> RATE_MCS_CHAN_WIDTH_POS; u32 format = rate & RATE_MCS_MOD_TYPE_MSK; + int index = 0; bool sgi; - if (format == RATE_MCS_CCK_MSK || - format == RATE_MCS_LEGACY_OFDM_MSK) { - int legacy_rate = rate & RATE_LEGACY_RATE_MSK; - int index = format == RATE_MCS_CCK_MSK ? - legacy_rate : - legacy_rate + IWL_FIRST_OFDM_RATE; + switch (format) { + case RATE_MCS_MOD_TYPE_LEGACY_OFDM: + index = IWL_FIRST_OFDM_RATE; + fallthrough; + case RATE_MCS_MOD_TYPE_CCK: + index += rate & RATE_LEGACY_RATE_MSK; return scnprintf(buf, bufsz, "Legacy | ANT: %s Rate: %s Mbps", iwl_rs_pretty_ant(ant), iwl_rate_mcs(index)->mbps); - } - - if (format == RATE_MCS_VHT_MSK) + case RATE_MCS_MOD_TYPE_VHT: type = "VHT"; - else if (format == RATE_MCS_HT_MSK) + break; + case RATE_MCS_MOD_TYPE_HT: type = "HT"; - else if (format == RATE_MCS_HE_MSK) + break; + case RATE_MCS_MOD_TYPE_HE: type = "HE"; - else if (format == RATE_MCS_EHT_MSK) + break; + case RATE_MCS_MOD_TYPE_EHT: type = "EHT"; - else + break; + default: type = "Unknown"; /* shouldn't happen */ + } - mcs = format == RATE_MCS_HT_MSK ? + mcs = format == RATE_MCS_MOD_TYPE_HT ? RATE_HT_MCS_INDEX(rate) : rate & RATE_MCS_CODE_MSK; - nss = ((rate & RATE_MCS_NSS_MSK) - >> RATE_MCS_NSS_POS) + 1; - sgi = format == RATE_MCS_HE_MSK ? + nss = u32_get_bits(rate, RATE_MCS_NSS_MSK); + sgi = format == RATE_MCS_MOD_TYPE_HE ? iwl_he_is_sgi(rate) : rate & RATE_MCS_SGI_MSK; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index a9e6bba2419e..0444a736c2b2 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2018-2024 Intel Corporation + * Copyright (C) 2018-2025 Intel Corporation */ #ifndef __iwl_fw_runtime_h__ #define __iwl_fw_runtime_h__ @@ -110,6 +110,9 @@ struct iwl_txf_iter_data { * Only read the UEFI variables if locked. * @sar_profiles: sar profiles as read from WRDS/EWRD BIOS tables * @geo_profiles: geographic profiles as read from WGDS BIOS table + * @phy_filters: specific phy filters as read from WPFC BIOS table + * @ppag_bios_rev: PPAG BIOS revision + * @ppag_bios_source: see &enum bios_source */ struct iwl_fw_runtime { struct iwl_trans *trans; @@ -178,12 +181,14 @@ struct iwl_fw_runtime { bool geo_enabled; struct iwl_ppag_chain ppag_chains[IWL_NUM_CHAIN_LIMITS]; u32 ppag_flags; - u8 ppag_ver; + u8 ppag_bios_rev; + u8 ppag_bios_source; struct iwl_sar_offset_mapping_cmd sgom_table; bool sgom_enabled; struct iwl_mcc_allowed_ap_type_cmd uats_table; bool uats_valid; u8 uefi_tables_lock_status; + struct iwl_phy_specific_cfg phy_filters; }; void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans, diff --git a/drivers/net/wireless/intel/iwlwifi/fw/smem.c b/drivers/net/wireless/intel/iwlwifi/fw/smem.c index 3f1272014daf..90fd69b4860c 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/smem.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/smem.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2021 Intel Corporation + * Copyright (C) 2012-2014, 2018-2021, 2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -102,7 +102,7 @@ void iwl_get_shared_mem_conf(struct iwl_fw_runtime *fwrt) } pkt = cmd.resp_pkt; - if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) + if (fwrt->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_22000) iwl_parse_shared_mem_22000(fwrt, pkt); else iwl_parse_shared_mem(fwrt, pkt); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c index 386aadbce2a2..48126ec6b94b 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c @@ -219,7 +219,8 @@ done: int iwl_uefi_reduce_power_parse(struct iwl_trans *trans, const u8 *data, size_t len, - struct iwl_pnvm_image *pnvm_data) + struct iwl_pnvm_image *pnvm_data, + __le32 sku_id[3]) { const struct iwl_ucode_tlv *tlv; @@ -241,23 +242,23 @@ int iwl_uefi_reduce_power_parse(struct iwl_trans *trans, } if (tlv_type == IWL_UCODE_TLV_PNVM_SKU) { - const struct iwl_sku_id *sku_id = + const struct iwl_sku_id *tlv_sku_id = (const void *)(data + sizeof(*tlv)); IWL_DEBUG_FW(trans, "Got IWL_UCODE_TLV_PNVM_SKU len %d\n", tlv_len); IWL_DEBUG_FW(trans, "sku_id 0x%0x 0x%0x 0x%0x\n", - le32_to_cpu(sku_id->data[0]), - le32_to_cpu(sku_id->data[1]), - le32_to_cpu(sku_id->data[2])); + le32_to_cpu(tlv_sku_id->data[0]), + le32_to_cpu(tlv_sku_id->data[1]), + le32_to_cpu(tlv_sku_id->data[2])); data += sizeof(*tlv) + ALIGN(tlv_len, 4); len -= ALIGN(tlv_len, 4); - if (trans->sku_id[0] == le32_to_cpu(sku_id->data[0]) && - trans->sku_id[1] == le32_to_cpu(sku_id->data[1]) && - trans->sku_id[2] == le32_to_cpu(sku_id->data[2])) { + if (sku_id[0] == tlv_sku_id->data[0] && + sku_id[1] == tlv_sku_id->data[1] && + sku_id[2] == tlv_sku_id->data[2]) { int ret = iwl_uefi_reduce_power_section(trans, data, len, pnvm_data); @@ -310,11 +311,12 @@ static int iwl_uefi_step_parse(struct uefi_cnv_common_step_data *common_step_dat if (common_step_data->revision != 1) return -EINVAL; - trans->mbx_addr_0_step = (u32)common_step_data->revision | + trans->conf.mbx_addr_0_step = + (u32)common_step_data->revision | (u32)common_step_data->cnvi_eq_channel << 8 | (u32)common_step_data->cnvr_eq_channel << 16 | (u32)common_step_data->radio1 << 24; - trans->mbx_addr_1_step = (u32)common_step_data->radio2; + trans->conf.mbx_addr_1_step = (u32)common_step_data->radio2; return 0; } @@ -323,7 +325,7 @@ void iwl_uefi_get_step_table(struct iwl_trans *trans) struct uefi_cnv_common_step_data *data; int ret; - if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) + if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) return; data = iwl_uefi_get_verified_variable_guid(trans, &IWL_EFI_WIFI_BT_GUID, @@ -408,8 +410,8 @@ static int iwl_uefi_uats_parse(struct uefi_cnv_wlan_uats_data *uats_data, return 0; } -int iwl_uefi_get_uats_table(struct iwl_trans *trans, - struct iwl_fw_runtime *fwrt) +void iwl_uefi_get_uats_table(struct iwl_trans *trans, + struct iwl_fw_runtime *fwrt) { struct uefi_cnv_wlan_uats_data *data; int ret; @@ -417,17 +419,12 @@ int iwl_uefi_get_uats_table(struct iwl_trans *trans, data = iwl_uefi_get_verified_variable(trans, IWL_UEFI_UATS_NAME, "UATS", sizeof(*data), NULL); if (IS_ERR(data)) - return -EINVAL; + return; ret = iwl_uefi_uats_parse(data, fwrt); - if (ret < 0) { + if (ret < 0) IWL_DEBUG_FW(trans, "Cannot read UATS table. rev is invalid\n"); - kfree(data); - return ret; - } - kfree(data); - return 0; } IWL_EXPORT_SYMBOL(iwl_uefi_get_uats_table); @@ -557,13 +554,14 @@ int iwl_uefi_get_ppag_table(struct iwl_fw_runtime *fwrt) goto out; } - fwrt->ppag_ver = data->revision; + fwrt->ppag_bios_rev = data->revision; fwrt->ppag_flags = iwl_bios_get_ppag_flags(data->ppag_modes, - fwrt->ppag_ver); + fwrt->ppag_bios_rev); BUILD_BUG_ON(sizeof(fwrt->ppag_chains) != sizeof(data->ppag_chains)); memcpy(&fwrt->ppag_chains, &data->ppag_chains, sizeof(data->ppag_chains)); + fwrt->ppag_bios_source = BIOS_SOURCE_UEFI; out: kfree(data); return ret; @@ -750,6 +748,10 @@ int iwl_uefi_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func, } *value = data->functions[func]; + + IWL_DEBUG_RADIO(fwrt, + "UEFI: DSM func=%d: value=%d\n", func, *value); + ret = 0; out: kfree(data); @@ -810,3 +812,31 @@ out: kfree(data); return ret; } + +int iwl_uefi_get_phy_filters(struct iwl_fw_runtime *fwrt) +{ + struct uefi_cnv_wpfc_data *data __free(kfree); + struct iwl_phy_specific_cfg *filters = &fwrt->phy_filters; + + data = iwl_uefi_get_verified_variable(fwrt->trans, IWL_UEFI_WPFC_NAME, + "WPFC", sizeof(*data), NULL); + if (IS_ERR(data)) + return -EINVAL; + + if (data->revision != 0) { + IWL_DEBUG_RADIO(fwrt, "Unsupported UEFI WPFC revision:%d\n", + data->revision); + return -EINVAL; + } + + BUILD_BUG_ON(ARRAY_SIZE(filters->filter_cfg_chains) != + ARRAY_SIZE(data->chains)); + + for (int i = 0; i < ARRAY_SIZE(filters->filter_cfg_chains); i++) { + filters->filter_cfg_chains[i] = cpu_to_le32(data->chains[i]); + IWL_DEBUG_RADIO(fwrt, "WPFC: chain %d: %u\n", i, data->chains[i]); + } + + IWL_DEBUG_RADIO(fwrt, "Loaded WPFC config from UEFI\n"); + return 0; +} diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h index eb3c05417da3..5a4c557e47c7 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h @@ -24,6 +24,7 @@ #define IWL_UEFI_WBEM_NAME L"UefiCnvWlanWBEM" #define IWL_UEFI_PUNCTURING_NAME L"UefiCnvWlanPuncturing" #define IWL_UEFI_DSBR_NAME L"UefiCnvCommonDSBR" +#define IWL_UEFI_WPFC_NAME L"WPFC" #define IWL_SGOM_MAP_SIZE 339 @@ -33,7 +34,7 @@ #define IWL_UEFI_EWRD_REVISION 2 #define IWL_UEFI_WGDS_REVISION 3 #define IWL_UEFI_MIN_PPAG_REV 1 -#define IWL_UEFI_MAX_PPAG_REV 3 +#define IWL_UEFI_MAX_PPAG_REV 4 #define IWL_UEFI_MIN_WTAS_REVISION 1 #define IWL_UEFI_MAX_WTAS_REVISION 2 #define IWL_UEFI_SPLC_REVISION 0 @@ -230,6 +231,18 @@ struct uefi_cnv_wlan_dsbr_data { u32 config; } __packed; +/** + * struct uefi_cnv_wpfc_data - BIOS Wi-Fi PHY filter Configuration + * @revision: the revision of the table + * @chains: configuration of each of the chains (a-d) + * + * specific PHY filter configuration + */ +struct uefi_cnv_wpfc_data { + u8 revision; + u32 chains[4]; +} __packed; + /* * This is known to be broken on v4.19 and to work on v5.4. Until we * figure out why this is the case and how to make it work, simply @@ -240,7 +253,8 @@ void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len); u8 *iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len); int iwl_uefi_reduce_power_parse(struct iwl_trans *trans, const u8 *data, size_t len, - struct iwl_pnvm_image *pnvm_data); + struct iwl_pnvm_image *pnvm_data, + __le32 sku_id[3]); void iwl_uefi_get_step_table(struct iwl_trans *trans); int iwl_uefi_handle_tlv_mem_desc(struct iwl_trans *trans, const u8 *data, u32 tlv_len, struct iwl_pnvm_image *pnvm_data); @@ -258,10 +272,11 @@ int iwl_uefi_get_wbem(struct iwl_fw_runtime *fwrt, u32 *value); int iwl_uefi_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func, u32 *value); void iwl_uefi_get_sgom_table(struct iwl_trans *trans, struct iwl_fw_runtime *fwrt); -int iwl_uefi_get_uats_table(struct iwl_trans *trans, - struct iwl_fw_runtime *fwrt); +void iwl_uefi_get_uats_table(struct iwl_trans *trans, + struct iwl_fw_runtime *fwrt); int iwl_uefi_get_puncturing(struct iwl_fw_runtime *fwrt); int iwl_uefi_get_dsbr(struct iwl_fw_runtime *fwrt, u32 *value); +int iwl_uefi_get_phy_filters(struct iwl_fw_runtime *fwrt); #else /* CONFIG_EFI */ static inline void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len) { @@ -271,7 +286,8 @@ static inline void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len) static inline int iwl_uefi_reduce_power_parse(struct iwl_trans *trans, const u8 *data, size_t len, - struct iwl_pnvm_image *pnvm_data) + struct iwl_pnvm_image *pnvm_data, + __le32 sku_id[3]) { return -EOPNOTSUPP; } @@ -352,11 +368,9 @@ void iwl_uefi_get_sgom_table(struct iwl_trans *trans, struct iwl_fw_runtime *fwr { } -static inline -int iwl_uefi_get_uats_table(struct iwl_trans *trans, - struct iwl_fw_runtime *fwrt) +static inline void +iwl_uefi_get_uats_table(struct iwl_trans *trans, struct iwl_fw_runtime *fwrt) { - return 0; } static inline @@ -370,5 +384,10 @@ int iwl_uefi_get_dsbr(struct iwl_fw_runtime *fwrt, u32 *value) { return -ENOENT; } + +static inline int iwl_uefi_get_phy_filters(struct iwl_fw_runtime *fwrt) +{ + return -ENOENT; +} #endif /* CONFIG_EFI */ #endif /* __iwl_fw_uefi__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index acafee538b8a..91f22ce36d74 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2005-2014, 2018-2021 Intel Corporation * Copyright (C) 2016-2017 Intel Deutschland GmbH - * Copyright (C) 2018-2024 Intel Corporation + * Copyright (C) 2018-2025 Intel Corporation */ #ifndef __IWL_CONFIG_H__ #define __IWL_CONFIG_H__ @@ -115,7 +115,29 @@ static inline u8 num_of_ant(u8 mask) } /** - * struct iwl_base_params - params not likely to change within a device family + * struct iwl_fw_mon_reg - FW monitor register info + * @addr: register address + * @mask: register mask + */ +struct iwl_fw_mon_reg { + u32 addr; + u32 mask; +}; + +/** + * struct iwl_fw_mon_regs - FW monitor registers + * @write_ptr: write pointer register + * @cycle_cnt: cycle count register + * @cur_frag: current fragment in use + */ +struct iwl_fw_mon_regs { + struct iwl_fw_mon_reg write_ptr; + struct iwl_fw_mon_reg cycle_cnt; + struct iwl_fw_mon_reg cur_frag; +}; + +/** + * struct iwl_family_base_params - base parameters for an entire family * @max_ll_items: max number of OTP blocks * @shadow_ram_support: shadow support for OTP memory * @led_compensation: compensate on the led on/off time per HW according @@ -124,12 +146,34 @@ static inline u8 num_of_ant(u8 mask) * @wd_timeout: TX queues watchdog timeout * @max_event_log_size: size of event log buffer size for ucode event logging * @shadow_reg_enable: HW shadow register support + * @apmg_not_supported: there's no APMG * @apmg_wake_up_wa: should the MAC access REQ be asserted when a command * is in flight. This is due to a HW bug in 7260, 3160 and 7265. * @scd_chain_ext_wa: should the chain extension feature in SCD be disabled. * @max_tfd_queue_size: max number of entries in tfd queue. + * @eeprom_size: EEPROM size + * @num_of_queues: number of HW TX queues supported + * @pcie_l1_allowed: PCIe L1 state is allowed + * @pll_cfg: PLL configuration needed + * @nvm_hw_section_num: the ID of the HW NVM section + * @features: hw features, any combination of feature_passlist + * @smem_offset: offset from which the SMEM begins + * @smem_len: the length of SMEM + * @mac_addr_from_csr: read HW address from CSR registers at this offset + * @d3_debug_data_base_addr: base address where D3 debug data is stored + * @d3_debug_data_length: length of the D3 debug data + * @min_ba_txq_size: minimum number of slots required in a TX queue used + * for aggregation + * @min_txq_size: minimum number of slots required in a TX queue + * @gp2_reg_addr: GP2 (timer) register address + * @min_umac_error_event_table: minimum SMEM location of UMAC error table + * @mon_dbgi_regs: monitor DBGI registers + * @mon_dram_regs: monitor DRAM registers + * @mon_smem_regs: monitor SMEM registers + * @ucode_api_max: Highest version of uCode API supported by driver. + * @ucode_api_min: Lowest version of uCode API supported by driver. */ -struct iwl_base_params { +struct iwl_family_base_params { unsigned int wd_timeout; u16 eeprom_size; @@ -140,6 +184,7 @@ struct iwl_base_params { shadow_reg_enable:1, pcie_l1_allowed:1, apmg_wake_up_wa:1, + apmg_not_supported:1, scd_chain_ext_wa:1; u16 num_of_queues; /* def: HW dependent */ @@ -147,6 +192,22 @@ struct iwl_base_params { u8 max_ll_items; u8 led_compensation; + u8 ucode_api_max; + u8 ucode_api_min; + u32 mac_addr_from_csr:10; + u8 nvm_hw_section_num; + netdev_features_t features; + u32 smem_offset; + u32 smem_len; + u32 min_umac_error_event_table; + u32 d3_debug_data_base_addr; + u32 d3_debug_data_length; + u32 min_txq_size; + u32 gp2_reg_addr; + u32 min_ba_txq_size; + const struct iwl_fw_mon_regs mon_dram_regs; + const struct iwl_fw_mon_regs mon_smem_regs; + const struct iwl_fw_mon_regs mon_dbgi_regs; }; /* @@ -238,7 +299,7 @@ struct iwl_pwr_tx_backoff { u32 backoff; }; -enum iwl_cfg_trans_ltr_delay { +enum iwl_mac_cfg_ltr_delay { IWL_CFG_TRANS_LTR_DELAY_NONE = 0, IWL_CFG_TRANS_LTR_DELAY_200US = 1, IWL_CFG_TRANS_LTR_DELAY_2500US = 2, @@ -246,35 +307,33 @@ enum iwl_cfg_trans_ltr_delay { }; /** - * struct iwl_cfg_trans_params - information needed to start the trans + * struct iwl_mac_cfg - information about the MAC-specific device part * * These values are specific to the device ID and do not change when * multiple configs are used for a single device ID. They values are * used, among other things, to boot the NIC so that the HW REV or * RFID can be read before deciding the remaining parameters to use. * - * @base_params: pointer to basic parameters + * @base: pointer to basic parameters * @device_family: the device family * @umac_prph_offset: offset to add to UMAC periphery address * @xtal_latency: power up latency to get the xtal stabilized * @extra_phy_cfg_flags: extra configuration flags to pass to the PHY - * @rf_id: need to read rf_id to determine the firmware image * @gen2: 22000 and on transport operation * @mq_rx_supported: multi-queue rx support * @integrated: discrete or integrated * @low_latency_xtal: use the low latency xtal if supported * @bisr_workaround: BISR hardware workaround (for 22260 series devices) - * @ltr_delay: LTR delay parameter, &enum iwl_cfg_trans_ltr_delay. + * @ltr_delay: LTR delay parameter, &enum iwl_mac_cfg_ltr_delay. * @imr_enabled: use the IMR if supported. */ -struct iwl_cfg_trans_params { - const struct iwl_base_params *base_params; +struct iwl_mac_cfg { + const struct iwl_family_base_params *base; enum iwl_device_family device_family; u32 umac_prph_offset; u32 xtal_latency; u32 extra_phy_cfg_flags; - u32 rf_id:1, - gen2:1, + u32 gen2:1, mq_rx_supported:1, integrated:1, low_latency_xtal:1, @@ -283,36 +342,21 @@ struct iwl_cfg_trans_params { imr_enabled:1; }; -/** - * struct iwl_fw_mon_reg - FW monitor register info - * @addr: register address - * @mask: register mask - */ -struct iwl_fw_mon_reg { - u32 addr; - u32 mask; -}; - -/** - * struct iwl_fw_mon_regs - FW monitor registers - * @write_ptr: write pointer register - * @cycle_cnt: cycle count register - * @cur_frag: current fragment in use +/* + * These sizes were picked according to 8 MSDUs inside 64/256/612 A-MSDUs + * in an A-MPDU, with additional overhead to account for processing time. + * They will be doubled for MACs starting from So/Ty that don't support + * putting multiple frames into a single buffer. */ -struct iwl_fw_mon_regs { - struct iwl_fw_mon_reg write_ptr; - struct iwl_fw_mon_reg cycle_cnt; - struct iwl_fw_mon_reg cur_frag; -}; +#define IWL_NUM_RBDS_NON_HE (64 * 8) +#define IWL_NUM_RBDS_HE (256 * 8) +#define IWL_NUM_RBDS_EHT (512 * 8) /** - * struct iwl_cfg - * @trans: the trans-specific configuration part - * @name: Official name of the device + * struct iwl_rf_cfg * @fw_name_pre: Firmware filename prefix. The api version and extension * (.ucode) will be added to filename before loading from disk. The * filename is constructed as <fw_name_pre>-<api>.ucode. - * @fw_name_mac: MAC name for this config, the remaining pieces of the * name will be generated dynamically * @ucode_api_max: Highest version of uCode API supported by driver. * @ucode_api_min: Lowest version of uCode API supported by driver. @@ -323,34 +367,25 @@ struct iwl_fw_mon_regs { * @non_shared_ant: the antenna that is for WiFi only * @nvm_ver: NVM version * @nvm_calib_ver: NVM calibration version + * @bw_limit: bandwidth limit for this device, if non-zero * @ht_params: point to ht parameters + * @eeprom_params: EEPROM parameters (old devices) + * @thermal_params: Thermal throttling parameters + * @lp_xtal_workaround: low-power crystal workaround needed * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off) * @rx_with_siso_diversity: 1x1 device with rx antenna diversity * @tx_with_siso_diversity: 1x1 device with tx antenna diversity * @internal_wimax_coex: internal wifi/wimax combo device - * @high_temp: Is this NIC is designated to be in high temperature. * @host_interrupt_operation_mode: device needs host interrupt operation * mode set - * @nvm_hw_section_num: the ID of the HW NVM section - * @mac_addr_from_csr: read HW address from CSR registers at this offset - * @features: hw features, any combination of feature_passlist * @pwr_tx_backoffs: translation table between power limits and backoffs - * @max_tx_agg_size: max TX aggregation size of the ADDBA request/response * @dccm_offset: offset from which DCCM begins * @dccm_len: length of DCCM (including runtime stack CCM) * @dccm2_offset: offset from which the second DCCM begins * @dccm2_len: length of the second DCCM - * @smem_offset: offset from which the SMEM begins - * @smem_len: the length of SMEM * @vht_mu_mimo_supported: VHT MU-MIMO support - * @cdb: CDB support * @nvm_type: see &enum iwl_nvm_type - * @d3_debug_data_base_addr: base address where D3 debug data is stored - * @d3_debug_data_length: length of the D3 debug data - * @min_txq_size: minimum number of slots required in a TX queue * @uhb_supported: ultra high band channels supported - * @min_ba_txq_size: minimum number of slots required in a TX queue which - * based on hardware support (HE - 256, EHT - 1K). * @num_rbds: number of receive buffer descriptors to use * (only used for multi-queue capable devices) * @@ -358,60 +393,38 @@ struct iwl_fw_mon_regs { * API differences in uCode shouldn't be handled here but through TLVs * and/or the uCode API version instead. */ -struct iwl_cfg { - struct iwl_cfg_trans_params trans; +struct iwl_rf_cfg { /* params specific to an individual device within a device family */ - const char *name; const char *fw_name_pre; - const char *fw_name_mac; /* params likely to change within a device family */ - const struct iwl_ht_params *ht_params; + const struct iwl_ht_params ht_params; const struct iwl_eeprom_params *eeprom_params; const struct iwl_pwr_tx_backoff *pwr_tx_backoffs; - const char *default_nvm_file_C_step; const struct iwl_tt_params *thermal_params; enum iwl_led_mode led_mode; enum iwl_nvm_type nvm_type; u32 max_data_size; u32 max_inst_size; - netdev_features_t features; u32 dccm_offset; u32 dccm_len; u32 dccm2_offset; u32 dccm2_len; - u32 smem_offset; - u32 smem_len; u16 nvm_ver; u16 nvm_calib_ver; + u16 bw_limit; u32 rx_with_siso_diversity:1, tx_with_siso_diversity:1, internal_wimax_coex:1, host_interrupt_operation_mode:1, - high_temp:1, - mac_addr_from_csr:10, lp_xtal_workaround:1, - apmg_not_supported:1, vht_mu_mimo_supported:1, - cdb:1, - dbgc_supported:1, uhb_supported:1; u8 valid_tx_ant; u8 valid_rx_ant; u8 non_shared_ant; - u8 nvm_hw_section_num; - u8 max_tx_agg_size; u8 ucode_api_max; u8 ucode_api_min; u16 num_rbds; - u32 min_umac_error_event_table; - u32 d3_debug_data_base_addr; - u32 d3_debug_data_length; - u32 min_txq_size; - u32 gp2_reg_addr; - u32 min_ba_txq_size; - const struct iwl_fw_mon_regs mon_dram_regs; - const struct iwl_fw_mon_regs mon_smem_regs; - const struct iwl_fw_mon_regs mon_dbgi_regs; }; #define IWL_CFG_ANY (~0) @@ -419,8 +432,10 @@ struct iwl_cfg { #define IWL_CFG_MAC_TYPE_PU 0x31 #define IWL_CFG_MAC_TYPE_TH 0x32 #define IWL_CFG_MAC_TYPE_QU 0x33 +#define IWL_CFG_MAC_TYPE_CC 0x34 #define IWL_CFG_MAC_TYPE_QUZ 0x35 #define IWL_CFG_MAC_TYPE_SO 0x37 +#define IWL_CFG_MAC_TYPE_TY 0x42 #define IWL_CFG_MAC_TYPE_SOF 0x43 #define IWL_CFG_MAC_TYPE_MA 0x44 #define IWL_CFG_MAC_TYPE_BZ 0x46 @@ -432,8 +447,6 @@ struct iwl_cfg { #define IWL_CFG_MAC_TYPE_BR 0x4C #define IWL_CFG_MAC_TYPE_DR 0x4D -#define IWL_CFG_RF_TYPE_TH 0x105 -#define IWL_CFG_RF_TYPE_TH1 0x108 #define IWL_CFG_RF_TYPE_JF2 0x105 #define IWL_CFG_RF_TYPE_JF1 0x108 #define IWL_CFG_RF_TYPE_HR2 0x10A @@ -451,12 +464,6 @@ struct iwl_cfg { #define IWL_CFG_RF_ID_HR 0x7 #define IWL_CFG_RF_ID_HR1 0x4 -#define IWL_CFG_NO_160 0x1 -#define IWL_CFG_160 0x0 - -#define IWL_CFG_NO_320 0x1 -#define IWL_CFG_320 0x0 - #define IWL_CFG_CORES_BT 0x0 #define IWL_CFG_CORES_BT_GNSS 0x5 @@ -467,55 +474,133 @@ struct iwl_cfg { #define IWL_CFG_IS_JACKET 0x1 #define IWL_SUBDEVICE_RF_ID(subdevice) ((u16)((subdevice) & 0x00F0) >> 4) -#define IWL_SUBDEVICE_NO_160(subdevice) ((u16)((subdevice) & 0x0200) >> 9) +#define IWL_SUBDEVICE_BW_LIM(subdevice) ((u16)((subdevice) & 0x0200) >> 9) #define IWL_SUBDEVICE_CORES(subdevice) ((u16)((subdevice) & 0x1C00) >> 10) struct iwl_dev_info { + const struct iwl_rf_cfg *cfg; + const char *name; u16 device; u16 subdevice; - u16 mac_type; - u16 rf_type; - u8 mac_step; - u8 rf_step; - u8 rf_id; - u8 no_160; - u8 cores; - u8 cdb; - u8 jacket; - const struct iwl_cfg *cfg; - const char *name; + u32 subdevice_m_l:4, + subdevice_m_h:4, + match_rf_type:1, + rf_type:9, + match_bw_limit:1, + bw_limit:1, + match_rf_step:1, + rf_step:4, + match_rf_id:1, + rf_id:4, + match_cdb:1, + cdb:1; }; #if IS_ENABLED(CONFIG_IWLWIFI_KUNIT_TESTS) extern const struct iwl_dev_info iwl_dev_info_table[]; extern const unsigned int iwl_dev_info_table_size; const struct iwl_dev_info * -iwl_pci_find_dev_info(u16 device, u16 subsystem_device, - u16 mac_type, u8 mac_step, u16 rf_type, u8 cdb, - u8 jacket, u8 rf_id, u8 no_160, u8 cores, u8 rf_step); +iwl_pci_find_dev_info(u16 device, u16 subsystem_device, u16 rf_type, u8 cdb, + u8 rf_id, u8 bw_limit, u8 rf_step); extern const struct pci_device_id iwl_hw_card_ids[]; #endif /* * This list declares the config structures for all devices. */ -extern const struct iwl_cfg_trans_params iwl9000_trans_cfg; -extern const struct iwl_cfg_trans_params iwl9560_trans_cfg; -extern const struct iwl_cfg_trans_params iwl9560_long_latency_trans_cfg; -extern const struct iwl_cfg_trans_params iwl9560_shared_clk_trans_cfg; -extern const struct iwl_cfg_trans_params iwl_qu_trans_cfg; -extern const struct iwl_cfg_trans_params iwl_qu_medium_latency_trans_cfg; -extern const struct iwl_cfg_trans_params iwl_qu_long_latency_trans_cfg; -extern const struct iwl_cfg_trans_params iwl_ax200_trans_cfg; -extern const struct iwl_cfg_trans_params iwl_so_trans_cfg; -extern const struct iwl_cfg_trans_params iwl_so_long_latency_trans_cfg; -extern const struct iwl_cfg_trans_params iwl_so_long_latency_imr_trans_cfg; -extern const struct iwl_cfg_trans_params iwl_ma_trans_cfg; -extern const struct iwl_cfg_trans_params iwl_bz_trans_cfg; -extern const struct iwl_cfg_trans_params iwl_gl_trans_cfg; -extern const struct iwl_cfg_trans_params iwl_sc_trans_cfg; -extern const struct iwl_cfg_trans_params iwl_dr_trans_cfg; -extern const struct iwl_cfg_trans_params iwl_br_trans_cfg; +extern const struct iwl_mac_cfg iwl1000_mac_cfg; +extern const struct iwl_mac_cfg iwl5000_mac_cfg; +extern const struct iwl_mac_cfg iwl2000_mac_cfg; +extern const struct iwl_mac_cfg iwl2030_mac_cfg; +extern const struct iwl_mac_cfg iwl105_mac_cfg; +extern const struct iwl_mac_cfg iwl135_mac_cfg; +extern const struct iwl_mac_cfg iwl5150_mac_cfg; +extern const struct iwl_mac_cfg iwl6005_mac_cfg; +extern const struct iwl_mac_cfg iwl6030_mac_cfg; +extern const struct iwl_mac_cfg iwl6000i_mac_cfg; +extern const struct iwl_mac_cfg iwl6050_mac_cfg; +extern const struct iwl_mac_cfg iwl6150_mac_cfg; +extern const struct iwl_mac_cfg iwl6000_mac_cfg; +extern const struct iwl_mac_cfg iwl7000_mac_cfg; +extern const struct iwl_mac_cfg iwl8000_mac_cfg; +extern const struct iwl_mac_cfg iwl9000_mac_cfg; +extern const struct iwl_mac_cfg iwl9560_mac_cfg; +extern const struct iwl_mac_cfg iwl9560_long_latency_mac_cfg; +extern const struct iwl_mac_cfg iwl9560_shared_clk_mac_cfg; +extern const struct iwl_mac_cfg iwl_qu_mac_cfg; +extern const struct iwl_mac_cfg iwl_qu_medium_latency_mac_cfg; +extern const struct iwl_mac_cfg iwl_qu_long_latency_mac_cfg; +extern const struct iwl_mac_cfg iwl_ax200_mac_cfg; +extern const struct iwl_mac_cfg iwl_ty_mac_cfg; +extern const struct iwl_mac_cfg iwl_so_mac_cfg; +extern const struct iwl_mac_cfg iwl_so_long_latency_mac_cfg; +extern const struct iwl_mac_cfg iwl_so_long_latency_imr_mac_cfg; +extern const struct iwl_mac_cfg iwl_ma_mac_cfg; +extern const struct iwl_mac_cfg iwl_bz_mac_cfg; +extern const struct iwl_mac_cfg iwl_gl_mac_cfg; +extern const struct iwl_mac_cfg iwl_sc_mac_cfg; +extern const struct iwl_mac_cfg iwl_dr_mac_cfg; + +extern const char iwl1000_bgn_name[]; +extern const char iwl1000_bg_name[]; +extern const char iwl100_bgn_name[]; +extern const char iwl100_bg_name[]; +extern const char iwl2000_2bgn_name[]; +extern const char iwl2000_2bgn_d_name[]; +extern const char iwl2030_2bgn_name[]; +extern const char iwl105_bgn_name[]; +extern const char iwl105_bgn_d_name[]; +extern const char iwl135_bgn_name[]; +extern const char iwl5300_agn_name[]; +extern const char iwl5100_bgn_name[]; +extern const char iwl5100_abg_name[]; +extern const char iwl5100_agn_name[]; +extern const char iwl5350_agn_name[]; +extern const char iwl5150_agn_name[]; +extern const char iwl5150_abg_name[]; +extern const char iwl6005_2agn_name[]; +extern const char iwl6005_2abg_name[]; +extern const char iwl6005_2bg_name[]; +extern const char iwl6005_2agn_sff_name[]; +extern const char iwl6005_2agn_d_name[]; +extern const char iwl6005_2agn_mow1_name[]; +extern const char iwl6005_2agn_mow2_name[]; +extern const char iwl6030_2agn_name[]; +extern const char iwl6030_2abg_name[]; +extern const char iwl6030_2bgn_name[]; +extern const char iwl6030_2bg_name[]; +extern const char iwl6035_2agn_name[]; +extern const char iwl6035_2agn_sff_name[]; +extern const char iwl1030_bgn_name[]; +extern const char iwl1030_bg_name[]; +extern const char iwl130_bgn_name[]; +extern const char iwl130_bg_name[]; +extern const char iwl6000i_2agn_name[]; +extern const char iwl6000i_2abg_name[]; +extern const char iwl6000i_2bg_name[]; +extern const char iwl6050_2agn_name[]; +extern const char iwl6050_2abg_name[]; +extern const char iwl6150_bgn_name[]; +extern const char iwl6150_bg_name[]; +extern const char iwl6000_3agn_name[]; +extern const char iwl7260_2ac_name[]; +extern const char iwl7260_2n_name[]; +extern const char iwl7260_n_name[]; +extern const char iwl3160_2ac_name[]; +extern const char iwl3160_2n_name[]; +extern const char iwl3160_n_name[]; +extern const char iwl3165_2ac_name[]; +extern const char iwl3168_2ac_name[]; +extern const char iwl7265_2ac_name[]; +extern const char iwl7265_2n_name[]; +extern const char iwl7265_n_name[]; +extern const char iwl8260_2n_name[]; +extern const char iwl8260_2ac_name[]; +extern const char iwl8265_2ac_name[]; +extern const char iwl8275_2ac_name[]; +extern const char iwl4165_2ac_name[]; +extern const char iwl_killer_1435i_name[]; +extern const char iwl_killer_1434_kix_name[]; extern const char iwl9162_name[]; extern const char iwl9260_name[]; extern const char iwl9260_1_name[]; @@ -548,129 +633,84 @@ extern const char iwl_ax211_killer_1675s_name[]; extern const char iwl_ax211_killer_1675i_name[]; extern const char iwl_ax411_killer_1690s_name[]; extern const char iwl_ax411_killer_1690i_name[]; +extern const char iwl_ax210_name[]; extern const char iwl_ax211_name[]; -extern const char iwl_ax231_name[]; extern const char iwl_ax411_name[]; -extern const char iwl_fm_name[]; -extern const char iwl_wh_name[]; -extern const char iwl_gl_name[]; -extern const char iwl_mtp_name[]; -extern const char iwl_dr_name[]; -extern const char iwl_br_name[]; +extern const char iwl_killer_be1750s_name[]; +extern const char iwl_killer_be1750i_name[]; +extern const char iwl_killer_be1750w_name[]; +extern const char iwl_killer_be1750x_name[]; +extern const char iwl_killer_be1790s_name[]; +extern const char iwl_killer_be1790i_name[]; +extern const char iwl_be201_name[]; +extern const char iwl_be200_name[]; +extern const char iwl_be202_name[]; +extern const char iwl_be401_name[]; +extern const char iwl_be213_name[]; +extern const char iwl_killer_be1775s_name[]; +extern const char iwl_killer_be1775i_name[]; +extern const char iwl_be211_name[]; +extern const char iwl_killer_bn1850w2_name[]; +extern const char iwl_killer_bn1850i_name[]; +extern const char iwl_bn201_name[]; +extern const char iwl_be221_name[]; +extern const char iwl_be223_name[]; #if IS_ENABLED(CONFIG_IWLDVM) -extern const struct iwl_cfg iwl5300_agn_cfg; -extern const struct iwl_cfg iwl5100_agn_cfg; -extern const struct iwl_cfg iwl5350_agn_cfg; -extern const struct iwl_cfg iwl5100_bgn_cfg; -extern const struct iwl_cfg iwl5100_abg_cfg; -extern const struct iwl_cfg iwl5150_agn_cfg; -extern const struct iwl_cfg iwl5150_abg_cfg; -extern const struct iwl_cfg iwl6005_2agn_cfg; -extern const struct iwl_cfg iwl6005_2abg_cfg; -extern const struct iwl_cfg iwl6005_2bg_cfg; -extern const struct iwl_cfg iwl6005_2agn_sff_cfg; -extern const struct iwl_cfg iwl6005_2agn_d_cfg; -extern const struct iwl_cfg iwl6005_2agn_mow1_cfg; -extern const struct iwl_cfg iwl6005_2agn_mow2_cfg; -extern const struct iwl_cfg iwl1030_bgn_cfg; -extern const struct iwl_cfg iwl1030_bg_cfg; -extern const struct iwl_cfg iwl6030_2agn_cfg; -extern const struct iwl_cfg iwl6030_2abg_cfg; -extern const struct iwl_cfg iwl6030_2bgn_cfg; -extern const struct iwl_cfg iwl6030_2bg_cfg; -extern const struct iwl_cfg iwl6000i_2agn_cfg; -extern const struct iwl_cfg iwl6000i_2abg_cfg; -extern const struct iwl_cfg iwl6000i_2bg_cfg; -extern const struct iwl_cfg iwl6000_3agn_cfg; -extern const struct iwl_cfg iwl6050_2agn_cfg; -extern const struct iwl_cfg iwl6050_2abg_cfg; -extern const struct iwl_cfg iwl6150_bgn_cfg; -extern const struct iwl_cfg iwl6150_bg_cfg; -extern const struct iwl_cfg iwl1000_bgn_cfg; -extern const struct iwl_cfg iwl1000_bg_cfg; -extern const struct iwl_cfg iwl100_bgn_cfg; -extern const struct iwl_cfg iwl100_bg_cfg; -extern const struct iwl_cfg iwl130_bgn_cfg; -extern const struct iwl_cfg iwl130_bg_cfg; -extern const struct iwl_cfg iwl2000_2bgn_cfg; -extern const struct iwl_cfg iwl2000_2bgn_d_cfg; -extern const struct iwl_cfg iwl2030_2bgn_cfg; -extern const struct iwl_cfg iwl6035_2agn_cfg; -extern const struct iwl_cfg iwl6035_2agn_sff_cfg; -extern const struct iwl_cfg iwl105_bgn_cfg; -extern const struct iwl_cfg iwl105_bgn_d_cfg; -extern const struct iwl_cfg iwl135_bgn_cfg; +extern const struct iwl_rf_cfg iwl5300_agn_cfg; +extern const struct iwl_rf_cfg iwl5350_agn_cfg; +extern const struct iwl_rf_cfg iwl5100_n_cfg; +extern const struct iwl_rf_cfg iwl5100_abg_cfg; +extern const struct iwl_rf_cfg iwl5150_agn_cfg; +extern const struct iwl_rf_cfg iwl5150_abg_cfg; +extern const struct iwl_rf_cfg iwl6005_non_n_cfg; +extern const struct iwl_rf_cfg iwl6005_n_cfg; +extern const struct iwl_rf_cfg iwl6030_n_cfg; +extern const struct iwl_rf_cfg iwl6030_non_n_cfg; +extern const struct iwl_rf_cfg iwl6000i_2agn_cfg; +extern const struct iwl_rf_cfg iwl6000i_non_n_cfg; +extern const struct iwl_rf_cfg iwl6000i_non_n_cfg; +extern const struct iwl_rf_cfg iwl6000_3agn_cfg; +extern const struct iwl_rf_cfg iwl6050_2agn_cfg; +extern const struct iwl_rf_cfg iwl6050_2abg_cfg; +extern const struct iwl_rf_cfg iwl6150_bgn_cfg; +extern const struct iwl_rf_cfg iwl6150_bg_cfg; +extern const struct iwl_rf_cfg iwl1000_bgn_cfg; +extern const struct iwl_rf_cfg iwl1000_bg_cfg; +extern const struct iwl_rf_cfg iwl100_bgn_cfg; +extern const struct iwl_rf_cfg iwl100_bg_cfg; +extern const struct iwl_rf_cfg iwl130_bgn_cfg; +extern const struct iwl_rf_cfg iwl130_bg_cfg; +extern const struct iwl_rf_cfg iwl2000_2bgn_cfg; +extern const struct iwl_rf_cfg iwl2030_2bgn_cfg; +extern const struct iwl_rf_cfg iwl6035_2agn_cfg; +extern const struct iwl_rf_cfg iwl105_bgn_cfg; +extern const struct iwl_rf_cfg iwl135_bgn_cfg; #endif /* CONFIG_IWLDVM */ #if IS_ENABLED(CONFIG_IWLMVM) -extern const struct iwl_ht_params iwl_22000_ht_params; -extern const struct iwl_cfg iwl7260_2ac_cfg; -extern const struct iwl_cfg iwl7260_2ac_cfg_high_temp; -extern const struct iwl_cfg iwl7260_2n_cfg; -extern const struct iwl_cfg iwl7260_n_cfg; -extern const struct iwl_cfg iwl3160_2ac_cfg; -extern const struct iwl_cfg iwl3160_2n_cfg; -extern const struct iwl_cfg iwl3160_n_cfg; -extern const struct iwl_cfg iwl3165_2ac_cfg; -extern const struct iwl_cfg iwl3168_2ac_cfg; -extern const struct iwl_cfg iwl7265_2ac_cfg; -extern const struct iwl_cfg iwl7265_2n_cfg; -extern const struct iwl_cfg iwl7265_n_cfg; -extern const struct iwl_cfg iwl7265d_2ac_cfg; -extern const struct iwl_cfg iwl7265d_2n_cfg; -extern const struct iwl_cfg iwl7265d_n_cfg; -extern const struct iwl_cfg iwl8260_2n_cfg; -extern const struct iwl_cfg iwl8260_2ac_cfg; -extern const struct iwl_cfg iwl8265_2ac_cfg; -extern const struct iwl_cfg iwl8275_2ac_cfg; -extern const struct iwl_cfg iwl4165_2ac_cfg; -extern const struct iwl_cfg iwl9260_2ac_cfg; -extern const struct iwl_cfg iwl9560_qu_b0_jf_b0_cfg; -extern const struct iwl_cfg iwl9560_qu_c0_jf_b0_cfg; -extern const struct iwl_cfg iwl9560_quz_a0_jf_b0_cfg; -extern const struct iwl_cfg iwl9560_2ac_cfg_soc; -extern const struct iwl_cfg iwl_qu_b0_hr1_b0; -extern const struct iwl_cfg iwl_qu_c0_hr1_b0; -extern const struct iwl_cfg iwl_quz_a0_hr1_b0; -extern const struct iwl_cfg iwl_qu_b0_hr_b0; -extern const struct iwl_cfg iwl_qu_c0_hr_b0; -extern const struct iwl_cfg iwl_ax200_cfg_cc; -extern const struct iwl_cfg iwl_ax201_cfg_qu_hr; -extern const struct iwl_cfg iwl_ax201_cfg_qu_c0_hr_b0; -extern const struct iwl_cfg iwl_ax201_cfg_quz_hr; -extern const struct iwl_cfg iwl_ax1650i_cfg_quz_hr; -extern const struct iwl_cfg iwl_ax1650s_cfg_quz_hr; -extern const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0; -extern const struct iwl_cfg killer1650i_2ax_cfg_qu_b0_hr_b0; -extern const struct iwl_cfg killer1650s_2ax_cfg_qu_c0_hr_b0; -extern const struct iwl_cfg killer1650i_2ax_cfg_qu_c0_hr_b0; -extern const struct iwl_cfg killer1650x_2ax_cfg; -extern const struct iwl_cfg killer1650w_2ax_cfg; -extern const struct iwl_cfg iwlax210_2ax_cfg_so_jf_b0; -extern const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0; -extern const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0_long; -extern const struct iwl_cfg iwlax210_2ax_cfg_ty_gf_a0; -extern const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0; -extern const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0_long; - -extern const struct iwl_cfg iwl_cfg_ma; - -extern const struct iwl_cfg iwl_cfg_so_a0_hr_a0; -extern const struct iwl_cfg iwl_cfg_quz_a0_hr_b0; +extern const struct iwl_rf_cfg iwl7260_cfg; +extern const struct iwl_rf_cfg iwl7260_high_temp_cfg; +extern const struct iwl_rf_cfg iwl3160_cfg; +extern const struct iwl_rf_cfg iwl3165_2ac_cfg; +extern const struct iwl_rf_cfg iwl3168_2ac_cfg; +extern const struct iwl_rf_cfg iwl7265_cfg; +extern const struct iwl_rf_cfg iwl7265d_cfg; +extern const struct iwl_rf_cfg iwl8260_cfg; +extern const struct iwl_rf_cfg iwl8265_cfg; +extern const struct iwl_rf_cfg iwl_rf_jf; +extern const struct iwl_rf_cfg iwl_rf_jf_80mhz; +extern const struct iwl_rf_cfg iwl_rf_hr1; +extern const struct iwl_rf_cfg iwl_rf_hr; +extern const struct iwl_rf_cfg iwl_rf_hr_80mhz; + +extern const struct iwl_rf_cfg iwl_rf_gf; #endif /* CONFIG_IWLMVM */ #if IS_ENABLED(CONFIG_IWLMLD) -extern const struct iwl_ht_params iwl_bz_ht_params; - -extern const struct iwl_ht_params iwl_bz_ht_params; - -extern const struct iwl_cfg iwl_cfg_bz; -extern const struct iwl_cfg iwl_cfg_gl; - -extern const struct iwl_cfg iwl_cfg_sc; -extern const struct iwl_cfg iwl_cfg_sc2; -extern const struct iwl_cfg iwl_cfg_sc2f; -extern const struct iwl_cfg iwl_cfg_dr; -extern const struct iwl_cfg iwl_cfg_br; +extern const struct iwl_rf_cfg iwl_rf_fm; +extern const struct iwl_rf_cfg iwl_rf_fm_160mhz; +#define iwl_rf_wh iwl_rf_fm +#define iwl_rf_wh_160mhz iwl_rf_fm_160mhz +#define iwl_rf_pe iwl_rf_fm #endif /* CONFIG_IWLMLD */ #endif /* __IWL_CONFIG_H__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h b/drivers/net/wireless/intel/iwlwifi/iwl-context-info-v2.h index 20563a32a21a..8c5c0ea46181 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-context-info-v2.h @@ -2,8 +2,8 @@ /* * Copyright (C) 2018, 2020-2025 Intel Corporation */ -#ifndef __iwl_context_info_file_gen3_h__ -#define __iwl_context_info_file_gen3_h__ +#ifndef __iwl_context_info_file_v2_h__ +#define __iwl_context_info_file_v2_h__ #include "iwl-context-info.h" @@ -58,6 +58,7 @@ enum iwl_prph_scratch_mtr_format { * @IWL_PRPH_SCRATCH_RB_SIZE_EXT_16K: 16kB RB size * @IWL_PRPH_SCRATCH_SCU_FORCE_ACTIVE: Indicate fw to set SCU_FORCE_ACTIVE * upon reset. + * @IWL_PRPH_SCRATCH_TOP_RESET: request TOP reset */ enum iwl_prph_scratch_flags { IWL_PRPH_SCRATCH_IMR_DEBUG_EN = BIT(1), @@ -74,15 +75,18 @@ enum iwl_prph_scratch_flags { IWL_PRPH_SCRATCH_RB_SIZE_EXT_12K = 9 << 20, IWL_PRPH_SCRATCH_RB_SIZE_EXT_16K = 10 << 20, IWL_PRPH_SCRATCH_SCU_FORCE_ACTIVE = BIT(29), + IWL_PRPH_SCRATCH_TOP_RESET = BIT(30), }; /** * enum iwl_prph_scratch_ext_flags - PRPH scratch control ext flags + * @IWL_PRPH_SCRATCH_EXT_EXT_FSEQ: external FSEQ image provided * @IWL_PRPH_SCRATCH_EXT_URM_FW: switch to URM mode based on fw setting * @IWL_PRPH_SCRATCH_EXT_URM_PERM: switch to permanent URM mode * @IWL_PRPH_SCRATCH_EXT_32KHZ_CLK_VALID: use external 32 KHz clock */ enum iwl_prph_scratch_ext_flags { + IWL_PRPH_SCRATCH_EXT_EXT_FSEQ = BIT(0), IWL_PRPH_SCRATCH_EXT_URM_FW = BIT(4), IWL_PRPH_SCRATCH_EXT_URM_PERM = BIT(5), IWL_PRPH_SCRATCH_EXT_32KHZ_CLK_VALID = BIT(8), @@ -202,6 +206,19 @@ struct iwl_prph_scratch_ctrl_cfg { struct iwl_prph_scratch_step_cfg step_cfg; } __packed; /* PERIPH_SCRATCH_CTRL_CFG_S */ +#define IWL_NUM_DRAM_FSEQ_ENTRIES 8 + +/** + * struct iwl_context_info_dram_fseq - images DRAM map (with fseq) + * each entry in the map represents a DRAM chunk of up to 32 KB + * @common: UMAC/LMAC/virtual images + * @fseq_img: FSEQ image DRAM map + */ +struct iwl_context_info_dram_fseq { + struct iwl_context_info_dram_nonfseq common; + __le64 fseq_img[IWL_NUM_DRAM_FSEQ_ENTRIES]; +} __packed; /* PERIPH_SCRATCH_DRAM_MAP_S */ + /** * struct iwl_prph_scratch - peripheral scratch mapping * @ctrl_cfg: control and configuration of prph scratch @@ -215,7 +232,7 @@ struct iwl_prph_scratch { __le32 fseq_override; __le32 step_analog_params; __le32 reserved[8]; - struct iwl_context_info_dram dram; + struct iwl_context_info_dram_fseq dram; } __packed; /* PERIPH_SCRATCH_S */ /** @@ -233,7 +250,7 @@ struct iwl_prph_info { } __packed; /* PERIPH_INFO_S */ /** - * struct iwl_context_info_gen3 - device INIT configuration + * struct iwl_context_info_v2 - device INIT configuration * @version: version of the context information * @size: size of context information in DWs * @config: context in which the peripheral would execute - a subset of @@ -276,7 +293,7 @@ struct iwl_prph_info { * @prph_scratch_size: the size of the peripheral scratch structure in DWs * @reserved: reserved */ -struct iwl_context_info_gen3 { +struct iwl_context_info_v2 { __le16 version; __le16 size; __le32 config; @@ -306,22 +323,22 @@ struct iwl_context_info_gen3 { __le32 reserved; } __packed; /* IPC_CONTEXT_INFO_S */ -int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, - const struct fw_img *fw); -void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans, bool alive); +int iwl_pcie_ctxt_info_v2_alloc(struct iwl_trans *trans, + const struct iwl_fw *fw, + const struct fw_img *img); +void iwl_pcie_ctxt_info_v2_kick(struct iwl_trans *trans); +void iwl_pcie_ctxt_info_v2_free(struct iwl_trans *trans, bool alive); -int iwl_trans_pcie_ctx_info_gen3_load_pnvm(struct iwl_trans *trans, - const struct iwl_pnvm_image *pnvm_payloads, - const struct iwl_ucode_capabilities *capa); -void iwl_trans_pcie_ctx_info_gen3_set_pnvm(struct iwl_trans *trans, - const struct iwl_ucode_capabilities *capa); +int iwl_trans_pcie_ctx_info_v2_load_pnvm(struct iwl_trans *trans, + const struct iwl_pnvm_image *pnvm_payloads, + const struct iwl_ucode_capabilities *capa); +void iwl_trans_pcie_ctx_info_v2_set_pnvm(struct iwl_trans *trans, + const struct iwl_ucode_capabilities *capa); int -iwl_trans_pcie_ctx_info_gen3_load_reduce_power(struct iwl_trans *trans, - const struct iwl_pnvm_image *payloads, - const struct iwl_ucode_capabilities *capa); +iwl_trans_pcie_ctx_info_v2_load_reduce_power(struct iwl_trans *trans, + const struct iwl_pnvm_image *payloads, + const struct iwl_ucode_capabilities *capa); void -iwl_trans_pcie_ctx_info_gen3_set_reduce_power(struct iwl_trans *trans, - const struct iwl_ucode_capabilities *capa); -int iwl_trans_pcie_ctx_info_gen3_set_step(struct iwl_trans *trans, - u32 mbx_addr_0_step, u32 mbx_addr_1_step); -#endif /* __iwl_context_info_file_gen3_h__ */ +iwl_trans_pcie_ctx_info_v2_set_reduce_power(struct iwl_trans *trans, + const struct iwl_ucode_capabilities *capa); +#endif /* __iwl_context_info_file_v2_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-context-info.h b/drivers/net/wireless/intel/iwlwifi/iwl-context-info.h index dfd44fabf237..7ae0fbdef208 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-context-info.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-context-info.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2018-2020, 2022, 2024 Intel Corporation + * Copyright (C) 2018-2020, 2022, 2024-2025 Intel Corporation */ #ifndef __iwl_context_info_file_h__ #define __iwl_context_info_file_h__ @@ -78,13 +78,13 @@ struct iwl_context_info_control { } __packed; /** - * struct iwl_context_info_dram - images DRAM map + * struct iwl_context_info_dram_nonfseq - images DRAM map * each entry in the map represents a DRAM chunk of up to 32 KB * @umac_img: UMAC image DRAM map * @lmac_img: LMAC image DRAM map * @virtual_img: paged image DRAM map */ -struct iwl_context_info_dram { +struct iwl_context_info_dram_nonfseq { __le64 umac_img[IWL_MAX_DRAM_ENTRY]; __le64 lmac_img[IWL_MAX_DRAM_ENTRY]; __le64 virtual_img[IWL_MAX_DRAM_ENTRY]; @@ -177,16 +177,16 @@ struct iwl_context_info { struct iwl_context_info_early_dbg_cfg edbg_cfg; struct iwl_context_info_pnvm_cfg pnvm_cfg; __le32 reserved2[16]; - struct iwl_context_info_dram dram; + struct iwl_context_info_dram_nonfseq dram; __le32 reserved3[16]; -} __packed; +} __packed; /* BOOT_LOADER_CONTEXT_INFO_S */ -int iwl_pcie_ctxt_info_init(struct iwl_trans *trans, const struct fw_img *fw); +int iwl_pcie_ctxt_info_init(struct iwl_trans *trans, const struct fw_img *img); void iwl_pcie_ctxt_info_free(struct iwl_trans *trans); void iwl_pcie_ctxt_info_free_paging(struct iwl_trans *trans); int iwl_pcie_init_fw_sec(struct iwl_trans *trans, const struct fw_img *fw, - struct iwl_context_info_dram *ctxt_dram); + struct iwl_context_info_dram_nonfseq *ctxt_dram); void *iwl_pcie_ctxt_info_dma_alloc_coherent(struct iwl_trans *trans, size_t size, dma_addr_t *phys); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h index 3ff493e920d2..0fd452cb94ae 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2005-2014, 2018-2024 Intel Corporation + * Copyright (C) 2005-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH * Copyright (C) 2016 Intel Deutschland GmbH */ @@ -107,6 +107,13 @@ /* GIO Chicken Bits (PCI Express bus link power management) */ #define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100) +#define CSR_IPC_STATE (CSR_BASE + 0x110) +#define CSR_IPC_STATE_RESET 0x00000030 +#define CSR_IPC_STATE_RESET_NONE 0 +#define CSR_IPC_STATE_RESET_SW_READY 1 +#define CSR_IPC_STATE_RESET_TOP_READY 2 +#define CSR_IPC_STATE_RESET_TOP_FOLLOWER 3 + #define CSR_IPC_SLEEP_CONTROL (CSR_BASE + 0x114) #define CSR_IPC_SLEEP_CONTROL_SUSPEND 0x3 #define CSR_IPC_SLEEP_CONTROL_RESUME 0 @@ -194,17 +201,19 @@ #define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */ #define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */ #define CSR_INT_BIT_SW_RX (1 << 3) /* Rx, command responses */ +#define CSR_INT_BIT_RESET_DONE (1 << 2) /* reset handshake with firmware is done */ #define CSR_INT_BIT_WAKEUP (1 << 1) /* NIC controller waking up (pwr mgmt) */ #define CSR_INT_BIT_ALIVE (1 << 0) /* uCode interrupts once it initializes */ -#define CSR_INI_SET_MASK (CSR_INT_BIT_FH_RX | \ - CSR_INT_BIT_HW_ERR | \ - CSR_INT_BIT_FH_TX | \ - CSR_INT_BIT_SW_ERR | \ - CSR_INT_BIT_RF_KILL | \ - CSR_INT_BIT_SW_RX | \ - CSR_INT_BIT_WAKEUP | \ - CSR_INT_BIT_ALIVE | \ +#define CSR_INI_SET_MASK (CSR_INT_BIT_FH_RX | \ + CSR_INT_BIT_HW_ERR | \ + CSR_INT_BIT_FH_TX | \ + CSR_INT_BIT_SW_ERR | \ + CSR_INT_BIT_RF_KILL | \ + CSR_INT_BIT_SW_RX | \ + CSR_INT_BIT_WAKEUP | \ + CSR_INT_BIT_RESET_DONE | \ + CSR_INT_BIT_ALIVE | \ CSR_INT_BIT_RX_PERIODIC) /* interrupt flags in FH (flow handler) (PCI busmaster DMA) */ @@ -641,7 +650,7 @@ enum msix_hw_int_causes { * HW address related registers * *****************************************************************************/ -#define CSR_ADDR_BASE(trans) ((trans)->cfg->mac_addr_from_csr) +#define CSR_ADDR_BASE(trans) ((trans)->mac_cfg->base->mac_addr_from_csr) #define CSR_MAC_ADDR0_OTP(trans) (CSR_ADDR_BASE(trans) + 0x00) #define CSR_MAC_ADDR1_OTP(trans) (CSR_ADDR_BASE(trans) + 0x04) #define CSR_MAC_ADDR0_STRAP(trans) (CSR_ADDR_BASE(trans) + 0x08) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index ce787326aa69..5c8f6dc9a3e0 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -503,7 +503,7 @@ void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans) int res; if (!iwlwifi_mod_params.enable_ini || - trans->trans_cfg->device_family <= IWL_DEVICE_FAMILY_8000) + trans->mac_cfg->device_family <= IWL_DEVICE_FAMILY_8000) return; res = firmware_request_nowarn(&fw, yoyo_bin, dev); @@ -603,11 +603,11 @@ static int iwl_dbg_tlv_alloc_fragments(struct iwl_fw_runtime *fwrt, return 0; num_frags = le32_to_cpu(fw_mon_cfg->max_frags_num); - if (fwrt->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) { + if (fwrt->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) { if (alloc_id != IWL_FW_INI_ALLOCATION_ID_DBGC1) return -EIO; num_frags = 1; - } else if (fwrt->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_BZ && + } else if (fwrt->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_BZ && alloc_id > IWL_FW_INI_ALLOCATION_ID_DBGC3) { return -EIO; } @@ -1241,7 +1241,7 @@ iwl_dbg_tlv_tp_trigger(struct iwl_fw_runtime *fwrt, bool sync, fwrt->trans->dbg.restart_required = false; - if (fwrt->trans->trans_cfg->device_family == + if (fwrt->trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_9000) { fwrt->trans->dbg.restart_required = true; } else if (tp == IWL_FW_INI_TIME_POINT_FW_ASSERT && diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h index 76166e1b10e5..99789c7cef3b 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h @@ -3,7 +3,7 @@ * * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved. * Copyright(C) 2016 Intel Deutschland GmbH - * Copyright(c) 2018, 2023 Intel Corporation + * Copyright(c) 2018, 2023, 2025 Intel Corporation *****************************************************************************/ #ifndef __IWLWIFI_DEVICE_TRACE @@ -54,11 +54,11 @@ static inline size_t iwl_rx_trace_len(const struct iwl_trans *trans, struct ieee80211_hdr *hdr = NULL; size_t hdr_offset; - if (cmd->cmd != trans->rx_mpdu_cmd) + if (cmd->cmd != trans->conf.rx_mpdu_cmd) return len; hdr_offset = sizeof(struct iwl_cmd_header) + - trans->rx_mpdu_cmd_hdr_size; + trans->conf.rx_mpdu_cmd_hdr_size; if (out_hdr_offset) *out_hdr_offset = hdr_offset; @@ -67,7 +67,8 @@ static inline size_t iwl_rx_trace_len(const struct iwl_trans *trans, if (!ieee80211_is_data(hdr->frame_control)) return len; /* maybe try to identify EAPOL frames? */ - return sizeof(__le32) + sizeof(*cmd) + trans->rx_mpdu_cmd_hdr_size + + return sizeof(__le32) + sizeof(*cmd) + + trans->conf.rx_mpdu_cmd_hdr_size + ieee80211_hdrlen(hdr->frame_control); } diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index d36837501e08..9504a0cb8b13 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -176,25 +176,86 @@ static inline char iwl_drv_get_step(int step) static bool iwl_drv_is_wifi7_supported(struct iwl_trans *trans) { - return CSR_HW_RFID_TYPE(trans->hw_rf_id) >= IWL_CFG_RF_TYPE_FM; + return CSR_HW_RFID_TYPE(trans->info.hw_rf_id) >= IWL_CFG_RF_TYPE_FM; } const char *iwl_drv_get_fwname_pre(struct iwl_trans *trans, char *buf) { char mac_step, rf_step; - const char *rf, *cdb; + const char *mac, *rf, *cdb; if (trans->cfg->fw_name_pre) return trans->cfg->fw_name_pre; - if (WARN_ON(!trans->cfg->fw_name_mac)) - return "unconfigured"; + mac_step = iwl_drv_get_step(trans->info.hw_rev_step); - mac_step = iwl_drv_get_step(trans->hw_rev_step); + switch (CSR_HW_REV_TYPE(trans->info.hw_rev)) { + case IWL_CFG_MAC_TYPE_PU: + mac = "9000-pu"; + mac_step = 'b'; + break; + case IWL_CFG_MAC_TYPE_TH: + mac = "9260-th"; + mac_step = 'b'; + break; + case IWL_CFG_MAC_TYPE_QU: + mac = "Qu"; + break; + case IWL_CFG_MAC_TYPE_CC: + /* special case - no RF since it's fixed (discrete) */ + scnprintf(buf, FW_NAME_PRE_BUFSIZE, "iwlwifi-cc-a0"); + return buf; + case IWL_CFG_MAC_TYPE_QUZ: + mac = "QuZ"; + /* all QuZ use A0 firmware */ + mac_step = 'a'; + break; + case IWL_CFG_MAC_TYPE_SO: + case IWL_CFG_MAC_TYPE_SOF: + mac = "so"; + mac_step = 'a'; + break; + case IWL_CFG_MAC_TYPE_TY: + mac = "ty"; + mac_step = 'a'; + break; + case IWL_CFG_MAC_TYPE_MA: + mac = "ma"; + break; + case IWL_CFG_MAC_TYPE_BZ: + case IWL_CFG_MAC_TYPE_BZ_W: + mac = "bz"; + break; + case IWL_CFG_MAC_TYPE_GL: + mac = "gl"; + break; + case IWL_CFG_MAC_TYPE_SC: + mac = "sc"; + break; + case IWL_CFG_MAC_TYPE_SC2: + mac = "sc2"; + break; + case IWL_CFG_MAC_TYPE_SC2F: + mac = "sc2f"; + break; + case IWL_CFG_MAC_TYPE_BR: + mac = "br"; + break; + case IWL_CFG_MAC_TYPE_DR: + mac = "dr"; + break; + default: + return "unknown-mac"; + } - rf_step = iwl_drv_get_step(CSR_HW_RFID_STEP(trans->hw_rf_id)); + rf_step = iwl_drv_get_step(CSR_HW_RFID_STEP(trans->info.hw_rf_id)); - switch (CSR_HW_RFID_TYPE(trans->hw_rf_id)) { + switch (CSR_HW_RFID_TYPE(trans->info.hw_rf_id)) { + case IWL_CFG_RF_TYPE_JF1: + case IWL_CFG_RF_TYPE_JF2: + rf = "jf"; + rf_step = 'b'; + break; case IWL_CFG_RF_TYPE_HR1: case IWL_CFG_RF_TYPE_HR2: rf = "hr"; @@ -202,29 +263,26 @@ const char *iwl_drv_get_fwname_pre(struct iwl_trans *trans, char *buf) break; case IWL_CFG_RF_TYPE_GF: rf = "gf"; + rf_step = 'a'; break; case IWL_CFG_RF_TYPE_FM: rf = "fm"; break; case IWL_CFG_RF_TYPE_WH: - if (SILICON_Z_STEP == - CSR_HW_RFID_STEP(trans->hw_rf_id)) { - rf = "whtc"; - rf_step = 'a'; - } else { - rf = "wh"; - } + rf = "wh"; + break; + case IWL_CFG_RF_TYPE_PE: + rf = "pe"; break; default: return "unknown-rf"; } - cdb = CSR_HW_RFID_IS_CDB(trans->hw_rf_id) ? "4" : ""; + cdb = CSR_HW_RFID_IS_CDB(trans->info.hw_rf_id) ? "4" : ""; scnprintf(buf, FW_NAME_PRE_BUFSIZE, "iwlwifi-%s-%c0-%s%s-%c0", - trans->cfg->fw_name_mac, mac_step, - rf, cdb, rf_step); + mac, mac_step, rf, cdb, rf_step); return buf; } @@ -233,39 +291,64 @@ IWL_EXPORT_SYMBOL(iwl_drv_get_fwname_pre); static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context); +static void iwl_get_ucode_api_versions(struct iwl_trans *trans, + unsigned int *api_min, + unsigned int *api_max) +{ + const struct iwl_family_base_params *base = trans->mac_cfg->base; + const struct iwl_rf_cfg *cfg = trans->cfg; + + if (!base->ucode_api_max) { + *api_min = cfg->ucode_api_min; + *api_max = cfg->ucode_api_max; + return; + } + + if (!cfg->ucode_api_max) { + *api_min = base->ucode_api_min; + *api_max = base->ucode_api_max; + return; + } + + *api_min = max(cfg->ucode_api_min, base->ucode_api_min); + *api_max = min(cfg->ucode_api_max, base->ucode_api_max); +} + static int iwl_request_firmware(struct iwl_drv *drv, bool first) { - const struct iwl_cfg *cfg = drv->trans->cfg; char _fw_name_pre[FW_NAME_PRE_BUFSIZE]; + unsigned int ucode_api_max, ucode_api_min; const char *fw_name_pre; - if (drv->trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_9000 && - (drv->trans->hw_rev_step != SILICON_B_STEP && - drv->trans->hw_rev_step != SILICON_C_STEP)) { + iwl_get_ucode_api_versions(drv->trans, &ucode_api_min, &ucode_api_max); + + if (drv->trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_9000 && + (drv->trans->info.hw_rev_step != SILICON_B_STEP && + drv->trans->info.hw_rev_step != SILICON_C_STEP)) { IWL_ERR(drv, "Only HW steps B and C are currently supported (0x%0x)\n", - drv->trans->hw_rev); + drv->trans->info.hw_rev); return -EINVAL; } fw_name_pre = iwl_drv_get_fwname_pre(drv->trans, _fw_name_pre); if (first) - drv->fw_index = cfg->ucode_api_max; + drv->fw_index = ucode_api_max; else drv->fw_index--; - if (drv->fw_index < cfg->ucode_api_min) { + if (drv->fw_index < ucode_api_min) { IWL_ERR(drv, "no suitable firmware found!\n"); - if (cfg->ucode_api_min == cfg->ucode_api_max) { + if (ucode_api_min == ucode_api_max) { IWL_ERR(drv, "%s-%d is required\n", fw_name_pre, - cfg->ucode_api_max); + ucode_api_max); } else { IWL_ERR(drv, "minimum version required: %s-%d\n", - fw_name_pre, cfg->ucode_api_min); + fw_name_pre, ucode_api_min); IWL_ERR(drv, "maximum version supported: %s-%d\n", - fw_name_pre, cfg->ucode_api_max); + fw_name_pre, ucode_api_max); } IWL_ERR(drv, @@ -1235,7 +1318,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, if (tlv_len != sizeof(*dbg_ptrs)) goto invalid_tlv_len; - if (drv->trans->trans_cfg->device_family < + if (drv->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_22000) break; drv->trans->dbg.umac_error_event_table = @@ -1251,7 +1334,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, if (tlv_len != sizeof(*dbg_ptrs)) goto invalid_tlv_len; - if (drv->trans->trans_cfg->device_family < + if (drv->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_22000) break; drv->trans->dbg.lmac_error_event_table[0] = @@ -1373,7 +1456,7 @@ static int iwl_alloc_ucode(struct iwl_drv *drv, static int validate_sec_sizes(struct iwl_drv *drv, struct iwl_firmware_pieces *pieces, - const struct iwl_cfg *cfg) + const struct iwl_rf_cfg *cfg) { IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %zd\n", get_sec_size(pieces, IWL_UCODE_REGULAR, @@ -1496,14 +1579,15 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) struct iwlwifi_opmode_table *op; int err; struct iwl_firmware_pieces *pieces; - const unsigned int api_max = drv->trans->cfg->ucode_api_max; - const unsigned int api_min = drv->trans->cfg->ucode_api_min; + unsigned int api_min, api_max; size_t trigger_tlv_sz[FW_DBG_TRIGGER_MAX]; u32 api_ver; int i; bool usniffer_images = false; bool failure = true; + iwl_get_ucode_api_versions(drv->trans, &api_min, &api_max); + fw->ucode_capa.max_probe_length = IWL_DEFAULT_MAX_PROBE_LENGTH; fw->ucode_capa.standard_phy_calibration_size = IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE; @@ -1697,14 +1781,14 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) fw->init_evtlog_size = (pieces->init_evtlog_size - 16)/12; else fw->init_evtlog_size = - drv->trans->trans_cfg->base_params->max_event_log_size; + drv->trans->mac_cfg->base->max_event_log_size; fw->init_errlog_ptr = pieces->init_errlog_ptr; fw->inst_evtlog_ptr = pieces->inst_evtlog_ptr; if (pieces->inst_evtlog_size) fw->inst_evtlog_size = (pieces->inst_evtlog_size - 16)/12; else fw->inst_evtlog_size = - drv->trans->trans_cfg->base_params->max_event_log_size; + drv->trans->mac_cfg->base->max_event_log_size; fw->inst_errlog_ptr = pieces->inst_errlog_ptr; /* diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.h b/drivers/net/wireless/intel/iwlwifi/iwl-drv.h index 854957bdf79d..595300a14639 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2005-2014, 2020-2021, 2023 Intel Corporation + * Copyright (C) 2005-2014, 2020-2021, 2023, 2025 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH */ #ifndef __iwl_drv_h__ @@ -53,7 +53,7 @@ struct iwl_drv; struct iwl_trans; -struct iwl_cfg; +struct iwl_rf_cfg; /** * iwl_drv_start - start the drv * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h index 5c8f1868db64..0f6de08b7473 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2005-2014, 2018-2021, 2023-2024 Intel Corporation + * Copyright (C) 2005-2014, 2018-2021, 2023-2025 Intel Corporation * Copyright (C) 2015-2017 Intel Deutschland GmbH */ #ifndef __iwl_fh_h__ @@ -71,7 +71,7 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(struct iwl_trans *trans, unsigned int chnl) { - if (trans->trans_cfg->gen2) { + if (trans->mac_cfg->gen2) { WARN_ON_ONCE(chnl >= 64); return TFH_TFDQ_CBB_TABLE + 8 * chnl; } @@ -378,14 +378,14 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(struct iwl_trans *trans, * Once the RXF-to-DRAM DMA is active, this flag is immediately turned off. */ #define RFH_GEN_STATUS 0xA09808 -#define RFH_GEN_STATUS_GEN3 0xA07824 +#define RFH_GEN_STATUS_AX210 0xA07824 #define RBD_FETCH_IDLE BIT(29) #define SRAM_DMA_IDLE BIT(30) #define RXF_DMA_IDLE BIT(31) /* DMA configuration */ #define RFH_RXF_DMA_CFG 0xA09820 -#define RFH_RXF_DMA_CFG_GEN3 0xA07880 +#define RFH_RXF_DMA_CFG_AX210 0xA07880 /* RB size */ #define RFH_RXF_DMA_RB_SIZE_MASK (0x000F0000) /* bits 16-19 */ #define RFH_RXF_DMA_RB_SIZE_POS 16 @@ -588,13 +588,12 @@ struct iwl_rb_status { #define TFD_QUEUE_SIZE_MAX (256) -#define TFD_QUEUE_SIZE_MAX_GEN3 (65536) /* cb size is the exponent - 3 */ #define TFD_QUEUE_CB_SIZE(x) (ilog2(x) - 3) #define TFD_QUEUE_SIZE_BC_DUP (64) #define TFD_QUEUE_BC_SIZE (TFD_QUEUE_SIZE_MAX + TFD_QUEUE_SIZE_BC_DUP) -#define TFD_QUEUE_BC_SIZE_GEN3_AX210 1024 -#define TFD_QUEUE_BC_SIZE_GEN3_BZ (1024 * 4) +#define TFD_QUEUE_BC_SIZE_AX210 1024 +#define TFD_QUEUE_BC_SIZE_BZ (1024 * 4) #define IWL_TX_DMA_MASK DMA_BIT_MASK(36) #define IWL_NUM_OF_TBS 20 #define IWL_TFH_NUM_TBS 25 @@ -717,30 +716,19 @@ struct iwl_tfh_tfd { /* Fixed (non-configurable) rx data from phy */ /** - * struct iwlagn_scd_bc_tbl - scheduler byte count table + * struct iwl_bc_tbl_entry - scheduler byte count table entry * base physical address provided by SCD_DRAM_BASE_ADDR * For devices up to 22000: * @tfd_offset: * For devices up to 22000: * 0-12 - tx command byte count * 12-16 - station index - * For 22000: + * For 22000 and on: * 0-12 - tx command byte count * 12-13 - number of 64 byte chunks * 14-16 - reserved */ -struct iwlagn_scd_bc_tbl { - __le16 tfd_offset[TFD_QUEUE_BC_SIZE]; -} __packed; - -/** - * struct iwl_gen3_bc_tbl_entry - scheduler byte count table entry gen3 - * For AX210 and on: - * @tfd_offset: 0-12 - tx command byte count - * 12-13 - number of 64 byte chunks - * 14-16 - reserved - */ -struct iwl_gen3_bc_tbl_entry { +struct iwl_bc_tbl_entry { __le16 tfd_offset; } __packed; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.c b/drivers/net/wireless/intel/iwlwifi/iwl-io.c index 0653ca8b974a..80591809164e 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2003-2014, 2018-2022, 2024 Intel Corporation + * Copyright (C) 2003-2014, 2018-2022, 2024-2025 Intel Corporation * Copyright (C) 2015-2016 Intel Deutschland GmbH */ #include <linux/delay.h> @@ -211,13 +211,13 @@ IWL_EXPORT_SYMBOL(iwl_clear_bits_prph); void iwl_force_nmi(struct iwl_trans *trans) { - if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000) + if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_9000) iwl_write_prph_delay(trans, DEVICE_SET_NMI_REG, DEVICE_SET_NMI_VAL_DRV, 1); - else if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) + else if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) iwl_write_umac_prph(trans, UREG_NIC_SET_NMI_DRIVER, UREG_NIC_SET_NMI_DRIVER_NMI_FROM_DRIVER); - else if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_BZ) + else if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_BZ) iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6, UREG_DOORBELL_TO_ISR6_NMI_BIT); else @@ -260,7 +260,7 @@ struct reg { static int iwl_dump_rfh(struct iwl_trans *trans, char **buf) { int i, q; - int num_q = trans->num_rx_queues; + int num_q = trans->info.num_rxqs; static const u32 rfh_tbl[] = { RFH_RXF_DMA_CFG, RFH_GEN_CFG, @@ -368,7 +368,7 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf) FH_TSSR_TX_ERROR_REG }; - if (trans->trans_cfg->mq_rx_supported) + if (trans->mac_cfg->mq_rx_supported) return iwl_dump_rfh(trans, buf); #ifdef CONFIG_IWLWIFI_DEBUGFS @@ -423,7 +423,7 @@ static void iwl_dump_host_monitor_block(struct iwl_trans *trans, static void iwl_dump_host_monitor(struct iwl_trans *trans) { - switch (trans->trans_cfg->device_family) { + switch (trans->mac_cfg->device_family) { case IWL_DEVICE_FAMILY_22000: case IWL_DEVICE_FAMILY_AX210: IWL_ERR(trans, "CSR_RESET = 0x%x\n", @@ -445,11 +445,11 @@ static void iwl_dump_host_monitor(struct iwl_trans *trans) int iwl_finish_nic_init(struct iwl_trans *trans) { - const struct iwl_cfg_trans_params *cfg_trans = trans->trans_cfg; + const struct iwl_mac_cfg *mac_cfg = trans->mac_cfg; u32 poll_ready; int err; - if (cfg_trans->bisr_workaround) { + if (mac_cfg->bisr_workaround) { /* ensure the TOP FSM isn't still in previous reset */ mdelay(2); } @@ -458,7 +458,7 @@ int iwl_finish_nic_init(struct iwl_trans *trans) * Set "initialization complete" bit to move adapter from * D0U* --> D0A* (powered-up active) state. */ - if (cfg_trans->device_family >= IWL_DEVICE_FAMILY_BZ) { + if (mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_BZ_MAC_ACCESS_REQ | CSR_GP_CNTRL_REG_FLAG_MAC_INIT); @@ -469,7 +469,7 @@ int iwl_finish_nic_init(struct iwl_trans *trans) poll_ready = CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY; } - if (cfg_trans->device_family == IWL_DEVICE_FAMILY_8000) + if (mac_cfg->device_family == IWL_DEVICE_FAMILY_8000) udelay(2); /* @@ -484,7 +484,7 @@ int iwl_finish_nic_init(struct iwl_trans *trans) iwl_dump_host_monitor(trans); } - if (cfg_trans->bisr_workaround) { + if (mac_cfg->bisr_workaround) { /* ensure BISR shift has finished */ udelay(200); } diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.h b/drivers/net/wireless/intel/iwlwifi/iwl-io.h index 37b3bd62897e..f4833c5fe86e 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2021, 2025 Intel Corporation */ #ifndef __iwl_io_h__ #define __iwl_io_h__ @@ -64,38 +64,38 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf); */ static inline u32 iwl_umac_prph(struct iwl_trans *trans, u32 ofs) { - return ofs + trans->trans_cfg->umac_prph_offset; + return ofs + trans->mac_cfg->umac_prph_offset; } static inline u32 iwl_read_umac_prph_no_grab(struct iwl_trans *trans, u32 ofs) { return iwl_read_prph_no_grab(trans, ofs + - trans->trans_cfg->umac_prph_offset); + trans->mac_cfg->umac_prph_offset); } static inline u32 iwl_read_umac_prph(struct iwl_trans *trans, u32 ofs) { - return iwl_read_prph(trans, ofs + trans->trans_cfg->umac_prph_offset); + return iwl_read_prph(trans, ofs + trans->mac_cfg->umac_prph_offset); } static inline void iwl_write_umac_prph_no_grab(struct iwl_trans *trans, u32 ofs, u32 val) { - iwl_write_prph_no_grab(trans, ofs + trans->trans_cfg->umac_prph_offset, + iwl_write_prph_no_grab(trans, ofs + trans->mac_cfg->umac_prph_offset, val); } static inline void iwl_write_umac_prph(struct iwl_trans *trans, u32 ofs, u32 val) { - iwl_write_prph(trans, ofs + trans->trans_cfg->umac_prph_offset, val); + iwl_write_prph(trans, ofs + trans->mac_cfg->umac_prph_offset, val); } static inline int iwl_poll_umac_prph_bit(struct iwl_trans *trans, u32 addr, u32 bits, u32 mask, int timeout) { return iwl_poll_prph_bit(trans, addr + - trans->trans_cfg->umac_prph_offset, + trans->mac_cfg->umac_prph_offset, bits, mask, timeout); } diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index c381511e9ec6..0592f0f59d1c 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2005-2014, 2018-2023 Intel Corporation + * Copyright (C) 2005-2014, 2018-2023, 2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -143,6 +143,9 @@ static struct ieee80211_rate iwl_cfg80211_rates[] = { * @NVM_CHANNEL_VALID: channel is usable for this SKU/geo * @NVM_CHANNEL_IBSS: usable as an IBSS channel and deprecated * when %IWL_NVM_SBANDS_FLAGS_LAR enabled. + * @NVM_CHANNEL_ALLOW_20MHZ_ACTIVITY: active scanning allowed and + * AP allowed only in 20 MHz. Valid only + * when %IWL_NVM_SBANDS_FLAGS_LAR enabled. * @NVM_CHANNEL_ACTIVE: active scanning allowed and allows IBSS * when %IWL_NVM_SBANDS_FLAGS_LAR enabled. * @NVM_CHANNEL_RADAR: radar detection required @@ -159,20 +162,21 @@ static struct ieee80211_rate iwl_cfg80211_rates[] = { * @NVM_CHANNEL_AFC: client support connection to UHB AFC AP */ enum iwl_nvm_channel_flags { - NVM_CHANNEL_VALID = BIT(0), - NVM_CHANNEL_IBSS = BIT(1), - NVM_CHANNEL_ACTIVE = BIT(3), - NVM_CHANNEL_RADAR = BIT(4), - NVM_CHANNEL_INDOOR_ONLY = BIT(5), - NVM_CHANNEL_GO_CONCURRENT = BIT(6), - NVM_CHANNEL_UNIFORM = BIT(7), - NVM_CHANNEL_20MHZ = BIT(8), - NVM_CHANNEL_40MHZ = BIT(9), - NVM_CHANNEL_80MHZ = BIT(10), - NVM_CHANNEL_160MHZ = BIT(11), - NVM_CHANNEL_DC_HIGH = BIT(12), - NVM_CHANNEL_VLP = BIT(13), - NVM_CHANNEL_AFC = BIT(14), + NVM_CHANNEL_VALID = BIT(0), + NVM_CHANNEL_IBSS = BIT(1), + NVM_CHANNEL_ALLOW_20MHZ_ACTIVITY = BIT(2), + NVM_CHANNEL_ACTIVE = BIT(3), + NVM_CHANNEL_RADAR = BIT(4), + NVM_CHANNEL_INDOOR_ONLY = BIT(5), + NVM_CHANNEL_GO_CONCURRENT = BIT(6), + NVM_CHANNEL_UNIFORM = BIT(7), + NVM_CHANNEL_20MHZ = BIT(8), + NVM_CHANNEL_40MHZ = BIT(9), + NVM_CHANNEL_80MHZ = BIT(10), + NVM_CHANNEL_160MHZ = BIT(11), + NVM_CHANNEL_DC_HIGH = BIT(12), + NVM_CHANNEL_VLP = BIT(13), + NVM_CHANNEL_AFC = BIT(14), }; /** @@ -332,7 +336,7 @@ static inline void iwl_nvm_print_channel_flags(struct device *dev, u32 level, } static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, enum nl80211_band band, - u32 nvm_flags, const struct iwl_cfg *cfg) + u32 nvm_flags, const struct iwl_rf_cfg *cfg) { u32 flags = IEEE80211_CHAN_NO_HT40; @@ -399,7 +403,7 @@ static int iwl_init_channel_map(struct iwl_trans *trans, const void * const nvm_ch_flags, u32 sbands_flags, bool v4) { - const struct iwl_cfg *cfg = trans->cfg; + const struct iwl_rf_cfg *cfg = trans->cfg; struct device *dev = trans->dev; int ch_idx; int n_channels = 0; @@ -500,7 +504,7 @@ static void iwl_init_vht_hw_capab(struct iwl_trans *trans, struct ieee80211_sta_vht_cap *vht_cap, u8 tx_chains, u8 rx_chains) { - const struct iwl_cfg *cfg = trans->cfg; + const struct iwl_rf_cfg *cfg = trans->cfg; int num_rx_ants = num_of_ant(rx_chains); int num_tx_ants = num_of_ant(tx_chains); @@ -513,7 +517,7 @@ static void iwl_init_vht_hw_capab(struct iwl_trans *trans, IEEE80211_VHT_MAX_AMPDU_1024K << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; - if (!trans->cfg->ht_params->stbc) + if (!trans->cfg->ht_params.stbc) vht_cap->cap &= ~IEEE80211_VHT_CAP_RXSTBC_MASK; if (data->vht160_supported) @@ -523,7 +527,7 @@ static void iwl_init_vht_hw_capab(struct iwl_trans *trans, if (cfg->vht_mu_mimo_supported) vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE; - if (cfg->ht_params->ldpc) + if (cfg->ht_params.ldpc) vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC; if (data->sku_cap_mimo_disabled) { @@ -531,21 +535,21 @@ static void iwl_init_vht_hw_capab(struct iwl_trans *trans, num_tx_ants = 1; } - if (trans->cfg->ht_params->stbc && num_tx_ants > 1) + if (trans->cfg->ht_params.stbc && num_tx_ants > 1) vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC; else vht_cap->cap |= IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN; switch (iwlwifi_mod_params.amsdu_size) { case IWL_AMSDU_DEF: - if (trans->trans_cfg->mq_rx_supported) + if (trans->mac_cfg->mq_rx_supported) vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454; else vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895; break; case IWL_AMSDU_2K: - if (trans->trans_cfg->mq_rx_supported) + if (trans->mac_cfg->mq_rx_supported) vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454; else @@ -916,8 +920,8 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans, { bool is_ap = iftype_data->types_mask & (BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_GO)); - bool slow_pcie = (!trans->trans_cfg->integrated && - trans->pcie_link_speed < PCI_EXP_LNKSTA_CLS_8_0GB); + bool slow_pcie = (!trans->mac_cfg->integrated && + trans->info.pcie_link_speed < PCI_EXP_LNKSTA_CLS_8_0GB); if (!data->sku_cap_11be_enable || iwlwifi_mod_params.disable_11be) iftype_data->eht_cap.has_eht = false; @@ -944,7 +948,8 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans, IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_MASK); break; case NL80211_BAND_6GHZ: - if (!trans->reduced_cap_sku) { + if (!trans->reduced_cap_sku && + (!trans->cfg->bw_limit || trans->cfg->bw_limit >= 320)) { iftype_data->eht_cap.eht_cap_elem.phy_cap_info[0] |= IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ; iftype_data->eht_cap.eht_cap_elem.phy_cap_info[1] |= @@ -1031,11 +1036,11 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans, cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << 2); } - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210 && !is_ap) + 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->hw_rf_id)) { + 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: @@ -1047,7 +1052,7 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans, break; } - if (CSR_HW_REV_TYPE(trans->hw_rev) == IWL_CFG_MAC_TYPE_GL && + 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 | @@ -1076,13 +1081,13 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans, iftype_data->he_cap.he_cap_elem.mac_cap_info[2] |= IEEE80211_HE_MAC_CAP2_BCAST_TWT; - if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000 && + if (trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_22000 && !is_ap) { iftype_data->vendor_elems.data = iwl_vendor_caps; iftype_data->vendor_elems.len = ARRAY_SIZE(iwl_vendor_caps); } - if (!trans->cfg->ht_params->stbc) { + if (!trans->cfg->ht_params.stbc) { iftype_data->he_cap.he_cap_elem.phy_cap_info[2] &= ~IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ; iftype_data->he_cap.he_cap_elem.phy_cap_info[7] &= @@ -1094,19 +1099,23 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans, iftype_data->eht_cap.eht_mcs_nss_supp.bw._320.rx_tx_mcs13_max_nss = 0; } - if (trans->no_160) + if (trans->cfg->bw_limit && trans->cfg->bw_limit < 160) iftype_data->he_cap.he_cap_elem.phy_cap_info[0] &= ~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; - if (trans->reduced_cap_sku) { + if ((trans->cfg->bw_limit && trans->cfg->bw_limit < 320) || + trans->reduced_cap_sku) { memset(&iftype_data->eht_cap.eht_mcs_nss_supp.bw._320, 0, sizeof(iftype_data->eht_cap.eht_mcs_nss_supp.bw._320)); + iftype_data->eht_cap.eht_cap_elem.phy_cap_info[2] &= + ~IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_320MHZ_MASK; + } + + if (trans->reduced_cap_sku) { iftype_data->eht_cap.eht_mcs_nss_supp.bw._80.rx_tx_mcs13_max_nss = 0; iftype_data->eht_cap.eht_mcs_nss_supp.bw._160.rx_tx_mcs13_max_nss = 0; iftype_data->eht_cap.eht_cap_elem.phy_cap_info[8] &= ~IEEE80211_EHT_PHY_CAP8_RX_4096QAM_WIDER_BW_DL_OFDMA; - iftype_data->eht_cap.eht_cap_elem.phy_cap_info[2] &= - ~IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_320MHZ_MASK; } } @@ -1242,7 +1251,7 @@ static void iwl_init_sbands(struct iwl_trans *trans, n_used, n_channels); } -static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw, +static int iwl_get_sku(const struct iwl_rf_cfg *cfg, const __le16 *nvm_sw, const __le16 *phy_sku) { if (cfg->nvm_type != IWL_NVM_EXT) @@ -1251,7 +1260,7 @@ static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw, return le32_to_cpup((const __le32 *)(phy_sku + SKU_FAMILY_8000)); } -static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw) +static int iwl_get_nvm_version(const struct iwl_rf_cfg *cfg, const __le16 *nvm_sw) { if (cfg->nvm_type != IWL_NVM_EXT) return le16_to_cpup(nvm_sw + NVM_VERSION); @@ -1260,7 +1269,7 @@ static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw) NVM_VERSION_EXT_NVM)); } -static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, const __le16 *nvm_sw, +static int iwl_get_radio_cfg(const struct iwl_rf_cfg *cfg, const __le16 *nvm_sw, const __le16 *phy_sku) { if (cfg->nvm_type != IWL_NVM_EXT) @@ -1270,7 +1279,7 @@ static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, const __le16 *nvm_sw, } -static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg, const __le16 *nvm_sw) +static int iwl_get_n_hw_addrs(const struct iwl_rf_cfg *cfg, const __le16 *nvm_sw) { int n_hw_addr; @@ -1282,7 +1291,7 @@ static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg, const __le16 *nvm_sw) return n_hw_addr & N_HW_ADDR_MASK; } -static void iwl_set_radio_cfg(const struct iwl_cfg *cfg, +static void iwl_set_radio_cfg(const struct iwl_rf_cfg *cfg, struct iwl_nvm_data *data, u32 radio_cfg) { @@ -1341,7 +1350,7 @@ static void iwl_set_hw_address_from_csr(struct iwl_trans *trans, } static void iwl_set_hw_address_family_8000(struct iwl_trans *trans, - const struct iwl_cfg *cfg, + const struct iwl_rf_cfg *cfg, struct iwl_nvm_data *data, const __le16 *mac_override, const __be16 *nvm_hw) @@ -1390,11 +1399,12 @@ static void iwl_set_hw_address_family_8000(struct iwl_trans *trans, } static int iwl_set_hw_address(struct iwl_trans *trans, - const struct iwl_cfg *cfg, + const struct iwl_rf_cfg *cfg, struct iwl_nvm_data *data, const __be16 *nvm_hw, const __le16 *mac_override) { - if (cfg->mac_addr_from_csr) { + const struct iwl_mac_cfg *mac_cfg = trans->mac_cfg; + if (mac_cfg->base->mac_addr_from_csr) { iwl_set_hw_address_from_csr(trans, data); } else if (cfg->nvm_type != IWL_NVM_EXT) { const u8 *hw_addr = (const u8 *)(nvm_hw + HW_ADDR); @@ -1424,7 +1434,7 @@ static int iwl_set_hw_address(struct iwl_trans *trans, } static bool -iwl_nvm_no_wide_in_5ghz(struct iwl_trans *trans, const struct iwl_cfg *cfg, +iwl_nvm_no_wide_in_5ghz(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg, const __be16 *nvm_hw) { /* @@ -1436,7 +1446,7 @@ iwl_nvm_no_wide_in_5ghz(struct iwl_trans *trans, const struct iwl_cfg *cfg, * in 5GHz otherwise the FW will throw a sysassert when we try * to use them. */ - if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000) { + if (trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_7000) { /* * Unlike the other sections in the NVM, the hw * section uses big-endian. @@ -1456,7 +1466,7 @@ iwl_nvm_no_wide_in_5ghz(struct iwl_trans *trans, const struct iwl_cfg *cfg, } struct iwl_nvm_data * -iwl_parse_mei_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, +iwl_parse_mei_nvm_data(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg, const struct iwl_mei_nvm *mei_nvm, const struct iwl_fw *fw, u8 tx_ant, u8 rx_ant) { @@ -1520,7 +1530,7 @@ iwl_parse_mei_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, IWL_EXPORT_SYMBOL(iwl_parse_mei_nvm_data); struct iwl_nvm_data * -iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, +iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg, const struct iwl_fw *fw, const __be16 *nvm_hw, const __le16 *nvm_sw, const __le16 *nvm_calib, const __le16 *regulatory, @@ -1620,7 +1630,7 @@ IWL_EXPORT_SYMBOL(iwl_parse_nvm_data); static u32 iwl_nvm_get_regdom_bw_flags(const u16 *nvm_chan, int ch_idx, u16 nvm_flags, struct iwl_reg_capa reg_capa, - const struct iwl_cfg *cfg) + const struct iwl_rf_cfg *cfg) { u32 flags = NL80211_RRF_NO_HT40; @@ -1655,6 +1665,10 @@ static u32 iwl_nvm_get_regdom_bw_flags(const u16 *nvm_chan, if (nvm_flags & NVM_CHANNEL_INDOOR_ONLY) flags |= NL80211_RRF_NO_OUTDOOR; + if (nvm_flags & NVM_CHANNEL_ALLOW_20MHZ_ACTIVITY && + flags & NL80211_RRF_NO_IR) + flags |= NL80211_RRF_ALLOW_20MHZ_ACTIVITY; + /* Set the GO concurrent flag only in case that NO_IR is set. * Otherwise it is meaningless */ @@ -1731,10 +1745,12 @@ static struct iwl_reg_capa iwl_get_reg_capa(u32 flags, u8 resp_ver) } struct ieee80211_regdomain * -iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, +iwl_parse_nvm_mcc_info(struct iwl_trans *trans, int num_of_ch, __le32 *channels, u16 fw_mcc, u16 geo_info, u32 cap, u8 resp_ver) { + const struct iwl_rf_cfg *cfg = trans->cfg; + struct device *dev = trans->dev; int ch_idx; u16 ch_flags; u32 reg_rule_flags, prev_reg_rule_flags = 0; @@ -1989,8 +2005,8 @@ int iwl_read_external_nvm(struct iwl_trans *trans, le32_to_cpu(dword_buff[3])); /* nvm file validation, dword_buff[2] holds the file version */ - if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_8000 && - trans->hw_rev_step == SILICON_C_STEP && + if (trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_8000 && + trans->info.hw_rev_step == SILICON_C_STEP && le32_to_cpu(dword_buff[2]) < 0xE4A) { ret = -EFAULT; goto out; @@ -2057,7 +2073,7 @@ int iwl_read_external_nvm(struct iwl_trans *trans, break; } - iwl_nvm_fixups(trans->hw_id, section_id, temp, section_size); + iwl_nvm_fixups(trans->info.hw_id, section_id, temp, section_size); kfree(nvm_sections[section_id].data); nvm_sections[section_id].data = temp; @@ -2160,7 +2176,7 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans, !!(mac_flags & NVM_MAC_SKU_FLAGS_BAND_5_2_ENABLED); nvm->sku_cap_mimo_disabled = !!(mac_flags & NVM_MAC_SKU_FLAGS_MIMO_DISABLED); - if (CSR_HW_RFID_TYPE(trans->hw_rf_id) >= IWL_CFG_RF_TYPE_FM) + if (CSR_HW_RFID_TYPE(trans->info.hw_rf_id) >= IWL_CFG_RF_TYPE_FM) nvm->sku_cap_11be_enable = true; /* Initialize PHY sku data */ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h index 0c6c3fb8c6dd..9ce9fa4e78fd 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2005-2015, 2018-2024 Intel Corporation + * Copyright (C) 2005-2015, 2018-2025 Intel Corporation * Copyright (C) 2016-2017 Intel Deutschland GmbH */ #ifndef __iwl_nvm_parse_h__ @@ -30,7 +30,7 @@ enum iwl_nvm_sbands_flags { * later with iwl_free_nvm_data(). */ struct iwl_nvm_data * -iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, +iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg, const struct iwl_fw *fw, const __be16 *nvm_hw, const __le16 *nvm_sw, const __le16 *nvm_calib, const __le16 *regulatory, @@ -46,9 +46,17 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, * accordingly. An ERR_PTR is returned on error. * If not given to the regulatory core, the user is responsible for freeing * the regdomain returned here with kfree. + * + * @trans: the transport + * @num_of_ch: the number of channels + * @channels: channel map + * @fw_mcc: firmware country code + * @geo_info: geo info value + * @cap: capability + * @resp_ver: FW response version */ struct ieee80211_regdomain * -iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, +iwl_parse_nvm_mcc_info(struct iwl_trans *trans, int num_of_ch, __le32 *channels, u16 fw_mcc, u16 geo_info, u32 cap, u8 resp_ver); @@ -87,7 +95,7 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans, * iwl_parse_mei_nvm_data - parse the mei_nvm_data and get an iwl_nvm_data */ struct iwl_nvm_data * -iwl_parse_mei_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, +iwl_parse_mei_nvm_data(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg, const struct iwl_mei_nvm *mei_nvm, const struct iwl_fw *fw, u8 set_tx_ant, u8 set_rx_ant); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-utils.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-utils.c index b3c25acd3691..ec312c90ff85 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-utils.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-utils.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2005-2014, 2018-2021, 2023 Intel Corporation + * Copyright (C) 2005-2014, 2018-2021, 2023, 2025 Intel Corporation * Copyright (C) 2015 Intel Mobile Communications GmbH */ #include <linux/types.h> @@ -42,7 +42,7 @@ void iwl_init_ht_hw_capab(struct iwl_trans *trans, enum nl80211_band band, u8 tx_chains, u8 rx_chains) { - const struct iwl_cfg *cfg = trans->cfg; + const struct iwl_rf_cfg *cfg = trans->cfg; int max_bit_rate = 0; tx_chains = hweight8(tx_chains); @@ -53,7 +53,8 @@ void iwl_init_ht_hw_capab(struct iwl_trans *trans, if (!(data->sku_cap_11n_enable) || (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL) || - !cfg->ht_params) { + /* there are no devices with HT but without HT40 entirely */ + !cfg->ht_params.ht40_bands) { ht_info->ht_supported = false; return; } @@ -64,17 +65,17 @@ void iwl_init_ht_hw_capab(struct iwl_trans *trans, ht_info->ht_supported = true; ht_info->cap = IEEE80211_HT_CAP_DSSSCCK40; - if (cfg->ht_params->stbc) { + if (cfg->ht_params.stbc) { ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); if (tx_chains > 1) ht_info->cap |= IEEE80211_HT_CAP_TX_STBC; } - if (cfg->ht_params->ldpc) + if (cfg->ht_params.ldpc) ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING; - if (trans->trans_cfg->mq_rx_supported || + if (trans->mac_cfg->mq_rx_supported || iwlwifi_mod_params.amsdu_size >= IWL_AMSDU_8K) ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; @@ -90,13 +91,13 @@ void iwl_init_ht_hw_capab(struct iwl_trans *trans, if (rx_chains >= 3) ht_info->mcs.rx_mask[2] = 0xFF; - if (cfg->ht_params->ht_greenfield_support) + if (cfg->ht_params.ht_greenfield_support) ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; ht_info->cap |= IEEE80211_HT_CAP_SGI_20; max_bit_rate = MAX_BIT_RATE_20_MHZ; - if (cfg->ht_params->ht40_bands & BIT(band)) { + if (cfg->ht_params.ht40_bands & BIT(band)) { ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; ht_info->cap |= IEEE80211_HT_CAP_SGI_40; max_bit_rate = MAX_BIT_RATE_40_MHZ; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h index 34eca1a568ea..5dc299296d6d 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2005-2014, 2018-2021, 2024 Intel Corporation + * Copyright (C) 2005-2014, 2018-2021, 2024-2025 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH * Copyright (C) 2015 Intel Deutschland GmbH */ @@ -17,7 +17,7 @@ struct sk_buff; struct iwl_device_cmd; struct iwl_rx_cmd_buffer; struct iwl_fw; -struct iwl_cfg; +struct iwl_rf_cfg; /** * DOC: Operational mode - what is it ? @@ -52,12 +52,20 @@ struct iwl_cfg; * any debug collection must happen synchronously as * the device will be shut down * @IWL_ERR_TYPE_CMD_QUEUE_FULL: command queue was full + * @IWL_ERR_TYPE_TOP_RESET_BY_BT: TOP reset initiated by BT + * @IWL_ERR_TYPE_TOP_FATAL_ERROR: TOP fatal error + * @IWL_ERR_TYPE_TOP_RESET_FAILED: TOP reset failed + * @IWL_ERR_TYPE_DEBUGFS: error/reset indication from debugfs */ enum iwl_fw_error_type { IWL_ERR_TYPE_IRQ, IWL_ERR_TYPE_NMI_FORCED, IWL_ERR_TYPE_RESET_HS_TIMEOUT, IWL_ERR_TYPE_CMD_QUEUE_FULL, + IWL_ERR_TYPE_TOP_RESET_BY_BT, + IWL_ERR_TYPE_TOP_FATAL_ERROR, + IWL_ERR_TYPE_TOP_RESET_FAILED, + IWL_ERR_TYPE_DEBUGFS, }; /** @@ -142,7 +150,7 @@ struct iwl_fw_error_dump_mode { */ struct iwl_op_mode_ops { struct iwl_op_mode *(*start)(struct iwl_trans *trans, - const struct iwl_cfg *cfg, + const struct iwl_rf_cfg *cfg, const struct iwl_fw *fw, struct dentry *dbgfs_dir); void (*stop)(struct iwl_op_mode *op_mode); @@ -242,6 +250,9 @@ static inline void iwl_op_mode_dump_error(struct iwl_op_mode *op_mode, { might_sleep(); + if (WARN_ON(mode->type == IWL_ERR_TYPE_TOP_RESET_BY_BT)) + return; + if (op_mode->ops->dump_error) op_mode->ops->dump_error(op_mode, mode); } diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c index e7b2e08645ef..8a40801cf0dd 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c @@ -15,7 +15,7 @@ #include <linux/dmapool.h> #include "fw/api/commands.h" #include "pcie/internal.h" -#include "iwl-context-info-gen3.h" +#include "iwl-context-info-v2.h" struct iwl_trans_dev_restart_data { struct list_head list; @@ -82,14 +82,14 @@ void iwl_trans_free_restart_list(void) struct iwl_trans_reprobe { struct device *dev; - struct work_struct work; + struct delayed_work work; }; static void iwl_trans_reprobe_wk(struct work_struct *wk) { struct iwl_trans_reprobe *reprobe; - reprobe = container_of(wk, typeof(*reprobe), work); + reprobe = container_of(wk, typeof(*reprobe), work.work); if (device_reprobe(reprobe->dev)) dev_err(reprobe->dev, "reprobe failed!\n"); @@ -98,6 +98,31 @@ static void iwl_trans_reprobe_wk(struct work_struct *wk) module_put(THIS_MODULE); } +static void iwl_trans_schedule_reprobe(struct iwl_trans *trans, + unsigned int delay_ms) +{ + struct iwl_trans_reprobe *reprobe; + + /* + * get a module reference to avoid doing this while unloading + * anyway and to avoid scheduling a work with code that's + * being removed. + */ + if (!try_module_get(THIS_MODULE)) { + IWL_ERR(trans, "Module is being unloaded - abort\n"); + return; + } + + reprobe = kzalloc(sizeof(*reprobe), GFP_KERNEL); + if (!reprobe) { + module_put(THIS_MODULE); + return; + } + reprobe->dev = get_device(trans->dev); + INIT_DELAYED_WORK(&reprobe->work, iwl_trans_reprobe_wk); + schedule_delayed_work(&reprobe->work, msecs_to_jiffies(delay_ms)); +} + #define IWL_TRANS_RESET_OK_TIME 7 /* seconds */ static enum iwl_reset_mode @@ -106,18 +131,46 @@ iwl_trans_determine_restart_mode(struct iwl_trans *trans) struct iwl_trans_dev_restart_data *data; enum iwl_reset_mode at_least = 0; unsigned int index; - static const enum iwl_reset_mode escalation_list[] = { + static const enum iwl_reset_mode escalation_list_old[] = { + IWL_RESET_MODE_SW_RESET, + IWL_RESET_MODE_REPROBE, + IWL_RESET_MODE_REPROBE, + IWL_RESET_MODE_FUNC_RESET, + IWL_RESET_MODE_PROD_RESET, + }; + static const enum iwl_reset_mode escalation_list_sc[] = { IWL_RESET_MODE_SW_RESET, IWL_RESET_MODE_REPROBE, IWL_RESET_MODE_REPROBE, IWL_RESET_MODE_FUNC_RESET, - /* FIXME: add TOP reset */ + IWL_RESET_MODE_TOP_RESET, IWL_RESET_MODE_PROD_RESET, - /* FIXME: add TOP reset */ + IWL_RESET_MODE_TOP_RESET, IWL_RESET_MODE_PROD_RESET, - /* FIXME: add TOP reset */ + IWL_RESET_MODE_TOP_RESET, IWL_RESET_MODE_PROD_RESET, }; + const enum iwl_reset_mode *escalation_list; + size_t escalation_list_size; + + /* used by TOP fatal error/TOP reset */ + if (trans->restart.mode.type == IWL_ERR_TYPE_TOP_RESET_FAILED) + return IWL_RESET_MODE_PROD_RESET; + + if (trans->request_top_reset) { + trans->request_top_reset = 0; + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_SC) + return IWL_RESET_MODE_TOP_RESET; + return IWL_RESET_MODE_PROD_RESET; + } + + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_SC) { + escalation_list = escalation_list_sc; + escalation_list_size = ARRAY_SIZE(escalation_list_sc); + } else { + escalation_list = escalation_list_old; + escalation_list_size = ARRAY_SIZE(escalation_list_old); + } if (trans->restart.during_reset) at_least = IWL_RESET_MODE_REPROBE; @@ -132,8 +185,8 @@ iwl_trans_determine_restart_mode(struct iwl_trans *trans) data->restart_count = 0; index = data->restart_count; - if (index >= ARRAY_SIZE(escalation_list)) { - index = ARRAY_SIZE(escalation_list) - 1; + if (index >= escalation_list_size) { + index = escalation_list_size - 1; if (!data->backoff) { data->backoff = true; return IWL_RESET_MODE_BACKOFF; @@ -144,15 +197,21 @@ iwl_trans_determine_restart_mode(struct iwl_trans *trans) return max(at_least, escalation_list[index]); } +#define IWL_TRANS_TOP_FOLLOWER_WAIT 180 /* ms */ + #define IWL_TRANS_RESET_DELAY (HZ * 60) static void iwl_trans_restart_wk(struct work_struct *wk) { struct iwl_trans *trans = container_of(wk, typeof(*trans), restart.wk.work); - struct iwl_trans_reprobe *reprobe; enum iwl_reset_mode mode; + if (trans->restart.mode.type == IWL_ERR_TYPE_TOP_RESET_BY_BT) { + iwl_trans_schedule_reprobe(trans, IWL_TRANS_TOP_FOLLOWER_WAIT); + return; + } + if (!trans->op_mode) return; @@ -187,31 +246,19 @@ static void iwl_trans_restart_wk(struct work_struct *wk) iwl_trans_inc_restart_count(trans->dev); switch (mode) { + case IWL_RESET_MODE_TOP_RESET: + trans->do_top_reset = 1; + IWL_ERR(trans, "Device error - TOP reset\n"); + fallthrough; case IWL_RESET_MODE_SW_RESET: - IWL_ERR(trans, "Device error - SW reset\n"); + if (mode == IWL_RESET_MODE_SW_RESET) + IWL_ERR(trans, "Device error - SW reset\n"); iwl_trans_opmode_sw_reset(trans, trans->restart.mode.type); break; case IWL_RESET_MODE_REPROBE: IWL_ERR(trans, "Device error - reprobe!\n"); - /* - * get a module reference to avoid doing this while unloading - * anyway and to avoid scheduling a work with code that's - * being removed. - */ - if (!try_module_get(THIS_MODULE)) { - IWL_ERR(trans, "Module is being unloaded - abort\n"); - return; - } - - reprobe = kzalloc(sizeof(*reprobe), GFP_KERNEL); - if (!reprobe) { - module_put(THIS_MODULE); - return; - } - reprobe->dev = get_device(trans->dev); - INIT_WORK(&reprobe->work, iwl_trans_reprobe_wk); - schedule_work(&reprobe->work); + iwl_trans_schedule_reprobe(trans, 0); break; default: iwl_trans_pcie_reset(trans, mode); @@ -221,7 +268,7 @@ static void iwl_trans_restart_wk(struct work_struct *wk) struct iwl_trans *iwl_trans_alloc(unsigned int priv_size, struct device *dev, - const struct iwl_cfg_trans_params *cfg_trans) + const struct iwl_mac_cfg *mac_cfg) { struct iwl_trans *trans; #ifdef CONFIG_LOCKDEP @@ -232,7 +279,7 @@ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size, if (!trans) return NULL; - trans->trans_cfg = cfg_trans; + trans->mac_cfg = mac_cfg; #ifdef CONFIG_LOCKDEP lockdep_init_map(&trans->sync_cmd_lockdep_map, "sync_cmd_lockdep_map", @@ -240,7 +287,6 @@ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size, #endif trans->dev = dev; - trans->num_rx_queues = 1; INIT_DELAYED_WORK(&trans->restart.wk, iwl_trans_restart_wk); @@ -251,14 +297,18 @@ int iwl_trans_init(struct iwl_trans *trans) { int txcmd_size, txcmd_align; - if (!trans->trans_cfg->gen2) { - txcmd_size = sizeof(struct iwl_tx_cmd); + /* check if name/num_rx_queues were set as a proxy for info being set */ + if (WARN_ON(!trans->info.name || !trans->info.num_rxqs)) + return -EINVAL; + + if (!trans->mac_cfg->gen2) { + txcmd_size = sizeof(struct iwl_tx_cmd_v6); txcmd_align = sizeof(void *); - } else if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) { - txcmd_size = sizeof(struct iwl_tx_cmd_gen2); + } else if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) { + txcmd_size = sizeof(struct iwl_tx_cmd_v9); txcmd_align = 64; } else { - txcmd_size = sizeof(struct iwl_tx_cmd_gen3); + txcmd_size = sizeof(struct iwl_tx_cmd); txcmd_align = 128; } @@ -266,7 +316,7 @@ int iwl_trans_init(struct iwl_trans *trans) txcmd_size += 36; /* biggest possible 802.11 header */ /* Ensure device TX cmd cannot reach/cross a page boundary in gen2 */ - if (WARN_ON(trans->trans_cfg->gen2 && txcmd_size >= txcmd_align)) + if (WARN_ON(trans->mac_cfg->gen2 && txcmd_size >= txcmd_align)) return -EINVAL; snprintf(trans->dev_cmd_pool_name, sizeof(trans->dev_cmd_pool_name), @@ -278,9 +328,6 @@ int iwl_trans_init(struct iwl_trans *trans) if (!trans->dev_cmd_pool) return -ENOMEM; - /* Initialize the wait queue for commands */ - init_waitqueue_head(&trans->wait_command_queue); - return 0; } @@ -298,17 +345,7 @@ int iwl_trans_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) test_bit(STATUS_RFKILL_OPMODE, &trans->status))) return -ERFKILL; - /* - * We can't test IWL_MVM_STATUS_IN_D3 in mvm->status because this - * bit is set early in the D3 flow, before we send all the commands - * that configure the firmware for D3 operation (power, patterns, ...) - * and we don't want to flag all those with CMD_SEND_IN_D3. - * So use the system_pm_mode instead. The only command sent after - * we set system_pm_mode is D3_CONFIG_CMD, which we now flag with - * CMD_SEND_IN_D3. - */ - if (unlikely(trans->system_pm_mode == IWL_PLAT_PM_MODE_D3 && - !(cmd->flags & CMD_SEND_IN_D3))) + if (unlikely(test_bit(STATUS_SUSPENDED, &trans->status))) return -EHOSTDOWN; if (unlikely(test_bit(STATUS_FW_ERROR, &trans->status))) @@ -321,7 +358,7 @@ int iwl_trans_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) if (!(cmd->flags & CMD_ASYNC)) lock_map_acquire_read(&trans->sync_cmd_lockdep_map); - if (trans->wide_cmd_header && !iwl_cmd_groupid(cmd->id)) { + if (trans->conf.wide_cmd_header && !iwl_cmd_groupid(cmd->id)) { if (cmd->id != REPLY_ERROR) cmd->id = DEF_ID(cmd->id); } @@ -365,11 +402,12 @@ const char *iwl_get_cmd_string(struct iwl_trans *trans, u32 id) grp = iwl_cmd_groupid(id); cmd = iwl_cmd_opcode(id); - if (!trans->command_groups || grp >= trans->command_groups_size || - !trans->command_groups[grp].arr) + if (!trans->conf.command_groups || + grp >= trans->conf.command_groups_size || + !trans->conf.command_groups[grp].arr) return "UNKNOWN"; - arr = &trans->command_groups[grp]; + arr = &trans->conf.command_groups[grp]; ret = bsearch(&cmd, arr->arr, arr->size, size, iwl_hcmd_names_cmp); if (!ret) return "UNKNOWN"; @@ -377,37 +415,29 @@ const char *iwl_get_cmd_string(struct iwl_trans *trans, u32 id) } IWL_EXPORT_SYMBOL(iwl_get_cmd_string); -int iwl_cmd_groups_verify_sorted(const struct iwl_trans_config *trans) +void iwl_trans_op_mode_enter(struct iwl_trans *trans, + struct iwl_op_mode *op_mode) { - int i, j; - const struct iwl_hcmd_arr *arr; + trans->op_mode = op_mode; - for (i = 0; i < trans->command_groups_size; i++) { - arr = &trans->command_groups[i]; - if (!arr->arr) - continue; - for (j = 0; j < arr->size - 1; j++) - if (arr->arr[j].cmd_id > arr->arr[j + 1].cmd_id) - return -1; - } - return 0; -} -IWL_EXPORT_SYMBOL(iwl_cmd_groups_verify_sorted); + if (WARN_ON(trans->conf.n_no_reclaim_cmds > MAX_NO_RECLAIM_CMDS)) + trans->conf.n_no_reclaim_cmds = + ARRAY_SIZE(trans->conf.no_reclaim_cmds); -void iwl_trans_configure(struct iwl_trans *trans, - const struct iwl_trans_config *trans_cfg) -{ - trans->op_mode = trans_cfg->op_mode; + WARN_ON_ONCE(!trans->conf.rx_mpdu_cmd); - iwl_trans_pcie_configure(trans, trans_cfg); - WARN_ON(iwl_cmd_groups_verify_sorted(trans_cfg)); + iwl_trans_pcie_op_mode_enter(trans); } -IWL_EXPORT_SYMBOL(iwl_trans_configure); +IWL_EXPORT_SYMBOL(iwl_trans_op_mode_enter); int iwl_trans_start_hw(struct iwl_trans *trans) { might_sleep(); + clear_bit(STATUS_TRANS_RESET_IN_PROGRESS, &trans->status); + /* opmode may not resume if it detects errors */ + clear_bit(STATUS_SUSPENDED, &trans->status); + return iwl_trans_pcie_start_hw(trans); } IWL_EXPORT_SYMBOL(iwl_trans_start_hw); @@ -421,6 +451,7 @@ void iwl_trans_op_mode_leave(struct iwl_trans *trans) cancel_delayed_work_sync(&trans->restart.wk); trans->op_mode = NULL; + memset(&trans->conf, 0, sizeof(trans->conf)); trans->state = IWL_TRANS_NO_FW; } @@ -497,18 +528,31 @@ IWL_EXPORT_SYMBOL(iwl_trans_dump_data); int iwl_trans_d3_suspend(struct iwl_trans *trans, bool test, bool reset) { + int err; + might_sleep(); - return iwl_trans_pcie_d3_suspend(trans, test, reset); + err = iwl_trans_pcie_d3_suspend(trans, test, reset); + + if (!err) + set_bit(STATUS_SUSPENDED, &trans->status); + + return err; } IWL_EXPORT_SYMBOL(iwl_trans_d3_suspend); int iwl_trans_d3_resume(struct iwl_trans *trans, enum iwl_d3_status *status, bool test, bool reset) { + int err; + might_sleep(); - return iwl_trans_pcie_d3_resume(trans, status, test, reset); + err = iwl_trans_pcie_d3_resume(trans, status, test, reset); + + clear_bit(STATUS_SUSPENDED, &trans->status); + + return err; } IWL_EXPORT_SYMBOL(iwl_trans_d3_resume); @@ -558,34 +602,39 @@ iwl_trans_release_nic_access(struct iwl_trans *trans) } IWL_EXPORT_SYMBOL(iwl_trans_release_nic_access); -void iwl_trans_fw_alive(struct iwl_trans *trans, u32 scd_addr) +void iwl_trans_fw_alive(struct iwl_trans *trans) { might_sleep(); trans->state = IWL_TRANS_FW_ALIVE; - if (trans->trans_cfg->gen2) + if (trans->mac_cfg->gen2) iwl_trans_pcie_gen2_fw_alive(trans); else - iwl_trans_pcie_fw_alive(trans, scd_addr); + iwl_trans_pcie_fw_alive(trans); } IWL_EXPORT_SYMBOL(iwl_trans_fw_alive); -int iwl_trans_start_fw(struct iwl_trans *trans, const struct fw_img *fw, - bool run_in_rfkill) +int iwl_trans_start_fw(struct iwl_trans *trans, const struct iwl_fw *fw, + enum iwl_ucode_type ucode_type, bool run_in_rfkill) { + const struct fw_img *img; int ret; might_sleep(); - WARN_ON_ONCE(!trans->rx_mpdu_cmd); + img = iwl_get_ucode_image(fw, ucode_type); + if (!img) + return -EINVAL; clear_bit(STATUS_FW_ERROR, &trans->status); - if (trans->trans_cfg->gen2) - ret = iwl_trans_pcie_gen2_start_fw(trans, fw, run_in_rfkill); + if (trans->mac_cfg->gen2) + ret = iwl_trans_pcie_gen2_start_fw(trans, fw, img, + run_in_rfkill); else - ret = iwl_trans_pcie_start_fw(trans, fw, run_in_rfkill); + ret = iwl_trans_pcie_start_fw(trans, fw, img, + run_in_rfkill); if (ret == 0) trans->state = IWL_TRANS_FW_STARTED; @@ -626,7 +675,7 @@ void iwl_trans_stop_device(struct iwl_trans *trans) iwl_op_mode_dump_error(trans->op_mode, &mode); } - if (trans->trans_cfg->gen2) + if (trans->mac_cfg->gen2) iwl_trans_pcie_gen2_stop_device(trans); else iwl_trans_pcie_stop_device(trans); @@ -645,7 +694,7 @@ int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, "bad state = %d\n", trans->state)) return -EIO; - if (trans->trans_cfg->gen2) + if (trans->mac_cfg->gen2) return iwl_txq_gen2_tx(trans, skb, dev_cmd, queue); return iwl_trans_pcie_tx(trans, skb, dev_cmd, queue); @@ -778,14 +827,14 @@ int iwl_trans_load_pnvm(struct iwl_trans *trans, const struct iwl_pnvm_image *pnvm_data, const struct iwl_ucode_capabilities *capa) { - return iwl_trans_pcie_ctx_info_gen3_load_pnvm(trans, pnvm_data, capa); + return iwl_trans_pcie_ctx_info_v2_load_pnvm(trans, pnvm_data, capa); } IWL_EXPORT_SYMBOL(iwl_trans_load_pnvm); void iwl_trans_set_pnvm(struct iwl_trans *trans, const struct iwl_ucode_capabilities *capa) { - iwl_trans_pcie_ctx_info_gen3_set_pnvm(trans, capa); + iwl_trans_pcie_ctx_info_v2_set_pnvm(trans, capa); } IWL_EXPORT_SYMBOL(iwl_trans_set_pnvm); @@ -793,7 +842,7 @@ int iwl_trans_load_reduce_power(struct iwl_trans *trans, const struct iwl_pnvm_image *payloads, const struct iwl_ucode_capabilities *capa) { - return iwl_trans_pcie_ctx_info_gen3_load_reduce_power(trans, payloads, + return iwl_trans_pcie_ctx_info_v2_load_reduce_power(trans, payloads, capa); } IWL_EXPORT_SYMBOL(iwl_trans_load_reduce_power); @@ -801,6 +850,6 @@ IWL_EXPORT_SYMBOL(iwl_trans_load_reduce_power); void iwl_trans_set_reduce_power(struct iwl_trans *trans, const struct iwl_ucode_capabilities *capa) { - iwl_trans_pcie_ctx_info_gen3_set_reduce_power(trans, capa); + iwl_trans_pcie_ctx_info_v2_set_reduce_power(trans, capa); } IWL_EXPORT_SYMBOL(iwl_trans_set_reduce_power); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index ce4954b0d524..012b1e44bce3 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2005-2014, 2018-2023 Intel Corporation + * Copyright (C) 2005-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -109,16 +109,12 @@ static inline u32 iwl_rx_packet_payload_len(const struct iwl_rx_packet *pkt) * the response. The caller needs to call iwl_free_resp when done. * @CMD_SEND_IN_RFKILL: Send the command even if the NIC is in RF-kill. * @CMD_BLOCK_TXQS: Block TXQs while the comment is executing. - * @CMD_SEND_IN_D3: Allow the command to be sent in D3 mode, relevant to - * SUSPEND and RESUME commands. We are in D3 mode when we set - * trans->system_pm_mode to IWL_PLAT_PM_MODE_D3. */ enum CMD_MODE { CMD_ASYNC = BIT(0), CMD_WANT_SKB = BIT(1), CMD_SEND_IN_RFKILL = BIT(2), CMD_BLOCK_TXQS = BIT(3), - CMD_SEND_IN_D3 = BIT(4), }; #define CMD_MODE_BITS 5 @@ -304,6 +300,10 @@ enum iwl_d3_status { * via iwl_trans_finish_sw_reset() * @STATUS_RESET_PENDING: reset worker was scheduled, but didn't dump * the firmware state yet + * @STATUS_TRANS_RESET_IN_PROGRESS: reset is still in progress, don't + * attempt another reset yet + * @STATUS_SUSPENDED: device is suspended, don't send commands that + * aren't marked accordingly */ enum iwl_trans_status { STATUS_SYNC_HCMD_ACTIVE, @@ -317,6 +317,8 @@ enum iwl_trans_status { STATUS_SUPPRESS_CMD_ERROR_ONCE, STATUS_IN_SW_RESET, STATUS_RESET_PENDING, + STATUS_TRANS_RESET_IN_PROGRESS, + STATUS_SUSPENDED, }; static inline int @@ -328,6 +330,7 @@ iwl_trans_get_rb_size_order(enum iwl_amsdu_size rb_size) case IWL_AMSDU_4K: return get_order(4 * 1024); case IWL_AMSDU_8K: + return get_order(8 * 1024); case IWL_AMSDU_12K: return get_order(16 * 1024); default: @@ -387,7 +390,8 @@ struct iwl_dump_sanitize_ops { /** * struct iwl_trans_config - transport configuration * - * @op_mode: pointer to the upper layer. + * These values should be set before iwl_trans_op_mode_enter(). + * * @cmd_queue: the index of the command queue. * Must be set before start_fw. * @cmd_fifo: the fifo for host commands @@ -398,8 +402,6 @@ struct iwl_dump_sanitize_ops { * @n_no_reclaim_cmds: # of commands in list * @rx_buf_size: RX buffer size needed for A-MSDUs * if unset 4k will be the RX buffer size - * @bc_table_dword: set to true if the BC table expects the byte count to be - * in DWORD (as opposed to bytes) * @scd_set_active: should the transport configure the SCD for HCMD queue * @command_groups: array of command groups, each member is an array of the * commands in the group; for debugging only @@ -410,17 +412,24 @@ struct iwl_dump_sanitize_ops { * @queue_alloc_cmd_ver: queue allocation command version, set to 0 * for using the older SCD_QUEUE_CFG, set to the version of * SCD_QUEUE_CONFIG_CMD otherwise. + * @wide_cmd_header: true when ucode supports wide command header format + * @rx_mpdu_cmd: MPDU RX command ID, must be assigned by opmode before + * starting the firmware, used for tracing + * @rx_mpdu_cmd_hdr_size: used for tracing, amount of data before the + * start of the 802.11 header in the @rx_mpdu_cmd + * @dsbr_urm_fw_dependent: switch to URM based on fw settings + * @dsbr_urm_permanent: switch to URM permanently + * @mbx_addr_0_step: step address data 0 + * @mbx_addr_1_step: step address data 1 + * @ext_32khz_clock_valid: if true, the external 32 KHz clock can be used */ struct iwl_trans_config { - struct iwl_op_mode *op_mode; - u8 cmd_queue; u8 cmd_fifo; - const u8 *no_reclaim_cmds; - unsigned int n_no_reclaim_cmds; + u8 n_no_reclaim_cmds; + u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; enum iwl_amsdu_size rx_buf_size; - bool bc_table_dword; bool scd_set_active; const struct iwl_hcmd_arr *command_groups; int command_groups_size; @@ -428,6 +437,16 @@ struct iwl_trans_config { u8 cb_data_offs; bool fw_reset_handshake; u8 queue_alloc_cmd_ver; + + bool wide_cmd_header; + u8 rx_mpdu_cmd, rx_mpdu_cmd_hdr_size; + + u8 dsbr_urm_fw_dependent:1, + dsbr_urm_permanent:1, + ext_32khz_clock_valid:1; + + u32 mbx_addr_0_step; + u32 mbx_addr_1_step; }; struct iwl_trans_dump_data { @@ -513,23 +532,6 @@ enum iwl_trans_state { */ /** - * enum iwl_plat_pm_mode - platform power management mode - * - * This enumeration describes the device's platform power management - * behavior when in system-wide suspend (i.e WoWLAN). - * - * @IWL_PLAT_PM_MODE_DISABLED: power management is disabled for this - * device. In system-wide suspend mode, it means that the all - * connections will be closed automatically by mac80211 before - * the platform is suspended. - * @IWL_PLAT_PM_MODE_D3: the device goes into D3 mode (i.e. WoWLAN). - */ -enum iwl_plat_pm_mode { - IWL_PLAT_PM_MODE_DISABLED, - IWL_PLAT_PM_MODE_D3, -}; - -/** * enum iwl_ini_cfg_state * @IWL_INI_CFG_STATE_NOT_LOADED: no debug cfg was given * @IWL_INI_CFG_STATE_LOADED: debug cfg was found and loaded @@ -819,106 +821,90 @@ struct iwl_txq { }; /** + * struct iwl_trans_info - transport info for outside use + * @name: the device name + * @max_skb_frags: maximum number of fragments an SKB can have when transmitted. + * 0 indicates that frag SKBs (NETIF_F_SG) aren't supported. + * @hw_rev: the revision data of the HW + * @hw_rev_step: The mac step of the HW + * @hw_rf_id: the device RF ID + * @hw_cnv_id: the device CNV ID + * @hw_crf_id: the device CRF ID + * @hw_wfpm_id: the device wfpm ID + * @hw_id: the ID of the device / sub-device + * Bits 0:15 represent the sub-device ID + * Bits 16:31 represent the device ID. + * @pcie_link_speed: current PCIe link speed (%PCI_EXP_LNKSTA_CLS_*), + * only valid for discrete (not integrated) NICs + * @num_rxqs: number of RX queues allocated by the transport + */ +struct iwl_trans_info { + const char *name; + u32 max_skb_frags; + u32 hw_rev; + u32 hw_rev_step; + u32 hw_rf_id; + u32 hw_crf_id; + u32 hw_cnv_id; + u32 hw_wfpm_id; + u32 hw_id; + u8 pcie_link_speed; + u8 num_rxqs; +}; + +/** * struct iwl_trans - transport common data * * @csme_own: true if we couldn't get ownership on the device * @op_mode: pointer to the op_mode - * @trans_cfg: the trans-specific configuration part + * @mac_cfg: the trans-specific configuration part * @cfg: pointer to the configuration * @drv: pointer to iwl_drv + * @conf: configuration set by the opmode before enter * @state: current device state * @status: a bit-mask of transport status flags * @dev: pointer to struct device * that represents the device - * @max_skb_frags: maximum number of fragments an SKB can have when transmitted. - * 0 indicates that frag SKBs (NETIF_F_SG) aren't supported. - * @hw_rf_id: a u32 with the device RF ID - * @hw_cnv_id: a u32 with the device CNV ID - * @hw_crf_id: a u32 with the device CRF ID - * @hw_wfpm_id: a u32 with the device wfpm ID - * @hw_id: a u32 with the ID of the device / sub-device. - * Set during transport allocation. - * @hw_id_str: a string with info about HW ID. Set during transport allocation. - * @sku_id: the SKU identifier (for PNVM matching) + * @info: device information for use by other layers * @pnvm_loaded: indicates PNVM was loaded - * @hw_rev: the revision data of the HW - * @hw_rev_step: The mac step of the HW * @pm_support: set to true in start_hw if link pm is supported * @ltr_enabled: set to true if the LTR is enabled * @fail_to_parse_pnvm_image: set to true if pnvm parsing failed * @reduce_power_loaded: indicates reduced power section was loaded * @failed_to_load_reduce_power_image: set to true if pnvm loading failed - * @command_groups: pointer to command group name list array - * @command_groups_size: array size of @command_groups - * @wide_cmd_header: true when ucode supports wide command header format - * @wait_command_queue: wait queue for sync commands - * @num_rx_queues: number of RX queues allocated by the transport; - * the transport must set this before calling iwl_drv_start() - * @iml_len: the length of the image loader - * @iml: a pointer to the image loader itself * @dev_cmd_pool: pool for Tx cmd allocation - for internal use only. * The user should use iwl_trans_{alloc,free}_tx_cmd. * @dev_cmd_pool_name: name for the TX command allocation pool * @dbgfs_dir: iwlwifi debugfs base dir for this device * @sync_cmd_lockdep_map: lockdep map for checking sync commands - * @rx_mpdu_cmd: MPDU RX command ID, must be assigned by opmode before - * starting the firmware, used for tracing - * @rx_mpdu_cmd_hdr_size: used for tracing, amount of data before the - * start of the 802.11 header in the @rx_mpdu_cmd * @dbg: additional debug data, see &struct iwl_trans_debug * @init_dram: FW initialization DMA data - * @system_pm_mode: the system-wide power management mode in use. - * This mode is set dynamically, depending on the WoWLAN values - * configured from the userspace at runtime. - * @name: the device name - * @mbx_addr_0_step: step address data 0 - * @mbx_addr_1_step: step address data 1 - * @pcie_link_speed: current PCIe link speed (%PCI_EXP_LNKSTA_CLS_*), - * only valid for discrete (not integrated) NICs - * @invalid_tx_cmd: invalid TX command buffer * @reduced_cap_sku: reduced capability supported SKU - * @no_160: device not supporting 160 MHz * @step_urm: STEP is in URM, no support for MCS>9 in 320 MHz * @restart: restart worker data * @restart.wk: restart worker * @restart.mode: reset/restart error mode information * @restart.during_reset: error occurred during previous software reset - * @me_recheck_wk: worker to recheck WiAMT/CSME presence - * @me_present: WiAMT/CSME is detected as present (1), not present (0) - * or unknown (-1, so can still use it as a boolean safely) * @trans_specific: data for the specific transport this is allocated for/with - * @dsbr_urm_fw_dependent: switch to URM based on fw settings - * @dsbr_urm_permanent: switch to URM permanently - * @ext_32khz_clock_valid: if true, the external 32 KHz clock can be used + * @request_top_reset: TOP reset was requested, used by the reset + * worker that should be scheduled (with appropriate reason) + * @do_top_reset: indication to the (PCIe) transport/context-info + * to do the TOP reset */ struct iwl_trans { bool csme_own; struct iwl_op_mode *op_mode; - const struct iwl_cfg_trans_params *trans_cfg; - const struct iwl_cfg *cfg; + const struct iwl_mac_cfg *mac_cfg; + const struct iwl_rf_cfg *cfg; struct iwl_drv *drv; + struct iwl_trans_config conf; enum iwl_trans_state state; unsigned long status; struct device *dev; - u32 max_skb_frags; - u32 hw_rev; - u32 hw_rev_step; - u32 hw_rf_id; - u32 hw_crf_id; - u32 hw_cnv_id; - u32 hw_wfpm_id; - u32 hw_id; - char hw_id_str[52]; - u32 sku_id[3]; - bool reduced_cap_sku; - u8 no_160:1, step_urm:1; - - u8 dsbr_urm_fw_dependent:1, - dsbr_urm_permanent:1; - bool ext_32khz_clock_valid; - - u8 rx_mpdu_cmd, rx_mpdu_cmd_hdr_size; + const struct iwl_trans_info info; + bool reduced_cap_sku; + bool step_urm; bool pm_support; bool ltr_enabled; @@ -927,16 +913,6 @@ struct iwl_trans { u8 reduce_power_loaded:1; u8 failed_to_load_reduce_power_image:1; - const struct iwl_hcmd_arr *command_groups; - int command_groups_size; - bool wide_cmd_header; - - wait_queue_head_t wait_command_queue; - u8 num_rx_queues; - - size_t iml_len; - u8 *iml; - /* The following fields are internal only */ struct kmem_cache *dev_cmd_pool; char dev_cmd_pool_name[50]; @@ -950,24 +926,14 @@ struct iwl_trans { struct iwl_trans_debug dbg; struct iwl_self_init_dram init_dram; - enum iwl_plat_pm_mode system_pm_mode; - - const char *name; - u32 mbx_addr_0_step; - u32 mbx_addr_1_step; - - u8 pcie_link_speed; - - struct iwl_dma_ptr invalid_tx_cmd; - struct { struct delayed_work wk; struct iwl_fw_error_dump_mode mode; bool during_reset; } restart; - struct delayed_work me_recheck_wk; - s8 me_present; + u8 request_top_reset:1, + do_top_reset:1; /* pointer to trans specific struct */ /*Ensure that this pointer will always be aligned to sizeof pointer */ @@ -975,19 +941,18 @@ struct iwl_trans { }; const char *iwl_get_cmd_string(struct iwl_trans *trans, u32 id); -int iwl_cmd_groups_verify_sorted(const struct iwl_trans_config *trans); -void iwl_trans_configure(struct iwl_trans *trans, - const struct iwl_trans_config *trans_cfg); +void iwl_trans_op_mode_enter(struct iwl_trans *trans, + struct iwl_op_mode *op_mode); int iwl_trans_start_hw(struct iwl_trans *trans); void iwl_trans_op_mode_leave(struct iwl_trans *trans); -void iwl_trans_fw_alive(struct iwl_trans *trans, u32 scd_addr); +void iwl_trans_fw_alive(struct iwl_trans *trans); -int iwl_trans_start_fw(struct iwl_trans *trans, const struct fw_img *fw, - bool run_in_rfkill); +int iwl_trans_start_fw(struct iwl_trans *trans, const struct iwl_fw *fw, + enum iwl_ucode_type ucode_type, bool run_in_rfkill); void iwl_trans_stop_device(struct iwl_trans *trans); @@ -1150,6 +1115,9 @@ static inline void iwl_trans_schedule_reset(struct iwl_trans *trans, { if (test_bit(STATUS_TRANS_DEAD, &trans->status)) return; + /* clear this on device init, not cleared on any unbind/reprobe */ + if (test_and_set_bit(STATUS_TRANS_RESET_IN_PROGRESS, &trans->status)) + return; trans->restart.mode.type = type; trans->restart.mode.context = IWL_ERR_CONTEXT_WORKER; @@ -1187,6 +1155,9 @@ static inline void iwl_trans_opmode_sw_reset(struct iwl_trans *trans, set_bit(STATUS_IN_SW_RESET, &trans->status); + if (WARN_ON(type == IWL_ERR_TYPE_TOP_RESET_BY_BT)) + return; + if (!trans->op_mode->ops->sw_reset || !trans->op_mode->ops->sw_reset(trans->op_mode, type)) clear_bit(STATUS_IN_SW_RESET, &trans->status); @@ -1234,7 +1205,7 @@ static inline void iwl_trans_finish_sw_reset(struct iwl_trans *trans) *****************************************************/ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size, struct device *dev, - const struct iwl_cfg_trans_params *cfg_trans); + const struct iwl_mac_cfg *cfg_trans); int iwl_trans_init(struct iwl_trans *trans); void iwl_trans_free(struct iwl_trans *trans); @@ -1245,6 +1216,19 @@ static inline bool iwl_trans_is_hw_error_value(u32 val) void iwl_trans_free_restart_list(void); +static inline u16 iwl_trans_get_num_rbds(struct iwl_trans *trans) +{ + u16 result = trans->cfg->num_rbds; + + /* + * Since AX210 family (So/Ty) the device cannot put mutliple + * frames into the same buffer, so double the value for them. + */ + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) + return 2 * result; + return result; +} + /***************************************************** * PCIe handling *****************************************************/ @@ -1256,6 +1240,8 @@ enum iwl_reset_mode { /* upper level modes: */ IWL_RESET_MODE_SW_RESET, IWL_RESET_MODE_REPROBE, + /* TOP reset doesn't require PCIe remove */ + IWL_RESET_MODE_TOP_RESET, /* PCIE level modes: */ IWL_RESET_MODE_REMOVE_ONLY, IWL_RESET_MODE_RESCAN, @@ -1272,4 +1258,19 @@ void iwl_trans_pcie_fw_reset_handshake(struct iwl_trans *trans); int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); +/* Internal helper */ +static inline void iwl_trans_set_info(struct iwl_trans *trans, + struct iwl_trans_info *info) +{ + struct iwl_trans_info *write; + + write = (void *)(uintptr_t)&trans->info; + *write = *info; +} + +static inline u16 iwl_trans_get_device_id(struct iwl_trans *trans) +{ + return u32_get_bits(trans->info.hw_id, GENMASK(31, 16)); +} + #endif /* __iwl_trans_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-utils.c b/drivers/net/wireless/intel/iwlwifi/iwl-utils.c index b14ec98e28b6..c5b49851e4b9 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-utils.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-utils.c @@ -4,7 +4,6 @@ */ #include <net/gso.h> #include <linux/ieee80211.h> -#include <net/gso.h> #include <net/ip.h> #include "iwl-drv.h" diff --git a/drivers/net/wireless/intel/iwlwifi/mld/agg.c b/drivers/net/wireless/intel/iwlwifi/mld/agg.c index 687a9450ac98..bda488ae9eec 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/agg.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/agg.c @@ -124,10 +124,12 @@ void iwl_mld_handle_bar_frame_release_notif(struct iwl_mld *mld, rcu_read_lock(); baid_data = rcu_dereference(mld->fw_id_to_ba[baid]); - if (IWL_FW_CHECK(mld, !baid_data, - "Got valid BAID %d but not allocated, invalid BAR release!\n", - baid)) + if (!baid_data) { + IWL_DEBUG_HT(mld, + "Got valid BAID %d but not allocated\n", + baid); goto out_unlock; + } if (IWL_FW_CHECK(mld, tid != baid_data->tid || sta_id > mld->fw->ucode_capa.num_stations || @@ -444,7 +446,7 @@ static void iwl_mld_init_reorder_buffer(struct iwl_mld *mld, struct iwl_mld_baid_data *data, u16 ssn) { - for (int i = 0; i < mld->trans->num_rx_queues; i++) { + for (int i = 0; i < mld->trans->info.num_rxqs; i++) { struct iwl_mld_reorder_buffer *reorder_buf = &data->reorder_buf[i]; struct iwl_mld_reorder_buf_entry *entries = @@ -468,7 +470,7 @@ static void iwl_mld_free_reorder_buffer(struct iwl_mld *mld, iwl_mld_sync_rx_queues(mld, IWL_MLD_RXQ_NOTIF_DEL_BA, &delba_data, sizeof(delba_data)); - for (int i = 0; i < mld->trans->num_rx_queues; i++) { + for (int i = 0; i < mld->trans->info.num_rxqs; i++) { struct iwl_mld_reorder_buffer *reorder_buf = &data->reorder_buf[i]; struct iwl_mld_reorder_buf_entry *entries = @@ -530,7 +532,7 @@ int iwl_mld_ampdu_rx_start(struct iwl_mld *mld, struct ieee80211_sta *sta, * before starting the BA session in the firmware */ baid_data = kzalloc(sizeof(*baid_data) + - mld->trans->num_rx_queues * reorder_buf_size, + mld->trans->info.num_rxqs * reorder_buf_size, GFP_KERNEL); if (!baid_data) return -ENOMEM; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/ap.c b/drivers/net/wireless/intel/iwlwifi/mld/ap.c index 571eabd0b511..26511b49d89a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/ap.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/ap.c @@ -11,6 +11,7 @@ #include "tx.h" #include "power.h" #include "key.h" +#include "phy.h" #include "iwl-utils.h" #include "fw/api/sta.h" @@ -269,6 +270,7 @@ int iwl_mld_start_ap_ibss(struct ieee80211_hw *hw, { struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); + struct ieee80211_chanctx_conf *ctx; int ret; if (vif->type == NL80211_IFTYPE_AP) @@ -314,6 +316,13 @@ int iwl_mld_start_ap_ibss(struct ieee80211_hw *hw, 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. + */ + ctx = wiphy_dereference(mld->wiphy, link->chanctx_conf); + iwl_mld_update_phy_chandef(mld, ctx); + return 0; rm_bcast: iwl_mld_remove_bcast_sta(mld, vif, link); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/coex.c b/drivers/net/wireless/intel/iwlwifi/mld/coex.c index 5f262bd43f21..32c727b3b391 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/coex.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/coex.c @@ -24,17 +24,13 @@ 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 = (void *)pkt->data; + const struct iwl_bt_coex_profile_notif *notif = (const 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)); - if (bt_is_active == mld->bt_is_active) - return; - + mld->last_bt_notif = *notif; 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); } diff --git a/drivers/net/wireless/intel/iwlwifi/mld/d3.c b/drivers/net/wireless/intel/iwlwifi/mld/d3.c index ee99298eebf5..339b148d6793 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/d3.c @@ -774,7 +774,7 @@ iwl_mld_update_ptk_rx_seq(struct iwl_mld *mld, return; for (int tid = 0; tid < IWL_MAX_TID_COUNT; tid++) { - for (int i = 1; i < mld->trans->num_rx_queues; i++) + for (int i = 1; i < mld->trans->info.num_rxqs; i++) memcpy(mld_ptk_pn->q[i].pn[tid], wowlan_status->ptk.aes_seq[tid].ccmp.pn, IEEE80211_CCMP_PN_LEN); @@ -1347,7 +1347,8 @@ int iwl_mld_no_wowlan_suspend(struct iwl_mld *mld) if (ret) { IWL_ERR(mld, "d3 suspend: trans_d3_suspend failed %d\n", ret); } else { - mld->trans->system_pm_mode = IWL_PLAT_PM_MODE_D3; + /* Async notification might send hcmds, which is not allowed in suspend */ + iwl_mld_cancel_async_notifications(mld); mld->fw_status.in_d3 = true; } @@ -1372,7 +1373,6 @@ int iwl_mld_no_wowlan_resume(struct iwl_mld *mld) IWL_DEBUG_WOWLAN(mld, "Starting the no wowlan resume flow\n"); - mld->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; mld->fw_status.in_d3 = false; iwl_fw_dbg_read_d3_debug_data(&mld->fwrt); @@ -1437,7 +1437,7 @@ iwl_mld_suspend_set_ucast_pn(struct iwl_mld *mld, struct ieee80211_sta *sta, ieee80211_get_key_rx_seq(key, tid, &seq); /* and use the internal data for all queues */ - for (int que = 1; que < mld->trans->num_rx_queues; que++) { + for (int que = 1; que < mld->trans->info.num_rxqs; que++) { u8 *cur_pn = mld_ptk_pn->q[que].pn[tid]; if (memcmp(max_pn, cur_pn, IEEE80211_CCMP_PN_LEN) < 0) @@ -1903,7 +1903,6 @@ int iwl_mld_wowlan_resume(struct iwl_mld *mld) IWL_DEBUG_WOWLAN(mld, "Starting the wowlan resume flow\n"); - mld->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; if (!mld->fw_status.in_d3) { IWL_DEBUG_WOWLAN(mld, "Device_powered_off() was called during wowlan\n"); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mld/debugfs.c index 93f9f78e4276..352da8aa7898 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/debugfs.c @@ -546,6 +546,9 @@ iwl_mld_add_debugfs_files(struct iwl_mld *mld, struct dentry *debugfs_dir) #endif MLD_DEBUGFS_ADD_FILE(inject_packet, debugfs_dir, 0200); + debugfs_create_bool("rx_ts_ptp", 0600, debugfs_dir, + &mld->monitor.ptp_time); + /* Create a symlink with mac80211. It will be removed when mac80211 * exits (before the opmode exits which removes the target.) */ @@ -997,8 +1000,8 @@ void iwl_mld_add_link_debugfs(struct ieee80211_hw *hw, mld_link_dir = debugfs_create_dir("iwlmld", dir); } -static ssize_t iwl_dbgfs_fixed_rate_write(struct iwl_mld *mld, char *buf, - size_t count, void *data) +static ssize_t _iwl_dbgfs_fixed_rate_write(struct iwl_mld *mld, char *buf, + size_t count, void *data, bool v3) { struct ieee80211_link_sta *link_sta = data; struct iwl_mld_link_sta *mld_link_sta; @@ -1020,6 +1023,10 @@ static ssize_t iwl_dbgfs_fixed_rate_write(struct iwl_mld *mld, char *buf, if (iwl_mld_dbgfs_fw_cmd_disabled(mld)) return -EIO; + /* input is in FW format (v2 or v3) so convert to v3 */ + rate = iwl_v3_rate_from_v2_v3(cpu_to_le32(rate), v3); + rate = le32_to_cpu(iwl_v3_rate_to_v2_v3(rate, mld->fw_rates_ver_3)); + ret = iwl_mld_send_tlc_dhc(mld, fw_sta_id, partial ? IWL_TLC_DEBUG_PARTIAL_FIXED_RATE : IWL_TLC_DEBUG_FIXED_RATE, @@ -1033,6 +1040,18 @@ static ssize_t iwl_dbgfs_fixed_rate_write(struct iwl_mld *mld, char *buf, return ret ? : count; } +static ssize_t iwl_dbgfs_fixed_rate_write(struct iwl_mld *mld, char *buf, + size_t count, void *data) +{ + return _iwl_dbgfs_fixed_rate_write(mld, buf, count, data, false); +} + +static ssize_t iwl_dbgfs_fixed_rate_v3_write(struct iwl_mld *mld, char *buf, + size_t count, void *data) +{ + return _iwl_dbgfs_fixed_rate_write(mld, buf, count, data, true); +} + static ssize_t iwl_dbgfs_tlc_dhc_write(struct iwl_mld *mld, char *buf, size_t count, void *data) { @@ -1072,6 +1091,7 @@ static ssize_t iwl_dbgfs_tlc_dhc_write(struct iwl_mld *mld, char *buf, LINK_STA_WIPHY_DEBUGFS_WRITE_OPS(tlc_dhc, 64); LINK_STA_WIPHY_DEBUGFS_WRITE_OPS(fixed_rate, 64); +LINK_STA_WIPHY_DEBUGFS_WRITE_OPS(fixed_rate_v3, 64); void iwl_mld_add_link_sta_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -1079,5 +1099,6 @@ void iwl_mld_add_link_sta_debugfs(struct ieee80211_hw *hw, struct dentry *dir) { LINK_STA_DEBUGFS_ADD_FILE(fixed_rate, dir, 0200); + LINK_STA_DEBUGFS_ADD_FILE(fixed_rate_v3, dir, 0200); LINK_STA_DEBUGFS_ADD_FILE(tlc_dhc, dir, 0200); } diff --git a/drivers/net/wireless/intel/iwlwifi/mld/fw.c b/drivers/net/wireless/intel/iwlwifi/mld/fw.c index 4b083d447ee2..73ed8d5cab43 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/fw.c @@ -8,10 +8,10 @@ #include "fw/api/alive.h" #include "fw/api/scan.h" #include "fw/api/rx.h" +#include "phy.h" #include "fw/dbg.h" #include "fw/pnvm.h" #include "hcmd.h" -#include "iwl-nvm-parse.h" #include "power.h" #include "mcc.h" #include "led.h" @@ -49,7 +49,7 @@ static int iwl_mld_send_rss_cfg_cmd(struct iwl_mld *mld) /* Do not direct RSS traffic to Q 0 which is our fallback queue */ for (int i = 0; i < ARRAY_SIZE(cmd.indirection_table); i++) cmd.indirection_table[i] = - 1 + (i % (mld->trans->num_rx_queues - 1)); + 1 + (i % (mld->trans->info.num_rxqs - 1)); netdev_rss_key_fill(cmd.secret_key, sizeof(cmd.secret_key)); return iwl_mld_send_cmd_pdu(mld, RSS_CONFIG_CMD, &cmd); @@ -99,17 +99,23 @@ static void iwl_mld_alive_imr_data(struct iwl_trans *trans, } } +struct iwl_mld_alive_data { + __le32 sku_id[3]; + bool valid; +}; + static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, struct iwl_rx_packet *pkt, void *data) { unsigned int pkt_len = iwl_rx_packet_payload_len(pkt); + unsigned int expected_sz; struct iwl_mld *mld = container_of(notif_wait, struct iwl_mld, notif_wait); struct iwl_trans *trans = mld->trans; u32 version = iwl_fw_lookup_notif_ver(mld->fw, LEGACY_GROUP, UCODE_ALIVE_NTFY, 0); - struct iwl_alive_ntf_v6 *palive; - bool *alive_valid = data; + struct iwl_mld_alive_data *alive_data = data; + struct iwl_alive_ntf *palive; struct iwl_umac_alive *umac; struct iwl_lmac_alive *lmac1; struct iwl_lmac_alive *lmac2 = NULL; @@ -117,7 +123,19 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, u32 umac_error_table; u16 status; - if (version < 6 || version > 7 || pkt_len != sizeof(*palive)) + switch (version) { + case 6: + case 7: + expected_sz = sizeof(struct iwl_alive_ntf_v6); + break; + case 8: + expected_sz = sizeof(struct iwl_alive_ntf); + break; + default: + return false; + } + + if (pkt_len != expected_sz) return false; palive = (void *)pkt->data; @@ -129,12 +147,15 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, lmac2 = &palive->lmac_data[1]; status = le16_to_cpu(palive->status); - trans->sku_id[0] = le32_to_cpu(palive->sku_id.data[0]); - trans->sku_id[1] = le32_to_cpu(palive->sku_id.data[1]); - trans->sku_id[2] = le32_to_cpu(palive->sku_id.data[2]); + BUILD_BUG_ON(sizeof(alive_data->sku_id) != + sizeof(palive->sku_id.data)); + memcpy(alive_data->sku_id, palive->sku_id.data, + sizeof(palive->sku_id.data)); IWL_DEBUG_FW(mld, "Got sku_id: 0x0%x 0x0%x 0x0%x\n", - trans->sku_id[0], trans->sku_id[1], trans->sku_id[2]); + le32_to_cpu(alive_data->sku_id[0]), + le32_to_cpu(alive_data->sku_id[1]), + le32_to_cpu(alive_data->sku_id[2])); lmac_error_event_table = le32_to_cpu(lmac1->dbg_ptrs.error_event_table_ptr); @@ -147,13 +168,13 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, umac_error_table = le32_to_cpu(umac->dbg_ptrs.error_info_addr) & ~FW_ADDR_CACHE_CONTROL; - if (umac_error_table >= trans->cfg->min_umac_error_event_table) + if (umac_error_table >= trans->mac_cfg->base->min_umac_error_event_table) iwl_fw_umac_set_alive_err_table(trans, umac_error_table); else IWL_ERR(mld, "Not valid error log pointer 0x%08X\n", umac_error_table); - *alive_valid = status == IWL_ALIVE_STATUS_OK; + alive_data->valid = status == IWL_ALIVE_STATUS_OK; IWL_DEBUG_FW(mld, "Alive ucode status 0x%04x revision 0x%01X 0x%01X\n", @@ -171,6 +192,10 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, IWL_DEBUG_FW(mld, "FW alive flags 0x%x\n", le16_to_cpu(palive->flags)); + if (version >= 8) + IWL_DEBUG_FW(mld, "platform_id 0x%llx\n", + le64_to_cpu(palive->platform_id)); + iwl_fwrt_update_fw_versions(&mld->fwrt, lmac1, umac); return true; @@ -208,24 +233,22 @@ static void iwl_mld_print_alive_notif_timeout(struct iwl_mld *mld) pc_data->pc_address); } -static int iwl_mld_load_fw_wait_alive(struct iwl_mld *mld) +static int iwl_mld_load_fw_wait_alive(struct iwl_mld *mld, + struct iwl_mld_alive_data *alive_data) { - const struct fw_img *fw = - iwl_get_ucode_image(mld->fw, IWL_UCODE_REGULAR); static const u16 alive_cmd[] = { UCODE_ALIVE_NTFY }; struct iwl_notification_wait alive_wait; - bool alive_valid = false; int ret; lockdep_assert_wiphy(mld->wiphy); iwl_init_notification_wait(&mld->notif_wait, &alive_wait, alive_cmd, ARRAY_SIZE(alive_cmd), - iwl_alive_fn, &alive_valid); + iwl_alive_fn, alive_data); iwl_dbg_tlv_time_point(&mld->fwrt, IWL_FW_INI_TIME_POINT_EARLY, NULL); - ret = iwl_trans_start_fw(mld->trans, fw, true); + ret = iwl_trans_start_fw(mld->trans, mld->fw, IWL_UCODE_REGULAR, true); if (ret) { iwl_remove_notification(&mld->notif_wait, &alive_wait); return ret; @@ -239,28 +262,26 @@ static int iwl_mld_load_fw_wait_alive(struct iwl_mld *mld) iwl_fw_dbg_error_collect(&mld->fwrt, FW_DBG_TRIGGER_ALIVE_TIMEOUT); iwl_mld_print_alive_notif_timeout(mld); - goto alive_failure; + return ret; } - if (!alive_valid) { + if (!alive_data->valid) { IWL_ERR(mld, "Loaded firmware is not valid!\n"); - ret = -EIO; - goto alive_failure; + return -EIO; } - iwl_trans_fw_alive(mld->trans, 0); + iwl_trans_fw_alive(mld->trans); return 0; - -alive_failure: - iwl_trans_stop_device(mld->trans); - return ret; } static int iwl_mld_run_fw_init_sequence(struct iwl_mld *mld) { struct iwl_notification_wait init_wait; - struct iwl_init_extended_cfg_cmd init_cfg = {}; + struct iwl_init_extended_cfg_cmd init_cfg = { + .init_flags = cpu_to_le32(BIT(IWL_INIT_PHY)), + }; + struct iwl_mld_alive_data alive_data = {}; static const u16 init_complete[] = { INIT_COMPLETE_NOTIF, }; @@ -268,19 +289,15 @@ static int iwl_mld_run_fw_init_sequence(struct iwl_mld *mld) lockdep_assert_wiphy(mld->wiphy); - ret = iwl_mld_load_fw_wait_alive(mld); + ret = iwl_mld_load_fw_wait_alive(mld, &alive_data); if (ret) return ret; - mld->trans->step_urm = - !!(iwl_read_umac_prph(mld->trans, CNVI_PMU_STEP_FLOW) & - CNVI_PMU_STEP_FLOW_FORCE_URM); - ret = iwl_pnvm_load(mld->trans, &mld->notif_wait, - &mld->fw->ucode_capa); + &mld->fw->ucode_capa, alive_data.sku_id); if (ret) { IWL_ERR(mld, "Timeout waiting for PNVM load %d\n", ret); - goto init_failure; + return ret; } iwl_dbg_tlv_time_point(&mld->fwrt, IWL_FW_INI_TIME_POINT_AFTER_ALIVE, @@ -298,31 +315,24 @@ static int iwl_mld_run_fw_init_sequence(struct iwl_mld *mld) if (ret) { IWL_ERR(mld, "Failed to send init config command: %d\n", ret); iwl_remove_notification(&mld->notif_wait, &init_wait); - goto init_failure; + return ret; + } + + ret = iwl_mld_send_phy_cfg_cmd(mld); + if (ret) { + IWL_ERR(mld, "Failed to send PHY config command: %d\n", ret); + iwl_remove_notification(&mld->notif_wait, &init_wait); + return ret; } ret = iwl_wait_notification(&mld->notif_wait, &init_wait, MLD_INIT_COMPLETE_TIMEOUT); if (ret) { IWL_ERR(mld, "Failed to get INIT_COMPLETE %d\n", ret); - goto init_failure; - } - - if (!mld->nvm_data) { - mld->nvm_data = iwl_get_nvm(mld->trans, mld->fw, 0, 0); - if (IS_ERR(mld->nvm_data)) { - ret = PTR_ERR(mld->nvm_data); - mld->nvm_data = NULL; - IWL_ERR(mld, "Failed to read NVM: %d\n", ret); - goto init_failure; - } + return ret; } return 0; - -init_failure: - iwl_trans_stop_device(mld->trans); - return ret; } int iwl_mld_load_fw(struct iwl_mld *mld) @@ -333,7 +343,7 @@ int iwl_mld_load_fw(struct iwl_mld *mld) ret = iwl_trans_start_hw(mld->trans); if (ret) - goto err; + return ret; ret = iwl_mld_run_fw_init_sequence(mld); if (ret) @@ -361,9 +371,10 @@ void iwl_mld_stop_fw(struct iwl_mld *mld) iwl_trans_stop_device(mld->trans); - wiphy_work_cancel(mld->wiphy, &mld->async_handlers_wk); - - iwl_mld_purge_async_handlers_list(mld); + /* HW is stopped, no more coming RX. Cancel all notifications in + * case they were sent just before stopping the HW. + */ + iwl_mld_cancel_async_notifications(mld); mld->fw_status.running = false; } @@ -526,7 +537,7 @@ int iwl_mld_start_fw(struct iwl_mld *mld) ret = iwl_mld_load_fw(mld); if (IWL_FW_CHECK(mld, ret, "Failed to start firmware %d\n", ret)) { iwl_fw_dbg_error_collect(&mld->fwrt, FW_DBG_TRIGGER_DRIVER); - goto error; + return ret; } IWL_DEBUG_INFO(mld, "uCode started.\n"); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/iface.c b/drivers/net/wireless/intel/iwlwifi/mld/iface.c index e49e2260ac05..235b55e0fe59 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/iface.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/iface.c @@ -22,9 +22,17 @@ void iwl_mld_cleanup_vif(void *data, u8 *mac, struct ieee80211_vif *vif) struct iwl_mld *mld = mld_vif->mld; struct iwl_mld_link *link; + mld_vif->emlsr.blocked_reasons &= ~IWL_MLD_EMLSR_BLOCKED_ROC; + + if (mld_vif->aux_sta.sta_id != IWL_INVALID_STA) + iwl_mld_free_internal_sta(mld, &mld_vif->aux_sta); + /* EMLSR is turned back on during recovery */ vif->driver_flags &= ~IEEE80211_VIF_EML_ACTIVE; + if (mld_vif->roc_activity != ROC_NUM_ACTIVITIES) + ieee80211_remain_on_channel_expired(mld->hw); + mld_vif->roc_activity = ROC_NUM_ACTIVITIES; for_each_mld_vif_valid_link(mld_vif, link) { @@ -103,6 +111,24 @@ static bool iwl_mld_is_nic_ack_enabled(struct iwl_mld *mld, IEEE80211_HE_MAC_CAP2_ACK_EN); } +static void iwl_mld_set_he_support(struct iwl_mld *mld, + struct ieee80211_vif *vif, + struct iwl_mac_config_cmd *cmd, + int cmd_ver) +{ + if (vif->type == NL80211_IFTYPE_AP) { + if (cmd_ver == 2) + cmd->wifi_gen_v2.he_ap_support = cpu_to_le16(1); + else + cmd->wifi_gen.he_ap_support = 1; + } else { + if (cmd_ver == 2) + cmd->wifi_gen_v2.he_support = cpu_to_le16(1); + else + cmd->wifi_gen.he_support = 1; + } +} + /* fill the common part for all interface types */ static void iwl_mld_mac_cmd_fill_common(struct iwl_mld *mld, struct ieee80211_vif *vif, @@ -112,6 +138,9 @@ static void iwl_mld_mac_cmd_fill_common(struct iwl_mld *mld, struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); struct ieee80211_bss_conf *link_conf; unsigned int link_id; + int cmd_ver = iwl_fw_lookup_cmd_ver(mld->fw, + WIDE_ID(MAC_CONF_GROUP, + MAC_CONFIG_CMD), 0); lockdep_assert_wiphy(mld->wiphy); @@ -138,12 +167,11 @@ static void iwl_mld_mac_cmd_fill_common(struct iwl_mld *mld, * and enable both when we have MLO. */ if (ieee80211_vif_is_mld(vif)) { - if (vif->type == NL80211_IFTYPE_AP) - cmd->he_ap_support = cpu_to_le16(1); + iwl_mld_set_he_support(mld, vif, cmd, cmd_ver); + if (cmd_ver == 2) + cmd->wifi_gen_v2.eht_support = cpu_to_le32(1); else - cmd->he_support = cpu_to_le16(1); - - cmd->eht_support = cpu_to_le32(1); + cmd->wifi_gen.eht_support = 1; return; } @@ -151,10 +179,7 @@ static void iwl_mld_mac_cmd_fill_common(struct iwl_mld *mld, if (!link_conf->he_support) continue; - if (vif->type == NL80211_IFTYPE_AP) - cmd->he_ap_support = cpu_to_le16(1); - else - cmd->he_support = cpu_to_le16(1); + iwl_mld_set_he_support(mld, vif, cmd, cmd_ver); /* EHT, if supported, was already set above */ break; @@ -226,11 +251,6 @@ static void iwl_mld_fill_mac_cmd_sta(struct iwl_mld *mld, if (vif->probe_req_reg && vif->cfg.assoc && vif->p2p) cmd->filter_flags |= cpu_to_le32(MAC_CFG_FILTER_ACCEPT_PROBE_REQ); - - if (vif->p2p) - cmd->client.ctwin = - cpu_to_le32(vif->bss_conf.p2p_noa_attr.oppps_ctwindow & - IEEE80211_P2P_OPPPS_CTWINDOW_MASK); } static void iwl_mld_fill_mac_cmd_ap(struct iwl_mld *mld, @@ -393,6 +413,7 @@ iwl_mld_init_vif(struct iwl_mld *mld, struct ieee80211_vif *vif) wiphy_delayed_work_init(&mld_vif->emlsr.tmp_non_bss_done_wk, iwl_mld_emlsr_tmp_non_bss_done_wk); } + iwl_mld_init_internal_sta(&mld_vif->aux_sta); return 0; } diff --git a/drivers/net/wireless/intel/iwlwifi/mld/iface.h b/drivers/net/wireless/intel/iwlwifi/mld/iface.h index ec14d0736cee..49e2ce65557d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/iface.h +++ b/drivers/net/wireless/intel/iwlwifi/mld/iface.h @@ -10,6 +10,7 @@ #include "link.h" #include "session-protect.h" #include "d3.h" +#include "fw/api/time-event.h" enum iwl_mld_cca_40mhz_wa_status { CCA_40_MHZ_WA_NONE, @@ -59,6 +60,7 @@ enum iwl_mld_emlsr_blocked { * loaded enough to justify EMLSR. * @IWL_MLD_EMLSR_EXIT_RFI: Exit EMLSR due to RFI * @IWL_MLD_EMLSR_EXIT_FW_REQUEST: Exit EMLSR because the FW requested it + * @IWL_MLD_EMLSR_EXIT_INVALID: internal exit reason due to invalid data */ enum iwl_mld_emlsr_exit { IWL_MLD_EMLSR_EXIT_BLOCK = 0x1, @@ -72,6 +74,7 @@ enum iwl_mld_emlsr_exit { IWL_MLD_EMLSR_EXIT_CHAN_LOAD = 0x100, IWL_MLD_EMLSR_EXIT_RFI = 0x200, IWL_MLD_EMLSR_EXIT_FW_REQUEST = 0x400, + IWL_MLD_EMLSR_EXIT_INVALID = 0x800, }; /** @@ -123,8 +126,6 @@ struct iwl_mld_emlsr { * Only valid for STA. (FIXME: needs to be per link) * @num_associated_stas: number of associated STAs. Relevant only for AP mode. * @ap_ibss_active: whether the AP/IBSS was started - * @roc_activity: the id of the roc_activity running. Relevant for p2p device - * only. Set to %ROC_NUM_ACTIVITIES when not in use. * @cca_40mhz_workaround: When we are connected in 2.4 GHz and 40 MHz, and the * environment is too loaded, we work around this by reconnecting to the * same AP with 20 MHz. This manages the status of the workaround. @@ -140,6 +141,9 @@ struct iwl_mld_emlsr { * @use_ps_poll: use ps_poll frames * @disable_bf: disable beacon filter * @dbgfs_slink: debugfs symlink for this interface + * @roc_activity: the id of the roc_activity running. Relevant for STA and + * p2p device only. Set to %ROC_NUM_ACTIVITIES when not in use. + * @aux_sta: station used for remain on channel. Used in P2P device. */ struct iwl_mld_vif { /* Add here fields that need clean up on restart */ @@ -151,7 +155,6 @@ struct iwl_mld_vif { struct ieee80211_key_conf __rcu *bigtks[2]; u8 num_associated_stas; bool ap_ibss_active; - u32 roc_activity; enum iwl_mld_cca_40mhz_wa_status cca_40mhz_workaround; #ifdef CONFIG_IWLWIFI_DEBUGFS bool beacon_inject_active; @@ -174,6 +177,8 @@ struct iwl_mld_vif { bool disable_bf; struct dentry *dbgfs_slink; #endif + enum iwl_roc_activity roc_activity; + struct iwl_mld_int_sta aux_sta; }; static inline struct iwl_mld_vif * diff --git a/drivers/net/wireless/intel/iwlwifi/mld/link.c b/drivers/net/wireless/intel/iwlwifi/mld/link.c index 82a4979a3af3..d0f56189ad3f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/link.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/link.c @@ -580,7 +580,7 @@ iwl_mld_get_omi_bw_reduction_pointers(struct iwl_mld *mld, *link_sta = NULL; - if (mld->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_SC) + if (mld->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_SC) return NULL; vif = iwl_mld_get_bss_vif(mld); @@ -782,10 +782,11 @@ iwl_mld_init_link(struct iwl_mld *mld, struct ieee80211_bss_conf *link, iwl_mld_init_internal_sta(&mld_link->bcast_sta); iwl_mld_init_internal_sta(&mld_link->mcast_sta); - iwl_mld_init_internal_sta(&mld_link->aux_sta); + iwl_mld_init_internal_sta(&mld_link->mon_sta); - wiphy_delayed_work_init(&mld_link->rx_omi.finished_work, - iwl_mld_omi_bw_finished_work); + if (!mld->fw_status.in_hw_restart) + wiphy_delayed_work_init(&mld_link->rx_omi.finished_work, + iwl_mld_omi_bw_finished_work); return iwl_mld_allocate_link_fw_id(mld, &mld_link->fw_id, link); } diff --git a/drivers/net/wireless/intel/iwlwifi/mld/link.h b/drivers/net/wireless/intel/iwlwifi/mld/link.h index 42b7bdcbd741..39f04aae5579 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/link.h +++ b/drivers/net/wireless/intel/iwlwifi/mld/link.h @@ -39,7 +39,7 @@ struct iwl_probe_resp_data { * @vif: the vif this link belongs to * @bcast_sta: station used for broadcast packets. Used in AP, GO and IBSS. * @mcast_sta: station used for multicast packets. Used in AP, GO and IBSS. - * @aux_sta: station used for remain on channel. Used in P2P device. + * @mon_sta: station used for TX injection in monitor interface. * @link_id: over the air link ID * @ap_early_keys: The firmware cannot install keys before bcast/mcast STAs, * but higher layers work differently, so we store the keys here for @@ -72,7 +72,7 @@ struct iwl_mld_link { struct ieee80211_vif *vif; struct iwl_mld_int_sta bcast_sta; struct iwl_mld_int_sta mcast_sta; - struct iwl_mld_int_sta aux_sta; + struct iwl_mld_int_sta mon_sta; u8 link_id; struct { @@ -89,7 +89,7 @@ struct iwl_mld_link { struct iwl_probe_resp_data __rcu *probe_resp_data; }; -/* Cleanup function for struct iwl_mld_phy, will be called in restart */ +/* Cleanup function for struct iwl_mld_link, will be called in restart */ static inline void iwl_mld_cleanup_link(struct iwl_mld *mld, struct iwl_mld_link *link) { @@ -105,8 +105,8 @@ iwl_mld_cleanup_link(struct iwl_mld *mld, struct iwl_mld_link *link) iwl_mld_free_internal_sta(mld, &link->bcast_sta); if (link->mcast_sta.sta_id != IWL_INVALID_STA) iwl_mld_free_internal_sta(mld, &link->mcast_sta); - if (link->aux_sta.sta_id != IWL_INVALID_STA) - iwl_mld_free_internal_sta(mld, &link->aux_sta); + if (link->mon_sta.sta_id != IWL_INVALID_STA) + iwl_mld_free_internal_sta(mld, &link->mon_sta); } /* Convert a percentage from [0,100] to [0,255] */ diff --git a/drivers/net/wireless/intel/iwlwifi/mld/low_latency.c b/drivers/net/wireless/intel/iwlwifi/mld/low_latency.c index a4a612afb3b3..f7faa87b8ba6 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/low_latency.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/low_latency.c @@ -21,7 +21,7 @@ static bool iwl_mld_calc_low_latency(struct iwl_mld *mld, { struct iwl_mld_low_latency *ll = &mld->low_latency; bool global_low_latency = false; - u8 num_rx_q = mld->trans->num_rx_queues; + u8 num_rx_q = mld->trans->info.num_rxqs; for (int mac_id = 0; mac_id < NUM_MAC_INDEX_DRIVER; mac_id++) { u32 total_vo_vi_pkts = 0; @@ -131,12 +131,12 @@ int iwl_mld_low_latency_init(struct iwl_mld *mld) struct iwl_mld_low_latency *ll = &mld->low_latency; unsigned long ts = jiffies; - ll->pkts_counters = kcalloc(mld->trans->num_rx_queues, + ll->pkts_counters = kcalloc(mld->trans->info.num_rxqs, sizeof(*ll->pkts_counters), GFP_KERNEL); if (!ll->pkts_counters) return -ENOMEM; - for (int q = 0; q < mld->trans->num_rx_queues; q++) + for (int q = 0; q < mld->trans->info.num_rxqs; q++) spin_lock_init(&ll->pkts_counters[q].lock); wiphy_delayed_work_init(&ll->work, iwl_mld_low_latency_wk); @@ -167,7 +167,7 @@ void iwl_mld_low_latency_restart_cleanup(struct iwl_mld *mld) memset(ll->window_start, 0, sizeof(ll->window_start)); memset(ll->result, 0, sizeof(ll->result)); - for (int q = 0; q < mld->trans->num_rx_queues; q++) + for (int q = 0; q < mld->trans->info.num_rxqs; q++) memset(ll->pkts_counters[q].vo_vi, 0, sizeof(ll->pkts_counters[q].vo_vi)); } @@ -276,7 +276,7 @@ void iwl_mld_low_latency_update_counters(struct iwl_mld *mld, return; if (WARN_ON_ONCE(fw_id >= ARRAY_SIZE(counters->vo_vi) || - queue >= mld->trans->num_rx_queues)) + queue >= mld->trans->info.num_rxqs)) return; if (mld->low_latency.stopped) @@ -324,7 +324,7 @@ void iwl_mld_low_latency_restart(struct iwl_mld *mld) ll->window_start[mac] = 0; low_latency |= ll->result[mac]; - for (int q = 0; q < mld->trans->num_rx_queues; q++) { + for (int q = 0; q < mld->trans->info.num_rxqs; q++) { spin_lock_bh(&ll->pkts_counters[q].lock); ll->pkts_counters[q].vo_vi[mac] = 0; spin_unlock_bh(&ll->pkts_counters[q].lock); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c index 68d97d3b8f02..4ba050397632 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c @@ -243,7 +243,6 @@ static void iwl_mac_hw_set_flags(struct iwl_mld *mld) ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW); ieee80211_hw_set(hw, HAS_RATE_CONTROL); ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER); - ieee80211_hw_set(hw, DISALLOW_PUNCTURING_5GHZ); ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS); ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); ieee80211_hw_set(hw, TDLS_WIDER_BW); @@ -305,7 +304,7 @@ static void iwl_mac_hw_set_wiphy(struct iwl_mld *mld) wiphy->max_remain_on_channel_duration = 10000; - wiphy->hw_version = mld->trans->hw_id; + wiphy->hw_version = mld->trans->info.hw_id; wiphy->hw_timestamp_max_peers = 1; @@ -351,9 +350,9 @@ static void iwl_mac_hw_set_misc(struct iwl_mld *mld) hw->queues = IEEE80211_NUM_ACS; hw->netdev_features = NETIF_F_HIGHDMA | NETIF_F_SG; - hw->netdev_features |= mld->cfg->features; + hw->netdev_features |= mld->trans->mac_cfg->base->features; - hw->max_tx_fragments = mld->trans->max_skb_frags; + hw->max_tx_fragments = mld->trans->info.max_skb_frags; hw->max_listen_interval = IWL_MLD_CONN_LISTEN_INTERVAL; hw->uapsd_max_sp_len = IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL; @@ -376,6 +375,24 @@ static void iwl_mac_hw_set_misc(struct iwl_mld *mld) static int iwl_mld_hw_verify_preconditions(struct iwl_mld *mld) { + int ratecheck; + + /* check for rates version 3 */ + ratecheck = + (iwl_fw_lookup_cmd_ver(mld->fw, TX_CMD, 0) >= 11) + + (iwl_fw_lookup_notif_ver(mld->fw, DATA_PATH_GROUP, + TLC_MNG_UPDATE_NOTIF, 0) >= 4) + + (iwl_fw_lookup_notif_ver(mld->fw, LEGACY_GROUP, + REPLY_RX_MPDU_CMD, 0) >= 6) + + (iwl_fw_lookup_notif_ver(mld->fw, DATA_PATH_GROUP, + RX_NO_DATA_NOTIF, 0) >= 4) + + (iwl_fw_lookup_notif_ver(mld->fw, LONG_GROUP, TX_CMD, 0) >= 9); + + if (ratecheck != 0 && ratecheck != 5) { + IWL_ERR(mld, "Firmware has inconsistent rates\n"); + return -EINVAL; + } + /* 11ax is expected to be enabled for all supported devices */ if (WARN_ON(!mld->nvm_data->sku_cap_11ax_enable)) return -EINVAL; @@ -541,15 +558,6 @@ void iwl_mld_mac80211_stop(struct ieee80211_hw *hw, bool suspend) (IS_ENABLED(CONFIG_PM_SLEEP) && iwl_mld_no_wowlan_suspend(mld))) iwl_mld_stop_fw(mld); - /* HW is stopped, no more coming RX. OTOH, the worker can't run as the - * wiphy lock is held. Cancel it in case it was scheduled just before - * we stopped the HW. - */ - wiphy_work_cancel(mld->wiphy, &mld->async_handlers_wk); - - /* Empty out the list, as the worker won't do that */ - iwl_mld_purge_async_handlers_list(mld); - /* Clear in_hw_restart flag when stopping the hw, as mac80211 won't * execute the restart. */ @@ -897,9 +905,8 @@ void iwl_mld_change_chanctx(struct ieee80211_hw *hw, return; } update: - phy->chandef = *chandef; - iwl_mld_phy_fw_action(mld, ctx, FW_CTXT_ACTION_MODIFY); + iwl_mld_update_phy_chandef(mld, ctx); } static u8 @@ -1031,12 +1038,19 @@ int iwl_mld_assign_vif_chanctx(struct ieee80211_hw *hw, iwl_mld_send_ap_tx_power_constraint_cmd(mld, vif, link); if (vif->type == NL80211_IFTYPE_MONITOR) { - /* TODO: task=sniffer add sniffer station */ + ret = iwl_mld_add_mon_sta(mld, vif, link); + if (ret) + goto deactivate_link; + mld->monitor.p80 = iwl_mld_chandef_get_primary_80(&vif->bss_conf.chanreq.oper); } return 0; + +deactivate_link: + if (mld_link->active) + iwl_mld_deactivate_link(mld, link); err: RCU_INIT_POINTER(mld_link->chan_ctx, NULL); return ret; @@ -1062,7 +1076,8 @@ void iwl_mld_unassign_vif_chanctx(struct ieee80211_hw *hw, iwl_mld_deactivate_link(mld, link); - /* TODO: task=sniffer remove sniffer station */ + if (vif->type == NL80211_IFTYPE_MONITOR) + iwl_mld_remove_mon_sta(mld, vif, link); if (n_active > 1) { /* Indicate to mac80211 that EML is disabled */ @@ -1258,9 +1273,14 @@ iwl_mld_mac80211_link_info_changed(struct ieee80211_hw *hw, } static void -iwl_mld_smps_wa(struct iwl_mld *mld, struct ieee80211_vif *vif, bool enable) +iwl_mld_smps_workaround(struct iwl_mld *mld, struct ieee80211_vif *vif, bool enable) { struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); + bool workaround_required = + iwl_fw_lookup_cmd_ver(mld->fw, MAC_PM_POWER_TABLE, 0) < 2; + + if (!workaround_required) + return; /* Send the device-level power commands since the * firmware checks the POWER_TABLE_CMD's POWER_SAVE_EN bit to @@ -1307,7 +1327,7 @@ void iwl_mld_mac80211_vif_cfg_changed(struct ieee80211_hw *hw, } if (changes & BSS_CHANGED_PS) { - iwl_mld_smps_wa(mld, vif, vif->cfg.ps); + iwl_mld_smps_workaround(mld, vif, vif->cfg.ps); iwl_mld_update_mac_power(mld, vif, false); } @@ -1320,13 +1340,22 @@ iwl_mld_mac80211_hw_scan(struct ieee80211_hw *hw, struct ieee80211_scan_request *hw_req) { struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); + int ret; if (WARN_ON(!hw_req->req.n_channels || hw_req->req.n_channels > mld->fw->ucode_capa.n_scan_channels)) return -EINVAL; - return iwl_mld_regular_scan_start(mld, vif, &hw_req->req, &hw_req->ies); + ret = iwl_mld_regular_scan_start(mld, vif, &hw_req->req, &hw_req->ies); + if (!ret) { + /* We will be busy with scanning, so the counters may not reflect the + * reality. Stop checking the counters until the scan ends + */ + iwl_mld_start_ignoring_tpt_updates(mld); + } + + return ret; } static void @@ -1342,8 +1371,11 @@ iwl_mld_mac80211_cancel_hw_scan(struct ieee80211_hw *hw, * cancel scan before ieee80211_scan_work() could run. * To handle that, simply return if the scan is not running. */ - if (mld->scan.status & IWL_MLD_SCAN_REGULAR) + if (mld->scan.status & IWL_MLD_SCAN_REGULAR) { iwl_mld_scan_stop(mld, IWL_MLD_SCAN_REGULAR, true); + /* Scan is over, we can check again the tpt counters */ + iwl_mld_stop_ignoring_tpt_updates(mld); + } } static int @@ -1720,7 +1752,7 @@ static int iwl_mld_move_sta_state_up(struct iwl_mld *mld, FW_CTXT_ACTION_MODIFY); if (ret) return ret; - iwl_mld_smps_wa(mld, vif, vif->cfg.ps); + iwl_mld_smps_workaround(mld, vif, vif->cfg.ps); } /* MFP is set by default before the station is authorized. @@ -1763,7 +1795,7 @@ static int iwl_mld_move_sta_state_down(struct iwl_mld *mld, &mld_vif->emlsr.check_tpt_wk); iwl_mld_reset_cca_40mhz_workaround(mld, vif); - iwl_mld_smps_wa(mld, vif, true); + iwl_mld_smps_workaround(mld, vif, true); } /* once we move into assoc state, need to update the FW to @@ -2004,7 +2036,7 @@ static int iwl_mld_alloc_ptk_pn(struct iwl_mld *mld, struct ieee80211_key_conf *key, struct iwl_mld_ptk_pn **ptk_pn) { - u8 num_rx_queues = mld->trans->num_rx_queues; + u8 num_rx_queues = mld->trans->info.num_rxqs; int keyidx = key->keyidx; struct ieee80211_key_seq seq; @@ -2460,15 +2492,17 @@ iwl_mld_change_vif_links(struct ieee80211_hw *hw, added |= BIT(0); for (int i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) { - if (removed & BIT(i)) + if (removed & BIT(i) && !WARN_ON(!old[i])) iwl_mld_remove_link(mld, old[i]); } for (int i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) { if (added & BIT(i)) { link_conf = link_conf_dereference_protected(vif, i); - if (WARN_ON(!link_conf)) - return -EINVAL; + if (!link_conf) { + err = -EINVAL; + goto remove_added_links; + } err = iwl_mld_add_link(mld, link_conf); if (err) @@ -2503,7 +2537,11 @@ remove_added_links: iwl_mld_remove_link(mld, link_conf); } - return err; + if (WARN_ON(!iwl_mld_error_before_recovery(mld))) + return err; + + /* reconfig will fix us anyway */ + return 0; } static int iwl_mld_change_sta_links(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mcc.c b/drivers/net/wireless/intel/iwlwifi/mld/mcc.c index daca14e208bd..19cb562e7a73 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mcc.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mcc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2024 Intel Corporation + * Copyright (C) 2024-2025 Intel Corporation */ #include <net/cfg80211.h> @@ -158,7 +158,7 @@ iwl_mld_get_regdomain(struct iwl_mld *mld, } IWL_DEBUG_LAR(mld, "MCC update response version: %d\n", resp_ver); - regd = iwl_parse_nvm_mcc_info(mld->trans->dev, mld->cfg, + regd = iwl_parse_nvm_mcc_info(mld->trans, __le32_to_cpu(resp->n_channels), resp->channels, __le16_to_cpu(resp->mcc), diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mld.c b/drivers/net/wireless/intel/iwlwifi/mld/mld.c index 73d2166a4c25..8cdd960c5245 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mld.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mld.c @@ -26,6 +26,8 @@ #include "hcmd.h" #include "fw/api/location.h" +#include "iwl-nvm-parse.h" + #define DRV_DESCRIPTION "Intel(R) MLD wireless driver for Linux" MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_LICENSE("GPL"); @@ -60,7 +62,7 @@ static void iwl_mld_hw_set_regulatory(struct iwl_mld *mld) VISIBLE_IF_IWLWIFI_KUNIT void iwl_construct_mld(struct iwl_mld *mld, struct iwl_trans *trans, - const struct iwl_cfg *cfg, const struct iwl_fw *fw, + const struct iwl_rf_cfg *cfg, const struct iwl_fw *fw, struct ieee80211_hw *hw, struct dentry *dbgfs_dir) { mld->dev = trans->dev; @@ -75,7 +77,6 @@ void iwl_construct_mld(struct iwl_mld *mld, struct iwl_trans *trans, /* Setup async RX handling */ spin_lock_init(&mld->async_handlers_lock); - INIT_LIST_HEAD(&mld->async_handlers_list); wiphy_work_init(&mld->async_handlers_wk, iwl_mld_async_handlers_wk); @@ -192,6 +193,7 @@ static const struct iwl_hcmd_names iwl_mld_system_names[] = { HCMD_NAME(SOC_CONFIGURATION_CMD), HCMD_NAME(INIT_EXTENDED_CFG_CMD), HCMD_NAME(FW_ERROR_RECOVERY_CMD), + HCMD_NAME(RFI_CONFIG_CMD), HCMD_NAME(RFI_GET_FREQ_TABLE_CMD), HCMD_NAME(SYSTEM_STATISTICS_CMD), HCMD_NAME(SYSTEM_STATISTICS_END_NOTIF), @@ -287,7 +289,9 @@ static const struct iwl_hcmd_names iwl_mld_statistics_names[] = { * Access is done through binary search */ static const struct iwl_hcmd_names iwl_mld_prot_offload_names[] = { - HCMD_NAME(STORED_BEACON_NTF), + HCMD_NAME(WOWLAN_WAKE_PKT_NOTIFICATION), + HCMD_NAME(WOWLAN_INFO_NOTIFICATION), + HCMD_NAME(D3_END_NOTIFICATION), }; /* Please keep this array *SORTED* by hex value. @@ -322,33 +326,40 @@ EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(global_iwl_mld_goups_size); static void iwl_mld_configure_trans(struct iwl_op_mode *op_mode) { - const struct iwl_mld *mld = IWL_OP_MODE_GET_MLD(op_mode); + struct iwl_mld *mld = IWL_OP_MODE_GET_MLD(op_mode); static const u8 no_reclaim_cmds[] = {TX_CMD}; - struct iwl_trans_config trans_cfg = { - .op_mode = op_mode, - /* Rx is not supported yet, but add it to avoid warnings */ - .rx_buf_size = iwl_amsdu_size_to_rxb_size(), - .command_groups = iwl_mld_groups, - .command_groups_size = ARRAY_SIZE(iwl_mld_groups), - .fw_reset_handshake = true, - .queue_alloc_cmd_ver = - iwl_fw_lookup_cmd_ver(mld->fw, - WIDE_ID(DATA_PATH_GROUP, - SCD_QUEUE_CONFIG_CMD), - 0), - .no_reclaim_cmds = no_reclaim_cmds, - .n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds), - .cb_data_offs = offsetof(struct ieee80211_tx_info, - driver_data[2]), - }; struct iwl_trans *trans = mld->trans; + u32 eckv_value; - trans->rx_mpdu_cmd = REPLY_RX_MPDU_CMD; - trans->iml = mld->fw->iml; - trans->iml_len = mld->fw->iml_len; - trans->wide_cmd_header = true; + iwl_bios_setup_step(trans, &mld->fwrt); + iwl_uefi_get_step_table(trans); - iwl_trans_configure(trans, &trans_cfg); + if (iwl_bios_get_eckv(&mld->fwrt, &eckv_value)) + IWL_DEBUG_RADIO(mld, "ECKV table doesn't exist in BIOS\n"); + else + trans->conf.ext_32khz_clock_valid = !!eckv_value; + + trans->conf.rx_buf_size = iwl_amsdu_size_to_rxb_size(); + trans->conf.command_groups = iwl_mld_groups; + trans->conf.command_groups_size = ARRAY_SIZE(iwl_mld_groups); + trans->conf.fw_reset_handshake = true; + trans->conf.queue_alloc_cmd_ver = + iwl_fw_lookup_cmd_ver(mld->fw, WIDE_ID(DATA_PATH_GROUP, + SCD_QUEUE_CONFIG_CMD), + 0); + trans->conf.cb_data_offs = offsetof(struct ieee80211_tx_info, + driver_data[2]); + BUILD_BUG_ON(sizeof(no_reclaim_cmds) > + sizeof(trans->conf.no_reclaim_cmds)); + memcpy(trans->conf.no_reclaim_cmds, no_reclaim_cmds, + sizeof(no_reclaim_cmds)); + trans->conf.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); + + trans->conf.rx_mpdu_cmd = REPLY_RX_MPDU_CMD; + trans->conf.rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start); + trans->conf.wide_cmd_header = true; + + iwl_trans_op_mode_enter(trans, op_mode); } /* @@ -359,13 +370,12 @@ iwl_mld_configure_trans(struct iwl_op_mode *op_mode) #define NUM_FW_LOAD_RETRIES 3 static struct iwl_op_mode * -iwl_op_mode_mld_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, +iwl_op_mode_mld_start(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg, const struct iwl_fw *fw, struct dentry *dbgfs_dir) { struct ieee80211_hw *hw; struct iwl_op_mode *op_mode; struct iwl_mld *mld; - u32 eckv_value; int ret; /* Allocate and initialize a new hardware device */ @@ -383,16 +393,13 @@ iwl_op_mode_mld_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, iwl_construct_mld(mld, trans, cfg, fw, hw, dbgfs_dir); + /* we'll verify later it matches between commands */ + mld->fw_rates_ver_3 = iwl_fw_lookup_cmd_ver(mld->fw, TX_CMD, 0) >= 11; + iwl_mld_construct_fw_runtime(mld, trans, fw, dbgfs_dir); iwl_mld_get_bios_tables(mld); iwl_uefi_get_sgom_table(trans, &mld->fwrt); - iwl_uefi_get_step_table(trans); - if (iwl_bios_get_eckv(&mld->fwrt, &eckv_value)) - IWL_DEBUG_RADIO(mld, "ECKV table doesn't exist in BIOS\n"); - else - trans->ext_32khz_clock_valid = !!eckv_value; - iwl_bios_setup_step(trans, &mld->fwrt); mld->bios_enable_puncturing = iwl_uefi_get_puncturing(&mld->fwrt); iwl_mld_hw_set_regulatory(mld); @@ -411,10 +418,17 @@ iwl_op_mode_mld_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, break; } + if (!ret) { + mld->nvm_data = iwl_get_nvm(mld->trans, mld->fw, 0, 0); + if (IS_ERR(mld->nvm_data)) { + IWL_ERR(mld, "Failed to read NVM: %d\n", ret); + ret = PTR_ERR(mld->nvm_data); + } + } + if (ret) { wiphy_unlock(mld->wiphy); rtnl_unlock(); - iwl_fw_flush_dumps(&mld->fwrt); goto err; } @@ -475,8 +489,9 @@ iwl_op_mode_mld_stop(struct iwl_op_mode *op_mode) iwl_mld_ptp_remove(mld); iwl_mld_leds_exit(mld); - wiphy_lock(mld->wiphy); iwl_mld_thermal_exit(mld); + + wiphy_lock(mld->wiphy); iwl_mld_low_latency_stop(mld); iwl_mld_deinit_time_sync(mld); wiphy_unlock(mld->wiphy); @@ -664,6 +679,13 @@ static bool iwl_mld_sw_reset(struct iwl_op_mode *op_mode, { struct iwl_mld *mld = IWL_OP_MODE_GET_MLD(op_mode); + /* SW reset can happen for TOP error w/o NIC error, so + * also abort scan here and set in_hw_restart, when we + * had a NIC error both were already done. + */ + iwl_mld_report_scan_aborted(mld); + mld->fw_status.in_hw_restart = true; + /* Do restart only in the following conditions are met: * - we consider the FW as running * - The trigger that brought us here is defined as one that requires @@ -692,7 +714,6 @@ static void iwl_mld_device_powered_off(struct iwl_op_mode *op_mode) struct iwl_mld *mld = IWL_OP_MODE_GET_MLD(op_mode); wiphy_lock(mld->wiphy); - mld->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; iwl_mld_stop_fw(mld); mld->fw_status.in_d3 = false; wiphy_unlock(mld->wiphy); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mld.h b/drivers/net/wireless/intel/iwlwifi/mld/mld.h index a4a16da6ebf3..1a2c44f44eff 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mld.h +++ b/drivers/net/wireless/intel/iwlwifi/mld/mld.h @@ -116,6 +116,7 @@ * @monitor.ampdu_toggle: the state of the previous packet to track A-MPDU * @monitor.cur_aid: current association id tracked by the sniffer * @monitor.cur_bssid: current bssid tracked by the sniffer + * @monitor.ptp_time: set the Rx mactime using the device's PTP clock time * @monitor.p80: primary channel position relative to he whole bandwidth, in * steps of 80 MHz * @fw_id_to_link_sta: maps a fw id of a sta to the corresponding @@ -126,7 +127,6 @@ * 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 @@ -154,6 +154,8 @@ * @radio_kill: bitmap of radio kill status * @radio_kill.hw: radio is killed by hw switch * @radio_kill.ct: radio is killed because the device it too hot + * @power_budget_mw: maximum cTDP power budget as defined for this system and + * device * @addresses: device MAC addresses. * @scan: instance of the scan object * @wowlan: WoWLAN support data. @@ -174,6 +176,7 @@ * @mcast_filter_cmd: pointer to the multicast filter command. * @mgmt_tx_ant: stores the last TX antenna index; used for setting * TX rate_n_flags for non-STA mgmt frames (toggles on every TX failure). + * @fw_rates_ver_3: FW rates are in version 3 * @low_latency: low-latency manager. * @tzone: thermal zone device's data * @cooling_dev: cooling device's related data @@ -184,6 +187,7 @@ * @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 */ @@ -201,19 +205,20 @@ struct iwl_mld { #ifdef CONFIG_IWLWIFI_DEBUGFS __le16 cur_aid; u8 cur_bssid[ETH_ALEN]; + bool ptp_time; #endif } monitor; #ifdef CONFIG_PM_SLEEP bool netdetect; #endif /* CONFIG_PM_SLEEP */ struct ieee80211_vif *p2p_device_vif; - bool bt_is_active; + struct iwl_bt_coex_profile_notif last_bt_notif; ); struct ieee80211_link_sta __rcu *fw_id_to_link_sta[IWL_STATION_COUNT_MAX]; /* And here fields that survive a fw restart */ struct device *dev; struct iwl_trans *trans; - const struct iwl_cfg *cfg; + const struct iwl_rf_cfg *cfg; const struct iwl_fw *fw; struct ieee80211_hw *hw; struct wiphy *wiphy; @@ -241,6 +246,8 @@ struct iwl_mld { ct:1; } radio_kill; + u32 power_budget_mw; + struct mac_address addresses[IWL_MLD_MAX_ADDRESSES]; struct iwl_mld_scan scan; #ifdef CONFIG_PM_SLEEP @@ -266,6 +273,8 @@ struct iwl_mld { u8 mgmt_tx_ant; + bool fw_rates_ver_3; + struct iwl_mld_low_latency low_latency; bool ibss_manager; @@ -286,7 +295,7 @@ struct iwl_mld { memset((void *)&(_ptr)->zeroed_on_hw_restart, 0, \ sizeof((_ptr)->zeroed_on_hw_restart)) -/* Cleanup function for struct iwl_mld_vif, will be called in restart */ +/* Cleanup function for struct iwl_mld, will be called in restart */ static inline void iwl_cleanup_mld(struct iwl_mld *mld) { @@ -410,7 +419,7 @@ iwl_mld_legacy_hw_idx_to_mac80211_idx(u32 rate_n_flags, int rate = rate_n_flags & RATE_LEGACY_RATE_MSK; bool is_lb = band == NL80211_BAND_2GHZ; - if (format == RATE_MCS_LEGACY_OFDM_MSK) + if (format == RATE_MCS_MOD_TYPE_LEGACY_OFDM) return is_lb ? rate + IWL_FIRST_OFDM_RATE : rate; /* CCK is not allowed in 5 GHz */ @@ -482,7 +491,7 @@ iwl_mld_is_dup(struct iwl_mld *mld, struct ieee80211_sta *sta, struct ieee80211_rx_status *rx_status, int queue); void iwl_construct_mld(struct iwl_mld *mld, struct iwl_trans *trans, - const struct iwl_cfg *cfg, const struct iwl_fw *fw, + const struct iwl_rf_cfg *cfg, const struct iwl_fw *fw, struct ieee80211_hw *hw, struct dentry *dbgfs_dir); #endif diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mlo.c b/drivers/net/wireless/intel/iwlwifi/mld/mlo.c index a870e169e265..dba5379ed009 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mlo.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mlo.c @@ -52,7 +52,8 @@ static void iwl_mld_print_emlsr_blocked(struct iwl_mld *mld, u32 mask) HOW(BT_COEX) \ HOW(CHAN_LOAD) \ HOW(RFI) \ - HOW(FW_REQUEST) + HOW(FW_REQUEST) \ + HOW(INVALID) static const char * iwl_mld_get_emlsr_exit_string(enum iwl_mld_emlsr_exit exit) @@ -325,23 +326,44 @@ static void iwl_mld_vif_iter_emlsr_mode_notif(void *data, u8 *mac, struct ieee80211_vif *vif) { - struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); - struct iwl_esr_mode_notif *notif = (void *)data; + const struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); + enum iwl_mvm_fw_esr_recommendation action; + const struct iwl_esr_mode_notif *notif = NULL; + + if (iwl_fw_lookup_notif_ver(mld_vif->mld->fw, DATA_PATH_GROUP, + ESR_MODE_NOTIF, 0) > 1) { + notif = (void *)data; + action = le32_to_cpu(notif->action); + } else { + const struct iwl_esr_mode_notif_v1 *notif_v1 = (void *)data; + + action = le32_to_cpu(notif_v1->action); + } if (!iwl_mld_vif_has_emlsr_cap(vif)) return; - switch (le32_to_cpu(notif->action)) { + switch (action) { case ESR_RECOMMEND_LEAVE: + if (notif) + IWL_DEBUG_INFO(mld_vif->mld, + "FW recommend leave reason = 0x%x\n", + le32_to_cpu(notif->leave_reason_mask)); + iwl_mld_exit_emlsr(mld_vif->mld, vif, IWL_MLD_EMLSR_EXIT_FW_REQUEST, iwl_mld_get_primary_link(vif)); break; - case ESR_RECOMMEND_ENTER: case ESR_FORCE_LEAVE: + if (notif) + IWL_DEBUG_INFO(mld_vif->mld, + "FW force leave reason = 0x%x\n", + le32_to_cpu(notif->leave_reason_mask)); + fallthrough; + case ESR_RECOMMEND_ENTER: default: IWL_WARN(mld_vif->mld, "Unexpected EMLSR notification: %d\n", - le32_to_cpu(notif->action)); + action); } } @@ -523,7 +545,7 @@ void iwl_mld_emlsr_check_tpt(struct wiphy *wiphy, struct wiphy_work *wk) } /* Sum up RX and TX MPDUs from the different queues/links */ - for (int q = 0; q < mld->trans->num_rx_queues; q++) { + for (int q = 0; q < mld->trans->info.num_rxqs; q++) { struct iwl_mld_per_q_mpdu_counter *queue_counter = &mld_sta->mpdu_counters[q]; @@ -635,6 +657,42 @@ 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, @@ -643,13 +701,14 @@ iwl_mld_emlsr_disallowed_with_link(struct iwl_mld *mld, { struct wiphy *wiphy = mld->wiphy; struct ieee80211_bss_conf *conf; - enum iwl_mld_emlsr_exit ret = 0; + u32 ret = 0; conf = wiphy_dereference(wiphy, vif->link_conf[link->link_id]); if (WARN_ON_ONCE(!conf)) - return false; + return IWL_MLD_EMLSR_EXIT_INVALID; - if (link->chandef->chan->band == NL80211_BAND_2GHZ && mld->bt_is_active) + if (link->chandef->chan->band == NL80211_BAND_2GHZ && + !iwl_mld_bt_allows_emlsr(mld, conf, true)) ret |= IWL_MLD_EMLSR_EXIT_BT_COEX; if (link->signal < @@ -731,7 +790,7 @@ iwl_mld_get_min_chan_load_thresh(struct ieee80211_chanctx_conf *chanctx) return 10; } -VISIBLE_IF_IWLWIFI_KUNIT bool +static bool iwl_mld_channel_load_allows_emlsr(struct iwl_mld *mld, struct ieee80211_vif *vif, const struct iwl_mld_link_sel_data *a, @@ -772,8 +831,8 @@ iwl_mld_channel_load_allows_emlsr(struct iwl_mld *mld, if (a->chandef->width <= b->chandef->width) return true; - bw_a = nl80211_chan_width_to_mhz(a->chandef->width); - bw_b = nl80211_chan_width_to_mhz(b->chandef->width); + bw_a = cfg80211_chandef_get_width(a->chandef); + bw_b = cfg80211_chandef_get_width(b->chandef); ratio = bw_a / bw_b; switch (ratio) { @@ -788,10 +847,9 @@ iwl_mld_channel_load_allows_emlsr(struct iwl_mld *mld, return false; } -EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_mld_channel_load_allows_emlsr); -static bool -iwl_mld_valid_emlsr_pair(struct ieee80211_vif *vif, +VISIBLE_IF_IWLWIFI_KUNIT u32 +iwl_mld_emlsr_pair_state(struct ieee80211_vif *vif, struct iwl_mld_link_sel_data *a, struct iwl_mld_link_sel_data *b) { @@ -800,12 +858,36 @@ iwl_mld_valid_emlsr_pair(struct ieee80211_vif *vif, u32 reason_mask = 0; /* Per-link considerations */ - if (iwl_mld_emlsr_disallowed_with_link(mld, vif, a, true) || - iwl_mld_emlsr_disallowed_with_link(mld, vif, b, false)) - return false; - - if (a->chandef->chan->band == b->chandef->chan->band) - reason_mask |= IWL_MLD_EMLSR_EXIT_EQUAL_BAND; + reason_mask = iwl_mld_emlsr_disallowed_with_link(mld, vif, a, true); + if (reason_mask) + return reason_mask; + + reason_mask = iwl_mld_emlsr_disallowed_with_link(mld, vif, b, false); + if (reason_mask) + return reason_mask; + + if (a->chandef->chan->band == b->chandef->chan->band) { + const struct cfg80211_chan_def *c_low = a->chandef; + const struct cfg80211_chan_def *c_high = b->chandef; + u32 c_low_upper_edge, c_high_lower_edge; + + if (c_low->chan->center_freq > c_high->chan->center_freq) + swap(c_low, c_high); + + c_low_upper_edge = c_low->chan->center_freq + + cfg80211_chandef_get_width(c_low) / 2; + c_high_lower_edge = c_high->chan->center_freq - + cfg80211_chandef_get_width(c_high) / 2; + + if (a->chandef->chan->band == NL80211_BAND_5GHZ && + c_low_upper_edge <= 5330 && c_high_lower_edge >= 5490) { + /* This case is fine - HW/FW can deal with it, there's + * enough separation between the two channels. + */ + } else { + reason_mask |= IWL_MLD_EMLSR_EXIT_EQUAL_BAND; + } + } if (!iwl_mld_channel_load_allows_emlsr(mld, vif, a, b)) reason_mask |= IWL_MLD_EMLSR_EXIT_CHAN_LOAD; @@ -818,11 +900,11 @@ iwl_mld_valid_emlsr_pair(struct ieee80211_vif *vif, nl80211_chan_width_to_mhz(a->chandef->width), nl80211_chan_width_to_mhz(b->chandef->width)); iwl_mld_print_emlsr_exit(mld, reason_mask); - return false; } - return true; + return reason_mask; } +EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_mld_emlsr_pair_state); /* Calculation is done with fixed-point with a scaling factor of 1/256 */ #define SCALE_FACTOR 256 @@ -850,7 +932,7 @@ unsigned int iwl_mld_get_emlsr_grade(struct iwl_mld *mld, *primary_id = a->link_id; - if (!iwl_mld_valid_emlsr_pair(vif, a, b)) + if (iwl_mld_emlsr_pair_state(vif, a, b)) return 0; primary_conf = wiphy_dereference(wiphy, vif->link_conf[*primary_id]); @@ -892,8 +974,11 @@ static void _iwl_mld_select_links(struct iwl_mld *mld, n_data = iwl_mld_set_link_sel_data(mld, vif, data, usable_links, &best_idx); - if (WARN(!n_data, "Couldn't find a valid grade for any link!\n")) + if (!n_data) { + IWL_DEBUG_EHT(mld, + "Couldn't find a valid grade for any link!\n"); return; + } /* Default to selecting the single best link */ best_link = &data[best_idx]; @@ -961,27 +1046,41 @@ 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 (!mld->bt_is_active) { - iwl_mld_retry_emlsr(mld, vif); + if (!iwl_mld_vif_has_emlsr_cap(vif)) return; - } - /* BT is turned ON but we are not in EMLSR, nothing to do */ - if (!iwl_mld_emlsr_active(vif)) + /* zeroed structure means that BT is OFF */ + if (!memcmp(notif, &zero_notif, sizeof(*notif))) { + iwl_mld_retry_emlsr(mld, vif); return; - - /* In EMLSR and BT is turned ON */ + } for_each_vif_active_link(vif, link, link_id) { + bool emlsr_active, emlsr_allowed; + if (WARN_ON(!link->chanreq.oper.chan)) continue; - if (link->chanreq.oper.chan->band == NL80211_BAND_2GHZ) { - iwl_mld_exit_emlsr(mld, vif, IWL_MLD_EMLSR_EXIT_BT_COEX, + 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, iwl_mld_get_primary_link(vif)); return; } @@ -1074,3 +1173,69 @@ void iwl_mld_retry_emlsr(struct iwl_mld *mld, struct ieee80211_vif *vif) iwl_mld_int_mlo_scan(mld, vif); } + +static void iwl_mld_ignore_tpt_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); + struct iwl_mld *mld = mld_vif->mld; + struct iwl_mld_sta *mld_sta; + bool *start = (void *)data; + + /* check_tpt_wk is only used when TPT block isn't set */ + if (mld_vif->emlsr.blocked_reasons & IWL_MLD_EMLSR_BLOCKED_TPT || + !IWL_MLD_AUTO_EML_ENABLE || !mld_vif->ap_sta) + return; + + mld_sta = iwl_mld_sta_from_mac80211(mld_vif->ap_sta); + + /* We only count for the AP sta in a MLO connection */ + if (!mld_sta->mpdu_counters) + return; + + if (*start) { + wiphy_delayed_work_cancel(mld_vif->mld->wiphy, + &mld_vif->emlsr.check_tpt_wk); + IWL_DEBUG_EHT(mld, "TPT check disabled\n"); + return; + } + + /* Clear the counters so we start from the beginning */ + for (int q = 0; q < mld->trans->info.num_rxqs; q++) { + struct iwl_mld_per_q_mpdu_counter *queue_counter = + &mld_sta->mpdu_counters[q]; + + spin_lock_bh(&queue_counter->lock); + + memset(queue_counter->per_link, 0, + sizeof(queue_counter->per_link)); + + spin_unlock_bh(&queue_counter->lock); + } + + /* Schedule the check in 5 seconds */ + wiphy_delayed_work_queue(mld_vif->mld->wiphy, + &mld_vif->emlsr.check_tpt_wk, + round_jiffies_relative(IWL_MLD_TPT_COUNT_WINDOW)); + IWL_DEBUG_EHT(mld, "TPT check enabled\n"); +} + +void iwl_mld_start_ignoring_tpt_updates(struct iwl_mld *mld) +{ + bool start = true; + + ieee80211_iterate_active_interfaces_mtx(mld->hw, + IEEE80211_IFACE_ITER_NORMAL, + iwl_mld_ignore_tpt_iter, + &start); +} + +void iwl_mld_stop_ignoring_tpt_updates(struct iwl_mld *mld) +{ + bool start = false; + + ieee80211_iterate_active_interfaces_mtx(mld->hw, + IEEE80211_IFACE_ITER_NORMAL, + iwl_mld_ignore_tpt_iter, + &start); +} diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mlo.h b/drivers/net/wireless/intel/iwlwifi/mld/mlo.h index 4fb1fdbe3df9..9afa3d6ea649 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mlo.h +++ b/drivers/net/wireless/intel/iwlwifi/mld/mlo.h @@ -37,7 +37,7 @@ static inline bool iwl_mld_vif_has_emlsr_cap(struct ieee80211_vif *vif) return ieee80211_vif_type_p2p(vif) == NL80211_IFTYPE_STATION && ieee80211_vif_is_mld(vif) && vif->cfg.eml_cap & IEEE80211_EML_CAP_EMLSR_SUPP && - !CSR_HW_RFID_IS_CDB(mld_vif->mld->trans->hw_rf_id); + !CSR_HW_RFID_IS_CDB(mld_vif->mld->trans->info.hw_rf_id); } static inline int @@ -158,10 +158,16 @@ struct iwl_mld_link_sel_data { }; #if IS_ENABLED(CONFIG_IWLWIFI_KUNIT_TESTS) -bool iwl_mld_channel_load_allows_emlsr(struct iwl_mld *mld, - struct ieee80211_vif *vif, - const struct iwl_mld_link_sel_data *a, - const struct iwl_mld_link_sel_data *b); +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); +void iwl_mld_stop_ignoring_tpt_updates(struct iwl_mld *mld); + #endif /* __iwl_mld_mlo_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/mld/notif.c b/drivers/net/wireless/intel/iwlwifi/mld/notif.c index fc18cba8aaa8..c0e62d46aba6 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/notif.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/notif.c @@ -183,47 +183,6 @@ static void iwl_mld_handle_mu_mimo_grp_notif(struct iwl_mld *mld, } static void -iwl_mld_handle_stored_beacon_notif(struct iwl_mld *mld, - struct iwl_rx_packet *pkt) -{ - unsigned int pkt_len = iwl_rx_packet_payload_len(pkt); - struct iwl_stored_beacon_notif *sb = (void *)pkt->data; - struct ieee80211_rx_status rx_status = {}; - struct sk_buff *skb; - u32 size = le32_to_cpu(sb->common.byte_count); - - if (size == 0) - return; - - if (pkt_len < struct_size(sb, data, size)) - return; - - skb = alloc_skb(size, GFP_ATOMIC); - if (!skb) { - IWL_ERR(mld, "alloc_skb failed\n"); - return; - } - - /* update rx_status according to the notification's metadata */ - rx_status.mactime = le64_to_cpu(sb->common.tsf); - /* TSF as indicated by the firmware is at INA time */ - rx_status.flag |= RX_FLAG_MACTIME_PLCP_START; - rx_status.device_timestamp = le32_to_cpu(sb->common.system_time); - rx_status.band = - iwl_mld_phy_band_to_nl80211(le16_to_cpu(sb->common.band)); - rx_status.freq = - ieee80211_channel_to_frequency(le16_to_cpu(sb->common.channel), - rx_status.band); - - /* copy the data */ - skb_put_data(skb, sb->data, size); - memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); - - /* pass it as regular rx to mac80211 */ - ieee80211_rx_napi(mld->hw, NULL, skb, NULL); -} - -static void iwl_mld_handle_channel_switch_start_notif(struct iwl_mld *mld, struct iwl_rx_packet *pkt) { @@ -345,12 +304,15 @@ CMD_VERSIONS(session_prot_notif, CMD_VERSIONS(missed_beacon_notif, CMD_VER_ENTRY(5, iwl_missed_beacons_notif)) CMD_VERSIONS(tx_resp_notif, - CMD_VER_ENTRY(8, iwl_tx_resp)) + CMD_VER_ENTRY(8, iwl_tx_resp) + CMD_VER_ENTRY(9, iwl_tx_resp)) CMD_VERSIONS(compressed_ba_notif, CMD_VER_ENTRY(5, iwl_compressed_ba_notif) - CMD_VER_ENTRY(6, iwl_compressed_ba_notif)) + CMD_VER_ENTRY(6, iwl_compressed_ba_notif) + CMD_VER_ENTRY(7, iwl_compressed_ba_notif)) CMD_VERSIONS(tlc_notif, - CMD_VER_ENTRY(3, iwl_tlc_update_notif)) + CMD_VER_ENTRY(3, iwl_tlc_update_notif) + CMD_VER_ENTRY(4, iwl_tlc_update_notif)) CMD_VERSIONS(mu_mimo_grp_notif, CMD_VER_ENTRY(1, iwl_mu_group_mgmt_notif)) CMD_VERSIONS(channel_switch_start_notif, @@ -361,8 +323,6 @@ CMD_VERSIONS(ct_kill_notif, CMD_VER_ENTRY(2, ct_kill_notif)) CMD_VERSIONS(temp_notif, CMD_VER_ENTRY(2, iwl_dts_measurement_notif)) -CMD_VERSIONS(stored_beacon_notif, - CMD_VER_ENTRY(4, iwl_stored_beacon_notif)) CMD_VERSIONS(roc_notif, CMD_VER_ENTRY(1, iwl_roc_notif)) CMD_VERSIONS(probe_resp_data_notif, @@ -378,7 +338,8 @@ CMD_VERSIONS(bt_coex_notif, CMD_VERSIONS(beacon_notification, CMD_VER_ENTRY(6, iwl_extended_beacon_notif)) CMD_VERSIONS(emlsr_mode_notif, - CMD_VER_ENTRY(1, iwl_esr_mode_notif)) + CMD_VER_ENTRY(1, iwl_esr_mode_notif_v1) + CMD_VER_ENTRY(2, iwl_esr_mode_notif)) CMD_VERSIONS(emlsr_trans_fail_notif, CMD_VER_ENTRY(1, iwl_esr_trans_fail_notif)) CMD_VERSIONS(uapsd_misbehaving_ap_notif, @@ -473,8 +434,6 @@ const struct iwl_rx_handler iwl_mld_rx_handlers[] = { RX_HANDLER_OF_ROC(MAC_CONF_GROUP, ROC_NOTIF, roc_notif) RX_HANDLER_NO_OBJECT(DATA_PATH_GROUP, MU_GROUP_MGMT_NOTIF, mu_mimo_grp_notif, RX_HANDLER_SYNC) - RX_HANDLER_NO_OBJECT(PROT_OFFLOAD_GROUP, STORED_BEACON_NTF, - stored_beacon_notif, RX_HANDLER_SYNC) RX_HANDLER_OF_VIF(MAC_CONF_GROUP, PROBE_RESPONSE_DATA_NOTIF, probe_resp_data_notif) RX_HANDLER_NO_OBJECT(PHY_OPS_GROUP, CT_KILL_NOTIFICATION, @@ -646,7 +605,7 @@ void iwl_mld_rx_rss(struct iwl_op_mode *op_mode, struct napi_struct *napi, struct iwl_mld *mld = IWL_OP_MODE_GET_MLD(op_mode); u16 cmd_id = WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd); - if (unlikely(queue >= mld->trans->num_rx_queues)) + if (unlikely(queue >= mld->trans->info.num_rxqs)) return; if (likely(cmd_id == WIDE_ID(LEGACY_GROUP, REPLY_RX_MPDU_CMD))) @@ -707,10 +666,14 @@ void iwl_mld_async_handlers_wk(struct wiphy *wiphy, struct wiphy_work *wk) } } -void iwl_mld_purge_async_handlers_list(struct iwl_mld *mld) +void iwl_mld_cancel_async_notifications(struct iwl_mld *mld) { struct iwl_async_handler_entry *entry, *tmp; + lockdep_assert_wiphy(mld->wiphy); + + wiphy_work_cancel(mld->wiphy, &mld->async_handlers_wk); + spin_lock_bh(&mld->async_handlers_lock); list_for_each_entry_safe(entry, tmp, &mld->async_handlers_list, list) { iwl_mld_log_async_handler_op(mld, "Purged", &entry->rxb); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/notif.h b/drivers/net/wireless/intel/iwlwifi/mld/notif.h index 2eaa1d4e138e..adcdd9dec192 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/notif.h +++ b/drivers/net/wireless/intel/iwlwifi/mld/notif.h @@ -15,7 +15,7 @@ void iwl_mld_rx_rss(struct iwl_op_mode *op_mode, struct napi_struct *napi, void iwl_mld_async_handlers_wk(struct wiphy *wiphy, struct wiphy_work *wk); -void iwl_mld_purge_async_handlers_list(struct iwl_mld *mld); +void iwl_mld_cancel_async_notifications(struct iwl_mld *mld); enum iwl_mld_object_type { IWL_MLD_OBJECT_TYPE_NONE, diff --git a/drivers/net/wireless/intel/iwlwifi/mld/phy.c b/drivers/net/wireless/intel/iwlwifi/mld/phy.c index 2fbc8090088b..d5a32ee56b92 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/phy.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/phy.c @@ -50,6 +50,9 @@ static void iwl_mld_chanctx_usage_iter(void *_data, u8 *mac, if (rcu_access_pointer(link_conf->chanctx_conf) != data->ctx) continue; + if (vif->type == NL80211_IFTYPE_AP && link_conf->ftm_responder) + data->use_def = true; + if (iwl_mld_chanctx_fils_enabled(vif, data->ctx)) data->use_def = true; } @@ -153,3 +156,43 @@ int iwl_mld_phy_fw_action(struct iwl_mld *mld, return ret; } + +static u32 iwl_mld_get_phy_config(struct iwl_mld *mld) +{ + u32 phy_config = ~(FW_PHY_CFG_TX_CHAIN | + FW_PHY_CFG_RX_CHAIN); + u32 valid_rx_ant = iwl_mld_get_valid_rx_ant(mld); + u32 valid_tx_ant = iwl_mld_get_valid_tx_ant(mld); + + phy_config |= valid_tx_ant << FW_PHY_CFG_TX_CHAIN_POS | + valid_rx_ant << FW_PHY_CFG_RX_CHAIN_POS; + + return mld->fw->phy_config & phy_config; +} + +int iwl_mld_send_phy_cfg_cmd(struct iwl_mld *mld) +{ + const struct iwl_tlv_calib_ctrl *default_calib = + &mld->fw->default_calib[IWL_UCODE_REGULAR]; + struct iwl_phy_cfg_cmd_v3 cmd = { + .phy_cfg = cpu_to_le32(iwl_mld_get_phy_config(mld)), + .calib_control.event_trigger = default_calib->event_trigger, + .calib_control.flow_trigger = default_calib->flow_trigger, + .phy_specific_cfg = mld->fwrt.phy_filters, + }; + + IWL_INFO(mld, "Sending Phy CFG command: 0x%x\n", cmd.phy_cfg); + + return iwl_mld_send_cmd_pdu(mld, PHY_CONFIGURATION_CMD, &cmd); +} + +void iwl_mld_update_phy_chandef(struct iwl_mld *mld, + struct ieee80211_chanctx_conf *ctx) +{ + struct iwl_mld_phy *phy = iwl_mld_phy_from_mac80211(ctx); + struct cfg80211_chan_def *chandef = + iwl_mld_get_chandef_from_chanctx(mld, ctx); + + phy->chandef = *chandef; + iwl_mld_phy_fw_action(mld, ctx, FW_CTXT_ACTION_MODIFY); +} diff --git a/drivers/net/wireless/intel/iwlwifi/mld/phy.h b/drivers/net/wireless/intel/iwlwifi/mld/phy.h index 2212a89321b7..0deaf179f07c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/phy.h +++ b/drivers/net/wireless/intel/iwlwifi/mld/phy.h @@ -52,4 +52,9 @@ iwl_mld_get_chandef_from_chanctx(struct iwl_mld *mld, struct ieee80211_chanctx_conf *ctx); u8 iwl_mld_get_fw_ctrl_pos(const struct cfg80211_chan_def *chandef); +int iwl_mld_send_phy_cfg_cmd(struct iwl_mld *mld); + +void iwl_mld_update_phy_chandef(struct iwl_mld *mld, + struct ieee80211_chanctx_conf *ctx); + #endif /* __iwl_mld_phy_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/mld/power.c b/drivers/net/wireless/intel/iwlwifi/mld/power.c index 2f16c174b57e..8cc276041360 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/power.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/power.c @@ -253,6 +253,9 @@ static void iwl_mld_power_build_cmd(struct iwl_mld *mld, cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); + if (iwl_fw_lookup_cmd_ver(mld->fw, MAC_PM_POWER_TABLE, 0) >= 2) + cmd->flags |= cpu_to_le16(POWER_FLAGS_ENABLE_SMPS_MSK); + /* firmware supports LPRX for beacons at rate 1 Mbps or 6 Mbps only */ if (link_conf->beacon_rate && (link_conf->beacon_rate->bitrate == 10 || diff --git a/drivers/net/wireless/intel/iwlwifi/mld/ptp.c b/drivers/net/wireless/intel/iwlwifi/mld/ptp.c index d5c3f853d96c..5ee38fc168c1 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/ptp.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/ptp.c @@ -21,7 +21,7 @@ static int iwl_mld_get_systime(struct iwl_mld *mld, u32 *gp2) { - *gp2 = iwl_read_prph(mld->trans, mld->trans->cfg->gp2_reg_addr); + *gp2 = iwl_read_prph(mld->trans, mld->trans->mac_cfg->base->gp2_reg_addr); if (*gp2 == 0x5a5a5a5a) return -EINVAL; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c b/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c index a75af8c1e8ab..326c300470ea 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c @@ -63,9 +63,9 @@ void iwl_mld_get_bios_tables(struct iwl_mld *mld) /* we don't fail if the table is not available */ } - ret = iwl_uefi_get_uats_table(mld->trans, &mld->fwrt); - if (ret) - IWL_DEBUG_RADIO(mld, "failed to read UATS table (%d)\n", ret); + iwl_uefi_get_uats_table(mld->trans, &mld->fwrt); + + iwl_bios_get_phy_filters(&mld->fwrt); } static int iwl_mld_geo_sar_init(struct iwl_mld *mld) diff --git a/drivers/net/wireless/intel/iwlwifi/mld/roc.c b/drivers/net/wireless/intel/iwlwifi/mld/roc.c index b87faca23ceb..e85f45bce79a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/roc.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/roc.c @@ -31,13 +31,54 @@ iwl_mld_vif_iter_emlsr_block_roc(void *data, u8 *mac, struct ieee80211_vif *vif) *result = ret; } +struct iwl_mld_roc_iter_data { + enum iwl_roc_activity activity; + struct ieee80211_vif *vif; + bool found; +}; + +static void iwl_mld_find_roc_vif_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); + struct iwl_mld_roc_iter_data *roc_data = data; + + if (mld_vif->roc_activity != roc_data->activity) + return; + + /* The FW supports one ROC of each type simultaneously */ + if (WARN_ON(roc_data->found)) { + roc_data->vif = NULL; + return; + } + + roc_data->found = true; + roc_data->vif = vif; +} + +static struct ieee80211_vif * +iwl_mld_find_roc_vif(struct iwl_mld *mld, enum iwl_roc_activity activity) +{ + struct iwl_mld_roc_iter_data roc_data = { + .activity = activity, + .found = false, + }; + + ieee80211_iterate_active_interfaces_mtx(mld->hw, + IEEE80211_IFACE_ITER_NORMAL, + iwl_mld_find_roc_vif_iter, + &roc_data); + + return roc_data.vif; +} + int iwl_mld_start_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_channel *channel, int duration, enum ieee80211_roc_type type) { struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); - struct iwl_mld_int_sta *aux_sta; + struct iwl_mld_int_sta *aux_sta = &mld_vif->aux_sta; struct iwl_roc_req cmd = { .action = cpu_to_le32(FW_CTXT_ACTION_ADD), }; @@ -49,38 +90,40 @@ int iwl_mld_start_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif, lockdep_assert_wiphy(mld->wiphy); - ieee80211_iterate_active_interfaces_mtx(mld->hw, - IEEE80211_IFACE_ITER_NORMAL, - iwl_mld_vif_iter_emlsr_block_roc, - &ret); - if (ret) - return ret; - - /* TODO: task=Hotspot 2.0 */ - if (vif->type != NL80211_IFTYPE_P2P_DEVICE) { + if (vif->type != NL80211_IFTYPE_P2P_DEVICE && + vif->type != NL80211_IFTYPE_STATION) { IWL_ERR(mld, "NOT SUPPORTED: ROC on vif->type %d\n", vif->type); return -EOPNOTSUPP; } - switch (type) { - case IEEE80211_ROC_TYPE_NORMAL: - activity = ROC_ACTIVITY_P2P_DISC; - break; - case IEEE80211_ROC_TYPE_MGMT_TX: - activity = ROC_ACTIVITY_P2P_NEG; - break; - default: - WARN_ONCE(1, "Got an invalid P2P ROC type\n"); - return -EINVAL; + if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { + switch (type) { + case IEEE80211_ROC_TYPE_NORMAL: + activity = ROC_ACTIVITY_P2P_DISC; + break; + case IEEE80211_ROC_TYPE_MGMT_TX: + activity = ROC_ACTIVITY_P2P_NEG; + break; + default: + WARN_ONCE(1, "Got an invalid P2P ROC type\n"); + return -EINVAL; + } + } else { + activity = ROC_ACTIVITY_HOTSPOT; } - if (WARN_ON(mld_vif->roc_activity != ROC_NUM_ACTIVITIES)) + /* The FW supports one ROC of each type simultaneously */ + if (WARN_ON(iwl_mld_find_roc_vif(mld, activity))) return -EBUSY; - /* No MLO on P2P device */ - aux_sta = &mld_vif->deflink.aux_sta; + ieee80211_iterate_active_interfaces_mtx(mld->hw, + IEEE80211_IFACE_ITER_NORMAL, + iwl_mld_vif_iter_emlsr_block_roc, + &ret); + if (ret) + return ret; ret = iwl_mld_add_aux_sta(mld, aux_sta); if (ret) @@ -91,9 +134,6 @@ int iwl_mld_start_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif, cmd.channel_info.channel = cpu_to_le32(channel->hw_value); cmd.channel_info.band = iwl_mld_nl80211_band_to_fw(channel->band); cmd.channel_info.width = IWL_PHY_CHANNEL_MODE20; - /* TODO: task=Hotspot 2.0, revisit those parameters when we add an ROC - * on the BSS vif - */ cmd.max_delay = cpu_to_le32(AUX_ROC_MAX_DELAY); cmd.duration = cpu_to_le32(MSEC_TO_TU(duration)); @@ -105,6 +145,7 @@ int iwl_mld_start_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif, IWL_ERR(mld, "Couldn't send the ROC_CMD\n"); return ret; } + mld_vif->roc_activity = activity; return 0; @@ -136,9 +177,9 @@ static void iwl_mld_destroy_roc(struct iwl_mld *mld, * we can flush the Tx on the queues */ - iwl_mld_flush_link_sta_txqs(mld, mld_vif->deflink.aux_sta.sta_id); + iwl_mld_flush_link_sta_txqs(mld, mld_vif->aux_sta.sta_id); - iwl_mld_remove_aux_sta(mld, vif, &vif->bss_conf); + iwl_mld_remove_aux_sta(mld, vif); } int iwl_mld_cancel_roc(struct ieee80211_hw *hw, @@ -156,8 +197,8 @@ int iwl_mld_cancel_roc(struct ieee80211_hw *hw, lockdep_assert_wiphy(mld->wiphy); - /* TODO: task=Hotspot 2.0 */ - if (WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE)) + if (WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE && + vif->type != NL80211_IFTYPE_STATION)) return -EOPNOTSUPP; /* No roc activity running it's probably already done */ @@ -192,10 +233,10 @@ void iwl_mld_handle_roc_notif(struct iwl_mld *mld, { const struct iwl_roc_notif *notif = (void *)pkt->data; u32 activity = le32_to_cpu(notif->activity); - /* TODO: task=Hotspot 2.0 - roc can run on BSS */ - struct ieee80211_vif *vif = mld->p2p_device_vif; struct iwl_mld_vif *mld_vif; + struct ieee80211_vif *vif; + vif = iwl_mld_find_roc_vif(mld, activity); if (WARN_ON(!vif)) return; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/rx.c b/drivers/net/wireless/intel/iwlwifi/mld/rx.c index c4f189bcece2..ce0093d5c638 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/rx.c @@ -33,17 +33,17 @@ struct iwl_mld_rx_phy_data { u32 gp2_on_air_rise; u16 phy_info; u8 energy_a, energy_b; - u8 channel; }; static void -iwl_mld_fill_phy_data(struct iwl_rx_mpdu_desc *desc, +iwl_mld_fill_phy_data(struct iwl_mld *mld, + struct iwl_rx_mpdu_desc *desc, struct iwl_mld_rx_phy_data *phy_data) { phy_data->phy_info = le16_to_cpu(desc->phy_info); - phy_data->rate_n_flags = le32_to_cpu(desc->v3.rate_n_flags); + phy_data->rate_n_flags = iwl_v3_rate_from_v2_v3(desc->v3.rate_n_flags, + mld->fw_rates_ver_3); phy_data->gp2_on_air_rise = le32_to_cpu(desc->v3.gp2_on_air_rise); - phy_data->channel = desc->v3.channel; phy_data->energy_a = desc->v3.energy_a; phy_data->energy_b = desc->v3.energy_b; phy_data->data0 = desc->v3.phy_data0; @@ -1162,8 +1162,6 @@ static void iwl_mld_add_rtap_sniffer_config(struct iwl_mld *mld, static void iwl_mld_rx_fill_status(struct iwl_mld *mld, struct sk_buff *skb, struct iwl_mld_rx_phy_data *phy_data, - struct iwl_rx_mpdu_desc *mpdu_desc, - struct ieee80211_hdr *hdr, int queue) { struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); @@ -1172,47 +1170,15 @@ static void iwl_mld_rx_fill_status(struct iwl_mld *mld, struct sk_buff *skb, u8 stbc = u32_get_bits(rate_n_flags, RATE_MCS_STBC_MSK); bool is_sgi = rate_n_flags & RATE_MCS_SGI_MSK; - if (WARN_ON_ONCE(phy_data->with_data && (!mpdu_desc || !hdr))) - return; - - /* Keep packets with CRC errors (and with overrun) for monitor mode - * (otherwise the firmware discards them) but mark them as bad. - */ - if (phy_data->with_data && - (!(mpdu_desc->status & cpu_to_le32(IWL_RX_MPDU_STATUS_CRC_OK)) || - !(mpdu_desc->status & cpu_to_le32(IWL_RX_MPDU_STATUS_OVERRUN_OK)))) { - IWL_DEBUG_RX(mld, "Bad CRC or FIFO: 0x%08X.\n", - le32_to_cpu(mpdu_desc->status)); - rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; - } - phy_data->info_type = IWL_RX_PHY_INFO_TYPE_NONE; - if (phy_data->with_data && - likely(!(phy_data->phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD))) { - rx_status->mactime = - le64_to_cpu(mpdu_desc->v3.tsf_on_air_rise); - - /* TSF as indicated by the firmware is at INA time */ - rx_status->flag |= RX_FLAG_MACTIME_PLCP_START; - } else { + if (phy_data->phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) phy_data->info_type = le32_get_bits(phy_data->data1, IWL_RX_PHY_DATA1_INFO_TYPE_MASK); - } - - /* management stuff on default queue */ - if (!queue && phy_data->with_data && - unlikely(ieee80211_is_beacon(hdr->frame_control) || - ieee80211_is_probe_resp(hdr->frame_control))) { - rx_status->boottime_ns = ktime_get_boottime_ns(); - - if (mld->scan.pass_all_sched_res == SCHED_SCAN_PASS_ALL_STATE_ENABLED) - mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_FOUND; - } /* set the preamble flag if appropriate */ - if (format == RATE_MCS_CCK_MSK && + if (format == RATE_MCS_MOD_TYPE_CCK && phy_data->phy_info & IWL_RX_MPDU_PHY_SHORT_PREAMBLE) rx_status->enc_flags |= RX_ENC_FLAG_SHORTPRE; @@ -1237,7 +1203,7 @@ static void iwl_mld_rx_fill_status(struct iwl_mld *mld, struct sk_buff *skb, } /* must be before L-SIG data */ - if (format == RATE_MCS_HE_MSK) + if (format == RATE_MCS_MOD_TYPE_HE) iwl_mld_rx_he(mld, skb, phy_data, queue); iwl_mld_decode_lsig(skb, phy_data); @@ -1245,40 +1211,53 @@ static void iwl_mld_rx_fill_status(struct iwl_mld *mld, struct sk_buff *skb, rx_status->device_timestamp = phy_data->gp2_on_air_rise; /* using TLV format and must be after all fixed len fields */ - if (format == RATE_MCS_EHT_MSK) + if (format == RATE_MCS_MOD_TYPE_EHT) iwl_mld_rx_eht(mld, skb, phy_data, queue); #ifdef CONFIG_IWLWIFI_DEBUGFS - if (unlikely(mld->monitor.on)) + if (unlikely(mld->monitor.on)) { iwl_mld_add_rtap_sniffer_config(mld, skb); + + if (mld->monitor.ptp_time) { + u64 adj_time = + iwl_mld_ptp_get_adj_time(mld, + phy_data->gp2_on_air_rise * + NSEC_PER_USEC); + + rx_status->mactime = div64_u64(adj_time, NSEC_PER_USEC); + rx_status->flag |= RX_FLAG_MACTIME_IS_RTAP_TS64; + rx_status->flag &= ~RX_FLAG_MACTIME; + } + } #endif - if (format != RATE_MCS_CCK_MSK && is_sgi) + if (format != RATE_MCS_MOD_TYPE_CCK && is_sgi) rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; if (rate_n_flags & RATE_MCS_LDPC_MSK) rx_status->enc_flags |= RX_ENC_FLAG_LDPC; switch (format) { - case RATE_MCS_HT_MSK: + case RATE_MCS_MOD_TYPE_HT: rx_status->encoding = RX_ENC_HT; rx_status->rate_idx = RATE_HT_MCS_INDEX(rate_n_flags); rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; break; - case RATE_MCS_VHT_MSK: - case RATE_MCS_HE_MSK: - case RATE_MCS_EHT_MSK: - if (format == RATE_MCS_VHT_MSK) { + case RATE_MCS_MOD_TYPE_VHT: + case RATE_MCS_MOD_TYPE_HE: + case RATE_MCS_MOD_TYPE_EHT: + if (format == RATE_MCS_MOD_TYPE_VHT) { rx_status->encoding = RX_ENC_VHT; - } else if (format == RATE_MCS_HE_MSK) { + } else if (format == RATE_MCS_MOD_TYPE_HE) { rx_status->encoding = RX_ENC_HE; rx_status->he_dcm = !!(rate_n_flags & RATE_HE_DUAL_CARRIER_MODE_MSK); - } else if (format == RATE_MCS_EHT_MSK) { + } else if (format == RATE_MCS_MOD_TYPE_EHT) { rx_status->encoding = RX_ENC_EHT; } - rx_status->nss = u32_get_bits(rate_n_flags, RATE_MCS_NSS_MSK) + 1; + rx_status->nss = u32_get_bits(rate_n_flags, + RATE_MCS_NSS_MSK) + 1; rx_status->rate_idx = rate_n_flags & RATE_MCS_CODE_MSK; rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; break; @@ -1735,15 +1714,11 @@ static void iwl_mld_rx_update_ampdu_ref(struct iwl_mld *mld, } static void -iwl_mld_fill_rx_status_band_freq(struct iwl_mld_rx_phy_data *phy_data, - struct iwl_rx_mpdu_desc *mpdu_desc, - struct ieee80211_rx_status *rx_status) +iwl_mld_fill_rx_status_band_freq(struct ieee80211_rx_status *rx_status, + u8 band, u8 channel) { - enum nl80211_band band; - - band = BAND_IN_RX_STATUS(mpdu_desc->mac_phy_idx); rx_status->band = iwl_mld_phy_band_to_nl80211(band); - rx_status->freq = ieee80211_channel_to_frequency(phy_data->channel, + rx_status->freq = ieee80211_channel_to_frequency(channel, rx_status->band); } @@ -1758,7 +1733,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; + u8 crypto_len = 0, band; u32 pkt_len = iwl_rx_packet_payload_len(pkt); u32 mpdu_len; enum iwl_mld_reorder_result reorder_res; @@ -1788,7 +1763,7 @@ void iwl_mld_rx_mpdu(struct iwl_mld *mld, struct napi_struct *napi, hdr = (void *)(pkt->data + mpdu_desc_size); - iwl_mld_fill_phy_data(mpdu_desc, &phy_data); + iwl_mld_fill_phy_data(mld, mpdu_desc, &phy_data); if (mpdu_desc->mac_flags2 & IWL_RX_MPDU_MFLG2_PAD) { /* If the device inserted padding it means that (it thought) @@ -1802,7 +1777,11 @@ void iwl_mld_rx_mpdu(struct iwl_mld *mld, struct napi_struct *napi, rx_status = IEEE80211_SKB_RXCB(skb); /* this is needed early */ - iwl_mld_fill_rx_status_band_freq(&phy_data, mpdu_desc, rx_status); + band = u8_get_bits(mpdu_desc->mac_phy_band, + IWL_RX_MPDU_MAC_PHY_BAND_BAND_MASK); + iwl_mld_fill_rx_status_band_freq(rx_status, band, + mpdu_desc->v3.channel); + rcu_read_lock(); @@ -1814,7 +1793,36 @@ void iwl_mld_rx_mpdu(struct iwl_mld *mld, struct napi_struct *napi, if (!queue && (phy_data.phy_info & IWL_RX_MPDU_PHY_AMPDU)) iwl_mld_rx_update_ampdu_ref(mld, &phy_data, rx_status); - iwl_mld_rx_fill_status(mld, skb, &phy_data, mpdu_desc, hdr, queue); + /* Keep packets with CRC errors (and with overrun) for monitor mode + * (otherwise the firmware discards them) but mark them as bad. + */ + if (!(mpdu_desc->status & cpu_to_le32(IWL_RX_MPDU_STATUS_CRC_OK)) || + !(mpdu_desc->status & cpu_to_le32(IWL_RX_MPDU_STATUS_OVERRUN_OK))) { + IWL_DEBUG_RX(mld, "Bad CRC or FIFO: 0x%08X.\n", + le32_to_cpu(mpdu_desc->status)); + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + } + + if (likely(!(phy_data.phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD))) { + rx_status->mactime = + le64_to_cpu(mpdu_desc->v3.tsf_on_air_rise); + + /* TSF as indicated by the firmware is at INA time */ + rx_status->flag |= RX_FLAG_MACTIME_PLCP_START; + } + + /* management stuff on default queue */ + if (!queue && unlikely(ieee80211_is_beacon(hdr->frame_control) || + ieee80211_is_probe_resp(hdr->frame_control))) { + rx_status->boottime_ns = ktime_get_boottime_ns(); + + if (mld->scan.pass_all_sched_res == + SCHED_SCAN_PASS_ALL_STATE_ENABLED) + mld->scan.pass_all_sched_res = + SCHED_SCAN_PASS_ALL_STATE_FOUND; + } + + iwl_mld_rx_fill_status(mld, 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)) @@ -1857,7 +1865,7 @@ void iwl_mld_sync_rx_queues(struct iwl_mld *mld, enum iwl_mld_internal_rxq_notif_type type, const void *notif_payload, u32 notif_payload_size) { - u8 num_rx_queues = mld->trans->num_rx_queues; + u8 num_rx_queues = mld->trans->info.num_rxqs; struct { struct iwl_rxq_sync_cmd sync_cmd; struct iwl_mld_internal_rxq_notif notif; @@ -1956,6 +1964,7 @@ void iwl_mld_rx_monitor_no_data(struct iwl_mld *mld, struct napi_struct *napi, struct ieee80211_rx_status *rx_status; struct sk_buff *skb; u32 format, rssi; + u8 channel; if (unlikely(mld->fw_status.in_hw_restart)) return; @@ -1968,14 +1977,16 @@ void iwl_mld_rx_monitor_no_data(struct iwl_mld *mld, struct napi_struct *napi, desc = (void *)pkt->data; rssi = le32_to_cpu(desc->rssi); + channel = u32_get_bits(rssi, RX_NO_DATA_CHANNEL_MSK); + phy_data.energy_a = u32_get_bits(rssi, RX_NO_DATA_CHAIN_A_MSK); phy_data.energy_b = u32_get_bits(rssi, RX_NO_DATA_CHAIN_B_MSK); - phy_data.channel = u32_get_bits(rssi, RX_NO_DATA_CHANNEL_MSK); phy_data.data0 = desc->phy_info[0]; phy_data.data1 = desc->phy_info[1]; phy_data.phy_info = IWL_RX_MPDU_PHY_TSF_OVERLOAD; phy_data.gp2_on_air_rise = le32_to_cpu(desc->on_air_rise_time); - phy_data.rate_n_flags = le32_to_cpu(desc->rate); + phy_data.rate_n_flags = iwl_v3_rate_from_v2_v3(desc->rate, + mld->fw_rates_ver_3); phy_data.with_data = false; BUILD_BUG_ON(sizeof(phy_data.rx_vec) != sizeof(desc->rx_vec)); @@ -2018,13 +2029,13 @@ void iwl_mld_rx_monitor_no_data(struct iwl_mld *mld, struct napi_struct *napi, break; } - rx_status->band = phy_data.channel > 14 ? NL80211_BAND_5GHZ : + rx_status->band = channel > 14 ? NL80211_BAND_5GHZ : NL80211_BAND_2GHZ; - rx_status->freq = ieee80211_channel_to_frequency(phy_data.channel, + rx_status->freq = ieee80211_channel_to_frequency(channel, rx_status->band); - iwl_mld_rx_fill_status(mld, skb, &phy_data, NULL, NULL, queue); + iwl_mld_rx_fill_status(mld, 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 @@ -2037,17 +2048,17 @@ void iwl_mld_rx_monitor_no_data(struct iwl_mld *mld, struct napi_struct *napi, * may be up to 8 spatial streams. */ switch (format) { - case RATE_MCS_VHT_MSK: + case RATE_MCS_MOD_TYPE_VHT: rx_status->nss = le32_get_bits(desc->rx_vec[0], RX_NO_DATA_RX_VEC0_VHT_NSTS_MSK) + 1; break; - case RATE_MCS_HE_MSK: + case RATE_MCS_MOD_TYPE_HE: rx_status->nss = le32_get_bits(desc->rx_vec[0], RX_NO_DATA_RX_VEC0_HE_NSTS_MSK) + 1; break; - case RATE_MCS_EHT_MSK: + case RATE_MCS_MOD_TYPE_EHT: rx_status->nss = le32_get_bits(desc->rx_vec[2], RX_NO_DATA_RX_VEC2_EHT_NSTS_MSK) + 1; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/scan.c b/drivers/net/wireless/intel/iwlwifi/mld/scan.c index 7ec04318ec2f..3fce7cd2d512 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/scan.c @@ -1920,6 +1920,9 @@ void iwl_mld_handle_scan_complete_notif(struct iwl_mld *mld, IWL_DEBUG_SCAN(mld, "Scan link is no longer valid\n"); ieee80211_scan_completed(mld->hw, &info); + + /* Scan is over, we can check again the tpt counters */ + iwl_mld_stop_ignoring_tpt_updates(mld); } else if (mld->scan.uid_status[uid] == IWL_MLD_SCAN_SCHED) { ieee80211_sched_scan_stopped(mld->hw); mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_DISABLED; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/sta.c b/drivers/net/wireless/intel/iwlwifi/mld/sta.c index 332a7aecec2d..8fb51209b4a6 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/sta.c @@ -401,9 +401,11 @@ static u32 iwl_mld_get_htc_flags(struct ieee80211_link_sta *link_sta) static int iwl_mld_send_sta_cmd(struct iwl_mld *mld, const struct iwl_sta_cfg_cmd *cmd) { - int ret = iwl_mld_send_cmd_pdu(mld, - WIDE_ID(MAC_CONF_GROUP, STA_CONFIG_CMD), - cmd); + u32 cmd_id = WIDE_ID(MAC_CONF_GROUP, STA_CONFIG_CMD); + int cmd_len = iwl_fw_lookup_cmd_ver(mld->fw, cmd_id, 0) > 1 ? + sizeof(*cmd) : + sizeof(struct iwl_sta_cfg_cmd_v1); + int ret = iwl_mld_send_cmd_pdu(mld, cmd_id, cmd, cmd_len); if (ret) IWL_ERR(mld, "STA_CONFIG_CMD send failed, ret=0x%x\n", ret); return ret; @@ -660,7 +662,7 @@ iwl_mld_alloc_dup_data(struct iwl_mld *mld, struct iwl_mld_sta *mld_sta) if (mld->fw_status.in_hw_restart) return 0; - dup_data = kcalloc(mld->trans->num_rx_queues, sizeof(*dup_data), + dup_data = kcalloc(mld->trans->info.num_rxqs, sizeof(*dup_data), GFP_KERNEL); if (!dup_data) return -ENOMEM; @@ -673,7 +675,7 @@ iwl_mld_alloc_dup_data(struct iwl_mld *mld, struct iwl_mld_sta *mld_sta) * This thus allows receiving a packet with seqno 0 and the * retry bit set as the very first packet on a new TID. */ - for (int q = 0; q < mld->trans->num_rx_queues; q++) + for (int q = 0; q < mld->trans->info.num_rxqs; q++) memset(dup_data[q].last_seq, 0xff, sizeof(dup_data[q].last_seq)); mld_sta->dup_data = dup_data; @@ -695,13 +697,13 @@ static void iwl_mld_alloc_mpdu_counters(struct iwl_mld *mld, sta->tdls || !ieee80211_vif_is_mld(vif)) return; - mld_sta->mpdu_counters = kcalloc(mld->trans->num_rx_queues, + mld_sta->mpdu_counters = kcalloc(mld->trans->info.num_rxqs, sizeof(*mld_sta->mpdu_counters), GFP_KERNEL); if (!mld_sta->mpdu_counters) return; - for (int q = 0; q < mld->trans->num_rx_queues; q++) + for (int q = 0; q < mld->trans->info.num_rxqs; q++) spin_lock_init(&mld_sta->mpdu_counters[q].lock); } @@ -947,7 +949,7 @@ static int iwl_mld_allocate_internal_txq(struct iwl_mld *mld, int queue, size; size = max_t(u32, IWL_MGMT_QUEUE_SIZE, - mld->trans->cfg->min_txq_size); + mld->trans->mac_cfg->base->min_txq_size); queue = iwl_trans_txq_alloc(mld->trans, 0, sta_mask, tid, size, IWL_WATCHDOG_DISABLED); @@ -1087,6 +1089,24 @@ int iwl_mld_add_aux_sta(struct iwl_mld *mld, 0, NULL, IWL_MAX_TID_COUNT); } +int iwl_mld_add_mon_sta(struct iwl_mld *mld, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link) +{ + struct iwl_mld_link *mld_link = iwl_mld_link_from_mac80211(link); + + if (WARN_ON(!mld_link)) + return -EINVAL; + + if (WARN_ON(vif->type != NL80211_IFTYPE_MONITOR)) + return -EINVAL; + + return iwl_mld_add_internal_sta(mld, &mld_link->mon_sta, + STATION_TYPE_BCAST_MGMT, + mld_link->fw_id, NULL, + IWL_MAX_TID_COUNT); +} + static void iwl_mld_remove_internal_sta(struct iwl_mld *mld, struct iwl_mld_int_sta *internal_sta, bool flush, u8 tid) @@ -1140,6 +1160,19 @@ void iwl_mld_remove_mcast_sta(struct iwl_mld *mld, } void iwl_mld_remove_aux_sta(struct iwl_mld *mld, + struct ieee80211_vif *vif) +{ + struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); + + if (WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE && + vif->type != NL80211_IFTYPE_STATION)) + return; + + iwl_mld_remove_internal_sta(mld, &mld_vif->aux_sta, false, + IWL_MAX_TID_COUNT); +} + +void iwl_mld_remove_mon_sta(struct iwl_mld *mld, struct ieee80211_vif *vif, struct ieee80211_bss_conf *link) { @@ -1148,11 +1181,10 @@ void iwl_mld_remove_aux_sta(struct iwl_mld *mld, if (WARN_ON(!mld_link)) return; - /* TODO: Hotspot 2.0 */ - if (WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE)) + if (WARN_ON(vif->type != NL80211_IFTYPE_MONITOR)) return; - iwl_mld_remove_internal_sta(mld, &mld_link->aux_sta, false, + iwl_mld_remove_internal_sta(mld, &mld_link->mon_sta, false, IWL_MAX_TID_COUNT); } diff --git a/drivers/net/wireless/intel/iwlwifi/mld/sta.h b/drivers/net/wireless/intel/iwlwifi/mld/sta.h index ddcffd7b9fde..1897b121aae2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/sta.h +++ b/drivers/net/wireless/intel/iwlwifi/mld/sta.h @@ -247,6 +247,10 @@ int iwl_mld_add_mcast_sta(struct iwl_mld *mld, int iwl_mld_add_aux_sta(struct iwl_mld *mld, struct iwl_mld_int_sta *internal_sta); +int iwl_mld_add_mon_sta(struct iwl_mld *mld, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link); + void iwl_mld_remove_bcast_sta(struct iwl_mld *mld, struct ieee80211_vif *vif, struct ieee80211_bss_conf *link); @@ -256,6 +260,9 @@ void iwl_mld_remove_mcast_sta(struct iwl_mld *mld, struct ieee80211_bss_conf *link); void iwl_mld_remove_aux_sta(struct iwl_mld *mld, + struct ieee80211_vif *vif); + +void iwl_mld_remove_mon_sta(struct iwl_mld *mld, struct ieee80211_vif *vif, struct ieee80211_bss_conf *link); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/stats.c b/drivers/net/wireless/intel/iwlwifi/mld/stats.c index 0715bbc31031..f633cb1cf510 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/stats.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/stats.c @@ -191,11 +191,12 @@ static void iwl_mld_sta_stats_fill_txrate(struct iwl_mld_sta *mld_sta, break; } - if (format == RATE_MCS_CCK_MSK || format == RATE_MCS_LEGACY_OFDM_MSK) { + if (format == RATE_MCS_MOD_TYPE_CCK || + format == RATE_MCS_MOD_TYPE_LEGACY_OFDM) { int rate = u32_get_bits(rate_n_flags, RATE_LEGACY_RATE_MSK); /* add the offset needed to get to the legacy ofdm indices */ - if (format == RATE_MCS_LEGACY_OFDM_MSK) + if (format == RATE_MCS_MOD_TYPE_LEGACY_OFDM) rate += IWL_FIRST_OFDM_RATE; switch (rate) { @@ -240,7 +241,7 @@ static void iwl_mld_sta_stats_fill_txrate(struct iwl_mld_sta *mld_sta, rinfo->nss = u32_get_bits(rate_n_flags, RATE_MCS_NSS_MSK) + 1; - if (format == RATE_MCS_HT_MSK) + if (format == RATE_MCS_MOD_TYPE_HT) rinfo->mcs = RATE_HT_MCS_INDEX(rate_n_flags); else rinfo->mcs = u32_get_bits(rate_n_flags, RATE_MCS_CODE_MSK); @@ -249,10 +250,10 @@ static void iwl_mld_sta_stats_fill_txrate(struct iwl_mld_sta *mld_sta, rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; switch (format) { - case RATE_MCS_EHT_MSK: + case RATE_MCS_MOD_TYPE_EHT: rinfo->flags |= RATE_INFO_FLAGS_EHT_MCS; break; - case RATE_MCS_HE_MSK: + case RATE_MCS_MOD_TYPE_HE: gi_ltf = u32_get_bits(rate_n_flags, RATE_MCS_HE_GI_LTF_MSK); rinfo->flags |= RATE_INFO_FLAGS_HE_MCS; @@ -293,10 +294,10 @@ static void iwl_mld_sta_stats_fill_txrate(struct iwl_mld_sta *mld_sta, if (rate_n_flags & RATE_HE_DUAL_CARRIER_MODE_MSK) rinfo->he_dcm = 1; break; - case RATE_MCS_HT_MSK: + case RATE_MCS_MOD_TYPE_HT: rinfo->flags |= RATE_INFO_FLAGS_MCS; break; - case RATE_MCS_VHT_MSK: + case RATE_MCS_MOD_TYPE_VHT: rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS; break; } @@ -467,12 +468,18 @@ static void iwl_mld_fill_chanctx_stats(struct ieee80211_hw *hw, old_load = phy->avg_channel_load_not_by_us; new_load = le32_to_cpu(per_phy[phy->fw_id].channel_load_not_by_us); - if (IWL_FW_CHECK(phy->mld, new_load > 100, "Invalid channel load %u\n", - new_load)) + + if (IWL_FW_CHECK(phy->mld, + new_load != IWL_STATS_UNKNOWN_CHANNEL_LOAD && + new_load > 100, + "Invalid channel load %u\n", new_load)) return; - /* give a weight of 0.5 for the old value */ - phy->avg_channel_load_not_by_us = (new_load >> 1) + (old_load >> 1); + if (new_load != IWL_STATS_UNKNOWN_CHANNEL_LOAD) { + /* update giving a weight of 0.5 for the old value */ + phy->avg_channel_load_not_by_us = (new_load >> 1) + + (old_load >> 1); + } iwl_mld_emlsr_check_chan_load(hw, phy, old_load); } diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tests/Makefile b/drivers/net/wireless/intel/iwlwifi/mld/tests/Makefile index 36317feb923b..3e2ae6020613 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/tests/Makefile +++ b/drivers/net/wireless/intel/iwlwifi/mld/tests/Makefile @@ -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 +iwlmld-tests-y += module.o hcmd.o utils.o link.o rx.o agg.o link-selection.o emlsr_with_bt.o ccflags-y += -I$(src)/../ obj-$(CONFIG_IWLWIFI_KUNIT_TESTS) += iwlmld-tests.o diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tests/agg.c b/drivers/net/wireless/intel/iwlwifi/mld/tests/agg.c index 1fd664be1a7c..29b0248cec3d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/tests/agg.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/tests/agg.c @@ -2,7 +2,7 @@ /* * KUnit tests for channel helper functions * - * Copyright (C) 2024 Intel Corporation + * Copyright (C) 2024-2025 Intel Corporation */ #include <kunit/test.h> #include <kunit/static_stub.h> @@ -474,14 +474,14 @@ static struct iwl_rx_mpdu_desc *setup_mpdu_desc(void) KUNIT_ALLOC_AND_ASSERT(test, mpdu_desc); mpdu_desc->reorder_data |= - cpu_to_le32(FIELD_PREP(IWL_RX_MPDU_REORDER_BAID_MASK, - param->rx_pkt.baid)); + le32_encode_bits(param->rx_pkt.baid, + IWL_RX_MPDU_REORDER_BAID_MASK); mpdu_desc->reorder_data |= - cpu_to_le32(FIELD_PREP(IWL_RX_MPDU_REORDER_SN_MASK, - param->rx_pkt.sn)); + le32_encode_bits(param->rx_pkt.sn, + IWL_RX_MPDU_REORDER_SN_MASK); mpdu_desc->reorder_data |= - cpu_to_le32(FIELD_PREP(IWL_RX_MPDU_REORDER_NSSN_MASK, - param->rx_pkt.nssn)); + le32_encode_bits(param->rx_pkt.nssn, + IWL_RX_MPDU_REORDER_NSSN_MASK); if (param->rx_pkt.old_sn) mpdu_desc->reorder_data |= cpu_to_le32(IWL_RX_MPDU_REORDER_BA_OLD_SN); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tests/emlsr_with_bt.c b/drivers/net/wireless/intel/iwlwifi/mld/tests/emlsr_with_bt.c new file mode 100644 index 000000000000..91556ee5c142 --- /dev/null +++ b/drivers/net/wireless/intel/iwlwifi/mld/tests/emlsr_with_bt.c @@ -0,0 +1,140 @@ +// 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); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tests/hcmd.c b/drivers/net/wireless/intel/iwlwifi/mld/tests/hcmd.c index 4e189bf8b3fb..0e3b9417dd63 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/tests/hcmd.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/tests/hcmd.c @@ -2,7 +2,7 @@ /* * KUnit tests for channel helper functions * - * Copyright (C) 2024 Intel Corporation + * Copyright (C) 2024-2025 Intel Corporation */ #include <kunit/test.h> @@ -30,10 +30,10 @@ static void test_hcmd_names_sorted(struct kunit *test) static void test_hcmd_names_for_rx(struct kunit *test) { static struct iwl_trans t = { - .command_groups = iwl_mld_groups, + .conf.command_groups = iwl_mld_groups, }; - t.command_groups_size = global_iwl_mld_goups_size; + t.conf.command_groups_size = global_iwl_mld_goups_size; for (unsigned int i = 0; i < iwl_mld_rx_handlers_num; i++) { const struct iwl_rx_handler *rxh; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tests/link-selection.c b/drivers/net/wireless/intel/iwlwifi/mld/tests/link-selection.c index 295dcfd3f85d..94a037bec1fa 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/tests/link-selection.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/tests/link-selection.c @@ -32,7 +32,7 @@ static const struct link_grading_test_case { .desc = "channel util of 128 (50%)", .input.link = { .link_id = 0, - .chandef = &chandef_2ghz, + .chandef = &chandef_2ghz_20mhz, .active = false, .has_chan_util_elem = true, .chan_util = 128, @@ -43,7 +43,7 @@ static const struct link_grading_test_case { .desc = "channel util of 180 (70%)", .input.link = { .link_id = 0, - .chandef = &chandef_2ghz, + .chandef = &chandef_2ghz_20mhz, .active = false, .has_chan_util_elem = true, .chan_util = 180, @@ -54,7 +54,7 @@ static const struct link_grading_test_case { .desc = "channel util of 180 (70%), channel load by us of 10%", .input.link = { .link_id = 0, - .chandef = &chandef_2ghz, + .chandef = &chandef_2ghz_20mhz, .has_chan_util_elem = true, .chan_util = 180, .active = true, @@ -66,7 +66,7 @@ static const struct link_grading_test_case { .desc = "no channel util element", .input.link = { .link_id = 0, - .chandef = &chandef_2ghz, + .chandef = &chandef_2ghz_20mhz, .active = true, }, .expected_grade = 120, @@ -132,7 +132,7 @@ static void test_link_grading(struct kunit *test) bool active = test_param->input.link.active; u16 valid_links; struct iwl_mld_kunit_link assoc_link = { - .band = test_param->input.link.chandef->chan->band, + .chandef = test_param->input.link.chandef, }; /* If the link is not active, use a different link as the assoc link */ @@ -172,108 +172,150 @@ static struct kunit_suite link_selection = { kunit_test_suite(link_selection); -static const struct channel_load_case { +static const struct link_pair_case { const char *desc; + const struct cfg80211_chan_def *chandef_a, *chandef_b; bool low_latency_vif; u32 chan_load_not_by_us; - enum nl80211_chan_width bw_a; - enum nl80211_chan_width bw_b; bool primary_link_active; - bool expected_result; -} channel_load_cases[] = { + u32 expected_result; +} link_pair_cases[] = { { .desc = "Unequal bandwidth, primary link inactive, EMLSR not allowed", .low_latency_vif = false, .primary_link_active = false, - .bw_a = NL80211_CHAN_WIDTH_40, - .bw_b = NL80211_CHAN_WIDTH_20, - .expected_result = false, + .chandef_a = &chandef_5ghz_40mhz, + .chandef_b = &chandef_6ghz_20mhz, + .expected_result = IWL_MLD_EMLSR_EXIT_CHAN_LOAD, }, { .desc = "Equal bandwidths, sufficient channel load, EMLSR allowed", .low_latency_vif = false, .primary_link_active = true, .chan_load_not_by_us = 11, - .bw_a = NL80211_CHAN_WIDTH_40, - .bw_b = NL80211_CHAN_WIDTH_40, - .expected_result = true, + .chandef_a = &chandef_5ghz_40mhz, + .chandef_b = &chandef_6ghz_40mhz, + .expected_result = 0, }, { .desc = "Equal bandwidths, insufficient channel load, EMLSR not allowed", .low_latency_vif = false, .primary_link_active = true, .chan_load_not_by_us = 6, - .bw_a = NL80211_CHAN_WIDTH_80, - .bw_b = NL80211_CHAN_WIDTH_80, - .expected_result = false, + .chandef_a = &chandef_5ghz_80mhz, + .chandef_b = &chandef_6ghz_80mhz, + .expected_result = IWL_MLD_EMLSR_EXIT_CHAN_LOAD, }, { .desc = "Low latency VIF, sufficient channel load, EMLSR allowed", .low_latency_vif = true, .primary_link_active = true, .chan_load_not_by_us = 6, - .bw_a = NL80211_CHAN_WIDTH_160, - .bw_b = NL80211_CHAN_WIDTH_160, - .expected_result = true, + .chandef_a = &chandef_5ghz_160mhz, + .chandef_b = &chandef_6ghz_160mhz, + .expected_result = 0, }, { .desc = "Different bandwidths (2x ratio), primary link load permits EMLSR", .low_latency_vif = false, .primary_link_active = true, .chan_load_not_by_us = 30, - .bw_a = NL80211_CHAN_WIDTH_40, - .bw_b = NL80211_CHAN_WIDTH_20, - .expected_result = true, + .chandef_a = &chandef_5ghz_40mhz, + .chandef_b = &chandef_6ghz_20mhz, + .expected_result = 0, }, { .desc = "Different bandwidths (4x ratio), primary link load permits EMLSR", .low_latency_vif = false, .primary_link_active = true, .chan_load_not_by_us = 45, - .bw_a = NL80211_CHAN_WIDTH_80, - .bw_b = NL80211_CHAN_WIDTH_20, - .expected_result = true, + .chandef_a = &chandef_5ghz_80mhz, + .chandef_b = &chandef_6ghz_20mhz, + .expected_result = 0, }, { .desc = "Different bandwidths (16x ratio), primary link load insufficient", .low_latency_vif = false, .primary_link_active = true, .chan_load_not_by_us = 45, - .bw_a = NL80211_CHAN_WIDTH_320, - .bw_b = NL80211_CHAN_WIDTH_20, - .expected_result = false, + .chandef_a = &chandef_6ghz_320mhz, + .chandef_b = &chandef_5ghz_20mhz, + .expected_result = IWL_MLD_EMLSR_EXIT_CHAN_LOAD, + }, + { + .desc = "Same band not allowed (2.4 GHz)", + .low_latency_vif = false, + .primary_link_active = true, + .chan_load_not_by_us = 30, + .chandef_a = &chandef_2ghz_20mhz, + .chandef_b = &chandef_2ghz_11_20mhz, + .expected_result = IWL_MLD_EMLSR_EXIT_EQUAL_BAND, + }, + { + .desc = "Same band not allowed (5 GHz)", + .low_latency_vif = false, + .primary_link_active = true, + .chan_load_not_by_us = 30, + .chandef_a = &chandef_5ghz_40mhz, + .chandef_b = &chandef_5ghz_40mhz, + .expected_result = IWL_MLD_EMLSR_EXIT_EQUAL_BAND, + }, + { + .desc = "Same band allowed (5 GHz separated)", + .low_latency_vif = false, + .primary_link_active = true, + .chan_load_not_by_us = 30, + .chandef_a = &chandef_5ghz_40mhz, + .chandef_b = &chandef_5ghz_120_40mhz, + .expected_result = 0, + }, + { + .desc = "Same band not allowed (6 GHz)", + .low_latency_vif = false, + .primary_link_active = true, + .chan_load_not_by_us = 30, + .chandef_a = &chandef_6ghz_160mhz, + .chandef_b = &chandef_6ghz_221_160mhz, + .expected_result = IWL_MLD_EMLSR_EXIT_EQUAL_BAND, }, }; -KUNIT_ARRAY_PARAM_DESC(channel_load, channel_load_cases, desc); +KUNIT_ARRAY_PARAM_DESC(link_pair, link_pair_cases, desc); -static void test_iwl_mld_channel_load_allows_emlsr(struct kunit *test) +static void test_iwl_mld_link_pair_allows_emlsr(struct kunit *test) { - const struct channel_load_case *params = test->param_value; + const struct link_pair_case *params = test->param_value; struct iwl_mld *mld = test->priv; struct ieee80211_vif *vif; - struct cfg80211_chan_def chandef_a, chandef_b; - struct iwl_mld_link_sel_data a = {.chandef = &chandef_a, - .link_id = 4}; - struct iwl_mld_link_sel_data b = {.chandef = &chandef_b, - .link_id = 5}; + 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, + .link_id = 4, + }; + struct iwl_mld_link_sel_data b = { + .chandef = params->chandef_b, + .link_id = 5, + }; struct iwl_mld_kunit_link assoc_link = { + .chandef = params->primary_link_active ? a.chandef : b.chandef, .id = params->primary_link_active ? a.link_id : b.link_id, - .bandwidth = params->primary_link_active ? params->bw_a : params->bw_b, }; - bool result; + u32 result; vif = iwlmld_kunit_setup_mlo_assoc(BIT(a.link_id) | BIT(b.link_id), &assoc_link); - chandef_a.width = params->bw_a; - chandef_b.width = params->bw_b; - if (params->low_latency_vif) iwl_mld_vif_from_mac80211(vif)->low_latency_causes = 1; 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 = @@ -282,22 +324,22 @@ static void test_iwl_mld_channel_load_allows_emlsr(struct kunit *test) phy->avg_channel_load_not_by_us = params->chan_load_not_by_us; } - result = iwl_mld_channel_load_allows_emlsr(mld, vif, &a, &b); + result = iwl_mld_emlsr_pair_state(vif, &a, &b); wiphy_unlock(mld->wiphy); KUNIT_EXPECT_EQ(test, result, params->expected_result); } -static struct kunit_case channel_load_criteria_test_cases[] = { - KUNIT_CASE_PARAM(test_iwl_mld_channel_load_allows_emlsr, channel_load_gen_params), +static struct kunit_case link_pair_criteria_test_cases[] = { + KUNIT_CASE_PARAM(test_iwl_mld_link_pair_allows_emlsr, link_pair_gen_params), {} }; -static struct kunit_suite channel_load_criteria_tests = { - .name = "iwlmld_channel_load_allows_emlsr", - .test_cases = channel_load_criteria_test_cases, +static struct kunit_suite link_pair_criteria_tests = { + .name = "iwlmld_link_pair_allows_emlsr", + .test_cases = link_pair_criteria_test_cases, .init = iwlmld_kunit_test_init, }; -kunit_test_suite(channel_load_criteria_tests); +kunit_test_suite(link_pair_criteria_tests); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tests/link.c b/drivers/net/wireless/intel/iwlwifi/mld/tests/link.c index 4a4eaa134bd3..69a0d67858bf 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/tests/link.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/tests/link.c @@ -63,11 +63,11 @@ static void test_missed_beacon(struct kunit *test) struct iwl_rx_packet *pkt; struct iwl_mld_kunit_link link1 = { .id = 0, - .band = NL80211_BAND_6GHZ, + .chandef = &chandef_6ghz_160mhz, }; struct iwl_mld_kunit_link link2 = { .id = 1, - .band = NL80211_BAND_5GHZ, + .chandef = &chandef_5ghz_80mhz, }; kunit_activate_static_stub(test, ieee80211_connection_loss, diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tests/utils.c b/drivers/net/wireless/intel/iwlwifi/mld/tests/utils.c index 9712ee696509..26cf27be762d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/tests/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/tests/utils.c @@ -24,7 +24,7 @@ int iwlmld_kunit_test_init(struct kunit *test) { struct iwl_mld *mld; struct iwl_trans *trans; - const struct iwl_cfg *cfg; + const struct iwl_rf_cfg *cfg; struct iwl_fw *fw; struct ieee80211_hw *hw; @@ -146,7 +146,7 @@ iwlmld_kunit_add_link(struct ieee80211_vif *vif, int link_id) } struct ieee80211_chanctx_conf * -iwlmld_kunit_add_chanctx_from_def(struct cfg80211_chan_def *def) +iwlmld_kunit_add_chanctx(const struct cfg80211_chan_def *def) { struct kunit *test = kunit_get_current_test(); struct iwl_mld *mld = test->priv; @@ -346,8 +346,7 @@ iwlmld_kunit_setup_assoc(bool mlo, struct iwl_mld_kunit_link *assoc_link) else link = &vif->bss_conf; - chan_ctx = iwlmld_kunit_add_chanctx(assoc_link->band, - assoc_link->bandwidth); + chan_ctx = iwlmld_kunit_add_chanctx(assoc_link->chandef); wiphy_lock(mld->wiphy); iwlmld_kunit_assign_chanctx_to_link(vif, link, chan_ctx); @@ -428,7 +427,7 @@ struct ieee80211_vif *iwlmld_kunit_assoc_emlsr(struct iwl_mld_kunit_link *link1, link = wiphy_dereference(mld->wiphy, vif->link_conf[link2->id]); KUNIT_EXPECT_NOT_NULL(test, link); - chan_ctx = iwlmld_kunit_add_chanctx(link2->band, link2->bandwidth); + chan_ctx = iwlmld_kunit_add_chanctx(link2->chandef); iwlmld_kunit_assign_chanctx_to_link(vif, link, chan_ctx); wiphy_unlock(mld->wiphy); @@ -472,3 +471,33 @@ struct iwl_mld_phy *iwlmld_kunit_get_phy_of_link(struct ieee80211_vif *vif, return iwl_mld_phy_from_mac80211(chanctx); } + +static const struct chandef_case { + const char *desc; + const struct cfg80211_chan_def *chandef; +} chandef_cases[] = { +#define CHANDEF(c, ...) { .desc = "chandef " #c " valid", .chandef = &c, }, + CHANDEF_LIST +#undef CHANDEF +}; + +KUNIT_ARRAY_PARAM_DESC(chandef, chandef_cases, desc); + +static void test_iwl_mld_chandef_valid(struct kunit *test) +{ + const struct chandef_case *params = test->param_value; + + KUNIT_EXPECT_EQ(test, true, cfg80211_chandef_valid(params->chandef)); +} + +static struct kunit_case chandef_test_cases[] = { + KUNIT_CASE_PARAM(test_iwl_mld_chandef_valid, chandef_gen_params), + {} +}; + +static struct kunit_suite chandef_tests = { + .name = "iwlmld_valid_test_chandefs", + .test_cases = chandef_test_cases, +}; + +kunit_test_suite(chandef_tests); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tests/utils.h b/drivers/net/wireless/intel/iwlwifi/mld/tests/utils.h index d3723653cf1b..edf8eef4e81a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/tests/utils.h +++ b/drivers/net/wireless/intel/iwlwifi/mld/tests/utils.h @@ -14,9 +14,8 @@ struct iwl_mld; int iwlmld_kunit_test_init(struct kunit *test); struct iwl_mld_kunit_link { + const struct cfg80211_chan_def *chandef; u8 id; - enum nl80211_band band; - enum nl80211_chan_width bandwidth; }; enum nl80211_iftype; @@ -42,50 +41,57 @@ static struct ieee80211_channel _name = { \ .hw_value = (_freq), \ } -#define CHANDEF(_name, _channel, _freq1, _width) \ -__maybe_unused static struct cfg80211_chan_def _name = { \ - .chan = &(_channel), \ - .center_freq1 = (_freq1), \ - .width = (_width), \ -} - CHANNEL(chan_2ghz, NL80211_BAND_2GHZ, 2412); +CHANNEL(chan_2ghz_11, NL80211_BAND_2GHZ, 2462); CHANNEL(chan_5ghz, NL80211_BAND_5GHZ, 5200); +CHANNEL(chan_5ghz_120, NL80211_BAND_5GHZ, 5600); CHANNEL(chan_6ghz, NL80211_BAND_6GHZ, 6115); +CHANNEL(chan_6ghz_221, NL80211_BAND_6GHZ, 7055); /* Feel free to add more */ +#undef CHANNEL + +#define CHANDEF_LIST \ + CHANDEF(chandef_2ghz_20mhz, chan_2ghz, 2412, \ + NL80211_CHAN_WIDTH_20) \ + CHANDEF(chandef_2ghz_40mhz, chan_2ghz, 2422, \ + NL80211_CHAN_WIDTH_40) \ + CHANDEF(chandef_2ghz_11_20mhz, chan_2ghz_11, 2462, \ + NL80211_CHAN_WIDTH_20) \ + CHANDEF(chandef_5ghz_20mhz, chan_5ghz, 5200, \ + NL80211_CHAN_WIDTH_20) \ + CHANDEF(chandef_5ghz_40mhz, chan_5ghz, 5210, \ + NL80211_CHAN_WIDTH_40) \ + CHANDEF(chandef_5ghz_80mhz, chan_5ghz, 5210, \ + NL80211_CHAN_WIDTH_80) \ + CHANDEF(chandef_5ghz_160mhz, chan_5ghz, 5250, \ + NL80211_CHAN_WIDTH_160) \ + CHANDEF(chandef_5ghz_120_40mhz, chan_5ghz_120, 5610, \ + NL80211_CHAN_WIDTH_40) \ + CHANDEF(chandef_6ghz_20mhz, chan_6ghz, 6115, \ + NL80211_CHAN_WIDTH_20) \ + CHANDEF(chandef_6ghz_40mhz, chan_6ghz, 6125, \ + NL80211_CHAN_WIDTH_40) \ + CHANDEF(chandef_6ghz_80mhz, chan_6ghz, 6145, \ + NL80211_CHAN_WIDTH_80) \ + CHANDEF(chandef_6ghz_160mhz, chan_6ghz, 6185, \ + NL80211_CHAN_WIDTH_160) \ + CHANDEF(chandef_6ghz_320mhz, chan_6ghz, 6105, \ + NL80211_CHAN_WIDTH_320) \ + CHANDEF(chandef_6ghz_221_160mhz, chan_6ghz_221, 6985, \ + NL80211_CHAN_WIDTH_160) \ + /* Feel free to add more */ -CHANDEF(chandef_2ghz, chan_2ghz, 2412, NL80211_CHAN_WIDTH_20); -CHANDEF(chandef_5ghz, chan_5ghz, 5200, NL80211_CHAN_WIDTH_40); -CHANDEF(chandef_6ghz, chan_6ghz, 6115, NL80211_CHAN_WIDTH_160); -/* Feel free to add more */ - -//struct cfg80211_chan_def; +#define CHANDEF(_name, _channel, _freq1, _width) \ +__maybe_unused static const struct cfg80211_chan_def _name = { \ + .chan = &(_channel), \ + .center_freq1 = (_freq1), \ + .width = (_width), \ +}; +CHANDEF_LIST +#undef CHANDEF struct ieee80211_chanctx_conf * -iwlmld_kunit_add_chanctx_from_def(struct cfg80211_chan_def *def); - -static inline struct ieee80211_chanctx_conf * -iwlmld_kunit_add_chanctx(enum nl80211_band band, enum nl80211_chan_width width) -{ - struct cfg80211_chan_def chandef; - - switch (band) { - case NL80211_BAND_2GHZ: - chandef = chandef_2ghz; - break; - case NL80211_BAND_5GHZ: - chandef = chandef_5ghz; - break; - default: - case NL80211_BAND_6GHZ: - chandef = chandef_6ghz; - break; - } - - chandef.width = width; - - return iwlmld_kunit_add_chanctx_from_def(&chandef); -} +iwlmld_kunit_add_chanctx(const struct cfg80211_chan_def *def); void iwlmld_kunit_assign_chanctx_to_link(struct ieee80211_vif *vif, struct ieee80211_bss_conf *link, diff --git a/drivers/net/wireless/intel/iwlwifi/mld/thermal.c b/drivers/net/wireless/intel/iwlwifi/mld/thermal.c index 1909953a9be9..f8a8c35066be 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/thermal.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/thermal.c @@ -13,6 +13,9 @@ #include "mld.h" #include "hcmd.h" +#define IWL_MLD_NUM_CTDP_STEPS 20 +#define IWL_MLD_MIN_CTDP_BUDGET_MW 150 + #define IWL_MLD_CT_KILL_DURATION (5 * HZ) void iwl_mld_handle_ct_kill_notif(struct iwl_mld *mld, @@ -116,8 +119,8 @@ free_resp: static int compare_temps(const void *a, const void *b) { - return ((s16)le16_to_cpu(*(__le16 *)a) - - (s16)le16_to_cpu(*(__le16 *)b)); + return ((s16)le16_to_cpu(*(const __le16 *)a) - + (s16)le16_to_cpu(*(const __le16 *)b)); } struct iwl_trip_walk_data { @@ -272,43 +275,27 @@ static void iwl_mld_thermal_zone_register(struct iwl_mld *mld) } } -/* budget in mWatt */ -static const u32 iwl_mld_cdev_budgets[] = { - 2400, /* cooling state 0 */ - 2000, /* cooling state 1 */ - 1800, /* cooling state 2 */ - 1600, /* cooling state 3 */ - 1400, /* cooling state 4 */ - 1200, /* cooling state 5 */ - 1000, /* cooling state 6 */ - 900, /* cooling state 7 */ - 800, /* cooling state 8 */ - 700, /* cooling state 9 */ - 650, /* cooling state 10 */ - 600, /* cooling state 11 */ - 550, /* cooling state 12 */ - 500, /* cooling state 13 */ - 450, /* cooling state 14 */ - 400, /* cooling state 15 */ - 350, /* cooling state 16 */ - 300, /* cooling state 17 */ - 250, /* cooling state 18 */ - 200, /* cooling state 19 */ - 150, /* cooling state 20 */ -}; - int iwl_mld_config_ctdp(struct iwl_mld *mld, u32 state, enum iwl_ctdp_cmd_operation op) { struct iwl_ctdp_cmd cmd = { .operation = cpu_to_le32(op), - .budget = cpu_to_le32(iwl_mld_cdev_budgets[state]), .window_size = 0, }; + u32 budget; int ret; lockdep_assert_wiphy(mld->wiphy); + /* Do a linear scale from IWL_MLD_MIN_CTDP_BUDGET_MW to the configured + * maximum in the predefined number of steps. + */ + budget = ((mld->power_budget_mw - IWL_MLD_MIN_CTDP_BUDGET_MW) * + (IWL_MLD_NUM_CTDP_STEPS - 1 - state)) / + (IWL_MLD_NUM_CTDP_STEPS - 1) + + IWL_MLD_MIN_CTDP_BUDGET_MW; + cmd.budget = cpu_to_le32(budget); + ret = iwl_mld_send_cmd_pdu(mld, WIDE_ID(PHY_OPS_GROUP, CTDP_CONFIG_CMD), &cmd); @@ -326,7 +313,7 @@ int iwl_mld_config_ctdp(struct iwl_mld *mld, u32 state, static int iwl_mld_tcool_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state) { - *state = ARRAY_SIZE(iwl_mld_cdev_budgets) - 1; + *state = IWL_MLD_NUM_CTDP_STEPS - 1; return 0; } @@ -354,7 +341,7 @@ static int iwl_mld_tcool_set_cur_state(struct thermal_cooling_device *cdev, goto unlock; } - if (new_state >= ARRAY_SIZE(iwl_mld_cdev_budgets)) { + if (new_state >= IWL_MLD_NUM_CTDP_STEPS) { ret = -EINVAL; goto unlock; } @@ -417,10 +404,50 @@ static void iwl_mld_cooling_device_unregister(struct iwl_mld *mld) } #endif /* CONFIG_THERMAL */ +static u32 iwl_mld_ctdp_get_max_budget(struct iwl_mld *mld) +{ + u64 bios_power_budget = 0; + u32 default_power_budget; + + switch (CSR_HW_RFID_TYPE(mld->trans->info.hw_rf_id)) { + case IWL_CFG_RF_TYPE_GF: + /* dual-radio devices have a higher budget */ + if (CSR_HW_RFID_IS_CDB(mld->trans->info.hw_rf_id)) + default_power_budget = 5200; + else + default_power_budget = 2880; + break; + case IWL_CFG_RF_TYPE_FM: + default_power_budget = 3450; + break; + case IWL_CFG_RF_TYPE_WH: + case IWL_CFG_RF_TYPE_PE: + default: + default_power_budget = 5550; + break; + } + + iwl_bios_get_pwr_limit(&mld->fwrt, &bios_power_budget); + + /* 32bit in UEFI, 16bit in ACPI; use BIOS value if it is in range */ + if (bios_power_budget && + bios_power_budget != 0xffff && bios_power_budget != 0xffffffff && + bios_power_budget >= IWL_MLD_MIN_CTDP_BUDGET_MW && + bios_power_budget <= default_power_budget) + return (u32)bios_power_budget; + + return default_power_budget; +} + void iwl_mld_thermal_initialize(struct iwl_mld *mld) { + lockdep_assert_not_held(&mld->wiphy->mtx); + wiphy_delayed_work_init(&mld->ct_kill_exit_wk, iwl_mld_exit_ctkill); + mld->power_budget_mw = iwl_mld_ctdp_get_max_budget(mld); + IWL_DEBUG_TEMP(mld, "cTDP power budget: %d mW\n", mld->power_budget_mw); + #ifdef CONFIG_THERMAL iwl_mld_cooling_device_register(mld); iwl_mld_thermal_zone_register(mld); @@ -429,7 +456,9 @@ void iwl_mld_thermal_initialize(struct iwl_mld *mld) void iwl_mld_thermal_exit(struct iwl_mld *mld) { + wiphy_lock(mld->wiphy); wiphy_delayed_work_cancel(mld->wiphy, &mld->ct_kill_exit_wk); + wiphy_unlock(mld->wiphy); #ifdef CONFIG_THERMAL iwl_mld_cooling_device_unregister(mld); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tlc.c b/drivers/net/wireless/intel/iwlwifi/mld/tlc.c index f054cc921d9d..a9ca92c0455e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/tlc.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/tlc.c @@ -44,7 +44,7 @@ iwl_mld_get_tlc_cmd_flags(struct iwl_mld *mld, u16 flags = 0; /* STBC flags */ - if (mld->cfg->ht_params->stbc && + if (mld->cfg->ht_params.stbc && (hweight8(iwl_mld_get_valid_tx_ant(mld)) > 1)) { if (he_cap->has_he && he_cap->he_cap_elem.phy_cap_info[2] & IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ) @@ -56,7 +56,7 @@ iwl_mld_get_tlc_cmd_flags(struct iwl_mld *mld, } /* LDPC */ - if (mld->cfg->ht_params->ldpc && + if (mld->cfg->ht_params.ldpc && ((ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING) || (has_vht && (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)))) flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK; @@ -658,7 +658,9 @@ void iwl_mld_handle_tlc_notif(struct iwl_mld *mld, if (WARN_ON(!mld_link_sta)) return; - mld_link_sta->last_rate_n_flags = le32_to_cpu(notif->rate); + mld_link_sta->last_rate_n_flags = + iwl_v3_rate_from_v2_v3(notif->rate, + mld->fw_rates_ver_3); rs_pretty_print_rate(pretty_rate, sizeof(pretty_rate), mld_link_sta->last_rate_n_flags); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tx.c b/drivers/net/wireless/intel/iwlwifi/mld/tx.c index 543abe72e465..3b4b575aadaa 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/tx.c @@ -76,14 +76,14 @@ static int iwl_mld_allocate_txq(struct iwl_mld *mld, struct ieee80211_txq *txq) */ unsigned int watchdog_timeout = txq->vif->type == NL80211_IFTYPE_AP ? IWL_WATCHDOG_DISABLED : - mld->trans->trans_cfg->base_params->wd_timeout; + mld->trans->mac_cfg->base->wd_timeout; int queue, size; lockdep_assert_wiphy(mld->wiphy); if (tid == IWL_MGMT_TID) size = max_t(u32, IWL_MGMT_QUEUE_SIZE, - mld->trans->cfg->min_txq_size); + mld->trans->mac_cfg->base->min_txq_size); else size = iwl_mld_get_queue_size(mld, txq); @@ -391,9 +391,9 @@ static u32 iwl_mld_mac80211_rate_idx_to_fw(struct iwl_mld *mld, /* Set CCK or OFDM flag */ if (rate_idx <= IWL_LAST_CCK_RATE) - rate_flags |= RATE_MCS_CCK_MSK; + rate_flags |= RATE_MCS_MOD_TYPE_CCK; else - rate_flags |= RATE_MCS_LEGACY_OFDM_MSK; + rate_flags |= RATE_MCS_MOD_TYPE_LEGACY_OFDM; /* Legacy rates are indexed: * 0 - 3 for CCK and 0 - 7 for OFDM @@ -425,47 +425,40 @@ static u32 iwl_mld_get_inject_tx_rate(struct iwl_mld *mld, struct ieee80211_tx_rate *rate = &info->control.rates[0]; u32 result; - /* we only care about legacy/HT/VHT so far, so we can - * build in v1 and use iwl_new_rate_from_v1() - * FIXME: in newer devices we only support the new rates, build - * the rate_n_flags in the new format here instead of using v1 and - * converting it. - */ - if (rate->flags & IEEE80211_TX_RC_VHT_MCS) { u8 mcs = ieee80211_rate_get_vht_mcs(rate); u8 nss = ieee80211_rate_get_vht_nss(rate); - result = RATE_MCS_VHT_MSK_V1; - result |= u32_encode_bits(mcs, RATE_VHT_MCS_RATE_CODE_MSK); + result = RATE_MCS_MOD_TYPE_VHT; + result |= u32_encode_bits(mcs, RATE_MCS_CODE_MSK); result |= u32_encode_bits(nss, RATE_MCS_NSS_MSK); if (rate->flags & IEEE80211_TX_RC_SHORT_GI) - result |= RATE_MCS_SGI_MSK_V1; + result |= RATE_MCS_SGI_MSK; if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) - result |= u32_encode_bits(1, RATE_MCS_CHAN_WIDTH_MSK_V1); + result |= RATE_MCS_CHAN_WIDTH_40; else if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH) - result |= u32_encode_bits(2, RATE_MCS_CHAN_WIDTH_MSK_V1); + result |= RATE_MCS_CHAN_WIDTH_80; else if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH) - result |= u32_encode_bits(3, RATE_MCS_CHAN_WIDTH_MSK_V1); - - result = iwl_new_rate_from_v1(result); + result |= RATE_MCS_CHAN_WIDTH_160; } else if (rate->flags & IEEE80211_TX_RC_MCS) { - result = RATE_MCS_HT_MSK_V1; - result |= u32_encode_bits(rate->idx, - RATE_HT_MCS_RATE_CODE_MSK_V1 | - RATE_HT_MCS_NSS_MSK_V1); + /* only MCS 0-15 are supported */ + u8 mcs = rate->idx & 7; + u8 nss = rate->idx > 7; + + result = RATE_MCS_MOD_TYPE_HT; + result |= u32_encode_bits(mcs, RATE_MCS_CODE_MSK); + result |= u32_encode_bits(nss, RATE_MCS_NSS_MSK); + if (rate->flags & IEEE80211_TX_RC_SHORT_GI) - result |= RATE_MCS_SGI_MSK_V1; + result |= RATE_MCS_SGI_MSK; if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) - result |= u32_encode_bits(1, RATE_MCS_CHAN_WIDTH_MSK_V1); + result |= RATE_MCS_CHAN_WIDTH_40; if (info->flags & IEEE80211_TX_CTL_LDPC) - result |= RATE_MCS_LDPC_MSK_V1; + result |= RATE_MCS_LDPC_MSK; if (u32_get_bits(info->flags, IEEE80211_TX_CTL_STBC)) result |= RATE_MCS_STBC_MSK; - - result = iwl_new_rate_from_v1(result); } else { result = iwl_mld_mac80211_rate_idx_to_fw(mld, info, rate->idx); } @@ -479,19 +472,23 @@ static u32 iwl_mld_get_inject_tx_rate(struct iwl_mld *mld, return result; } -static u32 iwl_mld_get_tx_rate_n_flags(struct iwl_mld *mld, - struct ieee80211_tx_info *info, - struct ieee80211_sta *sta, __le16 fc) +static __le32 iwl_mld_get_tx_rate_n_flags(struct iwl_mld *mld, + struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, __le16 fc) { + u32 rate; + if (unlikely(info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT)) - return iwl_mld_get_inject_tx_rate(mld, info, sta, fc); + rate = iwl_mld_get_inject_tx_rate(mld, info, sta, fc); + else + rate = iwl_mld_mac80211_rate_idx_to_fw(mld, info, -1) | + iwl_mld_get_tx_ant(mld, info, sta, fc); - return iwl_mld_mac80211_rate_idx_to_fw(mld, info, -1) | - iwl_mld_get_tx_ant(mld, info, sta, fc); + return iwl_v3_rate_to_v2_v3(rate, mld->fw_rates_ver_3); } static void -iwl_mld_fill_tx_cmd_hdr(struct iwl_tx_cmd_gen3 *tx_cmd, +iwl_mld_fill_tx_cmd_hdr(struct iwl_tx_cmd *tx_cmd, struct sk_buff *skb, bool amsdu) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -537,11 +534,11 @@ iwl_mld_fill_tx_cmd(struct iwl_mld *mld, struct sk_buff *skb, struct ieee80211_hdr *hdr = (void *)skb->data; struct iwl_mld_sta *mld_sta = sta ? iwl_mld_sta_from_mac80211(sta) : NULL; - struct iwl_tx_cmd_gen3 *tx_cmd; + struct iwl_tx_cmd *tx_cmd; bool amsdu = ieee80211_is_data_qos(hdr->frame_control) && (*ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_A_MSDU_PRESENT); - u32 rate_n_flags = 0; + __le32 rate_n_flags = 0; u16 flags = 0; dev_tx_cmd->hdr.cmd = TX_CMD; @@ -576,7 +573,7 @@ iwl_mld_fill_tx_cmd(struct iwl_mld *mld, struct sk_buff *skb, tx_cmd->flags = cpu_to_le16(flags); - tx_cmd->rate_n_flags = cpu_to_le32(rate_n_flags); + tx_cmd->rate_n_flags = rate_n_flags; } /* Caller of this need to check that info->control.vif is not NULL */ @@ -641,16 +638,36 @@ iwl_mld_get_tx_queue_id(struct iwl_mld *mld, struct ieee80211_txq *txq, case NL80211_IFTYPE_P2P_DEVICE: mld_vif = iwl_mld_vif_from_mac80211(info->control.vif); - if (mld_vif->roc_activity == ROC_NUM_ACTIVITIES) { - IWL_DEBUG_DROP(mld, "Drop tx outside ROC\n"); + if (mld_vif->roc_activity != ROC_ACTIVITY_P2P_DISC && + mld_vif->roc_activity != ROC_ACTIVITY_P2P_NEG) { + IWL_DEBUG_DROP(mld, + "Drop tx outside ROC with activity %d\n", + mld_vif->roc_activity); return IWL_MLD_INVALID_DROP_TX; } WARN_ON(!ieee80211_is_mgmt(fc)); - return mld_vif->deflink.aux_sta.queue_id; + return mld_vif->aux_sta.queue_id; + case NL80211_IFTYPE_MONITOR: + mld_vif = iwl_mld_vif_from_mac80211(info->control.vif); + return mld_vif->deflink.mon_sta.queue_id; + case NL80211_IFTYPE_STATION: + mld_vif = iwl_mld_vif_from_mac80211(info->control.vif); + + if (!(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)) { + IWL_DEBUG_DROP(mld, "Drop tx not off-channel\n"); + return IWL_MLD_INVALID_DROP_TX; + } + + if (mld_vif->roc_activity != ROC_ACTIVITY_HOTSPOT) { + IWL_DEBUG_DROP(mld, "Drop tx outside ROC\n"); + return IWL_MLD_INVALID_DROP_TX; + } + + WARN_ON(!ieee80211_is_mgmt(fc)); + return mld_vif->aux_sta.queue_id; default: - /* TODO: consider monitor (task=monitor) */ WARN_ONCE(1, "Unsupported vif type\n"); break; } @@ -831,7 +848,7 @@ static int iwl_mld_tx_tso_segment(struct iwl_mld *mld, struct sk_buff *skb, * 1 more for the potential data in the header */ if ((num_subframes * 2 + skb_shinfo(skb)->nr_frags + 1) > - mld->trans->max_skb_frags) + mld->trans->info.max_skb_frags) num_subframes = 1; if (num_subframes > 1) @@ -977,11 +994,14 @@ void iwl_mld_tx_from_txq(struct iwl_mld *mld, struct ieee80211_txq *txq) rcu_read_unlock(); } -static void iwl_mld_hwrate_to_tx_rate(u32 rate_n_flags, +static void iwl_mld_hwrate_to_tx_rate(struct iwl_mld *mld, + __le32 rate_n_flags_fw, struct ieee80211_tx_info *info) { enum nl80211_band band = info->band; struct ieee80211_tx_rate *tx_rate = &info->status.rates[0]; + u32 rate_n_flags = iwl_v3_rate_from_v2_v3(rate_n_flags_fw, + mld->fw_rates_ver_3); u32 sgi = rate_n_flags & RATE_MCS_SGI_MSK; u32 chan_width = rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK; u32 format = rate_n_flags & RATE_MCS_MOD_TYPE_MSK; @@ -1006,18 +1026,19 @@ static void iwl_mld_hwrate_to_tx_rate(u32 rate_n_flags, } switch (format) { - case RATE_MCS_HT_MSK: + case RATE_MCS_MOD_TYPE_HT: tx_rate->flags |= IEEE80211_TX_RC_MCS; tx_rate->idx = RATE_HT_MCS_INDEX(rate_n_flags); break; - case RATE_MCS_VHT_MSK: + case RATE_MCS_MOD_TYPE_VHT: ieee80211_rate_set_vht(tx_rate, rate_n_flags & RATE_MCS_CODE_MSK, - FIELD_GET(RATE_MCS_NSS_MSK, - rate_n_flags) + 1); + u32_get_bits(rate_n_flags, + RATE_MCS_NSS_MSK) + 1); tx_rate->flags |= IEEE80211_TX_RC_VHT_MCS; break; - case RATE_MCS_HE_MSK: + case RATE_MCS_MOD_TYPE_HE: + case RATE_MCS_MOD_TYPE_EHT: /* mac80211 cannot do this without ieee80211_tx_status_ext() * but it only matters for radiotap */ @@ -1111,8 +1132,7 @@ void iwl_mld_handle_tx_resp_notif(struct iwl_mld *mld, iwl_dbg_tlv_time_point(&mld->fwrt, tp, NULL); } - iwl_mld_hwrate_to_tx_rate(le32_to_cpu(tx_resp->initial_rate), - info); + iwl_mld_hwrate_to_tx_rate(mld, tx_resp->initial_rate, info); if (likely(!iwl_mld_time_sync_frame(mld, skb, hdr->addr1))) ieee80211_tx_status_skb(mld->hw, skb); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c index 21641d41a958..13cdc077d8d3 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2013-2014, 2018-2020, 2022-2024 Intel Corporation + * Copyright (C) 2013-2014, 2018-2020, 2022-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH */ #include <linux/ieee80211.h> @@ -181,7 +181,7 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id, struct iwl_mvm_sta *mvmsta; u32 value; - if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) + if (mvm->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) return 0; mvmsta = iwl_mvm_sta_from_staid_protected(mvm, sta_id); @@ -569,7 +569,7 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm) mvm->hw, IEEE80211_IFACE_ITER_NORMAL, iwl_mvm_bt_notif_iterator, &data); - if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + if (mvm->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { rcu_read_unlock(); return; } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 3e8b7168af01..507c03198c92 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -300,7 +300,7 @@ static void iwl_mvm_wowlan_get_rsc_tsc_data(struct ieee80211_hw *hw, for (i = 0; i < IWL_MAX_TID_COUNT; i++) { pn = iwl_mvm_find_max_pn(key, ptk_pn, &seq, i, - mvm->trans->num_rx_queues); + mvm->trans->info.num_rxqs); aes_sc[i].pn = cpu_to_le64((u64)pn[5] | ((u64)pn[4] << 8) | ((u64)pn[3] << 16) | @@ -421,7 +421,7 @@ static void iwl_mvm_wowlan_get_rsc_v5_data(struct ieee80211_hw *hw, for (i = 0; i < IWL_MAX_TID_COUNT; i++) { pn = iwl_mvm_find_max_pn(key, ptk_pn, &seq, i, - mvm->trans->num_rx_queues); + mvm->trans->info.num_rxqs); rsc[i] = cpu_to_le64((u64)pn[5] | ((u64)pn[4] << 8) | ((u64)pn[3] << 16) | @@ -1266,7 +1266,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, }; struct iwl_host_cmd d3_cfg_cmd = { .id = D3_CONFIG_CMD, - .flags = CMD_WANT_SKB | CMD_SEND_IN_D3, + .flags = CMD_WANT_SKB, .data[0] = &d3_cfg_cmd_data, .len[0] = sizeof(d3_cfg_cmd_data), }; @@ -1370,11 +1370,9 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, * recording before entering D3. In later devices the FW stops the * recording automatically. */ - if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000) + if (mvm->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_9000) iwl_fw_dbg_stop_restart_recording(&mvm->fwrt, NULL, true); - mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_D3; - /* must be last -- this switches firmware state */ ret = iwl_mvm_send_cmd(mvm, &d3_cfg_cmd); if (ret) @@ -1686,7 +1684,7 @@ static void iwl_mvm_set_aes_ptk_rx_seq(struct iwl_mvm *mvm, for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) { int i; - for (i = 1; i < mvm->trans->num_rx_queues; i++) + for (i = 1; i < mvm->trans->info.num_rxqs; i++) memcpy(ptk_pn->q[i].pn[tid], status->ptk.aes.seq[tid].ccmp.pn, IEEE80211_CCMP_PN_LEN); @@ -2825,7 +2823,7 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, status->qos_seq_ctr[i] + 0x10; } - if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { + if (mvm->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { i = mvm->offload_tid; iwl_trans_set_q_ptrs(mvm->trans, mvm_ap_sta->tid_data[i].txq_id, @@ -3407,9 +3405,9 @@ static int iwl_mvm_resume_firmware(struct iwl_mvm *mvm, bool test) int ret; enum iwl_d3_status d3_status; struct iwl_host_cmd cmd = { - .id = D0I3_END_CMD, - .flags = CMD_WANT_SKB | CMD_SEND_IN_D3, - }; + .id = D0I3_END_CMD, + .flags = CMD_WANT_SKB, + }; bool reset = fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG); @@ -3427,7 +3425,7 @@ static int iwl_mvm_resume_firmware(struct iwl_mvm *mvm, bool test) * AX210 and above don't need the command since they have * the doorbell interrupt. */ - if (mvm->trans->trans_cfg->device_family <= IWL_DEVICE_FAMILY_22000 && + if (mvm->trans->mac_cfg->device_family <= IWL_DEVICE_FAMILY_22000 && fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_D0I3_END_FIRST)) { ret = iwl_mvm_send_cmd(mvm, &cmd); if (ret < 0) @@ -3564,9 +3562,6 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) iwl_mvm_unblock_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_WOWLAN); - /* after the successful handshake, we're out of D3 */ - mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; - /* when reset is required we can't send these following commands */ if (d3_data.d3_end_flags & IWL_D0I3_RESET_REQUIRE) goto query_wakeup_reasons; @@ -3639,9 +3634,6 @@ out: */ set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status); - /* regardless of what happened, we're now out of D3 */ - mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; - return 1; } @@ -3679,8 +3671,7 @@ void iwl_mvm_fast_suspend(struct iwl_mvm *mvm) set_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); WARN_ON(iwl_mvm_power_update_device(mvm)); - mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_D3; - ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SEND_IN_D3, + ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, 0, sizeof(d3_cfg_cmd_data), &d3_cfg_cmd_data); if (ret) IWL_ERR(mvm, @@ -3735,7 +3726,6 @@ int iwl_mvm_fast_resume(struct iwl_mvm *mvm) out: clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); - mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; mvm->fast_resume = false; return ret; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 671d3f8d79c1..86a87ea89916 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -1277,7 +1277,7 @@ static ssize_t iwl_dbgfs_inject_packet_write(struct iwl_mvm *mvm, return -EIO; /* supporting only MQ RX */ - if (!mvm->trans->trans_cfg->mq_rx_supported) + if (!mvm->trans->mac_cfg->mq_rx_supported) return -EOPNOTSUPP; rxb._page = alloc_pages(GFP_ATOMIC, 0); @@ -1468,7 +1468,7 @@ static ssize_t iwl_dbgfs_fw_dbg_clear_write(struct iwl_mvm *mvm, char *buf, size_t count, loff_t *ppos) { - if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000) + if (mvm->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_9000) return -EOPNOTSUPP; /* diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 2b5a62604fc4..819e3228462a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -29,8 +29,8 @@ #define MVM_UCODE_CALIB_TIMEOUT (2 * HZ) struct iwl_mvm_alive_data { + __le32 sku_id[3]; bool valid; - u32 scd_base_addr; }; static int iwl_send_tx_ant_cfg(struct iwl_mvm *mvm, u8 valid_tx_ant) @@ -57,13 +57,13 @@ static int iwl_send_rss_cfg_cmd(struct iwl_mvm *mvm) BIT(IWL_RSS_HASH_TYPE_IPV6_PAYLOAD), }; - if (mvm->trans->num_rx_queues == 1) + if (mvm->trans->info.num_rxqs == 1) return 0; /* Do not direct RSS traffic to Q 0 which is our fallback queue */ for (i = 0; i < ARRAY_SIZE(cmd.indirection_table); i++) cmd.indirection_table[i] = - 1 + (i % (mvm->trans->num_rx_queues - 1)); + 1 + (i % (mvm->trans->info.num_rxqs - 1)); netdev_rss_key_fill(cmd.secret_key, sizeof(cmd.secret_key)); return iwl_mvm_send_cmd_pdu(mvm, RSS_CONFIG_CMD, 0, sizeof(cmd), &cmd); @@ -114,7 +114,7 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, u32 i; - if (version == 6) { + if (version >= 6) { struct iwl_alive_ntf_v6 *palive; if (pkt_len < sizeof(*palive)) @@ -157,6 +157,17 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, } } } + + if (version >= 8) { + const struct iwl_alive_ntf *palive_v8 = + (void *)pkt->data; + + if (pkt_len < sizeof(*palive_v8)) + return false; + + IWL_DEBUG_FW(mvm, "platform id: 0x%llx\n", + palive_v8->platform_id); + } } if (version >= 5) { @@ -171,14 +182,15 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, lmac2 = &palive->lmac_data[1]; status = le16_to_cpu(palive->status); - mvm->trans->sku_id[0] = le32_to_cpu(palive->sku_id.data[0]); - mvm->trans->sku_id[1] = le32_to_cpu(palive->sku_id.data[1]); - mvm->trans->sku_id[2] = le32_to_cpu(palive->sku_id.data[2]); + 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", - mvm->trans->sku_id[0], - mvm->trans->sku_id[1], - mvm->trans->sku_id[2]); + 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; @@ -221,7 +233,7 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, if (umac_error_table) { if (umac_error_table >= - mvm->trans->cfg->min_umac_error_event_table) { + mvm->trans->mac_cfg->base->min_umac_error_event_table) { iwl_fw_umac_set_alive_err_table(mvm->trans, umac_error_table); } else { @@ -233,7 +245,6 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, } } - alive_data->scd_base_addr = le32_to_cpu(lmac1->dbg_ptrs.scd_base_ptr); alive_data->valid = status == IWL_ALIVE_STATUS_OK; IWL_DEBUG_FW(mvm, @@ -282,7 +293,7 @@ static void iwl_mvm_print_pd_notification(struct iwl_mvm *mvm) IWL_ERR(mvm, #reg_name ": 0x%x\n", iwl_read_umac_prph(trans, reg_name)) struct iwl_trans *trans = mvm->trans; - enum iwl_device_family device_family = trans->trans_cfg->device_family; + enum iwl_device_family device_family = trans->mac_cfg->device_family; if (device_family < IWL_DEVICE_FAMILY_8000) return; @@ -304,7 +315,6 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, { struct iwl_notification_wait alive_wait; struct iwl_mvm_alive_data alive_data = {}; - const struct fw_img *fw; int ret; enum iwl_ucode_type old_type = mvm->fwrt.cur_fw_img; static const u16 alive_cmd[] = { UCODE_ALIVE_NTFY }; @@ -317,11 +327,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_START_FROM_ALIVE) && !(fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_USNIFFER_UNIFIED))) - fw = iwl_get_ucode_image(mvm->fw, IWL_UCODE_REGULAR_USNIFFER); - else - fw = iwl_get_ucode_image(mvm->fw, ucode_type); - if (WARN_ON(!fw)) - return -EINVAL; + ucode_type = IWL_UCODE_REGULAR_USNIFFER; iwl_fw_set_current_image(&mvm->fwrt, ucode_type); clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status); @@ -334,7 +340,8 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, * For the unified firmware case, the ucode_type is not * INIT, but we still need to run it. */ - ret = iwl_trans_start_fw(mvm->trans, fw, run_in_rfkill); + ret = iwl_trans_start_fw(mvm->trans, mvm->fw, ucode_type, + run_in_rfkill); if (ret) { iwl_fw_set_current_image(&mvm->fwrt, old_type); iwl_remove_notification(&mvm->notif_wait, &alive_wait); @@ -348,7 +355,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, ret = iwl_wait_notification(&mvm->notif_wait, &alive_wait, MVM_UCODE_ALIVE_TIMEOUT); - if (mvm->trans->trans_cfg->device_family == + if (mvm->trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_AX210) { /* print these registers regardless of alive fail/success */ IWL_INFO(mvm, "WFPM_UMAC_PD_NOTIFICATION: 0x%x\n", @@ -365,14 +372,14 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, struct iwl_trans *trans = mvm->trans; /* SecBoot info */ - if (trans->trans_cfg->device_family >= + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { IWL_ERR(mvm, "SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n", iwl_read_umac_prph(trans, UMAG_SB_CPU_1_STATUS), iwl_read_umac_prph(trans, UMAG_SB_CPU_2_STATUS)); - } else if (trans->trans_cfg->device_family >= + } else if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_8000) { IWL_ERR(mvm, "SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n", @@ -383,7 +390,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, iwl_mvm_print_pd_notification(mvm); /* LMAC/UMAC PC info */ - if (trans->trans_cfg->device_family >= + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { pc_data = trans->dbg.pc_data; for (count = 0; count < trans->dbg.num_pc; @@ -391,7 +398,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, IWL_ERR(mvm, "%s: 0x%x\n", pc_data->pc_name, pc_data->pc_address); - } else if (trans->trans_cfg->device_family >= + } else if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_9000) { IWL_ERR(mvm, "UMAC PC: 0x%x\n", iwl_read_umac_prph(trans, @@ -422,10 +429,10 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, /* if reached this point, Alive notification was received */ iwl_mei_alive_notif(true); - iwl_trans_fw_alive(mvm->trans, alive_data.scd_base_addr); + iwl_trans_fw_alive(mvm->trans); ret = iwl_pnvm_load(mvm->trans, &mvm->notif_wait, - &mvm->fw->ucode_capa); + &mvm->fw->ucode_capa, alive_data.sku_id); if (ret) { IWL_ERR(mvm, "Timeout waiting for PNVM load!\n"); iwl_fw_set_current_image(&mvm->fwrt, old_type); @@ -473,7 +480,7 @@ static void iwl_mvm_phy_filter_init(struct iwl_mvm *mvm, struct iwl_phy_specific_cfg *phy_filters) { #ifdef CONFIG_ACPI - *phy_filters = mvm->phy_filters; + *phy_filters = mvm->fwrt.phy_filters; #endif /* CONFIG_ACPI */ } @@ -490,7 +497,7 @@ static void iwl_mvm_uats_init(struct iwl_mvm *mvm) .dataflags[0] = IWL_HCMD_DFL_NOCOPY, }; - if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) { + if (mvm->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) { IWL_DEBUG_RADIO(mvm, "UATS feature is not supported\n"); return; } @@ -504,11 +511,10 @@ static void iwl_mvm_uats_init(struct iwl_mvm *mvm) return; } - ret = iwl_uefi_get_uats_table(mvm->trans, &mvm->fwrt); - if (ret < 0) { - IWL_DEBUG_FW(mvm, "failed to read UATS table (%d)\n", ret); + iwl_uefi_get_uats_table(mvm->trans, &mvm->fwrt); + + if (!mvm->fwrt.uats_valid) return; - } ret = iwl_mvm_send_cmd(mvm, &cmd); if (ret < 0) @@ -578,7 +584,7 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm) /* set flags extra PHY configuration flags from the device's cfg */ phy_cfg_cmd.phy_cfg |= - cpu_to_le32(mvm->trans->trans_cfg->extra_phy_cfg_flags); + cpu_to_le32(mvm->trans->mac_cfg->extra_phy_cfg_flags); phy_cfg_cmd.calib_control.event_trigger = mvm->fw->default_calib[ucode_type].event_trigger; @@ -617,7 +623,7 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm) mvm->rfkill_safe_init_done = false; - if (mvm->trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210) { + if (mvm->trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_AX210) { sb_cfg = iwl_read_umac_prph(mvm->trans, SB_MODIFY_CFG_FLAG); /* if needed, we'll reset this on our way out later */ mvm->fw_product_reset = sb_cfg == SB_CFG_RESIDES_IN_ROM; @@ -651,11 +657,6 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm) iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_AFTER_ALIVE, NULL); - if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) - mvm->trans->step_urm = !!(iwl_read_umac_prph(mvm->trans, - CNVI_PMU_STEP_FLOW) & - CNVI_PMU_STEP_FLOW_FORCE_URM); - /* Send init config command to mark that we are sending NVM access * commands */ @@ -756,7 +757,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm) goto remove_notif; } - if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000) { + if (mvm->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_8000) { ret = iwl_mvm_send_bt_init_conf(mvm); if (ret) goto remove_notif; @@ -1270,7 +1271,7 @@ void iwl_mvm_get_bios_tables(struct iwl_mvm *mvm) } } - iwl_acpi_get_phy_filters(&mvm->fwrt, &mvm->phy_filters); + iwl_acpi_get_phy_filters(&mvm->fwrt); if (iwl_bios_get_eckv(&mvm->fwrt, &mvm->ext_clock_valid)) IWL_DEBUG_RADIO(mvm, "ECKV table doesn't exist in BIOS\n"); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/led.c b/drivers/net/wireless/intel/iwlwifi/mvm/led.c index 1ea7c44250d4..c3cc1ea3ccc9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/led.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/led.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2019 Intel Corporation + * Copyright (C) 2012-2014, 2018-2019, 2025 Intel Corporation * Copyright (C) 2017 Intel Deutschland GmbH */ #include <linux/leds.h> @@ -102,7 +102,7 @@ void iwl_mvm_leds_sync(struct iwl_mvm *mvm) * if we control through the register, we're doing it * even when the firmware isn't up, so no need to sync */ - if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000) + if (mvm->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_8000) return; iwl_mvm_led_set(mvm, mvm->led.brightness > 0); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index bec18d197f31..9098a36530cc 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH */ @@ -938,12 +938,19 @@ u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct iwl_mvm *mvm, u16 iwl_mvm_mac_ctxt_get_beacon_flags(const struct iwl_fw *fw, u8 rate_idx) { - u16 flags = iwl_mvm_mac80211_idx_to_hwrate(fw, rate_idx); bool is_new_rate = iwl_fw_lookup_cmd_ver(fw, BEACON_TEMPLATE_CMD, 0) > 10; + u16 flags, cck_flag; - if (rate_idx <= IWL_FIRST_CCK_RATE) - flags |= is_new_rate ? IWL_MAC_BEACON_CCK - : IWL_MAC_BEACON_CCK_V1; + if (is_new_rate) { + flags = iwl_mvm_mac80211_idx_to_hwrate(fw, rate_idx); + cck_flag = IWL_MAC_BEACON_CCK; + } else { + cck_flag = IWL_MAC_BEACON_CCK_V1; + flags = iwl_fw_rate_idx_to_plcp(rate_idx); + } + + if (rate_idx <= IWL_LAST_CCK_RATE) + flags |= cck_flag; return flags; } @@ -969,7 +976,7 @@ u8 iwl_mvm_mac_ctxt_get_beacon_rate(struct iwl_mvm *mvm, static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct sk_buff *beacon, - struct iwl_tx_cmd *tx) + struct iwl_tx_cmd_v6 *tx) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct ieee80211_tx_info *info; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 1e916a0ce082..0f056a6641bd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -146,7 +146,7 @@ struct ieee80211_regdomain *iwl_mvm_get_regdomain(struct wiphy *wiphy, MCC_UPDATE_CMD, 0); IWL_DEBUG_LAR(mvm, "MCC update response version: %d\n", resp_ver); - regd = iwl_parse_nvm_mcc_info(mvm->trans->dev, mvm->cfg, + regd = iwl_parse_nvm_mcc_info(mvm->trans, __le32_to_cpu(resp->n_channels), resp->channels, __le16_to_cpu(resp->mcc), @@ -311,8 +311,8 @@ int iwl_mvm_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); /* This has been tested on those devices only */ - if (mvm->trans->trans_cfg->device_family != IWL_DEVICE_FAMILY_9000 && - mvm->trans->trans_cfg->device_family != IWL_DEVICE_FAMILY_22000) + if (mvm->trans->mac_cfg->device_family != IWL_DEVICE_FAMILY_9000 && + mvm->trans->mac_cfg->device_family != IWL_DEVICE_FAMILY_22000) return -EOPNOTSUPP; if (!mvm->nvm_data) @@ -391,7 +391,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) * for older devices. We also don't see this issue on any newer * devices. */ - if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_9000) + if (mvm->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_9000) ieee80211_hw_set(hw, TX_AMSDU); ieee80211_hw_set(hw, TX_FRAG_LIST); @@ -402,7 +402,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) /* We want to use the mac80211's reorder buffer for 9000 */ if (iwl_mvm_has_new_rx_api(mvm) && - mvm->trans->trans_cfg->device_family > IWL_DEVICE_FAMILY_9000) + mvm->trans->mac_cfg->device_family > IWL_DEVICE_FAMILY_9000) ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER); if (fw_has_capa(&mvm->fw->ucode_capa, @@ -417,10 +417,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) return -EINVAL; } - if (mvm->trans->num_rx_queues > 1) + if (mvm->trans->info.num_rxqs > 1) ieee80211_hw_set(hw, USES_RSS); - if (mvm->trans->max_skb_frags) + if (mvm->trans->info.max_skb_frags) hw->netdev_features = NETIF_F_HIGHDMA | NETIF_F_SG; hw->queues = IEEE80211_NUM_ACS; @@ -441,7 +441,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) hw->uapsd_queues = IWL_MVM_UAPSD_QUEUES; hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP; - hw->max_tx_fragments = mvm->trans->max_skb_frags; + hw->max_tx_fragments = mvm->trans->info.max_skb_frags; BUILD_BUG_ON(ARRAY_SIZE(mvm->ciphers) < ARRAY_SIZE(mvm_ciphers) + 6); memcpy(mvm->ciphers, mvm_ciphers, sizeof(mvm_ciphers)); @@ -544,7 +544,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG | REGULATORY_DISABLE_BEACON_HINTS; - if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) + if (mvm->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_DFS_CONCURRENT); @@ -610,7 +610,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) hw->wiphy->bands[NL80211_BAND_6GHZ] = &mvm->nvm_data->bands[NL80211_BAND_6GHZ]; - hw->wiphy->hw_version = mvm->trans->hw_id; + hw->wiphy->hw_version = mvm->trans->info.hw_id; if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; @@ -731,8 +731,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; - ieee80211_hw_set(hw, DISALLOW_PUNCTURING_5GHZ); - #ifdef CONFIG_PM_SLEEP if ((unified || mvm->fw->img[IWL_UCODE_WOWLAN].num_sec) && device_can_wakeup(mvm->trans->dev)) { @@ -771,7 +769,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) hw->wiphy->features |= NL80211_FEATURE_TDLS_CHANNEL_SWITCH; } - hw->netdev_features |= mvm->cfg->features; + hw->netdev_features |= mvm->trans->mac_cfg->base->features; if (!iwl_mvm_is_csum_supported(mvm)) hw->netdev_features &= ~IWL_CSUM_NETIF_FLAGS_MASK; @@ -1379,7 +1377,7 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm, bool suspend) iwl_mvm_rm_aux_sta(mvm); if (suspend && - mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { + mvm->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { iwl_mvm_fast_suspend(mvm); /* From this point on, we won't touch the device */ iwl_mvm_mei_device_state(mvm, false); @@ -1988,15 +1986,8 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, * interface is be handled as part of the stop_ap flow. */ if (vif->type == NL80211_IFTYPE_AP || - vif->type == NL80211_IFTYPE_ADHOC) { -#ifdef CONFIG_NL80211_TESTMODE - if (vif == mvm->noa_vif) { - mvm->noa_vif = NULL; - mvm->noa_duration = 0; - } -#endif + vif->type == NL80211_IFTYPE_ADHOC) goto out; - } iwl_mvm_power_update_mac(mvm); @@ -3059,7 +3050,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, * context. For the newer, the beacon is a resource that belongs to a * MAC, so need to send beacon template after adding the mac. */ - if (mvm->trans->trans_cfg->device_family > IWL_DEVICE_FAMILY_22000) { + if (mvm->trans->mac_cfg->device_family > IWL_DEVICE_FAMILY_22000) { /* Add the mac context */ ret = iwl_mvm_mac_ctxt_add(mvm, vif); if (ret) @@ -4105,7 +4096,8 @@ void iwl_mvm_smps_workaround(struct iwl_mvm *mvm, struct ieee80211_vif *vif, { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - if (!iwl_mvm_has_rlc_offload(mvm)) + if (!iwl_mvm_has_rlc_offload(mvm) || + iwl_fw_lookup_cmd_ver(mvm->fw, MAC_PM_POWER_TABLE, 0) >= 2) return; mvmvif->ps_disabled = !vif->cfg.ps; @@ -4395,7 +4387,7 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw, switch (key->cipher) { case WLAN_CIPHER_SUITE_TKIP: - if (!mvm->trans->trans_cfg->gen2) { + if (!mvm->trans->mac_cfg->gen2) { key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE; } else if (vif->type == NL80211_IFTYPE_STATION) { @@ -4512,7 +4504,7 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw, WARN_ON(rcu_access_pointer(mvmsta->ptk_pn[keyidx])); ptk_pn = kzalloc(struct_size(ptk_pn, q, - mvm->trans->num_rx_queues), + mvm->trans->info.num_rxqs), GFP_KERNEL); if (!ptk_pn) { ret = -ENOMEM; @@ -4521,7 +4513,7 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw, for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) { ieee80211_get_key_rx_seq(key, tid, &seq); - for (q = 0; q < mvm->trans->num_rx_queues; q++) + for (q = 0; q < mvm->trans->info.num_rxqs; q++) memcpy(ptk_pn->q[q].pn[tid], seq.ccmp.pn, IEEE80211_CCMP_PN_LEN); @@ -5525,70 +5517,6 @@ static int iwl_mvm_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, &mvm_sta->vif->bss_conf); } -#ifdef CONFIG_NL80211_TESTMODE -static const struct nla_policy iwl_mvm_tm_policy[IWL_MVM_TM_ATTR_MAX + 1] = { - [IWL_MVM_TM_ATTR_CMD] = { .type = NLA_U32 }, - [IWL_MVM_TM_ATTR_NOA_DURATION] = { .type = NLA_U32 }, - [IWL_MVM_TM_ATTR_BEACON_FILTER_STATE] = { .type = NLA_U32 }, -}; - -static int __iwl_mvm_mac_testmode_cmd(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - void *data, int len) -{ - struct nlattr *tb[IWL_MVM_TM_ATTR_MAX + 1]; - int err; - u32 noa_duration; - - err = nla_parse_deprecated(tb, IWL_MVM_TM_ATTR_MAX, data, len, - iwl_mvm_tm_policy, NULL); - if (err) - return err; - - if (!tb[IWL_MVM_TM_ATTR_CMD]) - return -EINVAL; - - switch (nla_get_u32(tb[IWL_MVM_TM_ATTR_CMD])) { - case IWL_MVM_TM_CMD_SET_NOA: - if (!vif || vif->type != NL80211_IFTYPE_AP || !vif->p2p || - !vif->bss_conf.enable_beacon || - !tb[IWL_MVM_TM_ATTR_NOA_DURATION]) - return -EINVAL; - - noa_duration = nla_get_u32(tb[IWL_MVM_TM_ATTR_NOA_DURATION]); - if (noa_duration >= vif->bss_conf.beacon_int) - return -EINVAL; - - mvm->noa_duration = noa_duration; - mvm->noa_vif = vif; - - return iwl_mvm_update_quotas(mvm, true, NULL); - case IWL_MVM_TM_CMD_SET_BEACON_FILTER: - /* must be associated client vif - ignore authorized */ - if (!vif || vif->type != NL80211_IFTYPE_STATION || - !vif->cfg.assoc || !vif->bss_conf.dtim_period || - !tb[IWL_MVM_TM_ATTR_BEACON_FILTER_STATE]) - return -EINVAL; - - if (nla_get_u32(tb[IWL_MVM_TM_ATTR_BEACON_FILTER_STATE])) - return iwl_mvm_enable_beacon_filter(mvm, vif); - return iwl_mvm_disable_beacon_filter(mvm, vif); - } - - return -EOPNOTSUPP; -} - -int iwl_mvm_mac_testmode_cmd(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - void *data, int len) -{ - struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); - - guard(mvm)(mvm); - return __iwl_mvm_mac_testmode_cmd(mvm, vif, data, len); -} -#endif - void iwl_mvm_channel_switch(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_channel_switch *chsw) { @@ -6140,12 +6068,12 @@ static void iwl_mvm_set_sta_rate(u32 rate_n_flags, struct rate_info *rinfo) break; } - if (format == RATE_MCS_CCK_MSK || - format == RATE_MCS_LEGACY_OFDM_MSK) { + if (format == RATE_MCS_MOD_TYPE_CCK || + format == RATE_MCS_MOD_TYPE_LEGACY_OFDM) { int rate = u32_get_bits(rate_n_flags, RATE_LEGACY_RATE_MSK); /* add the offset needed to get to the legacy ofdm indices */ - if (format == RATE_MCS_LEGACY_OFDM_MSK) + if (format == RATE_MCS_MOD_TYPE_LEGACY_OFDM) rate += IWL_FIRST_OFDM_RATE; switch (rate) { @@ -6190,7 +6118,7 @@ static void iwl_mvm_set_sta_rate(u32 rate_n_flags, struct rate_info *rinfo) rinfo->nss = u32_get_bits(rate_n_flags, RATE_MCS_NSS_MSK) + 1; - rinfo->mcs = format == RATE_MCS_HT_MSK ? + rinfo->mcs = format == RATE_MCS_MOD_TYPE_HT ? RATE_HT_MCS_INDEX(rate_n_flags) : u32_get_bits(rate_n_flags, RATE_MCS_CODE_MSK); @@ -6198,11 +6126,11 @@ static void iwl_mvm_set_sta_rate(u32 rate_n_flags, struct rate_info *rinfo) rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; switch (format) { - case RATE_MCS_EHT_MSK: + case RATE_MCS_MOD_TYPE_EHT: /* TODO: GI/LTF/RU. How does the firmware encode them? */ rinfo->flags |= RATE_INFO_FLAGS_EHT_MCS; break; - case RATE_MCS_HE_MSK: + case RATE_MCS_MOD_TYPE_HE: gi_ltf = u32_get_bits(rate_n_flags, RATE_MCS_HE_GI_LTF_MSK); rinfo->flags |= RATE_INFO_FLAGS_HE_MCS; @@ -6243,10 +6171,10 @@ static void iwl_mvm_set_sta_rate(u32 rate_n_flags, struct rate_info *rinfo) if (rate_n_flags & RATE_HE_DUAL_CARRIER_MODE_MSK) rinfo->he_dcm = 1; break; - case RATE_MCS_HT_MSK: + case RATE_MCS_MOD_TYPE_HT: rinfo->flags |= RATE_INFO_FLAGS_MCS; break; - case RATE_MCS_VHT_MSK: + case RATE_MCS_MOD_TYPE_VHT: rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS; break; } @@ -6426,17 +6354,10 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm, bool sync, const void *data, u32 size) { - struct { - struct iwl_rxq_sync_cmd cmd; - struct iwl_mvm_internal_rxq_notif notif; - } __packed cmd = { - .cmd.rxq_mask = cpu_to_le32(BIT(mvm->trans->num_rx_queues) - 1), - .cmd.count = - cpu_to_le32(sizeof(struct iwl_mvm_internal_rxq_notif) + - size), - .notif.type = type, - .notif.sync = sync, - }; + DEFINE_RAW_FLEX(struct iwl_rxq_sync_cmd, cmd, payload, + sizeof(struct iwl_mvm_internal_rxq_notif)); + struct iwl_mvm_internal_rxq_notif *notif = + (struct iwl_mvm_internal_rxq_notif *)cmd->payload; struct iwl_host_cmd hcmd = { .id = WIDE_ID(DATA_PATH_GROUP, TRIGGER_RX_QUEUES_NOTIF_CMD), .data[0] = &cmd, @@ -6447,16 +6368,22 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm, }; int ret; + cmd->rxq_mask = cpu_to_le32(BIT(mvm->trans->info.num_rxqs) - 1); + cmd->count = cpu_to_le32(sizeof(struct iwl_mvm_internal_rxq_notif) + + size); + notif->type = type; + notif->sync = sync; + /* size must be a multiple of DWORD */ - if (WARN_ON(cmd.cmd.count & cpu_to_le32(3))) + if (WARN_ON(cmd->count & cpu_to_le32(3))) return; if (!iwl_mvm_has_new_rx_api(mvm)) return; if (sync) { - cmd.notif.cookie = mvm->queue_sync_cookie; - mvm->queue_sync_state = (1 << mvm->trans->num_rx_queues) - 1; + notif->cookie = mvm->queue_sync_cookie; + mvm->queue_sync_state = (1 << mvm->trans->info.num_rxqs) - 1; } ret = iwl_mvm_send_cmd(mvm, &hcmd); @@ -6649,8 +6576,6 @@ const struct ieee80211_ops iwl_mvm_hw_ops = { .sync_rx_queues = iwl_mvm_sync_rx_queues, - CFG80211_TESTMODE_CMD(iwl_mvm_mac_testmode_cmd) - #ifdef CONFIG_PM_SLEEP /* look at d3.c */ .suspend = iwl_mvm_suspend, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac.c index bb7851042177..81ca9ff67be9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac.c @@ -1,17 +1,25 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2022 - 2024 Intel Corporation + * Copyright (C) 2022 - 2025 Intel Corporation */ #include "mvm.h" static void iwl_mvm_mld_set_he_support(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - struct iwl_mac_config_cmd *cmd) + struct iwl_mac_config_cmd *cmd, + int cmd_ver) { - if (vif->type == NL80211_IFTYPE_AP) - cmd->he_ap_support = cpu_to_le16(1); - else - cmd->he_support = cpu_to_le16(1); + if (vif->type == NL80211_IFTYPE_AP) { + if (cmd_ver == 2) + cmd->wifi_gen_v2.he_ap_support = cpu_to_le16(1); + else + cmd->wifi_gen.he_ap_support = 1; + } else { + if (cmd_ver == 2) + cmd->wifi_gen_v2.he_support = cpu_to_le16(1); + else + cmd->wifi_gen.he_support = 1; + } } static void iwl_mvm_mld_mac_ctxt_cmd_common(struct iwl_mvm *mvm, @@ -22,6 +30,12 @@ static void iwl_mvm_mld_mac_ctxt_cmd_common(struct iwl_mvm *mvm, struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct ieee80211_bss_conf *link_conf; unsigned int link_id; + int cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, + WIDE_ID(MAC_CONF_GROUP, + MAC_CONFIG_CMD), 0); + + if (WARN_ON(cmd_ver < 1 && cmd_ver > 3)) + return; cmd->id_and_color = cpu_to_le32(mvmvif->id); cmd->action = cpu_to_le32(action); @@ -30,8 +44,8 @@ static void iwl_mvm_mld_mac_ctxt_cmd_common(struct iwl_mvm *mvm, memcpy(cmd->local_mld_addr, vif->addr, ETH_ALEN); - cmd->he_support = 0; - cmd->eht_support = 0; + cmd->wifi_gen_v2.he_support = 0; + cmd->wifi_gen_v2.eht_support = 0; /* should be set by specific context type handler */ cmd->filter_flags = 0; @@ -51,8 +65,11 @@ static void iwl_mvm_mld_mac_ctxt_cmd_common(struct iwl_mvm *mvm, * and enable both when we have MLO. */ if (ieee80211_vif_is_mld(vif)) { - iwl_mvm_mld_set_he_support(mvm, vif, cmd); - cmd->eht_support = cpu_to_le32(1); + iwl_mvm_mld_set_he_support(mvm, vif, cmd, cmd_ver); + if (cmd_ver == 2) + cmd->wifi_gen_v2.eht_support = cpu_to_le32(1); + else + cmd->wifi_gen.eht_support = 1; return; } @@ -63,16 +80,19 @@ static void iwl_mvm_mld_mac_ctxt_cmd_common(struct iwl_mvm *mvm, continue; if (link_conf->he_support) - iwl_mvm_mld_set_he_support(mvm, vif, cmd); + iwl_mvm_mld_set_he_support(mvm, vif, cmd, cmd_ver); - /* it's not reasonable to have EHT without HE and FW API doesn't + /* It's not reasonable to have EHT without HE and FW API doesn't * support it. Ignore EHT in this case. */ if (!link_conf->he_support && link_conf->eht_support) continue; if (link_conf->eht_support) { - cmd->eht_support = cpu_to_le32(1); + if (cmd_ver == 2) + cmd->wifi_gen_v2.eht_support = cpu_to_le32(1); + else + cmd->wifi_gen.eht_support = 1; break; } } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c index 78d7153a0cfc..bf24f8cb673e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c @@ -150,19 +150,6 @@ static void iwl_mvm_mld_mac_remove_interface(struct ieee80211_hw *hw, iwl_mvm_vif_dbgfs_rm_link(mvm, vif); - /* For AP/GO interface, the tear down of the resources allocated to the - * interface is be handled as part of the stop_ap flow. - */ - if (vif->type == NL80211_IFTYPE_AP || - vif->type == NL80211_IFTYPE_ADHOC) { -#ifdef CONFIG_NL80211_TESTMODE - if (vif == mvm->noa_vif) { - mvm->noa_vif = NULL; - mvm->noa_duration = 0; - } -#endif - } - iwl_mvm_power_update_mac(mvm); /* Before the interface removal, mac80211 would cancel the ROC, and the @@ -1403,8 +1390,6 @@ const struct ieee80211_ops iwl_mvm_mld_hw_ops = { .sync_rx_queues = iwl_mvm_sync_rx_queues, - CFG80211_TESTMODE_CMD(iwl_mvm_mac_testmode_cmd) - #ifdef CONFIG_PM_SLEEP /* look at d3.c */ .suspend = iwl_mvm_suspend, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c index 9dd670041137..e1010521c3ea 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2022-2024 Intel Corporation + * Copyright (C) 2022-2025 Intel Corporation */ #include "mvm.h" #include "time-sync.h" @@ -48,9 +48,13 @@ u32 iwl_mvm_sta_fw_id_mask(struct iwl_mvm *mvm, struct ieee80211_sta *sta, static int iwl_mvm_mld_send_sta_cmd(struct iwl_mvm *mvm, struct iwl_sta_cfg_cmd *cmd) { + u32 cmd_id = WIDE_ID(MAC_CONF_GROUP, STA_CONFIG_CMD); + int cmd_len = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, 0) > 1 ? + sizeof(*cmd) : + sizeof(struct iwl_sta_cfg_cmd_v1); int ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(MAC_CONF_GROUP, STA_CONFIG_CMD), - 0, sizeof(*cmd), cmd); + 0, cmd_len, cmd); if (ret) IWL_ERR(mvm, "STA_CONFIG_CMD send failed, ret=0x%x\n", ret); return ret; @@ -144,7 +148,7 @@ int iwl_mvm_mld_add_int_sta_with_queue(struct iwl_mvm *mvm, { int ret, txq; unsigned int wdg_timeout = _wdg_timeout ? *_wdg_timeout : - mvm->trans->trans_cfg->base_params->wd_timeout; + mvm->trans->mac_cfg->base->wd_timeout; if (WARN_ON_ONCE(sta->sta_id == IWL_INVALID_STA)) return -ENOSPC; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index f6391c7a3e29..a4f412e750d0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -126,7 +126,7 @@ struct iwl_mvm_time_event_data { /* Power management */ /** - * enum iwl_power_scheme + * enum iwl_power_scheme - iwl power schemes * @IWL_POWER_SCHEME_CAM: Continuously Active Mode * @IWL_POWER_SCHEME_BPS: Balanced Power Save (default) * @IWL_POWER_SCHEME_LP: Low Power @@ -664,6 +664,8 @@ enum iwl_mvm_sched_scan_pass_all_states { * @min_backoff: The minimal tx backoff due to power restrictions * @params: Parameters to configure the thermal throttling algorithm. * @throttle: Is thermal throttling is active? + * @power_budget_mw: maximum cTDP power budget as defined for this system and + * device */ struct iwl_mvm_tt_mgmt { struct delayed_work ct_kill_exit; @@ -672,6 +674,8 @@ struct iwl_mvm_tt_mgmt { u32 min_backoff; struct iwl_tt_params params; bool throttle; + + u32 power_budget_mw; }; #ifdef CONFIG_THERMAL @@ -999,7 +1003,7 @@ struct iwl_mvm { struct iwl_trans *trans; const struct iwl_fw *fw; - const struct iwl_cfg *cfg; + const struct iwl_rf_cfg *cfg; struct iwl_phy_db *phy_db; struct ieee80211_hw *hw; @@ -1033,6 +1037,8 @@ struct iwl_mvm { u8 cca_40mhz_workaround; + u8 fw_rates_ver; + u32 ampdu_ref; bool ampdu_toggle; @@ -1246,11 +1252,6 @@ struct iwl_mvm { struct iwl_time_quota_cmd last_quota_cmd; -#ifdef CONFIG_NL80211_TESTMODE - u32 noa_duration; - struct ieee80211_vif *noa_vif; -#endif - /* Tx queues */ u16 aux_queue; u16 snif_queue; @@ -1348,10 +1349,6 @@ struct iwl_mvm { __le16 cur_aid; u8 cur_bssid[ETH_ALEN]; -#ifdef CONFIG_ACPI - struct iwl_phy_specific_cfg phy_filters; -#endif - /* report rx timestamp in ptp clock time */ bool rx_ts_ptp; @@ -1562,7 +1559,7 @@ static inline bool iwl_mvm_is_lar_supported(struct iwl_mvm *mvm) * Enable LAR only if it is supported by the FW (TLV) && * enabled in the NVM */ - if (mvm->cfg->nvm_type == IWL_NVM_EXT) + if (mvm->trans->cfg->nvm_type == IWL_NVM_EXT) return nvm_lar && tlv_lar; else return tlv_lar; @@ -1626,13 +1623,13 @@ static inline bool iwl_mvm_has_new_station_api(const struct iwl_fw *fw) static inline bool iwl_mvm_has_new_tx_api(struct iwl_mvm *mvm) { /* TODO - replace with TLV once defined */ - return mvm->trans->trans_cfg->gen2; + return mvm->trans->mac_cfg->gen2; } static inline bool iwl_mvm_has_unified_ucode(struct iwl_mvm *mvm) { /* TODO - better define this */ - return mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000; + return mvm->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_22000; } static inline bool iwl_mvm_is_cdb_supported(struct iwl_mvm *mvm) @@ -1657,7 +1654,7 @@ static inline bool iwl_mvm_cdb_scan_api(struct iwl_mvm *mvm) * but then there's a little bit of code in scan that won't make * any sense... */ - return mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000; + return mvm->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_22000; } static inline bool iwl_mvm_is_scan_ext_chan_supported(struct iwl_mvm *mvm) @@ -1732,13 +1729,13 @@ static inline bool iwl_mvm_is_ctdp_supported(struct iwl_mvm *mvm) static inline bool iwl_mvm_is_esr_supported(struct iwl_trans *trans) { - if (CSR_HW_RFID_IS_CDB(trans->hw_rf_id)) + if (CSR_HW_RFID_IS_CDB(trans->info.hw_rf_id)) return false; - switch (CSR_HW_RFID_TYPE(trans->hw_rf_id)) { + switch (CSR_HW_RFID_TYPE(trans->info.hw_rf_id)) { case IWL_CFG_RF_TYPE_FM: /* Step A doesn't support eSR */ - return CSR_HW_RFID_STEP(trans->hw_rf_id); + return CSR_HW_RFID_STEP(trans->info.hw_rf_id); case IWL_CFG_RF_TYPE_WH: case IWL_CFG_RF_TYPE_PE: return true; @@ -1757,8 +1754,8 @@ static inline int iwl_mvm_max_active_links(struct iwl_mvm *mvm, /* Check if HW supports eSR or STR */ if (iwl_mvm_is_esr_supported(trans) || - (CSR_HW_RFID_TYPE(trans->hw_rf_id) == IWL_CFG_RF_TYPE_FM && - CSR_HW_RFID_IS_CDB(trans->hw_rf_id))) + (CSR_HW_RFID_TYPE(trans->info.hw_rf_id) == IWL_CFG_RF_TYPE_FM && + CSR_HW_RFID_IS_CDB(trans->info.hw_rf_id))) return IWL_FW_MAX_ACTIVE_LINKS_NUM; return 1; @@ -1771,7 +1768,7 @@ extern const u8 iwl_mvm_ac_to_bz_tx_fifo[]; static inline u8 iwl_mvm_mac_ac_to_tx_fifo(struct iwl_mvm *mvm, enum ieee80211_ac_numbers ac) { - if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + if (mvm->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) return iwl_mvm_ac_to_bz_tx_fifo[ac]; if (iwl_mvm_has_new_tx_api(mvm)) return iwl_mvm_ac_to_gen2_tx_fifo[ac]; @@ -1810,9 +1807,6 @@ int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags, enum nl80211_band band, struct ieee80211_tx_rate *r); -void iwl_mvm_hwrate_to_tx_rate_v1(u32 rate_n_flags, - enum nl80211_band band, - struct ieee80211_tx_rate *r); u8 iwl_mvm_mac80211_idx_to_hwrate(const struct iwl_fw *fw, int rate_idx); u8 iwl_mvm_mac80211_ac_to_ucode_ac(enum ieee80211_ac_numbers ac); bool iwl_mvm_is_nic_ack_enabled(struct iwl_mvm *mvm, struct ieee80211_vif *vif); @@ -1843,9 +1837,9 @@ int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb, struct ieee80211_sta *sta); int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb); void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, - struct iwl_tx_cmd *tx_cmd, + struct iwl_tx_cmd_v6 *tx_cmd, struct ieee80211_tx_info *info, u8 sta_id); -void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd *tx_cmd, +void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd_v6 *tx_cmd, struct ieee80211_tx_info *info, struct ieee80211_sta *sta, __le16 fc); void iwl_mvm_mac_itxq_xmit(struct ieee80211_hw *hw, struct ieee80211_txq *txq); @@ -1876,7 +1870,7 @@ int iwl_mvm_set_sta_pkt_ext(struct iwl_mvm *mvm, void iwl_mvm_async_handlers_purge(struct iwl_mvm *mvm); static inline void iwl_mvm_set_tx_cmd_ccmp(struct ieee80211_tx_info *info, - struct iwl_tx_cmd *tx_cmd) + struct iwl_tx_cmd_v6 *tx_cmd) { struct ieee80211_key_conf *keyconf = info->control.hw_key; @@ -2138,6 +2132,10 @@ bool iwl_mvm_mld_valid_link_pair(struct ieee80211_vif *vif, const struct iwl_mvm_link_sel_data *b); s8 iwl_mvm_average_dbm_values(const struct iwl_umac_scan_channel_survey_notif *notif); + + +extern const struct iwl_hcmd_arr iwl_mvm_groups[]; +extern const unsigned int iwl_mvm_groups_size; #endif /* AP and IBSS */ @@ -2459,7 +2457,7 @@ void iwl_mvm_vif_set_low_latency(struct iwl_mvm_vif *mvmvif, bool set, */ static inline u32 iwl_mvm_flushable_queues(struct iwl_mvm *mvm) { - return ((BIT(mvm->trans->trans_cfg->base_params->num_of_queues) - 1) & + return ((BIT(mvm->trans->mac_cfg->base->num_of_queues) - 1) & ~BIT(IWL_MVM_DQA_CMD_QUEUE)); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c index 80ec59c58ae4..953218f1e025 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2019, 2021-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2019, 2021-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -120,7 +120,7 @@ static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section, } else { IWL_DEBUG_EEPROM(mvm->trans->dev, "NVM access command failed with status %d (device: %s)\n", - ret, mvm->trans->name); + ret, mvm->trans->info.name); ret = -ENODATA; } goto exit; @@ -191,7 +191,7 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section, while (ret == length) { /* Check no memory assumptions fail and cause an overflow */ if ((size_read + offset + length) > - mvm->trans->trans_cfg->base_params->eeprom_size) { + mvm->trans->mac_cfg->base->eeprom_size) { IWL_ERR(mvm, "EEPROM size is too small for NVM\n"); return -ENOBUFS; } @@ -206,7 +206,7 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section, offset += ret; } - iwl_nvm_fixups(mvm->trans->hw_id, section, data, offset); + iwl_nvm_fixups(mvm->trans->info.hw_id, section, data, offset); IWL_DEBUG_EEPROM(mvm->trans->dev, "NVM section %d read completed\n", section); @@ -226,7 +226,7 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) /* Checking for required sections */ if (mvm->trans->cfg->nvm_type == IWL_NVM) { if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data || - !mvm->nvm_sections[mvm->cfg->nvm_hw_section_num].data) { + !mvm->nvm_sections[mvm->trans->mac_cfg->base->nvm_hw_section_num].data) { IWL_ERR(mvm, "Can't parse empty OTP/NVM sections\n"); return NULL; } @@ -244,7 +244,7 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) return NULL; } /* MAC_OVERRIDE or at least HW section must exist */ - if (!mvm->nvm_sections[mvm->cfg->nvm_hw_section_num].data && + if (!mvm->nvm_sections[mvm->trans->mac_cfg->base->nvm_hw_section_num].data && !mvm->nvm_sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data) { IWL_ERR(mvm, "Can't parse mac_address, empty sections\n"); @@ -260,7 +260,7 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) } } - hw = (const __be16 *)sections[mvm->cfg->nvm_hw_section_num].data; + hw = (const __be16 *)sections[mvm->trans->mac_cfg->base->nvm_hw_section_num].data; sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data; calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data; mac_override = @@ -308,16 +308,15 @@ int iwl_nvm_init(struct iwl_mvm *mvm) int ret, section; u32 size_read = 0; u8 *nvm_buffer, *temp; - const char *nvm_file_C = mvm->cfg->default_nvm_file_C_step; - if (WARN_ON_ONCE(mvm->cfg->nvm_hw_section_num >= NVM_MAX_NUM_SECTIONS)) + if (WARN_ON_ONCE(mvm->trans->mac_cfg->base->nvm_hw_section_num >= NVM_MAX_NUM_SECTIONS)) return -EINVAL; /* load NVM values from nic */ /* Read From FW NVM */ IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n"); - nvm_buffer = kmalloc(mvm->trans->trans_cfg->base_params->eeprom_size, + nvm_buffer = kmalloc(mvm->trans->mac_cfg->base->eeprom_size, GFP_KERNEL); if (!nvm_buffer) return -ENOMEM; @@ -338,7 +337,7 @@ int iwl_nvm_init(struct iwl_mvm *mvm) break; } - iwl_nvm_fixups(mvm->trans->hw_id, section, temp, ret); + iwl_nvm_fixups(mvm->trans->info.hw_id, section, temp, ret); mvm->nvm_sections[section].data = temp; mvm->nvm_sections[section].length = ret; @@ -367,7 +366,7 @@ int iwl_nvm_init(struct iwl_mvm *mvm) mvm->nvm_reg_blob.size = ret; break; default: - if (section == mvm->cfg->nvm_hw_section_num) { + if (section == mvm->trans->mac_cfg->base->nvm_hw_section_num) { mvm->nvm_hw_blob.data = temp; mvm->nvm_hw_blob.size = ret; break; @@ -384,21 +383,8 @@ int iwl_nvm_init(struct iwl_mvm *mvm) /* read External NVM file from the mod param */ ret = iwl_read_external_nvm(mvm->trans, mvm->nvm_file_name, mvm->nvm_sections); - if (ret) { - mvm->nvm_file_name = nvm_file_C; - - if ((ret == -EFAULT || ret == -ENOENT) && - mvm->nvm_file_name) { - /* in case nvm file was failed try again */ - ret = iwl_read_external_nvm(mvm->trans, - mvm->nvm_file_name, - mvm->nvm_sections); - if (ret) - return ret; - } else { - return ret; - } - } + if (ret) + return ret; } /* parse the relevant nvm sections */ @@ -554,7 +540,7 @@ int iwl_mvm_init_mcc(struct iwl_mvm *mvm) struct ieee80211_regdomain *regd; char mcc[3]; - if (mvm->cfg->nvm_type == IWL_NVM_EXT) { + if (mvm->trans->cfg->nvm_type == IWL_NVM_EXT) { tlv_lar = fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_LAR_SUPPORT); nvm_lar = mvm->nvm_data->lar_enabled; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 76603ef02704..a2dc5c3b0596 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -92,11 +92,11 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode) IWL_DEBUG_INFO(mvm, "Radio type=0x%x-0x%x-0x%x\n", radio_cfg_type, radio_cfg_step, radio_cfg_dash); - if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) + if (mvm->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) return; /* SKU control */ - reg_val = CSR_HW_REV_STEP_DASH(mvm->trans->hw_rev); + reg_val = CSR_HW_REV_STEP_DASH(mvm->trans->info.hw_rev); /* radio configuration */ reg_val |= radio_cfg_type << CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE; @@ -114,7 +114,7 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode) * unrelated errors. Need to further investigate this, but for now * we'll separate cases. */ - if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000) + if (mvm->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_8000) reg_val |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI; if (iwl_fw_dbg_is_d3_debug_enabled(&mvm->fwrt)) @@ -135,7 +135,7 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode) * (PCIe power is lost before PERST# is asserted), causing ME FW * to lose ownership and not being able to obtain it back. */ - if (!mvm->trans->cfg->apmg_not_supported) + if (!mvm->trans->mac_cfg->base->apmg_not_supported) iwl_set_bits_mask_prph(mvm->trans, APMG_PS_CTRL_REG, APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS, ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS); @@ -777,7 +777,8 @@ static const struct iwl_hcmd_names iwl_mvm_bt_coex_names[] = { HCMD_NAME(PROFILE_NOTIF), }; -static const struct iwl_hcmd_arr iwl_mvm_groups[] = { +VISIBLE_IF_IWLWIFI_KUNIT +const struct iwl_hcmd_arr iwl_mvm_groups[] = { [LEGACY_GROUP] = HCMD_ARR(iwl_mvm_legacy_names), [LONG_GROUP] = HCMD_ARR(iwl_mvm_legacy_names), [SYSTEM_GROUP] = HCMD_ARR(iwl_mvm_system_names), @@ -793,6 +794,11 @@ static const struct iwl_hcmd_arr iwl_mvm_groups[] = { [DEBUG_GROUP] = HCMD_ARR(iwl_mvm_debug_names), [STATISTICS_GROUP] = HCMD_ARR(iwl_mvm_statistics_names), }; +EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_mvm_groups); +#if IS_ENABLED(CONFIG_IWLWIFI_KUNIT_TESTS) +const unsigned int iwl_mvm_groups_size = ARRAY_SIZE(iwl_mvm_groups); +EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_mvm_groups_size); +#endif /* this forward declaration can avoid to export the function */ static void iwl_mvm_async_handlers_wk(struct work_struct *wk); @@ -1272,13 +1278,12 @@ static void iwl_mvm_trig_link_selection(struct wiphy *wiphy, } static struct iwl_op_mode * -iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, +iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg, const struct iwl_fw *fw, struct dentry *dbgfs_dir) { struct ieee80211_hw *hw; struct iwl_op_mode *op_mode; struct iwl_mvm *mvm; - struct iwl_trans_config trans_cfg = {}; static const u8 no_reclaim_cmds[] = { TX_CMD, }; @@ -1286,6 +1291,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, size_t scan_size; u32 min_backoff; struct iwl_mvm_csme_conn_info *csme_conn_info __maybe_unused; + int ratecheck; int err; /* @@ -1306,18 +1312,13 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, if (!hw) return ERR_PTR(-ENOMEM); - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) max_agg = 512; else max_agg = IEEE80211_MAX_AMPDU_BUF_HE; hw->max_rx_aggregation_subframes = max_agg; - if (cfg->max_tx_agg_size) - hw->max_tx_aggregation_subframes = cfg->max_tx_agg_size; - else - hw->max_tx_aggregation_subframes = max_agg; - op_mode = hw->priv; mvm = IWL_OP_MODE_GET_MVM(op_mode); @@ -1337,19 +1338,58 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, mvm->init_status = 0; + /* start with v1 rates */ + mvm->fw_rates_ver = 1; + + /* check for rates version 2 */ + ratecheck = + (iwl_fw_lookup_cmd_ver(mvm->fw, TX_CMD, 0) >= 8) + + (iwl_fw_lookup_notif_ver(mvm->fw, DATA_PATH_GROUP, + TLC_MNG_UPDATE_NOTIF, 0) >= 3) + + (iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP, + REPLY_RX_MPDU_CMD, 0) >= 4) + + (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP, TX_CMD, 0) >= 6); + if (ratecheck != 0 && ratecheck != 4) { + IWL_ERR(mvm, "Firmware has inconsistent rates\n"); + err = -EINVAL; + goto out_free; + } + if (ratecheck == 4) + mvm->fw_rates_ver = 2; + + /* check for rates version 3 */ + ratecheck = + (iwl_fw_lookup_cmd_ver(mvm->fw, TX_CMD, 0) >= 11) + + (iwl_fw_lookup_notif_ver(mvm->fw, DATA_PATH_GROUP, + TLC_MNG_UPDATE_NOTIF, 0) >= 4) + + (iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP, + REPLY_RX_MPDU_CMD, 0) >= 6) + + (iwl_fw_lookup_notif_ver(mvm->fw, DATA_PATH_GROUP, + RX_NO_DATA_NOTIF, 0) >= 4) + + (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP, TX_CMD, 0) >= 9); + if (ratecheck != 0 && ratecheck != 5) { + IWL_ERR(mvm, "Firmware has inconsistent rates\n"); + err = -EINVAL; + goto out_free; + } + if (ratecheck == 5) + mvm->fw_rates_ver = 3; + + trans->conf.rx_mpdu_cmd = REPLY_RX_MPDU_CMD; + if (iwl_mvm_has_new_rx_api(mvm)) { op_mode->ops = &iwl_mvm_ops_mq; - trans->rx_mpdu_cmd_hdr_size = - (trans->trans_cfg->device_family >= + trans->conf.rx_mpdu_cmd_hdr_size = + (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) ? sizeof(struct iwl_rx_mpdu_desc) : IWL_RX_DESC_SIZE_V1; } else { op_mode->ops = &iwl_mvm_ops; - trans->rx_mpdu_cmd_hdr_size = + trans->conf.rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start); - if (WARN_ON(trans->num_rx_queues > 1)) { + if (WARN_ON(trans->info.num_rxqs > 1)) { err = -EINVAL; goto out_free; } @@ -1437,53 +1477,50 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, * Populate the state variables that the transport layer needs * to know about. */ - trans_cfg.op_mode = op_mode; - trans_cfg.no_reclaim_cmds = no_reclaim_cmds; - trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); + BUILD_BUG_ON(sizeof(no_reclaim_cmds) > + sizeof(trans->conf.no_reclaim_cmds)); + memcpy(trans->conf.no_reclaim_cmds, no_reclaim_cmds, + sizeof(no_reclaim_cmds)); + trans->conf.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); - trans_cfg.rx_buf_size = iwl_amsdu_size_to_rxb_size(); + trans->conf.rx_buf_size = iwl_amsdu_size_to_rxb_size(); - trans->wide_cmd_header = true; - trans_cfg.bc_table_dword = - mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210; + trans->conf.wide_cmd_header = true; - trans_cfg.command_groups = iwl_mvm_groups; - trans_cfg.command_groups_size = ARRAY_SIZE(iwl_mvm_groups); + trans->conf.command_groups = iwl_mvm_groups; + trans->conf.command_groups_size = ARRAY_SIZE(iwl_mvm_groups); - trans_cfg.cmd_queue = IWL_MVM_DQA_CMD_QUEUE; - trans_cfg.cmd_fifo = IWL_MVM_TX_FIFO_CMD; - trans_cfg.scd_set_active = true; + trans->conf.cmd_queue = IWL_MVM_DQA_CMD_QUEUE; + trans->conf.cmd_fifo = IWL_MVM_TX_FIFO_CMD; + trans->conf.scd_set_active = true; - trans_cfg.cb_data_offs = offsetof(struct ieee80211_tx_info, - driver_data[2]); + trans->conf.cb_data_offs = offsetof(struct ieee80211_tx_info, + driver_data[2]); snprintf(mvm->hw->wiphy->fw_version, sizeof(mvm->hw->wiphy->fw_version), "%.31s", fw->fw_version); - trans_cfg.fw_reset_handshake = fw_has_capa(&mvm->fw->ucode_capa, - IWL_UCODE_TLV_CAPA_FW_RESET_HANDSHAKE); + trans->conf.fw_reset_handshake = + fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_FW_RESET_HANDSHAKE); - trans_cfg.queue_alloc_cmd_ver = + trans->conf.queue_alloc_cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, WIDE_ID(DATA_PATH_GROUP, SCD_QUEUE_CONFIG_CMD), 0); mvm->sta_remove_requires_queue_remove = - trans_cfg.queue_alloc_cmd_ver > 0; + trans->conf.queue_alloc_cmd_ver > 0; mvm->mld_api_is_used = iwl_mvm_has_mld_api(mvm->fw); /* Configure transport layer */ - iwl_trans_configure(mvm->trans, &trans_cfg); + iwl_trans_op_mode_enter(mvm->trans, op_mode); - trans->rx_mpdu_cmd = REPLY_RX_MPDU_CMD; trans->dbg.dest_tlv = mvm->fw->dbg.dest_tlv; trans->dbg.n_dest_reg = mvm->fw->dbg.n_dest_reg; - trans->iml = mvm->fw->iml; - trans->iml_len = mvm->fw->iml_len; - /* set up notification wait support */ iwl_notification_wait_init(&mvm->notif_wait); @@ -2100,7 +2137,7 @@ static bool iwl_mvm_sw_reset(struct iwl_op_mode *op_mode, mvm->fwrt.trans->dbg.restart_required = false; ieee80211_restart_hw(mvm->hw); return true; - } else if (mvm->trans->trans_cfg->device_family <= IWL_DEVICE_FAMILY_8000) { + } else if (mvm->trans->mac_cfg->device_family <= IWL_DEVICE_FAMILY_8000) { ieee80211_restart_hw(mvm->hw); return true; } @@ -2125,7 +2162,6 @@ static void iwl_op_mode_mvm_device_powered_off(struct iwl_op_mode *op_mode) mutex_lock(&mvm->mutex); clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); - mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; iwl_mvm_stop_device(mvm); mvm->fast_resume = false; mutex_unlock(&mvm->mutex); @@ -2165,7 +2201,7 @@ static void iwl_mvm_rx_mq_rss(struct iwl_op_mode *op_mode, struct iwl_rx_packet *pkt = rxb_addr(rxb); u16 cmd = WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd); - if (unlikely(queue >= mvm->trans->num_rx_queues)) + if (unlikely(queue >= mvm->trans->info.num_rxqs)) return; if (unlikely(cmd == WIDE_ID(LEGACY_GROUP, FRAME_RELEASE))) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/power.c b/drivers/net/wireless/intel/iwlwifi/mvm/power.c index a386b315e52f..0057fddf88f0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/power.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2019, 2021-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2019, 2021-2025 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH */ @@ -376,6 +376,9 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, if (!vif->cfg.ps || !mvmvif->pm_enabled) return; + if (iwl_fw_lookup_cmd_ver(mvm->fw, MAC_PM_POWER_TABLE, 0) >= 2) + cmd->flags |= cpu_to_le16(POWER_FLAGS_ENABLE_SMPS_MSK); + if (iwl_mvm_vif_low_latency(mvmvif) && vif->p2p && (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS) || diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/quota.c b/drivers/net/wireless/intel/iwlwifi/mvm/quota.c index aad2614af9ad..798a7e4bea83 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/quota.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/quota.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018, 2021-2022 Intel Corporation + * Copyright (C) 2012-2014, 2018, 2021-2022, 2025 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -86,45 +86,6 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac, } } -static void iwl_mvm_adjust_quota_for_noa(struct iwl_mvm *mvm, - struct iwl_time_quota_cmd *cmd) -{ -#ifdef CONFIG_NL80211_TESTMODE - struct iwl_mvm_vif *mvmvif; - int i, phy_id = -1, beacon_int = 0; - - if (!mvm->noa_duration || !mvm->noa_vif) - return; - - mvmvif = iwl_mvm_vif_from_mac80211(mvm->noa_vif); - if (!mvmvif->ap_ibss_active) - return; - - phy_id = mvmvif->deflink.phy_ctxt->id; - beacon_int = mvm->noa_vif->bss_conf.beacon_int; - - for (i = 0; i < MAX_BINDINGS; i++) { - struct iwl_time_quota_data *data = - iwl_mvm_quota_cmd_get_quota(mvm, cmd, - i); - u32 id_n_c = le32_to_cpu(data->id_and_color); - u32 id = (id_n_c & FW_CTXT_ID_MSK) >> FW_CTXT_ID_POS; - u32 quota = le32_to_cpu(data->quota); - - if (id != phy_id) - continue; - - quota *= (beacon_int - mvm->noa_duration); - quota /= beacon_int; - - IWL_DEBUG_QUOTA(mvm, "quota: adjust for NoA from %d to %d\n", - le32_to_cpu(data->quota), quota); - - data->quota = cpu_to_le32(quota); - } -#endif -} - int iwl_mvm_update_quotas(struct iwl_mvm *mvm, bool force_update, struct ieee80211_vif *disabled_vif) @@ -260,8 +221,6 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, } } - iwl_mvm_adjust_quota_for_noa(mvm, &cmd); - /* check that we have non-zero quota for all valid bindings */ for (i = 0; i < MAX_BINDINGS; i++) { qdata = iwl_mvm_quota_cmd_get_quota(mvm, &cmd, i); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c index de5ac000272e..89ac4c6b3e54 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2018-2024 Intel Corporation + * Copyright (C) 2018-2025 Intel Corporation */ #include "rs.h" #include "fw-api.h" @@ -72,7 +72,7 @@ static u16 rs_fw_get_config_flags(struct iwl_mvm *mvm, u16 flags = 0; /* get STBC flags */ - if (mvm->cfg->ht_params->stbc && + if (mvm->cfg->ht_params.stbc && (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1)) { if (he_cap->has_he && he_cap->he_cap_elem.phy_cap_info[2] & IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ) @@ -83,7 +83,7 @@ static u16 rs_fw_get_config_flags(struct iwl_mvm *mvm, flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK; } - if (mvm->cfg->ht_params->ldpc && + if (mvm->cfg->ht_params.ldpc && ((ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING) || (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)))) flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK; @@ -454,22 +454,11 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm, if (flags & IWL_TLC_NOTIF_FLAG_RATE) { char pretty_rate[100]; - if (iwl_fw_lookup_notif_ver(mvm->fw, DATA_PATH_GROUP, - TLC_MNG_UPDATE_NOTIF, 0) < 3) { - rs_pretty_print_rate_v1(pretty_rate, - sizeof(pretty_rate), - le32_to_cpu(notif->rate)); - IWL_DEBUG_RATE(mvm, - "Got rate in old format. Rate: %s. Converting.\n", - pretty_rate); - lq_sta->last_rate_n_flags = - iwl_new_rate_from_v1(le32_to_cpu(notif->rate)); - } else { - lq_sta->last_rate_n_flags = le32_to_cpu(notif->rate); - } + lq_sta->last_rate_n_flags = + iwl_mvm_v3_rate_from_fw(notif->rate, mvm->fw_rates_ver); rs_pretty_print_rate(pretty_rate, sizeof(pretty_rate), lq_sta->last_rate_n_flags); - IWL_DEBUG_RATE(mvm, "new rate: %s\n", pretty_rate); + IWL_DEBUG_RATE(mvm, "rate: %s\n", pretty_rate); } if (flags & IWL_TLC_NOTIF_FLAG_AMSDU && !mvm_link_sta->orig_amsdu_len) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index 068c58e9c1eb..5802ed80a9ca 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -2,6 +2,7 @@ /****************************************************************************** * * Copyright(c) 2005 - 2014, 2018 - 2023 Intel Corporation. All rights reserved. + * Copyright(c) 2025 Intel Corporation * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH *****************************************************************************/ @@ -895,7 +896,7 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate, WARN_ON_ONCE(1); } } else if (ucode_rate & RATE_MCS_VHT_MSK_V1) { - nss = FIELD_GET(RATE_MCS_NSS_MSK, ucode_rate) + 1; + nss = FIELD_GET(RATE_VHT_MCS_NSS_MSK, ucode_rate) + 1; if (nss == 1) { rate->type = LQ_VHT_SISO; @@ -909,7 +910,7 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate, WARN_ON_ONCE(1); } } else if (ucode_rate & RATE_MCS_HE_MSK_V1) { - nss = FIELD_GET(RATE_MCS_NSS_MSK, ucode_rate) + 1; + nss = FIELD_GET(RATE_VHT_MCS_NSS_MSK, ucode_rate) + 1; if (nss == 1) { rate->type = LQ_HE_SISO; @@ -2696,8 +2697,10 @@ static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta, lq_sta = mvm_sta; spin_lock_bh(&lq_sta->pers.lock); - iwl_mvm_hwrate_to_tx_rate_v1(lq_sta->last_rate_n_flags, - info->band, &info->control.rates[0]); + iwl_mvm_hwrate_to_tx_rate(iwl_mvm_v3_rate_from_fw( + cpu_to_le32(lq_sta->last_rate_n_flags), + 1), + info->band, &info->control.rates[0]); info->control.rates[0].count = 1; /* Report the optimal rate based on rssi and STA caps if we haven't @@ -2707,8 +2710,12 @@ static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta, optimal_rate = rs_get_optimal_rate(mvm, lq_sta); last_ucode_rate = ucode_rate_from_rs_rate(mvm, optimal_rate); - iwl_mvm_hwrate_to_tx_rate_v1(last_ucode_rate, info->band, - &txrc->reported_rate); + last_ucode_rate = + iwl_mvm_v3_rate_from_fw(cpu_to_le32(last_ucode_rate), + 1); + iwl_mvm_hwrate_to_tx_rate(last_ucode_rate, info->band, + &txrc->reported_rate); + txrc->reported_rate.count = 1; } spin_unlock_bh(&lq_sta->pers.lock); } @@ -2813,11 +2820,11 @@ static void rs_ht_init(struct iwl_mvm *mvm, lq_sta->active_mimo2_rate &= ~((u16)0x2); lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; - if (mvm->cfg->ht_params->ldpc && + if (mvm->cfg->ht_params.ldpc && (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)) lq_sta->ldpc = true; - if (mvm->cfg->ht_params->stbc && + if (mvm->cfg->ht_params.stbc && (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) && (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC)) lq_sta->stbc_capable = true; @@ -2832,11 +2839,11 @@ static void rs_vht_init(struct iwl_mvm *mvm, { rs_vht_set_enabled_rates(sta, vht_cap, lq_sta); - if (mvm->cfg->ht_params->ldpc && + if (mvm->cfg->ht_params.ldpc && (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)) lq_sta->ldpc = true; - if (mvm->cfg->ht_params->stbc && + if (mvm->cfg->ht_params.stbc && (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) && (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK)) lq_sta->stbc_capable = true; @@ -2887,10 +2894,10 @@ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg) if (rate & RATE_MCS_HT_MSK_V1) { mvm->drv_rx_stats.ht_frames++; - nss = ((rate & RATE_HT_MCS_NSS_MSK_V1) >> RATE_HT_MCS_NSS_POS_V1) + 1; + nss = FIELD_GET(RATE_HT_MCS_MIMO2_MSK, rate) + 1; } else if (rate & RATE_MCS_VHT_MSK_V1) { mvm->drv_rx_stats.vht_frames++; - nss = FIELD_GET(RATE_MCS_NSS_MSK, rate) + 1; + nss = FIELD_GET(RATE_VHT_MCS_NSS_MSK, rate) + 1; } else { mvm->drv_rx_stats.legacy_frames++; } @@ -3304,7 +3311,7 @@ static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm, if (num_of_ant(ant) == 1) lq_cmd->single_stream_ant_msk = ant; - if (!mvm->trans->trans_cfg->gen2) + if (!mvm->trans->mac_cfg->gen2) lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; else lq_cmd->agg_frame_cnt_limit = @@ -3673,16 +3680,15 @@ int rs_pretty_print_rate_v1(char *buf, int bufsz, const u32 rate) if (rate & RATE_MCS_VHT_MSK_V1) { type = "VHT"; mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK; - nss = FIELD_GET(RATE_MCS_NSS_MSK, rate) + 1; + nss = FIELD_GET(RATE_VHT_MCS_NSS_MSK, rate) + 1; } else if (rate & RATE_MCS_HT_MSK_V1) { type = "HT"; mcs = rate & RATE_HT_MCS_INDEX_MSK_V1; - nss = ((rate & RATE_HT_MCS_NSS_MSK_V1) - >> RATE_HT_MCS_NSS_POS_V1) + 1; + nss = FIELD_GET(RATE_HT_MCS_MIMO2_MSK, rate) + 1; } else if (rate & RATE_MCS_HE_MSK_V1) { type = "HE"; mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK; - nss = FIELD_GET(RATE_MCS_NSS_MSK, rate) + 1; + nss = FIELD_GET(RATE_VHT_MCS_NSS_MSK, rate) + 1; } else { type = "Unknown"; /* shouldn't happen */ } @@ -4172,3 +4178,167 @@ int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, else return rs_drv_tx_protection(mvm, mvmsta, enable); } + +static u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags) +{ + int rate = rate_n_flags & RATE_LEGACY_RATE_MSK_V1; + int idx; + bool ofdm = !(rate_n_flags & RATE_MCS_CCK_MSK_V1); + int offset = ofdm ? IWL_FIRST_OFDM_RATE : 0; + int last = ofdm ? IWL_RATE_COUNT_LEGACY : IWL_FIRST_OFDM_RATE; + + for (idx = offset; idx < last; idx++) + if (iwl_fw_rate_idx_to_plcp(idx) == rate) + return idx - offset; + return IWL_RATE_INVALID; +} + +u32 iwl_mvm_v3_rate_from_fw(__le32 rate, u8 rate_ver) +{ + u32 rate_v3 = 0, rate_v1; + u32 dup = 0; + + if (rate_ver > 1) + return iwl_v3_rate_from_v2_v3(rate, rate_ver >= 3); + + rate_v1 = le32_to_cpu(rate); + if (rate_v1 == 0) + return rate_v1; + /* convert rate */ + if (rate_v1 & RATE_MCS_HT_MSK_V1) { + u32 nss; + + rate_v3 |= RATE_MCS_MOD_TYPE_HT; + rate_v3 |= + rate_v1 & RATE_HT_MCS_RATE_CODE_MSK_V1; + nss = u32_get_bits(rate_v1, RATE_HT_MCS_MIMO2_MSK); + rate_v3 |= u32_encode_bits(nss, RATE_MCS_NSS_MSK); + } else if (rate_v1 & RATE_MCS_VHT_MSK_V1 || + rate_v1 & RATE_MCS_HE_MSK_V1) { + u32 nss = u32_get_bits(rate_v1, RATE_VHT_MCS_NSS_MSK); + + rate_v3 |= rate_v1 & RATE_VHT_MCS_RATE_CODE_MSK; + + rate_v3 |= u32_encode_bits(nss, RATE_MCS_NSS_MSK); + + if (rate_v1 & RATE_MCS_HE_MSK_V1) { + u32 he_type_bits = rate_v1 & RATE_MCS_HE_TYPE_MSK_V1; + u32 he_type = he_type_bits >> RATE_MCS_HE_TYPE_POS_V1; + u32 he_106t = (rate_v1 & RATE_MCS_HE_106T_MSK_V1) >> + RATE_MCS_HE_106T_POS_V1; + u32 he_gi_ltf = (rate_v1 & RATE_MCS_HE_GI_LTF_MSK_V1) >> + RATE_MCS_HE_GI_LTF_POS; + + if ((he_type_bits == RATE_MCS_HE_TYPE_SU || + he_type_bits == RATE_MCS_HE_TYPE_EXT_SU) && + he_gi_ltf == RATE_MCS_HE_SU_4_LTF) + /* the new rate have an additional bit to + * represent the value 4 rather then using SGI + * bit for this purpose - as it was done in the + * old rate + */ + he_gi_ltf += (rate_v1 & RATE_MCS_SGI_MSK_V1) >> + RATE_MCS_SGI_POS_V1; + + rate_v3 |= he_gi_ltf << RATE_MCS_HE_GI_LTF_POS; + rate_v3 |= he_type << RATE_MCS_HE_TYPE_POS; + rate_v3 |= he_106t << RATE_MCS_HE_106T_POS; + rate_v3 |= rate_v1 & RATE_HE_DUAL_CARRIER_MODE_MSK; + rate_v3 |= RATE_MCS_MOD_TYPE_HE; + } else { + rate_v3 |= RATE_MCS_MOD_TYPE_VHT; + } + /* if legacy format */ + } else { + u32 legacy_rate = iwl_legacy_rate_to_fw_idx(rate_v1); + + if (WARN_ON_ONCE(legacy_rate == IWL_RATE_INVALID)) + legacy_rate = (rate_v1 & RATE_MCS_CCK_MSK_V1) ? + IWL_FIRST_CCK_RATE : IWL_FIRST_OFDM_RATE; + + rate_v3 |= legacy_rate; + if (!(rate_v1 & RATE_MCS_CCK_MSK_V1)) + rate_v3 |= RATE_MCS_MOD_TYPE_LEGACY_OFDM; + } + + /* convert flags */ + if (rate_v1 & RATE_MCS_LDPC_MSK_V1) + rate_v3 |= RATE_MCS_LDPC_MSK; + rate_v3 |= (rate_v1 & RATE_MCS_CHAN_WIDTH_MSK_V1) | + (rate_v1 & RATE_MCS_ANT_AB_MSK) | + (rate_v1 & RATE_MCS_STBC_MSK) | + (rate_v1 & RATE_MCS_BF_MSK); + + dup = (rate_v1 & RATE_MCS_DUP_MSK_V1) >> RATE_MCS_DUP_POS_V1; + if (dup) { + rate_v3 |= RATE_MCS_DUP_MSK; + rate_v3 |= dup << RATE_MCS_CHAN_WIDTH_POS; + } + + if ((!(rate_v1 & RATE_MCS_HE_MSK_V1)) && + (rate_v1 & RATE_MCS_SGI_MSK_V1)) + rate_v3 |= RATE_MCS_SGI_MSK; + + return rate_v3; +} + +__le32 iwl_mvm_v3_rate_to_fw(u32 rate, u8 rate_ver) +{ + u32 result = 0; + int rate_idx; + + if (rate_ver > 1) + return iwl_v3_rate_to_v2_v3(rate, rate_ver > 2); + + switch (rate & RATE_MCS_MOD_TYPE_MSK) { + case RATE_MCS_MOD_TYPE_CCK: + result = RATE_MCS_CCK_MSK_V1; + fallthrough; + case RATE_MCS_MOD_TYPE_LEGACY_OFDM: + rate_idx = u32_get_bits(rate, RATE_LEGACY_RATE_MSK); + if (!(result & RATE_MCS_CCK_MSK_V1)) + rate_idx += IWL_FIRST_OFDM_RATE; + result |= u32_encode_bits(iwl_fw_rate_idx_to_plcp(rate_idx), + RATE_LEGACY_RATE_MSK_V1); + break; + case RATE_MCS_MOD_TYPE_HT: + result = RATE_MCS_HT_MSK_V1; + result |= u32_encode_bits(u32_get_bits(rate, + RATE_HT_MCS_CODE_MSK), + RATE_HT_MCS_RATE_CODE_MSK_V1); + result |= u32_encode_bits(u32_get_bits(rate, + RATE_MCS_NSS_MSK), + RATE_HT_MCS_MIMO2_MSK); + break; + case RATE_MCS_MOD_TYPE_VHT: + result = RATE_MCS_VHT_MSK_V1; + result |= u32_encode_bits(u32_get_bits(rate, + RATE_VHT_MCS_NSS_MSK), + RATE_MCS_CODE_MSK); + result |= u32_encode_bits(u32_get_bits(rate, RATE_MCS_NSS_MSK), + RATE_VHT_MCS_NSS_MSK); + break; + case RATE_MCS_MOD_TYPE_HE: /* not generated */ + default: + WARN_ONCE(1, "bad modulation type %d\n", + u32_get_bits(rate, RATE_MCS_MOD_TYPE_MSK)); + return 0; + } + + if (rate & RATE_MCS_LDPC_MSK) + result |= RATE_MCS_LDPC_MSK_V1; + WARN_ON_ONCE(u32_get_bits(rate, RATE_MCS_CHAN_WIDTH_MSK) > + RATE_MCS_CHAN_WIDTH_160_VAL); + result |= (rate & RATE_MCS_CHAN_WIDTH_MSK_V1) | + (rate & RATE_MCS_ANT_AB_MSK) | + (rate & RATE_MCS_STBC_MSK) | + (rate & RATE_MCS_BF_MSK); + + /* not handling DUP since we don't use it */ + WARN_ON_ONCE(rate & RATE_MCS_DUP_MSK); + + if (rate & RATE_MCS_SGI_MSK) + result |= RATE_MCS_SGI_MSK_V1; + + return cpu_to_le32(result); +} diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h index ea81cb236d5c..69259ebb966b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h @@ -3,7 +3,7 @@ * * Copyright(c) 2015 Intel Mobile Communications GmbH * Copyright(c) 2017 Intel Deutschland GmbH - * Copyright (C) 2003 - 2014, 2018 - 2024 Intel Corporation + * Copyright (C) 2003 - 2014, 2018 - 2025 Intel Corporation *****************************************************************************/ #ifndef __rs_h__ @@ -424,6 +424,9 @@ void iwl_mvm_rate_control_unregister(void); struct iwl_mvm_sta; +u32 iwl_mvm_v3_rate_from_fw(__le32 rate, u8 rate_ver); +__le32 iwl_mvm_v3_rate_to_fw(u32 rate, u8 rate_ver); + int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, bool enable); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c index 2dbef7b46355..8eb0aa448c85 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -490,8 +490,6 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi, if (!(rate_n_flags & RATE_MCS_CCK_MSK_V1) && rate_n_flags & RATE_MCS_SGI_MSK_V1) rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; - if (rate_n_flags & RATE_HT_MCS_GF_MSK) - rx_status->enc_flags |= RX_ENC_FLAG_HT_GF; if (rate_n_flags & RATE_MCS_LDPC_MSK_V1) rx_status->enc_flags |= RX_ENC_FLAG_LDPC; if (rate_n_flags & RATE_MCS_HT_MSK_V1) { @@ -1001,7 +999,7 @@ static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm) sec_link = mvmvif->link[sec_link]->fw_link_id; /* Sum up RX and TX MPDUs from the different queues/links */ - for (int q = 0; q < mvm->trans->num_rx_queues; q++) { + for (int q = 0; q < mvm->trans->info.num_rxqs; q++) { spin_lock_bh(&mvmsta->mpdu_counters[q].lock); /* The link IDs that doesn't exist will contain 0 */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 14ea89f931bb..077aadbf95db 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH */ @@ -171,7 +171,7 @@ static int iwl_mvm_create_skb(struct iwl_mvm *mvm, struct sk_buff *skb, shdr->type != htons(ETH_P_PAE) && shdr->type != htons(ETH_P_TDLS)))) skb->ip_summed = CHECKSUM_NONE; - else if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_BZ) + else if (mvm->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_BZ) /* mac80211 assumes full CSUM including SNAP header */ skb_postpush_rcsum(skb, shdr, sizeof(*shdr)); } @@ -409,7 +409,7 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_sta *sta, !(status & IWL_RX_MPDU_RES_STATUS_TTAK_OK)) return 0; - if (mvm->trans->trans_cfg->gen2 && + if (mvm->trans->mac_cfg->gen2 && !(status & RX_MPDU_RES_STATUS_MIC_OK)) stats->flag |= RX_FLAG_MMIC_ERROR; @@ -426,7 +426,7 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_sta *sta, if (pkt_flags & FH_RSCSR_RADA_EN) { stats->flag |= RX_FLAG_ICV_STRIPPED; - if (mvm->trans->trans_cfg->gen2) + if (mvm->trans->mac_cfg->gen2) stats->flag |= RX_FLAG_MMIC_STRIPPED; } @@ -462,7 +462,7 @@ static void iwl_mvm_rx_csum(struct iwl_mvm *mvm, { struct iwl_rx_mpdu_desc *desc = (void *)pkt->data; - if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + if (mvm->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { if (pkt->len_n_flags & cpu_to_le32(FH_RSCSR_RPA_EN)) { u16 hwsum = be16_to_cpu(desc->v3.raw_xsum); @@ -744,7 +744,7 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm, baid = (reorder & IWL_RX_MPDU_REORDER_BAID_MASK) >> IWL_RX_MPDU_REORDER_BAID_SHIFT; - if (mvm->trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_9000) + if (mvm->trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_9000) return false; /* @@ -1944,7 +1944,7 @@ static void iwl_mvm_rx_fill_status(struct iwl_mvm *mvm, } /* must be before L-SIG data */ - if (format == RATE_MCS_HE_MSK) + if (format == RATE_MCS_MOD_TYPE_HE) iwl_mvm_rx_he(mvm, skb, phy_data, queue); iwl_mvm_decode_lsig(skb, phy_data); @@ -1966,45 +1966,45 @@ static void iwl_mvm_rx_fill_status(struct iwl_mvm *mvm, phy_data->energy_a, phy_data->energy_b); /* using TLV format and must be after all fixed len fields */ - if (format == RATE_MCS_EHT_MSK) + if (format == RATE_MCS_MOD_TYPE_EHT) iwl_mvm_rx_eht(mvm, skb, phy_data, queue); if (unlikely(mvm->monitor_on)) iwl_mvm_add_rtap_sniffer_config(mvm, skb); - is_sgi = format == RATE_MCS_HE_MSK ? + is_sgi = format == RATE_MCS_MOD_TYPE_HE ? iwl_he_is_sgi(rate_n_flags) : rate_n_flags & RATE_MCS_SGI_MSK; - if (!(format == RATE_MCS_CCK_MSK) && is_sgi) + if (!(format == RATE_MCS_MOD_TYPE_CCK) && is_sgi) rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; if (rate_n_flags & RATE_MCS_LDPC_MSK) rx_status->enc_flags |= RX_ENC_FLAG_LDPC; switch (format) { - case RATE_MCS_VHT_MSK: + case RATE_MCS_MOD_TYPE_VHT: rx_status->encoding = RX_ENC_VHT; break; - case RATE_MCS_HE_MSK: + case RATE_MCS_MOD_TYPE_HE: rx_status->encoding = RX_ENC_HE; rx_status->he_dcm = !!(rate_n_flags & RATE_HE_DUAL_CARRIER_MODE_MSK); break; - case RATE_MCS_EHT_MSK: + case RATE_MCS_MOD_TYPE_EHT: rx_status->encoding = RX_ENC_EHT; break; } switch (format) { - case RATE_MCS_HT_MSK: + case RATE_MCS_MOD_TYPE_HT: rx_status->encoding = RX_ENC_HT; rx_status->rate_idx = RATE_HT_MCS_INDEX(rate_n_flags); rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; break; - case RATE_MCS_VHT_MSK: - case RATE_MCS_HE_MSK: - case RATE_MCS_EHT_MSK: + case RATE_MCS_MOD_TYPE_VHT: + case RATE_MCS_MOD_TYPE_HE: + case RATE_MCS_MOD_TYPE_EHT: rx_status->nss = u32_get_bits(rate_n_flags, RATE_MCS_NSS_MSK) + 1; rx_status->rate_idx = rate_n_flags & RATE_MCS_CODE_MSK; @@ -2048,7 +2048,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, if (unlikely(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))) return; - if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) + if (mvm->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) desc_size = sizeof(*desc); else desc_size = IWL_RX_DESC_SIZE_V1; @@ -2058,8 +2058,10 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, return; } - if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { - phy_data.rate_n_flags = le32_to_cpu(desc->v3.rate_n_flags); + if (mvm->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + phy_data.rate_n_flags = + iwl_mvm_v3_rate_from_fw(desc->v3.rate_n_flags, + mvm->fw_rates_ver); phy_data.channel = desc->v3.channel; phy_data.gp2_on_air_rise = le32_to_cpu(desc->v3.gp2_on_air_rise); phy_data.energy_a = desc->v3.energy_a; @@ -2072,7 +2074,9 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, phy_data.eht_d4 = desc->phy_eht_data4; phy_data.d5 = desc->v3.phy_data5; } else { - phy_data.rate_n_flags = le32_to_cpu(desc->v1.rate_n_flags); + phy_data.rate_n_flags = + iwl_mvm_v3_rate_from_fw(desc->v1.rate_n_flags, + mvm->fw_rates_ver); phy_data.channel = desc->v1.channel; phy_data.gp2_on_air_rise = le32_to_cpu(desc->v1.gp2_on_air_rise); phy_data.energy_a = desc->v1.energy_a; @@ -2084,13 +2088,6 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, phy_data.d3 = desc->v1.phy_data3; } - if (iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP, - REPLY_RX_MPDU_CMD, 0) < 4) { - phy_data.rate_n_flags = iwl_new_rate_from_v1(phy_data.rate_n_flags); - IWL_DEBUG_DROP(mvm, "Got old format rate, converting. New rate: 0x%x\n", - phy_data.rate_n_flags); - } - format = phy_data.rate_n_flags & RATE_MCS_MOD_TYPE_MSK; len = le16_to_cpu(desc->mpdu_len); @@ -2138,14 +2135,14 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, } /* set the preamble flag if appropriate */ - if (format == RATE_MCS_CCK_MSK && + if (format == RATE_MCS_MOD_TYPE_CCK && phy_data.phy_info & IWL_RX_MPDU_PHY_SHORT_PREAMBLE) rx_status->enc_flags |= RX_ENC_FLAG_SHORTPRE; if (likely(!(phy_data.phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD))) { u64 tsf_on_air_rise; - if (mvm->trans->trans_cfg->device_family >= + if (mvm->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) tsf_on_air_rise = le64_to_cpu(desc->v3.tsf_on_air_rise); else @@ -2157,7 +2154,8 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, } if (iwl_mvm_is_band_in_rx_supported(mvm)) { - u8 band = BAND_IN_RX_STATUS(desc->mac_phy_idx); + u8 band = u8_get_bits(desc->mac_phy_band, + IWL_RX_MPDU_MAC_PHY_BAND_BAND_MASK); rx_status->band = iwl_mvm_nl80211_band_from_phy(band); } else { @@ -2303,7 +2301,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, *qc &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; - if (mvm->trans->trans_cfg->device_family == + if (mvm->trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_9000) { iwl_mvm_flip_address(hdr->addr3); @@ -2349,7 +2347,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, if (!iwl_mvm_reorder(mvm, napi, queue, sta, skb, desc) && likely(!iwl_mvm_time_sync_frame(mvm, skb, hdr->addr2)) && likely(!iwl_mvm_mei_filter_scan(mvm, skb))) { - if (mvm->trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_9000 && + if (mvm->trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_9000 && (desc->mac_flags2 & IWL_RX_MPDU_MFLG2_AMSDU) && !(desc->amsdu_info & IWL_RX_MPDU_AMSDU_LAST_SUBFRAME)) rx_status->flag |= RX_FLAG_AMSDU_MORE; @@ -2383,7 +2381,6 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi, phy_data.d1 = desc->phy_info[1]; phy_data.phy_info = IWL_RX_MPDU_PHY_TSF_OVERLOAD; phy_data.gp2_on_air_rise = le32_to_cpu(desc->on_air_rise_time); - phy_data.rate_n_flags = le32_to_cpu(desc->rate); phy_data.energy_a = u32_get_bits(rssi, RX_NO_DATA_CHAIN_A_MSK); phy_data.energy_b = u32_get_bits(rssi, RX_NO_DATA_CHAIN_B_MSK); phy_data.channel = u32_get_bits(rssi, RX_NO_DATA_CHANNEL_MSK); @@ -2391,14 +2388,8 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi, phy_data.rx_vec[0] = desc->rx_vec[0]; phy_data.rx_vec[1] = desc->rx_vec[1]; - if (iwl_fw_lookup_notif_ver(mvm->fw, DATA_PATH_GROUP, - RX_NO_DATA_NOTIF, 0) < 2) { - IWL_DEBUG_DROP(mvm, "Got an old rate format. Old rate: 0x%x\n", - phy_data.rate_n_flags); - phy_data.rate_n_flags = iwl_new_rate_from_v1(phy_data.rate_n_flags); - IWL_DEBUG_DROP(mvm, " Rate after conversion to the new format: 0x%x\n", - phy_data.rate_n_flags); - } + phy_data.rate_n_flags = iwl_mvm_v3_rate_from_fw(desc->rate, + mvm->fw_rates_ver); format = phy_data.rate_n_flags & RATE_MCS_MOD_TYPE_MSK; @@ -2411,7 +2402,7 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi, phy_data.rx_vec[2] = desc->rx_vec[2]; phy_data.rx_vec[3] = desc->rx_vec[3]; } else { - if (format == RATE_MCS_EHT_MSK) + if (format == RATE_MCS_MOD_TYPE_EHT) /* no support for EHT before version 3 API */ return; } @@ -2472,17 +2463,17 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi, * may be up to 8 spatial streams. */ switch (format) { - case RATE_MCS_VHT_MSK: + case RATE_MCS_MOD_TYPE_VHT: rx_status->nss = le32_get_bits(desc->rx_vec[0], RX_NO_DATA_RX_VEC0_VHT_NSTS_MSK) + 1; break; - case RATE_MCS_HE_MSK: + case RATE_MCS_MOD_TYPE_HE: rx_status->nss = le32_get_bits(desc->rx_vec[0], RX_NO_DATA_RX_VEC0_HE_NSTS_MSK) + 1; break; - case RATE_MCS_EHT_MSK: + case RATE_MCS_MOD_TYPE_EHT: rx_status->nss = le32_get_bits(desc->rx_vec[2], RX_NO_DATA_RX_VEC2_EHT_NSTS_MSK) + 1; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 78fd7faaed97..8ec4a007b4b0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2015, 2018-2024 Intel Corporation + * Copyright (C) 2012-2015, 2018-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -791,10 +791,10 @@ static int iwl_mvm_find_free_queue(struct iwl_mvm *mvm, u8 sta_id, lockdep_assert_held(&mvm->mutex); - if (WARN(maxq >= mvm->trans->trans_cfg->base_params->num_of_queues, + if (WARN(maxq >= mvm->trans->mac_cfg->base->num_of_queues, "max queue %d >= num_of_queues (%d)", maxq, - mvm->trans->trans_cfg->base_params->num_of_queues)) - maxq = mvm->trans->trans_cfg->base_params->num_of_queues - 1; + mvm->trans->mac_cfg->base->num_of_queues)) + maxq = mvm->trans->mac_cfg->base->num_of_queues - 1; /* This should not be hit with new TX path */ if (WARN_ON(iwl_mvm_has_new_tx_api(mvm))) @@ -852,7 +852,7 @@ int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm, if (tid == IWL_MAX_TID_COUNT) { tid = IWL_MGMT_TID; size = max_t(u32, IWL_MGMT_QUEUE_SIZE, - mvm->trans->cfg->min_txq_size); + mvm->trans->mac_cfg->base->min_txq_size); } else { size = iwl_mvm_get_queue_size(sta); } @@ -1765,7 +1765,7 @@ int iwl_mvm_sta_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif, mvm_sta->deflink.sta_id = sta_id; rcu_assign_pointer(mvm_sta->link[0], &mvm_sta->deflink); - if (!mvm->trans->trans_cfg->gen2) + if (!mvm->trans->mac_cfg->gen2) mvm_sta->deflink.lq_sta.rs_drv.pers.max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF; else @@ -1798,7 +1798,7 @@ int iwl_mvm_sta_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif, if (iwl_mvm_has_new_rx_api(mvm)) { int q; - dup_data = kcalloc(mvm->trans->num_rx_queues, + dup_data = kcalloc(mvm->trans->info.num_rxqs, sizeof(*dup_data), GFP_KERNEL); if (!dup_data) return -ENOMEM; @@ -1811,7 +1811,7 @@ int iwl_mvm_sta_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif, * This thus allows receiving a packet with seqno 0 and the * retry bit set as the very first packet on a new TID. */ - for (q = 0; q < mvm->trans->num_rx_queues; q++) + for (q = 0; q < mvm->trans->info.num_rxqs; q++) memset(dup_data[q].last_seq, 0xff, sizeof(dup_data[q].last_seq)); mvm_sta->dup_data = dup_data; @@ -1839,11 +1839,11 @@ int iwl_mvm_sta_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif, if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p && !sta->tdls && ieee80211_vif_is_mld(vif)) { mvm_sta->mpdu_counters = - kcalloc(mvm->trans->num_rx_queues, + kcalloc(mvm->trans->info.num_rxqs, sizeof(*mvm_sta->mpdu_counters), GFP_KERNEL); if (mvm_sta->mpdu_counters) - for (int q = 0; q < mvm->trans->num_rx_queues; q++) + for (int q = 0; q < mvm->trans->info.num_rxqs; q++) spin_lock_init(&mvm_sta->mpdu_counters[q].lock); } @@ -2189,7 +2189,7 @@ static void iwl_mvm_enable_aux_snif_queue(struct iwl_mvm *mvm, u16 queue, u8 sta_id, u8 fifo) { unsigned int wdg_timeout = - mvm->trans->trans_cfg->base_params->wd_timeout; + mvm->trans->mac_cfg->base->wd_timeout; struct iwl_trans_txq_scd_cfg cfg = { .fifo = fifo, .sta_id = sta_id, @@ -2206,7 +2206,7 @@ static void iwl_mvm_enable_aux_snif_queue(struct iwl_mvm *mvm, u16 queue, static int iwl_mvm_enable_aux_snif_queue_tvqm(struct iwl_mvm *mvm, u8 sta_id) { unsigned int wdg_timeout = - mvm->trans->trans_cfg->base_params->wd_timeout; + mvm->trans->mac_cfg->base->wd_timeout; WARN_ON(!iwl_mvm_has_new_tx_api(mvm)); @@ -2717,7 +2717,7 @@ static void iwl_mvm_free_reorder(struct iwl_mvm *mvm, iwl_mvm_sync_rxq_del_ba(mvm, data->baid); - for (i = 0; i < mvm->trans->num_rx_queues; i++) { + for (i = 0; i < mvm->trans->info.num_rxqs; i++) { int j; struct iwl_mvm_reorder_buffer *reorder_buf = &data->reorder_buf[i]; @@ -2750,7 +2750,7 @@ static void iwl_mvm_init_reorder_buffer(struct iwl_mvm *mvm, { int i; - for (i = 0; i < mvm->trans->num_rx_queues; i++) { + for (i = 0; i < mvm->trans->info.num_rxqs; i++) { struct iwl_mvm_reorder_buffer *reorder_buf = &data->reorder_buf[i]; struct iwl_mvm_reorder_buf_entry *entries = @@ -2925,7 +2925,7 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, * before starting the BA session in the firmware */ baid_data = kzalloc(sizeof(*baid_data) + - mvm->trans->num_rx_queues * + mvm->trans->info.num_rxqs * reorder_buf_size, GFP_KERNEL); if (!baid_data) @@ -3177,7 +3177,7 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, * to align the wrap around of ssn so we compare relevant values. */ normalized_ssn = tid_data->ssn; - if (mvm->trans->trans_cfg->gen2) + if (mvm->trans->mac_cfg->gen2) normalized_ssn &= 0xff; if (normalized_ssn == tid_data->next_reclaimed) { @@ -4305,7 +4305,7 @@ u16 iwl_mvm_tid_queued(struct iwl_mvm *mvm, struct iwl_mvm_tid_data *tid_data) * In 22000 HW, the next_reclaimed index is only 8 bit, so we'll need * to align the wrap around of ssn so we compare relevant values. */ - if (mvm->trans->trans_cfg->gen2) + if (mvm->trans->mac_cfg->gen2) sn &= 0xff; return ieee80211_sn_sub(sn, tid_data->next_reclaimed); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h index 19c905b641e2..6b183f5e9bbc 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH * Copyright (C) 2015-2016 Intel Deutschland GmbH */ @@ -225,8 +225,6 @@ struct iwl_mvm_vif; * @IWL_AGG_ON: aggregation session is up * @IWL_EMPTYING_HW_QUEUE_ADDBA: establishing a BA session - waiting for the * HW queue to be empty from packets for this RA /TID. - * @IWL_EMPTYING_HW_QUEUE_DELBA: tearing down a BA session - waiting for the - * HW queue to be empty from packets for this RA /TID. */ enum iwl_mvm_agg_state { IWL_AGG_OFF = 0, @@ -234,7 +232,6 @@ enum iwl_mvm_agg_state { IWL_AGG_STARTING, IWL_AGG_ON, IWL_EMPTYING_HW_QUEUE_ADDBA, - IWL_EMPTYING_HW_QUEUE_DELBA, }; /** @@ -262,7 +259,7 @@ struct iwl_mvm_tid_data { u16 seq_number; u16 next_reclaimed; /* The rest is Tx AGG related */ - u32 rate_n_flags; + __le32 rate_n_flags; u8 lq_color; bool amsdu_in_ampdu_allowed; enum iwl_mvm_agg_state state; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tests/Makefile b/drivers/net/wireless/intel/iwlwifi/mvm/tests/Makefile index 6bd56a28cffd..895d53f223e9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tests/Makefile +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tests/Makefile @@ -1,3 +1,3 @@ -iwlmvm-tests-y += module.o links.o scan.o +iwlmvm-tests-y += module.o links.o scan.o hcmd.o obj-$(CONFIG_IWLWIFI_KUNIT_TESTS) += iwlmvm-tests.o diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tests/hcmd.c b/drivers/net/wireless/intel/iwlwifi/mvm/tests/hcmd.c new file mode 100644 index 000000000000..1fee0320c756 --- /dev/null +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tests/hcmd.c @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * KUnit tests for channel helper functions + * + * Copyright (C) 2025 Intel Corporation + */ +#include <kunit/test.h> + +#include <iwl-trans.h> +#include "../mvm.h" + +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); + +static void test_hcmd_names_sorted(struct kunit *test) +{ + for (int i = 0; i < iwl_mvm_groups_size; i++) { + const struct iwl_hcmd_arr *arr = &iwl_mvm_groups[i]; + + if (!arr->arr) + continue; + + for (int j = 0; j < arr->size - 1; j++) + KUNIT_EXPECT_LE(test, arr->arr[j].cmd_id, + arr->arr[j + 1].cmd_id); + } +} + +static struct kunit_case hcmd_names_cases[] = { + KUNIT_CASE(test_hcmd_names_sorted), + {}, +}; + +static struct kunit_suite hcmd_names = { + .name = "iwlmvm-hcmd-names", + .test_cases = hcmd_names_cases, +}; + +kunit_test_suite(hcmd_names); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c index 1a30bb1ff8ca..478408f802d9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c @@ -771,15 +771,17 @@ static void iwl_mvm_cancel_session_protection(struct iwl_mvm *mvm, static void iwl_mvm_roc_rm_cmd(struct iwl_mvm *mvm, u32 activity) { - struct iwl_roc_req_v5 roc_cmd = { + struct iwl_roc_req roc_cmd = { .action = cpu_to_le32(FW_CTXT_ACTION_REMOVE), .activity = cpu_to_le32(activity), }; + u8 ver = iwl_fw_lookup_cmd_ver(mvm->fw, WIDE_ID(MAC_CONF_GROUP, ROC_CMD), 0); + u16 cmd_len = ver < 6 ? sizeof(struct iwl_roc_req_v5) : sizeof(roc_cmd); int ret; lockdep_assert_held(&mvm->mutex); ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(MAC_CONF_GROUP, ROC_CMD), 0, - sizeof(roc_cmd), &roc_cmd); + cmd_len, &roc_cmd); if (ret) IWL_ERR(mvm, "Couldn't send the ROC_CMD: %d\n", ret); } @@ -1102,11 +1104,13 @@ int iwl_mvm_roc_add_cmd(struct iwl_mvm *mvm, { int res; u32 duration_tu, delay; - struct iwl_roc_req_v5 roc_req = { + struct iwl_roc_req roc_req = { .action = cpu_to_le32(FW_CTXT_ACTION_ADD), .activity = cpu_to_le32(activity), .sta_id = cpu_to_le32(mvm->aux_sta.sta_id), }; + u8 ver = iwl_fw_lookup_cmd_ver(mvm->fw, WIDE_ID(MAC_CONF_GROUP, ROC_CMD), 0); + u16 cmd_len = ver < 6 ? sizeof(struct iwl_roc_req_v5) : sizeof(roc_req); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); lockdep_assert_held(&mvm->mutex); @@ -1136,7 +1140,7 @@ int iwl_mvm_roc_add_cmd(struct iwl_mvm *mvm, memcpy(roc_req.node_addr, vif->addr, ETH_ALEN); res = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(MAC_CONF_GROUP, ROC_CMD), - 0, sizeof(roc_req), &roc_req); + 0, cmd_len, &roc_req); if (!res) mvmvif->roc_activity = activity; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c index c851290e75a2..53bab21ebae2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2019-2022, 2024 Intel Corporation + * Copyright (C) 2012-2014, 2019-2022, 2024-2025 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH * Copyright (C) 2015-2016 Intel Deutschland GmbH */ @@ -8,6 +8,9 @@ #include "mvm.h" +#define IWL_MVM_NUM_CTDP_STEPS 20 +#define IWL_MVM_MIN_CTDP_BUDGET_MW 150 + #define IWL_MVM_TEMP_NOTIF_WAIT_TIMEOUT HZ void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm) @@ -479,43 +482,28 @@ static const struct iwl_tt_params iwl_mvm_default_tt_params = { .support_tx_backoff = true, }; -/* budget in mWatt */ -static const u32 iwl_mvm_cdev_budgets[] = { - 2400, /* cooling state 0 */ - 2000, /* cooling state 1 */ - 1800, /* cooling state 2 */ - 1600, /* cooling state 3 */ - 1400, /* cooling state 4 */ - 1200, /* cooling state 5 */ - 1000, /* cooling state 6 */ - 900, /* cooling state 7 */ - 800, /* cooling state 8 */ - 700, /* cooling state 9 */ - 650, /* cooling state 10 */ - 600, /* cooling state 11 */ - 550, /* cooling state 12 */ - 500, /* cooling state 13 */ - 450, /* cooling state 14 */ - 400, /* cooling state 15 */ - 350, /* cooling state 16 */ - 300, /* cooling state 17 */ - 250, /* cooling state 18 */ - 200, /* cooling state 19 */ - 150, /* cooling state 20 */ -}; - int iwl_mvm_ctdp_command(struct iwl_mvm *mvm, u32 op, u32 state) { struct iwl_ctdp_cmd cmd = { .operation = cpu_to_le32(op), - .budget = cpu_to_le32(iwl_mvm_cdev_budgets[state]), .window_size = 0, }; + u32 budget; int ret; u32 status; lockdep_assert_held(&mvm->mutex); + /* Do a linear scale from IWL_MVM_MIN_CTDP_BUDGET_MW to the configured + * maximum in the predefined number of steps. + */ + budget = ((mvm->thermal_throttle.power_budget_mw - + IWL_MVM_MIN_CTDP_BUDGET_MW) * + (IWL_MVM_NUM_CTDP_STEPS - 1 - state)) / + (IWL_MVM_NUM_CTDP_STEPS - 1) + + IWL_MVM_MIN_CTDP_BUDGET_MW; + cmd.budget = cpu_to_le32(budget); + status = 0; ret = iwl_mvm_send_cmd_pdu_status(mvm, WIDE_ID(PHY_OPS_GROUP, CTDP_CONFIG_CMD), @@ -552,8 +540,8 @@ int iwl_mvm_ctdp_command(struct iwl_mvm *mvm, u32 op, u32 state) #ifdef CONFIG_THERMAL static int compare_temps(const void *a, const void *b) { - return ((s16)le16_to_cpu(*(__le16 *)a) - - (s16)le16_to_cpu(*(__le16 *)b)); + return ((s16)le16_to_cpu(*(const __le16 *)a) - + (s16)le16_to_cpu(*(const __le16 *)b)); } struct iwl_trip_walk_data { @@ -707,7 +695,7 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm) static int iwl_mvm_tcool_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state) { - *state = ARRAY_SIZE(iwl_mvm_cdev_budgets) - 1; + *state = IWL_MVM_NUM_CTDP_STEPS - 1; return 0; } @@ -733,7 +721,7 @@ static int iwl_mvm_tcool_set_cur_state(struct thermal_cooling_device *cdev, mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) return -EIO; - if (new_state >= ARRAY_SIZE(iwl_mvm_cdev_budgets)) + if (new_state >= IWL_MVM_NUM_CTDP_STEPS) return -EINVAL; return iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_START, @@ -794,6 +782,47 @@ static void iwl_mvm_cooling_device_unregister(struct iwl_mvm *mvm) } #endif /* CONFIG_THERMAL */ +static u32 iwl_mvm_ctdp_get_max_budget(struct iwl_mvm *mvm) +{ + u64 bios_power_budget = 0; + u32 default_power_budget; + + switch (CSR_HW_RFID_TYPE(mvm->trans->info.hw_rf_id)) { + case IWL_CFG_RF_TYPE_JF2: + case IWL_CFG_RF_TYPE_JF1: + default_power_budget = 2000; + break; + case IWL_CFG_RF_TYPE_HR2: + case IWL_CFG_RF_TYPE_HR1: + default_power_budget = 2400; + break; + case IWL_CFG_RF_TYPE_GF: + /* dual-radio devices have a higher budget */ + if (CSR_HW_RFID_IS_CDB(mvm->trans->info.hw_rf_id)) + default_power_budget = 5200; + else + default_power_budget = 2880; + break; + case IWL_CFG_RF_TYPE_FM: + default_power_budget = 3450; + break; + default: + default_power_budget = 5550; + break; + } + + iwl_bios_get_pwr_limit(&mvm->fwrt, &bios_power_budget); + + /* 32bit in UEFI, 16bit in ACPI; use BIOS value if it is in range */ + if (bios_power_budget && + bios_power_budget != 0xffff && bios_power_budget != 0xffffffff && + bios_power_budget >= IWL_MVM_MIN_CTDP_BUDGET_MW && + bios_power_budget <= default_power_budget) + return (u32)bios_power_budget; + + return default_power_budget; +} + void iwl_mvm_thermal_initialize(struct iwl_mvm *mvm, u32 min_backoff) { struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle; @@ -805,6 +834,8 @@ void iwl_mvm_thermal_initialize(struct iwl_mvm *mvm, u32 min_backoff) else tt->params = iwl_mvm_default_tt_params; + tt->power_budget_mw = iwl_mvm_ctdp_get_max_budget(mvm); + IWL_DEBUG_TEMP(mvm, "cTDP power budget: %d mW\n", tt->power_budget_mw); tt->throttle = false; tt->dynamic_smps = false; tt->min_backoff = min_backoff; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index f67afb66ef2b..ac2cf1b8ce23 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -148,7 +148,7 @@ out: * Sets most of the Tx cmd's fields */ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, - struct iwl_tx_cmd *tx_cmd, + struct iwl_tx_cmd_v6 *tx_cmd, struct ieee80211_tx_info *info, u8 sta_id) { struct ieee80211_hdr *hdr = (void *)skb->data; @@ -283,14 +283,10 @@ static u32 iwl_mvm_convert_rate_idx(struct iwl_mvm *mvm, (rate_idx <= IWL_LAST_CCK_RATE); /* Set CCK or OFDM flag */ - if (iwl_fw_lookup_cmd_ver(mvm->fw, TX_CMD, 0) > 8) { - if (!is_cck) - rate_flags |= RATE_MCS_LEGACY_OFDM_MSK; - else - rate_flags |= RATE_MCS_CCK_MSK; - } else if (is_cck) { - rate_flags |= RATE_MCS_CCK_MSK_V1; - } + if (!is_cck) + rate_flags |= RATE_MCS_MOD_TYPE_LEGACY_OFDM; + else + rate_flags |= RATE_MCS_MOD_TYPE_CCK; return (u32)rate_plcp | rate_flags; } @@ -303,45 +299,35 @@ static u32 iwl_mvm_get_inject_tx_rate(struct iwl_mvm *mvm, struct ieee80211_tx_rate *rate = &info->control.rates[0]; u32 result; - /* - * we only care about legacy/HT/VHT so far, so we can - * build in v1 and use iwl_new_rate_from_v1() - */ - if (rate->flags & IEEE80211_TX_RC_VHT_MCS) { u8 mcs = ieee80211_rate_get_vht_mcs(rate); u8 nss = ieee80211_rate_get_vht_nss(rate); - result = RATE_MCS_VHT_MSK_V1; + result = RATE_MCS_MOD_TYPE_VHT; result |= u32_encode_bits(mcs, RATE_VHT_MCS_RATE_CODE_MSK); result |= u32_encode_bits(nss, RATE_MCS_NSS_MSK); if (rate->flags & IEEE80211_TX_RC_SHORT_GI) - result |= RATE_MCS_SGI_MSK_V1; + result |= RATE_MCS_SGI_MSK; if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) - result |= u32_encode_bits(1, RATE_MCS_CHAN_WIDTH_MSK_V1); + result |= RATE_MCS_CHAN_WIDTH_40; else if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH) - result |= u32_encode_bits(2, RATE_MCS_CHAN_WIDTH_MSK_V1); + result |= RATE_MCS_CHAN_WIDTH_80; else if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH) - result |= u32_encode_bits(3, RATE_MCS_CHAN_WIDTH_MSK_V1); - - if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP, TX_CMD, 0) > 6) - result = iwl_new_rate_from_v1(result); + result |= RATE_MCS_CHAN_WIDTH_160; } else if (rate->flags & IEEE80211_TX_RC_MCS) { - result = RATE_MCS_HT_MSK_V1; - result |= u32_encode_bits(rate->idx, - RATE_HT_MCS_RATE_CODE_MSK_V1 | - RATE_HT_MCS_NSS_MSK_V1); + result = RATE_MCS_MOD_TYPE_HT; + result |= u32_encode_bits(rate->idx & 0x7, + RATE_HT_MCS_CODE_MSK); + result |= u32_encode_bits(rate->idx >> 3, + RATE_MCS_NSS_MSK); if (rate->flags & IEEE80211_TX_RC_SHORT_GI) - result |= RATE_MCS_SGI_MSK_V1; + result |= RATE_MCS_SGI_MSK; if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) - result |= u32_encode_bits(1, RATE_MCS_CHAN_WIDTH_MSK_V1); + result |= RATE_MCS_CHAN_WIDTH_40; if (info->flags & IEEE80211_TX_CTL_LDPC) - result |= RATE_MCS_LDPC_MSK_V1; + result |= RATE_MCS_LDPC_MSK; if (u32_get_bits(info->flags, IEEE80211_TX_CTL_STBC)) result |= RATE_MCS_STBC_MSK; - - if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP, TX_CMD, 0) > 6) - result = iwl_new_rate_from_v1(result); } else { int rate_idx = info->control.rates[0].idx; @@ -391,21 +377,25 @@ static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm, return iwl_mvm_convert_rate_idx(mvm, info, rate_idx); } -static u32 iwl_mvm_get_tx_rate_n_flags(struct iwl_mvm *mvm, - struct ieee80211_tx_info *info, - struct ieee80211_sta *sta, __le16 fc) +static __le32 iwl_mvm_get_tx_rate_n_flags(struct iwl_mvm *mvm, + struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, __le16 fc) { + u32 rate; + if (unlikely(info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT)) - return iwl_mvm_get_inject_tx_rate(mvm, info, sta, fc); + rate = iwl_mvm_get_inject_tx_rate(mvm, info, sta, fc); + else + rate = iwl_mvm_get_tx_rate(mvm, info, sta, fc) | + iwl_mvm_get_tx_ant(mvm, info, sta, fc); - return iwl_mvm_get_tx_rate(mvm, info, sta, fc) | - iwl_mvm_get_tx_ant(mvm, info, sta, fc); + return iwl_mvm_v3_rate_to_fw(rate, mvm->fw_rates_ver); } /* * Sets the fields in the Tx cmd that are rate related */ -void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd *tx_cmd, +void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd_v6 *tx_cmd, struct ieee80211_tx_info *info, struct ieee80211_sta *sta, __le16 fc) { @@ -443,8 +433,7 @@ void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd *tx_cmd, } /* Set the rate in the TX cmd */ - tx_cmd->rate_n_flags = - cpu_to_le32(iwl_mvm_get_tx_rate_n_flags(mvm, info, sta, fc)); + tx_cmd->rate_n_flags = iwl_mvm_get_tx_rate_n_flags(mvm, info, sta, fc); } static inline void iwl_mvm_set_tx_cmd_pn(struct ieee80211_tx_info *info, @@ -469,7 +458,7 @@ static inline void iwl_mvm_set_tx_cmd_pn(struct ieee80211_tx_info *info, */ static void iwl_mvm_set_tx_cmd_crypto(struct iwl_mvm *mvm, struct ieee80211_tx_info *info, - struct iwl_tx_cmd *tx_cmd, + struct iwl_tx_cmd_v6 *tx_cmd, struct sk_buff *skb_frag, int hdrlen) { @@ -543,7 +532,7 @@ static bool iwl_mvm_use_host_rate(struct iwl_mvm *mvm, * (since we don't necesarily know the link), but FW rate * selection was fixed. */ - return mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_BZ; + return mvm->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_BZ; } static void iwl_mvm_copy_hdr(void *cmd, const void *hdr, int hdrlen, @@ -567,7 +556,7 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct iwl_device_tx_cmd *dev_cmd; - struct iwl_tx_cmd *tx_cmd; + struct iwl_tx_cmd_v6 *tx_cmd; dev_cmd = iwl_trans_alloc_tx_cmd(mvm->trans); @@ -577,7 +566,7 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, dev_cmd->hdr.cmd = TX_CMD; if (iwl_mvm_has_new_tx_api(mvm)) { - u32 rate_n_flags = 0; + __le32 rate_n_flags = 0; u16 flags = 0; struct iwl_mvm_sta *mvmsta = sta ? iwl_mvm_sta_from_mac80211(sta) : NULL; @@ -609,9 +598,9 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, flags |= IWL_TX_FLAGS_HIGH_PRI; } - if (mvm->trans->trans_cfg->device_family >= + if (mvm->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { - struct iwl_tx_cmd_gen3 *cmd = (void *)dev_cmd->payload; + struct iwl_tx_cmd *cmd = (void *)dev_cmd->payload; u32 offload_assist = iwl_mvm_tx_csum(mvm, skb, info, amsdu); @@ -624,9 +613,9 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, iwl_mvm_copy_hdr(cmd->hdr, hdr, hdrlen, addr3_override); cmd->flags = cpu_to_le16(flags); - cmd->rate_n_flags = cpu_to_le32(rate_n_flags); + cmd->rate_n_flags = rate_n_flags; } else { - struct iwl_tx_cmd_gen2 *cmd = (void *)dev_cmd->payload; + struct iwl_tx_cmd_v9 *cmd = (void *)dev_cmd->payload; u16 offload_assist = iwl_mvm_tx_csum(mvm, skb, info, amsdu); @@ -639,12 +628,12 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, iwl_mvm_copy_hdr(cmd->hdr, hdr, hdrlen, addr3_override); cmd->flags = cpu_to_le32(flags); - cmd->rate_n_flags = cpu_to_le32(rate_n_flags); + cmd->rate_n_flags = rate_n_flags; } goto out; } - tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload; + tx_cmd = (struct iwl_tx_cmd_v6 *)dev_cmd->payload; if (info->control.hw_key) iwl_mvm_set_tx_cmd_crypto(mvm, info, tx_cmd, skb, hdrlen); @@ -1023,7 +1012,7 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, * 1 more for the potential data in the header */ if ((num_subframes * 2 + skb_shinfo(skb)->nr_frags + 1) > - mvm->trans->max_skb_frags) + mvm->trans->info.max_skb_frags) num_subframes = 1; if (num_subframes > 1) @@ -1185,7 +1174,7 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb, seq_number &= IEEE80211_SCTL_SEQ; if (!iwl_mvm_has_new_tx_api(mvm)) { - struct iwl_tx_cmd *tx_cmd = (void *)dev_cmd->payload; + struct iwl_tx_cmd_v6 *tx_cmd = (void *)dev_cmd->payload; hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); hdr->seq_ctrl |= cpu_to_le16(seq_number); @@ -1372,8 +1361,7 @@ static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm, lockdep_assert_held(&mvmsta->lock); - if ((tid_data->state == IWL_AGG_ON || - tid_data->state == IWL_EMPTYING_HW_QUEUE_DELBA) && + if (tid_data->state == IWL_AGG_ON && iwl_mvm_tid_queued(mvm, tid_data) == 0) { /* * Now that this aggregation or DQA queue is empty tell @@ -1388,7 +1376,7 @@ static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm, * to align the wrap around of ssn so we compare relevant values. */ normalized_ssn = tid_data->ssn; - if (mvm->trans->trans_cfg->gen2) + if (mvm->trans->mac_cfg->gen2) normalized_ssn &= 0xff; if (normalized_ssn != tid_data->next_reclaimed) @@ -1402,15 +1390,6 @@ static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm, tid_data->state = IWL_AGG_STARTING; ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; - - case IWL_EMPTYING_HW_QUEUE_DELBA: - IWL_DEBUG_TX_QUEUES(mvm, - "Can continue DELBA flow ssn = next_recl = %d\n", - tid_data->next_reclaimed); - tid_data->state = IWL_AGG_OFF; - ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); - break; - default: break; } @@ -1477,7 +1456,7 @@ void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags, struct ieee80211_tx_rate *r) { u32 format = rate_n_flags & RATE_MCS_MOD_TYPE_MSK; - u32 rate = format == RATE_MCS_HT_MSK ? + u32 rate = format == RATE_MCS_MOD_TYPE_HT ? RATE_HT_MCS_INDEX(rate_n_flags) : rate_n_flags & RATE_MCS_CODE_MSK; @@ -1487,68 +1466,51 @@ void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags, if (rate_n_flags & RATE_MCS_SGI_MSK) r->flags |= IEEE80211_TX_RC_SHORT_GI; - if (format == RATE_MCS_HT_MSK) { + switch (format) { + case RATE_MCS_MOD_TYPE_HT: r->flags |= IEEE80211_TX_RC_MCS; r->idx = rate; - } else if (format == RATE_MCS_VHT_MSK) { + break; + case RATE_MCS_MOD_TYPE_VHT: ieee80211_rate_set_vht(r, rate, FIELD_GET(RATE_MCS_NSS_MSK, rate_n_flags) + 1); r->flags |= IEEE80211_TX_RC_VHT_MCS; - } else if (format == RATE_MCS_HE_MSK) { + break; + case RATE_MCS_MOD_TYPE_HE: + case RATE_MCS_MOD_TYPE_EHT: /* mac80211 cannot do this without ieee80211_tx_status_ext() * but it only matters for radiotap */ r->idx = 0; - } else { + break; + default: r->idx = iwl_mvm_legacy_hw_idx_to_mac80211_idx(rate_n_flags, band); } } -void iwl_mvm_hwrate_to_tx_rate_v1(u32 rate_n_flags, - enum nl80211_band band, - struct ieee80211_tx_rate *r) -{ - if (rate_n_flags & RATE_HT_MCS_GF_MSK) - r->flags |= IEEE80211_TX_RC_GREEN_FIELD; - - r->flags |= - iwl_mvm_get_hwrate_chan_width(rate_n_flags & - RATE_MCS_CHAN_WIDTH_MSK_V1); - - if (rate_n_flags & RATE_MCS_SGI_MSK_V1) - r->flags |= IEEE80211_TX_RC_SHORT_GI; - if (rate_n_flags & RATE_MCS_HT_MSK_V1) { - r->flags |= IEEE80211_TX_RC_MCS; - r->idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK_V1; - } else if (rate_n_flags & RATE_MCS_VHT_MSK_V1) { - ieee80211_rate_set_vht( - r, rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK, - FIELD_GET(RATE_MCS_NSS_MSK, rate_n_flags) + 1); - r->flags |= IEEE80211_TX_RC_VHT_MCS; - } else { - r->idx = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags, - band); - } -} - /* * translate ucode response to mac80211 tx status control values */ -static void iwl_mvm_hwrate_to_tx_status(const struct iwl_fw *fw, - u32 rate_n_flags, +static void iwl_mvm_hwrate_to_tx_status(struct iwl_mvm *mvm, + __le32 rate_n_flags, struct ieee80211_tx_info *info) { struct ieee80211_tx_rate *r = &info->status.rates[0]; + u32 rate; - if (iwl_fw_lookup_notif_ver(fw, LONG_GROUP, - TX_CMD, 0) <= 6) - rate_n_flags = iwl_new_rate_from_v1(rate_n_flags); + /* + * Technically this conversion is incorrect for BA status, however: + * - we only use the BA notif data for older firmware that have + * host rate scaling and don't use newer rate formats + * - the firmware API changed together for BA notif and TX CMD + * as well + */ + rate = iwl_mvm_v3_rate_from_fw(rate_n_flags, mvm->fw_rates_ver); info->status.antenna = - ((rate_n_flags & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS); - iwl_mvm_hwrate_to_tx_rate(rate_n_flags, - info->band, r); + ((rate & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS); + iwl_mvm_hwrate_to_tx_rate(rate, info->band, r); } static void iwl_mvm_tx_status_check_trigger(struct iwl_mvm *mvm, @@ -1613,7 +1575,7 @@ static inline u32 iwl_mvm_get_scd_ssn(struct iwl_mvm *mvm, u32 val = le32_to_cpup((__le32 *)iwl_mvm_get_agg_status(mvm, tx_resp) + tx_resp->frame_count); - if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) + if (mvm->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) return val & 0xFFFF; return val & 0xFFF; } @@ -1700,9 +1662,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, info->status.rates[0].count = tx_resp->failure_frame + 1; - iwl_mvm_hwrate_to_tx_status(mvm->fw, - le32_to_cpu(tx_resp->initial_rate), - info); + iwl_mvm_hwrate_to_tx_status(mvm, tx_resp->initial_rate, info); /* Don't assign the converted initial_rate, because driver * TLC uses this and doesn't support the new FW rate @@ -1944,7 +1904,7 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm, if (!WARN_ON_ONCE(!mvmsta)) { mvmsta->tid_data[tid].rate_n_flags = - le32_to_cpu(tx_resp->initial_rate); + tx_resp->initial_rate; mvmsta->tid_data[tid].tx_time = le16_to_cpu(tx_resp->wireless_media_time); mvmsta->tid_data[tid].lq_color = @@ -1969,7 +1929,7 @@ void iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid, int txq, int index, - struct ieee80211_tx_info *tx_info, u32 rate, + struct ieee80211_tx_info *tx_info, __le32 rate, bool is_flush) { struct sk_buff_head reclaimed_skbs; @@ -2053,7 +2013,9 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid, tx_info->status.status_driver_data[0] = RS_DRV_DATA_PACK(tid_data->lq_color, tx_info->status.status_driver_data[0]); - tx_info->status.status_driver_data[1] = (void *)(uintptr_t)rate; + /* the value is only consumed for old FW that has v1 rates anyway */ + tx_info->status.status_driver_data[1] = + (void *)(uintptr_t)le32_to_cpu(rate); skb_queue_walk(&reclaimed_skbs, skb) { struct ieee80211_hdr *hdr = (void *)skb->data; @@ -2072,7 +2034,7 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid, info->flags |= IEEE80211_TX_STAT_AMPDU; memcpy(&info->status, &tx_info->status, sizeof(tx_info->status)); - iwl_mvm_hwrate_to_tx_status(mvm->fw, rate, info); + iwl_mvm_hwrate_to_tx_status(mvm, rate, info); } } @@ -2095,7 +2057,7 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid, goto out; tx_info->band = chanctx_conf->def.chan->band; - iwl_mvm_hwrate_to_tx_status(mvm->fw, rate, tx_info); + iwl_mvm_hwrate_to_tx_status(mvm, rate, tx_info); IWL_DEBUG_TX_REPLY(mvm, "No reclaim. Update rs directly\n"); iwl_mvm_rs_tx_status(mvm, sta, tid, tx_info, false); @@ -2184,7 +2146,7 @@ void iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) (int)(le16_to_cpu(ba_tfd->q_num)), le16_to_cpu(ba_tfd->tfd_index), &ba_info, - le32_to_cpu(ba_res->tx_rate), false); + ba_res->tx_rate, false); } if (mvmsta) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index dd890dcd1505..62da0132f383 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH */ @@ -142,7 +142,7 @@ int iwl_mvm_legacy_hw_idx_to_mac80211_idx(u32 rate_n_flags, int rate = rate_n_flags & RATE_LEGACY_RATE_MSK; bool is_LB = band == NL80211_BAND_2GHZ; - if (format == RATE_MCS_LEGACY_OFDM_MSK) + if (format == RATE_MCS_MOD_TYPE_LEGACY_OFDM) return is_LB ? rate + IWL_FIRST_OFDM_RATE : rate; @@ -169,15 +169,9 @@ int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, u8 iwl_mvm_mac80211_idx_to_hwrate(const struct iwl_fw *fw, int rate_idx) { - if (iwl_fw_lookup_cmd_ver(fw, TX_CMD, 0) > 8) - /* In the new rate legacy rates are indexed: - * 0 - 3 for CCK and 0 - 7 for OFDM. - */ - return (rate_idx >= IWL_FIRST_OFDM_RATE ? - rate_idx - IWL_FIRST_OFDM_RATE : - rate_idx); - - return iwl_fw_rate_idx_to_plcp(rate_idx); + return (rate_idx >= IWL_FIRST_OFDM_RATE ? + rate_idx - IWL_FIRST_OFDM_RATE : + rate_idx); } u8 iwl_mvm_mac80211_ac_to_ucode_ac(enum ieee80211_ac_numbers ac) @@ -748,7 +742,7 @@ unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { unsigned int default_timeout = - mvm->trans->trans_cfg->base_params->wd_timeout; + mvm->trans->mac_cfg->base->wd_timeout; /* * We can't know when the station is asleep or awake, so we @@ -1187,9 +1181,9 @@ u32 iwl_mvm_get_systime(struct iwl_mvm *mvm) { u32 reg_addr = DEVICE_SYSTEM_TIME_REG; - if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000 && - mvm->trans->cfg->gp2_reg_addr) - reg_addr = mvm->trans->cfg->gp2_reg_addr; + if (mvm->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_22000 && + mvm->trans->mac_cfg->base->gp2_reg_addr) + reg_addr = mvm->trans->mac_cfg->base->gp2_reg_addr; return iwl_read_prph(mvm->trans, reg_addr); } diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-v2.c index 8aa7c455bdee..976fd1f58da4 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-v2.c @@ -5,7 +5,7 @@ #include <linux/dmi.h> #include "iwl-trans.h" #include "iwl-fh.h" -#include "iwl-context-info-gen3.h" +#include "iwl-context-info-v2.h" #include "internal.h" #include "iwl-prph.h" @@ -97,11 +97,12 @@ out: *control_flags |= IWL_PRPH_SCRATCH_EARLY_DEBUG_EN | dbg_flags; } -int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, - const struct fw_img *fw) +int iwl_pcie_ctxt_info_v2_alloc(struct iwl_trans *trans, + const struct iwl_fw *fw, + const struct fw_img *img) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_context_info_gen3 *ctxt_info_gen3; + struct iwl_context_info_v2 *ctxt_info_v2; struct iwl_prph_scratch *prph_scratch; struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl; struct iwl_prph_info *prph_info; @@ -109,9 +110,9 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, u32 control_flags_ext = 0; int ret; int cmdq_size = max_t(u32, IWL_CMD_QUEUE_SIZE, - trans->cfg->min_txq_size); + trans->mac_cfg->base->min_txq_size); - switch (trans_pcie->rx_buf_size) { + switch (trans->conf.rx_buf_size) { case IWL_AMSDU_DEF: return -EINVAL; case IWL_AMSDU_2K: @@ -131,13 +132,13 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, break; } - if (trans->dsbr_urm_fw_dependent) + if (trans->conf.dsbr_urm_fw_dependent) control_flags_ext |= IWL_PRPH_SCRATCH_EXT_URM_FW; - if (trans->dsbr_urm_permanent) + if (trans->conf.dsbr_urm_permanent) control_flags_ext |= IWL_PRPH_SCRATCH_EXT_URM_PERM; - if (trans->ext_32khz_clock_valid) + if (trans->conf.ext_32khz_clock_valid) control_flags_ext |= IWL_PRPH_SCRATCH_EXT_32KHZ_CLK_VALID; /* Allocate prph scratch */ @@ -151,16 +152,16 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, prph_sc_ctrl->version.version = 0; prph_sc_ctrl->version.mac_id = - cpu_to_le16((u16)trans->hw_rev); + cpu_to_le16((u16)trans->info.hw_rev); prph_sc_ctrl->version.size = cpu_to_le16(sizeof(*prph_scratch) / 4); control_flags |= IWL_PRPH_SCRATCH_MTR_MODE; control_flags |= IWL_PRPH_MTR_FORMAT_256B & IWL_PRPH_SCRATCH_MTR_FORMAT; - if (trans->trans_cfg->imr_enabled) + if (trans->mac_cfg->imr_enabled) control_flags |= IWL_PRPH_SCRATCH_IMR_DEBUG_EN; - if (CSR_HW_REV_TYPE(trans->hw_rev) == IWL_CFG_MAC_TYPE_GL && + if (CSR_HW_REV_TYPE(trans->info.hw_rev) == IWL_CFG_MAC_TYPE_GL && iwl_is_force_scu_active_approved()) { control_flags |= IWL_PRPH_SCRATCH_SCU_FORCE_ACTIVE; IWL_DEBUG_FW(trans, @@ -168,6 +169,11 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, IWL_PRPH_SCRATCH_SCU_FORCE_ACTIVE); } + if (trans->do_top_reset) { + WARN_ON(trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_SC); + control_flags |= IWL_PRPH_SCRATCH_TOP_RESET; + } + /* initialize RX default queue */ prph_sc_ctrl->rbd_cfg.free_rbd_addr = cpu_to_le64(trans_pcie->rxq->bd_dma); @@ -178,15 +184,16 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, prph_sc_ctrl->control.control_flags_ext = cpu_to_le32(control_flags_ext); /* initialize the Step equalizer data */ - prph_sc_ctrl->step_cfg.mbx_addr_0 = cpu_to_le32(trans->mbx_addr_0_step); - prph_sc_ctrl->step_cfg.mbx_addr_1 = cpu_to_le32(trans->mbx_addr_1_step); + prph_sc_ctrl->step_cfg.mbx_addr_0 = + cpu_to_le32(trans->conf.mbx_addr_0_step); + prph_sc_ctrl->step_cfg.mbx_addr_1 = + cpu_to_le32(trans->conf.mbx_addr_1_step); /* allocate ucode sections in dram and set addresses */ - ret = iwl_pcie_init_fw_sec(trans, fw, &prph_scratch->dram); + ret = iwl_pcie_init_fw_sec(trans, img, &prph_scratch->dram.common); if (ret) goto err_free_prph_scratch; - /* Allocate prph information * currently we don't assign to the prph info anything, but it would get * assigned later @@ -206,42 +213,58 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, } /* Allocate context info */ - ctxt_info_gen3 = dma_alloc_coherent(trans->dev, - sizeof(*ctxt_info_gen3), - &trans_pcie->ctxt_info_dma_addr, - GFP_KERNEL); - if (!ctxt_info_gen3) { + ctxt_info_v2 = dma_alloc_coherent(trans->dev, + sizeof(*ctxt_info_v2), + &trans_pcie->ctxt_info_dma_addr, + GFP_KERNEL); + if (!ctxt_info_v2) { ret = -ENOMEM; goto err_free_prph_info; } - ctxt_info_gen3->prph_info_base_addr = + ctxt_info_v2->prph_info_base_addr = cpu_to_le64(trans_pcie->prph_info_dma_addr); - ctxt_info_gen3->prph_scratch_base_addr = + ctxt_info_v2->prph_scratch_base_addr = cpu_to_le64(trans_pcie->prph_scratch_dma_addr); - ctxt_info_gen3->prph_scratch_size = - cpu_to_le32(sizeof(*prph_scratch)); - ctxt_info_gen3->cr_head_idx_arr_base_addr = + + /* + * This code assumes the FSEQ is last and we can make that + * optional; old devices _should_ be fine with a bigger size, + * but in simulation we check the size more precisely. + */ + BUILD_BUG_ON(offsetofend(typeof(*prph_scratch), dram.common) + + sizeof(prph_scratch->dram.fseq_img) != + sizeof(*prph_scratch)); + if (control_flags_ext & IWL_PRPH_SCRATCH_EXT_EXT_FSEQ) + ctxt_info_v2->prph_scratch_size = + cpu_to_le32(sizeof(*prph_scratch)); + else + ctxt_info_v2->prph_scratch_size = + cpu_to_le32(offsetofend(typeof(*prph_scratch), + dram.common)); + + ctxt_info_v2->cr_head_idx_arr_base_addr = cpu_to_le64(trans_pcie->rxq->rb_stts_dma); - ctxt_info_gen3->tr_tail_idx_arr_base_addr = + ctxt_info_v2->tr_tail_idx_arr_base_addr = cpu_to_le64(trans_pcie->prph_info_dma_addr + PAGE_SIZE / 2); - ctxt_info_gen3->cr_tail_idx_arr_base_addr = + ctxt_info_v2->cr_tail_idx_arr_base_addr = cpu_to_le64(trans_pcie->prph_info_dma_addr + 3 * PAGE_SIZE / 4); - ctxt_info_gen3->mtr_base_addr = - cpu_to_le64(trans_pcie->txqs.txq[trans_pcie->txqs.cmd.q_id]->dma_addr); - ctxt_info_gen3->mcr_base_addr = + ctxt_info_v2->mtr_base_addr = + cpu_to_le64(trans_pcie->txqs.txq[trans->conf.cmd_queue]->dma_addr); + ctxt_info_v2->mcr_base_addr = cpu_to_le64(trans_pcie->rxq->used_bd_dma); - ctxt_info_gen3->mtr_size = + ctxt_info_v2->mtr_size = cpu_to_le16(TFD_QUEUE_CB_SIZE(cmdq_size)); - ctxt_info_gen3->mcr_size = - cpu_to_le16(RX_QUEUE_CB_SIZE(trans->cfg->num_rbds)); + ctxt_info_v2->mcr_size = + cpu_to_le16(RX_QUEUE_CB_SIZE(iwl_trans_get_num_rbds(trans))); - trans_pcie->ctxt_info_gen3 = ctxt_info_gen3; + trans_pcie->ctxt_info_v2 = ctxt_info_v2; trans_pcie->prph_info = prph_info; trans_pcie->prph_scratch = prph_scratch; /* Allocate IML */ - trans_pcie->iml = dma_alloc_coherent(trans->dev, trans->iml_len, + trans_pcie->iml_len = fw->iml_len; + trans_pcie->iml = dma_alloc_coherent(trans->dev, fw->iml_len, &trans_pcie->iml_dma_addr, GFP_KERNEL); if (!trans_pcie->iml) { @@ -249,27 +272,15 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, goto err_free_ctxt_info; } - memcpy(trans_pcie->iml, trans->iml, trans->iml_len); - - iwl_enable_fw_load_int_ctx_info(trans); - - /* kick FW self load */ - iwl_write64(trans, CSR_CTXT_INFO_ADDR, - trans_pcie->ctxt_info_dma_addr); - iwl_write64(trans, CSR_IML_DATA_ADDR, - trans_pcie->iml_dma_addr); - iwl_write32(trans, CSR_IML_SIZE_ADDR, trans->iml_len); - - iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL, - CSR_AUTO_FUNC_BOOT_ENA); + memcpy(trans_pcie->iml, fw->iml, fw->iml_len); return 0; err_free_ctxt_info: - dma_free_coherent(trans->dev, sizeof(*trans_pcie->ctxt_info_gen3), - trans_pcie->ctxt_info_gen3, + dma_free_coherent(trans->dev, sizeof(*trans_pcie->ctxt_info_v2), + trans_pcie->ctxt_info_v2, trans_pcie->ctxt_info_dma_addr); - trans_pcie->ctxt_info_gen3 = NULL; + trans_pcie->ctxt_info_v2 = NULL; err_free_prph_info: dma_free_coherent(trans->dev, PAGE_SIZE, prph_info, trans_pcie->prph_info_dma_addr); @@ -283,14 +294,31 @@ err_free_prph_scratch: } -void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans, bool alive) +void iwl_pcie_ctxt_info_v2_kick(struct iwl_trans *trans) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + + iwl_enable_fw_load_int_ctx_info(trans, trans->do_top_reset); + + /* kick FW self load */ + iwl_write64(trans, CSR_CTXT_INFO_ADDR, trans_pcie->ctxt_info_dma_addr); + iwl_write64(trans, CSR_IML_DATA_ADDR, trans_pcie->iml_dma_addr); + iwl_write32(trans, CSR_IML_SIZE_ADDR, trans_pcie->iml_len); + + iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL, + CSR_AUTO_FUNC_BOOT_ENA); +} + +void iwl_pcie_ctxt_info_v2_free(struct iwl_trans *trans, bool alive) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); if (trans_pcie->iml) { - dma_free_coherent(trans->dev, trans->iml_len, trans_pcie->iml, + dma_free_coherent(trans->dev, trans_pcie->iml_len, + trans_pcie->iml, trans_pcie->iml_dma_addr); trans_pcie->iml_dma_addr = 0; + trans_pcie->iml_len = 0; trans_pcie->iml = NULL; } @@ -299,15 +327,15 @@ void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans, bool alive) if (alive) return; - if (!trans_pcie->ctxt_info_gen3) + if (!trans_pcie->ctxt_info_v2) return; - /* ctxt_info_gen3 and prph_scratch are still needed for PNVM load */ - dma_free_coherent(trans->dev, sizeof(*trans_pcie->ctxt_info_gen3), - trans_pcie->ctxt_info_gen3, + /* ctxt_info_v2 and prph_scratch are still needed for PNVM load */ + dma_free_coherent(trans->dev, sizeof(*trans_pcie->ctxt_info_v2), + trans_pcie->ctxt_info_v2, trans_pcie->ctxt_info_dma_addr); trans_pcie->ctxt_info_dma_addr = 0; - trans_pcie->ctxt_info_gen3 = NULL; + trans_pcie->ctxt_info_v2 = NULL; dma_free_coherent(trans->dev, sizeof(*trans_pcie->prph_scratch), trans_pcie->prph_scratch, @@ -322,9 +350,9 @@ void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans, bool alive) trans_pcie->prph_info = NULL; } -static int iwl_pcie_load_payloads_continuously(struct iwl_trans *trans, - const struct iwl_pnvm_image *pnvm_data, - struct iwl_dram_data *dram) +static int iwl_pcie_load_payloads_contig(struct iwl_trans *trans, + const struct iwl_pnvm_image *pnvm_data, + struct iwl_dram_data *dram) { u32 len, len0, len1; @@ -411,9 +439,9 @@ static int iwl_pcie_load_payloads_segments } -int iwl_trans_pcie_ctx_info_gen3_load_pnvm(struct iwl_trans *trans, - const struct iwl_pnvm_image *pnvm_payloads, - const struct iwl_ucode_capabilities *capa) +int iwl_trans_pcie_ctx_info_v2_load_pnvm(struct iwl_trans *trans, + const struct iwl_pnvm_image *pnvm_payloads, + const struct iwl_ucode_capabilities *capa) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl = @@ -428,7 +456,7 @@ int iwl_trans_pcie_ctx_info_gen3_load_pnvm(struct iwl_trans *trans, if (WARN_ON(prph_sc_ctrl->pnvm_cfg.pnvm_size)) return -EBUSY; - if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) + if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) return 0; if (!pnvm_payloads->n_chunks) { @@ -445,10 +473,8 @@ int iwl_trans_pcie_ctx_info_gen3_load_pnvm(struct iwl_trans *trans, trans->pnvm_loaded = true; } else { /* save only in one DRAM section */ - ret = iwl_pcie_load_payloads_continuously - (trans, - pnvm_payloads, - &dram_regions->drams[0]); + ret = iwl_pcie_load_payloads_contig(trans, pnvm_payloads, + &dram_regions->drams[0]); if (!ret) { dram_regions->n_regions = 1; trans->pnvm_loaded = true; @@ -483,7 +509,7 @@ static void iwl_pcie_set_pnvm_segments(struct iwl_trans *trans) cpu_to_le32(iwl_dram_regions_size(dram_regions)); } -static void iwl_pcie_set_continuous_pnvm(struct iwl_trans *trans) +static void iwl_pcie_set_contig_pnvm(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl = @@ -495,21 +521,21 @@ static void iwl_pcie_set_continuous_pnvm(struct iwl_trans *trans) cpu_to_le32(trans_pcie->pnvm_data.drams[0].size); } -void iwl_trans_pcie_ctx_info_gen3_set_pnvm(struct iwl_trans *trans, - const struct iwl_ucode_capabilities *capa) +void iwl_trans_pcie_ctx_info_v2_set_pnvm(struct iwl_trans *trans, + const struct iwl_ucode_capabilities *capa) { - if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) + if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) return; if (fw_has_capa(capa, IWL_UCODE_TLV_CAPA_FRAGMENTED_PNVM_IMG)) iwl_pcie_set_pnvm_segments(trans); else - iwl_pcie_set_continuous_pnvm(trans); + iwl_pcie_set_contig_pnvm(trans); } -int iwl_trans_pcie_ctx_info_gen3_load_reduce_power(struct iwl_trans *trans, - const struct iwl_pnvm_image *payloads, - const struct iwl_ucode_capabilities *capa) +int iwl_trans_pcie_ctx_info_v2_load_reduce_power(struct iwl_trans *trans, + const struct iwl_pnvm_image *payloads, + const struct iwl_ucode_capabilities *capa) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl = @@ -521,7 +547,7 @@ int iwl_trans_pcie_ctx_info_gen3_load_reduce_power(struct iwl_trans *trans, if (trans->reduce_power_loaded) return 0; - if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) + if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) return 0; if (WARN_ON(prph_sc_ctrl->reduce_power_cfg.size)) @@ -541,10 +567,8 @@ int iwl_trans_pcie_ctx_info_gen3_load_reduce_power(struct iwl_trans *trans, trans->reduce_power_loaded = true; } else { /* save only in one DRAM section */ - ret = iwl_pcie_load_payloads_continuously - (trans, - payloads, - &dram_regions->drams[0]); + ret = iwl_pcie_load_payloads_contig(trans, payloads, + &dram_regions->drams[0]); if (!ret) { dram_regions->n_regions = 1; trans->reduce_power_loaded = true; @@ -567,7 +591,7 @@ static void iwl_pcie_set_reduce_power_segments(struct iwl_trans *trans) cpu_to_le32(iwl_dram_regions_size(dram_regions)); } -static void iwl_pcie_set_continuous_reduce_power(struct iwl_trans *trans) +static void iwl_pcie_set_contig_reduce_power(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl = @@ -580,15 +604,15 @@ static void iwl_pcie_set_continuous_reduce_power(struct iwl_trans *trans) } void -iwl_trans_pcie_ctx_info_gen3_set_reduce_power(struct iwl_trans *trans, - const struct iwl_ucode_capabilities *capa) +iwl_trans_pcie_ctx_info_v2_set_reduce_power(struct iwl_trans *trans, + const struct iwl_ucode_capabilities *capa) { - if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) + if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) return; if (fw_has_capa(capa, IWL_UCODE_TLV_CAPA_FRAGMENTED_PNVM_IMG)) iwl_pcie_set_reduce_power_segments(trans); else - iwl_pcie_set_continuous_reduce_power(trans); + iwl_pcie_set_contig_reduce_power(trans); } diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c index 344e4d5a1c6e..cb36baac14da 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2018-2024 Intel Corporation + * Copyright (C) 2018-2025 Intel Corporation */ #include "iwl-trans.h" #include "iwl-fh.h" @@ -83,7 +83,7 @@ void iwl_pcie_ctxt_info_free_paging(struct iwl_trans *trans) int iwl_pcie_init_fw_sec(struct iwl_trans *trans, const struct fw_img *fw, - struct iwl_context_info_dram *ctxt_dram) + struct iwl_context_info_dram_nonfseq *ctxt_dram) { struct iwl_self_init_dram *dram = &trans->init_dram; int i, ret, lmac_cnt, umac_cnt, paging_cnt; @@ -161,7 +161,7 @@ int iwl_pcie_init_fw_sec(struct iwl_trans *trans, } int iwl_pcie_ctxt_info_init(struct iwl_trans *trans, - const struct fw_img *fw) + const struct fw_img *img) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_context_info *ctxt_info; @@ -180,11 +180,11 @@ int iwl_pcie_ctxt_info_init(struct iwl_trans *trans, ctxt_info->version.version = 0; ctxt_info->version.mac_id = - cpu_to_le16((u16)trans->hw_rev); + cpu_to_le16((u16)trans->info.hw_rev); /* size is in DWs */ ctxt_info->version.size = cpu_to_le16(sizeof(*ctxt_info) / 4); - switch (trans_pcie->rx_buf_size) { + switch (trans->conf.rx_buf_size) { case IWL_AMSDU_2K: rb_size = IWL_CTXT_INFO_RB_SIZE_2K; break; @@ -202,10 +202,10 @@ int iwl_pcie_ctxt_info_init(struct iwl_trans *trans, rb_size = IWL_CTXT_INFO_RB_SIZE_4K; } - WARN_ON(RX_QUEUE_CB_SIZE(trans->cfg->num_rbds) > 12); + WARN_ON(RX_QUEUE_CB_SIZE(iwl_trans_get_num_rbds(trans)) > 12); control_flags = IWL_CTXT_INFO_TFD_FORMAT_LONG; control_flags |= - u32_encode_bits(RX_QUEUE_CB_SIZE(trans->cfg->num_rbds), + u32_encode_bits(RX_QUEUE_CB_SIZE(iwl_trans_get_num_rbds(trans)), IWL_CTXT_INFO_RB_CB_SIZE); control_flags |= u32_encode_bits(rb_size, IWL_CTXT_INFO_RB_SIZE); ctxt_info->control.control_flags = cpu_to_le32(control_flags); @@ -218,12 +218,12 @@ int iwl_pcie_ctxt_info_init(struct iwl_trans *trans, /* initialize TX command queue */ ctxt_info->hcmd_cfg.cmd_queue_addr = - cpu_to_le64(trans_pcie->txqs.txq[trans_pcie->txqs.cmd.q_id]->dma_addr); + cpu_to_le64(trans_pcie->txqs.txq[trans->conf.cmd_queue]->dma_addr); ctxt_info->hcmd_cfg.cmd_queue_size = TFD_QUEUE_CB_SIZE(IWL_CMD_QUEUE_SIZE); /* allocate ucode sections in dram and set addresses */ - ret = iwl_pcie_init_fw_sec(trans, fw, &ctxt_info->dram); + ret = iwl_pcie_init_fw_sec(trans, img, &ctxt_info->dram); if (ret) { dma_free_coherent(trans->dev, sizeof(*trans_pcie->ctxt_info), ctxt_info, trans_pcie->ctxt_info_dma_addr); @@ -232,7 +232,7 @@ int iwl_pcie_ctxt_info_init(struct iwl_trans *trans, trans_pcie->ctxt_info = ctxt_info; - iwl_enable_fw_load_int_ctx_info(trans); + iwl_enable_fw_load_int_ctx_info(trans, false); /* Configure debug, if exists */ if (iwl_pcie_dbg_on(trans)) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 00056e76ea3d..656f8b06c27b 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2005-2014, 2018-2024 Intel Corporation + * Copyright (C) 2005-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -17,15 +17,13 @@ #include "iwl-prph.h" #include "internal.h" -#define TRANS_CFG_MARKER BIT(0) #define _IS_A(cfg, _struct) __builtin_types_compatible_p(typeof(cfg), \ struct _struct) extern int _invalid_type; -#define _TRANS_CFG_MARKER(cfg) \ - (__builtin_choose_expr(_IS_A(cfg, iwl_cfg_trans_params), \ - TRANS_CFG_MARKER, \ - __builtin_choose_expr(_IS_A(cfg, iwl_cfg), 0, _invalid_type))) -#define _ASSIGN_CFG(cfg) (_TRANS_CFG_MARKER(cfg) + (kernel_ulong_t)&(cfg)) +#define _TRANS_CFG_CHECK(cfg) \ + (__builtin_choose_expr(_IS_A(cfg, iwl_mac_cfg), \ + 0, _invalid_type)) +#define _ASSIGN_CFG(cfg) (_TRANS_CFG_CHECK(cfg) + (kernel_ulong_t)&(cfg)) #define IWL_PCI_DEVICE(dev, subdev, cfg) \ .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ @@ -35,515 +33,518 @@ extern int _invalid_type; /* Hardware specific file defines the PCI IDs table for that hardware module */ VISIBLE_IF_IWLWIFI_KUNIT const struct pci_device_id iwl_hw_card_ids[] = { #if IS_ENABLED(CONFIG_IWLDVM) - {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1301, iwl5100_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1204, iwl5100_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1304, iwl5100_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bgn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bgn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1221, iwl5100_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1321, iwl5100_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1224, iwl5100_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1324, iwl5100_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1225, iwl5100_bgn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1325, iwl5100_bgn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1226, iwl5100_abg_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1211, iwl5100_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1311, iwl5100_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1214, iwl5100_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1314, iwl5100_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1215, iwl5100_bgn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1315, iwl5100_bgn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1316, iwl5100_abg_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5000_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1301, iwl5000_mac_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1204, iwl5000_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1304, iwl5000_mac_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5000_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5000_mac_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1206, iwl5000_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1306, iwl5000_mac_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1221, iwl5000_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1321, iwl5000_mac_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1224, iwl5000_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1324, iwl5000_mac_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1225, iwl5000_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1325, iwl5000_mac_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1226, iwl5000_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1326, iwl5000_mac_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1211, iwl5000_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1311, iwl5000_mac_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1214, iwl5000_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1314, iwl5000_mac_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1215, iwl5000_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1315, iwl5000_mac_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1216, iwl5000_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1316, iwl5000_mac_cfg)}, /* Half Mini Card */ /* 5300 Series WiFi */ - {IWL_PCI_DEVICE(0x4235, 0x1021, iwl5300_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1121, iwl5300_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1024, iwl5300_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1124, iwl5300_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1001, iwl5300_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1101, iwl5300_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1004, iwl5300_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1104, iwl5300_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4236, 0x1011, iwl5300_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4236, 0x1111, iwl5300_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4236, 0x1014, iwl5300_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4236, 0x1114, iwl5300_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1021, iwl5000_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1121, iwl5000_mac_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1024, iwl5000_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1124, iwl5000_mac_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1001, iwl5000_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1101, iwl5000_mac_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1004, iwl5000_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1104, iwl5000_mac_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4236, 0x1011, iwl5000_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4236, 0x1111, iwl5000_mac_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4236, 0x1014, iwl5000_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4236, 0x1114, iwl5000_mac_cfg)}, /* Half Mini Card */ /* 5350 Series WiFi/WiMax */ - {IWL_PCI_DEVICE(0x423A, 0x1001, iwl5350_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423A, 0x1021, iwl5350_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423B, 0x1011, iwl5350_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423A, 0x1001, iwl5000_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423A, 0x1021, iwl5000_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423B, 0x1011, iwl5000_mac_cfg)}, /* Mini Card */ /* 5150 Series Wifi/WiMax */ - {IWL_PCI_DEVICE(0x423C, 0x1201, iwl5150_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423C, 0x1301, iwl5150_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x423C, 0x1206, iwl5150_abg_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x423C, 0x1326, iwl5150_abg_cfg)}, /* Half Mini Card */ - - {IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x423D, 0x1216, iwl5150_abg_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423D, 0x1316, iwl5150_abg_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1201, iwl5150_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1301, iwl5150_mac_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1206, iwl5150_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_mac_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_mac_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1326, iwl5150_mac_cfg)}, /* Half Mini Card */ + + {IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_mac_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x423D, 0x1216, iwl5150_mac_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423D, 0x1316, iwl5150_mac_cfg)}, /* Half Mini Card */ /* 6x00 Series */ - {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)}, - {IWL_PCI_DEVICE(0x422B, 0x1108, iwl6000_3agn_cfg)}, - {IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)}, - {IWL_PCI_DEVICE(0x422B, 0x1128, iwl6000_3agn_cfg)}, - {IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)}, - {IWL_PCI_DEVICE(0x422C, 0x1306, iwl6000i_2abg_cfg)}, - {IWL_PCI_DEVICE(0x422C, 0x1307, iwl6000i_2bg_cfg)}, - {IWL_PCI_DEVICE(0x422C, 0x1321, iwl6000i_2agn_cfg)}, - {IWL_PCI_DEVICE(0x422C, 0x1326, iwl6000i_2abg_cfg)}, - {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)}, - {IWL_PCI_DEVICE(0x4238, 0x1118, iwl6000_3agn_cfg)}, - {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)}, - {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)}, + {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_mac_cfg)}, + {IWL_PCI_DEVICE(0x422B, 0x1108, iwl6000_mac_cfg)}, + {IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_mac_cfg)}, + {IWL_PCI_DEVICE(0x422B, 0x1128, iwl6000_mac_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_mac_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1306, iwl6000i_mac_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1307, iwl6000i_mac_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1321, iwl6000i_mac_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1326, iwl6000i_mac_cfg)}, + {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_mac_cfg)}, + {IWL_PCI_DEVICE(0x4238, 0x1118, iwl6000_mac_cfg)}, + {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_mac_cfg)}, + {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_mac_cfg)}, /* 6x05 Series */ - {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_2bg_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1308, iwl6005_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6005_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6005_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1328, iwl6005_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0085, 0x1318, iwl6005_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_2agn_sff_cfg)}, - {IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_2agn_sff_cfg)}, - {IWL_PCI_DEVICE(0x0085, 0xC228, iwl6005_2agn_sff_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x4820, iwl6005_2agn_d_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1304, iwl6005_2agn_mow1_cfg)},/* low 5GHz active */ - {IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_2agn_mow2_cfg)},/* high 5GHz active */ + {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_mac_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_mac_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_mac_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1308, iwl6005_mac_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6005_mac_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6005_mac_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1328, iwl6005_mac_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_mac_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0x1318, iwl6005_mac_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_mac_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_mac_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_mac_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0xC228, iwl6005_mac_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x4820, iwl6005_mac_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1304, iwl6005_mac_cfg)},/* low 5GHz active */ + {IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_mac_cfg)},/* high 5GHz active */ /* 6x30 Series */ - {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)}, - {IWL_PCI_DEVICE(0x008A, 0x5307, iwl1030_bg_cfg)}, - {IWL_PCI_DEVICE(0x008A, 0x5325, iwl1030_bgn_cfg)}, - {IWL_PCI_DEVICE(0x008A, 0x5327, iwl1030_bg_cfg)}, - {IWL_PCI_DEVICE(0x008B, 0x5315, iwl1030_bgn_cfg)}, - {IWL_PCI_DEVICE(0x008B, 0x5317, iwl1030_bg_cfg)}, - {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6030_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6030_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6030_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5201, iwl6030_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5205, iwl6030_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5206, iwl6030_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5207, iwl6030_2bg_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5221, iwl6030_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5225, iwl6030_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5226, iwl6030_2abg_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5307, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5325, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5327, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x008B, 0x5315, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x008B, 0x5317, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5201, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5205, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5206, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5207, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5221, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5225, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5226, iwl6030_mac_cfg)}, /* 6x50 WiFi/WiMax Series */ - {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0087, 0x1306, iwl6050_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0087, 0x1321, iwl6050_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0087, 0x1326, iwl6050_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_mac_cfg)}, + {IWL_PCI_DEVICE(0x0087, 0x1306, iwl6050_mac_cfg)}, + {IWL_PCI_DEVICE(0x0087, 0x1321, iwl6050_mac_cfg)}, + {IWL_PCI_DEVICE(0x0087, 0x1326, iwl6050_mac_cfg)}, + {IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_mac_cfg)}, + {IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_mac_cfg)}, /* 6150 WiFi/WiMax Series */ - {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6150_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0885, 0x1307, iwl6150_bg_cfg)}, - {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6150_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0885, 0x1327, iwl6150_bg_cfg)}, - {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6150_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0886, 0x1317, iwl6150_bg_cfg)}, + {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6150_mac_cfg)}, + {IWL_PCI_DEVICE(0x0885, 0x1307, iwl6150_mac_cfg)}, + {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6150_mac_cfg)}, + {IWL_PCI_DEVICE(0x0885, 0x1327, iwl6150_mac_cfg)}, + {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6150_mac_cfg)}, + {IWL_PCI_DEVICE(0x0886, 0x1317, iwl6150_mac_cfg)}, /* 1000 Series WiFi */ - {IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1305, iwl1000_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1225, iwl1000_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1325, iwl1000_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0084, 0x1215, iwl1000_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0084, 0x1315, iwl1000_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1206, iwl1000_bg_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1306, iwl1000_bg_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1226, iwl1000_bg_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1326, iwl1000_bg_cfg)}, - {IWL_PCI_DEVICE(0x0084, 0x1216, iwl1000_bg_cfg)}, - {IWL_PCI_DEVICE(0x0084, 0x1316, iwl1000_bg_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1305, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1225, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1325, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0084, 0x1215, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0084, 0x1315, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1206, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1306, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1226, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1326, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0084, 0x1216, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0084, 0x1316, iwl1000_mac_cfg)}, /* 100 Series WiFi */ - {IWL_PCI_DEVICE(0x08AE, 0x1005, iwl100_bgn_cfg)}, - {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)}, - {IWL_PCI_DEVICE(0x08AF, 0x1015, iwl100_bgn_cfg)}, - {IWL_PCI_DEVICE(0x08AF, 0x1017, iwl100_bg_cfg)}, - {IWL_PCI_DEVICE(0x08AE, 0x1025, iwl100_bgn_cfg)}, - {IWL_PCI_DEVICE(0x08AE, 0x1027, iwl100_bg_cfg)}, + {IWL_PCI_DEVICE(0x08AE, 0x1005, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08AF, 0x1015, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08AF, 0x1017, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08AE, 0x1025, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08AE, 0x1027, iwl1000_mac_cfg)}, /* 130 Series WiFi */ - {IWL_PCI_DEVICE(0x0896, 0x5005, iwl130_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0896, 0x5007, iwl130_bg_cfg)}, - {IWL_PCI_DEVICE(0x0897, 0x5015, iwl130_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0897, 0x5017, iwl130_bg_cfg)}, - {IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)}, + {IWL_PCI_DEVICE(0x0896, 0x5005, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0896, 0x5007, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0897, 0x5015, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0897, 0x5017, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0896, 0x5025, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0896, 0x5027, iwl1000_mac_cfg)}, /* 2x00 Series */ - {IWL_PCI_DEVICE(0x0890, 0x4022, iwl2000_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0891, 0x4222, iwl2000_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0890, 0x4422, iwl2000_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0890, 0x4822, iwl2000_2bgn_d_cfg)}, + {IWL_PCI_DEVICE(0x0890, 0x4022, iwl2000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0891, 0x4222, iwl2000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0890, 0x4422, iwl2000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0890, 0x4822, iwl2000_mac_cfg)}, /* 2x30 Series */ - {IWL_PCI_DEVICE(0x0887, 0x4062, iwl2030_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0888, 0x4262, iwl2030_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0887, 0x4462, iwl2030_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0887, 0x4062, iwl2030_mac_cfg)}, + {IWL_PCI_DEVICE(0x0888, 0x4262, iwl2030_mac_cfg)}, + {IWL_PCI_DEVICE(0x0887, 0x4462, iwl2030_mac_cfg)}, /* 6x35 Series */ - {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, - {IWL_PCI_DEVICE(0x088E, 0x406A, iwl6035_2agn_sff_cfg)}, - {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, - {IWL_PCI_DEVICE(0x088F, 0x426A, iwl6035_2agn_sff_cfg)}, - {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, - {IWL_PCI_DEVICE(0x088E, 0x446A, iwl6035_2agn_sff_cfg)}, - {IWL_PCI_DEVICE(0x088E, 0x4860, iwl6035_2agn_cfg)}, - {IWL_PCI_DEVICE(0x088F, 0x5260, iwl6035_2agn_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x406A, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x088F, 0x426A, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x446A, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4860, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x088F, 0x5260, iwl6030_mac_cfg)}, /* 105 Series */ - {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0894, 0x0822, iwl105_bgn_d_cfg)}, + {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_mac_cfg)}, + {IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_mac_cfg)}, + {IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_mac_cfg)}, + {IWL_PCI_DEVICE(0x0894, 0x0822, iwl105_mac_cfg)}, /* 135 Series */ - {IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_mac_cfg)}, + {IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_mac_cfg)}, + {IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_mac_cfg)}, #endif /* CONFIG_IWLDVM */ #if IS_ENABLED(CONFIG_IWLMVM) /* 7260 Series */ - {IWL_PCI_DEVICE(0x08B1, 0x4070, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x4072, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x4170, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x4C60, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x4C70, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x4060, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x406A, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x4160, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x4062, iwl7260_n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x4162, iwl7260_n_cfg)}, - {IWL_PCI_DEVICE(0x08B2, 0x4270, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B2, 0x4272, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B2, 0x4260, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B2, 0x426A, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B2, 0x4262, iwl7260_n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x4470, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x4472, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x4460, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x446A, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x4462, iwl7260_n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x4870, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x486E, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x4A70, iwl7260_2ac_cfg_high_temp)}, - {IWL_PCI_DEVICE(0x08B1, 0x4A6E, iwl7260_2ac_cfg_high_temp)}, - {IWL_PCI_DEVICE(0x08B1, 0x4A6C, iwl7260_2ac_cfg_high_temp)}, - {IWL_PCI_DEVICE(0x08B1, 0x4570, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x4560, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B2, 0x4370, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B2, 0x4360, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x5070, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x5072, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x5170, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x5770, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x4020, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x402A, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B2, 0x4220, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0x4420, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xC070, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xC072, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xC170, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xC060, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xC06A, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xC160, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xC062, iwl7260_n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xC162, iwl7260_n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xC770, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xC760, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B2, 0xC270, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xCC70, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xCC60, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B2, 0xC272, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B2, 0xC260, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B2, 0xC26A, iwl7260_n_cfg)}, - {IWL_PCI_DEVICE(0x08B2, 0xC262, iwl7260_n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xC470, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xC472, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xC460, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xC462, iwl7260_n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xC570, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xC560, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B2, 0xC370, iwl7260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xC360, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xC020, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xC02A, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B2, 0xC220, iwl7260_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B1, 0xC420, iwl7260_2n_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4070, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4072, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4170, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4C60, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4C70, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4060, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x406A, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4160, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4062, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4162, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B2, 0x4270, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B2, 0x4272, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B2, 0x4260, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B2, 0x426A, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B2, 0x4262, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4470, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4472, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4460, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x446A, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4462, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4870, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x486E, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4A70, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4A6E, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4A6C, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4570, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4560, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B2, 0x4370, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B2, 0x4360, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x5070, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x5072, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x5170, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x5770, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4020, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x402A, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B2, 0x4220, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4420, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xC070, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xC072, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xC170, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xC060, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xC06A, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xC160, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xC062, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xC162, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xC770, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xC760, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B2, 0xC270, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xCC70, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xCC60, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B2, 0xC272, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B2, 0xC260, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B2, 0xC26A, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B2, 0xC262, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xC470, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xC472, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xC460, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xC462, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xC570, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xC560, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B2, 0xC370, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xC360, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xC020, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xC02A, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B2, 0xC220, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xC420, iwl7000_mac_cfg)}, /* 3160 Series */ - {IWL_PCI_DEVICE(0x08B3, 0x0070, iwl3160_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B3, 0x0072, iwl3160_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B3, 0x0170, iwl3160_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B3, 0x0172, iwl3160_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B3, 0x0060, iwl3160_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B3, 0x0062, iwl3160_n_cfg)}, - {IWL_PCI_DEVICE(0x08B4, 0x0270, iwl3160_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B4, 0x0272, iwl3160_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B3, 0x0470, iwl3160_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B3, 0x0472, iwl3160_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B4, 0x0370, iwl3160_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B3, 0x8070, iwl3160_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B3, 0x8072, iwl3160_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B3, 0x8170, iwl3160_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B3, 0x8172, iwl3160_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B3, 0x8060, iwl3160_2n_cfg)}, - {IWL_PCI_DEVICE(0x08B3, 0x8062, iwl3160_n_cfg)}, - {IWL_PCI_DEVICE(0x08B4, 0x8270, iwl3160_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B4, 0x8370, iwl3160_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B4, 0x8272, iwl3160_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B3, 0x8470, iwl3160_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B3, 0x8570, iwl3160_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B3, 0x1070, iwl3160_2ac_cfg)}, - {IWL_PCI_DEVICE(0x08B3, 0x1170, iwl3160_2ac_cfg)}, + {IWL_PCI_DEVICE(0x08B3, 0x0070, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B3, 0x0072, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B3, 0x0170, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B3, 0x0172, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B3, 0x0060, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B3, 0x0062, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B4, 0x0270, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B4, 0x0272, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B3, 0x0470, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B3, 0x0472, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B4, 0x0370, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B3, 0x8070, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B3, 0x8072, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B3, 0x8170, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B3, 0x8172, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B3, 0x8060, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B3, 0x8062, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B4, 0x8270, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B4, 0x8370, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B4, 0x8272, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B3, 0x8470, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B3, 0x8570, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B3, 0x1070, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x08B3, 0x1170, iwl7000_mac_cfg)}, /* 3165 Series */ - {IWL_PCI_DEVICE(0x3165, 0x4010, iwl3165_2ac_cfg)}, - {IWL_PCI_DEVICE(0x3165, 0x4012, iwl3165_2ac_cfg)}, - {IWL_PCI_DEVICE(0x3166, 0x4212, iwl3165_2ac_cfg)}, - {IWL_PCI_DEVICE(0x3165, 0x4410, iwl3165_2ac_cfg)}, - {IWL_PCI_DEVICE(0x3165, 0x4510, iwl3165_2ac_cfg)}, - {IWL_PCI_DEVICE(0x3165, 0x4110, iwl3165_2ac_cfg)}, - {IWL_PCI_DEVICE(0x3166, 0x4310, iwl3165_2ac_cfg)}, - {IWL_PCI_DEVICE(0x3166, 0x4210, iwl3165_2ac_cfg)}, - {IWL_PCI_DEVICE(0x3165, 0x8010, iwl3165_2ac_cfg)}, - {IWL_PCI_DEVICE(0x3165, 0x8110, iwl3165_2ac_cfg)}, + {IWL_PCI_DEVICE(0x3165, 0x4010, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x3165, 0x4012, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x3166, 0x4212, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x3165, 0x4410, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x3165, 0x4510, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x3165, 0x4110, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x3166, 0x4310, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x3166, 0x4210, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x3165, 0x8010, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x3165, 0x8110, iwl7000_mac_cfg)}, /* 3168 Series */ - {IWL_PCI_DEVICE(0x24FB, 0x2010, iwl3168_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FB, 0x2110, iwl3168_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FB, 0x2050, iwl3168_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FB, 0x2150, iwl3168_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FB, 0x0000, iwl3168_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24FB, 0x2010, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FB, 0x2110, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FB, 0x2050, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FB, 0x2150, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FB, 0x0000, iwl7000_mac_cfg)}, /* 7265 Series */ - {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x5110, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x5100, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095B, 0x5310, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_n_cfg)}, - {IWL_PCI_DEVICE(0x095B, 0x5210, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x5C10, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x5012, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x5412, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x5510, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x5400, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x5000, iwl7265_2n_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x500A, iwl7265_2n_cfg)}, - {IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x5102, iwl7265_n_cfg)}, - {IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x9012, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x900A, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095B, 0x9210, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095B, 0x9200, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095B, 0x9310, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x9410, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x5020, iwl7265_2n_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x502A, iwl7265_2n_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x5420, iwl7265_2n_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x5090, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x5190, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x5590, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095B, 0x5290, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x5490, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x5F10, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095B, 0x5212, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095B, 0x520A, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x9000, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x9400, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x9E10, iwl7265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5110, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5100, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095B, 0x5310, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095B, 0x5302, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095B, 0x5210, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5C10, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5012, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5412, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5410, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5510, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5400, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x1010, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5000, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x500A, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095B, 0x5200, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5002, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5102, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095B, 0x5202, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x9010, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x9012, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x900A, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x9110, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x9112, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095B, 0x9210, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095B, 0x9200, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x9510, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095B, 0x9310, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x9410, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5020, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x502A, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5420, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5090, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5190, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5590, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095B, 0x5290, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5490, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5F10, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095B, 0x5212, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095B, 0x520A, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x9000, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x9400, iwl7000_mac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x9E10, iwl7000_mac_cfg)}, /* 8000 Series */ - {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x1010, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x10B0, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x0130, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x1130, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x0132, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x1132, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x0110, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x01F0, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x0012, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x1012, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x1110, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x0050, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x0250, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x1050, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x0150, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x1150, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F4, 0x0030, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F4, 0x1030, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0xC010, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0xC110, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0xD010, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0xC050, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0xD050, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0xD0B0, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0xB0B0, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x8010, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x8110, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x9010, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x9110, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F4, 0x8030, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F4, 0x9030, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F4, 0xC030, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F4, 0xD030, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x8130, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x9130, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x8132, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x9132, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x8050, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x8150, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x9050, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x9150, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x0004, iwl8260_2n_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x0044, iwl8260_2n_cfg)}, - {IWL_PCI_DEVICE(0x24F5, 0x0010, iwl4165_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F6, 0x0030, iwl4165_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x0810, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x0910, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x0850, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x0950, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x0930, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x0000, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24F3, 0x4010, iwl8260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x0010, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x0110, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x1110, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x1130, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x0130, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x1010, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x10D0, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x0050, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x0150, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x9010, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x8110, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x8050, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x8010, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x0810, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x9110, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x8130, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x0910, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x0930, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x0950, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x0850, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x1014, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x3E02, iwl8275_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x3E01, iwl8275_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x1012, iwl8275_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x0012, iwl8275_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x0014, iwl8265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x24FD, 0x9074, iwl8265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x1010, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x10B0, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x0130, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x1130, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x0132, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x1132, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x0110, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x01F0, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x0012, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x1012, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x1110, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x0050, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x0250, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x1050, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x0150, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x1150, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F4, 0x0030, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F4, 0x1030, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0xC010, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0xC110, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0xD010, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0xC050, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0xD050, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0xD0B0, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0xB0B0, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x8010, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x8110, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x9010, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x9110, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F4, 0x8030, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F4, 0x9030, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F4, 0xC030, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F4, 0xD030, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x8130, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x9130, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x8132, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x9132, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x8050, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x8150, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x9050, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x9150, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x0004, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x0044, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F5, 0x0010, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F6, 0x0030, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x0810, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x0910, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x0850, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x0950, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x0930, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x0000, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x4010, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0xC030, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0xD030, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0010, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0110, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x1110, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x1130, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0130, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x1010, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x10D0, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0050, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0150, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x9010, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x8110, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x8050, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x8010, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0810, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x9110, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x8130, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0910, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0930, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0950, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0850, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x1014, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x3E02, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x3E01, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x1012, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0012, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0014, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x9074, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x1431, iwl8000_mac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x1432, iwl8000_mac_cfg)}, /* 9000 Series */ - {IWL_PCI_DEVICE(0x2526, PCI_ANY_ID, iwl9000_trans_cfg)}, - {IWL_PCI_DEVICE(0x271B, PCI_ANY_ID, iwl9000_trans_cfg)}, - {IWL_PCI_DEVICE(0x271C, PCI_ANY_ID, iwl9000_trans_cfg)}, - {IWL_PCI_DEVICE(0x30DC, PCI_ANY_ID, iwl9560_long_latency_trans_cfg)}, - {IWL_PCI_DEVICE(0x31DC, PCI_ANY_ID, iwl9560_shared_clk_trans_cfg)}, - {IWL_PCI_DEVICE(0x9DF0, PCI_ANY_ID, iwl9560_trans_cfg)}, - {IWL_PCI_DEVICE(0xA370, PCI_ANY_ID, iwl9560_trans_cfg)}, + {IWL_PCI_DEVICE(0x2526, PCI_ANY_ID, iwl9000_mac_cfg)}, + {IWL_PCI_DEVICE(0x271B, PCI_ANY_ID, iwl9000_mac_cfg)}, + {IWL_PCI_DEVICE(0x271C, PCI_ANY_ID, iwl9000_mac_cfg)}, + {IWL_PCI_DEVICE(0x30DC, PCI_ANY_ID, iwl9560_long_latency_mac_cfg)}, + {IWL_PCI_DEVICE(0x31DC, PCI_ANY_ID, iwl9560_shared_clk_mac_cfg)}, + {IWL_PCI_DEVICE(0x9DF0, PCI_ANY_ID, iwl9560_mac_cfg)}, + {IWL_PCI_DEVICE(0xA370, PCI_ANY_ID, iwl9560_mac_cfg)}, /* Qu devices */ - {IWL_PCI_DEVICE(0x02F0, PCI_ANY_ID, iwl_qu_trans_cfg)}, - {IWL_PCI_DEVICE(0x06F0, PCI_ANY_ID, iwl_qu_trans_cfg)}, + {IWL_PCI_DEVICE(0x02F0, PCI_ANY_ID, iwl_qu_mac_cfg)}, + {IWL_PCI_DEVICE(0x06F0, PCI_ANY_ID, iwl_qu_mac_cfg)}, - {IWL_PCI_DEVICE(0x34F0, PCI_ANY_ID, iwl_qu_medium_latency_trans_cfg)}, - {IWL_PCI_DEVICE(0x3DF0, PCI_ANY_ID, iwl_qu_medium_latency_trans_cfg)}, - {IWL_PCI_DEVICE(0x4DF0, PCI_ANY_ID, iwl_qu_medium_latency_trans_cfg)}, + {IWL_PCI_DEVICE(0x34F0, PCI_ANY_ID, iwl_qu_medium_latency_mac_cfg)}, + {IWL_PCI_DEVICE(0x3DF0, PCI_ANY_ID, iwl_qu_medium_latency_mac_cfg)}, + {IWL_PCI_DEVICE(0x4DF0, PCI_ANY_ID, iwl_qu_medium_latency_mac_cfg)}, - {IWL_PCI_DEVICE(0x43F0, PCI_ANY_ID, iwl_qu_long_latency_trans_cfg)}, - {IWL_PCI_DEVICE(0xA0F0, PCI_ANY_ID, iwl_qu_long_latency_trans_cfg)}, + {IWL_PCI_DEVICE(0x43F0, PCI_ANY_ID, iwl_qu_long_latency_mac_cfg)}, + {IWL_PCI_DEVICE(0xA0F0, PCI_ANY_ID, iwl_qu_long_latency_mac_cfg)}, - {IWL_PCI_DEVICE(0x2723, PCI_ANY_ID, iwl_ax200_trans_cfg)}, + {IWL_PCI_DEVICE(0x2723, PCI_ANY_ID, iwl_ax200_mac_cfg)}, -/* So devices */ - {IWL_PCI_DEVICE(0x2725, PCI_ANY_ID, iwl_so_trans_cfg)}, - {IWL_PCI_DEVICE(0x7A70, PCI_ANY_ID, iwl_so_long_latency_imr_trans_cfg)}, - {IWL_PCI_DEVICE(0x7AF0, PCI_ANY_ID, iwl_so_trans_cfg)}, - {IWL_PCI_DEVICE(0x51F0, PCI_ANY_ID, iwl_so_long_latency_trans_cfg)}, - {IWL_PCI_DEVICE(0x51F1, PCI_ANY_ID, iwl_so_long_latency_imr_trans_cfg)}, - {IWL_PCI_DEVICE(0x54F0, PCI_ANY_ID, iwl_so_long_latency_trans_cfg)}, - {IWL_PCI_DEVICE(0x7F70, PCI_ANY_ID, iwl_so_trans_cfg)}, +/* Ty/So devices */ + {IWL_PCI_DEVICE(0x2725, PCI_ANY_ID, iwl_ty_mac_cfg)}, + {IWL_PCI_DEVICE(0x7A70, PCI_ANY_ID, iwl_so_long_latency_imr_mac_cfg)}, + {IWL_PCI_DEVICE(0x7AF0, PCI_ANY_ID, iwl_so_mac_cfg)}, + {IWL_PCI_DEVICE(0x51F0, PCI_ANY_ID, iwl_so_long_latency_mac_cfg)}, + {IWL_PCI_DEVICE(0x51F1, PCI_ANY_ID, iwl_so_long_latency_imr_mac_cfg)}, + {IWL_PCI_DEVICE(0x54F0, PCI_ANY_ID, iwl_so_long_latency_mac_cfg)}, + {IWL_PCI_DEVICE(0x7F70, PCI_ANY_ID, iwl_so_mac_cfg)}, /* Ma devices */ - {IWL_PCI_DEVICE(0x2729, PCI_ANY_ID, iwl_ma_trans_cfg)}, - {IWL_PCI_DEVICE(0x7E40, PCI_ANY_ID, iwl_ma_trans_cfg)}, + {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) /* Bz devices */ - {IWL_PCI_DEVICE(0x272b, PCI_ANY_ID, iwl_gl_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x0000, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x0090, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x0094, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x0098, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x009C, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x00C0, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x00C4, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x00E0, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x00E4, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x00E8, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x00EC, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x0100, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x0110, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x0114, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x0118, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x011C, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x0310, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x0314, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x0510, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x0A10, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x1671, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x1672, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x1771, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x1772, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x1791, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x1792, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x4090, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x40C4, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x40E0, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x4110, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0xA840, 0x4314, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0x7740, PCI_ANY_ID, iwl_bz_trans_cfg)}, - {IWL_PCI_DEVICE(0x4D40, PCI_ANY_ID, iwl_bz_trans_cfg)}, + {IWL_PCI_DEVICE(0x272b, PCI_ANY_ID, iwl_gl_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x0000, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x0090, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x0094, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x0098, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x009C, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x00C0, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x00C4, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x00E0, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x00E4, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x00E8, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x00EC, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x0100, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x0110, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x0114, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x0118, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x011C, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x0310, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x0314, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x0510, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x0A10, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x1671, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x1672, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x1771, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x1772, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x1791, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x1792, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x4090, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x40C4, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x40E0, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x4110, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x4314, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x1775, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0xA840, 0x1776, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0x7740, PCI_ANY_ID, iwl_bz_mac_cfg)}, + {IWL_PCI_DEVICE(0x4D40, PCI_ANY_ID, iwl_bz_mac_cfg)}, /* Sc devices */ - {IWL_PCI_DEVICE(0xE440, PCI_ANY_ID, iwl_sc_trans_cfg)}, - {IWL_PCI_DEVICE(0xE340, PCI_ANY_ID, iwl_sc_trans_cfg)}, - {IWL_PCI_DEVICE(0xD340, PCI_ANY_ID, iwl_sc_trans_cfg)}, - {IWL_PCI_DEVICE(0x6E70, PCI_ANY_ID, iwl_sc_trans_cfg)}, - -/* Dr devices */ - {IWL_PCI_DEVICE(0x272F, PCI_ANY_ID, iwl_dr_trans_cfg)}, + {IWL_PCI_DEVICE(0xE440, PCI_ANY_ID, iwl_sc_mac_cfg)}, + {IWL_PCI_DEVICE(0xE340, PCI_ANY_ID, iwl_sc_mac_cfg)}, + {IWL_PCI_DEVICE(0xD340, PCI_ANY_ID, iwl_sc_mac_cfg)}, + {IWL_PCI_DEVICE(0x6E70, PCI_ANY_ID, iwl_sc_mac_cfg)}, #endif /* CONFIG_IWLMLD */ {0} @@ -551,689 +552,518 @@ VISIBLE_IF_IWLWIFI_KUNIT const struct pci_device_id iwl_hw_card_ids[] = { MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_hw_card_ids); -#define _IWL_DEV_INFO(_device, _subdevice, _mac_type, _mac_step, _rf_type, \ - _rf_id, _rf_step, _no_160, _cores, _cdb, _cfg, _name) \ - { .device = (_device), .subdevice = (_subdevice), .cfg = &(_cfg), \ - .name = _name, .mac_type = _mac_type, .rf_type = _rf_type, .rf_step = _rf_step, \ - .no_160 = _no_160, .cores = _cores, .rf_id = _rf_id, \ - .mac_step = _mac_step, .cdb = _cdb, .jacket = IWL_CFG_ANY } - -#define IWL_DEV_INFO(_device, _subdevice, _cfg, _name) \ - _IWL_DEV_INFO(_device, _subdevice, IWL_CFG_ANY, IWL_CFG_ANY, \ - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, \ - IWL_CFG_ANY, _cfg, _name) +#define _IWL_DEV_INFO(_cfg, _name, ...) { \ + .cfg = &_cfg, \ + .name = _name, \ + .device = IWL_CFG_ANY, \ + .subdevice = IWL_CFG_ANY, \ + .subdevice_m_h = 15, \ + __VA_ARGS__ \ +} +#define IWL_DEV_INFO(_cfg, _name, ...) \ + _IWL_DEV_INFO(_cfg, _name, __VA_ARGS__) + +#define DEVICE(n) .device = (n) +#define SUBDEV(n) .subdevice = (n) +#define _LOWEST_BIT(n) (__builtin_ffs(n) - 1) +#define _BIT_ABOVE_MASK(n) ((n) + (1 << _LOWEST_BIT(n))) +#define _HIGHEST_BIT(n) (__builtin_ffs(_BIT_ABOVE_MASK(n)) - 2) +#define _IS_POW2(n) (((n) & ((n) - 1)) == 0) +#define _IS_CONTIG(n) _IS_POW2(_BIT_ABOVE_MASK(n)) +#define _CHECK_MASK(m) BUILD_BUG_ON_ZERO(!_IS_CONTIG(m)) +#define SUBDEV_MASKED(v, m) .subdevice = (v) + _CHECK_MASK(m), \ + .subdevice_m_l = _LOWEST_BIT(m), \ + .subdevice_m_h = _HIGHEST_BIT(m) +#define RF_TYPE(n) .match_rf_type = 1, \ + .rf_type = IWL_CFG_RF_TYPE_##n +#define RF_STEP(n) .match_rf_step = 1, \ + .rf_step = SILICON_##n##_STEP +#define RF_ID(n) .match_rf_id = 1, \ + .rf_id = IWL_CFG_RF_ID_##n +#define NO_CDB .match_cdb = 1, .cdb = 0 +#define CDB .match_cdb = 1, .cdb = 1 +#define BW_NOT_LIMITED .match_bw_limit = 1, .bw_limit = 0 +#define BW_LIMITED .match_bw_limit = 1, .bw_limit = 1 VISIBLE_IF_IWLWIFI_KUNIT const struct iwl_dev_info iwl_dev_info_table[] = { +#if IS_ENABLED(CONFIG_IWLDVM) + IWL_DEV_INFO(iwl5100_n_cfg, iwl5100_agn_name, + DEVICE(0x4232), SUBDEV_MASKED(0x1, 0xF)), + IWL_DEV_INFO(iwl5100_n_cfg, iwl5100_agn_name, + DEVICE(0x4232), SUBDEV_MASKED(0x4, 0xF)), + IWL_DEV_INFO(iwl5100_n_cfg, iwl5100_bgn_name, + DEVICE(0x4232), SUBDEV_MASKED(0x5, 0xF)), + IWL_DEV_INFO(iwl5100_abg_cfg, iwl5100_abg_name, + DEVICE(0x4232), SUBDEV_MASKED(0x6, 0xF)), + IWL_DEV_INFO(iwl5100_n_cfg, iwl5100_agn_name, + DEVICE(0x4237), SUBDEV_MASKED(0x1, 0xF)), + IWL_DEV_INFO(iwl5100_n_cfg, iwl5100_agn_name, + DEVICE(0x4237), SUBDEV_MASKED(0x4, 0xF)), + IWL_DEV_INFO(iwl5100_n_cfg, iwl5100_bgn_name, + DEVICE(0x4237), SUBDEV_MASKED(0x5, 0xF)), + IWL_DEV_INFO(iwl5100_abg_cfg, iwl5100_abg_name, + DEVICE(0x4237), SUBDEV_MASKED(0x6, 0xF)), + +/* 5300 Series WiFi */ + IWL_DEV_INFO(iwl5300_agn_cfg, iwl5300_agn_name, + DEVICE(0x4235), SUBDEV_MASKED(0x1, 0xF)), + IWL_DEV_INFO(iwl5300_agn_cfg, iwl5300_agn_name, + DEVICE(0x4235), SUBDEV_MASKED(0x4, 0xF)), + IWL_DEV_INFO(iwl5300_agn_cfg, iwl5300_agn_name, + DEVICE(0x4236), SUBDEV_MASKED(0x1, 0xF)), + IWL_DEV_INFO(iwl5300_agn_cfg, iwl5300_agn_name, + DEVICE(0x4236), SUBDEV_MASKED(0x4, 0xF)), + +/* 5350 Series WiFi/WiMax */ + IWL_DEV_INFO(iwl5350_agn_cfg, iwl5350_agn_name, + DEVICE(0x423A)), + IWL_DEV_INFO(iwl5350_agn_cfg, iwl5350_agn_name, + DEVICE(0x423B)), + +/* 5150 Series Wifi/WiMax */ + IWL_DEV_INFO(iwl5150_agn_cfg, iwl5150_agn_name, + DEVICE(0x423C), SUBDEV_MASKED(0x1, 0xF)), + IWL_DEV_INFO(iwl5150_abg_cfg, iwl5150_abg_name, + DEVICE(0x423C), SUBDEV_MASKED(0x6, 0xF)), + + IWL_DEV_INFO(iwl5150_agn_cfg, iwl5150_agn_name, + DEVICE(0x423D), SUBDEV_MASKED(0x1, 0xF)), + IWL_DEV_INFO(iwl5150_abg_cfg, iwl5150_abg_name, + DEVICE(0x423D), SUBDEV_MASKED(0x6, 0xF)), + +/* 6x00 Series */ + IWL_DEV_INFO(iwl6000_3agn_cfg, iwl6000_3agn_name, + DEVICE(0x422B), SUBDEV_MASKED(0x1, 0xF)), + IWL_DEV_INFO(iwl6000_3agn_cfg, iwl6000_3agn_name, + DEVICE(0x422B), SUBDEV_MASKED(0x8, 0xF)), + IWL_DEV_INFO(iwl6000i_2agn_cfg, iwl6000i_2agn_name, + DEVICE(0x422C), SUBDEV_MASKED(0x1, 0xF)), + IWL_DEV_INFO(iwl6000i_non_n_cfg, iwl6000i_2abg_name, + DEVICE(0x422C), SUBDEV_MASKED(0x6, 0xF)), + IWL_DEV_INFO(iwl6000i_non_n_cfg, iwl6000i_2bg_name, + DEVICE(0x422C), SUBDEV_MASKED(0x7, 0xF)), + IWL_DEV_INFO(iwl6000_3agn_cfg, iwl6000_3agn_name, + DEVICE(0x4238), SUBDEV(0x1111)), + IWL_DEV_INFO(iwl6000_3agn_cfg, iwl6000_3agn_name, + DEVICE(0x4238), SUBDEV(0x1118)), + IWL_DEV_INFO(iwl6000i_2agn_cfg, iwl6000i_2agn_name, + DEVICE(0x4239), SUBDEV(0x1311)), + IWL_DEV_INFO(iwl6000i_non_n_cfg, iwl6000i_2abg_name, + DEVICE(0x4239), SUBDEV(0x1316)), + +/* 6x05 Series */ + IWL_DEV_INFO(iwl6005_n_cfg, iwl6005_2agn_name, + DEVICE(0x0082), SUBDEV_MASKED(0x1, 0xF)), + IWL_DEV_INFO(iwl6005_non_n_cfg, iwl6005_2abg_name, + DEVICE(0x0082), SUBDEV_MASKED(0x6, 0xF)), + IWL_DEV_INFO(iwl6005_non_n_cfg, iwl6005_2bg_name, + DEVICE(0x0082), SUBDEV_MASKED(0x7, 0xF)), + IWL_DEV_INFO(iwl6005_n_cfg, iwl6005_2agn_name, + DEVICE(0x0082), SUBDEV_MASKED(0x8, 0xF)), + + IWL_DEV_INFO(iwl6005_n_cfg, iwl6005_2agn_name, + DEVICE(0x0085), SUBDEV_MASKED(0x1, 0xF)), + IWL_DEV_INFO(iwl6005_n_cfg, iwl6005_2agn_name, + DEVICE(0x0085), SUBDEV_MASKED(0x8, 0xF)), + IWL_DEV_INFO(iwl6005_non_n_cfg, iwl6005_2abg_name, + DEVICE(0x0085), SUBDEV_MASKED(0x6, 0xF)), + + IWL_DEV_INFO(iwl6005_n_cfg, iwl6005_2agn_sff_name, + DEVICE(0x0082), SUBDEV_MASKED(0xC000, 0xF000)), + IWL_DEV_INFO(iwl6005_n_cfg, iwl6005_2agn_d_name, + DEVICE(0x0082), SUBDEV(0x4820)), + IWL_DEV_INFO(iwl6005_n_cfg, iwl6005_2agn_mow1_name, + DEVICE(0x0082), SUBDEV(0x1304)),/* low 5GHz active */ + IWL_DEV_INFO(iwl6005_n_cfg, iwl6005_2agn_mow2_name, + DEVICE(0x0082), SUBDEV(0x1305)),/* high 5GHz active */ + +/* 6x30 Series */ + IWL_DEV_INFO(iwl6030_n_cfg, iwl1030_bgn_name, + DEVICE(0x008A), SUBDEV_MASKED(0x5, 0xF)), + IWL_DEV_INFO(iwl6030_non_n_cfg, iwl1030_bg_name, + DEVICE(0x008A), SUBDEV_MASKED(0x7, 0xF)), + IWL_DEV_INFO(iwl6030_n_cfg, iwl1030_bgn_name, + DEVICE(0x008B), SUBDEV(0x5315)), + IWL_DEV_INFO(iwl6030_non_n_cfg, iwl1030_bg_name, + DEVICE(0x008B), SUBDEV(0x5317)), + IWL_DEV_INFO(iwl6030_n_cfg, iwl6030_2agn_name, + DEVICE(0x0090), SUBDEV(0x5211)), + IWL_DEV_INFO(iwl6030_n_cfg, iwl6030_2bgn_name, + DEVICE(0x0090), SUBDEV(0x5215)), + IWL_DEV_INFO(iwl6030_non_n_cfg, iwl6030_2abg_name, + DEVICE(0x0090), SUBDEV(0x5216)), + IWL_DEV_INFO(iwl6030_n_cfg, iwl6030_2agn_name, + DEVICE(0x0091), SUBDEV_MASKED(0x1, 0xF)), + IWL_DEV_INFO(iwl6030_n_cfg, iwl6030_2bgn_name, + DEVICE(0x0091), SUBDEV_MASKED(0x5, 0xF)), + IWL_DEV_INFO(iwl6030_non_n_cfg, iwl6030_2abg_name, + DEVICE(0x0091), SUBDEV_MASKED(0x6, 0xF)), + IWL_DEV_INFO(iwl6030_non_n_cfg, iwl6030_2bg_name, + DEVICE(0x0091), SUBDEV(0x5207)), + +/* 6x50 WiFi/WiMax Series */ + IWL_DEV_INFO(iwl6050_2agn_cfg, iwl6050_2agn_name, + DEVICE(0x0087), SUBDEV_MASKED(0x1, 0xF)), + IWL_DEV_INFO(iwl6050_2abg_cfg, iwl6050_2abg_name, + DEVICE(0x0087), SUBDEV_MASKED(0x6, 0xF)), + IWL_DEV_INFO(iwl6050_2agn_cfg, iwl6050_2agn_name, + DEVICE(0x0089), SUBDEV(0x1311)), + IWL_DEV_INFO(iwl6050_2abg_cfg, iwl6050_2abg_name, + DEVICE(0x0089), SUBDEV(0x1316)), + +/* 6150 WiFi/WiMax Series */ + IWL_DEV_INFO(iwl6150_bgn_cfg, iwl6150_bgn_name, + DEVICE(0x0885), SUBDEV_MASKED(0x5, 0xF)), + IWL_DEV_INFO(iwl6150_bg_cfg, iwl6150_bg_name, + DEVICE(0x0885), SUBDEV_MASKED(0x7, 0xF)), + IWL_DEV_INFO(iwl6150_bgn_cfg, iwl6150_bgn_name, + DEVICE(0x0886), SUBDEV(0x1315)), + IWL_DEV_INFO(iwl6150_bg_cfg, iwl6150_bg_name, + DEVICE(0x0886), SUBDEV(0x1317)), + +/* 1000 Series WiFi */ + IWL_DEV_INFO(iwl1000_bgn_cfg, iwl1000_bgn_name, + DEVICE(0x0083), SUBDEV_MASKED(0x5, 0xF)), + IWL_DEV_INFO(iwl1000_bg_cfg, iwl1000_bg_name, + DEVICE(0x0083), SUBDEV_MASKED(0x6, 0xF)), + IWL_DEV_INFO(iwl1000_bg_cfg, iwl1000_bg_name, + DEVICE(0x0084), SUBDEV(0x1216)), + IWL_DEV_INFO(iwl1000_bg_cfg, iwl1000_bg_name, + DEVICE(0x0084), SUBDEV(0x1316)), + +/* 100 Series WiFi */ + IWL_DEV_INFO(iwl100_bgn_cfg, iwl100_bgn_name, + DEVICE(0x08AE), SUBDEV_MASKED(0x5, 0xF)), + IWL_DEV_INFO(iwl100_bg_cfg, iwl100_bg_name, + DEVICE(0x08AE), SUBDEV_MASKED(0x7, 0xF)), + IWL_DEV_INFO(iwl100_bgn_cfg, iwl100_bgn_name, + DEVICE(0x08AF), SUBDEV(0x1015)), + IWL_DEV_INFO(iwl100_bg_cfg, iwl100_bg_name, + DEVICE(0x08AF), SUBDEV(0x1017)), + +/* 130 Series WiFi */ + IWL_DEV_INFO(iwl130_bgn_cfg, iwl130_bgn_name, + DEVICE(0x0896), SUBDEV_MASKED(0x5, 0xF)), + IWL_DEV_INFO(iwl130_bg_cfg, iwl130_bg_name, + DEVICE(0x0896), SUBDEV_MASKED(0x7, 0xF)), + IWL_DEV_INFO(iwl130_bgn_cfg, iwl130_bgn_name, + DEVICE(0x0897), SUBDEV(0x5015)), + IWL_DEV_INFO(iwl130_bg_cfg, iwl130_bg_name, + DEVICE(0x0897), SUBDEV(0x5017)), + +/* 2x00 Series */ + IWL_DEV_INFO(iwl2000_2bgn_cfg, iwl2000_2bgn_name, + DEVICE(0x0890), SUBDEV(0x4022)), + IWL_DEV_INFO(iwl2000_2bgn_cfg, iwl2000_2bgn_name, + DEVICE(0x0891), SUBDEV(0x4222)), + IWL_DEV_INFO(iwl2000_2bgn_cfg, iwl2000_2bgn_name, + DEVICE(0x0890), SUBDEV(0x4422)), + IWL_DEV_INFO(iwl2000_2bgn_cfg, iwl2000_2bgn_d_name, + DEVICE(0x0890), SUBDEV(0x4822)), + +/* 2x30 Series */ + IWL_DEV_INFO(iwl2030_2bgn_cfg, iwl2030_2bgn_name, + DEVICE(0x0887)), + IWL_DEV_INFO(iwl2030_2bgn_cfg, iwl2030_2bgn_name, + DEVICE(0x0888), SUBDEV(0x4262)), + +/* 6x35 Series */ + IWL_DEV_INFO(iwl6035_2agn_cfg, iwl6035_2agn_name, + DEVICE(0x088E), SUBDEV_MASKED(0x0, 0xF)), + IWL_DEV_INFO(iwl6035_2agn_cfg, iwl6035_2agn_sff_name, + DEVICE(0x088E), SUBDEV_MASKED(0xA, 0xF)), + IWL_DEV_INFO(iwl6035_2agn_cfg, iwl6035_2agn_name, + DEVICE(0x088F), SUBDEV_MASKED(0x0, 0xF)), + IWL_DEV_INFO(iwl6035_2agn_cfg, iwl6035_2agn_sff_name, + DEVICE(0x088F), SUBDEV_MASKED(0xA, 0xF)), + +/* 105 Series */ + IWL_DEV_INFO(iwl105_bgn_cfg, iwl105_bgn_name, + DEVICE(0x0894)), + IWL_DEV_INFO(iwl105_bgn_cfg, iwl105_bgn_name, + DEVICE(0x0895), SUBDEV(0x0222)), + +/* 135 Series */ + IWL_DEV_INFO(iwl135_bgn_cfg, iwl135_bgn_name, + DEVICE(0x0892)), + IWL_DEV_INFO(iwl135_bgn_cfg, iwl135_bgn_name, + DEVICE(0x0893), SUBDEV(0x0262)), +#endif /* CONFIG_IWLDVM */ + #if IS_ENABLED(CONFIG_IWLMVM) -/* 9000 */ - IWL_DEV_INFO(0x2526, 0x1550, iwl9260_2ac_cfg, iwl9260_killer_1550_name), - IWL_DEV_INFO(0x2526, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_name), - IWL_DEV_INFO(0x2526, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_name), - IWL_DEV_INFO(0x30DC, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_name), - IWL_DEV_INFO(0x30DC, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_name), - IWL_DEV_INFO(0x31DC, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_name), - IWL_DEV_INFO(0x31DC, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_name), - IWL_DEV_INFO(0xA370, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_name), - IWL_DEV_INFO(0xA370, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_name), - IWL_DEV_INFO(0x54F0, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_160_name), - IWL_DEV_INFO(0x54F0, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_name), - IWL_DEV_INFO(0x51F0, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_160_name), - IWL_DEV_INFO(0x51F0, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_160_name), - IWL_DEV_INFO(0x51F0, 0x1691, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name), - IWL_DEV_INFO(0x51F0, 0x1692, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name), - IWL_DEV_INFO(0x51F1, 0x1692, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name), - IWL_DEV_INFO(0x54F0, 0x1691, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name), - IWL_DEV_INFO(0x54F0, 0x1692, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name), - IWL_DEV_INFO(0x7A70, 0x1691, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name), - IWL_DEV_INFO(0x7A70, 0x1692, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name), - IWL_DEV_INFO(0x7AF0, 0x1691, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name), - IWL_DEV_INFO(0x7AF0, 0x1692, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name), - IWL_DEV_INFO(0x7F70, 0x1691, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name), - IWL_DEV_INFO(0x7F70, 0x1692, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name), - - IWL_DEV_INFO(0x271C, 0x0214, iwl9260_2ac_cfg, iwl9260_1_name), - IWL_DEV_INFO(0x7E40, 0x1691, iwl_cfg_ma, iwl_ax411_killer_1690s_name), - IWL_DEV_INFO(0x7E40, 0x1692, iwl_cfg_ma, iwl_ax411_killer_1690i_name), - -/* AX200 */ - IWL_DEV_INFO(0x2723, IWL_CFG_ANY, iwl_ax200_cfg_cc, iwl_ax200_name), - IWL_DEV_INFO(0x2723, 0x1653, iwl_ax200_cfg_cc, iwl_ax200_killer_1650w_name), - IWL_DEV_INFO(0x2723, 0x1654, iwl_ax200_cfg_cc, iwl_ax200_killer_1650x_name), - - /* Qu with Hr */ - IWL_DEV_INFO(0x43F0, 0x0070, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x43F0, 0x0074, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x43F0, 0x0078, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x43F0, 0x007C, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x43F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0, iwl_ax201_killer_1650s_name), - IWL_DEV_INFO(0x43F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0, iwl_ax201_killer_1650i_name), - IWL_DEV_INFO(0x43F0, 0x2074, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x43F0, 0x4070, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0xA0F0, 0x0070, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0xA0F0, 0x0074, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0xA0F0, 0x0078, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0xA0F0, 0x007C, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0xA0F0, 0x0A10, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0xA0F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0, NULL), - IWL_DEV_INFO(0xA0F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0, NULL), - IWL_DEV_INFO(0xA0F0, 0x2074, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0xA0F0, 0x4070, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0xA0F0, 0x6074, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x02F0, 0x0070, iwl_ax201_cfg_quz_hr, NULL), - IWL_DEV_INFO(0x02F0, 0x0074, iwl_ax201_cfg_quz_hr, NULL), - IWL_DEV_INFO(0x02F0, 0x6074, iwl_ax201_cfg_quz_hr, NULL), - IWL_DEV_INFO(0x02F0, 0x0078, iwl_ax201_cfg_quz_hr, NULL), - IWL_DEV_INFO(0x02F0, 0x007C, iwl_ax201_cfg_quz_hr, NULL), - IWL_DEV_INFO(0x02F0, 0x0310, iwl_ax201_cfg_quz_hr, NULL), - IWL_DEV_INFO(0x02F0, 0x1651, iwl_ax1650s_cfg_quz_hr, NULL), - IWL_DEV_INFO(0x02F0, 0x1652, iwl_ax1650i_cfg_quz_hr, NULL), - IWL_DEV_INFO(0x02F0, 0x2074, iwl_ax201_cfg_quz_hr, NULL), - IWL_DEV_INFO(0x02F0, 0x4070, iwl_ax201_cfg_quz_hr, NULL), - IWL_DEV_INFO(0x06F0, 0x0070, iwl_ax201_cfg_quz_hr, NULL), - IWL_DEV_INFO(0x06F0, 0x0074, iwl_ax201_cfg_quz_hr, NULL), - IWL_DEV_INFO(0x06F0, 0x0078, iwl_ax201_cfg_quz_hr, NULL), - IWL_DEV_INFO(0x06F0, 0x007C, iwl_ax201_cfg_quz_hr, NULL), - IWL_DEV_INFO(0x06F0, 0x0310, iwl_ax201_cfg_quz_hr, NULL), - IWL_DEV_INFO(0x06F0, 0x1651, iwl_ax1650s_cfg_quz_hr, NULL), - IWL_DEV_INFO(0x06F0, 0x1652, iwl_ax1650i_cfg_quz_hr, NULL), - IWL_DEV_INFO(0x06F0, 0x2074, iwl_ax201_cfg_quz_hr, NULL), - IWL_DEV_INFO(0x06F0, 0x4070, iwl_ax201_cfg_quz_hr, NULL), - IWL_DEV_INFO(0x34F0, 0x0070, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x34F0, 0x0074, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x34F0, 0x0078, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x34F0, 0x007C, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x34F0, 0x0310, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x34F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0, NULL), - IWL_DEV_INFO(0x34F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0, NULL), - IWL_DEV_INFO(0x34F0, 0x2074, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x34F0, 0x4070, iwl_ax201_cfg_qu_hr, NULL), - - IWL_DEV_INFO(0x3DF0, 0x0070, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x3DF0, 0x0074, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x3DF0, 0x0078, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x3DF0, 0x007C, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x3DF0, 0x0310, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x3DF0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0, NULL), - IWL_DEV_INFO(0x3DF0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0, NULL), - IWL_DEV_INFO(0x3DF0, 0x2074, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x3DF0, 0x4070, iwl_ax201_cfg_qu_hr, NULL), - - IWL_DEV_INFO(0x4DF0, 0x0070, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x4DF0, 0x0074, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x4DF0, 0x0078, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x4DF0, 0x007C, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x4DF0, 0x0310, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x4DF0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0, NULL), - IWL_DEV_INFO(0x4DF0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0, NULL), - IWL_DEV_INFO(0x4DF0, 0x2074, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x4DF0, 0x4070, iwl_ax201_cfg_qu_hr, NULL), - IWL_DEV_INFO(0x4DF0, 0x6074, iwl_ax201_cfg_qu_hr, NULL), - - /* So with HR */ - IWL_DEV_INFO(0x2725, 0x0090, iwlax211_2ax_cfg_so_gf_a0, NULL), - IWL_DEV_INFO(0x2725, 0x0020, iwlax210_2ax_cfg_ty_gf_a0, NULL), - IWL_DEV_INFO(0x2725, 0x2020, iwlax210_2ax_cfg_ty_gf_a0, NULL), - IWL_DEV_INFO(0x2725, 0x0024, iwlax210_2ax_cfg_ty_gf_a0, NULL), - IWL_DEV_INFO(0x2725, 0x0310, iwlax210_2ax_cfg_ty_gf_a0, NULL), - IWL_DEV_INFO(0x2725, 0x0510, iwlax210_2ax_cfg_ty_gf_a0, NULL), - IWL_DEV_INFO(0x2725, 0x0A10, iwlax210_2ax_cfg_ty_gf_a0, NULL), - IWL_DEV_INFO(0x2725, 0xE020, iwlax210_2ax_cfg_ty_gf_a0, NULL), - IWL_DEV_INFO(0x2725, 0xE024, iwlax210_2ax_cfg_ty_gf_a0, NULL), - IWL_DEV_INFO(0x2725, 0x4020, iwlax210_2ax_cfg_ty_gf_a0, NULL), - IWL_DEV_INFO(0x2725, 0x6020, iwlax210_2ax_cfg_ty_gf_a0, NULL), - IWL_DEV_INFO(0x2725, 0x6024, iwlax210_2ax_cfg_ty_gf_a0, NULL), - IWL_DEV_INFO(0x2725, 0x1673, iwlax210_2ax_cfg_ty_gf_a0, iwl_ax210_killer_1675w_name), - IWL_DEV_INFO(0x2725, 0x1674, iwlax210_2ax_cfg_ty_gf_a0, iwl_ax210_killer_1675x_name), - IWL_DEV_INFO(0x7A70, 0x0090, iwlax211_2ax_cfg_so_gf_a0_long, NULL), - IWL_DEV_INFO(0x7A70, 0x0098, iwlax211_2ax_cfg_so_gf_a0_long, NULL), - IWL_DEV_INFO(0x7A70, 0x00B0, iwlax411_2ax_cfg_so_gf4_a0_long, NULL), - IWL_DEV_INFO(0x7A70, 0x0310, iwlax211_2ax_cfg_so_gf_a0_long, NULL), - IWL_DEV_INFO(0x7A70, 0x0510, iwlax211_2ax_cfg_so_gf_a0_long, NULL), - IWL_DEV_INFO(0x7A70, 0x0A10, iwlax211_2ax_cfg_so_gf_a0_long, NULL), - IWL_DEV_INFO(0x7AF0, 0x0090, iwlax211_2ax_cfg_so_gf_a0, NULL), - IWL_DEV_INFO(0x7AF0, 0x0098, iwlax211_2ax_cfg_so_gf_a0, NULL), - IWL_DEV_INFO(0x7AF0, 0x00B0, iwlax411_2ax_cfg_so_gf4_a0, NULL), - IWL_DEV_INFO(0x7AF0, 0x0310, iwlax211_2ax_cfg_so_gf_a0, NULL), - IWL_DEV_INFO(0x7AF0, 0x0510, iwlax211_2ax_cfg_so_gf_a0, NULL), - IWL_DEV_INFO(0x7AF0, 0x0A10, iwlax211_2ax_cfg_so_gf_a0, NULL), - - /* So with JF */ - IWL_DEV_INFO(0x7A70, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_160_name), - IWL_DEV_INFO(0x7A70, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_160_name), - IWL_DEV_INFO(0x7AF0, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_160_name), - IWL_DEV_INFO(0x7AF0, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_160_name), - - /* SO with GF2 */ - IWL_DEV_INFO(0x2726, 0x1671, iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675s_name), - IWL_DEV_INFO(0x2726, 0x1672, iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675i_name), - IWL_DEV_INFO(0x51F0, 0x1671, iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675s_name), - IWL_DEV_INFO(0x51F0, 0x1672, iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675i_name), - IWL_DEV_INFO(0x51F1, 0x1671, iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675s_name), - IWL_DEV_INFO(0x51F1, 0x1672, iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675i_name), - IWL_DEV_INFO(0x54F0, 0x1671, iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675s_name), - IWL_DEV_INFO(0x54F0, 0x1672, iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675i_name), - IWL_DEV_INFO(0x7A70, 0x1671, iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675s_name), - IWL_DEV_INFO(0x7A70, 0x1672, iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675i_name), - IWL_DEV_INFO(0x7AF0, 0x1671, iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675s_name), - IWL_DEV_INFO(0x7AF0, 0x1672, iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675i_name), - IWL_DEV_INFO(0x7F70, 0x1671, iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675s_name), - IWL_DEV_INFO(0x7F70, 0x1672, iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_killer_1675i_name), - - /* MA with GF2 */ - IWL_DEV_INFO(0x7E40, 0x1671, iwl_cfg_ma, iwl_ax211_killer_1675s_name), - IWL_DEV_INFO(0x7E40, 0x1672, iwl_cfg_ma, iwl_ax211_killer_1675i_name), - - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_2ac_cfg_soc, iwl9461_160_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_2ac_cfg_soc, iwl9461_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_2ac_cfg_soc, iwl9462_160_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_2ac_cfg_soc, iwl9462_name), - - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_2ac_cfg_soc, iwl9560_160_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_2ac_cfg_soc, iwl9560_name), - - _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_TH, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_TH, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT_GNSS, IWL_CFG_NO_CDB, - iwl9260_2ac_cfg, iwl9270_160_name), - _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_TH, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_TH, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT_GNSS, IWL_CFG_NO_CDB, - iwl9260_2ac_cfg, iwl9270_name), - - _IWL_DEV_INFO(0x271B, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_TH, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_TH1, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9260_2ac_cfg, iwl9162_160_name), - _IWL_DEV_INFO(0x271B, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_TH, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_TH1, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9260_2ac_cfg, iwl9162_name), - - _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_TH, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_TH, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9260_2ac_cfg, iwl9260_160_name), - _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_TH, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_TH, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9260_2ac_cfg, iwl9260_name), - -/* Qu with Jf */ - /* Qu B step */ - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_qu_b0_jf_b0_cfg, iwl9461_160_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_qu_b0_jf_b0_cfg, iwl9461_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_qu_b0_jf_b0_cfg, iwl9462_160_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_qu_b0_jf_b0_cfg, iwl9462_name), - - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, - IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_qu_b0_jf_b0_cfg, iwl9560_160_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, - IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_qu_b0_jf_b0_cfg, iwl9560_name), - - _IWL_DEV_INFO(IWL_CFG_ANY, 0x1551, - IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, - IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_qu_b0_jf_b0_cfg, iwl9560_killer_1550s_name), - _IWL_DEV_INFO(IWL_CFG_ANY, 0x1552, - IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, - IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_qu_b0_jf_b0_cfg, iwl9560_killer_1550i_name), - - /* Qu C step */ - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_qu_c0_jf_b0_cfg, iwl9461_160_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_qu_c0_jf_b0_cfg, iwl9461_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_qu_c0_jf_b0_cfg, iwl9462_160_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_qu_c0_jf_b0_cfg, iwl9462_name), - - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, - IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_qu_c0_jf_b0_cfg, iwl9560_160_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, - IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_qu_c0_jf_b0_cfg, iwl9560_name), - - _IWL_DEV_INFO(IWL_CFG_ANY, 0x1551, - IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, - IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_qu_c0_jf_b0_cfg, iwl9560_killer_1550s_name), - _IWL_DEV_INFO(IWL_CFG_ANY, 0x1552, - IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, - IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_qu_c0_jf_b0_cfg, iwl9560_killer_1550i_name), - - /* QuZ */ - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_quz_a0_jf_b0_cfg, iwl9461_160_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_quz_a0_jf_b0_cfg, iwl9461_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_quz_a0_jf_b0_cfg, iwl9462_160_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_quz_a0_jf_b0_cfg, iwl9462_name), - - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_quz_a0_jf_b0_cfg, iwl9560_160_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_quz_a0_jf_b0_cfg, iwl9560_name), - - _IWL_DEV_INFO(IWL_CFG_ANY, 0x1551, - IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_quz_a0_jf_b0_cfg, iwl9560_killer_1550s_name), - _IWL_DEV_INFO(IWL_CFG_ANY, 0x1552, - IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9560_quz_a0_jf_b0_cfg, iwl9560_killer_1550i_name), - -/* Qu with Hr */ - /* Qu B step */ - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, - IWL_CFG_RF_TYPE_HR1, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwl_qu_b0_hr1_b0, iwl_ax101_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, - IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwl_qu_b0_hr_b0, iwl_ax203_name), - - /* Qu C step */ - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, - IWL_CFG_RF_TYPE_HR1, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwl_qu_c0_hr1_b0, iwl_ax101_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, - IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwl_qu_c0_hr_b0, iwl_ax203_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, - IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwl_qu_c0_hr_b0, iwl_ax201_name), - - /* QuZ */ - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QUZ, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_HR1, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwl_quz_a0_hr1_b0, iwl_ax101_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QUZ, SILICON_B_STEP, - IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwl_cfg_quz_a0_hr_b0, iwl_ax203_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QUZ, SILICON_B_STEP, - IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwl_cfg_quz_a0_hr_b0, iwl_ax201_name), - -/* Ma */ - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_MA, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwl_cfg_ma, iwl_ax201_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_MA, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_ma, iwl_ax211_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_MA, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwl_cfg_ma, iwl_ax231_name), - -/* So with Hr */ - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwl_cfg_so_a0_hr_a0, iwl_ax203_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_HR1, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwl_cfg_so_a0_hr_a0, iwl_ax101_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwl_cfg_so_a0_hr_a0, iwl_ax201_name), - -/* So-F with Hr */ - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwl_cfg_so_a0_hr_a0, iwl_ax203_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_HR1, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwl_cfg_so_a0_hr_a0, iwl_ax101_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwl_cfg_so_a0_hr_a0, iwl_ax201_name), - -/* So-F with Gf */ - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_CDB, - iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_name), - -/* SoF with JF2 */ - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwlax210_2ax_cfg_so_jf_b0, iwl9560_160_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwlax210_2ax_cfg_so_jf_b0, iwl9560_name), - -/* SoF with JF */ - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwlax210_2ax_cfg_so_jf_b0, iwl9461_160_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwlax210_2ax_cfg_so_jf_b0, iwl9462_160_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwlax210_2ax_cfg_so_jf_b0, iwl9461_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwlax210_2ax_cfg_so_jf_b0, iwl9462_name), - -/* So with GF */ - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_CDB, - iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_name), - -/* So with JF2 */ - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwlax210_2ax_cfg_so_jf_b0, iwl9560_160_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwlax210_2ax_cfg_so_jf_b0, iwl9560_name), - -/* So with JF */ - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwlax210_2ax_cfg_so_jf_b0, iwl9461_160_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwlax210_2ax_cfg_so_jf_b0, iwl9462_160_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwlax210_2ax_cfg_so_jf_b0, iwl9461_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwlax210_2ax_cfg_so_jf_b0, iwl9462_name), +/* 7260 Series */ + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2ac_name, + DEVICE(0x08B1)), // unlisted ones fall through to here + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B1), SUBDEV(0x4060)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B1), SUBDEV(0x406A)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B1), SUBDEV(0x4160)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_n_name, + DEVICE(0x08B1), SUBDEV(0x4062)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_n_name, + DEVICE(0x08B1), SUBDEV(0x4162)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B1), SUBDEV(0x4460)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B1), SUBDEV(0x446A)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_n_name, + DEVICE(0x08B1), SUBDEV(0x4462)), + IWL_DEV_INFO(iwl7260_high_temp_cfg, iwl7260_2ac_name, + DEVICE(0x08B1), SUBDEV(0x4A70)), + IWL_DEV_INFO(iwl7260_high_temp_cfg, iwl7260_2ac_name, + DEVICE(0x08B1), SUBDEV(0x4A6E)), + IWL_DEV_INFO(iwl7260_high_temp_cfg, iwl7260_2ac_name, + DEVICE(0x08B1), SUBDEV(0x4A6C)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B1), SUBDEV(0x4560)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B1), SUBDEV(0x4020)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B1), SUBDEV(0x402A)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B1), SUBDEV(0x4420)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B1), SUBDEV(0xC060)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B1), SUBDEV(0xC06A)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B1), SUBDEV(0xC160)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_n_name, + DEVICE(0x08B1), SUBDEV(0xC062)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_n_name, + DEVICE(0x08B1), SUBDEV(0xC162)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B1), SUBDEV(0xC760)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B1), SUBDEV(0xC460)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_n_name, + DEVICE(0x08B1), SUBDEV(0xC462)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B1), SUBDEV(0xC560)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B1), SUBDEV(0xC360)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B1), SUBDEV(0xC020)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B1), SUBDEV(0xC02A)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B1), SUBDEV(0xC420)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2ac_name, + DEVICE(0x08B2), SUBDEV(0x4270)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2ac_name, + DEVICE(0x08B2), SUBDEV(0x4272)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B2), SUBDEV(0x4260)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B2), SUBDEV(0x426A)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_n_name, + DEVICE(0x08B2), SUBDEV(0x4262)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2ac_name, + DEVICE(0x08B2), SUBDEV(0x4370)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B2), SUBDEV(0x4360)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B2), SUBDEV(0x4220)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2ac_name, + DEVICE(0x08B2), SUBDEV(0xC270)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2ac_name, + DEVICE(0x08B2), SUBDEV(0xC272)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B2), SUBDEV(0xC260)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_n_name, + DEVICE(0x08B2), SUBDEV(0xC26A)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_n_name, + DEVICE(0x08B2), SUBDEV(0xC262)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2ac_name, + DEVICE(0x08B2), SUBDEV(0xC370)), + IWL_DEV_INFO(iwl7260_cfg, iwl7260_2n_name, + DEVICE(0x08B2), SUBDEV(0xC220)), +/* 3160 Series */ + IWL_DEV_INFO(iwl3160_cfg, iwl3160_2ac_name, + DEVICE(0x08B3)), + + IWL_DEV_INFO(iwl3160_cfg, iwl3160_n_name, + DEVICE(0x08B3), SUBDEV_MASKED(0x62, 0xFF)), + IWL_DEV_INFO(iwl3160_cfg, iwl3160_2n_name, + DEVICE(0x08B3), SUBDEV_MASKED(0x60, 0xFF)), + + IWL_DEV_INFO(iwl3160_cfg, iwl3160_2ac_name, + DEVICE(0x08B4)), + +/* 3165 Series */ + IWL_DEV_INFO(iwl3165_2ac_cfg, iwl3165_2ac_name, + DEVICE(0x3165)), + IWL_DEV_INFO(iwl3165_2ac_cfg, iwl3165_2ac_name, + DEVICE(0x3166)), + +/* 3168 Series */ + IWL_DEV_INFO(iwl3168_2ac_cfg, iwl3168_2ac_name, + DEVICE(0x24FB)), + +/* 7265 Series */ + IWL_DEV_INFO(iwl7265_cfg, iwl7265_2ac_name, + DEVICE(0x095A)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_2n_name, + DEVICE(0x095A), SUBDEV(0x5000)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_2n_name, + DEVICE(0x095A), SUBDEV(0x500A)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_n_name, + DEVICE(0x095A), SUBDEV(0x5002)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_n_name, + DEVICE(0x095A), SUBDEV(0x5102)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_2n_name, + DEVICE(0x095A), SUBDEV(0x5020)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_2n_name, + DEVICE(0x095A), SUBDEV(0x502A)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_2n_name, + DEVICE(0x095A), SUBDEV(0x5090)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_2n_name, + DEVICE(0x095A), SUBDEV(0x5190)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_2n_name, + DEVICE(0x095A), SUBDEV(0x5100)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_2n_name, + DEVICE(0x095A), SUBDEV(0x5400)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_2n_name, + DEVICE(0x095A), SUBDEV(0x5420)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_2n_name, + DEVICE(0x095A), SUBDEV(0x5490)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_2n_name, + DEVICE(0x095A), SUBDEV(0x5C10)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_2n_name, + DEVICE(0x095A), SUBDEV(0x5590)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_2n_name, + DEVICE(0x095A), SUBDEV(0x9000)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_2n_name, + DEVICE(0x095A), SUBDEV(0x900A)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_2n_name, + DEVICE(0x095A), SUBDEV(0x9400)), + + IWL_DEV_INFO(iwl7265_cfg, iwl7265_2ac_name, + DEVICE(0x095B)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_2n_name, + DEVICE(0x095B), SUBDEV(0x520A)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_n_name, + DEVICE(0x095B), SUBDEV(0x5302)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_2n_name, + DEVICE(0x095B), SUBDEV(0x5200)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_n_name, + DEVICE(0x095B), SUBDEV(0x5202)), + IWL_DEV_INFO(iwl7265_cfg, iwl7265_2n_name, + DEVICE(0x095B), SUBDEV(0x9200)), + +/* 8000 Series */ + IWL_DEV_INFO(iwl8260_cfg, iwl8260_2ac_name, + DEVICE(0x24F3)), + IWL_DEV_INFO(iwl8260_cfg, iwl8260_2n_name, + DEVICE(0x24F3), SUBDEV(0x0004)), + IWL_DEV_INFO(iwl8260_cfg, iwl8260_2n_name, + DEVICE(0x24F3), SUBDEV(0x0044)), + IWL_DEV_INFO(iwl8265_cfg, iwl8265_2ac_name, + DEVICE(0x24FD)), + IWL_DEV_INFO(iwl8265_cfg, iwl8275_2ac_name, + DEVICE(0x24FD), SUBDEV(0x3E02)), + IWL_DEV_INFO(iwl8265_cfg, iwl8275_2ac_name, + DEVICE(0x24FD), SUBDEV(0x3E01)), + IWL_DEV_INFO(iwl8265_cfg, iwl8275_2ac_name, + DEVICE(0x24FD), SUBDEV(0x1012)), + IWL_DEV_INFO(iwl8265_cfg, iwl8275_2ac_name, + DEVICE(0x24FD), SUBDEV(0x0012)), + IWL_DEV_INFO(iwl8265_cfg, iwl_killer_1435i_name, + DEVICE(0x24FD), SUBDEV(0x1431)), + IWL_DEV_INFO(iwl8265_cfg, iwl_killer_1434_kix_name, + DEVICE(0x24FD), SUBDEV(0x1432)), + +/* JF1 RF */ + IWL_DEV_INFO(iwl_rf_jf, iwl9461_160_name, + RF_TYPE(JF1)), + IWL_DEV_INFO(iwl_rf_jf_80mhz, iwl9461_name, + RF_TYPE(JF1), BW_LIMITED), + IWL_DEV_INFO(iwl_rf_jf, iwl9462_160_name, + RF_TYPE(JF1), RF_ID(JF1_DIV)), + IWL_DEV_INFO(iwl_rf_jf_80mhz, iwl9462_name, + RF_TYPE(JF1), RF_ID(JF1_DIV), BW_LIMITED), +/* JF2 RF */ + IWL_DEV_INFO(iwl_rf_jf, iwl9260_160_name, + RF_TYPE(JF2)), + IWL_DEV_INFO(iwl_rf_jf_80mhz, iwl9260_name, + RF_TYPE(JF2), BW_LIMITED), + IWL_DEV_INFO(iwl_rf_jf, iwl9560_160_name, + RF_TYPE(JF2), RF_ID(JF)), + IWL_DEV_INFO(iwl_rf_jf_80mhz, iwl9560_name, + RF_TYPE(JF2), RF_ID(JF), BW_LIMITED), + +/* HR RF */ + IWL_DEV_INFO(iwl_rf_hr, iwl_ax201_name, RF_TYPE(HR2)), + IWL_DEV_INFO(iwl_rf_hr_80mhz, iwl_ax101_name, RF_TYPE(HR1)), + IWL_DEV_INFO(iwl_rf_hr_80mhz, iwl_ax203_name, RF_TYPE(HR2), BW_LIMITED), + IWL_DEV_INFO(iwl_rf_hr, iwl_ax200_name, DEVICE(0x2723)), + +/* GF RF */ + IWL_DEV_INFO(iwl_rf_gf, iwl_ax211_name, RF_TYPE(GF)), + IWL_DEV_INFO(iwl_rf_gf, iwl_ax411_name, RF_TYPE(GF), CDB), + IWL_DEV_INFO(iwl_rf_gf, iwl_ax210_name, DEVICE(0x2725)), + +/* Killer CRFs */ + IWL_DEV_INFO(iwl_rf_jf, iwl9260_killer_1550_name, SUBDEV(0x1550)), + IWL_DEV_INFO(iwl_rf_jf, iwl9560_killer_1550s_name, SUBDEV(0x1551)), + IWL_DEV_INFO(iwl_rf_jf, iwl9560_killer_1550i_name, SUBDEV(0x1552)), + + IWL_DEV_INFO(iwl_rf_hr, iwl_ax201_killer_1650s_name, SUBDEV(0x1651)), + IWL_DEV_INFO(iwl_rf_hr, iwl_ax201_killer_1650i_name, SUBDEV(0x1652)), + + IWL_DEV_INFO(iwl_rf_gf, iwl_ax211_killer_1675s_name, SUBDEV(0x1671)), + IWL_DEV_INFO(iwl_rf_gf, iwl_ax211_killer_1675i_name, SUBDEV(0x1672)), + IWL_DEV_INFO(iwl_rf_gf, iwl_ax210_killer_1675w_name, SUBDEV(0x1673)), + IWL_DEV_INFO(iwl_rf_gf, iwl_ax210_killer_1675x_name, SUBDEV(0x1674)), + IWL_DEV_INFO(iwl_rf_gf, iwl_ax411_killer_1690s_name, SUBDEV(0x1691)), + IWL_DEV_INFO(iwl_rf_gf, iwl_ax411_killer_1690i_name, SUBDEV(0x1692)), + +/* Killer discrete */ + IWL_DEV_INFO(iwl_rf_hr, iwl_ax200_killer_1650w_name, + DEVICE(0x2723), SUBDEV(0x1653)), + IWL_DEV_INFO(iwl_rf_hr, iwl_ax200_killer_1650x_name, + DEVICE(0x2723), SUBDEV(0x1654)), #endif /* CONFIG_IWLMVM */ #if IS_ENABLED(CONFIG_IWLMLD) -/* Bz */ - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_bz, iwl_ax201_name), - - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_bz, iwl_ax211_name), - - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_bz, iwl_fm_name), - - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_WH, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_bz, iwl_wh_name), - - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_BZ_W, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_bz, iwl_ax201_name), - - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_BZ_W, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_bz, iwl_ax211_name), - - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_BZ_W, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_bz, iwl_fm_name), - - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_BZ_W, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_WH, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_bz, iwl_wh_name), - -/* Ga (Gl) */ - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_GL, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_320, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwl_cfg_gl, iwl_gl_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_GL, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_NO_320, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwl_cfg_gl, iwl_mtp_name), - -/* Sc */ - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SC, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_sc, iwl_ax211_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SC, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_sc, iwl_fm_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SC, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_WH, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_sc, iwl_wh_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SC2, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_sc2, iwl_ax211_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SC2, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_sc2, iwl_fm_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SC2, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_WH, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_sc2, iwl_wh_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SC2F, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_sc2f, iwl_ax211_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SC2F, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_sc2f, iwl_fm_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SC2F, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_WH, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_sc2f, iwl_wh_name), - -/* Dr */ - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_DR, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_dr, iwl_dr_name), - -/* Br */ - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_BR, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, - iwl_cfg_br, iwl_br_name), +/* FM RF */ + IWL_DEV_INFO(iwl_rf_fm, iwl_be201_name, RF_TYPE(FM)), + IWL_DEV_INFO(iwl_rf_fm, iwl_be401_name, RF_TYPE(FM), CDB), + /* the discrete NICs got the RF B0, it's only for the name anyway */ + IWL_DEV_INFO(iwl_rf_fm, iwl_be200_name, RF_TYPE(FM), + DEVICE(0x272B), RF_STEP(B)), + IWL_DEV_INFO(iwl_rf_fm_160mhz, iwl_be202_name, + RF_TYPE(FM), BW_LIMITED), + +/* Killer CRFs */ + IWL_DEV_INFO(iwl_rf_fm, iwl_killer_be1750s_name, SUBDEV(0x1771)), + IWL_DEV_INFO(iwl_rf_fm, iwl_killer_be1750i_name, SUBDEV(0x1772)), + IWL_DEV_INFO(iwl_rf_fm, iwl_killer_be1790s_name, SUBDEV(0x1791)), + IWL_DEV_INFO(iwl_rf_fm, iwl_killer_be1790i_name, SUBDEV(0x1792)), + +/* Killer discrete */ + IWL_DEV_INFO(iwl_rf_fm, iwl_killer_be1750w_name, + DEVICE(0x272B), SUBDEV(0x1773)), + IWL_DEV_INFO(iwl_rf_fm, iwl_killer_be1750x_name, + DEVICE(0x272B), SUBDEV(0x1774)), + +/* WH RF */ + IWL_DEV_INFO(iwl_rf_wh, iwl_be211_name, RF_TYPE(WH)), + IWL_DEV_INFO(iwl_rf_wh_160mhz, iwl_be213_name, RF_TYPE(WH), BW_LIMITED), + +/* PE RF */ + IWL_DEV_INFO(iwl_rf_pe, iwl_bn201_name, RF_TYPE(PE)), + IWL_DEV_INFO(iwl_rf_pe, iwl_be223_name, RF_TYPE(PE), SUBDEV(0x0524)), + IWL_DEV_INFO(iwl_rf_pe, iwl_be221_name, RF_TYPE(PE), SUBDEV(0x0324)), + +/* Killer */ + IWL_DEV_INFO(iwl_rf_wh, iwl_killer_be1775s_name, SUBDEV(0x1776)), + IWL_DEV_INFO(iwl_rf_wh, iwl_killer_be1775i_name, SUBDEV(0x1775)), + + IWL_DEV_INFO(iwl_rf_pe, iwl_killer_bn1850w2_name, SUBDEV(0x1851)), + IWL_DEV_INFO(iwl_rf_pe, iwl_killer_bn1850i_name, SUBDEV(0x1852)), #endif /* CONFIG_IWLMLD */ }; EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_dev_info_table); @@ -1246,13 +1076,15 @@ EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_dev_info_table_size); /* * Read rf id and cdb info from prph register and store it */ -static void get_crf_id(struct iwl_trans *iwl_trans) +static void get_crf_id(struct iwl_trans *iwl_trans, + struct iwl_trans_info *info) { u32 sd_reg_ver_addr; + u32 hw_wfpm_id; u32 val = 0; u8 step; - if (iwl_trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) + if (iwl_trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) sd_reg_ver_addr = SD_REG_VER_GEN2; else sd_reg_ver_addr = SD_REG_VER; @@ -1263,83 +1095,83 @@ static void get_crf_id(struct iwl_trans *iwl_trans) iwl_write_umac_prph_no_grab(iwl_trans, WFPM_CTRL_REG, val); /* Read crf info */ - iwl_trans->hw_crf_id = iwl_read_prph_no_grab(iwl_trans, sd_reg_ver_addr); + info->hw_crf_id = iwl_read_prph_no_grab(iwl_trans, sd_reg_ver_addr); /* Read cnv info */ - iwl_trans->hw_cnv_id = - iwl_read_prph_no_grab(iwl_trans, CNVI_AUX_MISC_CHIP); + info->hw_cnv_id = iwl_read_prph_no_grab(iwl_trans, CNVI_AUX_MISC_CHIP); /* For BZ-W, take B step also when A step is indicated */ - if (CSR_HW_REV_TYPE(iwl_trans->hw_rev) == IWL_CFG_MAC_TYPE_BZ_W) + if (CSR_HW_REV_TYPE(info->hw_rev) == IWL_CFG_MAC_TYPE_BZ_W) step = SILICON_B_STEP; /* In BZ, the MAC step must be read from the CNVI aux register */ - if (CSR_HW_REV_TYPE(iwl_trans->hw_rev) == IWL_CFG_MAC_TYPE_BZ) { - step = CNVI_AUX_MISC_CHIP_MAC_STEP(iwl_trans->hw_cnv_id); + if (CSR_HW_REV_TYPE(info->hw_rev) == IWL_CFG_MAC_TYPE_BZ) { + step = CNVI_AUX_MISC_CHIP_MAC_STEP(info->hw_cnv_id); /* For BZ-U, take B step also when A step is indicated */ - if ((CNVI_AUX_MISC_CHIP_PROD_TYPE(iwl_trans->hw_cnv_id) == + if ((CNVI_AUX_MISC_CHIP_PROD_TYPE(info->hw_cnv_id) == CNVI_AUX_MISC_CHIP_PROD_TYPE_BZ_U) && step == SILICON_A_STEP) step = SILICON_B_STEP; } - if (CSR_HW_REV_TYPE(iwl_trans->hw_rev) == IWL_CFG_MAC_TYPE_BZ || - CSR_HW_REV_TYPE(iwl_trans->hw_rev) == IWL_CFG_MAC_TYPE_BZ_W) { - iwl_trans->hw_rev_step = step; - iwl_trans->hw_rev |= step; + if (CSR_HW_REV_TYPE(info->hw_rev) == IWL_CFG_MAC_TYPE_BZ || + CSR_HW_REV_TYPE(info->hw_rev) == IWL_CFG_MAC_TYPE_BZ_W) { + info->hw_rev_step = step; + info->hw_rev |= step; } /* Read cdb info (also contains the jacket info if needed in the future */ - iwl_trans->hw_wfpm_id = - iwl_read_umac_prph_no_grab(iwl_trans, WFPM_OTP_CFG1_ADDR); + hw_wfpm_id = iwl_read_umac_prph_no_grab(iwl_trans, WFPM_OTP_CFG1_ADDR); IWL_INFO(iwl_trans, "Detected crf-id 0x%x, cnv-id 0x%x wfpm id 0x%x\n", - iwl_trans->hw_crf_id, iwl_trans->hw_cnv_id, - iwl_trans->hw_wfpm_id); + info->hw_crf_id, info->hw_cnv_id, hw_wfpm_id); } /* * In case that there is no OTP on the NIC, map the rf id and cdb info * from the prph registers. */ -static int map_crf_id(struct iwl_trans *iwl_trans) +static int map_crf_id(struct iwl_trans *iwl_trans, + struct iwl_trans_info *info) { int ret = 0; - u32 val = iwl_trans->hw_crf_id; + u32 val = info->hw_crf_id; u32 step_id = REG_CRF_ID_STEP(val); u32 slave_id = REG_CRF_ID_SLAVE(val); - u32 jacket_id_cnv = REG_CRF_ID_SLAVE(iwl_trans->hw_cnv_id); - u32 jacket_id_wfpm = WFPM_OTP_CFG1_IS_JACKET(iwl_trans->hw_wfpm_id); - u32 cdb_id_wfpm = WFPM_OTP_CFG1_IS_CDB(iwl_trans->hw_wfpm_id); + u32 jacket_id_cnv = REG_CRF_ID_SLAVE(info->hw_cnv_id); + u32 hw_wfpm_id = iwl_read_umac_prph_no_grab(iwl_trans, + WFPM_OTP_CFG1_ADDR); + u32 jacket_id_wfpm = WFPM_OTP_CFG1_IS_JACKET(hw_wfpm_id); + u32 cdb_id_wfpm = WFPM_OTP_CFG1_IS_CDB(hw_wfpm_id); /* Map between crf id to rf id */ switch (REG_CRF_ID_TYPE(val)) { case REG_CRF_ID_TYPE_JF_1: - iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_JF1 << 12); + info->hw_rf_id = (IWL_CFG_RF_TYPE_JF1 << 12); break; case REG_CRF_ID_TYPE_JF_2: - iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_JF2 << 12); + info->hw_rf_id = (IWL_CFG_RF_TYPE_JF2 << 12); break; case REG_CRF_ID_TYPE_HR_NONE_CDB_1X1: - iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_HR1 << 12); + info->hw_rf_id = (IWL_CFG_RF_TYPE_HR1 << 12); break; case REG_CRF_ID_TYPE_HR_NONE_CDB: - iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_HR2 << 12); + info->hw_rf_id = (IWL_CFG_RF_TYPE_HR2 << 12); break; case REG_CRF_ID_TYPE_HR_CDB: - iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_HR2 << 12); + info->hw_rf_id = (IWL_CFG_RF_TYPE_HR2 << 12); break; case REG_CRF_ID_TYPE_GF: - iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_GF << 12); + info->hw_rf_id = (IWL_CFG_RF_TYPE_GF << 12); break; case REG_CRF_ID_TYPE_FM: - iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_FM << 12); + info->hw_rf_id = (IWL_CFG_RF_TYPE_FM << 12); break; case REG_CRF_ID_TYPE_WHP: - iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_WH << 12); + info->hw_rf_id = (IWL_CFG_RF_TYPE_WH << 12); break; case REG_CRF_ID_TYPE_PE: - iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_PE << 12); + info->hw_rf_id = (IWL_CFG_RF_TYPE_PE << 12); break; default: ret = -EIO; @@ -1351,28 +1183,28 @@ static int map_crf_id(struct iwl_trans *iwl_trans) } /* Set Step-id */ - iwl_trans->hw_rf_id |= (step_id << 8); + info->hw_rf_id |= (step_id << 8); /* Set CDB capabilities */ if (cdb_id_wfpm || slave_id) { - iwl_trans->hw_rf_id += BIT(28); + info->hw_rf_id += BIT(28); IWL_INFO(iwl_trans, "Adding cdb to rf id\n"); } /* Set Jacket capabilities */ if (jacket_id_wfpm || jacket_id_cnv) { - iwl_trans->hw_rf_id += BIT(29); + info->hw_rf_id += BIT(29); IWL_INFO(iwl_trans, "Adding jacket to rf id\n"); } IWL_INFO(iwl_trans, "Detected rf-type 0x%x step-id 0x%x slave-id 0x%x from crf id 0x%x\n", - REG_CRF_ID_TYPE(val), step_id, slave_id, iwl_trans->hw_rf_id); + REG_CRF_ID_TYPE(val), step_id, slave_id, info->hw_rf_id); IWL_INFO(iwl_trans, "Detected cdb-id 0x%x jacket-id 0x%x from wfpm id 0x%x\n", - cdb_id_wfpm, jacket_id_wfpm, iwl_trans->hw_wfpm_id); + cdb_id_wfpm, jacket_id_wfpm, hw_wfpm_id); IWL_INFO(iwl_trans, "Detected jacket-id 0x%x from cnvi id 0x%x\n", - jacket_id_cnv, iwl_trans->hw_cnv_id); + jacket_id_cnv, info->hw_cnv_id); out: return ret; @@ -1382,9 +1214,8 @@ out: #define PCI_CFG_RETRY_TIMEOUT 0x041 VISIBLE_IF_IWLWIFI_KUNIT const struct iwl_dev_info * -iwl_pci_find_dev_info(u16 device, u16 subsystem_device, - u16 mac_type, u8 mac_step, u16 rf_type, u8 cdb, - u8 jacket, u8 rf_id, u8 no_160, u8 cores, u8 rf_step) +iwl_pci_find_dev_info(u16 device, u16 subsystem_device, u16 rf_type, u8 cdb, + u8 rf_id, u8 bw_limit, u8 rf_step) { int num_devices = ARRAY_SIZE(iwl_dev_info_table); int i; @@ -1394,49 +1225,32 @@ iwl_pci_find_dev_info(u16 device, u16 subsystem_device, for (i = num_devices - 1; i >= 0; i--) { const struct iwl_dev_info *dev_info = &iwl_dev_info_table[i]; + u16 subdevice_mask; if (dev_info->device != (u16)IWL_CFG_ANY && dev_info->device != device) continue; - if (dev_info->subdevice != (u16)IWL_CFG_ANY && - dev_info->subdevice != subsystem_device) - continue; - - if (dev_info->mac_type != (u16)IWL_CFG_ANY && - dev_info->mac_type != mac_type) - continue; - - if (dev_info->mac_step != (u8)IWL_CFG_ANY && - dev_info->mac_step != mac_step) - continue; - - if (dev_info->rf_type != (u16)IWL_CFG_ANY && - dev_info->rf_type != rf_type) - continue; + subdevice_mask = GENMASK(dev_info->subdevice_m_h, + dev_info->subdevice_m_l); - if (dev_info->cdb != (u8)IWL_CFG_ANY && - dev_info->cdb != cdb) + if (dev_info->subdevice != (u16)IWL_CFG_ANY && + dev_info->subdevice != (subsystem_device & subdevice_mask)) continue; - if (dev_info->jacket != (u8)IWL_CFG_ANY && - dev_info->jacket != jacket) + if (dev_info->match_rf_type && dev_info->rf_type != rf_type) continue; - if (dev_info->rf_id != (u8)IWL_CFG_ANY && - dev_info->rf_id != rf_id) + if (dev_info->match_cdb && dev_info->cdb != cdb) continue; - if (dev_info->no_160 != (u8)IWL_CFG_ANY && - dev_info->no_160 != no_160) + if (dev_info->match_rf_id && dev_info->rf_id != rf_id) continue; - if (dev_info->cores != (u8)IWL_CFG_ANY && - dev_info->cores != cores) + if (dev_info->match_bw_limit && dev_info->bw_limit != bw_limit) continue; - if (dev_info->rf_step != (u8)IWL_CFG_ANY && - dev_info->rf_step != rf_step) + if (dev_info->match_rf_step && dev_info->rf_step != rf_step) continue; return dev_info; @@ -1448,30 +1262,32 @@ EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_pci_find_dev_info); static void iwl_pcie_recheck_me_status(struct work_struct *wk) { - struct iwl_trans *trans = container_of(wk, typeof(*trans), - me_recheck_wk.work); + struct iwl_trans_pcie *trans_pcie = container_of(wk, + typeof(*trans_pcie), + me_recheck_wk.work); u32 val; - val = iwl_read32(trans, CSR_HW_IF_CONFIG_REG); - trans->me_present = !!(val & CSR_HW_IF_CONFIG_REG_IAMT_UP); + val = iwl_read32(trans_pcie->trans, CSR_HW_IF_CONFIG_REG); + trans_pcie->me_present = !!(val & CSR_HW_IF_CONFIG_REG_IAMT_UP); } static void iwl_pcie_check_me_status(struct iwl_trans *trans) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); u32 val; - trans->me_present = -1; + trans_pcie->me_present = -1; - INIT_DELAYED_WORK(&trans->me_recheck_wk, + INIT_DELAYED_WORK(&trans_pcie->me_recheck_wk, iwl_pcie_recheck_me_status); /* we don't have a good way of determining this until BZ */ - if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_BZ) + if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_BZ) return; val = iwl_read_prph(trans, CNVI_SCU_REG_FOR_ECO_1); if (val & CNVI_SCU_REG_FOR_ECO_1_WIAMT_KNOWN) { - trans->me_present = + trans_pcie->me_present = !!(val & CNVI_SCU_REG_FOR_ECO_1_WIAMT_PRESENT); return; } @@ -1479,38 +1295,28 @@ static void iwl_pcie_check_me_status(struct iwl_trans *trans) val = iwl_read32(trans, CSR_HW_IF_CONFIG_REG); if (val & (CSR_HW_IF_CONFIG_REG_ME_OWN | CSR_HW_IF_CONFIG_REG_IAMT_UP)) { - trans->me_present = 1; + trans_pcie->me_present = 1; return; } /* recheck again later, ME might still be initializing */ - schedule_delayed_work(&trans->me_recheck_wk, HZ); + schedule_delayed_work(&trans_pcie->me_recheck_wk, HZ); } static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - const struct iwl_cfg_trans_params *trans; - const struct iwl_cfg *cfg_7265d __maybe_unused = NULL; + const struct iwl_mac_cfg *trans; const struct iwl_dev_info *dev_info; + struct iwl_trans_info info = { + .hw_id = (pdev->device << 16) + pdev->subsystem_device, + }; struct iwl_trans *iwl_trans; struct iwl_trans_pcie *trans_pcie; int ret; - const struct iwl_cfg *cfg; - trans = (void *)(ent->driver_data & ~TRANS_CFG_MARKER); + trans = (void *)ent->driver_data; - /* - * This is needed for backwards compatibility with the old - * tables, so we don't need to change all the config structs - * at the same time. The cfg is used to compare with the old - * full cfg structs. - */ - cfg = (void *)(ent->driver_data & ~TRANS_CFG_MARKER); - - /* make sure trans is the first element in iwl_cfg */ - BUILD_BUG_ON(offsetof(struct iwl_cfg, trans)); - - iwl_trans = iwl_trans_pcie_alloc(pdev, ent, trans); + iwl_trans = iwl_trans_pcie_alloc(pdev, trans, &info); if (IS_ERR(iwl_trans)) return PTR_ERR(iwl_trans); @@ -1519,6 +1325,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) iwl_trans_pcie_check_product_reset_status(pdev); iwl_trans_pcie_check_product_reset_mode(pdev); + /* set the things we know so far for the grab NIC access */ + iwl_trans_set_info(iwl_trans, &info); + /* * Let's try to grab NIC access early here. Sometimes, NICs may * fail to initialize, and if that happens it's better if we see @@ -1532,7 +1341,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) goto out_free_trans; if (iwl_trans_grab_nic_access(iwl_trans)) { - get_crf_id(iwl_trans); + get_crf_id(iwl_trans, &info); /* all good */ iwl_trans_release_nic_access(iwl_trans); } else { @@ -1541,38 +1350,32 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } } - iwl_trans->hw_rf_id = iwl_read32(iwl_trans, CSR_HW_RF_ID); + info.hw_rf_id = iwl_read32(iwl_trans, CSR_HW_RF_ID); /* * The RF_ID is set to zero in blank OTP so read version to * extract the RF_ID. * This is relevant only for family 9000 and up. */ - if (iwl_trans->trans_cfg->rf_id && - iwl_trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_9000 && - !CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id) && map_crf_id(iwl_trans)) { + if (iwl_trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_9000 && + !CSR_HW_RFID_TYPE(info.hw_rf_id) && map_crf_id(iwl_trans, &info)) { ret = -EINVAL; goto out_free_trans; } IWL_INFO(iwl_trans, "PCI dev %04x/%04x, rev=0x%x, rfid=0x%x\n", pdev->device, pdev->subsystem_device, - iwl_trans->hw_rev, iwl_trans->hw_rf_id); + info.hw_rev, info.hw_rf_id); dev_info = iwl_pci_find_dev_info(pdev->device, pdev->subsystem_device, - CSR_HW_REV_TYPE(iwl_trans->hw_rev), - iwl_trans->hw_rev_step, - CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id), - CSR_HW_RFID_IS_CDB(iwl_trans->hw_rf_id), - CSR_HW_RFID_IS_JACKET(iwl_trans->hw_rf_id), + CSR_HW_RFID_TYPE(info.hw_rf_id), + CSR_HW_RFID_IS_CDB(info.hw_rf_id), IWL_SUBDEVICE_RF_ID(pdev->subsystem_device), - IWL_SUBDEVICE_NO_160(pdev->subsystem_device), - IWL_SUBDEVICE_CORES(pdev->subsystem_device), - CSR_HW_RFID_STEP(iwl_trans->hw_rf_id)); + IWL_SUBDEVICE_BW_LIM(pdev->subsystem_device), + CSR_HW_RFID_STEP(info.hw_rf_id)); if (dev_info) { iwl_trans->cfg = dev_info->cfg; - iwl_trans->name = dev_info->name; - iwl_trans->no_160 = dev_info->no_160 == IWL_CFG_NO_160; + info.name = dev_info->name; } #if IS_ENABLED(CONFIG_IWLMVM) @@ -1583,82 +1386,41 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * all the parameters that the transport uses must, until that is * changed, be identical to the ones in the 7265D configuration. */ - if (cfg == &iwl7265_2ac_cfg) - cfg_7265d = &iwl7265d_2ac_cfg; - else if (cfg == &iwl7265_2n_cfg) - cfg_7265d = &iwl7265d_2n_cfg; - else if (cfg == &iwl7265_n_cfg) - cfg_7265d = &iwl7265d_n_cfg; - if (cfg_7265d && - (iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D) - iwl_trans->cfg = cfg_7265d; - - /* - * This is a hack to switch from Qu B0 to Qu C0. We need to - * do this for all cfgs that use Qu B0, except for those using - * Jf, which have already been moved to the new table. The - * rest must be removed once we convert Qu with Hr as well. - */ - if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QU_C0) { - if (iwl_trans->cfg == &iwl_ax201_cfg_qu_hr) - iwl_trans->cfg = &iwl_ax201_cfg_qu_c0_hr_b0; - else if (iwl_trans->cfg == &killer1650s_2ax_cfg_qu_b0_hr_b0) - iwl_trans->cfg = &killer1650s_2ax_cfg_qu_c0_hr_b0; - else if (iwl_trans->cfg == &killer1650i_2ax_cfg_qu_b0_hr_b0) - iwl_trans->cfg = &killer1650i_2ax_cfg_qu_c0_hr_b0; - } - - /* same thing for QuZ... */ - if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QUZ) { - if (iwl_trans->cfg == &iwl_ax201_cfg_qu_hr) - iwl_trans->cfg = &iwl_ax201_cfg_quz_hr; - else if (iwl_trans->cfg == &killer1650s_2ax_cfg_qu_b0_hr_b0) - iwl_trans->cfg = &iwl_ax1650s_cfg_quz_hr; - else if (iwl_trans->cfg == &killer1650i_2ax_cfg_qu_b0_hr_b0) - iwl_trans->cfg = &iwl_ax1650i_cfg_quz_hr; - } - + if (iwl_trans->cfg == &iwl7265_cfg && + (info.hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D) + iwl_trans->cfg = &iwl7265d_cfg; #endif - /* - * If we didn't set the cfg yet, the PCI ID table entry should have - * been a full config - if yes, use it, otherwise fail. - */ if (!iwl_trans->cfg) { - if (ent->driver_data & TRANS_CFG_MARKER) { - pr_err("No config found for PCI dev %04x/%04x, rev=0x%x, rfid=0x%x\n", - pdev->device, pdev->subsystem_device, - iwl_trans->hw_rev, iwl_trans->hw_rf_id); - ret = -EINVAL; - goto out_free_trans; - } - iwl_trans->cfg = cfg; + pr_err("No config found for PCI dev %04x/%04x, rev=0x%x, rfid=0x%x\n", + pdev->device, pdev->subsystem_device, + info.hw_rev, info.hw_rf_id); + ret = -EINVAL; + goto out_free_trans; } - /* if we don't have a name yet, copy name from the old cfg */ - if (!iwl_trans->name) - iwl_trans->name = iwl_trans->cfg->name; + IWL_INFO(iwl_trans, "Detected %s\n", info.name); - IWL_INFO(iwl_trans, "Detected %s\n", iwl_trans->name); - - if (iwl_trans->trans_cfg->mq_rx_supported) { + if (iwl_trans->mac_cfg->mq_rx_supported) { if (WARN_ON(!iwl_trans->cfg->num_rbds)) { ret = -EINVAL; goto out_free_trans; } - trans_pcie->num_rx_bufs = iwl_trans->cfg->num_rbds; + trans_pcie->num_rx_bufs = iwl_trans_get_num_rbds(iwl_trans); } else { trans_pcie->num_rx_bufs = RX_QUEUE_SIZE; } - if (!iwl_trans->trans_cfg->integrated) { + if (!iwl_trans->mac_cfg->integrated) { u16 link_status; pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &link_status); - iwl_trans->pcie_link_speed = + info.pcie_link_speed = u16_get_bits(link_status, PCI_EXP_LNKSTA_CLS); } + iwl_trans_set_info(iwl_trans, &info); + ret = iwl_trans_init(iwl_trans); if (ret) goto out_free_trans; @@ -1690,11 +1452,12 @@ out_free_trans: static void iwl_pci_remove(struct pci_dev *pdev) { struct iwl_trans *trans = pci_get_drvdata(pdev); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); if (!trans) return; - cancel_delayed_work_sync(&trans->me_recheck_wk); + cancel_delayed_work_sync(&trans_pcie->me_recheck_wk); iwl_drv_stop(trans->drv); @@ -1738,27 +1501,11 @@ static int _iwl_pci_resume(struct device *device, bool restore) * Scratch value was altered, this means the device was powered off, we * need to reset it completely. * Note: MAC (bits 0:7) will be cleared upon suspend even with wowlan, - * but not bits [15:8]. So if we have bits set in lower word, assume - * the device is alive. - * For older devices, just try silently to grab the NIC. + * so assume that any bits there mean that the device is usable. */ - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { - if (!(iwl_read32(trans, CSR_FUNC_SCRATCH) & - CSR_FUNC_SCRATCH_POWER_OFF_MASK)) - device_was_powered_off = true; - } else { - /* - * bh are re-enabled by iwl_trans_pcie_release_nic_access, - * so re-enable them if _iwl_trans_pcie_grab_nic_access fails. - */ - local_bh_disable(); - if (_iwl_trans_pcie_grab_nic_access(trans, true)) { - iwl_trans_pcie_release_nic_access(trans); - } else { - device_was_powered_off = true; - local_bh_enable(); - } - } + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ && + !iwl_read32(trans, CSR_FUNC_SCRATCH)) + device_was_powered_off = true; if (restore || device_was_powered_off) { trans->state = IWL_TRANS_NO_FW; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 114a9195ad7f..3b7c12fc4f9e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -194,7 +194,7 @@ struct iwl_rb_allocator { static inline u16 iwl_get_closed_rb_stts(struct iwl_trans *trans, struct iwl_rxq *rxq) { - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { __le16 *rb_stts = rxq->rb_stts; return le16_to_cpu(READ_ONCE(*rb_stts)); @@ -269,6 +269,7 @@ enum iwl_pcie_fw_reset_state { FW_RESET_REQUESTED, FW_RESET_OK, FW_RESET_ERROR, + FW_RESET_TOP_REQUESTED, }; /** @@ -288,22 +289,14 @@ enum iwl_pcie_imr_status { /** * struct iwl_pcie_txqs - TX queues data * - * @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes) - * @page_offs: offset from skb->cb to mac header page pointer - * @dev_cmd_offs: offset from skb->cb to iwl_device_tx_cmd pointer * @queue_used: bit mask of used queues * @queue_stopped: bit mask of stopped queues * @txq: array of TXQ data structures representing the TXQs * @scd_bc_tbls: gen1 pointer to the byte count table of the scheduler - * @queue_alloc_cmd_ver: queue allocation command version * @bc_pool: bytecount DMA allocations pool * @bc_tbl_size: bytecount table size * @tso_hdr_page: page allocated (per CPU) for A-MSDU headers when doing TSO * (and similar usage) - * @cmd: command queue data - * @cmd.fifo: FIFO number - * @cmd.q_id: queue ID - * @cmd.wdg_timeout: watchdog timeout * @tfd: TFD data * @tfd.max_tbs: max number of buffers per TFD * @tfd.size: TFD size @@ -315,26 +308,15 @@ struct iwl_pcie_txqs { struct iwl_txq *txq[IWL_MAX_TVQM_QUEUES]; struct dma_pool *bc_pool; size_t bc_tbl_size; - bool bc_table_dword; - u8 page_offs; - u8 dev_cmd_offs; struct iwl_tso_hdr_page __percpu *tso_hdr_page; struct { - u8 fifo; - u8 q_id; - unsigned int wdg_timeout; - } cmd; - - struct { u8 max_tbs; u16 size; u8 addr_size; } tfd; struct iwl_dma_ptr scd_bc_tbls; - - u8 queue_alloc_cmd_ver; }; /** @@ -344,7 +326,7 @@ struct iwl_pcie_txqs { * @global_table: table mapping received VID from hw to rxb * @rba: allocator for RX replenishing * @ctxt_info: context information for FW self init - * @ctxt_info_gen3: context information for gen3 devices + * @ctxt_info_v2: context information for v1 devices * @prph_info: prph info for self init * @prph_scratch: prph scratch for self init * @ctxt_info_dma_addr: dma addr of context information @@ -352,6 +334,7 @@ struct iwl_pcie_txqs { * @prph_scratch_dma_addr: dma addr of prph scratch * @ctxt_info_dma_addr: dma addr of context information * @iml: image loader image virtual address + * @iml_len: image loader image size * @iml_dma_addr: image loader image DMA address * @trans: pointer to the generic transport area * @scd_base_addr: scheduler sram base address in SRAM @@ -363,9 +346,6 @@ struct iwl_pcie_txqs { * @hw_base: pci hardware address support * @ucode_write_complete: indicates that the ucode has been copied. * @ucode_write_waitq: wait queue for uCode load - * @cmd_queue - command queue number - * @rx_buf_size: Rx buffer size - * @scd_set_active: should the transport configure the SCD for HCMD queue * @rx_page_order: page order for receive buffer size * @rx_buf_bytes: RX buffer (RB) size in bytes * @reg_lock: protect hw register access @@ -406,19 +386,20 @@ struct iwl_pcie_txqs { * @pcie_dbg_dumped_once: indicates PCIe regs were dumped already * @opmode_down: indicates opmode went away * @num_rx_bufs: number of RX buffers to allocate/use - * @no_reclaim_cmds: special commands not using reclaim flow - * (firmware workaround) - * @n_no_reclaim_cmds: number of special commands not using reclaim flow * @affinity_mask: IRQ affinity mask for each RX queue * @debug_rfkill: RF-kill debugging state, -1 for unset, 0/1 for radio * enable/disable - * @fw_reset_handshake: indicates FW reset handshake is needed * @fw_reset_state: state of FW reset handshake * @fw_reset_waitq: waitqueue for FW reset handshake * @is_down: indicates the NIC is down * @isr_stats: interrupt statistics * @napi_dev: (fake) netdev for NAPI registration * @txqs: transport tx queues data. + * @me_present: WiAMT/CSME is detected as present (1), not present (0) + * or unknown (-1, so can still use it as a boolean safely) + * @me_recheck_wk: worker to recheck WiAMT/CSME presence + * @invalid_tx_cmd: invalid TX command buffer + * @wait_command_queue: wait queue for sync commands */ struct iwl_trans_pcie { struct iwl_rxq *rxq; @@ -427,11 +408,12 @@ struct iwl_trans_pcie { struct iwl_rb_allocator rba; union { struct iwl_context_info *ctxt_info; - struct iwl_context_info_gen3 *ctxt_info_gen3; + struct iwl_context_info_v2 *ctxt_info_v2; }; struct iwl_prph_info *prph_info; struct iwl_prph_scratch *prph_scratch; void *iml; + size_t iml_len; dma_addr_t ctxt_info_dma_addr; dma_addr_t prph_info_dma_addr; dma_addr_t prph_scratch_dma_addr; @@ -470,12 +452,8 @@ struct iwl_trans_pcie { wait_queue_head_t ucode_write_waitq; wait_queue_head_t sx_waitq; - u8 n_no_reclaim_cmds; - u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; u16 num_rx_bufs; - enum iwl_amsdu_size rx_buf_size; - bool scd_set_active; bool pcie_dbg_dumped_once; u32 rx_page_order; u32 rx_buf_bytes; @@ -510,7 +488,6 @@ struct iwl_trans_pcie { void *base_rb_stts; dma_addr_t base_rb_stts_dma; - bool fw_reset_handshake; enum iwl_pcie_fw_reset_state fw_reset_state; wait_queue_head_t fw_reset_waitq; enum iwl_pcie_imr_status imr_status; @@ -518,6 +495,13 @@ struct iwl_trans_pcie { char rf_name[32]; struct iwl_pcie_txqs txqs; + + s8 me_present; + struct delayed_work me_recheck_wk; + + struct iwl_dma_ptr invalid_tx_cmd; + + wait_queue_head_t wait_command_queue; }; static inline struct iwl_trans_pcie * @@ -552,8 +536,8 @@ iwl_trans_pcie_get_trans(struct iwl_trans_pcie *trans_pcie) */ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, - const struct pci_device_id *ent, - const struct iwl_cfg_trans_params *cfg_trans); + const struct iwl_mac_cfg *mac_cfg, + struct iwl_trans_info *info); void iwl_trans_pcie_free(struct iwl_trans *trans); void iwl_trans_pcie_free_pnvm_dram_regions(struct iwl_dram_regions *dram_regions, struct device *dev); @@ -623,7 +607,7 @@ struct iwl_tso_page_info { IWL_TSO_PAGE_DATA_SIZE)) int iwl_pcie_tx_init(struct iwl_trans *trans); -void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr); +void iwl_pcie_tx_start(struct iwl_trans *trans); int iwl_pcie_tx_stop(struct iwl_trans *trans); void iwl_pcie_tx_free(struct iwl_trans *trans); bool iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int queue, u16 ssn, @@ -679,7 +663,7 @@ static inline void *iwl_txq_get_tfd(struct iwl_trans *trans, { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - if (trans->trans_cfg->gen2) + if (trans->mac_cfg->gen2) idx = iwl_txq_get_cmd_index(txq, idx); return (u8 *)txq->tfds + trans_pcie->txqs.tfd.size * idx; @@ -718,7 +702,7 @@ static inline void iwl_txq_stop(struct iwl_trans *trans, struct iwl_txq *txq) static inline int iwl_txq_inc_wrap(struct iwl_trans *trans, int index) { return ++index & - (trans->trans_cfg->base_params->max_tfd_queue_size - 1); + (trans->mac_cfg->base->max_tfd_queue_size - 1); } /** @@ -729,7 +713,7 @@ static inline int iwl_txq_inc_wrap(struct iwl_trans *trans, int index) static inline int iwl_txq_dec_wrap(struct iwl_trans *trans, int index) { return --index & - (trans->trans_cfg->base_params->max_tfd_queue_size - 1); + (trans->mac_cfg->base->max_tfd_queue_size - 1); } void iwl_txq_log_scd_error(struct iwl_trans *trans, struct iwl_txq *txq); @@ -752,10 +736,12 @@ int iwl_txq_gen2_set_tb(struct iwl_trans *trans, static inline void iwl_txq_set_tfd_invalid_gen2(struct iwl_trans *trans, struct iwl_tfh_tfd *tfd) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + tfd->num_tbs = 0; - iwl_txq_gen2_set_tb(trans, tfd, trans->invalid_tx_cmd.dma, - trans->invalid_tx_cmd.size); + iwl_txq_gen2_set_tb(trans, tfd, trans_pcie->invalid_tx_cmd.dma, + trans_pcie->invalid_tx_cmd.size); } void iwl_txq_gen2_tfd_unmap(struct iwl_trans *trans, @@ -782,7 +768,7 @@ static inline u16 iwl_txq_gen1_tfd_tb_get_len(struct iwl_trans *trans, struct iwl_tfd *tfd; struct iwl_tfd_tb *tb; - if (trans->trans_cfg->gen2) { + if (trans->mac_cfg->gen2) { struct iwl_tfh_tfd *tfh_tfd = _tfd; struct iwl_tfh_tb *tfh_tb = &tfh_tfd->tbs[idx]; @@ -940,11 +926,13 @@ static inline void iwl_enable_fw_load_int(struct iwl_trans *trans) } } -static inline void iwl_enable_fw_load_int_ctx_info(struct iwl_trans *trans) +static inline void iwl_enable_fw_load_int_ctx_info(struct iwl_trans *trans, + bool top_reset) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - IWL_DEBUG_ISR(trans, "Enabling ALIVE interrupt only\n"); + IWL_DEBUG_ISR(trans, "Enabling %s interrupt only\n", + top_reset ? "RESET" : "ALIVE"); if (!trans_pcie->msix_enabled) { /* @@ -954,11 +942,20 @@ static inline void iwl_enable_fw_load_int_ctx_info(struct iwl_trans *trans) * RX interrupt which will allow us to receive the ALIVE * notification (which is Rx) and continue the flow. */ - trans_pcie->inta_mask = CSR_INT_BIT_ALIVE | CSR_INT_BIT_FH_RX; + if (top_reset) + trans_pcie->inta_mask = CSR_INT_BIT_RESET_DONE; + else + trans_pcie->inta_mask = CSR_INT_BIT_ALIVE | + CSR_INT_BIT_FH_RX; iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); } else { - iwl_enable_hw_int_msk_msix(trans, - MSIX_HW_INT_CAUSES_REG_ALIVE); + u32 val = top_reset ? MSIX_HW_INT_CAUSES_REG_RESET_DONE + : MSIX_HW_INT_CAUSES_REG_ALIVE; + + iwl_enable_hw_int_msk_msix(trans, val); + + if (top_reset) + return; /* * Leave all the FH causes enabled to get the ALIVE * notification. @@ -1005,7 +1002,7 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) MSIX_HW_INT_CAUSES_REG_RF_KILL); } - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_9000) { + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_9000) { /* * On 9000-series devices this bit isn't enabled by default, so * when we power down the device we need set the bit to allow it @@ -1076,8 +1073,7 @@ static inline void iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans) { } void iwl_pcie_rx_allocator_work(struct work_struct *data); /* common trans ops for all generations transports */ -void iwl_trans_pcie_configure(struct iwl_trans *trans, - const struct iwl_trans_config *trans_cfg); +void iwl_trans_pcie_op_mode_enter(struct iwl_trans *trans); int iwl_trans_pcie_start_hw(struct iwl_trans *trans); void iwl_trans_pcie_op_mode_leave(struct iwl_trans *trans); void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val); @@ -1107,11 +1103,14 @@ int iwl_trans_pcie_read_config32(struct iwl_trans *trans, u32 ofs, bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans); void __releases(nic_access_nobh) iwl_trans_pcie_release_nic_access(struct iwl_trans *trans); +void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans, u8 max_power); /* transport gen 1 exported functions */ -void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr); +void iwl_trans_pcie_fw_alive(struct iwl_trans *trans); int iwl_trans_pcie_start_fw(struct iwl_trans *trans, - const struct fw_img *fw, bool run_in_rfkill); + const struct iwl_fw *fw, + const struct fw_img *img, + bool run_in_rfkill); void iwl_trans_pcie_stop_device(struct iwl_trans *trans); /* common functions that are used by gen2 transport */ @@ -1129,15 +1128,12 @@ int iwl_pcie_alloc_dma_ptr(struct iwl_trans *trans, void iwl_pcie_free_dma_ptr(struct iwl_trans *trans, struct iwl_dma_ptr *ptr); void iwl_pcie_apply_destination(struct iwl_trans *trans); -/* common functions that are used by gen3 transport */ -void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans, u8 max_power); - /* transport gen 2 exported functions */ int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans, - const struct fw_img *fw, bool run_in_rfkill); + const struct iwl_fw *fw, + const struct fw_img *img, + bool run_in_rfkill); void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans); -int iwl_trans_pcie_gen2_send_hcmd(struct iwl_trans *trans, - struct iwl_host_cmd *cmd); void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans); int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index 4a4f8de4efe2..f0405eddc367 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -12,7 +12,8 @@ #include "iwl-io.h" #include "internal.h" #include "iwl-op-mode.h" -#include "iwl-context-info-gen3.h" +#include "iwl-context-info-v2.h" +#include "fw/dbg.h" /****************************************************************************** * @@ -143,12 +144,12 @@ static inline __le32 iwl_pcie_dma_addr2rbd_ptr(dma_addr_t dma_addr) */ int iwl_pcie_rx_stop(struct iwl_trans *trans) { - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { /* TODO: remove this once fw does it */ - iwl_write_umac_prph(trans, RFH_RXF_DMA_CFG_GEN3, 0); - return iwl_poll_umac_prph_bit(trans, RFH_GEN_STATUS_GEN3, + iwl_write_umac_prph(trans, RFH_RXF_DMA_CFG_AX210, 0); + return iwl_poll_umac_prph_bit(trans, RFH_GEN_STATUS_AX210, RXF_DMA_IDLE, RXF_DMA_IDLE, 1000); - } else if (trans->trans_cfg->mq_rx_supported) { + } else if (trans->mac_cfg->mq_rx_supported) { iwl_write_prph(trans, RFH_RXF_DMA_CFG, 0); return iwl_poll_prph_bit(trans, RFH_GEN_STATUS, RXF_DMA_IDLE, RXF_DMA_IDLE, 1000); @@ -175,7 +176,7 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, * 1. shadow registers aren't enabled * 2. there is a chance that the NIC is asleep */ - if (!trans->trans_cfg->base_params->shadow_reg_enable && + if (!trans->mac_cfg->base->shadow_reg_enable && test_bit(STATUS_TPOWER_PMI, &trans->status)) { reg = iwl_read32(trans, CSR_UCODE_DRV_GP1); @@ -190,9 +191,9 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, } rxq->write_actual = round_down(rxq->write, 8); - if (!trans->trans_cfg->mq_rx_supported) + if (!trans->mac_cfg->mq_rx_supported) iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, rxq->write_actual); - else if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + else if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) iwl_write32(trans, HBUS_TARG_WRPTR, rxq->write_actual | HBUS_TARG_WRPTR_RX_Q(rxq->id)); else @@ -205,7 +206,7 @@ static void iwl_pcie_rxq_check_wrptr(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int i; - for (i = 0; i < trans->num_rx_queues; i++) { + for (i = 0; i < trans->info.num_rxqs; i++) { struct iwl_rxq *rxq = &trans_pcie->rxq[i]; if (!rxq->need_update) @@ -221,7 +222,7 @@ static void iwl_pcie_restock_bd(struct iwl_trans *trans, struct iwl_rxq *rxq, struct iwl_rx_mem_buffer *rxb) { - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { struct iwl_rx_transfer_desc *bd = rxq->bd; BUILD_BUG_ON(sizeof(*bd) != 2 * sizeof(u64)); @@ -348,7 +349,7 @@ static void iwl_pcie_rxsq_restock(struct iwl_trans *trans, static void iwl_pcie_rxq_restock(struct iwl_trans *trans, struct iwl_rxq *rxq) { - if (trans->trans_cfg->mq_rx_supported) + if (trans->mac_cfg->mq_rx_supported) iwl_pcie_rxmq_restock(trans, rxq); else iwl_pcie_rxsq_restock(trans, rxq); @@ -362,8 +363,8 @@ static struct page *iwl_pcie_rx_alloc_page(struct iwl_trans *trans, u32 *offset, gfp_t priority) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - unsigned int rbsize = iwl_trans_get_rb_size(trans_pcie->rx_buf_size); unsigned int allocsize = PAGE_SIZE << trans_pcie->rx_page_order; + unsigned int rbsize = trans_pcie->rx_buf_bytes; struct page *page; gfp_t gfp_mask = priority; @@ -657,19 +658,19 @@ void iwl_pcie_rx_allocator_work(struct work_struct *data) static int iwl_pcie_free_bd_size(struct iwl_trans *trans) { - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) return sizeof(struct iwl_rx_transfer_desc); - return trans->trans_cfg->mq_rx_supported ? + return trans->mac_cfg->mq_rx_supported ? sizeof(__le64) : sizeof(__le32); } static int iwl_pcie_used_bd_size(struct iwl_trans *trans) { - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) return sizeof(struct iwl_rx_completion_desc_bz); - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) return sizeof(struct iwl_rx_completion_desc); return sizeof(__le32); @@ -701,7 +702,7 @@ static void iwl_pcie_free_rxq_dma(struct iwl_trans *trans, static size_t iwl_pcie_rb_stts_size(struct iwl_trans *trans) { - bool use_rx_td = (trans->trans_cfg->device_family >= + bool use_rx_td = (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210); if (use_rx_td) @@ -720,8 +721,8 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans, int free_size; spin_lock_init(&rxq->lock); - if (trans->trans_cfg->mq_rx_supported) - rxq->queue_size = trans->cfg->num_rbds; + if (trans->mac_cfg->mq_rx_supported) + rxq->queue_size = iwl_trans_get_num_rbds(trans); else rxq->queue_size = RX_QUEUE_SIZE; @@ -736,7 +737,7 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans, if (!rxq->bd) goto err; - if (trans->trans_cfg->mq_rx_supported) { + if (trans->mac_cfg->mq_rx_supported) { rxq->used_bd = dma_alloc_coherent(dev, iwl_pcie_used_bd_size(trans) * rxq->queue_size, @@ -753,7 +754,7 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans, return 0; err: - for (i = 0; i < trans->num_rx_queues; i++) { + for (i = 0; i < trans->info.num_rxqs; i++) { struct iwl_rxq *rxq = &trans_pcie->rxq[i]; iwl_pcie_free_rxq_dma(trans, rxq); @@ -772,7 +773,7 @@ static int iwl_pcie_rx_alloc(struct iwl_trans *trans) if (WARN_ON(trans_pcie->rxq)) return -EINVAL; - trans_pcie->rxq = kcalloc(trans->num_rx_queues, sizeof(struct iwl_rxq), + trans_pcie->rxq = kcalloc(trans->info.num_rxqs, sizeof(struct iwl_rxq), GFP_KERNEL); trans_pcie->rx_pool = kcalloc(RX_POOL_SIZE(trans_pcie->num_rx_bufs), sizeof(trans_pcie->rx_pool[0]), @@ -795,7 +796,7 @@ static int iwl_pcie_rx_alloc(struct iwl_trans *trans) */ trans_pcie->base_rb_stts = dma_alloc_coherent(trans->dev, - rb_stts_size * trans->num_rx_queues, + rb_stts_size * trans->info.num_rxqs, &trans_pcie->base_rb_stts_dma, GFP_KERNEL); if (!trans_pcie->base_rb_stts) { @@ -803,7 +804,7 @@ static int iwl_pcie_rx_alloc(struct iwl_trans *trans) goto err; } - for (i = 0; i < trans->num_rx_queues; i++) { + for (i = 0; i < trans->info.num_rxqs; i++) { struct iwl_rxq *rxq = &trans_pcie->rxq[i]; rxq->id = i; @@ -816,7 +817,7 @@ static int iwl_pcie_rx_alloc(struct iwl_trans *trans) err: if (trans_pcie->base_rb_stts) { dma_free_coherent(trans->dev, - rb_stts_size * trans->num_rx_queues, + rb_stts_size * trans->info.num_rxqs, trans_pcie->base_rb_stts, trans_pcie->base_rb_stts_dma); trans_pcie->base_rb_stts = NULL; @@ -834,11 +835,10 @@ err: static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); u32 rb_size; const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ - switch (trans_pcie->rx_buf_size) { + switch (trans->conf.rx_buf_size) { case IWL_AMSDU_4K: rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; break; @@ -906,7 +906,7 @@ static void iwl_pcie_rx_mq_hw_init(struct iwl_trans *trans) u32 rb_size, enabled = 0; int i; - switch (trans_pcie->rx_buf_size) { + switch (trans->conf.rx_buf_size) { case IWL_AMSDU_2K: rb_size = RFH_RXF_DMA_RB_SIZE_2K; break; @@ -932,7 +932,7 @@ static void iwl_pcie_rx_mq_hw_init(struct iwl_trans *trans) /* disable free amd used rx queue operation */ iwl_write_prph_no_grab(trans, RFH_RXF_RXQ_ACTIVE, 0); - for (i = 0; i < trans->num_rx_queues; i++) { + for (i = 0; i < trans->info.num_rxqs; i++) { /* Tell device where to find RBD free table in DRAM */ iwl_write_prph64_no_grab(trans, RFH_Q_FRBDCB_BA_LSB(i), @@ -976,7 +976,7 @@ static void iwl_pcie_rx_mq_hw_init(struct iwl_trans *trans) RFH_GEN_CFG_VAL(DEFAULT_RXQ_NUM, 0) | RFH_GEN_CFG_SERVICE_DMA_SNOOP | RFH_GEN_CFG_VAL(RB_CHUNK_SIZE, - trans->trans_cfg->integrated ? + trans->mac_cfg->integrated ? RFH_GEN_CFG_RB_CHUNK_SIZE_64 : RFH_GEN_CFG_RB_CHUNK_SIZE_128)); /* Enable the relevant rx queues */ @@ -1072,7 +1072,7 @@ void iwl_pcie_rx_napi_sync(struct iwl_trans *trans) if (unlikely(!trans_pcie->rxq)) return; - for (i = 0; i < trans->num_rx_queues; i++) { + for (i = 0; i < trans->info.num_rxqs; i++) { struct iwl_rxq *rxq = &trans_pcie->rxq[i]; if (rxq && rxq->napi.poll) @@ -1109,7 +1109,7 @@ static int _iwl_pcie_rx_init(struct iwl_trans *trans) for (i = 0; i < RX_QUEUE_SIZE; i++) def_rxq->queue[i] = NULL; - for (i = 0; i < trans->num_rx_queues; i++) { + for (i = 0; i < trans->info.num_rxqs; i++) { struct iwl_rxq *rxq = &trans_pcie->rxq[i]; spin_lock_bh(&rxq->lock); @@ -1122,7 +1122,7 @@ static int _iwl_pcie_rx_init(struct iwl_trans *trans) rxq->write = 0; rxq->write_actual = 0; memset(rxq->rb_stts, 0, - (trans->trans_cfg->device_family >= + (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) ? sizeof(__le16) : sizeof(struct iwl_rb_status)); @@ -1144,9 +1144,9 @@ static int _iwl_pcie_rx_init(struct iwl_trans *trans) } /* move the pool to the default queue and allocator ownerships */ - queue_size = trans->trans_cfg->mq_rx_supported ? + queue_size = trans->mac_cfg->mq_rx_supported ? trans_pcie->num_rx_bufs - 1 : RX_QUEUE_SIZE; - allocator_pool_size = trans->num_rx_queues * + allocator_pool_size = trans->info.num_rxqs * (RX_CLAIM_REQ_ALLOC - RX_POST_REQ_ALLOC); num_alloc = queue_size + allocator_pool_size; @@ -1175,7 +1175,7 @@ int iwl_pcie_rx_init(struct iwl_trans *trans) if (ret) return ret; - if (trans->trans_cfg->mq_rx_supported) + if (trans->mac_cfg->mq_rx_supported) iwl_pcie_rx_mq_hw_init(trans); else iwl_pcie_rx_hw_init(trans, trans_pcie->rxq); @@ -1223,14 +1223,14 @@ void iwl_pcie_rx_free(struct iwl_trans *trans) if (trans_pcie->base_rb_stts) { dma_free_coherent(trans->dev, - rb_stts_size * trans->num_rx_queues, + rb_stts_size * trans->info.num_rxqs, trans_pcie->base_rb_stts, trans_pcie->base_rb_stts_dma); trans_pcie->base_rb_stts = NULL; trans_pcie->base_rb_stts_dma = 0; } - for (i = 0; i < trans->num_rx_queues; i++) { + for (i = 0; i < trans->info.num_rxqs; i++) { struct iwl_rxq *rxq = &trans_pcie->rxq[i]; iwl_pcie_free_rxq_dma(trans, rxq); @@ -1301,7 +1301,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, int i) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_txq *txq = trans_pcie->txqs.txq[trans_pcie->txqs.cmd.q_id]; + struct iwl_txq *txq = trans_pcie->txqs.txq[trans->conf.cmd_queue]; bool page_stolen = false; int max_len = trans_pcie->rx_buf_bytes; u32 offset = 0; @@ -1368,8 +1368,8 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, if (reclaim && !pkt->hdr.group_id) { int i; - for (i = 0; i < trans_pcie->n_no_reclaim_cmds; i++) { - if (trans_pcie->no_reclaim_cmds[i] == + for (i = 0; i < trans->conf.n_no_reclaim_cmds; i++) { + if (trans->conf.no_reclaim_cmds[i] == pkt->hdr.cmd) { reclaim = false; break; @@ -1408,7 +1408,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, } page_stolen |= rxcb._page_stolen; - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) break; } @@ -1454,18 +1454,18 @@ static struct iwl_rx_mem_buffer *iwl_pcie_get_rxb(struct iwl_trans *trans, BUILD_BUG_ON(sizeof(struct iwl_rx_completion_desc) != 32); BUILD_BUG_ON(sizeof(struct iwl_rx_completion_desc_bz) != 4); - if (!trans->trans_cfg->mq_rx_supported) { + if (!trans->mac_cfg->mq_rx_supported) { rxb = rxq->queue[i]; rxq->queue[i] = NULL; return rxb; } - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { struct iwl_rx_completion_desc_bz *cd = rxq->used_bd; vid = le16_to_cpu(cd[i].rbid); *join = cd[i].flags & IWL_RX_CD_FLAGS_FRAGMENTED; - } else if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + } else if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { struct iwl_rx_completion_desc *cd = rxq->used_bd; vid = le16_to_cpu(cd[i].rbid); @@ -1648,7 +1648,7 @@ irqreturn_t iwl_pcie_irq_rx_msix_handler(int irq, void *dev_id) trace_iwlwifi_dev_irq_msix(trans->dev, entry, false, 0, 0); - if (WARN_ON(entry->entry >= trans->num_rx_queues)) + if (WARN_ON(entry->entry >= trans->info.num_rxqs)) return IRQ_NONE; if (!trans_pcie->rxq) { @@ -1683,18 +1683,18 @@ static void iwl_pcie_irq_handle_error(struct iwl_trans *trans) /* W/A for WiFi/WiMAX coex and WiMAX own the RF */ if (trans->cfg->internal_wimax_coex && - !trans->cfg->apmg_not_supported && + !trans->mac_cfg->base->apmg_not_supported && (!(iwl_read_prph(trans, APMG_CLK_CTRL_REG) & APMS_CLK_VAL_MRB_FUNC_MODE) || (iwl_read_prph(trans, APMG_PS_CTRL_REG) & APMG_PS_CTRL_VAL_RESET_REQ))) { clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status); iwl_op_mode_wimax_active(trans->op_mode); - wake_up(&trans->wait_command_queue); + wake_up(&trans_pcie->wait_command_queue); return; } - for (i = 0; i < trans->trans_cfg->base_params->num_of_queues; i++) { + for (i = 0; i < trans->mac_cfg->base->num_of_queues; i++) { if (!trans_pcie->txqs.txq[i]) continue; timer_delete(&trans_pcie->txqs.txq[i]->stuck_timer); @@ -1705,7 +1705,7 @@ static void iwl_pcie_irq_handle_error(struct iwl_trans *trans) iwl_trans_fw_error(trans, IWL_ERR_TYPE_IRQ); clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status); - wake_up(&trans->wait_command_queue); + wake_up(&trans_pcie->wait_command_queue); } static u32 iwl_pcie_int_cause_non_ict(struct iwl_trans *trans) @@ -1820,7 +1820,7 @@ void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans, bool from_irq) &trans->status)) IWL_DEBUG_RF_KILL(trans, "Rfkill while SYNC HCMD in flight\n"); - wake_up(&trans->wait_command_queue); + wake_up(&trans_pcie->wait_command_queue); } else { clear_bit(STATUS_RFKILL_HW, &trans->status); if (trans_pcie->opmode_down) @@ -1828,6 +1828,54 @@ void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans, bool from_irq) } } +static void iwl_trans_pcie_handle_reset_interrupt(struct iwl_trans *trans) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + u32 state; + + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_SC) { + u32 val = iwl_read32(trans, CSR_IPC_STATE); + + state = u32_get_bits(val, CSR_IPC_STATE_RESET); + IWL_DEBUG_ISR(trans, "IPC state = 0x%x/%d\n", val, state); + } else { + state = CSR_IPC_STATE_RESET_SW_READY; + } + + switch (state) { + case CSR_IPC_STATE_RESET_SW_READY: + if (trans_pcie->fw_reset_state == FW_RESET_REQUESTED) { + IWL_DEBUG_ISR(trans, "Reset flow completed\n"); + trans_pcie->fw_reset_state = FW_RESET_OK; + wake_up(&trans_pcie->fw_reset_waitq); + break; + } + fallthrough; + case CSR_IPC_STATE_RESET_TOP_READY: + /* FIXME: handle this case when requesting TOP reset */ + fallthrough; + case CSR_IPC_STATE_RESET_NONE: + IWL_FW_CHECK_FAILED(trans, + "Invalid reset interrupt (state=%d)!\n", + state); + break; + case CSR_IPC_STATE_RESET_TOP_FOLLOWER: + if (trans_pcie->fw_reset_state == FW_RESET_REQUESTED) { + /* if we were in reset, wake that up */ + IWL_INFO(trans, + "TOP reset from BT while doing reset\n"); + trans_pcie->fw_reset_state = FW_RESET_OK; + wake_up(&trans_pcie->fw_reset_waitq); + } else { + IWL_INFO(trans, "TOP reset from BT\n"); + trans->state = IWL_TRANS_NO_FW; + iwl_trans_schedule_reset(trans, + IWL_ERR_TYPE_TOP_RESET_BY_BT); + } + break; + } +} + irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) { struct iwl_trans *trans = dev_id; @@ -1936,7 +1984,7 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) if (inta & CSR_INT_BIT_ALIVE) { IWL_DEBUG_ISR(trans, "Alive interrupt\n"); isr_stats->alive++; - if (trans->trans_cfg->gen2) { + if (trans->mac_cfg->gen2) { /* * We can restock, since firmware configured * the RFH @@ -1947,6 +1995,11 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) handled |= CSR_INT_BIT_ALIVE; } + if (inta & CSR_INT_BIT_RESET_DONE) { + iwl_trans_pcie_handle_reset_interrupt(trans); + handled |= CSR_INT_BIT_RESET_DONE; + } + /* Safely ignore these bits for debug checks below */ inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE); @@ -1968,7 +2021,12 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) IWL_ERR(trans, "Microcode SW error detected. " " Restarting 0x%X.\n", inta); isr_stats->sw++; - iwl_pcie_irq_handle_error(trans); + if (trans_pcie->fw_reset_state == FW_RESET_REQUESTED) { + trans_pcie->fw_reset_state = FW_RESET_ERROR; + wake_up(&trans_pcie->fw_reset_waitq); + } else { + iwl_pcie_irq_handle_error(trans); + } handled |= CSR_INT_BIT_SW_ERR; } @@ -2074,7 +2132,7 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) iwl_enable_rfkill_int(trans); /* Re-enable the ALIVE / Rx interrupt if it occurred */ else if (handled & (CSR_INT_BIT_ALIVE | CSR_INT_BIT_FH_RX)) - iwl_enable_fw_load_int_ctx_info(trans); + iwl_enable_fw_load_int_ctx_info(trans, false); spin_unlock_bh(&trans_pcie->irq_lock); } @@ -2289,7 +2347,7 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id) } } - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) sw_err = inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR_BZ; else sw_err = inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR; @@ -2297,9 +2355,13 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id) if (inta_hw & MSIX_HW_INT_CAUSES_REG_TOP_FATAL_ERR) { IWL_ERR(trans, "TOP Fatal error detected, inta_hw=0x%x.\n", inta_hw); - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) - iwl_trans_pcie_reset(trans, - IWL_RESET_MODE_PROD_RESET); + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { + trans->request_top_reset = 1; + iwl_op_mode_nic_error(trans->op_mode, + IWL_ERR_TYPE_TOP_FATAL_ERROR); + iwl_trans_schedule_reset(trans, + IWL_ERR_TYPE_TOP_FATAL_ERROR); + } } /* Error detected by uCode */ @@ -2338,7 +2400,7 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id) if (inta_hw & MSIX_HW_INT_CAUSES_REG_ALIVE) { IWL_DEBUG_ISR(trans, "Alive interrupt\n"); isr_stats->alive++; - if (trans->trans_cfg->gen2) { + if (trans->mac_cfg->gen2) { /* We can restock, since firmware configured the RFH */ iwl_pcie_rxmq_restock(trans, trans_pcie->rxq); } @@ -2388,11 +2450,8 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id) iwl_pcie_irq_handle_error(trans); } - if (inta_hw & MSIX_HW_INT_CAUSES_REG_RESET_DONE) { - IWL_DEBUG_ISR(trans, "Reset flow completed\n"); - trans_pcie->fw_reset_state = FW_RESET_OK; - wake_up(&trans_pcie->fw_reset_waitq); - } + if (inta_hw & MSIX_HW_INT_CAUSES_REG_RESET_DONE) + iwl_trans_pcie_handle_reset_interrupt(trans); if (!polling) iwl_pcie_clear_irq(trans, entry->entry); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index 472f26f83ba8..38ad719161e6 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -6,7 +6,7 @@ #include "iwl-trans.h" #include "iwl-prph.h" #include "iwl-context-info.h" -#include "iwl-context-info-gen3.h" +#include "iwl-context-info-v2.h" #include "internal.h" #include "fw/dbg.h" @@ -81,13 +81,13 @@ static void iwl_pcie_gen2_apm_stop(struct iwl_trans *trans, bool op_mode_leave) /* Stop device's DMA activity */ iwl_pcie_apm_stop_master(trans); - iwl_trans_sw_reset(trans, false); + iwl_trans_pcie_sw_reset(trans, false); /* * Clear "initialization complete" bit to move adapter from * D0A* (powered-up Active) --> D0U* (Uninitialized) state. */ - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_INIT); else @@ -102,10 +102,10 @@ void iwl_trans_pcie_fw_reset_handshake(struct iwl_trans *trans) trans_pcie->fw_reset_state = FW_RESET_REQUESTED; - if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) + if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) iwl_write_umac_prph(trans, UREG_NIC_SET_NMI_DRIVER, UREG_NIC_SET_NMI_DRIVER_RESET_HANDSHAKE); - else if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210) + else if (trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_AX210) iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6, UREG_DOORBELL_TO_ISR6_RESET_HANDSHAKE); else @@ -117,13 +117,23 @@ void iwl_trans_pcie_fw_reset_handshake(struct iwl_trans *trans) trans_pcie->fw_reset_state != FW_RESET_REQUESTED, FW_RESET_TIMEOUT); if (!ret || trans_pcie->fw_reset_state == FW_RESET_ERROR) { - u32 inta_hw = iwl_read32(trans, CSR_MSIX_HW_INT_CAUSES_AD); + bool reset_done; + u32 inta_hw; + + if (trans_pcie->msix_enabled) { + inta_hw = iwl_read32(trans, CSR_MSIX_HW_INT_CAUSES_AD); + reset_done = + inta_hw & MSIX_HW_INT_CAUSES_REG_RESET_DONE; + } else { + inta_hw = iwl_read32(trans, CSR_INT_MASK); + reset_done = inta_hw & CSR_INT_BIT_RESET_DONE; + } IWL_ERR(trans, - "timeout waiting for FW reset ACK (inta_hw=0x%x)\n", - inta_hw); + "timeout waiting for FW reset ACK (inta_hw=0x%x, reset_done %d)\n", + inta_hw, reset_done); - if (!(inta_hw & MSIX_HW_INT_CAUSES_REG_RESET_DONE)) { + if (!reset_done) { struct iwl_fw_error_dump_mode mode = { .type = IWL_ERR_TYPE_RESET_HS_TIMEOUT, .context = IWL_ERR_CONTEXT_FROM_OPMODE, @@ -147,7 +157,7 @@ static void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans) return; if (trans->state >= IWL_TRANS_FW_STARTED && - trans_pcie->fw_reset_handshake) { + trans->conf.fw_reset_handshake) { /* * Reset handshake can dump firmware on timeout, but that * should assume that the firmware is already dead. @@ -181,8 +191,8 @@ static void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans) } iwl_pcie_ctxt_info_free_paging(trans); - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) - iwl_pcie_ctxt_info_gen3_free(trans, false); + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) + iwl_pcie_ctxt_info_v2_free(trans, false); else iwl_pcie_ctxt_info_free(trans); @@ -190,7 +200,7 @@ static void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans) iwl_pcie_gen2_apm_stop(trans, false); /* re-take ownership to prevent other users from stealing the device */ - iwl_trans_sw_reset(trans, true); + iwl_trans_pcie_sw_reset(trans, true); /* * Upon stop, the IVAR table gets erased, so msi-x won't @@ -243,7 +253,7 @@ static int iwl_pcie_gen2_nic_init(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int queue_size = max_t(u32, IWL_CMD_QUEUE_SIZE, - trans->cfg->min_txq_size); + trans->mac_cfg->base->min_txq_size); int ret; /* TODO: most of the logic can be removed in A0 - but not in Z0 */ @@ -260,7 +270,7 @@ static int iwl_pcie_gen2_nic_init(struct iwl_trans *trans) return -ENOMEM; /* Allocate or reset and init all Tx and Command queues */ - if (iwl_txq_gen2_init(trans, trans_pcie->txqs.cmd.q_id, queue_size)) + if (iwl_txq_gen2_init(trans, trans->conf.cmd_queue, queue_size)) return -ENOMEM; /* enable shadow regs in HW */ @@ -281,7 +291,7 @@ static void iwl_pcie_get_rf_name(struct iwl_trans *trans) if (buf[0]) return; - switch (CSR_HW_RFID_TYPE(trans->hw_rf_id)) { + switch (CSR_HW_RFID_TYPE(trans->info.hw_rf_id)) { case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_JF): pos = scnprintf(buf, buflen, "JF"); break; @@ -305,7 +315,7 @@ static void iwl_pcie_get_rf_name(struct iwl_trans *trans) break; case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_WP): if (SILICON_Z_STEP == - CSR_HW_RFID_STEP(trans->hw_rf_id)) + CSR_HW_RFID_STEP(trans->info.hw_rf_id)) pos = scnprintf(buf, buflen, "WHTC"); else pos = scnprintf(buf, buflen, "WH"); @@ -314,7 +324,7 @@ static void iwl_pcie_get_rf_name(struct iwl_trans *trans) return; } - switch (CSR_HW_RFID_TYPE(trans->hw_rf_id)) { + switch (CSR_HW_RFID_TYPE(trans->info.hw_rf_id)) { case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_HR): case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_HR1): case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_HRCDB): @@ -337,7 +347,7 @@ static void iwl_pcie_get_rf_name(struct iwl_trans *trans) } pos += scnprintf(buf + pos, buflen - pos, ", rfid=0x%x", - trans->hw_rf_id); + trans->info.hw_rf_id); IWL_INFO(trans, "Detected RF %s\n", buf); @@ -364,8 +374,8 @@ void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans) /* now that we got alive we can free the fw image & the context info. * paging memory cannot be freed included since FW will still use it */ - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) - iwl_pcie_ctxt_info_gen3_free(trans, true); + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) + iwl_pcie_ctxt_info_v2_free(trans, true); else iwl_pcie_ctxt_info_free(trans); @@ -379,6 +389,11 @@ void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans) iwl_pcie_get_rf_name(trans); mutex_unlock(&trans_pcie->mutex); + + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + trans->step_urm = !!(iwl_read_umac_prph(trans, + CNVI_PMU_STEP_FLOW) & + CNVI_PMU_STEP_FLOW_FORCE_URM); } static bool iwl_pcie_set_ltr(struct iwl_trans *trans) @@ -398,21 +413,21 @@ static bool iwl_pcie_set_ltr(struct iwl_trans *trans) * initialize the LTR to ~250 usec (see ltr_val above). * The firmware initializes this again later (to a smaller value). */ - if ((trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210 || - trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) && - !trans->trans_cfg->integrated) { + if ((trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_AX210 || + trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_22000) && + !trans->mac_cfg->integrated) { iwl_write32(trans, CSR_LTR_LONG_VAL_AD, ltr_val); return true; } - if (trans->trans_cfg->integrated && - trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) { + if (trans->mac_cfg->integrated && + trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_22000) { iwl_write_prph(trans, HPM_MAC_LTR_CSR, HPM_MAC_LRT_ENABLE_ALL); iwl_write_prph(trans, HPM_UMAC_LTR, ltr_val); return true; } - if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210) { + if (trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_AX210) { /* First clear the interrupt, just in case */ iwl_write32(trans, CSR_MSIX_HW_INT_CAUSES_AD, MSIX_HW_INT_CAUSES_REG_IML); @@ -469,16 +484,22 @@ static void iwl_pcie_spin_for_iml(struct iwl_trans *trans) } int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans, - const struct fw_img *fw, bool run_in_rfkill) + const struct iwl_fw *fw, + const struct fw_img *img, + bool run_in_rfkill) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); bool hw_rfkill, keep_ram_busy; + bool top_reset_done = false; int ret; + mutex_lock(&trans_pcie->mutex); +again: /* This may fail if AMT took ownership of the device */ if (iwl_pcie_prepare_card_hw(trans)) { IWL_WARN(trans, "Exit HW not ready\n"); - return -EIO; + ret = -EIO; + goto out; } iwl_enable_rfkill_int(trans); @@ -495,8 +516,6 @@ int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans, /* Make sure it finished running */ iwl_pcie_synchronize_irqs(trans); - mutex_lock(&trans_pcie->mutex); - /* If platform's RF_KILL switch is NOT set to KILL */ hw_rfkill = iwl_pcie_check_hw_rf_kill(trans); if (hw_rfkill && !run_in_rfkill) { @@ -526,22 +545,37 @@ int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans, goto out; } - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) - ret = iwl_pcie_ctxt_info_gen3_init(trans, fw); - else - ret = iwl_pcie_ctxt_info_init(trans, fw); - if (ret) - goto out; + if (WARN_ON(trans->do_top_reset && + trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_SC)) + return -EINVAL; + + /* we need to wait later - set state */ + if (trans->do_top_reset) + trans_pcie->fw_reset_state = FW_RESET_TOP_REQUESTED; + + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + if (!top_reset_done) { + ret = iwl_pcie_ctxt_info_v2_alloc(trans, fw, img); + if (ret) + goto out; + } + + iwl_pcie_ctxt_info_v2_kick(trans); + } else { + ret = iwl_pcie_ctxt_info_init(trans, img); + if (ret) + goto out; + } keep_ram_busy = !iwl_pcie_set_ltr(trans); - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { IWL_DEBUG_POWER(trans, "function scratch register value is 0x%08x\n", iwl_read32(trans, CSR_FUNC_SCRATCH)); iwl_write32(trans, CSR_FUNC_SCRATCH, CSR_FUNC_SCRATCH_INIT_VALUE); iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_ROM_START); - } else if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + } else if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1); } else { iwl_write_prph(trans, UREG_CPU_INIT_RUN, 1); @@ -550,6 +584,38 @@ int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans, if (keep_ram_busy) iwl_pcie_spin_for_iml(trans); + if (trans->do_top_reset) { + trans->do_top_reset = 0; + +#define FW_TOP_RESET_TIMEOUT (HZ / 4) + ret = wait_event_timeout(trans_pcie->fw_reset_waitq, + trans_pcie->fw_reset_state != FW_RESET_TOP_REQUESTED, + FW_TOP_RESET_TIMEOUT); + + if (trans_pcie->fw_reset_state != FW_RESET_OK) { + if (trans_pcie->fw_reset_state != FW_RESET_TOP_REQUESTED) + IWL_ERR(trans, + "TOP reset interrupted by error (state %d)!\n", + trans_pcie->fw_reset_state); + else + IWL_ERR(trans, "TOP reset timed out!\n"); + iwl_op_mode_nic_error(trans->op_mode, + IWL_ERR_TYPE_TOP_RESET_FAILED); + iwl_trans_schedule_reset(trans, + IWL_ERR_TYPE_TOP_RESET_FAILED); + ret = -EIO; + goto out; + } + + msleep(10); + IWL_INFO(trans, "TOP reset successful, reinit now\n"); + /* now load the firmware again properly */ + trans_pcie->prph_scratch->ctrl_cfg.control.control_flags &= + ~cpu_to_le32(IWL_PRPH_SCRATCH_TOP_RESET); + top_reset_done = true; + goto again; + } + /* re-check RF-Kill state since we may have missed the interrupt */ hw_rfkill = iwl_pcie_check_hw_rf_kill(trans); if (hw_rfkill && !run_in_rfkill) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 102a6123bba0..cc4d289b110d 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -28,7 +28,7 @@ #include "mei/iwl-mei.h" #include "internal.h" #include "iwl-fh.h" -#include "iwl-context-info-gen3.h" +#include "iwl-context-info-v2.h" /* extended range in FW SRAM */ #define IWL_FW_MEM_EXTENDED_START 0x40000 @@ -131,7 +131,7 @@ out: int iwl_trans_pcie_sw_reset(struct iwl_trans *trans, bool retake_ownership) { /* Reset entire device - do controller reset (results in SHRD_HW_RST) */ - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_SW_RESET); usleep_range(10000, 20000); @@ -237,7 +237,7 @@ static void iwl_trans_pcie_write_shr(struct iwl_trans *trans, u32 reg, u32 val) static void iwl_pcie_set_pwr(struct iwl_trans *trans, bool vaux) { - if (trans->cfg->apmg_not_supported) + if (trans->mac_cfg->base->apmg_not_supported) return; if (vaux && pci_pme_capable(to_pci_dev(trans->dev), PCI_D3cold)) @@ -293,7 +293,7 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans) */ /* Disable L0S exit timer (platform NMI Work/Around) */ - if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000) + if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_8000) iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS, CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); @@ -317,7 +317,7 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans) iwl_pcie_apm_config(trans); /* Configure analog phase-lock-loop before activating to D0A */ - if (trans->trans_cfg->base_params->pll_cfg) + if (trans->mac_cfg->base->pll_cfg) iwl_set_bit(trans, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL); ret = iwl_finish_nic_init(trans); @@ -353,7 +353,7 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans) * bits do not disable clocks. This preserves any hardware * bits already set by default in "CLK_CTRL_REG" after reset. */ - if (!trans->cfg->apmg_not_supported) { + if (!trans->mac_cfg->base->apmg_not_supported) { iwl_write_prph(trans, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT); udelay(20); @@ -469,7 +469,7 @@ void iwl_pcie_apm_stop_master(struct iwl_trans *trans) /* stop device's busmaster DMA activity */ - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_BUS_MASTER_DISABLE_REQ); @@ -501,10 +501,10 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans, bool op_mode_leave) iwl_pcie_apm_init(trans); /* inform ME that we are leaving */ - if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000) + if (trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_7000) iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG, APMG_PCIDEV_STT_VAL_WAKE_ME); - else if (trans->trans_cfg->device_family >= + else if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_8000) { iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG, CSR_RESET_LINK_PWR_MGMT_DISABLED); @@ -565,7 +565,7 @@ static int iwl_pcie_nic_init(struct iwl_trans *trans) return -ENOMEM; } - if (trans->trans_cfg->base_params->shadow_reg_enable) { + if (trans->mac_cfg->base->shadow_reg_enable) { /* enable shadow regs in HW */ iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, 0x800FFFFF); IWL_DEBUG_INFO(trans, "Enabling shadow registers in device\n"); @@ -634,7 +634,7 @@ int iwl_pcie_prepare_card_hw(struct iwl_trans *trans) IWL_DEBUG_INFO(trans, "Couldn't prepare the card but SAP is connected\n"); trans->csme_own = true; - if (trans->trans_cfg->device_family != + if (trans->mac_cfg->device_family != IWL_DEVICE_FAMILY_9000) IWL_ERR(trans, "SAP not supported for this NIC family\n"); @@ -819,7 +819,7 @@ static int iwl_pcie_load_cpu_sections_8000(struct iwl_trans *trans, iwl_enable_interrupts(trans); - if (trans->trans_cfg->gen2) { + if (trans->mac_cfg->gen2) { if (cpu == 1) iwl_write_prph(trans, UREG_UCODE_LOAD_STATUS, 0xFFFF); @@ -977,7 +977,7 @@ monitor: if (dest->monitor_mode == EXTERNAL_MODE && fw_mon->size) { iwl_write_prph(trans, le32_to_cpu(dest->base_reg), fw_mon->physical >> dest->base_shift); - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000) + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_8000) iwl_write_prph(trans, le32_to_cpu(dest->end_reg), (fw_mon->physical + fw_mon->size - 256) >> dest->end_shift); @@ -1153,7 +1153,7 @@ static void iwl_pcie_map_non_rx_causes(struct iwl_trans *trans) */ iwl_pcie_map_list(trans, causes_list_common, ARRAY_SIZE(causes_list_common), val); - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) iwl_pcie_map_list(trans, causes_list_bz, ARRAY_SIZE(causes_list_bz), val); else @@ -1175,7 +1175,7 @@ static void iwl_pcie_map_rx_causes(struct iwl_trans *trans) * the other (N - 2) interrupt vectors. */ val = BIT(MSIX_FH_INT_CAUSES_Q(0)); - for (idx = 1; idx < trans->num_rx_queues; idx++) { + for (idx = 1; idx < trans->info.num_rxqs; idx++) { iwl_write8(trans, CSR_MSIX_RX_IVAR(idx), MSIX_FH_INT_CAUSES_Q(idx - offset)); val |= BIT(MSIX_FH_INT_CAUSES_Q(idx)); @@ -1196,7 +1196,7 @@ void iwl_pcie_conf_msix_hw(struct iwl_trans_pcie *trans_pcie) struct iwl_trans *trans = trans_pcie->trans; if (!trans_pcie->msix_enabled) { - if (trans->trans_cfg->mq_rx_supported && + if (trans->mac_cfg->mq_rx_supported && test_bit(STATUS_DEVICE_ENABLED, &trans->status)) iwl_write_umac_prph(trans, UREG_CHICK, UREG_CHICK_MSI_ENABLE); @@ -1271,7 +1271,7 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool from_irq) iwl_pcie_rx_stop(trans); /* Power-down device's busmaster DMA clocks */ - if (!trans->cfg->apmg_not_supported) { + if (!trans->mac_cfg->base->apmg_not_supported) { iwl_write_prph(trans, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); udelay(5); @@ -1279,7 +1279,7 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool from_irq) } /* Make sure (redundant) we've released our request to stay awake */ - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_BZ_MAC_ACCESS_REQ); else @@ -1337,7 +1337,9 @@ void iwl_pcie_synchronize_irqs(struct iwl_trans *trans) } int iwl_trans_pcie_start_fw(struct iwl_trans *trans, - const struct fw_img *fw, bool run_in_rfkill) + const struct iwl_fw *fw, + const struct fw_img *img, + bool run_in_rfkill) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); bool hw_rfkill; @@ -1408,10 +1410,10 @@ int iwl_trans_pcie_start_fw(struct iwl_trans *trans, iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); /* Load the given image to the HW */ - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000) - ret = iwl_pcie_load_given_ucode_8000(trans, fw); + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_8000) + ret = iwl_pcie_load_given_ucode_8000(trans, img); else - ret = iwl_pcie_load_given_ucode(trans, fw); + ret = iwl_pcie_load_given_ucode(trans, img); /* re-check RF-Kill state since we may have missed the interrupt */ hw_rfkill = iwl_pcie_check_hw_rf_kill(trans); @@ -1423,10 +1425,10 @@ out: return ret; } -void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr) +void iwl_trans_pcie_fw_alive(struct iwl_trans *trans) { iwl_pcie_reset_ict(trans); - iwl_pcie_tx_start(trans, scd_addr); + iwl_pcie_tx_start(trans); } void iwl_trans_pcie_handle_stop_rfkill(struct iwl_trans *trans, @@ -1485,7 +1487,7 @@ void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state, bool from_irq) IWL_WARN(trans, "reporting RF_KILL (radio %s)\n", state ? "disabled" : "enabled"); if (iwl_op_mode_hw_rf_kill(trans->op_mode, state) && - !WARN_ON(trans->trans_cfg->gen2)) + !WARN_ON(trans->mac_cfg->gen2)) _iwl_trans_pcie_stop_device(trans, from_irq); } @@ -1505,7 +1507,7 @@ static void iwl_pcie_d3_complete_suspend(struct iwl_trans *trans, iwl_pcie_synchronize_irqs(trans); - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_BZ_MAC_ACCESS_REQ); iwl_clear_bit(trans, CSR_GP_CNTRL, @@ -1534,11 +1536,11 @@ static int iwl_pcie_d3_handshake(struct iwl_trans *trans, bool suspend) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int ret; - if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210) + if (trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_AX210) iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6, suspend ? UREG_DOORBELL_TO_ISR6_SUSPEND : UREG_DOORBELL_TO_ISR6_RESUME); - else if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + else if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) iwl_write32(trans, CSR_IPC_SLEEP_CONTROL, suspend ? CSR_IPC_SLEEP_CONTROL_SUSPEND : CSR_IPC_SLEEP_CONTROL_RESUME); @@ -1593,7 +1595,7 @@ int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, goto out; } - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_BZ_MAC_ACCESS_REQ); else @@ -1653,17 +1655,18 @@ out: static void iwl_pcie_set_interrupt_capa(struct pci_dev *pdev, struct iwl_trans *trans, - const struct iwl_cfg_trans_params *cfg_trans) + const struct iwl_mac_cfg *mac_cfg, + struct iwl_trans_info *info) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int max_irqs, num_irqs, i, ret; u16 pci_cmd; u32 max_rx_queues = IWL_MAX_RX_HW_QUEUES; - if (!cfg_trans->mq_rx_supported) + if (!mac_cfg->mq_rx_supported) goto enable_msi; - if (cfg_trans->device_family <= IWL_DEVICE_FAMILY_9000) + if (mac_cfg->device_family <= IWL_DEVICE_FAMILY_9000) max_rx_queues = IWL_9000_MAX_RX_HW_QUEUES; max_irqs = min_t(u32, num_online_cpus() + 2, max_rx_queues); @@ -1693,27 +1696,28 @@ iwl_pcie_set_interrupt_capa(struct pci_dev *pdev, * More than two interrupts: we will use fewer RSS queues. */ if (num_irqs <= max_irqs - 2) { - trans_pcie->trans->num_rx_queues = num_irqs + 1; + info->num_rxqs = num_irqs + 1; trans_pcie->shared_vec_mask = IWL_SHARED_IRQ_NON_RX | IWL_SHARED_IRQ_FIRST_RSS; } else if (num_irqs == max_irqs - 1) { - trans_pcie->trans->num_rx_queues = num_irqs; + info->num_rxqs = num_irqs; trans_pcie->shared_vec_mask = IWL_SHARED_IRQ_NON_RX; } else { - trans_pcie->trans->num_rx_queues = num_irqs - 1; + info->num_rxqs = num_irqs - 1; } IWL_DEBUG_INFO(trans, "MSI-X enabled with rx queues %d, vec mask 0x%x\n", - trans_pcie->trans->num_rx_queues, trans_pcie->shared_vec_mask); + info->num_rxqs, trans_pcie->shared_vec_mask); - WARN_ON(trans_pcie->trans->num_rx_queues > IWL_MAX_RX_HW_QUEUES); + WARN_ON(info->num_rxqs > IWL_MAX_RX_HW_QUEUES); trans_pcie->alloc_vecs = num_irqs; trans_pcie->msix_enabled = true; return; enable_msi: + info->num_rxqs = 1; ret = pci_enable_msi(pdev); if (ret) { dev_err(&pdev->dev, "pci_enable_msi failed - %d\n", ret); @@ -1726,14 +1730,15 @@ enable_msi: } } -static void iwl_pcie_irq_set_affinity(struct iwl_trans *trans) +static void iwl_pcie_irq_set_affinity(struct iwl_trans *trans, + struct iwl_trans_info *info) { #if defined(CONFIG_SMP) int iter_rx_q, i, ret, cpu, offset; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); i = trans_pcie->shared_vec_mask & IWL_SHARED_IRQ_FIRST_RSS ? 0 : 1; - iter_rx_q = trans_pcie->trans->num_rx_queues - 1 + i; + iter_rx_q = info->num_rxqs - 1 + i; offset = 1 + i; for (; i < iter_rx_q ; i++) { /* @@ -1753,7 +1758,8 @@ static void iwl_pcie_irq_set_affinity(struct iwl_trans *trans) } static int iwl_pcie_init_msix_handler(struct pci_dev *pdev, - struct iwl_trans_pcie *trans_pcie) + struct iwl_trans_pcie *trans_pcie, + struct iwl_trans_info *info) { int i; @@ -1782,7 +1788,7 @@ static int iwl_pcie_init_msix_handler(struct pci_dev *pdev, return ret; } } - iwl_pcie_irq_set_affinity(trans_pcie->trans); + iwl_pcie_irq_set_affinity(trans_pcie->trans, info); return 0; } @@ -1791,7 +1797,7 @@ static int iwl_trans_pcie_clear_persistence_bit(struct iwl_trans *trans) { u32 hpm, wprot; - switch (trans->trans_cfg->device_family) { + switch (trans->mac_cfg->device_family) { case IWL_DEVICE_FAMILY_9000: wprot = PREG_PRPH_WPROT_9000; break; @@ -1860,8 +1866,8 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans) if (err) return err; - if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000 && - trans->trans_cfg->integrated) { + if (trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_22000 && + trans->mac_cfg->integrated) { err = iwl_pcie_gen2_force_power_gating(trans); if (err) return err; @@ -1936,7 +1942,7 @@ u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs) static u32 iwl_trans_pcie_prph_msk(struct iwl_trans *trans) { - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) return 0x00FFFFFF; else return 0x000FFFFF; @@ -1960,45 +1966,17 @@ void iwl_trans_pcie_write_prph(struct iwl_trans *trans, u32 addr, u32 val) iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WDAT, val); } -void iwl_trans_pcie_configure(struct iwl_trans *trans, - const struct iwl_trans_config *trans_cfg) +void iwl_trans_pcie_op_mode_enter(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); /* free all first - we might be reconfigured for a different size */ iwl_pcie_free_rbs_pool(trans); - trans_pcie->txqs.cmd.q_id = trans_cfg->cmd_queue; - trans_pcie->txqs.cmd.fifo = trans_cfg->cmd_fifo; - trans_pcie->txqs.page_offs = trans_cfg->cb_data_offs; - trans_pcie->txqs.dev_cmd_offs = trans_cfg->cb_data_offs + sizeof(void *); - trans_pcie->txqs.queue_alloc_cmd_ver = trans_cfg->queue_alloc_cmd_ver; - - if (WARN_ON(trans_cfg->n_no_reclaim_cmds > MAX_NO_RECLAIM_CMDS)) - trans_pcie->n_no_reclaim_cmds = 0; - else - trans_pcie->n_no_reclaim_cmds = trans_cfg->n_no_reclaim_cmds; - if (trans_pcie->n_no_reclaim_cmds) - memcpy(trans_pcie->no_reclaim_cmds, trans_cfg->no_reclaim_cmds, - trans_pcie->n_no_reclaim_cmds * sizeof(u8)); - - trans_pcie->rx_buf_size = trans_cfg->rx_buf_size; trans_pcie->rx_page_order = - iwl_trans_get_rb_size_order(trans_pcie->rx_buf_size); + iwl_trans_get_rb_size_order(trans->conf.rx_buf_size); trans_pcie->rx_buf_bytes = - iwl_trans_get_rb_size(trans_pcie->rx_buf_size); - trans_pcie->supported_dma_mask = DMA_BIT_MASK(12); - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) - trans_pcie->supported_dma_mask = DMA_BIT_MASK(11); - - trans_pcie->txqs.bc_table_dword = trans_cfg->bc_table_dword; - trans_pcie->scd_set_active = trans_cfg->scd_set_active; - - trans->command_groups = trans_cfg->command_groups; - trans->command_groups_size = trans_cfg->command_groups_size; - - - trans_pcie->fw_reset_handshake = trans_cfg->fw_reset_handshake; + iwl_trans_get_rb_size(trans->conf.rx_buf_size); } void iwl_trans_pcie_free_pnvm_dram_regions(struct iwl_dram_regions *dram_regions, @@ -2026,11 +2004,14 @@ void iwl_trans_pcie_free_pnvm_dram_regions(struct iwl_dram_regions *dram_regions static void iwl_pcie_free_invalid_tx_cmd(struct iwl_trans *trans) { - iwl_pcie_free_dma_ptr(trans, &trans->invalid_tx_cmd); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + + iwl_pcie_free_dma_ptr(trans, &trans_pcie->invalid_tx_cmd); } static int iwl_pcie_alloc_invalid_tx_cmd(struct iwl_trans *trans) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_cmd_header_wide bad_cmd = { .cmd = INVALID_WR_PTR_CMD, .group_id = DEBUG_GROUP, @@ -2040,11 +2021,11 @@ static int iwl_pcie_alloc_invalid_tx_cmd(struct iwl_trans *trans) }; int ret; - ret = iwl_pcie_alloc_dma_ptr(trans, &trans->invalid_tx_cmd, + ret = iwl_pcie_alloc_dma_ptr(trans, &trans_pcie->invalid_tx_cmd, sizeof(bad_cmd)); if (ret) return ret; - memcpy(trans->invalid_tx_cmd.addr, &bad_cmd, sizeof(bad_cmd)); + memcpy(trans_pcie->invalid_tx_cmd.addr, &bad_cmd, sizeof(bad_cmd)); return 0; } @@ -2055,7 +2036,7 @@ void iwl_trans_pcie_free(struct iwl_trans *trans) iwl_pcie_synchronize_irqs(trans); - if (trans->trans_cfg->gen2) + if (trans->mac_cfg->gen2) iwl_txq_gen2_tx_free(trans); else iwl_pcie_tx_free(trans); @@ -2348,6 +2329,7 @@ out: void iwl_trans_pcie_reset(struct iwl_trans *trans, enum iwl_reset_mode mode) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_trans_pcie_removal *removal; char _msg = 0, *msg = &_msg; @@ -2358,9 +2340,9 @@ void iwl_trans_pcie_reset(struct iwl_trans *trans, enum iwl_reset_mode mode) if (test_bit(STATUS_TRANS_DEAD, &trans->status)) return; - if (trans->me_present && mode == IWL_RESET_MODE_PROD_RESET) { + if (trans_pcie->me_present && mode == IWL_RESET_MODE_PROD_RESET) { mode = IWL_RESET_MODE_FUNC_RESET; - if (trans->me_present < 0) + if (trans_pcie->me_present < 0) msg = " instead of product reset as ME may be present"; else msg = " instead of product reset as ME is present"; @@ -2395,7 +2377,7 @@ void iwl_trans_pcie_reset(struct iwl_trans *trans, enum iwl_reset_mode mode) removal->pdev = to_pci_dev(trans->dev); removal->mode = mode; - removal->integrated = trans->trans_cfg->integrated; + removal->integrated = trans->mac_cfg->integrated; INIT_WORK(&removal->work, iwl_trans_pcie_removal_wk); pci_dev_get(removal->pdev); schedule_work(&removal->work); @@ -2423,7 +2405,7 @@ bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent) if (trans_pcie->cmd_hold_nic_awake) goto out; - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { write = CSR_GP_CNTRL_REG_FLAG_BZ_MAC_ACCESS_REQ; mask = CSR_GP_CNTRL_REG_FLAG_MAC_STATUS; poll = CSR_GP_CNTRL_REG_FLAG_MAC_STATUS; @@ -2431,7 +2413,7 @@ bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent) /* this bit wakes up the NIC */ __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, write); - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000) + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_8000) udelay(2); /* @@ -2518,7 +2500,7 @@ iwl_trans_pcie_release_nic_access(struct iwl_trans *trans) if (trans_pcie->cmd_hold_nic_awake) goto out; - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_BZ_MAC_ACCESS_REQ); else @@ -2617,7 +2599,7 @@ int iwl_trans_pcie_rxq_dma_data(struct iwl_trans *trans, int queue, { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - if (queue >= trans->num_rx_queues || !trans_pcie->rxq) + if (queue >= trans->info.num_rxqs || !trans_pcie->rxq) return -EINVAL; data->fr_bd_cb = trans_pcie->rxq[queue].bd_dma; @@ -2698,10 +2680,10 @@ int iwl_trans_pcie_wait_txqs_empty(struct iwl_trans *trans, u32 txq_bm) /* waiting for all the tx frames complete might take a while */ for (cnt = 0; - cnt < trans->trans_cfg->base_params->num_of_queues; + cnt < trans->mac_cfg->base->num_of_queues; cnt++) { - if (cnt == trans_pcie->txqs.cmd.q_id) + if (cnt == trans->conf.cmd_queue) continue; if (!test_bit(cnt, trans_pcie->txqs.queue_used)) continue; @@ -2842,7 +2824,7 @@ static void *iwl_dbgfs_tx_queue_seq_start(struct seq_file *seq, loff_t *pos) struct iwl_dbgfs_tx_queue_priv *priv = seq->private; struct iwl_dbgfs_tx_queue_state *state; - if (*pos >= priv->trans->trans_cfg->base_params->num_of_queues) + if (*pos >= priv->trans->mac_cfg->base->num_of_queues) return NULL; state = kmalloc(sizeof(*state), GFP_KERNEL); @@ -2860,7 +2842,7 @@ static void *iwl_dbgfs_tx_queue_seq_next(struct seq_file *seq, *pos = ++state->pos; - if (*pos >= priv->trans->trans_cfg->base_params->num_of_queues) + if (*pos >= priv->trans->mac_cfg->base->num_of_queues) return NULL; return state; @@ -2892,7 +2874,7 @@ static int iwl_dbgfs_tx_queue_seq_show(struct seq_file *seq, void *v) else seq_puts(seq, "(unallocated)"); - if (state->pos == trans_pcie->txqs.cmd.q_id) + if (state->pos == trans->conf.cmd_queue) seq_puts(seq, " (HCMD)"); seq_puts(seq, "\n"); @@ -2930,7 +2912,7 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file, int pos = 0, i, ret; size_t bufsz; - bufsz = sizeof(char) * 121 * trans->num_rx_queues; + bufsz = sizeof(char) * 121 * trans->info.num_rxqs; if (!trans_pcie->rxq) return -EAGAIN; @@ -2939,9 +2921,11 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file, if (!buf) return -ENOMEM; - for (i = 0; i < trans->num_rx_queues && pos < bufsz; i++) { + for (i = 0; i < trans->info.num_rxqs && pos < bufsz; i++) { struct iwl_rxq *rxq = &trans_pcie->rxq[i]; + spin_lock_bh(&rxq->lock); + pos += scnprintf(buf + pos, bufsz - pos, "queue#: %2d\n", i); pos += scnprintf(buf + pos, bufsz - pos, "\tread: %u\n", @@ -2962,6 +2946,7 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file, pos += scnprintf(buf + pos, bufsz - pos, "\tclosed_rb_num: Not Allocated\n"); } + spin_unlock_bh(&rxq->lock); } ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); @@ -3266,8 +3251,9 @@ static ssize_t iwl_dbgfs_reset_write(struct file *file, { struct iwl_trans *trans = file->private_data; static const char * const modes[] = { - [IWL_RESET_MODE_SW_RESET] = "n/a", - [IWL_RESET_MODE_REPROBE] = "n/a", + [IWL_RESET_MODE_SW_RESET] = "sw", + [IWL_RESET_MODE_REPROBE] = "reprobe", + [IWL_RESET_MODE_TOP_RESET] = "top", [IWL_RESET_MODE_REMOVE_ONLY] = "remove", [IWL_RESET_MODE_RESCAN] = "rescan", [IWL_RESET_MODE_FUNC_RESET] = "function", @@ -3286,8 +3272,18 @@ static ssize_t iwl_dbgfs_reset_write(struct file *file, if (mode < 0) return mode; - if (mode < IWL_RESET_MODE_REMOVE_ONLY) - return -EINVAL; + if (mode < IWL_RESET_MODE_REMOVE_ONLY) { + if (!test_bit(STATUS_DEVICE_ENABLED, &trans->status)) + return -EINVAL; + if (mode == IWL_RESET_MODE_TOP_RESET) { + if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_SC) + return -EINVAL; + trans->request_top_reset = 1; + } + iwl_op_mode_nic_error(trans->op_mode, IWL_ERR_TYPE_DEBUGFS); + iwl_trans_schedule_reset(trans, IWL_ERR_TYPE_DEBUGFS); + return count; + } iwl_trans_pcie_reset(trans, mode); @@ -3428,7 +3424,7 @@ static u32 iwl_trans_pcie_fh_regs_dump(struct iwl_trans *trans, (*data)->len = cpu_to_le32(fh_regs_len); val = (void *)(*data)->data; - if (!trans->trans_cfg->gen2) + if (!trans->mac_cfg->gen2) for (i = FH_MEM_LOWER_BOUND; i < FH_MEM_UPPER_BOUND; i += sizeof(u32)) *val++ = cpu_to_le32(iwl_trans_pcie_read32(trans, i)); @@ -3475,7 +3471,7 @@ iwl_trans_pcie_dump_pointers(struct iwl_trans *trans, { u32 base, base_high, write_ptr, write_ptr_val, wrap_cnt; - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { base = DBGC_CUR_DBGBUF_BASE_ADDR_LSB; base_high = DBGC_CUR_DBGBUF_BASE_ADDR_MSB; write_ptr = DBGC_CUR_DBGBUF_STATUS; @@ -3495,7 +3491,7 @@ iwl_trans_pcie_dump_pointers(struct iwl_trans *trans, cpu_to_le32(iwl_read_prph(trans, wrap_cnt)); fw_mon_data->fw_mon_base_ptr = cpu_to_le32(iwl_read_prph(trans, base)); - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { fw_mon_data->fw_mon_base_high_ptr = cpu_to_le32(iwl_read_prph(trans, base_high)); write_ptr_val &= DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK; @@ -3515,8 +3511,8 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans, if (trans->dbg.dest_tlv || (fw_mon->size && - (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000 || - trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210))) { + (trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_7000 || + trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210))) { struct iwl_fw_error_dump_fw_mon *fw_mon_data; (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_FW_MONITOR); @@ -3539,14 +3535,14 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans, IWL_LDBG_M2S_BUF_BA_MSK) << trans->dbg.dest_tlv->base_shift; base *= IWL_M2S_UNIT_SIZE; - base += trans->cfg->smem_offset; + base += trans->mac_cfg->base->smem_offset; } else { base = iwl_read_prph(trans, base) << trans->dbg.dest_tlv->base_shift; } - iwl_trans_read_mem(trans, base, fw_mon_data->data, - monitor_len / sizeof(u32)); + iwl_trans_pcie_read_mem(trans, base, fw_mon_data->data, + monitor_len / sizeof(u32)); } else if (trans->dbg.dest_tlv->monitor_mode == MARBH_MODE) { monitor_len = iwl_trans_pci_dump_marbh_monitor(trans, @@ -3580,7 +3576,7 @@ static int iwl_trans_get_fw_monitor_len(struct iwl_trans *trans, u32 *len) base = (cfg_reg & IWL_LDBG_M2S_BUF_BA_MSK) << trans->dbg.dest_tlv->base_shift; base *= IWL_M2S_UNIT_SIZE; - base += trans->cfg->smem_offset; + base += trans->mac_cfg->base->smem_offset; monitor_len = (cfg_reg & IWL_LDBG_M2S_BUF_SIZE_MSK) >> @@ -3596,7 +3592,7 @@ static int iwl_trans_get_fw_monitor_len(struct iwl_trans *trans, u32 *len) trans->dbg.dest_tlv->end_shift; /* Make "end" point to the actual end */ - if (trans->trans_cfg->device_family >= + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_8000 || trans->dbg.dest_tlv->monitor_mode == MARBH_MODE) end += (1 << trans->dbg.dest_tlv->end_shift); @@ -3617,13 +3613,13 @@ iwl_trans_pcie_dump_data(struct iwl_trans *trans, u32 dump_mask, { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_fw_error_dump_data *data; - struct iwl_txq *cmdq = trans_pcie->txqs.txq[trans_pcie->txqs.cmd.q_id]; + struct iwl_txq *cmdq = trans_pcie->txqs.txq[trans->conf.cmd_queue]; struct iwl_fw_error_dump_txcmd *txcmd; struct iwl_trans_dump_data *dump_data; u32 len, num_rbs = 0, monitor_len = 0; int i, ptr; bool dump_rbs = test_bit(STATUS_FW_ERROR, &trans->status) && - !trans->trans_cfg->mq_rx_supported && + !trans->mac_cfg->mq_rx_supported && dump_mask & BIT(IWL_FW_ERROR_DUMP_RB); if (!dump_mask) @@ -3648,7 +3644,7 @@ iwl_trans_pcie_dump_data(struct iwl_trans *trans, u32 dump_mask, /* FH registers */ if (dump_mask & BIT(IWL_FW_ERROR_DUMP_FH_REGS)) { - if (trans->trans_cfg->gen2) + if (trans->mac_cfg->gen2) len += sizeof(*data) + (iwl_umac_prph(trans, FH_MEM_UPPER_BOUND_GEN2) - iwl_umac_prph(trans, FH_MEM_LOWER_BOUND_GEN2)); @@ -3662,15 +3658,18 @@ iwl_trans_pcie_dump_data(struct iwl_trans *trans, u32 dump_mask, /* Dump RBs is supported only for pre-9000 devices (1 queue) */ struct iwl_rxq *rxq = &trans_pcie->rxq[0]; /* RBs */ + spin_lock_bh(&rxq->lock); num_rbs = iwl_get_closed_rb_stts(trans, rxq); num_rbs = (num_rbs - rxq->read) & RX_QUEUE_MASK; + spin_unlock_bh(&rxq->lock); + len += num_rbs * (sizeof(*data) + sizeof(struct iwl_fw_error_dump_rb) + (PAGE_SIZE << trans_pcie->rx_page_order)); } /* Paged memory for gen2 HW */ - if (trans->trans_cfg->gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING)) + if (trans->mac_cfg->gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING)) for (i = 0; i < trans->init_dram.paging_cnt; i++) len += sizeof(*data) + sizeof(struct iwl_fw_error_dump_paging) + @@ -3695,7 +3694,7 @@ iwl_trans_pcie_dump_data(struct iwl_trans *trans, u32 dump_mask, u8 tfdidx; u32 caplen, cmdlen; - if (trans->trans_cfg->gen2) + if (trans->mac_cfg->gen2) tfdidx = idx; else tfdidx = ptr; @@ -3735,7 +3734,7 @@ iwl_trans_pcie_dump_data(struct iwl_trans *trans, u32 dump_mask, len += iwl_trans_pcie_dump_rbs(trans, &data, num_rbs); /* Paged memory for gen2 HW */ - if (trans->trans_cfg->gen2 && + if (trans->mac_cfg->gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING)) { for (i = 0; i < trans->init_dram.paging_cnt; i++) { struct iwl_fw_error_dump_paging *paging; @@ -3775,7 +3774,7 @@ void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans) if (trans_pcie->msix_enabled) { inta_addr = CSR_MSIX_HW_INT_CAUSES_AD; - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) sw_err_bit = MSIX_HW_INT_CAUSES_REG_SW_ERR_BZ; else sw_err_bit = MSIX_HW_INT_CAUSES_REG_SW_ERR; @@ -3787,12 +3786,14 @@ void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans) iwl_trans_sync_nmi_with_addr(trans, inta_addr, sw_err_bit); } -struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, - const struct pci_device_id *ent, - const struct iwl_cfg_trans_params *cfg_trans) +struct iwl_trans * +iwl_trans_pcie_alloc(struct pci_dev *pdev, + const struct iwl_mac_cfg *mac_cfg, + struct iwl_trans_info *info) { struct iwl_trans_pcie *trans_pcie, **priv; struct iwl_trans *trans; + unsigned int bc_tbl_n_entries; int ret, addr_size; u32 bar0; @@ -3809,13 +3810,16 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, return ERR_PTR(ret); trans = iwl_trans_alloc(sizeof(struct iwl_trans_pcie), &pdev->dev, - cfg_trans); + mac_cfg); if (!trans) return ERR_PTR(-ENOMEM); trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - if (trans->trans_cfg->gen2) { + /* Initialize the wait queue for commands */ + init_waitqueue_head(&trans_pcie->wait_command_queue); + + if (trans->mac_cfg->gen2) { trans_pcie->txqs.tfd.addr_size = 64; trans_pcie->txqs.tfd.max_tbs = IWL_TFH_NUM_TBS; trans_pcie->txqs.tfd.size = sizeof(struct iwl_tfh_tfd); @@ -3824,10 +3828,12 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, trans_pcie->txqs.tfd.max_tbs = IWL_NUM_OF_TBS; trans_pcie->txqs.tfd.size = sizeof(struct iwl_tfd); } - trans->max_skb_frags = IWL_TRANS_PCIE_MAX_FRAGS(trans_pcie); - /* Set a short watchdog for the command queue */ - trans_pcie->txqs.cmd.wdg_timeout = IWL_DEF_WD_TIMEOUT; + trans_pcie->supported_dma_mask = (u32)DMA_BIT_MASK(12); + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) + trans_pcie->supported_dma_mask = (u32)DMA_BIT_MASK(11); + + info->max_skb_frags = IWL_TRANS_PCIE_MAX_FRAGS(trans_pcie); trans_pcie->txqs.tso_hdr_page = alloc_percpu(struct iwl_tso_hdr_page); if (!trans_pcie->txqs.tso_hdr_page) { @@ -3835,20 +3841,21 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, goto out_free_trans; } - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) - trans_pcie->txqs.bc_tbl_size = - sizeof(struct iwl_gen3_bc_tbl_entry) * TFD_QUEUE_BC_SIZE_GEN3_BZ; - else if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) - trans_pcie->txqs.bc_tbl_size = - sizeof(struct iwl_gen3_bc_tbl_entry) * TFD_QUEUE_BC_SIZE_GEN3_AX210; + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + bc_tbl_n_entries = TFD_QUEUE_BC_SIZE_BZ; + else if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) + bc_tbl_n_entries = TFD_QUEUE_BC_SIZE_AX210; else - trans_pcie->txqs.bc_tbl_size = sizeof(struct iwlagn_scd_bc_tbl); + bc_tbl_n_entries = TFD_QUEUE_BC_SIZE; + + trans_pcie->txqs.bc_tbl_size = + sizeof(struct iwl_bc_tbl_entry) * bc_tbl_n_entries; /* * For gen2 devices, we use a single allocation for each byte-count * table, but they're pretty small (1k) so use a DMA pool that we * allocate here. */ - if (trans->trans_cfg->gen2) { + if (trans->mac_cfg->gen2) { trans_pcie->txqs.bc_pool = dmam_pool_create("iwlwifi:bc", trans->dev, trans_pcie->txqs.bc_tbl_size, @@ -3861,7 +3868,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, /* Some things must not change even if the config does */ WARN_ON(trans_pcie->txqs.tfd.addr_size != - (trans->trans_cfg->gen2 ? 64 : 36)); + (trans->mac_cfg->gen2 ? 64 : 36)); /* Initialize NAPI here - it should be before registering to mac80211 * in the opmode but after the HW struct is allocated. @@ -3895,7 +3902,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, trans_pcie->debug_rfkill = -1; - if (!cfg_trans->base_params->pcie_l1_allowed) { + if (!mac_cfg->base->pcie_l1_allowed) { /* * W/A - seems to solve weird behavior. We need to remove this * if we don't want to stay in L1 all the time. This wastes a @@ -3939,8 +3946,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, trans_pcie->pci_dev = pdev; iwl_disable_interrupts(trans); - trans->hw_rev = iwl_read32(trans, CSR_HW_REV); - if (trans->hw_rev == 0xffffffff) { + info->hw_rev = iwl_read32(trans, CSR_HW_REV); + if (info->hw_rev == 0xffffffff) { dev_err(&pdev->dev, "HW_REV=0xFFFFFFFF, PCI issues?\n"); ret = -EIO; goto out_no_pci; @@ -3952,17 +3959,14 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, * "dash" value). To keep hw_rev backwards compatible - we'll store it * in the old format. */ - if (cfg_trans->device_family >= IWL_DEVICE_FAMILY_8000) - trans->hw_rev_step = trans->hw_rev & 0xF; + if (mac_cfg->device_family >= IWL_DEVICE_FAMILY_8000) + info->hw_rev_step = info->hw_rev & 0xF; else - trans->hw_rev_step = (trans->hw_rev & 0xC) >> 2; + info->hw_rev_step = (info->hw_rev & 0xC) >> 2; - IWL_DEBUG_INFO(trans, "HW REV: 0x%0x\n", trans->hw_rev); + IWL_DEBUG_INFO(trans, "HW REV: 0x%0x\n", info->hw_rev); - iwl_pcie_set_interrupt_capa(pdev, trans, cfg_trans); - trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; - snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), - "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device); + iwl_pcie_set_interrupt_capa(pdev, trans, mac_cfg, info); init_waitqueue_head(&trans_pcie->sx_waitq); @@ -3971,7 +3975,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, goto out_no_pci; if (trans_pcie->msix_enabled) { - ret = iwl_pcie_init_msix_handler(pdev, trans_pcie); + ret = iwl_pcie_init_msix_handler(pdev, trans_pcie, info); if (ret) goto out_no_pci; } else { diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c index 71227fd3dac0..df0545f09da9 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c @@ -18,13 +18,12 @@ static struct page *get_workaround_page(struct iwl_trans *trans, struct sk_buff *skb) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_tso_page_info *info; struct page **page_ptr; struct page *ret; dma_addr_t phys; - page_ptr = (void *)((u8 *)skb->cb + trans_pcie->txqs.page_offs); + page_ptr = (void *)((u8 *)skb->cb + trans->conf.cb_data_offs); ret = alloc_page(GFP_ATOMIC); if (!ret) @@ -164,7 +163,7 @@ static int iwl_txq_gen2_build_amsdu(struct iwl_trans *trans, struct iwl_device_tx_cmd *dev_cmd) { #ifdef CONFIG_INET - struct iwl_tx_cmd_gen2 *tx_cmd = (void *)dev_cmd->payload; + struct iwl_tx_cmd_v9 *tx_cmd = (void *)dev_cmd->payload; struct ieee80211_hdr *hdr = (void *)skb->data; unsigned int snap_ip_tcp_hdrlen, ip_hdrlen, total_len, hdr_room; unsigned int mss = skb_shinfo(skb)->gso_size; @@ -491,21 +490,21 @@ struct iwl_tfh_tfd *iwl_txq_gen2_build_tfd(struct iwl_trans *trans, bool amsdu; /* There must be data left over for TB1 or this code must be changed */ - BUILD_BUG_ON(sizeof(struct iwl_tx_cmd_gen2) < IWL_FIRST_TB_SIZE); + BUILD_BUG_ON(sizeof(struct iwl_tx_cmd_v9) < IWL_FIRST_TB_SIZE); BUILD_BUG_ON(sizeof(struct iwl_cmd_header) + - offsetofend(struct iwl_tx_cmd_gen2, dram_info) > + offsetofend(struct iwl_tx_cmd_v9, dram_info) > IWL_FIRST_TB_SIZE); - BUILD_BUG_ON(sizeof(struct iwl_tx_cmd_gen3) < IWL_FIRST_TB_SIZE); + BUILD_BUG_ON(sizeof(struct iwl_tx_cmd) < IWL_FIRST_TB_SIZE); BUILD_BUG_ON(sizeof(struct iwl_cmd_header) + - offsetofend(struct iwl_tx_cmd_gen3, dram_info) > + offsetofend(struct iwl_tx_cmd, dram_info) > IWL_FIRST_TB_SIZE); memset(tfd, 0, sizeof(*tfd)); - if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) - len = sizeof(struct iwl_tx_cmd_gen2); + if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) + len = sizeof(struct iwl_tx_cmd_v9); else - len = sizeof(struct iwl_tx_cmd_gen3); + len = sizeof(struct iwl_tx_cmd); amsdu = ieee80211_is_data_qos(hdr->frame_control) && (*ieee80211_get_qos_ctl(hdr) & @@ -536,17 +535,17 @@ int iwl_txq_space(struct iwl_trans *trans, const struct iwl_txq *q) * If q->n_window is smaller than max_tfd_queue_size, there is no need * to reserve any queue entries for this purpose. */ - if (q->n_window < trans->trans_cfg->base_params->max_tfd_queue_size) + if (q->n_window < trans->mac_cfg->base->max_tfd_queue_size) max = q->n_window; else - max = trans->trans_cfg->base_params->max_tfd_queue_size - 1; + max = trans->mac_cfg->base->max_tfd_queue_size - 1; /* * max_tfd_queue_size is a power of 2, so the following is equivalent to * modulo by max_tfd_queue_size and is well defined. */ used = (q->write_ptr - q->read_ptr) & - (trans->trans_cfg->base_params->max_tfd_queue_size - 1); + (trans->mac_cfg->base->max_tfd_queue_size - 1); if (WARN_ON(used > max)) return 0; @@ -561,8 +560,8 @@ static void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans *trans, struct iwl_txq *txq, u16 byte_cnt, int num_tbs) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int idx = iwl_txq_get_cmd_index(txq, txq->write_ptr); + struct iwl_bc_tbl_entry *scd_bc_tbl = txq->bc_tbl.addr; u8 filled_tfd_size, num_fetch_chunks; u16 len = byte_cnt; __le16 bc_ent; @@ -582,24 +581,16 @@ static void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans *trans, */ num_fetch_chunks = DIV_ROUND_UP(filled_tfd_size, 64) - 1; - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { - struct iwl_gen3_bc_tbl_entry *scd_bc_tbl_gen3 = txq->bc_tbl.addr; - - /* Starting from AX210, the HW expects bytes */ - WARN_ON(trans_pcie->txqs.bc_table_dword); + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { WARN_ON(len > 0x3FFF); bc_ent = cpu_to_le16(len | (num_fetch_chunks << 14)); - scd_bc_tbl_gen3[idx].tfd_offset = bc_ent; } else { - struct iwlagn_scd_bc_tbl *scd_bc_tbl = txq->bc_tbl.addr; - - /* Before AX210, the HW expects DW */ - WARN_ON(!trans_pcie->txqs.bc_table_dword); len = DIV_ROUND_UP(len, 4); WARN_ON(len > 0xFFF); bc_ent = cpu_to_le16(len | (num_fetch_chunks << 12)); - scd_bc_tbl->tfd_offset[idx] = bc_ent; } + + scd_bc_tbl[idx].tfd_offset = bc_ent; } static u8 iwl_txq_gen2_get_num_tbs(struct iwl_tfh_tfd *tfd) @@ -756,7 +747,8 @@ int iwl_txq_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_device_tx_cmd **dev_cmd_ptr; dev_cmd_ptr = (void *)((u8 *)skb->cb + - trans_pcie->txqs.dev_cmd_offs); + trans->conf.cb_data_offs + + sizeof(void *)); *dev_cmd_ptr = dev_cmd; __skb_queue_tail(&txq->overflow_q, skb); @@ -785,16 +777,16 @@ int iwl_txq_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb, return -1; } - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { - struct iwl_tx_cmd_gen3 *tx_cmd_gen3 = + if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + struct iwl_tx_cmd *tx_cmd = (void *)dev_cmd->payload; - cmd_len = le16_to_cpu(tx_cmd_gen3->len); + cmd_len = le16_to_cpu(tx_cmd->len); } else { - struct iwl_tx_cmd_gen2 *tx_cmd_gen2 = + struct iwl_tx_cmd_v9 *tx_cmd_v9 = (void *)dev_cmd->payload; - cmd_len = le16_to_cpu(tx_cmd_gen2->len); + cmd_len = le16_to_cpu(tx_cmd_v9->len); } /* Set up entry for this TFD in Tx byte-count array */ @@ -832,7 +824,7 @@ static void iwl_txq_gen2_unmap(struct iwl_trans *trans, int txq_id) IWL_DEBUG_TX_REPLY(trans, "Q %d Free %d\n", txq_id, txq->read_ptr); - if (txq_id != trans_pcie->txqs.cmd.q_id) { + if (txq_id != trans->conf.cmd_queue) { int idx = iwl_txq_get_cmd_index(txq, txq->read_ptr); struct iwl_cmd_meta *cmd_meta = &txq->entries[idx].meta; struct sk_buff *skb = txq->entries[idx].skb; @@ -906,7 +898,7 @@ static void iwl_txq_gen2_free(struct iwl_trans *trans, int txq_id) iwl_txq_gen2_unmap(trans, txq_id); /* De-alloc array of command/tx buffers */ - if (txq_id == trans_pcie->txqs.cmd.q_id) + if (txq_id == trans->conf.cmd_queue) for (i = 0; i < txq->n_window; i++) { kfree_sensitive(txq->entries[i].cmd); kfree_sensitive(txq->entries[i].free_buf); @@ -1007,7 +999,7 @@ static int iwl_pcie_txq_alloc_response(struct iwl_trans *trans, txq->id = qid; trans_pcie->txqs.txq[qid] = txq; - wr_ptr &= (trans->trans_cfg->base_params->max_tfd_queue_size - 1); + wr_ptr &= (trans->mac_cfg->base->max_tfd_queue_size - 1); /* Place first TFD at index corresponding to start sequence number */ txq->read_ptr = wr_ptr; @@ -1043,8 +1035,8 @@ int iwl_txq_dyn_alloc(struct iwl_trans *trans, u32 flags, u32 sta_mask, /* but must be power of 2 values for calculating read/write pointers */ size = rounddown_pow_of_two(size); - if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_BZ && - trans->hw_rev_step == SILICON_A_STEP) { + if (trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_BZ && + trans->info.hw_rev_step == SILICON_A_STEP) { size = 4096; txq = iwl_txq_dyn_alloc_dma(trans, size, timeout); } else { @@ -1064,7 +1056,7 @@ int iwl_txq_dyn_alloc(struct iwl_trans *trans, u32 flags, u32 sta_mask, if (IS_ERR(txq)) return PTR_ERR(txq); - if (trans_pcie->txqs.queue_alloc_cmd_ver == 0) { + if (trans->conf.queue_alloc_cmd_ver == 0) { memset(&cmd.old, 0, sizeof(cmd.old)); cmd.old.tfdq_addr = cpu_to_le64(txq->dma_addr); cmd.old.byte_cnt_addr = cpu_to_le64(txq->bc_tbl.dma); @@ -1081,7 +1073,7 @@ int iwl_txq_dyn_alloc(struct iwl_trans *trans, u32 flags, u32 sta_mask, hcmd.id = SCD_QUEUE_CFG; hcmd.len[0] = sizeof(cmd.old); hcmd.data[0] = &cmd.old; - } else if (trans_pcie->txqs.queue_alloc_cmd_ver == 3) { + } else if (trans->conf.queue_alloc_cmd_ver == 3) { memset(&cmd.new, 0, sizeof(cmd.new)); cmd.new.operation = cpu_to_le32(IWL_SCD_QUEUE_ADD); cmd.new.u.add.tfdq_dram_addr = cpu_to_le64(txq->dma_addr); @@ -1176,7 +1168,7 @@ int iwl_txq_gen2_init(struct iwl_trans *trans, int txq_id, int queue_size) } ret = iwl_txq_init(trans, queue, queue_size, - (txq_id == trans_pcie->txqs.cmd.q_id)); + (txq_id == trans->conf.cmd_queue)); if (ret) { IWL_ERR(trans, "Tx %d queue alloc failed\n", txq_id); goto error; @@ -1206,7 +1198,7 @@ int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_txq *txq = trans_pcie->txqs.txq[trans_pcie->txqs.cmd.q_id]; + struct iwl_txq *txq = trans_pcie->txqs.txq[trans->conf.cmd_queue]; struct iwl_device_cmd *out_cmd; struct iwl_cmd_meta *out_meta; void *dup_buf = NULL; @@ -1323,7 +1315,7 @@ int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans, cpu_to_le16(cmd_size - sizeof(struct iwl_cmd_header_wide)); out_cmd->hdr_wide.reserved = 0; out_cmd->hdr_wide.sequence = - cpu_to_le16(QUEUE_TO_SEQ(trans_pcie->txqs.cmd.q_id) | + cpu_to_le16(QUEUE_TO_SEQ(trans->conf.cmd_queue) | INDEX_TO_SEQ(txq->write_ptr)); cmd_pos = sizeof(struct iwl_cmd_header_wide); @@ -1371,7 +1363,7 @@ int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans, "Sending command %s (%.2x.%.2x), seq: 0x%04X, %d bytes at %d[%d]:%d\n", iwl_get_cmd_string(trans, cmd->id), group_id, out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), - cmd_size, txq->write_ptr, idx, trans_pcie->txqs.cmd.q_id); + cmd_size, txq->write_ptr, idx, trans->conf.cmd_queue); /* start the TFD with the minimum copy bytes */ tb0_size = min_t(int, copy_size, IWL_FIRST_TB_SIZE); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index 9fc4e98693eb..7abd7c7daa89 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -78,7 +78,6 @@ void iwl_pcie_free_dma_ptr(struct iwl_trans *trans, struct iwl_dma_ptr *ptr) static void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); u32 reg = 0; int txq_id = txq->id; @@ -90,8 +89,8 @@ static void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, * 2. NIC is woken up for CMD regardless of shadow outside this function * 3. there is a chance that the NIC is asleep */ - if (!trans->trans_cfg->base_params->shadow_reg_enable && - txq_id != trans_pcie->txqs.cmd.q_id && + if (!trans->mac_cfg->base->shadow_reg_enable && + txq_id != trans->conf.cmd_queue && test_bit(STATUS_TPOWER_PMI, &trans->status)) { /* * wake up nic if it's powered down ... @@ -125,7 +124,7 @@ void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int i; - for (i = 0; i < trans->trans_cfg->base_params->num_of_queues; i++) { + for (i = 0; i < trans->mac_cfg->base->num_of_queues; i++) { struct iwl_txq *txq = trans_pcie->txqs.txq[i]; if (!test_bit(i, trans_pcie->txqs.queue_used)) @@ -193,7 +192,7 @@ static void iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - if (!trans->trans_cfg->base_params->apmg_wake_up_wa) + if (!trans->mac_cfg->base->apmg_wake_up_wa) return; spin_lock(&trans_pcie->reg_lock); @@ -226,11 +225,10 @@ static void iwl_pcie_free_and_unmap_tso_page(struct iwl_trans *trans, void iwl_pcie_free_tso_pages(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_cmd_meta *cmd_meta) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct page **page_ptr; struct page *next; - page_ptr = (void *)((u8 *)skb->cb + trans_pcie->txqs.page_offs); + page_ptr = (void *)((u8 *)skb->cb + trans->conf.cb_data_offs); next = *page_ptr; *page_ptr = NULL; @@ -280,10 +278,12 @@ iwl_txq_gen1_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx) static void iwl_txq_set_tfd_invalid_gen1(struct iwl_trans *trans, struct iwl_tfd *tfd) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + tfd->num_tbs = 0; - iwl_pcie_gen1_tfd_set_tb(tfd, 0, trans->invalid_tx_cmd.dma, - trans->invalid_tx_cmd.size); + iwl_pcie_gen1_tfd_set_tb(tfd, 0, trans_pcie->invalid_tx_cmd.dma, + trans_pcie->invalid_tx_cmd.size); } static void iwl_txq_gen1_tfd_unmap(struct iwl_trans *trans, @@ -355,7 +355,7 @@ static void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq, /* We have only q->n_window txq->entries, but we use * TFD_QUEUE_SIZE_MAX tfds */ - if (trans->trans_cfg->gen2) + if (trans->mac_cfg->gen2) iwl_txq_gen2_tfd_unmap(trans, &txq->entries[idx].meta, iwl_txq_get_tfd(trans, txq, read_ptr)); else @@ -394,7 +394,7 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id) IWL_DEBUG_TX_REPLY(trans, "Q %d Free %d\n", txq_id, txq->read_ptr); - if (txq_id != trans_pcie->txqs.cmd.q_id) { + if (txq_id != trans->conf.cmd_queue) { struct sk_buff *skb = txq->entries[txq->read_ptr].skb; struct iwl_cmd_meta *cmd_meta = &txq->entries[txq->read_ptr].meta; @@ -408,7 +408,7 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id) txq->read_ptr = iwl_txq_inc_wrap(trans, txq->read_ptr); if (txq->read_ptr == txq->write_ptr && - txq_id == trans_pcie->txqs.cmd.q_id) + txq_id == trans->conf.cmd_queue) iwl_pcie_clear_cmd_in_flight(trans); } @@ -446,7 +446,7 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) iwl_pcie_txq_unmap(trans, txq_id); /* De-alloc array of command/tx buffers */ - if (txq_id == trans_pcie->txqs.cmd.q_id) + if (txq_id == trans->conf.cmd_queue) for (i = 0; i < txq->n_window; i++) { kfree_sensitive(txq->entries[i].cmd); kfree_sensitive(txq->entries[i].free_buf); @@ -456,7 +456,7 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) if (txq->tfds) { dma_free_coherent(dev, trans_pcie->txqs.tfd.size * - trans->trans_cfg->base_params->max_tfd_queue_size, + trans->mac_cfg->base->max_tfd_queue_size, txq->tfds, txq->dma_addr); txq->dma_addr = 0; txq->tfds = NULL; @@ -475,10 +475,10 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) memset(txq, 0, sizeof(*txq)); } -void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) +void iwl_pcie_tx_start(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - int nq = trans->trans_cfg->base_params->num_of_queues; + int nq = trans->mac_cfg->base->num_of_queues; int chan; u32 reg_val; int clear_dwords = (SCD_TRANS_TBL_OFFSET_QUEUE(nq) - @@ -493,13 +493,10 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) trans_pcie->scd_base_addr = iwl_read_prph(trans, SCD_SRAM_BASE_ADDR); - WARN_ON(scd_base_addr != 0 && - scd_base_addr != trans_pcie->scd_base_addr); - /* reset context data, TX status and translation data */ - iwl_trans_write_mem(trans, trans_pcie->scd_base_addr + - SCD_CONTEXT_MEM_LOWER_BOUND, - NULL, clear_dwords); + iwl_trans_pcie_write_mem(trans, trans_pcie->scd_base_addr + + SCD_CONTEXT_MEM_LOWER_BOUND, + NULL, clear_dwords); iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, trans_pcie->txqs.scd_bc_tbls.dma >> 10); @@ -507,12 +504,12 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) /* The chain extension of the SCD doesn't work well. This feature is * enabled by default by the HW, so we need to disable it manually. */ - if (trans->trans_cfg->base_params->scd_chain_ext_wa) + if (trans->mac_cfg->base->scd_chain_ext_wa) iwl_write_prph(trans, SCD_CHAINEXT_EN, 0); - iwl_trans_ac_txq_enable(trans, trans_pcie->txqs.cmd.q_id, - trans_pcie->txqs.cmd.fifo, - trans_pcie->txqs.cmd.wdg_timeout); + iwl_trans_ac_txq_enable(trans, trans->conf.cmd_queue, + trans->conf.cmd_fifo, + IWL_DEF_WD_TIMEOUT); /* Activate all Tx DMA/FIFO channels */ iwl_scd_activate_fifos(trans); @@ -529,7 +526,7 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); /* Enable L1-Active */ - if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000) + if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_8000) iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG, APMG_PCIDEV_STT_VAL_L1_ACT_DIS); } @@ -543,13 +540,13 @@ void iwl_trans_pcie_tx_reset(struct iwl_trans *trans) * we should never get here in gen2 trans mode return early to avoid * having invalid accesses */ - if (WARN_ON_ONCE(trans->trans_cfg->gen2)) + if (WARN_ON_ONCE(trans->mac_cfg->gen2)) return; - for (txq_id = 0; txq_id < trans->trans_cfg->base_params->num_of_queues; + for (txq_id = 0; txq_id < trans->mac_cfg->base->num_of_queues; txq_id++) { struct iwl_txq *txq = trans_pcie->txqs.txq[txq_id]; - if (trans->trans_cfg->gen2) + if (trans->mac_cfg->gen2) iwl_write_direct64(trans, FH_MEM_CBBC_QUEUE(trans, txq_id), txq->dma_addr); @@ -571,7 +568,7 @@ void iwl_trans_pcie_tx_reset(struct iwl_trans *trans) * while we were in WoWLAN in which case SCD_SRAM_BASE_ADDR will * contain garbage. */ - iwl_pcie_tx_start(trans, 0); + iwl_pcie_tx_start(trans); } static void iwl_pcie_tx_stop_fh(struct iwl_trans *trans) @@ -633,7 +630,7 @@ int iwl_pcie_tx_stop(struct iwl_trans *trans) return 0; /* Unmap DMA from host system and free skb's */ - for (txq_id = 0; txq_id < trans->trans_cfg->base_params->num_of_queues; + for (txq_id = 0; txq_id < trans->mac_cfg->base->num_of_queues; txq_id++) iwl_pcie_txq_unmap(trans, txq_id); @@ -656,7 +653,7 @@ void iwl_pcie_tx_free(struct iwl_trans *trans) /* Tx queues */ if (trans_pcie->txq_memory) { for (txq_id = 0; - txq_id < trans->trans_cfg->base_params->num_of_queues; + txq_id < trans->mac_cfg->base->num_of_queues; txq_id++) { iwl_pcie_txq_free(trans, txq_id); trans_pcie->txqs.txq[txq_id] = NULL; @@ -678,7 +675,7 @@ void iwl_txq_log_scd_error(struct iwl_trans *trans, struct iwl_txq *txq) bool active; u8 fifo; - if (trans->trans_cfg->gen2) { + if (trans->mac_cfg->gen2) { IWL_ERR(trans, "Queue %d is stuck %d %d\n", txq_id, txq->read_ptr, txq->write_ptr); /* TODO: access new SCD registers and dump them */ @@ -695,9 +692,9 @@ void iwl_txq_log_scd_error(struct iwl_trans *trans, struct iwl_txq *txq) jiffies_to_msecs(txq->wd_timeout), txq->read_ptr, txq->write_ptr, iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) & - (trans->trans_cfg->base_params->max_tfd_queue_size - 1), + (trans->mac_cfg->base->max_tfd_queue_size - 1), iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id)) & - (trans->trans_cfg->base_params->max_tfd_queue_size - 1), + (trans->mac_cfg->base->max_tfd_queue_size - 1), iwl_read_direct32(trans, FH_TX_TRB_REG(fifo))); } @@ -723,8 +720,8 @@ int iwl_pcie_txq_alloc(struct iwl_trans *trans, struct iwl_txq *txq, int slots_num, bool cmd_queue) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - size_t num_entries = trans->trans_cfg->gen2 ? - slots_num : trans->trans_cfg->base_params->max_tfd_queue_size; + size_t num_entries = trans->mac_cfg->gen2 ? + slots_num : trans->mac_cfg->base->max_tfd_queue_size; size_t tfd_sz; size_t tb0_buf_sz; int i; @@ -779,7 +776,7 @@ int iwl_pcie_txq_alloc(struct iwl_trans *trans, struct iwl_txq *txq, for (i = 0; i < num_entries; i++) { void *tfd = iwl_txq_get_tfd(trans, txq, i); - if (trans->trans_cfg->gen2) + if (trans->mac_cfg->gen2) iwl_txq_set_tfd_invalid_gen2(trans, tfd); else iwl_txq_set_tfd_invalid_gen1(trans, tfd); @@ -799,6 +796,8 @@ error: return -ENOMEM; } +#define BC_TABLE_SIZE (sizeof(struct iwl_bc_tbl_entry) * TFD_QUEUE_BC_SIZE) + /* * iwl_pcie_tx_alloc - allocate TX context * Allocate all Tx DMA structures and initialize them @@ -808,12 +807,12 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans) int ret; int txq_id, slots_num; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - u16 bc_tbls_size = trans->trans_cfg->base_params->num_of_queues; + u16 bc_tbls_size = trans->mac_cfg->base->num_of_queues; - if (WARN_ON(trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)) + if (WARN_ON(trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)) return -EINVAL; - bc_tbls_size *= sizeof(struct iwlagn_scd_bc_tbl); + bc_tbls_size *= BC_TABLE_SIZE; /*It is not allowed to alloc twice, so warn when this happens. * We cannot rely on the previous allocation, so free and fail */ @@ -837,7 +836,7 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans) } trans_pcie->txq_memory = - kcalloc(trans->trans_cfg->base_params->num_of_queues, + kcalloc(trans->mac_cfg->base->num_of_queues, sizeof(struct iwl_txq), GFP_KERNEL); if (!trans_pcie->txq_memory) { IWL_ERR(trans, "Not enough memory for txq\n"); @@ -846,16 +845,16 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans) } /* Alloc and init all Tx queues, including the command queue (#4/#9) */ - for (txq_id = 0; txq_id < trans->trans_cfg->base_params->num_of_queues; + for (txq_id = 0; txq_id < trans->mac_cfg->base->num_of_queues; txq_id++) { - bool cmd_queue = (txq_id == trans_pcie->txqs.cmd.q_id); + bool cmd_queue = (txq_id == trans->conf.cmd_queue); if (cmd_queue) slots_num = max_t(u32, IWL_CMD_QUEUE_SIZE, - trans->cfg->min_txq_size); + trans->mac_cfg->base->min_txq_size); else slots_num = max_t(u32, IWL_DEFAULT_QUEUE_SIZE, - trans->cfg->min_ba_txq_size); + trans->mac_cfg->base->min_ba_txq_size); trans_pcie->txqs.txq[txq_id] = &trans_pcie->txq_memory[txq_id]; ret = iwl_pcie_txq_alloc(trans, trans_pcie->txqs.txq[txq_id], slots_num, cmd_queue); @@ -905,7 +904,7 @@ int iwl_txq_init(struct iwl_trans *trans, struct iwl_txq *txq, int slots_num, bool cmd_queue) { u32 tfd_queue_max_size = - trans->trans_cfg->base_params->max_tfd_queue_size; + trans->mac_cfg->base->max_tfd_queue_size; int ret; txq->need_update = false; @@ -963,16 +962,16 @@ int iwl_pcie_tx_init(struct iwl_trans *trans) spin_unlock_bh(&trans_pcie->irq_lock); /* Alloc and init all Tx queues, including the command queue (#4/#9) */ - for (txq_id = 0; txq_id < trans->trans_cfg->base_params->num_of_queues; + for (txq_id = 0; txq_id < trans->mac_cfg->base->num_of_queues; txq_id++) { - bool cmd_queue = (txq_id == trans_pcie->txqs.cmd.q_id); + bool cmd_queue = (txq_id == trans->conf.cmd_queue); if (cmd_queue) slots_num = max_t(u32, IWL_CMD_QUEUE_SIZE, - trans->cfg->min_txq_size); + trans->mac_cfg->base->min_txq_size); else slots_num = max_t(u32, IWL_DEFAULT_QUEUE_SIZE, - trans->cfg->min_ba_txq_size); + trans->mac_cfg->base->min_ba_txq_size); ret = iwl_txq_init(trans, trans_pcie->txqs.txq[txq_id], slots_num, cmd_queue); if (ret) { @@ -991,7 +990,7 @@ int iwl_pcie_tx_init(struct iwl_trans *trans) } iwl_set_bits_prph(trans, SCD_GP_CTRL, SCD_GP_CTRL_AUTO_ACTIVE_MODE); - if (trans->trans_cfg->base_params->num_of_queues > 20) + if (trans->mac_cfg->base->num_of_queues > 20) iwl_set_bits_prph(trans, SCD_GP_CTRL, SCD_GP_CTRL_ENABLE_31_QUEUES); @@ -1012,7 +1011,7 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans, if (test_bit(STATUS_TRANS_DEAD, &trans->status)) return -ENODEV; - if (!trans->trans_cfg->base_params->apmg_wake_up_wa) + if (!trans->mac_cfg->base->apmg_wake_up_wa) return 0; /* @@ -1090,12 +1089,12 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx) idx = iwl_txq_get_cmd_index(txq, idx); r = iwl_txq_get_cmd_index(txq, txq->read_ptr); - if (idx >= trans->trans_cfg->base_params->max_tfd_queue_size || + if (idx >= trans->mac_cfg->base->max_tfd_queue_size || (!iwl_txq_used(txq, idx, txq->read_ptr, txq->write_ptr))) { WARN_ONCE(test_bit(txq_id, trans_pcie->txqs.queue_used), "%s: Read index for DMA queue txq id (%d), index %d is out of range [0-%d] %d %d.\n", __func__, txq_id, idx, - trans->trans_cfg->base_params->max_tfd_queue_size, + trans->mac_cfg->base->max_tfd_queue_size, txq->write_ptr, txq->read_ptr); return; } @@ -1164,15 +1163,15 @@ bool iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, fifo = cfg->fifo; /* Disable the scheduler prior configuring the cmd queue */ - if (txq_id == trans_pcie->txqs.cmd.q_id && - trans_pcie->scd_set_active) + if (txq_id == trans->conf.cmd_queue && + trans->conf.scd_set_active) iwl_scd_enable_set_active(trans, 0); /* Stop this Tx queue before configuring it */ iwl_scd_txq_set_inactive(trans, txq_id); /* Set this queue as a chain-building queue unless it is CMD */ - if (txq_id != trans_pcie->txqs.cmd.q_id) + if (txq_id != trans->conf.cmd_queue) iwl_scd_txq_set_chain(trans, txq_id); if (cfg->aggregate) { @@ -1206,7 +1205,7 @@ bool iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, * this sad hardware issue. * This bug has been fixed on devices 9000 and up. */ - scd_bug = !trans->trans_cfg->mq_rx_supported && + scd_bug = !trans->mac_cfg->mq_rx_supported && !((ssn - txq->write_ptr) & 0x3f) && (ssn != txq->write_ptr); if (scd_bug) @@ -1242,8 +1241,8 @@ bool iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, SCD_QUEUE_STTS_REG_MSK); /* enable the scheduler for this queue (only) */ - if (txq_id == trans_pcie->txqs.cmd.q_id && - trans_pcie->scd_set_active) + if (txq_id == trans->conf.cmd_queue && + trans->conf.scd_set_active) iwl_scd_enable_set_active(trans, BIT(txq_id)); IWL_DEBUG_TX_QUEUES(trans, @@ -1293,8 +1292,9 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id, if (configure_scd) { iwl_scd_txq_set_inactive(trans, txq_id); - iwl_trans_write_mem(trans, stts_addr, (const void *)zero_val, - ARRAY_SIZE(zero_val)); + iwl_trans_pcie_write_mem(trans, stts_addr, + (const void *)zero_val, + ARRAY_SIZE(zero_val)); } iwl_pcie_txq_unmap(trans, txq_id); @@ -1310,10 +1310,10 @@ static void iwl_trans_pcie_block_txq_ptrs(struct iwl_trans *trans, bool block) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int i; - for (i = 0; i < trans->trans_cfg->base_params->num_of_queues; i++) { + for (i = 0; i < trans->mac_cfg->base->num_of_queues; i++) { struct iwl_txq *txq = trans_pcie->txqs.txq[i]; - if (i == trans_pcie->txqs.cmd.q_id) + if (i == trans->conf.cmd_queue) continue; /* we skip the command queue (obviously) so it's OK to nest */ @@ -1346,7 +1346,7 @@ int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_txq *txq = trans_pcie->txqs.txq[trans_pcie->txqs.cmd.q_id]; + struct iwl_txq *txq = trans_pcie->txqs.txq[trans->conf.cmd_queue]; struct iwl_device_cmd *out_cmd; struct iwl_cmd_meta *out_meta; void *dup_buf = NULL; @@ -1361,7 +1361,7 @@ int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD]; unsigned long flags; - if (WARN(!trans->wide_cmd_header && + if (WARN(!trans->conf.wide_cmd_header && group_id > IWL_ALWAYS_LONG_GROUP, "unsupported wide command %#x\n", cmd->id)) return -EINVAL; @@ -1475,7 +1475,7 @@ int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, sizeof(struct iwl_cmd_header_wide)); out_cmd->hdr_wide.reserved = 0; out_cmd->hdr_wide.sequence = - cpu_to_le16(QUEUE_TO_SEQ(trans_pcie->txqs.cmd.q_id) | + cpu_to_le16(QUEUE_TO_SEQ(trans->conf.cmd_queue) | INDEX_TO_SEQ(txq->write_ptr)); cmd_pos = sizeof(struct iwl_cmd_header_wide); @@ -1483,7 +1483,7 @@ int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, } else { out_cmd->hdr.cmd = iwl_cmd_opcode(cmd->id); out_cmd->hdr.sequence = - cpu_to_le16(QUEUE_TO_SEQ(trans_pcie->txqs.cmd.q_id) | + cpu_to_le16(QUEUE_TO_SEQ(trans->conf.cmd_queue) | INDEX_TO_SEQ(txq->write_ptr)); out_cmd->hdr.group_id = 0; @@ -1534,7 +1534,7 @@ int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, iwl_get_cmd_string(trans, cmd->id), group_id, out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), - cmd_size, txq->write_ptr, idx, trans_pcie->txqs.cmd.q_id); + cmd_size, txq->write_ptr, idx, trans->conf.cmd_queue); /* start the TFD with the minimum copy bytes */ tb0_size = min_t(int, copy_size, IWL_FIRST_TB_SIZE); @@ -1633,14 +1633,14 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, struct iwl_device_cmd *cmd; struct iwl_cmd_meta *meta; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_txq *txq = trans_pcie->txqs.txq[trans_pcie->txqs.cmd.q_id]; + struct iwl_txq *txq = trans_pcie->txqs.txq[trans->conf.cmd_queue]; /* 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_pcie->txqs.cmd.q_id, + 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_pcie->txqs.cmd.q_id, sequence, txq->read_ptr, + txq_id, trans->conf.cmd_queue, sequence, txq->read_ptr, txq->write_ptr)) { iwl_print_hex_error(trans, pkt, 32); return; @@ -1654,7 +1654,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, group_id = cmd->hdr.group_id; cmd_id = WIDE_ID(group_id, cmd->hdr.cmd); - if (trans->trans_cfg->gen2) + if (trans->mac_cfg->gen2) iwl_txq_gen2_tfd_unmap(trans, meta, iwl_txq_get_tfd(trans, txq, index)); else @@ -1683,7 +1683,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status); IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", iwl_get_cmd_string(trans, cmd_id)); - wake_up(&trans->wait_command_queue); + wake_up(&trans_pcie->wait_command_queue); } meta->flags = 0; @@ -1753,7 +1753,7 @@ static void *iwl_pcie_get_page_hdr(struct iwl_trans *trans, dma_addr_t phys; void *ret; - page_ptr = (void *)((u8 *)skb->cb + trans_pcie->txqs.page_offs); + page_ptr = (void *)((u8 *)skb->cb + trans->conf.cb_data_offs); if (WARN_ON(*page_ptr)) return NULL; @@ -1912,7 +1912,7 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, u16 tb1_len) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_tx_cmd *tx_cmd = (void *)dev_cmd->payload; + struct iwl_tx_cmd_v6 *tx_cmd = (void *)dev_cmd->payload; struct ieee80211_hdr *hdr = (void *)skb->data; unsigned int snap_ip_tcp_hdrlen, ip_hdrlen, total_len, hdr_room; unsigned int mss = skb_shinfo(skb)->gso_size; @@ -2067,14 +2067,14 @@ static void iwl_txq_gen1_update_byte_cnt_tbl(struct iwl_trans *trans, int num_tbs) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwlagn_scd_bc_tbl *scd_bc_tbl; + struct iwl_bc_tbl_entry *scd_bc_tbl; int write_ptr = txq->write_ptr; int txq_id = txq->id; u8 sec_ctl = 0; u16 len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; __le16 bc_ent; struct iwl_device_tx_cmd *dev_cmd = txq->entries[txq->write_ptr].cmd; - struct iwl_tx_cmd *tx_cmd = (void *)dev_cmd->payload; + struct iwl_tx_cmd_v6 *tx_cmd = (void *)dev_cmd->payload; u8 sta_id = tx_cmd->sta_id; scd_bc_tbl = trans_pcie->txqs.scd_bc_tbls.addr; @@ -2092,7 +2092,8 @@ static void iwl_txq_gen1_update_byte_cnt_tbl(struct iwl_trans *trans, len += IEEE80211_WEP_IV_LEN + IEEE80211_WEP_ICV_LEN; break; } - if (trans_pcie->txqs.bc_table_dword) + + if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) len = DIV_ROUND_UP(len, 4); if (WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX)) @@ -2100,10 +2101,10 @@ static void iwl_txq_gen1_update_byte_cnt_tbl(struct iwl_trans *trans, bc_ent = cpu_to_le16(len | (sta_id << 12)); - scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent; + scd_bc_tbl[txq_id * BC_TABLE_SIZE + write_ptr].tfd_offset = bc_ent; if (write_ptr < TFD_QUEUE_SIZE_BC_DUP) - scd_bc_tbl[txq_id].tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = + scd_bc_tbl[txq_id * BC_TABLE_SIZE + TFD_QUEUE_SIZE_MAX + write_ptr].tfd_offset = bc_ent; } @@ -2112,7 +2113,7 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct ieee80211_hdr *hdr; - struct iwl_tx_cmd *tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload; + struct iwl_tx_cmd_v6 *tx_cmd = (struct iwl_tx_cmd_v6 *)dev_cmd->payload; struct iwl_cmd_meta *out_meta; struct iwl_txq *txq; dma_addr_t tb0_phys, tb1_phys, scratch_phys; @@ -2153,7 +2154,8 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_device_tx_cmd **dev_cmd_ptr; dev_cmd_ptr = (void *)((u8 *)skb->cb + - trans_pcie->txqs.dev_cmd_offs); + trans->conf.cb_data_offs + + sizeof(void *)); *dev_cmd_ptr = dev_cmd; __skb_queue_tail(&txq->overflow_q, skb); @@ -2184,7 +2186,7 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, tb0_phys = iwl_txq_get_first_tb_dma(txq, txq->write_ptr); scratch_phys = tb0_phys + sizeof(struct iwl_cmd_header) + - offsetof(struct iwl_tx_cmd, scratch); + offsetof(struct iwl_tx_cmd_v6, scratch); tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); @@ -2199,7 +2201,7 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, * (This calculation modifies the TX command, so do it before the * setup of the first TB) */ - len = sizeof(struct iwl_tx_cmd) + sizeof(struct iwl_cmd_header) + + len = sizeof(struct iwl_tx_cmd_v6) + sizeof(struct iwl_cmd_header) + hdr_len - IWL_FIRST_TB_SIZE; /* do not align A-MSDU to dword as the subframe header aligns it */ amsdu = ieee80211_is_data_qos(fc) && @@ -2222,9 +2224,9 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, IWL_FIRST_TB_SIZE, true); /* there must be data left over for TB1 or this code must be changed */ - BUILD_BUG_ON(sizeof(struct iwl_tx_cmd) < IWL_FIRST_TB_SIZE); + BUILD_BUG_ON(sizeof(struct iwl_tx_cmd_v6) < IWL_FIRST_TB_SIZE); BUILD_BUG_ON(sizeof(struct iwl_cmd_header) + - offsetofend(struct iwl_tx_cmd, scratch) > + offsetofend(struct iwl_tx_cmd_v6, scratch) > IWL_FIRST_TB_SIZE); /* map the data for TB1 */ @@ -2312,24 +2314,24 @@ static void iwl_txq_gen1_inval_byte_cnt_tbl(struct iwl_trans *trans, int read_ptr) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwlagn_scd_bc_tbl *scd_bc_tbl = trans_pcie->txqs.scd_bc_tbls.addr; + struct iwl_bc_tbl_entry *scd_bc_tbl = trans_pcie->txqs.scd_bc_tbls.addr; int txq_id = txq->id; u8 sta_id = 0; __le16 bc_ent; struct iwl_device_tx_cmd *dev_cmd = txq->entries[read_ptr].cmd; - struct iwl_tx_cmd *tx_cmd = (void *)dev_cmd->payload; + struct iwl_tx_cmd_v6 *tx_cmd = (void *)dev_cmd->payload; WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX); - if (txq_id != trans_pcie->txqs.cmd.q_id) + if (txq_id != trans->conf.cmd_queue) sta_id = tx_cmd->sta_id; bc_ent = cpu_to_le16(1 | (sta_id << 12)); - scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent; + scd_bc_tbl[txq_id * BC_TABLE_SIZE + read_ptr].tfd_offset = bc_ent; if (read_ptr < TFD_QUEUE_SIZE_BC_DUP) - scd_bc_tbl[txq_id].tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = + scd_bc_tbl[txq_id * BC_TABLE_SIZE + TFD_QUEUE_SIZE_MAX + read_ptr].tfd_offset = bc_ent; } @@ -2343,7 +2345,7 @@ void iwl_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, int txq_read_ptr, txq_write_ptr; /* This function is not meant to release cmd queue*/ - if (WARN_ON(txq_id == trans_pcie->txqs.cmd.q_id)) + if (WARN_ON(txq_id == trans->conf.cmd_queue)) return; if (WARN_ON(!txq)) @@ -2385,7 +2387,7 @@ void iwl_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, IWL_ERR(trans, "%s: Read index for txq id (%d), last_to_free %d is out of range [0-%d] %d %d.\n", __func__, txq_id, last_to_free, - trans->trans_cfg->base_params->max_tfd_queue_size, + trans->mac_cfg->base->max_tfd_queue_size, txq_write_ptr, txq_read_ptr); iwl_op_mode_time_point(trans->op_mode, @@ -2414,7 +2416,7 @@ void iwl_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, txq->entries[read_ptr].skb = NULL; - if (!trans->trans_cfg->gen2) + if (!trans->mac_cfg->gen2) iwl_txq_gen1_inval_byte_cnt_tbl(trans, txq, txq_read_ptr); @@ -2456,7 +2458,8 @@ void iwl_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, struct iwl_device_tx_cmd *dev_cmd_ptr; dev_cmd_ptr = *(void **)((u8 *)skb->cb + - trans_pcie->txqs.dev_cmd_offs); + trans->conf.cb_data_offs + + sizeof(void *)); /* * Note that we can very well be overflowing again. @@ -2548,11 +2551,11 @@ next_queue: #define HOST_COMPLETE_TIMEOUT (2 * HZ) static int iwl_trans_pcie_send_hcmd_sync(struct iwl_trans *trans, - struct iwl_host_cmd *cmd) + struct iwl_host_cmd *cmd, + const char *cmd_str) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - const char *cmd_str = iwl_get_cmd_string(trans, cmd->id); - struct iwl_txq *txq = trans_pcie->txqs.txq[trans_pcie->txqs.cmd.q_id]; + struct iwl_txq *txq = trans_pcie->txqs.txq[trans->conf.cmd_queue]; int cmd_idx; int ret; @@ -2565,7 +2568,7 @@ static int iwl_trans_pcie_send_hcmd_sync(struct iwl_trans *trans, IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", cmd_str); - if (trans->trans_cfg->gen2) + if (trans->mac_cfg->gen2) cmd_idx = iwl_pcie_gen2_enqueue_hcmd(trans, cmd); else cmd_idx = iwl_pcie_enqueue_hcmd(trans, cmd); @@ -2578,7 +2581,7 @@ static int iwl_trans_pcie_send_hcmd_sync(struct iwl_trans *trans, return ret; } - ret = wait_event_timeout(trans->wait_command_queue, + ret = wait_event_timeout(trans_pcie->wait_command_queue, !test_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status), HOST_COMPLETE_TIMEOUT); @@ -2594,7 +2597,7 @@ static int iwl_trans_pcie_send_hcmd_sync(struct iwl_trans *trans, cmd_str); ret = -ETIMEDOUT; - iwl_trans_sync_nmi(trans); + iwl_trans_pcie_sync_nmi(trans); goto cancel; } @@ -2645,6 +2648,8 @@ cancel: int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) { + const char *cmd_str = iwl_get_cmd_string(trans, cmd->id); + /* Make sure the NIC is still alive in the bus */ if (test_bit(STATUS_TRANS_DEAD, &trans->status)) return -ENODEV; @@ -2656,20 +2661,16 @@ int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, return -ERFKILL; } - if (unlikely(trans->system_pm_mode == IWL_PLAT_PM_MODE_D3 && - !(cmd->flags & CMD_SEND_IN_D3))) { - IWL_DEBUG_WOWLAN(trans, "Dropping CMD 0x%x: D3\n", cmd->id); - return -EHOSTDOWN; - } - if (cmd->flags & CMD_ASYNC) { int ret; + IWL_DEBUG_INFO(trans, "Sending async command %s\n", cmd_str); + /* An asynchronous command can not expect an SKB to be set. */ if (WARN_ON(cmd->flags & CMD_WANT_SKB)) return -EINVAL; - if (trans->trans_cfg->gen2) + if (trans->mac_cfg->gen2) ret = iwl_pcie_gen2_enqueue_hcmd(trans, cmd); else ret = iwl_pcie_enqueue_hcmd(trans, cmd); @@ -2683,6 +2684,5 @@ int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, return 0; } - return iwl_trans_pcie_send_hcmd_sync(trans, cmd); + return iwl_trans_pcie_send_hcmd_sync(trans, cmd, cmd_str); } -IWL_EXPORT_SYMBOL(iwl_trans_pcie_send_hcmd); diff --git a/drivers/net/wireless/intel/iwlwifi/tests/devinfo.c b/drivers/net/wireless/intel/iwlwifi/tests/devinfo.c index d0bda23c628a..784433bb246a 100644 --- a/drivers/net/wireless/intel/iwlwifi/tests/devinfo.c +++ b/drivers/net/wireless/intel/iwlwifi/tests/devinfo.c @@ -2,7 +2,7 @@ /* * KUnit tests for the iwlwifi device info table * - * Copyright (C) 2023-2024 Intel Corporation + * Copyright (C) 2023-2025 Intel Corporation */ #include <kunit/test.h> #include <linux/pci.h> @@ -13,10 +13,50 @@ MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); static void iwl_pci_print_dev_info(const char *pfx, const struct iwl_dev_info *di) { - printk(KERN_DEBUG "%sdev=%.4x,subdev=%.4x,mac_type=%.4x,mac_step=%.4x,rf_type=%.4x,cdb=%d,jacket=%d,rf_id=%.2x,no_160=%d,cores=%.2x\n", - pfx, di->device, di->subdevice, di->mac_type, di->mac_step, - di->rf_type, di->cdb, di->jacket, di->rf_id, di->no_160, - di->cores); + u16 subdevice_mask = GENMASK(di->subdevice_m_h, di->subdevice_m_l); + char buf[100] = {}; + int pos = 0; + + if (di->match_rf_type) + pos += scnprintf(buf + pos, sizeof(buf) - pos, + " rf_type=%03x", di->rf_type); + else + pos += scnprintf(buf + pos, sizeof(buf) - pos, + " rf_type=*"); + + if (di->match_bw_limit) + pos += scnprintf(buf + pos, sizeof(buf) - pos, + " bw_limit=%d", di->bw_limit); + else + pos += scnprintf(buf + pos, sizeof(buf) - pos, + " bw_limit=*"); + + if (di->match_rf_step) + pos += scnprintf(buf + pos, sizeof(buf) - pos, + " rf_step=%c", + di->rf_step == SILICON_Z_STEP ? 'Z' : + 'A' + di->rf_step); + else + pos += scnprintf(buf + pos, sizeof(buf) - pos, + " rf_step=*"); + + if (di->match_rf_id) + pos += scnprintf(buf + pos, sizeof(buf) - pos, + " rf_id=0x%x", di->rf_id); + else + pos += scnprintf(buf + pos, sizeof(buf) - pos, + " rf_id=*"); + + if (di->match_cdb) + pos += scnprintf(buf + pos, sizeof(buf) - pos, + " cdb=%d", di->cdb); + else + pos += scnprintf(buf + pos, sizeof(buf) - pos, + " cdb=*"); + + + printk(KERN_DEBUG "%sdev=%04x subdev=%04x/%04x%s\n", + pfx, di->device, di->subdevice, subdevice_mask, buf); } static void devinfo_table_order(struct kunit *test) @@ -28,11 +68,14 @@ static void devinfo_table_order(struct kunit *test) const struct iwl_dev_info *ret; ret = iwl_pci_find_dev_info(di->device, di->subdevice, - di->mac_type, di->mac_step, di->rf_type, di->cdb, - di->jacket, di->rf_id, - di->no_160, di->cores, di->rf_step); - if (ret != di) { + di->rf_id, di->bw_limit, + di->rf_step); + if (!ret) { + iwl_pci_print_dev_info("No entry found for: ", di); + KUNIT_FAIL(test, + "No entry found for entry at index %d\n", idx); + } else if (ret != di) { iwl_pci_print_dev_info("searched: ", di); iwl_pci_print_dev_info("found: ", ret); KUNIT_FAIL(test, @@ -42,6 +85,92 @@ static void devinfo_table_order(struct kunit *test) } } +static void devinfo_names(struct kunit *test) +{ + int idx; + + for (idx = 0; idx < iwl_dev_info_table_size; idx++) { + const struct iwl_dev_info *di = &iwl_dev_info_table[idx]; + + KUNIT_ASSERT_TRUE(test, di->name); + } +} + +static void devinfo_no_cfg_dups(struct kunit *test) +{ + for (int i = 0; i < iwl_dev_info_table_size; i++) { + const struct iwl_rf_cfg *cfg_i = iwl_dev_info_table[i].cfg; + + for (int j = 0; j < i; j++) { + const struct iwl_rf_cfg *cfg_j = iwl_dev_info_table[j].cfg; + + if (cfg_i == cfg_j) + continue; + + KUNIT_EXPECT_NE_MSG(test, memcmp(cfg_i, cfg_j, + sizeof(*cfg_i)), 0, + "identical configs: %ps and %ps\n", + cfg_i, cfg_j); + } + } +} + +static void devinfo_no_name_dups(struct kunit *test) +{ + for (int i = 0; i < iwl_dev_info_table_size; i++) { + for (int j = 0; j < i; j++) { + if (iwl_dev_info_table[i].name == iwl_dev_info_table[j].name) + continue; + + KUNIT_EXPECT_NE_MSG(test, + strcmp(iwl_dev_info_table[i].name, + iwl_dev_info_table[j].name), + 0, + "name dup: %ps/%ps", + iwl_dev_info_table[i].name, + iwl_dev_info_table[j].name); + } + } +} + +static void devinfo_check_subdev_match(struct kunit *test) +{ + for (int i = 0; i < iwl_dev_info_table_size; i++) { + const struct iwl_dev_info *di = &iwl_dev_info_table[i]; + u16 subdevice_mask = GENMASK(di->subdevice_m_h, + di->subdevice_m_l); + + /* if BW limit bit is matched then must have a limit */ + if (di->match_bw_limit == 1 && di->bw_limit == 1) + KUNIT_EXPECT_NE(test, di->cfg->bw_limit, 0); + + /* if subdevice is ANY we can have RF ID/BW limit */ + if (di->subdevice == (u16)IWL_CFG_ANY) + continue; + + /* same if the subdevice mask doesn't overlap them */ + if (IWL_SUBDEVICE_RF_ID(subdevice_mask) == 0 && + IWL_SUBDEVICE_BW_LIM(subdevice_mask) == 0) + continue; + + /* but otherwise they shouldn't be used */ + KUNIT_EXPECT_EQ(test, (int)di->match_rf_id, 0); + KUNIT_EXPECT_EQ(test, (int)di->match_bw_limit, 0); + } +} + +static void devinfo_check_killer_subdev(struct kunit *test) +{ + for (int i = 0; i < iwl_dev_info_table_size; i++) { + const struct iwl_dev_info *di = &iwl_dev_info_table[i]; + + if (!strstr(di->name, "Killer")) + continue; + + KUNIT_EXPECT_NE(test, di->subdevice, (u16)IWL_CFG_ANY); + } +} + static void devinfo_pci_ids(struct kunit *test) { struct pci_dev *dev; @@ -64,9 +193,36 @@ static void devinfo_pci_ids(struct kunit *test) } } +static void devinfo_no_mac_cfg_dups(struct kunit *test) +{ + for (int i = 0; iwl_hw_card_ids[i].vendor; i++) { + const struct iwl_mac_cfg *cfg_i = + (void *)iwl_hw_card_ids[i].driver_data; + + for (int j = 0; j < i; j++) { + const struct iwl_mac_cfg *cfg_j = + (void *)iwl_hw_card_ids[j].driver_data; + + if (cfg_i == cfg_j) + continue; + + KUNIT_EXPECT_NE_MSG(test, memcmp(cfg_j, cfg_i, + sizeof(*cfg_i)), 0, + "identical configs: %ps and %ps\n", + cfg_i, cfg_j); + } + } +} + static struct kunit_case devinfo_test_cases[] = { KUNIT_CASE(devinfo_table_order), + KUNIT_CASE(devinfo_names), + KUNIT_CASE(devinfo_no_cfg_dups), + KUNIT_CASE(devinfo_no_name_dups), + KUNIT_CASE(devinfo_check_subdev_match), + KUNIT_CASE(devinfo_check_killer_subdev), KUNIT_CASE(devinfo_pci_ids), + KUNIT_CASE(devinfo_no_mac_cfg_dups), {} }; |