first set of iwlwifi patches for v5.17

* A few mei fixes;
 * Some improvements in D3;
 * Support for new FW API commands;
 * Fixes and cleanups in device configurations;
 * Support some new FW API command versions;
 * Fix WGDS revision 3 reading bug;
 * Some firmware debugging improvements;
 * Fixes for in device configuration structures;
 * Improvements in the session protection code;
 * Support SAR GEO Offset Mapping (SGOM) via BIOS;
 * Continued work on the new Bz device family;
 * Some more firmware debugging improvements;
 * Support new FW API version 68;
 * Add some new device IDs;
 * Some other small fixes, clean-ups and improvements.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEF3LNfgb2BPWm68smoUecoho8xfoFAmGwdr4ACgkQoUecoho8
 xfrRjg/9Ffb5e5xIaRW01WCYuF+KUes9fxVTYmniv/5LiN5cUOADUXx5EkkBiM2v
 TbHOLil1YvUgpfdGk75Hp2QwGLuEvhiLBxenCPKDKiWb3cCoB/0X3R0PglBGkCuT
 jGSQF6kVnws6acobUozgua7iuBrng2kWgCZ50LpmxOjWYteBA1SYqIP9ywVLEHLi
 G0MX23gbVwsUKgukyfS2C5vRpUnYoyZ585vztUY7+527MM/07l9srDYUZ1hHW8hR
 ypXN44h+2zyeoufXmob8KY3noCp+h6KE8wlv5qVQjgwY+Zp2UfIGGnHR06fk2O3i
 01JKFxlCx+6AyU7wJHvHlPd12EtiCwRdDey+29/QKxuU6jpV1k11sNxXoKQeP4Ol
 5sSh1p1r9AVzo9F3wNkmyEukYyrMe52f+cP44Zvo5+GoMeSvp1VbNpxcVMQLSBIA
 ZR4MInMaFi6YeWknNll/hzeQEhOlo/QpPhnENeN9K3i5Aa8af9sOIR14CBDi27Ed
 FcQz83SxC0hmkepLaibEO8QHHFBNOHm2/iugSoUrKj0cmsyUuDthxPCo5FrJTS+k
 KJbtH7OS5wXWCz0lML+uNCGcZXszV12malaedTtqtgl9Q3/mPuCQy1tRmVpQ/kTE
 aMcxIX9MsPy8534x2kdpcpWwwi3iWLafl7QuMiHMjhRG+Thg+5U=
 =tgbw
 -----END PGP SIGNATURE-----

Merge tag 'iwlwifi-next-for-kalle-2021-12-08' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next

first set of iwlwifi patches for v5.17

* A few mei fixes;
* Some improvements in D3;
* Support for new FW API commands;
* Fixes and cleanups in device configurations;
* Support some new FW API command versions;
* Fix WGDS revision 3 reading bug;
* Some firmware debugging improvements;
* Fixes for in device configuration structures;
* Improvements in the session protection code;
* Support SAR GEO Offset Mapping (SGOM) via BIOS;
* Continued work on the new Bz device family;
* Some more firmware debugging improvements;
* Support new FW API version 68;
* Add some new device IDs;
* Some other small fixes, clean-ups and improvements.
This commit is contained in:
Kalle Valo 2021-12-16 10:25:12 +02:00
Родитель 4d375c2e51 977df8bd58
Коммит f06bd8a147
50 изменённых файлов: 1321 добавлений и 354 удалений

Просмотреть файл

@ -2,6 +2,7 @@
config IWLWIFI
tristate "Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlwifi) "
depends on PCI && HAS_IOMEM && CFG80211
depends on IWLMEI || !IWLMEI
select FW_LOADER
help
Select to build the driver supporting the:
@ -92,32 +93,6 @@ config IWLWIFI_BCAST_FILTERING
If unsure, don't enable this option, as some programs might
expect incoming broadcasts for their normal operations.
config IWLMEI
tristate "Intel Management Engine communication over WLAN"
depends on INTEL_MEI
depends on PM
depends on IWLMVM
help
Enables the iwlmei kernel module.
CSME stands for Converged Security and Management Engine. It is a CPU
on the chipset and runs a dedicated firmware. AMT (Active Management
Technology) is one of the applications that run on that CPU. AMT
allows to control the platform remotely.
This kernel module allows to communicate with the Intel Management
Engine over Wifi. This is supported starting from Tiger Lake
platforms and has been tested on 9260 devices only.
If AMT is configured not to use the wireless device, this module is
harmless (and useless).
Enabling this option on a platform that has a different device and
has Wireless enabled on AMT can prevent WiFi from working correctly.
For more information see
<https://software.intel.com/en-us/manageability/>
If unsure, say N.
menu "Debugging Options"
config IWLWIFI_DEBUG
@ -172,3 +147,28 @@ config IWLWIFI_DEVICE_TRACING
endmenu
endif
config IWLMEI
tristate "Intel Management Engine communication over WLAN"
depends on INTEL_MEI
depends on PM
help
Enables the iwlmei kernel module.
CSME stands for Converged Security and Management Engine. It is a CPU
on the chipset and runs a dedicated firmware. AMT (Active Management
Technology) is one of the applications that run on that CPU. AMT
allows to control the platform remotely.
This kernel module allows to communicate with the Intel Management
Engine over Wifi. This is supported starting from Tiger Lake
platforms and has been tested on 9260 devices only.
If AMT is configured not to use the wireless device, this module is
harmless (and useless).
Enabling this option on a platform that has a different device and
has Wireless enabled on AMT can prevent WiFi from working correctly.
For more information see
<https://software.intel.com/en-us/manageability/>
If unsure, say N.

Просмотреть файл

@ -9,7 +9,7 @@
#include "iwl-prph.h"
/* Highest firmware API version supported */
#define IWL_22000_UCODE_API_MAX 67
#define IWL_22000_UCODE_API_MAX 68
/* Lowest firmware API version supported */
#define IWL_22000_UCODE_API_MIN 39
@ -54,7 +54,8 @@
#define IWL_BZ_A_GF4_A_FW_PRE "iwlwifi-bz-a0-gf4-a0-"
#define IWL_BZ_A_MR_A_FW_PRE "iwlwifi-bz-a0-mr-a0-"
#define IWL_BZ_A_FM_A_FW_PRE "iwlwifi-bz-a0-fm-a0-"
#define IWL_GL_A_FM_A_FW_PRE "iwlwifi-gl-a0-fm7-a0-"
#define IWL_GL_A_FM_A_FW_PRE "iwlwifi-gl-a0-fm-a0-"
#define IWL_BZ_Z_GF_A_FW_PRE "iwlwifi-bz-z0-gf-a0-"
#define IWL_QU_B_HR_B_MODULE_FIRMWARE(api) \
@ -113,6 +114,8 @@
IWL_BZ_A_FM_A_FW_PRE __stringify(api) ".ucode"
#define IWL_GL_A_FM_A_MODULE_FIRMWARE(api) \
IWL_GL_A_FM_A_FW_PRE __stringify(api) ".ucode"
#define IWL_BZ_Z_GF_A_MODULE_FIRMWARE(api) \
IWL_BZ_Z_GF_A_FW_PRE __stringify(api) ".ucode"
static const struct iwl_base_params iwl_22000_base_params = {
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
@ -626,7 +629,7 @@ const struct iwl_cfg iwl_ax200_cfg_cc = {
};
const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0 = {
.name = "Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW)",
.name = "Killer(R) Wi-Fi 6 AX1650s 160MHz Wireless Network Adapter (201NGW)",
.fw_name_pre = IWL_QU_B_HR_B_FW_PRE,
IWL_DEVICE_22500,
/*
@ -639,7 +642,7 @@ const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0 = {
};
const struct iwl_cfg killer1650i_2ax_cfg_qu_b0_hr_b0 = {
.name = "Killer(R) Wi-Fi 6 AX1650s 160MHz Wireless Network Adapter (201D2W)",
.name = "Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201D2W)",
.fw_name_pre = IWL_QU_B_HR_B_FW_PRE,
IWL_DEVICE_22500,
/*
@ -652,7 +655,7 @@ const struct iwl_cfg killer1650i_2ax_cfg_qu_b0_hr_b0 = {
};
const struct iwl_cfg killer1650s_2ax_cfg_qu_c0_hr_b0 = {
.name = "Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW)",
.name = "Killer(R) Wi-Fi 6 AX1650s 160MHz Wireless Network Adapter (201NGW)",
.fw_name_pre = IWL_QU_C_HR_B_FW_PRE,
IWL_DEVICE_22500,
/*
@ -665,7 +668,7 @@ const struct iwl_cfg killer1650s_2ax_cfg_qu_c0_hr_b0 = {
};
const struct iwl_cfg killer1650i_2ax_cfg_qu_c0_hr_b0 = {
.name = "Killer(R) Wi-Fi 6 AX1650s 160MHz Wireless Network Adapter (201D2W)",
.name = "Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201D2W)",
.fw_name_pre = IWL_QU_C_HR_B_FW_PRE,
IWL_DEVICE_22500,
/*
@ -696,13 +699,6 @@ const struct iwl_cfg iwlax210_2ax_cfg_so_jf_b0 = {
.num_rbds = IWL_NUM_RBDS_NON_HE,
};
const struct iwl_cfg iwlax210_2ax_cfg_so_hr_a0 = {
.name = "Intel(R) Wi-Fi 6 AX210 160MHz",
.fw_name_pre = IWL_SO_A_HR_B_FW_PRE,
IWL_DEVICE_AX210,
.num_rbds = IWL_NUM_RBDS_AX210_HE,
};
const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0 = {
.name = iwl_ax211_name,
.fw_name_pre = IWL_SO_A_GF_A_FW_PRE,
@ -879,6 +875,13 @@ const struct iwl_cfg iwl_cfg_gl_a0_fm_a0 = {
.num_rbds = IWL_NUM_RBDS_AX210_HE,
};
const struct iwl_cfg iwl_cfg_bz_z0_gf_a0 = {
.fw_name_pre = IWL_BZ_Z_GF_A_FW_PRE,
.uhb_supported = true,
IWL_DEVICE_BZ,
.num_rbds = IWL_NUM_RBDS_AX210_HE,
};
MODULE_FIRMWARE(IWL_QU_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QNJ_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));

Просмотреть файл

@ -1974,12 +1974,8 @@ static void iwl_nic_config(struct iwl_op_mode *op_mode)
/* SKU Control */
iwl_trans_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH |
CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP,
(CSR_HW_REV_STEP(priv->trans->hw_rev) <<
CSR_HW_IF_CONFIG_REG_POS_MAC_STEP) |
(CSR_HW_REV_DASH(priv->trans->hw_rev) <<
CSR_HW_IF_CONFIG_REG_POS_MAC_DASH));
CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP_DASH,
CSR_HW_REV_STEP_DASH(priv->trans->hw_rev));
/* write radio config values to register */
if (priv->nvm_data->radio_cfg_type <= EEPROM_RF_CONFIG_TYPE_MAX) {

Просмотреть файл

@ -789,7 +789,7 @@ int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt)
* looking up in ACPI
*/
if (wifi_pkg->package.count !=
min_size + profile_size * num_profiles) {
hdr_size + profile_size * num_profiles) {
ret = -EINVAL;
goto out_free;
}
@ -852,6 +852,8 @@ read_table:
}
}
fwrt->geo_num_profiles = num_profiles;
fwrt->geo_enabled = true;
ret = 0;
out_free:
kfree(data);

Просмотреть файл

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2012-2014, 2018, 2020 Intel Corporation
* Copyright (C) 2012-2014, 2018, 2020-2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@ -97,6 +97,21 @@ struct iwl_alive_ntf_v5 {
struct iwl_sku_id sku_id;
} __packed; /* UCODE_ALIVE_NTFY_API_S_VER_5 */
struct iwl_imr_alive_info {
__le64 base_addr;
__le32 size;
__le32 enabled;
} __packed; /* IMR_ALIVE_INFO_API_S_VER_1 */
struct iwl_alive_ntf_v6 {
__le16 status;
__le16 flags;
struct iwl_lmac_alive lmac_data[2];
struct iwl_umac_alive umac_data;
struct iwl_sku_id sku_id;
struct iwl_imr_alive_info imr;
} __packed; /* UCODE_ALIVE_NTFY_API_S_VER_6 */
/**
* enum iwl_extended_cfg_flag - commands driver may send before
* finishing init flow

Просмотреть файл

@ -51,7 +51,7 @@ enum iwl_legacy_cmds {
* @UCODE_ALIVE_NTFY:
* Alive data from the firmware, as described in
* &struct iwl_alive_ntf_v3 or &struct iwl_alive_ntf_v4 or
* &struct iwl_alive_ntf_v5.
* &struct iwl_alive_ntf_v5 or &struct iwl_alive_ntf_v6.
*/
UCODE_ALIVE_NTFY = 0x1,
@ -72,7 +72,8 @@ enum iwl_legacy_cmds {
/**
* @PHY_CONTEXT_CMD:
* Add/modify/remove a PHY context, using &struct iwl_phy_context_cmd.
* Add/modify/remove a PHY context, using &struct iwl_phy_context_cmd
* or &struct iwl_phy_context_cmd_v1.
*/
PHY_CONTEXT_CMD = 0x8,
@ -356,7 +357,7 @@ enum iwl_legacy_cmds {
* &struct iwl_notif_statistics_v11,
* &struct iwl_notif_statistics_v10,
* &struct iwl_notif_statistics,
* &struct iwl_statistics_operational_ntfy
* &struct iwl_statistics_operational_ntfy_ver_14
*/
STATISTICS_CMD = 0x9c,
@ -365,6 +366,7 @@ enum iwl_legacy_cmds {
* one of &struct iwl_notif_statistics_v10,
* &struct iwl_notif_statistics_v11,
* &struct iwl_notif_statistic,
* &struct iwl_statistics_operational_ntfy_ver_14
* &struct iwl_statistics_operational_ntfy
*/
STATISTICS_NOTIFICATION = 0x9d,
@ -612,6 +614,11 @@ enum iwl_system_subcmd_ids {
* @RFI_GET_FREQ_TABLE_CMD: &struct iwl_rfi_config_cmd
*/
RFI_GET_FREQ_TABLE_CMD = 0xc,
/**
* @SYSTEM_FEATURES_CONTROL_CMD: &struct iwl_system_features_control_cmd
*/
SYSTEM_FEATURES_CONTROL_CMD = 0xd,
};
#endif /* __iwl_fw_api_commands_h__ */

Просмотреть файл

@ -554,7 +554,7 @@ struct iwl_wowlan_gtk_status_v1 {
} __packed; /* WOWLAN_GTK_MATERIAL_VER_1 */
/**
* struct iwl_wowlan_gtk_status - GTK status
* struct iwl_wowlan_gtk_status_v2 - GTK status
* @key: GTK material
* @key_len: GTK legth, if set to 0, the key is not available
* @key_flags: information about the key:
@ -565,7 +565,7 @@ struct iwl_wowlan_gtk_status_v1 {
* @tkip_mic_key: TKIP RX MIC key
* @rsc: TSC RSC counters
*/
struct iwl_wowlan_gtk_status {
struct iwl_wowlan_gtk_status_v2 {
u8 key[WOWLAN_KEY_MAX_SIZE];
u8 key_len;
u8 key_flags;
@ -574,6 +574,41 @@ struct iwl_wowlan_gtk_status {
struct iwl_wowlan_rsc_tsc_params_cmd_ver_2 rsc;
} __packed; /* WOWLAN_GTK_MATERIAL_VER_2 */
/**
* struct iwl_wowlan_all_rsc_tsc_v5 - key counters
* @ucast_rsc: unicast RSC values
* @mcast_rsc: multicast RSC values (per key map value)
* @sta_id: station ID
* @mcast_key_id_map: map of key id to @mcast_rsc entry
*/
struct iwl_wowlan_all_rsc_tsc_v5 {
__le64 ucast_rsc[IWL_MAX_TID_COUNT];
__le64 mcast_rsc[2][IWL_MAX_TID_COUNT];
__le32 sta_id;
u8 mcast_key_id_map[4];
} __packed; /* ALL_TSC_RSC_API_S_VER_5 */
/**
* struct iwl_wowlan_gtk_status_v3 - GTK status
* @key: GTK material
* @key_len: GTK length, if set to 0, the key is not available
* @key_flags: information about the key:
* bits[0:1]: key index assigned by the AP
* bits[2:6]: GTK index of the key in the internal DB
* bit[7]: Set iff this is the currently used GTK
* @reserved: padding
* @tkip_mic_key: TKIP RX MIC key
* @sc: RSC/TSC counters
*/
struct iwl_wowlan_gtk_status_v3 {
u8 key[WOWLAN_KEY_MAX_SIZE];
u8 key_len;
u8 key_flags;
u8 reserved[2];
u8 tkip_mic_key[IWL_MIC_KEY_SIZE];
struct iwl_wowlan_all_rsc_tsc_v5 sc;
} __packed; /* WOWLAN_GTK_MATERIAL_VER_3 */
#define IWL_WOWLAN_GTK_IDX_MASK (BIT(0) | BIT(1))
/**
@ -640,7 +675,7 @@ struct iwl_wowlan_status_v6 {
* @wake_packet: wakeup packet
*/
struct iwl_wowlan_status_v7 {
struct iwl_wowlan_gtk_status gtk[WOWLAN_GTK_KEYS_NUM];
struct iwl_wowlan_gtk_status_v2 gtk[WOWLAN_GTK_KEYS_NUM];
struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM];
__le64 replay_ctr;
__le16 pattern_number;
@ -676,7 +711,7 @@ struct iwl_wowlan_status_v7 {
* @wake_packet: wakeup packet
*/
struct iwl_wowlan_status_v9 {
struct iwl_wowlan_gtk_status gtk[WOWLAN_GTK_KEYS_NUM];
struct iwl_wowlan_gtk_status_v2 gtk[WOWLAN_GTK_KEYS_NUM];
struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM];
__le64 replay_ctr;
__le16 pattern_number;
@ -693,6 +728,44 @@ struct iwl_wowlan_status_v9 {
u8 wake_packet[]; /* can be truncated from _length to _bufsize */
} __packed; /* WOWLAN_STATUSES_RSP_API_S_VER_9 */
/**
* struct iwl_wowlan_status_v12 - WoWLAN status
* @gtk: GTK data
* @igtk: IGTK data
* @replay_ctr: GTK rekey replay counter
* @pattern_number: number of the matched pattern
* @non_qos_seq_ctr: non-QoS sequence counter to use next.
* Reserved if the struct has version >= 10.
* @qos_seq_ctr: QoS sequence counters to use next
* @wakeup_reasons: wakeup reasons, see &enum iwl_wowlan_wakeup_reason
* @num_of_gtk_rekeys: number of GTK rekeys
* @transmitted_ndps: number of transmitted neighbor discovery packets
* @received_beacons: number of received beacons
* @wake_packet_length: wakeup packet length
* @wake_packet_bufsize: wakeup packet buffer size
* @tid_tear_down: bit mask of tids whose BA sessions were closed
* in suspend state
* @reserved: unused
* @wake_packet: wakeup packet
*/
struct iwl_wowlan_status_v12 {
struct iwl_wowlan_gtk_status_v3 gtk[WOWLAN_GTK_KEYS_NUM];
struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM];
__le64 replay_ctr;
__le16 pattern_number;
__le16 non_qos_seq_ctr;
__le16 qos_seq_ctr[8];
__le32 wakeup_reasons;
__le32 num_of_gtk_rekeys;
__le32 transmitted_ndps;
__le32 received_beacons;
__le32 wake_packet_length;
__le32 wake_packet_bufsize;
u8 tid_tear_down;
u8 reserved[3];
u8 wake_packet[]; /* can be truncated from _length to _bufsize */
} __packed; /* WOWLAN_STATUSES_RSP_API_S_VER_12 */
/* TODO: NetDetect API */
#endif /* __iwl_fw_api_d3_h__ */

Просмотреть файл

@ -31,6 +31,11 @@ enum iwl_data_path_subcmd_ids {
*/
STA_HE_CTXT_CMD = 0x7,
/**
* @RLC_CONFIG_CMD: &struct iwl_rlc_config_cmd
*/
RLC_CONFIG_CMD = 0x8,
/**
* @RFH_QUEUE_CONFIG_CMD: &struct iwl_rfh_queue_config
*/
@ -195,4 +200,61 @@ struct iwl_thermal_dual_chain_request {
__le32 event;
} __packed; /* THERMAL_DUAL_CHAIN_DISABLE_REQ_NTFY_API_S_VER_1 */
enum iwl_rlc_chain_info {
IWL_RLC_CHAIN_INFO_DRIVER_FORCE = BIT(0),
IWL_RLC_CHAIN_INFO_VALID = 0x000e,
IWL_RLC_CHAIN_INFO_FORCE = 0x0070,
IWL_RLC_CHAIN_INFO_FORCE_MIMO = 0x0380,
IWL_RLC_CHAIN_INFO_COUNT = 0x0c00,
IWL_RLC_CHAIN_INFO_MIMO_COUNT = 0x3000,
};
/**
* struct iwl_rlc_properties - RLC properties
* @rx_chain_info: RX chain info, &enum iwl_rlc_chain_info
* @reserved: reserved
*/
struct iwl_rlc_properties {
__le32 rx_chain_info;
__le32 reserved;
} __packed; /* RLC_PROPERTIES_S_VER_1 */
enum iwl_sad_mode {
IWL_SAD_MODE_ENABLED = BIT(0),
IWL_SAD_MODE_DEFAULT_ANT_MSK = 0x6,
IWL_SAD_MODE_DEFAULT_ANT_FW = 0x0,
IWL_SAD_MODE_DEFAULT_ANT_A = 0x2,
IWL_SAD_MODE_DEFAULT_ANT_B = 0x4,
};
/**
* struct iwl_sad_properties - SAD properties
* @chain_a_sad_mode: chain A SAD mode, &enum iwl_sad_mode
* @chain_b_sad_mode: chain B SAD mode, &enum iwl_sad_mode
* @mac_id: MAC index
* @reserved: reserved
*/
struct iwl_sad_properties {
__le32 chain_a_sad_mode;
__le32 chain_b_sad_mode;
__le32 mac_id;
__le32 reserved;
} __packed;
/**
* struct iwl_rlc_config_cmd - RLC configuration
* @phy_id: PHY index
* @rlc: RLC properties, &struct iwl_rlc_properties
* @sad: SAD (single antenna diversity) options, &struct iwl_sad_properties
* @flags: flags, &enum iwl_rlc_flags
* @reserved: reserved
*/
struct iwl_rlc_config_cmd {
__le32 phy_id;
struct iwl_rlc_properties rlc;
struct iwl_sad_properties sad;
u8 flags;
u8 reserved[3];
} __packed; /* RLC_CONFIG_CMD_API_S_VER_2 */
#endif /* __iwl_fw_api_datapath_h__ */

Просмотреть файл

@ -7,7 +7,6 @@
#include <linux/bitops.h>
#define IWL_FW_INI_HW_SMEM_REGION_ID 15
#define IWL_FW_INI_MAX_REGION_ID 64
#define IWL_FW_INI_MAX_NAME 32
#define IWL_FW_INI_MAX_CFG_NAME 64
@ -124,6 +123,9 @@ struct iwl_fw_ini_region_internal_buffer {
* @hdr: debug header
* @id: region id. Max id is &IWL_FW_INI_MAX_REGION_ID
* @type: region type. One of &enum iwl_fw_ini_region_type
* @sub_type: region sub type
* @sub_type_ver: region sub type
* @reserved: not in use
* @name: region name
* @dev_addr: device address configuration. Used by
* &IWL_FW_INI_REGION_DEVICE_MEMORY, &IWL_FW_INI_REGION_PERIPHERY_MAC,
@ -146,7 +148,10 @@ struct iwl_fw_ini_region_internal_buffer {
struct iwl_fw_ini_region_tlv {
struct iwl_fw_ini_header hdr;
__le32 id;
__le32 type;
u8 type;
u8 sub_type;
u8 sub_type_ver;
u8 reserved;
u8 name[IWL_FW_INI_MAX_NAME];
union {
struct iwl_fw_ini_region_dev_addr dev_addr;
@ -306,6 +311,7 @@ enum iwl_fw_ini_config_set_type {
* @IWL_FW_INI_ALLOCATION_ID_DBGC1: allocation meant for DBGC1 configuration
* @IWL_FW_INI_ALLOCATION_ID_DBGC2: allocation meant for DBGC2 configuration
* @IWL_FW_INI_ALLOCATION_ID_DBGC3: allocation meant for DBGC3 configuration
* @IWL_FW_INI_ALLOCATION_ID_DBGC4: allocation meant for DBGC4 configuration
* @IWL_FW_INI_ALLOCATION_NUM: number of allocation ids
*/
enum iwl_fw_ini_allocation_id {
@ -313,6 +319,7 @@ enum iwl_fw_ini_allocation_id {
IWL_FW_INI_ALLOCATION_ID_DBGC1,
IWL_FW_INI_ALLOCATION_ID_DBGC2,
IWL_FW_INI_ALLOCATION_ID_DBGC3,
IWL_FW_INI_ALLOCATION_ID_DBGC4,
IWL_FW_INI_ALLOCATION_NUM,
}; /* FW_DEBUG_TLV_ALLOCATION_ID_E_VER_1 */
@ -379,6 +386,8 @@ enum iwl_fw_ini_region_type {
IWL_FW_INI_REGION_NUM
}; /* FW_TLV_DEBUG_REGION_TYPE_API_E */
#define IWL_FW_INI_REGION_DEVICE_MEMORY_SUBTYPE_HW_SMEM 1
/**
* enum iwl_fw_ini_time_point
*

Просмотреть файл

@ -33,6 +33,11 @@ enum iwl_regulatory_and_nvm_subcmd_ids {
*/
TAS_CONFIG = 0x3,
/**
* @SAR_OFFSET_MAPPING_TABLE_CMD: &iwl_sar_offset_mapping_cmd
*/
SAR_OFFSET_MAPPING_TABLE_CMD = 0x4,
/**
* @PNVM_INIT_COMPLETE_NTFY: &struct iwl_pnvm_init_complete_ntfy
*/

Просмотреть файл

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2012-2014, 2018, 2020 Intel Corporation
* Copyright (C) 2012-2014, 2018, 2020-2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@ -150,11 +150,12 @@ struct iwl_phy_context_cmd {
/* COMMON_INDEX_HDR_API_S_VER_1 */
__le32 id_and_color;
__le32 action;
/* PHY_CONTEXT_DATA_API_S_VER_3 */
/* PHY_CONTEXT_DATA_API_S_VER_3, PHY_CONTEXT_DATA_API_S_VER_4 */
struct iwl_fw_channel_info ci;
__le32 lmac_id;
__le32 rxchain_info;
__le32 rxchain_info; /* reserved in _VER_4 */
__le32 dsp_cfg_flags;
__le32 reserved;
} __packed; /* PHY_CONTEXT_CMD_API_VER_3 */
} __packed; /* PHY_CONTEXT_CMD_API_VER_3, PHY_CONTEXT_CMD_API_VER_4 */
#endif /* __iwl_fw_api_phy_ctxt_h__ */

Просмотреть файл

@ -503,6 +503,20 @@ union iwl_ppag_table_cmd {
} v2;
} __packed;
#define MCC_TO_SAR_OFFSET_TABLE_ROW_SIZE 26
#define MCC_TO_SAR_OFFSET_TABLE_COL_SIZE 13
/**
* struct iwl_sar_offset_mapping_cmd - struct for SAR_OFFSET_MAPPING_TABLE_CMD
* @offset_map: mapping a mcc to a geo sar group
* @reserved: reserved
*/
struct iwl_sar_offset_mapping_cmd {
u8 offset_map[MCC_TO_SAR_OFFSET_TABLE_ROW_SIZE]
[MCC_TO_SAR_OFFSET_TABLE_COL_SIZE];
u16 reserved;
} __packed; /*SAR_OFFSET_MAPPING_TABLE_CMD_API_S*/
/**
* struct iwl_beacon_filter_cmd
* REPLY_BEACON_FILTERING_CMD = 0xd2 (command)

Просмотреть файл

@ -659,6 +659,19 @@ enum iwl_umac_scan_general_flags_v2 {
IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN_FILTER_IN = BIT(14),
};
/**
* enum iwl_umac_scan_general_params_flags2 - UMAC scan general flags2
*
* @IWL_UMAC_SCAN_GEN_PARAMS_FLAGS2_RESPECT_P2P_GO_LB: scan event scheduling
* should be aware of a P2P GO operation on the 2GHz band.
* @IWL_UMAC_SCAN_GEN_PARAMS_FLAGS2_RESPECT_P2P_GO_HB: scan event scheduling
* should be aware of a P2P GO operation on the 5GHz or 6GHz band.
*/
enum iwl_umac_scan_general_params_flags2 {
IWL_UMAC_SCAN_GEN_PARAMS_FLAGS2_RESPECT_P2P_GO_LB = BIT(0),
IWL_UMAC_SCAN_GEN_PARAMS_FLAGS2_RESPECT_P2P_GO_HB = BIT(1),
};
/**
* struct iwl_scan_channel_cfg_umac
* @flags: bitmap - 0-19: directed scan to i'th ssid.
@ -941,8 +954,8 @@ struct iwl_scan_channel_params_v6 {
} __packed; /* SCAN_CHANNEL_PARAMS_API_S_VER_6 */
/**
* struct iwl_scan_general_params_v10
* @flags: &enum iwl_umac_scan_flags
* struct iwl_scan_general_params_v11
* @flags: &enum iwl_umac_scan_general_flags_v2
* @reserved: reserved for future
* @scan_start_mac_id: report the scan start TSF time according to this mac TSF
* @active_dwell: dwell time for active scan per LMAC
@ -952,7 +965,8 @@ struct iwl_scan_channel_params_v6 {
* for 5GHz channels
* @adwell_default_social_chn: adaptive dwell default number of
* APs per social channel
* @reserved1: reserved for future
* @flags2: for version 11 see &enum iwl_umac_scan_general_params_flags2.
* Otherwise reserved.
* @adwell_max_budget: the maximal number of TUs that adaptive dwell
* can add to the total scan time
* @max_out_of_time: max out of serving channel time, per LMAC
@ -963,7 +977,7 @@ struct iwl_scan_channel_params_v6 {
* @num_of_fragments: number of fragments needed for full fragmented
* scan coverage.
*/
struct iwl_scan_general_params_v10 {
struct iwl_scan_general_params_v11 {
__le16 flags;
u8 reserved;
u8 scan_start_mac_id;
@ -971,14 +985,14 @@ struct iwl_scan_general_params_v10 {
u8 adwell_default_2g;
u8 adwell_default_5g;
u8 adwell_default_social_chn;
u8 reserved1;
u8 flags2;
__le16 adwell_max_budget;
__le32 max_out_of_time[SCAN_TWO_LMACS];
__le32 suspend_time[SCAN_TWO_LMACS];
__le32 scan_priority;
u8 passive_dwell[SCAN_TWO_LMACS];
u8 num_of_fragments[SCAN_TWO_LMACS];
} __packed; /* SCAN_GENERAL_PARAMS_API_S_VER_10 */
} __packed; /* SCAN_GENERAL_PARAMS_API_S_VER_11 and *_VER_10 */
/**
* struct iwl_scan_periodic_parms_v1
@ -994,31 +1008,31 @@ struct iwl_scan_periodic_parms_v1 {
/**
* struct iwl_scan_req_params_v12
* @general_params: &struct iwl_scan_general_params_v10
* @general_params: &struct iwl_scan_general_params_v11
* @channel_params: &struct iwl_scan_channel_params_v4
* @periodic_params: &struct iwl_scan_periodic_parms_v1
* @probe_params: &struct iwl_scan_probe_params_v3
*/
struct iwl_scan_req_params_v12 {
struct iwl_scan_general_params_v10 general_params;
struct iwl_scan_general_params_v11 general_params;
struct iwl_scan_channel_params_v4 channel_params;
struct iwl_scan_periodic_parms_v1 periodic_params;
struct iwl_scan_probe_params_v3 probe_params;
} __packed; /* SCAN_REQUEST_PARAMS_API_S_VER_12 */
/**
* struct iwl_scan_req_params_v14
* @general_params: &struct iwl_scan_general_params_v10
* struct iwl_scan_req_params_v15
* @general_params: &struct iwl_scan_general_params_v11
* @channel_params: &struct iwl_scan_channel_params_v6
* @periodic_params: &struct iwl_scan_periodic_parms_v1
* @probe_params: &struct iwl_scan_probe_params_v4
*/
struct iwl_scan_req_params_v14 {
struct iwl_scan_general_params_v10 general_params;
struct iwl_scan_req_params_v15 {
struct iwl_scan_general_params_v11 general_params;
struct iwl_scan_channel_params_v6 channel_params;
struct iwl_scan_periodic_parms_v1 periodic_params;
struct iwl_scan_probe_params_v4 probe_params;
} __packed; /* SCAN_REQUEST_PARAMS_API_S_VER_14 */
} __packed; /* SCAN_REQUEST_PARAMS_API_S_VER_15 and *_VER_14 */
/**
* struct iwl_scan_req_umac_v12
@ -1033,16 +1047,16 @@ struct iwl_scan_req_umac_v12 {
} __packed; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_12 */
/**
* struct iwl_scan_req_umac_v14
* struct iwl_scan_req_umac_v15
* @uid: scan id, &enum iwl_umac_scan_uid_offsets
* @ooc_priority: out of channel priority - &enum iwl_scan_priority
* @scan_params: scan parameters
*/
struct iwl_scan_req_umac_v14 {
struct iwl_scan_req_umac_v15 {
__le32 uid;
__le32 ooc_priority;
struct iwl_scan_req_params_v14 scan_params;
} __packed; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_14 */
struct iwl_scan_req_params_v15 scan_params;
} __packed; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_15 and *_VER_14 */
/**
* struct iwl_umac_scan_abort

Просмотреть файл

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2012-2014, 2018, 2020 Intel Corporation
* Copyright (C) 2012-2014, 2018, 2020 - 2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@ -432,6 +432,7 @@ enum iwl_fw_statistics_type {
FW_STATISTICS_HE,
}; /* FW_STATISTICS_TYPE_API_E_VER_1 */
#define IWL_STATISTICS_TYPE_MSK 0x7f
/**
* struct iwl_statistics_ntfy_hdr
*
@ -445,11 +446,98 @@ struct iwl_statistics_ntfy_hdr {
__le16 size;
}; /* STATISTICS_NTFY_HDR_API_S_VER_1 */
/**
* struct iwl_statistics_ntfy_per_mac
*
* @beacon_filter_average_energy: Average energy [-dBm] of the 2
* antennas.
* @air_time: air time
* @beacon_counter: all beacons (both filtered and not filtered)
* @beacon_average_energy: all beacons (both filtered and not
* filtered)
* @beacon_rssi_a: beacon RSSI on antenna A
* @beacon_rssi_b: beacon RSSI on antenna B
* @rx_bytes: RX byte count
*/
struct iwl_statistics_ntfy_per_mac {
__le32 beacon_filter_average_energy;
__le32 air_time;
__le32 beacon_counter;
__le32 beacon_average_energy;
__le32 beacon_rssi_a;
__le32 beacon_rssi_b;
__le32 rx_bytes;
} __packed; /* STATISTICS_NTFY_PER_MAC_API_S_VER_1 */
#define IWL_STATS_MAX_BW_INDEX 5
/** struct iwl_statistics_ntfy_per_phy
* @channel_load: channel load
* @channel_load_by_us: device contribution to MCLM
* @channel_load_not_by_us: other devices' contribution to MCLM
* @clt: CLT HW timer (TIM_CH_LOAD2)
* @act: active accumulator SW
* @elp: elapsed time accumulator SW
* @rx_detected_per_ch_width: number of deferred TX per channel width,
* 0 - 20, 1/2/3 - 40/80/160
* @success_per_ch_width: number of frames that got ACK/BACK/CTS
* per channel BW. note, BACK counted as 1
* @fail_per_ch_width: number of frames that didn't get ACK/BACK/CTS
* per channel BW. note BACK counted as 1
* @last_tx_ch_width_indx: last txed frame channel width index
*/
struct iwl_statistics_ntfy_per_phy {
__le32 channel_load;
__le32 channel_load_by_us;
__le32 channel_load_not_by_us;
__le32 clt;
__le32 act;
__le32 elp;
__le32 rx_detected_per_ch_width[IWL_STATS_MAX_BW_INDEX];
__le32 success_per_ch_width[IWL_STATS_MAX_BW_INDEX];
__le32 fail_per_ch_width[IWL_STATS_MAX_BW_INDEX];
__le32 last_tx_ch_width_indx;
} __packed; /* STATISTICS_NTFY_PER_PHY_API_S_VER_1 */
/**
* struct iwl_statistics_ntfy_per_sta
*
* @average_energy: in fact it is minus the energy..
*/
struct iwl_statistics_ntfy_per_sta {
__le32 average_energy;
} __packed; /* STATISTICS_NTFY_PER_STA_API_S_VER_1 */
#define IWL_STATS_MAX_PHY_OPERTINAL 3
/**
* struct iwl_statistics_operational_ntfy
*
* @hdr: general statistics header
* @flags: bitmap of possible notification structures
* @per_mac_stats: per mac statistics, &struct iwl_statistics_ntfy_per_mac
* @per_phy_stats: per phy statistics, &struct iwl_statistics_ntfy_per_phy
* @per_sta_stats: per sta statistics, &struct iwl_statistics_ntfy_per_sta
* @rx_time: rx time
* @tx_time: usec the radio is transmitting.
* @on_time_rf: The total time in usec the RF is awake.
* @on_time_scan: usec the radio is awake due to scan.
*/
struct iwl_statistics_operational_ntfy {
struct iwl_statistics_ntfy_hdr hdr;
__le32 flags;
struct iwl_statistics_ntfy_per_mac per_mac_stats[MAC_INDEX_AUX];
struct iwl_statistics_ntfy_per_phy per_phy_stats[IWL_STATS_MAX_PHY_OPERTINAL];
struct iwl_statistics_ntfy_per_sta per_sta_stats[IWL_MVM_STATION_COUNT_MAX];
__le64 rx_time;
__le64 tx_time;
__le64 on_time_rf;
__le64 on_time_scan;
} __packed; /* STATISTICS_OPERATIONAL_NTFY_API_S_VER_15 */
/**
* struct iwl_statistics_operational_ntfy_ver_14
*
* @hdr: general statistics header
* @flags: bitmap of possible notification structures
* @mac_id: mac on which the beacon was received
* @beacon_filter_average_energy: Average energy [-dBm] of the 2
* antennas.
@ -469,7 +557,7 @@ struct iwl_statistics_ntfy_hdr {
* @average_energy: in fact it is minus the energy..
* @reserved: reserved
*/
struct iwl_statistics_operational_ntfy {
struct iwl_statistics_operational_ntfy_ver_14 {
struct iwl_statistics_ntfy_hdr hdr;
__le32 flags;
__le32 mac_id;

Просмотреть файл

@ -1,11 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2012-2014, 2019-2020 Intel Corporation
* Copyright (C) 2012-2014, 2019-2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
#ifndef __iwl_fw_api_soc_h__
#define __iwl_fw_api_soc_h__
#ifndef __iwl_fw_api_system_h__
#define __iwl_fw_api_system_h__
#define SOC_CONFIG_CMD_FLAGS_DISCRETE BIT(0)
#define SOC_CONFIG_CMD_FLAGS_LOW_LATENCY BIT(1)
@ -32,4 +32,12 @@ struct iwl_soc_configuration_cmd {
* SOC_CONFIGURATION_CMD_S_VER_2
*/
#endif /* __iwl_fw_api_soc_h__ */
/**
* struct iwl_system_features_control_cmd - system features control command
* @features: bitmap of features to disable
*/
struct iwl_system_features_control_cmd {
__le32 features[4];
} __packed; /* SYSTEM_FEATURES_CONTROL_CMD_API_S_VER_1 */
#endif /* __iwl_fw_api_system_h__ */

Просмотреть файл

@ -880,7 +880,7 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,
dump_info->hw_type =
cpu_to_le32(CSR_HW_REV_TYPE(fwrt->trans->hw_rev));
dump_info->hw_step =
cpu_to_le32(CSR_HW_REV_STEP(fwrt->trans->hw_rev));
cpu_to_le32(fwrt->trans->hw_rev_step);
memcpy(dump_info->fw_human_readable, fwrt->fw->human_readable,
sizeof(dump_info->fw_human_readable));
strncpy(dump_info->dev_human_readable, fwrt->trans->name,
@ -1165,8 +1165,7 @@ static int iwl_dump_ini_dev_mem_iter(struct iwl_fw_runtime *fwrt,
iwl_trans_read_mem_bytes(fwrt->trans, addr, range->data,
le32_to_cpu(reg->dev_addr.size));
if ((le32_to_cpu(reg->id) & IWL_FW_INI_REGION_V2_MASK) ==
IWL_FW_INI_HW_SMEM_REGION_ID &&
if (reg->sub_type == IWL_FW_INI_REGION_DEVICE_MEMORY_SUBTYPE_HW_SMEM &&
fwrt->sanitize_ops && fwrt->sanitize_ops->frob_txf)
fwrt->sanitize_ops->frob_txf(fwrt->sanitize_ctx,
range->data,
@ -1988,17 +1987,18 @@ static u32 iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, struct list_head *list,
{
struct iwl_fw_ini_region_tlv *reg = (void *)reg_data->reg_tlv->data;
struct iwl_fw_ini_dump_entry *entry;
struct iwl_fw_error_dump_data *tlv;
struct iwl_fw_ini_error_dump_data *tlv;
struct iwl_fw_ini_error_dump_header *header;
u32 type = le32_to_cpu(reg->type), id = le32_to_cpu(reg->id);
u32 type = reg->type;
u32 id = le32_to_cpu(reg->id);
u32 num_of_ranges, i, size;
void *range;
/*
* The higher part of the ID in version 2 is irrelevant for
* The higher part of the ID from 2 is irrelevant for
* us, so mask it out.
*/
if (le32_to_cpu(reg->hdr.version) == 2)
if (le32_to_cpu(reg->hdr.version) >= 2)
id &= IWL_FW_INI_REGION_V2_MASK;
if (!ops->get_num_of_ranges || !ops->get_size || !ops->fill_mem_hdr ||
@ -2017,6 +2017,9 @@ static u32 iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, struct list_head *list,
tlv = (void *)entry->data;
tlv->type = reg->type;
tlv->sub_type = reg->sub_type;
tlv->sub_type_ver = reg->sub_type_ver;
tlv->reserved = reg->reserved;
tlv->len = cpu_to_le32(size);
IWL_DEBUG_FW(fwrt, "WRT: Collecting region: id=%d, type=%d\n", id,
@ -2099,7 +2102,7 @@ static u32 iwl_dump_ini_info(struct iwl_fw_runtime *fwrt,
dump->ver_type = cpu_to_le32(fwrt->dump.fw_ver.type);
dump->ver_subtype = cpu_to_le32(fwrt->dump.fw_ver.subtype);
dump->hw_step = cpu_to_le32(CSR_HW_REV_STEP(fwrt->trans->hw_rev));
dump->hw_step = cpu_to_le32(fwrt->trans->hw_rev_step);
/*
* Several HWs all have type == 0x42, so we'll override this value
@ -2291,7 +2294,7 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt,
}
reg = (void *)reg_data.reg_tlv->data;
reg_type = le32_to_cpu(reg->type);
reg_type = reg->type;
if (reg_type >= ARRAY_SIZE(iwl_dump_ini_region_ops))
continue;

Просмотреть файл

@ -212,7 +212,9 @@ static void iwl_fwrt_dump_lmac_error_log(struct iwl_fw_runtime *fwrt, u8 lmac_nu
IWL_ERR(trans, "HW error, resetting before reading\n");
/* reset the device */
iwl_trans_sw_reset(trans);
err = iwl_trans_sw_reset(trans, true);
if (err)
return;
err = iwl_finish_nic_init(trans);
if (err)

Просмотреть файл

@ -231,6 +231,24 @@ 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_error_dump_data - data for one type
* @type: &enum iwl_fw_ini_region_type
* @sub_type: sub type id
* @sub_type_ver: sub type version
* @reserved: not in use
* @len: the length starting from %data
* @data: the data itself
*/
struct iwl_fw_ini_error_dump_data {
u8 type;
u8 sub_type;
u8 sub_type_ver;
u8 reserved;
__le32 len;
__u8 data[];
} __packed;
/**
* struct iwl_fw_ini_dump_entry
* @list: list of dump entries

Просмотреть файл

@ -8,7 +8,7 @@
#include "dbg.h"
#include "debugfs.h"
#include "fw/api/soc.h"
#include "fw/api/system.h"
#include "fw/api/commands.h"
#include "fw/api/rx.h"
#include "fw/api/datapath.h"

Просмотреть файл

@ -156,8 +156,12 @@ struct iwl_fw_runtime {
u8 sar_chain_b_profile;
struct iwl_geo_profile geo_profiles[ACPI_NUM_GEO_PROFILES_REV3];
u32 geo_rev;
u32 geo_num_profiles;
bool geo_enabled;
union iwl_ppag_table_cmd ppag_table;
u32 ppag_ver;
struct iwl_sar_offset_mapping_cmd sgom_table;
bool sgom_enabled;
#endif
};

Просмотреть файл

@ -11,6 +11,7 @@
#include "fw/uefi.h"
#include "fw/api/alive.h"
#include <linux/efi.h>
#include "fw/runtime.h"
#define IWL_EFI_VAR_GUID EFI_GUID(0x92daaf2f, 0xc02b, 0x455b, \
0xb2, 0xec, 0xf5, 0xa3, \
@ -266,3 +267,90 @@ out:
return data;
}
#ifdef CONFIG_ACPI
static int iwl_uefi_sgom_parse(struct uefi_cnv_wlan_sgom_data *sgom_data,
struct iwl_fw_runtime *fwrt)
{
int i, j;
if (sgom_data->revision != 1)
return -EINVAL;
memcpy(fwrt->sgom_table.offset_map, sgom_data->offset_map,
sizeof(fwrt->sgom_table.offset_map));
for (i = 0; i < MCC_TO_SAR_OFFSET_TABLE_ROW_SIZE; i++) {
for (j = 0; j < MCC_TO_SAR_OFFSET_TABLE_COL_SIZE; j++) {
/* since each byte is composed of to values, */
/* one for each letter, */
/* extract and check each of them separately */
u8 value = fwrt->sgom_table.offset_map[i][j];
u8 low = value & 0xF;
u8 high = (value & 0xF0) >> 4;
if (high > fwrt->geo_num_profiles)
high = 0;
if (low > fwrt->geo_num_profiles)
low = 0;
fwrt->sgom_table.offset_map[i][j] = (high << 4) | low;
}
}
fwrt->sgom_enabled = true;
return 0;
}
void iwl_uefi_get_sgom_table(struct iwl_trans *trans,
struct iwl_fw_runtime *fwrt)
{
struct efivar_entry *sgom_efivar;
struct uefi_cnv_wlan_sgom_data *data;
unsigned long package_size;
int err, ret;
if (!fwrt->geo_enabled)
return;
sgom_efivar = kzalloc(sizeof(*sgom_efivar), GFP_KERNEL);
if (!sgom_efivar)
return;
memcpy(&sgom_efivar->var.VariableName, IWL_UEFI_SGOM_NAME,
sizeof(IWL_UEFI_SGOM_NAME));
sgom_efivar->var.VendorGuid = IWL_EFI_VAR_GUID;
/* TODO: we hardcode a maximum length here, because reading
* from the UEFI is not working. To implement this properly,
* we have to call efivar_entry_size().
*/
package_size = IWL_HARDCODED_SGOM_SIZE;
data = kmalloc(package_size, GFP_KERNEL);
if (!data) {
data = ERR_PTR(-ENOMEM);
goto out;
}
err = efivar_entry_get(sgom_efivar, NULL, &package_size, data);
if (err) {
IWL_DEBUG_FW(trans,
"SGOM UEFI variable not found %d\n", err);
goto out_free;
}
IWL_DEBUG_FW(trans, "Read SGOM from UEFI with size %lu\n",
package_size);
ret = iwl_uefi_sgom_parse(data, fwrt);
if (ret < 0)
IWL_DEBUG_FW(trans, "Cannot read SGOM tables. rev is invalid\n");
out_free:
kfree(data);
out:
kfree(sgom_efivar);
}
IWL_EXPORT_SYMBOL(iwl_uefi_get_sgom_table);
#endif /* CONFIG_ACPI */

Просмотреть файл

@ -7,6 +7,7 @@
#define IWL_UEFI_OEM_PNVM_NAME L"UefiCnvWlanOemSignedPnvm"
#define IWL_UEFI_REDUCED_POWER_NAME L"UefiCnvWlanReducedPower"
#define IWL_UEFI_SGOM_NAME L"UefiCnvWlanSarGeoOffsetMapping"
/*
* TODO: we have these hardcoded values that the caller must pass,
@ -16,6 +17,7 @@
*/
#define IWL_HARDCODED_PNVM_SIZE 4096
#define IWL_HARDCODED_REDUCE_POWER_SIZE 32768
#define IWL_HARDCODED_SGOM_SIZE 339
struct pnvm_sku_package {
u8 rev;
@ -25,6 +27,16 @@ struct pnvm_sku_package {
u8 data[];
} __packed;
struct uefi_cnv_wlan_sgom_data {
u8 revision;
u8 offset_map[IWL_HARDCODED_SGOM_SIZE - 1];
} __packed;
/*
* This is known to be broken on v4.19 and to work on v5.4. Until we
* figure out why this is the case and how to make it work, simply
* disable the feature in old kernels.
*/
#ifdef CONFIG_EFI
void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len);
void *iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len);
@ -42,4 +54,12 @@ void *iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len)
}
#endif /* CONFIG_EFI */
#if defined(CONFIG_EFI) && defined(CONFIG_ACPI)
void iwl_uefi_get_sgom_table(struct iwl_trans *trans, struct iwl_fw_runtime *fwrt);
#else
static inline
void iwl_uefi_get_sgom_table(struct iwl_trans *trans, struct iwl_fw_runtime *fwrt)
{
}
#endif
#endif /* __iwl_fw_uefi__ */

Просмотреть файл

@ -610,7 +610,6 @@ extern const struct iwl_cfg killer1650x_2ax_cfg;
extern const struct iwl_cfg killer1650w_2ax_cfg;
extern const struct iwl_cfg iwl_qnj_b0_hr_b0_cfg;
extern const struct iwl_cfg iwlax210_2ax_cfg_so_jf_b0;
extern const struct iwl_cfg iwlax210_2ax_cfg_so_hr_a0;
extern const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0;
extern const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0_long;
extern const struct iwl_cfg iwlax210_2ax_cfg_ty_gf_a0;
@ -634,6 +633,7 @@ extern const struct iwl_cfg iwl_cfg_bz_a0_gf4_a0;
extern const struct iwl_cfg iwl_cfg_bz_a0_mr_a0;
extern const struct iwl_cfg iwl_cfg_bz_a0_fm_a0;
extern const struct iwl_cfg iwl_cfg_gl_a0_fm_a0;
extern const struct iwl_cfg iwl_cfg_bz_z0_gf_a0;
#endif /* CONFIG_IWLMVM */
#endif /* __IWL_CONFIG_H__ */

Просмотреть файл

@ -105,6 +105,10 @@
/* GIO Chicken Bits (PCI Express bus link power management) */
#define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100)
#define CSR_IPC_SLEEP_CONTROL (CSR_BASE + 0x114)
#define CSR_IPC_SLEEP_CONTROL_SUSPEND 0x3
#define CSR_IPC_SLEEP_CONTROL_RESUME 0
/* Doorbell NMI (since Bz) */
#define CSR_DOORBELL_VECTOR (CSR_BASE + 0x130)
#define CSR_DOORBELL_VECTOR_NMI BIT(1)
@ -143,8 +147,7 @@
#define CSR_FUNC_SCRATCH_INIT_VALUE (0x01010101)
/* Bits for CSR_HW_IF_CONFIG_REG */
#define CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH (0x00000003)
#define CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP (0x0000000C)
#define CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP_DASH (0x0000000F)
#define CSR_HW_IF_CONFIG_REG_BIT_MONITOR_SRAM (0x00000080)
#define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x000000C0)
#define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100)
@ -287,8 +290,7 @@
#define CSR_GP_CNTRL_REG_FLAG_SW_RESET BIT(31)
/* HW REV */
#define CSR_HW_REV_DASH(_val) (((_val) & 0x0000003) >> 0)
#define CSR_HW_REV_STEP(_val) (((_val) & 0x000000C) >> 2)
#define CSR_HW_REV_STEP_DASH(_val) ((_val) & CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP_DASH)
#define CSR_HW_REV_TYPE(_val) (((_val) & 0x000FFF0) >> 4)
/* HW RFID */
@ -306,6 +308,7 @@ enum {
SILICON_A_STEP = 0,
SILICON_B_STEP,
SILICON_C_STEP,
SILICON_Z_STEP = 0xf,
};
@ -328,10 +331,10 @@ enum {
#define CSR_HW_REV_TYPE_7265D (0x0000210)
#define CSR_HW_REV_TYPE_NONE (0x00001F0)
#define CSR_HW_REV_TYPE_QNJ (0x0000360)
#define CSR_HW_REV_TYPE_QNJ_B0 (0x0000364)
#define CSR_HW_REV_TYPE_QU_B0 (0x0000334)
#define CSR_HW_REV_TYPE_QU_C0 (0x0000338)
#define CSR_HW_REV_TYPE_QUZ (0x0000354)
#define CSR_HW_REV_TYPE_QNJ_B0 (0x0000361)
#define CSR_HW_REV_TYPE_QU_B0 (0x0000331)
#define CSR_HW_REV_TYPE_QU_C0 (0x0000332)
#define CSR_HW_REV_TYPE_QUZ (0x0000351)
#define CSR_HW_REV_TYPE_HR_CDB (0x0000340)
#define CSR_HW_REV_TYPE_SO (0x0000370)
#define CSR_HW_REV_TYPE_TY (0x0000420)

Просмотреть файл

@ -59,7 +59,7 @@ 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 = 2,},
[IWL_DBG_TLV_TYPE_REGION] = {.min_ver = 1, .max_ver = 3,},
[IWL_DBG_TLV_TYPE_TRIGGER] = {.min_ver = 1, .max_ver = 1,},
[IWL_DBG_TLV_TYPE_CONF_SET] = {.min_ver = 1, .max_ver = 1,},
};
@ -177,14 +177,14 @@ static int iwl_dbg_tlv_alloc_region(struct iwl_trans *trans,
const struct iwl_fw_ini_region_tlv *reg = (const void *)tlv->data;
struct iwl_ucode_tlv **active_reg;
u32 id = le32_to_cpu(reg->id);
u32 type = le32_to_cpu(reg->type);
u8 type = reg->type;
u32 tlv_len = sizeof(*tlv) + le32_to_cpu(tlv->length);
/*
* The higher part of the ID in version 2 is irrelevant for
* The higher part of the ID in from version 2 is irrelevant for
* us, so mask it out.
*/
if (le32_to_cpu(reg->hdr.version) == 2)
if (le32_to_cpu(reg->hdr.version) >= 2)
id &= IWL_FW_INI_REGION_V2_MASK;
if (le32_to_cpu(tlv->length) < sizeof(*reg))
@ -473,7 +473,7 @@ void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans)
int res;
if (!iwlwifi_mod_params.enable_ini ||
trans->trans_cfg->device_family <= IWL_DEVICE_FAMILY_9000)
trans->trans_cfg->device_family <= IWL_DEVICE_FAMILY_8000)
return;
res = firmware_request_nowarn(&fw, yoyo_bin, dev);
@ -1244,7 +1244,7 @@ static void iwl_dbg_tlv_init_cfg(struct iwl_fw_runtime *fwrt)
}
reg = (void *)(*active_reg)->data;
reg_type = le32_to_cpu(reg->type);
reg_type = reg->type;
if (reg_type != IWL_FW_INI_REGION_DRAM_BUFFER ||
!(BIT(le32_to_cpu(reg->dram_alloc_id)) & failed_alloc))

Просмотреть файл

@ -163,8 +163,8 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
char tag[8];
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)) {
(drv->trans->hw_rev_step != SILICON_B_STEP &&
drv->trans->hw_rev_step != SILICON_C_STEP)) {
IWL_ERR(drv,
"Only HW steps B and C are currently supported (0x%0x)\n",
drv->trans->hw_rev);

Просмотреть файл

@ -1609,7 +1609,7 @@ int iwl_read_external_nvm(struct iwl_trans *trans,
/* nvm file validation, dword_buff[2] holds the file version */
if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_8000 &&
CSR_HW_REV_STEP(trans->hw_rev) == SILICON_C_STEP &&
trans->hw_rev_step == SILICON_C_STEP &&
le32_to_cpu(dword_buff[2]) < 0xE4A) {
ret = -EFAULT;
goto out;

Просмотреть файл

@ -455,6 +455,13 @@ enum {
#define UREG_DOORBELL_TO_ISR6_RESUME BIT(19)
#define UREG_DOORBELL_TO_ISR6_PNVM BIT(20)
/*
* From BZ family driver triggers this bit for suspend and resume
* The driver should update CSR_IPC_SLEEP_CONTROL before triggering
* this interrupt with suspend/resume value
*/
#define UREG_DOORBELL_TO_ISR6_SLEEP_CTRL BIT(31)
#define CNVI_MBOX_C 0xA3400C
#define FSEQ_ERROR_CODE 0xA340C8

Просмотреть файл

@ -296,6 +296,8 @@ enum iwl_d3_status {
* are sent
* @STATUS_TRANS_IDLE: the trans is idle - general commands are not to be sent
* @STATUS_TRANS_DEAD: trans is dead - avoid any read/write operation
* @STATUS_SUPPRESS_CMD_ERROR_ONCE: suppress "FW error in SYNC CMD" once,
* e.g. for testing
*/
enum iwl_trans_status {
STATUS_SYNC_HCMD_ACTIVE,
@ -308,6 +310,7 @@ enum iwl_trans_status {
STATUS_TRANS_GOING_IDLE,
STATUS_TRANS_IDLE,
STATUS_TRANS_DEAD,
STATUS_SUPPRESS_CMD_ERROR_ONCE,
};
static inline int
@ -593,7 +596,7 @@ struct iwl_trans_ops {
void (*configure)(struct iwl_trans *trans,
const struct iwl_trans_config *trans_cfg);
void (*set_pmi)(struct iwl_trans *trans, bool state);
void (*sw_reset)(struct iwl_trans *trans);
int (*sw_reset)(struct iwl_trans *trans, bool retake_ownership);
bool (*grab_nic_access)(struct iwl_trans *trans);
void (*release_nic_access)(struct iwl_trans *trans);
void (*set_bits_mask)(struct iwl_trans *trans, u32 reg, u32 mask,
@ -938,6 +941,7 @@ struct iwl_trans_txqs {
* @hw_id: a u32 with the ID of the device / sub-device.
* Set during transport allocation.
* @hw_id_str: a string with info about HW ID. Set during transport allocation.
* @hw_rev_step: The mac step of the HW
* @pm_support: set to true in start_hw if link pm is supported
* @ltr_enabled: set to true if the LTR is enabled
* @wide_cmd_header: true when ucode supports wide command header format
@ -971,6 +975,7 @@ struct iwl_trans {
struct device *dev;
u32 max_skb_frags;
u32 hw_rev;
u32 hw_rev_step;
u32 hw_rf_id;
u32 hw_id;
char hw_id_str[52];
@ -1384,10 +1389,12 @@ static inline void iwl_trans_set_pmi(struct iwl_trans *trans, bool state)
trans->ops->set_pmi(trans, state);
}
static inline void iwl_trans_sw_reset(struct iwl_trans *trans)
static inline int iwl_trans_sw_reset(struct iwl_trans *trans,
bool retake_ownership)
{
if (trans->ops->sw_reset)
trans->ops->sw_reset(trans);
return trans->ops->sw_reset(trans, retake_ownership);
return 0;
}
static inline void

Просмотреть файл

@ -119,6 +119,7 @@ struct iwl_sap_shared_mem_ctrl_blk {
struct iwl_mei_shared_mem_ptrs {
struct iwl_sap_shared_mem_ctrl_blk *ctrl;
void *q_head[SAP_DIRECTION_MAX][SAP_QUEUE_IDX_MAX];
size_t q_size[SAP_DIRECTION_MAX][SAP_QUEUE_IDX_MAX];
};
struct iwl_mei_filters {
@ -209,7 +210,7 @@ static void iwl_mei_free_shared_mem(struct mei_cl_device *cldev)
struct iwl_mei *mei = mei_cldev_get_drvdata(cldev);
if (mei_cldev_dma_unmap(cldev))
dev_err(&cldev->dev, "Coudln't unmap the shared mem properly\n");
dev_err(&cldev->dev, "Couldn't unmap the shared mem properly\n");
memset(&mei->shared_mem, 0, sizeof(mei->shared_mem));
}
@ -271,6 +272,8 @@ static void iwl_mei_init_shared_mem(struct iwl_mei *mei)
mem->q_head[dir][queue] = q_head;
q_head +=
le32_to_cpu(mem->ctrl->dir[dir].q_ctrl_blk[queue].size);
mem->q_size[dir][queue] =
le32_to_cpu(mem->ctrl->dir[dir].q_ctrl_blk[queue].size);
}
}
@ -280,11 +283,11 @@ static void iwl_mei_init_shared_mem(struct iwl_mei *mei)
static ssize_t iwl_mei_write_cyclic_buf(struct mei_cl_device *cldev,
struct iwl_sap_q_ctrl_blk *notif_q,
u8 *q_head,
const struct iwl_sap_hdr *hdr)
const struct iwl_sap_hdr *hdr,
u32 q_sz)
{
u32 rd = le32_to_cpu(READ_ONCE(notif_q->rd_ptr));
u32 wr = le32_to_cpu(READ_ONCE(notif_q->wr_ptr));
u32 q_sz = le32_to_cpu(notif_q->size);
size_t room_in_buf;
size_t tx_sz = sizeof(*hdr) + le16_to_cpu(hdr->len);
@ -382,6 +385,7 @@ static int iwl_mei_send_sap_msg_payload(struct mei_cl_device *cldev,
struct iwl_sap_q_ctrl_blk *notif_q;
struct iwl_sap_dir *dir;
void *q_head;
u32 q_sz;
int ret;
lockdep_assert_held(&iwl_mei_mutex);
@ -404,7 +408,8 @@ static int iwl_mei_send_sap_msg_payload(struct mei_cl_device *cldev,
dir = &mei->shared_mem.ctrl->dir[SAP_DIRECTION_HOST_TO_ME];
notif_q = &dir->q_ctrl_blk[SAP_QUEUE_IDX_NOTIF];
q_head = mei->shared_mem.q_head[SAP_DIRECTION_HOST_TO_ME][SAP_QUEUE_IDX_NOTIF];
ret = iwl_mei_write_cyclic_buf(q_head, notif_q, q_head, hdr);
q_sz = mei->shared_mem.q_size[SAP_DIRECTION_HOST_TO_ME][SAP_QUEUE_IDX_NOTIF];
ret = iwl_mei_write_cyclic_buf(q_head, notif_q, q_head, hdr, q_sz);
if (ret < 0)
return ret;
@ -454,10 +459,10 @@ void iwl_mei_add_data_to_ring(struct sk_buff *skb, bool cb_tx)
dir = &mei->shared_mem.ctrl->dir[SAP_DIRECTION_HOST_TO_ME];
notif_q = &dir->q_ctrl_blk[SAP_QUEUE_IDX_DATA];
q_head = mei->shared_mem.q_head[SAP_DIRECTION_HOST_TO_ME][SAP_QUEUE_IDX_DATA];
q_sz = mei->shared_mem.q_size[SAP_DIRECTION_HOST_TO_ME][SAP_QUEUE_IDX_DATA];
rd = le32_to_cpu(READ_ONCE(notif_q->rd_ptr));
wr = le32_to_cpu(READ_ONCE(notif_q->wr_ptr));
q_sz = le32_to_cpu(notif_q->size);
hdr_sz = cb_tx ? sizeof(struct iwl_sap_cb_data) :
sizeof(struct iwl_sap_hdr);
tx_sz = skb->len + hdr_sz;
@ -627,6 +632,8 @@ static void iwl_mei_handle_csme_filters(struct mei_cl_device *cldev,
lockdep_is_held(&iwl_mei_mutex));
new_filters = kzalloc(sizeof(*new_filters), GFP_KERNEL);
if (!new_filters)
return;
/* Copy the OOB filters */
new_filters->filters = filters->filters;
@ -1074,11 +1081,11 @@ static void iwl_mei_handle_sap_rx_cmd(struct mei_cl_device *cldev,
static void iwl_mei_handle_sap_rx(struct mei_cl_device *cldev,
struct iwl_sap_q_ctrl_blk *notif_q,
const u8 *q_head,
struct sk_buff_head *skbs)
struct sk_buff_head *skbs,
u32 q_sz)
{
u32 rd = le32_to_cpu(READ_ONCE(notif_q->rd_ptr));
u32 wr = le32_to_cpu(READ_ONCE(notif_q->wr_ptr));
u32 q_sz = le32_to_cpu(notif_q->size);
ssize_t valid_rx_sz;
if (rd > q_sz || wr > q_sz) {
@ -1110,6 +1117,7 @@ static void iwl_mei_handle_check_shared_area(struct mei_cl_device *cldev)
struct sk_buff_head tx_skbs;
struct iwl_sap_dir *dir;
void *q_head;
u32 q_sz;
if (!mei->shared_mem.ctrl)
return;
@ -1117,22 +1125,24 @@ static void iwl_mei_handle_check_shared_area(struct mei_cl_device *cldev)
dir = &mei->shared_mem.ctrl->dir[SAP_DIRECTION_ME_TO_HOST];
notif_q = &dir->q_ctrl_blk[SAP_QUEUE_IDX_NOTIF];
q_head = mei->shared_mem.q_head[SAP_DIRECTION_ME_TO_HOST][SAP_QUEUE_IDX_NOTIF];
q_sz = mei->shared_mem.q_size[SAP_DIRECTION_ME_TO_HOST][SAP_QUEUE_IDX_NOTIF];
/*
* Do not hold the mutex here, but rather each and every message
* handler takes it.
* This allows message handlers to take it at a certain time.
*/
iwl_mei_handle_sap_rx(cldev, notif_q, q_head, NULL);
iwl_mei_handle_sap_rx(cldev, notif_q, q_head, NULL, q_sz);
mutex_lock(&iwl_mei_mutex);
dir = &mei->shared_mem.ctrl->dir[SAP_DIRECTION_ME_TO_HOST];
notif_q = &dir->q_ctrl_blk[SAP_QUEUE_IDX_DATA];
q_head = mei->shared_mem.q_head[SAP_DIRECTION_ME_TO_HOST][SAP_QUEUE_IDX_DATA];
q_sz = mei->shared_mem.q_size[SAP_DIRECTION_ME_TO_HOST][SAP_QUEUE_IDX_DATA];
__skb_queue_head_init(&tx_skbs);
iwl_mei_handle_sap_rx(cldev, notif_q, q_head, &tx_skbs);
iwl_mei_handle_sap_rx(cldev, notif_q, q_head, &tx_skbs, q_sz);
if (skb_queue_empty(&tx_skbs)) {
mutex_unlock(&iwl_mei_mutex);
@ -1754,7 +1764,7 @@ static void iwl_mei_dbgfs_register(struct iwl_mei *mei)
mei->dbgfs_dir, &iwl_mei_status);
debugfs_create_file("send_start_message", S_IWUSR, mei->dbgfs_dir,
mei, &iwl_mei_dbgfs_send_start_message_ops);
debugfs_create_file("req_ownserhip", S_IWUSR, mei->dbgfs_dir,
debugfs_create_file("req_ownership", S_IWUSR, mei->dbgfs_dir,
mei, &iwl_mei_dbgfs_req_ownership_ops);
}

Просмотреть файл

@ -1390,6 +1390,13 @@ struct iwl_wowlan_status_data {
u16 qos_seq_ctr[8];
u8 tid_tear_down;
struct {
/* including RX MIC key for TKIP */
u8 key[WOWLAN_KEY_MAX_SIZE];
u8 len;
u8 flags;
} gtk;
struct {
/*
* We store both the TKIP and AES representations
@ -1400,11 +1407,15 @@ struct iwl_wowlan_status_data {
struct {
struct ieee80211_key_seq seq[IWL_MAX_TID_COUNT];
} tkip, aes;
/* including RX MIC key for TKIP */
u8 key[WOWLAN_KEY_MAX_SIZE];
u8 len;
u8 flags;
} gtk;
/*
* We use -1 for when we have valid data but don't know
* the key ID from firmware, and thus it needs to be
* installed with the last key (depending on rekeying).
*/
s8 key_id;
bool valid;
} gtk_seq[2];
struct {
/* Same as above */
@ -1556,12 +1567,10 @@ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
kfree_skb(pkt);
}
static void iwl_mvm_aes_sc_to_seq(struct aes_sc *sc,
struct ieee80211_key_seq *seq)
static void iwl_mvm_le64_to_aes_seq(__le64 le_pn, struct ieee80211_key_seq *seq)
{
u64 pn;
u64 pn = le64_to_cpu(le_pn);
pn = le64_to_cpu(sc->pn);
seq->ccmp.pn[0] = pn >> 40;
seq->ccmp.pn[1] = pn >> 32;
seq->ccmp.pn[2] = pn >> 24;
@ -1570,6 +1579,20 @@ static void iwl_mvm_aes_sc_to_seq(struct aes_sc *sc,
seq->ccmp.pn[5] = pn;
}
static void iwl_mvm_aes_sc_to_seq(struct aes_sc *sc,
struct ieee80211_key_seq *seq)
{
iwl_mvm_le64_to_aes_seq(sc->pn, seq);
}
static void iwl_mvm_le64_to_tkip_seq(__le64 le_pn, struct ieee80211_key_seq *seq)
{
u64 pn = le64_to_cpu(le_pn);
seq->tkip.iv16 = (u16)pn;
seq->tkip.iv32 = (u32)(pn >> 16);
}
static void iwl_mvm_tkip_sc_to_seq(struct tkip_sc *sc,
struct ieee80211_key_seq *seq)
{
@ -1630,10 +1653,12 @@ static void iwl_mvm_convert_key_counters(struct iwl_wowlan_status_data *status,
/* GTK RX counters */
for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
iwl_mvm_tkip_sc_to_seq(&sc->tkip.multicast_rsc[i],
&status->gtk.tkip.seq[i]);
&status->gtk_seq[0].tkip.seq[i]);
iwl_mvm_aes_sc_to_seq(&sc->aes.multicast_rsc[i],
&status->gtk.aes.seq[i]);
&status->gtk_seq[0].aes.seq[i]);
}
status->gtk_seq[0].valid = true;
status->gtk_seq[0].key_id = -1;
/* PTK TX counter */
status->ptk.tkip.tx_pn = (u64)le16_to_cpu(sc->tkip.tsc.iv16) |
@ -1649,24 +1674,103 @@ static void iwl_mvm_convert_key_counters(struct iwl_wowlan_status_data *status,
}
}
static void iwl_mvm_set_key_rx_seq(struct iwl_mvm *mvm,
struct ieee80211_key_conf *key,
struct iwl_wowlan_status_data *status)
static void
iwl_mvm_convert_key_counters_v5_gtk_seq(struct iwl_wowlan_status_data *status,
struct iwl_wowlan_all_rsc_tsc_v5 *sc,
unsigned int idx, unsigned int key_id)
{
int tid;
for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
iwl_mvm_le64_to_tkip_seq(sc->mcast_rsc[idx][tid],
&status->gtk_seq[idx].tkip.seq[tid]);
iwl_mvm_le64_to_aes_seq(sc->mcast_rsc[idx][tid],
&status->gtk_seq[idx].aes.seq[tid]);
}
status->gtk_seq[idx].valid = true;
status->gtk_seq[idx].key_id = key_id;
}
static void
iwl_mvm_convert_key_counters_v5(struct iwl_wowlan_status_data *status,
struct iwl_wowlan_all_rsc_tsc_v5 *sc)
{
int i, tid;
BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_MAX_TID_COUNT);
BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_NUM_RSC);
BUILD_BUG_ON(ARRAY_SIZE(sc->mcast_rsc) != ARRAY_SIZE(status->gtk_seq));
/* GTK RX counters */
for (i = 0; i < ARRAY_SIZE(sc->mcast_key_id_map); i++) {
u8 entry = sc->mcast_key_id_map[i];
if (entry < ARRAY_SIZE(sc->mcast_rsc))
iwl_mvm_convert_key_counters_v5_gtk_seq(status, sc,
entry, i);
}
/* PTK TX counters not needed, assigned in device */
/* PTK RX counters */
for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
iwl_mvm_le64_to_tkip_seq(sc->ucast_rsc[tid],
&status->ptk.tkip.seq[tid]);
iwl_mvm_le64_to_aes_seq(sc->ucast_rsc[tid],
&status->ptk.aes.seq[tid]);
}
}
static void iwl_mvm_set_key_rx_seq_idx(struct ieee80211_key_conf *key,
struct iwl_wowlan_status_data *status,
int idx)
{
switch (key->cipher) {
case WLAN_CIPHER_SUITE_CCMP:
case WLAN_CIPHER_SUITE_GCMP:
case WLAN_CIPHER_SUITE_GCMP_256:
iwl_mvm_set_key_rx_seq_tids(key, status->gtk.aes.seq);
iwl_mvm_set_key_rx_seq_tids(key, status->gtk_seq[idx].aes.seq);
break;
case WLAN_CIPHER_SUITE_TKIP:
iwl_mvm_set_key_rx_seq_tids(key, status->gtk.tkip.seq);
iwl_mvm_set_key_rx_seq_tids(key, status->gtk_seq[idx].tkip.seq);
break;
default:
WARN_ON(1);
}
}
static void iwl_mvm_set_key_rx_seq(struct ieee80211_key_conf *key,
struct iwl_wowlan_status_data *status,
bool installed)
{
int i;
for (i = 0; i < ARRAY_SIZE(status->gtk_seq); i++) {
if (!status->gtk_seq[i].valid)
continue;
/* Handle the case where we know the key ID */
if (status->gtk_seq[i].key_id == key->keyidx) {
s8 new_key_id = -1;
if (status->num_of_gtk_rekeys)
new_key_id = status->gtk.flags &
IWL_WOWLAN_GTK_IDX_MASK;
/* Don't install a new key's value to an old key */
if (new_key_id != key->keyidx)
iwl_mvm_set_key_rx_seq_idx(key, status, i);
continue;
}
/* handle the case where we didn't, last key only */
if (status->gtk_seq[i].key_id == -1 &&
(!status->num_of_gtk_rekeys || installed))
iwl_mvm_set_key_rx_seq_idx(key, status, i);
}
}
struct iwl_mvm_d3_gtk_iter_data {
struct iwl_mvm *mvm;
struct iwl_wowlan_status_data *status;
@ -1740,8 +1844,9 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
if (data->status->num_of_gtk_rekeys)
ieee80211_remove_key(key);
else if (data->last_gtk == key)
iwl_mvm_set_key_rx_seq(data->mvm, key, data->status);
if (data->last_gtk == key)
iwl_mvm_set_key_rx_seq(key, data->status, false);
}
static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
@ -1825,7 +1930,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
key = ieee80211_gtk_rekey_add(vif, &conf.conf);
if (IS_ERR(key))
return false;
iwl_mvm_set_key_rx_seq(mvm, key, status);
iwl_mvm_set_key_rx_seq(key, status, true);
replay_ctr = cpu_to_be64(status->replay_ctr);
@ -1893,9 +1998,10 @@ iwl_mvm_parse_wowlan_status_common_ ## _ver(struct iwl_mvm *mvm, \
iwl_mvm_parse_wowlan_status_common(v6)
iwl_mvm_parse_wowlan_status_common(v7)
iwl_mvm_parse_wowlan_status_common(v9)
iwl_mvm_parse_wowlan_status_common(v12)
static void iwl_mvm_convert_gtk(struct iwl_wowlan_status_data *status,
struct iwl_wowlan_gtk_status *data)
static void iwl_mvm_convert_gtk_v2(struct iwl_wowlan_status_data *status,
struct iwl_wowlan_gtk_status_v2 *data)
{
BUILD_BUG_ON(sizeof(status->gtk.key) < sizeof(data->key));
BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY +
@ -1913,6 +2019,26 @@ static void iwl_mvm_convert_gtk(struct iwl_wowlan_status_data *status,
data->tkip_mic_key, sizeof(data->tkip_mic_key));
}
static void iwl_mvm_convert_gtk_v3(struct iwl_wowlan_status_data *status,
struct iwl_wowlan_gtk_status_v3 *data)
{
/* The parts we need are identical in v2 and v3 */
#define CHECK(_f) do { \
BUILD_BUG_ON(offsetof(struct iwl_wowlan_gtk_status_v2, _f) != \
offsetof(struct iwl_wowlan_gtk_status_v3, _f)); \
BUILD_BUG_ON(offsetofend(struct iwl_wowlan_gtk_status_v2, _f) !=\
offsetofend(struct iwl_wowlan_gtk_status_v3, _f)); \
} while (0)
CHECK(key);
CHECK(key_len);
CHECK(key_flags);
CHECK(tkip_mic_key);
#undef CHECK
iwl_mvm_convert_gtk_v2(status, (void *)data);
}
static void iwl_mvm_convert_igtk(struct iwl_wowlan_status_data *status,
struct iwl_wowlan_igtk_status *data)
{
@ -2012,7 +2138,7 @@ iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id)
goto out_free_resp;
iwl_mvm_convert_key_counters(status, &v7->gtk[0].rsc.all_tsc_rsc);
iwl_mvm_convert_gtk(status, &v7->gtk[0]);
iwl_mvm_convert_gtk_v2(status, &v7->gtk[0]);
iwl_mvm_convert_igtk(status, &v7->igtk[0]);
} else if (notif_ver == 9 || notif_ver == 10 || notif_ver == 11) {
struct iwl_wowlan_status_v9 *v9 = (void *)cmd.resp_pkt->data;
@ -2025,10 +2151,22 @@ iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id)
goto out_free_resp;
iwl_mvm_convert_key_counters(status, &v9->gtk[0].rsc.all_tsc_rsc);
iwl_mvm_convert_gtk(status, &v9->gtk[0]);
iwl_mvm_convert_gtk_v2(status, &v9->gtk[0]);
iwl_mvm_convert_igtk(status, &v9->igtk[0]);
status->tid_tear_down = v9->tid_tear_down;
} else if (notif_ver == 12) {
struct iwl_wowlan_status_v12 *v12 = (void *)cmd.resp_pkt->data;
status = iwl_mvm_parse_wowlan_status_common_v12(mvm, v12, len);
if (IS_ERR(status))
goto out_free_resp;
iwl_mvm_convert_key_counters_v5(status, &v12->gtk[0].sc);
iwl_mvm_convert_gtk_v3(status, &v12->gtk[0]);
iwl_mvm_convert_igtk(status, &v12->igtk[0]);
status->tid_tear_down = v12->tid_tear_down;
} else {
IWL_ERR(mvm,
"Firmware advertises unknown WoWLAN status response %d!\n",

Просмотреть файл

@ -1022,6 +1022,11 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf,
if (mvm->fw_restart >= 0)
mvm->fw_restart++;
if (count == 6 && !strcmp(buf, "nolog\n")) {
set_bit(IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE, &mvm->status);
set_bit(STATUS_SUPPRESS_CMD_ERROR_ONCE, &mvm->trans->status);
}
/* take the return value to make compiler happy - it will fail anyway */
ret = iwl_mvm_send_cmd_pdu(mvm,
WIDE_ID(LONG_GROUP, REPLY_ERROR),
@ -1038,6 +1043,9 @@ static ssize_t iwl_dbgfs_fw_nmi_write(struct iwl_mvm *mvm, char *buf,
if (!iwl_mvm_firmware_running(mvm))
return -EIO;
if (count == 6 && !strcmp(buf, "nolog\n"))
set_bit(IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE, &mvm->status);
iwl_force_nmi(mvm->trans);
return count;

Просмотреть файл

@ -15,7 +15,7 @@
#include "fw/api/datapath.h"
#include "fw/api/phy.h"
#include "fw/api/config.h"
#include "fw/api/soc.h"
#include "fw/api/system.h"
#include "fw/api/alive.h"
#include "fw/api/binding.h"
#include "fw/api/cmdhdr.h"

Просмотреть файл

@ -123,13 +123,15 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
struct iwl_lmac_alive *lmac2 = NULL;
u16 status;
u32 lmac_error_event_table, umac_error_table;
u32 version = iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
UCODE_ALIVE_NTFY, 0);
/*
* For v5 and above, we can check the version, for older
* versions we need to check the size.
*/
if (iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
UCODE_ALIVE_NTFY, 0) == 5) {
if (version == 5 || version == 6) {
/* v5 and v6 are compatible (only IMR addition) */
struct iwl_alive_ntf_v5 *palive;
if (pkt_len < sizeof(*palive))
@ -516,7 +518,6 @@ static void iwl_mvm_phy_filter_init(struct iwl_mvm *mvm,
cpu_to_le32(IWL_MVM_PHY_FILTER_CHAIN_D);
}
}
#else /* CONFIG_ACPI */
static void iwl_mvm_phy_filter_init(struct iwl_mvm *mvm,
@ -525,6 +526,49 @@ static void iwl_mvm_phy_filter_init(struct iwl_mvm *mvm,
}
#endif /* CONFIG_ACPI */
#if defined(CONFIG_ACPI) && defined(CONFIG_EFI)
static int iwl_mvm_sgom_init(struct iwl_mvm *mvm)
{
u8 cmd_ver;
int ret;
struct iwl_host_cmd cmd = {
.id = WIDE_ID(REGULATORY_AND_NVM_GROUP,
SAR_OFFSET_MAPPING_TABLE_CMD),
.flags = 0,
.data[0] = &mvm->fwrt.sgom_table,
.len[0] = sizeof(mvm->fwrt.sgom_table),
.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
};
if (!mvm->fwrt.sgom_enabled) {
IWL_DEBUG_RADIO(mvm, "SGOM table is disabled\n");
return 0;
}
cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, REGULATORY_AND_NVM_GROUP,
SAR_OFFSET_MAPPING_TABLE_CMD,
IWL_FW_CMD_VER_UNKNOWN);
if (cmd_ver != 2) {
IWL_DEBUG_RADIO(mvm, "command version is unsupported. version = %d\n",
cmd_ver);
return 0;
}
ret = iwl_mvm_send_cmd(mvm, &cmd);
if (ret < 0)
IWL_ERR(mvm, "failed to send SAR_OFFSET_MAPPING_CMD (%d)\n", ret);
return ret;
}
#else
static int iwl_mvm_sgom_init(struct iwl_mvm *mvm)
{
return 0;
}
#endif
static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
{
struct iwl_phy_cfg_cmd_v3 phy_cfg_cmd;
@ -1338,6 +1382,7 @@ static u8 iwl_mvm_eval_dsm_rfi(struct iwl_mvm *mvm)
void iwl_mvm_get_acpi_tables(struct iwl_mvm *mvm)
{
}
#endif /* CONFIG_ACPI */
void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
@ -1632,6 +1677,10 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
else if (ret < 0)
goto error;
ret = iwl_mvm_sgom_init(mvm);
if (ret)
goto error;
iwl_mvm_tas_init(mvm);
iwl_mvm_leds_sync(mvm);

Просмотреть файл

@ -1732,6 +1732,7 @@ static void iwl_mvm_recalc_multicast(struct iwl_mvm *mvm)
struct iwl_mvm_mc_iter_data iter_data = {
.mvm = mvm,
};
int ret;
lockdep_assert_held(&mvm->mutex);
@ -1741,6 +1742,22 @@ static void iwl_mvm_recalc_multicast(struct iwl_mvm *mvm)
ieee80211_iterate_active_interfaces_atomic(
mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_mc_iface_iterator, &iter_data);
/*
* Send a (synchronous) ech command so that we wait for the
* multiple asynchronous MCAST_FILTER_CMD commands sent by
* the interface iterator. Otherwise, we might get here over
* and over again (by userspace just sending a lot of these)
* and the CPU can send them faster than the firmware can
* process them.
* Note that the CPU is still faster - but with this we'll
* actually send fewer commands overall because the CPU will
* not schedule the work in mac80211 as frequently if it's
* still running when rescheduled (possibly multiple times).
*/
ret = iwl_mvm_send_cmd_pdu(mvm, ECHO_CMD, 0, 0, NULL);
if (ret)
IWL_ERR(mvm, "Failed to synchronize multicast groups update\n");
}
static u64 iwl_mvm_prepare_multicast(struct ieee80211_hw *hw,
@ -3388,6 +3405,11 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
true);
} else if (old_state == IEEE80211_STA_AUTHORIZED &&
new_state == IEEE80211_STA_ASSOC) {
/* once we move into assoc state, need to update rate scale to
* disable using wide bandwidth
*/
iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
false);
if (!sta->tdls) {
/* Multicast data frames are no longer allowed */
iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
@ -3410,16 +3432,16 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
if (vif->type == NL80211_IFTYPE_AP) {
mvmvif->ap_assoc_sta_count--;
iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
} else if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
/* remove session protection if still running */
} else if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
iwl_mvm_stop_session_protection(mvm, vif);
}
ret = 0;
} else if (old_state == IEEE80211_STA_AUTH &&
new_state == IEEE80211_STA_NONE) {
ret = 0;
} else if (old_state == IEEE80211_STA_NONE &&
new_state == IEEE80211_STA_NOTEXIST) {
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
iwl_mvm_stop_session_protection(mvm, vif);
ret = iwl_mvm_rm_sta(mvm, vif, sta);
if (sta->tdls) {
iwl_mvm_recalc_tdls_state(mvm, vif, false);
@ -3585,13 +3607,14 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
struct iwl_mvm_sta *mvmsta;
struct iwl_mvm_sta *mvmsta = NULL;
struct iwl_mvm_key_pn *ptk_pn;
int keyidx = key->keyidx;
int ret, i;
u8 key_offset;
mvmsta = iwl_mvm_sta_from_mac80211(sta);
if (sta)
mvmsta = iwl_mvm_sta_from_mac80211(sta);
switch (key->cipher) {
case WLAN_CIPHER_SUITE_TKIP:
@ -3693,7 +3716,7 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
}
if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
sta && iwl_mvm_has_new_rx_api(mvm) &&
mvmsta && iwl_mvm_has_new_rx_api(mvm) &&
key->flags & IEEE80211_KEY_FLAG_PAIRWISE &&
(key->cipher == WLAN_CIPHER_SUITE_CCMP ||
key->cipher == WLAN_CIPHER_SUITE_GCMP ||
@ -3727,7 +3750,7 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
else
key_offset = STA_KEY_IDX_INVALID;
if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
if (mvmsta && key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
mvmsta->pairwise_cipher = key->cipher;
IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n");
@ -3770,7 +3793,7 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
break;
}
if (sta && iwl_mvm_has_new_rx_api(mvm) &&
if (mvmsta && iwl_mvm_has_new_rx_api(mvm) &&
key->flags & IEEE80211_KEY_FLAG_PAIRWISE &&
(key->cipher == WLAN_CIPHER_SUITE_CCMP ||
key->cipher == WLAN_CIPHER_SUITE_GCMP ||

Просмотреть файл

@ -94,11 +94,10 @@ struct iwl_mvm_phy_ctxt {
enum nl80211_chan_width width;
/*
* TODO: This should probably be removed. Currently here only for rate
* scaling algorithm
*/
struct ieee80211_channel *channel;
/* track for RLC config command */
u32 center_freq1;
};
struct iwl_mvm_time_event_data {
@ -1138,6 +1137,8 @@ struct iwl_mvm {
* @IWL_MVM_STATUS_FIRMWARE_RUNNING: firmware is running
* @IWL_MVM_STATUS_NEED_FLUSH_P2P: need to flush P2P bcast STA
* @IWL_MVM_STATUS_IN_D3: in D3 (or at least about to go into it)
* @IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE: suppress one error log
* if this is set, when intentionally triggered
* @IWL_MVM_STATUS_STARTING: starting mac,
* used to disable restart flow while in STARTING state
*/
@ -1151,6 +1152,7 @@ enum iwl_mvm_status {
IWL_MVM_STATUS_FIRMWARE_RUNNING,
IWL_MVM_STATUS_NEED_FLUSH_P2P,
IWL_MVM_STATUS_IN_D3,
IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE,
IWL_MVM_STATUS_STARTING,
};

Просмотреть файл

@ -26,6 +26,7 @@
#include "time-event.h"
#include "fw-api.h"
#include "fw/acpi.h"
#include "fw/uefi.h"
#define DRV_DESCRIPTION "The new Intel(R) wireless AGN driver for Linux"
MODULE_DESCRIPTION(DRV_DESCRIPTION);
@ -78,7 +79,7 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
{
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash;
u32 reg_val = 0;
u32 reg_val;
u32 phy_config = iwl_mvm_get_phy_config(mvm);
radio_cfg_type = (phy_config & FW_PHY_CFG_RADIO_TYPE) >>
@ -89,10 +90,7 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
FW_PHY_CFG_RADIO_DASH_POS;
/* SKU control */
reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) <<
CSR_HW_IF_CONFIG_REG_POS_MAC_STEP;
reg_val |= CSR_HW_REV_DASH(mvm->trans->hw_rev) <<
CSR_HW_IF_CONFIG_REG_POS_MAC_DASH;
reg_val = CSR_HW_REV_STEP_DASH(mvm->trans->hw_rev);
/* radio configuration */
reg_val |= radio_cfg_type << CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE;
@ -117,8 +115,7 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
reg_val |= CSR_HW_IF_CONFIG_REG_D3_DEBUG;
iwl_trans_set_bits_mask(mvm->trans, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH |
CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP |
CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP_DASH |
CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE |
CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP |
CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH |
@ -502,6 +499,9 @@ static const struct iwl_hcmd_names iwl_mvm_system_names[] = {
HCMD_NAME(SHARED_MEM_CFG_CMD),
HCMD_NAME(INIT_EXTENDED_CFG_CMD),
HCMD_NAME(FW_ERROR_RECOVERY_CMD),
HCMD_NAME(RFI_CONFIG_CMD),
HCMD_NAME(RFI_GET_FREQ_TABLE_CMD),
HCMD_NAME(SYSTEM_FEATURES_CONTROL_CMD),
};
/* Please keep this array *SORTED* by hex value.
@ -534,6 +534,7 @@ static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = {
HCMD_NAME(UPDATE_MU_GROUPS_CMD),
HCMD_NAME(TRIGGER_RX_QUEUES_NOTIF_CMD),
HCMD_NAME(STA_HE_CTXT_CMD),
HCMD_NAME(RLC_CONFIG_CMD),
HCMD_NAME(RFH_QUEUE_CONFIG_CMD),
HCMD_NAME(TLC_MNG_CONFIG_CMD),
HCMD_NAME(CHEST_COLLECTOR_FILTER_CONFIG_CMD),
@ -1057,7 +1058,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
};
int scan_size;
u32 min_backoff;
enum iwl_amsdu_size rb_size_default;
struct iwl_mvm_csme_conn_info *csme_conn_info __maybe_unused;
/*
@ -1097,6 +1097,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
&iwl_mvm_sanitize_ops, mvm, dbgfs_dir);
iwl_mvm_get_acpi_tables(mvm);
iwl_uefi_get_sgom_table(trans, &mvm->fwrt);
mvm->init_status = 0;
@ -1200,14 +1201,9 @@ 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->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
rb_size_default = IWL_AMSDU_2K;
else
rb_size_default = IWL_AMSDU_4K;
switch (iwlwifi_mod_params.amsdu_size) {
case IWL_AMSDU_DEF:
trans_cfg.rx_buf_size = rb_size_default;
trans_cfg.rx_buf_size = IWL_AMSDU_4K;
break;
case IWL_AMSDU_4K:
trans_cfg.rx_buf_size = IWL_AMSDU_4K;
@ -1221,7 +1217,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
default:
pr_err("%s: Unsupported amsdu_size: %d\n", KBUILD_MODNAME,
iwlwifi_mod_params.amsdu_size);
trans_cfg.rx_buf_size = rb_size_default;
trans_cfg.rx_buf_size = IWL_AMSDU_4K;
}
trans->wide_cmd_header = true;
@ -1850,7 +1846,9 @@ static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode, bool sync)
{
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
if (!test_bit(STATUS_TRANS_DEAD, &mvm->trans->status))
if (!test_bit(STATUS_TRANS_DEAD, &mvm->trans->status) &&
!test_and_clear_bit(IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE,
&mvm->status))
iwl_mvm_dump_nic_error_log(mvm);
if (sync) {

Просмотреть файл

@ -157,8 +157,43 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
/* Set the channel info data */
iwl_mvm_set_chan_info_chandef(mvm, &cmd->ci, chandef);
iwl_mvm_phy_ctxt_set_rxchain(mvm, ctxt, &cmd->rxchain_info,
/* we only support RLC command version 2 */
if (iwl_fw_lookup_cmd_ver(mvm->fw, DATA_PATH_GROUP,
RLC_CONFIG_CMD, 0) < 2)
iwl_mvm_phy_ctxt_set_rxchain(mvm, ctxt, &cmd->rxchain_info,
chains_static, chains_dynamic);
}
static int iwl_mvm_phy_send_rlc(struct iwl_mvm *mvm,
struct iwl_mvm_phy_ctxt *ctxt,
u8 chains_static, u8 chains_dynamic)
{
struct iwl_rlc_config_cmd cmd = {
.phy_id = cpu_to_le32(ctxt->id),
};
if (iwl_fw_lookup_cmd_ver(mvm->fw, DATA_PATH_GROUP,
RLC_CONFIG_CMD, 0) < 2)
return 0;
BUILD_BUG_ON(IWL_RLC_CHAIN_INFO_DRIVER_FORCE !=
PHY_RX_CHAIN_DRIVER_FORCE_MSK);
BUILD_BUG_ON(IWL_RLC_CHAIN_INFO_VALID !=
PHY_RX_CHAIN_VALID_MSK);
BUILD_BUG_ON(IWL_RLC_CHAIN_INFO_FORCE !=
PHY_RX_CHAIN_FORCE_SEL_MSK);
BUILD_BUG_ON(IWL_RLC_CHAIN_INFO_FORCE_MIMO !=
PHY_RX_CHAIN_FORCE_MIMO_SEL_MSK);
BUILD_BUG_ON(IWL_RLC_CHAIN_INFO_COUNT != PHY_RX_CHAIN_CNT_MSK);
BUILD_BUG_ON(IWL_RLC_CHAIN_INFO_MIMO_COUNT !=
PHY_RX_CHAIN_MIMO_CNT_MSK);
iwl_mvm_phy_ctxt_set_rxchain(mvm, ctxt, &cmd.rlc.rx_chain_info,
chains_static, chains_dynamic);
return iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(RLC_CONFIG_CMD,
DATA_PATH_GROUP, 2),
0, sizeof(cmd), &cmd);
}
/*
@ -177,7 +212,7 @@ static int iwl_mvm_phy_ctxt_apply(struct iwl_mvm *mvm,
int ver = iwl_fw_lookup_cmd_ver(mvm->fw, IWL_ALWAYS_LONG_GROUP,
PHY_CONTEXT_CMD, 1);
if (ver == 3) {
if (ver == 3 || ver == 4) {
struct iwl_phy_context_cmd cmd = {};
/* Set the command header fields */
@ -211,9 +246,16 @@ static int iwl_mvm_phy_ctxt_apply(struct iwl_mvm *mvm,
}
if (ret)
if (ret) {
IWL_ERR(mvm, "PHY ctxt cmd error. ret=%d\n", ret);
return ret;
return ret;
}
if (action != FW_CTXT_ACTION_REMOVE)
return iwl_mvm_phy_send_rlc(mvm, ctxt, chains_static,
chains_dynamic);
return 0;
}
/*
@ -228,6 +270,8 @@ int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
lockdep_assert_held(&mvm->mutex);
ctxt->channel = chandef->chan;
ctxt->width = chandef->width;
ctxt->center_freq1 = chandef->center_freq1;
return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
chains_static, chains_dynamic,
@ -257,6 +301,14 @@ int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
lockdep_assert_held(&mvm->mutex);
if (iwl_fw_lookup_cmd_ver(mvm->fw, DATA_PATH_GROUP,
RLC_CONFIG_CMD, 0) >= 2 &&
ctxt->channel == chandef->chan &&
ctxt->width == chandef->width &&
ctxt->center_freq1 == chandef->center_freq1)
return iwl_mvm_phy_send_rlc(mvm, ctxt, chains_static,
chains_dynamic);
if (fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT) &&
ctxt->channel->band != chandef->chan->band) {
@ -275,6 +327,8 @@ int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
ctxt->channel = chandef->chan;
ctxt->width = chandef->width;
ctxt->center_freq1 = chandef->center_freq1;
return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
chains_static, chains_dynamic,
action);

Просмотреть файл

@ -7,7 +7,7 @@
#include "fw/api/commands.h"
#include "fw/api/phy-ctxt.h"
/**
/*
* DDR needs frequency in units of 16.666MHz, so provide FW with the
* frequency values in the adjusted format.
*/

Просмотреть файл

@ -291,8 +291,12 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,
notif = (void *)pkt->data;
sta = rcu_dereference(mvm->fw_id_to_mac_id[notif->sta_id]);
if (IS_ERR_OR_NULL(sta)) {
IWL_ERR(mvm, "Invalid sta id (%d) in FW TLC notification\n",
notif->sta_id);
/* can happen in remove station flow where mvm removed internally
* the station before removing from FW
*/
IWL_DEBUG_RATE(mvm,
"Invalid mvm RCU pointer for sta id (%d) in TLC notification\n",
notif->sta_id);
goto out;
}

Просмотреть файл

@ -527,40 +527,19 @@ struct iwl_mvm_stat_data {
u8 *beacon_average_energy;
};
static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
struct ieee80211_vif *vif)
struct iwl_mvm_stat_data_all_macs {
struct iwl_mvm *mvm;
__le32 flags;
struct iwl_statistics_ntfy_per_mac *per_mac_stats;
};
static void iwl_mvm_update_vif_sig(struct ieee80211_vif *vif, int sig)
{
struct iwl_mvm_stat_data *data = _data;
struct iwl_mvm *mvm = data->mvm;
int sig = -data->beacon_filter_average_energy;
int last_event;
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm *mvm = mvmvif->mvm;
int thold = vif->bss_conf.cqm_rssi_thold;
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.
*/
mvmvif->beacon_stats.num_beacons =
le32_to_cpu(data->beacon_counter[vif_id]);
mvmvif->beacon_stats.avg_signal =
-data->beacon_average_energy[vif_id];
/* make sure that beacon statistics don't go backwards with TCM
* request to clear statistics
*/
if (le32_to_cpu(data->flags) & IWL_STATISTICS_REPLY_FLG_CLEAR)
mvmvif->beacon_stats.accu_num_beacons +=
mvmvif->beacon_stats.num_beacons;
if (mvmvif->id != id)
return;
if (vif->type != NL80211_IFTYPE_STATION)
return;
int last_event;
if (sig == 0) {
IWL_DEBUG_RX(mvm, "RSSI is 0 - skip signal based decision\n");
@ -618,6 +597,73 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
}
}
static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
struct ieee80211_vif *vif)
{
struct iwl_mvm_stat_data *data = _data;
int sig = -data->beacon_filter_average_energy;
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.
*/
mvmvif->beacon_stats.num_beacons =
le32_to_cpu(data->beacon_counter[vif_id]);
mvmvif->beacon_stats.avg_signal =
-data->beacon_average_energy[vif_id];
if (mvmvif->id != id)
return;
if (vif->type != NL80211_IFTYPE_STATION)
return;
/* make sure that beacon statistics don't go backwards with TCM
* request to clear statistics
*/
if (le32_to_cpu(data->flags) & IWL_STATISTICS_REPLY_FLG_CLEAR)
mvmvif->beacon_stats.accu_num_beacons +=
mvmvif->beacon_stats.num_beacons;
iwl_mvm_update_vif_sig(vif, sig);
}
static void iwl_mvm_stat_iterator_all_macs(void *_data, u8 *mac,
struct ieee80211_vif *vif)
{
struct iwl_mvm_stat_data_all_macs *data = _data;
struct iwl_statistics_ntfy_per_mac *mac_stats;
int sig;
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
u16 vif_id = mvmvif->id;
if (WARN_ONCE(vif_id > MAC_INDEX_AUX, "invalid vif id: %d", vif_id))
return;
if (vif->type != NL80211_IFTYPE_STATION)
return;
mac_stats = &data->per_mac_stats[vif_id];
mvmvif->beacon_stats.num_beacons =
le32_to_cpu(mac_stats->beacon_counter);
mvmvif->beacon_stats.avg_signal =
-le32_to_cpu(mac_stats->beacon_average_energy);
/* make sure that beacon statistics don't go backwards with TCM
* request to clear statistics
*/
if (le32_to_cpu(data->flags) & IWL_STATISTICS_REPLY_FLG_CLEAR)
mvmvif->beacon_stats.accu_num_beacons +=
mvmvif->beacon_stats.num_beacons;
sig = -le32_to_cpu(mac_stats->beacon_filter_average_energy);
iwl_mvm_update_vif_sig(vif, sig);
}
static inline void
iwl_mvm_rx_stats_check_trigger(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt)
{
@ -684,47 +730,41 @@ iwl_mvm_update_tcm_from_stats(struct iwl_mvm *mvm, __le32 *air_time_le,
}
static void
iwl_mvm_handle_rx_statistics_tlv(struct iwl_mvm *mvm,
struct iwl_rx_packet *pkt)
iwl_mvm_stats_ver_15(struct iwl_mvm *mvm,
struct iwl_statistics_operational_ntfy *stats)
{
struct iwl_mvm_stat_data_all_macs data = {
.mvm = mvm,
.flags = stats->flags,
.per_mac_stats = stats->per_mac_stats,
};
ieee80211_iterate_active_interfaces(mvm->hw,
IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_stat_iterator_all_macs,
&data);
}
static void
iwl_mvm_stats_ver_14(struct iwl_mvm *mvm,
struct iwl_statistics_operational_ntfy_ver_14 *stats)
{
struct iwl_mvm_stat_data data = {
.mvm = mvm,
};
u8 beacon_average_energy[MAC_INDEX_AUX];
u8 average_energy[IWL_MVM_STATION_COUNT_MAX];
struct iwl_statistics_operational_ntfy *stats;
int expected_size;
__le32 flags;
int i;
expected_size = sizeof(*stats);
if (WARN_ONCE(iwl_rx_packet_payload_len(pkt) < expected_size,
"received invalid statistics size (%d)!, expected_size: %d\n",
iwl_rx_packet_payload_len(pkt), expected_size))
return;
stats = (void *)&pkt->data;
if (WARN_ONCE(stats->hdr.type != FW_STATISTICS_OPERATIONAL ||
stats->hdr.version !=
iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP, STATISTICS_CMD, 0),
"received unsupported hdr type %d, version %d\n",
stats->hdr.type, stats->hdr.version))
return;
flags = stats->flags;
mvm->radio_stats.rx_time = le64_to_cpu(stats->rx_time);
mvm->radio_stats.tx_time = le64_to_cpu(stats->tx_time);
mvm->radio_stats.on_time_rf = le64_to_cpu(stats->on_time_rf);
mvm->radio_stats.on_time_scan = le64_to_cpu(stats->on_time_scan);
iwl_mvm_rx_stats_check_trigger(mvm, pkt);
data.mac_id = stats->mac_id;
data.beacon_filter_average_energy =
le32_to_cpu(stats->beacon_filter_average_energy);
data.flags = flags;
data.beacon_counter = stats->beacon_counter;
for (i = 0; i < ARRAY_SIZE(beacon_average_energy); i++)
beacon_average_energy[i] =
le32_to_cpu(stats->beacon_average_energy[i]);
@ -735,9 +775,105 @@ iwl_mvm_handle_rx_statistics_tlv(struct iwl_mvm *mvm,
IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_stat_iterator,
&data);
}
static bool iwl_mvm_verify_stats_len(struct iwl_mvm *mvm,
struct iwl_rx_packet *pkt,
u32 expected_size)
{
struct iwl_statistics_ntfy_hdr *hdr;
if (WARN_ONCE(iwl_rx_packet_payload_len(pkt) < expected_size,
"received invalid statistics size (%d)!, expected_size: %d\n",
iwl_rx_packet_payload_len(pkt), expected_size))
return false;
hdr = (void *)&pkt->data;
if (WARN_ONCE((hdr->type & IWL_STATISTICS_TYPE_MSK) != FW_STATISTICS_OPERATIONAL ||
hdr->version !=
iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP, STATISTICS_NOTIFICATION, 0),
"received unsupported hdr type %d, version %d\n",
hdr->type, hdr->version))
return false;
if (WARN_ONCE(le16_to_cpu(hdr->size) != expected_size,
"received invalid statistics size in header (%d)!, expected_size: %d\n",
le16_to_cpu(hdr->size), expected_size))
return false;
return true;
}
static void
iwl_mvm_handle_rx_statistics_tlv(struct iwl_mvm *mvm,
struct iwl_rx_packet *pkt)
{
u8 average_energy[IWL_MVM_STATION_COUNT_MAX];
__le32 air_time[MAC_INDEX_AUX];
__le32 rx_bytes[MAC_INDEX_AUX];
__le32 flags = 0;
int i;
u32 notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
STATISTICS_NOTIFICATION, 0);
if (WARN_ONCE(notif_ver > 15,
"invalid statistics version id: %d\n", notif_ver))
return;
if (notif_ver == 14) {
struct iwl_statistics_operational_ntfy_ver_14 *stats =
(void *)pkt->data;
if (!iwl_mvm_verify_stats_len(mvm, pkt, sizeof(*stats)))
return;
iwl_mvm_stats_ver_14(mvm, stats);
flags = stats->flags;
mvm->radio_stats.rx_time = le64_to_cpu(stats->rx_time);
mvm->radio_stats.tx_time = le64_to_cpu(stats->tx_time);
mvm->radio_stats.on_time_rf = le64_to_cpu(stats->on_time_rf);
mvm->radio_stats.on_time_scan =
le64_to_cpu(stats->on_time_scan);
for (i = 0; i < ARRAY_SIZE(average_energy); i++)
average_energy[i] = le32_to_cpu(stats->average_energy[i]);
for (i = 0; i < ARRAY_SIZE(air_time); i++) {
air_time[i] = stats->air_time[i];
rx_bytes[i] = stats->rx_bytes[i];
}
}
if (notif_ver == 15) {
struct iwl_statistics_operational_ntfy *stats =
(void *)pkt->data;
if (!iwl_mvm_verify_stats_len(mvm, pkt, sizeof(*stats)))
return;
iwl_mvm_stats_ver_15(mvm, stats);
flags = stats->flags;
mvm->radio_stats.rx_time = le64_to_cpu(stats->rx_time);
mvm->radio_stats.tx_time = le64_to_cpu(stats->tx_time);
mvm->radio_stats.on_time_rf = le64_to_cpu(stats->on_time_rf);
mvm->radio_stats.on_time_scan =
le64_to_cpu(stats->on_time_scan);
for (i = 0; i < ARRAY_SIZE(average_energy); i++)
average_energy[i] =
le32_to_cpu(stats->per_sta_stats[i].average_energy);
for (i = 0; i < ARRAY_SIZE(air_time); i++) {
air_time[i] = stats->per_mac_stats[i].air_time;
rx_bytes[i] = stats->per_mac_stats[i].rx_bytes;
}
}
iwl_mvm_rx_stats_check_trigger(mvm, pkt);
for (i = 0; i < ARRAY_SIZE(average_energy); i++)
average_energy[i] = le32_to_cpu(stats->average_energy[i]);
ieee80211_iterate_stations_atomic(mvm->hw, iwl_mvm_stats_energy_iter,
average_energy);
/*
@ -746,8 +882,7 @@ iwl_mvm_handle_rx_statistics_tlv(struct iwl_mvm *mvm,
* request and once in statistics notification.
*/
if (le32_to_cpu(flags) & IWL_STATISTICS_REPLY_FLG_CLEAR)
iwl_mvm_update_tcm_from_stats(mvm, stats->air_time,
stats->rx_bytes);
iwl_mvm_update_tcm_from_stats(mvm, air_time, rx_bytes);
}
void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
@ -761,8 +896,8 @@ void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
u8 *energy;
/* From ver 14 and up we use TLV statistics format */
if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP,
STATISTICS_CMD, 0) >= 14)
if (iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
STATISTICS_NOTIFICATION, 0) >= 14)
return iwl_mvm_handle_rx_statistics_tlv(mvm, pkt);
if (!iwl_mvm_has_new_rx_stats_api(mvm)) {

Просмотреть файл

@ -766,8 +766,11 @@ static void iwl_mvm_release_frames_from_notif(struct iwl_mvm *mvm,
rcu_read_lock();
ba_data = rcu_dereference(mvm->baid_map[baid]);
if (WARN_ON_ONCE(!ba_data))
if (!ba_data) {
WARN(!(flags & IWL_MVM_RELEASE_FROM_RSS_SYNC),
"BAID %d not found in map\n", baid);
goto out;
}
sta = rcu_dereference(mvm->fw_id_to_mac_id[ba_data->sta_id]);
if (WARN_ON_ONCE(IS_ERR_OR_NULL(sta)))

Просмотреть файл

@ -1394,8 +1394,8 @@ static u32 iwl_mvm_scan_umac_ooc_priority(struct iwl_mvm_scan_params *params)
}
static void
iwl_mvm_scan_umac_dwell_v10(struct iwl_mvm *mvm,
struct iwl_scan_general_params_v10 *general_params,
iwl_mvm_scan_umac_dwell_v11(struct iwl_mvm *mvm,
struct iwl_scan_general_params_v11 *general_params,
struct iwl_mvm_scan_params *params)
{
struct iwl_mvm_scan_timing_params *timing, *hb_timing;
@ -2238,15 +2238,15 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
}
static void
iwl_mvm_scan_umac_fill_general_p_v10(struct iwl_mvm *mvm,
iwl_mvm_scan_umac_fill_general_p_v11(struct iwl_mvm *mvm,
struct iwl_mvm_scan_params *params,
struct ieee80211_vif *vif,
struct iwl_scan_general_params_v10 *gp,
struct iwl_scan_general_params_v11 *gp,
u16 gen_flags)
{
struct iwl_mvm_vif *scan_vif = iwl_mvm_vif_from_mac80211(vif);
iwl_mvm_scan_umac_dwell_v10(mvm, gp, params);
iwl_mvm_scan_umac_dwell_v11(mvm, gp, params);
gp->flags = cpu_to_le16(gen_flags);
@ -2350,7 +2350,7 @@ static int iwl_mvm_scan_umac_v12(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
cmd->uid = cpu_to_le32(uid);
gen_flags = iwl_mvm_scan_umac_flags_v2(mvm, params, vif, type);
iwl_mvm_scan_umac_fill_general_p_v10(mvm, params, vif,
iwl_mvm_scan_umac_fill_general_p_v11(mvm, params, vif,
&scan_p->general_params,
gen_flags);
@ -2367,12 +2367,13 @@ static int iwl_mvm_scan_umac_v12(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
return 0;
}
static int iwl_mvm_scan_umac_v14(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
struct iwl_mvm_scan_params *params, int type,
int uid)
static int iwl_mvm_scan_umac_v14_and_above(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct iwl_mvm_scan_params *params,
int type, int uid, u32 version)
{
struct iwl_scan_req_umac_v14 *cmd = mvm->scan_cmd;
struct iwl_scan_req_params_v14 *scan_p = &cmd->scan_params;
struct iwl_scan_req_umac_v15 *cmd = mvm->scan_cmd;
struct iwl_scan_req_params_v15 *scan_p = &cmd->scan_params;
struct iwl_scan_channel_params_v6 *cp = &scan_p->channel_params;
struct iwl_scan_probe_params_v4 *pb = &scan_p->probe_params;
int ret;
@ -2385,7 +2386,7 @@ static int iwl_mvm_scan_umac_v14(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
cmd->uid = cpu_to_le32(uid);
gen_flags = iwl_mvm_scan_umac_flags_v2(mvm, params, vif, type);
iwl_mvm_scan_umac_fill_general_p_v10(mvm, params, vif,
iwl_mvm_scan_umac_fill_general_p_v11(mvm, params, vif,
&scan_p->general_params,
gen_flags);
@ -2425,6 +2426,20 @@ static int iwl_mvm_scan_umac_v14(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
return 0;
}
static int iwl_mvm_scan_umac_v14(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
struct iwl_mvm_scan_params *params, int type,
int uid)
{
return iwl_mvm_scan_umac_v14_and_above(mvm, vif, params, type, uid, 14);
}
static int iwl_mvm_scan_umac_v15(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
struct iwl_mvm_scan_params *params, int type,
int uid)
{
return iwl_mvm_scan_umac_v14_and_above(mvm, vif, params, type, uid, 15);
}
static int iwl_mvm_num_scans(struct iwl_mvm *mvm)
{
return hweight32(mvm->scan_status & IWL_MVM_SCAN_MASK);
@ -2540,6 +2555,7 @@ struct iwl_scan_umac_handler {
static const struct iwl_scan_umac_handler iwl_scan_umac_handlers[] = {
/* set the newest version first to shorten the list traverse time */
IWL_SCAN_UMAC_HANDLER(15),
IWL_SCAN_UMAC_HANDLER(14),
IWL_SCAN_UMAC_HANDLER(12),
};
@ -2940,15 +2956,14 @@ static int iwl_mvm_scan_stop_wait(struct iwl_mvm *mvm, int type)
1 * HZ);
}
#define IWL_SCAN_REQ_UMAC_HANDLE_SIZE(_ver) { \
case (_ver): return sizeof(struct iwl_scan_req_umac_v##_ver); \
}
static int iwl_scan_req_umac_get_size(u8 scan_ver)
{
switch (scan_ver) {
IWL_SCAN_REQ_UMAC_HANDLE_SIZE(14);
IWL_SCAN_REQ_UMAC_HANDLE_SIZE(12);
case 12:
return sizeof(struct iwl_scan_req_umac_v12);
case 14:
case 15:
return sizeof(struct iwl_scan_req_umac_v15);
}
return 0;

Просмотреть файл

@ -2684,6 +2684,16 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
RCU_INIT_POINTER(mvm->baid_map[baid], NULL);
kfree_rcu(baid_data, rcu_head);
IWL_DEBUG_HT(mvm, "BAID %d is free\n", baid);
/*
* After we've deleted it, do another queue sync
* so if an IWL_MVM_RXQ_NSSN_SYNC was concurrently
* running it won't find a new session in the old
* BAID. It can find the NULL pointer for the BAID,
* but we must not have it find a different session.
*/
iwl_mvm_sync_rx_queues_internal(mvm, IWL_MVM_RXQ_EMPTY,
true, NULL, 0);
}
return 0;

Просмотреть файл

@ -1158,15 +1158,10 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
mvmvif->color)),
.action = cpu_to_le32(FW_CTXT_ACTION_ADD),
.conf_id = cpu_to_le32(SESSION_PROTECT_CONF_ASSOC),
.duration_tu = cpu_to_le32(MSEC_TO_TU(duration)),
};
/* The time_event_data.id field is reused to save session
* protection's configuration.
*/
mvmvif->time_event_data.id = SESSION_PROTECT_CONF_ASSOC;
cmd.conf_id = cpu_to_le32(mvmvif->time_event_data.id);
lockdep_assert_held(&mvm->mutex);
spin_lock_bh(&mvm->time_event_lock);
@ -1180,6 +1175,11 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
}
iwl_mvm_te_clear_data(mvm, te_data);
/*
* The time_event_data.id field is reused to save session
* protection's configuration.
*/
te_data->id = le32_to_cpu(cmd.conf_id);
te_data->duration = le32_to_cpu(cmd.duration_tu);
te_data->vif = vif;
spin_unlock_bh(&mvm->time_event_lock);

Просмотреть файл

@ -340,25 +340,64 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
ieee80211_request_smps(vif, smps_mode);
}
static bool iwl_wait_stats_complete(struct iwl_notif_wait_data *notif_wait,
struct iwl_rx_packet *pkt, void *data)
{
WARN_ON(pkt->hdr.cmd != STATISTICS_NOTIFICATION);
return true;
}
int iwl_mvm_request_statistics(struct iwl_mvm *mvm, bool clear)
{
struct iwl_statistics_cmd scmd = {
.flags = clear ? cpu_to_le32(IWL_STATISTICS_FLG_CLEAR) : 0,
};
struct iwl_host_cmd cmd = {
.id = STATISTICS_CMD,
.len[0] = sizeof(scmd),
.data[0] = &scmd,
.flags = CMD_WANT_SKB,
};
int ret;
ret = iwl_mvm_send_cmd(mvm, &cmd);
if (ret)
return ret;
/* From version 15 - STATISTICS_NOTIFICATION, the reply for
* STATISTICS_CMD is empty, and the response is with
* STATISTICS_NOTIFICATION notification
*/
if (iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
STATISTICS_NOTIFICATION, 0) < 15) {
cmd.flags = CMD_WANT_SKB;
iwl_mvm_handle_rx_statistics(mvm, cmd.resp_pkt);
iwl_free_resp(&cmd);
ret = iwl_mvm_send_cmd(mvm, &cmd);
if (ret)
return ret;
iwl_mvm_handle_rx_statistics(mvm, cmd.resp_pkt);
iwl_free_resp(&cmd);
} else {
struct iwl_notification_wait stats_wait;
static const u16 stats_complete[] = {
STATISTICS_NOTIFICATION,
};
iwl_init_notification_wait(&mvm->notif_wait, &stats_wait,
stats_complete, ARRAY_SIZE(stats_complete),
iwl_wait_stats_complete, NULL);
ret = iwl_mvm_send_cmd(mvm, &cmd);
if (ret) {
iwl_remove_notification(&mvm->notif_wait, &stats_wait);
return ret;
}
/* 200ms should be enough for FW to collect data from all
* LMACs and send STATISTICS_NOTIFICATION to host
*/
ret = iwl_wait_notification(&mvm->notif_wait, &stats_wait, HZ / 5);
if (ret)
return ret;
}
if (clear)
iwl_mvm_accu_radio_stats(mvm);

Просмотреть файл

@ -562,6 +562,7 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
IWL_DEV_INFO(0x43F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0, iwl_ax201_killer_1650i_name),
IWL_DEV_INFO(0x43F0, 0x2074, iwl_ax201_cfg_qu_hr, NULL),
IWL_DEV_INFO(0x43F0, 0x4070, iwl_ax201_cfg_qu_hr, NULL),
IWL_DEV_INFO(0x43F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0, iwl_ax201_killer_1650s_name),
IWL_DEV_INFO(0xA0F0, 0x0070, iwl_ax201_cfg_qu_hr, NULL),
IWL_DEV_INFO(0xA0F0, 0x0074, iwl_ax201_cfg_qu_hr, NULL),
IWL_DEV_INFO(0xA0F0, 0x0078, iwl_ax201_cfg_qu_hr, NULL),
@ -959,6 +960,11 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY,
IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB,
iwl_qu_c0_hr_b0, iwl_ax203_name),
_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP,
IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY,
IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB,
iwl_qu_c0_hr_b0, iwl_ax201_name),
/* QuZ */
_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
@ -1097,6 +1103,11 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY,
IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB,
iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_name),
_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY,
IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY,
IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_CDB,
iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_name),
/* Bz */
_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
@ -1130,6 +1141,13 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB,
iwl_cfg_gl_a0_fm_a0, iwl_bz_name),
/* BZ Z step */
_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
IWL_CFG_MAC_TYPE_BZ, SILICON_Z_STEP,
IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY,
IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB,
iwl_cfg_bz_z0_gf_a0, iwl_bz_name),
/* SoF with JF2 */
_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY,
@ -1204,6 +1222,11 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY,
IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB,
iwlax211_2ax_cfg_so_gf_a0, iwl_ax211_name),
_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY,
IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY,
IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_CDB,
iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_name),
/* So with JF2 */
_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
@ -1456,7 +1479,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dev_info = iwl_pci_find_dev_info(pdev->device, pdev->subsystem_device,
CSR_HW_REV_TYPE(iwl_trans->hw_rev),
CSR_HW_REV_STEP(iwl_trans->hw_rev),
iwl_trans->hw_rev_step,
CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id),
CSR_HW_RFID_IS_CDB(iwl_trans->hw_rf_id),
IWL_SUBDEVICE_RF_ID(pdev->subsystem_device),
@ -1497,21 +1520,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
(iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D)
iwl_trans->cfg = cfg_7265d;
if (cfg == &iwlax210_2ax_cfg_so_hr_a0) {
if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_TY) {
iwl_trans->cfg = &iwlax210_2ax_cfg_ty_gf_a0;
} else if (CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id) ==
CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_JF)) {
iwl_trans->cfg = &iwlax210_2ax_cfg_so_jf_b0;
} else if (CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id) ==
CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_GF)) {
iwl_trans->cfg = &iwlax211_2ax_cfg_so_gf_a0;
} else if (CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id) ==
CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_GF4)) {
iwl_trans->cfg = &iwlax411_2ax_cfg_so_gf4_a0;
}
}
/*
* This is a hack to switch from Qu B0 to Qu C0. We need to
* do this for all cfgs that use Qu B0, except for those using

Просмотреть файл

@ -81,7 +81,7 @@ static void iwl_pcie_gen2_apm_stop(struct iwl_trans *trans, bool op_mode_leave)
/* Stop device's DMA activity */
iwl_pcie_apm_stop_master(trans);
iwl_trans_sw_reset(trans);
iwl_trans_sw_reset(trans, false);
/*
* Clear "initialization complete" bit to move adapter from
@ -105,9 +105,12 @@ static void iwl_trans_pcie_fw_reset_handshake(struct iwl_trans *trans)
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_RESET_HANDSHAKE);
else
else if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210)
iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6,
UREG_DOORBELL_TO_ISR6_RESET_HANDSHAKE);
else
iwl_write32(trans, CSR_DOORBELL_VECTOR,
UREG_DOORBELL_TO_ISR6_RESET_HANDSHAKE);
/* wait 200ms */
ret = wait_event_timeout(trans_pcie->fw_reset_waitq,
@ -166,7 +169,8 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
/* Stop the device, and put it in low power state */
iwl_pcie_gen2_apm_stop(trans, false);
iwl_trans_sw_reset(trans);
/* re-take ownership to prevent other users from stealing the device */
iwl_trans_sw_reset(trans, true);
/*
* Upon stop, the IVAR table gets erased, so msi-x won't
@ -196,9 +200,6 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
* interrupt
*/
iwl_enable_rfkill_int(trans);
/* re-take ownership to prevent other users from stealing the device */
iwl_pcie_prepare_card_hw(trans);
}
void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)

Просмотреть файл

@ -127,7 +127,8 @@ out:
kfree(buf);
}
static void iwl_trans_pcie_sw_reset(struct iwl_trans *trans)
static int iwl_trans_pcie_sw_reset(struct iwl_trans *trans,
bool retake_ownership)
{
/* Reset entire device - do controller reset (results in SHRD_HW_RST) */
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
@ -137,6 +138,11 @@ static void iwl_trans_pcie_sw_reset(struct iwl_trans *trans)
iwl_set_bit(trans, CSR_RESET,
CSR_RESET_REG_FLAG_SW_RESET);
usleep_range(5000, 6000);
if (retake_ownership)
return iwl_pcie_prepare_card_hw(trans);
return 0;
}
static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans)
@ -382,9 +388,11 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans)
__iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_XTAL_ON);
iwl_trans_pcie_sw_reset(trans);
ret = iwl_trans_pcie_sw_reset(trans, true);
if (!ret)
ret = iwl_finish_nic_init(trans);
ret = iwl_finish_nic_init(trans);
if (WARN_ON(ret)) {
/* Release XTAL ON request */
__iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
@ -409,7 +417,10 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans)
apmg_xtal_cfg_reg |
SHR_APMG_XTAL_CFG_XTAL_ON_REQ);
iwl_trans_pcie_sw_reset(trans);
ret = iwl_trans_pcie_sw_reset(trans, true);
if (ret)
IWL_ERR(trans,
"iwl_pcie_apm_lp_xtal_enable: failed to retake NIC ownership\n");
/* Enable LP XTAL by indirect access through CSR */
apmg_gp1_reg = iwl_trans_pcie_read_shr(trans, SHR_APMG_GP1_REG);
@ -515,7 +526,7 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans, bool op_mode_leave)
return;
}
iwl_trans_pcie_sw_reset(trans);
iwl_trans_pcie_sw_reset(trans, false);
/*
* Clear "initialization complete" bit to move adapter from
@ -1261,7 +1272,8 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans)
/* Stop the device, and put it in low power state */
iwl_pcie_apm_stop(trans, false);
iwl_trans_pcie_sw_reset(trans);
/* re-take ownership to prevent other users from stealing the device */
iwl_trans_pcie_sw_reset(trans, true);
/*
* Upon stop, the IVAR table gets erased, so msi-x won't
@ -1291,9 +1303,6 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans)
* interrupt
*/
iwl_enable_rfkill_int(trans);
/* re-take ownership to prevent other users from stealing the device */
iwl_pcie_prepare_card_hw(trans);
}
void iwl_pcie_synchronize_irqs(struct iwl_trans *trans)
@ -1499,33 +1508,54 @@ void iwl_pcie_d3_complete_suspend(struct iwl_trans *trans,
iwl_pcie_set_pwr(trans, true);
}
static int iwl_pcie_d3_handshake(struct iwl_trans *trans, bool suspend)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
int ret;
if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210) {
iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6,
suspend ? UREG_DOORBELL_TO_ISR6_SUSPEND :
UREG_DOORBELL_TO_ISR6_RESUME);
} else if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
iwl_write32(trans, CSR_IPC_SLEEP_CONTROL,
suspend ? CSR_IPC_SLEEP_CONTROL_SUSPEND :
CSR_IPC_SLEEP_CONTROL_RESUME);
iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6,
UREG_DOORBELL_TO_ISR6_SLEEP_CTRL);
} else {
return 0;
}
ret = wait_event_timeout(trans_pcie->sx_waitq,
trans_pcie->sx_complete, 2 * HZ);
/* Invalidate it toward next suspend or resume */
trans_pcie->sx_complete = false;
if (!ret) {
IWL_ERR(trans, "Timeout %s D3\n",
suspend ? "entering" : "exiting");
return -ETIMEDOUT;
}
return 0;
}
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);
if (!reset)
/* 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 = iwl_pcie_d3_handshake(trans, true);
if (ret)
return ret;
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;
@ -1542,6 +1572,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
if (test) {
iwl_enable_interrupts(trans);
*status = IWL_D3_STATUS_ALIVE;
ret = 0;
goto out;
}
@ -1590,25 +1621,10 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
*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);
if (*status == IWL_D3_STATUS_ALIVE)
ret = iwl_pcie_d3_handshake(trans, false);
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;
return ret;
}
static void
@ -1795,9 +1811,7 @@ static int iwl_pcie_gen2_force_power_gating(struct iwl_trans *trans)
iwl_clear_bits_prph(trans, HPM_HIPM_GEN_CFG,
HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE);
iwl_trans_pcie_sw_reset(trans);
return 0;
return iwl_trans_pcie_sw_reset(trans, true);
}
static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans)
@ -1817,7 +1831,9 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans)
if (err)
return err;
iwl_trans_pcie_sw_reset(trans);
err = iwl_trans_pcie_sw_reset(trans, true);
if (err)
return err;
if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000 &&
trans->trans_cfg->integrated) {
@ -3616,8 +3632,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
* in the old format.
*/
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);
trans->hw_rev_step = trans->hw_rev & 0xF;
else
trans->hw_rev_step = (trans->hw_rev & 0xC) >> 2;
IWL_DEBUG_INFO(trans, "HW REV: 0x%0x\n", trans->hw_rev);

Просмотреть файл

@ -1072,6 +1072,7 @@ int iwl_txq_alloc(struct iwl_trans *trans, struct iwl_txq *txq, int slots_num,
return 0;
err_free_tfds:
dma_free_coherent(trans->dev, tfd_sz, txq->tfds, txq->dma_addr);
txq->tfds = NULL;
error:
if (txq->entries && cmd_queue)
for (i = 0; i < slots_num; i++)
@ -1752,8 +1753,11 @@ static int iwl_trans_txq_send_hcmd_sync(struct iwl_trans *trans,
}
if (test_bit(STATUS_FW_ERROR, &trans->status)) {
IWL_ERR(trans, "FW error in SYNC CMD %s\n", cmd_str);
dump_stack();
if (!test_and_clear_bit(STATUS_SUPPRESS_CMD_ERROR_ONCE,
&trans->status)) {
IWL_ERR(trans, "FW error in SYNC CMD %s\n", cmd_str);
dump_stack();
}
ret = -EIO;
goto cancel;
}