Third batch of iwlwifi patches intended for v4.21
* Some cleanups in the HW configuration structures; * More work on the debugging infrastructure; * Fixes related to 802.11ax; * Other cleanups and small fixes; -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEF3LNfgb2BPWm68smoUecoho8xfoFAlwTkTYACgkQoUecoho8 xfooKBAAmCUWzdK2YP3P4grxE6Oj5rBcnGgzeqmj0HVlIsdapyUAfCecBqzJyc/t 0K9+eiwT5bCXuae6cH8eN8VS2KmvTqqRbzFX5C2wuLCGBp1Kcu2kqJiLsw6fOhVh TPWnVtLZ+xZPzZ+/UsMpu2qlRn/rzYtRCXfcLbgvjRwe12M6geHaibSkEnXV40pU 6BLRT9TcsgmbcN9ySKYgJJsLZpJDiBbVuyRz0+PAr8GBh8sLdoDIt4tR6o88lIv0 ciCexVyNrJpc3VQolzxAi7fRrZTKURNbusoTjRM2KdEplHHvghcJARBuoXbUwvt3 CCWuQFba849eZYcGRKJq6U0Vhv1T8ww0uqk6LXyYJB0kRd/LVpogH8zQ6DmvhxKO xaQLm4j/ZtiE3ezM25O//fsoW/Q01jj61GBHO5uHCP0E+s04L0eiG1yPPtQ3aiVz epQTI6nLVdhaKPrSZCBfJ3eupNTPusEtgTa+e1D1dPKd2RadspkjAz4OZhKOmcq5 OftGmkljJli08lY0GwSk0g1QQ+EMk4+5+snXtOunbRvNbtWVyHR6TKZSri469ivW bz3g+HNvQ/wRoLSl74RZu+Nkjk7exUm6UpPOeZQOQ+Ldcy3MMODRmJgy+HvyJTyA QU3LJGmhbjjYZx8E+7afek8yZ2yzyejycxmI9dHkqyUXLvD58ZQ= =LwNg -----END PGP SIGNATURE----- Merge tag 'iwlwifi-next-for-kalle-2018-12-14' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next Third batch of iwlwifi patches intended for v4.21 * Some cleanups in the HW configuration structures; * More work on the debugging infrastructure; * Fixes related to 802.11ax; * Other cleanups and small fixes;
This commit is contained in:
commit
30ed3c6c09
@ -48,7 +48,7 @@
|
||||
static const struct iwl_base_params iwl1000_base_params = {
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.max_tfd_queue_size = 256,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
|
||||
.pll_cfg = true,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_1000,
|
||||
.shadow_ram_support = false,
|
||||
|
@ -57,7 +57,7 @@
|
||||
#define IWL135_MODULE_FIRMWARE(api) IWL135_FW_PRE __stringify(api) ".ucode"
|
||||
|
||||
static const struct iwl_base_params iwl2000_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.max_tfd_queue_size = 256,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_2x00,
|
||||
@ -71,7 +71,7 @@ static const struct iwl_base_params iwl2000_base_params = {
|
||||
|
||||
|
||||
static const struct iwl_base_params iwl2030_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.max_tfd_queue_size = 256,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_2x00,
|
||||
|
@ -63,7 +63,6 @@
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL_22000_NVM_VERSION 0x0a1d
|
||||
#define IWL_22000_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
|
||||
/* Memory offsets and lengths */
|
||||
#define IWL_22000_DCCM_OFFSET 0x800000 /* LMAC1 */
|
||||
@ -106,10 +105,8 @@
|
||||
#define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \
|
||||
IWL_QU_B_JF_B_FW_PRE __stringify(api) ".ucode"
|
||||
|
||||
#define NVM_HW_SECTION_NUM_FAMILY_22000 10
|
||||
|
||||
static const struct iwl_base_params iwl_22000_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_22000,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
|
||||
.num_of_queues = 512,
|
||||
.max_tfd_queue_size = 256,
|
||||
.shadow_ram_support = true,
|
||||
@ -121,7 +118,7 @@ static const struct iwl_base_params iwl_22000_base_params = {
|
||||
};
|
||||
|
||||
static const struct iwl_base_params iwl_22560_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_22000,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
|
||||
.num_of_queues = 512,
|
||||
.max_tfd_queue_size = 65536,
|
||||
.shadow_ram_support = true,
|
||||
@ -142,7 +139,7 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
|
||||
.ucode_api_max = IWL_22000_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL_22000_UCODE_API_MIN, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_22000, \
|
||||
.nvm_hw_section_num = 10, \
|
||||
.non_shared_ant = ANT_B, \
|
||||
.dccm_offset = IWL_22000_DCCM_OFFSET, \
|
||||
.dccm_len = IWL_22000_DCCM_LEN, \
|
||||
@ -157,7 +154,6 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
|
||||
.mac_addr_from_csr = true, \
|
||||
.ht_params = &iwl_22000_ht_params, \
|
||||
.nvm_ver = IWL_22000_NVM_VERSION, \
|
||||
.nvm_calib_ver = IWL_22000_TX_POWER_VERSION, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.use_tfh = true, \
|
||||
.rf_id = true, \
|
||||
|
@ -66,7 +66,7 @@
|
||||
#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE __stringify(api) ".ucode"
|
||||
|
||||
static const struct iwl_base_params iwl6000_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.max_tfd_queue_size = 256,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
|
||||
@ -79,7 +79,7 @@ static const struct iwl_base_params iwl6000_base_params = {
|
||||
};
|
||||
|
||||
static const struct iwl_base_params iwl6050_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.max_tfd_queue_size = 256,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
|
||||
@ -92,7 +92,7 @@ static const struct iwl_base_params iwl6050_base_params = {
|
||||
};
|
||||
|
||||
static const struct iwl_base_params iwl6000_g2_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.max_tfd_queue_size = 256,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
|
||||
|
@ -80,17 +80,11 @@
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL7260_NVM_VERSION 0x0a1d
|
||||
#define IWL7260_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
#define IWL3160_NVM_VERSION 0x709
|
||||
#define IWL3160_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
#define IWL3165_NVM_VERSION 0x709
|
||||
#define IWL3165_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
#define IWL3168_NVM_VERSION 0xd01
|
||||
#define IWL3168_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
#define IWL7265_NVM_VERSION 0x0a1d
|
||||
#define IWL7265_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
#define IWL7265D_NVM_VERSION 0x0c11
|
||||
#define IWL7265_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
|
||||
/* DCCM offsets and lengths */
|
||||
#define IWL7000_DCCM_OFFSET 0x800000
|
||||
@ -113,10 +107,8 @@
|
||||
#define IWL7265D_FW_PRE "iwlwifi-7265D-"
|
||||
#define IWL7265D_MODULE_FIRMWARE(api) IWL7265D_FW_PRE __stringify(api) ".ucode"
|
||||
|
||||
#define NVM_HW_SECTION_NUM_FAMILY_7000 0
|
||||
|
||||
static const struct iwl_base_params iwl7000_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_7000,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_16K,
|
||||
.num_of_queues = 31,
|
||||
.max_tfd_queue_size = 256,
|
||||
.shadow_ram_support = true,
|
||||
@ -159,7 +151,7 @@ static const struct iwl_ht_params iwl7000_ht_params = {
|
||||
.device_family = IWL_DEVICE_FAMILY_7000, \
|
||||
.base_params = &iwl7000_base_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_7000, \
|
||||
.nvm_hw_section_num = 0, \
|
||||
.non_shared_ant = ANT_A, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
|
||||
.dccm_offset = IWL7000_DCCM_OFFSET, \
|
||||
@ -191,7 +183,6 @@ const struct iwl_cfg iwl7260_2ac_cfg = {
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL7260_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7260_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.lp_xtal_workaround = true,
|
||||
.dccm_len = IWL7260_DCCM_LEN,
|
||||
@ -203,7 +194,6 @@ const struct iwl_cfg iwl7260_2ac_cfg_high_temp = {
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL7260_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7260_TX_POWER_VERSION,
|
||||
.high_temp = true,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.lp_xtal_workaround = true,
|
||||
@ -217,7 +207,6 @@ const struct iwl_cfg iwl7260_2n_cfg = {
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL7260_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7260_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.lp_xtal_workaround = true,
|
||||
.dccm_len = IWL7260_DCCM_LEN,
|
||||
@ -229,7 +218,6 @@ const struct iwl_cfg iwl7260_n_cfg = {
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL7260_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7260_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.lp_xtal_workaround = true,
|
||||
.dccm_len = IWL7260_DCCM_LEN,
|
||||
@ -241,7 +229,6 @@ const struct iwl_cfg iwl3160_2ac_cfg = {
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL3160_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL3160_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.dccm_len = IWL3160_DCCM_LEN,
|
||||
};
|
||||
@ -252,7 +239,6 @@ const struct iwl_cfg iwl3160_2n_cfg = {
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL3160_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL3160_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.dccm_len = IWL3160_DCCM_LEN,
|
||||
};
|
||||
@ -263,7 +249,6 @@ const struct iwl_cfg iwl3160_n_cfg = {
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL3160_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL3160_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.dccm_len = IWL3160_DCCM_LEN,
|
||||
};
|
||||
@ -291,7 +276,6 @@ const struct iwl_cfg iwl3165_2ac_cfg = {
|
||||
IWL_DEVICE_7005D,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL3165_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL3165_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
@ -302,7 +286,6 @@ const struct iwl_cfg iwl3168_2ac_cfg = {
|
||||
IWL_DEVICE_3008,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL3168_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL3168_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
.nvm_type = IWL_NVM_SDP,
|
||||
@ -314,7 +297,6 @@ const struct iwl_cfg iwl7265_2ac_cfg = {
|
||||
IWL_DEVICE_7005,
|
||||
.ht_params = &iwl7265_ht_params,
|
||||
.nvm_ver = IWL7265_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
@ -325,7 +307,6 @@ const struct iwl_cfg iwl7265_2n_cfg = {
|
||||
IWL_DEVICE_7005,
|
||||
.ht_params = &iwl7265_ht_params,
|
||||
.nvm_ver = IWL7265_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
@ -336,7 +317,6 @@ const struct iwl_cfg iwl7265_n_cfg = {
|
||||
IWL_DEVICE_7005,
|
||||
.ht_params = &iwl7265_ht_params,
|
||||
.nvm_ver = IWL7265_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
@ -347,7 +327,6 @@ const struct iwl_cfg iwl7265d_2ac_cfg = {
|
||||
IWL_DEVICE_7005D,
|
||||
.ht_params = &iwl7265_ht_params,
|
||||
.nvm_ver = IWL7265D_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
@ -358,7 +337,6 @@ const struct iwl_cfg iwl7265d_2n_cfg = {
|
||||
IWL_DEVICE_7005D,
|
||||
.ht_params = &iwl7265_ht_params,
|
||||
.nvm_ver = IWL7265D_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
@ -369,7 +347,6 @@ const struct iwl_cfg iwl7265d_n_cfg = {
|
||||
IWL_DEVICE_7005D,
|
||||
.ht_params = &iwl7265_ht_params,
|
||||
.nvm_ver = IWL7265D_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
|
@ -75,7 +75,6 @@
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL8000_NVM_VERSION 0x0a1d
|
||||
#define IWL8000_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
|
||||
/* Memory offsets and lengths */
|
||||
#define IWL8260_DCCM_OFFSET 0x800000
|
||||
@ -93,11 +92,10 @@
|
||||
#define IWL8265_MODULE_FIRMWARE(api) \
|
||||
IWL8265_FW_PRE __stringify(api) ".ucode"
|
||||
|
||||
#define NVM_HW_SECTION_NUM_FAMILY_8000 10
|
||||
#define DEFAULT_NVM_FILE_FAMILY_8000C "nvmData-8000C"
|
||||
|
||||
static const struct iwl_base_params iwl8000_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_8000,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
|
||||
.num_of_queues = 31,
|
||||
.max_tfd_queue_size = 256,
|
||||
.shadow_ram_support = true,
|
||||
@ -139,7 +137,7 @@ static const struct iwl_tt_params iwl8000_tt_params = {
|
||||
.device_family = IWL_DEVICE_FAMILY_8000, \
|
||||
.base_params = &iwl8000_base_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_8000, \
|
||||
.nvm_hw_section_num = 10, \
|
||||
.features = NETIF_F_RXCSUM, \
|
||||
.non_shared_ant = ANT_A, \
|
||||
.dccm_offset = IWL8260_DCCM_OFFSET, \
|
||||
@ -177,7 +175,6 @@ const struct iwl_cfg iwl8260_2n_cfg = {
|
||||
IWL_DEVICE_8260,
|
||||
.ht_params = &iwl8000_ht_params,
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL8000_TX_POWER_VERSION,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl8260_2ac_cfg = {
|
||||
@ -186,7 +183,6 @@ const struct iwl_cfg iwl8260_2ac_cfg = {
|
||||
IWL_DEVICE_8260,
|
||||
.ht_params = &iwl8000_ht_params,
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL8000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
@ -196,7 +192,6 @@ const struct iwl_cfg iwl8265_2ac_cfg = {
|
||||
IWL_DEVICE_8265,
|
||||
.ht_params = &iwl8000_ht_params,
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL8000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.vht_mu_mimo_supported = true,
|
||||
};
|
||||
@ -207,7 +202,6 @@ const struct iwl_cfg iwl8275_2ac_cfg = {
|
||||
IWL_DEVICE_8265,
|
||||
.ht_params = &iwl8000_ht_params,
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL8000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.vht_mu_mimo_supported = true,
|
||||
};
|
||||
@ -218,7 +212,6 @@ const struct iwl_cfg iwl4165_2ac_cfg = {
|
||||
IWL_DEVICE_8000,
|
||||
.ht_params = &iwl8000_ht_params,
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL8000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
|
@ -64,7 +64,6 @@
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL9000_NVM_VERSION 0x0a1d
|
||||
#define IWL9000_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
|
||||
/* Memory offsets and lengths */
|
||||
#define IWL9000_DCCM_OFFSET 0x800000
|
||||
@ -90,10 +89,8 @@
|
||||
#define IWL9260B_MODULE_FIRMWARE(api) \
|
||||
IWL9260B_FW_PRE __stringify(api) ".ucode"
|
||||
|
||||
#define NVM_HW_SECTION_NUM_FAMILY_9000 10
|
||||
|
||||
static const struct iwl_base_params iwl9000_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_9000,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
|
||||
.num_of_queues = 31,
|
||||
.max_tfd_queue_size = 256,
|
||||
.shadow_ram_support = true,
|
||||
@ -137,7 +134,7 @@ static const struct iwl_tt_params iwl9000_tt_params = {
|
||||
.device_family = IWL_DEVICE_FAMILY_9000, \
|
||||
.base_params = &iwl9000_base_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_9000, \
|
||||
.nvm_hw_section_num = 10, \
|
||||
.non_shared_ant = ANT_B, \
|
||||
.dccm_offset = IWL9000_DCCM_OFFSET, \
|
||||
.dccm_len = IWL9000_DCCM_LEN, \
|
||||
@ -157,17 +154,17 @@ static const struct iwl_tt_params iwl9000_tt_params = {
|
||||
.min_umac_error_event_table = 0x800000, \
|
||||
.csr = &iwl_csr_v1, \
|
||||
.d3_debug_data_base_addr = 0x401000, \
|
||||
.d3_debug_data_length = 92 * 1024
|
||||
.d3_debug_data_length = 92 * 1024, \
|
||||
.ht_params = &iwl9000_ht_params, \
|
||||
.nvm_ver = IWL9000_NVM_VERSION, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
|
||||
|
||||
|
||||
const struct iwl_cfg iwl9160_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 9160",
|
||||
.fw_name_pre = IWL9260A_FW_PRE,
|
||||
.fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl9260_2ac_cfg = {
|
||||
@ -175,10 +172,6 @@ const struct iwl_cfg iwl9260_2ac_cfg = {
|
||||
.fw_name_pre = IWL9260A_FW_PRE,
|
||||
.fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl9260_killer_2ac_cfg = {
|
||||
@ -186,10 +179,6 @@ const struct iwl_cfg iwl9260_killer_2ac_cfg = {
|
||||
.fw_name_pre = IWL9260A_FW_PRE,
|
||||
.fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl9270_2ac_cfg = {
|
||||
@ -197,10 +186,6 @@ const struct iwl_cfg iwl9270_2ac_cfg = {
|
||||
.fw_name_pre = IWL9260A_FW_PRE,
|
||||
.fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl9460_2ac_cfg = {
|
||||
@ -208,10 +193,6 @@ const struct iwl_cfg iwl9460_2ac_cfg = {
|
||||
.fw_name_pre = IWL9260A_FW_PRE,
|
||||
.fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl9460_2ac_cfg_soc = {
|
||||
@ -220,10 +201,6 @@ const struct iwl_cfg iwl9460_2ac_cfg_soc = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
};
|
||||
@ -234,10 +211,6 @@ const struct iwl_cfg iwl9461_2ac_cfg_soc = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
};
|
||||
@ -248,10 +221,6 @@ const struct iwl_cfg iwl9462_2ac_cfg_soc = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
};
|
||||
@ -261,10 +230,6 @@ const struct iwl_cfg iwl9560_2ac_cfg = {
|
||||
.fw_name_pre = IWL9260A_FW_PRE,
|
||||
.fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl9560_2ac_cfg_soc = {
|
||||
@ -273,10 +238,6 @@ const struct iwl_cfg iwl9560_2ac_cfg_soc = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
};
|
||||
@ -287,10 +248,6 @@ const struct iwl_cfg iwl9560_killer_2ac_cfg_soc = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
};
|
||||
@ -301,10 +258,6 @@ const struct iwl_cfg iwl9560_killer_s_2ac_cfg_soc = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
};
|
||||
@ -315,10 +268,6 @@ const struct iwl_cfg iwl9460_2ac_cfg_shared_clk = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
.extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
|
||||
@ -330,10 +279,6 @@ const struct iwl_cfg iwl9461_2ac_cfg_shared_clk = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
.extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
|
||||
@ -345,10 +290,6 @@ const struct iwl_cfg iwl9462_2ac_cfg_shared_clk = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
.extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
|
||||
@ -360,10 +301,6 @@ const struct iwl_cfg iwl9560_2ac_cfg_shared_clk = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
.extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
|
||||
@ -375,10 +312,6 @@ const struct iwl_cfg iwl9560_killer_2ac_cfg_shared_clk = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
.extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
|
||||
@ -390,10 +323,6 @@ const struct iwl_cfg iwl9560_killer_s_2ac_cfg_shared_clk = {
|
||||
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
|
||||
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.integrated = true,
|
||||
.soc_latency = 5000,
|
||||
.extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
|
||||
|
@ -1224,6 +1224,23 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_nvm_check_version(struct iwl_nvm_data *data,
|
||||
struct iwl_trans *trans)
|
||||
{
|
||||
if (data->nvm_version >= trans->cfg->nvm_ver ||
|
||||
data->calib_version >= trans->cfg->nvm_calib_ver) {
|
||||
IWL_DEBUG_INFO(trans, "device EEPROM VER=0x%x, CALIB=0x%x\n",
|
||||
data->nvm_version, data->calib_version);
|
||||
return 0;
|
||||
}
|
||||
|
||||
IWL_ERR(trans,
|
||||
"Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
|
||||
data->nvm_version, trans->cfg->nvm_ver,
|
||||
data->calib_version, trans->cfg->nvm_calib_ver);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
const struct iwl_cfg *cfg,
|
||||
const struct iwl_fw *fw,
|
||||
|
@ -345,66 +345,98 @@ enum iwl_rx_mpdu_mac_info {
|
||||
IWL_RX_MPDU_PHY_PHY_INDEX_MASK = 0xf0,
|
||||
};
|
||||
|
||||
/*
|
||||
* enum iwl_rx_he_phy - HE PHY data
|
||||
*/
|
||||
enum iwl_rx_he_phy {
|
||||
IWL_RX_HE_PHY_BEAM_CHNG = BIT(0),
|
||||
IWL_RX_HE_PHY_UPLINK = BIT(1),
|
||||
IWL_RX_HE_PHY_BSS_COLOR_MASK = 0xfc,
|
||||
IWL_RX_HE_PHY_SPATIAL_REUSE_MASK = 0xf00,
|
||||
IWL_RX_HE_PHY_SU_EXT_BW10 = BIT(12),
|
||||
IWL_RX_HE_PHY_TXOP_DUR_MASK = 0xfe000,
|
||||
IWL_RX_HE_PHY_LDPC_EXT_SYM = BIT(20),
|
||||
IWL_RX_HE_PHY_PRE_FEC_PAD_MASK = 0x600000,
|
||||
IWL_RX_HE_PHY_PE_DISAMBIG = BIT(23),
|
||||
IWL_RX_HE_PHY_DOPPLER = BIT(24),
|
||||
/* TSF overload low dword */
|
||||
enum iwl_rx_phy_data0 {
|
||||
/* info type: HE any */
|
||||
IWL_RX_PHY_DATA0_HE_BEAM_CHNG = 0x00000001,
|
||||
IWL_RX_PHY_DATA0_HE_UPLINK = 0x00000002,
|
||||
IWL_RX_PHY_DATA0_HE_BSS_COLOR_MASK = 0x000000fc,
|
||||
IWL_RX_PHY_DATA0_HE_SPATIAL_REUSE_MASK = 0x00000f00,
|
||||
/* 1 bit reserved */
|
||||
IWL_RX_PHY_DATA0_HE_TXOP_DUR_MASK = 0x000fe000,
|
||||
IWL_RX_PHY_DATA0_HE_LDPC_EXT_SYM = 0x00100000,
|
||||
IWL_RX_PHY_DATA0_HE_PRE_FEC_PAD_MASK = 0x00600000,
|
||||
IWL_RX_PHY_DATA0_HE_PE_DISAMBIG = 0x00800000,
|
||||
IWL_RX_PHY_DATA0_HE_DOPPLER = 0x01000000,
|
||||
/* 6 bits reserved */
|
||||
IWL_RX_HE_PHY_DELIM_EOF = BIT(31),
|
||||
IWL_RX_PHY_DATA0_HE_DELIM_EOF = 0x80000000,
|
||||
};
|
||||
|
||||
/* second dword - common data */
|
||||
IWL_RX_HE_PHY_HE_LTF_NUM_MASK = 0xe000000000ULL,
|
||||
IWL_RX_HE_PHY_RU_ALLOC_SEC80 = BIT_ULL(32 + 8),
|
||||
enum iwl_rx_phy_info_type {
|
||||
IWL_RX_PHY_INFO_TYPE_NONE = 0,
|
||||
IWL_RX_PHY_INFO_TYPE_CCK = 1,
|
||||
IWL_RX_PHY_INFO_TYPE_OFDM_LGCY = 2,
|
||||
IWL_RX_PHY_INFO_TYPE_HT = 3,
|
||||
IWL_RX_PHY_INFO_TYPE_VHT_SU = 4,
|
||||
IWL_RX_PHY_INFO_TYPE_VHT_MU = 5,
|
||||
IWL_RX_PHY_INFO_TYPE_HE_SU = 6,
|
||||
IWL_RX_PHY_INFO_TYPE_HE_MU = 7,
|
||||
IWL_RX_PHY_INFO_TYPE_HE_TB = 8,
|
||||
IWL_RX_PHY_INFO_TYPE_HE_MU_EXT = 9,
|
||||
IWL_RX_PHY_INFO_TYPE_HE_TB_EXT = 10,
|
||||
};
|
||||
|
||||
/* TSF overload high dword */
|
||||
enum iwl_rx_phy_data1 {
|
||||
/*
|
||||
* check this first - if TSF overload is set,
|
||||
* see &enum iwl_rx_phy_info_type
|
||||
*/
|
||||
IWL_RX_PHY_DATA1_INFO_TYPE_MASK = 0xf0000000,
|
||||
|
||||
/* info type: HT/VHT/HE any */
|
||||
IWL_RX_PHY_DATA1_LSIG_LEN_MASK = 0x0fff0000,
|
||||
|
||||
/* info type: HE MU/MU-EXT */
|
||||
IWL_RX_PHY_DATA1_HE_MU_SIGB_COMPRESSION = 0x00000001,
|
||||
IWL_RX_PHY_DATA1_HE_MU_SIBG_SYM_OR_USER_NUM_MASK = 0x0000001e,
|
||||
|
||||
/* info type: HE any */
|
||||
IWL_RX_PHY_DATA1_HE_LTF_NUM_MASK = 0x000000e0,
|
||||
IWL_RX_PHY_DATA1_HE_RU_ALLOC_SEC80 = 0x00000100,
|
||||
/* trigger encoded */
|
||||
IWL_RX_HE_PHY_RU_ALLOC_MASK = 0xfe0000000000ULL,
|
||||
IWL_RX_HE_PHY_INFO_TYPE_MASK = 0xf000000000000000ULL,
|
||||
IWL_RX_HE_PHY_INFO_TYPE_SU = 0x0, /* TSF low valid (first DW) */
|
||||
IWL_RX_HE_PHY_INFO_TYPE_MU = 0x1, /* TSF low/high valid (both DWs) */
|
||||
IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO = 0x2, /* same + SIGB-common0/1/2 valid */
|
||||
IWL_RX_HE_PHY_INFO_TYPE_TB = 0x3, /* TSF low/high valid (both DWs) */
|
||||
IWL_RX_PHY_DATA1_HE_RU_ALLOC_MASK = 0x0000fe00,
|
||||
|
||||
/* second dword - MU data */
|
||||
IWL_RX_HE_PHY_MU_SIGB_COMPRESSION = BIT_ULL(32 + 0),
|
||||
IWL_RX_HE_PHY_MU_SIBG_SYM_OR_USER_NUM_MASK = 0x1e00000000ULL,
|
||||
IWL_RX_HE_PHY_MU_SIGB_MCS_MASK = 0xf000000000000ULL,
|
||||
IWL_RX_HE_PHY_MU_SIGB_DCM = BIT_ULL(32 + 21),
|
||||
IWL_RX_HE_PHY_MU_PREAMBLE_PUNC_TYPE_MASK = 0xc0000000000000ULL,
|
||||
|
||||
/* second dword - TB data */
|
||||
IWL_RX_HE_PHY_TB_PILOT_TYPE = BIT_ULL(32 + 0),
|
||||
IWL_RX_HE_PHY_TB_LOW_SS_MASK = 0xe00000000ULL
|
||||
/* info type: HE TB/TX-EXT */
|
||||
IWL_RX_PHY_DATA1_HE_TB_PILOT_TYPE = 0x00000001,
|
||||
IWL_RX_PHY_DATA1_HE_TB_LOW_SS_MASK = 0x0000000e,
|
||||
};
|
||||
|
||||
enum iwl_rx_he_sigb_common0 {
|
||||
/* goes into Metadata DW 7 */
|
||||
enum iwl_rx_phy_data2 {
|
||||
/* info type: HE MU-EXT */
|
||||
/* the a1/a2/... is what the PHY/firmware calls the values */
|
||||
IWL_RX_HE_SIGB_COMMON0_CH1_RU0 = 0x000000ff, /* a1 */
|
||||
IWL_RX_HE_SIGB_COMMON0_CH1_RU2 = 0x0000ff00, /* a2 */
|
||||
IWL_RX_HE_SIGB_COMMON0_CH2_RU0 = 0x00ff0000, /* b1 */
|
||||
IWL_RX_HE_SIGB_COMMON0_CH2_RU2 = 0xff000000, /* b2 */
|
||||
IWL_RX_PHY_DATA2_HE_MU_EXT_CH1_RU0 = 0x000000ff, /* a1 */
|
||||
IWL_RX_PHY_DATA2_HE_MU_EXT_CH1_RU2 = 0x0000ff00, /* a2 */
|
||||
IWL_RX_PHY_DATA2_HE_MU_EXT_CH2_RU0 = 0x00ff0000, /* b1 */
|
||||
IWL_RX_PHY_DATA2_HE_MU_EXT_CH2_RU2 = 0xff000000, /* b2 */
|
||||
|
||||
/* info type: HE TB-EXT */
|
||||
IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE1 = 0x0000000f,
|
||||
IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE2 = 0x000000f0,
|
||||
IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE3 = 0x00000f00,
|
||||
IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE4 = 0x0000f000,
|
||||
};
|
||||
|
||||
enum iwl_rx_he_sigb_common1 {
|
||||
IWL_RX_HE_SIGB_COMMON1_CH1_RU1 = 0x000000ff, /* c1 */
|
||||
IWL_RX_HE_SIGB_COMMON1_CH1_RU3 = 0x0000ff00, /* c2 */
|
||||
IWL_RX_HE_SIGB_COMMON1_CH2_RU1 = 0x00ff0000, /* d1 */
|
||||
IWL_RX_HE_SIGB_COMMON1_CH2_RU3 = 0xff000000, /* d2 */
|
||||
/* goes into Metadata DW 8 */
|
||||
enum iwl_rx_phy_data3 {
|
||||
/* info type: HE MU-EXT */
|
||||
IWL_RX_PHY_DATA3_HE_MU_EXT_CH1_RU1 = 0x000000ff, /* c1 */
|
||||
IWL_RX_PHY_DATA3_HE_MU_EXT_CH1_RU3 = 0x0000ff00, /* c2 */
|
||||
IWL_RX_PHY_DATA3_HE_MU_EXT_CH2_RU1 = 0x00ff0000, /* d1 */
|
||||
IWL_RX_PHY_DATA3_HE_MU_EXT_CH2_RU3 = 0xff000000, /* d2 */
|
||||
};
|
||||
|
||||
enum iwl_rx_he_sigb_common2 {
|
||||
IWL_RX_HE_SIGB_COMMON2_CH1_CTR_RU = 0x0001,
|
||||
IWL_RX_HE_SIGB_COMMON2_CH2_CTR_RU = 0x0002,
|
||||
IWL_RX_HE_SIGB_COMMON2_CH1_CRC_OK = 0x0004,
|
||||
IWL_RX_HE_SIGB_COMMON2_CH2_CRC_OK = 0x0008,
|
||||
/* goes into Metadata DW 4 high 16 bits */
|
||||
enum iwl_rx_phy_data4 {
|
||||
/* info type: HE MU-EXT */
|
||||
IWL_RX_PHY_DATA4_HE_MU_EXT_CH1_CTR_RU = 0x0001,
|
||||
IWL_RX_PHY_DATA4_HE_MU_EXT_CH2_CTR_RU = 0x0002,
|
||||
IWL_RX_PHY_DATA4_HE_MU_EXT_CH1_CRC_OK = 0x0004,
|
||||
IWL_RX_PHY_DATA4_HE_MU_EXT_CH2_CRC_OK = 0x0008,
|
||||
IWL_RX_PHY_DATA4_HE_MU_EXT_SIGB_MCS_MASK = 0x00f0,
|
||||
IWL_RX_PHY_DATA4_HE_MU_EXT_SIGB_DCM = 0x0100,
|
||||
IWL_RX_PHY_DATA4_HE_MU_EXT_PREAMBLE_PUNC_TYPE_MASK = 0x0600,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -419,9 +451,9 @@ struct iwl_rx_mpdu_desc_v1 {
|
||||
__le32 rss_hash;
|
||||
|
||||
/**
|
||||
* @sigb_common0: for HE sniffer, HE-SIG-B common part 0
|
||||
* @phy_data2: depends on info type (see @phy_data1)
|
||||
*/
|
||||
__le32 sigb_common0;
|
||||
__le32 phy_data2;
|
||||
};
|
||||
|
||||
/* DW8 - carries filter_match only when rpa_en == 1 */
|
||||
@ -432,9 +464,9 @@ struct iwl_rx_mpdu_desc_v1 {
|
||||
__le32 filter_match;
|
||||
|
||||
/**
|
||||
* @sigb_common1: for HE sniffer, HE-SIG-B common part 1
|
||||
* @phy_data3: depends on info type (see @phy_data1)
|
||||
*/
|
||||
__le32 sigb_common1;
|
||||
__le32 phy_data3;
|
||||
};
|
||||
|
||||
/* DW9 */
|
||||
@ -472,12 +504,19 @@ struct iwl_rx_mpdu_desc_v1 {
|
||||
* %IWL_RX_MPDU_PHY_TSF_OVERLOAD isn't set
|
||||
*/
|
||||
__le64 tsf_on_air_rise;
|
||||
/**
|
||||
* @he_phy_data:
|
||||
* HE PHY data, see &enum iwl_rx_he_phy, valid
|
||||
* only if %IWL_RX_MPDU_PHY_TSF_OVERLOAD is set
|
||||
*/
|
||||
__le64 he_phy_data;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* @phy_data0: depends on info_type, see @phy_data1
|
||||
*/
|
||||
__le32 phy_data0;
|
||||
/**
|
||||
* @phy_data1: valid only if
|
||||
* %IWL_RX_MPDU_PHY_TSF_OVERLOAD is set,
|
||||
* see &enum iwl_rx_phy_data1.
|
||||
*/
|
||||
__le32 phy_data1;
|
||||
};
|
||||
};
|
||||
} __packed;
|
||||
|
||||
@ -493,9 +532,9 @@ struct iwl_rx_mpdu_desc_v3 {
|
||||
__le32 filter_match;
|
||||
|
||||
/**
|
||||
* @sigb_common0: for HE sniffer, HE-SIG-B common part 0
|
||||
* @phy_data2: depends on info type (see @phy_data1)
|
||||
*/
|
||||
__le32 sigb_common0;
|
||||
__le32 phy_data2;
|
||||
};
|
||||
|
||||
/* DW8 - carries rss_hash only when rpa_en == 1 */
|
||||
@ -506,9 +545,9 @@ struct iwl_rx_mpdu_desc_v3 {
|
||||
__le32 rss_hash;
|
||||
|
||||
/**
|
||||
* @sigb_common1: for HE sniffer, HE-SIG-B common part 1
|
||||
* @phy_data3: depends on info type (see @phy_data1)
|
||||
*/
|
||||
__le32 sigb_common1;
|
||||
__le32 phy_data3;
|
||||
};
|
||||
/* DW9 */
|
||||
/**
|
||||
@ -556,12 +595,19 @@ struct iwl_rx_mpdu_desc_v3 {
|
||||
* %IWL_RX_MPDU_PHY_TSF_OVERLOAD isn't set
|
||||
*/
|
||||
__le64 tsf_on_air_rise;
|
||||
/**
|
||||
* @he_phy_data:
|
||||
* HE PHY data, see &enum iwl_rx_he_phy, valid
|
||||
* only if %IWL_RX_MPDU_PHY_TSF_OVERLOAD is set
|
||||
*/
|
||||
__le64 he_phy_data;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* @phy_data0: depends on info_type, see @phy_data1
|
||||
*/
|
||||
__le32 phy_data0;
|
||||
/**
|
||||
* @phy_data1: valid only if
|
||||
* %IWL_RX_MPDU_PHY_TSF_OVERLOAD is set,
|
||||
* see &enum iwl_rx_phy_data1.
|
||||
*/
|
||||
__le32 phy_data1;
|
||||
};
|
||||
};
|
||||
/* DW16 & DW17 */
|
||||
/**
|
||||
@ -613,9 +659,9 @@ struct iwl_rx_mpdu_desc {
|
||||
__le16 l3l4_flags;
|
||||
|
||||
/**
|
||||
* @sigb_common2: for HE sniffer, HE-SIG-B common part 2
|
||||
* @phy_data4: depends on info type, see phy_data1
|
||||
*/
|
||||
__le16 sigb_common2;
|
||||
__le16 phy_data4;
|
||||
};
|
||||
/* DW5 */
|
||||
/**
|
||||
|
@ -605,6 +605,28 @@ static void iwl_fw_dump_mem(struct iwl_fw_runtime *fwrt,
|
||||
IWL_DEBUG_INFO(fwrt, "WRT memory dump. Type=%u\n", dump_mem->type);
|
||||
}
|
||||
|
||||
static void iwl_fw_dump_named_mem(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_error_dump_data **dump_data,
|
||||
u32 len, u32 ofs, u8 *name, u8 name_len)
|
||||
{
|
||||
struct iwl_fw_error_dump_named_mem *dump_mem;
|
||||
|
||||
if (!len)
|
||||
return;
|
||||
|
||||
(*dump_data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
|
||||
(*dump_data)->len = cpu_to_le32(len + sizeof(*dump_mem));
|
||||
dump_mem = (void *)(*dump_data)->data;
|
||||
dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_NAMED_MEM);
|
||||
dump_mem->offset = cpu_to_le32(ofs);
|
||||
dump_mem->name_len = name_len;
|
||||
memcpy(dump_mem->name, name, name_len);
|
||||
iwl_trans_read_mem_bytes(fwrt->trans, ofs, dump_mem->data, len);
|
||||
*dump_data = iwl_fw_error_next_data(*dump_data);
|
||||
|
||||
IWL_DEBUG_INFO(fwrt, "WRT memory dump. Type=%u\n", dump_mem->type);
|
||||
}
|
||||
|
||||
#define ADD_LEN(len, item_len, const_len) \
|
||||
do {size_t item = item_len; len += (!!item) * const_len + item; } \
|
||||
while (0)
|
||||
@ -928,6 +950,238 @@ out:
|
||||
return dump_file;
|
||||
}
|
||||
|
||||
static void iwl_dump_prph_ini(struct iwl_trans *trans,
|
||||
struct iwl_fw_error_dump_data **data,
|
||||
struct iwl_fw_ini_region_cfg *reg)
|
||||
{
|
||||
struct iwl_fw_error_dump_prph *prph;
|
||||
unsigned long flags;
|
||||
u32 i, size = le32_to_cpu(reg->num_regions);
|
||||
|
||||
IWL_DEBUG_INFO(trans, "WRT PRPH dump\n");
|
||||
|
||||
if (!iwl_trans_grab_nic_access(trans, &flags))
|
||||
return;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
(*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PRPH);
|
||||
(*data)->len = cpu_to_le32(le32_to_cpu(reg->size) +
|
||||
sizeof(*prph));
|
||||
prph = (void *)(*data)->data;
|
||||
prph->prph_start = reg->start_addr[i];
|
||||
prph->data[0] = cpu_to_le32(iwl_read_prph_no_grab(trans,
|
||||
le32_to_cpu(prph->prph_start)));
|
||||
*data = iwl_fw_error_next_data(*data);
|
||||
}
|
||||
iwl_trans_release_nic_access(trans, &flags);
|
||||
}
|
||||
|
||||
static void iwl_dump_csr_ini(struct iwl_trans *trans,
|
||||
struct iwl_fw_error_dump_data **data,
|
||||
struct iwl_fw_ini_region_cfg *reg)
|
||||
{
|
||||
int i, num = le32_to_cpu(reg->num_regions);
|
||||
u32 size = le32_to_cpu(reg->size);
|
||||
|
||||
IWL_DEBUG_INFO(trans, "WRT CSR dump\n");
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
u32 add = le32_to_cpu(reg->start_addr[i]);
|
||||
__le32 *val;
|
||||
int j;
|
||||
|
||||
(*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_CSR);
|
||||
(*data)->len = cpu_to_le32(size);
|
||||
val = (void *)(*data)->data;
|
||||
|
||||
for (j = 0; j < size; j += 4)
|
||||
*val++ = cpu_to_le32(iwl_trans_read32(trans, j + add));
|
||||
|
||||
*data = iwl_fw_error_next_data(*data);
|
||||
}
|
||||
}
|
||||
|
||||
static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_ini_trigger *trigger)
|
||||
{
|
||||
int i, num, size = 0, hdr_len = sizeof(struct iwl_fw_error_dump_data);
|
||||
|
||||
if (!trigger || !trigger->num_regions)
|
||||
return 0;
|
||||
|
||||
num = le32_to_cpu(trigger->num_regions);
|
||||
for (i = 0; i < num; i++) {
|
||||
u32 reg_id = le32_to_cpu(trigger->data[i]);
|
||||
struct iwl_fw_ini_region_cfg *reg;
|
||||
enum iwl_fw_ini_region_type type;
|
||||
u32 num_entries;
|
||||
|
||||
if (WARN_ON(reg_id >= ARRAY_SIZE(fwrt->dump.active_regs)))
|
||||
continue;
|
||||
|
||||
reg = fwrt->dump.active_regs[reg_id].reg;
|
||||
if (WARN(!reg, "Unassigned region %d\n", reg_id))
|
||||
continue;
|
||||
|
||||
type = le32_to_cpu(reg->region_type);
|
||||
num_entries = le32_to_cpu(reg->num_regions);
|
||||
|
||||
switch (type) {
|
||||
case IWL_FW_INI_REGION_DEVICE_MEMORY:
|
||||
size += hdr_len +
|
||||
sizeof(struct iwl_fw_error_dump_named_mem) +
|
||||
le32_to_cpu(reg->size);
|
||||
break;
|
||||
case IWL_FW_INI_REGION_PERIPHERY_MAC:
|
||||
case IWL_FW_INI_REGION_PERIPHERY_PHY:
|
||||
case IWL_FW_INI_REGION_PERIPHERY_AUX:
|
||||
size += num_entries *
|
||||
(hdr_len +
|
||||
sizeof(struct iwl_fw_error_dump_prph) +
|
||||
sizeof(u32));
|
||||
break;
|
||||
case IWL_FW_INI_REGION_TXF:
|
||||
size += iwl_fw_txf_len(fwrt, &fwrt->smem_cfg);
|
||||
break;
|
||||
case IWL_FW_INI_REGION_RXF:
|
||||
size += iwl_fw_rxf_len(fwrt, &fwrt->smem_cfg);
|
||||
break;
|
||||
case IWL_FW_INI_REGION_PAGING:
|
||||
if (!iwl_fw_dbg_is_paging_enabled(fwrt))
|
||||
break;
|
||||
size += fwrt->num_of_paging_blk *
|
||||
(hdr_len +
|
||||
sizeof(struct iwl_fw_error_dump_paging) +
|
||||
PAGING_BLOCK_SIZE);
|
||||
break;
|
||||
case IWL_FW_INI_REGION_CSR:
|
||||
size += num_entries *
|
||||
(hdr_len + le32_to_cpu(reg->size));
|
||||
break;
|
||||
case IWL_FW_INI_REGION_DRAM_BUFFER:
|
||||
/* Transport takes care of DRAM dumping */
|
||||
case IWL_FW_INI_REGION_INTERNAL_BUFFER:
|
||||
case IWL_FW_INI_REGION_DRAM_IMR:
|
||||
/* Undefined yet */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_ini_trigger *trigger,
|
||||
struct iwl_fw_error_dump_data **data,
|
||||
u32 *dump_mask)
|
||||
{
|
||||
int i, num = le32_to_cpu(trigger->num_regions);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
u32 reg_id = le32_to_cpu(trigger->data[i]);
|
||||
enum iwl_fw_ini_region_type type;
|
||||
struct iwl_fw_ini_region_cfg *reg;
|
||||
|
||||
if (reg_id >= ARRAY_SIZE(fwrt->dump.active_regs))
|
||||
continue;
|
||||
|
||||
reg = fwrt->dump.active_regs[reg_id].reg;
|
||||
/* Don't warn, get_trigger_len already warned */
|
||||
if (!reg)
|
||||
continue;
|
||||
|
||||
type = le32_to_cpu(reg->region_type);
|
||||
switch (type) {
|
||||
case IWL_FW_INI_REGION_DEVICE_MEMORY:
|
||||
if (WARN_ON(le32_to_cpu(reg->num_regions) > 1))
|
||||
continue;
|
||||
iwl_fw_dump_named_mem(fwrt, data,
|
||||
le32_to_cpu(reg->size),
|
||||
le32_to_cpu(reg->start_addr[0]),
|
||||
reg->name,
|
||||
le32_to_cpu(reg->name_len));
|
||||
break;
|
||||
case IWL_FW_INI_REGION_PERIPHERY_MAC:
|
||||
case IWL_FW_INI_REGION_PERIPHERY_PHY:
|
||||
case IWL_FW_INI_REGION_PERIPHERY_AUX:
|
||||
iwl_dump_prph_ini(fwrt->trans, data, reg);
|
||||
break;
|
||||
case IWL_FW_INI_REGION_DRAM_BUFFER:
|
||||
*dump_mask |= IWL_FW_ERROR_DUMP_FW_MONITOR;
|
||||
break;
|
||||
case IWL_FW_INI_REGION_PAGING:
|
||||
if (iwl_fw_dbg_is_paging_enabled(fwrt))
|
||||
iwl_dump_paging(fwrt, data);
|
||||
else
|
||||
*dump_mask |= IWL_FW_ERROR_DUMP_PAGING;
|
||||
break;
|
||||
case IWL_FW_INI_REGION_TXF:
|
||||
iwl_fw_dump_txf(fwrt, data);
|
||||
break;
|
||||
case IWL_FW_INI_REGION_RXF:
|
||||
iwl_fw_dump_rxf(fwrt, data);
|
||||
break;
|
||||
case IWL_FW_INI_REGION_CSR:
|
||||
iwl_dump_csr_ini(fwrt->trans, data, reg);
|
||||
break;
|
||||
case IWL_FW_INI_REGION_DRAM_IMR:
|
||||
case IWL_FW_INI_REGION_INTERNAL_BUFFER:
|
||||
/* This is undefined yet */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct iwl_fw_error_dump_file *
|
||||
_iwl_fw_error_ini_dump(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_dump_ptrs *fw_error_dump,
|
||||
u32 *dump_mask)
|
||||
{
|
||||
int size, id = le32_to_cpu(fwrt->dump.desc->trig_desc.type);
|
||||
struct iwl_fw_error_dump_data *dump_data;
|
||||
struct iwl_fw_error_dump_file *dump_file;
|
||||
struct iwl_fw_ini_trigger *trigger, *ext;
|
||||
|
||||
if (id == FW_DBG_TRIGGER_FW_ASSERT)
|
||||
id = IWL_FW_TRIGGER_ID_FW_ASSERT;
|
||||
else if (id == FW_DBG_TRIGGER_USER)
|
||||
id = IWL_FW_TRIGGER_ID_USER_TRIGGER;
|
||||
else if (id < FW_DBG_TRIGGER_MAX)
|
||||
return NULL;
|
||||
|
||||
if (WARN_ON(id >= ARRAY_SIZE(fwrt->dump.active_trigs)))
|
||||
return NULL;
|
||||
|
||||
trigger = fwrt->dump.active_trigs[id].conf;
|
||||
ext = fwrt->dump.active_trigs[id].conf_ext;
|
||||
|
||||
size = sizeof(*dump_file);
|
||||
size += iwl_fw_ini_get_trigger_len(fwrt, trigger);
|
||||
size += iwl_fw_ini_get_trigger_len(fwrt, ext);
|
||||
|
||||
if (!size)
|
||||
return NULL;
|
||||
|
||||
dump_file = vzalloc(size);
|
||||
if (!dump_file)
|
||||
return NULL;
|
||||
|
||||
fw_error_dump->fwrt_ptr = dump_file;
|
||||
|
||||
dump_file->barker = cpu_to_le32(IWL_FW_ERROR_DUMP_BARKER);
|
||||
dump_data = (void *)dump_file->data;
|
||||
dump_file->file_len = cpu_to_le32(size);
|
||||
|
||||
*dump_mask = 0;
|
||||
if (trigger)
|
||||
iwl_fw_ini_dump_trigger(fwrt, trigger, &dump_data, dump_mask);
|
||||
if (ext)
|
||||
iwl_fw_ini_dump_trigger(fwrt, ext, &dump_data, dump_mask);
|
||||
|
||||
return dump_file;
|
||||
}
|
||||
|
||||
void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
struct iwl_fw_dump_ptrs *fw_error_dump;
|
||||
@ -948,13 +1202,18 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
|
||||
if (!fw_error_dump)
|
||||
goto out;
|
||||
|
||||
dump_file = _iwl_fw_error_dump(fwrt, fw_error_dump);
|
||||
if (fwrt->trans->ini_valid)
|
||||
dump_file = _iwl_fw_error_ini_dump(fwrt, fw_error_dump,
|
||||
&dump_mask);
|
||||
else
|
||||
dump_file = _iwl_fw_error_dump(fwrt, fw_error_dump);
|
||||
|
||||
if (!dump_file) {
|
||||
kfree(fw_error_dump);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (fwrt->dump.monitor_only)
|
||||
if (!fwrt->trans->ini_valid && fwrt->dump.monitor_only)
|
||||
dump_mask &= IWL_FW_ERROR_DUMP_FW_MONITOR;
|
||||
|
||||
fw_error_dump->trans_ptr = iwl_trans_dump_data(fwrt->trans, dump_mask);
|
||||
@ -1070,10 +1329,10 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect_desc);
|
||||
|
||||
int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
|
||||
enum iwl_fw_dbg_trigger trig,
|
||||
const char *str, size_t len,
|
||||
struct iwl_fw_dbg_trigger_tlv *trigger)
|
||||
int _iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
|
||||
enum iwl_fw_dbg_trigger trig,
|
||||
const char *str, size_t len,
|
||||
struct iwl_fw_dbg_trigger_tlv *trigger)
|
||||
{
|
||||
struct iwl_fw_dump_desc *desc;
|
||||
unsigned int delay = 0;
|
||||
@ -1108,6 +1367,47 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
|
||||
|
||||
return iwl_fw_dbg_collect_desc(fwrt, desc, monitor_only, delay);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(_iwl_fw_dbg_collect);
|
||||
|
||||
int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
|
||||
u32 id, const char *str, size_t len)
|
||||
{
|
||||
struct iwl_fw_dump_desc *desc;
|
||||
u32 occur, delay;
|
||||
|
||||
if (!fwrt->trans->ini_valid)
|
||||
return _iwl_fw_dbg_collect(fwrt, id, str, len, NULL);
|
||||
|
||||
if (id == FW_DBG_TRIGGER_USER)
|
||||
id = IWL_FW_TRIGGER_ID_USER_TRIGGER;
|
||||
|
||||
if (WARN_ON(!fwrt->dump.active_trigs[id].active))
|
||||
return -EINVAL;
|
||||
|
||||
delay = le32_to_cpu(fwrt->dump.active_trigs[id].conf->ignore_consec);
|
||||
occur = le32_to_cpu(fwrt->dump.active_trigs[id].conf->occurrences);
|
||||
if (!occur)
|
||||
return 0;
|
||||
|
||||
if (le32_to_cpu(fwrt->dump.active_trigs[id].conf->force_restart)) {
|
||||
IWL_WARN(fwrt, "Force restart: trigger %d fired.\n", id);
|
||||
iwl_force_nmi(fwrt->trans);
|
||||
return 0;
|
||||
}
|
||||
|
||||
desc = kzalloc(sizeof(*desc) + len, GFP_ATOMIC);
|
||||
if (!desc)
|
||||
return -ENOMEM;
|
||||
|
||||
occur--;
|
||||
fwrt->dump.active_trigs[id].conf->occurrences = cpu_to_le32(occur);
|
||||
|
||||
desc->len = len;
|
||||
desc->trig_desc.type = cpu_to_le32(id);
|
||||
memcpy(desc->trig_desc.data, str, len);
|
||||
|
||||
return iwl_fw_dbg_collect_desc(fwrt, desc, true, delay);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect);
|
||||
|
||||
int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
|
||||
@ -1136,8 +1436,8 @@ int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
|
||||
len = strlen(buf) + 1;
|
||||
}
|
||||
|
||||
ret = iwl_fw_dbg_collect(fwrt, le32_to_cpu(trigger->id), buf, len,
|
||||
trigger);
|
||||
ret = _iwl_fw_dbg_collect(fwrt, le32_to_cpu(trigger->id), buf, len,
|
||||
trigger);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -1409,6 +1709,12 @@ static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt,
|
||||
active->conf = trig;
|
||||
}
|
||||
|
||||
/* Since zero means infinity - just set to -1 */
|
||||
if (!le32_to_cpu(trig->occurrences))
|
||||
trig->occurrences = cpu_to_le32(-1);
|
||||
if (!le32_to_cpu(trig->ignore_consec))
|
||||
trig->ignore_consec = cpu_to_le32(-1);
|
||||
|
||||
iter += sizeof(*trig) +
|
||||
le32_to_cpu(trig->num_regions) * sizeof(__le32);
|
||||
|
||||
|
@ -108,10 +108,12 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt);
|
||||
int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
|
||||
const struct iwl_fw_dump_desc *desc,
|
||||
bool monitor_only, unsigned int delay);
|
||||
int _iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
|
||||
enum iwl_fw_dbg_trigger trig,
|
||||
const char *str, size_t len,
|
||||
struct iwl_fw_dbg_trigger_tlv *trigger);
|
||||
int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
|
||||
enum iwl_fw_dbg_trigger trig,
|
||||
const char *str, size_t len,
|
||||
struct iwl_fw_dbg_trigger_tlv *trigger);
|
||||
u32 id, const char *str, size_t len);
|
||||
int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_dbg_trigger_tlv *trigger,
|
||||
const char *fmt, ...) __printf(3, 4);
|
||||
@ -213,6 +215,37 @@ _iwl_fw_dbg_trigger_on(struct iwl_fw_runtime *fwrt,
|
||||
_iwl_fw_dbg_trigger_on((fwrt), (wdev), (id)); \
|
||||
})
|
||||
|
||||
static inline bool
|
||||
_iwl_fw_ini_trigger_on(struct iwl_fw_runtime *fwrt,
|
||||
const enum iwl_fw_dbg_trigger id)
|
||||
{
|
||||
struct iwl_fw_ini_active_triggers *trig = &fwrt->dump.active_trigs[id];
|
||||
u32 ms;
|
||||
|
||||
if (!fwrt->trans->ini_valid)
|
||||
return false;
|
||||
|
||||
if (!trig || !trig->active)
|
||||
return false;
|
||||
|
||||
ms = le32_to_cpu(trig->conf->ignore_consec);
|
||||
if (ms)
|
||||
ms /= USEC_PER_MSEC;
|
||||
|
||||
if (iwl_fw_dbg_no_trig_window(fwrt, id, ms)) {
|
||||
IWL_WARN(fwrt, "Trigger %d fired in no-collect window\n", id);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define iwl_fw_ini_trigger_on(fwrt, wdev, id) ({ \
|
||||
BUILD_BUG_ON(!__builtin_constant_p(id)); \
|
||||
BUILD_BUG_ON((id) >= IWL_FW_TRIGGER_ID_NUM); \
|
||||
_iwl_fw_ini_trigger_on((fwrt), (wdev), (id)); \
|
||||
})
|
||||
|
||||
static inline void
|
||||
_iwl_fw_dbg_trigger_simple_stop(struct iwl_fw_runtime *fwrt,
|
||||
struct wireless_dev *wdev,
|
||||
@ -329,7 +362,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work);
|
||||
|
||||
static inline bool iwl_fw_dbg_type_on(struct iwl_fw_runtime *fwrt, u32 type)
|
||||
{
|
||||
return (fwrt->fw->dbg.dump_mask & BIT(type));
|
||||
return (fwrt->fw->dbg.dump_mask & BIT(type) || fwrt->trans->ini_valid);
|
||||
}
|
||||
|
||||
static inline bool iwl_fw_dbg_is_d3_debug_enabled(struct iwl_fw_runtime *fwrt)
|
||||
|
@ -249,6 +249,7 @@ struct iwl_fw_error_dump_prph {
|
||||
enum iwl_fw_error_dump_mem_type {
|
||||
IWL_FW_ERROR_DUMP_MEM_SRAM,
|
||||
IWL_FW_ERROR_DUMP_MEM_SMEM,
|
||||
IWL_FW_ERROR_DUMP_MEM_NAMED_MEM = 10,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -263,6 +264,22 @@ struct iwl_fw_error_dump_mem {
|
||||
u8 data[];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_fw_error_dump_named_mem - chunk of memory
|
||||
* @type: &enum iwl_fw_error_dump_mem_type
|
||||
* @offset: the offset from which the memory was read
|
||||
* @name_len: name length
|
||||
* @name: file name
|
||||
* @data: the content of the memory
|
||||
*/
|
||||
struct iwl_fw_error_dump_named_mem {
|
||||
__le32 type;
|
||||
__le32 offset;
|
||||
u8 name_len;
|
||||
u8 name[32];
|
||||
u8 data[];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_fw_error_dump_rb - content of an Receive Buffer
|
||||
* @index: the index of the Receive Buffer in the Rx queue
|
||||
|
@ -138,7 +138,7 @@ struct iwl_fw_runtime {
|
||||
u8 conf;
|
||||
|
||||
/* ts of the beginning of a non-collect fw dbg data period */
|
||||
unsigned long non_collect_ts_start[FW_DBG_TRIGGER_MAX - 1];
|
||||
unsigned long non_collect_ts_start[IWL_FW_TRIGGER_ID_NUM - 1];
|
||||
u32 *d3_debug_data;
|
||||
struct iwl_fw_ini_active_regs active_regs[IWL_FW_INI_MAX_REGION_ID];
|
||||
struct iwl_fw_ini_active_triggers active_trigs[IWL_FW_TRIGGER_ID_NUM];
|
||||
|
@ -265,11 +265,9 @@ struct iwl_tt_params {
|
||||
#define EEPROM_REGULATORY_BAND_NO_HT40 0
|
||||
|
||||
/* lower blocks contain EEPROM image and calibration data */
|
||||
#define OTP_LOW_IMAGE_SIZE (2 * 512 * sizeof(u16)) /* 2 KB */
|
||||
#define OTP_LOW_IMAGE_SIZE_FAMILY_7000 (16 * 512 * sizeof(u16)) /* 16 KB */
|
||||
#define OTP_LOW_IMAGE_SIZE_FAMILY_8000 (32 * 512 * sizeof(u16)) /* 32 KB */
|
||||
#define OTP_LOW_IMAGE_SIZE_FAMILY_9000 OTP_LOW_IMAGE_SIZE_FAMILY_8000
|
||||
#define OTP_LOW_IMAGE_SIZE_FAMILY_22000 OTP_LOW_IMAGE_SIZE_FAMILY_9000
|
||||
#define OTP_LOW_IMAGE_SIZE_2K (2 * 512 * sizeof(u16)) /* 2 KB */
|
||||
#define OTP_LOW_IMAGE_SIZE_16K (16 * 512 * sizeof(u16)) /* 16 KB */
|
||||
#define OTP_LOW_IMAGE_SIZE_32K (32 * 512 * sizeof(u16)) /* 32 KB */
|
||||
|
||||
struct iwl_eeprom_params {
|
||||
const u8 regulatory_bands[7];
|
||||
|
@ -927,22 +927,3 @@ iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg,
|
||||
return NULL;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_parse_eeprom_data);
|
||||
|
||||
/* helper functions */
|
||||
int iwl_nvm_check_version(struct iwl_nvm_data *data,
|
||||
struct iwl_trans *trans)
|
||||
{
|
||||
if (data->nvm_version >= trans->cfg->nvm_ver ||
|
||||
data->calib_version >= trans->cfg->nvm_calib_ver) {
|
||||
IWL_DEBUG_INFO(trans, "device EEPROM VER=0x%x, CALIB=0x%x\n",
|
||||
data->nvm_version, data->calib_version);
|
||||
return 0;
|
||||
}
|
||||
|
||||
IWL_ERR(trans,
|
||||
"Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
|
||||
data->nvm_version, trans->cfg->nvm_ver,
|
||||
data->calib_version, trans->cfg->nvm_calib_ver);
|
||||
return -EINVAL;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_nvm_check_version);
|
||||
|
@ -7,6 +7,7 @@
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2018 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,6 +29,7 @@
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -117,9 +119,6 @@ struct iwl_nvm_data *
|
||||
iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg,
|
||||
const u8 *eeprom, size_t eeprom_size);
|
||||
|
||||
int iwl_nvm_check_version(struct iwl_nvm_data *data,
|
||||
struct iwl_trans *trans);
|
||||
|
||||
int iwl_init_sband_channels(struct iwl_nvm_data *data,
|
||||
struct ieee80211_supported_band *sband,
|
||||
int n_channels, enum nl80211_band band);
|
||||
|
@ -362,6 +362,12 @@
|
||||
#define MON_BUFF_END_ADDR (0xa03c40)
|
||||
#define MON_BUFF_WRPTR (0xa03c44)
|
||||
#define MON_BUFF_CYCLE_CNT (0xa03c48)
|
||||
/* FW monitor family 8000 and on */
|
||||
#define MON_BUFF_BASE_ADDR_VER2 (0xa03c3c)
|
||||
#define MON_BUFF_END_ADDR_VER2 (0xa03c20)
|
||||
#define MON_BUFF_WRPTR_VER2 (0xa03c24)
|
||||
#define MON_BUFF_CYCLE_CNT_VER2 (0xa03c28)
|
||||
#define MON_BUFF_SHIFT_VER2 (0x8)
|
||||
|
||||
#define MON_DMARB_RD_CTL_ADDR (0xa03c60)
|
||||
#define MON_DMARB_RD_DATA_ADDR (0xa03c5c)
|
||||
|
@ -1284,7 +1284,7 @@ static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
|
||||
return 0;
|
||||
|
||||
iwl_fw_dbg_collect(&mvm->fwrt, FW_DBG_TRIGGER_USER, buf,
|
||||
(count - 1), NULL);
|
||||
(count - 1));
|
||||
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE);
|
||||
|
||||
|
@ -547,7 +547,9 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
|
||||
if (mvm->nvm_file_name)
|
||||
iwl_mvm_load_nvm_to_nic(mvm);
|
||||
|
||||
WARN_ON(iwl_nvm_check_version(mvm->nvm_data, mvm->trans));
|
||||
WARN_ONCE(mvm->nvm_data->nvm_version < mvm->trans->cfg->nvm_ver,
|
||||
"Too old NVM version (0x%0x, required = 0x%0x)",
|
||||
mvm->nvm_data->nvm_version, mvm->trans->cfg->nvm_ver);
|
||||
|
||||
/*
|
||||
* abort after reading the nvm in case RF Kill is on, we will complete
|
||||
@ -1018,10 +1020,14 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_EARLY);
|
||||
|
||||
ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_AFTER_ALIVE);
|
||||
|
||||
return iwl_init_paging(&mvm->fwrt, mvm->fwrt.cur_fw_img);
|
||||
}
|
||||
|
||||
@ -1050,11 +1056,13 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
||||
if (ret)
|
||||
IWL_ERR(mvm, "Failed to initialize Smart Fifo\n");
|
||||
|
||||
mvm->fwrt.dump.conf = FW_DBG_INVALID;
|
||||
/* if we have a destination, assume EARLY START */
|
||||
if (mvm->fw->dbg.dest_tlv)
|
||||
mvm->fwrt.dump.conf = FW_DBG_START_FROM_ALIVE;
|
||||
iwl_fw_start_dbg_conf(&mvm->fwrt, FW_DBG_START_FROM_ALIVE);
|
||||
if (!mvm->trans->ini_valid) {
|
||||
mvm->fwrt.dump.conf = FW_DBG_INVALID;
|
||||
/* if we have a destination, assume EARLY START */
|
||||
if (mvm->fw->dbg.dest_tlv)
|
||||
mvm->fwrt.dump.conf = FW_DBG_START_FROM_ALIVE;
|
||||
iwl_fw_start_dbg_conf(&mvm->fwrt, FW_DBG_START_FROM_ALIVE);
|
||||
}
|
||||
|
||||
ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
|
||||
if (ret)
|
||||
|
@ -1532,6 +1532,8 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mvm_beacon_loss_iterator,
|
||||
mb);
|
||||
|
||||
iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_MISSED_BEACONS);
|
||||
}
|
||||
|
||||
void iwl_mvm_rx_stored_beacon_notif(struct iwl_mvm *mvm,
|
||||
|
@ -1129,6 +1129,8 @@ int __iwl_mvm_mac_start(struct iwl_mvm *mvm)
|
||||
}
|
||||
ret = iwl_mvm_up(mvm);
|
||||
|
||||
iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_POST_INIT);
|
||||
|
||||
if (ret && test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
|
||||
/* Something went wrong - we need to finish some cleanup
|
||||
* that normally iwl_mvm_mac_restart_complete() below
|
||||
|
@ -593,31 +593,28 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
|
||||
int hyst = vif->bss_conf.cqm_rssi_hyst;
|
||||
u16 id = le32_to_cpu(data->mac_id);
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
u16 vif_id = mvmvif->id;
|
||||
|
||||
/* This doesn't need the MAC ID check since it's not taking the
|
||||
* data copied into the "data" struct, but rather the data from
|
||||
* the notification directly.
|
||||
*/
|
||||
if (data->general) {
|
||||
u16 vif_id = mvmvif->id;
|
||||
if (iwl_mvm_is_cdb_supported(mvm)) {
|
||||
struct mvm_statistics_general_cdb *general =
|
||||
data->general;
|
||||
|
||||
if (iwl_mvm_is_cdb_supported(mvm)) {
|
||||
struct mvm_statistics_general_cdb *general =
|
||||
data->general;
|
||||
mvmvif->beacon_stats.num_beacons =
|
||||
le32_to_cpu(general->beacon_counter[vif_id]);
|
||||
mvmvif->beacon_stats.avg_signal =
|
||||
-general->beacon_average_energy[vif_id];
|
||||
} else {
|
||||
struct mvm_statistics_general_v8 *general =
|
||||
data->general;
|
||||
|
||||
mvmvif->beacon_stats.num_beacons =
|
||||
le32_to_cpu(general->beacon_counter[vif_id]);
|
||||
mvmvif->beacon_stats.avg_signal =
|
||||
-general->beacon_average_energy[vif_id];
|
||||
} else {
|
||||
struct mvm_statistics_general_v8 *general =
|
||||
data->general;
|
||||
|
||||
mvmvif->beacon_stats.num_beacons =
|
||||
le32_to_cpu(general->beacon_counter[vif_id]);
|
||||
mvmvif->beacon_stats.avg_signal =
|
||||
-general->beacon_average_energy[vif_id];
|
||||
}
|
||||
mvmvif->beacon_stats.num_beacons =
|
||||
le32_to_cpu(general->beacon_counter[vif_id]);
|
||||
mvmvif->beacon_stats.avg_signal =
|
||||
-general->beacon_average_energy[vif_id];
|
||||
}
|
||||
|
||||
if (mvmvif->id != id)
|
||||
|
@ -863,68 +863,66 @@ static void iwl_mvm_flip_address(u8 *addr)
|
||||
ether_addr_copy(addr, mac_addr);
|
||||
}
|
||||
|
||||
static void iwl_mvm_decode_he_sigb(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_mpdu_desc *desc,
|
||||
u32 rate_n_flags,
|
||||
struct ieee80211_radiotap_he_mu *he_mu)
|
||||
struct iwl_mvm_rx_phy_data {
|
||||
enum iwl_rx_phy_info_type info_type;
|
||||
__le32 d0, d1, d2, d3;
|
||||
__le16 d4;
|
||||
};
|
||||
|
||||
static void iwl_mvm_decode_he_mu_ext(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_rx_phy_data *phy_data,
|
||||
u32 rate_n_flags,
|
||||
struct ieee80211_radiotap_he_mu *he_mu)
|
||||
{
|
||||
u32 sigb0, sigb1;
|
||||
u16 sigb2;
|
||||
u32 phy_data2 = le32_to_cpu(phy_data->d2);
|
||||
u32 phy_data3 = le32_to_cpu(phy_data->d3);
|
||||
u16 phy_data4 = le16_to_cpu(phy_data->d4);
|
||||
|
||||
if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
|
||||
sigb0 = le32_to_cpu(desc->v3.sigb_common0);
|
||||
sigb1 = le32_to_cpu(desc->v3.sigb_common1);
|
||||
} else {
|
||||
sigb0 = le32_to_cpu(desc->v1.sigb_common0);
|
||||
sigb1 = le32_to_cpu(desc->v1.sigb_common1);
|
||||
}
|
||||
|
||||
sigb2 = le16_to_cpu(desc->sigb_common2);
|
||||
|
||||
if (FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH1_CRC_OK, sigb2)) {
|
||||
if (FIELD_GET(IWL_RX_PHY_DATA4_HE_MU_EXT_CH1_CRC_OK, phy_data4)) {
|
||||
he_mu->flags1 |=
|
||||
cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_RU_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU_KNOWN);
|
||||
|
||||
he_mu->flags1 |=
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH1_CTR_RU,
|
||||
sigb2),
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_PHY_DATA4_HE_MU_EXT_CH1_CTR_RU,
|
||||
phy_data4),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU);
|
||||
|
||||
he_mu->ru_ch1[0] = FIELD_GET(IWL_RX_HE_SIGB_COMMON0_CH1_RU0,
|
||||
sigb0);
|
||||
he_mu->ru_ch1[1] = FIELD_GET(IWL_RX_HE_SIGB_COMMON1_CH1_RU1,
|
||||
sigb1);
|
||||
he_mu->ru_ch1[2] = FIELD_GET(IWL_RX_HE_SIGB_COMMON0_CH1_RU2,
|
||||
sigb0);
|
||||
he_mu->ru_ch1[3] = FIELD_GET(IWL_RX_HE_SIGB_COMMON1_CH1_RU3,
|
||||
sigb1);
|
||||
he_mu->ru_ch1[0] = FIELD_GET(IWL_RX_PHY_DATA2_HE_MU_EXT_CH1_RU0,
|
||||
phy_data2);
|
||||
he_mu->ru_ch1[1] = FIELD_GET(IWL_RX_PHY_DATA3_HE_MU_EXT_CH1_RU1,
|
||||
phy_data3);
|
||||
he_mu->ru_ch1[2] = FIELD_GET(IWL_RX_PHY_DATA2_HE_MU_EXT_CH1_RU2,
|
||||
phy_data2);
|
||||
he_mu->ru_ch1[3] = FIELD_GET(IWL_RX_PHY_DATA3_HE_MU_EXT_CH1_RU3,
|
||||
phy_data3);
|
||||
}
|
||||
|
||||
if (FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH2_CRC_OK, sigb2) &&
|
||||
if (FIELD_GET(IWL_RX_PHY_DATA4_HE_MU_EXT_CH2_CRC_OK, phy_data4) &&
|
||||
(rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) != RATE_MCS_CHAN_WIDTH_20) {
|
||||
he_mu->flags1 |=
|
||||
cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_RU_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_CTR_26T_RU_KNOWN);
|
||||
|
||||
he_mu->flags2 |=
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH2_CTR_RU,
|
||||
sigb2),
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_PHY_DATA4_HE_MU_EXT_CH2_CTR_RU,
|
||||
phy_data4),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS2_CH2_CTR_26T_RU);
|
||||
|
||||
he_mu->ru_ch2[0] = FIELD_GET(IWL_RX_HE_SIGB_COMMON0_CH2_RU0,
|
||||
sigb0);
|
||||
he_mu->ru_ch2[1] = FIELD_GET(IWL_RX_HE_SIGB_COMMON1_CH2_RU1,
|
||||
sigb1);
|
||||
he_mu->ru_ch2[2] = FIELD_GET(IWL_RX_HE_SIGB_COMMON0_CH2_RU2,
|
||||
sigb0);
|
||||
he_mu->ru_ch2[3] = FIELD_GET(IWL_RX_HE_SIGB_COMMON1_CH2_RU3,
|
||||
sigb1);
|
||||
he_mu->ru_ch2[0] = FIELD_GET(IWL_RX_PHY_DATA2_HE_MU_EXT_CH2_RU0,
|
||||
phy_data2);
|
||||
he_mu->ru_ch2[1] = FIELD_GET(IWL_RX_PHY_DATA3_HE_MU_EXT_CH2_RU1,
|
||||
phy_data3);
|
||||
he_mu->ru_ch2[2] = FIELD_GET(IWL_RX_PHY_DATA2_HE_MU_EXT_CH2_RU2,
|
||||
phy_data2);
|
||||
he_mu->ru_ch2[3] = FIELD_GET(IWL_RX_PHY_DATA3_HE_MU_EXT_CH2_RU3,
|
||||
phy_data3);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
iwl_mvm_decode_he_phy_ru_alloc(u64 he_phy_data, u32 rate_n_flags,
|
||||
iwl_mvm_decode_he_phy_ru_alloc(struct iwl_mvm_rx_phy_data *phy_data,
|
||||
u32 rate_n_flags,
|
||||
struct ieee80211_radiotap_he *he,
|
||||
struct ieee80211_radiotap_he_mu *he_mu,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
@ -937,7 +935,7 @@ iwl_mvm_decode_he_phy_ru_alloc(u64 he_phy_data, u32 rate_n_flags,
|
||||
* happen though as management frames where we need
|
||||
* the TSF/timers are not be transmitted in HE-MU.
|
||||
*/
|
||||
u8 ru = FIELD_GET(IWL_RX_HE_PHY_RU_ALLOC_MASK, he_phy_data);
|
||||
u8 ru = le32_get_bits(phy_data->d1, IWL_RX_PHY_DATA1_HE_RU_ALLOC_MASK);
|
||||
u8 offs = 0;
|
||||
|
||||
rx_status->bw = RATE_INFO_BW_HE_RU;
|
||||
@ -976,7 +974,7 @@ iwl_mvm_decode_he_phy_ru_alloc(u64 he_phy_data, u32 rate_n_flags,
|
||||
IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET);
|
||||
he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET_KNOWN);
|
||||
if (he_phy_data & IWL_RX_HE_PHY_RU_ALLOC_SEC80)
|
||||
if (phy_data->d1 & cpu_to_le32(IWL_RX_PHY_DATA1_HE_RU_ALLOC_SEC80))
|
||||
he->data2 |=
|
||||
cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC);
|
||||
|
||||
@ -996,106 +994,122 @@ iwl_mvm_decode_he_phy_ru_alloc(u64 he_phy_data, u32 rate_n_flags,
|
||||
}
|
||||
|
||||
static void iwl_mvm_decode_he_phy_data(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_mpdu_desc *desc,
|
||||
struct iwl_mvm_rx_phy_data *phy_data,
|
||||
struct ieee80211_radiotap_he *he,
|
||||
struct ieee80211_radiotap_he_mu *he_mu,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
u64 he_phy_data, u32 rate_n_flags,
|
||||
int queue)
|
||||
u32 rate_n_flags, int queue)
|
||||
{
|
||||
u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK;
|
||||
bool sigb_data;
|
||||
u16 d1known = IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN;
|
||||
u16 d2known = IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN;
|
||||
|
||||
he->data1 |= cpu_to_le16(d1known);
|
||||
he->data2 |= cpu_to_le16(d2known);
|
||||
he->data3 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_BSS_COLOR_MASK,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR);
|
||||
he->data3 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_UPLINK,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_DATA3_UL_DL);
|
||||
he->data3 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_LDPC_EXT_SYM,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG);
|
||||
he->data4 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SPATIAL_REUSE_MASK,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE);
|
||||
he->data5 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_PRE_FEC_PAD_MASK,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD);
|
||||
he->data5 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_PE_DISAMBIG,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG);
|
||||
he->data6 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_TXOP_DUR_MASK,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_DATA6_TXOP);
|
||||
he->data6 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_DOPPLER,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_DATA6_DOPPLER);
|
||||
|
||||
switch (he_type) {
|
||||
case RATE_MCS_HE_TYPE_MU:
|
||||
he_mu->flags1 |=
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIGB_DCM,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM);
|
||||
he_mu->flags1 |=
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIGB_MCS_MASK,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS);
|
||||
he_mu->flags2 |=
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIBG_SYM_OR_USER_NUM_MASK,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS);
|
||||
he_mu->flags2 |=
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIGB_COMPRESSION,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP);
|
||||
he_mu->flags2 |=
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_PREAMBLE_PUNC_TYPE_MASK,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW);
|
||||
|
||||
sigb_data = FIELD_GET(IWL_RX_HE_PHY_INFO_TYPE_MASK,
|
||||
he_phy_data) ==
|
||||
IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO;
|
||||
if (sigb_data)
|
||||
iwl_mvm_decode_he_sigb(mvm, desc, rate_n_flags, he_mu);
|
||||
switch (phy_data->info_type) {
|
||||
case IWL_RX_PHY_INFO_TYPE_NONE:
|
||||
case IWL_RX_PHY_INFO_TYPE_CCK:
|
||||
case IWL_RX_PHY_INFO_TYPE_OFDM_LGCY:
|
||||
case IWL_RX_PHY_INFO_TYPE_HT:
|
||||
case IWL_RX_PHY_INFO_TYPE_VHT_SU:
|
||||
case IWL_RX_PHY_INFO_TYPE_VHT_MU:
|
||||
return;
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_TB_EXT:
|
||||
he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE2_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE3_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE4_KNOWN);
|
||||
he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE1),
|
||||
IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE1);
|
||||
he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE2),
|
||||
IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE2);
|
||||
he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE3),
|
||||
IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE3);
|
||||
he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE4),
|
||||
IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE4);
|
||||
/* fall through */
|
||||
case RATE_MCS_HE_TYPE_TRIG:
|
||||
he->data2 |=
|
||||
cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN);
|
||||
he->data5 |=
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_HE_LTF_NUM_MASK,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS);
|
||||
break;
|
||||
case RATE_MCS_HE_TYPE_SU:
|
||||
case RATE_MCS_HE_TYPE_EXT_SU:
|
||||
he->data1 |=
|
||||
cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BEAM_CHANGE_KNOWN);
|
||||
he->data3 |=
|
||||
le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_BEAM_CHNG,
|
||||
he_phy_data),
|
||||
IEEE80211_RADIOTAP_HE_DATA3_BEAM_CHANGE);
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_SU:
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_MU:
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_MU_EXT:
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_TB:
|
||||
/* HE common */
|
||||
he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN);
|
||||
he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN);
|
||||
he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA0_HE_BSS_COLOR_MASK),
|
||||
IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR);
|
||||
if (phy_data->info_type != IWL_RX_PHY_INFO_TYPE_HE_TB &&
|
||||
phy_data->info_type != IWL_RX_PHY_INFO_TYPE_HE_TB_EXT) {
|
||||
he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN);
|
||||
he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA0_HE_UPLINK),
|
||||
IEEE80211_RADIOTAP_HE_DATA3_UL_DL);
|
||||
}
|
||||
he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA0_HE_LDPC_EXT_SYM),
|
||||
IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG);
|
||||
he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA0_HE_SPATIAL_REUSE_MASK),
|
||||
IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE);
|
||||
he->data5 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA0_HE_PRE_FEC_PAD_MASK),
|
||||
IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD);
|
||||
he->data5 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA0_HE_PE_DISAMBIG),
|
||||
IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG);
|
||||
he->data5 |= le16_encode_bits(le32_get_bits(phy_data->d1,
|
||||
IWL_RX_PHY_DATA1_HE_LTF_NUM_MASK),
|
||||
IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS);
|
||||
he->data6 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA0_HE_TXOP_DUR_MASK),
|
||||
IEEE80211_RADIOTAP_HE_DATA6_TXOP);
|
||||
he->data6 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA0_HE_DOPPLER),
|
||||
IEEE80211_RADIOTAP_HE_DATA6_DOPPLER);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (FIELD_GET(IWL_RX_HE_PHY_INFO_TYPE_MASK, he_phy_data)) {
|
||||
case IWL_RX_HE_PHY_INFO_TYPE_MU:
|
||||
case IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO:
|
||||
case IWL_RX_HE_PHY_INFO_TYPE_TB:
|
||||
iwl_mvm_decode_he_phy_ru_alloc(he_phy_data, rate_n_flags,
|
||||
switch (phy_data->info_type) {
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_MU_EXT:
|
||||
he_mu->flags1 |=
|
||||
le16_encode_bits(le16_get_bits(phy_data->d4,
|
||||
IWL_RX_PHY_DATA4_HE_MU_EXT_SIGB_DCM),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM);
|
||||
he_mu->flags1 |=
|
||||
le16_encode_bits(le16_get_bits(phy_data->d4,
|
||||
IWL_RX_PHY_DATA4_HE_MU_EXT_SIGB_MCS_MASK),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS);
|
||||
he_mu->flags2 |=
|
||||
le16_encode_bits(le16_get_bits(phy_data->d4,
|
||||
IWL_RX_PHY_DATA4_HE_MU_EXT_PREAMBLE_PUNC_TYPE_MASK),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW);
|
||||
iwl_mvm_decode_he_mu_ext(mvm, phy_data, rate_n_flags, he_mu);
|
||||
/* fall through */
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_MU:
|
||||
he_mu->flags2 |=
|
||||
le16_encode_bits(le32_get_bits(phy_data->d1,
|
||||
IWL_RX_PHY_DATA1_HE_MU_SIBG_SYM_OR_USER_NUM_MASK),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS);
|
||||
he_mu->flags2 |=
|
||||
le16_encode_bits(le32_get_bits(phy_data->d1,
|
||||
IWL_RX_PHY_DATA1_HE_MU_SIGB_COMPRESSION),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP);
|
||||
/* fall through */
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_TB:
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_TB_EXT:
|
||||
iwl_mvm_decode_he_phy_ru_alloc(phy_data, rate_n_flags,
|
||||
he, he_mu, rx_status);
|
||||
break;
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_SU:
|
||||
he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BEAM_CHANGE_KNOWN);
|
||||
he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0,
|
||||
IWL_RX_PHY_DATA0_HE_BEAM_CHNG),
|
||||
IEEE80211_RADIOTAP_HE_DATA3_BEAM_CHANGE);
|
||||
break;
|
||||
default:
|
||||
/* nothing */
|
||||
break;
|
||||
@ -1103,13 +1117,10 @@ static void iwl_mvm_decode_he_phy_data(struct iwl_mvm *mvm,
|
||||
}
|
||||
|
||||
static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
struct iwl_rx_mpdu_desc *desc,
|
||||
struct iwl_mvm_rx_phy_data *phy_data,
|
||||
u32 rate_n_flags, u16 phy_info, int queue)
|
||||
{
|
||||
struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
|
||||
/* this is invalid e.g. because puncture type doesn't allow 0b11 */
|
||||
#define HE_PHY_DATA_INVAL ((u64)-1)
|
||||
u64 he_phy_data = HE_PHY_DATA_INVAL;
|
||||
struct ieee80211_radiotap_he *he = NULL;
|
||||
struct ieee80211_radiotap_he_mu *he_mu = NULL;
|
||||
u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK;
|
||||
@ -1136,49 +1147,41 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
radiotap_len += sizeof(known);
|
||||
rx_status->flag |= RX_FLAG_RADIOTAP_HE;
|
||||
|
||||
if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) {
|
||||
if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
|
||||
he_phy_data = le64_to_cpu(desc->v3.he_phy_data);
|
||||
else
|
||||
he_phy_data = le64_to_cpu(desc->v1.he_phy_data);
|
||||
|
||||
if (he_type == RATE_MCS_HE_TYPE_MU) {
|
||||
he_mu = skb_put_data(skb, &mu_known, sizeof(mu_known));
|
||||
radiotap_len += sizeof(mu_known);
|
||||
rx_status->flag |= RX_FLAG_RADIOTAP_HE_MU;
|
||||
}
|
||||
if (phy_data->info_type == IWL_RX_PHY_INFO_TYPE_HE_MU ||
|
||||
phy_data->info_type == IWL_RX_PHY_INFO_TYPE_HE_MU_EXT) {
|
||||
he_mu = skb_put_data(skb, &mu_known, sizeof(mu_known));
|
||||
radiotap_len += sizeof(mu_known);
|
||||
rx_status->flag |= RX_FLAG_RADIOTAP_HE_MU;
|
||||
}
|
||||
|
||||
/* temporarily hide the radiotap data */
|
||||
__skb_pull(skb, radiotap_len);
|
||||
|
||||
if (he_phy_data != HE_PHY_DATA_INVAL &&
|
||||
he_type == RATE_MCS_HE_TYPE_SU) {
|
||||
if (phy_data->info_type == IWL_RX_PHY_INFO_TYPE_HE_SU) {
|
||||
/* report the AMPDU-EOF bit on single frames */
|
||||
if (!queue && !(phy_info & IWL_RX_MPDU_PHY_AMPDU)) {
|
||||
rx_status->flag |= RX_FLAG_AMPDU_DETAILS;
|
||||
rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN;
|
||||
if (FIELD_GET(IWL_RX_HE_PHY_DELIM_EOF, he_phy_data))
|
||||
if (phy_data->d0 & cpu_to_le32(IWL_RX_PHY_DATA0_HE_DELIM_EOF))
|
||||
rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
if (he_phy_data != HE_PHY_DATA_INVAL)
|
||||
iwl_mvm_decode_he_phy_data(mvm, desc, he, he_mu, rx_status,
|
||||
he_phy_data, rate_n_flags, queue);
|
||||
if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD)
|
||||
iwl_mvm_decode_he_phy_data(mvm, phy_data, he, he_mu, rx_status,
|
||||
rate_n_flags, queue);
|
||||
|
||||
/* update aggregation data for monitor sake on default queue */
|
||||
if (!queue && (phy_info & IWL_RX_MPDU_PHY_AMPDU)) {
|
||||
if (!queue && (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) &&
|
||||
(phy_info & IWL_RX_MPDU_PHY_AMPDU)) {
|
||||
bool toggle_bit = phy_info & IWL_RX_MPDU_PHY_AMPDU_TOGGLE;
|
||||
|
||||
/* toggle is switched whenever new aggregation starts */
|
||||
if (toggle_bit != mvm->ampdu_toggle &&
|
||||
he_phy_data != HE_PHY_DATA_INVAL &&
|
||||
(he_type == RATE_MCS_HE_TYPE_MU ||
|
||||
he_type == RATE_MCS_HE_TYPE_SU)) {
|
||||
rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN;
|
||||
if (FIELD_GET(IWL_RX_HE_PHY_DELIM_EOF,
|
||||
he_phy_data))
|
||||
if (phy_data->d0 & cpu_to_le32(IWL_RX_PHY_DATA0_HE_DELIM_EOF))
|
||||
rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT;
|
||||
}
|
||||
}
|
||||
@ -1261,43 +1264,34 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
break;
|
||||
}
|
||||
|
||||
he->data5 |= le16_encode_bits(ltf, IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE);
|
||||
he->data5 |= le16_encode_bits(ltf,
|
||||
IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE);
|
||||
}
|
||||
|
||||
if (he_type == RATE_MCS_HE_TYPE_SU ||
|
||||
he_type == RATE_MCS_HE_TYPE_EXT_SU) {
|
||||
u16 val;
|
||||
static void iwl_mvm_decode_lsig(struct sk_buff *skb,
|
||||
struct iwl_mvm_rx_phy_data *phy_data)
|
||||
{
|
||||
struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
|
||||
struct ieee80211_radiotap_lsig *lsig;
|
||||
|
||||
/* LTF syms correspond to streams */
|
||||
he->data2 |=
|
||||
cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN);
|
||||
switch (rx_status->nss) {
|
||||
case 1:
|
||||
val = 0;
|
||||
break;
|
||||
case 2:
|
||||
val = 1;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
val = 2;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
val = 3;
|
||||
break;
|
||||
case 7:
|
||||
case 8:
|
||||
val = 4;
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(1, "invalid nss: %d\n",
|
||||
rx_status->nss);
|
||||
val = 0;
|
||||
}
|
||||
|
||||
he->data5 |=
|
||||
le16_encode_bits(val,
|
||||
IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS);
|
||||
switch (phy_data->info_type) {
|
||||
case IWL_RX_PHY_INFO_TYPE_HT:
|
||||
case IWL_RX_PHY_INFO_TYPE_VHT_SU:
|
||||
case IWL_RX_PHY_INFO_TYPE_VHT_MU:
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_TB_EXT:
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_SU:
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_MU:
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_MU_EXT:
|
||||
case IWL_RX_PHY_INFO_TYPE_HE_TB:
|
||||
lsig = skb_put(skb, sizeof(*lsig));
|
||||
lsig->data1 = cpu_to_le16(IEEE80211_RADIOTAP_LSIG_DATA1_LENGTH_KNOWN);
|
||||
lsig->data2 = le16_encode_bits(le32_get_bits(phy_data->d1,
|
||||
IWL_RX_PHY_DATA1_LSIG_LEN_MASK),
|
||||
IEEE80211_RADIOTAP_LSIG_DATA2_LENGTH);
|
||||
rx_status->flag |= RX_FLAG_RADIOTAP_LSIG;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1315,6 +1309,10 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct sk_buff *skb;
|
||||
u8 crypt_len = 0, channel, energy_a, energy_b;
|
||||
size_t desc_size;
|
||||
struct iwl_mvm_rx_phy_data phy_data = {
|
||||
.d4 = desc->phy_data4,
|
||||
.info_type = IWL_RX_PHY_INFO_TYPE_NONE,
|
||||
};
|
||||
|
||||
if (unlikely(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)))
|
||||
return;
|
||||
@ -1326,6 +1324,11 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
energy_a = desc->v3.energy_a;
|
||||
energy_b = desc->v3.energy_b;
|
||||
desc_size = sizeof(*desc);
|
||||
|
||||
phy_data.d0 = desc->v3.phy_data0;
|
||||
phy_data.d1 = desc->v3.phy_data1;
|
||||
phy_data.d2 = desc->v3.phy_data2;
|
||||
phy_data.d3 = desc->v3.phy_data3;
|
||||
} else {
|
||||
rate_n_flags = le32_to_cpu(desc->v1.rate_n_flags);
|
||||
channel = desc->v1.channel;
|
||||
@ -1333,8 +1336,18 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
energy_a = desc->v1.energy_a;
|
||||
energy_b = desc->v1.energy_b;
|
||||
desc_size = IWL_RX_DESC_SIZE_V1;
|
||||
|
||||
phy_data.d0 = desc->v1.phy_data0;
|
||||
phy_data.d1 = desc->v1.phy_data1;
|
||||
phy_data.d2 = desc->v1.phy_data2;
|
||||
phy_data.d3 = desc->v1.phy_data3;
|
||||
}
|
||||
|
||||
if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD)
|
||||
phy_data.info_type =
|
||||
le32_get_bits(phy_data.d1,
|
||||
IWL_RX_PHY_DATA1_INFO_TYPE_MASK);
|
||||
|
||||
hdr = (void *)(pkt->data + desc_size);
|
||||
/* Dont use dev_alloc_skb(), we'll have enough headroom once
|
||||
* ieee80211_hdr pulled.
|
||||
@ -1373,7 +1386,10 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
}
|
||||
|
||||
if (rate_n_flags & RATE_MCS_HE_MSK)
|
||||
iwl_mvm_rx_he(mvm, skb, desc, rate_n_flags, phy_info, queue);
|
||||
iwl_mvm_rx_he(mvm, skb, &phy_data, rate_n_flags,
|
||||
phy_info, queue);
|
||||
|
||||
iwl_mvm_decode_lsig(skb, &phy_data);
|
||||
|
||||
rx_status = IEEE80211_SKB_RXCB(skb);
|
||||
|
||||
|
@ -1893,6 +1893,8 @@ 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,
|
||||
|
@ -1378,6 +1378,7 @@ void iwl_mvm_pause_tcm(struct iwl_mvm *mvm, bool with_cancel)
|
||||
void iwl_mvm_resume_tcm(struct iwl_mvm *mvm)
|
||||
{
|
||||
int mac;
|
||||
bool low_latency = false;
|
||||
|
||||
spin_lock_bh(&mvm->tcm.lock);
|
||||
mvm->tcm.ts = jiffies;
|
||||
@ -1389,10 +1390,23 @@ void iwl_mvm_resume_tcm(struct iwl_mvm *mvm)
|
||||
memset(&mdata->tx.pkts, 0, sizeof(mdata->tx.pkts));
|
||||
memset(&mdata->rx.airtime, 0, sizeof(mdata->rx.airtime));
|
||||
memset(&mdata->tx.airtime, 0, sizeof(mdata->tx.airtime));
|
||||
|
||||
if (mvm->tcm.result.low_latency[mac])
|
||||
low_latency = true;
|
||||
}
|
||||
/* The TCM data needs to be reset before "paused" flag changes */
|
||||
smp_mb();
|
||||
mvm->tcm.paused = false;
|
||||
|
||||
/*
|
||||
* if the current load is not low or low latency is active, force
|
||||
* re-evaluation to cover the case of no traffic.
|
||||
*/
|
||||
if (mvm->tcm.result.global_load > IWL_MVM_TRAFFIC_LOW)
|
||||
schedule_delayed_work(&mvm->tcm.work, MVM_TCM_PERIOD);
|
||||
else if (low_latency)
|
||||
schedule_delayed_work(&mvm->tcm.work, MVM_LL_PERIOD);
|
||||
|
||||
spin_unlock_bh(&mvm->tcm.lock);
|
||||
}
|
||||
|
||||
|
@ -94,11 +94,14 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
|
||||
cpu_to_le64(trans_pcie->rxq->bd_dma);
|
||||
|
||||
/* Configure debug, for integration */
|
||||
iwl_pcie_alloc_fw_monitor(trans, 0);
|
||||
prph_sc_ctrl->hwm_cfg.hwm_base_addr =
|
||||
cpu_to_le64(trans->fw_mon[0].physical);
|
||||
prph_sc_ctrl->hwm_cfg.hwm_size =
|
||||
cpu_to_le32(trans->fw_mon[0].size);
|
||||
if (!trans->ini_valid)
|
||||
iwl_pcie_alloc_fw_monitor(trans, 0);
|
||||
if (trans->num_blocks) {
|
||||
prph_sc_ctrl->hwm_cfg.hwm_base_addr =
|
||||
cpu_to_le64(trans->fw_mon[0].physical);
|
||||
prph_sc_ctrl->hwm_cfg.hwm_size =
|
||||
cpu_to_le32(trans->fw_mon[0].size);
|
||||
}
|
||||
|
||||
/* allocate ucode sections in dram and set addresses */
|
||||
ret = iwl_pcie_init_fw_sec(trans, fw, &prph_scratch->dram);
|
||||
|
@ -227,7 +227,7 @@ int iwl_pcie_ctxt_info_init(struct iwl_trans *trans,
|
||||
iwl_enable_interrupts(trans);
|
||||
|
||||
/* Configure debug, if exists */
|
||||
if (trans->dbg_dest_tlv)
|
||||
if (iwl_pcie_dbg_on(trans))
|
||||
iwl_pcie_apply_destination(trans);
|
||||
|
||||
/* kick FW self load */
|
||||
|
@ -1009,6 +1009,11 @@ static inline void __iwl_trans_pcie_set_bit(struct iwl_trans *trans,
|
||||
__iwl_trans_pcie_set_bits_mask(trans, reg, mask, mask);
|
||||
}
|
||||
|
||||
static inline bool iwl_pcie_dbg_on(struct iwl_trans *trans)
|
||||
{
|
||||
return (trans->dbg_dest_tlv || trans->ini_valid);
|
||||
}
|
||||
|
||||
void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state);
|
||||
void iwl_trans_pcie_dump_regs(struct iwl_trans *trans);
|
||||
|
||||
|
@ -924,6 +924,20 @@ 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->ini_valid) {
|
||||
if (!trans->num_blocks)
|
||||
return;
|
||||
|
||||
iwl_write_prph(trans, MON_BUFF_BASE_ADDR_VER2,
|
||||
trans->fw_mon[0].physical >>
|
||||
MON_BUFF_SHIFT_VER2);
|
||||
iwl_write_prph(trans, MON_BUFF_END_ADDR_VER2,
|
||||
(trans->fw_mon[0].physical +
|
||||
trans->fw_mon[0].size - 256) >>
|
||||
MON_BUFF_SHIFT_VER2);
|
||||
return;
|
||||
}
|
||||
|
||||
IWL_INFO(trans, "Applying debug destination %s\n",
|
||||
get_fw_dbg_mode_string(dest->monitor_mode));
|
||||
|
||||
@ -1026,7 +1040,7 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
|
||||
(trans->fw_mon[0].physical +
|
||||
trans->fw_mon[0].size) >> 4);
|
||||
}
|
||||
} else if (trans->dbg_dest_tlv) {
|
||||
} else if (iwl_pcie_dbg_on(trans)) {
|
||||
iwl_pcie_apply_destination(trans);
|
||||
}
|
||||
|
||||
@ -1047,7 +1061,7 @@ static int iwl_pcie_load_given_ucode_8000(struct iwl_trans *trans,
|
||||
IWL_DEBUG_FW(trans, "working with %s CPU\n",
|
||||
image->is_dual_cpus ? "Dual" : "Single");
|
||||
|
||||
if (trans->dbg_dest_tlv)
|
||||
if (iwl_pcie_dbg_on(trans))
|
||||
iwl_pcie_apply_destination(trans);
|
||||
|
||||
IWL_DEBUG_POWER(trans, "Original WFPM value = 0x%08X\n",
|
||||
@ -3015,6 +3029,34 @@ iwl_trans_pci_dump_marbh_monitor(struct iwl_trans *trans,
|
||||
return monitor_len;
|
||||
}
|
||||
|
||||
static void
|
||||
iwl_trans_pcie_dump_pointers(struct iwl_trans *trans,
|
||||
struct iwl_fw_error_dump_fw_mon *fw_mon_data)
|
||||
{
|
||||
u32 base, write_ptr, wrap_cnt;
|
||||
|
||||
/* If there was a dest TLV - use the values from there */
|
||||
if (trans->ini_valid) {
|
||||
base = MON_BUFF_BASE_ADDR_VER2;
|
||||
write_ptr = MON_BUFF_WRPTR_VER2;
|
||||
wrap_cnt = MON_BUFF_CYCLE_CNT_VER2;
|
||||
} else if (trans->dbg_dest_tlv) {
|
||||
write_ptr = le32_to_cpu(trans->dbg_dest_tlv->write_ptr_reg);
|
||||
wrap_cnt = le32_to_cpu(trans->dbg_dest_tlv->wrap_count);
|
||||
base = le32_to_cpu(trans->dbg_dest_tlv->base_reg);
|
||||
} else {
|
||||
base = MON_BUFF_BASE_ADDR;
|
||||
write_ptr = MON_BUFF_WRPTR;
|
||||
wrap_cnt = MON_BUFF_CYCLE_CNT;
|
||||
}
|
||||
fw_mon_data->fw_mon_wr_ptr =
|
||||
cpu_to_le32(iwl_read_prph(trans, write_ptr));
|
||||
fw_mon_data->fw_mon_cycle_cnt =
|
||||
cpu_to_le32(iwl_read_prph(trans, wrap_cnt));
|
||||
fw_mon_data->fw_mon_base_ptr =
|
||||
cpu_to_le32(iwl_read_prph(trans, base));
|
||||
}
|
||||
|
||||
static u32
|
||||
iwl_trans_pcie_dump_monitor(struct iwl_trans *trans,
|
||||
struct iwl_fw_error_dump_data **data,
|
||||
@ -3024,30 +3066,14 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans,
|
||||
|
||||
if ((trans->num_blocks &&
|
||||
trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) ||
|
||||
trans->dbg_dest_tlv) {
|
||||
(trans->dbg_dest_tlv && !trans->ini_valid) ||
|
||||
(trans->ini_valid && trans->num_blocks)) {
|
||||
struct iwl_fw_error_dump_fw_mon *fw_mon_data;
|
||||
u32 base, write_ptr, wrap_cnt;
|
||||
|
||||
/* If there was a dest TLV - use the values from there */
|
||||
if (trans->dbg_dest_tlv) {
|
||||
write_ptr =
|
||||
le32_to_cpu(trans->dbg_dest_tlv->write_ptr_reg);
|
||||
wrap_cnt = le32_to_cpu(trans->dbg_dest_tlv->wrap_count);
|
||||
base = le32_to_cpu(trans->dbg_dest_tlv->base_reg);
|
||||
} else {
|
||||
base = MON_BUFF_BASE_ADDR;
|
||||
write_ptr = MON_BUFF_WRPTR;
|
||||
wrap_cnt = MON_BUFF_CYCLE_CNT;
|
||||
}
|
||||
|
||||
(*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_FW_MONITOR);
|
||||
fw_mon_data = (void *)(*data)->data;
|
||||
fw_mon_data->fw_mon_wr_ptr =
|
||||
cpu_to_le32(iwl_read_prph(trans, write_ptr));
|
||||
fw_mon_data->fw_mon_cycle_cnt =
|
||||
cpu_to_le32(iwl_read_prph(trans, wrap_cnt));
|
||||
fw_mon_data->fw_mon_base_ptr =
|
||||
cpu_to_le32(iwl_read_prph(trans, base));
|
||||
|
||||
iwl_trans_pcie_dump_pointers(trans, fw_mon_data);
|
||||
|
||||
len += sizeof(**data) + sizeof(*fw_mon_data);
|
||||
if (trans->num_blocks) {
|
||||
@ -3057,6 +3083,7 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans,
|
||||
|
||||
monitor_len = trans->fw_mon[0].size;
|
||||
} else if (trans->dbg_dest_tlv->monitor_mode == SMEM_MODE) {
|
||||
u32 base = le32_to_cpu(fw_mon_data->fw_mon_base_ptr);
|
||||
/*
|
||||
* Update pointers to reflect actual values after
|
||||
* shifting
|
||||
|
@ -583,18 +583,6 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb,
|
||||
|
||||
spin_lock(&txq->lock);
|
||||
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
|
||||
struct iwl_tx_cmd_gen3 *tx_cmd_gen3 =
|
||||
(void *)dev_cmd->payload;
|
||||
|
||||
cmd_len = le16_to_cpu(tx_cmd_gen3->len);
|
||||
} else {
|
||||
struct iwl_tx_cmd_gen2 *tx_cmd_gen2 =
|
||||
(void *)dev_cmd->payload;
|
||||
|
||||
cmd_len = le16_to_cpu(tx_cmd_gen2->len);
|
||||
}
|
||||
|
||||
if (iwl_queue_space(trans, txq) < txq->high_mark) {
|
||||
iwl_stop_queue(trans, txq);
|
||||
|
||||
@ -632,6 +620,18 @@ 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) {
|
||||
struct iwl_tx_cmd_gen3 *tx_cmd_gen3 =
|
||||
(void *)dev_cmd->payload;
|
||||
|
||||
cmd_len = le16_to_cpu(tx_cmd_gen3->len);
|
||||
} else {
|
||||
struct iwl_tx_cmd_gen2 *tx_cmd_gen2 =
|
||||
(void *)dev_cmd->payload;
|
||||
|
||||
cmd_len = le16_to_cpu(tx_cmd_gen2->len);
|
||||
}
|
||||
|
||||
/* Set up entry for this TFD in Tx byte-count array */
|
||||
iwl_pcie_gen2_update_byte_tbl(trans_pcie, txq, cmd_len,
|
||||
iwl_pcie_gen2_get_num_tbs(trans, tfd));
|
||||
|
@ -1245,11 +1245,11 @@ void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
|
||||
|
||||
if (idx >= trans->cfg->base_params->max_tfd_queue_size ||
|
||||
(!iwl_queue_used(txq, idx))) {
|
||||
IWL_ERR(trans,
|
||||
"%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,
|
||||
txq->write_ptr, txq->read_ptr);
|
||||
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,
|
||||
txq->write_ptr, txq->read_ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user