diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/fw')
25 files changed, 787 insertions, 176 deletions
| diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c index bf431fa4fe81..790c96df58cb 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c @@ -242,17 +242,16 @@ found:  IWL_EXPORT_SYMBOL(iwl_acpi_get_wifi_pkg_range);  int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt, -		     __le32 *block_list_array, -		     int *block_list_size) +		     struct iwl_tas_config_cmd_v3 *cmd)  {  	union acpi_object *wifi_pkg, *data; -	int ret, tbl_rev, i; -	bool enabled; +	int ret, tbl_rev, i, block_list_size, enabled;  	data = iwl_acpi_get_object(fwrt->dev, ACPI_WTAS_METHOD);  	if (IS_ERR(data))  		return PTR_ERR(data); +	/* try to read wtas table revision 1 or revision 0*/  	wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data,  					 ACPI_WTAS_WIFI_DATA_SIZE,  					 &tbl_rev); @@ -261,40 +260,54 @@ int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt,  		goto out_free;  	} -	if (wifi_pkg->package.elements[0].type != ACPI_TYPE_INTEGER || -	    tbl_rev != 0) { +	if (tbl_rev == 1 && wifi_pkg->package.elements[1].type == +		ACPI_TYPE_INTEGER) { +		u32 tas_selection = +			(u32)wifi_pkg->package.elements[1].integer.value; +		u16 override_iec = +			(tas_selection & ACPI_WTAS_OVERRIDE_IEC_MSK) >> ACPI_WTAS_OVERRIDE_IEC_POS; +		u16 enabled_iec = (tas_selection & ACPI_WTAS_ENABLE_IEC_MSK) >> +			ACPI_WTAS_ENABLE_IEC_POS; + +		enabled = tas_selection & ACPI_WTAS_ENABLED_MSK; +		cmd->override_tas_iec = cpu_to_le16(override_iec); +		cmd->enable_tas_iec = cpu_to_le16(enabled_iec); + +	} else if (tbl_rev == 0 && +		wifi_pkg->package.elements[1].type == ACPI_TYPE_INTEGER) { +		enabled = !!wifi_pkg->package.elements[1].integer.value; +	} else {  		ret = -EINVAL;  		goto out_free;  	} -	enabled = !!wifi_pkg->package.elements[1].integer.value; -  	if (!enabled) { -		*block_list_size = -1;  		IWL_DEBUG_RADIO(fwrt, "TAS not enabled\n");  		ret = 0;  		goto out_free;  	} +	IWL_DEBUG_RADIO(fwrt, "Reading TAS table revision %d\n", tbl_rev);  	if (wifi_pkg->package.elements[2].type != ACPI_TYPE_INTEGER ||  	    wifi_pkg->package.elements[2].integer.value >  	    APCI_WTAS_BLACK_LIST_MAX) {  		IWL_DEBUG_RADIO(fwrt, "TAS invalid array size %llu\n", -				wifi_pkg->package.elements[1].integer.value); +				wifi_pkg->package.elements[2].integer.value);  		ret = -EINVAL;  		goto out_free;  	} -	*block_list_size = wifi_pkg->package.elements[2].integer.value; +	block_list_size = wifi_pkg->package.elements[2].integer.value; +	cmd->block_list_size = cpu_to_le32(block_list_size); -	IWL_DEBUG_RADIO(fwrt, "TAS array size %d\n", *block_list_size); -	if (*block_list_size > APCI_WTAS_BLACK_LIST_MAX) { +	IWL_DEBUG_RADIO(fwrt, "TAS array size %u\n", block_list_size); +	if (block_list_size > APCI_WTAS_BLACK_LIST_MAX) {  		IWL_DEBUG_RADIO(fwrt, "TAS invalid array size value %u\n", -				*block_list_size); +				block_list_size);  		ret = -EINVAL;  		goto out_free;  	} -	for (i = 0; i < *block_list_size; i++) { +	for (i = 0; i < block_list_size; i++) {  		u32 country;  		if (wifi_pkg->package.elements[3 + i].type != @@ -306,11 +319,11 @@ int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt,  		}  		country = wifi_pkg->package.elements[3 + i].integer.value; -		block_list_array[i] = cpu_to_le32(country); +		cmd->block_list_array[i] = cpu_to_le32(country);  		IWL_DEBUG_RADIO(fwrt, "TAS block list country %d\n", country);  	} -	ret = 0; +	ret = 1;  out_free:  	kfree(data);  	return ret; @@ -789,7 +802,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 +865,8 @@ read_table:  		}  	} +	fwrt->geo_num_profiles = num_profiles; +	fwrt->geo_enabled = true;  	ret = 0;  out_free:  	kfree(data); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h index 4aaa8a6b071b..22b3c665f91a 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h @@ -65,10 +65,19 @@  #define ACPI_ECKV_WIFI_DATA_SIZE	2  /* - * 1 type, 1 enabled, 1 block list size, 16 block list array + * TAS size: 1 elelment for type, + *	     1 element for enabled field, + *	     1 element for block list size, + *	     16 elements for block list array   */  #define APCI_WTAS_BLACK_LIST_MAX	16  #define ACPI_WTAS_WIFI_DATA_SIZE	(3 + APCI_WTAS_BLACK_LIST_MAX) +#define ACPI_WTAS_ENABLED_MSK		0x1 +#define ACPI_WTAS_OVERRIDE_IEC_MSK	0x2 +#define ACPI_WTAS_ENABLE_IEC_MSK	0x4 +#define ACPI_WTAS_OVERRIDE_IEC_POS	0x1 +#define ACPI_WTAS_ENABLE_IEC_POS	0x2 +  #define ACPI_PPAG_WIFI_DATA_SIZE_V1	((IWL_NUM_CHAIN_LIMITS * \  					  IWL_NUM_SUB_BANDS_V1) + 2) @@ -105,6 +114,11 @@ struct iwl_geo_profile {  	struct iwl_geo_profile_band bands[ACPI_GEO_NUM_BANDS_REV2];  }; +/* Same thing as with SAR, all revisions fit in revision 2 */ +struct iwl_ppag_chain { +	s8 subbands[ACPI_SAR_NUM_SUB_BANDS_REV2]; +}; +  enum iwl_dsm_funcs_rev_0 {  	DSM_FUNC_QUERY = 0,  	DSM_FUNC_DISABLE_SRD = 1, @@ -198,8 +212,8 @@ int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt,  		     struct iwl_per_chain_offset *table,  		     u32 n_bands, u32 n_profiles); -int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt, __le32 *block_list_array, -		     int *block_list_size); +int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt, +		     struct iwl_tas_config_cmd_v3 *cmd);  __le32 iwl_acpi_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt); @@ -280,8 +294,7 @@ static inline bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt)  }  static inline int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt, -				   __le32 *block_list_array, -				   int *block_list_size) +				   struct iwl_tas_config_cmd_v3 *cmd)  {  	return -ENOENT;  } diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h b/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h index c840a97e6a62..e00ab21e7358 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h @@ -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 @@ -143,15 +158,6 @@ enum iwl_card_state_flags {  };  /** - * struct iwl_radio_version_notif - information on the card state - * ( CARD_STATE_NOTIFICATION = 0xa1 ) - * @flags: &enum iwl_card_state_flags - */ -struct iwl_card_state_notif { -	__le32 flags; -} __packed; /* CARD_STATE_NTFY_API_S_VER_1 */ - -/**   * enum iwl_error_recovery_flags - flags for error recovery cmd   * @ERROR_RECOVERY_UPDATE_DB: update db from blob sent   * @ERROR_RECOVERY_END_OF_RECOVERY: end of recovery diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h index ee6b5844a871..0703e41403a6 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h @@ -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, @@ -90,7 +91,8 @@ enum iwl_legacy_cmds {  	/**  	 * @SCAN_CFG_CMD: -	 * uses &struct iwl_scan_config_v1 or &struct iwl_scan_config +	 * uses &struct iwl_scan_config_v1, &struct iwl_scan_config_v2 +	 * or &struct iwl_scan_config  	 */  	SCAN_CFG_CMD = 0xc, @@ -356,7 +358,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 +367,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, @@ -383,13 +386,6 @@ enum iwl_legacy_cmds {  	REDUCE_TX_POWER_CMD = 0x9f,  	/** -	 * @CARD_STATE_NOTIFICATION: -	 * Card state (RF/CT kill) notification, -	 * uses &struct iwl_card_state_notif -	 */ -	CARD_STATE_NOTIFICATION = 0xa1, - -	/**  	 * @MISSED_BEACONS_NOTIFICATION: &struct iwl_missed_beacons_notif  	 */  	MISSED_BEACONS_NOTIFICATION = 0xa2, @@ -612,6 +608,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__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h index 1503119ea910..4cd9ab23954e 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.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__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h b/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h index 985b0dc5b52a..89236f42c5a4 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h @@ -32,6 +32,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  	 */  	RFH_QUEUE_CONFIG_CMD = 0xD, @@ -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__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h index 3988f5fea33a..456b7eaac570 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.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 version + * @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,17 @@ enum iwl_fw_ini_region_type {  	IWL_FW_INI_REGION_NUM  }; /* FW_TLV_DEBUG_REGION_TYPE_API_E */ +enum iwl_fw_ini_region_device_memory_subtype { +	IWL_FW_INI_REGION_DEVICE_MEMORY_SUBTYPE_HW_SMEM = 1, +	IWL_FW_INI_REGION_DEVICE_MEMORY_SUBTYPE_UMAC_ERROR_TABLE = 5, +	IWL_FW_INI_REGION_DEVICE_MEMORY_SUBTYPE_LMAC_1_ERROR_TABLE = 7, +	IWL_FW_INI_REGION_DEVICE_MEMORY_SUBTYPE_LMAC_2_ERROR_TABLE = 10, +	IWL_FW_INI_REGION_DEVICE_MEMORY_SUBTYPE_TCM_1_ERROR_TABLE = 14, +	IWL_FW_INI_REGION_DEVICE_MEMORY_SUBTYPE_TCM_2_ERROR_TABLE = 16, +	IWL_FW_INI_REGION_DEVICE_MEMORY_SUBTYPE_RCM_1_ERROR_TABLE = 18, +	IWL_FW_INI_REGION_DEVICE_MEMORY_SUBTYPE_RCM_2_ERROR_TABLE = 20, +}; /* FW_TLV_DEBUG_REGION_DEVICE_MEMORY_SUBTYPE_API_E */ +  /**   * enum iwl_fw_ini_time_point   * @@ -465,4 +483,17 @@ enum iwl_fw_ini_trigger_apply_policy {  	IWL_FW_INI_APPLY_POLICY_OVERRIDE_CFG		= BIT(9),  	IWL_FW_INI_APPLY_POLICY_OVERRIDE_DATA		= BIT(10),  }; + +/** + * enum iwl_fw_ini_trigger_reset_fw_policy - Determines how to handle reset + * + * @IWL_FW_INI_RESET_FW_MODE_NOTHING: do not stop FW and reload (default) + * @IWL_FW_INI_RESET_FW_MODE_STOP_FW_ONLY: stop FW without reload FW + * @IWL_FW_INI_RESET_FW_MODE_STOP_AND_RELOAD_FW: stop FW with reload FW + */ +enum iwl_fw_ini_trigger_reset_fw_policy { +	IWL_FW_INI_RESET_FW_MODE_NOTHING = 0, +	IWL_FW_INI_RESET_FW_MODE_STOP_FW_ONLY, +	IWL_FW_INI_RESET_FW_MODE_STOP_AND_RELOAD_FW +};  #endif diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h index 3551a3f1c1aa..4949fcf85257 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h @@ -34,6 +34,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  	 */  	PNVM_INIT_COMPLETE_NTFY = 0xFE, @@ -388,18 +393,33 @@ enum iwl_mcc_source {  	MCC_SOURCE_GETTING_MCC_TEST_MODE = 0x11,  }; -#define IWL_TAS_BLACK_LIST_MAX 16 +#define IWL_TAS_BLOCK_LIST_MAX 16  /** - * struct iwl_tas_config_cmd - configures the TAS + * struct iwl_tas_config_cmd_v2 - configures the TAS   * @block_list_size: size of relevant field in block_list_array - * @block_list_array: block list countries (without TAS) + * @block_list_array: list of countries where TAS must be disabled   */ -struct iwl_tas_config_cmd { +struct iwl_tas_config_cmd_v2 {  	__le32 block_list_size; -	__le32 block_list_array[IWL_TAS_BLACK_LIST_MAX]; +	__le32 block_list_array[IWL_TAS_BLOCK_LIST_MAX];  } __packed; /* TAS_CONFIG_CMD_API_S_VER_2 */  /** + * struct iwl_tas_config_cmd_v3 - configures the TAS + * @block_list_size: size of relevant field in block_list_array + * @block_list_array: list of countries where TAS must be disabled + * @override_tas_iec: indicates whether to override default value of IEC regulatory + * @enable_tas_iec: in case override_tas_iec is set - + *	indicates whether IEC regulatory is enabled or disabled + */ +struct iwl_tas_config_cmd_v3 { +	__le32 block_list_size; +	__le32 block_list_array[IWL_TAS_BLOCK_LIST_MAX]; +	__le16 override_tas_iec; +	__le16 enable_tas_iec; +} __packed; /* TAS_CONFIG_CMD_API_S_VER_3 */ + +/**   * enum iwl_lari_configs - bit masks for the various LARI config operations   * @LARI_CONFIG_DISABLE_11AC_UKRAINE_MSK: disable 11ac in ukraine   * @LARI_CONFIG_CHANGE_ETSI_TO_PASSIVE_MSK: ETSI 5.8GHz SRD passive scan diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h b/drivers/net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h index 68b788b92b7a..e66f77924f83 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2012-2014, 2018, 2020 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__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h index 4d671c878bb7..81318208f2f6 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h @@ -419,7 +419,7 @@ struct iwl_geo_tx_power_profiles_cmd_v1 {   * struct iwl_geo_tx_power_profile_cmd_v2 - struct for PER_CHAIN_LIMIT_OFFSET_CMD cmd.   * @ops: operations, value from &enum iwl_geo_per_chain_offset_operation   * @table: offset profile per band. - * @table_revision: BIOS table revision. + * @table_revision: 0 for not-South Korea, 1 for South Korea (the name is misleading)   */  struct iwl_geo_tx_power_profiles_cmd_v2 {  	__le32 ops; @@ -431,7 +431,7 @@ struct iwl_geo_tx_power_profiles_cmd_v2 {   * struct iwl_geo_tx_power_profile_cmd_v3 - struct for PER_CHAIN_LIMIT_OFFSET_CMD cmd.   * @ops: operations, value from &enum iwl_geo_per_chain_offset_operation   * @table: offset profile per band. - * @table_revision: BIOS table revision. + * @table_revision: 0 for not-South Korea, 1 for South Korea (the name is misleading)   */  struct iwl_geo_tx_power_profiles_cmd_v3 {  	__le32 ops; @@ -443,7 +443,7 @@ struct iwl_geo_tx_power_profiles_cmd_v3 {   * struct iwl_geo_tx_power_profile_cmd_v4 - struct for PER_CHAIN_LIMIT_OFFSET_CMD cmd.   * @ops: operations, value from &enum iwl_geo_per_chain_offset_operation   * @table: offset profile per band. - * @table_revision: BIOS table revision. + * @table_revision: 0 for not-South Korea, 1 for South Korea (the name is misleading)   */  struct iwl_geo_tx_power_profiles_cmd_v4 {  	__le32 ops; @@ -455,7 +455,7 @@ struct iwl_geo_tx_power_profiles_cmd_v4 {   * struct iwl_geo_tx_power_profile_cmd_v5 - struct for PER_CHAIN_LIMIT_OFFSET_CMD cmd.   * @ops: operations, value from &enum iwl_geo_per_chain_offset_operation   * @table: offset profile per band. - * @table_revision: BIOS table revision. + * @table_revision: 0 for not-South Korea, 1 for South Korea (the name is misleading)   */  struct iwl_geo_tx_power_profiles_cmd_v5 {  	__le32 ops; @@ -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) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h index a09081d7ed45..173a6991587b 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h @@ -116,9 +116,20 @@ enum IWL_TLC_MNG_NSS {  	IWL_TLC_NSS_MAX  }; -enum IWL_TLC_HT_BW_RATES { -	IWL_TLC_HT_BW_NONE_160, -	IWL_TLC_HT_BW_160, +/** + * enum IWL_TLC_MCS_PER_BW - mcs index per BW + * @IWL_TLC_MCS_PER_BW_80: mcs for bw - 20Hhz, 40Hhz, 80Hhz + * @IWL_TLC_MCS_PER_BW_160: mcs for bw - 160Mhz + * @IWL_TLC_MCS_PER_BW_320: mcs for bw - 320Mhz + * @IWL_TLC_MCS_PER_BW_NUM_V3: number of entries up to version 3 + * @IWL_TLC_MCS_PER_BW_NUM_V4: number of entries from version 4 + */ +enum IWL_TLC_MCS_PER_BW { +	IWL_TLC_MCS_PER_BW_80, +	IWL_TLC_MCS_PER_BW_160, +	IWL_TLC_MCS_PER_BW_320, +	IWL_TLC_MCS_PER_BW_NUM_V3 = IWL_TLC_MCS_PER_BW_160 + 1, +	IWL_TLC_MCS_PER_BW_NUM_V4 = IWL_TLC_MCS_PER_BW_320 + 1,  };  /** @@ -131,8 +142,8 @@ enum IWL_TLC_HT_BW_RATES {   * @amsdu: TX amsdu is supported   * @flags: bitmask of &enum iwl_tlc_mng_cfg_flags   * @non_ht_rates: bitmap of supported legacy rates - * @ht_rates: bitmap of &enum iwl_tlc_mng_ht_rates, per <nss, channel-width> - *	      pair (0 - 80mhz width and below, 1 - 160mhz). + * @ht_rates: bitmap of &enum iwl_tlc_mng_ht_rates, per &enum IWL_TLC_MCS_PER_BW + *	      <nss, channel-width> pair (0 - 80mhz width and below, 1 - 160mhz).   * @max_mpdu_len: max MPDU length, in bytes   * @sgi_ch_width_supp: bitmap of SGI support per channel width   *		       use BIT(@enum iwl_tlc_mng_cfg_cw) @@ -140,7 +151,7 @@ enum IWL_TLC_HT_BW_RATES {   * @max_tx_op: max TXOP in uSecs for all AC (BK, BE, VO, VI),   *	       set zero for no limit.   */ -struct iwl_tlc_config_cmd { +struct iwl_tlc_config_cmd_v3 {  	u8 sta_id;  	u8 reserved1[3];  	u8 max_ch_width; @@ -149,7 +160,7 @@ struct iwl_tlc_config_cmd {  	u8 amsdu;  	__le16 flags;  	__le16 non_ht_rates; -	__le16 ht_rates[IWL_TLC_NSS_MAX][2]; +	__le16 ht_rates[IWL_TLC_NSS_MAX][IWL_TLC_MCS_PER_BW_NUM_V3];  	__le16 max_mpdu_len;  	u8 sgi_ch_width_supp;  	u8 reserved2; @@ -157,6 +168,37 @@ struct iwl_tlc_config_cmd {  } __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_3 */  /** + * struct tlc_config_cmd - TLC configuration + * @sta_id: station id + * @reserved1: reserved + * @max_ch_width: max supported channel width from &enum iwl_tlc_mng_cfg_cw + * @mode: &enum iwl_tlc_mng_cfg_mode + * @chains: bitmask of &enum iwl_tlc_mng_cfg_chains + * @sgi_ch_width_supp: bitmap of SGI support per channel width + *		       use BIT(&enum iwl_tlc_mng_cfg_cw) + * @flags: bitmask of &enum iwl_tlc_mng_cfg_flags + * @non_ht_rates: bitmap of supported legacy rates + * @ht_rates: bitmap of &enum iwl_tlc_mng_ht_rates, per <nss, channel-width> + *	      pair (0 - 80mhz width and below, 1 - 160mhz, 2 - 320mhz). + * @max_mpdu_len: max MPDU length, in bytes + * @max_tx_op: max TXOP in uSecs for all AC (BK, BE, VO, VI), + *	       set zero for no limit. + */ +struct iwl_tlc_config_cmd_v4 { +	u8 sta_id; +	u8 reserved1[3]; +	u8 max_ch_width; +	u8 mode; +	u8 chains; +	u8 sgi_ch_width_supp; +	__le16 flags; +	__le16 non_ht_rates; +	__le16 ht_rates[IWL_TLC_NSS_MAX][IWL_TLC_MCS_PER_BW_NUM_V4]; +	__le16 max_mpdu_len; +	__le16 max_tx_op; +} __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_4 */ + +/**   * enum iwl_tlc_update_flags - updated fields   * @IWL_TLC_NOTIF_FLAG_RATE: last initial rate update   * @IWL_TLC_NOTIF_FLAG_AMSDU: umsdu parameters update diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h index 8b200379f7c2..5413087ae909 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h @@ -82,6 +82,16 @@ enum iwl_scan_offload_band_selection {  	IWL_SCAN_OFFLOAD_SELECT_ANY	= 0xc,  }; +enum iwl_scan_offload_auth_alg { +	IWL_AUTH_ALGO_UNSUPPORTED  = 0x00, +	IWL_AUTH_ALGO_NONE         = 0x01, +	IWL_AUTH_ALGO_PSK          = 0x02, +	IWL_AUTH_ALGO_8021X        = 0x04, +	IWL_AUTH_ALGO_SAE          = 0x08, +	IWL_AUTH_ALGO_8021X_SHA384 = 0x10, +	IWL_AUTH_ALGO_OWE          = 0x20, +}; +  /**   * struct iwl_scan_offload_profile - SCAN_OFFLOAD_PROFILE_S   * @ssid_index:		index to ssid list in fixed part @@ -201,7 +211,7 @@ struct iwl_scan_channel_cfg_lmac {  	__le32 iter_interval;  } __packed; -/* +/**   * struct iwl_scan_probe_segment - PROBE_SEGMENT_API_S_VER_1   * @offset: offset in the data block   * @len: length of the segment @@ -211,7 +221,8 @@ struct iwl_scan_probe_segment {  	__le16 len;  } __packed; -/* iwl_scan_probe_req - PROBE_REQUEST_FRAME_API_S_VER_2 +/** + * struct iwl_scan_probe_req_v1 - PROBE_REQUEST_FRAME_API_S_VER_2   * @mac_header: first (and common) part of the probe   * @band_data: band specific data   * @common_data: last (and common) part of the probe @@ -224,7 +235,8 @@ struct iwl_scan_probe_req_v1 {  	u8 buf[SCAN_OFFLOAD_PROBE_REQ_SIZE];  } __packed; -/* iwl_scan_probe_req - PROBE_REQUEST_FRAME_API_S_VER_v2 +/** + * struct iwl_scan_probe_req - PROBE_REQUEST_FRAME_API_S_VER_v2   * @mac_header: first (and common) part of the probe   * @band_data: band specific data   * @common_data: last (and common) part of the probe @@ -247,7 +259,8 @@ enum iwl_scan_channel_flags {  	IWL_SCAN_CHANNEL_FLAG_6G_PSC_NO_FILTER  = BIT(6),  }; -/* struct iwl_scan_channel_opt - CHANNEL_OPTIMIZATION_API_S +/** + * struct iwl_scan_channel_opt - CHANNEL_OPTIMIZATION_API_S   * @flags: enum iwl_scan_channel_flags   * @non_ebs_ratio: defines the ratio of number of scan iterations where EBS is   *	involved. @@ -492,7 +505,7 @@ struct iwl_scan_dwell {  } __packed;  /** - * struct iwl_scan_config_v1 + * struct iwl_scan_config_v1 - scan configuration command   * @flags:			enum scan_config_flags   * @tx_chains:			valid_tx antenna - ANT_* definitions   * @rx_chains:			valid_rx antenna - ANT_* definitions @@ -524,6 +537,21 @@ struct iwl_scan_config_v1 {  #define SCAN_LB_LMAC_IDX 0  #define SCAN_HB_LMAC_IDX 1 +/** + * struct iwl_scan_config_v2 - scan configuration command + * @flags:			enum scan_config_flags + * @tx_chains:			valid_tx antenna - ANT_* definitions + * @rx_chains:			valid_rx antenna - ANT_* definitions + * @legacy_rates:		default legacy rates - enum scan_config_rates + * @out_of_channel_time:	default max out of serving channel time + * @suspend_time:		default max suspend time + * @dwell:			dwells for the scan + * @mac_addr:			default mac address to be used in probes + * @bcast_sta_id:		the index of the station in the fw + * @channel_flags:		default channel flags - enum iwl_channel_flags + *				scan_config_channel_flag + * @channel_array:		default supported channels + */  struct iwl_scan_config_v2 {  	__le32 flags;  	__le32 tx_chains; @@ -539,7 +567,7 @@ struct iwl_scan_config_v2 {  } __packed; /* SCAN_CONFIG_DB_CMD_API_S_2 */  /** - * struct iwl_scan_config + * struct iwl_scan_config - scan configuration command   * @enable_cam_mode: whether to enable CAM mode.   * @enable_promiscouos_mode: whether to enable promiscouos mode   * @bcast_sta_id: the index of the station in the fw. Deprecated starting with @@ -640,6 +668,10 @@ enum iwl_umac_scan_general_flags2 {   * @IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN_FILTER_IN: in case   *      &IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN is enabled and scan is   *      activated over 6GHz PSC channels, filter in beacons and probe responses. + * @IWL_UMAC_SCAN_GEN_FLAGS_V2_OCE: if set, send probe requests in a minimum + *      rate of 5.5Mpbs, filter in broadcast probe responses and set the max + *      channel time indication field in the FILS request parameters element + *      (if included by the driver in the probe request IEs).   */  enum iwl_umac_scan_general_flags_v2 {  	IWL_UMAC_SCAN_GEN_FLAGS_V2_PERIODIC             = BIT(0), @@ -657,6 +689,20 @@ enum iwl_umac_scan_general_flags_v2 {  	IWL_UMAC_SCAN_GEN_FLAGS_V2_TRIGGER_UHB_SCAN     = BIT(12),  	IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN    = BIT(13),  	IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN_FILTER_IN = BIT(14), +	IWL_UMAC_SCAN_GEN_FLAGS_V2_OCE                  = BIT(15), +}; + +/** + * 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),  };  /** @@ -941,8 +987,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 +998,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 +1010,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 +1018,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 +1041,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 +1080,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 diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/stats.h b/drivers/net/wireless/intel/iwlwifi/fw/api/stats.h index 18cca15caa3a..898e62326e6c 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/stats.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/stats.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2012-2014, 2018, 2020 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   * @@ -446,10 +447,97 @@ struct iwl_statistics_ntfy_hdr {  }; /* 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; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/soc.h b/drivers/net/wireless/intel/iwlwifi/fw/api/system.h index c5df1171462b..acf5d4b9a214 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/soc.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/system.h @@ -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__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h index 4a74c0ea0f31..e73cc7380a26 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h @@ -177,6 +177,17 @@ enum iwl_tx_offload_assist_flags_pos {  #define IWL_TX_CMD_OFFLD_MH_MASK	0x1f  #define IWL_TX_CMD_OFFLD_IP_HDR_MASK	0x3f +enum iwl_tx_offload_assist_bz { +	IWL_TX_CMD_OFFLD_BZ_RESULT_OFFS		= 0x000003ff, +	IWL_TX_CMD_OFFLD_BZ_START_OFFS		= 0x001ff800, +	IWL_TX_CMD_OFFLD_BZ_MH_LEN		= 0x07c00000, +	IWL_TX_CMD_OFFLD_BZ_MH_PAD		= 0x08000000, +	IWL_TX_CMD_OFFLD_BZ_AMSDU		= 0x10000000, +	IWL_TX_CMD_OFFLD_BZ_ZERO2ONES		= 0x20000000, +	IWL_TX_CMD_OFFLD_BZ_ENABLE_CSUM		= 0x40000000, +	IWL_TX_CMD_OFFLD_BZ_PARTIAL_CSUM	= 0x80000000, +}; +  /* TODO: complete documentation for try_cnt and btkill_cnt */  /**   * struct iwl_tx_cmd - TX command struct to FW diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index a39013c401c9..7ad9cee925da 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -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, @@ -1565,7 +1564,7 @@ iwl_dump_ini_dbgi_sram_iter(struct iwl_fw_runtime *fwrt,  	iwl_write_prph_no_grab(fwrt->trans, DBGI_SRAM_TARGET_ACCESS_CFG,  			       DBGI_SRAM_TARGET_ACCESS_CFG_RESET_ADDRESS_MSK);  	for (i = 0; i < (le32_to_cpu(reg->dev_addr.size) / 4); i++) { -		prph_data = iwl_read_prph(fwrt->trans, (i % 2) ? +		prph_data = iwl_read_prph_no_grab(fwrt->trans, (i % 2) ?  					  DBGI_SRAM_TARGET_ACCESS_RDATA_MSB :  					  DBGI_SRAM_TARGET_ACCESS_RDATA_LSB);  		if (prph_data == 0x5a5a5a5a) { @@ -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 @@ -2107,7 +2110,7 @@ static u32 iwl_dump_ini_info(struct iwl_fw_runtime *fwrt,  	 */  	hw_type = CSR_HW_REV_TYPE(fwrt->trans->hw_rev);  	if (hw_type == IWL_AX210_HW_TYPE) { -		u32 prph_val = iwl_read_prph(fwrt->trans, WFPM_OTP_CFG1_ADDR_GEN2); +		u32 prph_val = iwl_read_umac_prph(fwrt->trans, WFPM_OTP_CFG1_ADDR);  		u32 is_jacket = !!(prph_val & WFPM_OTP_CFG1_IS_JACKET_BIT);  		u32 is_cdb = !!(prph_val & WFPM_OTP_CFG1_IS_CDB_BIT);  		u32 masked_bits = is_jacket | (is_cdb << 1); @@ -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; @@ -2716,6 +2719,9 @@ static void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt, u8 wk_idx)  	iwl_fw_dbg_stop_restart_recording(fwrt, ¶ms, false); +	if (fwrt->trans->dbg.last_tp_resetfw == IWL_FW_INI_RESET_FW_MODE_STOP_FW_ONLY) +		iwl_force_nmi(fwrt->trans); +  out:  	if (iwl_trans_dbg_ini_valid(fwrt->trans)) {  		iwl_fw_error_dump_data_free(dump_data); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dump.c b/drivers/net/wireless/intel/iwlwifi/fw/dump.c index 016b3a4c5f51..b90f1e9ce691 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dump.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dump.c @@ -12,6 +12,7 @@  #include "iwl-io.h"  #include "iwl-prph.h"  #include "iwl-csr.h" +#include "pnvm.h"  /*   * Note: This structure is read from the device with IO accesses, @@ -19,53 +20,6 @@   * read with u32-sized accesses, any members with a different size   * need to be ordered correctly though!   */ -struct iwl_error_event_table_v1 { -	u32 valid;		/* (nonzero) valid, (0) log is empty */ -	u32 error_id;		/* type of error */ -	u32 pc;			/* program counter */ -	u32 blink1;		/* branch link */ -	u32 blink2;		/* branch link */ -	u32 ilink1;		/* interrupt link */ -	u32 ilink2;		/* interrupt link */ -	u32 data1;		/* error-specific data */ -	u32 data2;		/* error-specific data */ -	u32 data3;		/* error-specific data */ -	u32 bcon_time;		/* beacon timer */ -	u32 tsf_low;		/* network timestamp function timer */ -	u32 tsf_hi;		/* network timestamp function timer */ -	u32 gp1;		/* GP1 timer register */ -	u32 gp2;		/* GP2 timer register */ -	u32 gp3;		/* GP3 timer register */ -	u32 ucode_ver;		/* uCode version */ -	u32 hw_ver;		/* HW Silicon version */ -	u32 brd_ver;		/* HW board version */ -	u32 log_pc;		/* log program counter */ -	u32 frame_ptr;		/* frame pointer */ -	u32 stack_ptr;		/* stack pointer */ -	u32 hcmd;		/* last host command header */ -	u32 isr0;		/* isr status register LMPM_NIC_ISR0: -				 * rxtx_flag */ -	u32 isr1;		/* isr status register LMPM_NIC_ISR1: -				 * host_flag */ -	u32 isr2;		/* isr status register LMPM_NIC_ISR2: -				 * enc_flag */ -	u32 isr3;		/* isr status register LMPM_NIC_ISR3: -				 * time_flag */ -	u32 isr4;		/* isr status register LMPM_NIC_ISR4: -				 * wico interrupt */ -	u32 isr_pref;		/* isr status register LMPM_NIC_PREF_STAT */ -	u32 wait_event;		/* wait event() caller address */ -	u32 l2p_control;	/* L2pControlField */ -	u32 l2p_duration;	/* L2pDurationField */ -	u32 l2p_mhvalid;	/* L2pMhValidBits */ -	u32 l2p_addr_match;	/* L2pAddrMatchStat */ -	u32 lmpm_pmg_sel;	/* indicate which clocks are turned on -				 * (LMPM_PMG_SEL) */ -	u32 u_timestamp;	/* indicate when the date and time of the -				 * compilation */ -	u32 flow_handler;	/* FH read/write pointers, RX credit */ -} __packed /* LOG_ERROR_TABLE_API_S_VER_1 */; -  struct iwl_error_event_table {  	u32 valid;		/* (nonzero) valid, (0) log is empty */  	u32 error_id;		/* type of error */ @@ -147,6 +101,7 @@ static void iwl_fwrt_dump_umac_error_log(struct iwl_fw_runtime *fwrt)  	struct iwl_trans *trans = fwrt->trans;  	struct iwl_umac_error_event_table table = {};  	u32 base = fwrt->trans->dbg.umac_error_event_table; +	char pnvm_name[MAX_PNVM_NAME];  	if (!base &&  	    !(fwrt->trans->dbg.error_event_table_tlv_status & @@ -164,6 +119,13 @@ static void iwl_fwrt_dump_umac_error_log(struct iwl_fw_runtime *fwrt)  			fwrt->trans->status, table.valid);  	} +	if ((table.error_id & ~FW_SYSASSERT_CPU_MASK) == +	    FW_SYSASSERT_PNVM_MISSING) { +		iwl_pnvm_get_fs_name(trans, pnvm_name, sizeof(pnvm_name)); +		IWL_ERR(fwrt, "PNVM data is missing, please install %s\n", +			pnvm_name); +	} +  	IWL_ERR(fwrt, "0x%08X | %s\n", table.error_id,  		iwl_fw_lookup_assert_desc(table.error_id));  	IWL_ERR(fwrt, "0x%08X | umac branchlink1\n", table.blink1); @@ -212,7 +174,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) @@ -295,21 +259,21 @@ struct iwl_tcm_error_event_table {  	u32 reserved[4];  } __packed; /* TCM_LOG_ERROR_TABLE_API_S_VER_1 */ -static void iwl_fwrt_dump_tcm_error_log(struct iwl_fw_runtime *fwrt) +static void iwl_fwrt_dump_tcm_error_log(struct iwl_fw_runtime *fwrt, int idx)  {  	struct iwl_trans *trans = fwrt->trans;  	struct iwl_tcm_error_event_table table = {}; -	u32 base = fwrt->trans->dbg.tcm_error_event_table; +	u32 base = fwrt->trans->dbg.tcm_error_event_table[idx];  	int i; +	u32 flag = idx ? IWL_ERROR_EVENT_TABLE_TCM2 : +			 IWL_ERROR_EVENT_TABLE_TCM1; -	if (!base || -	    !(fwrt->trans->dbg.error_event_table_tlv_status & -	      IWL_ERROR_EVENT_TABLE_TCM)) +	if (!base || !(fwrt->trans->dbg.error_event_table_tlv_status & flag))  		return;  	iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table)); -	IWL_ERR(fwrt, "TCM status:\n"); +	IWL_ERR(fwrt, "TCM%d status:\n", idx + 1);  	IWL_ERR(fwrt, "0x%08X | error ID\n", table.error_id);  	IWL_ERR(fwrt, "0x%08X | tcm branchlink2\n", table.blink2);  	IWL_ERR(fwrt, "0x%08X | tcm interruptlink1\n", table.ilink1); @@ -328,13 +292,72 @@ static void iwl_fwrt_dump_tcm_error_log(struct iwl_fw_runtime *fwrt)  	for (i = 0; i < ARRAY_SIZE(table.sw_status); i++)  		IWL_ERR(fwrt, "0x%08X | tcm SW status[%d]\n",  			table.sw_status[i], i); +} -	if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { -		u32 scratch = iwl_read32(trans, CSR_FUNC_SCRATCH); +/* + * RCM error struct. + * Note: This structure is read from the device with IO accesses, + * and the reading already does the endian conversion. As it is + * read with u32-sized accesses, any members with a different size + * need to be ordered correctly though! + */ +struct iwl_rcm_error_event_table { +	u32 valid; +	u32 error_id; +	u32 blink2; +	u32 ilink1; +	u32 ilink2; +	u32 data1, data2, data3; +	u32 logpc; +	u32 frame_pointer; +	u32 stack_pointer; +	u32 msgid; +	u32 isr; +	u32 frame_hw_status; +	u32 mbx_lmac_to_rcm_req; +	u32 mbx_rcm_to_lmac_req; +	u32 mh_ctl; +	u32 mh_addr1_lo; +	u32 mh_info; +	u32 mh_err; +	u32 reserved[3]; +} __packed; /* RCM_LOG_ERROR_TABLE_API_S_VER_1 */ + +static void iwl_fwrt_dump_rcm_error_log(struct iwl_fw_runtime *fwrt, int idx) +{ +	struct iwl_trans *trans = fwrt->trans; +	struct iwl_rcm_error_event_table table = {}; +	u32 base = fwrt->trans->dbg.rcm_error_event_table[idx]; +	u32 flag = idx ? IWL_ERROR_EVENT_TABLE_RCM2 : +			 IWL_ERROR_EVENT_TABLE_RCM1; -		IWL_ERR(fwrt, "Function Scratch status:\n"); -		IWL_ERR(fwrt, "0x%08X | Func Scratch\n", scratch); -	} +	if (!base || !(fwrt->trans->dbg.error_event_table_tlv_status & flag)) +		return; + +	iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table)); + +	IWL_ERR(fwrt, "RCM%d status:\n", idx + 1); +	IWL_ERR(fwrt, "0x%08X | error ID\n", table.error_id); +	IWL_ERR(fwrt, "0x%08X | rcm branchlink2\n", table.blink2); +	IWL_ERR(fwrt, "0x%08X | rcm interruptlink1\n", table.ilink1); +	IWL_ERR(fwrt, "0x%08X | rcm interruptlink2\n", table.ilink2); +	IWL_ERR(fwrt, "0x%08X | rcm data1\n", table.data1); +	IWL_ERR(fwrt, "0x%08X | rcm data2\n", table.data2); +	IWL_ERR(fwrt, "0x%08X | rcm data3\n", table.data3); +	IWL_ERR(fwrt, "0x%08X | rcm log PC\n", table.logpc); +	IWL_ERR(fwrt, "0x%08X | rcm frame pointer\n", table.frame_pointer); +	IWL_ERR(fwrt, "0x%08X | rcm stack pointer\n", table.stack_pointer); +	IWL_ERR(fwrt, "0x%08X | rcm msg ID\n", table.msgid); +	IWL_ERR(fwrt, "0x%08X | rcm ISR status\n", table.isr); +	IWL_ERR(fwrt, "0x%08X | frame HW status\n", table.frame_hw_status); +	IWL_ERR(fwrt, "0x%08X | LMAC-to-RCM request mbox\n", +		table.mbx_lmac_to_rcm_req); +	IWL_ERR(fwrt, "0x%08X | RCM-to-LMAC request mbox\n", +		table.mbx_rcm_to_lmac_req); +	IWL_ERR(fwrt, "0x%08X | MAC header control\n", table.mh_ctl); +	IWL_ERR(fwrt, "0x%08X | MAC header addr1 low\n", table.mh_addr1_lo); +	IWL_ERR(fwrt, "0x%08X | MAC header info\n", table.mh_info); +	IWL_ERR(fwrt, "0x%08X | MAC header error\n", table.mh_err);  }  static void iwl_fwrt_dump_iml_error_log(struct iwl_fw_runtime *fwrt) @@ -418,8 +441,18 @@ void iwl_fwrt_dump_error_logs(struct iwl_fw_runtime *fwrt)  	if (fwrt->trans->dbg.lmac_error_event_table[1])  		iwl_fwrt_dump_lmac_error_log(fwrt, 1);  	iwl_fwrt_dump_umac_error_log(fwrt); -	iwl_fwrt_dump_tcm_error_log(fwrt); +	iwl_fwrt_dump_tcm_error_log(fwrt, 0); +	iwl_fwrt_dump_rcm_error_log(fwrt, 0); +	iwl_fwrt_dump_tcm_error_log(fwrt, 1); +	iwl_fwrt_dump_rcm_error_log(fwrt, 1);  	iwl_fwrt_dump_iml_error_log(fwrt);  	iwl_fwrt_dump_fseq_regs(fwrt); + +	if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { +		u32 scratch = iwl_read32(fwrt->trans, CSR_FUNC_SCRATCH); + +		IWL_ERR(fwrt, "Function Scratch status:\n"); +		IWL_ERR(fwrt, "0x%08X | Func Scratch\n", scratch); +	}  }  IWL_EXPORT_SYMBOL(iwl_fwrt_dump_error_logs); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h index 9036b32ec765..079fa0023bd8 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h @@ -232,6 +232,24 @@ struct iwl_fw_error_dump_mem {  #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   * @size: size of the data diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 3d572f5024bb..e4ebda64cd52 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -98,7 +98,6 @@ enum iwl_ucode_tlv_type {  	IWL_UCODE_TLV_PNVM_VERSION		= 62,  	IWL_UCODE_TLV_PNVM_SKU			= 64, -	IWL_UCODE_TLV_TCM_DEBUG_ADDRS		= 65,  	IWL_UCODE_TLV_SEC_TABLE_ADDR		= 66,  	IWL_UCODE_TLV_D3_KEK_KCK_ADDR		= 67, diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.c b/drivers/net/wireless/intel/iwlwifi/fw/img.c index 24a966673691..530674a35eeb 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/img.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/img.c @@ -1,6 +1,6 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /* - * Copyright(c) 2019 - 2020 Intel Corporation + * Copyright(c) 2019 - 2021 Intel Corporation   */  #include "img.h" @@ -49,10 +49,9 @@ u8 iwl_fw_lookup_notif_ver(const struct iwl_fw *fw, u8 grp, u8 cmd, u8 def)  }  EXPORT_SYMBOL_GPL(iwl_fw_lookup_notif_ver); -#define FW_SYSASSERT_CPU_MASK 0xf0000000  static const struct {  	const char *name; -	u8 num; +	u32 num;  } advanced_lookup[] = {  	{ "NMI_INTERRUPT_WDG", 0x34 },  	{ "SYSASSERT", 0x35 }, @@ -73,6 +72,7 @@ static const struct {  	{ "NMI_INTERRUPT_ACTION_PT", 0x7C },  	{ "NMI_INTERRUPT_UNKNOWN", 0x84 },  	{ "NMI_INTERRUPT_INST_ACTION_PT", 0x86 }, +	{ "PNVM_MISSING", FW_SYSASSERT_PNVM_MISSING },  	{ "ADVANCED_SYSASSERT", 0 },  }; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.h b/drivers/net/wireless/intel/iwlwifi/fw/img.h index 993bda17fa30..fa7b1780064c 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/img.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/img.h @@ -279,4 +279,8 @@ u8 iwl_fw_lookup_cmd_ver(const struct iwl_fw *fw, u8 grp, u8 cmd, u8 def);  u8 iwl_fw_lookup_notif_ver(const struct iwl_fw *fw, u8 grp, u8 cmd, u8 def);  const char *iwl_fw_lookup_assert_desc(u32 num); + +#define FW_SYSASSERT_CPU_MASK		0xf0000000 +#define FW_SYSASSERT_PNVM_MISSING	0x0010070d +  #endif  /* __iwl_fw_img_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/init.c b/drivers/net/wireless/intel/iwlwifi/fw/init.c index 566957ac4539..139ece879fab 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/init.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/init.c @@ -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" diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index 69799f1ed2c4..3cb0ddbe3ab2 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h @@ -156,8 +156,13 @@ struct iwl_fw_runtime {  	u8 sar_chain_b_profile;  	struct iwl_geo_profile geo_profiles[ACPI_NUM_GEO_PROFILES_REV3];  	u32 geo_rev; -	union iwl_ppag_table_cmd ppag_table; +	u32 geo_num_profiles; +	bool geo_enabled; +	struct iwl_ppag_chain ppag_chains[IWL_NUM_CHAIN_LIMITS]; +	u32 ppag_flags;  	u32 ppag_ver; +	struct iwl_sar_offset_mapping_cmd sgom_table; +	bool sgom_enabled;  #endif  }; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c index c875bf35533c..bd82c24811c8 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c @@ -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,	\ @@ -86,6 +87,7 @@ static void *iwl_uefi_reduce_power_section(struct iwl_trans *trans,  		if (len < tlv_len) {  			IWL_ERR(trans, "invalid TLV len: %zd/%u\n",  				len, tlv_len); +			kfree(reduce_power_data);  			reduce_power_data = ERR_PTR(-EINVAL);  			goto out;  		} @@ -105,6 +107,7 @@ static void *iwl_uefi_reduce_power_section(struct iwl_trans *trans,  				IWL_DEBUG_FW(trans,  					     "Couldn't allocate (more) reduce_power_data\n"); +				kfree(reduce_power_data);  				reduce_power_data = ERR_PTR(-ENOMEM);  				goto out;  			} @@ -134,6 +137,10 @@ static void *iwl_uefi_reduce_power_section(struct iwl_trans *trans,  done:  	if (!size) {  		IWL_DEBUG_FW(trans, "Empty REDUCE_POWER, skipping.\n"); +		/* Better safe than sorry, but 'reduce_power_data' should +		 * always be NULL if !size. +		 */ +		kfree(reduce_power_data);  		reduce_power_data = ERR_PTR(-ENOENT);  		goto out;  	} @@ -260,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 */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h index d552c656ac9f..09d2a971b3a0 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h @@ -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__ */ |