mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-16 23:26:42 +07:00
Patches intended for v5.4
* Remove (broken) d0i3 support; * Debug infrastructure work continues; * Bump support FW API version to 50; * Fix for the SN value in certain suspend/resume situations; * Some work on new FW scan APIs; * Work on LTR FW APIs; * New FW channel-switch support; * Support new ACPI value for per-platform antenna gain; * Support for single antenna diversity; * Support for new WoWLAN FW API; * Initial refactoring of the device selection code; * A bunch of clean-ups; * Other small fixes and improvements; -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEF3LNfgb2BPWm68smoUecoho8xfoFAl1yXFYACgkQoUecoho8 xfr1og/8C2CYJ7dDg/uWBUHu1L8YvukNf4/DoMkrioJ5dVBKt37v+LDqSRTssnvm m9kbeEwu7nyNaX1YRLnK16lwthaOlIUcp7cnmJWF6JaIFmZeGFN8mdV2ccEKFJnk iAoWrlXWcHQ4NI6e5gw+JzunxSa86czV/jl7JETLxMu8y3FH5dg3sEIVjc4uIyq1 u91SPwxF+hUIlP5UAYvBJSzBLug3o/Fn6kMXiGG+spf2gAWVfYgQm8YIV9aJ+nb+ +R2BKNFzuMa76Y5VeacV+DUqNQ5sPvr3Q8Ftagkg3g0w0aKJcMlZ9tJCZhNCo+HK Fja6oQODsG2pVkYnPTDc4VZ3PHigebsCztiX2oNIReSSrTPAJMH2+LTp7KWY0j1h a5hzQWf2OLRVFRbPTW6cgT2Fd+v2ywG4HnAHIRtkiCl8L/118AK42zBVxbzaSk3r aq2/LfDVQ1fe9Rp6T+ZsSckc1Y2loEW3zAu9obiERw6//WS3DuWbGotBbsoDo29C cD8kSGuoeaDl4T/J44tGWfubbTRuii061/zkNtX5cHPhYs6Kc1U5Lyuoq+2yqbBR tCATJFFnGT61Z3h4691Mp38teMzhkdv9LneIuy5gkSIPaDVk6NG2usfH1OTuaECK kuaK8KvGUD3bdwoxudkl1owpncYTXWBVnDBA6GV4CVavU48PLjg= =1L5G -----END PGP SIGNATURE----- Merge tag 'iwlwifi-next-for-kalle-2019-09-06' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next Patches intended for v5.4 * Remove (broken) d0i3 support; * Debug infrastructure work continues; * Bump support FW API version to 50; * Fix for the SN value in certain suspend/resume situations; * Some work on new FW scan APIs; * Work on LTR FW APIs; * New FW channel-switch support; * Support new ACPI value for per-platform antenna gain; * Support for single antenna diversity; * Support for new WoWLAN FW API; * Initial refactoring of the device selection code; * A bunch of clean-ups; * Other small fixes and improvements;
This commit is contained in:
commit
67e974c3ae
@ -92,20 +92,6 @@ config IWLWIFI_BCAST_FILTERING
|
||||
If unsure, don't enable this option, as some programs might
|
||||
expect incoming broadcasts for their normal operations.
|
||||
|
||||
config IWLWIFI_PCIE_RTPM
|
||||
bool "Enable runtime power management mode for PCIe devices"
|
||||
depends on IWLMVM && PM && EXPERT
|
||||
help
|
||||
Say Y here to enable runtime power management for PCIe
|
||||
devices. If enabled, the device will go into low power mode
|
||||
when idle for a short period of time, allowing for improved
|
||||
power saving during runtime. Note that this feature requires
|
||||
a tight integration with the platform. It is not recommended
|
||||
to enable this feature without proper validation with the
|
||||
specific target platform.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
menu "Debugging Options"
|
||||
|
||||
config IWLWIFI_DEBUG
|
||||
|
@ -2,7 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
@ -69,16 +69,16 @@ static const struct iwl_eeprom_params iwl1000_eeprom_params = {
|
||||
.fw_name_pre = IWL1000_FW_PRE, \
|
||||
.ucode_api_max = IWL1000_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL1000_UCODE_API_MIN, \
|
||||
.device_family = IWL_DEVICE_FAMILY_1000, \
|
||||
.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, \
|
||||
.base_params = &iwl1000_base_params, \
|
||||
.trans.base_params = &iwl1000_base_params, \
|
||||
.eeprom_params = &iwl1000_eeprom_params, \
|
||||
.led_mode = IWL_LED_BLINK, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.csr = &iwl_csr_v1
|
||||
.trans.csr = &iwl_csr_v1
|
||||
|
||||
const struct iwl_cfg iwl1000_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 1000 BGN",
|
||||
@ -95,17 +95,17 @@ const struct iwl_cfg iwl1000_bg_cfg = {
|
||||
.fw_name_pre = IWL100_FW_PRE, \
|
||||
.ucode_api_max = IWL100_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL100_UCODE_API_MIN, \
|
||||
.device_family = IWL_DEVICE_FAMILY_100, \
|
||||
.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, \
|
||||
.base_params = &iwl1000_base_params, \
|
||||
.trans.base_params = &iwl1000_base_params, \
|
||||
.eeprom_params = &iwl1000_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.rx_with_siso_diversity = true, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.csr = &iwl_csr_v1
|
||||
.trans.csr = &iwl_csr_v1
|
||||
|
||||
const struct iwl_cfg iwl100_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 100 BGN",
|
||||
|
@ -2,7 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
@ -95,16 +95,16 @@ static const struct iwl_eeprom_params iwl20x0_eeprom_params = {
|
||||
.fw_name_pre = IWL2000_FW_PRE, \
|
||||
.ucode_api_max = IWL2000_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL2000_UCODE_API_MIN, \
|
||||
.device_family = IWL_DEVICE_FAMILY_2000, \
|
||||
.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, \
|
||||
.base_params = &iwl2000_base_params, \
|
||||
.trans.base_params = &iwl2000_base_params, \
|
||||
.eeprom_params = &iwl20x0_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.csr = &iwl_csr_v1
|
||||
.trans.csr = &iwl_csr_v1
|
||||
|
||||
|
||||
const struct iwl_cfg iwl2000_2bgn_cfg = {
|
||||
@ -123,16 +123,16 @@ const struct iwl_cfg iwl2000_2bgn_d_cfg = {
|
||||
.fw_name_pre = IWL2030_FW_PRE, \
|
||||
.ucode_api_max = IWL2030_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL2030_UCODE_API_MIN, \
|
||||
.device_family = IWL_DEVICE_FAMILY_2030, \
|
||||
.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, \
|
||||
.base_params = &iwl2030_base_params, \
|
||||
.trans.base_params = &iwl2030_base_params, \
|
||||
.eeprom_params = &iwl20x0_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.csr = &iwl_csr_v1
|
||||
.trans.csr = &iwl_csr_v1
|
||||
|
||||
const struct iwl_cfg iwl2030_2bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 2230 BGN",
|
||||
@ -144,17 +144,17 @@ const struct iwl_cfg iwl2030_2bgn_cfg = {
|
||||
.fw_name_pre = IWL105_FW_PRE, \
|
||||
.ucode_api_max = IWL105_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL105_UCODE_API_MIN, \
|
||||
.device_family = IWL_DEVICE_FAMILY_105, \
|
||||
.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, \
|
||||
.base_params = &iwl2000_base_params, \
|
||||
.trans.base_params = &iwl2000_base_params, \
|
||||
.eeprom_params = &iwl20x0_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.rx_with_siso_diversity = true, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.csr = &iwl_csr_v1
|
||||
.trans.csr = &iwl_csr_v1
|
||||
|
||||
const struct iwl_cfg iwl105_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 105 BGN",
|
||||
@ -172,17 +172,17 @@ const struct iwl_cfg iwl105_bgn_d_cfg = {
|
||||
.fw_name_pre = IWL135_FW_PRE, \
|
||||
.ucode_api_max = IWL135_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL135_UCODE_API_MIN, \
|
||||
.device_family = IWL_DEVICE_FAMILY_135, \
|
||||
.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, \
|
||||
.base_params = &iwl2030_base_params, \
|
||||
.trans.base_params = &iwl2030_base_params, \
|
||||
.eeprom_params = &iwl20x0_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.rx_with_siso_diversity = true, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.csr = &iwl_csr_v1
|
||||
.trans.csr = &iwl_csr_v1
|
||||
|
||||
const struct iwl_cfg iwl135_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 135 BGN",
|
||||
|
@ -56,7 +56,7 @@
|
||||
#include "iwl-config.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL_22000_UCODE_API_MAX 48
|
||||
#define IWL_22000_UCODE_API_MAX 50
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_22000_UCODE_API_MIN 39
|
||||
@ -76,7 +76,6 @@
|
||||
#define IWL_22000_HR_FW_PRE "iwlwifi-Qu-a0-hr-a0-"
|
||||
#define IWL_22000_HR_CDB_FW_PRE "iwlwifi-QuIcp-z0-hrcdb-a0-"
|
||||
#define IWL_22000_HR_A_F0_FW_PRE "iwlwifi-QuQnj-f0-hr-a0-"
|
||||
#define IWL_22000_HR_B_F0_FW_PRE "iwlwifi-Qu-b0-hr-b0-"
|
||||
#define IWL_22000_QU_B_HR_B_FW_PRE "iwlwifi-Qu-b0-hr-b0-"
|
||||
#define IWL_22000_HR_B_FW_PRE "iwlwifi-QuQnj-b0-hr-b0-"
|
||||
#define IWL_22000_HR_A0_FW_PRE "iwlwifi-QuQnj-a0-hr-a0-"
|
||||
@ -99,8 +98,6 @@
|
||||
IWL_22000_JF_FW_PRE __stringify(api) ".ucode"
|
||||
#define IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(api) \
|
||||
IWL_22000_HR_A_F0_FW_PRE __stringify(api) ".ucode"
|
||||
#define IWL_22000_HR_B_F0_QNJ_MODULE_FIRMWARE(api) \
|
||||
IWL_22000_HR_B_F0_FW_PRE __stringify(api) ".ucode"
|
||||
#define IWL_22000_QU_B_HR_B_MODULE_FIRMWARE(api) \
|
||||
IWL_22000_QU_B_HR_B_FW_PRE __stringify(api) ".ucode"
|
||||
#define IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(api) \
|
||||
@ -172,15 +169,15 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
|
||||
.smem_len = IWL_22000_SMEM_LEN, \
|
||||
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \
|
||||
.apmg_not_supported = true, \
|
||||
.mq_rx_supported = true, \
|
||||
.trans.mq_rx_supported = true, \
|
||||
.vht_mu_mimo_supported = true, \
|
||||
.mac_addr_from_csr = true, \
|
||||
.ht_params = &iwl_22000_ht_params, \
|
||||
.nvm_ver = IWL_22000_NVM_VERSION, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.use_tfh = true, \
|
||||
.rf_id = true, \
|
||||
.gen2 = true, \
|
||||
.trans.use_tfh = true, \
|
||||
.trans.rf_id = true, \
|
||||
.trans.gen2 = true, \
|
||||
.nvm_type = IWL_NVM_EXT, \
|
||||
.dbgc_supported = true, \
|
||||
.min_umac_error_event_table = 0x400000, \
|
||||
@ -191,28 +188,25 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
|
||||
.fw_mon_smem_cycle_cnt_ptr_addr = 0xa0c174, \
|
||||
.fw_mon_smem_cycle_cnt_ptr_msk = 0xfffff
|
||||
|
||||
#define IWL_DEVICE_AX200_COMMON \
|
||||
IWL_DEVICE_22000_COMMON, \
|
||||
.umac_prph_offset = 0x300000
|
||||
|
||||
#define IWL_DEVICE_22500 \
|
||||
IWL_DEVICE_22000_COMMON, \
|
||||
.device_family = IWL_DEVICE_FAMILY_22000, \
|
||||
.base_params = &iwl_22000_base_params, \
|
||||
.csr = &iwl_csr_v1, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_22000, \
|
||||
.trans.base_params = &iwl_22000_base_params, \
|
||||
.trans.csr = &iwl_csr_v1, \
|
||||
.gp2_reg_addr = 0xa02c68
|
||||
|
||||
#define IWL_DEVICE_22560 \
|
||||
IWL_DEVICE_22000_COMMON, \
|
||||
.device_family = IWL_DEVICE_FAMILY_22560, \
|
||||
.base_params = &iwl_22560_base_params, \
|
||||
.csr = &iwl_csr_v2
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_22560, \
|
||||
.trans.base_params = &iwl_22560_base_params, \
|
||||
.trans.csr = &iwl_csr_v2
|
||||
|
||||
#define IWL_DEVICE_AX210 \
|
||||
IWL_DEVICE_AX200_COMMON, \
|
||||
.device_family = IWL_DEVICE_FAMILY_AX210, \
|
||||
.base_params = &iwl_22560_base_params, \
|
||||
.csr = &iwl_csr_v1, \
|
||||
IWL_DEVICE_22000_COMMON, \
|
||||
.trans.umac_prph_offset = 0x300000, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_AX210, \
|
||||
.trans.base_params = &iwl_22560_base_params, \
|
||||
.trans.csr = &iwl_csr_v1, \
|
||||
.min_txq_size = 128, \
|
||||
.gp2_reg_addr = 0xd02c68, \
|
||||
.min_256_ba_txq_size = 512
|
||||
@ -246,6 +240,7 @@ const struct iwl_cfg iwl_ax101_cfg_qu_hr = {
|
||||
* 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,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl_ax201_cfg_qu_hr = {
|
||||
@ -342,7 +337,7 @@ const struct iwl_cfg iwl_ax200_cfg_cc = {
|
||||
* HT size; mac80211 would otherwise pick the HE max (256) by default.
|
||||
*/
|
||||
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
|
||||
.bisr_workaround = 1,
|
||||
.trans.bisr_workaround = 1,
|
||||
};
|
||||
|
||||
const struct iwl_cfg killer1650x_2ax_cfg = {
|
||||
@ -355,7 +350,7 @@ const struct iwl_cfg killer1650x_2ax_cfg = {
|
||||
* HT size; mac80211 would otherwise pick the HE max (256) by default.
|
||||
*/
|
||||
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
|
||||
.bisr_workaround = 1,
|
||||
.trans.bisr_workaround = 1,
|
||||
};
|
||||
|
||||
const struct iwl_cfg killer1650w_2ax_cfg = {
|
||||
@ -368,7 +363,7 @@ const struct iwl_cfg killer1650w_2ax_cfg = {
|
||||
* HT size; mac80211 would otherwise pick the HE max (256) by default.
|
||||
*/
|
||||
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
|
||||
.bisr_workaround = 1,
|
||||
.trans.bisr_workaround = 1,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -663,7 +658,6 @@ const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0 = {
|
||||
MODULE_FIRMWARE(IWL_22000_HR_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_22000_JF_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_22000_HR_B_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
|
||||
|
@ -67,16 +67,16 @@ static const struct iwl_eeprom_params iwl5000_eeprom_params = {
|
||||
.fw_name_pre = IWL5000_FW_PRE, \
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN, \
|
||||
.device_family = IWL_DEVICE_FAMILY_5000, \
|
||||
.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, \
|
||||
.base_params = &iwl5000_base_params, \
|
||||
.trans.base_params = &iwl5000_base_params, \
|
||||
.eeprom_params = &iwl5000_eeprom_params, \
|
||||
.led_mode = IWL_LED_BLINK, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.csr = &iwl_csr_v1
|
||||
.trans.csr = &iwl_csr_v1
|
||||
|
||||
const struct iwl_cfg iwl5300_agn_cfg = {
|
||||
.name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
|
||||
@ -115,34 +115,34 @@ const struct iwl_cfg iwl5350_agn_cfg = {
|
||||
.fw_name_pre = IWL5000_FW_PRE,
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN,
|
||||
.device_family = IWL_DEVICE_FAMILY_5000,
|
||||
.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,
|
||||
.base_params = &iwl5000_base_params,
|
||||
.trans.base_params = &iwl5000_base_params,
|
||||
.eeprom_params = &iwl5000_eeprom_params,
|
||||
.ht_params = &iwl5000_ht_params,
|
||||
.led_mode = IWL_LED_BLINK,
|
||||
.internal_wimax_coex = true,
|
||||
.csr = &iwl_csr_v1,
|
||||
.trans.csr = &iwl_csr_v1,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_5150 \
|
||||
.fw_name_pre = IWL5150_FW_PRE, \
|
||||
.ucode_api_max = IWL5150_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL5150_UCODE_API_MIN, \
|
||||
.device_family = IWL_DEVICE_FAMILY_5150, \
|
||||
.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, \
|
||||
.base_params = &iwl5000_base_params, \
|
||||
.trans.base_params = &iwl5000_base_params, \
|
||||
.eeprom_params = &iwl5000_eeprom_params, \
|
||||
.led_mode = IWL_LED_BLINK, \
|
||||
.internal_wimax_coex = true, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.csr = &iwl_csr_v1
|
||||
.trans.csr = &iwl_csr_v1
|
||||
|
||||
const struct iwl_cfg iwl5150_agn_cfg = {
|
||||
.name = "Intel(R) WiMAX/WiFi Link 5150 AGN",
|
||||
|
@ -2,7 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
@ -116,16 +116,16 @@ static const struct iwl_eeprom_params iwl6000_eeprom_params = {
|
||||
.fw_name_pre = IWL6005_FW_PRE, \
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN, \
|
||||
.device_family = IWL_DEVICE_FAMILY_6005, \
|
||||
.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, \
|
||||
.base_params = &iwl6000_g2_base_params, \
|
||||
.trans.base_params = &iwl6000_g2_base_params, \
|
||||
.eeprom_params = &iwl6000_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.csr = &iwl_csr_v1
|
||||
.trans.csr = &iwl_csr_v1
|
||||
|
||||
const struct iwl_cfg iwl6005_2agn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6205 AGN",
|
||||
@ -171,16 +171,16 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = {
|
||||
.fw_name_pre = IWL6030_FW_PRE, \
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN, \
|
||||
.device_family = IWL_DEVICE_FAMILY_6030, \
|
||||
.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, \
|
||||
.base_params = &iwl6000_g2_base_params, \
|
||||
.trans.base_params = &iwl6000_g2_base_params, \
|
||||
.eeprom_params = &iwl6000_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.csr = &iwl_csr_v1
|
||||
.trans.csr = &iwl_csr_v1
|
||||
|
||||
const struct iwl_cfg iwl6030_2agn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6230 AGN",
|
||||
@ -208,16 +208,16 @@ const struct iwl_cfg iwl6030_2bg_cfg = {
|
||||
.fw_name_pre = IWL6030_FW_PRE, \
|
||||
.ucode_api_max = IWL6035_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL6035_UCODE_API_MIN, \
|
||||
.device_family = IWL_DEVICE_FAMILY_6030, \
|
||||
.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, \
|
||||
.base_params = &iwl6000_g2_base_params, \
|
||||
.trans.base_params = &iwl6000_g2_base_params, \
|
||||
.eeprom_params = &iwl6000_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.csr = &iwl_csr_v1
|
||||
.trans.csr = &iwl_csr_v1
|
||||
|
||||
const struct iwl_cfg iwl6035_2agn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6235 AGN",
|
||||
@ -262,18 +262,18 @@ 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, \
|
||||
.device_family = IWL_DEVICE_FAMILY_6000i, \
|
||||
.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, \
|
||||
.base_params = &iwl6000_base_params, \
|
||||
.trans.base_params = &iwl6000_base_params, \
|
||||
.eeprom_params = &iwl6000_eeprom_params, \
|
||||
.led_mode = IWL_LED_BLINK, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.csr = &iwl_csr_v1
|
||||
.trans.csr = &iwl_csr_v1
|
||||
|
||||
const struct iwl_cfg iwl6000i_2agn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6200 AGN",
|
||||
@ -295,19 +295,19 @@ const struct iwl_cfg iwl6000i_2bg_cfg = {
|
||||
.fw_name_pre = IWL6050_FW_PRE, \
|
||||
.ucode_api_max = IWL6050_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL6050_UCODE_API_MIN, \
|
||||
.device_family = IWL_DEVICE_FAMILY_6050, \
|
||||
.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, \
|
||||
.base_params = &iwl6050_base_params, \
|
||||
.trans.base_params = &iwl6050_base_params, \
|
||||
.eeprom_params = &iwl6000_eeprom_params, \
|
||||
.led_mode = IWL_LED_BLINK, \
|
||||
.internal_wimax_coex = true, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.csr = &iwl_csr_v1
|
||||
.trans.csr = &iwl_csr_v1
|
||||
|
||||
const struct iwl_cfg iwl6050_2agn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN",
|
||||
@ -324,17 +324,17 @@ const struct iwl_cfg iwl6050_2abg_cfg = {
|
||||
.fw_name_pre = IWL6050_FW_PRE, \
|
||||
.ucode_api_max = IWL6050_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL6050_UCODE_API_MIN, \
|
||||
.device_family = IWL_DEVICE_FAMILY_6150, \
|
||||
.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, \
|
||||
.base_params = &iwl6050_base_params, \
|
||||
.trans.base_params = &iwl6050_base_params, \
|
||||
.eeprom_params = &iwl6000_eeprom_params, \
|
||||
.led_mode = IWL_LED_BLINK, \
|
||||
.internal_wimax_coex = true, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.csr = &iwl_csr_v1
|
||||
.trans.csr = &iwl_csr_v1
|
||||
|
||||
const struct iwl_cfg iwl6150_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN",
|
||||
@ -352,16 +352,16 @@ const struct iwl_cfg iwl6000_3agn_cfg = {
|
||||
.fw_name_pre = IWL6000_FW_PRE,
|
||||
.ucode_api_max = IWL6000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000_UCODE_API_MIN,
|
||||
.device_family = IWL_DEVICE_FAMILY_6000,
|
||||
.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,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.trans.base_params = &iwl6000_base_params,
|
||||
.eeprom_params = &iwl6000_eeprom_params,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.led_mode = IWL_LED_BLINK,
|
||||
.csr = &iwl_csr_v1,
|
||||
.trans.csr = &iwl_csr_v1,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -31,7 +31,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -148,14 +148,14 @@ static const struct iwl_ht_params iwl7000_ht_params = {
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_7000_COMMON \
|
||||
.device_family = IWL_DEVICE_FAMILY_7000, \
|
||||
.base_params = &iwl7000_base_params, \
|
||||
.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, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.dccm_offset = IWL7000_DCCM_OFFSET, \
|
||||
.csr = &iwl_csr_v1
|
||||
.trans.csr = &iwl_csr_v1
|
||||
|
||||
#define IWL_DEVICE_7000 \
|
||||
IWL_DEVICE_7000_COMMON, \
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Copyright(c) 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -30,7 +30,7 @@
|
||||
*
|
||||
* Copyright(c) 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -134,8 +134,8 @@ static const struct iwl_tt_params iwl8000_tt_params = {
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_8000_COMMON \
|
||||
.device_family = IWL_DEVICE_FAMILY_8000, \
|
||||
.base_params = &iwl8000_base_params, \
|
||||
.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, \
|
||||
@ -152,7 +152,7 @@ static const struct iwl_tt_params iwl8000_tt_params = {
|
||||
.nvm_type = IWL_NVM_EXT, \
|
||||
.dbgc_supported = true, \
|
||||
.min_umac_error_event_table = 0x800000, \
|
||||
.csr = &iwl_csr_v1
|
||||
.trans.csr = &iwl_csr_v1
|
||||
|
||||
#define IWL_DEVICE_8000 \
|
||||
IWL_DEVICE_8000_COMMON, \
|
||||
|
@ -122,8 +122,8 @@ static const struct iwl_tt_params iwl9000_tt_params = {
|
||||
#define IWL_DEVICE_9000 \
|
||||
.ucode_api_max = IWL9000_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL9000_UCODE_API_MIN, \
|
||||
.device_family = IWL_DEVICE_FAMILY_9000, \
|
||||
.base_params = &iwl9000_base_params, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_9000, \
|
||||
.trans.base_params = &iwl9000_base_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = 10, \
|
||||
.non_shared_ant = ANT_B, \
|
||||
@ -136,14 +136,14 @@ static const struct iwl_tt_params iwl9000_tt_params = {
|
||||
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \
|
||||
.thermal_params = &iwl9000_tt_params, \
|
||||
.apmg_not_supported = true, \
|
||||
.mq_rx_supported = true, \
|
||||
.trans.mq_rx_supported = true, \
|
||||
.vht_mu_mimo_supported = true, \
|
||||
.mac_addr_from_csr = true, \
|
||||
.rf_id = true, \
|
||||
.trans.rf_id = true, \
|
||||
.nvm_type = IWL_NVM_EXT, \
|
||||
.dbgc_supported = true, \
|
||||
.min_umac_error_event_table = 0x800000, \
|
||||
.csr = &iwl_csr_v1, \
|
||||
.trans.csr = &iwl_csr_v1, \
|
||||
.d3_debug_data_base_addr = 0x401000, \
|
||||
.d3_debug_data_length = 92 * 1024, \
|
||||
.ht_params = &iwl9000_ht_params, \
|
||||
|
@ -2,6 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
@ -483,7 +484,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->cfg->device_family) {
|
||||
switch (priv->trans->trans_cfg->device_family) {
|
||||
case IWL_DEVICE_FAMILY_6005:
|
||||
case IWL_DEVICE_FAMILY_6030:
|
||||
case IWL_DEVICE_FAMILY_6000:
|
||||
|
@ -2,6 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
@ -120,9 +121,9 @@ static int iwl_led_cmd(struct iwl_priv *priv,
|
||||
}
|
||||
|
||||
led_cmd.on = iwl_blink_compensation(priv, on,
|
||||
priv->cfg->base_params->led_compensation);
|
||||
priv->trans->trans_cfg->base_params->led_compensation);
|
||||
led_cmd.off = iwl_blink_compensation(priv, off,
|
||||
priv->cfg->base_params->led_compensation);
|
||||
priv->trans->trans_cfg->base_params->led_compensation);
|
||||
|
||||
ret = iwl_send_led_cmd(priv, &led_cmd);
|
||||
if (!ret) {
|
||||
|
@ -2,7 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* Copyright (C) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portions of the ieee80211 subsystem header files.
|
||||
@ -1099,7 +1099,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
goto done;
|
||||
}
|
||||
|
||||
scd_queues = BIT(priv->cfg->base_params->num_of_queues) - 1;
|
||||
scd_queues = BIT(priv->trans->trans_cfg->base_params->num_of_queues) - 1;
|
||||
scd_queues &= ~(BIT(IWL_IPAN_CMD_QUEUE_NUM) |
|
||||
BIT(IWL_DEFAULT_CMD_QUEUE_NUM));
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* Copyright (C) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portions of the ieee80211 subsystem header files.
|
||||
@ -1267,7 +1267,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
priv->cfg = cfg;
|
||||
priv->fw = fw;
|
||||
|
||||
switch (priv->cfg->device_family) {
|
||||
switch (priv->trans->trans_cfg->device_family) {
|
||||
case IWL_DEVICE_FAMILY_1000:
|
||||
case IWL_DEVICE_FAMILY_100:
|
||||
priv->lib = &iwl_dvm_1000_cfg;
|
||||
@ -1342,7 +1342,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
driver_data[2]);
|
||||
|
||||
WARN_ON(sizeof(priv->transport_queue_stop) * BITS_PER_BYTE <
|
||||
priv->cfg->base_params->num_of_queues);
|
||||
priv->trans->trans_cfg->base_params->num_of_queues);
|
||||
|
||||
ucode_flags = fw->ucode_capa.flags;
|
||||
|
||||
@ -1405,7 +1405,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
/* Reset chip to save power until we load uCode during "up". */
|
||||
iwl_trans_stop_device(priv->trans);
|
||||
|
||||
priv->nvm_data = iwl_parse_eeprom_data(priv->trans->dev, priv->cfg,
|
||||
priv->nvm_data = iwl_parse_eeprom_data(priv->trans, priv->cfg,
|
||||
priv->eeprom_blob,
|
||||
priv->eeprom_blob_size);
|
||||
if (!priv->nvm_data)
|
||||
|
@ -2,6 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portions of the ieee80211 subsystem header files.
|
||||
@ -199,7 +200,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
|
||||
else
|
||||
cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
|
||||
|
||||
if (priv->cfg->base_params->shadow_reg_enable)
|
||||
if (priv->trans->trans_cfg->base_params->shadow_reg_enable)
|
||||
cmd->flags |= IWL_POWER_SHADOW_REG_ENA;
|
||||
else
|
||||
cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA;
|
||||
|
@ -2,6 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
@ -467,7 +468,7 @@ static int iwlagn_alloc_agg_txq(struct iwl_priv *priv, int mq)
|
||||
int q;
|
||||
|
||||
for (q = IWLAGN_FIRST_AMPDU_QUEUE;
|
||||
q < priv->cfg->base_params->num_of_queues; q++) {
|
||||
q < priv->trans->trans_cfg->base_params->num_of_queues; q++) {
|
||||
if (!test_and_set_bit(q, priv->agg_q_alloc)) {
|
||||
priv->queue_to_mac80211[q] = mq;
|
||||
return q;
|
||||
@ -1281,7 +1282,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->cfg->base_params->num_of_queues) {
|
||||
if (scd_flow >= priv->trans->trans_cfg->base_params->num_of_queues) {
|
||||
IWL_ERR(priv,
|
||||
"BUG_ON scd_flow is bigger than number of queues\n");
|
||||
return;
|
||||
|
@ -68,6 +68,7 @@
|
||||
#define ACPI_WRDD_METHOD "WRDD"
|
||||
#define ACPI_SPLC_METHOD "SPLC"
|
||||
#define ACPI_ECKV_METHOD "ECKV"
|
||||
#define ACPI_PPAG_METHOD "PPAG"
|
||||
|
||||
#define ACPI_WIFI_DOMAIN (0x07)
|
||||
|
||||
@ -92,6 +93,17 @@
|
||||
#define ACPI_WGDS_NUM_BANDS 2
|
||||
#define ACPI_WGDS_TABLE_SIZE 3
|
||||
|
||||
#define ACPI_PPAG_NUM_CHAINS 2
|
||||
#define ACPI_PPAG_NUM_SUB_BANDS 5
|
||||
#define ACPI_PPAG_WIFI_DATA_SIZE ((ACPI_PPAG_NUM_CHAINS * \
|
||||
ACPI_PPAG_NUM_SUB_BANDS) + 3)
|
||||
|
||||
/* PPAG gain value bounds in 1/8 dBm */
|
||||
#define ACPI_PPAG_MIN_LB -16
|
||||
#define ACPI_PPAG_MAX_LB 24
|
||||
#define ACPI_PPAG_MIN_HB -16
|
||||
#define ACPI_PPAG_MAX_HB 40
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
|
||||
void *iwl_acpi_get_object(struct device *dev, acpi_string method);
|
||||
|
@ -474,6 +474,13 @@ enum iwl_legacy_cmds {
|
||||
*/
|
||||
REPLY_RX_MPDU_CMD = 0xc1,
|
||||
|
||||
/**
|
||||
* @BAR_FRAME_RELEASE: Frame release from BAR notification, used for
|
||||
* multi-TID BAR (previously, the BAR frame itself was reported
|
||||
* instead). Uses &struct iwl_bar_frame_release.
|
||||
*/
|
||||
BAR_FRAME_RELEASE = 0xc2,
|
||||
|
||||
/**
|
||||
* @FRAME_RELEASE:
|
||||
* Frame release (reorder helper) notification, uses
|
||||
|
@ -396,6 +396,7 @@ enum iwl_wowlan_flags {
|
||||
* @is_11n_connection: indicates HT connection
|
||||
* @offloading_tid: TID reserved for firmware use
|
||||
* @flags: extra flags, see &enum iwl_wowlan_flags
|
||||
* @sta_id: station ID for wowlan.
|
||||
* @reserved: reserved
|
||||
*/
|
||||
struct iwl_wowlan_config_cmd {
|
||||
@ -406,8 +407,9 @@ struct iwl_wowlan_config_cmd {
|
||||
u8 is_11n_connection;
|
||||
u8 offloading_tid;
|
||||
u8 flags;
|
||||
u8 reserved[2];
|
||||
} __packed; /* WOWLAN_CONFIG_API_S_VER_4 */
|
||||
u8 sta_id;
|
||||
u8 reserved;
|
||||
} __packed; /* WOWLAN_CONFIG_API_S_VER_5 */
|
||||
|
||||
/*
|
||||
* WOWLAN_TSC_RSC_PARAMS
|
||||
|
@ -140,17 +140,6 @@ struct iwl_fw_ini_hcmd_tlv {
|
||||
struct iwl_fw_ini_hcmd hcmd;
|
||||
} __packed; /* FW_DEBUG_TLV_HCMD_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_fw_ini_debug_flow_tlv - (IWL_UCODE_TLV_TYPE_DEBUG_FLOW)
|
||||
*
|
||||
* @header: header
|
||||
* @debug_flow_cfg: &enum iwl_fw_ini_debug_flow
|
||||
*/
|
||||
struct iwl_fw_ini_debug_flow_tlv {
|
||||
struct iwl_fw_ini_header header;
|
||||
__le32 debug_flow_cfg;
|
||||
} __packed; /* FW_DEBUG_TLV_FLOW_TLV_S_VER_1 */
|
||||
|
||||
#define IWL_FW_INI_MAX_REGION_ID 64
|
||||
#define IWL_FW_INI_MAX_NAME 32
|
||||
|
||||
@ -408,27 +397,6 @@ enum iwl_fw_ini_trigger_id {
|
||||
IWL_FW_TRIGGER_ID_NUM,
|
||||
}; /* FW_DEBUG_TLV_TRIGGER_ID_E_VER_1 */
|
||||
|
||||
/**
|
||||
* enum iwl_fw_ini_apply_point
|
||||
*
|
||||
* @IWL_FW_INI_APPLY_INVALID: invalid
|
||||
* @IWL_FW_INI_APPLY_EARLY: pre loading FW
|
||||
* @IWL_FW_INI_APPLY_AFTER_ALIVE: first cmd from host after alive
|
||||
* @IWL_FW_INI_APPLY_POST_INIT: last cmd in initialization sequence
|
||||
* @IWL_FW_INI_APPLY_MISSED_BEACONS: missed beacons notification
|
||||
* @IWL_FW_INI_APPLY_SCAN_COMPLETE: scan completed
|
||||
* @IWL_FW_INI_APPLY_NUM: number of apply points
|
||||
*/
|
||||
enum iwl_fw_ini_apply_point {
|
||||
IWL_FW_INI_APPLY_INVALID,
|
||||
IWL_FW_INI_APPLY_EARLY,
|
||||
IWL_FW_INI_APPLY_AFTER_ALIVE,
|
||||
IWL_FW_INI_APPLY_POST_INIT,
|
||||
IWL_FW_INI_APPLY_MISSED_BEACONS,
|
||||
IWL_FW_INI_APPLY_SCAN_COMPLETE,
|
||||
IWL_FW_INI_APPLY_NUM,
|
||||
}; /* FW_DEBUG_TLV_APPLY_POINT_E_VER_1 */
|
||||
|
||||
/**
|
||||
* enum iwl_fw_ini_allocation_id
|
||||
*
|
||||
@ -439,6 +407,7 @@ enum iwl_fw_ini_apply_point {
|
||||
* @IWL_FW_INI_ALLOCATION_ID_SDFX: for SDFX module
|
||||
* @IWL_FW_INI_ALLOCATION_ID_FW_DUMP: used for crash and runtime dumps
|
||||
* @IWL_FW_INI_ALLOCATION_ID_USER_DEFINED: for future user scenarios
|
||||
* @IWL_FW_INI_ALLOCATION_NUM: number of allocation ids
|
||||
*/
|
||||
enum iwl_fw_ini_allocation_id {
|
||||
IWL_FW_INI_ALLOCATION_INVALID,
|
||||
@ -448,6 +417,7 @@ enum iwl_fw_ini_allocation_id {
|
||||
IWL_FW_INI_ALLOCATION_ID_SDFX,
|
||||
IWL_FW_INI_ALLOCATION_ID_FW_DUMP,
|
||||
IWL_FW_INI_ALLOCATION_ID_USER_DEFINED,
|
||||
IWL_FW_INI_ALLOCATION_NUM,
|
||||
}; /* FW_DEBUG_TLV_ALLOCATION_ID_E_VER_1 */
|
||||
|
||||
/**
|
||||
@ -519,4 +489,72 @@ enum iwl_fw_ini_region_type {
|
||||
IWL_FW_INI_REGION_NUM
|
||||
}; /* FW_DEBUG_TLV_REGION_TYPE_E_VER_1 */
|
||||
|
||||
/**
|
||||
* enum iwl_fw_ini_time_point
|
||||
*
|
||||
* Hard coded time points in which the driver can send hcmd or perform dump
|
||||
* collection
|
||||
*
|
||||
* @IWL_FW_INI_TIME_POINT_EARLY: pre loading the FW
|
||||
* @IWL_FW_INI_TIME_POINT_AFTER_ALIVE: first cmd from host after alive notif
|
||||
* @IWL_FW_INI_TIME_POINT_POST_INIT: last cmd in series of init sequence
|
||||
* @IWL_FW_INI_TIME_POINT_FW_ASSERT: FW assert
|
||||
* @IWL_FW_INI_TIME_POINT_FW_HW_ERROR: FW HW error
|
||||
* @IWL_FW_INI_TIME_POINT_FW_TFD_Q_HANG: TFD queue hang
|
||||
* @IWL_FW_INI_TIME_POINT_FW_DHC_NOTIFOCATION: DHC cmd response and notif
|
||||
* @IWL_FW_INI_TIME_POINT_FW_RSP_OR_NOTIF: FW response or notification.
|
||||
* data field holds id and group
|
||||
* @IWL_FW_INI_TIME_POINT_USER_TRIGGER: user trigger time point
|
||||
* @IWL_FW_INI_TIME_POINT_PERIODIC: periodic timepoint that fires in constant
|
||||
* intervals. data field holds the interval time in msec
|
||||
* @IWL_FW_INI_TIME_POINT_WDG_TIMEOUT: watchdog timeout
|
||||
* @IWL_FW_INI_TIME_POINT_HOST_ASSERT: Unused
|
||||
* @IWL_FW_INI_TIME_POINT_HOST_ALIVE_TIMEOUT: alive timeout
|
||||
* @IWL_FW_INI_TIME_POINT_HOST_DEVICE_ENABLE: device enable
|
||||
* @IWL_FW_INI_TIME_POINT_HOST_DEVICE_DISABLE: device disable
|
||||
* @IWL_FW_INI_TIME_POINT_HOST_D3_START: D3 start
|
||||
* @IWL_FW_INI_TIME_POINT_HOST_D3_END: D3 end
|
||||
* @IWL_FW_INI_TIME_POINT_MISSED_BEACONS: missed beacons
|
||||
* @IWL_FW_INI_TIME_POINT_ASSOC_FAILED: association failure
|
||||
* @IWL_FW_INI_TIME_POINT_TX_FAILED: Tx frame failed
|
||||
* @IWL_FW_INI_TIME_POINT_TX_WFD_ACTION_FRAME_FAILED: wifi direct action
|
||||
* frame failed
|
||||
* @IWL_FW_INI_TIME_POINT_TX_LATENCY_THRESHOLD: Tx latency threshold
|
||||
* @IWL_FW_INI_TIME_POINT_HANG_OCCURRED: hang occurred
|
||||
* @IWL_FW_INI_TIME_POINT_EAPOL_FAILED: EAPOL failed
|
||||
* @IWL_FW_INI_TIME_POINT_FAKE_TX: fake Tx
|
||||
* @IWL_FW_INI_TIME_POINT_DEASSOC: de association
|
||||
* @IWL_FW_INI_TIME_POINT_NUM: number of time points
|
||||
*/
|
||||
enum iwl_fw_ini_time_point {
|
||||
IWL_FW_INI_TIME_POINT_INVALID,
|
||||
IWL_FW_INI_TIME_POINT_EARLY,
|
||||
IWL_FW_INI_TIME_POINT_AFTER_ALIVE,
|
||||
IWL_FW_INI_TIME_POINT_POST_INIT,
|
||||
IWL_FW_INI_TIME_POINT_FW_ASSERT,
|
||||
IWL_FW_INI_TIME_POINT_FW_HW_ERROR,
|
||||
IWL_FW_INI_TIME_POINT_FW_TFD_Q_HANG,
|
||||
IWL_FW_INI_TIME_POINT_FW_DHC_NOTIFOCATION,
|
||||
IWL_FW_INI_TIME_POINT_FW_RSP_OR_NOTIF,
|
||||
IWL_FW_INI_TIME_POINT_USER_TRIGGER,
|
||||
IWL_FW_INI_TIME_POINT_PERIODIC,
|
||||
IWL_FW_INI_TIME_POINT_WDG_TIMEOUT,
|
||||
IWL_FW_INI_TIME_POINT_HOST_ASSERT,
|
||||
IWL_FW_INI_TIME_POINT_HOST_ALIVE_TIMEOUT,
|
||||
IWL_FW_INI_TIME_POINT_HOST_DEVICE_ENABLE,
|
||||
IWL_FW_INI_TIME_POINT_HOST_DEVICE_DISABLE,
|
||||
IWL_FW_INI_TIME_POINT_HOST_D3_START,
|
||||
IWL_FW_INI_TIME_POINT_HOST_D3_END,
|
||||
IWL_FW_INI_TIME_POINT_MISSED_BEACONS,
|
||||
IWL_FW_INI_TIME_POINT_ASSOC_FAILED,
|
||||
IWL_FW_INI_TIME_POINT_TX_FAILED,
|
||||
IWL_FW_INI_TIME_POINT_TX_WFD_ACTION_FRAME_FAILED,
|
||||
IWL_FW_INI_TIME_POINT_TX_LATENCY_THRESHOLD,
|
||||
IWL_FW_INI_TIME_POINT_HANG_OCCURRED,
|
||||
IWL_FW_INI_TIME_POINT_EAPOL_FAILED,
|
||||
IWL_FW_INI_TIME_POINT_FAKE_TX,
|
||||
IWL_FW_INI_TIME_POINT_DEASSOC,
|
||||
IWL_FW_INI_TIME_POINT_NUM,
|
||||
}; /* FW_TLV_DEBUG_TIME_POINT_API_E */
|
||||
|
||||
#endif
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* Copyright (C) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -31,7 +31,7 @@
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* Copyright (C) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -80,6 +80,19 @@ enum iwl_debug_cmds {
|
||||
* &struct iwl_dbg_mem_access_rsp
|
||||
*/
|
||||
UMAC_RD_WR = 0x1,
|
||||
/**
|
||||
* @DBGC_SUSPEND_RESUME:
|
||||
* DBGC suspend/resume commad. Uses a single dword as data:
|
||||
* 0 - resume DBGC recording
|
||||
* 1 - suspend DBGC recording
|
||||
*/
|
||||
DBGC_SUSPEND_RESUME = 0x7,
|
||||
/**
|
||||
* @BUFFER_ALLOCATION:
|
||||
* passes DRAM buffers to a DBGC
|
||||
* &struct iwl_buf_alloc_cmd
|
||||
*/
|
||||
BUFFER_ALLOCATION = 0x8,
|
||||
/**
|
||||
* @MFU_ASSERT_DUMP_NTF:
|
||||
* &struct iwl_mfu_assert_dump_notif
|
||||
@ -102,6 +115,16 @@ enum {
|
||||
FW_ERR_FATAL = 0xFF
|
||||
};
|
||||
|
||||
/** enum iwl_dbg_suspend_resume_cmds - dbgc suspend resume operations
|
||||
* dbgc suspend resume command operations
|
||||
* @DBGC_RESUME_CMD: resume dbgc recording
|
||||
* @DBGC_SUSPEND_CMD: stop dbgc recording
|
||||
*/
|
||||
enum iwl_dbg_suspend_resume_cmds {
|
||||
DBGC_RESUME_CMD,
|
||||
DBGC_SUSPEND_CMD,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_error_resp - FW error indication
|
||||
* ( REPLY_ERROR = 0x2 )
|
||||
@ -335,49 +358,39 @@ struct iwl_dbg_mem_access_rsp {
|
||||
__le32 data[];
|
||||
} __packed; /* DEBUG_(U|L)MAC_RD_WR_RSP_API_S_VER_1 */
|
||||
|
||||
#define LDBG_CFG_COMMAND_SIZE 80
|
||||
#define BUFFER_ALLOCATION 0x27
|
||||
#define START_DEBUG_RECORDING 0x29
|
||||
#define STOP_DEBUG_RECORDING 0x2A
|
||||
/**
|
||||
* struct iwl_dbg_suspend_resume_cmd - dbgc suspend resume command
|
||||
* @operation: suspend or resume operation, uses
|
||||
* &enum iwl_dbg_suspend_resume_cmds
|
||||
*/
|
||||
struct iwl_dbg_suspend_resume_cmd {
|
||||
__le32 operation;
|
||||
} __packed;
|
||||
|
||||
/* maximum fragments to be allocated per target of allocationId */
|
||||
#define IWL_BUFFER_LOCATION_MAX_FRAGS 2
|
||||
#define BUF_ALLOC_MAX_NUM_FRAGS 16
|
||||
|
||||
/**
|
||||
* struct iwl_fragment_data single fragment structure
|
||||
* @address: 64bit start address
|
||||
* @size: size in bytes
|
||||
* struct iwl_buf_alloc_frag - a DBGC fragment
|
||||
* @addr: base address of the fragment
|
||||
* @size: size of the fragment
|
||||
*/
|
||||
struct iwl_fragment_data {
|
||||
__le64 address;
|
||||
struct iwl_buf_alloc_frag {
|
||||
__le64 addr;
|
||||
__le32 size;
|
||||
} __packed; /* FRAGMENT_STRUCTURE_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_buffer_allocation_cmd - buffer allocation command structure
|
||||
* @allocation_id: id of the allocation
|
||||
* @buffer_location: location of the buffer
|
||||
* struct iwl_buf_alloc_cmd - buffer allocation command
|
||||
* @alloc_id: &enum iwl_fw_ini_allocation_id
|
||||
* @buf_location: &enum iwl_fw_ini_buffer_location
|
||||
* @num_frags: number of fragments
|
||||
* @fragments: memory fragments
|
||||
* @frags: fragments array
|
||||
*/
|
||||
struct iwl_buffer_allocation_cmd {
|
||||
__le32 allocation_id;
|
||||
__le32 buffer_location;
|
||||
struct iwl_buf_alloc_cmd {
|
||||
__le32 alloc_id;
|
||||
__le32 buf_location;
|
||||
__le32 num_frags;
|
||||
struct iwl_fragment_data fragments[IWL_BUFFER_LOCATION_MAX_FRAGS];
|
||||
} __packed; /* BUFFER_ALLOCATION_CMD_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_ldbg_config_cmd - LDBG config command
|
||||
* @type: configuration type
|
||||
* @pad: reserved space for type-dependent data
|
||||
*/
|
||||
struct iwl_ldbg_config_cmd {
|
||||
__le32 type;
|
||||
union {
|
||||
u8 pad[LDBG_CFG_COMMAND_SIZE - sizeof(__le32)];
|
||||
struct iwl_buffer_allocation_cmd buffer_allocation;
|
||||
}; /* LDBG_CFG_BODY_API_U_VER_2 (partially) */
|
||||
} __packed; /* LDBG_CFG_CMD_API_S_VER_2 */
|
||||
struct iwl_buf_alloc_frag frags[BUF_ALLOC_MAX_NUM_FRAGS];
|
||||
} __packed; /* BUFFER_ALLOCATION_CMD_API_S_VER_2 */
|
||||
|
||||
#endif /* __iwl_fw_api_debug_h__ */
|
||||
|
@ -82,7 +82,7 @@ enum iwl_location_subcmd_ids {
|
||||
TOF_RANGE_ABORT_CMD = 0x2,
|
||||
/**
|
||||
* @TOF_RANGE_REQ_EXT_CMD: TOF extended ranging config,
|
||||
* uses &struct iwl_tof_range_request_ext_cmd
|
||||
* uses &struct iwl_tof_range_req_ext_cmd
|
||||
*/
|
||||
TOF_RANGE_REQ_EXT_CMD = 0x3,
|
||||
/**
|
||||
@ -292,7 +292,7 @@ struct iwl_tof_responder_dyn_config_cmd {
|
||||
} __packed; /* TOF_RESPONDER_DYN_CONFIG_CMD_API_S_VER_2 */
|
||||
|
||||
/**
|
||||
* struct iwl_tof_range_request_ext_cmd - extended range req for WLS
|
||||
* struct iwl_tof_range_req_ext_cmd - extended range req for WLS
|
||||
* @tsf_timer_offset_msec: the recommended time offset (mSec) from the AP's TSF
|
||||
* @reserved: reserved
|
||||
* @min_delta_ftm: Minimal time between two consecutive measurements,
|
||||
|
@ -500,6 +500,9 @@ struct iwl_he_pkt_ext {
|
||||
* enabled AGG, i.e. both BACK and non-BACK frames in a single AGG
|
||||
* @STA_CTXT_HE_MU_EDCA_CW: indicates that there is an element of MU EDCA
|
||||
* parameter set, i.e. the backoff counters for trig-based ACs
|
||||
* @STA_CTXT_HE_RU_2MHZ_BLOCK: indicates that 26-tone RU OFDMA transmission are
|
||||
* not allowed (as there are OBSS that might classify such transmissions as
|
||||
* radar pulses).
|
||||
*/
|
||||
enum iwl_he_sta_ctxt_flags {
|
||||
STA_CTXT_HE_REF_BSSID_VALID = BIT(4),
|
||||
@ -511,6 +514,7 @@ enum iwl_he_sta_ctxt_flags {
|
||||
STA_CTXT_HE_CONST_TRIG_RND_ALLOC = BIT(10),
|
||||
STA_CTXT_HE_ACK_ENABLED = BIT(11),
|
||||
STA_CTXT_HE_MU_EDCA_CW = BIT(12),
|
||||
STA_CTXT_HE_RU_2MHZ_BLOCK = BIT(14),
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -8,6 +8,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -30,6 +31,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -89,6 +91,11 @@ enum iwl_phy_ops_subcmd_ids {
|
||||
*/
|
||||
GEO_TX_POWER_LIMIT = 0x05,
|
||||
|
||||
/**
|
||||
* @PER_PLATFORM_ANT_GAIN_CMD: &struct iwl_ppag_table_cmd
|
||||
*/
|
||||
PER_PLATFORM_ANT_GAIN_CMD = 0x07,
|
||||
|
||||
/**
|
||||
* @CT_KILL_NOTIFICATION: &struct ct_kill_notif
|
||||
*/
|
||||
|
@ -449,6 +449,18 @@ struct iwl_geo_tx_power_profiles_resp {
|
||||
__le32 profile_idx;
|
||||
} __packed; /* GEO_TX_POWER_LIMIT_RESP */
|
||||
|
||||
/**
|
||||
* struct iwl_ppag_table_cmd - struct for PER_PLATFORM_ANT_GAIN_CMD cmd.
|
||||
* @enabled: 1 if PPAG is enabled, 0 otherwise
|
||||
* @gain: table of antenna gain values per chain and sub-band
|
||||
* @reserved: reserved
|
||||
*/
|
||||
struct iwl_ppag_table_cmd {
|
||||
__le32 enabled;
|
||||
s8 gain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS];
|
||||
s8 reserved[2];
|
||||
} __packed; /* PER_PLATFORM_ANT_GAIN_CMD */
|
||||
|
||||
/**
|
||||
* struct iwl_beacon_filter_cmd
|
||||
* REPLY_BEACON_FILTERING_CMD = 0xd2 (command)
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -29,7 +29,7 @@
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -166,8 +166,16 @@ enum iwl_tlc_mng_ht_rates {
|
||||
IWL_TLC_MNG_HT_RATE_MAX = IWL_TLC_MNG_HT_RATE_MCS11,
|
||||
};
|
||||
|
||||
/* Maximum supported tx antennas number */
|
||||
#define MAX_NSS 2
|
||||
enum IWL_TLC_MNG_NSS {
|
||||
IWL_TLC_NSS_1,
|
||||
IWL_TLC_NSS_2,
|
||||
IWL_TLC_NSS_MAX
|
||||
};
|
||||
|
||||
enum IWL_TLC_HT_BW_RATES {
|
||||
IWL_TLC_HT_BW_NONE_160,
|
||||
IWL_TLC_HT_BW_160,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tlc_config_cmd - TLC configuration
|
||||
@ -195,7 +203,7 @@ struct iwl_tlc_config_cmd {
|
||||
u8 amsdu;
|
||||
__le16 flags;
|
||||
__le16 non_ht_rates;
|
||||
__le16 ht_rates[MAX_NSS][2];
|
||||
__le16 ht_rates[IWL_TLC_NSS_MAX][2];
|
||||
__le16 max_mpdu_len;
|
||||
u8 sgi_ch_width_supp;
|
||||
u8 reserved2[1];
|
||||
|
@ -746,6 +746,38 @@ struct iwl_frame_release {
|
||||
__le16 nssn;
|
||||
};
|
||||
|
||||
/**
|
||||
* enum iwl_bar_frame_release_sta_tid - STA/TID information for BAR release
|
||||
* @IWL_BAR_FRAME_RELEASE_TID_MASK: TID mask
|
||||
* @IWL_BAR_FRAME_RELEASE_STA_MASK: STA mask
|
||||
*/
|
||||
enum iwl_bar_frame_release_sta_tid {
|
||||
IWL_BAR_FRAME_RELEASE_TID_MASK = 0x0000000f,
|
||||
IWL_BAR_FRAME_RELEASE_STA_MASK = 0x000001f0,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum iwl_bar_frame_release_ba_info - BA information for BAR release
|
||||
* @IWL_BAR_FRAME_RELEASE_NSSN_MASK: NSSN mask
|
||||
* @IWL_BAR_FRAME_RELEASE_SN_MASK: SN mask (ignored by driver)
|
||||
* @IWL_BAR_FRAME_RELEASE_BAID_MASK: BAID mask
|
||||
*/
|
||||
enum iwl_bar_frame_release_ba_info {
|
||||
IWL_BAR_FRAME_RELEASE_NSSN_MASK = 0x00000fff,
|
||||
IWL_BAR_FRAME_RELEASE_SN_MASK = 0x00fff000,
|
||||
IWL_BAR_FRAME_RELEASE_BAID_MASK = 0x3f000000,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_bar_frame_release - frame release from BAR info
|
||||
* @sta_tid: STA & TID information, see &enum iwl_bar_frame_release_sta_tid.
|
||||
* @ba_info: BA information, see &enum iwl_bar_frame_release_ba_info.
|
||||
*/
|
||||
struct iwl_bar_frame_release {
|
||||
__le32 sta_tid;
|
||||
__le32 ba_info;
|
||||
} __packed; /* RX_BAR_TO_FRAME_RELEASE_API_S_VER_1 */
|
||||
|
||||
enum iwl_rss_hash_func_en {
|
||||
IWL_RSS_HASH_TYPE_IPV4_TCP,
|
||||
IWL_RSS_HASH_TYPE_IPV4_UDP,
|
||||
|
@ -93,6 +93,8 @@ struct iwl_ssid_ie {
|
||||
#define IWL_SCAN_SHORT_BLACKLIST_LEN 16
|
||||
#define IWL_SCAN_MAX_PROFILES 11
|
||||
#define SCAN_OFFLOAD_PROBE_REQ_SIZE 512
|
||||
#define SCAN_NUM_BAND_PROBE_DATA_V_1 2
|
||||
#define SCAN_NUM_BAND_PROBE_DATA_V_2 3
|
||||
|
||||
/* Default watchdog (in MS) for scheduled scan iteration */
|
||||
#define IWL_SCHED_SCAN_WATCHDOG cpu_to_le16(15000)
|
||||
@ -251,9 +253,22 @@ struct iwl_scan_probe_segment {
|
||||
* @common_data: last (and common) part of the probe
|
||||
* @buf: raw data block
|
||||
*/
|
||||
struct iwl_scan_probe_req_v1 {
|
||||
struct iwl_scan_probe_segment mac_header;
|
||||
struct iwl_scan_probe_segment band_data[SCAN_NUM_BAND_PROBE_DATA_V_1];
|
||||
struct iwl_scan_probe_segment common_data;
|
||||
u8 buf[SCAN_OFFLOAD_PROBE_REQ_SIZE];
|
||||
} __packed;
|
||||
|
||||
/* iwl_scan_probe_req - PROBE_REQUEST_FRAME_API_S_VER_v2
|
||||
* @mac_header: first (and common) part of the probe
|
||||
* @band_data: band specific data
|
||||
* @common_data: last (and common) part of the probe
|
||||
* @buf: raw data block
|
||||
*/
|
||||
struct iwl_scan_probe_req {
|
||||
struct iwl_scan_probe_segment mac_header;
|
||||
struct iwl_scan_probe_segment band_data[2];
|
||||
struct iwl_scan_probe_segment band_data[SCAN_NUM_BAND_PROBE_DATA_V_2];
|
||||
struct iwl_scan_probe_segment common_data;
|
||||
u8 buf[SCAN_OFFLOAD_PROBE_REQ_SIZE];
|
||||
} __packed;
|
||||
@ -608,15 +623,29 @@ enum iwl_umac_scan_general_flags2 {
|
||||
* struct iwl_scan_channel_cfg_umac
|
||||
* @flags: bitmap - 0-19: directed scan to i'th ssid.
|
||||
* @channel_num: channel number 1-13 etc.
|
||||
* @band: band of channel: 0 for 2GHz, 1 for 5GHz
|
||||
* @iter_count: repetition count for the channel.
|
||||
* @iter_interval: interval between two scan iterations on one channel.
|
||||
*/
|
||||
struct iwl_scan_channel_cfg_umac {
|
||||
__le32 flags;
|
||||
/* Both versions are of the same size, so use a union without adjusting
|
||||
* the command size later
|
||||
*/
|
||||
union {
|
||||
struct {
|
||||
u8 channel_num;
|
||||
u8 iter_count;
|
||||
__le16 iter_interval;
|
||||
} __packed; /* SCAN_CHANNEL_CFG_S_VER2 */
|
||||
} v1; /* SCAN_CHANNEL_CFG_S_VER1 */
|
||||
struct {
|
||||
u8 channel_num;
|
||||
u8 band;
|
||||
u8 iter_count;
|
||||
u8 iter_interval;
|
||||
} v2; /* SCAN_CHANNEL_CFG_S_VER2 */
|
||||
};
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_scan_umac_schedule
|
||||
@ -630,6 +659,16 @@ struct iwl_scan_umac_schedule {
|
||||
u8 reserved;
|
||||
} __packed; /* SCAN_SCHED_PARAM_API_S_VER_1 */
|
||||
|
||||
struct iwl_scan_req_umac_tail_v1 {
|
||||
/* SCAN_PERIODIC_PARAMS_API_S_VER_1 */
|
||||
struct iwl_scan_umac_schedule schedule[IWL_MAX_SCHED_SCAN_PLANS];
|
||||
__le16 delay;
|
||||
__le16 reserved;
|
||||
/* SCAN_PROBE_PARAMS_API_S_VER_1 */
|
||||
struct iwl_scan_probe_req_v1 preq;
|
||||
struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_scan_req_umac_tail - the rest of the UMAC scan request command
|
||||
* parameters following channels configuration array.
|
||||
@ -639,12 +678,12 @@ struct iwl_scan_umac_schedule {
|
||||
* @preq: probe request with IEs blocks
|
||||
* @direct_scan: list of SSIDs for directed active scan
|
||||
*/
|
||||
struct iwl_scan_req_umac_tail {
|
||||
struct iwl_scan_req_umac_tail_v2 {
|
||||
/* SCAN_PERIODIC_PARAMS_API_S_VER_1 */
|
||||
struct iwl_scan_umac_schedule schedule[IWL_MAX_SCHED_SCAN_PLANS];
|
||||
__le16 delay;
|
||||
__le16 reserved;
|
||||
/* SCAN_PROBE_PARAMS_API_S_VER_1 */
|
||||
/* SCAN_PROBE_PARAMS_API_S_VER_2 */
|
||||
struct iwl_scan_probe_req preq;
|
||||
struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX];
|
||||
} __packed;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -202,7 +202,7 @@ _iwl_fw_dbg_trigger_on(struct iwl_fw_runtime *fwrt,
|
||||
{
|
||||
struct iwl_fw_dbg_trigger_tlv *trig;
|
||||
|
||||
if (fwrt->trans->dbg.ini_valid)
|
||||
if (iwl_trans_dbg_ini_valid(fwrt->trans))
|
||||
return NULL;
|
||||
|
||||
if (!iwl_fw_dbg_trigger_enabled(fwrt->fw, id))
|
||||
@ -229,8 +229,9 @@ iwl_fw_ini_trigger_on(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_ini_trigger *trig;
|
||||
u32 usec;
|
||||
|
||||
if (!fwrt->trans->dbg.ini_valid || id == IWL_FW_TRIGGER_ID_INVALID ||
|
||||
id >= IWL_FW_TRIGGER_ID_NUM || !fwrt->dump.active_trigs[id].active)
|
||||
if (!iwl_trans_dbg_ini_valid(fwrt->trans) ||
|
||||
id == IWL_FW_TRIGGER_ID_INVALID || id >= IWL_FW_TRIGGER_ID_NUM ||
|
||||
!fwrt->dump.active_trigs[id].active)
|
||||
return false;
|
||||
|
||||
trig = fwrt->dump.active_trigs[id].trig;
|
||||
@ -262,69 +263,9 @@ _iwl_fw_dbg_trigger_simple_stop(struct iwl_fw_runtime *fwrt,
|
||||
_iwl_fw_dbg_trigger_simple_stop((fwrt), (wdev), \
|
||||
iwl_fw_dbg_get_trigger((fwrt)->fw,\
|
||||
(trig)))
|
||||
|
||||
static inline void
|
||||
_iwl_fw_dbg_stop_recording(struct iwl_trans *trans,
|
||||
struct iwl_fw_dbg_params *params)
|
||||
{
|
||||
if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
|
||||
iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100);
|
||||
return;
|
||||
}
|
||||
|
||||
if (params) {
|
||||
params->in_sample = iwl_read_umac_prph(trans, DBGC_IN_SAMPLE);
|
||||
params->out_ctrl = iwl_read_umac_prph(trans, DBGC_OUT_CTRL);
|
||||
}
|
||||
|
||||
iwl_write_umac_prph(trans, DBGC_IN_SAMPLE, 0);
|
||||
/* wait for the DBGC to finish writing the internal buffer to DRAM to
|
||||
* avoid halting the HW while writing
|
||||
*/
|
||||
usleep_range(700, 1000);
|
||||
iwl_write_umac_prph(trans, DBGC_OUT_CTRL, 0);
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
trans->dbg.rec_on = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
iwl_fw_dbg_stop_recording(struct iwl_trans *trans,
|
||||
struct iwl_fw_dbg_params *params)
|
||||
{
|
||||
/* if the FW crashed or not debug monitor cfg was given, there is
|
||||
* no point in stopping
|
||||
*/
|
||||
if (test_bit(STATUS_FW_ERROR, &trans->status) ||
|
||||
(!trans->dbg.dest_tlv &&
|
||||
trans->dbg.ini_dest == IWL_FW_INI_LOCATION_INVALID))
|
||||
return;
|
||||
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
|
||||
IWL_ERR(trans,
|
||||
"WRT: unsupported device family %d for debug stop recording\n",
|
||||
trans->cfg->device_family);
|
||||
return;
|
||||
}
|
||||
_iwl_fw_dbg_stop_recording(trans, params);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_iwl_fw_dbg_restart_recording(struct iwl_trans *trans,
|
||||
struct iwl_fw_dbg_params *params)
|
||||
{
|
||||
if (WARN_ON(!params))
|
||||
return;
|
||||
|
||||
if (trans->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);
|
||||
} else {
|
||||
iwl_write_umac_prph(trans, DBGC_IN_SAMPLE, params->in_sample);
|
||||
iwl_write_umac_prph(trans, DBGC_OUT_CTRL, params->out_ctrl);
|
||||
}
|
||||
}
|
||||
int iwl_fw_dbg_stop_restart_recording(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_dbg_params *params,
|
||||
bool stop);
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
static inline void iwl_fw_set_dbg_rec_on(struct iwl_fw_runtime *fwrt)
|
||||
@ -336,30 +277,6 @@ static inline void iwl_fw_set_dbg_rec_on(struct iwl_fw_runtime *fwrt)
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
iwl_fw_dbg_restart_recording(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_dbg_params *params)
|
||||
{
|
||||
/* if the FW crashed or not debug monitor cfg was given, there is
|
||||
* no point in restarting
|
||||
*/
|
||||
if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status) ||
|
||||
(!fwrt->trans->dbg.dest_tlv &&
|
||||
fwrt->trans->dbg.ini_dest == IWL_FW_INI_LOCATION_INVALID))
|
||||
return;
|
||||
|
||||
if (fwrt->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
|
||||
IWL_ERR(fwrt,
|
||||
"WRT: unsupported device family %d for debug restart recording\n",
|
||||
fwrt->trans->cfg->device_family);
|
||||
return;
|
||||
}
|
||||
_iwl_fw_dbg_restart_recording(fwrt->trans, params);
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
iwl_fw_set_dbg_rec_on(fwrt);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void iwl_fw_dump_conf_clear(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
fwrt->dump.conf = FW_DBG_INVALID;
|
||||
@ -385,7 +302,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->cfg->gen2 &&
|
||||
!fwrt->trans->trans_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;
|
||||
@ -397,24 +314,13 @@ static inline void iwl_fw_flush_dumps(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
int i;
|
||||
|
||||
del_timer(&fwrt->dump.periodic_trig);
|
||||
iwl_dbg_tlv_del_timers(fwrt->trans);
|
||||
for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++) {
|
||||
flush_delayed_work(&fwrt->dump.wks[i].wk);
|
||||
fwrt->dump.wks[i].ini_trig_id = IWL_FW_TRIGGER_ID_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void iwl_fw_cancel_dumps(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
int i;
|
||||
|
||||
del_timer(&fwrt->dump.periodic_trig);
|
||||
for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++) {
|
||||
cancel_delayed_work_sync(&fwrt->dump.wks[i].wk);
|
||||
fwrt->dump.wks[i].ini_trig_id = IWL_FW_TRIGGER_ID_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
static inline void iwl_fw_cancel_timestamp(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
@ -451,10 +357,7 @@ static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) {}
|
||||
|
||||
#endif /* CONFIG_IWLWIFI_DEBUGFS */
|
||||
|
||||
void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
|
||||
enum iwl_fw_ini_apply_point apply_point);
|
||||
|
||||
void iwl_fwrt_stop_device(struct iwl_fw_runtime *fwrt);
|
||||
void iwl_fw_dbg_stop_sync(struct iwl_fw_runtime *fwrt);
|
||||
|
||||
static inline void iwl_fw_lmac1_set_alive_err_table(struct iwl_trans *trans,
|
||||
u32 lmac_error_event_table)
|
||||
@ -478,7 +381,7 @@ static inline void iwl_fw_umac_set_alive_err_table(struct iwl_trans *trans,
|
||||
|
||||
static inline void iwl_fw_error_collect(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
if (fwrt->trans->dbg.ini_valid && fwrt->trans->dbg.hw_error) {
|
||||
if (iwl_trans_dbg_ini_valid(fwrt->trans) && fwrt->trans->dbg.hw_error) {
|
||||
_iwl_fw_dbg_ini_collect(fwrt, IWL_FW_TRIGGER_ID_FW_HW_ERROR);
|
||||
fwrt->trans->dbg.hw_error = false;
|
||||
} else {
|
||||
@ -486,8 +389,6 @@ static inline void iwl_fw_error_collect(struct iwl_fw_runtime *fwrt)
|
||||
}
|
||||
}
|
||||
|
||||
void iwl_fw_dbg_periodic_trig_handler(struct timer_list *t);
|
||||
|
||||
void iwl_fw_error_print_fseq_regs(struct iwl_fw_runtime *fwrt);
|
||||
|
||||
static inline void iwl_fwrt_update_fw_versions(struct iwl_fw_runtime *fwrt,
|
||||
|
@ -287,6 +287,28 @@ struct iwl_fw_error_dump_mem {
|
||||
/* Use bit 31 as dump info type to avoid colliding with region types */
|
||||
#define IWL_INI_DUMP_INFO_TYPE BIT(31)
|
||||
|
||||
/**
|
||||
* struct iwl_fw_ini_dump_entry
|
||||
* @list: list of dump entries
|
||||
* @size: size of the data
|
||||
* @data: entry data
|
||||
*/
|
||||
struct iwl_fw_ini_dump_entry {
|
||||
struct list_head list;
|
||||
u32 size;
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_fw_error_dump_file - header of dump file
|
||||
* @barker: must be %IWL_FW_INI_ERROR_DUMP_BARKER
|
||||
* @file_len: the length of all the file including the header
|
||||
*/
|
||||
struct iwl_fw_ini_dump_file_hdr {
|
||||
__le32 barker;
|
||||
__le32 file_len;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_fw_ini_fifo_hdr - fifo range header
|
||||
* @fifo_num: the fifo number. In case of umac rx fifo, set BIT(31) to
|
||||
@ -301,10 +323,10 @@ struct iwl_fw_ini_fifo_hdr {
|
||||
/**
|
||||
* struct iwl_fw_ini_error_dump_range - range of memory
|
||||
* @range_data_size: the size of this range, in bytes
|
||||
* @internal_base_addr - base address of internal memory range
|
||||
* @dram_base_addr - base address of dram monitor range
|
||||
* @page_num - page number of memory range
|
||||
* @fifo_hdr - fifo header of memory range
|
||||
* @internal_base_addr: base address of internal memory range
|
||||
* @dram_base_addr: base address of dram monitor range
|
||||
* @page_num: page number of memory range
|
||||
* @fifo_hdr: fifo header of memory range
|
||||
* @data: the actual memory
|
||||
*/
|
||||
struct iwl_fw_ini_error_dump_range {
|
||||
@ -432,10 +454,10 @@ struct iwl_fw_error_dump_rb {
|
||||
|
||||
/**
|
||||
* struct iwl_fw_ini_monitor_dump - ini monitor dump
|
||||
* @header - header of the region
|
||||
* @write_ptr - write pointer position in the buffer
|
||||
* @cycle_cnt - cycles count
|
||||
* @ranges - the memory ranges of this this region
|
||||
* @header: header of the region
|
||||
* @write_ptr: write pointer position in the buffer
|
||||
* @cycle_cnt: cycles count
|
||||
* @ranges: the memory ranges of this this region
|
||||
*/
|
||||
struct iwl_fw_ini_monitor_dump {
|
||||
struct iwl_fw_ini_error_dump_header header;
|
||||
|
@ -157,8 +157,7 @@ enum iwl_ucode_tlv_type {
|
||||
IWL_UCODE_TLV_TYPE_HCMD = IWL_UCODE_TLV_DEBUG_BASE + 2,
|
||||
IWL_UCODE_TLV_TYPE_REGIONS = IWL_UCODE_TLV_DEBUG_BASE + 3,
|
||||
IWL_UCODE_TLV_TYPE_TRIGGERS = IWL_UCODE_TLV_DEBUG_BASE + 4,
|
||||
IWL_UCODE_TLV_TYPE_DEBUG_FLOW = IWL_UCODE_TLV_DEBUG_BASE + 5,
|
||||
IWL_UCODE_TLV_DEBUG_MAX = IWL_UCODE_TLV_TYPE_DEBUG_FLOW,
|
||||
IWL_UCODE_TLV_DEBUG_MAX = IWL_UCODE_TLV_TYPE_TRIGGERS,
|
||||
|
||||
/* TLVs 0x1000-0x2000 are for internal driver usage */
|
||||
IWL_UCODE_TLV_FW_DBG_DUMP_LST = 0x1000,
|
||||
@ -323,6 +322,7 @@ enum iwl_ucode_tlv_api {
|
||||
IWL_UCODE_TLV_API_FTM_RTT_ACCURACY = (__force iwl_ucode_tlv_api_t)54,
|
||||
IWL_UCODE_TLV_API_SAR_TABLE_VER = (__force iwl_ucode_tlv_api_t)55,
|
||||
IWL_UCODE_TLV_API_ADWELL_HB_DEF_N_AP = (__force iwl_ucode_tlv_api_t)57,
|
||||
IWL_UCODE_TLV_API_SCAN_EXT_CHAN_VER = (__force iwl_ucode_tlv_api_t)58,
|
||||
|
||||
NUM_IWL_UCODE_TLV_API
|
||||
#ifdef __CHECKER__
|
||||
@ -441,9 +441,11 @@ enum iwl_ucode_tlv_capa {
|
||||
IWL_UCODE_TLV_CAPA_DYNAMIC_QUOTA = (__force iwl_ucode_tlv_capa_t)44,
|
||||
IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2 = (__force iwl_ucode_tlv_capa_t)45,
|
||||
IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD = (__force iwl_ucode_tlv_capa_t)46,
|
||||
IWL_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS = (__force iwl_ucode_tlv_capa_t)48,
|
||||
IWL_UCODE_TLV_CAPA_FTM_CALIBRATED = (__force iwl_ucode_tlv_capa_t)47,
|
||||
IWL_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS = (__force iwl_ucode_tlv_capa_t)48,
|
||||
IWL_UCODE_TLV_CAPA_CS_MODIFY = (__force iwl_ucode_tlv_capa_t)49,
|
||||
IWL_UCODE_TLV_CAPA_SET_LTR_GEN2 = (__force iwl_ucode_tlv_capa_t)50,
|
||||
IWL_UCODE_TLV_CAPA_SET_PPAG = (__force iwl_ucode_tlv_capa_t)52,
|
||||
|
||||
/* set 2 */
|
||||
IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64,
|
||||
@ -465,6 +467,8 @@ enum iwl_ucode_tlv_capa {
|
||||
IWL_UCODE_TLV_CAPA_LED_CMD_SUPPORT = (__force iwl_ucode_tlv_capa_t)88,
|
||||
IWL_UCODE_TLV_CAPA_MCC_UPDATE_11AX_SUPPORT = (__force iwl_ucode_tlv_capa_t)89,
|
||||
IWL_UCODE_TLV_CAPA_CSI_REPORTING = (__force iwl_ucode_tlv_capa_t)90,
|
||||
IWL_UCODE_TLV_CAPA_DBG_SUSPEND_RESUME_CMD_SUPP = (__force iwl_ucode_tlv_capa_t)92,
|
||||
IWL_UCODE_TLV_CAPA_DBG_BUF_ALLOC_CMD_SUPP = (__force iwl_ucode_tlv_capa_t)93,
|
||||
|
||||
/* set 3 */
|
||||
IWL_UCODE_TLV_CAPA_MLME_OFFLOAD = (__force iwl_ucode_tlv_capa_t)96,
|
||||
@ -521,6 +525,10 @@ enum iwl_fw_phy_cfg {
|
||||
FW_PHY_CFG_TX_CHAIN = 0xf << FW_PHY_CFG_TX_CHAIN_POS,
|
||||
FW_PHY_CFG_RX_CHAIN_POS = 20,
|
||||
FW_PHY_CFG_RX_CHAIN = 0xf << FW_PHY_CFG_RX_CHAIN_POS,
|
||||
FW_PHY_CFG_CHAIN_SAD_POS = 23,
|
||||
FW_PHY_CFG_CHAIN_SAD_ENABLED = 0x1 << FW_PHY_CFG_CHAIN_SAD_POS,
|
||||
FW_PHY_CFG_CHAIN_SAD_ANT_A = 0x2 << FW_PHY_CFG_CHAIN_SAD_POS,
|
||||
FW_PHY_CFG_CHAIN_SAD_ANT_B = 0x4 << FW_PHY_CFG_CHAIN_SAD_POS,
|
||||
FW_PHY_CFG_SHARED_CLK = BIT(31),
|
||||
};
|
||||
|
||||
@ -965,4 +973,19 @@ struct iwl_fw_cmd_version {
|
||||
u8 notif_ver;
|
||||
} __packed;
|
||||
|
||||
static inline size_t _iwl_tlv_array_len(const struct iwl_ucode_tlv *tlv,
|
||||
size_t fixed_size, size_t var_size)
|
||||
{
|
||||
size_t var_len = le32_to_cpu(tlv->length) - fixed_size;
|
||||
|
||||
if (WARN_ON(var_len % var_size))
|
||||
return 0;
|
||||
|
||||
return var_len / var_size;
|
||||
}
|
||||
|
||||
#define iwl_tlv_array_len(_tlv_ptr, _struct_ptr, _memb) \
|
||||
_iwl_tlv_array_len((_tlv_ptr), sizeof(*(_struct_ptr)), \
|
||||
sizeof(_struct_ptr->_memb[0]))
|
||||
|
||||
#endif /* __iwl_fw_file_h__ */
|
||||
|
@ -227,15 +227,6 @@ struct iwl_fw_dbg {
|
||||
u32 dump_mask;
|
||||
};
|
||||
|
||||
/**
|
||||
* @tlv: the buffer allocation tlv
|
||||
* @is_alloc: indicates if the buffer was already allocated
|
||||
*/
|
||||
struct iwl_fw_ini_allocation_data {
|
||||
struct iwl_fw_ini_allocation_tlv tlv;
|
||||
u32 is_alloc;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_fw_ini_active_triggers
|
||||
* @active: is this trigger active
|
||||
|
@ -81,8 +81,6 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
|
||||
INIT_DELAYED_WORK(&fwrt->dump.wks[i].wk, iwl_fw_error_dump_wk);
|
||||
}
|
||||
iwl_fwrt_dbgfs_register(fwrt, dbgfs_dir);
|
||||
timer_setup(&fwrt->dump.periodic_trig,
|
||||
iwl_fw_dbg_periodic_trig_handler, 0);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fw_runtime_init);
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -31,7 +31,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -322,7 +322,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->cfg->gen2)
|
||||
if (fwrt->trans->trans_cfg->gen2)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
|
@ -64,7 +64,6 @@
|
||||
#include "iwl-trans.h"
|
||||
#include "img.h"
|
||||
#include "fw/api/debug.h"
|
||||
#include "fw/api/dbg-tlv.h"
|
||||
#include "fw/api/paging.h"
|
||||
#include "iwl-eeprom-parse.h"
|
||||
|
||||
@ -91,6 +90,20 @@ struct iwl_fwrt_shared_mem_cfg {
|
||||
|
||||
#define IWL_FW_RUNTIME_DUMP_WK_NUM 5
|
||||
|
||||
/**
|
||||
* struct iwl_txf_iter_data - Tx fifo iterator data struct
|
||||
* @fifo: fifo number
|
||||
* @lmac: lmac number
|
||||
* @fifo_size: fifo size
|
||||
* @internal_txf: non zero if fifo is internal Tx fifo
|
||||
*/
|
||||
struct iwl_txf_iter_data {
|
||||
int fifo;
|
||||
int lmac;
|
||||
u32 fifo_size;
|
||||
u8 internal_txf;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_fw_runtime - runtime data for firmware
|
||||
* @fw: firmware image
|
||||
@ -144,8 +157,8 @@ struct iwl_fw_runtime {
|
||||
struct iwl_fw_ini_active_triggers active_trigs[IWL_FW_TRIGGER_ID_NUM];
|
||||
u32 lmac_err_id[MAX_NUM_LMAC];
|
||||
u32 umac_err_id;
|
||||
void *fifo_iter;
|
||||
struct timer_list periodic_trig;
|
||||
|
||||
struct iwl_txf_iter_data txf_iter_data;
|
||||
|
||||
u8 img_name[IWL_FW_INI_MAX_IMG_NAME_LEN];
|
||||
u8 internal_dbg_cfg_name[IWL_FW_INI_MAX_DBG_CFG_NAME_LEN];
|
||||
@ -190,6 +203,10 @@ static inline void iwl_fw_runtime_free(struct iwl_fw_runtime *fwrt)
|
||||
kfree(active->trig);
|
||||
active->trig = NULL;
|
||||
}
|
||||
|
||||
iwl_dbg_tlv_del_timers(fwrt->trans);
|
||||
for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++)
|
||||
cancel_delayed_work_sync(&fwrt->dump.wks[i].wk);
|
||||
}
|
||||
|
||||
void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt);
|
||||
|
@ -151,7 +151,7 @@ void iwl_get_shared_mem_conf(struct iwl_fw_runtime *fwrt)
|
||||
}
|
||||
|
||||
pkt = cmd.resp_pkt;
|
||||
if (fwrt->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000)
|
||||
if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000)
|
||||
iwl_parse_shared_mem_22000(fwrt, pkt);
|
||||
else
|
||||
iwl_parse_shared_mem(fwrt, pkt);
|
||||
|
@ -161,7 +161,8 @@ static inline u8 num_of_ant(u8 mask)
|
||||
!!((mask) & ANT_C);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* struct iwl_base_params - params not likely to change within a device 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
|
||||
@ -330,8 +331,37 @@ struct iwl_csr_params {
|
||||
u32 mac_addr1_strap;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_cfg_trans - information needed to start the trans
|
||||
*
|
||||
* These values cannot be changed when multiple configs are used for a
|
||||
* single PCI ID, because they are needed before the HW REV or RFID
|
||||
* can be read.
|
||||
*
|
||||
* @base_params: pointer to basic parameters
|
||||
* @csr: csr flags and addresses that are different across devices
|
||||
* @device_family: the device family
|
||||
* @umac_prph_offset: offset to add to UMAC periphery address
|
||||
* @rf_id: need to read rf_id to determine the firmware image
|
||||
* @use_tfh: use TFH
|
||||
* @gen2: 22000 and on transport operation
|
||||
* @mq_rx_supported: multi-queue rx support
|
||||
*/
|
||||
struct iwl_cfg_trans_params {
|
||||
const struct iwl_base_params *base_params;
|
||||
const struct iwl_csr_params *csr;
|
||||
enum iwl_device_family device_family;
|
||||
u32 umac_prph_offset;
|
||||
u32 rf_id:1,
|
||||
use_tfh:1,
|
||||
gen2:1,
|
||||
mq_rx_supported:1,
|
||||
bisr_workaround:1;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_cfg
|
||||
* @trans: the trans-specific configuration part
|
||||
* @name: Official name of the device
|
||||
* @fw_name_pre: Firmware filename prefix. The api version and extension
|
||||
* (.ucode) will be added to filename before loading from disk. The
|
||||
@ -346,10 +376,10 @@ struct iwl_csr_params {
|
||||
* @nvm_ver: NVM version
|
||||
* @nvm_calib_ver: NVM calibration version
|
||||
* @lib: pointer to the lib ops
|
||||
* @base_params: pointer to basic parameters
|
||||
* @ht_params: point to ht parameters
|
||||
* @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
|
||||
@ -358,7 +388,6 @@ struct iwl_csr_params {
|
||||
* @mac_addr_from_csr: read HW address from CSR registers
|
||||
* @features: hw features, any combination of feature_whitelist
|
||||
* @pwr_tx_backoffs: translation table between power limits and backoffs
|
||||
* @csr: csr flags and addresses that are different across devices
|
||||
* @max_rx_agg_size: max RX aggregation size of the ADDBA request/response
|
||||
* @max_tx_agg_size: max TX aggregation size of the ADDBA request/response
|
||||
* @max_ht_ampdu_factor: the exponent of the max length of A-MPDU that the
|
||||
@ -371,18 +400,14 @@ struct iwl_csr_params {
|
||||
* @dccm2_len: length of the second DCCM
|
||||
* @smem_offset: offset from which the SMEM begins
|
||||
* @smem_len: the length of SMEM
|
||||
* @mq_rx_supported: multi-queue rx support
|
||||
* @vht_mu_mimo_supported: VHT MU-MIMO support
|
||||
* @rf_id: need to read rf_id to determine the firmware image
|
||||
* @integrated: discrete or integrated
|
||||
* @gen2: 22000 and on transport operation
|
||||
* @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
|
||||
* @bisr_workaround: BISR hardware workaround (for 22260 series devices)
|
||||
* @min_txq_size: minimum number of slots required in a TX queue
|
||||
* @umac_prph_offset: offset to add to UMAC periphery address
|
||||
* @uhb_supported: ultra high band channels supported
|
||||
* @min_256_ba_txq_size: minimum number of slots required in a TX queue which
|
||||
* supports 256 BA aggregation
|
||||
@ -392,19 +417,16 @@ struct iwl_csr_params {
|
||||
* and/or the uCode API version instead.
|
||||
*/
|
||||
struct iwl_cfg {
|
||||
struct iwl_cfg_trans_params trans;
|
||||
/* params specific to an individual device within a device family */
|
||||
const char *name;
|
||||
const char *fw_name_pre;
|
||||
/* params not likely to change within a device family */
|
||||
const struct iwl_base_params *base_params;
|
||||
/* params likely to change within a device family */
|
||||
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;
|
||||
const struct iwl_csr_params *csr;
|
||||
enum iwl_device_family device_family;
|
||||
enum iwl_led_mode led_mode;
|
||||
enum iwl_nvm_type nvm_type;
|
||||
u32 max_data_size;
|
||||
@ -420,6 +442,7 @@ struct iwl_cfg {
|
||||
u16 nvm_ver;
|
||||
u16 nvm_calib_ver;
|
||||
u32 rx_with_siso_diversity:1,
|
||||
tx_with_siso_diversity:1,
|
||||
bt_shared_single_ant:1,
|
||||
internal_wimax_coex:1,
|
||||
host_interrupt_operation_mode:1,
|
||||
@ -428,15 +451,10 @@ struct iwl_cfg {
|
||||
lp_xtal_workaround:1,
|
||||
disable_dummy_notification:1,
|
||||
apmg_not_supported:1,
|
||||
mq_rx_supported:1,
|
||||
vht_mu_mimo_supported:1,
|
||||
rf_id:1,
|
||||
integrated:1,
|
||||
use_tfh:1,
|
||||
gen2:1,
|
||||
cdb:1,
|
||||
dbgc_supported:1,
|
||||
bisr_workaround:1,
|
||||
uhb_supported:1;
|
||||
u8 valid_tx_ant;
|
||||
u8 valid_rx_ant;
|
||||
@ -453,7 +471,6 @@ struct iwl_cfg {
|
||||
u32 d3_debug_data_base_addr;
|
||||
u32 d3_debug_data_length;
|
||||
u32 min_txq_size;
|
||||
u32 umac_prph_offset;
|
||||
u32 fw_mon_smem_write_ptr_addr;
|
||||
u32 fw_mon_smem_write_ptr_msk;
|
||||
u32 fw_mon_smem_cycle_cnt_ptr_addr;
|
||||
|
@ -60,149 +60,112 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#include <linux/firmware.h>
|
||||
#include "iwl-drv.h"
|
||||
#include "iwl-trans.h"
|
||||
#include "iwl-dbg-tlv.h"
|
||||
#include "fw/dbg.h"
|
||||
#include "fw/runtime.h"
|
||||
|
||||
void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
|
||||
bool ext)
|
||||
{
|
||||
struct iwl_apply_point_data *data;
|
||||
struct iwl_fw_ini_header *header = (void *)&tlv->data[0];
|
||||
u32 apply_point = le32_to_cpu(header->apply_point);
|
||||
|
||||
int copy_size = le32_to_cpu(tlv->length) + sizeof(*tlv);
|
||||
int offset_size = copy_size;
|
||||
|
||||
if (le32_to_cpu(header->tlv_version) != 1)
|
||||
return;
|
||||
|
||||
if (WARN_ONCE(apply_point >= IWL_FW_INI_APPLY_NUM,
|
||||
"Invalid apply point id %d\n", apply_point))
|
||||
return;
|
||||
|
||||
if (ext)
|
||||
data = &trans->dbg.apply_points_ext[apply_point];
|
||||
else
|
||||
data = &trans->dbg.apply_points[apply_point];
|
||||
|
||||
/* add room for is_alloc field in &iwl_fw_ini_allocation_data struct */
|
||||
if (le32_to_cpu(tlv->type) == IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION) {
|
||||
struct iwl_fw_ini_allocation_data *buf_alloc =
|
||||
(void *)tlv->data;
|
||||
|
||||
offset_size += sizeof(buf_alloc->is_alloc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure we still have room to copy this TLV. Offset points to the
|
||||
* location the last copy ended.
|
||||
/**
|
||||
* enum iwl_dbg_tlv_type - debug TLV types
|
||||
* @IWL_DBG_TLV_TYPE_DEBUG_INFO: debug info TLV
|
||||
* @IWL_DBG_TLV_TYPE_BUF_ALLOC: buffer allocation TLV
|
||||
* @IWL_DBG_TLV_TYPE_HCMD: host command TLV
|
||||
* @IWL_DBG_TLV_TYPE_REGION: region TLV
|
||||
* @IWL_DBG_TLV_TYPE_TRIGGER: trigger TLV
|
||||
* @IWL_DBG_TLV_TYPE_NUM: number of debug TLVs
|
||||
*/
|
||||
if (WARN_ONCE(data->offset + offset_size > data->size,
|
||||
"Not enough memory for apply point %d\n",
|
||||
apply_point))
|
||||
return;
|
||||
enum iwl_dbg_tlv_type {
|
||||
IWL_DBG_TLV_TYPE_DEBUG_INFO =
|
||||
IWL_UCODE_TLV_TYPE_DEBUG_INFO - IWL_UCODE_TLV_DEBUG_BASE,
|
||||
IWL_DBG_TLV_TYPE_BUF_ALLOC,
|
||||
IWL_DBG_TLV_TYPE_HCMD,
|
||||
IWL_DBG_TLV_TYPE_REGION,
|
||||
IWL_DBG_TLV_TYPE_TRIGGER,
|
||||
IWL_DBG_TLV_TYPE_NUM,
|
||||
};
|
||||
|
||||
memcpy(data->data + data->offset, (void *)tlv, copy_size);
|
||||
data->offset += offset_size;
|
||||
/**
|
||||
* struct iwl_dbg_tlv_ver_data - debug TLV version struct
|
||||
* @min_ver: min version supported
|
||||
* @max_ver: max version supported
|
||||
*/
|
||||
struct iwl_dbg_tlv_ver_data {
|
||||
int min_ver;
|
||||
int max_ver;
|
||||
};
|
||||
|
||||
static const struct iwl_dbg_tlv_ver_data
|
||||
dbg_ver_table[IWL_DBG_TLV_TYPE_NUM] = {
|
||||
[IWL_DBG_TLV_TYPE_DEBUG_INFO] = {.min_ver = 1, .max_ver = 1,},
|
||||
[IWL_DBG_TLV_TYPE_BUF_ALLOC] = {.min_ver = 1, .max_ver = 1,},
|
||||
[IWL_DBG_TLV_TYPE_HCMD] = {.min_ver = 1, .max_ver = 1,},
|
||||
[IWL_DBG_TLV_TYPE_REGION] = {.min_ver = 1, .max_ver = 1,},
|
||||
[IWL_DBG_TLV_TYPE_TRIGGER] = {.min_ver = 1, .max_ver = 1,},
|
||||
};
|
||||
|
||||
static bool iwl_dbg_tlv_ver_support(struct iwl_ucode_tlv *tlv)
|
||||
{
|
||||
struct iwl_fw_ini_header *hdr = (void *)&tlv->data[0];
|
||||
u32 type = le32_to_cpu(tlv->type);
|
||||
u32 tlv_idx = type - IWL_UCODE_TLV_DEBUG_BASE;
|
||||
u32 ver = le32_to_cpu(hdr->tlv_version);
|
||||
|
||||
if (ver < dbg_ver_table[tlv_idx].min_ver ||
|
||||
ver > dbg_ver_table[tlv_idx].max_ver)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data,
|
||||
void iwl_dbg_tlv_alloc(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
|
||||
bool ext)
|
||||
{
|
||||
struct iwl_ucode_tlv *tlv;
|
||||
u32 size[IWL_FW_INI_APPLY_NUM] = {0};
|
||||
int i;
|
||||
|
||||
while (len >= sizeof(*tlv)) {
|
||||
u32 tlv_len, tlv_type, apply;
|
||||
struct iwl_fw_ini_header *hdr;
|
||||
|
||||
len -= sizeof(*tlv);
|
||||
tlv = (void *)data;
|
||||
|
||||
tlv_len = le32_to_cpu(tlv->length);
|
||||
tlv_type = le32_to_cpu(tlv->type);
|
||||
|
||||
if (len < tlv_len)
|
||||
return;
|
||||
|
||||
len -= ALIGN(tlv_len, 4);
|
||||
data += sizeof(*tlv) + ALIGN(tlv_len, 4);
|
||||
|
||||
if (tlv_type < IWL_UCODE_TLV_DEBUG_BASE ||
|
||||
tlv_type > IWL_UCODE_TLV_DEBUG_MAX)
|
||||
continue;
|
||||
|
||||
hdr = (void *)&tlv->data[0];
|
||||
apply = le32_to_cpu(hdr->apply_point);
|
||||
|
||||
if (le32_to_cpu(hdr->tlv_version) != 1)
|
||||
continue;
|
||||
struct iwl_fw_ini_header *hdr = (void *)&tlv->data[0];
|
||||
u32 type = le32_to_cpu(tlv->type);
|
||||
u32 pnt = le32_to_cpu(hdr->apply_point);
|
||||
u32 tlv_idx = type - IWL_UCODE_TLV_DEBUG_BASE;
|
||||
enum iwl_ini_cfg_state *cfg_state = ext ?
|
||||
&trans->dbg.external_ini_cfg : &trans->dbg.internal_ini_cfg;
|
||||
|
||||
IWL_DEBUG_FW(trans, "WRT: read TLV 0x%x, apply point %d\n",
|
||||
le32_to_cpu(tlv->type), apply);
|
||||
type, pnt);
|
||||
|
||||
if (WARN_ON(apply >= IWL_FW_INI_APPLY_NUM))
|
||||
continue;
|
||||
|
||||
/* add room for is_alloc field in &iwl_fw_ini_allocation_data
|
||||
* struct
|
||||
*/
|
||||
if (tlv_type == IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION) {
|
||||
struct iwl_fw_ini_allocation_data *buf_alloc =
|
||||
(void *)tlv->data;
|
||||
|
||||
size[apply] += sizeof(buf_alloc->is_alloc);
|
||||
if (tlv_idx >= IWL_DBG_TLV_TYPE_NUM) {
|
||||
IWL_ERR(trans, "WRT: Unsupported TLV 0x%x\n", type);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
size[apply] += sizeof(*tlv) + tlv_len;
|
||||
if (!iwl_dbg_tlv_ver_support(tlv)) {
|
||||
IWL_ERR(trans, "WRT: Unsupported TLV 0x%x version %u\n", type,
|
||||
le32_to_cpu(hdr->tlv_version));
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(size); i++) {
|
||||
void *mem;
|
||||
if (*cfg_state == IWL_INI_CFG_STATE_NOT_LOADED)
|
||||
*cfg_state = IWL_INI_CFG_STATE_LOADED;
|
||||
|
||||
if (!size[i])
|
||||
continue;
|
||||
|
||||
mem = kzalloc(size[i], GFP_KERNEL);
|
||||
|
||||
if (!mem) {
|
||||
IWL_ERR(trans, "No memory for apply point %d\n", i);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ext) {
|
||||
trans->dbg.apply_points_ext[i].data = mem;
|
||||
trans->dbg.apply_points_ext[i].size = size[i];
|
||||
} else {
|
||||
trans->dbg.apply_points[i].data = mem;
|
||||
trans->dbg.apply_points[i].size = size[i];
|
||||
}
|
||||
|
||||
trans->dbg.ini_valid = true;
|
||||
}
|
||||
out_err:
|
||||
*cfg_state = IWL_INI_CFG_STATE_CORRUPTED;
|
||||
}
|
||||
|
||||
void iwl_fw_dbg_free(struct iwl_trans *trans)
|
||||
void iwl_dbg_tlv_del_timers(struct iwl_trans *trans)
|
||||
{
|
||||
int i;
|
||||
/* will be used later */
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_dbg_tlv_del_timers);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(trans->dbg.apply_points); i++) {
|
||||
kfree(trans->dbg.apply_points[i].data);
|
||||
trans->dbg.apply_points[i].size = 0;
|
||||
trans->dbg.apply_points[i].offset = 0;
|
||||
|
||||
kfree(trans->dbg.apply_points_ext[i].data);
|
||||
trans->dbg.apply_points_ext[i].size = 0;
|
||||
trans->dbg.apply_points_ext[i].offset = 0;
|
||||
}
|
||||
void iwl_dbg_tlv_free(struct iwl_trans *trans)
|
||||
{
|
||||
/* will be used again later */
|
||||
}
|
||||
|
||||
static int iwl_parse_fw_dbg_tlv(struct iwl_trans *trans, const u8 *data,
|
||||
static int iwl_dbg_tlv_parse_bin(struct iwl_trans *trans, const u8 *data,
|
||||
size_t len)
|
||||
{
|
||||
struct iwl_ucode_tlv *tlv;
|
||||
enum iwl_ucode_tlv_type tlv_type;
|
||||
u32 tlv_len;
|
||||
|
||||
while (len >= sizeof(*tlv)) {
|
||||
@ -210,7 +173,6 @@ static int iwl_parse_fw_dbg_tlv(struct iwl_trans *trans, const u8 *data,
|
||||
tlv = (void *)data;
|
||||
|
||||
tlv_len = le32_to_cpu(tlv->length);
|
||||
tlv_type = le32_to_cpu(tlv->type);
|
||||
|
||||
if (len < tlv_len) {
|
||||
IWL_ERR(trans, "invalid TLV len: %zd/%u\n",
|
||||
@ -220,39 +182,33 @@ static int iwl_parse_fw_dbg_tlv(struct iwl_trans *trans, const u8 *data,
|
||||
len -= ALIGN(tlv_len, 4);
|
||||
data += sizeof(*tlv) + ALIGN(tlv_len, 4);
|
||||
|
||||
switch (tlv_type) {
|
||||
case IWL_UCODE_TLV_TYPE_DEBUG_INFO:
|
||||
case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION:
|
||||
case IWL_UCODE_TLV_TYPE_HCMD:
|
||||
case IWL_UCODE_TLV_TYPE_REGIONS:
|
||||
case IWL_UCODE_TLV_TYPE_TRIGGERS:
|
||||
case IWL_UCODE_TLV_TYPE_DEBUG_FLOW:
|
||||
iwl_fw_dbg_copy_tlv(trans, tlv, true);
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(1, "Invalid TLV %x\n", tlv_type);
|
||||
break;
|
||||
}
|
||||
iwl_dbg_tlv_alloc(trans, tlv, true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void iwl_load_fw_dbg_tlv(struct device *dev, struct iwl_trans *trans)
|
||||
void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans)
|
||||
{
|
||||
const struct firmware *fw;
|
||||
int res;
|
||||
|
||||
if (trans->dbg.external_ini_loaded || !iwlwifi_mod_params.enable_ini)
|
||||
if (!iwlwifi_mod_params.enable_ini)
|
||||
return;
|
||||
|
||||
res = request_firmware(&fw, "iwl-dbg-tlv.ini", dev);
|
||||
if (res)
|
||||
return;
|
||||
|
||||
iwl_alloc_dbg_tlv(trans, fw->size, fw->data, true);
|
||||
iwl_parse_fw_dbg_tlv(trans, fw->data, fw->size);
|
||||
iwl_dbg_tlv_parse_bin(trans, fw->data, fw->size);
|
||||
|
||||
trans->dbg.external_ini_loaded = true;
|
||||
release_firmware(fw);
|
||||
}
|
||||
|
||||
void iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt,
|
||||
enum iwl_fw_ini_time_point tp_id,
|
||||
union iwl_dbg_tlv_tp_data *tp_data)
|
||||
{
|
||||
/* will be used later */
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_dbg_tlv_time_point);
|
||||
|
@ -5,7 +5,7 @@
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* Copyright (C) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -28,7 +28,7 @@
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* Copyright (C) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -66,22 +66,32 @@
|
||||
|
||||
/**
|
||||
* struct iwl_apply_point_data
|
||||
* @data: start address of this apply point data
|
||||
* @size total size of the data
|
||||
* @offset: current offset of the copied data
|
||||
* @list: list to go through the TLVs of the apply point
|
||||
* @tlv: a debug TLV
|
||||
*/
|
||||
struct iwl_apply_point_data {
|
||||
void *data;
|
||||
int size;
|
||||
int offset;
|
||||
struct list_head list;
|
||||
struct iwl_ucode_tlv tlv;
|
||||
};
|
||||
|
||||
/**
|
||||
* union iwl_dbg_tlv_tp_data - data that is given in a time point
|
||||
* @fw_pkt: a packet received from the FW
|
||||
*/
|
||||
union iwl_dbg_tlv_tp_data {
|
||||
struct iwl_rx_packet *fw_pkt;
|
||||
};
|
||||
|
||||
struct iwl_trans;
|
||||
void iwl_load_fw_dbg_tlv(struct device *dev, struct iwl_trans *trans);
|
||||
void iwl_fw_dbg_free(struct iwl_trans *trans);
|
||||
void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
|
||||
bool ext);
|
||||
void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data,
|
||||
struct iwl_fw_runtime;
|
||||
|
||||
void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans);
|
||||
void iwl_dbg_tlv_free(struct iwl_trans *trans);
|
||||
void iwl_dbg_tlv_alloc(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
|
||||
bool ext);
|
||||
void iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt,
|
||||
enum iwl_fw_ini_time_point tp_id,
|
||||
union iwl_dbg_tlv_tp_data *tp_data);
|
||||
void iwl_dbg_tlv_del_timers(struct iwl_trans *trans);
|
||||
|
||||
#endif /* __iwl_dbg_tlv_h__*/
|
||||
|
@ -75,7 +75,6 @@ static inline size_t iwl_rx_trace_len(const struct iwl_trans *trans,
|
||||
|
||||
#include <linux/tracepoint.h>
|
||||
#include <linux/device.h>
|
||||
#include "iwl-trans.h"
|
||||
|
||||
|
||||
#if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__)
|
||||
|
@ -215,7 +215,7 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
|
||||
const struct iwl_cfg *cfg = drv->trans->cfg;
|
||||
char tag[8];
|
||||
|
||||
if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_9000 &&
|
||||
if (drv->trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_9000 &&
|
||||
(CSR_HW_REV_STEP(drv->trans->hw_rev) != SILICON_B_STEP &&
|
||||
CSR_HW_REV_STEP(drv->trans->hw_rev) != SILICON_C_STEP)) {
|
||||
IWL_ERR(drv,
|
||||
@ -647,9 +647,6 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
|
||||
len -= sizeof(*ucode);
|
||||
|
||||
if (iwlwifi_mod_params.enable_ini)
|
||||
iwl_alloc_dbg_tlv(drv->trans, len, data, false);
|
||||
|
||||
while (len >= sizeof(*tlv)) {
|
||||
len -= sizeof(*tlv);
|
||||
tlv = (void *)data;
|
||||
@ -1123,7 +1120,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
|
||||
if (tlv_len != sizeof(*dbg_ptrs))
|
||||
goto invalid_tlv_len;
|
||||
if (drv->trans->cfg->device_family <
|
||||
if (drv->trans->trans_cfg->device_family <
|
||||
IWL_DEVICE_FAMILY_22000)
|
||||
break;
|
||||
drv->trans->dbg.umac_error_event_table =
|
||||
@ -1139,7 +1136,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
|
||||
if (tlv_len != sizeof(*dbg_ptrs))
|
||||
goto invalid_tlv_len;
|
||||
if (drv->trans->cfg->device_family <
|
||||
if (drv->trans->trans_cfg->device_family <
|
||||
IWL_DEVICE_FAMILY_22000)
|
||||
break;
|
||||
drv->trans->dbg.lmac_error_event_table[0] =
|
||||
@ -1154,9 +1151,8 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
case IWL_UCODE_TLV_TYPE_HCMD:
|
||||
case IWL_UCODE_TLV_TYPE_REGIONS:
|
||||
case IWL_UCODE_TLV_TYPE_TRIGGERS:
|
||||
case IWL_UCODE_TLV_TYPE_DEBUG_FLOW:
|
||||
if (iwlwifi_mod_params.enable_ini)
|
||||
iwl_fw_dbg_copy_tlv(drv->trans, tlv, false);
|
||||
iwl_dbg_tlv_alloc(drv->trans, tlv, false);
|
||||
break;
|
||||
case IWL_UCODE_TLV_CMD_VERSIONS:
|
||||
if (tlv_len % sizeof(struct iwl_fw_cmd_version)) {
|
||||
@ -1526,14 +1522,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->cfg->base_params->max_event_log_size;
|
||||
drv->trans->trans_cfg->base_params->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->cfg->base_params->max_event_log_size;
|
||||
drv->trans->trans_cfg->base_params->max_event_log_size;
|
||||
fw->inst_errlog_ptr = pieces->inst_errlog_ptr;
|
||||
|
||||
/*
|
||||
@ -1640,7 +1636,7 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans)
|
||||
init_completion(&drv->request_firmware_complete);
|
||||
INIT_LIST_HEAD(&drv->list);
|
||||
|
||||
iwl_load_fw_dbg_tlv(drv->trans->dev, drv->trans);
|
||||
iwl_dbg_tlv_load_bin(drv->trans->dev, drv->trans);
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
/* Create the device debugfs entries. */
|
||||
@ -1662,8 +1658,8 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans)
|
||||
err_fw:
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
debugfs_remove_recursive(drv->dbgfs_drv);
|
||||
iwl_dbg_tlv_free(drv->trans);
|
||||
#endif
|
||||
iwl_fw_dbg_free(drv->trans);
|
||||
kfree(drv);
|
||||
err:
|
||||
return ERR_PTR(ret);
|
||||
@ -1693,7 +1689,7 @@ void iwl_drv_stop(struct iwl_drv *drv)
|
||||
debugfs_remove_recursive(drv->dbgfs_drv);
|
||||
#endif
|
||||
|
||||
iwl_fw_dbg_free(drv->trans);
|
||||
iwl_dbg_tlv_free(drv->trans);
|
||||
|
||||
kfree(drv);
|
||||
}
|
||||
@ -1704,8 +1700,6 @@ struct iwl_mod_params iwlwifi_mod_params = {
|
||||
.fw_restart = true,
|
||||
.bt_coex_active = true,
|
||||
.power_level = IWL_POWER_INDEX_1,
|
||||
.d0i3_disable = true,
|
||||
.d0i3_timeout = 1000,
|
||||
.uapsd_disable = IWL_DISABLE_UAPSD_BSS | IWL_DISABLE_UAPSD_P2P_CLIENT,
|
||||
/* the rest are 0 by default */
|
||||
};
|
||||
@ -1823,9 +1817,6 @@ MODULE_PARM_DESC(antenna_coupling,
|
||||
module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, 0444);
|
||||
MODULE_PARM_DESC(nvm_file, "NVM file name");
|
||||
|
||||
module_param_named(d0i3_disable, iwlwifi_mod_params.d0i3_disable, bool, 0444);
|
||||
MODULE_PARM_DESC(d0i3_disable, "disable d0i3 functionality (default: Y)");
|
||||
|
||||
module_param_named(lar_disable, iwlwifi_mod_params.lar_disable, bool, 0444);
|
||||
MODULE_PARM_DESC(lar_disable, "disable LAR functionality (default: N)");
|
||||
|
||||
@ -1873,9 +1864,6 @@ module_param_named(fw_monitor, iwlwifi_mod_params.fw_monitor, bool, 0444);
|
||||
MODULE_PARM_DESC(fw_monitor,
|
||||
"firmware monitor - to debug FW (default: false - needs lots of memory)");
|
||||
|
||||
module_param_named(d0i3_timeout, iwlwifi_mod_params.d0i3_timeout, uint, 0444);
|
||||
MODULE_PARM_DESC(d0i3_timeout, "Timeout to D0i3 entry when idle (ms)");
|
||||
|
||||
module_param_named(disable_11ac, iwlwifi_mod_params.disable_11ac, bool, 0444);
|
||||
MODULE_PARM_DESC(disable_11ac, "Disable VHT capabilities (default: false)");
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -29,7 +29,7 @@
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -728,12 +728,13 @@ int iwl_init_sband_channels(struct iwl_nvm_data *data,
|
||||
#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
|
||||
#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
|
||||
|
||||
void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
|
||||
void iwl_init_ht_hw_capab(struct iwl_trans *trans,
|
||||
struct iwl_nvm_data *data,
|
||||
struct ieee80211_sta_ht_cap *ht_info,
|
||||
enum nl80211_band band,
|
||||
u8 tx_chains, u8 rx_chains)
|
||||
{
|
||||
const struct iwl_cfg *cfg = trans->cfg;
|
||||
int max_bit_rate = 0;
|
||||
|
||||
tx_chains = hweight8(tx_chains);
|
||||
@ -765,7 +766,7 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
|
||||
if (cfg->ht_params->ldpc)
|
||||
ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
|
||||
|
||||
if ((cfg->mq_rx_supported &&
|
||||
if ((trans->trans_cfg->mq_rx_supported &&
|
||||
iwlwifi_mod_params.amsdu_size == IWL_AMSDU_DEF) ||
|
||||
iwlwifi_mod_params.amsdu_size >= IWL_AMSDU_8K)
|
||||
ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
|
||||
@ -805,10 +806,11 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
|
||||
}
|
||||
}
|
||||
|
||||
static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
|
||||
static void iwl_init_sbands(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
struct iwl_nvm_data *data,
|
||||
const u8 *eeprom, size_t eeprom_size)
|
||||
{
|
||||
struct device *dev = trans->dev;
|
||||
int n_channels = iwl_init_channel_map(dev, cfg, data,
|
||||
eeprom, eeprom_size);
|
||||
int n_used = 0;
|
||||
@ -820,7 +822,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
|
||||
sband->n_bitrates = N_RATES_24;
|
||||
n_used += iwl_init_sband_channels(data, sband, n_channels,
|
||||
NL80211_BAND_2GHZ);
|
||||
iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, NL80211_BAND_2GHZ,
|
||||
iwl_init_ht_hw_capab(trans, data, &sband->ht_cap, NL80211_BAND_2GHZ,
|
||||
data->valid_tx_ant, data->valid_rx_ant);
|
||||
|
||||
sband = &data->bands[NL80211_BAND_5GHZ];
|
||||
@ -829,7 +831,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
|
||||
sband->n_bitrates = N_RATES_52;
|
||||
n_used += iwl_init_sband_channels(data, sband, n_channels,
|
||||
NL80211_BAND_5GHZ);
|
||||
iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, NL80211_BAND_5GHZ,
|
||||
iwl_init_ht_hw_capab(trans, data, &sband->ht_cap, NL80211_BAND_5GHZ,
|
||||
data->valid_tx_ant, data->valid_rx_ant);
|
||||
|
||||
if (n_channels != n_used)
|
||||
@ -840,10 +842,11 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
|
||||
/* EEPROM data functions */
|
||||
|
||||
struct iwl_nvm_data *
|
||||
iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg,
|
||||
iwl_parse_eeprom_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
const u8 *eeprom, size_t eeprom_size)
|
||||
{
|
||||
struct iwl_nvm_data *data;
|
||||
struct device *dev = trans->dev;
|
||||
const void *tmp;
|
||||
u16 radio_cfg, sku;
|
||||
|
||||
@ -918,7 +921,7 @@ iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg,
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
iwl_init_sbands(dev, cfg, data, eeprom, eeprom_size);
|
||||
iwl_init_sbands(trans, cfg, data, eeprom, eeprom_size);
|
||||
|
||||
return data;
|
||||
err_free:
|
||||
|
@ -116,14 +116,14 @@ struct iwl_nvm_data {
|
||||
* later with iwl_free_nvm_data().
|
||||
*/
|
||||
struct iwl_nvm_data *
|
||||
iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg,
|
||||
iwl_parse_eeprom_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
const u8 *eeprom, size_t eeprom_size);
|
||||
|
||||
int iwl_init_sband_channels(struct iwl_nvm_data *data,
|
||||
struct ieee80211_supported_band *sband,
|
||||
int n_channels, enum nl80211_band band);
|
||||
|
||||
void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
|
||||
void iwl_init_ht_hw_capab(struct iwl_trans *trans,
|
||||
struct iwl_nvm_data *data,
|
||||
struct ieee80211_sta_ht_cap *ht_info,
|
||||
enum nl80211_band band,
|
||||
|
@ -6,7 +6,7 @@
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -27,7 +27,7 @@
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -193,7 +193,7 @@ static int iwl_init_otp_access(struct iwl_trans *trans)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = iwl_finish_nic_init(trans);
|
||||
ret = iwl_finish_nic_init(trans, trans->trans_cfg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -207,7 +207,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->cfg->base_params->shadow_ram_support)
|
||||
if (trans->trans_cfg->base_params->shadow_ram_support)
|
||||
iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
|
||||
CSR_RESET_LINK_PWR_MGMT_DISABLED);
|
||||
|
||||
@ -328,7 +328,7 @@ static int iwl_find_otp_image(struct iwl_trans *trans,
|
||||
}
|
||||
/* more in the link list, continue */
|
||||
usedblocks++;
|
||||
} while (usedblocks <= trans->cfg->base_params->max_ll_items);
|
||||
} while (usedblocks <= trans->trans_cfg->base_params->max_ll_items);
|
||||
|
||||
/* OTP has no valid blocks */
|
||||
IWL_DEBUG_EEPROM(trans->dev, "OTP has no valid blocks\n");
|
||||
@ -361,7 +361,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->cfg->base_params->eeprom_size;
|
||||
sz = trans->trans_cfg->base_params->eeprom_size;
|
||||
IWL_DEBUG_EEPROM(trans->dev, "NVM size = %d\n", sz);
|
||||
|
||||
e = kmalloc(sz, GFP_KERNEL);
|
||||
@ -396,7 +396,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->cfg->base_params->shadow_ram_support) {
|
||||
if (!trans->trans_cfg->base_params->shadow_ram_support) {
|
||||
ret = iwl_find_otp_image(trans, &validblockaddr);
|
||||
if (ret)
|
||||
goto err_unlock;
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -29,7 +29,7 @@
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -127,7 +127,7 @@
|
||||
static inline unsigned int FH_MEM_CBBC_QUEUE(struct iwl_trans *trans,
|
||||
unsigned int chnl)
|
||||
{
|
||||
if (trans->cfg->use_tfh) {
|
||||
if (trans->trans_cfg->use_tfh) {
|
||||
WARN_ON_ONCE(chnl >= 64);
|
||||
return TFH_TFDQ_CBB_TABLE + 8 * chnl;
|
||||
}
|
||||
|
@ -304,10 +304,10 @@ IWL_EXPORT_SYMBOL(iwl_clear_bits_prph);
|
||||
|
||||
void iwl_force_nmi(struct iwl_trans *trans)
|
||||
{
|
||||
if (trans->cfg->device_family < IWL_DEVICE_FAMILY_9000)
|
||||
if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000)
|
||||
iwl_write_prph(trans, DEVICE_SET_NMI_REG,
|
||||
DEVICE_SET_NMI_VAL_DRV);
|
||||
else if (trans->cfg->device_family < IWL_DEVICE_FAMILY_AX210)
|
||||
else if (trans->trans_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_MSK);
|
||||
else
|
||||
@ -458,7 +458,7 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf)
|
||||
FH_TSSR_TX_ERROR_REG
|
||||
};
|
||||
|
||||
if (trans->cfg->mq_rx_supported)
|
||||
if (trans->trans_cfg->mq_rx_supported)
|
||||
return iwl_dump_rfh(trans, buf);
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
@ -492,11 +492,12 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iwl_finish_nic_init(struct iwl_trans *trans)
|
||||
int iwl_finish_nic_init(struct iwl_trans *trans,
|
||||
const struct iwl_cfg_trans_params *cfg_trans)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (trans->cfg->bisr_workaround) {
|
||||
if (cfg_trans->bisr_workaround) {
|
||||
/* ensure the TOP FSM isn't still in previous reset */
|
||||
mdelay(2);
|
||||
}
|
||||
@ -506,9 +507,9 @@ int iwl_finish_nic_init(struct iwl_trans *trans)
|
||||
* D0U* --> D0A* (powered-up active) state.
|
||||
*/
|
||||
iwl_set_bit(trans, CSR_GP_CNTRL,
|
||||
BIT(trans->cfg->csr->flag_init_done));
|
||||
BIT(cfg_trans->csr->flag_init_done));
|
||||
|
||||
if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
|
||||
if (cfg_trans->device_family == IWL_DEVICE_FAMILY_8000)
|
||||
udelay(2);
|
||||
|
||||
/*
|
||||
@ -517,13 +518,13 @@ int iwl_finish_nic_init(struct iwl_trans *trans)
|
||||
* and accesses to uCode SRAM.
|
||||
*/
|
||||
err = iwl_poll_bit(trans, CSR_GP_CNTRL,
|
||||
BIT(trans->cfg->csr->flag_mac_clock_ready),
|
||||
BIT(trans->cfg->csr->flag_mac_clock_ready),
|
||||
BIT(cfg_trans->csr->flag_mac_clock_ready),
|
||||
BIT(cfg_trans->csr->flag_mac_clock_ready),
|
||||
25000);
|
||||
if (err < 0)
|
||||
IWL_DEBUG_INFO(trans, "Failed to wake NIC\n");
|
||||
|
||||
if (trans->cfg->bisr_workaround) {
|
||||
if (cfg_trans->bisr_workaround) {
|
||||
/* ensure BISR shift has finished */
|
||||
udelay(200);
|
||||
}
|
||||
|
@ -99,7 +99,8 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
|
||||
void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask);
|
||||
void iwl_force_nmi(struct iwl_trans *trans);
|
||||
|
||||
int iwl_finish_nic_init(struct iwl_trans *trans);
|
||||
int iwl_finish_nic_init(struct iwl_trans *trans,
|
||||
const struct iwl_cfg_trans_params *cfg_trans);
|
||||
|
||||
/* Error handling */
|
||||
int iwl_dump_fh(struct iwl_trans *trans, char **buf);
|
||||
@ -111,35 +112,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->cfg->umac_prph_offset;
|
||||
return ofs + trans->cfg->trans.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->cfg->umac_prph_offset);
|
||||
return iwl_read_prph_no_grab(trans, ofs +
|
||||
trans->cfg->trans.umac_prph_offset);
|
||||
}
|
||||
|
||||
static inline u32 iwl_read_umac_prph(struct iwl_trans *trans, u32 ofs)
|
||||
{
|
||||
return iwl_read_prph(trans, ofs + trans->cfg->umac_prph_offset);
|
||||
return iwl_read_prph(trans, ofs + trans->cfg->trans.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->cfg->umac_prph_offset, val);
|
||||
iwl_write_prph_no_grab(trans, ofs + trans->cfg->trans.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->cfg->umac_prph_offset, val);
|
||||
iwl_write_prph(trans, ofs + trans->cfg->trans.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->cfg->umac_prph_offset,
|
||||
return iwl_poll_prph_bit(trans, addr +
|
||||
trans->cfg->trans.umac_prph_offset,
|
||||
bits, mask, timeout);
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -27,7 +27,7 @@
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -115,9 +115,6 @@ enum iwl_uapsd_disable {
|
||||
* @nvm_file: specifies a external NVM file
|
||||
* @uapsd_disable: disable U-APSD, see &enum iwl_uapsd_disable, default =
|
||||
* IWL_DISABLE_UAPSD_BSS | IWL_DISABLE_UAPSD_P2P_CLIENT
|
||||
* @d0i3_disable: disable d0i3, default = 1,
|
||||
* @d0i3_timeout: time to wait after no refs are taken before
|
||||
* entering D0i3 (in msecs)
|
||||
* @lar_disable: disable LAR (regulatory), default = 0
|
||||
* @fw_monitor: allow to use firmware monitor
|
||||
* @disable_11ac: disable VHT capabilities, default = false.
|
||||
@ -139,8 +136,6 @@ struct iwl_mod_params {
|
||||
int antenna_coupling;
|
||||
char *nvm_file;
|
||||
u32 uapsd_disable;
|
||||
bool d0i3_disable;
|
||||
unsigned int d0i3_timeout;
|
||||
bool lar_disable;
|
||||
bool fw_monitor;
|
||||
bool disable_11ac;
|
||||
|
@ -393,11 +393,12 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
|
||||
return n_channels;
|
||||
}
|
||||
|
||||
static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
|
||||
static void iwl_init_vht_hw_capab(struct iwl_trans *trans,
|
||||
struct iwl_nvm_data *data,
|
||||
struct ieee80211_sta_vht_cap *vht_cap,
|
||||
u8 tx_chains, u8 rx_chains)
|
||||
{
|
||||
const struct iwl_cfg *cfg = trans->cfg;
|
||||
int num_rx_ants = num_of_ant(rx_chains);
|
||||
int num_tx_ants = num_of_ant(tx_chains);
|
||||
unsigned int max_ampdu_exponent = (cfg->max_vht_ampdu_exponent ?:
|
||||
@ -434,14 +435,14 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
|
||||
|
||||
switch (iwlwifi_mod_params.amsdu_size) {
|
||||
case IWL_AMSDU_DEF:
|
||||
if (cfg->mq_rx_supported)
|
||||
if (trans->trans_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 (cfg->mq_rx_supported)
|
||||
if (trans->trans_cfg->mq_rx_supported)
|
||||
vht_cap->cap |=
|
||||
IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
|
||||
else
|
||||
@ -669,11 +670,13 @@ static void iwl_init_he_hw_capab(struct ieee80211_supported_band *sband,
|
||||
}
|
||||
}
|
||||
|
||||
static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
|
||||
static void iwl_init_sbands(struct iwl_trans *trans,
|
||||
struct iwl_nvm_data *data,
|
||||
const void *nvm_ch_flags, u8 tx_chains,
|
||||
u8 rx_chains, u32 sbands_flags, bool v4)
|
||||
{
|
||||
struct device *dev = trans->dev;
|
||||
const struct iwl_cfg *cfg = trans->cfg;
|
||||
int n_channels;
|
||||
int n_used = 0;
|
||||
struct ieee80211_supported_band *sband;
|
||||
@ -686,7 +689,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
|
||||
sband->n_bitrates = N_RATES_24;
|
||||
n_used += iwl_init_sband_channels(data, sband, n_channels,
|
||||
NL80211_BAND_2GHZ);
|
||||
iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, NL80211_BAND_2GHZ,
|
||||
iwl_init_ht_hw_capab(trans, data, &sband->ht_cap, NL80211_BAND_2GHZ,
|
||||
tx_chains, rx_chains);
|
||||
|
||||
if (data->sku_cap_11ax_enable && !iwlwifi_mod_params.disable_11ax)
|
||||
@ -698,10 +701,10 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
|
||||
sband->n_bitrates = N_RATES_52;
|
||||
n_used += iwl_init_sband_channels(data, sband, n_channels,
|
||||
NL80211_BAND_5GHZ);
|
||||
iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, NL80211_BAND_5GHZ,
|
||||
iwl_init_ht_hw_capab(trans, data, &sband->ht_cap, NL80211_BAND_5GHZ,
|
||||
tx_chains, rx_chains);
|
||||
if (data->sku_cap_11ac_enable && !iwlwifi_mod_params.disable_11ac)
|
||||
iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap,
|
||||
iwl_init_vht_hw_capab(trans, data, &sband->vht_cap,
|
||||
tx_chains, rx_chains);
|
||||
|
||||
if (data->sku_cap_11ax_enable && !iwlwifi_mod_params.disable_11ax)
|
||||
@ -793,10 +796,10 @@ static void iwl_set_hw_address_from_csr(struct iwl_trans *trans,
|
||||
{
|
||||
__le32 mac_addr0 =
|
||||
cpu_to_le32(iwl_read32(trans,
|
||||
trans->cfg->csr->mac_addr0_strap));
|
||||
trans->trans_cfg->csr->mac_addr0_strap));
|
||||
__le32 mac_addr1 =
|
||||
cpu_to_le32(iwl_read32(trans,
|
||||
trans->cfg->csr->mac_addr1_strap));
|
||||
trans->trans_cfg->csr->mac_addr1_strap));
|
||||
|
||||
iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
|
||||
/*
|
||||
@ -807,9 +810,9 @@ static void iwl_set_hw_address_from_csr(struct iwl_trans *trans,
|
||||
return;
|
||||
|
||||
mac_addr0 = cpu_to_le32(iwl_read32(trans,
|
||||
trans->cfg->csr->mac_addr0_otp));
|
||||
trans->trans_cfg->csr->mac_addr0_otp));
|
||||
mac_addr1 = cpu_to_le32(iwl_read32(trans,
|
||||
trans->cfg->csr->mac_addr1_otp));
|
||||
trans->trans_cfg->csr->mac_addr1_otp));
|
||||
|
||||
iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
|
||||
}
|
||||
@ -896,7 +899,7 @@ static int iwl_set_hw_address(struct iwl_trans *trans,
|
||||
}
|
||||
|
||||
static bool
|
||||
iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct iwl_cfg *cfg,
|
||||
iwl_nvm_no_wide_in_5ghz(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
const __be16 *nvm_hw)
|
||||
{
|
||||
/*
|
||||
@ -908,7 +911,7 @@ iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct iwl_cfg *cfg,
|
||||
* in 5GHz otherwise the FW will throw a sysassert when we try
|
||||
* to use them.
|
||||
*/
|
||||
if (cfg->device_family == IWL_DEVICE_FAMILY_7000) {
|
||||
if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000) {
|
||||
/*
|
||||
* Unlike the other sections in the NVM, the hw
|
||||
* section uses big-endian.
|
||||
@ -917,7 +920,7 @@ iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct iwl_cfg *cfg,
|
||||
u8 sku = (subsystem_id & 0x1e) >> 1;
|
||||
|
||||
if (sku == 5 || sku == 9) {
|
||||
IWL_DEBUG_EEPROM(dev,
|
||||
IWL_DEBUG_EEPROM(trans->dev,
|
||||
"disabling wide channels in 5GHz (0x%0x %d)\n",
|
||||
subsystem_id, sku);
|
||||
return true;
|
||||
@ -934,7 +937,6 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
const __le16 *mac_override, const __le16 *phy_sku,
|
||||
u8 tx_chains, u8 rx_chains, bool lar_fw_supported)
|
||||
{
|
||||
struct device *dev = trans->dev;
|
||||
struct iwl_nvm_data *data;
|
||||
bool lar_enabled;
|
||||
u32 sku, radio_cfg;
|
||||
@ -942,7 +944,11 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
u16 lar_config;
|
||||
const __le16 *ch_section;
|
||||
|
||||
if (cfg->nvm_type != IWL_NVM_EXT)
|
||||
if (cfg->uhb_supported)
|
||||
data = kzalloc(struct_size(data, channels,
|
||||
IWL_NVM_NUM_CHANNELS_UHB),
|
||||
GFP_KERNEL);
|
||||
else if (cfg->nvm_type != IWL_NVM_EXT)
|
||||
data = kzalloc(struct_size(data, channels,
|
||||
IWL_NVM_NUM_CHANNELS),
|
||||
GFP_KERNEL);
|
||||
@ -1012,10 +1018,10 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
if (lar_fw_supported && lar_enabled)
|
||||
sbands_flags |= IWL_NVM_SBANDS_FLAGS_LAR;
|
||||
|
||||
if (iwl_nvm_no_wide_in_5ghz(dev, cfg, nvm_hw))
|
||||
if (iwl_nvm_no_wide_in_5ghz(trans, cfg, nvm_hw))
|
||||
sbands_flags |= IWL_NVM_SBANDS_FLAGS_NO_WIDE_IN_5GHZ;
|
||||
|
||||
iwl_init_sbands(dev, cfg, data, ch_section, tx_chains, rx_chains,
|
||||
iwl_init_sbands(trans, data, ch_section, tx_chains, rx_chains,
|
||||
sbands_flags, false);
|
||||
data->calib_version = 255;
|
||||
|
||||
@ -1066,11 +1072,6 @@ static u32 iwl_nvm_get_regdom_bw_flags(const u16 *nvm_chan,
|
||||
return flags;
|
||||
}
|
||||
|
||||
struct regdb_ptrs {
|
||||
struct ieee80211_wmm_rule *rule;
|
||||
u32 token;
|
||||
};
|
||||
|
||||
struct ieee80211_regdomain *
|
||||
iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
|
||||
int num_of_ch, __le32 *channels, u16 fw_mcc,
|
||||
@ -1082,7 +1083,6 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
|
||||
const u16 *nvm_chan;
|
||||
struct ieee80211_regdomain *regd, *copy_rd;
|
||||
struct ieee80211_reg_rule *rule;
|
||||
struct regdb_ptrs *regdb_ptrs;
|
||||
enum nl80211_band band;
|
||||
int center_freq, prev_center_freq = 0;
|
||||
int valid_rules = 0;
|
||||
@ -1114,12 +1114,6 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
|
||||
if (!regd)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
regdb_ptrs = kcalloc(num_of_ch, sizeof(*regdb_ptrs), GFP_KERNEL);
|
||||
if (!regdb_ptrs) {
|
||||
copy_rd = ERR_PTR(-ENOMEM);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* set alpha2 from FW. */
|
||||
regd->alpha2[0] = fw_mcc >> 8;
|
||||
regd->alpha2[1] = fw_mcc & 0xff;
|
||||
@ -1191,8 +1185,6 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
|
||||
if (!copy_rd)
|
||||
copy_rd = ERR_PTR(-ENOMEM);
|
||||
|
||||
out:
|
||||
kfree(regdb_ptrs);
|
||||
kfree(regd);
|
||||
return copy_rd;
|
||||
}
|
||||
@ -1311,7 +1303,7 @@ 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->cfg->device_family == IWL_DEVICE_FAMILY_8000 &&
|
||||
if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_8000 &&
|
||||
CSR_HW_REV_STEP(trans->hw_rev) == SILICON_C_STEP &&
|
||||
le32_to_cpu(dword_buff[2]) < 0xE4A) {
|
||||
ret = -EFAULT;
|
||||
@ -1495,7 +1487,7 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
|
||||
channel_profile = v4 ? (void *)rsp->regulatory.channel_profile :
|
||||
(void *)rsp_v3->regulatory.channel_profile;
|
||||
|
||||
iwl_init_sbands(trans->dev, trans->cfg, nvm,
|
||||
iwl_init_sbands(trans, nvm,
|
||||
channel_profile,
|
||||
nvm->valid_tx_ant & fw->valid_tx_ant,
|
||||
nvm->valid_rx_ant & fw->valid_rx_ant,
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -31,7 +31,7 @@
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -140,9 +140,6 @@ struct iwl_cfg;
|
||||
* @nic_config: configure NIC, called before firmware is started.
|
||||
* May sleep
|
||||
* @wimax_active: invoked when WiMax becomes active. May sleep
|
||||
* @enter_d0i3: configure the fw to enter d0i3. return 1 to indicate d0i3
|
||||
* entrance is aborted (e.g. due to held reference). May sleep.
|
||||
* @exit_d0i3: configure the fw to exit d0i3. May sleep.
|
||||
*/
|
||||
struct iwl_op_mode_ops {
|
||||
struct iwl_op_mode *(*start)(struct iwl_trans *trans,
|
||||
@ -164,8 +161,6 @@ struct iwl_op_mode_ops {
|
||||
void (*cmd_queue_full)(struct iwl_op_mode *op_mode);
|
||||
void (*nic_config)(struct iwl_op_mode *op_mode);
|
||||
void (*wimax_active)(struct iwl_op_mode *op_mode);
|
||||
int (*enter_d0i3)(struct iwl_op_mode *op_mode);
|
||||
int (*exit_d0i3)(struct iwl_op_mode *op_mode);
|
||||
};
|
||||
|
||||
int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops);
|
||||
@ -258,22 +253,4 @@ static inline void iwl_op_mode_wimax_active(struct iwl_op_mode *op_mode)
|
||||
op_mode->ops->wimax_active(op_mode);
|
||||
}
|
||||
|
||||
static inline int iwl_op_mode_enter_d0i3(struct iwl_op_mode *op_mode)
|
||||
{
|
||||
might_sleep();
|
||||
|
||||
if (!op_mode->ops->enter_d0i3)
|
||||
return 0;
|
||||
return op_mode->ops->enter_d0i3(op_mode);
|
||||
}
|
||||
|
||||
static inline int iwl_op_mode_exit_d0i3(struct iwl_op_mode *op_mode)
|
||||
{
|
||||
might_sleep();
|
||||
|
||||
if (!op_mode->ops->exit_d0i3)
|
||||
return 0;
|
||||
return op_mode->ops->exit_d0i3(op_mode);
|
||||
}
|
||||
|
||||
#endif /* __iwl_op_mode_h__ */
|
||||
|
@ -451,6 +451,8 @@ enum {
|
||||
|
||||
#define UREG_DOORBELL_TO_ISR6 0xA05C04
|
||||
#define UREG_DOORBELL_TO_ISR6_NMI_BIT BIT(0)
|
||||
#define UREG_DOORBELL_TO_ISR6_SUSPEND BIT(18)
|
||||
#define UREG_DOORBELL_TO_ISR6_RESUME BIT(19)
|
||||
|
||||
#define FSEQ_ERROR_CODE 0xA340C8
|
||||
#define FSEQ_TOP_INIT_VERSION 0xA34038
|
||||
@ -460,4 +462,7 @@ enum {
|
||||
#define FSEQ_ALIVE_TOKEN 0xA340F0
|
||||
#define FSEQ_CNVI_ID 0xA3408C
|
||||
#define FSEQ_CNVR_ID 0xA34090
|
||||
|
||||
#define IWL_D3_SLEEP_STATUS_SUSPEND 0xD3
|
||||
#define IWL_D3_SLEEP_STATUS_RESUME 0xD0
|
||||
#endif /* __iwl_prph_h__ */
|
||||
|
@ -66,7 +66,6 @@
|
||||
|
||||
struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
|
||||
struct device *dev,
|
||||
const struct iwl_cfg *cfg,
|
||||
const struct iwl_trans_ops *ops)
|
||||
{
|
||||
struct iwl_trans *trans;
|
||||
@ -84,7 +83,6 @@ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
|
||||
#endif
|
||||
|
||||
trans->dev = dev;
|
||||
trans->cfg = cfg;
|
||||
trans->ops = ops;
|
||||
trans->num_rx_queues = 1;
|
||||
|
||||
@ -202,17 +200,3 @@ int iwl_cmd_groups_verify_sorted(const struct iwl_trans_config *trans)
|
||||
return 0;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_cmd_groups_verify_sorted);
|
||||
|
||||
void iwl_trans_ref(struct iwl_trans *trans)
|
||||
{
|
||||
if (trans->ops->ref)
|
||||
trans->ops->ref(trans);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_trans_ref);
|
||||
|
||||
void iwl_trans_unref(struct iwl_trans *trans)
|
||||
{
|
||||
if (trans->ops->unref)
|
||||
trans->ops->unref(trans);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_trans_unref);
|
||||
|
@ -159,13 +159,6 @@ static inline u32 iwl_rx_packet_payload_len(const struct iwl_rx_packet *pkt)
|
||||
* @CMD_ASYNC: Return right away and don't wait for the response
|
||||
* @CMD_WANT_SKB: Not valid with CMD_ASYNC. The caller needs the buffer of
|
||||
* the response. The caller needs to call iwl_free_resp when done.
|
||||
* @CMD_HIGH_PRIO: The command is high priority - it goes to the front of the
|
||||
* command queue, but after other high priority commands. Valid only
|
||||
* with CMD_ASYNC.
|
||||
* @CMD_SEND_IN_IDLE: The command should be sent even when the trans is idle.
|
||||
* @CMD_MAKE_TRANS_IDLE: The command response should mark the trans as idle.
|
||||
* @CMD_WAKE_UP_TRANS: The command response should wake up the trans
|
||||
* (i.e. mark it as non-idle).
|
||||
* @CMD_WANT_ASYNC_CALLBACK: the op_mode's async callback function must be
|
||||
* called after this command completes. Valid only with CMD_ASYNC.
|
||||
*/
|
||||
@ -173,11 +166,7 @@ enum CMD_MODE {
|
||||
CMD_ASYNC = BIT(0),
|
||||
CMD_WANT_SKB = BIT(1),
|
||||
CMD_SEND_IN_RFKILL = BIT(2),
|
||||
CMD_HIGH_PRIO = BIT(3),
|
||||
CMD_SEND_IN_IDLE = BIT(4),
|
||||
CMD_MAKE_TRANS_IDLE = BIT(5),
|
||||
CMD_WAKE_UP_TRANS = BIT(6),
|
||||
CMD_WANT_ASYNC_CALLBACK = BIT(7),
|
||||
CMD_WANT_ASYNC_CALLBACK = BIT(3),
|
||||
};
|
||||
|
||||
#define DEF_CMD_PAYLOAD_SIZE 320
|
||||
@ -463,9 +452,8 @@ struct iwl_trans_rxq_dma_data {
|
||||
*
|
||||
* All the handlers MUST be implemented
|
||||
*
|
||||
* @start_hw: starts the HW. If low_power is true, the NIC needs to be taken
|
||||
* out of a low power state. From that point on, the HW can send
|
||||
* interrupts. May sleep.
|
||||
* @start_hw: starts the HW. From that point on, the HW can send interrupts.
|
||||
* May sleep.
|
||||
* @op_mode_leave: Turn off the HW RF kill indication if on
|
||||
* May sleep
|
||||
* @start_fw: allocates and inits all the resources for the transport
|
||||
@ -475,9 +463,8 @@ struct iwl_trans_rxq_dma_data {
|
||||
* the SCD base address in SRAM, then provide it here, or 0 otherwise.
|
||||
* May sleep
|
||||
* @stop_device: stops the whole device (embedded CPU put to reset) and stops
|
||||
* the HW. If low_power is true, the NIC will be put in low power state.
|
||||
* From that point on, the HW will be stopped but will still issue an
|
||||
* interrupt if the HW RF kill switch is triggered.
|
||||
* the HW. From that point on, the HW will be stopped but will still issue
|
||||
* an interrupt if the HW RF kill switch is triggered.
|
||||
* This callback must do the right thing and not crash even if %start_hw()
|
||||
* was called but not &start_fw(). May sleep.
|
||||
* @d3_suspend: put the device into the correct mode for WoWLAN during
|
||||
@ -535,11 +522,6 @@ struct iwl_trans_rxq_dma_data {
|
||||
* @release_nic_access: let the NIC go to sleep. The "flags" parameter
|
||||
* must be the same one that was sent before to the grab_nic_access.
|
||||
* @set_bits_mask - set SRAM register according to value and mask.
|
||||
* @ref: grab a reference to the transport/FW layers, disallowing
|
||||
* certain low power states
|
||||
* @unref: release a reference previously taken with @ref. Note that
|
||||
* initially the reference count is 1, making an initial @unref
|
||||
* necessary to allow low power states.
|
||||
* @dump_data: return a vmalloc'ed buffer with debug data, maybe containing last
|
||||
* TX'ed commands and similar. The buffer will be vfree'd by the caller.
|
||||
* Note that the transport must fill in the proper file headers.
|
||||
@ -548,14 +530,14 @@ struct iwl_trans_rxq_dma_data {
|
||||
*/
|
||||
struct iwl_trans_ops {
|
||||
|
||||
int (*start_hw)(struct iwl_trans *iwl_trans, bool low_power);
|
||||
int (*start_hw)(struct iwl_trans *iwl_trans);
|
||||
void (*op_mode_leave)(struct iwl_trans *iwl_trans);
|
||||
int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw,
|
||||
bool run_in_rfkill);
|
||||
void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr);
|
||||
void (*stop_device)(struct iwl_trans *trans, bool low_power);
|
||||
void (*stop_device)(struct iwl_trans *trans);
|
||||
|
||||
void (*d3_suspend)(struct iwl_trans *trans, bool test, bool reset);
|
||||
int (*d3_suspend)(struct iwl_trans *trans, bool test, bool reset);
|
||||
int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status,
|
||||
bool test, bool reset);
|
||||
|
||||
@ -566,6 +548,8 @@ struct iwl_trans_ops {
|
||||
void (*reclaim)(struct iwl_trans *trans, int queue, int ssn,
|
||||
struct sk_buff_head *skbs);
|
||||
|
||||
void (*set_q_ptrs)(struct iwl_trans *trans, int queue, int ptr);
|
||||
|
||||
bool (*txq_enable)(struct iwl_trans *trans, int queue, u16 ssn,
|
||||
const struct iwl_trans_txq_scd_cfg *cfg,
|
||||
unsigned int queue_wdg_timeout);
|
||||
@ -607,8 +591,6 @@ struct iwl_trans_ops {
|
||||
unsigned long *flags);
|
||||
void (*set_bits_mask)(struct iwl_trans *trans, u32 reg, u32 mask,
|
||||
u32 value);
|
||||
void (*ref)(struct iwl_trans *trans);
|
||||
void (*unref)(struct iwl_trans *trans);
|
||||
int (*suspend)(struct iwl_trans *trans);
|
||||
void (*resume)(struct iwl_trans *trans);
|
||||
|
||||
@ -632,9 +614,6 @@ enum iwl_trans_state {
|
||||
/**
|
||||
* DOC: Platform power management
|
||||
*
|
||||
* There are two types of platform power management: system-wide
|
||||
* (WoWLAN) and runtime.
|
||||
*
|
||||
* In system-wide power management the entire platform goes into a low
|
||||
* power state (e.g. idle or suspend to RAM) at the same time and the
|
||||
* device is configured as a wakeup source for the entire platform.
|
||||
@ -643,54 +622,46 @@ enum iwl_trans_state {
|
||||
* put the platform in low power mode). The device's behavior in this
|
||||
* mode is dictated by the wake-on-WLAN configuration.
|
||||
*
|
||||
* In runtime power management, only the devices which are themselves
|
||||
* idle enter a low power state. This is done at runtime, which means
|
||||
* that the entire system is still running normally. This mode is
|
||||
* usually triggered automatically by the device driver and requires
|
||||
* the ability to enter and exit the low power modes in a very short
|
||||
* time, so there is not much impact in usability.
|
||||
*
|
||||
* The terms used for the device's behavior are as follows:
|
||||
*
|
||||
* - D0: the device is fully powered and the host is awake;
|
||||
* - D3: the device is in low power mode and only reacts to
|
||||
* specific events (e.g. magic-packet received or scan
|
||||
* results found);
|
||||
* - D0I3: the device is in low power mode and reacts to any
|
||||
* activity (e.g. RX);
|
||||
*
|
||||
* These terms reflect the power modes in the firmware and are not to
|
||||
* be confused with the physical device power state. The NIC can be
|
||||
* in D0I3 mode even if, for instance, the PCI device is in D3 state.
|
||||
* be confused with the physical device power state.
|
||||
*/
|
||||
|
||||
/**
|
||||
* enum iwl_plat_pm_mode - platform power management mode
|
||||
*
|
||||
* This enumeration describes the device's platform power management
|
||||
* behavior when in idle mode (i.e. runtime power management) or when
|
||||
* in system-wide suspend (i.e WoWLAN).
|
||||
* behavior when in system-wide suspend (i.e WoWLAN).
|
||||
*
|
||||
* @IWL_PLAT_PM_MODE_DISABLED: power management is disabled for this
|
||||
* device. At runtime, this means that nothing happens and the
|
||||
* device always remains in active. In system-wide suspend mode,
|
||||
* it means that the all connections will be closed automatically
|
||||
* by mac80211 before the platform is suspended.
|
||||
* 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).
|
||||
* For runtime power management, this mode is not officially
|
||||
* supported.
|
||||
* @IWL_PLAT_PM_MODE_D0I3: the device goes into D0I3 mode.
|
||||
*/
|
||||
enum iwl_plat_pm_mode {
|
||||
IWL_PLAT_PM_MODE_DISABLED,
|
||||
IWL_PLAT_PM_MODE_D3,
|
||||
IWL_PLAT_PM_MODE_D0I3,
|
||||
};
|
||||
|
||||
/* Max time to wait for trans to become idle/non-idle on d0i3
|
||||
* enter/exit (in msecs).
|
||||
/**
|
||||
* 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
|
||||
* @IWL_INI_CFG_STATE_CORRUPTED: debug cfg was found and some of the TLVs
|
||||
* are corrupted. The rest of the debug TLVs will still be used
|
||||
*/
|
||||
#define IWL_TRANS_IDLE_TIMEOUT 2000
|
||||
enum iwl_ini_cfg_state {
|
||||
IWL_INI_CFG_STATE_NOT_LOADED,
|
||||
IWL_INI_CFG_STATE_LOADED,
|
||||
IWL_INI_CFG_STATE_CORRUPTED,
|
||||
};
|
||||
|
||||
/* Max time to wait for nmi interrupt */
|
||||
#define IWL_TRANS_NMI_TIMEOUT (HZ / 4)
|
||||
@ -733,8 +704,8 @@ struct iwl_self_init_dram {
|
||||
* @umac_error_event_table: addr of umac error table
|
||||
* @error_event_table_tlv_status: bitmap that indicates what error table
|
||||
* pointers was recevied via TLV. uses enum &iwl_error_event_table_status
|
||||
* @external_ini_loaded: indicates if an external ini cfg was given
|
||||
* @ini_valid: indicates if debug ini mode is on
|
||||
* @internal_ini_cfg: internal debug cfg state. Uses &enum iwl_ini_cfg_state
|
||||
* @external_ini_cfg: external debug cfg state. Uses &enum iwl_ini_cfg_state
|
||||
* @num_blocks: number of blocks in fw_mon
|
||||
* @fw_mon: address of the buffers for firmware monitor
|
||||
* @hw_error: equals true if hw error interrupt was received from the FW
|
||||
@ -752,14 +723,11 @@ struct iwl_trans_debug {
|
||||
u32 umac_error_event_table;
|
||||
unsigned int error_event_table_tlv_status;
|
||||
|
||||
bool external_ini_loaded;
|
||||
bool ini_valid;
|
||||
|
||||
struct iwl_apply_point_data apply_points[IWL_FW_INI_APPLY_NUM];
|
||||
struct iwl_apply_point_data apply_points_ext[IWL_FW_INI_APPLY_NUM];
|
||||
enum iwl_ini_cfg_state internal_ini_cfg;
|
||||
enum iwl_ini_cfg_state external_ini_cfg;
|
||||
|
||||
int num_blocks;
|
||||
struct iwl_dram_data fw_mon[IWL_FW_INI_APPLY_NUM];
|
||||
struct iwl_dram_data fw_mon[IWL_FW_INI_ALLOCATION_NUM];
|
||||
|
||||
bool hw_error;
|
||||
enum iwl_fw_ini_buffer_location ini_dest;
|
||||
@ -770,6 +738,7 @@ struct iwl_trans_debug {
|
||||
*
|
||||
* @ops - pointer to iwl_trans_ops
|
||||
* @op_mode - pointer to the op_mode
|
||||
* @trans_cfg: the trans-specific configuration part
|
||||
* @cfg - pointer to the configuration
|
||||
* @drv - pointer to iwl_drv
|
||||
* @status: a bit-mask of transport status flags
|
||||
@ -797,13 +766,11 @@ struct iwl_trans_debug {
|
||||
* @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.
|
||||
* @runtime_pm_mode: the runtime power management mode in use. This
|
||||
* mode is set during the initialization phase and is not
|
||||
* supposed to change during runtime.
|
||||
*/
|
||||
struct iwl_trans {
|
||||
const struct iwl_trans_ops *ops;
|
||||
struct iwl_op_mode *op_mode;
|
||||
const struct iwl_cfg_trans_params *trans_cfg;
|
||||
const struct iwl_cfg *cfg;
|
||||
struct iwl_drv *drv;
|
||||
enum iwl_trans_state state;
|
||||
@ -844,8 +811,6 @@ struct iwl_trans {
|
||||
struct iwl_self_init_dram init_dram;
|
||||
|
||||
enum iwl_plat_pm_mode system_pm_mode;
|
||||
enum iwl_plat_pm_mode runtime_pm_mode;
|
||||
bool suspending;
|
||||
|
||||
/* pointer to trans specific struct */
|
||||
/*Ensure that this pointer will always be aligned to sizeof pointer */
|
||||
@ -864,16 +829,11 @@ static inline void iwl_trans_configure(struct iwl_trans *trans,
|
||||
WARN_ON(iwl_cmd_groups_verify_sorted(trans_cfg));
|
||||
}
|
||||
|
||||
static inline int _iwl_trans_start_hw(struct iwl_trans *trans, bool low_power)
|
||||
static inline int iwl_trans_start_hw(struct iwl_trans *trans)
|
||||
{
|
||||
might_sleep();
|
||||
|
||||
return trans->ops->start_hw(trans, low_power);
|
||||
}
|
||||
|
||||
static inline int iwl_trans_start_hw(struct iwl_trans *trans)
|
||||
{
|
||||
return trans->ops->start_hw(trans, true);
|
||||
return trans->ops->start_hw(trans);
|
||||
}
|
||||
|
||||
static inline void iwl_trans_op_mode_leave(struct iwl_trans *trans)
|
||||
@ -909,27 +869,23 @@ static inline int iwl_trans_start_fw(struct iwl_trans *trans,
|
||||
return trans->ops->start_fw(trans, fw, run_in_rfkill);
|
||||
}
|
||||
|
||||
static inline void _iwl_trans_stop_device(struct iwl_trans *trans,
|
||||
bool low_power)
|
||||
static inline void iwl_trans_stop_device(struct iwl_trans *trans)
|
||||
{
|
||||
might_sleep();
|
||||
|
||||
trans->ops->stop_device(trans, low_power);
|
||||
trans->ops->stop_device(trans);
|
||||
|
||||
trans->state = IWL_TRANS_NO_FW;
|
||||
}
|
||||
|
||||
static inline void iwl_trans_stop_device(struct iwl_trans *trans)
|
||||
{
|
||||
_iwl_trans_stop_device(trans, true);
|
||||
}
|
||||
|
||||
static inline void iwl_trans_d3_suspend(struct iwl_trans *trans, bool test,
|
||||
static inline int iwl_trans_d3_suspend(struct iwl_trans *trans, bool test,
|
||||
bool reset)
|
||||
{
|
||||
might_sleep();
|
||||
if (trans->ops->d3_suspend)
|
||||
trans->ops->d3_suspend(trans, test, reset);
|
||||
if (!trans->ops->d3_suspend)
|
||||
return 0;
|
||||
|
||||
return trans->ops->d3_suspend(trans, test, reset);
|
||||
}
|
||||
|
||||
static inline int iwl_trans_d3_resume(struct iwl_trans *trans,
|
||||
@ -1004,6 +960,17 @@ static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue,
|
||||
trans->ops->reclaim(trans, queue, ssn, skbs);
|
||||
}
|
||||
|
||||
static inline void iwl_trans_set_q_ptrs(struct iwl_trans *trans, int queue,
|
||||
int ptr)
|
||||
{
|
||||
if (WARN_ON_ONCE(trans->state != IWL_TRANS_FW_ALIVE)) {
|
||||
IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
|
||||
return;
|
||||
}
|
||||
|
||||
trans->ops->set_q_ptrs(trans, queue, ptr);
|
||||
}
|
||||
|
||||
static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue,
|
||||
bool configure_scd)
|
||||
{
|
||||
@ -1261,16 +1228,19 @@ static inline void iwl_trans_sync_nmi(struct iwl_trans *trans)
|
||||
trans->ops->sync_nmi(trans);
|
||||
}
|
||||
|
||||
static inline bool iwl_trans_dbg_ini_valid(struct iwl_trans *trans)
|
||||
{
|
||||
return trans->dbg.internal_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED ||
|
||||
trans->dbg.external_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED;
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* transport helper functions
|
||||
*****************************************************/
|
||||
struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
|
||||
struct device *dev,
|
||||
const struct iwl_cfg *cfg,
|
||||
const struct iwl_trans_ops *ops);
|
||||
void iwl_trans_free(struct iwl_trans *trans);
|
||||
void iwl_trans_ref(struct iwl_trans *trans);
|
||||
void iwl_trans_unref(struct iwl_trans *trans);
|
||||
|
||||
/*****************************************************
|
||||
* driver (transport) register/unregister functions
|
||||
|
@ -153,5 +153,6 @@
|
||||
#define IWL_MVM_FTM_INITIATOR_DYNACK true
|
||||
#define IWL_MVM_D3_DEBUG false
|
||||
#define IWL_MVM_USE_TWT false
|
||||
#define IWL_MVM_AMPDU_CONSEC_DROPS_DELBA 10
|
||||
|
||||
#endif /* __MVM_CONSTANTS_H */
|
||||
|
@ -735,32 +735,8 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
iwl_mvm_iter_d0i3_ap_keys(struct iwl_mvm *mvm,
|
||||
static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
void (*iter)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key,
|
||||
void *data),
|
||||
void *data)
|
||||
{
|
||||
struct ieee80211_sta *ap_sta;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
ap_sta = rcu_dereference(mvm->fw_id_to_mac_id[mvm->d0i3_ap_sta_id]);
|
||||
if (IS_ERR_OR_NULL(ap_sta))
|
||||
goto out;
|
||||
|
||||
ieee80211_iter_keys_rcu(mvm->hw, vif, iter, data);
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
bool d0i3,
|
||||
u32 cmd_flags)
|
||||
{
|
||||
struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {};
|
||||
@ -768,7 +744,7 @@ int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
|
||||
bool unified = fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
|
||||
struct wowlan_key_data key_data = {
|
||||
.configure_keys = !d0i3 && !unified,
|
||||
.configure_keys = !unified,
|
||||
.use_rsc_tsc = false,
|
||||
.tkip = &tkip_cmd,
|
||||
.use_tkip = false,
|
||||
@ -784,10 +760,7 @@ int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
|
||||
* if we have to configure keys, call ieee80211_iter_keys(),
|
||||
* as we need non-atomic context in order to take the
|
||||
* required locks.
|
||||
* for the d0i3 we can't use ieee80211_iter_keys(), as
|
||||
* taking (almost) any mutex might result in deadlock.
|
||||
*/
|
||||
if (!d0i3) {
|
||||
/*
|
||||
* Note that currently we don't propagate cmd_flags
|
||||
* to the iterator. In case of key_data.configure_keys,
|
||||
@ -795,14 +768,8 @@ int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
|
||||
* iwl_mvm_wowlan_program_keys() will take care of
|
||||
* locking/unlocking mvm->mutex.
|
||||
*/
|
||||
ieee80211_iter_keys(mvm->hw, vif,
|
||||
iwl_mvm_wowlan_program_keys,
|
||||
ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_program_keys,
|
||||
&key_data);
|
||||
} else {
|
||||
iwl_mvm_iter_d0i3_ap_keys(mvm, vif,
|
||||
iwl_mvm_wowlan_program_keys,
|
||||
&key_data);
|
||||
}
|
||||
|
||||
if (key_data.error) {
|
||||
ret = -EIO;
|
||||
@ -830,7 +797,7 @@ int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
|
||||
}
|
||||
|
||||
/* configure rekey data only if offloaded rekey is supported (d3) */
|
||||
if (mvmvif->rekey_data.valid && !d0i3) {
|
||||
if (mvmvif->rekey_data.valid) {
|
||||
memset(&kek_kck_cmd, 0, sizeof(kek_kck_cmd));
|
||||
memcpy(kek_kck_cmd.kck, mvmvif->rekey_data.kck,
|
||||
NL80211_KCK_LEN);
|
||||
@ -864,6 +831,8 @@ iwl_mvm_wowlan_config(struct iwl_mvm *mvm,
|
||||
bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
|
||||
|
||||
mvm->offload_tid = wowlan_config_cmd->offloading_tid;
|
||||
|
||||
if (!unified_image) {
|
||||
ret = iwl_mvm_switch_to_d3(mvm);
|
||||
if (ret)
|
||||
@ -881,8 +850,7 @@ iwl_mvm_wowlan_config(struct iwl_mvm *mvm,
|
||||
* that isn't really a problem though.
|
||||
*/
|
||||
mutex_unlock(&mvm->mutex);
|
||||
ret = iwl_mvm_wowlan_config_key_params(mvm, vif, false,
|
||||
CMD_ASYNC);
|
||||
ret = iwl_mvm_wowlan_config_key_params(mvm, vif, CMD_ASYNC);
|
||||
mutex_lock(&mvm->mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -936,6 +904,8 @@ iwl_mvm_netdetect_config(struct iwl_mvm *mvm,
|
||||
wowlan_config_cmd.wakeup_filter |=
|
||||
cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
|
||||
|
||||
wowlan_config_cmd.sta_id = mvm->aux_sta.sta_id;
|
||||
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, 0,
|
||||
sizeof(wowlan_config_cmd),
|
||||
&wowlan_config_cmd);
|
||||
@ -1043,6 +1013,8 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
|
||||
} else {
|
||||
struct iwl_wowlan_config_cmd wowlan_config_cmd = {};
|
||||
|
||||
wowlan_config_cmd.sta_id = mvmvif->ap_sta_id;
|
||||
|
||||
ap_sta = rcu_dereference_protected(
|
||||
mvm->fw_id_to_mac_id[mvmvif->ap_sta_id],
|
||||
lockdep_is_held(&mvm->mutex));
|
||||
@ -1082,8 +1054,8 @@ 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->cfg->device_family < IWL_DEVICE_FAMILY_9000)
|
||||
iwl_fw_dbg_stop_recording(mvm->trans, NULL);
|
||||
if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000)
|
||||
iwl_fw_dbg_stop_restart_recording(&mvm->fwrt, NULL, true);
|
||||
|
||||
/* must be last -- this switches firmware state */
|
||||
ret = iwl_mvm_send_cmd(mvm, &d3_cfg_cmd);
|
||||
@ -1100,13 +1072,12 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
|
||||
|
||||
clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
|
||||
|
||||
iwl_trans_d3_suspend(mvm->trans, test, !unified_image);
|
||||
ret = iwl_trans_d3_suspend(mvm->trans, test, !unified_image);
|
||||
out:
|
||||
if (ret < 0) {
|
||||
iwl_mvm_free_nd(mvm);
|
||||
|
||||
if (!unified_image) {
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
|
||||
if (mvm->fw_restart > 0) {
|
||||
mvm->fw_restart--;
|
||||
ieee80211_restart_hw(mvm->hw);
|
||||
@ -1119,37 +1090,12 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iwl_mvm_enter_d0i3_sync(struct iwl_mvm *mvm)
|
||||
{
|
||||
struct iwl_notification_wait wait_d3;
|
||||
static const u16 d3_notif[] = { D3_CONFIG_CMD };
|
||||
int ret;
|
||||
|
||||
iwl_init_notification_wait(&mvm->notif_wait, &wait_d3,
|
||||
d3_notif, ARRAY_SIZE(d3_notif),
|
||||
NULL, NULL);
|
||||
|
||||
ret = iwl_mvm_enter_d0i3(mvm->hw->priv);
|
||||
if (ret)
|
||||
goto remove_notif;
|
||||
|
||||
ret = iwl_wait_notification(&mvm->notif_wait, &wait_d3, HZ);
|
||||
WARN_ON_ONCE(ret);
|
||||
return ret;
|
||||
|
||||
remove_notif:
|
||||
iwl_remove_notification(&mvm->notif_wait, &wait_d3);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
struct iwl_trans *trans = mvm->trans;
|
||||
int ret;
|
||||
|
||||
/* make sure the d0i3 exit work is not pending */
|
||||
flush_work(&mvm->d0i3_exit_work);
|
||||
iwl_mvm_pause_tcm(mvm, true);
|
||||
|
||||
iwl_fw_runtime_suspend(&mvm->fwrt);
|
||||
@ -1158,25 +1104,6 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (wowlan->any) {
|
||||
trans->system_pm_mode = IWL_PLAT_PM_MODE_D0I3;
|
||||
|
||||
if (iwl_mvm_enter_d0i3_on_suspend(mvm)) {
|
||||
ret = iwl_mvm_enter_d0i3_sync(mvm);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
mutex_lock(&mvm->d0i3_suspend_mutex);
|
||||
__set_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags);
|
||||
mutex_unlock(&mvm->d0i3_suspend_mutex);
|
||||
|
||||
iwl_trans_d3_suspend(trans, false, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
trans->system_pm_mode = IWL_PLAT_PM_MODE_D3;
|
||||
|
||||
return __iwl_mvm_suspend(hw, wowlan, false);
|
||||
@ -1735,6 +1662,13 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
|
||||
mvm_ap_sta->tid_data[i].seq_number = seq;
|
||||
}
|
||||
|
||||
if (mvm->trans->trans_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,
|
||||
mvm_ap_sta->tid_data[i].seq_number >> 4);
|
||||
}
|
||||
|
||||
/* now we have all the data we need, unlock to avoid mac80211 issues */
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
@ -1752,30 +1686,6 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
|
||||
return false;
|
||||
}
|
||||
|
||||
void iwl_mvm_d0i3_update_keys(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
struct iwl_wowlan_status *status)
|
||||
{
|
||||
struct iwl_mvm_d3_gtk_iter_data gtkdata = {
|
||||
.mvm = mvm,
|
||||
.status = status,
|
||||
};
|
||||
|
||||
/*
|
||||
* rekey handling requires taking locks that can't be taken now.
|
||||
* however, d0i3 doesn't offload rekey, so we're fine.
|
||||
*/
|
||||
if (WARN_ON_ONCE(status->num_of_gtk_rekeys))
|
||||
return;
|
||||
|
||||
/* find last GTK that we used initially, if any */
|
||||
gtkdata.find_phase = true;
|
||||
iwl_mvm_iter_d0i3_ap_keys(mvm, vif, iwl_mvm_d3_update_keys, >kdata);
|
||||
|
||||
gtkdata.find_phase = false;
|
||||
iwl_mvm_iter_d0i3_ap_keys(mvm, vif, iwl_mvm_d3_update_keys, >kdata);
|
||||
}
|
||||
|
||||
#define ND_QUERY_BUF_LEN (sizeof(struct iwl_scan_offload_profile_match) * \
|
||||
IWL_SCAN_MAX_PROFILES)
|
||||
|
||||
@ -2024,15 +1934,6 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
|
||||
if (IS_ERR_OR_NULL(vif))
|
||||
goto err;
|
||||
|
||||
ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test, !unified_image);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
if (d3_status != IWL_D3_STATUS_ALIVE) {
|
||||
IWL_INFO(mvm, "Device was reset during suspend\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt);
|
||||
|
||||
if (iwl_mvm_check_rt_status(mvm, vif)) {
|
||||
@ -2044,6 +1945,15 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test, !unified_image);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
if (d3_status != IWL_D3_STATUS_ALIVE) {
|
||||
IWL_INFO(mvm, "Device was reset during suspend\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (d0i3_first) {
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, 0, 0, NULL);
|
||||
if (ret < 0) {
|
||||
@ -2059,6 +1969,9 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
|
||||
*/
|
||||
iwl_mvm_update_changed_regdom(mvm);
|
||||
|
||||
/* Re-configure PPAG settings */
|
||||
iwl_mvm_ppag_send_cmd(mvm);
|
||||
|
||||
if (!unified_image)
|
||||
/* Re-configure default SAR profile */
|
||||
iwl_mvm_sar_select_profile(mvm, 1, 1);
|
||||
@ -2115,14 +2028,6 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
|
||||
* 2. We are using a unified image but had an error while exiting D3
|
||||
*/
|
||||
set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status);
|
||||
/*
|
||||
* When switching images we return 1, which causes mac80211
|
||||
* to do a reconfig with IEEE80211_RECONFIG_TYPE_RESTART.
|
||||
* This type of reconfig calls iwl_mvm_restart_complete(),
|
||||
* where we unref the IWL_MVM_REF_UCODE_DOWN, so we need
|
||||
* to take the reference here.
|
||||
*/
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -2134,52 +2039,11 @@ static int iwl_mvm_resume_d3(struct iwl_mvm *mvm)
|
||||
return __iwl_mvm_resume(mvm, false);
|
||||
}
|
||||
|
||||
static int iwl_mvm_resume_d0i3(struct iwl_mvm *mvm)
|
||||
{
|
||||
bool exit_now;
|
||||
enum iwl_d3_status d3_status;
|
||||
struct iwl_trans *trans = mvm->trans;
|
||||
|
||||
iwl_trans_d3_resume(trans, &d3_status, false, false);
|
||||
|
||||
/*
|
||||
* make sure to clear D0I3_DEFER_WAKEUP before
|
||||
* calling iwl_trans_resume(), which might wait
|
||||
* for d0i3 exit completion.
|
||||
*/
|
||||
mutex_lock(&mvm->d0i3_suspend_mutex);
|
||||
__clear_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags);
|
||||
exit_now = __test_and_clear_bit(D0I3_PENDING_WAKEUP,
|
||||
&mvm->d0i3_suspend_flags);
|
||||
mutex_unlock(&mvm->d0i3_suspend_mutex);
|
||||
if (exit_now) {
|
||||
IWL_DEBUG_RPM(mvm, "Run deferred d0i3 exit\n");
|
||||
_iwl_mvm_exit_d0i3(mvm);
|
||||
}
|
||||
|
||||
iwl_trans_resume(trans);
|
||||
|
||||
if (iwl_mvm_enter_d0i3_on_suspend(mvm)) {
|
||||
int ret = iwl_mvm_exit_d0i3(mvm->hw->priv);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
/*
|
||||
* d0i3 exit will be deferred until reconfig_complete.
|
||||
* make sure there we are out of d0i3.
|
||||
*/
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iwl_mvm_resume(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
int ret;
|
||||
|
||||
if (mvm->trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3)
|
||||
ret = iwl_mvm_resume_d0i3(mvm);
|
||||
else
|
||||
ret = iwl_mvm_resume_d3(mvm);
|
||||
|
||||
mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;
|
||||
|
@ -1056,19 +1056,11 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf,
|
||||
static ssize_t iwl_dbgfs_fw_nmi_write(struct iwl_mvm *mvm, char *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!iwl_mvm_firmware_running(mvm))
|
||||
return -EIO;
|
||||
|
||||
ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_NMI);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
iwl_force_nmi(mvm->trans);
|
||||
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_NMI);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -1181,8 +1173,8 @@ static ssize_t iwl_dbgfs_inject_packet_write(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_mpdu_desc *desc;
|
||||
int bin_len = count / 2;
|
||||
int ret = -EINVAL;
|
||||
size_t mpdu_cmd_hdr_size =
|
||||
(mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) ?
|
||||
size_t mpdu_cmd_hdr_size = (mvm->trans->trans_cfg->device_family >=
|
||||
IWL_DEVICE_FAMILY_22560) ?
|
||||
sizeof(struct iwl_rx_mpdu_desc) :
|
||||
IWL_RX_DESC_SIZE_V1;
|
||||
|
||||
@ -1190,7 +1182,7 @@ static ssize_t iwl_dbgfs_inject_packet_write(struct iwl_mvm *mvm,
|
||||
return -EIO;
|
||||
|
||||
/* supporting only 9000 descriptor */
|
||||
if (!mvm->trans->cfg->mq_rx_supported)
|
||||
if (!mvm->trans->trans_cfg->mq_rx_supported)
|
||||
return -ENOTSUPP;
|
||||
|
||||
rxb._page = alloc_pages(GFP_ATOMIC, 0);
|
||||
@ -1380,19 +1372,12 @@ static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
|
||||
char *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_WRITE);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (count == 0)
|
||||
return 0;
|
||||
|
||||
iwl_fw_dbg_collect(&mvm->fwrt, FW_DBG_TRIGGER_USER, buf,
|
||||
(count - 1), NULL);
|
||||
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -1579,87 +1564,6 @@ static ssize_t iwl_dbgfs_bcast_filters_macs_write(struct iwl_mvm *mvm,
|
||||
}
|
||||
#endif
|
||||
|
||||
#define PRINT_MVM_REF(ref) do { \
|
||||
if (mvm->refs[ref]) \
|
||||
pos += scnprintf(buf + pos, bufsz - pos, \
|
||||
"\t(0x%lx): %d %s\n", \
|
||||
BIT(ref), mvm->refs[ref], #ref); \
|
||||
} while (0)
|
||||
|
||||
static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_mvm *mvm = file->private_data;
|
||||
int i, pos = 0;
|
||||
char buf[256];
|
||||
const size_t bufsz = sizeof(buf);
|
||||
u32 refs = 0;
|
||||
|
||||
for (i = 0; i < IWL_MVM_REF_COUNT; i++)
|
||||
if (mvm->refs[i])
|
||||
refs |= BIT(i);
|
||||
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "taken mvm refs: 0x%x\n",
|
||||
refs);
|
||||
|
||||
PRINT_MVM_REF(IWL_MVM_REF_UCODE_DOWN);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_SCAN);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_ROC);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_ROC_AUX);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_P2P_CLIENT);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_AP_IBSS);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_USER);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_TX);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_TX_AGG);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_ADD_IF);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_START_AP);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_BSS_CHANGED);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_PREPARE_TX);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_PROTECT_TDLS);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_CHECK_CTKILL);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_PRPH_READ);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_PRPH_WRITE);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_NMI);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_TM_CMD);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_EXIT_WORK);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_PROTECT_CSA);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_FW_DBG_COLLECT);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_INIT_UCODE);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_SENDING_CMD);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_RX);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_d0i3_refs_write(struct iwl_mvm *mvm, char *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
unsigned long value;
|
||||
int ret;
|
||||
bool taken;
|
||||
|
||||
ret = kstrtoul(buf, 10, &value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
taken = mvm->refs[IWL_MVM_REF_USER];
|
||||
if (value == 1 && !taken)
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_USER);
|
||||
else if (value == 0 && taken)
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_USER);
|
||||
else
|
||||
ret = -EINVAL;
|
||||
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return count;
|
||||
}
|
||||
|
||||
#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
|
||||
_MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
|
||||
#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
|
||||
@ -1692,21 +1596,14 @@ iwl_dbgfs_prph_reg_read(struct file *file,
|
||||
int pos = 0;
|
||||
char buf[32];
|
||||
const size_t bufsz = sizeof(buf);
|
||||
int ret;
|
||||
|
||||
if (!mvm->dbgfs_prph_reg_addr)
|
||||
return -EINVAL;
|
||||
|
||||
ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_READ);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "Reg 0x%x: (0x%x)\n",
|
||||
mvm->dbgfs_prph_reg_addr,
|
||||
iwl_read_prph(mvm->trans, mvm->dbgfs_prph_reg_addr));
|
||||
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_READ);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
}
|
||||
|
||||
@ -1716,7 +1613,6 @@ iwl_dbgfs_prph_reg_write(struct iwl_mvm *mvm, char *buf,
|
||||
{
|
||||
u8 args;
|
||||
u32 value;
|
||||
int ret;
|
||||
|
||||
args = sscanf(buf, "%i %i", &mvm->dbgfs_prph_reg_addr, &value);
|
||||
/* if we only want to set the reg address - nothing more to do */
|
||||
@ -1727,13 +1623,8 @@ iwl_dbgfs_prph_reg_write(struct iwl_mvm *mvm, char *buf,
|
||||
if (args != 2)
|
||||
return -EINVAL;
|
||||
|
||||
ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_WRITE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
iwl_write_prph(mvm->trans, mvm->dbgfs_prph_reg_addr, value);
|
||||
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE);
|
||||
out:
|
||||
return count;
|
||||
}
|
||||
@ -1867,6 +1758,38 @@ iwl_dbgfs_uapsd_noagg_bssids_read(struct file *file, char __user *user_buf,
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
iwl_dbgfs_ltr_config_write(struct iwl_mvm *mvm,
|
||||
char *buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
int ret;
|
||||
struct iwl_ltr_config_cmd ltr_config = {0};
|
||||
|
||||
if (!iwl_mvm_firmware_running(mvm))
|
||||
return -EIO;
|
||||
|
||||
if (sscanf(buf, "%x,%x,%x,%x,%x,%x,%x",
|
||||
<r_config.flags,
|
||||
<r_config.static_long,
|
||||
<r_config.static_short,
|
||||
<r_config.ltr_cfg_values[0],
|
||||
<r_config.ltr_cfg_values[1],
|
||||
<r_config.ltr_cfg_values[2],
|
||||
<r_config.ltr_cfg_values[3]) != 7) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0, sizeof(ltr_config),
|
||||
<r_config);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
if (ret)
|
||||
IWL_ERR(mvm, "failed to send ltr configuration cmd\n");
|
||||
|
||||
return ret ?: count;
|
||||
}
|
||||
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64);
|
||||
|
||||
/* Device wide debugfs entries */
|
||||
@ -1892,7 +1815,6 @@ MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(bt_tx_prio, 10);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(bt_force_ant, 10);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 64);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl,
|
||||
@ -1916,6 +1838,8 @@ MVM_DEBUGFS_READ_WRITE_STA_FILE_OPS(amsdu_len, 16);
|
||||
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(he_sniffer_params, 32);
|
||||
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(ltr_config, 512);
|
||||
|
||||
static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
@ -2091,7 +2015,6 @@ void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
|
||||
MVM_DEBUGFS_ADD_FILE(bt_force_ant, mvm->debugfs_dir, 0200);
|
||||
MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir, 0600);
|
||||
MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, 0600);
|
||||
MVM_DEBUGFS_ADD_FILE(d0i3_refs, mvm->debugfs_dir, 0600);
|
||||
MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, 0600);
|
||||
MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, 0200);
|
||||
MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, 0200);
|
||||
@ -2104,6 +2027,9 @@ void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
|
||||
#endif
|
||||
MVM_DEBUGFS_ADD_FILE(he_sniffer_params, mvm->debugfs_dir, 0600);
|
||||
|
||||
if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_LTR_GEN2))
|
||||
MVM_DEBUGFS_ADD_FILE(ltr_config, mvm->debugfs_dir, 0200);
|
||||
|
||||
debugfs_create_bool("enable_scan_iteration_notif", 0600,
|
||||
mvm->debugfs_dir, &mvm->scan_iter_notif_enabled);
|
||||
debugfs_create_bool("drop_bcn_ap_mode", 0600, mvm->debugfs_dir,
|
||||
|
@ -357,13 +357,14 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
|
||||
iwl_fw_dbg_error_collect(&mvm->fwrt,
|
||||
FW_DBG_TRIGGER_ALIVE_TIMEOUT);
|
||||
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000)
|
||||
if (trans->trans_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->cfg->device_family >= IWL_DEVICE_FAMILY_8000)
|
||||
else if (trans->trans_cfg->device_family >=
|
||||
IWL_DEVICE_FAMILY_8000)
|
||||
IWL_ERR(mvm,
|
||||
"SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n",
|
||||
iwl_read_prph(trans, SB_CPU_1_STATUS),
|
||||
@ -430,7 +431,7 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
|
||||
iwl_wait_init_complete,
|
||||
NULL);
|
||||
|
||||
iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_EARLY);
|
||||
iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_EARLY, NULL);
|
||||
|
||||
/* Will also start the device */
|
||||
ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR);
|
||||
@ -438,7 +439,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
|
||||
IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret);
|
||||
goto error;
|
||||
}
|
||||
iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_AFTER_ALIVE);
|
||||
iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_AFTER_ALIVE,
|
||||
NULL);
|
||||
|
||||
/* Send init config command to mark that we are sending NVM access
|
||||
* commands
|
||||
@ -557,7 +559,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
|
||||
goto remove_notif;
|
||||
}
|
||||
|
||||
if (mvm->cfg->device_family < IWL_DEVICE_FAMILY_8000) {
|
||||
if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000) {
|
||||
ret = iwl_mvm_send_bt_init_conf(mvm);
|
||||
if (ret)
|
||||
goto remove_notif;
|
||||
@ -1002,6 +1004,113 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
|
||||
return iwl_mvm_send_cmd_pdu(mvm, cmd_wide_id, 0, sizeof(cmd), &cmd);
|
||||
}
|
||||
|
||||
static int iwl_mvm_get_ppag_table(struct iwl_mvm *mvm)
|
||||
{
|
||||
union acpi_object *wifi_pkg, *data, *enabled;
|
||||
int i, j, ret, tbl_rev;
|
||||
int idx = 2;
|
||||
|
||||
mvm->ppag_table.enabled = cpu_to_le32(0);
|
||||
data = iwl_acpi_get_object(mvm->dev, ACPI_PPAG_METHOD);
|
||||
if (IS_ERR(data))
|
||||
return PTR_ERR(data);
|
||||
|
||||
wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data,
|
||||
ACPI_PPAG_WIFI_DATA_SIZE, &tbl_rev);
|
||||
|
||||
if (IS_ERR(wifi_pkg) || tbl_rev != 0) {
|
||||
ret = PTR_ERR(wifi_pkg);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
enabled = &wifi_pkg->package.elements[1];
|
||||
if (enabled->type != ACPI_TYPE_INTEGER ||
|
||||
(enabled->integer.value != 0 && enabled->integer.value != 1)) {
|
||||
ret = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
mvm->ppag_table.enabled = cpu_to_le32(enabled->integer.value);
|
||||
if (!mvm->ppag_table.enabled) {
|
||||
ret = 0;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/*
|
||||
* read, verify gain values and save them into the PPAG table.
|
||||
* first sub-band (j=0) corresponds to Low-Band (2.4GHz), and the
|
||||
* following sub-bands to High-Band (5GHz).
|
||||
*/
|
||||
for (i = 0; i < ACPI_PPAG_NUM_CHAINS; i++) {
|
||||
for (j = 0; j < ACPI_PPAG_NUM_SUB_BANDS; j++) {
|
||||
union acpi_object *ent;
|
||||
|
||||
ent = &wifi_pkg->package.elements[idx++];
|
||||
if (ent->type != ACPI_TYPE_INTEGER ||
|
||||
(j == 0 && ent->integer.value > ACPI_PPAG_MAX_LB) ||
|
||||
(j == 0 && ent->integer.value < ACPI_PPAG_MIN_LB) ||
|
||||
(j != 0 && ent->integer.value > ACPI_PPAG_MAX_HB) ||
|
||||
(j != 0 && ent->integer.value < ACPI_PPAG_MIN_HB)) {
|
||||
mvm->ppag_table.enabled = cpu_to_le32(0);
|
||||
ret = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
mvm->ppag_table.gain[i][j] = ent->integer.value;
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
out_free:
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm)
|
||||
{
|
||||
int i, j, ret;
|
||||
|
||||
if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_PPAG)) {
|
||||
IWL_DEBUG_RADIO(mvm,
|
||||
"PPAG capability not supported by FW, command not sent.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
IWL_DEBUG_RADIO(mvm, "Sending PER_PLATFORM_ANT_GAIN_CMD\n");
|
||||
IWL_DEBUG_RADIO(mvm, "PPAG is %s\n",
|
||||
mvm->ppag_table.enabled ? "enabled" : "disabled");
|
||||
|
||||
for (i = 0; i < ACPI_PPAG_NUM_CHAINS; i++) {
|
||||
for (j = 0; j < ACPI_PPAG_NUM_SUB_BANDS; j++) {
|
||||
IWL_DEBUG_RADIO(mvm,
|
||||
"PPAG table: chain[%d] band[%d]: gain = %d\n",
|
||||
i, j, mvm->ppag_table.gain[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(PHY_OPS_GROUP,
|
||||
PER_PLATFORM_ANT_GAIN_CMD),
|
||||
0, sizeof(mvm->ppag_table),
|
||||
&mvm->ppag_table);
|
||||
if (ret < 0)
|
||||
IWL_ERR(mvm, "failed to send PER_PLATFORM_ANT_GAIN_CMD (%d)\n",
|
||||
ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iwl_mvm_ppag_init(struct iwl_mvm *mvm)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = iwl_mvm_get_ppag_table(mvm);
|
||||
if (ret < 0) {
|
||||
IWL_DEBUG_RADIO(mvm,
|
||||
"PPAG BIOS table invalid or unavailable. (%d)\n",
|
||||
ret);
|
||||
return 0;
|
||||
}
|
||||
return iwl_mvm_ppag_send_cmd(mvm);
|
||||
}
|
||||
|
||||
#else /* CONFIG_ACPI */
|
||||
static int iwl_mvm_sar_get_wrds_table(struct iwl_mvm *mvm)
|
||||
{
|
||||
@ -1033,6 +1142,16 @@ int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static int iwl_mvm_ppag_init(struct iwl_mvm *mvm)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif /* CONFIG_ACPI */
|
||||
|
||||
void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
|
||||
@ -1140,17 +1259,13 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Stop and start the transport without entering low power
|
||||
* mode. This will save the state of other components on the
|
||||
* device that are triggered by the INIT firwmare (MFUART).
|
||||
*/
|
||||
_iwl_trans_stop_device(mvm->trans, false);
|
||||
ret = _iwl_trans_start_hw(mvm->trans, false);
|
||||
iwl_fw_dbg_stop_sync(&mvm->fwrt);
|
||||
iwl_trans_stop_device(mvm->trans);
|
||||
ret = iwl_trans_start_hw(mvm->trans);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_EARLY);
|
||||
iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_EARLY, NULL);
|
||||
|
||||
mvm->rfkill_safe_init_done = false;
|
||||
ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR);
|
||||
@ -1159,7 +1274,8 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm)
|
||||
|
||||
mvm->rfkill_safe_init_done = true;
|
||||
|
||||
iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_AFTER_ALIVE);
|
||||
iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_AFTER_ALIVE,
|
||||
NULL);
|
||||
|
||||
return iwl_init_paging(&mvm->fwrt, mvm->fwrt.cur_fw_img);
|
||||
}
|
||||
@ -1169,6 +1285,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
||||
int ret, i;
|
||||
struct ieee80211_channel *chan;
|
||||
struct cfg80211_chan_def chandef;
|
||||
struct ieee80211_supported_band *sband = NULL;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
@ -1191,7 +1308,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
||||
if (ret)
|
||||
IWL_ERR(mvm, "Failed to initialize Smart Fifo\n");
|
||||
|
||||
if (!mvm->trans->dbg.ini_valid) {
|
||||
if (!iwl_trans_dbg_ini_valid(mvm->trans)) {
|
||||
mvm->fwrt.dump.conf = FW_DBG_INVALID;
|
||||
/* if we have a destination, assume EARLY START */
|
||||
if (mvm->fw->dbg.dest_tlv)
|
||||
@ -1219,7 +1336,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
||||
goto error;
|
||||
|
||||
/* Init RSS configuration */
|
||||
if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000) {
|
||||
if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) {
|
||||
ret = iwl_configure_rxq(mvm);
|
||||
if (ret) {
|
||||
IWL_ERR(mvm, "Failed to configure RX queues: %d\n",
|
||||
@ -1246,9 +1363,11 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
||||
/* reset quota debouncing buffer - 0xff will yield invalid data */
|
||||
memset(&mvm->last_quota_cmd, 0xff, sizeof(mvm->last_quota_cmd));
|
||||
|
||||
if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_DQA_SUPPORT)) {
|
||||
ret = iwl_mvm_send_dqa_cmd(mvm);
|
||||
if (ret)
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Add auxiliary station for scanning */
|
||||
ret = iwl_mvm_add_aux_sta(mvm);
|
||||
@ -1256,7 +1375,15 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
||||
goto error;
|
||||
|
||||
/* Add all the PHY contexts */
|
||||
chan = &mvm->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[0];
|
||||
i = 0;
|
||||
while (!sband && i < NUM_NL80211_BANDS)
|
||||
sband = mvm->hw->wiphy->bands[i++];
|
||||
|
||||
if (WARN_ON_ONCE(!sband))
|
||||
goto error;
|
||||
|
||||
chan = &sband->channels[0];
|
||||
|
||||
cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
|
||||
for (i = 0; i < NUM_PHY_CTX; i++) {
|
||||
/*
|
||||
@ -1270,7 +1397,6 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_THERMAL
|
||||
if (iwl_mvm_is_tt_in_fw(mvm)) {
|
||||
/* in order to give the responsibility of ct-kill and
|
||||
* TX backoff to FW we need to send empty temperature reporting
|
||||
@ -1282,6 +1408,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
||||
iwl_mvm_tt_tx_backoff(mvm, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_THERMAL
|
||||
/* TODO: read the budget from BIOS / Platform NVM */
|
||||
|
||||
/*
|
||||
@ -1294,11 +1421,9 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
||||
if (ret)
|
||||
goto error;
|
||||
}
|
||||
#else
|
||||
/* Initialize tx backoffs to the minimal possible */
|
||||
iwl_mvm_tt_tx_backoff(mvm, 0);
|
||||
#endif
|
||||
|
||||
if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_LTR_GEN2))
|
||||
WARN_ON(iwl_mvm_config_ltr(mvm));
|
||||
|
||||
ret = iwl_mvm_power_update_device(mvm);
|
||||
@ -1323,16 +1448,16 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* allow FW/transport low power modes if not during restart */
|
||||
if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN);
|
||||
|
||||
if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
|
||||
iwl_mvm_send_recovery_cmd(mvm, ERROR_RECOVERY_UPDATE_DB);
|
||||
|
||||
if (iwl_acpi_get_eckv(mvm->dev, &mvm->ext_clock_valid))
|
||||
IWL_DEBUG_INFO(mvm, "ECKV table doesn't exist in BIOS\n");
|
||||
|
||||
ret = iwl_mvm_ppag_init(mvm);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
ret = iwl_mvm_sar_init(mvm);
|
||||
if (ret == 0) {
|
||||
ret = iwl_mvm_sar_geo_init(mvm);
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -29,7 +29,7 @@
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -156,7 +156,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->cfg->device_family < IWL_DEVICE_FAMILY_8000)
|
||||
if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000)
|
||||
return;
|
||||
|
||||
iwl_mvm_led_set(mvm, mvm->led.brightness > 0);
|
||||
|
@ -1431,6 +1431,9 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
|
||||
else if (rx_missed_bcon_since_rx > IWL_MVM_MISSED_BEACONS_THRESHOLD)
|
||||
ieee80211_beacon_loss(vif);
|
||||
|
||||
iwl_dbg_tlv_time_point(&mvm->fwrt,
|
||||
IWL_FW_INI_TIME_POINT_MISSED_BEACONS, NULL);
|
||||
|
||||
trigger = iwl_fw_dbg_trigger_on(&mvm->fwrt, ieee80211_vif_to_wdev(vif),
|
||||
FW_DBG_TRIGGER_MISSED_BEACONS);
|
||||
if (!trigger)
|
||||
@ -1447,8 +1450,6 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
|
||||
rx_missed_bcon >= stop_trig_missed_bcon)
|
||||
iwl_fw_dbg_collect_trig(&mvm->fwrt, trigger, NULL);
|
||||
|
||||
iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_MISSED_BEACONS);
|
||||
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
@ -1594,6 +1595,8 @@ void iwl_mvm_channel_switch_noa_notif(struct iwl_mvm *mvm,
|
||||
RCU_INIT_POINTER(mvm->csa_vif, NULL);
|
||||
return;
|
||||
case NL80211_IFTYPE_STATION:
|
||||
if (!fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
|
||||
iwl_mvm_csa_client_absent(mvm, vif);
|
||||
cancel_delayed_work(&mvmvif->csa_work);
|
||||
ieee80211_chswitch_done(vif, true);
|
||||
|
@ -213,91 +213,6 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key);
|
||||
|
||||
void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
|
||||
{
|
||||
if (!iwl_mvm_is_d0i3_supported(mvm))
|
||||
return;
|
||||
|
||||
IWL_DEBUG_RPM(mvm, "Take mvm reference - type %d\n", ref_type);
|
||||
spin_lock_bh(&mvm->refs_lock);
|
||||
mvm->refs[ref_type]++;
|
||||
spin_unlock_bh(&mvm->refs_lock);
|
||||
iwl_trans_ref(mvm->trans);
|
||||
}
|
||||
|
||||
void iwl_mvm_unref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
|
||||
{
|
||||
if (!iwl_mvm_is_d0i3_supported(mvm))
|
||||
return;
|
||||
|
||||
IWL_DEBUG_RPM(mvm, "Leave mvm reference - type %d\n", ref_type);
|
||||
spin_lock_bh(&mvm->refs_lock);
|
||||
if (WARN_ON(!mvm->refs[ref_type])) {
|
||||
spin_unlock_bh(&mvm->refs_lock);
|
||||
return;
|
||||
}
|
||||
mvm->refs[ref_type]--;
|
||||
spin_unlock_bh(&mvm->refs_lock);
|
||||
iwl_trans_unref(mvm->trans);
|
||||
}
|
||||
|
||||
static void iwl_mvm_unref_all_except(struct iwl_mvm *mvm,
|
||||
enum iwl_mvm_ref_type except_ref)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (!iwl_mvm_is_d0i3_supported(mvm))
|
||||
return;
|
||||
|
||||
spin_lock_bh(&mvm->refs_lock);
|
||||
for (i = 0; i < IWL_MVM_REF_COUNT; i++) {
|
||||
if (except_ref == i || !mvm->refs[i])
|
||||
continue;
|
||||
|
||||
IWL_DEBUG_RPM(mvm, "Cleanup: remove mvm ref type %d (%d)\n",
|
||||
i, mvm->refs[i]);
|
||||
for (j = 0; j < mvm->refs[i]; j++)
|
||||
iwl_trans_unref(mvm->trans);
|
||||
mvm->refs[i] = 0;
|
||||
}
|
||||
spin_unlock_bh(&mvm->refs_lock);
|
||||
}
|
||||
|
||||
bool iwl_mvm_ref_taken(struct iwl_mvm *mvm)
|
||||
{
|
||||
int i;
|
||||
bool taken = false;
|
||||
|
||||
if (!iwl_mvm_is_d0i3_supported(mvm))
|
||||
return true;
|
||||
|
||||
spin_lock_bh(&mvm->refs_lock);
|
||||
for (i = 0; i < IWL_MVM_REF_COUNT; i++) {
|
||||
if (mvm->refs[i]) {
|
||||
taken = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&mvm->refs_lock);
|
||||
|
||||
return taken;
|
||||
}
|
||||
|
||||
int iwl_mvm_ref_sync(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
|
||||
{
|
||||
iwl_mvm_ref(mvm, ref_type);
|
||||
|
||||
if (!wait_event_timeout(mvm->d0i3_exit_waitq,
|
||||
!test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status),
|
||||
HZ)) {
|
||||
WARN_ON_ONCE(1);
|
||||
iwl_mvm_unref(mvm, ref_type);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
|
||||
{
|
||||
int i;
|
||||
@ -485,7 +400,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->cfg->device_family >= IWL_DEVICE_FAMILY_9000)
|
||||
if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_9000)
|
||||
ieee80211_hw_set(hw, TX_AMSDU);
|
||||
ieee80211_hw_set(hw, TX_FRAG_LIST);
|
||||
|
||||
@ -762,12 +677,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
||||
mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
if (iwl_mvm_is_d0i3_supported(mvm) &&
|
||||
device_can_wakeup(mvm->trans->dev)) {
|
||||
mvm->wowlan.flags = WIPHY_WOWLAN_ANY;
|
||||
hw->wiphy->wowlan = &mvm->wowlan;
|
||||
}
|
||||
|
||||
if ((unified || mvm->fw->img[IWL_UCODE_WOWLAN].num_sec) &&
|
||||
mvm->trans->ops->d3_suspend &&
|
||||
mvm->trans->ops->d3_resume &&
|
||||
@ -833,46 +742,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool iwl_mvm_defer_tx(struct iwl_mvm *mvm,
|
||||
struct ieee80211_sta *sta,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct iwl_mvm_sta *mvmsta;
|
||||
bool defer = false;
|
||||
|
||||
/*
|
||||
* double check the IN_D0I3 flag both before and after
|
||||
* taking the spinlock, in order to prevent taking
|
||||
* the spinlock when not needed.
|
||||
*/
|
||||
if (likely(!test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status)))
|
||||
return false;
|
||||
|
||||
spin_lock(&mvm->d0i3_tx_lock);
|
||||
/*
|
||||
* testing the flag again ensures the skb dequeue
|
||||
* loop (on d0i3 exit) hasn't run yet.
|
||||
*/
|
||||
if (!test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status))
|
||||
goto out;
|
||||
|
||||
mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
if (mvmsta->sta_id == IWL_MVM_INVALID_STA ||
|
||||
mvmsta->sta_id != mvm->d0i3_ap_sta_id)
|
||||
goto out;
|
||||
|
||||
__skb_queue_tail(&mvm->d0i3_tx, skb);
|
||||
|
||||
/* trigger wakeup */
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_TX);
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_TX);
|
||||
|
||||
defer = true;
|
||||
out:
|
||||
spin_unlock(&mvm->d0i3_tx_lock);
|
||||
return defer;
|
||||
}
|
||||
|
||||
static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
|
||||
struct ieee80211_tx_control *control,
|
||||
struct sk_buff *skb)
|
||||
@ -917,8 +786,6 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
if (sta) {
|
||||
if (iwl_mvm_defer_tx(mvm, sta, skb))
|
||||
return;
|
||||
if (iwl_mvm_tx_skb(mvm, skb, sta))
|
||||
goto drop;
|
||||
return;
|
||||
@ -1086,7 +953,6 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
int ret;
|
||||
bool tx_agg_ref = false;
|
||||
struct ieee80211_sta *sta = params->sta;
|
||||
enum ieee80211_ampdu_mlme_action action = params->action;
|
||||
u16 tid = params->tid;
|
||||
@ -1101,31 +967,6 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
|
||||
if (!(mvm->nvm_data->sku_cap_11n_enable))
|
||||
return -EACCES;
|
||||
|
||||
/* return from D0i3 before starting a new Tx aggregation */
|
||||
switch (action) {
|
||||
case IEEE80211_AMPDU_TX_START:
|
||||
case IEEE80211_AMPDU_TX_STOP_CONT:
|
||||
case IEEE80211_AMPDU_TX_STOP_FLUSH:
|
||||
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
|
||||
case IEEE80211_AMPDU_TX_OPERATIONAL:
|
||||
/*
|
||||
* for tx start, wait synchronously until D0i3 exit to
|
||||
* get the correct sequence number for the tid.
|
||||
* additionally, some other ampdu actions use direct
|
||||
* target access, which is not handled automatically
|
||||
* by the trans layer (unlike commands), so wait for
|
||||
* d0i3 exit in these cases as well.
|
||||
*/
|
||||
ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_TX_AGG);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
tx_agg_ref = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
switch (action) {
|
||||
@ -1186,13 +1027,6 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
|
||||
}
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
/*
|
||||
* If the tid is marked as started, we won't use it for offloaded
|
||||
* traffic on the next D0i3 entry. It's safe to unref.
|
||||
*/
|
||||
if (tx_agg_ref)
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_TX_AGG);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1216,11 +1050,6 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
|
||||
|
||||
static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
|
||||
{
|
||||
/* cleanup all stale references (scan, roc), but keep the
|
||||
* ucode_down ref until reconfig is complete
|
||||
*/
|
||||
iwl_mvm_unref_all_except(mvm, IWL_MVM_REF_UCODE_DOWN);
|
||||
|
||||
iwl_mvm_stop_device(mvm);
|
||||
|
||||
mvm->cur_aid = 0;
|
||||
@ -1242,7 +1071,6 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
|
||||
ieee80211_iterate_interfaces(mvm->hw, 0, iwl_mvm_cleanup_iterator, mvm);
|
||||
|
||||
mvm->p2p_device_vif = NULL;
|
||||
mvm->d0i3_ap_sta_id = IWL_MVM_INVALID_STA;
|
||||
|
||||
iwl_mvm_reset_phy_ctxts(mvm);
|
||||
memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
|
||||
@ -1251,9 +1079,6 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
|
||||
|
||||
ieee80211_wake_queues(mvm->hw);
|
||||
|
||||
/* clear any stale d0i3 state */
|
||||
clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
|
||||
|
||||
mvm->vif_count = 0;
|
||||
mvm->rx_ba_sessions = 0;
|
||||
mvm->fwrt.dump.conf = FW_DBG_INVALID;
|
||||
@ -1278,18 +1103,13 @@ int __iwl_mvm_mac_start(struct iwl_mvm *mvm)
|
||||
clear_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status);
|
||||
/* Clean up some internal and mac80211 state on restart */
|
||||
iwl_mvm_restart_cleanup(mvm);
|
||||
} else {
|
||||
/* Hold the reference to prevent runtime suspend while
|
||||
* the start procedure runs. It's a bit confusing
|
||||
* that the UCODE_DOWN reference is taken, but it just
|
||||
* means "UCODE is not UP yet". ( TODO: rename this
|
||||
* reference).
|
||||
*/
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
|
||||
}
|
||||
ret = iwl_mvm_up(mvm);
|
||||
|
||||
iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_POST_INIT);
|
||||
iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_POST_INIT,
|
||||
NULL);
|
||||
iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_PERIODIC,
|
||||
NULL);
|
||||
|
||||
if (ret && test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
|
||||
/* Something went wrong - we need to finish some cleanup
|
||||
@ -1297,9 +1117,6 @@ int __iwl_mvm_mac_start(struct iwl_mvm *mvm)
|
||||
* would do.
|
||||
*/
|
||||
clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
|
||||
#ifdef CONFIG_PM
|
||||
iwl_mvm_d0i3_enable_tx(mvm, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -1310,19 +1127,6 @@ static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
int ret;
|
||||
|
||||
/* Some hw restart cleanups must not hold the mutex */
|
||||
if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
|
||||
/*
|
||||
* Make sure we are out of d0i3. This is needed
|
||||
* to make sure the reference accounting is correct
|
||||
* (and there is no stale d0i3_exit_work).
|
||||
*/
|
||||
wait_event_timeout(mvm->d0i3_exit_waitq,
|
||||
!test_bit(IWL_MVM_STATUS_IN_D0I3,
|
||||
&mvm->status),
|
||||
HZ);
|
||||
}
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
ret = __iwl_mvm_mac_start(mvm);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
@ -1337,17 +1141,12 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm)
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
|
||||
#ifdef CONFIG_PM
|
||||
iwl_mvm_d0i3_enable_tx(mvm, NULL);
|
||||
#endif
|
||||
|
||||
ret = iwl_mvm_update_quotas(mvm, true, NULL);
|
||||
if (ret)
|
||||
IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n",
|
||||
ret);
|
||||
|
||||
/* allow transport/FW low power modes */
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN);
|
||||
|
||||
iwl_mvm_send_recovery_cmd(mvm, ERROR_RECOVERY_END_OF_RECOVERY);
|
||||
|
||||
/*
|
||||
@ -1359,17 +1158,6 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm)
|
||||
mutex_unlock(&mvm->mutex);
|
||||
}
|
||||
|
||||
static void iwl_mvm_resume_complete(struct iwl_mvm *mvm)
|
||||
{
|
||||
if (iwl_mvm_is_d0i3_supported(mvm) &&
|
||||
iwl_mvm_enter_d0i3_on_suspend(mvm))
|
||||
WARN_ONCE(!wait_event_timeout(mvm->d0i3_exit_waitq,
|
||||
!test_bit(IWL_MVM_STATUS_IN_D0I3,
|
||||
&mvm->status),
|
||||
HZ),
|
||||
"D0i3 exit on resume timed out\n");
|
||||
}
|
||||
|
||||
static void
|
||||
iwl_mvm_mac_reconfig_complete(struct ieee80211_hw *hw,
|
||||
enum ieee80211_reconfig_type reconfig_type)
|
||||
@ -1381,7 +1169,6 @@ iwl_mvm_mac_reconfig_complete(struct ieee80211_hw *hw,
|
||||
iwl_mvm_restart_complete(mvm);
|
||||
break;
|
||||
case IEEE80211_RECONFIG_TYPE_SUSPEND:
|
||||
iwl_mvm_resume_complete(mvm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1443,7 +1230,6 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
|
||||
flush_work(&mvm->d0i3_exit_work);
|
||||
flush_work(&mvm->async_handlers_wk);
|
||||
flush_work(&mvm->add_stream_wk);
|
||||
|
||||
@ -1457,7 +1243,6 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
|
||||
*/
|
||||
clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status);
|
||||
|
||||
iwl_fw_cancel_dumps(&mvm->fwrt);
|
||||
cancel_delayed_work_sync(&mvm->cs_tx_unblock_dwork);
|
||||
cancel_delayed_work_sync(&mvm->scan_timeout_dwork);
|
||||
iwl_fw_free_dump_desc(&mvm->fwrt);
|
||||
@ -1543,16 +1328,21 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw,
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (!fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
|
||||
iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false);
|
||||
|
||||
iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
|
||||
|
||||
if (!fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) {
|
||||
ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
iwl_mvm_stop_session_protection(mvm, vif);
|
||||
}
|
||||
}
|
||||
|
||||
mvmvif->ps_disabled = false;
|
||||
|
||||
@ -1611,15 +1401,6 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
|
||||
mvmvif->mvm = mvm;
|
||||
RCU_INIT_POINTER(mvmvif->probe_resp_data, NULL);
|
||||
|
||||
/*
|
||||
* make sure D0i3 exit is completed, otherwise a target access
|
||||
* during tx queue configuration could be done when still in
|
||||
* D0i3 state.
|
||||
*/
|
||||
ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_ADD_IF);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Not much to do here. The stack will not allow interface
|
||||
* types or combinations that we didn't advertise, so we
|
||||
@ -1755,8 +1536,6 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
|
||||
out_unlock:
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_ADD_IF);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2254,6 +2033,10 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm,
|
||||
|
||||
flags = 0;
|
||||
|
||||
/* Block 26-tone RU OFDMA transmissions */
|
||||
if (mvmvif->he_ru_2mhz_block)
|
||||
flags |= STA_CTXT_HE_RU_2MHZ_BLOCK;
|
||||
|
||||
/* HTC flags */
|
||||
if (sta->he_cap.he_cap_elem.mac_cap_info[0] &
|
||||
IEEE80211_HE_MAC_CAP0_HTC_HE)
|
||||
@ -2520,7 +2303,6 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
|
||||
iwl_mvm_sf_update(mvm, vif, false);
|
||||
iwl_mvm_power_vif_assoc(mvm, vif);
|
||||
if (vif->p2p) {
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_P2P_CLIENT);
|
||||
iwl_mvm_update_smps(mvm, vif,
|
||||
IWL_MVM_SMPS_REQ_PROT,
|
||||
IEEE80211_SMPS_DYNAMIC);
|
||||
@ -2556,9 +2338,6 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
|
||||
IWL_ERR(mvm,
|
||||
"failed to remove AP station\n");
|
||||
|
||||
if (mvm->d0i3_ap_sta_id == mvmvif->ap_sta_id)
|
||||
mvm->d0i3_ap_sta_id =
|
||||
IWL_MVM_INVALID_STA;
|
||||
mvmvif->ap_sta_id = IWL_MVM_INVALID_STA;
|
||||
}
|
||||
|
||||
@ -2567,9 +2346,6 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
|
||||
if (ret)
|
||||
IWL_ERR(mvm, "failed to update quotas\n");
|
||||
|
||||
if (vif->p2p)
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_P2P_CLIENT);
|
||||
|
||||
/* this will take the cleared BSSID from bss_conf */
|
||||
ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
|
||||
if (ret)
|
||||
@ -2657,14 +2433,6 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
int ret, i;
|
||||
|
||||
/*
|
||||
* iwl_mvm_mac_ctxt_add() might read directly from the device
|
||||
* (the system time), so make sure it is available.
|
||||
*/
|
||||
ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_START_AP);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
/* Send the beacon template */
|
||||
@ -2760,8 +2528,6 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
|
||||
if (vif->p2p && mvm->p2p_device_vif)
|
||||
iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL);
|
||||
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_AP_IBSS);
|
||||
|
||||
iwl_mvm_bt_coex_vif_change(mvm);
|
||||
|
||||
/* we don't support TDLS during DCM */
|
||||
@ -2783,7 +2549,6 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
|
||||
iwl_mvm_mac_ctxt_remove(mvm, vif);
|
||||
out_unlock:
|
||||
mutex_unlock(&mvm->mutex);
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_START_AP);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2821,8 +2586,6 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
|
||||
|
||||
iwl_mvm_bt_coex_vif_change(mvm);
|
||||
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_AP_IBSS);
|
||||
|
||||
/* Need to update the P2P Device MAC (only GO, IBSS is single vif) */
|
||||
if (vif->p2p && mvm->p2p_device_vif)
|
||||
iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL);
|
||||
@ -2896,14 +2659,6 @@ static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
|
||||
/*
|
||||
* iwl_mvm_bss_info_changed_station() might call
|
||||
* iwl_mvm_protect_session(), which reads directly from
|
||||
* the device (the system time), so make sure it is available.
|
||||
*/
|
||||
if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_BSS_CHANGED))
|
||||
return;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
if (changes & BSS_CHANGED_IDLE && !bss_conf->idle)
|
||||
@ -2927,7 +2682,6 @@ static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
mutex_unlock(&mvm->mutex);
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_BSS_CHANGED);
|
||||
}
|
||||
|
||||
static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
|
||||
@ -3205,6 +2959,51 @@ iwl_mvm_tdls_check_trigger(struct iwl_mvm *mvm,
|
||||
peer_addr, action);
|
||||
}
|
||||
|
||||
struct iwl_mvm_he_obss_narrow_bw_ru_data {
|
||||
bool tolerated;
|
||||
};
|
||||
|
||||
static void iwl_mvm_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy,
|
||||
struct cfg80211_bss *bss,
|
||||
void *_data)
|
||||
{
|
||||
struct iwl_mvm_he_obss_narrow_bw_ru_data *data = _data;
|
||||
const struct element *elem;
|
||||
|
||||
elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, bss->ies->data,
|
||||
bss->ies->len);
|
||||
|
||||
if (!elem || elem->datalen < 10 ||
|
||||
!(elem->data[10] &
|
||||
WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT)) {
|
||||
data->tolerated = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void iwl_mvm_check_he_obss_narrow_bw_ru(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_mvm_he_obss_narrow_bw_ru_data iter_data = {
|
||||
.tolerated = true,
|
||||
};
|
||||
|
||||
if (!(vif->bss_conf.chandef.chan->flags & IEEE80211_CHAN_RADAR)) {
|
||||
mvmvif->he_ru_2mhz_block = false;
|
||||
return;
|
||||
}
|
||||
|
||||
cfg80211_bss_iter(hw->wiphy, &vif->bss_conf.chandef,
|
||||
iwl_mvm_check_he_obss_narrow_bw_ru_iter,
|
||||
&iter_data);
|
||||
|
||||
/*
|
||||
* If there is at least one AP on radar channel that cannot
|
||||
* tolerate 26-tone RU UL OFDMA transmissions using HE TB PPDU.
|
||||
*/
|
||||
mvmvif->he_ru_2mhz_block = !iter_data.tolerated;
|
||||
}
|
||||
|
||||
static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
@ -3306,6 +3105,11 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
|
||||
iwl_mvm_cfg_he_sta(mvm, vif, mvm_sta->sta_id);
|
||||
} else if (vif->type == NL80211_IFTYPE_STATION) {
|
||||
vif->bss_conf.he_support = sta->he_cap.has_he;
|
||||
|
||||
mvmvif->he_ru_2mhz_block = false;
|
||||
if (sta->he_cap.has_he)
|
||||
iwl_mvm_check_he_obss_narrow_bw_ru(hw, vif);
|
||||
|
||||
iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
|
||||
}
|
||||
|
||||
@ -3447,13 +3251,6 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
|
||||
u32 duration = IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS;
|
||||
u32 min_duration = IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS;
|
||||
|
||||
/*
|
||||
* iwl_mvm_protect_session() reads directly from the device
|
||||
* (the system time), so make sure it is available.
|
||||
*/
|
||||
if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PREPARE_TX))
|
||||
return;
|
||||
|
||||
if (req_duration > duration)
|
||||
duration = req_duration;
|
||||
|
||||
@ -3461,8 +3258,6 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
|
||||
/* Try really hard to protect the session and hear a beacon */
|
||||
iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500, false);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_PREPARE_TX);
|
||||
}
|
||||
|
||||
static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
|
||||
@ -3537,7 +3332,7 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
|
||||
|
||||
switch (key->cipher) {
|
||||
case WLAN_CIPHER_SUITE_TKIP:
|
||||
if (!mvm->trans->cfg->gen2) {
|
||||
if (!mvm->trans->trans_cfg->gen2) {
|
||||
key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
|
||||
key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
|
||||
} else if (vif->type == NL80211_IFTYPE_STATION) {
|
||||
@ -4278,23 +4073,12 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
|
||||
IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) {
|
||||
u32 duration = 3 * vif->bss_conf.beacon_int;
|
||||
|
||||
|
||||
/* iwl_mvm_protect_session() reads directly from the
|
||||
* device (the system time), so make sure it is
|
||||
* available.
|
||||
*/
|
||||
ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PROTECT_CSA);
|
||||
if (ret)
|
||||
goto out_remove_binding;
|
||||
|
||||
/* Protect the session to make sure we hear the first
|
||||
* beacon on the new channel.
|
||||
*/
|
||||
iwl_mvm_protect_session(mvm, vif, duration, duration,
|
||||
vif->bss_conf.beacon_int / 2,
|
||||
true);
|
||||
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_CSA);
|
||||
}
|
||||
|
||||
iwl_mvm_update_quotas(mvm, false, NULL);
|
||||
@ -4644,6 +4428,42 @@ static int iwl_mvm_schedule_client_csa(struct iwl_mvm *mvm,
|
||||
0, sizeof(cmd), &cmd);
|
||||
}
|
||||
|
||||
static int iwl_mvm_old_pre_chan_sw_sta(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_channel_switch *chsw)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
u32 apply_time;
|
||||
|
||||
/* Schedule the time event to a bit before beacon 1,
|
||||
* to make sure we're in the new channel when the
|
||||
* GO/AP arrives. In case count <= 1 immediately schedule the
|
||||
* TE (this might result with some packet loss or connection
|
||||
* loss).
|
||||
*/
|
||||
if (chsw->count <= 1)
|
||||
apply_time = 0;
|
||||
else
|
||||
apply_time = chsw->device_timestamp +
|
||||
((vif->bss_conf.beacon_int * (chsw->count - 1) -
|
||||
IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024);
|
||||
|
||||
if (chsw->block_tx)
|
||||
iwl_mvm_csa_client_absent(mvm, vif);
|
||||
|
||||
if (mvmvif->bf_data.bf_enabled) {
|
||||
int ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
iwl_mvm_schedule_csa_period(mvm, vif, vif->bss_conf.beacon_int,
|
||||
apply_time);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define IWL_MAX_CSA_BLOCK_TX 1500
|
||||
static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
@ -4652,7 +4472,6 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
struct ieee80211_vif *csa_vif;
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
u32 apply_time;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
@ -4696,21 +4515,7 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
|
||||
|
||||
break;
|
||||
case NL80211_IFTYPE_STATION:
|
||||
/* Schedule the time event to a bit before beacon 1,
|
||||
* to make sure we're in the new channel when the
|
||||
* GO/AP arrives. In case count <= 1 immediately schedule the
|
||||
* TE (this might result with some packet loss or connection
|
||||
* loss).
|
||||
*/
|
||||
if (chsw->count <= 1)
|
||||
apply_time = 0;
|
||||
else
|
||||
apply_time = chsw->device_timestamp +
|
||||
((vif->bss_conf.beacon_int * (chsw->count - 1) -
|
||||
IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024);
|
||||
|
||||
if (chsw->block_tx) {
|
||||
iwl_mvm_csa_client_absent(mvm, vif);
|
||||
/*
|
||||
* In case of undetermined / long time with immediate
|
||||
* quiet monitor status to gracefully disconnect
|
||||
@ -4722,19 +4527,14 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
|
||||
msecs_to_jiffies(IWL_MAX_CSA_BLOCK_TX));
|
||||
}
|
||||
|
||||
if (mvmvif->bf_data.bf_enabled) {
|
||||
ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
|
||||
if (!fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) {
|
||||
ret = iwl_mvm_old_pre_chan_sw_sta(mvm, vif, chsw);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
|
||||
} else {
|
||||
iwl_mvm_schedule_client_csa(mvm, vif, chsw);
|
||||
else
|
||||
iwl_mvm_schedule_csa_period(mvm, vif,
|
||||
vif->bss_conf.beacon_int,
|
||||
apply_time);
|
||||
}
|
||||
|
||||
mvmvif->csa_count = chsw->count;
|
||||
mvmvif->csa_misbehave = false;
|
||||
|
@ -258,38 +258,6 @@ enum iwl_mvm_smps_type_request {
|
||||
NUM_IWL_MVM_SMPS_REQ,
|
||||
};
|
||||
|
||||
enum iwl_mvm_ref_type {
|
||||
IWL_MVM_REF_UCODE_DOWN,
|
||||
IWL_MVM_REF_SCAN,
|
||||
IWL_MVM_REF_ROC,
|
||||
IWL_MVM_REF_ROC_AUX,
|
||||
IWL_MVM_REF_P2P_CLIENT,
|
||||
IWL_MVM_REF_AP_IBSS,
|
||||
IWL_MVM_REF_USER,
|
||||
IWL_MVM_REF_TX,
|
||||
IWL_MVM_REF_TX_AGG,
|
||||
IWL_MVM_REF_ADD_IF,
|
||||
IWL_MVM_REF_START_AP,
|
||||
IWL_MVM_REF_BSS_CHANGED,
|
||||
IWL_MVM_REF_PREPARE_TX,
|
||||
IWL_MVM_REF_PROTECT_TDLS,
|
||||
IWL_MVM_REF_CHECK_CTKILL,
|
||||
IWL_MVM_REF_PRPH_READ,
|
||||
IWL_MVM_REF_PRPH_WRITE,
|
||||
IWL_MVM_REF_NMI,
|
||||
IWL_MVM_REF_TM_CMD,
|
||||
IWL_MVM_REF_EXIT_WORK,
|
||||
IWL_MVM_REF_PROTECT_CSA,
|
||||
IWL_MVM_REF_FW_DBG_COLLECT,
|
||||
IWL_MVM_REF_INIT_UCODE,
|
||||
IWL_MVM_REF_SENDING_CMD,
|
||||
IWL_MVM_REF_RX,
|
||||
|
||||
/* update debugfs.c when changing this */
|
||||
|
||||
IWL_MVM_REF_COUNT,
|
||||
};
|
||||
|
||||
enum iwl_bt_force_ant_mode {
|
||||
BT_FORCE_ANT_DIS = 0,
|
||||
BT_FORCE_ANT_AUTO,
|
||||
@ -504,6 +472,9 @@ struct iwl_mvm_vif {
|
||||
|
||||
/* we can only have 2 GTK + 2 IGTK active at a time */
|
||||
struct ieee80211_key_conf *ap_early_keys[4];
|
||||
|
||||
/* 26-tone RU OFDMA transmissions should be blocked */
|
||||
bool he_ru_2mhz_block;
|
||||
};
|
||||
|
||||
static inline struct iwl_mvm_vif *
|
||||
@ -617,11 +588,6 @@ struct iwl_mvm_frame_stats {
|
||||
int last_frame_idx;
|
||||
};
|
||||
|
||||
enum {
|
||||
D0I3_DEFER_WAKEUP,
|
||||
D0I3_PENDING_WAKEUP,
|
||||
};
|
||||
|
||||
#define IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE 0xff
|
||||
#define IWL_MVM_DEBUG_SET_TEMPERATURE_MIN -100
|
||||
#define IWL_MVM_DEBUG_SET_TEMPERATURE_MAX 200
|
||||
@ -695,6 +661,12 @@ struct iwl_mvm_tcm {
|
||||
* @valid: reordering is valid for this queue
|
||||
* @lock: protect reorder buffer internal state
|
||||
* @mvm: mvm pointer, needed for frame timer context
|
||||
* @consec_oldsn_drops: consecutive drops due to old SN
|
||||
* @consec_oldsn_ampdu_gp2: A-MPDU GP2 timestamp to track
|
||||
* when to apply old SN consecutive drop workaround
|
||||
* @consec_oldsn_prev_drop: track whether or not an MPDU
|
||||
* that was single/part of the previous A-MPDU was
|
||||
* dropped due to old SN
|
||||
*/
|
||||
struct iwl_mvm_reorder_buffer {
|
||||
u16 head_sn;
|
||||
@ -708,6 +680,9 @@ struct iwl_mvm_reorder_buffer {
|
||||
bool valid;
|
||||
spinlock_t lock;
|
||||
struct iwl_mvm *mvm;
|
||||
unsigned int consec_oldsn_drops;
|
||||
u32 consec_oldsn_ampdu_gp2;
|
||||
unsigned int consec_oldsn_prev_drop:1;
|
||||
} ____cacheline_aligned_in_smp;
|
||||
|
||||
/**
|
||||
@ -1011,10 +986,6 @@ struct iwl_mvm {
|
||||
unsigned long fw_key_table[BITS_TO_LONGS(STA_KEY_MAX_NUM)];
|
||||
u8 fw_key_deleted[STA_KEY_MAX_NUM];
|
||||
|
||||
/* references taken by the driver and spinlock protecting them */
|
||||
spinlock_t refs_lock;
|
||||
u8 refs[IWL_MVM_REF_COUNT];
|
||||
|
||||
u8 vif_count;
|
||||
struct ieee80211_vif __rcu *vif_id_to_mac[NUM_MAC_INDEX_DRIVER];
|
||||
|
||||
@ -1039,6 +1010,7 @@ struct iwl_mvm {
|
||||
struct ieee80211_channel **nd_channels;
|
||||
int n_nd_channels;
|
||||
bool net_detect;
|
||||
u8 offload_tid;
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
bool d3_wake_sysassert;
|
||||
bool d3_test_active;
|
||||
@ -1048,17 +1020,6 @@ struct iwl_mvm {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* d0i3 */
|
||||
u8 d0i3_ap_sta_id;
|
||||
bool d0i3_offloading;
|
||||
struct work_struct d0i3_exit_work;
|
||||
struct sk_buff_head d0i3_tx;
|
||||
/* protect d0i3_suspend_flags */
|
||||
struct mutex d0i3_suspend_mutex;
|
||||
unsigned long d0i3_suspend_flags;
|
||||
/* sync d0i3_tx queue and IWL_MVM_STATUS_IN_D0I3 status flag */
|
||||
spinlock_t d0i3_tx_lock;
|
||||
wait_queue_head_t d0i3_exit_waitq;
|
||||
wait_queue_head_t rx_sync_waitq;
|
||||
|
||||
/* BT-Coex */
|
||||
@ -1184,6 +1145,8 @@ struct iwl_mvm {
|
||||
struct iwl_mvm_sar_profile sar_profiles[ACPI_SAR_PROFILE_NUM];
|
||||
struct iwl_mvm_geo_profile geo_profiles[ACPI_NUM_GEO_PROFILES];
|
||||
u32 geo_rev;
|
||||
struct iwl_ppag_table_cmd ppag_table;
|
||||
u32 ppag_rev;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -1201,7 +1164,6 @@ struct iwl_mvm {
|
||||
* @IWL_MVM_STATUS_ROC_RUNNING: remain-on-channel is running
|
||||
* @IWL_MVM_STATUS_HW_RESTART_REQUESTED: HW restart was requested
|
||||
* @IWL_MVM_STATUS_IN_HW_RESTART: HW restart is active
|
||||
* @IWL_MVM_STATUS_IN_D0I3: NIC is in D0i3
|
||||
* @IWL_MVM_STATUS_ROC_AUX_RUNNING: AUX remain-on-channel is running
|
||||
* @IWL_MVM_STATUS_FIRMWARE_RUNNING: firmware is running
|
||||
* @IWL_MVM_STATUS_NEED_FLUSH_P2P: need to flush P2P bcast STA
|
||||
@ -1212,7 +1174,6 @@ enum iwl_mvm_status {
|
||||
IWL_MVM_STATUS_ROC_RUNNING,
|
||||
IWL_MVM_STATUS_HW_RESTART_REQUESTED,
|
||||
IWL_MVM_STATUS_IN_HW_RESTART,
|
||||
IWL_MVM_STATUS_IN_D0I3,
|
||||
IWL_MVM_STATUS_ROC_AUX_RUNNING,
|
||||
IWL_MVM_STATUS_FIRMWARE_RUNNING,
|
||||
IWL_MVM_STATUS_NEED_FLUSH_P2P,
|
||||
@ -1291,13 +1252,6 @@ iwl_mvm_rcu_dereference_vif_id(struct iwl_mvm *mvm, u8 vif_id, bool rcu)
|
||||
lockdep_is_held(&mvm->mutex));
|
||||
}
|
||||
|
||||
static inline bool iwl_mvm_is_d0i3_supported(struct iwl_mvm *mvm)
|
||||
{
|
||||
return !iwlwifi_mod_params.d0i3_disable &&
|
||||
fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_D0I3_SUPPORT);
|
||||
}
|
||||
|
||||
static inline bool iwl_mvm_is_adaptive_dwell_supported(struct iwl_mvm *mvm)
|
||||
{
|
||||
return fw_has_api(&mvm->fw->ucode_capa,
|
||||
@ -1333,19 +1287,6 @@ static inline bool iwl_mvm_is_short_beacon_notif_supported(struct iwl_mvm *mvm)
|
||||
IWL_UCODE_TLV_API_SHORT_BEACON_NOTIF);
|
||||
}
|
||||
|
||||
static inline bool iwl_mvm_enter_d0i3_on_suspend(struct iwl_mvm *mvm)
|
||||
{
|
||||
/* For now we only use this mode to differentiate between
|
||||
* slave transports, which handle D0i3 entry in suspend by
|
||||
* themselves in conjunction with runtime PM D0i3. So, this
|
||||
* function is used to check whether we need to do anything
|
||||
* when entering suspend or if the transport layer has already
|
||||
* done it.
|
||||
*/
|
||||
return (mvm->trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3) &&
|
||||
(mvm->trans->runtime_pm_mode != IWL_PLAT_PM_MODE_D0I3);
|
||||
}
|
||||
|
||||
static inline bool iwl_mvm_is_dqa_data_queue(struct iwl_mvm *mvm, u8 queue)
|
||||
{
|
||||
return (queue >= IWL_MVM_DQA_MIN_DATA_QUEUE) &&
|
||||
@ -1424,13 +1365,13 @@ static inline bool iwl_mvm_has_new_rx_api(struct iwl_mvm *mvm)
|
||||
static inline bool iwl_mvm_has_new_tx_api(struct iwl_mvm *mvm)
|
||||
{
|
||||
/* TODO - replace with TLV once defined */
|
||||
return mvm->trans->cfg->use_tfh;
|
||||
return mvm->trans->trans_cfg->use_tfh;
|
||||
}
|
||||
|
||||
static inline bool iwl_mvm_has_unified_ucode(struct iwl_mvm *mvm)
|
||||
{
|
||||
/* TODO - better define this */
|
||||
return mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000;
|
||||
return mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000;
|
||||
}
|
||||
|
||||
static inline bool iwl_mvm_is_cdb_supported(struct iwl_mvm *mvm)
|
||||
@ -1455,7 +1396,13 @@ 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->cfg->device_family >= IWL_DEVICE_FAMILY_22000;
|
||||
return mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000;
|
||||
}
|
||||
|
||||
static inline bool iwl_mvm_is_scan_ext_chan_supported(struct iwl_mvm *mvm)
|
||||
{
|
||||
return fw_has_api(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_API_SCAN_EXT_CHAN_VER);
|
||||
}
|
||||
|
||||
static inline bool iwl_mvm_has_new_rx_stats_api(struct iwl_mvm *mvm)
|
||||
@ -1487,7 +1434,6 @@ iwl_mvm_get_agg_status(struct iwl_mvm *mvm, void *tx_resp)
|
||||
|
||||
static inline bool iwl_mvm_is_tt_in_fw(struct iwl_mvm *mvm)
|
||||
{
|
||||
#ifdef CONFIG_THERMAL
|
||||
/* these two TLV are redundant since the responsibility to CT-kill by
|
||||
* FW happens only after we send at least one command of
|
||||
* temperature THs report.
|
||||
@ -1496,9 +1442,6 @@ static inline bool iwl_mvm_is_tt_in_fw(struct iwl_mvm *mvm)
|
||||
IWL_UCODE_TLV_CAPA_CT_KILL_BY_FW) &&
|
||||
fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_TEMP_THS_REPORT_SUPPORT);
|
||||
#else /* CONFIG_THERMAL */
|
||||
return false;
|
||||
#endif /* CONFIG_THERMAL */
|
||||
}
|
||||
|
||||
static inline bool iwl_mvm_is_ctdp_supported(struct iwl_mvm *mvm)
|
||||
@ -1663,6 +1606,8 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct iwl_rx_cmd_buffer *rxb, int queue);
|
||||
void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct iwl_rx_cmd_buffer *rxb, int queue);
|
||||
void iwl_mvm_rx_bar_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct iwl_rx_cmd_buffer *rxb, int queue);
|
||||
int iwl_mvm_notify_rx_queue(struct iwl_mvm *mvm, u32 rxq_mask,
|
||||
const u8 *data, u32 count, bool async);
|
||||
void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
@ -1863,30 +1808,9 @@ void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw,
|
||||
extern const struct file_operations iwl_dbgfs_d3_test_ops;
|
||||
struct iwl_wowlan_status *iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm);
|
||||
#ifdef CONFIG_PM
|
||||
int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
bool host_awake,
|
||||
u32 cmd_flags);
|
||||
void iwl_mvm_d0i3_update_keys(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
struct iwl_wowlan_status *status);
|
||||
void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif);
|
||||
#else
|
||||
static inline int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
bool host_awake,
|
||||
u32 cmd_flags)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void iwl_mvm_d0i3_update_keys(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
struct iwl_wowlan_status *status)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
{
|
||||
@ -1900,19 +1824,6 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
|
||||
bool offload_ns,
|
||||
u32 cmd_flags);
|
||||
|
||||
/* D0i3 */
|
||||
void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type);
|
||||
void iwl_mvm_unref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type);
|
||||
int iwl_mvm_ref_sync(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type);
|
||||
bool iwl_mvm_ref_taken(struct iwl_mvm *mvm);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq);
|
||||
int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode);
|
||||
int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode);
|
||||
int _iwl_mvm_exit_d0i3(struct iwl_mvm *mvm);
|
||||
#endif
|
||||
|
||||
/* BT Coex */
|
||||
int iwl_mvm_send_bt_init_conf(struct iwl_mvm *mvm);
|
||||
void iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
|
||||
@ -1943,9 +1854,6 @@ iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
|
||||
struct iwl_beacon_filter_cmd *cmd)
|
||||
{}
|
||||
#endif
|
||||
int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
bool enable, u32 flags);
|
||||
int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
u32 flags);
|
||||
@ -2025,7 +1933,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->cfg->base_params->num_of_queues) - 1) &
|
||||
return ((BIT(mvm->trans->trans_cfg->base_params->num_of_queues) - 1) &
|
||||
~BIT(IWL_MVM_DQA_CMD_QUEUE));
|
||||
}
|
||||
|
||||
@ -2034,7 +1942,8 @@ static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm)
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
iwl_fw_cancel_timestamp(&mvm->fwrt);
|
||||
clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status);
|
||||
iwl_fwrt_stop_device(&mvm->fwrt);
|
||||
iwl_fw_dbg_stop_sync(&mvm->fwrt);
|
||||
iwl_trans_stop_device(mvm->trans);
|
||||
iwl_free_fw_paging(&mvm->fwrt);
|
||||
iwl_fw_dump_conf_clear(&mvm->fwrt);
|
||||
}
|
||||
@ -2154,6 +2063,7 @@ void iwl_mvm_event_frame_timeout_callback(struct iwl_mvm *mvm,
|
||||
|
||||
int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b);
|
||||
int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm);
|
||||
int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm);
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
void iwl_mvm_sta_add_debugfs(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
|
@ -249,7 +249,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->cfg->base_params->eeprom_size) {
|
||||
mvm->trans->trans_cfg->base_params->eeprom_size) {
|
||||
IWL_ERR(mvm, "EEPROM size is too small for NVM\n");
|
||||
return -ENOBUFS;
|
||||
}
|
||||
@ -372,7 +372,7 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
|
||||
/* Read From FW NVM */
|
||||
IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
|
||||
|
||||
nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
|
||||
nvm_buffer = kmalloc(mvm->trans->trans_cfg->base_params->eeprom_size,
|
||||
GFP_KERNEL);
|
||||
if (!nvm_buffer)
|
||||
return -ENOMEM;
|
||||
|
@ -173,7 +173,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->cfg->device_family < IWL_DEVICE_FAMILY_8000)
|
||||
if (mvm->trans->trans_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))
|
||||
@ -389,6 +389,7 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
|
||||
HCMD_NAME(SCAN_ITERATION_COMPLETE_UMAC),
|
||||
HCMD_NAME(REPLY_RX_PHY_CMD),
|
||||
HCMD_NAME(REPLY_RX_MPDU_CMD),
|
||||
HCMD_NAME(BAR_FRAME_RELEASE),
|
||||
HCMD_NAME(FRAME_RELEASE),
|
||||
HCMD_NAME(BA_NOTIF),
|
||||
HCMD_NAME(MCC_UPDATE_CMD),
|
||||
@ -414,6 +415,7 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
|
||||
HCMD_NAME(SCAN_ITERATION_COMPLETE),
|
||||
HCMD_NAME(D0I3_END_CMD),
|
||||
HCMD_NAME(LTR_CONFIG),
|
||||
HCMD_NAME(LDBG_CONFIG_CMD),
|
||||
};
|
||||
|
||||
/* Please keep this array *SORTED* by hex value.
|
||||
@ -465,6 +467,8 @@ static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = {
|
||||
* Access is done through binary search
|
||||
*/
|
||||
static const struct iwl_hcmd_names iwl_mvm_debug_names[] = {
|
||||
HCMD_NAME(DBGC_SUSPEND_RESUME),
|
||||
HCMD_NAME(BUFFER_ALLOCATION),
|
||||
HCMD_NAME(MFU_ASSERT_DUMP_NTF),
|
||||
};
|
||||
|
||||
@ -514,9 +518,6 @@ static const struct iwl_hcmd_arr iwl_mvm_groups[] = {
|
||||
|
||||
/* this forward declaration can avoid to export the function */
|
||||
static void iwl_mvm_async_handlers_wk(struct work_struct *wk);
|
||||
#ifdef CONFIG_PM
|
||||
static void iwl_mvm_d0i3_exit_work(struct work_struct *wk);
|
||||
#endif
|
||||
|
||||
static u32 iwl_mvm_min_backoff(struct iwl_mvm *mvm)
|
||||
{
|
||||
@ -564,23 +565,16 @@ static void iwl_mvm_tx_unblock_dwork(struct work_struct *work)
|
||||
static int iwl_mvm_fwrt_dump_start(void *ctx)
|
||||
{
|
||||
struct iwl_mvm *mvm = ctx;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_FW_DBG_COLLECT);
|
||||
if (ret)
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void iwl_mvm_fwrt_dump_end(void *ctx)
|
||||
{
|
||||
struct iwl_mvm *mvm = ctx;
|
||||
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_FW_DBG_COLLECT);
|
||||
|
||||
mutex_unlock(&mvm->mutex);
|
||||
}
|
||||
|
||||
@ -672,7 +666,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
if (iwl_mvm_has_new_rx_api(mvm)) {
|
||||
op_mode->ops = &iwl_mvm_ops_mq;
|
||||
trans->rx_mpdu_cmd_hdr_size =
|
||||
(trans->cfg->device_family >=
|
||||
(trans->trans_cfg->device_family >=
|
||||
IWL_DEVICE_FAMILY_22560) ?
|
||||
sizeof(struct iwl_rx_mpdu_desc) :
|
||||
IWL_RX_DESC_SIZE_V1;
|
||||
@ -700,7 +694,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
mvm->drop_bcn_ap_mode = true;
|
||||
|
||||
mutex_init(&mvm->mutex);
|
||||
mutex_init(&mvm->d0i3_suspend_mutex);
|
||||
spin_lock_init(&mvm->async_handlers_lock);
|
||||
INIT_LIST_HEAD(&mvm->time_event_list);
|
||||
INIT_LIST_HEAD(&mvm->aux_roc_te_list);
|
||||
@ -710,18 +703,11 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
|
||||
INIT_WORK(&mvm->async_handlers_wk, iwl_mvm_async_handlers_wk);
|
||||
INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk);
|
||||
#ifdef CONFIG_PM
|
||||
INIT_WORK(&mvm->d0i3_exit_work, iwl_mvm_d0i3_exit_work);
|
||||
#endif
|
||||
INIT_DELAYED_WORK(&mvm->tdls_cs.dwork, iwl_mvm_tdls_ch_switch_work);
|
||||
INIT_DELAYED_WORK(&mvm->scan_timeout_dwork, iwl_mvm_scan_timeout_wk);
|
||||
INIT_WORK(&mvm->add_stream_wk, iwl_mvm_add_new_dqa_stream_wk);
|
||||
INIT_LIST_HEAD(&mvm->add_stream_txqs);
|
||||
|
||||
spin_lock_init(&mvm->d0i3_tx_lock);
|
||||
spin_lock_init(&mvm->refs_lock);
|
||||
skb_queue_head_init(&mvm->d0i3_tx);
|
||||
init_waitqueue_head(&mvm->d0i3_exit_waitq);
|
||||
init_waitqueue_head(&mvm->rx_sync_waitq);
|
||||
|
||||
atomic_set(&mvm->queue_sync_counter, 0);
|
||||
@ -744,7 +730,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
trans_cfg.no_reclaim_cmds = no_reclaim_cmds;
|
||||
trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
|
||||
|
||||
if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
|
||||
if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560)
|
||||
rb_size_default = IWL_AMSDU_2K;
|
||||
else
|
||||
rb_size_default = IWL_AMSDU_4K;
|
||||
@ -768,12 +754,9 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
trans_cfg.rx_buf_size = rb_size_default;
|
||||
}
|
||||
|
||||
BUILD_BUG_ON(sizeof(struct iwl_ldbg_config_cmd) !=
|
||||
LDBG_CFG_COMMAND_SIZE);
|
||||
|
||||
trans->wide_cmd_header = true;
|
||||
trans_cfg.bc_table_dword =
|
||||
mvm->trans->cfg->device_family < IWL_DEVICE_FAMILY_22560;
|
||||
mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_22560;
|
||||
|
||||
trans_cfg.command_groups = iwl_mvm_groups;
|
||||
trans_cfg.command_groups_size = ARRAY_SIZE(iwl_mvm_groups);
|
||||
@ -832,13 +815,11 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
goto out_free;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_INIT_UCODE);
|
||||
err = iwl_run_init_mvm_ucode(mvm, true);
|
||||
if (err && err != -ERFKILL)
|
||||
iwl_fw_dbg_error_collect(&mvm->fwrt, FW_DBG_TRIGGER_DRIVER);
|
||||
if (!iwlmvm_mod_params.init_dbg || !err)
|
||||
iwl_mvm_stop_device(mvm);
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_INIT_UCODE);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
if (err < 0) {
|
||||
IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err);
|
||||
@ -870,11 +851,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
else
|
||||
memset(&mvm->rx_stats, 0, sizeof(struct mvm_statistics_rx));
|
||||
|
||||
/* The transport always starts with a taken reference, we can
|
||||
* release it now if d0i3 is supported */
|
||||
if (iwl_mvm_is_d0i3_supported(mvm))
|
||||
iwl_trans_unref(mvm->trans);
|
||||
|
||||
iwl_mvm_toggle_tx_ant(mvm, &mvm->mgmt_last_antenna_idx);
|
||||
|
||||
return op_mode;
|
||||
@ -898,13 +874,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
|
||||
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
|
||||
int i;
|
||||
|
||||
/* If d0i3 is supported, we have released the reference that
|
||||
* the transport started with, so we should take it back now
|
||||
* that we are leaving.
|
||||
*/
|
||||
if (iwl_mvm_is_d0i3_supported(mvm))
|
||||
iwl_trans_ref(mvm->trans);
|
||||
|
||||
iwl_mvm_leds_exit(mvm);
|
||||
|
||||
iwl_mvm_thermal_exit(mvm);
|
||||
@ -931,7 +900,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
|
||||
|
||||
iwl_fw_runtime_free(&mvm->fwrt);
|
||||
mutex_destroy(&mvm->mutex);
|
||||
mutex_destroy(&mvm->d0i3_suspend_mutex);
|
||||
|
||||
ieee80211_free_hw(mvm->hw);
|
||||
}
|
||||
@ -1020,7 +988,10 @@ static void iwl_mvm_rx_common(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_packet *pkt)
|
||||
{
|
||||
int i;
|
||||
union iwl_dbg_tlv_tp_data tp_data = { .fw_pkt = pkt };
|
||||
|
||||
iwl_dbg_tlv_time_point(&mvm->fwrt,
|
||||
IWL_FW_INI_TIME_POINT_FW_RSP_OR_NOTIF, &tp_data);
|
||||
iwl_mvm_rx_check_trigger(mvm, pkt);
|
||||
|
||||
/*
|
||||
@ -1091,6 +1062,8 @@ static void iwl_mvm_rx_mq(struct iwl_op_mode *op_mode,
|
||||
iwl_mvm_rx_queue_notif(mvm, napi, rxb, 0);
|
||||
else if (cmd == WIDE_ID(LEGACY_GROUP, FRAME_RELEASE))
|
||||
iwl_mvm_rx_frame_release(mvm, napi, rxb, 0);
|
||||
else if (cmd == WIDE_ID(LEGACY_GROUP, BAR_FRAME_RELEASE))
|
||||
iwl_mvm_rx_bar_frame_release(mvm, napi, rxb, 0);
|
||||
else if (cmd == WIDE_ID(DATA_PATH_GROUP, RX_NO_DATA_NOTIF))
|
||||
iwl_mvm_rx_monitor_no_data(mvm, napi, rxb, 0);
|
||||
else
|
||||
@ -1234,8 +1207,7 @@ static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
|
||||
* Stop the device if we run OPERATIONAL firmware or if we are in the
|
||||
* middle of the calibrations.
|
||||
*/
|
||||
return state && (mvm->fwrt.cur_fw_img != IWL_UCODE_INIT ||
|
||||
rfkill_safe_init_done);
|
||||
return state && rfkill_safe_init_done;
|
||||
}
|
||||
|
||||
static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
|
||||
@ -1267,7 +1239,7 @@ static void iwl_mvm_reprobe_wk(struct work_struct *wk)
|
||||
void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
|
||||
{
|
||||
iwl_abort_notification_waits(&mvm->notif_wait);
|
||||
del_timer(&mvm->fwrt.dump.periodic_trig);
|
||||
iwl_dbg_tlv_del_timers(mvm->trans);
|
||||
|
||||
/*
|
||||
* This is a bit racy, but worst case we tell mac80211 about
|
||||
@ -1319,9 +1291,6 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
|
||||
} else if (mvm->fwrt.cur_fw_img == IWL_UCODE_REGULAR &&
|
||||
mvm->hw_registered &&
|
||||
!test_bit(STATUS_TRANS_DEAD, &mvm->trans->status)) {
|
||||
/* don't let the transport/FW power down */
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
|
||||
|
||||
if (mvm->fw->ucode_capa.error_log_size) {
|
||||
u32 src_size = mvm->fw->ucode_capa.error_log_size;
|
||||
u32 src_addr = mvm->fw->ucode_capa.error_log_addr;
|
||||
@ -1363,422 +1332,6 @@ static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode)
|
||||
iwl_mvm_nic_restart(mvm, true);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
struct iwl_d0i3_iter_data {
|
||||
struct iwl_mvm *mvm;
|
||||
struct ieee80211_vif *connected_vif;
|
||||
u8 ap_sta_id;
|
||||
u8 vif_count;
|
||||
u8 offloading_tid;
|
||||
bool disable_offloading;
|
||||
};
|
||||
|
||||
static bool iwl_mvm_disallow_offloading(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
struct iwl_d0i3_iter_data *iter_data)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_mvm_sta *mvmsta;
|
||||
u32 available_tids = 0;
|
||||
u8 tid;
|
||||
|
||||
if (WARN_ON(vif->type != NL80211_IFTYPE_STATION ||
|
||||
mvmvif->ap_sta_id == IWL_MVM_INVALID_STA))
|
||||
return false;
|
||||
|
||||
mvmsta = iwl_mvm_sta_from_staid_rcu(mvm, mvmvif->ap_sta_id);
|
||||
if (!mvmsta)
|
||||
return false;
|
||||
|
||||
spin_lock_bh(&mvmsta->lock);
|
||||
for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
|
||||
struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
|
||||
|
||||
/*
|
||||
* in case of pending tx packets, don't use this tid
|
||||
* for offloading in order to prevent reuse of the same
|
||||
* qos seq counters.
|
||||
*/
|
||||
if (iwl_mvm_tid_queued(mvm, tid_data))
|
||||
continue;
|
||||
|
||||
if (tid_data->state != IWL_AGG_OFF)
|
||||
continue;
|
||||
|
||||
available_tids |= BIT(tid);
|
||||
}
|
||||
spin_unlock_bh(&mvmsta->lock);
|
||||
|
||||
/*
|
||||
* disallow protocol offloading if we have no available tid
|
||||
* (with no pending frames and no active aggregation,
|
||||
* as we don't handle "holes" properly - the scheduler needs the
|
||||
* frame's seq number and TFD index to match)
|
||||
*/
|
||||
if (!available_tids)
|
||||
return true;
|
||||
|
||||
/* for simplicity, just use the first available tid */
|
||||
iter_data->offloading_tid = ffs(available_tids) - 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void iwl_mvm_enter_d0i3_iterator(void *_data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_d0i3_iter_data *data = _data;
|
||||
struct iwl_mvm *mvm = data->mvm;
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE;
|
||||
|
||||
IWL_DEBUG_RPM(mvm, "entering D0i3 - vif %pM\n", vif->addr);
|
||||
if (vif->type != NL80211_IFTYPE_STATION ||
|
||||
!vif->bss_conf.assoc)
|
||||
return;
|
||||
|
||||
/*
|
||||
* in case of pending tx packets or active aggregations,
|
||||
* avoid offloading features in order to prevent reuse of
|
||||
* the same qos seq counters.
|
||||
*/
|
||||
if (iwl_mvm_disallow_offloading(mvm, vif, data))
|
||||
data->disable_offloading = true;
|
||||
|
||||
iwl_mvm_update_d0i3_power_mode(mvm, vif, true, flags);
|
||||
iwl_mvm_send_proto_offload(mvm, vif, data->disable_offloading,
|
||||
false, flags);
|
||||
|
||||
/*
|
||||
* on init/association, mvm already configures POWER_TABLE_CMD
|
||||
* and REPLY_MCAST_FILTER_CMD, so currently don't
|
||||
* reconfigure them (we might want to use different
|
||||
* params later on, though).
|
||||
*/
|
||||
data->ap_sta_id = mvmvif->ap_sta_id;
|
||||
data->vif_count++;
|
||||
|
||||
/*
|
||||
* no new commands can be sent at this stage, so it's safe
|
||||
* to save the vif pointer during d0i3 entrance.
|
||||
*/
|
||||
data->connected_vif = vif;
|
||||
}
|
||||
|
||||
static void iwl_mvm_set_wowlan_data(struct iwl_mvm *mvm,
|
||||
struct iwl_wowlan_config_cmd *cmd,
|
||||
struct iwl_d0i3_iter_data *iter_data)
|
||||
{
|
||||
struct ieee80211_sta *ap_sta;
|
||||
struct iwl_mvm_sta *mvm_ap_sta;
|
||||
|
||||
if (iter_data->ap_sta_id == IWL_MVM_INVALID_STA)
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
ap_sta = rcu_dereference(mvm->fw_id_to_mac_id[iter_data->ap_sta_id]);
|
||||
if (IS_ERR_OR_NULL(ap_sta))
|
||||
goto out;
|
||||
|
||||
mvm_ap_sta = iwl_mvm_sta_from_mac80211(ap_sta);
|
||||
cmd->is_11n_connection = ap_sta->ht_cap.ht_supported;
|
||||
cmd->offloading_tid = iter_data->offloading_tid;
|
||||
cmd->flags = ENABLE_L3_FILTERING | ENABLE_NBNS_FILTERING |
|
||||
ENABLE_DHCP_FILTERING | ENABLE_STORE_BEACON;
|
||||
/*
|
||||
* The d0i3 uCode takes care of the nonqos counters,
|
||||
* so configure only the qos seq ones.
|
||||
*/
|
||||
iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, cmd);
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
|
||||
u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE;
|
||||
int ret;
|
||||
struct iwl_d0i3_iter_data d0i3_iter_data = {
|
||||
.mvm = mvm,
|
||||
};
|
||||
struct iwl_wowlan_config_cmd wowlan_config_cmd = {
|
||||
.wakeup_filter = cpu_to_le32(IWL_WOWLAN_WAKEUP_RX_FRAME |
|
||||
IWL_WOWLAN_WAKEUP_BEACON_MISS |
|
||||
IWL_WOWLAN_WAKEUP_LINK_CHANGE),
|
||||
};
|
||||
struct iwl_d3_manager_config d3_cfg_cmd = {
|
||||
.min_sleep_time = cpu_to_le32(1000),
|
||||
.wakeup_flags = cpu_to_le32(IWL_WAKEUP_D3_CONFIG_FW_ERROR),
|
||||
};
|
||||
|
||||
IWL_DEBUG_RPM(mvm, "MVM entering D0i3\n");
|
||||
|
||||
if (WARN_ON_ONCE(mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR))
|
||||
return -EINVAL;
|
||||
|
||||
set_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
|
||||
|
||||
/*
|
||||
* iwl_mvm_ref_sync takes a reference before checking the flag.
|
||||
* so by checking there is no held reference we prevent a state
|
||||
* in which iwl_mvm_ref_sync continues successfully while we
|
||||
* configure the firmware to enter d0i3
|
||||
*/
|
||||
if (iwl_mvm_ref_taken(mvm)) {
|
||||
IWL_DEBUG_RPM(mvm->trans, "abort d0i3 due to taken ref\n");
|
||||
clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
|
||||
wake_up(&mvm->d0i3_exit_waitq);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ieee80211_iterate_active_interfaces_atomic(mvm->hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mvm_enter_d0i3_iterator,
|
||||
&d0i3_iter_data);
|
||||
if (d0i3_iter_data.vif_count == 1) {
|
||||
mvm->d0i3_ap_sta_id = d0i3_iter_data.ap_sta_id;
|
||||
mvm->d0i3_offloading = !d0i3_iter_data.disable_offloading;
|
||||
} else {
|
||||
WARN_ON_ONCE(d0i3_iter_data.vif_count > 1);
|
||||
mvm->d0i3_ap_sta_id = IWL_MVM_INVALID_STA;
|
||||
mvm->d0i3_offloading = false;
|
||||
}
|
||||
|
||||
iwl_mvm_pause_tcm(mvm, true);
|
||||
/* make sure we have no running tx while configuring the seqno */
|
||||
synchronize_net();
|
||||
|
||||
/* Flush the hw queues, in case something got queued during entry */
|
||||
/* TODO new tx api */
|
||||
if (iwl_mvm_has_new_tx_api(mvm)) {
|
||||
WARN_ONCE(1, "d0i3: Need to implement flush TX queue\n");
|
||||
} else {
|
||||
ret = iwl_mvm_flush_tx_path(mvm, iwl_mvm_flushable_queues(mvm),
|
||||
flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* configure wowlan configuration only if needed */
|
||||
if (mvm->d0i3_ap_sta_id != IWL_MVM_INVALID_STA) {
|
||||
/* wake on beacons only if beacon storing isn't supported */
|
||||
if (!fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_BEACON_STORING))
|
||||
wowlan_config_cmd.wakeup_filter |=
|
||||
cpu_to_le32(IWL_WOWLAN_WAKEUP_BCN_FILTERING);
|
||||
|
||||
iwl_mvm_wowlan_config_key_params(mvm,
|
||||
d0i3_iter_data.connected_vif,
|
||||
true, flags);
|
||||
|
||||
iwl_mvm_set_wowlan_data(mvm, &wowlan_config_cmd,
|
||||
&d0i3_iter_data);
|
||||
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, flags,
|
||||
sizeof(wowlan_config_cmd),
|
||||
&wowlan_config_cmd);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD,
|
||||
flags | CMD_MAKE_TRANS_IDLE,
|
||||
sizeof(d3_cfg_cmd), &d3_cfg_cmd);
|
||||
}
|
||||
|
||||
static void iwl_mvm_exit_d0i3_iterator(void *_data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm *mvm = _data;
|
||||
u32 flags = CMD_ASYNC | CMD_HIGH_PRIO;
|
||||
|
||||
IWL_DEBUG_RPM(mvm, "exiting D0i3 - vif %pM\n", vif->addr);
|
||||
if (vif->type != NL80211_IFTYPE_STATION ||
|
||||
!vif->bss_conf.assoc)
|
||||
return;
|
||||
|
||||
iwl_mvm_update_d0i3_power_mode(mvm, vif, false, flags);
|
||||
}
|
||||
|
||||
struct iwl_mvm_d0i3_exit_work_iter_data {
|
||||
struct iwl_mvm *mvm;
|
||||
struct iwl_wowlan_status *status;
|
||||
u32 wakeup_reasons;
|
||||
};
|
||||
|
||||
static void iwl_mvm_d0i3_exit_work_iter(void *_data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_d0i3_exit_work_iter_data *data = _data;
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
u32 reasons = data->wakeup_reasons;
|
||||
|
||||
/* consider only the relevant station interface */
|
||||
if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc ||
|
||||
data->mvm->d0i3_ap_sta_id != mvmvif->ap_sta_id)
|
||||
return;
|
||||
|
||||
if (reasons & IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH)
|
||||
iwl_mvm_connection_loss(data->mvm, vif, "D0i3");
|
||||
else if (reasons & IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON)
|
||||
ieee80211_beacon_loss(vif);
|
||||
else
|
||||
iwl_mvm_d0i3_update_keys(data->mvm, vif, data->status);
|
||||
}
|
||||
|
||||
void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq)
|
||||
{
|
||||
struct ieee80211_sta *sta = NULL;
|
||||
struct iwl_mvm_sta *mvm_ap_sta;
|
||||
int i;
|
||||
bool wake_queues = false;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
spin_lock_bh(&mvm->d0i3_tx_lock);
|
||||
|
||||
if (mvm->d0i3_ap_sta_id == IWL_MVM_INVALID_STA)
|
||||
goto out;
|
||||
|
||||
IWL_DEBUG_RPM(mvm, "re-enqueue packets\n");
|
||||
|
||||
/* get the sta in order to update seq numbers and re-enqueue skbs */
|
||||
sta = rcu_dereference_protected(
|
||||
mvm->fw_id_to_mac_id[mvm->d0i3_ap_sta_id],
|
||||
lockdep_is_held(&mvm->mutex));
|
||||
|
||||
if (IS_ERR_OR_NULL(sta)) {
|
||||
sta = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mvm->d0i3_offloading && qos_seq) {
|
||||
/* update qos seq numbers if offloading was enabled */
|
||||
mvm_ap_sta = iwl_mvm_sta_from_mac80211(sta);
|
||||
for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
|
||||
u16 seq = le16_to_cpu(qos_seq[i]);
|
||||
/* firmware stores last-used one, we store next one */
|
||||
seq += 0x10;
|
||||
mvm_ap_sta->tid_data[i].seq_number = seq;
|
||||
}
|
||||
}
|
||||
out:
|
||||
/* re-enqueue (or drop) all packets */
|
||||
while (!skb_queue_empty(&mvm->d0i3_tx)) {
|
||||
struct sk_buff *skb = __skb_dequeue(&mvm->d0i3_tx);
|
||||
|
||||
if (!sta || iwl_mvm_tx_skb(mvm, skb, sta))
|
||||
ieee80211_free_txskb(mvm->hw, skb);
|
||||
|
||||
/* if the skb_queue is not empty, we need to wake queues */
|
||||
wake_queues = true;
|
||||
}
|
||||
clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
|
||||
wake_up(&mvm->d0i3_exit_waitq);
|
||||
mvm->d0i3_ap_sta_id = IWL_MVM_INVALID_STA;
|
||||
if (wake_queues)
|
||||
ieee80211_wake_queues(mvm->hw);
|
||||
|
||||
spin_unlock_bh(&mvm->d0i3_tx_lock);
|
||||
}
|
||||
|
||||
static void iwl_mvm_d0i3_exit_work(struct work_struct *wk)
|
||||
{
|
||||
struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, d0i3_exit_work);
|
||||
struct iwl_mvm_d0i3_exit_work_iter_data iter_data = {
|
||||
.mvm = mvm,
|
||||
};
|
||||
|
||||
struct iwl_wowlan_status *status;
|
||||
u32 wakeup_reasons = 0;
|
||||
__le16 *qos_seq = NULL;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
status = iwl_mvm_send_wowlan_get_status(mvm);
|
||||
if (IS_ERR_OR_NULL(status)) {
|
||||
/* set to NULL so we don't need to check before kfree'ing */
|
||||
status = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
wakeup_reasons = le32_to_cpu(status->wakeup_reasons);
|
||||
qos_seq = status->qos_seq_ctr;
|
||||
|
||||
IWL_DEBUG_RPM(mvm, "wakeup reasons: 0x%x\n", wakeup_reasons);
|
||||
|
||||
iter_data.wakeup_reasons = wakeup_reasons;
|
||||
iter_data.status = status;
|
||||
ieee80211_iterate_active_interfaces(mvm->hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mvm_d0i3_exit_work_iter,
|
||||
&iter_data);
|
||||
out:
|
||||
iwl_mvm_d0i3_enable_tx(mvm, qos_seq);
|
||||
|
||||
IWL_DEBUG_INFO(mvm, "d0i3 exit completed (wakeup reasons: 0x%x)\n",
|
||||
wakeup_reasons);
|
||||
|
||||
/* qos_seq might point inside resp_pkt, so free it only now */
|
||||
kfree(status);
|
||||
|
||||
/* the FW might have updated the regdomain */
|
||||
iwl_mvm_update_changed_regdom(mvm);
|
||||
|
||||
iwl_mvm_resume_tcm(mvm);
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_EXIT_WORK);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
}
|
||||
|
||||
int _iwl_mvm_exit_d0i3(struct iwl_mvm *mvm)
|
||||
{
|
||||
u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE |
|
||||
CMD_WAKE_UP_TRANS;
|
||||
int ret;
|
||||
|
||||
IWL_DEBUG_RPM(mvm, "MVM exiting D0i3\n");
|
||||
|
||||
if (WARN_ON_ONCE(mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&mvm->d0i3_suspend_mutex);
|
||||
if (test_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags)) {
|
||||
IWL_DEBUG_RPM(mvm, "Deferring d0i3 exit until resume\n");
|
||||
__set_bit(D0I3_PENDING_WAKEUP, &mvm->d0i3_suspend_flags);
|
||||
mutex_unlock(&mvm->d0i3_suspend_mutex);
|
||||
return 0;
|
||||
}
|
||||
mutex_unlock(&mvm->d0i3_suspend_mutex);
|
||||
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, flags, 0, NULL);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ieee80211_iterate_active_interfaces_atomic(mvm->hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mvm_exit_d0i3_iterator,
|
||||
mvm);
|
||||
out:
|
||||
schedule_work(&mvm->d0i3_exit_work);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
|
||||
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_EXIT_WORK);
|
||||
return _iwl_mvm_exit_d0i3(mvm);
|
||||
}
|
||||
|
||||
#define IWL_MVM_D0I3_OPS \
|
||||
.enter_d0i3 = iwl_mvm_enter_d0i3, \
|
||||
.exit_d0i3 = iwl_mvm_exit_d0i3,
|
||||
#else /* CONFIG_PM */
|
||||
#define IWL_MVM_D0I3_OPS
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
#define IWL_MVM_COMMON_OPS \
|
||||
/* these could be differentiated */ \
|
||||
.async_cb = iwl_mvm_async_cb, \
|
||||
@ -1789,7 +1342,6 @@ int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode)
|
||||
.nic_error = iwl_mvm_nic_error, \
|
||||
.cmd_queue_full = iwl_mvm_cmd_queue_full, \
|
||||
.nic_config = iwl_mvm_nic_config, \
|
||||
IWL_MVM_D0I3_OPS \
|
||||
/* as we only register one, these MUST be common! */ \
|
||||
.start = iwl_op_mode_mvm_start, \
|
||||
.stop = iwl_op_mode_mvm_stop
|
||||
|
@ -289,8 +289,17 @@ void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
|
||||
if (ctxt->ref == 0) {
|
||||
struct ieee80211_channel *chan;
|
||||
struct cfg80211_chan_def chandef;
|
||||
struct ieee80211_supported_band *sband = NULL;
|
||||
enum nl80211_band band = NL80211_BAND_2GHZ;
|
||||
|
||||
while (!sband && band < NUM_NL80211_BANDS)
|
||||
sband = mvm->hw->wiphy->bands[band++];
|
||||
|
||||
if (WARN_ON(!sband))
|
||||
return;
|
||||
|
||||
chan = &sband->channels[0];
|
||||
|
||||
chan = &mvm->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[0];
|
||||
cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
|
||||
iwl_mvm_phy_ctxt_changed(mvm, ctxt, &chandef, 1, 1);
|
||||
}
|
||||
|
@ -127,12 +127,11 @@ int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm,
|
||||
static
|
||||
void iwl_mvm_beacon_filter_set_cqm_params(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
struct iwl_beacon_filter_cmd *cmd,
|
||||
bool d0i3)
|
||||
struct iwl_beacon_filter_cmd *cmd)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
|
||||
if (vif->bss_conf.cqm_rssi_thold && !d0i3) {
|
||||
if (vif->bss_conf.cqm_rssi_thold) {
|
||||
cmd->bf_energy_delta =
|
||||
cpu_to_le32(vif->bss_conf.cqm_rssi_hyst);
|
||||
/* fw uses an absolute value for this */
|
||||
@ -849,8 +848,7 @@ iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
|
||||
static int _iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
struct iwl_beacon_filter_cmd *cmd,
|
||||
u32 cmd_flags,
|
||||
bool d0i3)
|
||||
u32 cmd_flags)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
int ret;
|
||||
@ -859,13 +857,11 @@ static int _iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
|
||||
vif->type != NL80211_IFTYPE_STATION || vif->p2p)
|
||||
return 0;
|
||||
|
||||
iwl_mvm_beacon_filter_set_cqm_params(mvm, vif, cmd, d0i3);
|
||||
if (!d0i3)
|
||||
iwl_mvm_beacon_filter_set_cqm_params(mvm, vif, cmd);
|
||||
iwl_mvm_beacon_filter_debugfs_parameters(vif, cmd);
|
||||
ret = iwl_mvm_beacon_filter_send_cmd(mvm, cmd, cmd_flags);
|
||||
|
||||
/* don't change bf_enabled in case of temporary d0i3 configuration */
|
||||
if (!ret && !d0i3)
|
||||
if (!ret)
|
||||
mvmvif->bf_data.bf_enabled = true;
|
||||
|
||||
return ret;
|
||||
@ -880,12 +876,12 @@ int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
|
||||
.bf_enable_beacon_filter = cpu_to_le32(1),
|
||||
};
|
||||
|
||||
return _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd, flags, false);
|
||||
return _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd, flags);
|
||||
}
|
||||
|
||||
static int _iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
u32 flags, bool d0i3)
|
||||
u32 flags)
|
||||
{
|
||||
struct iwl_beacon_filter_cmd cmd = {};
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
@ -896,8 +892,7 @@ static int _iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
|
||||
|
||||
ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd, flags);
|
||||
|
||||
/* don't change bf_enabled in case of temporary d0i3 configuration */
|
||||
if (!ret && !d0i3)
|
||||
if (!ret)
|
||||
mvmvif->bf_data.bf_enabled = false;
|
||||
|
||||
return ret;
|
||||
@ -907,7 +902,7 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
u32 flags)
|
||||
{
|
||||
return _iwl_mvm_disable_beacon_filter(mvm, vif, flags, false);
|
||||
return _iwl_mvm_disable_beacon_filter(mvm, vif, flags);
|
||||
}
|
||||
|
||||
static int iwl_mvm_power_set_ps(struct iwl_mvm *mvm)
|
||||
@ -958,7 +953,7 @@ static int iwl_mvm_power_set_ba(struct iwl_mvm *mvm,
|
||||
!vif->bss_conf.ps ||
|
||||
iwl_mvm_vif_low_latency(mvmvif));
|
||||
|
||||
return _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd, 0, false);
|
||||
return _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd, 0);
|
||||
}
|
||||
|
||||
int iwl_mvm_power_update_ps(struct iwl_mvm *mvm)
|
||||
@ -1022,58 +1017,3 @@ int iwl_mvm_power_update_mac(struct iwl_mvm *mvm)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
bool enable, u32 flags)
|
||||
{
|
||||
int ret;
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_mac_power_cmd cmd = {};
|
||||
|
||||
if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
|
||||
return 0;
|
||||
|
||||
if (!vif->bss_conf.assoc)
|
||||
return 0;
|
||||
|
||||
iwl_mvm_power_build_cmd(mvm, vif, &cmd, !enable);
|
||||
|
||||
iwl_mvm_power_log(mvm, &cmd);
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
memcpy(&mvmvif->mac_pwr_cmd, &cmd, sizeof(cmd));
|
||||
#endif
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, flags,
|
||||
sizeof(cmd), &cmd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* configure beacon filtering */
|
||||
if (mvmvif != mvm->bf_allowed_vif)
|
||||
return 0;
|
||||
|
||||
if (enable) {
|
||||
struct iwl_beacon_filter_cmd cmd_bf = {
|
||||
IWL_BF_CMD_CONFIG_D0I3,
|
||||
.bf_enable_beacon_filter = cpu_to_le32(1),
|
||||
};
|
||||
/*
|
||||
* When beacon storing is supported - disable beacon filtering
|
||||
* altogether - the latest beacon will be sent when exiting d0i3
|
||||
*/
|
||||
if (fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_BEACON_STORING))
|
||||
ret = _iwl_mvm_disable_beacon_filter(mvm, vif, flags,
|
||||
true);
|
||||
else
|
||||
ret = _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd_bf,
|
||||
flags, true);
|
||||
} else {
|
||||
if (mvmvif->bf_data.bf_enabled)
|
||||
ret = iwl_mvm_enable_beacon_filter(mvm, vif, flags);
|
||||
else
|
||||
ret = iwl_mvm_disable_beacon_filter(mvm, vif, flags);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ rs_fw_vht_set_enabled_rates(const struct ieee80211_sta *sta,
|
||||
int i, highest_mcs;
|
||||
|
||||
for (i = 0; i < sta->rx_nss; i++) {
|
||||
if (i == MAX_NSS)
|
||||
if (i == IWL_TLC_NSS_MAX)
|
||||
break;
|
||||
|
||||
highest_mcs = rs_fw_vht_highest_rx_mcs_index(vht_cap, i + 1);
|
||||
@ -204,9 +204,10 @@ rs_fw_vht_set_enabled_rates(const struct ieee80211_sta *sta,
|
||||
if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
|
||||
supp &= ~BIT(IWL_TLC_MNG_HT_RATE_MCS9);
|
||||
|
||||
cmd->ht_rates[i][0] = cpu_to_le16(supp);
|
||||
cmd->ht_rates[i][IWL_TLC_HT_BW_NONE_160] = cpu_to_le16(supp);
|
||||
if (sta->bandwidth == IEEE80211_STA_RX_BW_160)
|
||||
cmd->ht_rates[i][1] = cmd->ht_rates[i][0];
|
||||
cmd->ht_rates[i][IWL_TLC_HT_BW_160] =
|
||||
cmd->ht_rates[i][IWL_TLC_HT_BW_NONE_160];
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,7 +242,7 @@ rs_fw_he_set_enabled_rates(const struct ieee80211_sta *sta,
|
||||
le16_to_cpu(sband->iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sta->rx_nss && i < MAX_NSS; i++) {
|
||||
for (i = 0; i < sta->rx_nss && i < IWL_TLC_NSS_MAX; i++) {
|
||||
u16 _mcs_160 = (mcs_160 >> (2 * i)) & 0x3;
|
||||
u16 _mcs_80 = (mcs_80 >> (2 * i)) & 0x3;
|
||||
u16 _tx_mcs_160 = (tx_mcs_160 >> (2 * i)) & 0x3;
|
||||
@ -255,7 +256,7 @@ rs_fw_he_set_enabled_rates(const struct ieee80211_sta *sta,
|
||||
}
|
||||
if (_mcs_80 > _tx_mcs_80)
|
||||
_mcs_80 = _tx_mcs_80;
|
||||
cmd->ht_rates[i][0] =
|
||||
cmd->ht_rates[i][IWL_TLC_HT_BW_NONE_160] =
|
||||
cpu_to_le16(rs_fw_he_ieee80211_mcs_to_rs_mcs(_mcs_80));
|
||||
|
||||
/* If one side doesn't support - mark both as not supporting */
|
||||
@ -266,7 +267,7 @@ rs_fw_he_set_enabled_rates(const struct ieee80211_sta *sta,
|
||||
}
|
||||
if (_mcs_160 > _tx_mcs_160)
|
||||
_mcs_160 = _tx_mcs_160;
|
||||
cmd->ht_rates[i][1] =
|
||||
cmd->ht_rates[i][IWL_TLC_HT_BW_160] =
|
||||
cpu_to_le16(rs_fw_he_ieee80211_mcs_to_rs_mcs(_mcs_160));
|
||||
}
|
||||
}
|
||||
@ -300,8 +301,10 @@ static void rs_fw_set_supp_rates(struct ieee80211_sta *sta,
|
||||
rs_fw_vht_set_enabled_rates(sta, vht_cap, cmd);
|
||||
} else if (ht_cap->ht_supported) {
|
||||
cmd->mode = IWL_TLC_MNG_MODE_HT;
|
||||
cmd->ht_rates[0][0] = cpu_to_le16(ht_cap->mcs.rx_mask[0]);
|
||||
cmd->ht_rates[1][0] = cpu_to_le16(ht_cap->mcs.rx_mask[1]);
|
||||
cmd->ht_rates[IWL_TLC_NSS_1][IWL_TLC_HT_BW_NONE_160] =
|
||||
cpu_to_le16(ht_cap->mcs.rx_mask[0]);
|
||||
cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_HT_BW_NONE_160] =
|
||||
cpu_to_le16(ht_cap->mcs.rx_mask[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3079,11 +3079,7 @@ static void __iwl_mvm_rs_tx_status(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv;
|
||||
|
||||
/* Treat uninitialized rate scaling data same as non-existing. */
|
||||
if (!lq_sta) {
|
||||
IWL_DEBUG_RATE(mvm, "Station rate scaling not created yet.\n");
|
||||
return;
|
||||
} else if (!lq_sta->pers.drv) {
|
||||
if (!lq_sta->pers.drv) {
|
||||
IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n");
|
||||
return;
|
||||
}
|
||||
@ -3342,7 +3338,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->cfg->gen2)
|
||||
if (!mvm->trans->trans_cfg->gen2)
|
||||
lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
|
||||
else
|
||||
lq_cmd->agg_frame_cnt_limit =
|
||||
|
@ -8,6 +8,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -29,6 +30,8 @@
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -349,7 +352,6 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
u32 rate_n_flags;
|
||||
u32 rx_pkt_status;
|
||||
u8 crypt_len = 0;
|
||||
bool take_ref;
|
||||
|
||||
phy_info = &mvm->last_phy_info;
|
||||
rx_res = (struct iwl_rx_mpdu_res_start *)pkt->data;
|
||||
@ -557,22 +559,8 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
ieee80211_is_probe_resp(hdr->frame_control)))
|
||||
rx_status->boottime_ns = ktime_get_boottime_ns();
|
||||
|
||||
/* Take a reference briefly to kick off a d0i3 entry delay so
|
||||
* we can handle bursts of RX packets without toggling the
|
||||
* state too often. But don't do this for beacons if we are
|
||||
* going to idle because the beacon filtering changes we make
|
||||
* cause the firmware to send us collateral beacons. */
|
||||
take_ref = !(test_bit(STATUS_TRANS_GOING_IDLE, &mvm->trans->status) &&
|
||||
ieee80211_is_beacon(hdr->frame_control));
|
||||
|
||||
if (take_ref)
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_RX);
|
||||
|
||||
iwl_mvm_pass_packet_to_mac80211(mvm, sta, napi, skb, hdr, len,
|
||||
crypt_len, rxb);
|
||||
|
||||
if (take_ref)
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_RX);
|
||||
}
|
||||
|
||||
struct iwl_mvm_stat_data {
|
||||
|
@ -349,7 +349,7 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
|
||||
!(status & IWL_RX_MPDU_RES_STATUS_TTAK_OK))
|
||||
return 0;
|
||||
|
||||
if (mvm->trans->cfg->gen2 &&
|
||||
if (mvm->trans->trans_cfg->gen2 &&
|
||||
!(status & RX_MPDU_RES_STATUS_MIC_OK))
|
||||
stats->flag |= RX_FLAG_MMIC_ERROR;
|
||||
|
||||
@ -366,7 +366,7 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
|
||||
|
||||
if (pkt_flags & FH_RSCSR_RADA_EN) {
|
||||
stats->flag |= RX_FLAG_ICV_STRIPPED;
|
||||
if (mvm->trans->cfg->gen2)
|
||||
if (mvm->trans->trans_cfg->gen2)
|
||||
stats->flag |= RX_FLAG_MMIC_STRIPPED;
|
||||
}
|
||||
|
||||
@ -377,8 +377,16 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
|
||||
stats->flag |= RX_FLAG_DECRYPTED;
|
||||
return 0;
|
||||
default:
|
||||
/* Expected in monitor (not having the keys) */
|
||||
if (!mvm->monitor_on)
|
||||
/*
|
||||
* Sometimes we can get frames that were not decrypted
|
||||
* because the firmware didn't have the keys yet. This can
|
||||
* happen after connection where we can get multicast frames
|
||||
* before the GTK is installed.
|
||||
* Silently drop those frames.
|
||||
* Also drop un-decrypted frames in monitor mode.
|
||||
*/
|
||||
if (!is_multicast_ether_addr(hdr->addr1) &&
|
||||
!mvm->monitor_on && net_ratelimit())
|
||||
IWL_ERR(mvm, "Unhandled alg: 0x%x\n", status);
|
||||
}
|
||||
|
||||
@ -781,6 +789,55 @@ void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
wake_up(&mvm->rx_sync_waitq);
|
||||
}
|
||||
|
||||
static void iwl_mvm_oldsn_workaround(struct iwl_mvm *mvm,
|
||||
struct ieee80211_sta *sta, int tid,
|
||||
struct iwl_mvm_reorder_buffer *buffer,
|
||||
u32 reorder, u32 gp2, int queue)
|
||||
{
|
||||
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
|
||||
if (gp2 != buffer->consec_oldsn_ampdu_gp2) {
|
||||
/* we have a new (A-)MPDU ... */
|
||||
|
||||
/*
|
||||
* reset counter to 0 if we didn't have any oldsn in
|
||||
* the last A-MPDU (as detected by GP2 being identical)
|
||||
*/
|
||||
if (!buffer->consec_oldsn_prev_drop)
|
||||
buffer->consec_oldsn_drops = 0;
|
||||
|
||||
/* either way, update our tracking state */
|
||||
buffer->consec_oldsn_ampdu_gp2 = gp2;
|
||||
} else if (buffer->consec_oldsn_prev_drop) {
|
||||
/*
|
||||
* tracking state didn't change, and we had an old SN
|
||||
* indication before - do nothing in this case, we
|
||||
* already noted this one down and are waiting for the
|
||||
* next A-MPDU (by GP2)
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/* return unless this MPDU has old SN */
|
||||
if (!(reorder & IWL_RX_MPDU_REORDER_BA_OLD_SN))
|
||||
return;
|
||||
|
||||
/* update state */
|
||||
buffer->consec_oldsn_prev_drop = 1;
|
||||
buffer->consec_oldsn_drops++;
|
||||
|
||||
/* if limit is reached, send del BA and reset state */
|
||||
if (buffer->consec_oldsn_drops == IWL_MVM_AMPDU_CONSEC_DROPS_DELBA) {
|
||||
IWL_WARN(mvm,
|
||||
"reached %d old SN frames from %pM on queue %d, stopping BA session on TID %d\n",
|
||||
IWL_MVM_AMPDU_CONSEC_DROPS_DELBA,
|
||||
sta->addr, queue, tid);
|
||||
ieee80211_stop_rx_ba_session(mvmsta->vif, BIT(tid), sta->addr);
|
||||
buffer->consec_oldsn_prev_drop = 0;
|
||||
buffer->consec_oldsn_drops = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the MPDU was buffered\dropped, false if it should be passed
|
||||
* to upper layer.
|
||||
@ -792,6 +849,7 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
|
||||
struct sk_buff *skb,
|
||||
struct iwl_rx_mpdu_desc *desc)
|
||||
{
|
||||
struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
|
||||
struct ieee80211_hdr *hdr = iwl_mvm_skb_get_hdr(skb);
|
||||
struct iwl_mvm_sta *mvm_sta;
|
||||
struct iwl_mvm_baid_data *baid_data;
|
||||
@ -894,6 +952,9 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
|
||||
min_sn, IWL_MVM_RELEASE_SEND_RSS_SYNC);
|
||||
}
|
||||
|
||||
iwl_mvm_oldsn_workaround(mvm, sta, tid, buffer, reorder,
|
||||
rx_status->device_timestamp, queue);
|
||||
|
||||
/* drop any oudated packets */
|
||||
if (ieee80211_sn_less(sn, buffer->head_sn))
|
||||
goto drop;
|
||||
@ -1504,7 +1565,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->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
|
||||
if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
|
||||
rate_n_flags = le32_to_cpu(desc->v3.rate_n_flags);
|
||||
channel = desc->v3.channel;
|
||||
gp2_on_air_rise = le32_to_cpu(desc->v3.gp2_on_air_rise);
|
||||
@ -1605,7 +1666,8 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
if (likely(!(phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD))) {
|
||||
u64 tsf_on_air_rise;
|
||||
|
||||
if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
|
||||
if (mvm->trans->trans_cfg->device_family >=
|
||||
IWL_DEVICE_FAMILY_22560)
|
||||
tsf_on_air_rise = le64_to_cpu(desc->v3.tsf_on_air_rise);
|
||||
else
|
||||
tsf_on_air_rise = le64_to_cpu(desc->v1.tsf_on_air_rise);
|
||||
@ -1731,7 +1793,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->cfg->device_family ==
|
||||
if (mvm->trans->trans_cfg->device_family ==
|
||||
IWL_DEVICE_FAMILY_9000) {
|
||||
iwl_mvm_flip_address(hdr->addr3);
|
||||
|
||||
@ -1960,3 +2022,42 @@ void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
le16_to_cpu(release->nssn),
|
||||
queue, 0);
|
||||
}
|
||||
|
||||
void iwl_mvm_rx_bar_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct iwl_rx_cmd_buffer *rxb, int queue)
|
||||
{
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
struct iwl_bar_frame_release *release = (void *)pkt->data;
|
||||
unsigned int baid = le32_get_bits(release->ba_info,
|
||||
IWL_BAR_FRAME_RELEASE_BAID_MASK);
|
||||
unsigned int nssn = le32_get_bits(release->ba_info,
|
||||
IWL_BAR_FRAME_RELEASE_NSSN_MASK);
|
||||
unsigned int sta_id = le32_get_bits(release->sta_tid,
|
||||
IWL_BAR_FRAME_RELEASE_STA_MASK);
|
||||
unsigned int tid = le32_get_bits(release->sta_tid,
|
||||
IWL_BAR_FRAME_RELEASE_TID_MASK);
|
||||
struct iwl_mvm_baid_data *baid_data;
|
||||
|
||||
if (WARN_ON_ONCE(baid == IWL_RX_REORDER_DATA_INVALID_BAID ||
|
||||
baid >= ARRAY_SIZE(mvm->baid_map)))
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
baid_data = rcu_dereference(mvm->baid_map[baid]);
|
||||
if (!baid_data) {
|
||||
IWL_DEBUG_RX(mvm,
|
||||
"Got valid BAID %d but not allocated, invalid BAR release!\n",
|
||||
baid);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (WARN(tid != baid_data->tid || sta_id != baid_data->sta_id,
|
||||
"baid 0x%x is mapped to sta:%d tid:%d, but BAR release received for sta:%d tid:%d\n",
|
||||
baid, baid_data->sta_id, baid_data->tid, sta_id,
|
||||
tid))
|
||||
goto out;
|
||||
|
||||
iwl_mvm_release_frames_from_notif(mvm, napi, baid, nssn, queue, 0);
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
@ -77,7 +77,10 @@
|
||||
#define IWL_SCAN_DWELL_FRAGMENTED 44
|
||||
#define IWL_SCAN_DWELL_EXTENDED 90
|
||||
#define IWL_SCAN_NUM_OF_FRAGS 3
|
||||
#define IWL_SCAN_LAST_2_4_CHN 14
|
||||
|
||||
#define IWL_SCAN_BAND_5_2 0
|
||||
#define IWL_SCAN_BAND_2_4 1
|
||||
|
||||
/* adaptive dwell max budget time [TU] for full scan */
|
||||
#define IWL_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN 300
|
||||
@ -512,7 +515,6 @@ void iwl_mvm_rx_lmac_scan_complete_notif(struct iwl_mvm *mvm,
|
||||
|
||||
mvm->scan_status &= ~IWL_MVM_SCAN_REGULAR;
|
||||
ieee80211_scan_completed(mvm->hw, &info);
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
|
||||
cancel_delayed_work(&mvm->scan_timeout_dwork);
|
||||
iwl_mvm_resume_tcm(mvm);
|
||||
} else {
|
||||
@ -957,11 +959,24 @@ static int iwl_mvm_scan_lmac_flags(struct iwl_mvm *mvm,
|
||||
return flags;
|
||||
}
|
||||
|
||||
static void
|
||||
iwl_mvm_scan_set_legacy_probe_req(struct iwl_scan_probe_req_v1 *p_req,
|
||||
struct iwl_scan_probe_req *src_p_req)
|
||||
{
|
||||
int i;
|
||||
|
||||
p_req->mac_header = src_p_req->mac_header;
|
||||
for (i = 0; i < SCAN_NUM_BAND_PROBE_DATA_V_1; i++)
|
||||
p_req->band_data[i] = src_p_req->band_data[i];
|
||||
p_req->common_data = src_p_req->common_data;
|
||||
memcpy(p_req->buf, src_p_req->buf, sizeof(p_req->buf));
|
||||
}
|
||||
|
||||
static int iwl_mvm_scan_lmac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct iwl_mvm_scan_params *params)
|
||||
{
|
||||
struct iwl_scan_req_lmac *cmd = mvm->scan_cmd;
|
||||
struct iwl_scan_probe_req *preq =
|
||||
struct iwl_scan_probe_req_v1 *preq =
|
||||
(void *)(cmd->data + sizeof(struct iwl_scan_channel_cfg_lmac) *
|
||||
mvm->fw->ucode_capa.n_scan_channels);
|
||||
u32 ssid_bitmap = 0;
|
||||
@ -1031,7 +1046,7 @@ static int iwl_mvm_scan_lmac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
iwl_mvm_lmac_scan_cfg_channels(mvm, params->channels,
|
||||
params->n_channels, ssid_bitmap, cmd);
|
||||
|
||||
*preq = params->preq;
|
||||
iwl_mvm_scan_set_legacy_probe_req(preq, ¶ms->preq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1205,7 +1220,7 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
|
||||
cmd_size = sizeof(struct iwl_scan_config);
|
||||
else
|
||||
cmd_size = sizeof(struct iwl_scan_config_v1);
|
||||
cmd_size += mvm->fw->ucode_capa.n_scan_channels;
|
||||
cmd_size += num_channels;
|
||||
|
||||
cfg = kzalloc(cmd_size, GFP_KERNEL);
|
||||
if (!cfg)
|
||||
@ -1385,9 +1400,17 @@ iwl_mvm_umac_scan_cfg_channels(struct iwl_mvm *mvm,
|
||||
|
||||
for (i = 0; i < n_channels; i++) {
|
||||
channel_cfg[i].flags = cpu_to_le32(ssid_bitmap);
|
||||
channel_cfg[i].channel_num = channels[i]->hw_value;
|
||||
channel_cfg[i].iter_count = 1;
|
||||
channel_cfg[i].iter_interval = 0;
|
||||
channel_cfg[i].v1.channel_num = channels[i]->hw_value;
|
||||
if (iwl_mvm_is_scan_ext_chan_supported(mvm)) {
|
||||
channel_cfg[i].v2.band =
|
||||
channels[i]->hw_value <= IWL_SCAN_LAST_2_4_CHN ?
|
||||
IWL_SCAN_BAND_2_4 : IWL_SCAN_BAND_5_2;
|
||||
channel_cfg[i].v2.iter_count = 1;
|
||||
channel_cfg[i].v2.iter_interval = 0;
|
||||
} else {
|
||||
channel_cfg[i].v1.iter_count = 1;
|
||||
channel_cfg[i].v1.iter_interval = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1477,9 +1500,12 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct iwl_scan_req_umac *cmd = mvm->scan_cmd;
|
||||
struct iwl_scan_umac_chan_param *chan_param;
|
||||
void *cmd_data = iwl_mvm_get_scan_req_umac_data(mvm);
|
||||
struct iwl_scan_req_umac_tail *sec_part = cmd_data +
|
||||
sizeof(struct iwl_scan_channel_cfg_umac) *
|
||||
void *sec_part = cmd_data + sizeof(struct iwl_scan_channel_cfg_umac) *
|
||||
mvm->fw->ucode_capa.n_scan_channels;
|
||||
struct iwl_scan_req_umac_tail_v2 *tail_v2 =
|
||||
(struct iwl_scan_req_umac_tail_v2 *)sec_part;
|
||||
struct iwl_scan_req_umac_tail_v1 *tail_v1;
|
||||
struct iwl_ssid_ie *direct_scan;
|
||||
int uid, i;
|
||||
u32 ssid_bitmap = 0;
|
||||
u8 channel_flags = 0;
|
||||
@ -1541,18 +1567,12 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
chan_param->flags = channel_flags;
|
||||
chan_param->count = params->n_channels;
|
||||
|
||||
iwl_scan_build_ssids(params, sec_part->direct_scan, &ssid_bitmap);
|
||||
|
||||
iwl_mvm_umac_scan_cfg_channels(mvm, params->channels,
|
||||
params->n_channels, ssid_bitmap,
|
||||
cmd_data);
|
||||
|
||||
for (i = 0; i < params->n_scan_plans; i++) {
|
||||
struct cfg80211_sched_scan_plan *scan_plan =
|
||||
¶ms->scan_plans[i];
|
||||
|
||||
sec_part->schedule[i].iter_count = scan_plan->iterations;
|
||||
sec_part->schedule[i].interval =
|
||||
tail_v2->schedule[i].iter_count = scan_plan->iterations;
|
||||
tail_v2->schedule[i].interval =
|
||||
cpu_to_le16(scan_plan->interval);
|
||||
}
|
||||
|
||||
@ -1562,12 +1582,24 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
* For example, when regular scan is requested the driver sets one scan
|
||||
* plan with one iteration.
|
||||
*/
|
||||
if (!sec_part->schedule[i - 1].iter_count)
|
||||
sec_part->schedule[i - 1].iter_count = 0xff;
|
||||
if (!tail_v2->schedule[i - 1].iter_count)
|
||||
tail_v2->schedule[i - 1].iter_count = 0xff;
|
||||
|
||||
sec_part->delay = cpu_to_le16(params->delay);
|
||||
sec_part->preq = params->preq;
|
||||
tail_v2->delay = cpu_to_le16(params->delay);
|
||||
|
||||
if (iwl_mvm_is_scan_ext_chan_supported(mvm)) {
|
||||
tail_v2->preq = params->preq;
|
||||
direct_scan = tail_v2->direct_scan;
|
||||
} else {
|
||||
tail_v1 = (struct iwl_scan_req_umac_tail_v1 *)sec_part;
|
||||
iwl_mvm_scan_set_legacy_probe_req(&tail_v1->preq,
|
||||
¶ms->preq);
|
||||
direct_scan = tail_v1->direct_scan;
|
||||
}
|
||||
iwl_scan_build_ssids(params, direct_scan, &ssid_bitmap);
|
||||
iwl_mvm_umac_scan_cfg_channels(mvm, params->channels,
|
||||
params->n_channels, ssid_bitmap,
|
||||
cmd_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1758,7 +1790,6 @@ int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
IWL_DEBUG_SCAN(mvm, "Scan request was sent successfully\n");
|
||||
mvm->scan_status |= IWL_MVM_SCAN_REGULAR;
|
||||
mvm->scan_vif = iwl_mvm_vif_from_mac80211(vif);
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_SCAN);
|
||||
|
||||
schedule_delayed_work(&mvm->scan_timeout_dwork,
|
||||
msecs_to_jiffies(SCAN_TIMEOUT));
|
||||
@ -1884,7 +1915,6 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
|
||||
memcpy(info.tsf_bssid, mvm->scan_vif->bssid, ETH_ALEN);
|
||||
ieee80211_scan_completed(mvm->hw, &info);
|
||||
mvm->scan_vif = NULL;
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
|
||||
cancel_delayed_work(&mvm->scan_timeout_dwork);
|
||||
iwl_mvm_resume_tcm(mvm);
|
||||
} else if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_SCHED) {
|
||||
@ -1909,8 +1939,6 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
|
||||
mvm->last_ebs_successful = false;
|
||||
|
||||
mvm->scan_uid_status[uid] = 0;
|
||||
|
||||
iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_SCAN_COMPLETE);
|
||||
}
|
||||
|
||||
void iwl_mvm_rx_umac_scan_iter_complete_notif(struct iwl_mvm *mvm,
|
||||
@ -1999,6 +2027,7 @@ static int iwl_mvm_scan_stop_wait(struct iwl_mvm *mvm, int type)
|
||||
int iwl_mvm_scan_size(struct iwl_mvm *mvm)
|
||||
{
|
||||
int base_size = IWL_SCAN_REQ_UMAC_SIZE_V1;
|
||||
int tail_size;
|
||||
|
||||
if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm))
|
||||
base_size = IWL_SCAN_REQ_UMAC_SIZE_V8;
|
||||
@ -2007,16 +2036,21 @@ int iwl_mvm_scan_size(struct iwl_mvm *mvm)
|
||||
else if (iwl_mvm_cdb_scan_api(mvm))
|
||||
base_size = IWL_SCAN_REQ_UMAC_SIZE_V6;
|
||||
|
||||
if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN))
|
||||
if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
|
||||
if (iwl_mvm_is_scan_ext_chan_supported(mvm))
|
||||
tail_size = sizeof(struct iwl_scan_req_umac_tail_v2);
|
||||
else
|
||||
tail_size = sizeof(struct iwl_scan_req_umac_tail_v1);
|
||||
|
||||
return base_size +
|
||||
sizeof(struct iwl_scan_channel_cfg_umac) *
|
||||
mvm->fw->ucode_capa.n_scan_channels +
|
||||
sizeof(struct iwl_scan_req_umac_tail);
|
||||
|
||||
tail_size;
|
||||
}
|
||||
return sizeof(struct iwl_scan_req_lmac) +
|
||||
sizeof(struct iwl_scan_channel_cfg_lmac) *
|
||||
mvm->fw->ucode_capa.n_scan_channels +
|
||||
sizeof(struct iwl_scan_probe_req);
|
||||
sizeof(struct iwl_scan_probe_req_v1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2099,10 +2133,6 @@ int iwl_mvm_scan_stop(struct iwl_mvm *mvm, int type, bool notify)
|
||||
mvm->scan_status &= ~type;
|
||||
|
||||
if (type == IWL_MVM_SCAN_REGULAR) {
|
||||
/* Since the rx handler won't do anything now, we have
|
||||
* to release the scan reference here.
|
||||
*/
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
|
||||
cancel_delayed_work(&mvm->scan_timeout_dwork);
|
||||
if (notify) {
|
||||
struct cfg80211_scan_info info = {
|
||||
|
@ -67,14 +67,6 @@
|
||||
#include "sta.h"
|
||||
#include "rs.h"
|
||||
|
||||
static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm);
|
||||
|
||||
static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
|
||||
u32 sta_id,
|
||||
struct ieee80211_key_conf *key, bool mcast,
|
||||
u32 tkip_iv32, u16 *tkip_p1k, u32 cmd_flags,
|
||||
u8 key_offset, bool mfp);
|
||||
|
||||
/*
|
||||
* New version of ADD_STA_sta command added new fields at the end of the
|
||||
* structure, so sending the size of the relevant API's structure is enough to
|
||||
@ -1612,7 +1604,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
|
||||
mvm_sta->mac_id_n_color = FW_CMD_ID_AND_COLOR(mvmvif->id,
|
||||
mvmvif->color);
|
||||
mvm_sta->vif = vif;
|
||||
if (!mvm->trans->cfg->gen2)
|
||||
if (!mvm->trans->trans_cfg->gen2)
|
||||
mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
|
||||
else
|
||||
mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF;
|
||||
@ -1895,10 +1887,6 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
|
||||
|
||||
/* unassoc - go ahead - remove the AP STA now */
|
||||
mvmvif->ap_sta_id = IWL_MVM_INVALID_STA;
|
||||
|
||||
/* clear d0i3_ap_sta_id if no longer relevant */
|
||||
if (mvm->d0i3_ap_sta_id == sta_id)
|
||||
mvm->d0i3_ap_sta_id = IWL_MVM_INVALID_STA;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1966,7 +1954,7 @@ static void iwl_mvm_enable_aux_snif_queue(struct iwl_mvm *mvm, u16 *queue,
|
||||
u8 sta_id, u8 fifo)
|
||||
{
|
||||
unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ?
|
||||
mvm->cfg->base_params->wd_timeout :
|
||||
mvm->trans->trans_cfg->base_params->wd_timeout :
|
||||
IWL_WATCHDOG_DISABLED;
|
||||
|
||||
if (iwl_mvm_has_new_tx_api(mvm)) {
|
||||
@ -2771,13 +2759,6 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
|
||||
spin_lock_bh(&mvmsta->lock);
|
||||
|
||||
/* possible race condition - we entered D0i3 while starting agg */
|
||||
if (test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status)) {
|
||||
spin_unlock_bh(&mvmsta->lock);
|
||||
IWL_ERR(mvm, "Entered D0i3 while starting Tx agg\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note the possible cases:
|
||||
* 1. An enabled TXQ - TXQ needs to become agg'ed
|
||||
@ -2832,7 +2813,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->cfg->gen2)
|
||||
if (mvm->trans->trans_cfg->gen2)
|
||||
normalized_ssn &= 0xff;
|
||||
|
||||
if (normalized_ssn == tid_data->next_reclaimed) {
|
||||
@ -3872,7 +3853,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->cfg->gen2)
|
||||
if (mvm->trans->trans_cfg->gen2)
|
||||
sn &= 0xff;
|
||||
|
||||
return ieee80211_sn_sub(sn, tid_data->next_reclaimed);
|
||||
|
@ -205,19 +205,10 @@ void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw,
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
u32 duration = 2 * vif->bss_conf.dtim_period * vif->bss_conf.beacon_int;
|
||||
|
||||
/*
|
||||
* iwl_mvm_protect_session() reads directly from the device
|
||||
* (the system time), so make sure it is available.
|
||||
*/
|
||||
if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PROTECT_TDLS))
|
||||
return;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
/* Protect the session to hear the TDLS setup response on the channel */
|
||||
iwl_mvm_protect_session(mvm, vif, duration, duration, 100, true);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_TDLS);
|
||||
}
|
||||
|
||||
static const char *
|
||||
|
@ -106,10 +106,8 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)
|
||||
* in the case that the time event actually completed in the firmware
|
||||
* (which is handled in iwl_mvm_te_handle_notif).
|
||||
*/
|
||||
if (test_and_clear_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status))
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_ROC);
|
||||
if (test_and_clear_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status))
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_ROC_AUX);
|
||||
clear_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status);
|
||||
clear_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status);
|
||||
|
||||
synchronize_net();
|
||||
|
||||
@ -357,7 +355,6 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
|
||||
|
||||
if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) {
|
||||
set_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status);
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_ROC);
|
||||
ieee80211_ready_on_channel(mvm->hw);
|
||||
} else if (te_data->id == TE_CHANNEL_SWITCH_PERIOD) {
|
||||
iwl_mvm_te_handle_notify_csa(mvm, te_data, notif);
|
||||
@ -405,7 +402,6 @@ static int iwl_mvm_aux_roc_te_handle_notif(struct iwl_mvm *mvm,
|
||||
} else if (le32_to_cpu(notif->action) == TE_V2_NOTIF_HOST_EVENT_START) {
|
||||
set_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status);
|
||||
te_data->running = true;
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_ROC_AUX);
|
||||
ieee80211_ready_on_channel(mvm->hw); /* Start TE */
|
||||
} else {
|
||||
IWL_DEBUG_TE(mvm,
|
||||
|
@ -5,7 +5,7 @@
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014, 2019 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 - 2016 Intel Deutschland GmbH
|
||||
*
|
||||
@ -27,7 +27,7 @@
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2012 - 2014, 2019 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 - 2016 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
@ -298,16 +298,8 @@ static void check_exit_ctkill(struct work_struct *work)
|
||||
if (__iwl_mvm_mac_start(mvm))
|
||||
goto reschedule;
|
||||
|
||||
/* make sure the device is available for direct read/writes */
|
||||
if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_CHECK_CTKILL)) {
|
||||
__iwl_mvm_mac_stop(mvm);
|
||||
goto reschedule;
|
||||
}
|
||||
|
||||
ret = iwl_mvm_get_temp(mvm, &temp);
|
||||
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_CHECK_CTKILL);
|
||||
|
||||
__iwl_mvm_mac_stop(mvm);
|
||||
|
||||
if (ret)
|
||||
|
@ -546,7 +546,7 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
hdr->frame_control);
|
||||
}
|
||||
|
||||
if (mvm->trans->cfg->device_family >=
|
||||
if (mvm->trans->trans_cfg->device_family >=
|
||||
IWL_DEVICE_FAMILY_22560) {
|
||||
struct iwl_tx_cmd_gen3 *cmd = (void *)dev_cmd->payload;
|
||||
|
||||
@ -1169,8 +1169,9 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
schedule_work(&mvm->add_stream_wk);
|
||||
}
|
||||
|
||||
IWL_DEBUG_TX(mvm, "TX to [%d|%d] Q:%d - seq: 0x%x\n", mvmsta->sta_id,
|
||||
tid, txq_id, IEEE80211_SEQ_TO_SN(seq_number));
|
||||
IWL_DEBUG_TX(mvm, "TX to [%d|%d] Q:%d - seq: 0x%x len %d\n",
|
||||
mvmsta->sta_id, tid, txq_id,
|
||||
IEEE80211_SEQ_TO_SN(seq_number), skb->len);
|
||||
|
||||
/* From now on, we cannot access info->control */
|
||||
iwl_mvm_skb_prepare_status(skb, dev_cmd);
|
||||
@ -1271,7 +1272,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->cfg->gen2)
|
||||
if (mvm->trans->trans_cfg->gen2)
|
||||
normalized_ssn &= 0xff;
|
||||
|
||||
if (normalized_ssn != tid_data->next_reclaimed)
|
||||
|
@ -88,17 +88,11 @@ int iwl_mvm_send_cmd(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd)
|
||||
* the mutex, this ensures we don't try to send two
|
||||
* (or more) synchronous commands at a time.
|
||||
*/
|
||||
if (!(cmd->flags & CMD_ASYNC)) {
|
||||
if (!(cmd->flags & CMD_ASYNC))
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
if (!(cmd->flags & CMD_SEND_IN_IDLE))
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_SENDING_CMD);
|
||||
}
|
||||
|
||||
ret = iwl_trans_send_cmd(mvm->trans, cmd);
|
||||
|
||||
if (!(cmd->flags & (CMD_ASYNC | CMD_SEND_IN_IDLE)))
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_SENDING_CMD);
|
||||
|
||||
/*
|
||||
* If the caller wants the SKB, then don't hide any problems, the
|
||||
* caller might access the response buffer which will be NULL if
|
||||
@ -537,7 +531,7 @@ static void iwl_mvm_dump_lmac_error_log(struct iwl_mvm *mvm, u8 lmac_num)
|
||||
/* reset the device */
|
||||
iwl_trans_sw_reset(trans);
|
||||
|
||||
err = iwl_finish_nic_init(trans);
|
||||
err = iwl_finish_nic_init(trans, trans->trans_cfg);
|
||||
if (err)
|
||||
return;
|
||||
}
|
||||
@ -945,8 +939,9 @@ unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm,
|
||||
{
|
||||
struct iwl_fw_dbg_trigger_tlv *trigger;
|
||||
struct iwl_fw_dbg_trigger_txq_timer *txq_timer;
|
||||
unsigned int default_timeout =
|
||||
cmd_q ? IWL_DEF_WD_TIMEOUT : mvm->cfg->base_params->wd_timeout;
|
||||
unsigned int default_timeout = cmd_q ?
|
||||
IWL_DEF_WD_TIMEOUT :
|
||||
mvm->trans->trans_cfg->base_params->wd_timeout;
|
||||
|
||||
if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_TXQ_TIMERS)) {
|
||||
/*
|
||||
@ -990,7 +985,7 @@ unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm,
|
||||
return default_timeout;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return mvm->cfg->base_params->wd_timeout;
|
||||
return mvm->trans->trans_cfg->base_params->wd_timeout;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1436,7 +1431,7 @@ u32 iwl_mvm_get_systime(struct iwl_mvm *mvm)
|
||||
{
|
||||
u32 reg_addr = DEVICE_SYSTEM_TIME_REG;
|
||||
|
||||
if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000 &&
|
||||
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;
|
||||
|
||||
|
@ -96,7 +96,7 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
|
||||
cpu_to_le64(trans_pcie->rxq->bd_dma);
|
||||
|
||||
/* Configure debug, for integration */
|
||||
if (!trans->dbg.ini_valid)
|
||||
if (!iwl_trans_dbg_ini_valid(trans))
|
||||
iwl_pcie_alloc_fw_monitor(trans, 0);
|
||||
if (trans->dbg.num_blocks) {
|
||||
prph_sc_ctrl->hwm_cfg.hwm_base_addr =
|
||||
@ -180,7 +180,7 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
|
||||
|
||||
iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL,
|
||||
CSR_AUTO_FUNC_BOOT_ENA);
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
|
||||
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
|
||||
iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1);
|
||||
else
|
||||
iwl_set_bit(trans, CSR_GP_CNTRL, CSR_AUTO_FUNC_INIT);
|
||||
|
@ -65,7 +65,6 @@
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
@ -73,6 +72,7 @@
|
||||
|
||||
#include "iwl-trans.h"
|
||||
#include "iwl-drv.h"
|
||||
#include "iwl-prph.h"
|
||||
#include "internal.h"
|
||||
|
||||
#define IWL_PCI_DEVICE(dev, subdev, cfg) \
|
||||
@ -994,15 +994,22 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
|
||||
const struct iwl_cfg *cfg_7265d __maybe_unused = NULL;
|
||||
struct iwl_trans *iwl_trans;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
if (WARN_ONCE(!cfg->csr, "CSR addresses aren't configured\n"))
|
||||
return -EINVAL;
|
||||
|
||||
iwl_trans = iwl_trans_pcie_alloc(pdev, ent, cfg);
|
||||
iwl_trans = iwl_trans_pcie_alloc(pdev, ent, &cfg->trans);
|
||||
if (IS_ERR(iwl_trans))
|
||||
return PTR_ERR(iwl_trans);
|
||||
|
||||
/* the trans_cfg should never change, so set it now */
|
||||
iwl_trans->trans_cfg = &cfg->trans;
|
||||
|
||||
if (WARN_ONCE(!iwl_trans->trans_cfg->csr,
|
||||
"CSR addresses aren't configured\n")) {
|
||||
ret = -EINVAL;
|
||||
goto out_free_trans;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_IWLMVM)
|
||||
/*
|
||||
* special-case 7265D, it has the same PCI IDs.
|
||||
@ -1018,29 +1025,70 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
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->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D)
|
||||
cfg = cfg_7265d;
|
||||
iwl_trans->cfg = cfg_7265d;
|
||||
|
||||
iwl_trans->hw_rf_id = iwl_read32(iwl_trans, CSR_HW_RF_ID);
|
||||
|
||||
if (cfg == &iwlax210_2ax_cfg_so_hr_a0) {
|
||||
if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_TY) {
|
||||
cfg = &iwlax210_2ax_cfg_ty_gf_a0;
|
||||
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) {
|
||||
cfg = &iwlax210_2ax_cfg_so_jf_a0;
|
||||
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF)) {
|
||||
cfg = &iwlax211_2ax_cfg_so_gf_a0;
|
||||
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF4)) {
|
||||
cfg = &iwlax411_2ax_cfg_so_gf4_a0;
|
||||
}
|
||||
} else if (cfg == &iwl_ax101_cfg_qu_hr) {
|
||||
if ((CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
|
||||
iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0) ||
|
||||
(CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR1))) {
|
||||
cfg = &iwl22000_2ax_cfg_qnj_hr_b0;
|
||||
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) {
|
||||
cfg = &iwl_ax101_cfg_qu_hr;
|
||||
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) {
|
||||
cfg = &iwl22000_2ax_cfg_jf;
|
||||
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HRCDB)) {
|
||||
IWL_ERR(iwl_trans, "RF ID HRCDB is not supported\n");
|
||||
return -EINVAL;
|
||||
} else {
|
||||
IWL_ERR(iwl_trans, "Unrecognized RF ID 0x%08x\n",
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id));
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
|
||||
((cfg != &iwl_ax200_cfg_cc &&
|
||||
cfg != &killer1650x_2ax_cfg &&
|
||||
cfg != &killer1650w_2ax_cfg &&
|
||||
cfg != &iwl_ax201_cfg_quz_hr) ||
|
||||
iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0)) {
|
||||
u32 hw_status;
|
||||
|
||||
if (iwl_trans->cfg->rf_id && cfg == &iwl22000_2ac_cfg_hr_cdb &&
|
||||
iwl_trans->hw_rev != CSR_HW_REV_TYPE_HR_CDB) {
|
||||
u32 rf_id_chp = CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id);
|
||||
u32 jf_chp_id = CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF);
|
||||
u32 hr_chp_id = CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR);
|
||||
|
||||
if (rf_id_chp == jf_chp_id) {
|
||||
if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ)
|
||||
cfg = &iwl9560_2ac_cfg_qnj_jf_b0;
|
||||
else
|
||||
cfg = &iwl22000_2ac_cfg_jf;
|
||||
} else if (rf_id_chp == hr_chp_id) {
|
||||
if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ)
|
||||
cfg = &iwl22000_2ax_cfg_qnj_hr_a0;
|
||||
else
|
||||
hw_status = iwl_read_prph(iwl_trans, UMAG_GEN_HW_STATUS);
|
||||
if (CSR_HW_RF_STEP(iwl_trans->hw_rf_id) == SILICON_B_STEP)
|
||||
/*
|
||||
* b step fw is the same for physical card and fpga
|
||||
*/
|
||||
cfg = &iwl22000_2ax_cfg_qnj_hr_b0;
|
||||
else if ((hw_status & UMAG_GEN_HW_IS_FPGA) &&
|
||||
CSR_HW_RF_STEP(iwl_trans->hw_rf_id) == SILICON_A_STEP) {
|
||||
cfg = &iwl22000_2ax_cfg_qnj_hr_a0_f0;
|
||||
} else {
|
||||
/*
|
||||
* a step no FPGA
|
||||
*/
|
||||
cfg = &iwl22000_2ac_cfg_hr;
|
||||
}
|
||||
iwl_trans->cfg = cfg;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1050,22 +1098,18 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
* thing to do to support Qu C-step.
|
||||
*/
|
||||
if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QU_C0) {
|
||||
if (iwl_trans->cfg == &iwl_ax101_cfg_qu_hr)
|
||||
iwl_trans->cfg = &iwl_ax101_cfg_qu_c0_hr_b0;
|
||||
else if (iwl_trans->cfg == &iwl_ax201_cfg_qu_hr)
|
||||
iwl_trans->cfg = &iwl_ax201_cfg_qu_c0_hr_b0;
|
||||
else if (iwl_trans->cfg == &iwl9461_2ac_cfg_qu_b0_jf_b0)
|
||||
iwl_trans->cfg = &iwl9461_2ac_cfg_qu_c0_jf_b0;
|
||||
else if (iwl_trans->cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0)
|
||||
iwl_trans->cfg = &iwl9462_2ac_cfg_qu_c0_jf_b0;
|
||||
else if (iwl_trans->cfg == &iwl9560_2ac_cfg_qu_b0_jf_b0)
|
||||
iwl_trans->cfg = &iwl9560_2ac_cfg_qu_c0_jf_b0;
|
||||
else if (iwl_trans->cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0)
|
||||
iwl_trans->cfg = &iwl9560_2ac_160_cfg_qu_c0_jf_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;
|
||||
if (cfg == &iwl_ax101_cfg_qu_hr)
|
||||
cfg = &iwl_ax101_cfg_qu_c0_hr_b0;
|
||||
else if (cfg == &iwl_ax201_cfg_qu_hr)
|
||||
cfg = &iwl_ax201_cfg_qu_c0_hr_b0;
|
||||
else if (cfg == &iwl9461_2ac_cfg_qu_b0_jf_b0)
|
||||
cfg = &iwl9461_2ac_cfg_qu_c0_jf_b0;
|
||||
else if (cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0)
|
||||
cfg = &iwl9462_2ac_cfg_qu_c0_jf_b0;
|
||||
else if (cfg == &iwl9560_2ac_cfg_qu_b0_jf_b0)
|
||||
cfg = &iwl9560_2ac_cfg_qu_c0_jf_b0;
|
||||
else if (cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0)
|
||||
cfg = &iwl9560_2ac_160_cfg_qu_c0_jf_b0;
|
||||
}
|
||||
|
||||
/* same thing for QuZ... */
|
||||
@ -1085,6 +1129,23 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
}
|
||||
|
||||
#endif
|
||||
/* now set the real cfg we decided to use */
|
||||
iwl_trans->cfg = cfg;
|
||||
|
||||
if (iwl_trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000 &&
|
||||
iwl_trans_grab_nic_access(iwl_trans, &flags)) {
|
||||
u32 hw_step;
|
||||
|
||||
hw_step = iwl_read_umac_prph_no_grab(iwl_trans, WFPM_CTRL_REG);
|
||||
hw_step |= ENABLE_WFPM;
|
||||
iwl_write_umac_prph_no_grab(iwl_trans, WFPM_CTRL_REG, hw_step);
|
||||
hw_step = iwl_read_prph_no_grab(iwl_trans, CNVI_AUX_MISC_CHIP);
|
||||
hw_step = (hw_step >> HW_STEP_LOCATION_BITS) & 0xF;
|
||||
if (hw_step == 0x3)
|
||||
iwl_trans->hw_rev = (iwl_trans->hw_rev & 0xFFFFFFF3) |
|
||||
(SILICON_C_STEP << 2);
|
||||
iwl_trans_release_nic_access(iwl_trans, &flags);
|
||||
}
|
||||
|
||||
pci_set_drvdata(pdev, iwl_trans);
|
||||
iwl_trans->drv = iwl_drv_start(iwl_trans);
|
||||
@ -1097,25 +1158,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
/* register transport layer debugfs here */
|
||||
iwl_trans_pcie_dbgfs_register(iwl_trans);
|
||||
|
||||
/* if RTPM is in use, enable it in our device */
|
||||
if (iwl_trans->runtime_pm_mode != IWL_PLAT_PM_MODE_DISABLED) {
|
||||
/* We explicitly set the device to active here to
|
||||
* clear contingent errors.
|
||||
*/
|
||||
pm_runtime_set_active(&pdev->dev);
|
||||
|
||||
pm_runtime_set_autosuspend_delay(&pdev->dev,
|
||||
iwlwifi_mod_params.d0i3_timeout);
|
||||
pm_runtime_use_autosuspend(&pdev->dev);
|
||||
|
||||
/* We are not supposed to call pm_runtime_allow() by
|
||||
* ourselves, but let userspace enable runtime PM via
|
||||
* sysfs. However, since we don't enable this from
|
||||
* userspace yet, we need to allow/forbid() ourselves.
|
||||
*/
|
||||
pm_runtime_allow(&pdev->dev);
|
||||
}
|
||||
|
||||
/* The PCI device starts with a reference taken and we are
|
||||
* supposed to release it here. But to simplify the
|
||||
* interaction with the opmode, we don't do it now, but let
|
||||
@ -1133,15 +1175,6 @@ static void iwl_pci_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct iwl_trans *trans = pci_get_drvdata(pdev);
|
||||
|
||||
/* if RTPM was in use, restore it to the state before probe */
|
||||
if (trans->runtime_pm_mode != IWL_PLAT_PM_MODE_DISABLED) {
|
||||
/* We should not call forbid here, but we do for now.
|
||||
* Check the comment to pm_runtime_allow() in
|
||||
* iwl_pci_probe().
|
||||
*/
|
||||
pm_runtime_forbid(trans->dev);
|
||||
}
|
||||
|
||||
iwl_drv_stop(trans->drv);
|
||||
|
||||
iwl_trans_pcie_free(trans);
|
||||
@ -1199,164 +1232,9 @@ static int iwl_pci_resume(struct device *device)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iwl_pci_fw_enter_d0i3(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
int ret;
|
||||
|
||||
if (test_bit(STATUS_FW_ERROR, &trans->status))
|
||||
return 0;
|
||||
|
||||
set_bit(STATUS_TRANS_GOING_IDLE, &trans->status);
|
||||
|
||||
/* config the fw */
|
||||
ret = iwl_op_mode_enter_d0i3(trans->op_mode);
|
||||
if (ret == 1) {
|
||||
IWL_DEBUG_RPM(trans, "aborting d0i3 entrance\n");
|
||||
clear_bit(STATUS_TRANS_GOING_IDLE, &trans->status);
|
||||
return -EBUSY;
|
||||
}
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = wait_event_timeout(trans_pcie->d0i3_waitq,
|
||||
test_bit(STATUS_TRANS_IDLE, &trans->status),
|
||||
msecs_to_jiffies(IWL_TRANS_IDLE_TIMEOUT));
|
||||
if (!ret) {
|
||||
IWL_ERR(trans, "Timeout entering D0i3\n");
|
||||
ret = -ETIMEDOUT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
clear_bit(STATUS_TRANS_GOING_IDLE, &trans->status);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
clear_bit(STATUS_TRANS_GOING_IDLE, &trans->status);
|
||||
iwl_trans_fw_error(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int iwl_pci_fw_exit_d0i3(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
int ret;
|
||||
|
||||
/* sometimes a D0i3 entry is not followed through */
|
||||
if (!test_bit(STATUS_TRANS_IDLE, &trans->status))
|
||||
return 0;
|
||||
|
||||
/* config the fw */
|
||||
ret = iwl_op_mode_exit_d0i3(trans->op_mode);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* we clear STATUS_TRANS_IDLE only when D0I3_END command is completed */
|
||||
|
||||
ret = wait_event_timeout(trans_pcie->d0i3_waitq,
|
||||
!test_bit(STATUS_TRANS_IDLE, &trans->status),
|
||||
msecs_to_jiffies(IWL_TRANS_IDLE_TIMEOUT));
|
||||
if (!ret) {
|
||||
IWL_ERR(trans, "Timeout exiting D0i3\n");
|
||||
ret = -ETIMEDOUT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
clear_bit(STATUS_TRANS_IDLE, &trans->status);
|
||||
iwl_trans_fw_error(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_PCIE_RTPM
|
||||
static int iwl_pci_runtime_suspend(struct device *device)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(device);
|
||||
struct iwl_trans *trans = pci_get_drvdata(pdev);
|
||||
int ret;
|
||||
|
||||
IWL_DEBUG_RPM(trans, "entering runtime suspend\n");
|
||||
|
||||
if (test_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
|
||||
ret = iwl_pci_fw_enter_d0i3(trans);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
trans->system_pm_mode = IWL_PLAT_PM_MODE_D0I3;
|
||||
|
||||
iwl_trans_d3_suspend(trans, false, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_pci_runtime_resume(struct device *device)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(device);
|
||||
struct iwl_trans *trans = pci_get_drvdata(pdev);
|
||||
enum iwl_d3_status d3_status;
|
||||
|
||||
IWL_DEBUG_RPM(trans, "exiting runtime suspend (resume)\n");
|
||||
|
||||
iwl_trans_d3_resume(trans, &d3_status, false, false);
|
||||
|
||||
if (test_bit(STATUS_DEVICE_ENABLED, &trans->status))
|
||||
return iwl_pci_fw_exit_d0i3(trans);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_pci_system_prepare(struct device *device)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(device);
|
||||
struct iwl_trans *trans = pci_get_drvdata(pdev);
|
||||
|
||||
IWL_DEBUG_RPM(trans, "preparing for system suspend\n");
|
||||
|
||||
/* This is called before entering system suspend and before
|
||||
* the runtime resume is called. Set the suspending flag to
|
||||
* prevent the wakelock from being taken.
|
||||
*/
|
||||
trans->suspending = true;
|
||||
|
||||
/* Wake the device up from runtime suspend before going to
|
||||
* platform suspend. This is needed because we don't know
|
||||
* whether wowlan any is set and, if it's not, mac80211 will
|
||||
* disconnect (in which case, we can't be in D0i3).
|
||||
*/
|
||||
pm_runtime_resume(device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void iwl_pci_system_complete(struct device *device)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(device);
|
||||
struct iwl_trans *trans = pci_get_drvdata(pdev);
|
||||
|
||||
IWL_DEBUG_RPM(trans, "completing system suspend\n");
|
||||
|
||||
/* This is called as a counterpart to the prepare op. It is
|
||||
* called either when suspending fails or when suspend
|
||||
* completed successfully. Now there's no risk of grabbing
|
||||
* the wakelock anymore, so we can release the suspending
|
||||
* flag.
|
||||
*/
|
||||
trans->suspending = false;
|
||||
}
|
||||
#endif /* CONFIG_IWLWIFI_PCIE_RTPM */
|
||||
|
||||
static const struct dev_pm_ops iwl_dev_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(iwl_pci_suspend,
|
||||
iwl_pci_resume)
|
||||
#ifdef CONFIG_IWLWIFI_PCIE_RTPM
|
||||
SET_RUNTIME_PM_OPS(iwl_pci_runtime_suspend,
|
||||
iwl_pci_runtime_resume,
|
||||
NULL)
|
||||
.prepare = iwl_pci_system_prepare,
|
||||
.complete = iwl_pci_system_complete,
|
||||
#endif /* CONFIG_IWLWIFI_PCIE_RTPM */
|
||||
};
|
||||
|
||||
#define IWL_PM_OPS (&iwl_dev_pm_ops)
|
||||
|
@ -253,7 +253,8 @@ struct iwl_dma_ptr {
|
||||
*/
|
||||
static inline int iwl_queue_inc_wrap(struct iwl_trans *trans, int index)
|
||||
{
|
||||
return ++index & (trans->cfg->base_params->max_tfd_queue_size - 1);
|
||||
return ++index &
|
||||
(trans->trans_cfg->base_params->max_tfd_queue_size - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -263,7 +264,7 @@ static inline int iwl_queue_inc_wrap(struct iwl_trans *trans, int index)
|
||||
static inline __le16 iwl_get_closed_rb_stts(struct iwl_trans *trans,
|
||||
struct iwl_rxq *rxq)
|
||||
{
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
|
||||
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
|
||||
__le16 *rb_stts = rxq->rb_stts;
|
||||
|
||||
return READ_ONCE(*rb_stts);
|
||||
@ -280,7 +281,8 @@ static inline __le16 iwl_get_closed_rb_stts(struct iwl_trans *trans,
|
||||
*/
|
||||
static inline int iwl_queue_dec_wrap(struct iwl_trans *trans, int index)
|
||||
{
|
||||
return --index & (trans->cfg->base_params->max_tfd_queue_size - 1);
|
||||
return --index &
|
||||
(trans->trans_cfg->base_params->max_tfd_queue_size - 1);
|
||||
}
|
||||
|
||||
struct iwl_cmd_meta {
|
||||
@ -556,9 +558,10 @@ struct iwl_trans_pcie {
|
||||
void __iomem *hw_base;
|
||||
|
||||
bool ucode_write_complete;
|
||||
bool sx_complete;
|
||||
wait_queue_head_t ucode_write_waitq;
|
||||
wait_queue_head_t wait_command_queue;
|
||||
wait_queue_head_t d0i3_waitq;
|
||||
wait_queue_head_t sx_waitq;
|
||||
|
||||
u8 page_offs, dev_cmd_offs;
|
||||
|
||||
@ -581,7 +584,6 @@ struct iwl_trans_pcie {
|
||||
/*protect hw register */
|
||||
spinlock_t reg_lock;
|
||||
bool cmd_hold_nic_awake;
|
||||
bool ref_cmd_in_flight;
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
struct cont_rec fw_mon_data;
|
||||
@ -635,9 +637,10 @@ iwl_trans_pcie_get_trans(struct iwl_trans_pcie *trans_pcie)
|
||||
* Convention: trans API functions: iwl_trans_pcie_XXX
|
||||
* Other functions: iwl_pcie_XXX
|
||||
*/
|
||||
struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
|
||||
struct iwl_trans
|
||||
*iwl_trans_pcie_alloc(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent,
|
||||
const struct iwl_cfg *cfg);
|
||||
const struct iwl_cfg_trans_params *cfg_trans);
|
||||
void iwl_trans_pcie_free(struct iwl_trans *trans);
|
||||
|
||||
/*****************************************************
|
||||
@ -697,6 +700,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
|
||||
struct iwl_rx_cmd_buffer *rxb);
|
||||
void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
|
||||
struct sk_buff_head *skbs);
|
||||
void iwl_trans_pcie_set_q_ptrs(struct iwl_trans *trans, int txq_id, int ptr);
|
||||
void iwl_trans_pcie_tx_reset(struct iwl_trans *trans);
|
||||
void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans_pcie *trans_pcie,
|
||||
struct iwl_txq *txq, u16 byte_cnt,
|
||||
@ -705,7 +709,7 @@ void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans_pcie *trans_pcie,
|
||||
static inline u16 iwl_pcie_tfd_tb_get_len(struct iwl_trans *trans, void *_tfd,
|
||||
u8 idx)
|
||||
{
|
||||
if (trans->cfg->use_tfh) {
|
||||
if (trans->trans_cfg->use_tfh) {
|
||||
struct iwl_tfh_tfd *tfd = _tfd;
|
||||
struct iwl_tfh_tb *tb = &tfd->tbs[idx];
|
||||
|
||||
@ -911,7 +915,7 @@ static inline void *iwl_pcie_get_tfd(struct iwl_trans *trans,
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
if (trans->cfg->use_tfh)
|
||||
if (trans->trans_cfg->use_tfh)
|
||||
idx = iwl_pcie_get_cmd_index(txq, idx);
|
||||
|
||||
return txq->tfds + trans_pcie->tfd_size * idx;
|
||||
@ -955,7 +959,7 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans *trans)
|
||||
MSIX_HW_INT_CAUSES_REG_RF_KILL);
|
||||
}
|
||||
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_9000) {
|
||||
if (trans->trans_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
|
||||
@ -1045,7 +1049,7 @@ static inline void __iwl_trans_pcie_set_bit(struct iwl_trans *trans,
|
||||
|
||||
static inline bool iwl_pcie_dbg_on(struct iwl_trans *trans)
|
||||
{
|
||||
return (trans->dbg.dest_tlv || trans->dbg.ini_valid);
|
||||
return (trans->dbg.dest_tlv || iwl_trans_dbg_ini_valid(trans));
|
||||
}
|
||||
|
||||
void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state);
|
||||
@ -1058,9 +1062,6 @@ void iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans);
|
||||
static inline void iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans) { }
|
||||
#endif
|
||||
|
||||
int iwl_pci_fw_exit_d0i3(struct iwl_trans *trans);
|
||||
int iwl_pci_fw_enter_d0i3(struct iwl_trans *trans);
|
||||
|
||||
void iwl_pcie_rx_allocator_work(struct work_struct *data);
|
||||
|
||||
/* common functions that are used by gen2 transport */
|
||||
@ -1113,10 +1114,11 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb,
|
||||
struct iwl_device_cmd *dev_cmd, int txq_id);
|
||||
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,
|
||||
bool low_power);
|
||||
void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power);
|
||||
void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans);
|
||||
void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans);
|
||||
void iwl_pcie_gen2_txq_unmap(struct iwl_trans *trans, int txq_id);
|
||||
void iwl_pcie_gen2_tx_free(struct iwl_trans *trans);
|
||||
void iwl_pcie_gen2_tx_stop(struct iwl_trans *trans);
|
||||
void iwl_pcie_d3_complete_suspend(struct iwl_trans *trans,
|
||||
bool test, bool reset);
|
||||
#endif /* __iwl_trans_int_pcie_h__ */
|
||||
|
@ -200,12 +200,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->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
|
||||
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
|
||||
/* TODO: remove this for 22560 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,
|
||||
RXF_DMA_IDLE, RXF_DMA_IDLE, 1000);
|
||||
} else if (trans->cfg->mq_rx_supported) {
|
||||
} else if (trans->trans_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);
|
||||
@ -232,7 +232,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->cfg->base_params->shadow_reg_enable &&
|
||||
if (!trans->trans_cfg->base_params->shadow_reg_enable &&
|
||||
test_bit(STATUS_TPOWER_PMI, &trans->status)) {
|
||||
reg = iwl_read32(trans, CSR_UCODE_DRV_GP1);
|
||||
|
||||
@ -240,18 +240,18 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans,
|
||||
IWL_DEBUG_INFO(trans, "Rx queue requesting wakeup, GP1 = 0x%x\n",
|
||||
reg);
|
||||
iwl_set_bit(trans, CSR_GP_CNTRL,
|
||||
BIT(trans->cfg->csr->flag_mac_access_req));
|
||||
BIT(trans->trans_cfg->csr->flag_mac_access_req));
|
||||
rxq->need_update = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
rxq->write_actual = round_down(rxq->write, 8);
|
||||
if (trans->cfg->device_family == IWL_DEVICE_FAMILY_22560)
|
||||
if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22560)
|
||||
iwl_write32(trans, HBUS_TARG_WRPTR,
|
||||
(rxq->write_actual |
|
||||
((FIRST_RX_QUEUE + rxq->id) << 16)));
|
||||
else if (trans->cfg->mq_rx_supported)
|
||||
else if (trans->trans_cfg->mq_rx_supported)
|
||||
iwl_write32(trans, RFH_Q_FRBDCB_WIDX_TRG(rxq->id),
|
||||
rxq->write_actual);
|
||||
else
|
||||
@ -279,7 +279,7 @@ static void iwl_pcie_restock_bd(struct iwl_trans *trans,
|
||||
struct iwl_rxq *rxq,
|
||||
struct iwl_rx_mem_buffer *rxb)
|
||||
{
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
|
||||
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
|
||||
struct iwl_rx_transfer_desc *bd = rxq->bd;
|
||||
|
||||
BUILD_BUG_ON(sizeof(*bd) != 2 * sizeof(u64));
|
||||
@ -405,7 +405,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->cfg->mq_rx_supported)
|
||||
if (trans->trans_cfg->mq_rx_supported)
|
||||
iwl_pcie_rxmq_restock(trans, rxq);
|
||||
else
|
||||
iwl_pcie_rxsq_restock(trans, rxq);
|
||||
@ -682,7 +682,7 @@ static int iwl_pcie_free_bd_size(struct iwl_trans *trans, bool use_rx_td)
|
||||
if (use_rx_td)
|
||||
return sizeof(*rx_td);
|
||||
else
|
||||
return trans->cfg->mq_rx_supported ? sizeof(__le64) :
|
||||
return trans->trans_cfg->mq_rx_supported ? sizeof(__le64) :
|
||||
sizeof(__le32);
|
||||
}
|
||||
|
||||
@ -690,7 +690,7 @@ static void iwl_pcie_free_rxq_dma(struct iwl_trans *trans,
|
||||
struct iwl_rxq *rxq)
|
||||
{
|
||||
struct device *dev = trans->dev;
|
||||
bool use_rx_td = (trans->cfg->device_family >=
|
||||
bool use_rx_td = (trans->trans_cfg->device_family >=
|
||||
IWL_DEVICE_FAMILY_22560);
|
||||
int free_size = iwl_pcie_free_bd_size(trans, use_rx_td);
|
||||
|
||||
@ -712,7 +712,7 @@ static void iwl_pcie_free_rxq_dma(struct iwl_trans *trans,
|
||||
rxq->used_bd_dma = 0;
|
||||
rxq->used_bd = NULL;
|
||||
|
||||
if (trans->cfg->device_family < IWL_DEVICE_FAMILY_22560)
|
||||
if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_22560)
|
||||
return;
|
||||
|
||||
if (rxq->tr_tail)
|
||||
@ -735,13 +735,13 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans,
|
||||
struct device *dev = trans->dev;
|
||||
int i;
|
||||
int free_size;
|
||||
bool use_rx_td = (trans->cfg->device_family >=
|
||||
bool use_rx_td = (trans->trans_cfg->device_family >=
|
||||
IWL_DEVICE_FAMILY_22560);
|
||||
size_t rb_stts_size = use_rx_td ? sizeof(__le16) :
|
||||
sizeof(struct iwl_rb_status);
|
||||
|
||||
spin_lock_init(&rxq->lock);
|
||||
if (trans->cfg->mq_rx_supported)
|
||||
if (trans->trans_cfg->mq_rx_supported)
|
||||
rxq->queue_size = MQ_RX_TABLE_SIZE;
|
||||
else
|
||||
rxq->queue_size = RX_QUEUE_SIZE;
|
||||
@ -757,7 +757,7 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans,
|
||||
if (!rxq->bd)
|
||||
goto err;
|
||||
|
||||
if (trans->cfg->mq_rx_supported) {
|
||||
if (trans->trans_cfg->mq_rx_supported) {
|
||||
rxq->used_bd = dma_alloc_coherent(dev,
|
||||
(use_rx_td ? sizeof(*rxq->cd) : sizeof(__le32)) * rxq->queue_size,
|
||||
&rxq->used_bd_dma,
|
||||
@ -807,7 +807,7 @@ int iwl_pcie_rx_alloc(struct iwl_trans *trans)
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
struct iwl_rb_allocator *rba = &trans_pcie->rba;
|
||||
int i, ret;
|
||||
size_t rb_stts_size = trans->cfg->device_family >=
|
||||
size_t rb_stts_size = trans->trans_cfg->device_family >=
|
||||
IWL_DEVICE_FAMILY_22560 ?
|
||||
sizeof(__le16) : sizeof(struct iwl_rb_status);
|
||||
|
||||
@ -1074,8 +1074,8 @@ int _iwl_pcie_rx_init(struct iwl_trans *trans)
|
||||
rxq->read = 0;
|
||||
rxq->write = 0;
|
||||
rxq->write_actual = 0;
|
||||
memset(rxq->rb_stts, 0,
|
||||
(trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) ?
|
||||
memset(rxq->rb_stts, 0, (trans->trans_cfg->device_family >=
|
||||
IWL_DEVICE_FAMILY_22560) ?
|
||||
sizeof(__le16) : sizeof(struct iwl_rb_status));
|
||||
|
||||
iwl_pcie_rx_init_rxb_lists(rxq);
|
||||
@ -1088,7 +1088,7 @@ int _iwl_pcie_rx_init(struct iwl_trans *trans)
|
||||
}
|
||||
|
||||
/* move the pool to the default queue and allocator ownerships */
|
||||
queue_size = trans->cfg->mq_rx_supported ?
|
||||
queue_size = trans->trans_cfg->mq_rx_supported ?
|
||||
MQ_RX_NUM_RBDS : RX_QUEUE_SIZE;
|
||||
allocator_pool_size = trans->num_rx_queues *
|
||||
(RX_CLAIM_REQ_ALLOC - RX_POST_REQ_ALLOC);
|
||||
@ -1120,7 +1120,7 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (trans->cfg->mq_rx_supported)
|
||||
if (trans->trans_cfg->mq_rx_supported)
|
||||
iwl_pcie_rx_mq_hw_init(trans);
|
||||
else
|
||||
iwl_pcie_rx_hw_init(trans, trans_pcie->rxq);
|
||||
@ -1151,7 +1151,7 @@ void iwl_pcie_rx_free(struct iwl_trans *trans)
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
struct iwl_rb_allocator *rba = &trans_pcie->rba;
|
||||
int i;
|
||||
size_t rb_stts_size = trans->cfg->device_family >=
|
||||
size_t rb_stts_size = trans->trans_cfg->device_family >=
|
||||
IWL_DEVICE_FAMILY_22560 ?
|
||||
sizeof(__le16) : sizeof(struct iwl_rb_status);
|
||||
|
||||
@ -1347,7 +1347,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
|
||||
}
|
||||
|
||||
page_stolen |= rxcb._page_stolen;
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
|
||||
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560)
|
||||
break;
|
||||
offset += ALIGN(len, FH_RSCSR_FRAME_ALIGN);
|
||||
}
|
||||
@ -1392,14 +1392,14 @@ static struct iwl_rx_mem_buffer *iwl_pcie_get_rxb(struct iwl_trans *trans,
|
||||
|
||||
BUILD_BUG_ON(sizeof(struct iwl_rx_completion_desc) != 32);
|
||||
|
||||
if (!trans->cfg->mq_rx_supported) {
|
||||
if (!trans->trans_cfg->mq_rx_supported) {
|
||||
rxb = rxq->queue[i];
|
||||
rxq->queue[i] = NULL;
|
||||
return rxb;
|
||||
}
|
||||
|
||||
/* used_bd is a 32/16 bit but only 12 are used to retrieve the vid */
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
|
||||
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560)
|
||||
vid = le16_to_cpu(rxq->cd[i].rbid) & 0x0FFF;
|
||||
else
|
||||
vid = le32_to_cpu(rxq->bd_32[i]) & 0x0FFF;
|
||||
@ -1515,7 +1515,7 @@ static void iwl_pcie_rx_handle(struct iwl_trans *trans, int queue)
|
||||
/* Backtrack one entry */
|
||||
rxq->read = i;
|
||||
/* update cr tail with the rxq read pointer */
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
|
||||
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560)
|
||||
*rxq->cr_tail = cpu_to_le16(r);
|
||||
spin_unlock(&rxq->lock);
|
||||
|
||||
@ -1597,7 +1597,7 @@ static void iwl_pcie_irq_handle_error(struct iwl_trans *trans)
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) {
|
||||
for (i = 0; i < trans->trans_cfg->base_params->num_of_queues; i++) {
|
||||
if (!trans_pcie->txq[i])
|
||||
continue;
|
||||
del_timer(&trans_pcie->txq[i]->stuck_timer);
|
||||
@ -1838,7 +1838,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->cfg->gen2) {
|
||||
if (trans->trans_cfg->gen2) {
|
||||
/*
|
||||
* We can restock, since firmware configured
|
||||
* the RFH
|
||||
@ -2179,13 +2179,13 @@ 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->cfg->gen2) {
|
||||
if (trans->trans_cfg->gen2) {
|
||||
/* We can restock, since firmware configured the RFH */
|
||||
iwl_pcie_rxmq_restock(trans, trans_pcie->rxq);
|
||||
}
|
||||
}
|
||||
|
||||
if (trans->cfg->device_family == IWL_DEVICE_FAMILY_22560 &&
|
||||
if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22560 &&
|
||||
inta_hw & MSIX_HW_INT_CAUSES_REG_IPC) {
|
||||
/* Reflect IML transfer status */
|
||||
int res = iwl_read32(trans, CSR_IML_RESP_ADDR);
|
||||
@ -2196,6 +2196,16 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
|
||||
iwl_pcie_irq_handle_error(trans);
|
||||
}
|
||||
} else if (inta_hw & MSIX_HW_INT_CAUSES_REG_WAKEUP) {
|
||||
u32 sleep_notif =
|
||||
le32_to_cpu(trans_pcie->prph_info->sleep_notif);
|
||||
if (sleep_notif == IWL_D3_SLEEP_STATUS_SUSPEND ||
|
||||
sleep_notif == IWL_D3_SLEEP_STATUS_RESUME) {
|
||||
IWL_DEBUG_ISR(trans,
|
||||
"Sx interrupt: sleep notification = 0x%x\n",
|
||||
sleep_notif);
|
||||
trans_pcie->sx_complete = true;
|
||||
wake_up(&trans_pcie->sx_waitq);
|
||||
} else {
|
||||
/* uCode wakes up after power-down sleep */
|
||||
IWL_DEBUG_ISR(trans, "Wakeup interrupt\n");
|
||||
iwl_pcie_rxq_check_wrptr(trans);
|
||||
@ -2203,6 +2213,7 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
|
||||
|
||||
isr_stats->wakeup++;
|
||||
}
|
||||
}
|
||||
|
||||
if (inta_hw & MSIX_HW_INT_CAUSES_REG_IML) {
|
||||
/* Reflect IML transfer status */
|
||||
|
@ -92,7 +92,7 @@ int iwl_pcie_gen2_apm_init(struct iwl_trans *trans)
|
||||
|
||||
iwl_pcie_apm_config(trans);
|
||||
|
||||
ret = iwl_finish_nic_init(trans);
|
||||
ret = iwl_finish_nic_init(trans, trans->trans_cfg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -133,10 +133,10 @@ static void iwl_pcie_gen2_apm_stop(struct iwl_trans *trans, bool op_mode_leave)
|
||||
* D0A* (powered-up Active) --> D0U* (Uninitialized) state.
|
||||
*/
|
||||
iwl_clear_bit(trans, CSR_GP_CNTRL,
|
||||
BIT(trans->cfg->csr->flag_init_done));
|
||||
BIT(trans->trans_cfg->csr->flag_init_done));
|
||||
}
|
||||
|
||||
void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power)
|
||||
void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
@ -147,9 +147,6 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power)
|
||||
|
||||
trans_pcie->is_down = true;
|
||||
|
||||
/* Stop dbgc before stopping device */
|
||||
iwl_fw_dbg_stop_recording(trans, NULL);
|
||||
|
||||
/* tell the device to stop sending interrupts */
|
||||
iwl_disable_interrupts(trans);
|
||||
|
||||
@ -171,14 +168,14 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power)
|
||||
}
|
||||
|
||||
iwl_pcie_ctxt_info_free_paging(trans);
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
|
||||
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560)
|
||||
iwl_pcie_ctxt_info_gen3_free(trans);
|
||||
else
|
||||
iwl_pcie_ctxt_info_free(trans);
|
||||
|
||||
/* Make sure (redundant) we've released our request to stay awake */
|
||||
iwl_clear_bit(trans, CSR_GP_CNTRL,
|
||||
BIT(trans->cfg->csr->flag_mac_access_req));
|
||||
BIT(trans->trans_cfg->csr->flag_mac_access_req));
|
||||
|
||||
/* Stop the device, and put it in low power state */
|
||||
iwl_pcie_gen2_apm_stop(trans, false);
|
||||
@ -218,7 +215,7 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power)
|
||||
iwl_pcie_prepare_card_hw(trans);
|
||||
}
|
||||
|
||||
void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power)
|
||||
void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
bool was_in_rfkill;
|
||||
@ -226,7 +223,7 @@ void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power)
|
||||
mutex_lock(&trans_pcie->mutex);
|
||||
trans_pcie->opmode_down = true;
|
||||
was_in_rfkill = test_bit(STATUS_RFKILL_OPMODE, &trans->status);
|
||||
_iwl_trans_pcie_gen2_stop_device(trans, low_power);
|
||||
_iwl_trans_pcie_gen2_stop_device(trans);
|
||||
iwl_trans_pcie_handle_stop_rfkill(trans, was_in_rfkill);
|
||||
mutex_unlock(&trans_pcie->mutex);
|
||||
}
|
||||
@ -343,7 +340,7 @@ int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
|
||||
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560)
|
||||
ret = iwl_pcie_ctxt_info_gen3_init(trans, fw);
|
||||
else
|
||||
ret = iwl_pcie_ctxt_info_init(trans, fw);
|
||||
|
@ -69,7 +69,6 @@
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
@ -185,8 +184,8 @@ void iwl_trans_pcie_dump_regs(struct iwl_trans *trans)
|
||||
static void iwl_trans_pcie_sw_reset(struct iwl_trans *trans)
|
||||
{
|
||||
/* Reset entire device - do controller reset (results in SHRD_HW_RST) */
|
||||
iwl_set_bit(trans, trans->cfg->csr->addr_sw_reset,
|
||||
BIT(trans->cfg->csr->flag_sw_reset));
|
||||
iwl_set_bit(trans, trans->trans_cfg->csr->addr_sw_reset,
|
||||
BIT(trans->trans_cfg->csr->flag_sw_reset));
|
||||
usleep_range(5000, 6000);
|
||||
}
|
||||
|
||||
@ -216,8 +215,7 @@ static void iwl_pcie_alloc_fw_monitor_block(struct iwl_trans *trans,
|
||||
for (power = max_power; power >= min_power; power--) {
|
||||
size = BIT(power);
|
||||
cpu_addr = dma_alloc_coherent(trans->dev, size, &phys,
|
||||
GFP_KERNEL | __GFP_NOWARN |
|
||||
__GFP_ZERO | __GFP_COMP);
|
||||
GFP_KERNEL | __GFP_NOWARN);
|
||||
if (!cpu_addr)
|
||||
continue;
|
||||
|
||||
@ -343,7 +341,7 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans)
|
||||
*/
|
||||
|
||||
/* Disable L0S exit timer (platform NMI Work/Around) */
|
||||
if (trans->cfg->device_family < IWL_DEVICE_FAMILY_8000)
|
||||
if (trans->trans_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);
|
||||
|
||||
@ -367,10 +365,10 @@ 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->cfg->base_params->pll_cfg)
|
||||
if (trans->trans_cfg->base_params->pll_cfg)
|
||||
iwl_set_bit(trans, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
|
||||
|
||||
ret = iwl_finish_nic_init(trans);
|
||||
ret = iwl_finish_nic_init(trans, trans->trans_cfg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -442,7 +440,7 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans)
|
||||
|
||||
iwl_trans_pcie_sw_reset(trans);
|
||||
|
||||
ret = iwl_finish_nic_init(trans);
|
||||
ret = iwl_finish_nic_init(trans, trans->trans_cfg);
|
||||
if (WARN_ON(ret)) {
|
||||
/* Release XTAL ON request */
|
||||
__iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
|
||||
@ -492,7 +490,7 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans)
|
||||
* D0A* (powered-up Active) --> D0U* (Uninitialized) state.
|
||||
*/
|
||||
iwl_clear_bit(trans, CSR_GP_CNTRL,
|
||||
BIT(trans->cfg->csr->flag_init_done));
|
||||
BIT(trans->trans_cfg->csr->flag_init_done));
|
||||
|
||||
/* Activates XTAL resources monitor */
|
||||
__iwl_trans_pcie_set_bit(trans, CSR_MONITOR_CFG_REG,
|
||||
@ -514,12 +512,12 @@ void iwl_pcie_apm_stop_master(struct iwl_trans *trans)
|
||||
int ret;
|
||||
|
||||
/* stop device's busmaster DMA activity */
|
||||
iwl_set_bit(trans, trans->cfg->csr->addr_sw_reset,
|
||||
BIT(trans->cfg->csr->flag_stop_master));
|
||||
iwl_set_bit(trans, trans->trans_cfg->csr->addr_sw_reset,
|
||||
BIT(trans->trans_cfg->csr->flag_stop_master));
|
||||
|
||||
ret = iwl_poll_bit(trans, trans->cfg->csr->addr_sw_reset,
|
||||
BIT(trans->cfg->csr->flag_master_dis),
|
||||
BIT(trans->cfg->csr->flag_master_dis), 100);
|
||||
ret = iwl_poll_bit(trans, trans->trans_cfg->csr->addr_sw_reset,
|
||||
BIT(trans->trans_cfg->csr->flag_master_dis),
|
||||
BIT(trans->trans_cfg->csr->flag_master_dis), 100);
|
||||
if (ret < 0)
|
||||
IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n");
|
||||
|
||||
@ -535,10 +533,11 @@ 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->cfg->device_family == IWL_DEVICE_FAMILY_7000)
|
||||
if (trans->trans_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->cfg->device_family >= IWL_DEVICE_FAMILY_8000) {
|
||||
else if (trans->trans_cfg->device_family >=
|
||||
IWL_DEVICE_FAMILY_8000) {
|
||||
iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
|
||||
CSR_RESET_LINK_PWR_MGMT_DISABLED);
|
||||
iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
|
||||
@ -568,7 +567,7 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans, bool op_mode_leave)
|
||||
* D0A* (powered-up Active) --> D0U* (Uninitialized) state.
|
||||
*/
|
||||
iwl_clear_bit(trans, CSR_GP_CNTRL,
|
||||
BIT(trans->cfg->csr->flag_init_done));
|
||||
BIT(trans->trans_cfg->csr->flag_init_done));
|
||||
}
|
||||
|
||||
static int iwl_pcie_nic_init(struct iwl_trans *trans)
|
||||
@ -595,7 +594,7 @@ static int iwl_pcie_nic_init(struct iwl_trans *trans)
|
||||
if (iwl_pcie_tx_init(trans))
|
||||
return -ENOMEM;
|
||||
|
||||
if (trans->cfg->base_params->shadow_reg_enable) {
|
||||
if (trans->trans_cfg->base_params->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");
|
||||
@ -833,7 +832,7 @@ static int iwl_pcie_load_cpu_sections_8000(struct iwl_trans *trans,
|
||||
|
||||
iwl_enable_interrupts(trans);
|
||||
|
||||
if (trans->cfg->use_tfh) {
|
||||
if (trans->trans_cfg->use_tfh) {
|
||||
if (cpu == 1)
|
||||
iwl_write_prph(trans, UREG_UCODE_LOAD_STATUS,
|
||||
0xFFFF);
|
||||
@ -898,12 +897,12 @@ void iwl_pcie_apply_destination(struct iwl_trans *trans)
|
||||
const struct iwl_fw_dbg_dest_tlv_v1 *dest = trans->dbg.dest_tlv;
|
||||
int i;
|
||||
|
||||
if (trans->dbg.ini_valid) {
|
||||
if (iwl_trans_dbg_ini_valid(trans)) {
|
||||
if (!trans->dbg.num_blocks)
|
||||
return;
|
||||
|
||||
IWL_DEBUG_FW(trans,
|
||||
"WRT: applying DRAM buffer[0] destination\n");
|
||||
"WRT: Applying DRAM buffer[0] destination\n");
|
||||
iwl_write_umac_prph(trans, MON_BUFF_BASE_ADDR_VER2,
|
||||
trans->dbg.fw_mon[0].physical >>
|
||||
MON_BUFF_SHIFT_VER2);
|
||||
@ -965,7 +964,7 @@ void iwl_pcie_apply_destination(struct iwl_trans *trans)
|
||||
iwl_write_prph(trans, le32_to_cpu(dest->base_reg),
|
||||
trans->dbg.fw_mon[0].physical >>
|
||||
dest->base_shift);
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000)
|
||||
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000)
|
||||
iwl_write_prph(trans, le32_to_cpu(dest->end_reg),
|
||||
(trans->dbg.fw_mon[0].physical +
|
||||
trans->dbg.fw_mon[0].size - 256) >>
|
||||
@ -1007,7 +1006,7 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
|
||||
|
||||
/* supported for 7000 only for the moment */
|
||||
if (iwlwifi_mod_params.fw_monitor &&
|
||||
trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
|
||||
trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000) {
|
||||
iwl_pcie_alloc_fw_monitor(trans, 0);
|
||||
|
||||
if (trans->dbg.fw_mon[0].size) {
|
||||
@ -1136,7 +1135,7 @@ static void iwl_pcie_map_non_rx_causes(struct iwl_trans *trans)
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
int val = trans_pcie->def_irq | MSIX_NON_AUTO_CLEAR_CAUSE;
|
||||
int i, arr_size =
|
||||
(trans->cfg->device_family != IWL_DEVICE_FAMILY_22560) ?
|
||||
(trans->trans_cfg->device_family != IWL_DEVICE_FAMILY_22560) ?
|
||||
ARRAY_SIZE(causes_list) : ARRAY_SIZE(causes_list_v2);
|
||||
|
||||
/*
|
||||
@ -1146,7 +1145,8 @@ static void iwl_pcie_map_non_rx_causes(struct iwl_trans *trans)
|
||||
*/
|
||||
for (i = 0; i < arr_size; i++) {
|
||||
struct iwl_causes_list *causes =
|
||||
(trans->cfg->device_family != IWL_DEVICE_FAMILY_22560) ?
|
||||
(trans->trans_cfg->device_family !=
|
||||
IWL_DEVICE_FAMILY_22560) ?
|
||||
causes_list : causes_list_v2;
|
||||
|
||||
iwl_write8(trans, CSR_MSIX_IVAR(causes[i].addr), val);
|
||||
@ -1190,7 +1190,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->cfg->mq_rx_supported &&
|
||||
if (trans->trans_cfg->mq_rx_supported &&
|
||||
test_bit(STATUS_DEVICE_ENABLED, &trans->status))
|
||||
iwl_write_umac_prph(trans, UREG_CHICK,
|
||||
UREG_CHICK_MSI_ENABLE);
|
||||
@ -1231,7 +1231,7 @@ static void iwl_pcie_init_msix(struct iwl_trans_pcie *trans_pcie)
|
||||
trans_pcie->hw_mask = trans_pcie->hw_init_mask;
|
||||
}
|
||||
|
||||
static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
|
||||
static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
@ -1242,9 +1242,6 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
|
||||
|
||||
trans_pcie->is_down = true;
|
||||
|
||||
/* Stop dbgc before stopping device */
|
||||
iwl_fw_dbg_stop_recording(trans, NULL);
|
||||
|
||||
/* tell the device to stop sending interrupts */
|
||||
iwl_disable_interrupts(trans);
|
||||
|
||||
@ -1274,7 +1271,7 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
|
||||
|
||||
/* Make sure (redundant) we've released our request to stay awake */
|
||||
iwl_clear_bit(trans, CSR_GP_CNTRL,
|
||||
BIT(trans->cfg->csr->flag_mac_access_req));
|
||||
BIT(trans->trans_cfg->csr->flag_mac_access_req));
|
||||
|
||||
/* Stop the device, and put it in low power state */
|
||||
iwl_pcie_apm_stop(trans, false);
|
||||
@ -1401,7 +1398,7 @@ static 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->cfg->device_family >= IWL_DEVICE_FAMILY_8000)
|
||||
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000)
|
||||
ret = iwl_pcie_load_given_ucode_8000(trans, fw);
|
||||
else
|
||||
ret = iwl_pcie_load_given_ucode(trans, fw);
|
||||
@ -1451,7 +1448,7 @@ void iwl_trans_pcie_handle_stop_rfkill(struct iwl_trans *trans,
|
||||
iwl_trans_pcie_rf_kill(trans, hw_rfkill);
|
||||
}
|
||||
|
||||
static void iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
|
||||
static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
bool was_in_rfkill;
|
||||
@ -1459,7 +1456,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
|
||||
mutex_lock(&trans_pcie->mutex);
|
||||
trans_pcie->opmode_down = true;
|
||||
was_in_rfkill = test_bit(STATUS_RFKILL_OPMODE, &trans->status);
|
||||
_iwl_trans_pcie_stop_device(trans, low_power);
|
||||
_iwl_trans_pcie_stop_device(trans);
|
||||
iwl_trans_pcie_handle_stop_rfkill(trans, was_in_rfkill);
|
||||
mutex_unlock(&trans_pcie->mutex);
|
||||
}
|
||||
@ -1474,22 +1471,16 @@ void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state)
|
||||
IWL_WARN(trans, "reporting RF_KILL (radio %s)\n",
|
||||
state ? "disabled" : "enabled");
|
||||
if (iwl_op_mode_hw_rf_kill(trans->op_mode, state)) {
|
||||
if (trans->cfg->gen2)
|
||||
_iwl_trans_pcie_gen2_stop_device(trans, true);
|
||||
if (trans->trans_cfg->gen2)
|
||||
_iwl_trans_pcie_gen2_stop_device(trans);
|
||||
else
|
||||
_iwl_trans_pcie_stop_device(trans, true);
|
||||
_iwl_trans_pcie_stop_device(trans);
|
||||
}
|
||||
}
|
||||
|
||||
static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test,
|
||||
bool reset)
|
||||
void iwl_pcie_d3_complete_suspend(struct iwl_trans *trans,
|
||||
bool test, bool reset)
|
||||
{
|
||||
if (!reset) {
|
||||
/* Enable persistence mode to avoid reset */
|
||||
iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
|
||||
CSR_HW_IF_CONFIG_REG_PERSIST_MODE);
|
||||
}
|
||||
|
||||
iwl_disable_interrupts(trans);
|
||||
|
||||
/*
|
||||
@ -1504,9 +1495,9 @@ static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test,
|
||||
iwl_pcie_synchronize_irqs(trans);
|
||||
|
||||
iwl_clear_bit(trans, CSR_GP_CNTRL,
|
||||
BIT(trans->cfg->csr->flag_mac_access_req));
|
||||
BIT(trans->trans_cfg->csr->flag_mac_access_req));
|
||||
iwl_clear_bit(trans, CSR_GP_CNTRL,
|
||||
BIT(trans->cfg->csr->flag_init_done));
|
||||
BIT(trans->trans_cfg->csr->flag_init_done));
|
||||
|
||||
if (reset) {
|
||||
/*
|
||||
@ -1520,6 +1511,42 @@ static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test,
|
||||
iwl_pcie_set_pwr(trans, true);
|
||||
}
|
||||
|
||||
static int iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test,
|
||||
bool reset)
|
||||
{
|
||||
int ret;
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
/*
|
||||
* Family IWL_DEVICE_FAMILY_AX210 and above persist mode is set by FW.
|
||||
*/
|
||||
if (!reset && trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) {
|
||||
/* Enable persistence mode to avoid reset */
|
||||
iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
|
||||
CSR_HW_IF_CONFIG_REG_PERSIST_MODE);
|
||||
}
|
||||
|
||||
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
|
||||
iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6,
|
||||
UREG_DOORBELL_TO_ISR6_SUSPEND);
|
||||
|
||||
ret = wait_event_timeout(trans_pcie->sx_waitq,
|
||||
trans_pcie->sx_complete, 2 * HZ);
|
||||
/*
|
||||
* Invalidate it toward resume.
|
||||
*/
|
||||
trans_pcie->sx_complete = false;
|
||||
|
||||
if (!ret) {
|
||||
IWL_ERR(trans, "Timeout entering D3\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
iwl_pcie_d3_complete_suspend(trans, test, reset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
|
||||
enum iwl_d3_status *status,
|
||||
bool test, bool reset)
|
||||
@ -1531,13 +1558,13 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
|
||||
if (test) {
|
||||
iwl_enable_interrupts(trans);
|
||||
*status = IWL_D3_STATUS_ALIVE;
|
||||
return 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
iwl_set_bit(trans, CSR_GP_CNTRL,
|
||||
BIT(trans->cfg->csr->flag_mac_access_req));
|
||||
BIT(trans->trans_cfg->csr->flag_mac_access_req));
|
||||
|
||||
ret = iwl_finish_nic_init(trans);
|
||||
ret = iwl_finish_nic_init(trans, trans->trans_cfg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -1557,7 +1584,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
|
||||
|
||||
if (!reset) {
|
||||
iwl_clear_bit(trans, CSR_GP_CNTRL,
|
||||
BIT(trans->cfg->csr->flag_mac_access_req));
|
||||
BIT(trans->trans_cfg->csr->flag_mac_access_req));
|
||||
} else {
|
||||
iwl_trans_pcie_tx_reset(trans);
|
||||
|
||||
@ -1578,17 +1605,38 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
|
||||
else
|
||||
*status = IWL_D3_STATUS_ALIVE;
|
||||
|
||||
out:
|
||||
if (*status == IWL_D3_STATUS_ALIVE &&
|
||||
trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
|
||||
trans_pcie->sx_complete = false;
|
||||
iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6,
|
||||
UREG_DOORBELL_TO_ISR6_RESUME);
|
||||
|
||||
ret = wait_event_timeout(trans_pcie->sx_waitq,
|
||||
trans_pcie->sx_complete, 2 * HZ);
|
||||
/*
|
||||
* Invalidate it toward next suspend.
|
||||
*/
|
||||
trans_pcie->sx_complete = false;
|
||||
|
||||
if (!ret) {
|
||||
IWL_ERR(trans, "Timeout exiting D3\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void iwl_pcie_set_interrupt_capa(struct pci_dev *pdev,
|
||||
struct iwl_trans *trans)
|
||||
static void
|
||||
iwl_pcie_set_interrupt_capa(struct pci_dev *pdev,
|
||||
struct iwl_trans *trans,
|
||||
const struct iwl_cfg_trans_params *cfg_trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
int max_irqs, num_irqs, i, ret;
|
||||
u16 pci_cmd;
|
||||
|
||||
if (!trans->cfg->mq_rx_supported)
|
||||
if (!cfg_trans->mq_rx_supported)
|
||||
goto enable_msi;
|
||||
|
||||
max_irqs = min_t(u32, num_online_cpus() + 2, IWL_MAX_RX_HW_QUEUES);
|
||||
@ -1709,7 +1757,7 @@ static int iwl_trans_pcie_clear_persistence_bit(struct iwl_trans *trans)
|
||||
{
|
||||
u32 hpm, wprot;
|
||||
|
||||
switch (trans->cfg->device_family) {
|
||||
switch (trans->trans_cfg->device_family) {
|
||||
case IWL_DEVICE_FAMILY_9000:
|
||||
wprot = PREG_PRPH_WPROT_9000;
|
||||
break;
|
||||
@ -1736,7 +1784,7 @@ static int iwl_trans_pcie_clear_persistence_bit(struct iwl_trans *trans)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
|
||||
static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
int err;
|
||||
@ -1772,20 +1820,16 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
|
||||
/* ...rfkill can call stop_device and set it false if needed */
|
||||
iwl_pcie_check_hw_rf_kill(trans);
|
||||
|
||||
/* Make sure we sync here, because we'll need full access later */
|
||||
if (low_power)
|
||||
pm_runtime_resume(trans->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
|
||||
static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
int ret;
|
||||
|
||||
mutex_lock(&trans_pcie->mutex);
|
||||
ret = _iwl_trans_pcie_start_hw(trans, low_power);
|
||||
ret = _iwl_trans_pcie_start_hw(trans);
|
||||
mutex_unlock(&trans_pcie->mutex);
|
||||
|
||||
return ret;
|
||||
@ -1828,7 +1872,7 @@ static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs)
|
||||
|
||||
static u32 iwl_trans_pcie_prph_msk(struct iwl_trans *trans)
|
||||
{
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
|
||||
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560)
|
||||
return 0x00FFFFFF;
|
||||
else
|
||||
return 0x000FFFFF;
|
||||
@ -1899,7 +1943,7 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
|
||||
|
||||
iwl_pcie_synchronize_irqs(trans);
|
||||
|
||||
if (trans->cfg->gen2)
|
||||
if (trans->trans_cfg->gen2)
|
||||
iwl_pcie_gen2_tx_free(trans);
|
||||
else
|
||||
iwl_pcie_tx_free(trans);
|
||||
@ -1981,8 +2025,8 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,
|
||||
|
||||
/* this bit wakes up the NIC */
|
||||
__iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
|
||||
BIT(trans->cfg->csr->flag_mac_access_req));
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000)
|
||||
BIT(trans->trans_cfg->csr->flag_mac_access_req));
|
||||
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000)
|
||||
udelay(2);
|
||||
|
||||
/*
|
||||
@ -2006,8 +2050,8 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,
|
||||
* and do not save/restore SRAM when power cycling.
|
||||
*/
|
||||
ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
|
||||
BIT(trans->cfg->csr->flag_val_mac_access_en),
|
||||
(BIT(trans->cfg->csr->flag_mac_clock_ready) |
|
||||
BIT(trans->trans_cfg->csr->flag_val_mac_access_en),
|
||||
(BIT(trans->trans_cfg->csr->flag_mac_clock_ready) |
|
||||
CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
|
||||
if (unlikely(ret < 0)) {
|
||||
u32 cntrl = iwl_read32(trans, CSR_GP_CNTRL);
|
||||
@ -2089,7 +2133,7 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans,
|
||||
goto out;
|
||||
|
||||
__iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
|
||||
BIT(trans->cfg->csr->flag_mac_access_req));
|
||||
BIT(trans->trans_cfg->csr->flag_mac_access_req));
|
||||
/*
|
||||
* Above we read the CSR_GP_CNTRL register, which will flush
|
||||
* any previous writes, but we need the write that clears the
|
||||
@ -2196,7 +2240,7 @@ 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->cfg->base_params->num_of_queues; i++) {
|
||||
for (i = 0; i < trans->trans_cfg->base_params->num_of_queues; i++) {
|
||||
struct iwl_txq *txq = trans_pcie->txq[i];
|
||||
|
||||
if (i == trans_pcie->cmd_queue)
|
||||
@ -2227,7 +2271,7 @@ void iwl_trans_pcie_log_scd_error(struct iwl_trans *trans, struct iwl_txq *txq)
|
||||
bool active;
|
||||
u8 fifo;
|
||||
|
||||
if (trans->cfg->use_tfh) {
|
||||
if (trans->trans_cfg->use_tfh) {
|
||||
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 */
|
||||
@ -2244,9 +2288,9 @@ void iwl_trans_pcie_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->cfg->base_params->max_tfd_queue_size - 1),
|
||||
(trans->trans_cfg->base_params->max_tfd_queue_size - 1),
|
||||
iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id)) &
|
||||
(trans->cfg->base_params->max_tfd_queue_size - 1),
|
||||
(trans->trans_cfg->base_params->max_tfd_queue_size - 1),
|
||||
iwl_read_direct32(trans, FH_TX_TRB_REG(fifo)));
|
||||
}
|
||||
|
||||
@ -2335,7 +2379,9 @@ static int iwl_trans_pcie_wait_txqs_empty(struct iwl_trans *trans, u32 txq_bm)
|
||||
int ret = 0;
|
||||
|
||||
/* waiting for all the tx frames complete might take a while */
|
||||
for (cnt = 0; cnt < trans->cfg->base_params->num_of_queues; cnt++) {
|
||||
for (cnt = 0;
|
||||
cnt < trans->trans_cfg->base_params->num_of_queues;
|
||||
cnt++) {
|
||||
|
||||
if (cnt == trans_pcie->cmd_queue)
|
||||
continue;
|
||||
@ -2363,37 +2409,6 @@ static void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg,
|
||||
spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
|
||||
}
|
||||
|
||||
static void iwl_trans_pcie_ref(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
if (iwlwifi_mod_params.d0i3_disable)
|
||||
return;
|
||||
|
||||
pm_runtime_get(&trans_pcie->pci_dev->dev);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
IWL_DEBUG_RPM(trans, "runtime usage count: %d\n",
|
||||
atomic_read(&trans_pcie->pci_dev->dev.power.usage_count));
|
||||
#endif /* CONFIG_PM */
|
||||
}
|
||||
|
||||
static void iwl_trans_pcie_unref(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
if (iwlwifi_mod_params.d0i3_disable)
|
||||
return;
|
||||
|
||||
pm_runtime_mark_last_busy(&trans_pcie->pci_dev->dev);
|
||||
pm_runtime_put_autosuspend(&trans_pcie->pci_dev->dev);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
IWL_DEBUG_RPM(trans, "runtime usage count: %d\n",
|
||||
atomic_read(&trans_pcie->pci_dev->dev.power.usage_count));
|
||||
#endif /* CONFIG_PM */
|
||||
}
|
||||
|
||||
static const char *get_csr_string(int cmd)
|
||||
{
|
||||
#define IWL_CMD(x) case x: return #x
|
||||
@ -2510,7 +2525,8 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
|
||||
int ret;
|
||||
size_t bufsz;
|
||||
|
||||
bufsz = sizeof(char) * 75 * trans->cfg->base_params->num_of_queues;
|
||||
bufsz = sizeof(char) * 75 *
|
||||
trans->trans_cfg->base_params->num_of_queues;
|
||||
|
||||
if (!trans_pcie->txq_memory)
|
||||
return -EAGAIN;
|
||||
@ -2519,7 +2535,9 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
for (cnt = 0; cnt < trans->cfg->base_params->num_of_queues; cnt++) {
|
||||
for (cnt = 0;
|
||||
cnt < trans->trans_cfg->base_params->num_of_queues;
|
||||
cnt++) {
|
||||
txq = trans_pcie->txq[cnt];
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"hwq %.2d: read=%u write=%u use=%d stop=%d need_update=%d frozen=%d%s\n",
|
||||
@ -2989,7 +3007,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->cfg->gen2)
|
||||
if (!trans->trans_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));
|
||||
@ -3037,7 +3055,7 @@ iwl_trans_pcie_dump_pointers(struct iwl_trans *trans,
|
||||
{
|
||||
u32 base, base_high, write_ptr, write_ptr_val, wrap_cnt;
|
||||
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
|
||||
if (trans->trans_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;
|
||||
@ -3057,7 +3075,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->cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
|
||||
if (trans->trans_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;
|
||||
@ -3074,8 +3092,8 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans,
|
||||
|
||||
if (trans->dbg.dest_tlv ||
|
||||
(trans->dbg.num_blocks &&
|
||||
(trans->cfg->device_family == IWL_DEVICE_FAMILY_7000 ||
|
||||
trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210))) {
|
||||
(trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000 ||
|
||||
trans->trans_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);
|
||||
@ -3158,7 +3176,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->cfg->device_family >=
|
||||
if (trans->trans_cfg->device_family >=
|
||||
IWL_DEVICE_FAMILY_8000 ||
|
||||
trans->dbg.dest_tlv->monitor_mode == MARBH_MODE)
|
||||
end += (1 << trans->dbg.dest_tlv->end_shift);
|
||||
@ -3184,7 +3202,7 @@ static struct iwl_trans_dump_data
|
||||
u32 len, num_rbs = 0, monitor_len = 0;
|
||||
int i, ptr;
|
||||
bool dump_rbs = test_bit(STATUS_FW_ERROR, &trans->status) &&
|
||||
!trans->cfg->mq_rx_supported &&
|
||||
!trans->trans_cfg->mq_rx_supported &&
|
||||
dump_mask & BIT(IWL_FW_ERROR_DUMP_RB);
|
||||
|
||||
if (!dump_mask)
|
||||
@ -3209,7 +3227,7 @@ static struct iwl_trans_dump_data
|
||||
|
||||
/* FH registers */
|
||||
if (dump_mask & BIT(IWL_FW_ERROR_DUMP_FH_REGS)) {
|
||||
if (trans->cfg->gen2)
|
||||
if (trans->trans_cfg->gen2)
|
||||
len += sizeof(*data) +
|
||||
(iwl_umac_prph(trans, FH_MEM_UPPER_BOUND_GEN2) -
|
||||
iwl_umac_prph(trans, FH_MEM_LOWER_BOUND_GEN2));
|
||||
@ -3233,7 +3251,7 @@ static struct iwl_trans_dump_data
|
||||
}
|
||||
|
||||
/* Paged memory for gen2 HW */
|
||||
if (trans->cfg->gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING))
|
||||
if (trans->trans_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) +
|
||||
@ -3288,7 +3306,8 @@ static struct iwl_trans_dump_data
|
||||
len += iwl_trans_pcie_dump_rbs(trans, &data, num_rbs);
|
||||
|
||||
/* Paged memory for gen2 HW */
|
||||
if (trans->cfg->gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING)) {
|
||||
if (trans->trans_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;
|
||||
u32 page_len = trans->init_dram.paging[i].size;
|
||||
@ -3315,18 +3334,11 @@ static struct iwl_trans_dump_data
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int iwl_trans_pcie_suspend(struct iwl_trans *trans)
|
||||
{
|
||||
if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3 &&
|
||||
(trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3))
|
||||
return iwl_pci_fw_enter_d0i3(trans);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void iwl_trans_pcie_resume(struct iwl_trans *trans)
|
||||
{
|
||||
if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3 &&
|
||||
(trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3))
|
||||
iwl_pci_fw_exit_d0i3(trans);
|
||||
}
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
@ -3345,8 +3357,6 @@ static void iwl_trans_pcie_resume(struct iwl_trans *trans)
|
||||
.grab_nic_access = iwl_trans_pcie_grab_nic_access, \
|
||||
.release_nic_access = iwl_trans_pcie_release_nic_access, \
|
||||
.set_bits_mask = iwl_trans_pcie_set_bits_mask, \
|
||||
.ref = iwl_trans_pcie_ref, \
|
||||
.unref = iwl_trans_pcie_unref, \
|
||||
.dump_data = iwl_trans_pcie_dump_data, \
|
||||
.d3_suspend = iwl_trans_pcie_d3_suspend, \
|
||||
.d3_resume = iwl_trans_pcie_d3_resume, \
|
||||
@ -3400,6 +3410,8 @@ static const struct iwl_trans_ops trans_ops_pcie_gen2 = {
|
||||
.tx = iwl_trans_pcie_gen2_tx,
|
||||
.reclaim = iwl_trans_pcie_reclaim,
|
||||
|
||||
.set_q_ptrs = iwl_trans_pcie_set_q_ptrs,
|
||||
|
||||
.txq_alloc = iwl_trans_pcie_dyn_txq_alloc,
|
||||
.txq_free = iwl_trans_pcie_dyn_txq_free,
|
||||
.wait_txq_empty = iwl_trans_pcie_wait_txq_empty,
|
||||
@ -3411,7 +3423,7 @@ static const struct iwl_trans_ops trans_ops_pcie_gen2 = {
|
||||
|
||||
struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent,
|
||||
const struct iwl_cfg *cfg)
|
||||
const struct iwl_cfg_trans_params *cfg_trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie;
|
||||
struct iwl_trans *trans;
|
||||
@ -3421,12 +3433,13 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
if (cfg->gen2)
|
||||
if (cfg_trans->gen2)
|
||||
trans = iwl_trans_alloc(sizeof(struct iwl_trans_pcie),
|
||||
&pdev->dev, cfg, &trans_ops_pcie_gen2);
|
||||
&pdev->dev, &trans_ops_pcie_gen2);
|
||||
else
|
||||
trans = iwl_trans_alloc(sizeof(struct iwl_trans_pcie),
|
||||
&pdev->dev, cfg, &trans_ops_pcie);
|
||||
&pdev->dev, &trans_ops_pcie);
|
||||
|
||||
if (!trans)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@ -3445,7 +3458,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
|
||||
}
|
||||
trans_pcie->debug_rfkill = -1;
|
||||
|
||||
if (!cfg->base_params->pcie_l1_allowed) {
|
||||
if (!cfg_trans->base_params->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
|
||||
@ -3458,7 +3471,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
|
||||
|
||||
trans_pcie->def_rx_queue = 0;
|
||||
|
||||
if (cfg->use_tfh) {
|
||||
if (cfg_trans->use_tfh) {
|
||||
addr_size = 64;
|
||||
trans_pcie->max_tbs = IWL_TFH_NUM_TBS;
|
||||
trans_pcie->tfd_size = sizeof(struct iwl_tfh_tfd);
|
||||
@ -3520,9 +3533,7 @@ 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 (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000) {
|
||||
unsigned long flags;
|
||||
|
||||
if (cfg_trans->device_family >= IWL_DEVICE_FAMILY_8000) {
|
||||
trans->hw_rev = (trans->hw_rev & 0xfff0) |
|
||||
(CSR_HW_REV_STEP(trans->hw_rev << 2) << 2);
|
||||
|
||||
@ -3536,94 +3547,15 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
|
||||
* in-order to recognize C step driver should read chip version
|
||||
* id located at the AUX bus MISC address space.
|
||||
*/
|
||||
ret = iwl_finish_nic_init(trans);
|
||||
ret = iwl_finish_nic_init(trans, cfg_trans);
|
||||
if (ret)
|
||||
goto out_no_pci;
|
||||
|
||||
if (iwl_trans_grab_nic_access(trans, &flags)) {
|
||||
u32 hw_step;
|
||||
|
||||
hw_step = iwl_read_umac_prph_no_grab(trans,
|
||||
WFPM_CTRL_REG);
|
||||
hw_step |= ENABLE_WFPM;
|
||||
iwl_write_umac_prph_no_grab(trans, WFPM_CTRL_REG,
|
||||
hw_step);
|
||||
hw_step = iwl_read_prph_no_grab(trans,
|
||||
CNVI_AUX_MISC_CHIP);
|
||||
hw_step = (hw_step >> HW_STEP_LOCATION_BITS) & 0xF;
|
||||
if (hw_step == 0x3)
|
||||
trans->hw_rev = (trans->hw_rev & 0xFFFFFFF3) |
|
||||
(SILICON_C_STEP << 2);
|
||||
iwl_trans_release_nic_access(trans, &flags);
|
||||
}
|
||||
}
|
||||
|
||||
IWL_DEBUG_INFO(trans, "HW REV: 0x%0x\n", trans->hw_rev);
|
||||
|
||||
#if IS_ENABLED(CONFIG_IWLMVM)
|
||||
trans->hw_rf_id = iwl_read32(trans, CSR_HW_RF_ID);
|
||||
|
||||
if (cfg == &iwlax210_2ax_cfg_so_hr_a0) {
|
||||
if (trans->hw_rev == CSR_HW_REV_TYPE_TY) {
|
||||
trans->cfg = &iwlax210_2ax_cfg_ty_gf_a0;
|
||||
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) {
|
||||
trans->cfg = &iwlax210_2ax_cfg_so_jf_a0;
|
||||
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF)) {
|
||||
trans->cfg = &iwlax211_2ax_cfg_so_gf_a0;
|
||||
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF4)) {
|
||||
trans->cfg = &iwlax411_2ax_cfg_so_gf4_a0;
|
||||
}
|
||||
} else if (cfg == &iwl_ax101_cfg_qu_hr) {
|
||||
if ((CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
|
||||
trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0) ||
|
||||
(CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR1))) {
|
||||
trans->cfg = &iwl22000_2ax_cfg_qnj_hr_b0;
|
||||
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) {
|
||||
trans->cfg = &iwl_ax101_cfg_qu_hr;
|
||||
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) {
|
||||
trans->cfg = &iwl22000_2ax_cfg_jf;
|
||||
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HRCDB)) {
|
||||
IWL_ERR(trans, "RF ID HRCDB is not supported\n");
|
||||
ret = -EINVAL;
|
||||
goto out_no_pci;
|
||||
} else {
|
||||
IWL_ERR(trans, "Unrecognized RF ID 0x%08x\n",
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id));
|
||||
ret = -EINVAL;
|
||||
goto out_no_pci;
|
||||
}
|
||||
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
|
||||
trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0) {
|
||||
u32 hw_status;
|
||||
|
||||
hw_status = iwl_read_prph(trans, UMAG_GEN_HW_STATUS);
|
||||
if (CSR_HW_RF_STEP(trans->hw_rf_id) == SILICON_B_STEP)
|
||||
/*
|
||||
* b step fw is the same for physical card and fpga
|
||||
*/
|
||||
trans->cfg = &iwl22000_2ax_cfg_qnj_hr_b0;
|
||||
else if ((hw_status & UMAG_GEN_HW_IS_FPGA) &&
|
||||
CSR_HW_RF_STEP(trans->hw_rf_id) == SILICON_A_STEP) {
|
||||
trans->cfg = &iwl22000_2ax_cfg_qnj_hr_a0_f0;
|
||||
} else {
|
||||
/*
|
||||
* a step no FPGA
|
||||
*/
|
||||
trans->cfg = &iwl22000_2ac_cfg_hr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
iwl_pcie_set_interrupt_capa(pdev, trans);
|
||||
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);
|
||||
@ -3631,7 +3563,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
|
||||
/* Initialize the wait queue for commands */
|
||||
init_waitqueue_head(&trans_pcie->wait_command_queue);
|
||||
|
||||
init_waitqueue_head(&trans_pcie->d0i3_waitq);
|
||||
init_waitqueue_head(&trans_pcie->sx_waitq);
|
||||
|
||||
if (trans_pcie->msix_enabled) {
|
||||
ret = iwl_pcie_init_msix_handler(pdev, trans_pcie);
|
||||
@ -3657,12 +3589,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
|
||||
WQ_HIGHPRI | WQ_UNBOUND, 1);
|
||||
INIT_WORK(&trans_pcie->rba.rx_alloc, iwl_pcie_rx_allocator_work);
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_PCIE_RTPM
|
||||
trans->runtime_pm_mode = IWL_PLAT_PM_MODE_D0I3;
|
||||
#else
|
||||
trans->runtime_pm_mode = IWL_PLAT_PM_MODE_DISABLED;
|
||||
#endif /* CONFIG_IWLWIFI_PCIE_RTPM */
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
trans_pcie->fw_mon_data.state = IWL_FW_MON_DBGFS_STATE_CLOSED;
|
||||
mutex_init(&trans_pcie->fw_mon_data.mutex);
|
||||
|
@ -50,7 +50,6 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <net/tso.h>
|
||||
#include <linux/tcp.h>
|
||||
|
||||
@ -114,7 +113,7 @@ void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans_pcie *trans_pcie,
|
||||
*/
|
||||
num_fetch_chunks = DIV_ROUND_UP(filled_tfd_size, 64) - 1;
|
||||
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
|
||||
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
|
||||
/* Starting from 22560, the HW expects bytes */
|
||||
WARN_ON(trans_pcie->bc_table_dword);
|
||||
WARN_ON(len > 0x3FFF);
|
||||
@ -548,7 +547,7 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct iwl_trans *trans,
|
||||
|
||||
memset(tfd, 0, sizeof(*tfd));
|
||||
|
||||
if (trans->cfg->device_family < IWL_DEVICE_FAMILY_22560)
|
||||
if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_22560)
|
||||
len = sizeof(struct iwl_tx_cmd_gen2);
|
||||
else
|
||||
len = sizeof(struct iwl_tx_cmd_gen3);
|
||||
@ -630,7 +629,7 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
|
||||
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
|
||||
struct iwl_tx_cmd_gen3 *tx_cmd_gen3 =
|
||||
(void *)dev_cmd->payload;
|
||||
|
||||
@ -647,12 +646,8 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb,
|
||||
iwl_pcie_gen2_get_num_tbs(trans, tfd));
|
||||
|
||||
/* start timer if queue currently empty */
|
||||
if (txq->read_ptr == txq->write_ptr) {
|
||||
if (txq->wd_timeout)
|
||||
if (txq->read_ptr == txq->write_ptr && txq->wd_timeout)
|
||||
mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);
|
||||
IWL_DEBUG_RPM(trans, "Q: %d first tx - take ref\n", txq->id);
|
||||
iwl_trans_ref(trans);
|
||||
}
|
||||
|
||||
/* Tell device the write index *just past* this latest filled TFD */
|
||||
txq->write_ptr = iwl_queue_inc_wrap(trans, txq->write_ptr);
|
||||
@ -897,12 +892,6 @@ static int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans,
|
||||
mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);
|
||||
|
||||
spin_lock_irqsave(&trans_pcie->reg_lock, flags);
|
||||
if (!(cmd->flags & CMD_SEND_IN_IDLE) &&
|
||||
!trans_pcie->ref_cmd_in_flight) {
|
||||
trans_pcie->ref_cmd_in_flight = true;
|
||||
IWL_DEBUG_RPM(trans, "set ref_cmd_in_flight - ref\n");
|
||||
iwl_trans_ref(trans);
|
||||
}
|
||||
/* Increment and update queue's write index */
|
||||
txq->write_ptr = iwl_queue_inc_wrap(trans, txq->write_ptr);
|
||||
iwl_pcie_gen2_txq_inc_wr_ptr(trans, txq);
|
||||
@ -936,16 +925,6 @@ static int iwl_pcie_gen2_send_hcmd_sync(struct iwl_trans *trans,
|
||||
|
||||
IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", cmd_str);
|
||||
|
||||
if (pm_runtime_suspended(&trans_pcie->pci_dev->dev)) {
|
||||
ret = wait_event_timeout(trans_pcie->d0i3_waitq,
|
||||
pm_runtime_active(&trans_pcie->pci_dev->dev),
|
||||
msecs_to_jiffies(IWL_TRANS_IDLE_TIMEOUT));
|
||||
if (!ret) {
|
||||
IWL_ERR(trans, "Timeout exiting D0i3 before hcmd\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
cmd_idx = iwl_pcie_gen2_enqueue_hcmd(trans, cmd);
|
||||
if (cmd_idx < 0) {
|
||||
ret = cmd_idx;
|
||||
@ -1070,23 +1049,6 @@ void iwl_pcie_gen2_txq_unmap(struct iwl_trans *trans, int txq_id)
|
||||
}
|
||||
iwl_pcie_gen2_free_tfd(trans, txq);
|
||||
txq->read_ptr = iwl_queue_inc_wrap(trans, txq->read_ptr);
|
||||
|
||||
if (txq->read_ptr == txq->write_ptr) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&trans_pcie->reg_lock, flags);
|
||||
if (txq_id != trans_pcie->cmd_queue) {
|
||||
IWL_DEBUG_RPM(trans, "Q %d - last tx freed\n",
|
||||
txq->id);
|
||||
iwl_trans_unref(trans);
|
||||
} else if (trans_pcie->ref_cmd_in_flight) {
|
||||
trans_pcie->ref_cmd_in_flight = false;
|
||||
IWL_DEBUG_RPM(trans,
|
||||
"clear ref_cmd_in_flight\n");
|
||||
iwl_trans_unref(trans);
|
||||
}
|
||||
spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
while (!skb_queue_empty(&txq->overflow_q)) {
|
||||
@ -1167,7 +1129,7 @@ int iwl_trans_pcie_dyn_txq_alloc_dma(struct iwl_trans *trans,
|
||||
if (!txq)
|
||||
return -ENOMEM;
|
||||
ret = iwl_pcie_alloc_dma_ptr(trans, &txq->bc_tbl,
|
||||
(trans->cfg->device_family >=
|
||||
(trans->trans_cfg->device_family >=
|
||||
IWL_DEVICE_FAMILY_22560) ?
|
||||
sizeof(struct iwl_gen3_bc_tbl) :
|
||||
sizeof(struct iwlagn_scd_bc_tbl));
|
||||
@ -1231,7 +1193,7 @@ int iwl_trans_pcie_txq_alloc_response(struct iwl_trans *trans,
|
||||
|
||||
txq->id = qid;
|
||||
trans_pcie->txq[qid] = txq;
|
||||
wr_ptr &= (trans->cfg->base_params->max_tfd_queue_size - 1);
|
||||
wr_ptr &= (trans->trans_cfg->base_params->max_tfd_queue_size - 1);
|
||||
|
||||
/* Place first TFD at index corresponding to start sequence number */
|
||||
txq->read_ptr = wr_ptr;
|
||||
|
@ -65,7 +65,6 @@
|
||||
#include <linux/ieee80211.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <net/ip6_checksum.h>
|
||||
#include <net/tso.h>
|
||||
|
||||
@ -114,17 +113,17 @@ int iwl_queue_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->cfg->base_params->max_tfd_queue_size)
|
||||
if (q->n_window < trans->trans_cfg->base_params->max_tfd_queue_size)
|
||||
max = q->n_window;
|
||||
else
|
||||
max = trans->cfg->base_params->max_tfd_queue_size - 1;
|
||||
max = trans->trans_cfg->base_params->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->cfg->base_params->max_tfd_queue_size - 1);
|
||||
(trans->trans_cfg->base_params->max_tfd_queue_size - 1);
|
||||
|
||||
if (WARN_ON(used > max))
|
||||
return 0;
|
||||
@ -293,7 +292,7 @@ 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->cfg->base_params->shadow_reg_enable &&
|
||||
if (!trans->trans_cfg->base_params->shadow_reg_enable &&
|
||||
txq_id != trans_pcie->cmd_queue &&
|
||||
test_bit(STATUS_TPOWER_PMI, &trans->status)) {
|
||||
/*
|
||||
@ -307,7 +306,7 @@ static void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans,
|
||||
IWL_DEBUG_INFO(trans, "Tx queue %d requesting wakeup, GP1 = 0x%x\n",
|
||||
txq_id, reg);
|
||||
iwl_set_bit(trans, CSR_GP_CNTRL,
|
||||
BIT(trans->cfg->csr->flag_mac_access_req));
|
||||
BIT(trans->trans_cfg->csr->flag_mac_access_req));
|
||||
txq->need_update = true;
|
||||
return;
|
||||
}
|
||||
@ -328,7 +327,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->cfg->base_params->num_of_queues; i++) {
|
||||
for (i = 0; i < trans->trans_cfg->base_params->num_of_queues; i++) {
|
||||
struct iwl_txq *txq = trans_pcie->txq[i];
|
||||
|
||||
if (!test_bit(i, trans_pcie->queue_used))
|
||||
@ -347,7 +346,7 @@ static inline dma_addr_t iwl_pcie_tfd_tb_get_addr(struct iwl_trans *trans,
|
||||
void *_tfd, u8 idx)
|
||||
{
|
||||
|
||||
if (trans->cfg->use_tfh) {
|
||||
if (trans->trans_cfg->use_tfh) {
|
||||
struct iwl_tfh_tfd *tfd = _tfd;
|
||||
struct iwl_tfh_tb *tb = &tfd->tbs[idx];
|
||||
|
||||
@ -390,7 +389,7 @@ static inline void iwl_pcie_tfd_set_tb(struct iwl_trans *trans, void *tfd,
|
||||
|
||||
static inline u8 iwl_pcie_tfd_get_num_tbs(struct iwl_trans *trans, void *_tfd)
|
||||
{
|
||||
if (trans->cfg->use_tfh) {
|
||||
if (trans->trans_cfg->use_tfh) {
|
||||
struct iwl_tfh_tfd *tfd = _tfd;
|
||||
|
||||
return le16_to_cpu(tfd->num_tbs) & 0x1f;
|
||||
@ -437,7 +436,7 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans,
|
||||
|
||||
meta->tbs = 0;
|
||||
|
||||
if (trans->cfg->use_tfh) {
|
||||
if (trans->trans_cfg->use_tfh) {
|
||||
struct iwl_tfh_tfd *tfd_fh = (void *)tfd;
|
||||
|
||||
tfd_fh->num_tbs = 0;
|
||||
@ -525,14 +524,14 @@ int iwl_pcie_txq_alloc(struct iwl_trans *trans, struct iwl_txq *txq,
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
size_t tfd_sz = trans_pcie->tfd_size *
|
||||
trans->cfg->base_params->max_tfd_queue_size;
|
||||
trans->trans_cfg->base_params->max_tfd_queue_size;
|
||||
size_t tb0_buf_sz;
|
||||
int i;
|
||||
|
||||
if (WARN_ON(txq->entries || txq->tfds))
|
||||
return -EINVAL;
|
||||
|
||||
if (trans->cfg->use_tfh)
|
||||
if (trans->trans_cfg->use_tfh)
|
||||
tfd_sz = trans_pcie->tfd_size * slots_num;
|
||||
|
||||
timer_setup(&txq->stuck_timer, iwl_pcie_txq_stuck_timer, 0);
|
||||
@ -591,7 +590,8 @@ int iwl_pcie_txq_init(struct iwl_trans *trans, struct iwl_txq *txq,
|
||||
int slots_num, bool cmd_queue)
|
||||
{
|
||||
int ret;
|
||||
u32 tfd_queue_max_size = trans->cfg->base_params->max_tfd_queue_size;
|
||||
u32 tfd_queue_max_size =
|
||||
trans->trans_cfg->base_params->max_tfd_queue_size;
|
||||
|
||||
txq->need_update = false;
|
||||
|
||||
@ -639,20 +639,14 @@ static void iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans)
|
||||
|
||||
lockdep_assert_held(&trans_pcie->reg_lock);
|
||||
|
||||
if (trans_pcie->ref_cmd_in_flight) {
|
||||
trans_pcie->ref_cmd_in_flight = false;
|
||||
IWL_DEBUG_RPM(trans, "clear ref_cmd_in_flight - unref\n");
|
||||
iwl_trans_unref(trans);
|
||||
}
|
||||
|
||||
if (!trans->cfg->base_params->apmg_wake_up_wa)
|
||||
if (!trans->trans_cfg->base_params->apmg_wake_up_wa)
|
||||
return;
|
||||
if (WARN_ON(!trans_pcie->cmd_hold_nic_awake))
|
||||
return;
|
||||
|
||||
trans_pcie->cmd_hold_nic_awake = false;
|
||||
__iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
|
||||
BIT(trans->cfg->csr->flag_mac_access_req));
|
||||
BIT(trans->trans_cfg->csr->flag_mac_access_req));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -683,13 +677,8 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id)
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&trans_pcie->reg_lock, flags);
|
||||
if (txq_id != trans_pcie->cmd_queue) {
|
||||
IWL_DEBUG_RPM(trans, "Q %d - last tx freed\n",
|
||||
txq->id);
|
||||
iwl_trans_unref(trans);
|
||||
} else {
|
||||
if (txq_id == trans_pcie->cmd_queue)
|
||||
iwl_pcie_clear_cmd_in_flight(trans);
|
||||
}
|
||||
spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
|
||||
}
|
||||
}
|
||||
@ -737,7 +726,7 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
|
||||
if (txq->tfds) {
|
||||
dma_free_coherent(dev,
|
||||
trans_pcie->tfd_size *
|
||||
trans->cfg->base_params->max_tfd_queue_size,
|
||||
trans->trans_cfg->base_params->max_tfd_queue_size,
|
||||
txq->tfds, txq->dma_addr);
|
||||
txq->dma_addr = 0;
|
||||
txq->tfds = NULL;
|
||||
@ -759,7 +748,7 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
|
||||
void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
int nq = trans->cfg->base_params->num_of_queues;
|
||||
int nq = trans->trans_cfg->base_params->num_of_queues;
|
||||
int chan;
|
||||
u32 reg_val;
|
||||
int clear_dwords = (SCD_TRANS_TBL_OFFSET_QUEUE(nq) -
|
||||
@ -786,7 +775,7 @@ 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->cfg->base_params->scd_chain_ext_wa)
|
||||
if (trans->trans_cfg->base_params->scd_chain_ext_wa)
|
||||
iwl_write_prph(trans, SCD_CHAINEXT_EN, 0);
|
||||
|
||||
iwl_trans_ac_txq_enable(trans, trans_pcie->cmd_queue,
|
||||
@ -808,7 +797,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->cfg->device_family < IWL_DEVICE_FAMILY_8000)
|
||||
if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000)
|
||||
iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG,
|
||||
APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
|
||||
}
|
||||
@ -822,13 +811,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->cfg->gen2))
|
||||
if (WARN_ON_ONCE(trans->trans_cfg->gen2))
|
||||
return;
|
||||
|
||||
for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues;
|
||||
for (txq_id = 0; txq_id < trans->trans_cfg->base_params->num_of_queues;
|
||||
txq_id++) {
|
||||
struct iwl_txq *txq = trans_pcie->txq[txq_id];
|
||||
if (trans->cfg->use_tfh)
|
||||
if (trans->trans_cfg->use_tfh)
|
||||
iwl_write_direct64(trans,
|
||||
FH_MEM_CBBC_QUEUE(trans, txq_id),
|
||||
txq->dma_addr);
|
||||
@ -911,7 +900,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->cfg->base_params->num_of_queues;
|
||||
for (txq_id = 0; txq_id < trans->trans_cfg->base_params->num_of_queues;
|
||||
txq_id++)
|
||||
iwl_pcie_txq_unmap(trans, txq_id);
|
||||
|
||||
@ -933,7 +922,7 @@ void iwl_pcie_tx_free(struct iwl_trans *trans)
|
||||
/* Tx queues */
|
||||
if (trans_pcie->txq_memory) {
|
||||
for (txq_id = 0;
|
||||
txq_id < trans->cfg->base_params->num_of_queues;
|
||||
txq_id < trans->trans_cfg->base_params->num_of_queues;
|
||||
txq_id++) {
|
||||
iwl_pcie_txq_free(trans, txq_id);
|
||||
trans_pcie->txq[txq_id] = NULL;
|
||||
@ -957,9 +946,10 @@ 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->cfg->base_params->num_of_queues;
|
||||
u16 bc_tbls_size = trans->trans_cfg->base_params->num_of_queues;
|
||||
|
||||
bc_tbls_size *= (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) ?
|
||||
bc_tbls_size *= (trans->trans_cfg->device_family >=
|
||||
IWL_DEVICE_FAMILY_22560) ?
|
||||
sizeof(struct iwl_gen3_bc_tbl) :
|
||||
sizeof(struct iwlagn_scd_bc_tbl);
|
||||
|
||||
@ -984,7 +974,8 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans)
|
||||
goto error;
|
||||
}
|
||||
|
||||
trans_pcie->txq_memory = kcalloc(trans->cfg->base_params->num_of_queues,
|
||||
trans_pcie->txq_memory =
|
||||
kcalloc(trans->trans_cfg->base_params->num_of_queues,
|
||||
sizeof(struct iwl_txq), GFP_KERNEL);
|
||||
if (!trans_pcie->txq_memory) {
|
||||
IWL_ERR(trans, "Not enough memory for txq\n");
|
||||
@ -993,7 +984,7 @@ 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->cfg->base_params->num_of_queues;
|
||||
for (txq_id = 0; txq_id < trans->trans_cfg->base_params->num_of_queues;
|
||||
txq_id++) {
|
||||
bool cmd_queue = (txq_id == trans_pcie->cmd_queue);
|
||||
|
||||
@ -1047,7 +1038,7 @@ int iwl_pcie_tx_init(struct iwl_trans *trans)
|
||||
spin_unlock(&trans_pcie->irq_lock);
|
||||
|
||||
/* Alloc and init all Tx queues, including the command queue (#4/#9) */
|
||||
for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues;
|
||||
for (txq_id = 0; txq_id < trans->trans_cfg->base_params->num_of_queues;
|
||||
txq_id++) {
|
||||
bool cmd_queue = (txq_id == trans_pcie->cmd_queue);
|
||||
|
||||
@ -1075,7 +1066,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->cfg->base_params->num_of_queues > 20)
|
||||
if (trans->trans_cfg->base_params->num_of_queues > 20)
|
||||
iwl_set_bits_prph(trans, SCD_GP_CTRL,
|
||||
SCD_GP_CTRL_ENABLE_31_QUEUES);
|
||||
|
||||
@ -1147,7 +1138,7 @@ void iwl_trans_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->cfg->base_params->max_tfd_queue_size,
|
||||
trans->trans_cfg->base_params->max_tfd_queue_size,
|
||||
txq->write_ptr, txq->read_ptr);
|
||||
goto out;
|
||||
}
|
||||
@ -1170,7 +1161,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
|
||||
|
||||
txq->entries[read_ptr].skb = NULL;
|
||||
|
||||
if (!trans->cfg->use_tfh)
|
||||
if (!trans->trans_cfg->use_tfh)
|
||||
iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq);
|
||||
|
||||
iwl_pcie_txq_free_tfd(trans, txq);
|
||||
@ -1225,20 +1216,28 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
|
||||
txq->overflow_tx = false;
|
||||
}
|
||||
|
||||
if (txq->read_ptr == txq->write_ptr) {
|
||||
IWL_DEBUG_RPM(trans, "Q %d - last tx reclaimed\n", txq->id);
|
||||
iwl_trans_unref(trans);
|
||||
}
|
||||
|
||||
out:
|
||||
spin_unlock_bh(&txq->lock);
|
||||
}
|
||||
|
||||
/* Set wr_ptr of specific device and txq */
|
||||
void iwl_trans_pcie_set_q_ptrs(struct iwl_trans *trans, int txq_id, int ptr)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
struct iwl_txq *txq = trans_pcie->txq[txq_id];
|
||||
|
||||
spin_lock_bh(&txq->lock);
|
||||
|
||||
txq->write_ptr = ptr;
|
||||
txq->read_ptr = txq->write_ptr;
|
||||
|
||||
spin_unlock_bh(&txq->lock);
|
||||
}
|
||||
|
||||
static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans,
|
||||
const struct iwl_host_cmd *cmd)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
const struct iwl_cfg *cfg = trans->cfg;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&trans_pcie->reg_lock);
|
||||
@ -1247,32 +1246,25 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans,
|
||||
if (test_bit(STATUS_TRANS_DEAD, &trans->status))
|
||||
return -ENODEV;
|
||||
|
||||
if (!(cmd->flags & CMD_SEND_IN_IDLE) &&
|
||||
!trans_pcie->ref_cmd_in_flight) {
|
||||
trans_pcie->ref_cmd_in_flight = true;
|
||||
IWL_DEBUG_RPM(trans, "set ref_cmd_in_flight - ref\n");
|
||||
iwl_trans_ref(trans);
|
||||
}
|
||||
|
||||
/*
|
||||
* wake up the NIC to make sure that the firmware will see the host
|
||||
* command - we will let the NIC sleep once all the host commands
|
||||
* returned. This needs to be done only on NICs that have
|
||||
* apmg_wake_up_wa set.
|
||||
*/
|
||||
if (cfg->base_params->apmg_wake_up_wa &&
|
||||
if (trans->trans_cfg->base_params->apmg_wake_up_wa &&
|
||||
!trans_pcie->cmd_hold_nic_awake) {
|
||||
__iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
|
||||
BIT(cfg->csr->flag_mac_access_req));
|
||||
BIT(trans->trans_cfg->csr->flag_mac_access_req));
|
||||
|
||||
ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
|
||||
BIT(cfg->csr->flag_val_mac_access_en),
|
||||
(BIT(cfg->csr->flag_mac_clock_ready) |
|
||||
BIT(trans->trans_cfg->csr->flag_val_mac_access_en),
|
||||
(BIT(trans->trans_cfg->csr->flag_mac_clock_ready) |
|
||||
CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP),
|
||||
15000);
|
||||
if (ret < 0) {
|
||||
__iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
|
||||
BIT(cfg->csr->flag_mac_access_req));
|
||||
BIT(trans->trans_cfg->csr->flag_mac_access_req));
|
||||
IWL_ERR(trans, "Failed to wake NIC for hcmd\n");
|
||||
return -EIO;
|
||||
}
|
||||
@ -1302,12 +1294,12 @@ void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
|
||||
idx = iwl_pcie_get_cmd_index(txq, idx);
|
||||
r = iwl_pcie_get_cmd_index(txq, txq->read_ptr);
|
||||
|
||||
if (idx >= trans->cfg->base_params->max_tfd_queue_size ||
|
||||
if (idx >= trans->trans_cfg->base_params->max_tfd_queue_size ||
|
||||
(!iwl_queue_used(txq, idx))) {
|
||||
WARN_ONCE(test_bit(txq_id, trans_pcie->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->cfg->base_params->max_tfd_queue_size,
|
||||
trans->trans_cfg->base_params->max_tfd_queue_size,
|
||||
txq->write_ptr, txq->read_ptr);
|
||||
return;
|
||||
}
|
||||
@ -1421,7 +1413,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->cfg->mq_rx_supported &&
|
||||
scd_bug = !trans->trans_cfg->mq_rx_supported &&
|
||||
!((ssn - txq->write_ptr) & 0x3f) &&
|
||||
(ssn != txq->write_ptr);
|
||||
if (scd_bug)
|
||||
@ -1867,20 +1859,6 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
|
||||
wake_up(&trans_pcie->wait_command_queue);
|
||||
}
|
||||
|
||||
if (meta->flags & CMD_MAKE_TRANS_IDLE) {
|
||||
IWL_DEBUG_INFO(trans, "complete %s - mark trans as idle\n",
|
||||
iwl_get_cmd_string(trans, cmd->hdr.cmd));
|
||||
set_bit(STATUS_TRANS_IDLE, &trans->status);
|
||||
wake_up(&trans_pcie->d0i3_waitq);
|
||||
}
|
||||
|
||||
if (meta->flags & CMD_WAKE_UP_TRANS) {
|
||||
IWL_DEBUG_INFO(trans, "complete %s - clear trans idle flag\n",
|
||||
iwl_get_cmd_string(trans, cmd->hdr.cmd));
|
||||
clear_bit(STATUS_TRANS_IDLE, &trans->status);
|
||||
wake_up(&trans_pcie->d0i3_waitq);
|
||||
}
|
||||
|
||||
meta->flags = 0;
|
||||
|
||||
spin_unlock_bh(&txq->lock);
|
||||
@ -1927,16 +1905,6 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
|
||||
IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n",
|
||||
iwl_get_cmd_string(trans, cmd->id));
|
||||
|
||||
if (pm_runtime_suspended(&trans_pcie->pci_dev->dev)) {
|
||||
ret = wait_event_timeout(trans_pcie->d0i3_waitq,
|
||||
pm_runtime_active(&trans_pcie->pci_dev->dev),
|
||||
msecs_to_jiffies(IWL_TRANS_IDLE_TIMEOUT));
|
||||
if (!ret) {
|
||||
IWL_ERR(trans, "Timeout exiting D0i3 before hcmd\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
cmd_idx = iwl_pcie_enqueue_hcmd(trans, cmd);
|
||||
if (cmd_idx < 0) {
|
||||
ret = cmd_idx;
|
||||
@ -2504,8 +2472,7 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
|
||||
wait_write_ptr = ieee80211_has_morefrags(fc);
|
||||
|
||||
/* start timer if queue currently empty */
|
||||
if (txq->read_ptr == txq->write_ptr) {
|
||||
if (txq->wd_timeout) {
|
||||
if (txq->read_ptr == txq->write_ptr && txq->wd_timeout) {
|
||||
/*
|
||||
* If the TXQ is active, then set the timer, if not,
|
||||
* set the timer in remainder so that the timer will
|
||||
@ -2518,9 +2485,6 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
|
||||
else
|
||||
txq->frozen_expiry_remainder = txq->wd_timeout;
|
||||
}
|
||||
IWL_DEBUG_RPM(trans, "Q: %d first tx - take ref\n", txq->id);
|
||||
iwl_trans_ref(trans);
|
||||
}
|
||||
|
||||
/* Tell device the write index *just past* this latest filled TFD */
|
||||
txq->write_ptr = iwl_queue_inc_wrap(trans, txq->write_ptr);
|
||||
|
Loading…
Reference in New Issue
Block a user