diff options
Diffstat (limited to 'sys/contrib/dev/iwlwifi/fw')
48 files changed, 2652 insertions, 1044 deletions
diff --git a/sys/contrib/dev/iwlwifi/fw/acpi.c b/sys/contrib/dev/iwlwifi/fw/acpi.c index 8c8880b44827..7ec22738b5d6 100644 --- a/sys/contrib/dev/iwlwifi/fw/acpi.c +++ b/sys/contrib/dev/iwlwifi/fw/acpi.c @@ -1,7 +1,7 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /*   * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2019-2024 Intel Corporation + * Copyright (C) 2019-2025 Intel Corporation   */  #include <linux/uuid.h>  #include "iwl-drv.h" @@ -79,9 +79,9 @@ static void *iwl_acpi_get_object(struct device *dev, acpi_string method)   * method (DSM) interface. The returned acpi object must be freed by calling   * function.   */ -static void *iwl_acpi_get_dsm_object(struct device *dev, int rev, int func, -				     union acpi_object *args, -				     const guid_t *guid) +union acpi_object *iwl_acpi_get_dsm_object(struct device *dev, int rev, +					   int func, union acpi_object *args, +					   const guid_t *guid)  {  	union acpi_object *obj; @@ -108,7 +108,7 @@ static int iwl_acpi_get_dsm_integer(struct device *dev, int rev, int func,  				    size_t expected_size)  {  	union acpi_object *obj; -	int ret = 0; +	int ret;  	obj = iwl_acpi_get_dsm_object(dev, rev, func, NULL, guid);  	if (IS_ERR(obj)) { @@ -123,8 +123,10 @@ static int iwl_acpi_get_dsm_integer(struct device *dev, int rev, int func,  	} else if (obj->type == ACPI_TYPE_BUFFER) {  		__le64 le_value = 0; -		if (WARN_ON_ONCE(expected_size > sizeof(le_value))) -			return -EINVAL; +		if (WARN_ON_ONCE(expected_size > sizeof(le_value))) { +			ret = -EINVAL; +			goto out; +		}  		/* if the buffer size doesn't match the expected size */  		if (obj->buffer.length != expected_size) @@ -145,8 +147,9 @@ static int iwl_acpi_get_dsm_integer(struct device *dev, int rev, int func,  	}  	IWL_DEBUG_DEV_RADIO(dev, -			    "ACPI: DSM method evaluated: func=%d, ret=%d\n", -			    func, ret); +			    "ACPI: DSM method evaluated: func=%d, value=%lld\n", +			    func, *value); +	ret = 0;  out:  	ACPI_FREE(obj);  	return ret; @@ -166,7 +169,7 @@ int iwl_acpi_get_dsm(struct iwl_fw_runtime *fwrt,  	BUILD_BUG_ON(ARRAY_SIZE(acpi_dsm_size) != DSM_FUNC_NUM_FUNCS); -	if (WARN_ON(func >= ARRAY_SIZE(acpi_dsm_size))) +	if (WARN_ON(func >= ARRAY_SIZE(acpi_dsm_size) || !func))  		return -EINVAL;  	expected_size = acpi_dsm_size[func]; @@ -175,6 +178,29 @@ int iwl_acpi_get_dsm(struct iwl_fw_runtime *fwrt,  	if (expected_size != sizeof(u8) && expected_size != sizeof(u32))  		return -EOPNOTSUPP; +	if (!fwrt->acpi_dsm_funcs_valid) { +		ret = iwl_acpi_get_dsm_integer(fwrt->dev, ACPI_DSM_REV, +					       DSM_FUNC_QUERY, +					       &iwl_guid, &tmp, +					       acpi_dsm_size[DSM_FUNC_QUERY]); +		if (ret) { +			/* always indicate BIT(0) to avoid re-reading */ +			fwrt->acpi_dsm_funcs_valid = BIT(0); +			return ret; +		} + +		IWL_DEBUG_RADIO(fwrt, "ACPI DSM validity bitmap 0x%x\n", +				(u32)tmp); +		/* always indicate BIT(0) to avoid re-reading */ +		fwrt->acpi_dsm_funcs_valid = tmp | BIT(0); +	} + +	if (!(fwrt->acpi_dsm_funcs_valid & BIT(func))) { +		IWL_DEBUG_RADIO(fwrt, "ACPI DSM %d not indicated as valid\n", +				func); +		return -ENODATA; +	} +  	ret = iwl_acpi_get_dsm_integer(fwrt->dev, ACPI_DSM_REV, func,  				       &iwl_guid, &tmp, expected_size);  	if (ret) @@ -259,13 +285,14 @@ int iwl_acpi_get_tas_table(struct iwl_fw_runtime *fwrt,  			   struct iwl_tas_data *tas_data)  {  	union acpi_object *wifi_pkg, *data; -	int ret, tbl_rev, i, block_list_size, enabled; +	int ret, tbl_rev, block_list_size, enabled; +	u32 tas_selection;  	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*/ +	/* try to read wtas table */  	wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data,  					 ACPI_WTAS_WIFI_DATA_SIZE,  					 &tbl_rev); @@ -274,27 +301,23 @@ int iwl_acpi_get_tas_table(struct iwl_fw_runtime *fwrt,  		goto out_free;  	} -	if (tbl_rev == 1 && wifi_pkg->package.elements[1].type == -		ACPI_TYPE_INTEGER) { -		u32 tas_selection = -			(u32)wifi_pkg->package.elements[1].integer.value; - -		enabled = iwl_parse_tas_selection(fwrt, tas_data, -						  tas_selection); - -	} else if (tbl_rev == 0 && -		wifi_pkg->package.elements[1].type == ACPI_TYPE_INTEGER) { -		enabled = !!wifi_pkg->package.elements[1].integer.value; -	} else { +	if (tbl_rev < 0 || tbl_rev > 2 || +	    wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) {  		ret = -EINVAL;  		goto out_free;  	} -	if (!enabled) { -		IWL_DEBUG_RADIO(fwrt, "TAS not enabled\n"); -		ret = 0; -		goto out_free; -	} +	tas_selection = (u32)wifi_pkg->package.elements[1].integer.value; +	enabled = tas_selection & IWL_WTAS_ENABLED_MSK; + +	IWL_DEBUG_RADIO(fwrt, "TAS selection as read from BIOS: 0x%x\n", +			tas_selection); +	tas_data->table_source = BIOS_SOURCE_ACPI; +	tas_data->table_revision = tbl_rev; +	tas_data->tas_selection = tas_selection; + +	IWL_DEBUG_RADIO(fwrt, "TAS %s enabled\n", +			enabled ? "is" : "not");  	IWL_DEBUG_RADIO(fwrt, "Reading TAS table revision %d\n", tbl_rev);  	if (wifi_pkg->package.elements[2].type != ACPI_TYPE_INTEGER || @@ -305,13 +328,14 @@ int iwl_acpi_get_tas_table(struct iwl_fw_runtime *fwrt,  		ret = -EINVAL;  		goto out_free;  	} +  	block_list_size = wifi_pkg->package.elements[2].integer.value; -	tas_data->block_list_size = cpu_to_le32(block_list_size); +	tas_data->block_list_size = block_list_size;  	IWL_DEBUG_RADIO(fwrt, "TAS array size %u\n", block_list_size); -	for (i = 0; i < block_list_size; i++) { -		u32 country; +	for (int i = 0; i < block_list_size; i++) { +		u16 country;  		if (wifi_pkg->package.elements[3 + i].type !=  		    ACPI_TYPE_INTEGER) { @@ -322,11 +346,11 @@ int iwl_acpi_get_tas_table(struct iwl_fw_runtime *fwrt,  		}  		country = wifi_pkg->package.elements[3 + i].integer.value; -		tas_data->block_list_array[i] = cpu_to_le32(country); +		tas_data->block_list_array[i] = country;  		IWL_DEBUG_RADIO(fwrt, "TAS block list country %d\n", country);  	} -	ret = 1; +	ret = enabled;  out_free:  	kfree(data);  	return ret; @@ -357,6 +381,11 @@ int iwl_acpi_get_mcc(struct iwl_fw_runtime *fwrt, char *mcc)  	}  	mcc_val = wifi_pkg->package.elements[1].integer.value; +	if (mcc_val != BIOS_MCC_CHINA) { +		ret = -EINVAL; +		IWL_DEBUG_RADIO(fwrt, "ACPI WRDD is supported only for CN\n"); +		goto out_free; +	}  	mcc[0] = (mcc_val >> 8) & 0xff;  	mcc[1] = mcc_val & 0xff; @@ -424,38 +453,28 @@ out_free:  	return ret;  } -static int iwl_acpi_sar_set_profile(union acpi_object *table, -				    struct iwl_sar_profile *profile, -				    bool enabled, u8 num_chains, -				    u8 num_sub_bands) +static int +iwl_acpi_parse_chains_table(union acpi_object *table, +			    struct iwl_sar_profile_chain *chains, +			    u8 num_chains, u8 num_sub_bands)  { -	int i, j, idx = 0; - -	/* -	 * The table from ACPI is flat, but we store it in a -	 * structured array. -	 */ -	for (i = 0; i < BIOS_SAR_MAX_CHAINS_PER_PROFILE; i++) { -		for (j = 0; j < BIOS_SAR_MAX_SUB_BANDS_NUM; j++) { +	for (u8 chain = 0; chain < num_chains; chain++) { +		for (u8 subband = 0; subband < BIOS_SAR_MAX_SUB_BANDS_NUM; +		     subband++) {  			/* if we don't have the values, use the default */ -			if (i >= num_chains || j >= num_sub_bands) { -				profile->chains[i].subbands[j] = 0; +			if (subband >= num_sub_bands) { +				chains[chain].subbands[subband] = 0; +			} else if (table->type != ACPI_TYPE_INTEGER || +				   table->integer.value > U8_MAX) { +				return -EINVAL;  			} else { -				if (table[idx].type != ACPI_TYPE_INTEGER || -				    table[idx].integer.value > U8_MAX) -					return -EINVAL; - -				profile->chains[i].subbands[j] = -					table[idx].integer.value; - -				idx++; +				chains[chain].subbands[subband] = +					table->integer.value; +				table++;  			}  		}  	} -	/* Only if all values were valid can the profile be enabled */ -	profile->enabled = enabled; -  	return 0;  } @@ -538,9 +557,11 @@ read_table:  	/* The profile from WRDS is officially profile 1, but goes  	 * into sar_profiles[0] (because we don't have a profile 0).  	 */ -	ret = iwl_acpi_sar_set_profile(table, &fwrt->sar_profiles[0], -				       flags & IWL_SAR_ENABLE_MSK, -				       num_chains, num_sub_bands); +	ret = iwl_acpi_parse_chains_table(table, fwrt->sar_profiles[0].chains, +					  num_chains, num_sub_bands); +	if (!ret && flags & IWL_SAR_ENABLE_MSK) +		fwrt->sar_profiles[0].enabled = true; +  out_free:  	kfree(data);  	return ret; @@ -552,7 +573,7 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)  	bool enabled;  	int i, n_profiles, tbl_rev, pos;  	int ret = 0; -	u8 num_chains, num_sub_bands; +	u8 num_sub_bands;  	data = iwl_acpi_get_object(fwrt->dev, ACPI_EWRD_METHOD);  	if (IS_ERR(data)) @@ -568,7 +589,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)  			goto out_free;  		} -		num_chains = ACPI_SAR_NUM_CHAINS_REV2;  		num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV2;  		goto read_table; @@ -584,7 +604,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)  			goto out_free;  		} -		num_chains = ACPI_SAR_NUM_CHAINS_REV1;  		num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV1;  		goto read_table; @@ -600,7 +619,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)  			goto out_free;  		} -		num_chains = ACPI_SAR_NUM_CHAINS_REV0;  		num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV0;  		goto read_table; @@ -632,23 +650,54 @@ read_table:  	/* the tables start at element 3 */  	pos = 3; +	BUILD_BUG_ON(ACPI_SAR_NUM_CHAINS_REV0 != ACPI_SAR_NUM_CHAINS_REV1); +	BUILD_BUG_ON(ACPI_SAR_NUM_CHAINS_REV2 != 2 * ACPI_SAR_NUM_CHAINS_REV0); + +	/* parse non-cdb chains for all profiles */  	for (i = 0; i < n_profiles; i++) {  		union acpi_object *table = &wifi_pkg->package.elements[pos]; +  		/* The EWRD profiles officially go from 2 to 4, but we  		 * save them in sar_profiles[1-3] (because we don't  		 * have profile 0).  So in the array we start from 1.  		 */ -		ret = iwl_acpi_sar_set_profile(table, -					       &fwrt->sar_profiles[i + 1], -					       enabled, num_chains, -					       num_sub_bands); +		ret = iwl_acpi_parse_chains_table(table, +						  fwrt->sar_profiles[i + 1].chains, +						  ACPI_SAR_NUM_CHAINS_REV0, +						  num_sub_bands);  		if (ret < 0) -			break; +			goto out_free;  		/* go to the next table */ -		pos += num_chains * num_sub_bands; +		pos += ACPI_SAR_NUM_CHAINS_REV0 * num_sub_bands;  	} +	/* non-cdb table revisions */ +	if (tbl_rev < 2) +		goto set_enabled; + +	/* parse cdb chains for all profiles */ +	for (i = 0; i < n_profiles; i++) { +		struct iwl_sar_profile_chain *chains; +		union acpi_object *table; + +		table = &wifi_pkg->package.elements[pos]; +		chains = &fwrt->sar_profiles[i + 1].chains[ACPI_SAR_NUM_CHAINS_REV0]; +		ret = iwl_acpi_parse_chains_table(table, +						  chains, +						  ACPI_SAR_NUM_CHAINS_REV0, +						  num_sub_bands); +		if (ret < 0) +			goto out_free; + +		/* go to the next table */ +		pos += ACPI_SAR_NUM_CHAINS_REV0 * num_sub_bands; +	} + +set_enabled: +	for (i = 0; i < n_profiles; i++) +		fwrt->sar_profiles[i + 1].enabled = enabled; +  out_free:  	kfree(data);  	return ret; @@ -821,12 +870,12 @@ int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt)  	if (IS_ERR(data))  		return PTR_ERR(data); -	/* try to read ppag table rev 3, 2 or 1 (all have the same data size) */ +	/* try to read ppag table rev 1 to 4 (all have the same data size) */  	wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data,  				ACPI_PPAG_WIFI_DATA_SIZE_V2, &tbl_rev);  	if (!IS_ERR(wifi_pkg)) { -		if (tbl_rev >= 1 && tbl_rev <= 3) { +		if (tbl_rev >= 1 && tbl_rev <= 4) {  			num_sub_bands = IWL_NUM_SUB_BANDS_V2;  			IWL_DEBUG_RADIO(fwrt,  					"Reading PPAG table (tbl_rev=%d)\n", @@ -856,7 +905,7 @@ int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt)  	goto out_free;  read_table: -	fwrt->ppag_ver = tbl_rev; +	fwrt->ppag_bios_rev = tbl_rev;  	flags = &wifi_pkg->package.elements[1];  	if (flags->type != ACPI_TYPE_INTEGER) { @@ -865,7 +914,7 @@ read_table:  	}  	fwrt->ppag_flags = iwl_bios_get_ppag_flags(flags->integer.value, -						   fwrt->ppag_ver); +						   fwrt->ppag_bios_rev);  	/*  	 * read, verify gain values and save them into the PPAG table. @@ -886,6 +935,7 @@ read_table:  		}  	} +	fwrt->ppag_bios_source = BIOS_SOURCE_ACPI;  	ret = 0;  out_free: @@ -893,40 +943,39 @@ out_free:  	return ret;  } -void iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt, -			      struct iwl_phy_specific_cfg *filters) +int iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt)  { +	struct iwl_phy_specific_cfg *filters = &fwrt->phy_filters;  	struct iwl_phy_specific_cfg tmp = {}; -	union acpi_object *wifi_pkg, *data; +	union acpi_object *wifi_pkg, *data __free(kfree);  	int tbl_rev, i;  	data = iwl_acpi_get_object(fwrt->dev, ACPI_WPFC_METHOD);  	if (IS_ERR(data)) -		return; +		return PTR_ERR(data);  	wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data,  					 ACPI_WPFC_WIFI_DATA_SIZE,  					 &tbl_rev);  	if (IS_ERR(wifi_pkg)) -		goto out_free; +		return PTR_ERR(wifi_pkg);  	if (tbl_rev != 0) -		goto out_free; +		return -EINVAL;  	BUILD_BUG_ON(ARRAY_SIZE(filters->filter_cfg_chains) !=  		     ACPI_WPFC_WIFI_DATA_SIZE - 1);  	for (i = 0; i < ARRAY_SIZE(filters->filter_cfg_chains); i++) {  		if (wifi_pkg->package.elements[i + 1].type != ACPI_TYPE_INTEGER) -			goto out_free; +			return -EINVAL;  		tmp.filter_cfg_chains[i] =  			cpu_to_le32(wifi_pkg->package.elements[i + 1].integer.value);  	}  	IWL_DEBUG_RADIO(fwrt, "Loaded WPFC filter config from ACPI\n");  	*filters = tmp; -out_free: -	kfree(data); +	return 0;  }  IWL_EXPORT_SYMBOL(iwl_acpi_get_phy_filters); @@ -998,3 +1047,37 @@ out_free:  	kfree(data);  	return ret;  } + +int iwl_acpi_get_dsbr(struct iwl_fw_runtime *fwrt, u32 *value) +{ +	union acpi_object *wifi_pkg, *data; +	int ret = -ENOENT; +	int tbl_rev; + +	data = iwl_acpi_get_object(fwrt->dev, ACPI_DSBR_METHOD); +	if (IS_ERR(data)) +		return ret; + +	wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data, +					 ACPI_DSBR_WIFI_DATA_SIZE, +					 &tbl_rev); +	if (IS_ERR(wifi_pkg)) +		goto out_free; + +	if (tbl_rev != ACPI_DSBR_WIFI_DATA_REV) { +		IWL_DEBUG_RADIO(fwrt, "Unsupported ACPI DSBR revision:%d\n", +				tbl_rev); +		goto out_free; +	} + +	if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) +		goto out_free; + +	*value = wifi_pkg->package.elements[1].integer.value; +	IWL_DEBUG_RADIO(fwrt, "Loaded DSBR config from ACPI value: 0x%x\n", +			*value); +	ret = 0; +out_free: +	kfree(data); +	return ret; +} diff --git a/sys/contrib/dev/iwlwifi/fw/acpi.h b/sys/contrib/dev/iwlwifi/fw/acpi.h index bb88398a6987..68d8fb5f6357 100644 --- a/sys/contrib/dev/iwlwifi/fw/acpi.h +++ b/sys/contrib/dev/iwlwifi/fw/acpi.h @@ -1,7 +1,7 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /*   * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2018-2023 Intel Corporation + * Copyright (C) 2018-2023, 2025 Intel Corporation   */  #ifndef __iwl_fw_acpi__  #define __iwl_fw_acpi__ @@ -28,6 +28,7 @@  #define ACPI_WPFC_METHOD	"WPFC"  #define ACPI_GLAI_METHOD	"GLAI"  #define ACPI_WBEM_METHOD	"WBEM" +#define ACPI_DSBR_METHOD	"DSBR"  #define ACPI_WIFI_DOMAIN	(0x07) @@ -76,6 +77,13 @@  #define ACPI_WBEM_WIFI_DATA_SIZE	2  /*   * One element for domain type, + * and one for DSBR response data + */ +#define ACPI_DSBR_WIFI_DATA_SIZE	2 +#define ACPI_DSBR_WIFI_DATA_REV		1 + +/* + * One element for domain type,   * and one for the status   */  #define ACPI_GLAI_WIFI_DATA_SIZE	2 @@ -101,6 +109,30 @@  #define ACPI_DSM_REV 0 +#define DSM_INTERNAL_FUNC_GET_PLAT_INFO	1 +/* TBD: VPRO is BIT(0) in the result, but what's the result? */ + +#define DSM_INTERNAL_FUNC_PRODUCT_RESET	2 + +/* DSM_INTERNAL_FUNC_PRODUCT_RESET - product reset (aka "PLDR") */ +enum iwl_dsm_internal_product_reset_cmds { +	DSM_INTERNAL_PLDR_CMD_GET_MODE = 1, +	DSM_INTERNAL_PLDR_CMD_SET_MODE = 2, +	DSM_INTERNAL_PLDR_CMD_GET_STATUS = 3, +}; + +enum iwl_dsm_internal_product_reset_mode { +	DSM_INTERNAL_PLDR_MODE_EN_PROD_RESET	= BIT(0), +	DSM_INTERNAL_PLDR_MODE_EN_WIFI_FLR	= BIT(1), +	DSM_INTERNAL_PLDR_MODE_EN_BT_OFF_ON	= BIT(2), +}; + +struct iwl_dsm_internal_product_reset_cmd { +	/* cmd is from enum iwl_dsm_internal_product_reset_cmds */ +	u16 cmd; +	u16 value; +} __packed; +  #define IWL_ACPI_WBEM_REV0_MASK (BIT(0) | BIT(1))  #define IWL_ACPI_WBEM_REVISION 0 @@ -110,6 +142,10 @@ struct iwl_fw_runtime;  extern const guid_t iwl_guid; +union acpi_object *iwl_acpi_get_dsm_object(struct device *dev, int rev, +					   int func, union acpi_object *args, +					   const guid_t *guid); +  /**   * iwl_acpi_get_mcc - read MCC from ACPI, if available   * @@ -144,8 +180,7 @@ int iwl_acpi_get_tas_table(struct iwl_fw_runtime *fwrt,  int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt); -void iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt, -			      struct iwl_phy_specific_cfg *filters); +int iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt);  void iwl_acpi_get_guid_lock_status(struct iwl_fw_runtime *fwrt); @@ -153,10 +188,14 @@ int iwl_acpi_get_dsm(struct iwl_fw_runtime *fwrt,  		     enum iwl_dsm_funcs func, u32 *value);  int iwl_acpi_get_wbem(struct iwl_fw_runtime *fwrt, u32 *value); + +int iwl_acpi_get_dsbr(struct iwl_fw_runtime *fwrt, u32 *value); +  #else /* CONFIG_ACPI */ -static inline void *iwl_acpi_get_dsm_object(struct device *dev, int rev, -					    int func, union acpi_object *args) +static inline union acpi_object * +iwl_acpi_get_dsm_object(struct device *dev, int rev, int func, +			union acpi_object *args, const guid_t *guid)  {  	return ERR_PTR(-ENOENT);  } @@ -204,8 +243,10 @@ static inline int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt)  	return -ENOENT;  } -/* macro since the second argument doesn't always exist */ -#define iwl_acpi_get_phy_filters(fwrt, filters) do { } while (0) +static inline int iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt) +{ +	return -ENOENT; +}  static inline void iwl_acpi_get_guid_lock_status(struct iwl_fw_runtime *fwrt)  { @@ -221,6 +262,11 @@ static inline int iwl_acpi_get_wbem(struct iwl_fw_runtime *fwrt, u32 *value)  {  	return -ENOENT;  } + +static inline int iwl_acpi_get_dsbr(struct iwl_fw_runtime *fwrt, u32 *value) +{ +	return -ENOENT; +}  #endif /* CONFIG_ACPI */  #endif /* __iwl_fw_acpi__ */ diff --git a/sys/contrib/dev/iwlwifi/fw/api/alive.h b/sys/contrib/dev/iwlwifi/fw/api/alive.h index ebe85fdf08d3..ad5b95cad0bf 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/alive.h +++ b/sys/contrib/dev/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-2021, 2024 Intel Corporation + * Copyright (C) 2012-2014, 2018, 2020-2021, 2024-2025 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2016-2017 Intel Deutschland GmbH   */ @@ -82,21 +82,6 @@ struct iwl_alive_ntf_v3 {  	struct iwl_umac_alive umac_data;  } __packed; /* UCODE_ALIVE_NTFY_API_S_VER_3 */ -struct iwl_alive_ntf_v4 { -	__le16 status; -	__le16 flags; -	struct iwl_lmac_alive lmac_data[2]; -	struct iwl_umac_alive umac_data; -} __packed; /* UCODE_ALIVE_NTFY_API_S_VER_4 */ - -struct iwl_alive_ntf_v5 { -	__le16 status; -	__le16 flags; -	struct iwl_lmac_alive lmac_data[2]; -	struct iwl_umac_alive umac_data; -	struct iwl_sku_id sku_id; -} __packed; /* UCODE_ALIVE_NTFY_API_S_VER_5 */ -  struct iwl_imr_alive_info {  	__le64 base_addr;  	__le32 size; @@ -112,12 +97,22 @@ struct iwl_alive_ntf_v6 {  	struct iwl_imr_alive_info imr;  } __packed; /* UCODE_ALIVE_NTFY_API_S_VER_6 */ +struct iwl_alive_ntf { +	__le16 status; +	__le16 flags; +	struct iwl_lmac_alive lmac_data[2]; +	struct iwl_umac_alive umac_data; +	struct iwl_sku_id sku_id; +	struct iwl_imr_alive_info imr; +	__le64 platform_id; +} __packed; /* UCODE_ALIVE_NTFY_API_S_VER_8 */ +  /**   * enum iwl_extended_cfg_flags - commands driver may send before   *	finishing init flow   * @IWL_INIT_DEBUG_CFG: driver is going to send debug config command   * @IWL_INIT_NVM: driver is going to send NVM_ACCESS commands - * @IWL_INIT_PHY: driver is going to send PHY_DB commands + * @IWL_INIT_PHY: driver is going to send the PHY_CONFIGURATION_CMD   */  enum iwl_extended_cfg_flags {  	IWL_INIT_DEBUG_CFG, diff --git a/sys/contrib/dev/iwlwifi/fw/api/binding.h b/sys/contrib/dev/iwlwifi/fw/api/binding.h index 2397fdc37fc5..9b942c4aabd9 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/binding.h +++ b/sys/contrib/dev/iwlwifi/fw/api/binding.h @@ -56,8 +56,6 @@ struct iwl_binding_cmd {  } __packed; /* BINDING_CMD_API_S_VER_2 */  #define IWL_BINDING_CMD_SIZE_V1	sizeof(struct iwl_binding_cmd_v1) -#define IWL_LMAC_24G_INDEX		0 -#define IWL_LMAC_5G_INDEX		1  /* The maximal number of fragments in the FW's schedule session */  #define IWL_MVM_MAX_QUOTA 128 diff --git a/sys/contrib/dev/iwlwifi/fw/api/coex.h b/sys/contrib/dev/iwlwifi/fw/api/coex.h index b97a43353779..ddc84430d895 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/coex.h +++ b/sys/contrib/dev/iwlwifi/fw/api/coex.h @@ -95,7 +95,7 @@ enum iwl_bt_ci_compliance {  }; /* BT_COEX_CI_COMPLIENCE_E_VER_1 */  /** - * struct iwl_bt_coex_profile_notif - notification about BT coex + * struct iwl_bt_coex_prof_old_notif - notification about BT coex   * @mbox_msg: message from BT to WiFi   * @msg_idx: the index of the message   * @bt_ci_compliance: enum %iwl_bt_ci_compliance @@ -110,7 +110,7 @@ enum iwl_bt_ci_compliance {   * @wifi_loss_mid_high_rssi: The predicted lost WiFi rate (% of air time that   *	BT is utilizing) when the RSSI is mid/high (>= -65 dBm)   */ -struct iwl_bt_coex_profile_notif { +struct iwl_bt_coex_prof_old_notif {  	__le32 mbox_msg[4];  	__le32 msg_idx;  	__le32 bt_ci_compliance; @@ -126,4 +126,29 @@ struct iwl_bt_coex_profile_notif {  	     * BT_COEX_PROFILE_NTFY_API_S_VER_5  	     */ +/** + * enum iwl_bt_coex_subcmd_ids - coex configuration command IDs + */ +enum iwl_bt_coex_subcmd_ids { +       /** +	*@PROFILE_NOTIF: &struct iwl_bt_coex_profile_notif +	*/ +	PROFILE_NOTIF = 0xFF, +}; + +#define COEX_NUM_BAND	3 +#define COEX_NUM_CHAINS	2 + +/** + * struct iwl_bt_coex_profile_notif - notification about BT coex + * @wifi_loss_low_rssi: The predicted lost WiFi rate (% of air time that BT is + *	utilizing) when the RSSI is low (<= -65 dBm) + * @wifi_loss_mid_high_rssi: The predicted lost WiFi rate (% of air time that + *	BT is utilizing) when the RSSI is mid/high (>= -65 dBm) + */ +struct iwl_bt_coex_profile_notif { +	u8 wifi_loss_low_rssi[COEX_NUM_BAND][COEX_NUM_CHAINS]; +	u8 wifi_loss_mid_high_rssi[COEX_NUM_BAND][COEX_NUM_CHAINS]; +} __packed; /* BT_COEX_BT_PROFILE_NTF_API_S_VER_1 */ +  #endif /* __iwl_fw_api_coex_h__ */ diff --git a/sys/contrib/dev/iwlwifi/fw/api/commands.h b/sys/contrib/dev/iwlwifi/fw/api/commands.h index 7544c4cb1a30..997b0c9ce984 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/commands.h +++ b/sys/contrib/dev/iwlwifi/fw/api/commands.h @@ -2,7 +2,7 @@  /*   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2016-2017 Intel Deutschland GmbH - * Copyright (C) 2018-2022 Intel Corporation + * Copyright (C) 2018-2022, 2024-2025 Intel Corporation   */  #ifndef __iwl_fw_api_commands_h__  #define __iwl_fw_api_commands_h__ @@ -25,6 +25,8 @@   * @NAN_GROUP: NAN group, uses command IDs from &enum iwl_nan_subcmd_ids   * @LOCATION_GROUP: location group, uses command IDs from   *	&enum iwl_location_subcmd_ids + * @BT_COEX_GROUP: bt coex group, uses command IDs from + *	&enum iwl_bt_coex_subcmd_ids   * @PROT_OFFLOAD_GROUP: protocol offload group, uses command IDs from   *	&enum iwl_prot_offload_subcmd_ids   * @REGULATORY_AND_NVM_GROUP: regulatory/NVM group, uses command IDs from @@ -43,6 +45,7 @@ enum iwl_mvm_command_groups {  	SCAN_GROUP = 0x6,  	NAN_GROUP = 0x7,  	LOCATION_GROUP = 0x8, +	BT_COEX_GROUP = 0x9,  	PROT_OFFLOAD_GROUP = 0xb,  	REGULATORY_AND_NVM_GROUP = 0xc,  	DEBUG_GROUP = 0xf, @@ -142,10 +145,10 @@ enum iwl_legacy_cmds {  	REMOVE_STA = 0x19,  	/** -	 * @TX_CMD: uses &struct iwl_tx_cmd or &struct iwl_tx_cmd_gen2 or -	 *	&struct iwl_tx_cmd_gen3, -	 *	response in &struct iwl_mvm_tx_resp or -	 *	&struct iwl_mvm_tx_resp_v3 +	 * @TX_CMD: uses &struct iwl_tx_cmd_v6 or &struct iwl_tx_cmd_v9 or +	 *	&struct iwl_tx_cmd, +	 *	response in &struct iwl_tx_resp or +	 *	&struct iwl_tx_resp_v3  	 */  	TX_CMD = 0x1c, @@ -398,7 +401,7 @@ enum iwl_legacy_cmds {  	REDUCE_TX_POWER_CMD = 0x9f,  	/** -	 * @MISSED_BEACONS_NOTIFICATION: &struct iwl_missed_beacons_notif +	 * @MISSED_BEACONS_NOTIFICATION: &struct iwl_missed_beacons_notif_v4  	 */  	MISSED_BEACONS_NOTIFICATION = 0xa2, @@ -444,7 +447,7 @@ enum iwl_legacy_cmds {  	/**  	 * @BA_NOTIF: -	 * BlockAck notification, uses &struct iwl_mvm_compressed_ba_notif +	 * BlockAck notification, uses &struct iwl_compressed_ba_notif  	 * or &struct iwl_mvm_ba_notif depending on the HW  	 */  	BA_NOTIF = 0xc5, @@ -467,7 +470,7 @@ enum iwl_legacy_cmds {  	MARKER_CMD = 0xcb,  	/** -	 * @BT_PROFILE_NOTIFICATION: &struct iwl_bt_coex_profile_notif +	 * @BT_PROFILE_NOTIFICATION: &struct iwl_bt_coex_prof_old_notif  	 */  	BT_PROFILE_NOTIFICATION = 0xce, @@ -499,11 +502,16 @@ enum iwl_legacy_cmds {  	/**  	 * @DTS_MEASUREMENT_NOTIFICATION:  	 * &struct iwl_dts_measurement_notif_v1 or -	 * &struct iwl_dts_measurement_notif_v2 +	 * &struct iwl_dts_measurement_notif  	 */  	DTS_MEASUREMENT_NOTIFICATION = 0xdd,  	/** +	 * @DEBUG_HOST_COMMAND: &struct iwl_dhc_cmd +	 */ +	DEBUG_HOST_COMMAND = 0xf1, + +	/**  	 * @LDBG_CONFIG_CMD: configure continuous trace recording  	 */  	LDBG_CONFIG_CMD = 0xf6, @@ -565,9 +573,8 @@ enum iwl_legacy_cmds {  	WOWLAN_KEK_KCK_MATERIAL = 0xe4,  	/** -	 * @WOWLAN_GET_STATUSES: response in &struct iwl_wowlan_status_v6, -	 *	&struct iwl_wowlan_status_v7, &struct iwl_wowlan_status_v9 or -	 *	&struct iwl_wowlan_status_v12 +	 * @WOWLAN_GET_STATUSES: response in &struct iwl_wowlan_status_v6 or +	 *	&struct iwl_wowlan_status_v7  	 */  	WOWLAN_GET_STATUSES = 0xe5, diff --git a/sys/contrib/dev/iwlwifi/fw/api/context.h b/sys/contrib/dev/iwlwifi/fw/api/context.h index 1fa5678c1cd6..464eed9b5e71 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/context.h +++ b/sys/contrib/dev/iwlwifi/fw/api/context.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2012-2014, 2022 Intel Corporation + * Copyright (C) 2012-2014, 2022, 2024 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2016-2017 Intel Deutschland GmbH   */ @@ -14,6 +14,9 @@   * @FW_CTXT_COLOR_POS: position of the color   * @FW_CTXT_COLOR_MSK: mask of the color   * @FW_CTXT_INVALID: value used to indicate unused/invalid + * @FW_CTXT_ID_INVALID: value used to indicate unused/invalid. This can be + *	used with newer firmware which no longer use the color. Typically, + *	firmware versions supported by iwlmld can use this value.   */  enum iwl_ctxt_id_and_color {  	FW_CTXT_ID_POS		= 0, @@ -21,6 +24,7 @@ enum iwl_ctxt_id_and_color {  	FW_CTXT_COLOR_POS	= 8,  	FW_CTXT_COLOR_MSK	= 0xff << FW_CTXT_COLOR_POS,  	FW_CTXT_INVALID		= 0xffffffff, +	FW_CTXT_ID_INVALID	= 0xff,  };  #define FW_CMD_ID_AND_COLOR(_id, _color) (((_id) << FW_CTXT_ID_POS) |\ @@ -40,4 +44,7 @@ enum iwl_ctxt_action {  	FW_CTXT_ACTION_REMOVE,  }; /* COMMON_CONTEXT_ACTION_API_E_VER_1 */ +#define IWL_LMAC_24G_INDEX		0 +#define IWL_LMAC_5G_INDEX		1 +  #endif /* __iwl_fw_api_context_h__ */ diff --git a/sys/contrib/dev/iwlwifi/fw/api/d3.h b/sys/contrib/dev/iwlwifi/fw/api/d3.h index ffee7927cf26..53445087e9cb 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/d3.h +++ b/sys/contrib/dev/iwlwifi/fw/api/d3.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation   * Copyright (C) 2013-2014 Intel Mobile Communications GmbH   * Copyright (C) 2015-2017 Intel Deutschland GmbH   */ @@ -19,9 +19,11 @@ enum iwl_d0i3_flags {  /**   * enum iwl_d3_wakeup_flags - D3 manager wakeup flags   * @IWL_WAKEUP_D3_CONFIG_FW_ERROR: wake up on firmware sysassert + * @IWL_WAKEUP_D3_HOST_TIMER: wake up on host timer expiry   */  enum iwl_d3_wakeup_flags { -	IWL_WAKEUP_D3_CONFIG_FW_ERROR = BIT(0), +	IWL_WAKEUP_D3_CONFIG_FW_ERROR	= BIT(0), +	IWL_WAKEUP_D3_HOST_TIMER	= BIT(1),  }; /* D3_MANAGER_WAKEUP_CONFIG_API_E_VER_3 */  /** @@ -368,7 +370,7 @@ enum iwl_wowlan_flags {  };  /** - * struct iwl_wowlan_config_cmd - WoWLAN configuration (versions 5 and 6) + * struct iwl_wowlan_config_cmd_v6 - WoWLAN configuration (versions 5 and 6)   * @wakeup_filter: filter from &enum iwl_wowlan_wakeup_filters   * @non_qos_seq: non-QoS sequence counter to use next.   *               Reserved if the struct has version >= 6. @@ -380,7 +382,7 @@ enum iwl_wowlan_flags {   * @sta_id: station ID for wowlan.   * @reserved: reserved   */ -struct iwl_wowlan_config_cmd { +struct iwl_wowlan_config_cmd_v6 {  	__le32 wakeup_filter;  	__le16 non_qos_seq;  	__le16 qos_seq[8]; @@ -390,7 +392,27 @@ struct iwl_wowlan_config_cmd {  	u8 flags;  	u8 sta_id;  	u8 reserved; -} __packed; /* WOWLAN_CONFIG_API_S_VER_5 */ +} __packed; /* WOWLAN_CONFIG_API_S_VER_6 */ + +/** + * struct iwl_wowlan_config_cmd - WoWLAN configuration + * @wakeup_filter: filter from &enum iwl_wowlan_wakeup_filters + * @wowlan_ba_teardown_tids: bitmap of BA sessions to tear down + * @is_11n_connection: indicates HT connection + * @offloading_tid: TID reserved for firmware use + * @flags: extra flags, see &enum iwl_wowlan_flags + * @sta_id: station ID for wowlan. + * @reserved: reserved + */ +struct iwl_wowlan_config_cmd { +	__le32 wakeup_filter; +	u8 wowlan_ba_teardown_tids; +	u8 is_11n_connection; +	u8 offloading_tid; +	u8 flags; +	u8 sta_id; +	u8 reserved[3]; +} __packed; /* WOWLAN_CONFIG_API_S_VER_7 */  #define IWL_NUM_RSC	16  #define WOWLAN_KEY_MAX_SIZE	32 @@ -434,11 +456,6 @@ struct iwl_wowlan_rsc_tsc_params_cmd_ver_2 {  	union iwl_all_tsc_rsc all_tsc_rsc;  } __packed; /* ALL_TSC_RSC_API_S_VER_2 */ -struct iwl_wowlan_rsc_tsc_params_cmd_v4 { -	struct iwl_wowlan_rsc_tsc_params_cmd_ver_2 params; -	__le32 sta_id; -} __packed; /* ALL_TSC_RSC_API_S_VER_4 */ -  struct iwl_wowlan_rsc_tsc_params_cmd {  	__le64 ucast_rsc[IWL_MAX_TID_COUNT];  	__le64 mcast_rsc[WOWLAN_GTK_KEYS_NUM][IWL_MAX_TID_COUNT]; @@ -698,82 +715,6 @@ struct iwl_wowlan_status_v7 {  } __packed; /* WOWLAN_STATUSES_API_S_VER_7 */  /** - * struct iwl_wowlan_status_v9 - WoWLAN status (versions 9 and 10) - * @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_v9 { -	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; -	__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_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 */ - -/**   * struct iwl_wowlan_info_notif_v1 - WoWLAN information notification   * @gtk: GTK data   * @igtk: IGTK data @@ -810,39 +751,6 @@ struct iwl_wowlan_info_notif_v1 {  	u8 reserved2[2];  } __packed; /* WOWLAN_INFO_NTFY_API_S_VER_1 */ -/** - * struct iwl_wowlan_info_notif_v2 - WoWLAN information notification - * @gtk: GTK data - * @igtk: IGTK data - * @replay_ctr: GTK rekey replay counter - * @pattern_number: number of the matched patterns - * @reserved1: reserved - * @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 - * @tid_tear_down: bit mask of tids whose BA sessions were closed - *	in suspend state - * @station_id: station id - * @reserved2: reserved - */ -struct iwl_wowlan_info_notif_v2 { -	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 reserved1; -	__le16 qos_seq_ctr[8]; -	__le32 wakeup_reasons; -	__le32 num_of_gtk_rekeys; -	__le32 transmitted_ndps; -	__le32 received_beacons; -	u8 tid_tear_down; -	u8 station_id; -	u8 reserved2[2]; -} __packed; /* WOWLAN_INFO_NTFY_API_S_VER_2 */ -  /* MAX MLO keys of non-active links that can arrive in the notification */  #define WOWLAN_MAX_MLO_KEYS 18 @@ -890,7 +798,7 @@ struct iwl_wowlan_mlo_gtk {  } __packed; /* WOWLAN_MLO_GTK_KEY_API_S_VER_1 */  /** - * struct iwl_wowlan_info_notif - WoWLAN information notification + * struct iwl_wowlan_info_notif_v3 - WoWLAN information notification   * @gtk: GTK data   * @igtk: IGTK data   * @bigtk: BIGTK data @@ -905,12 +813,9 @@ struct iwl_wowlan_mlo_gtk {   * @tid_tear_down: bit mask of tids whose BA sessions were closed   *	in suspend state   * @station_id: station id - * @num_mlo_link_keys: number of &struct iwl_wowlan_mlo_gtk structs - *	following this notif, or reserved in version < 4   * @reserved2: reserved - * @mlo_gtks: array of GTKs of size num_mlo_link_keys for version >= 4   */ -struct iwl_wowlan_info_notif { +struct iwl_wowlan_info_notif_v3 {  	struct iwl_wowlan_gtk_status_v3 gtk[WOWLAN_GTK_KEYS_NUM];  	struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM];  	struct iwl_wowlan_igtk_status bigtk[WOWLAN_BIGTK_KEYS_NUM]; @@ -924,10 +829,47 @@ struct iwl_wowlan_info_notif {  	__le32 received_beacons;  	u8 tid_tear_down;  	u8 station_id; +	u8 reserved2[2]; +} __packed; /* WOWLAN_INFO_NTFY_API_S_VER_3 */ + +/** + * struct iwl_wowlan_info_notif - WoWLAN information notification + * @gtk: GTK data + * @igtk: IGTK data + * @bigtk: BIGTK data + * @replay_ctr: GTK rekey replay counter + * @pattern_number: number of the matched patterns + * @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 + * @tid_tear_down: bit mask of tids whose BA sessions were closed + *	in suspend state + * @station_id: station id + * @num_mlo_link_keys: number of &struct iwl_wowlan_mlo_gtk structs + *	following this notif + * @tid_offloaded_tx: tid used by the firmware to transmit data packets + *	while in wowlan + * @mlo_gtks: array of GTKs of size num_mlo_link_keys + */ +struct iwl_wowlan_info_notif { +	struct iwl_wowlan_gtk_status_v3 gtk[WOWLAN_GTK_KEYS_NUM]; +	struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM]; +	struct iwl_wowlan_igtk_status bigtk[WOWLAN_BIGTK_KEYS_NUM]; +	__le64 replay_ctr; +	__le16 pattern_number; +	__le16 qos_seq_ctr; +	__le32 wakeup_reasons; +	__le32 num_of_gtk_rekeys; +	__le32 transmitted_ndps; +	__le32 received_beacons; +	u8 tid_tear_down; +	u8 station_id;  	u8 num_mlo_link_keys; -	u8 reserved2; +	u8 tid_offloaded_tx;  	struct iwl_wowlan_mlo_gtk mlo_gtks[]; -} __packed; /* WOWLAN_INFO_NTFY_API_S_VER_3, _VER_4 */ +} __packed; /* WOWLAN_INFO_NTFY_API_S_VER_5 */  /**   * struct iwl_wowlan_wake_pkt_notif - WoWLAN wake packet notification @@ -947,7 +889,7 @@ struct iwl_wowlan_wake_pkt_notif {   * struct iwl_mvm_d3_end_notif -  d3 end notification   * @flags: See &enum iwl_d0i3_flags   */ -struct iwl_mvm_d3_end_notif { +struct iwl_d3_end_notif {  	__le32 flags;  } __packed; diff --git a/sys/contrib/dev/iwlwifi/fw/api/datapath.h b/sys/contrib/dev/iwlwifi/fw/api/datapath.h index 2ab38eaeb290..b1c6ee8ae2df 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/datapath.h +++ b/sys/contrib/dev/iwlwifi/fw/api/datapath.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2024 Intel Corporation + * Copyright (C) 2024-2025 Intel Corporation   * Copyright (C) 2012-2014, 2018-2022 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2016-2017 Intel Deutschland GmbH @@ -92,7 +92,7 @@ enum iwl_data_path_subcmd_ids {  	/**  	 * @ESR_MODE_NOTIF: notification to recommend/force a wanted esr mode, -	 *	uses &struct iwl_mvm_esr_mode_notif +	 *	uses &struct iwl_esr_mode_notif or &struct iwl_esr_mode_notif_v1  	 */  	ESR_MODE_NOTIF = 0xF3, @@ -119,6 +119,11 @@ enum iwl_data_path_subcmd_ids {  	TLC_MNG_UPDATE_NOTIF = 0xF7,  	/** +	 * @BEACON_FILTER_IN_NOTIF: &struct iwl_beacon_filter_notif +	 */ +	BEACON_FILTER_IN_NOTIF = 0xF8, + +	/**  	 * @STA_PM_NOTIF: &struct iwl_mvm_pm_state_notification  	 */  	STA_PM_NOTIF = 0xFD, @@ -391,7 +396,7 @@ enum iwl_datapath_monitor_notif_type {  struct iwl_datapath_monitor_notif {  	__le32 type; -	u8 mac_id; +	u8 link_id;  	u8 reserved[3];  } __packed; /* MONITOR_NTF_API_S_VER_1 */ diff --git a/sys/contrib/dev/iwlwifi/fw/api/dbg-tlv.h b/sys/contrib/dev/iwlwifi/fw/api/dbg-tlv.h index 855cd13a181e..3173fa96cb48 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/dbg-tlv.h +++ b/sys/contrib/dev/iwlwifi/fw/api/dbg-tlv.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2018-2024 Intel Corporation + * Copyright (C) 2018-2025 Intel Corporation   */  #ifndef __iwl_fw_dbg_tlv_h__  #define __iwl_fw_dbg_tlv_h__ @@ -476,6 +476,8 @@ enum iwl_fw_ini_region_device_memory_subtype {   * @IWL_FW_INI_TIME_POINT_PRESET_OVERRIDE_START: start handling override preset   *	request   * @IWL_FW_INI_TIME_SCAN_FAILURE: failed scan channel list + * @IWL_FW_INI_TIME_ESR_LINK_UP: EMLSR is active (several links are activated) + * @IWL_FW_INI_TIME_ESR_LINK_DOWN: EMLSR is inactive (only one active link left)   * @IWL_FW_INI_TIME_POINT_NUM: number of time points   */  enum iwl_fw_ini_time_point { @@ -509,6 +511,8 @@ enum iwl_fw_ini_time_point {  	IWL_FW_INI_TIME_POINT_PRESET_OVERRIDE_EXT_REQ,  	IWL_FW_INI_TIME_POINT_PRESET_OVERRIDE_START,  	IWL_FW_INI_TIME_SCAN_FAILURE, +	IWL_FW_INI_TIME_ESR_LINK_UP, +	IWL_FW_INI_TIME_ESR_LINK_DOWN,  	IWL_FW_INI_TIME_POINT_NUM,  }; /* FW_TLV_DEBUG_TIME_POINT_API_E */ @@ -523,6 +527,8 @@ enum iwl_fw_ini_time_point {   * @IWL_FW_INI_APPLY_POLICY_OVERRIDE_DATA: override trigger data.   *	Append otherwise   * @IWL_FW_INI_APPLY_POLICY_DUMP_COMPLETE_CMD: send cmd once dump collected + * @IWL_FW_INI_APPLY_POLICY_SPLIT_DUMP_RESET: split this dump into regions + *	before and after the reset handshake   */  enum iwl_fw_ini_trigger_apply_policy {  	IWL_FW_INI_APPLY_POLICY_MATCH_TIME_POINT	= BIT(0), @@ -531,6 +537,7 @@ enum iwl_fw_ini_trigger_apply_policy {  	IWL_FW_INI_APPLY_POLICY_OVERRIDE_CFG		= BIT(9),  	IWL_FW_INI_APPLY_POLICY_OVERRIDE_DATA		= BIT(10),  	IWL_FW_INI_APPLY_POLICY_DUMP_COMPLETE_CMD	= BIT(16), +	IWL_FW_INI_APPLY_POLICY_SPLIT_DUMP_RESET	= BIT(17),  };  /** @@ -552,12 +559,14 @@ enum iwl_fw_ini_trigger_reset_fw_policy {   * @IWL_FW_INI_DEBUG_DUMP_POLICY_NO_LIMIT: OS has no limit of dump size   * @IWL_FW_INI_DEBUG_DUMP_POLICY_MAX_LIMIT_600KB: mini dump only 600KB region dump   * @IWL_FW_IWL_DEBUG_DUMP_POLICY_MAX_LIMIT_5MB: mini dump 5MB size dump + * @IWL_FW_IWL_DEBUG_DUMP_POLICY_BEFORE_RESET: dump this region before reset + *	handshake (if requested by %IWL_FW_INI_APPLY_POLICY_SPLIT_DUMP_RESET)   */  enum iwl_fw_ini_dump_policy {  	IWL_FW_INI_DEBUG_DUMP_POLICY_NO_LIMIT           = BIT(0),  	IWL_FW_INI_DEBUG_DUMP_POLICY_MAX_LIMIT_600KB    = BIT(1),  	IWL_FW_IWL_DEBUG_DUMP_POLICY_MAX_LIMIT_5MB      = BIT(2), - +	IWL_FW_IWL_DEBUG_DUMP_POLICY_BEFORE_RESET	= BIT(3),  };  /** diff --git a/sys/contrib/dev/iwlwifi/fw/api/debug.h b/sys/contrib/dev/iwlwifi/fw/api/debug.h index bea0f4668cc8..0cf1e5124fba 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/debug.h +++ b/sys/contrib/dev/iwlwifi/fw/api/debug.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2005-2014, 2018-2024 Intel Corporation + * Copyright (C) 2005-2014, 2018-2025 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2016-2017 Intel Deutschland GmbH   */ @@ -51,7 +51,7 @@ enum iwl_debug_cmds {  	/**  	 * @GET_TAS_STATUS:  	 * sends command to fw to get TAS status -	 * the response is &struct iwl_mvm_tas_status_resp +	 * the response is &struct iwl_tas_status_resp  	 */  	GET_TAS_STATUS = 0xA,  	/** @@ -439,25 +439,20 @@ struct iwl_dbg_dump_complete_cmd {  	__le32 tp_data;  } __packed; /* FW_DUMP_COMPLETE_CMD_API_S_VER_1 */ -#define TAS_LMAC_BAND_HB       0 -#define TAS_LMAC_BAND_LB       1 -#define TAS_LMAC_BAND_UHB      2 -#define TAS_LMAC_BAND_INVALID  3 -  /** - * struct iwl_mvm_tas_status_per_mac - tas status per lmac + * struct iwl_tas_status_per_mac - tas status per lmac   * @static_status: tas statically enabled or disabled per lmac - TRUE/FALSE   * @static_dis_reason: TAS static disable reason, uses - *	&enum iwl_mvm_tas_statically_disabled_reason + *	&enum iwl_tas_statically_disabled_reason   * @dynamic_status: Current TAS  status. uses - *	&enum iwl_mvm_tas_dyna_status + *	&enum iwl_tas_dyna_status   * @near_disconnection: is TAS currently near disconnection per lmac? - TRUE/FALSE   * @max_reg_pwr_limit: Regulatory power limits in dBm   * @sar_limit: SAR limits per lmac in dBm   * @band: Band per lmac   * @reserved: reserved   */ -struct iwl_mvm_tas_status_per_mac { +struct iwl_tas_status_per_mac {  	u8 static_status;  	u8 static_dis_reason;  	u8 dynamic_status; @@ -466,31 +461,35 @@ struct iwl_mvm_tas_status_per_mac {  	__le16 sar_limit;  	u8 band;  	u8 reserved[3]; -} __packed; /*DEBUG_GET_TAS_STATUS_PER_MAC_S_VER_1*/ +} __packed; /* DEBUG_GET_TAS_STATUS_PER_MAC_S_VER_1 */  /** - * struct iwl_mvm_tas_status_resp - Response to GET_TAS_STATUS + * struct iwl_tas_status_resp - Response to GET_TAS_STATUS   * @tas_fw_version: TAS FW version   * @is_uhb_for_usa_enable: is UHB enabled in USA? - TRUE/FALSE   * @curr_mcc: current mcc   * @block_list: country block list   * @tas_status_mac: TAS status per lmac, uses - *	&struct iwl_mvm_tas_status_per_mac + *	&struct iwl_tas_status_per_mac   * @in_dual_radio: is TAS in dual radio? - TRUE/FALSE + * @uhb_allowed_flags: see &enum iwl_tas_uhb_allowed_flags. + *	This member is valid only when fw has + *	%IWL_UCODE_TLV_CAPA_UHB_CANADA_TAS_SUPPORT capability.   * @reserved: reserved   */ -struct iwl_mvm_tas_status_resp { +struct iwl_tas_status_resp {  	u8 tas_fw_version;  	u8 is_uhb_for_usa_enable;  	__le16 curr_mcc;  	__le16 block_list[16]; -	struct iwl_mvm_tas_status_per_mac tas_status_mac[2]; +	struct iwl_tas_status_per_mac tas_status_mac[2];  	u8 in_dual_radio; -	u8 reserved[3]; -} __packed; /*DEBUG_GET_TAS_STATUS_RSP_API_S_VER_3*/ +	u8 uhb_allowed_flags; +	u8 reserved[2]; +} __packed; /* DEBUG_GET_TAS_STATUS_RSP_API_S_VER_3 */  /** - * enum iwl_mvm_tas_dyna_status - TAS current running status + * enum iwl_tas_dyna_status - TAS current running status   * @TAS_DYNA_INACTIVE: TAS status is inactive   * @TAS_DYNA_INACTIVE_MVM_MODE: TAS is disabled due because FW is in MVM mode   *	or is in softap mode. @@ -503,7 +502,7 @@ struct iwl_mvm_tas_status_resp {   * @TAS_DYNA_ACTIVE: TAS is currently active   * @TAS_DYNA_STATUS_MAX: TAS status max value   */ -enum iwl_mvm_tas_dyna_status { +enum iwl_tas_dyna_status {  	TAS_DYNA_INACTIVE,  	TAS_DYNA_INACTIVE_MVM_MODE,  	TAS_DYNA_INACTIVE_TRIGGER_MODE, @@ -512,19 +511,22 @@ enum iwl_mvm_tas_dyna_status {  	TAS_DYNA_ACTIVE,  	TAS_DYNA_STATUS_MAX, -}; /*_TAS_DYNA_STATUS_E*/ +};  /** - * enum iwl_mvm_tas_statically_disabled_reason - TAS statically disabled reason + * enum iwl_tas_statically_disabled_reason - TAS statically disabled reason   * @TAS_DISABLED_DUE_TO_BIOS: TAS is disabled because TAS is disabled in BIOS   * @TAS_DISABLED_DUE_TO_SAR_6DBM: TAS is disabled because SAR limit is less than 6 Dbm   * @TAS_DISABLED_REASON_INVALID: TAS disable reason is invalid + * @TAS_DISABLED_DUE_TO_TABLE_SOURCE_INVALID: TAS is disabled due to + *	table source invalid   * @TAS_DISABLED_REASON_MAX: TAS disable reason max value   */ -enum iwl_mvm_tas_statically_disabled_reason { +enum iwl_tas_statically_disabled_reason {  	TAS_DISABLED_DUE_TO_BIOS,  	TAS_DISABLED_DUE_TO_SAR_6DBM,  	TAS_DISABLED_REASON_INVALID, +	TAS_DISABLED_DUE_TO_TABLE_SOURCE_INVALID,  	TAS_DISABLED_REASON_MAX,  }; /*_TAS_STATICALLY_DISABLED_REASON_E*/ diff --git a/sys/contrib/dev/iwlwifi/fw/api/dhc.h b/sys/contrib/dev/iwlwifi/fw/api/dhc.h new file mode 100644 index 000000000000..ddba2fc9254c --- /dev/null +++ b/sys/contrib/dev/iwlwifi/fw/api/dhc.h @@ -0,0 +1,230 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* + * Copyright (C) 2025 Intel Corporation + */ +#ifndef __iwl_fw_api_dhc_h__ +#define __iwl_fw_api_dhc_h__ + +#define DHC_TABLE_MASK_POS (28) + +/** + * enum iwl_dhc_table_id - DHC table operations index + */ +enum iwl_dhc_table_id { +	/** +	 * @DHC_TABLE_INTEGRATION: select the integration table +	 */ +	DHC_TABLE_INTEGRATION	= 2 << DHC_TABLE_MASK_POS, +	/** +	 * @DHC_TABLE_TOOLS: select the tools table +	 */ +	DHC_TABLE_TOOLS		= 0, +}; + +/** + * enum iwl_dhc_umac_tools_table - tools operations + * @DHC_TOOLS_UMAC_GET_TAS_STATUS: Get TAS status. + *	See @struct iwl_dhc_tas_status_resp + */ +enum iwl_dhc_umac_tools_table { +	DHC_TOOLS_UMAC_GET_TAS_STATUS = 0, +}; + +/** + * enum iwl_dhc_umac_integration_table - integration operations + */ +enum iwl_dhc_umac_integration_table { +	/** +	 * @DHC_INT_UMAC_TWT_OPERATION: trigger a TWT operation +	 */ +	DHC_INT_UMAC_TWT_OPERATION = 4, +	/** +	 * @DHC_INTEGRATION_TLC_DEBUG_CONFIG: TLC debug +	 */ +	DHC_INTEGRATION_TLC_DEBUG_CONFIG = 1, +	/** +	 * @DHC_INTEGRATION_MAX: Maximum UMAC integration table entries +	 */ +	DHC_INTEGRATION_MAX +}; + +#define DHC_TARGET_UMAC BIT(27) + +/** + * struct iwl_dhc_cmd - debug host command + * @length: length in DWs of the data structure that is concatenated to the end + *	of this struct + * @index_and_mask: bit 31 is 1 for data set operation else it's 0 + *	bits 28-30 is the index of the table of the operation - + *	&enum iwl_dhc_table_id * + *	bit 27 is 0 if the cmd targeted to LMAC and 1 if targeted to UMAC, + *	(LMAC is 0 for backward compatibility) + *	bit 26 is 0 if the cmd targeted to LMAC0 and 1 if targeted to LMAC1, + *	relevant only if bit 27 set to 0 + *	bits 0-25 is a specific entry index in the table specified in bits 28-30 + * + * @data: the concatenated data. + */ +struct iwl_dhc_cmd { +	__le32 length; +	__le32 index_and_mask; +#if defined(__linux__) +	__le32 data[]; +#elif defined(__FreeBSD__) +	__le32 data[0]; +#endif +} __packed; /* DHC_CMD_API_S */ + +/** + * struct iwl_dhc_payload_hdr - DHC payload header + * @version: a version of a payload + * @reserved: reserved for alignment + */ +struct iwl_dhc_payload_hdr { +	u8 version; +	u8 reserved[3]; +} __packed; /* DHC_PAYLOAD_HDR_API_S_VER_1 */ + +/** + * struct iwl_dhc_tas_status_per_radio - TAS status per radio + * @band: &PHY_BAND_5 for high band, PHY_BAND_24 for low band and + *	&PHY_BAND_6 for ultra high band. + * @static_status: TAS statically enabled or disabled + * @static_disable_reason: TAS static disable reason, uses + *	&enum iwl_tas_statically_disabled_reason + * @near_disconnection: is TAS currently near disconnection per radio + * @dynamic_status_ant_a: Antenna A current TAS status. + *	uses &enum iwl_tas_dyna_status + * @dynamic_status_ant_b: Antenna B current TAS status. + *	uses &enum iwl_tas_dyna_status + * @max_reg_pwr_limit_ant_a: Antenna A regulatory power limits in dBm + * @max_reg_pwr_limit_ant_b: Antenna B regulatory power limits in dBm + * @sar_limit_ant_a: Antenna A SAR limit per radio in dBm + * @sar_limit_ant_b: Antenna B SAR limit per radio in dBm + * @reserved: reserved for alignment + */ +struct iwl_dhc_tas_status_per_radio { +	u8 band; +	u8 static_status; +	u8 static_disable_reason; +	u8 near_disconnection; +	u8 dynamic_status_ant_a; +	u8 dynamic_status_ant_b; +	__le16 max_reg_pwr_limit_ant_a; +	__le16 max_reg_pwr_limit_ant_b; +	__le16 sar_limit_ant_a; +	__le16 sar_limit_ant_b; +	u8 reserved[2]; +} __packed; /* DHC_TAS_STATUS_PER_RADIO_S_VER_1 */ + +/** + * struct iwl_dhc_tas_status_resp - Response to DHC_TOOLS_UMAC_GET_TAS_STATUS + * @header: DHC payload header, uses &struct iwl_dhc_payload_hdr + * @tas_config_info: see @struct bios_value_u32 + * @mcc_block_list: block listed country codes + * @tas_status_radio: TAS status, uses &struct iwl_dhc_tas_status_per_radio + * @curr_mcc: current mcc + * @valid_radio_mask: represent entry in tas_status_per_radio is valid. + * @reserved: reserved for alignment + */ +struct iwl_dhc_tas_status_resp { +	struct iwl_dhc_payload_hdr header; +	struct bios_value_u32 tas_config_info; +	__le16 mcc_block_list[IWL_WTAS_BLACK_LIST_MAX]; +	struct iwl_dhc_tas_status_per_radio tas_status_radio[2]; +	__le16 curr_mcc; +	u8 valid_radio_mask; +	u8 reserved; +} __packed; /* DHC_TAS_STATUS_RSP_API_S_VER_1 */ + +/** + * struct iwl_dhc_cmd_resp_v1 - debug host command response + * @status: status of the command + * @data: the response data + */ +struct iwl_dhc_cmd_resp_v1 { +	__le32 status; +	__le32 data[]; +} __packed; /* DHC_RESP_API_S_VER_1 */ + +/** + * struct iwl_dhc_cmd_resp - debug host command response + * @status: status of the command + * @descriptor: command descriptor (index_and_mask) returned + * @data: the response data + */ +struct iwl_dhc_cmd_resp { +	__le32 status; +	__le32 descriptor; +	__le32 data[]; +} __packed; /* DHC_RESP_API_S_VER_2 and DHC_RESP_API_S_VER_3 */ + +/** + * enum iwl_dhc_twt_operation_type - describes the TWT operation type + * + * @DHC_TWT_REQUEST: Send a Request TWT command + * @DHC_TWT_SUGGEST: Send a Suggest TWT command + * @DHC_TWT_DEMAND: Send a Demand TWT command + * @DHC_TWT_GROUPING: Send a Grouping TWT command + * @DHC_TWT_ACCEPT: Send a Accept TWT command + * @DHC_TWT_ALTERNATE: Send a Alternate TWT command + * @DHC_TWT_DICTATE: Send a Dictate TWT command + * @DHC_TWT_REJECT: Send a Reject TWT command + * @DHC_TWT_TEARDOWN: Send a TearDown TWT command + */ +enum iwl_dhc_twt_operation_type { +	DHC_TWT_REQUEST, +	DHC_TWT_SUGGEST, +	DHC_TWT_DEMAND, +	DHC_TWT_GROUPING, +	DHC_TWT_ACCEPT, +	DHC_TWT_ALTERNATE, +	DHC_TWT_DICTATE, +	DHC_TWT_REJECT, +	DHC_TWT_TEARDOWN, +}; /* DHC_TWT_OPERATION_TYPE_E */ + +/** + * struct iwl_dhc_twt_operation - trigger a TWT operation + * + * @mac_id: the mac Id on which to trigger TWT operation + * @twt_operation: see &enum iwl_dhc_twt_operation_type + * @target_wake_time: when should we be on channel + * @interval_exp: the exponent for the interval + * @interval_mantissa: the mantissa for the interval + * @min_wake_duration: the minimum duration for the wake period + * @trigger: is the TWT triggered or not + * @flow_type: is the TWT announced or not + * @flow_id: the TWT flow identifier from 0 to 7 + * @protection: is the TWT protected + * @ndo_paging_indicator: is ndo_paging_indicator set + * @responder_pm_mode: is responder_pm_mode set + * @negotiation_type: if the responder wants to doze outside the TWT SP + * @twt_request: 1 for TWT request, 0 otherwise + * @implicit: is TWT implicit + * @twt_group_assignment: the TWT group assignment + * @twt_channel: the TWT channel + * @reserved: reserved + */ +struct iwl_dhc_twt_operation { +	__le32 mac_id; +	__le32 twt_operation; +	__le64 target_wake_time; +	__le32 interval_exp; +	__le32 interval_mantissa; +	__le32 min_wake_duration; +	u8 trigger; +	u8 flow_type; +	u8 flow_id; +	u8 protection; +	u8 ndo_paging_indicator; +	u8 responder_pm_mode; +	u8 negotiation_type; +	u8 twt_request; +	u8 implicit; +	u8 twt_group_assignment; +	u8 twt_channel; +	u8 reserved; +}; /* DHC_TWT_OPERATION_API_S */ + +#endif /* __iwl_fw_api_dhc_h__ */ diff --git a/sys/contrib/dev/iwlwifi/fw/api/location.h b/sys/contrib/dev/iwlwifi/fw/api/location.h index 30a54c7fa001..33541f92c7c7 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/location.h +++ b/sys/contrib/dev/iwlwifi/fw/api/location.h @@ -2,10 +2,15 @@  /*   * Copyright (C) 2015-2017 Intel Deutschland GmbH   * Copyright (C) 2018-2022 Intel Corporation - * Copyright (C) 2024 Intel Corporation + * Copyright (C) 2024-2025 Intel Corporation   */  #ifndef __iwl_fw_api_location_h__  #define __iwl_fw_api_location_h__ +#include <linux/ieee80211.h> +#include <linux/if_ether.h> +#include <linux/types.h> +#include <linux/bits.h> +#include "rs.h"  /**   * enum iwl_location_subcmd_ids - location group command IDs @@ -616,6 +621,9 @@ struct iwl_tof_range_req_ap_entry_v2 {   *	continue with the session and will provide the LMR feedback.   * @IWL_INITIATOR_AP_FLAGS_TEST_INCORRECT_SAC: send an incorrect SAC in the   *	first NDP exchange. This is used for testing. + * @IWL_INITIATOR_AP_FLAGS_TEST_BAD_SLTF: use incorrect secure LTF tx key. This + *	is used for testing. Only supported from version 15 of the range request + *	command.   */  enum iwl_initiator_ap_flags {  	IWL_INITIATOR_AP_FLAGS_ASAP = BIT(1), @@ -633,6 +641,7 @@ enum iwl_initiator_ap_flags {  	IWL_INITIATOR_AP_FLAGS_PMF = BIT(14),  	IWL_INITIATOR_AP_FLAGS_TERMINATE_ON_LMR_FEEDBACK = BIT(15),  	IWL_INITIATOR_AP_FLAGS_TEST_INCORRECT_SAC = BIT(16), +	IWL_INITIATOR_AP_FLAGS_TEST_BAD_SLTF = BIT(17),  };  /** @@ -767,7 +776,7 @@ enum iwl_location_cipher {   * @num_of_bursts: Recommended value to be sent to the AP. 2s Exponent of   *	the number of measurement iterations (min 2^0 = 1, max 2^14)   * @sta_id: the station id of the AP. Only relevant when associated to the AP, - *	otherwise should be set to &IWL_MVM_INVALID_STA. + *	otherwise should be set to &IWL_INVALID_STA.   * @cipher: pairwise cipher suite for secured measurement.   *          &enum iwl_location_cipher.   * @hltk: HLTK to be used for secured 11az measurement @@ -814,7 +823,7 @@ struct iwl_tof_range_req_ap_entry_v6 {   * @num_of_bursts: Recommended value to be sent to the AP. 2s Exponent of   *	the number of measurement iterations (min 2^0 = 1, max 2^14)   * @sta_id: the station id of the AP. Only relevant when associated to the AP, - *	otherwise should be set to &IWL_MVM_INVALID_STA. + *	otherwise should be set to &IWL_INVALID_STA.   * @cipher: pairwise cipher suite for secured measurement.   *          &enum iwl_location_cipher.   * @hltk: HLTK to be used for secured 11az measurement @@ -827,10 +836,10 @@ struct iwl_tof_range_req_ap_entry_v6 {   *	&IWL_INITIATOR_AP_FLAGS_TB is set.   * @rx_pn: the next expected PN for protected management frames Rx. LE byte   *	order. Only valid if &IWL_INITIATOR_AP_FLAGS_SECURED is set and sta_id - *	is set to &IWL_MVM_INVALID_STA. + *	is set to &IWL_INVALID_STA.   * @tx_pn: the next PN to use for protected management frames Tx. LE byte   *	order. Only valid if &IWL_INITIATOR_AP_FLAGS_SECURED is set and sta_id - *	is set to &IWL_MVM_INVALID_STA. + *	is set to &IWL_INVALID_STA.   */  struct iwl_tof_range_req_ap_entry_v7 {  	__le32 initiator_ap_flags; @@ -872,7 +881,7 @@ struct iwl_tof_range_req_ap_entry_v7 {   * @num_of_bursts: Recommended value to be sent to the AP. 2s Exponent of   *	the number of measurement iterations (min 2^0 = 1, max 2^14)   * @sta_id: the station id of the AP. Only relevant when associated to the AP, - *	otherwise should be set to &IWL_MVM_INVALID_STA. + *	otherwise should be set to &IWL_INVALID_STA.   * @cipher: pairwise cipher suite for secured measurement.   *          &enum iwl_location_cipher.   * @hltk: HLTK to be used for secured 11az measurement @@ -885,10 +894,10 @@ struct iwl_tof_range_req_ap_entry_v7 {   *	&IWL_INITIATOR_AP_FLAGS_TB is set.   * @rx_pn: the next expected PN for protected management frames Rx. LE byte   *	order. Only valid if &IWL_INITIATOR_AP_FLAGS_SECURED is set and sta_id - *	is set to &IWL_MVM_INVALID_STA. + *	is set to &IWL_INVALID_STA.   * @tx_pn: the next PN to use for protected management frames Tx. LE byte   *	order. Only valid if &IWL_INITIATOR_AP_FLAGS_SECURED is set and sta_id - *	is set to &IWL_MVM_INVALID_STA. + *	is set to &IWL_INVALID_STA.   * @r2i_ndp_params: parameters for R2I NDP ranging negotiation.   *      bits 0 - 2: max LTF repetitions   *      bits 3 - 5: max number of spatial streams @@ -946,7 +955,7 @@ struct iwl_tof_range_req_ap_entry_v8 {   * @num_of_bursts: Recommended value to be sent to the AP. 2s Exponent of   *	the number of measurement iterations (min 2^0 = 1, max 2^14)   * @sta_id: the station id of the AP. Only relevant when associated to the AP, - *	otherwise should be set to &IWL_MVM_INVALID_STA. + *	otherwise should be set to &IWL_INVALID_STA.   * @cipher: pairwise cipher suite for secured measurement.   *          &enum iwl_location_cipher.   * @hltk: HLTK to be used for secured 11az measurement @@ -961,10 +970,10 @@ struct iwl_tof_range_req_ap_entry_v8 {   *	&IWL_INITIATOR_AP_FLAGS_TB or &IWL_INITIATOR_AP_FLAGS_NON_TB is set.   * @rx_pn: the next expected PN for protected management frames Rx. LE byte   *	order. Only valid if &IWL_INITIATOR_AP_FLAGS_SECURED is set and sta_id - *	is set to &IWL_MVM_INVALID_STA. + *	is set to &IWL_INVALID_STA.   * @tx_pn: the next PN to use for protected management frames Tx. LE byte   *	order. Only valid if &IWL_INITIATOR_AP_FLAGS_SECURED is set and sta_id - *	is set to &IWL_MVM_INVALID_STA. + *	is set to &IWL_INVALID_STA.   * @r2i_ndp_params: parameters for R2I NDP ranging negotiation.   *      bits 0 - 2: max LTF repetitions   *      bits 3 - 5: max number of spatial streams @@ -1011,7 +1020,7 @@ struct iwl_tof_range_req_ap_entry_v9 {  } __packed; /* LOCATION_RANGE_REQ_AP_ENTRY_CMD_API_S_VER_9 */  /** - * struct iwl_tof_range_req_ap_entry_v10 - AP configuration parameters + * struct iwl_tof_range_req_ap_entry - AP configuration parameters   * @initiator_ap_flags: see &enum iwl_initiator_ap_flags.   * @band: 0 for 5.2 GHz, 1 for 2.4 GHz, 2 for 6GHz   * @channel_num: AP Channel number @@ -1029,7 +1038,7 @@ struct iwl_tof_range_req_ap_entry_v9 {   * @num_of_bursts: Recommended value to be sent to the AP. 2s Exponent of   *	the number of measurement iterations (min 2^0 = 1, max 2^14)   * @sta_id: the station id of the AP. Only relevant when associated to the AP, - *	otherwise should be set to &IWL_MVM_INVALID_STA. + *	otherwise should be set to &IWL_INVALID_STA.   * @cipher: pairwise cipher suite for secured measurement.   *          &enum iwl_location_cipher.   * @hltk: HLTK to be used for secured 11az measurement @@ -1042,10 +1051,10 @@ struct iwl_tof_range_req_ap_entry_v9 {   *	&IWL_INITIATOR_AP_FLAGS_TB is set.   * @rx_pn: the next expected PN for protected management frames Rx. LE byte   *	order. Only valid if &IWL_INITIATOR_AP_FLAGS_SECURED is set and sta_id - *	is set to &IWL_MVM_INVALID_STA. + *	is set to &IWL_INVALID_STA.   * @tx_pn: the next PN to use for protected management frames Tx. LE byte   *	order. Only valid if &IWL_INITIATOR_AP_FLAGS_SECURED is set and sta_id - *	is set to &IWL_MVM_INVALID_STA. + *	is set to &IWL_INVALID_STA.   * @r2i_ndp_params: parameters for R2I NDP ranging negotiation.   *      bits 0 - 2: max LTF repetitions   *      bits 3 - 5: max number of spatial streams @@ -1059,7 +1068,7 @@ struct iwl_tof_range_req_ap_entry_v9 {   * @min_time_between_msr: For non trigger based NDP ranging, the minimum time   *	between measurements in units of milliseconds   */ -struct iwl_tof_range_req_ap_entry_v10 { +struct iwl_tof_range_req_ap_entry {  	__le32 initiator_ap_flags;  	u8 band;  	u8 channel_num; @@ -1130,7 +1139,7 @@ enum iwl_tof_initiator_flags {  	IWL_TOF_INITIATOR_FLAGS_NON_ASAP_SUPPORT = BIT(20),  }; /* LOCATION_RANGE_REQ_CMD_API_S_VER_5 */ -#define IWL_MVM_TOF_MAX_APS 5 +#define IWL_TOF_MAX_APS 5  #define IWL_MVM_TOF_MAX_TWO_SIDED_APS 5  /** @@ -1149,7 +1158,7 @@ enum iwl_tof_initiator_flags {   *		   when the session is done (successfully / partially).   *		   one of iwl_tof_response_mode.   * @reserved0: reserved - * @num_of_ap: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) + * @num_of_ap: Number of APs to measure (error if > IWL_TOF_MAX_APS)   * @macaddr_random: '0' Use default source MAC address (i.e. p2_p),   *	            '1' Use MAC Address randomization according to the below   * @range_req_bssid: ranging request BSSID @@ -1179,7 +1188,7 @@ struct iwl_tof_range_req_cmd_v5 {  	u8 ftm_tx_chains;  	__le16 common_calib;  	__le16 specific_calib; -	struct iwl_tof_range_req_ap_entry_v2 ap[IWL_MVM_TOF_MAX_APS]; +	struct iwl_tof_range_req_ap_entry_v2 ap[IWL_TOF_MAX_APS];  } __packed;  /* LOCATION_RANGE_REQ_CMD_API_S_VER_5 */ @@ -1188,7 +1197,7 @@ struct iwl_tof_range_req_cmd_v5 {   * @initiator_flags: see flags @ iwl_tof_initiator_flags   * @request_id: A Token incremented per request. The same Token will be   *		sent back in the range response - * @num_of_ap: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) + * @num_of_ap: Number of APs to measure (error if > IWL_TOF_MAX_APS)   * @range_req_bssid: ranging request BSSID   * @macaddr_mask: Bits set to 0 shall be copied from the MAC address template.   *		  Bits set to 1 shall be randomized by the UMAC @@ -1212,7 +1221,7 @@ struct iwl_tof_range_req_cmd_v7 {  	__le32 tsf_mac_id;  	__le16 common_calib;  	__le16 specific_calib; -	struct iwl_tof_range_req_ap_entry_v3 ap[IWL_MVM_TOF_MAX_APS]; +	struct iwl_tof_range_req_ap_entry_v3 ap[IWL_TOF_MAX_APS];  } __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_7 */  /** @@ -1220,7 +1229,7 @@ struct iwl_tof_range_req_cmd_v7 {   * @initiator_flags: see flags @ iwl_tof_initiator_flags   * @request_id: A Token incremented per request. The same Token will be   *		sent back in the range response - * @num_of_ap: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) + * @num_of_ap: Number of APs to measure (error if > IWL_TOF_MAX_APS)   * @range_req_bssid: ranging request BSSID   * @macaddr_mask: Bits set to 0 shall be copied from the MAC address template.   *		  Bits set to 1 shall be randomized by the UMAC @@ -1244,7 +1253,7 @@ struct iwl_tof_range_req_cmd_v8 {  	__le32 tsf_mac_id;  	__le16 common_calib;  	__le16 specific_calib; -	struct iwl_tof_range_req_ap_entry_v4 ap[IWL_MVM_TOF_MAX_APS]; +	struct iwl_tof_range_req_ap_entry_v4 ap[IWL_TOF_MAX_APS];  } __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_8 */  /** @@ -1252,7 +1261,7 @@ struct iwl_tof_range_req_cmd_v8 {   * @initiator_flags: see flags @ iwl_tof_initiator_flags   * @request_id: A Token incremented per request. The same Token will be   *		sent back in the range response - * @num_of_ap: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) + * @num_of_ap: Number of APs to measure (error if > IWL_TOF_MAX_APS)   * @range_req_bssid: ranging request BSSID   * @macaddr_mask: Bits set to 0 shall be copied from the MAC address template.   *		  Bits set to 1 shall be randomized by the UMAC @@ -1272,7 +1281,7 @@ struct iwl_tof_range_req_cmd_v9 {  	u8 macaddr_template[ETH_ALEN];  	__le32 req_timeout_ms;  	__le32 tsf_mac_id; -	struct iwl_tof_range_req_ap_entry_v6 ap[IWL_MVM_TOF_MAX_APS]; +	struct iwl_tof_range_req_ap_entry_v6 ap[IWL_TOF_MAX_APS];  } __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_9 */  /** @@ -1280,7 +1289,7 @@ struct iwl_tof_range_req_cmd_v9 {   * @initiator_flags: see flags @ iwl_tof_initiator_flags   * @request_id: A Token incremented per request. The same Token will be   *		sent back in the range response - * @num_of_ap: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) + * @num_of_ap: Number of APs to measure (error if > IWL_TOF_MAX_APS)   * @range_req_bssid: ranging request BSSID   * @macaddr_mask: Bits set to 0 shall be copied from the MAC address template.   *		  Bits set to 1 shall be randomized by the UMAC @@ -1300,7 +1309,7 @@ struct iwl_tof_range_req_cmd_v11 {  	u8 macaddr_template[ETH_ALEN];  	__le32 req_timeout_ms;  	__le32 tsf_mac_id; -	struct iwl_tof_range_req_ap_entry_v7 ap[IWL_MVM_TOF_MAX_APS]; +	struct iwl_tof_range_req_ap_entry_v7 ap[IWL_TOF_MAX_APS];  } __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_11 */  /** @@ -1308,7 +1317,7 @@ struct iwl_tof_range_req_cmd_v11 {   * @initiator_flags: see flags @ iwl_tof_initiator_flags   * @request_id: A Token incremented per request. The same Token will be   *		sent back in the range response - * @num_of_ap: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) + * @num_of_ap: Number of APs to measure (error if > IWL_TOF_MAX_APS)   * @range_req_bssid: ranging request BSSID   * @macaddr_mask: Bits set to 0 shall be copied from the MAC address template.   *		  Bits set to 1 shall be randomized by the UMAC @@ -1328,7 +1337,7 @@ struct iwl_tof_range_req_cmd_v12 {  	u8 macaddr_template[ETH_ALEN];  	__le32 req_timeout_ms;  	__le32 tsf_mac_id; -	struct iwl_tof_range_req_ap_entry_v8 ap[IWL_MVM_TOF_MAX_APS]; +	struct iwl_tof_range_req_ap_entry_v8 ap[IWL_TOF_MAX_APS];  } __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_12 */  /** @@ -1336,7 +1345,7 @@ struct iwl_tof_range_req_cmd_v12 {   * @initiator_flags: see flags @ iwl_tof_initiator_flags   * @request_id: A Token incremented per request. The same Token will be   *		sent back in the range response - * @num_of_ap: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) + * @num_of_ap: Number of APs to measure (error if > IWL_TOF_MAX_APS)   * @range_req_bssid: ranging request BSSID   * @macaddr_mask: Bits set to 0 shall be copied from the MAC address template.   *		  Bits set to 1 shall be randomized by the UMAC @@ -1356,15 +1365,15 @@ struct iwl_tof_range_req_cmd_v13 {  	u8 macaddr_template[ETH_ALEN];  	__le32 req_timeout_ms;  	__le32 tsf_mac_id; -	struct iwl_tof_range_req_ap_entry_v9 ap[IWL_MVM_TOF_MAX_APS]; +	struct iwl_tof_range_req_ap_entry_v9 ap[IWL_TOF_MAX_APS];  } __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_13 */  /** - * struct iwl_tof_range_req_cmd_v14 - start measurement cmd + * struct iwl_tof_range_req_cmd - start measurement cmd   * @initiator_flags: see flags @ iwl_tof_initiator_flags   * @request_id: A Token incremented per request. The same Token will be   *		sent back in the range response - * @num_of_ap: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) + * @num_of_ap: Number of APs to measure (error if > IWL_TOF_MAX_APS)   * @range_req_bssid: ranging request BSSID   * @macaddr_mask: Bits set to 0 shall be copied from the MAC address template.   *		  Bits set to 1 shall be randomized by the UMAC @@ -1373,9 +1382,9 @@ struct iwl_tof_range_req_cmd_v13 {   *	This is the session time for completing the measurement.   * @tsf_mac_id: report the measurement start time for each ap in terms of the   *	TSF of this mac id. 0xff to disable TSF reporting. - * @ap: per-AP request data, see &struct iwl_tof_range_req_ap_entry_v10. + * @ap: per-AP request data, see &struct iwl_tof_range_req_ap_entry.   */ -struct iwl_tof_range_req_cmd_v14 { +struct iwl_tof_range_req_cmd {  	__le32 initiator_flags;  	u8 request_id;  	u8 num_of_ap; @@ -1384,8 +1393,8 @@ struct iwl_tof_range_req_cmd_v14 {  	u8 macaddr_template[ETH_ALEN];  	__le32 req_timeout_ms;  	__le32 tsf_mac_id; -	struct iwl_tof_range_req_ap_entry_v10 ap[IWL_MVM_TOF_MAX_APS]; -} __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_13 */ +	struct iwl_tof_range_req_ap_entry ap[IWL_TOF_MAX_APS]; +} __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_15 */  /*   * enum iwl_tof_range_request_status - status of the sent request @@ -1605,7 +1614,7 @@ struct iwl_tof_range_rsp_ap_entry_ntfy_v5 {  } __packed; /* LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_5 */  /** - * struct iwl_tof_range_rsp_ap_entry_ntfy_v6 - AP parameters (response) + * struct iwl_tof_range_rsp_ap_entry_ntfy_v7 - AP parameters (response)   * @bssid: BSSID of the AP   * @measure_status: current APs measurement status, one of   *	&enum iwl_tof_entry_status. @@ -1641,7 +1650,7 @@ struct iwl_tof_range_rsp_ap_entry_ntfy_v5 {   * @tx_pn: the last PN used for this responder Tx in case PMF is configured in   *	LE byte order.   */ -struct iwl_tof_range_rsp_ap_entry_ntfy_v6 { +struct iwl_tof_range_rsp_ap_entry_ntfy_v7 {  	u8 bssid[ETH_ALEN];  	u8 measure_status;  	u8 measure_bw; @@ -1668,6 +1677,65 @@ struct iwl_tof_range_rsp_ap_entry_ntfy_v6 {  } __packed; /* LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_6,  	       LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_7 */ +/** + * struct iwl_tof_range_rsp_ap_entry_ntfy - AP parameters (response) + * @bssid: BSSID of the AP + * @measure_status: current APs measurement status, one of + *	&enum iwl_tof_entry_status. + * @measure_bw: Current AP Bandwidth: 0  20MHz, 1  40MHz, 2  80MHz + * @rtt: The Round Trip Time that took for the last measurement for + *	current AP [pSec] + * @rtt_variance: The Variance of the RTT values measured for current AP + * @rtt_spread: The Difference between the maximum and the minimum RTT + *	values measured for current AP in the current session [pSec] + * @rssi: RSSI as uploaded in the Channel Estimation notification + * @rssi_spread: The Difference between the maximum and the minimum RSSI values + *	measured for current AP in the current session + * @last_burst: 1 if no more FTM sessions are scheduled for this responder + * @refusal_period: refusal period in case of + *	@IWL_TOF_ENTRY_RESPONDER_CANNOT_COLABORATE [sec] + * @timestamp: The GP2 Clock [usec] where Channel Estimation notification was + *	uploaded by the LMAC + * @start_tsf: measurement start time in TSF of the mac specified in the range + *	request + * @reserved1: reserved, for backwards compatibility + * @t2t3_initiator: as calculated from the algo in the initiator + * @t1t4_responder: as calculated from the algo in the responder + * @common_calib: Calib val that was used in for this AP measurement + * @specific_calib: val that was used in for this AP measurement + * @papd_calib_output: The result of the tof papd calibration that was injected + *	into the algorithm. + * @rttConfidence: a value between 0 - 31 that represents the rtt accuracy. + * @reserved: for alignment + * @rx_pn: the last PN used for this responder Rx in case PMF is configured in + *	LE byte order. + * @tx_pn: the last PN used for this responder Tx in case PMF is configured in + *	LE byte order. + */ +struct iwl_tof_range_rsp_ap_entry_ntfy { +	u8 bssid[ETH_ALEN]; +	u8 measure_status; +	u8 measure_bw; +	__le32 rtt; +	__le32 rtt_variance; +	__le32 rtt_spread; +	s8 rssi; +	u8 rssi_spread; +	u8 last_burst; +	u8 refusal_period; +	__le32 timestamp; +	__le32 start_tsf; +	__le32 reserved1[2]; +	__le32 t2t3_initiator; +	__le32 t1t4_responder; +	__le16 common_calib; +	__le16 specific_calib; +	__le32 papd_calib_output; +	u8 rttConfidence; +	u8 reserved[3]; +	u8 rx_pn[IEEE80211_CCMP_PN_LEN]; +	u8 tx_pn[IEEE80211_CCMP_PN_LEN]; +} __packed; /* LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_8 */  /**   * enum iwl_tof_response_status - tof response status @@ -1691,7 +1759,7 @@ enum iwl_tof_response_status {   * @request_status: status of current measurement session, one of   *	&enum iwl_tof_response_status.   * @last_in_batch: reprot policy (when not all responses are uploaded at once) - * @num_of_aps: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) + * @num_of_aps: Number of APs to measure (error if > IWL_TOF_MAX_APS)   * @ap: per-AP data   */  struct iwl_tof_range_rsp_ntfy_v5 { @@ -1699,7 +1767,7 @@ struct iwl_tof_range_rsp_ntfy_v5 {  	u8 request_status;  	u8 last_in_batch;  	u8 num_of_aps; -	struct iwl_tof_range_rsp_ap_entry_ntfy_v3 ap[IWL_MVM_TOF_MAX_APS]; +	struct iwl_tof_range_rsp_ap_entry_ntfy_v3 ap[IWL_TOF_MAX_APS];  } __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_5 */  /** @@ -1715,7 +1783,7 @@ struct iwl_tof_range_rsp_ntfy_v6 {  	u8 num_of_aps;  	u8 last_report;  	u8 reserved; -	struct iwl_tof_range_rsp_ap_entry_ntfy_v4 ap[IWL_MVM_TOF_MAX_APS]; +	struct iwl_tof_range_rsp_ap_entry_ntfy_v4 ap[IWL_TOF_MAX_APS];  } __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_6 */  /** @@ -1731,25 +1799,42 @@ struct iwl_tof_range_rsp_ntfy_v7 {  	u8 num_of_aps;  	u8 last_report;  	u8 reserved; -	struct iwl_tof_range_rsp_ap_entry_ntfy_v5 ap[IWL_MVM_TOF_MAX_APS]; +	struct iwl_tof_range_rsp_ap_entry_ntfy_v5 ap[IWL_TOF_MAX_APS];  } __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_7 */  /** - * struct iwl_tof_range_rsp_ntfy_v8 - ranging response notification + * struct iwl_tof_range_rsp_ntfy_v9 - ranging response notification   * @request_id: A Token ID of the corresponding Range request   * @num_of_aps: Number of APs results   * @last_report: 1 if no more FTM sessions are scheduled, 0 otherwise.   * @reserved: reserved   * @ap: per-AP data   */ -struct iwl_tof_range_rsp_ntfy_v8 { +struct iwl_tof_range_rsp_ntfy_v9 {  	u8 request_id;  	u8 num_of_aps;  	u8 last_report;  	u8 reserved; -	struct iwl_tof_range_rsp_ap_entry_ntfy_v6 ap[IWL_MVM_TOF_MAX_APS]; +	struct iwl_tof_range_rsp_ap_entry_ntfy_v7 ap[IWL_TOF_MAX_APS];  } __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_8, -	       LOCATION_RANGE_RSP_NTFY_API_S_VER_9 */ +	     * LOCATION_RANGE_RSP_NTFY_API_S_VER_9 +	     */ + +/** + * struct iwl_tof_range_rsp_ntfy - ranging response notification + * @request_id: A Token ID of the corresponding Range request + * @num_of_aps: Number of APs results + * @last_report: 1 if no more FTM sessions are scheduled, 0 otherwise. + * @reserved: reserved + * @ap: per-AP data + */ +struct iwl_tof_range_rsp_ntfy { +	u8 request_id; +	u8 num_of_aps; +	u8 last_report; +	u8 reserved; +	struct iwl_tof_range_rsp_ap_entry_ntfy ap[IWL_TOF_MAX_APS]; +} __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_10 */  #define IWL_MVM_TOF_MCSI_BUF_SIZE  (245)  /** diff --git a/sys/contrib/dev/iwlwifi/fw/api/mac-cfg.h b/sys/contrib/dev/iwlwifi/fw/api/mac-cfg.h index ca6fa66d1917..b9f559dac39f 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/mac-cfg.h +++ b/sys/contrib/dev/iwlwifi/fw/api/mac-cfg.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2012-2014, 2018-2019, 2021-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2019, 2021-2025 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2016-2017 Intel Deutschland GmbH   */ @@ -42,15 +42,15 @@ enum iwl_mac_conf_subcmd_ids {  	 */  	LINK_CONFIG_CMD = 0x9,  	/** -	 * @STA_CONFIG_CMD: &struct iwl_mvm_sta_cfg_cmd +	 * @STA_CONFIG_CMD: &struct iwl_sta_cfg_cmd  	 */  	STA_CONFIG_CMD = 0xA,  	/** -	 * @AUX_STA_CMD: &struct iwl_mvm_aux_sta_cmd +	 * @AUX_STA_CMD: &struct iwl_aux_sta_cmd  	 */  	AUX_STA_CMD = 0xB,  	/** -	 * @STA_REMOVE_CMD: &struct iwl_mvm_remove_sta_cmd +	 * @STA_REMOVE_CMD: &struct iwl_remove_sta_cmd  	 */  	STA_REMOVE_CMD = 0xC,  	/** @@ -62,11 +62,23 @@ enum iwl_mac_conf_subcmd_ids {  	 */  	ROC_CMD = 0xE,  	/** +	 * @TWT_OPERATION_CMD: &struct iwl_twt_operation_cmd +	 */ +	TWT_OPERATION_CMD = 0x10, +	/** +	 * @MISSED_BEACONS_NOTIF: &struct iwl_missed_beacons_notif +	 */ +	MISSED_BEACONS_NOTIF = 0xF6, +	/** +	 * @EMLSR_TRANS_FAIL_NOTIF: &struct iwl_esr_trans_fail_notif +	 */ +	EMLSR_TRANS_FAIL_NOTIF = 0xF7, +	/**  	 * @ROC_NOTIF: &struct iwl_roc_notif  	 */  	ROC_NOTIF = 0xF8,  	/** -	 * @SESSION_PROTECTION_NOTIF: &struct iwl_mvm_session_prot_notif +	 * @SESSION_PROTECTION_NOTIF: &struct iwl_session_prot_notif  	 */  	SESSION_PROTECTION_NOTIF = 0xFB, @@ -299,8 +311,41 @@ enum iwl_mac_config_filter_flags {  }; /* MAC_FILTER_FLAGS_MASK_E_VER_1 */  /** + * struct iwl_mac_wifi_gen_support_v2 - parameters of iwl_mac_config_cmd + *	with support up to eht as in version 2 of the command + * + * @he_support: does this MAC support HE + * @he_ap_support: HE AP enabled, "pseudo HE", no trigger frame handling + * @eht_support: does this MAC support EHT. Requires he_support + */ +struct iwl_mac_wifi_gen_support_v2 { +	__le16 he_support; +	__le16 he_ap_support; +	__le32 eht_support; +} __packed; + +/** + * struct iwl_mac_wifi_gen_support - parameters of iwl_mac_config_cmd + *	with support up to uhr as in version 3 of the command + * ( MAC_CONTEXT_CONFIG_CMD = 0x8 ) + * + * @he_support: does this MAC support HE + * @he_ap_support: HE AP enabled, "pseudo HE", no trigger frame handling + * @eht_support: does this MAC support EHT. Requires he_support + * @uhr_support: does this MAC support UHR. Requires eht_support + * @reserved: reserved for alignment and to match version 2's size + */ +struct iwl_mac_wifi_gen_support { +	u8 he_support; +	u8 he_ap_support; +	u8 eht_support; +	u8 uhr_support; +	__le32 reserved; +} __packed; + +/**   * struct iwl_mac_config_cmd - command structure to configure MAC contexts in - *	MLD API + *	MLD API for versions 2 and 3   * ( MAC_CONTEXT_CONFIG_CMD = 0x8 )   *   * @id_and_color: ID and color of the MAC @@ -309,9 +354,8 @@ enum iwl_mac_config_filter_flags {   * @local_mld_addr: mld address   * @reserved_for_local_mld_addr: reserved   * @filter_flags: combination of &enum iwl_mac_config_filter_flags - * @he_support: does this MAC support HE - * @he_ap_support: HE AP enabled, "pseudo HE", no trigger frame handling - * @eht_support: does this MAC support EHT. Requires he_support + * @wifi_gen_v2: he/eht parameters as in cmd version 2 + * @wifi_gen: he/eht/uhr parameters as in cmd version 3   * @nic_not_ack_enabled: mark that the NIC doesn't support receiving   *	ACK-enabled AGG, (i.e. both BACK and non-BACK frames in single AGG).   *	If the NIC is not ACK_ENABLED it may use the EOF-bit in first non-0 @@ -320,7 +364,6 @@ enum iwl_mac_config_filter_flags {   * @p2p_dev: mac data for p2p device   */  struct iwl_mac_config_cmd { -	/* COMMON_INDEX_HDR_API_S_VER_1 */  	__le32 id_and_color;  	__le32 action;  	/* MAC_CONTEXT_TYPE_API_E */ @@ -328,16 +371,17 @@ struct iwl_mac_config_cmd {  	u8 local_mld_addr[6];  	__le16 reserved_for_local_mld_addr;  	__le32 filter_flags; -	__le16 he_support; -	__le16 he_ap_support; -	__le32 eht_support; +	union { +		struct iwl_mac_wifi_gen_support_v2 wifi_gen_v2; +		struct iwl_mac_wifi_gen_support wifi_gen; +	};  	__le32 nic_not_ack_enabled;  	/* MAC_CONTEXT_CONFIG_SPECIFIC_DATA_API_U_VER_2 */  	union {  		struct iwl_mac_client_data client;  		struct iwl_mac_p2p_dev_data p2p_dev;  	}; -} __packed; /* MAC_CONTEXT_CONFIG_CMD_API_S_VER_2 */ +} __packed; /* MAC_CONTEXT_CONFIG_CMD_API_S_VER_2_VER_3 */  /**   * enum iwl_link_ctx_modify_flags - indicate to the fw what fields are being @@ -374,6 +418,8 @@ struct iwl_mac_config_cmd {   * @LINK_CONTEXT_MODIFY_EHT_PARAMS: covers iwl_link_ctx_cfg_cmd::puncture_mask.   *	This flag can be set only if the MAC that this link relates to has   *	eht_support set to true. No longer used since _VER_3 of this command. + * @LINK_CONTEXT_MODIFY_BANDWIDTH: Covers iwl_link_ctx_cfg_cmd::modify_bandwidth. + *	Request RX OMI to the AP to modify bandwidth of this link.   * @LINK_CONTEXT_MODIFY_ALL: set all above flags   */  enum iwl_link_ctx_modify_flags { @@ -385,6 +431,7 @@ enum iwl_link_ctx_modify_flags {  	LINK_CONTEXT_MODIFY_HE_PARAMS		= BIT(5),  	LINK_CONTEXT_MODIFY_BSS_COLOR_DISABLE	= BIT(6),  	LINK_CONTEXT_MODIFY_EHT_PARAMS		= BIT(7), +	LINK_CONTEXT_MODIFY_BANDWIDTH		= BIT(8),  	LINK_CONTEXT_MODIFY_ALL			= 0xff,  }; /* LINK_CONTEXT_MODIFY_MASK_E_VER_1 */ @@ -426,6 +473,40 @@ enum iwl_link_ctx_flags {  }; /* LINK_CONTEXT_FLAG_E_VER_1 */  /** + * enum iwl_link_modify_bandwidth - link modify (RX OMI) bandwidth + * @IWL_LINK_MODIFY_BW_20: request 20 MHz + * @IWL_LINK_MODIFY_BW_40: request 40 MHz + * @IWL_LINK_MODIFY_BW_80: request 80 MHz + * @IWL_LINK_MODIFY_BW_160: request 160 MHz + * @IWL_LINK_MODIFY_BW_320: request 320 MHz + */ +enum iwl_link_modify_bandwidth { +	IWL_LINK_MODIFY_BW_20, +	IWL_LINK_MODIFY_BW_40, +	IWL_LINK_MODIFY_BW_80, +	IWL_LINK_MODIFY_BW_160, +	IWL_LINK_MODIFY_BW_320, +}; + +/** + * struct iwl_npca_params - NPCA parameters (non-primary channel access) + * + * @switch_delay: after switch, delay TX according to destination AP + * @switch_back_delay: switch back to control channel before OBSS frame end + * @min_dur_threshold: minimum PPDU time to switch to the non-primary + *	NPCA channel + * @flags: NPCA flags - bit 0: puncturing allowed, bit 1: new TX allowed + * @reserved: reserved for alignment purposes + */ +struct iwl_npca_params { +	u8 switch_delay; +	u8 switch_back_delay; +	__le16 min_dur_threshold; +	__le16 flags; +	__le16 reserved; +} __packed; /* NPCA_PARAM_API_S_VER_1 */ + +/**   * struct iwl_link_config_cmd - command structure to configure the LINK context   *	in MLD API   * ( LINK_CONFIG_CMD =0x9 ) @@ -446,6 +527,11 @@ enum iwl_link_ctx_flags {   * @listen_lmac: indicates whether the link should be allocated on the Listen   *	Lmac or on the Main Lmac. Cannot be changed on an active Link.   *	Relevant only for eSR. + * @block_tx: tell the firmware that this link can't Tx. This should be used + *	only when a link is de-activated because of CSA with mode = 1. + *	Available since version 5. + * @modify_bandwidth: bandwidth request value for RX OMI (see also + *	%LINK_CONTEXT_MODIFY_BANDWIDTH), from &enum iwl_link_modify_bandwidth.   * @reserved1: in version 2, listen_lmac became reserved   * @cck_rates: basic rates available for CCK   * @ofdm_rates: basic rates available for OFDM @@ -472,9 +558,13 @@ enum iwl_link_ctx_flags {   * @bssid_index: index of the associated VAP   * @bss_color: 11ax AP ID that is used in the HE SIG-A to mark inter BSS frame   * @spec_link_id: link_id as the AP knows it - * @reserved2: alignment + * @ul_mu_data_disable: OM Control UL MU Data Disable RX Support (bit 44) in + *	HE MAC Capabilities information field as defined in figure 9-897 in + *	IEEE802.11REVme-D5.0   * @ibss_bssid_addr: bssid for ibss   * @reserved_for_ibss_bssid_addr: reserved + * @npca_params: NPCA parameters + * @prio_edca_params: priority EDCA parameters for enhanced QoS   * @reserved3: reserved for future use   */  struct iwl_link_config_cmd { @@ -487,8 +577,12 @@ struct iwl_link_config_cmd {  	__le32 modify_mask;  	__le32 active;  	union { -		__le32 listen_lmac; -		__le32 reserved1; +		__le32 listen_lmac; /* only _VER_1 */ +		struct { +			u8 block_tx; /* since _VER_5 */ +			u8 modify_bandwidth; /* since _VER_6 */ +			u8 reserved1[2]; +		};  	};  	__le32 cck_rates;  	__le32 ofdm_rates; @@ -508,24 +602,26 @@ struct iwl_link_config_cmd {  	__le16 puncture_mask; /* removed in _VER_3 */  	__le16 frame_time_rts_th;  	__le32 flags; -	__le32 flags_mask; +	__le32 flags_mask; /* removed in _VER_6 */  	/* The below fields are for multi-bssid */  	u8 ref_bssid_addr[6];  	__le16 reserved_for_ref_bssid_addr;  	u8 bssid_index;  	u8 bss_color;  	u8 spec_link_id; -	u8 reserved2; +	u8 ul_mu_data_disable;  	u8 ibss_bssid_addr[6];  	__le16 reserved_for_ibss_bssid_addr; -	__le32 reserved3[8]; -} __packed; /* LINK_CONTEXT_CONFIG_CMD_API_S_VER_1, _VER_2, _VER_3 */ +	struct iwl_npca_params npca_params; /* since _VER_7 */ +	struct iwl_ac_qos prio_edca_params; /* since _VER_7 */ +	__le32 reserved3[4]; +} __packed; /* LINK_CONTEXT_CONFIG_CMD_API_S_VER_1, _VER_2, _VER_3, _VER_4, _VER_5, _VER_6, _VER_7 */  /* Currently FW supports link ids in the range 0-3 and can have   * at most two active links for each vif.   */ -#define IWL_MVM_FW_MAX_ACTIVE_LINKS_NUM 2 -#define IWL_MVM_FW_MAX_LINK_ID 3 +#define IWL_FW_MAX_ACTIVE_LINKS_NUM 2 +#define IWL_FW_MAX_LINK_ID 3  /**   * enum iwl_fw_sta_type - FW station types @@ -547,7 +643,7 @@ enum iwl_fw_sta_type {  }; /* STATION_TYPE_E_VER_1 */  /** - * struct iwl_mvm_sta_cfg_cmd - cmd structure to add a peer sta to the uCode's + * struct iwl_sta_cfg_cmd_v1 - cmd structure to add a peer sta to the uCode's   *	station table   * ( STA_CONFIG_CMD = 0xA )   * @@ -579,7 +675,7 @@ enum iwl_fw_sta_type {   *	capa   * @htc_flags: which features are supported in HTC   */ -struct iwl_mvm_sta_cfg_cmd { +struct iwl_sta_cfg_cmd_v1 {  	__le32 sta_id;  	__le32 link_id;  	u8 peer_mld_address[ETH_ALEN]; @@ -603,7 +699,78 @@ struct iwl_mvm_sta_cfg_cmd {  } __packed; /* STA_CMD_API_S_VER_1 */  /** - * struct iwl_mvm_aux_sta_cmd - command for AUX STA configuration + * struct iwl_sta_cfg_cmd - cmd structure to add a peer sta to the uCode's + *	station table + * ( STA_CONFIG_CMD = 0xA ) + * + * @sta_id: index of station in uCode's station table + * @link_id: the id of the link that is used to communicate with this sta + * @peer_mld_address: the peers mld address + * @reserved_for_peer_mld_address: reserved + * @peer_link_address: the address of the link that is used to communicate + *	with this sta + * @reserved_for_peer_link_address: reserved + * @station_type: type of this station. See &enum iwl_fw_sta_type + * @assoc_id: for GO only + * @beamform_flags: beam forming controls + * @mfp: indicates whether the STA uses management frame protection or not. + * @mimo: indicates whether the sta uses mimo or not + * @mimo_protection: indicates whether the sta uses mimo protection or not + * @ack_enabled: indicates that the AP supports receiving ACK- + *	enabled AGG, i.e. both BACK and non-BACK frames in a single AGG + * @trig_rnd_alloc: indicates that trigger based random allocation + *	is enabled according to UORA element existence + * @tx_ampdu_spacing: minimum A-MPDU spacing: + *	4 - 2us density, 5 - 4us density, 6 - 8us density, 7 - 16us density + * @tx_ampdu_max_size: maximum A-MPDU length: 0 - 8K, 1 - 16K, 2 - 32K, + *	3 - 64K, 4 - 128K, 5 - 256K, 6 - 512K, 7 - 1024K. + * @sp_length: the size of the SP in actual number of frames + * @uapsd_acs:  4 LS bits are trigger enabled ACs, 4 MS bits are the deliver + *	enabled ACs. + * @pkt_ext: optional, exists according to PPE-present bit in the HE/EHT-PHY + *	capa + * @htc_flags: which features are supported in HTC + * @use_ldpc_x2_cw: Indicates whether to use LDPC with double CW + * @use_icf: Indicates whether to use ICF instead of RTS + * @dps_pad_time: DPS (Dynamic Power Save) padding delay resolution to ensure + *	proper timing alignment + * @dps_trans_delay: DPS minimal time that takes the peer to return to low power + * @mic_prep_pad_delay: MIC prep time padding + * @mic_compute_pad_delay: MIC compute time padding + * @reserved: Reserved for alignment + */ +struct iwl_sta_cfg_cmd { +	__le32 sta_id; +	__le32 link_id; +	u8 peer_mld_address[ETH_ALEN]; +	__le16 reserved_for_peer_mld_address; +	u8 peer_link_address[ETH_ALEN]; +	__le16 reserved_for_peer_link_address; +	__le32 station_type; +	__le32 assoc_id; +	__le32 beamform_flags; +	__le32 mfp; +	__le32 mimo; +	__le32 mimo_protection; +	__le32 ack_enabled; +	__le32 trig_rnd_alloc; +	__le32 tx_ampdu_spacing; +	__le32 tx_ampdu_max_size; +	__le32 sp_length; +	__le32 uapsd_acs; +	struct iwl_he_pkt_ext_v2 pkt_ext; +	__le32 htc_flags; +	u8 use_ldpc_x2_cw; +	u8 use_icf; +	u8 dps_pad_time; +	u8 dps_trans_delay; +	u8 mic_prep_pad_delay; +	u8 mic_compute_pad_delay; +	u8 reserved[2]; +} __packed; /* STA_CMD_API_S_VER_2 */ + +/** + * struct iwl_aux_sta_cmd - command for AUX STA configuration   * ( AUX_STA_CMD = 0xB )   *   * @sta_id: index of aux sta to configure @@ -611,7 +778,7 @@ struct iwl_mvm_sta_cfg_cmd {   * @mac_addr: mac addr of the auxilary sta   * @reserved_for_mac_addr: reserved   */ -struct iwl_mvm_aux_sta_cmd { +struct iwl_aux_sta_cmd {  	__le32 sta_id;  	__le32 lmac_id;  	u8 mac_addr[ETH_ALEN]; @@ -620,13 +787,13 @@ struct iwl_mvm_aux_sta_cmd {  } __packed; /* AUX_STA_CMD_API_S_VER_1 */  /** - * struct iwl_mvm_remove_sta_cmd - a cmd structure to remove a sta added by + * struct iwl_remove_sta_cmd - a cmd structure to remove a sta added by   *	STA_CONFIG_CMD or AUX_STA_CONFIG_CMD   * ( STA_REMOVE_CMD = 0xC )   *   * @sta_id: index of station to remove   */ -struct iwl_mvm_remove_sta_cmd { +struct iwl_remove_sta_cmd {  	__le32 sta_id;  } __packed; /* REMOVE_STA_API_S_VER_1 */ @@ -644,9 +811,9 @@ struct iwl_mvm_sta_disable_tx_cmd {  /**   * enum iwl_mvm_fw_esr_recommendation - FW recommendation code - * @ESR_RECOMMEND_LEAVE: recommendation to leave esr - * @ESR_FORCE_LEAVE: force exiting esr - * @ESR_RECOMMEND_ENTER: recommendation to enter esr + * @ESR_RECOMMEND_LEAVE: recommendation to leave EMLSR + * @ESR_FORCE_LEAVE: force exiting EMLSR + * @ESR_RECOMMEND_ENTER: recommendation to enter EMLSR   */  enum iwl_mvm_fw_esr_recommendation {  	ESR_RECOMMEND_LEAVE, @@ -655,12 +822,169 @@ enum iwl_mvm_fw_esr_recommendation {  }; /* ESR_MODE_RECOMMENDATION_CODE_API_E_VER_1 */  /** - * struct iwl_mvm_esr_mode_notif - FWs recommendation/force for esr mode + * struct iwl_esr_mode_notif_v1 - FW recommendation/force for EMLSR mode   * - * @action: the action to apply on esr state. See &iwl_mvm_fw_esr_recommendation + * @action: the action to apply on EMLSR state. + *	See &iwl_mvm_fw_esr_recommendation   */ -struct iwl_mvm_esr_mode_notif { +struct iwl_esr_mode_notif_v1 {  	__le32 action;  } __packed; /* ESR_MODE_RECOMMENDATION_NTFY_API_S_VER_1 */ +/** + * enum iwl_esr_leave_reason - reasons for leaving EMLSR mode + * + * @ESR_LEAVE_REASON_OMI_MU_UL_DISALLOWED: OMI MU UL disallowed + * @ESR_LEAVE_REASON_NO_TRIG_FOR_ESR_STA: No trigger for EMLSR station + * @ESR_LEAVE_REASON_NO_ESR_STA_IN_MU_DL: No EMLSR station in MU DL + * @ESR_LEAVE_REASON_BAD_ACTIV_FRAME_TH: Bad activation frame threshold + * @ESR_LEAVE_REASON_RTS_IN_DUAL_LISTEN: RTS in dual listen + */ +enum iwl_esr_leave_reason { +	ESR_LEAVE_REASON_OMI_MU_UL_DISALLOWED	= BIT(0), +	ESR_LEAVE_REASON_NO_TRIG_FOR_ESR_STA	= BIT(1), +	ESR_LEAVE_REASON_NO_ESR_STA_IN_MU_DL	= BIT(2), +	ESR_LEAVE_REASON_BAD_ACTIV_FRAME_TH	= BIT(3), +	ESR_LEAVE_REASON_RTS_IN_DUAL_LISTEN	= BIT(4), +}; + +/** + * struct iwl_esr_mode_notif - FW recommendation/force for EMLSR mode + * + * @action: the action to apply on EMLSR state. + *	See &iwl_mvm_fw_esr_recommendation + * @leave_reason_mask: mask for various reasons to leave EMLSR mode. + *	See &iwl_esr_leave_reason + */ +struct iwl_esr_mode_notif { +	__le32 action; +	__le32 leave_reason_mask; +} __packed; /* ESR_MODE_RECOMMENDATION_NTFY_API_S_VER_2 */ + +/** + * struct iwl_missed_beacons_notif - sent when by the firmware upon beacon loss + *  ( MISSED_BEACONS_NOTIF = 0xF6 ) + * @link_id: fw link ID + * @consec_missed_beacons_since_last_rx: number of consecutive missed + *	beacons since last RX. + * @consec_missed_beacons: number of consecutive missed beacons + * @other_link_id: used in EMLSR only. The fw link ID for + *	&consec_missed_beacons_other_link. IWL_MVM_FW_LINK_ID_INVALID (0xff) if + *	invalid. + * @consec_missed_beacons_other_link: number of consecutive missed beacons on + *	&other_link_id. + */ +struct iwl_missed_beacons_notif { +	__le32 link_id; +	__le32 consec_missed_beacons_since_last_rx; +	__le32 consec_missed_beacons; +	__le32 other_link_id; +	__le32 consec_missed_beacons_other_link; +} __packed; /* MISSED_BEACON_NTFY_API_S_VER_5 */ + +/* + * enum iwl_esr_trans_fail_code: to be used to parse the notif below + * + * @ESR_TRANS_FAILED_TX_STATUS_ERROR: failed to TX EML OMN frame + * @ESR_TRANSITION_FAILED_TX_TIMEOUT: timeout on the EML OMN frame + * @ESR_TRANSITION_FAILED_BEACONS_NOT_HEARD: can't get a beacon on the new link + */ +enum iwl_esr_trans_fail_code { +	ESR_TRANS_FAILED_TX_STATUS_ERROR, +	ESR_TRANSITION_FAILED_TX_TIMEOUT, +	ESR_TRANSITION_FAILED_BEACONS_NOT_HEARD, +}; + +/** + * struct iwl_esr_trans_fail_notif - FW reports a failure in EMLSR transition + * + * @link_id: the link_id that still works after the failure + * @activation: true if the link was activated, false otherwise + * @err_code: see &enum iwl_esr_trans_fail_code + */ +struct iwl_esr_trans_fail_notif { +	__le32 link_id; +	__le32 activation; +	__le32 err_code; +} __packed; /* ESR_TRANSITION_FAILED_NTFY_API_S_VER_1 */ + +/* + * enum iwl_twt_operation_type: TWT operation in a TWT action frame + * + * @TWT_OPERATION_REQUEST: TWT Request + * @TWT_OPERATION_SUGGEST: TWT Suggest + * @TWT_OPERATION_DEMAND: TWT Demand + * @TWT_OPERATION_GROUPING: TWT Grouping + * @TWT_OPERATION_ACCEPT: TWT Accept + * @TWT_OPERATION_ALTERNATE: TWT Alternate + * @TWT_OPERATION_DICTATE: TWT Dictate + * @TWT_OPERATION_REJECT: TWT Reject + * @TWT_OPERATION_TEARDOWN: TWT Teardown + * @TWT_OPERATION_UNAVAILABILITY: TWT Unavailability + */ +enum iwl_twt_operation_type { +	TWT_OPERATION_REQUEST, +	TWT_OPERATION_SUGGEST, +	TWT_OPERATION_DEMAND, +	TWT_OPERATION_GROUPING, +	TWT_OPERATION_ACCEPT, +	TWT_OPERATION_ALTERNATE, +	TWT_OPERATION_DICTATE, +	TWT_OPERATION_REJECT, +	TWT_OPERATION_TEARDOWN, +	TWT_OPERATION_UNAVAILABILITY, +	TWT_OPERATION_MAX, +}; /* TWT_OPERATION_TYPE_E_VER_1 */ + +/** + * struct iwl_twt_operation_cmd - initiate a TWT session from driver + * + * @link_id: FW link id to initiate the TWT + * @twt_operation: &enum iwl_twt_operation_type + * @target_wake_time: TSF time to start the TWT + * @interval_exponent: the exponent for the interval + * @interval_mantissa: the mantissa for the interval + * @minimum_wake_duration: the minimum duration for the wake period + * @trigger: is the TWT triggered or not + * @flow_type: is the TWT announced (0) or not (1) + * @flow_id: the TWT flow identifier 0 - 7 + * @twt_protection: is the TWT protected + * @ndp_paging_indicator: is ndp paging indicator set + * @responder_pm_mode: is responder pm mode set + * @negotiation_type: if the responder wants to doze outside the TWT SP + * @twt_request: 1 for TWT request (STA), 0 for TWT response (AP) + * @implicit: is TWT implicit + * @twt_group_assignment: the TWT group assignment + * @twt_channel: the TWT channel + * @restricted_info_present: is this a restricted TWT + * @dl_bitmap_valid: is DL (download) bitmap valid (restricted TWT) + * @ul_bitmap_valid: is UL (upload) bitmap valid (restricted TWT) + * @dl_tid_bitmap: DL TID bitmap (restricted TWT) + * @ul_tid_bitmap: UL TID bitmap (restricted TWT) + */ +struct iwl_twt_operation_cmd { +	__le32 link_id; +	__le32 twt_operation; +	__le64 target_wake_time; +	__le32 interval_exponent; +	__le32 interval_mantissa; +	__le32 minimum_wake_duration; +	u8 trigger; +	u8 flow_type; +	u8 flow_id; +	u8 twt_protection; +	u8 ndp_paging_indicator; +	u8 responder_pm_mode; +	u8 negotiation_type; +	u8 twt_request; +	u8 implicit; +	u8 twt_group_assignment; +	u8 twt_channel; +	u8 restricted_info_present; +	u8 dl_bitmap_valid; +	u8 ul_bitmap_valid; +	u8 dl_tid_bitmap; +	u8 ul_tid_bitmap; +} __packed; /* TWT_OPERATION_API_S_VER_1 */ +  #endif /* __iwl_fw_api_mac_cfg_h__ */ diff --git a/sys/contrib/dev/iwlwifi/fw/api/mac.h b/sys/contrib/dev/iwlwifi/fw/api/mac.h index bcbbf8c4a297..2a174c00b712 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/mac.h +++ b/sys/contrib/dev/iwlwifi/fw/api/mac.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2012-2014, 2018-2022, 2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2022, 2024-2025 Intel Corporation   * Copyright (C) 2017 Intel Deutschland GmbH   */  #ifndef __iwl_fw_api_mac_h__ @@ -16,8 +16,8 @@  #define NUM_MAC_INDEX		(NUM_MAC_INDEX_DRIVER + 1)  #define NUM_MAC_INDEX_CDB	(NUM_MAC_INDEX_DRIVER + 2) -#define IWL_MVM_STATION_COUNT_MAX	16 -#define IWL_MVM_INVALID_STA		0xFF +#define IWL_STATION_COUNT_MAX	16 +#define IWL_INVALID_STA		0xFF  enum iwl_ac {  	AC_BK, @@ -287,9 +287,9 @@ struct iwl_ac_qos {  	__le16 cw_min;  	__le16 cw_max;  	u8 aifsn; -	u8 fifos_mask; +	u8 fifos_mask; /* not in use since _VER_3 */  	__le16 edca_txop; -} __packed; /* AC_QOS_API_S_VER_2 */ +} __packed; /* AC_QOS_API_S_VER_2, _VER_3 */  /**   * struct iwl_mac_ctx_cmd - command structure to configure MAC contexts @@ -378,7 +378,7 @@ struct iwl_missed_beacons_notif_ver_3 {  } __packed; /* MISSED_BEACON_NTFY_API_S_VER_3 */  /** - * struct iwl_missed_beacons_notif - information on missed beacons + * struct iwl_missed_beacons_notif_v4 - information on missed beacons   * ( MISSED_BEACONS_NOTIFICATION = 0xa2 )   * @link_id: fw link ID   * @consec_missed_beacons_since_last_rx: number of consecutive missed @@ -387,7 +387,7 @@ struct iwl_missed_beacons_notif_ver_3 {   * @num_expected_beacons: number of expected beacons   * @num_recvd_beacons: number of received beacons   */ -struct iwl_missed_beacons_notif { +struct iwl_missed_beacons_notif_v4 {  	__le32 link_id;  	__le32 consec_missed_beacons_since_last_rx;  	__le32 consec_missed_beacons; diff --git a/sys/contrib/dev/iwlwifi/fw/api/nvm-reg.h b/sys/contrib/dev/iwlwifi/fw/api/nvm-reg.h index d424d0126367..e90f3187e55c 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/nvm-reg.h +++ b/sys/contrib/dev/iwlwifi/fw/api/nvm-reg.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2016-2017 Intel Deutschland GmbH   */ @@ -464,21 +464,30 @@ struct iwl_tas_config_cmd_v3 {  } __packed; /* TAS_CONFIG_CMD_API_S_VER_3 */  /** + * enum iwl_tas_uhb_allowed_flags - per country TAS UHB allowed flags. + * @TAS_UHB_ALLOWED_CANADA: TAS UHB is allowed in Canada. This flag is valid + *	only when fw has %IWL_UCODE_TLV_CAPA_UHB_CANADA_TAS_SUPPORT capability. + */ +enum iwl_tas_uhb_allowed_flags { +	TAS_UHB_ALLOWED_CANADA	= BIT(0), +}; + +/**   * struct iwl_tas_config_cmd_v4 - configures the TAS   * @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   * @usa_tas_uhb_allowed: if set, allow TAS UHB in the USA - * @reserved: reserved -*/ + * @uhb_allowed_flags: see &enum iwl_tas_uhb_allowed_flags. + */  struct iwl_tas_config_cmd_v4 {  	u8 override_tas_iec;  	u8 enable_tas_iec;  	u8 usa_tas_uhb_allowed; -	u8 reserved; +	u8 uhb_allowed_flags;  } __packed; /* TAS_CONFIG_CMD_API_S_VER_4 */ -struct iwl_tas_config_cmd { +struct iwl_tas_config_cmd_v2_v4 {  	struct iwl_tas_config_cmd_common common;  	union {  		struct iwl_tas_config_cmd_v3 v3; @@ -487,6 +496,46 @@ struct iwl_tas_config_cmd {  };  /** + * enum bios_source - source of bios data + * @BIOS_SOURCE_NONE: BIOS source is not defined + * @BIOS_SOURCE_ACPI: BIOS source is ACPI + * @BIOS_SOURCE_UEFI: BIOS source is UEFI + */ +enum bios_source { +	BIOS_SOURCE_NONE, +	BIOS_SOURCE_ACPI, +	BIOS_SOURCE_UEFI, +}; + +/** + * struct bios_value_u32 - BIOS configuration. + * @table_source: see &enum bios_source + * @table_revision: table revision. + * @reserved: reserved + * @value: value in bios. + */ +struct bios_value_u32 { +	u8 table_source; +	u8 table_revision; +	u8 reserved[2]; +	__le32 value; +} __packed; /* BIOS_TABLE_SOURCE_U32_S_VER_1 */ + +/** + * struct iwl_tas_config_cmd - 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 + * @reserved: reserved + * @tas_config_info: see @struct bios_value_u32 + */ +struct iwl_tas_config_cmd { +	__le16 block_list_size; +	__le16 block_list_array[IWL_WTAS_BLACK_LIST_MAX]; +	u8 reserved[2]; +	struct bios_value_u32 tas_config_info; +} __packed; /* TAS_CONFIG_CMD_API_S_VER_5 */ + +/**   * enum iwl_lari_config_masks - 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 @@ -705,7 +754,7 @@ struct iwl_lari_config_change_cmd_v10 {   *	according to the BIOS definitions.   *	For LARI cmd version 11 - bits 0:4 are supported.   *	For LARI cmd version 12 - bits 0:6 are supported and bits 7:31 are - *	reserved. No need to mask out the reserved bits. + *	reserved.   * @force_disable_channels_bitmap: Bitmap of disabled bands/channels.   *	Each bit represents a set of channels in a specific band that should be   *	disabled @@ -738,6 +787,7 @@ struct iwl_lari_config_change_cmd {  /* Activate UNII-1 (5.2GHz) for World Wide */  #define ACTIVATE_5G2_IN_WW_MASK			BIT(4)  #define CHAN_STATE_ACTIVE_BITMAP_CMD_V11	0x1F +#define CHAN_STATE_ACTIVE_BITMAP_CMD_V12	0x7F  /**   * struct iwl_pnvm_init_complete_ntfy - PNVM initialization complete diff --git a/sys/contrib/dev/iwlwifi/fw/api/offload.h b/sys/contrib/dev/iwlwifi/fw/api/offload.h index 6a7bbfd6b2b7..2a1c2b0f19e4 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/offload.h +++ b/sys/contrib/dev/iwlwifi/fw/api/offload.h @@ -3,7 +3,7 @@   * Copyright (C) 2012-2014 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2016-2017 Intel Deutschland GmbH - * Copyright (C) 2021-2024 Intel Corporation + * Copyright (C) 2021-2025 Intel Corporation   */  #ifndef __iwl_fw_api_offload_h__  #define __iwl_fw_api_offload_h__ @@ -19,7 +19,7 @@ enum iwl_prot_offload_subcmd_ids {  	/**  	 * @WOWLAN_INFO_NOTIFICATION: Notification in -	 * &struct iwl_wowlan_info_notif_v1, &struct iwl_wowlan_info_notif_v2, +	 * &struct iwl_wowlan_info_notif_v1, iwl_wowlan_info_notif_v3,  	 * or &struct iwl_wowlan_info_notif  	 */  	WOWLAN_INFO_NOTIFICATION = 0xFD, @@ -31,7 +31,7 @@ enum iwl_prot_offload_subcmd_ids {  	/**  	 * @STORED_BEACON_NTF: &struct iwl_stored_beacon_notif_v2 or -	 *	&struct iwl_stored_beacon_notif_v3 +	 *	&struct iwl_stored_beacon_notif  	 */  	STORED_BEACON_NTF = 0xFF,  }; @@ -71,18 +71,18 @@ struct iwl_stored_beacon_notif_v2 {  } __packed; /* WOWLAN_STROED_BEACON_INFO_S_VER_2 */  /** - * struct iwl_stored_beacon_notif_v3 - Stored beacon notification + * struct iwl_stored_beacon_notif - Stored beacon notification   *   * @common: fields common for all versions   * @sta_id: station for which the beacon was received   * @reserved: reserved for alignment   * @data: beacon data, length in @byte_count   */ -struct iwl_stored_beacon_notif_v3 { +struct iwl_stored_beacon_notif {  	struct iwl_stored_beacon_notif_common common;  	u8 sta_id;  	u8 reserved[3];  	u8 data[MAX_STORED_BEACON_SIZE]; -} __packed; /* WOWLAN_STROED_BEACON_INFO_S_VER_3 */ +} __packed; /* WOWLAN_STROED_BEACON_INFO_S_VER_3, _VER_4 */  #endif /* __iwl_fw_api_offload_h__ */ diff --git a/sys/contrib/dev/iwlwifi/fw/api/phy-ctxt.h b/sys/contrib/dev/iwlwifi/fw/api/phy-ctxt.h index 4d8a12799c4d..4594a7c94bd6 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/phy-ctxt.h +++ b/sys/contrib/dev/iwlwifi/fw/api/phy-ctxt.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2012-2014, 2018, 2020-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018, 2020-2025 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2016-2017 Intel Deutschland GmbH   */ @@ -146,6 +146,7 @@ struct iwl_phy_context_cmd_v1 {   * @sbb_ctrl_channel_loc: location of the control channel   * @puncture_mask: bitmap of punctured subchannels   * @dsp_cfg_flags: set to 0 + * @secondary_ctrl_chnl_loc: location of secondary control channel   * @reserved: reserved to align to 64 bit   */  struct iwl_phy_context_cmd { @@ -164,11 +165,13 @@ struct iwl_phy_context_cmd {  		};  	};  	__le32 dsp_cfg_flags; -	__le32 reserved; +	u8 secondary_ctrl_chnl_loc; +	u8 reserved[3];  } __packed; /* PHY_CONTEXT_CMD_API_VER_3,  	     * PHY_CONTEXT_CMD_API_VER_4,  	     * PHY_CONTEXT_CMD_API_VER_5, -	     * PHY_CONTEXT_CMD_API_VER_6 +	     * PHY_CONTEXT_CMD_API_VER_6, +	     * PHY_CONTEXT_CMD_API_S_VER_7  	     */  #endif /* __iwl_fw_api_phy_ctxt_h__ */ diff --git a/sys/contrib/dev/iwlwifi/fw/api/phy.h b/sys/contrib/dev/iwlwifi/fw/api/phy.h index c73d4d597857..4c5221debbcb 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/phy.h +++ b/sys/contrib/dev/iwlwifi/fw/api/phy.h @@ -1,11 +1,16 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2012-2014, 2019-2022, 2024 Intel Corporation + * Copyright (C) 2012-2014, 2019-2022, 2024-2025 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2016-2017 Intel Deutschland GmbH   */  #ifndef __iwl_fw_api_phy_h__  #define __iwl_fw_api_phy_h__ +#include <linux/types.h> +#include <linux/bits.h> +#if defined(__FreeBSD__) +#include <linux/bitops.h> +#endif  /**   * enum iwl_phy_ops_subcmd_ids - PHY group commands @@ -19,7 +24,7 @@ enum iwl_phy_ops_subcmd_ids {  	CMD_DTS_MEASUREMENT_TRIGGER_WIDE = 0x0,  	/** -	 * @CTDP_CONFIG_CMD: &struct iwl_mvm_ctdp_cmd +	 * @CTDP_CONFIG_CMD: &struct iwl_ctdp_cmd  	 */  	CTDP_CONFIG_CMD = 0x03, @@ -55,7 +60,7 @@ enum iwl_phy_ops_subcmd_ids {  	/**  	 * @DTS_MEASUREMENT_NOTIF_WIDE:  	 * &struct iwl_dts_measurement_notif_v1 or -	 * &struct iwl_dts_measurement_notif_v2 +	 * &struct iwl_dts_measurement_notif  	 */  	DTS_MEASUREMENT_NOTIF_WIDE = 0xFF,  }; @@ -152,13 +157,13 @@ struct iwl_dts_measurement_notif_v1 {  } __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S_VER_1*/  /** - * struct iwl_dts_measurement_notif_v2 - measurements notification + * struct iwl_dts_measurement_notif - measurements notification   *   * @temp: the measured temperature   * @voltage: the measured voltage   * @threshold_idx: the trip index that was crossed   */ -struct iwl_dts_measurement_notif_v2 { +struct iwl_dts_measurement_notif {  	__le32 temp;  	__le32 voltage;  	__le32 threshold_idx; @@ -195,25 +200,25 @@ struct ct_kill_notif {  } __packed; /* CT_KILL_NOTIFICATION_API_S_VER_1, CT_KILL_NOTIFICATION_API_S_VER_2 */  /** -* enum iwl_mvm_ctdp_cmd_operation - CTDP command operations +* enum iwl_ctdp_cmd_operation - CTDP command operations  * @CTDP_CMD_OPERATION_START: update the current budget  * @CTDP_CMD_OPERATION_STOP: stop ctdp  * @CTDP_CMD_OPERATION_REPORT: get the average budget  */ -enum iwl_mvm_ctdp_cmd_operation { +enum iwl_ctdp_cmd_operation {  	CTDP_CMD_OPERATION_START	= 0x1,  	CTDP_CMD_OPERATION_STOP		= 0x2,  	CTDP_CMD_OPERATION_REPORT	= 0x4,  };/* CTDP_CMD_OPERATION_TYPE_E */  /** - * struct iwl_mvm_ctdp_cmd - track and manage the FW power consumption budget + * struct iwl_ctdp_cmd - track and manage the FW power consumption budget   * - * @operation: see &enum iwl_mvm_ctdp_cmd_operation + * @operation: see &enum iwl_ctdp_cmd_operation   * @budget: the budget in milliwatt   * @window_size: defined in API but not used   */ -struct iwl_mvm_ctdp_cmd { +struct iwl_ctdp_cmd {  	__le32 operation;  	__le32 budget;  	__le32 window_size; diff --git a/sys/contrib/dev/iwlwifi/fw/api/power.h b/sys/contrib/dev/iwlwifi/fw/api/power.h index 6e6a92d173cc..786b3bf4b448 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/power.h +++ b/sys/contrib/dev/iwlwifi/fw/api/power.h @@ -1,12 +1,14 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation   * Copyright (C) 2013-2014 Intel Mobile Communications GmbH   * Copyright (C) 2015-2017 Intel Deutschland GmbH   */  #ifndef __iwl_fw_api_power_h__  #define __iwl_fw_api_power_h__ +#include "nvm-reg.h" +  /* Power Management Commands, Responses, Notifications */  /** @@ -54,7 +56,7 @@ struct iwl_ltr_config_cmd_v1 {   * @flags: See &enum iwl_ltr_config_flags   * @static_long: static LTR Long register value.   * @static_short: static LTR Short register value. - * @ltr_cfg_values: LTR parameters table values (in usec) in folowing order: + * @ltr_cfg_values: LTR parameters table values (in usec) in following order:   *	TX, RX, Short Idle, Long Idle. Used only if %LTR_CFG_FLAG_UPDATE_VALUES   *	is set.   * @ltr_short_idle_timeout: LTR Short Idle timeout (in usec). Used only if @@ -89,6 +91,7 @@ struct iwl_ltr_config_cmd {   * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable.   * @POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK: AP/GO's uAPSD misbehaving   *		detection enablement + * @POWER_FLAGS_ENABLE_SMPS_MSK: SMPS is allowed for this vif  */  enum iwl_power_flags {  	POWER_FLAGS_POWER_SAVE_ENA_MSK		= BIT(0), @@ -99,6 +102,7 @@ enum iwl_power_flags {  	POWER_FLAGS_ADVANCE_PM_ENA_MSK		= BIT(9),  	POWER_FLAGS_LPRX_ENA_MSK		= BIT(11),  	POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK	= BIT(12), +	POWER_FLAGS_ENABLE_SMPS_MSK		= BIT(14),  };  #define IWL_POWER_VEC_SIZE 5 @@ -216,7 +220,6 @@ struct iwl_mac_power_cmd {  	/* CONTEXT_DESC_API_T_VER_1 */  	__le32 id_and_color; -	/* CLIENT_PM_POWER_TABLE_S_VER_1 */  	__le16 flags;  	__le16 keep_alive_seconds;  	__le32 rx_data_timeout; @@ -237,7 +240,7 @@ struct iwl_mac_power_cmd {  	u8 heavy_rx_thld_percentage;  	u8 limited_ps_threshold;  	u8 reserved; -} __packed; +} __packed; /* CLIENT_PM_POWER_TABLE_S_VER_1, VER_2 */  /*   * struct iwl_uapsd_misbehaving_ap_notif - FW sends this notification when @@ -252,21 +255,8 @@ struct iwl_uapsd_misbehaving_ap_notif {  	u8 reserved[3];  } __packed; -/** - * struct iwl_reduce_tx_power_cmd - TX power reduction command - * REDUCE_TX_POWER_CMD = 0x9f - * @flags: (reserved for future implementation) - * @mac_context_id: id of the mac ctx for which we are reducing TX power. - * @pwr_restriction: TX power restriction in dBms. - */ -struct iwl_reduce_tx_power_cmd { -	u8 flags; -	u8 mac_context_id; -	__le16 pwr_restriction; -} __packed; /* TX_REDUCED_POWER_API_S_VER_1 */ -  enum iwl_dev_tx_power_cmd_mode { -	IWL_TX_POWER_MODE_SET_MAC = 0, +	IWL_TX_POWER_MODE_SET_LINK = 0,  	IWL_TX_POWER_MODE_SET_DEVICE = 1,  	IWL_TX_POWER_MODE_SET_CHAINS = 2,  	IWL_TX_POWER_MODE_SET_ACK = 3, @@ -283,20 +273,16 @@ enum iwl_dev_tx_power_cmd_mode {  /**   * struct iwl_dev_tx_power_common - Common part of the TX power reduction cmd   * @set_mode: see &enum iwl_dev_tx_power_cmd_mode - * @mac_context_id: id of the mac ctx for which we are reducing TX power. + * @link_id: id of the link ctx for which we are reducing TX power. + *	For version 9 / 10, this is the link id. For earlier versions, it is + *	the mac id.   * @pwr_restriction: TX power restriction in 1/8 dBms. - * @dev_24: device TX power restriction in 1/8 dBms - * @dev_52_low: device TX power restriction upper band - low - * @dev_52_high: device TX power restriction upper band - high   */  struct iwl_dev_tx_power_common {  	__le32 set_mode; -	__le32 mac_context_id; +	__le32 link_id;  	__le16 pwr_restriction; -	__le16 dev_24; -	__le16 dev_52_low; -	__le16 dev_52_high; -}; +} __packed;  /**   * struct iwl_dev_tx_power_cmd_v3 - TX power reduction command version 3 @@ -343,7 +329,7 @@ struct iwl_dev_tx_power_cmd_v5 {  } __packed; /* TX_REDUCED_POWER_API_S_VER_5 */  /** - * struct iwl_dev_tx_power_cmd_v6 - TX power reduction command version 6 + * struct iwl_dev_tx_power_cmd_v8 - TX power reduction command version 8   * @per_chain: per chain restrictions   * @enable_ack_reduction: enable or disable close range ack TX power   *	reduction. @@ -354,43 +340,74 @@ struct iwl_dev_tx_power_cmd_v5 {   * @reserved: reserved (padding)   * @timer_period: timer in milliseconds. if expires FW will change to default   *	BIOS values. relevant if setMode is IWL_TX_POWER_MODE_SET_SAR_TIMER + * @flags: reduce power flags. + * @tpc_vlp_backoff_level: user backoff of UNII5,7 VLP channels in USA. + *	Not in use.   */ -struct iwl_dev_tx_power_cmd_v6 { +struct iwl_dev_tx_power_cmd_v8 {  	__le16 per_chain[IWL_NUM_CHAIN_TABLES_V2][IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V2];  	u8 enable_ack_reduction;  	u8 per_chain_restriction_changed;  	u8 reserved[2];  	__le32 timer_period; -} __packed; /* TX_REDUCED_POWER_API_S_VER_6 */ +	__le32 flags; +	__le32 tpc_vlp_backoff_level; +} __packed; /* TX_REDUCED_POWER_API_S_VER_8 */ + +/* + * @dev_24: device TX power restriction in 1/8 dBms + * @dev_52_low: device TX power restriction upper band - low + * @dev_52_high: device TX power restriction upper band - high + */ +struct iwl_dev_tx_power_cmd_per_band { +	__le16 dev_24; +	__le16 dev_52_low; +	__le16 dev_52_high; +} __packed;  /** - * struct iwl_dev_tx_power_cmd_v7 - TX power reduction command version 7 + * struct iwl_dev_tx_power_cmd_v3_v8 - TX power reduction command (multiversion) + * @per_band: per band restrictions + * @common: common part of the command + * @v3: version 3 part of the command + * @v4: version 4 part of the command + * @v5: version 5 part of the command + * @v8: version 8 part of the command + */ +struct iwl_dev_tx_power_cmd_v3_v8 { +	struct iwl_dev_tx_power_common common; +	struct iwl_dev_tx_power_cmd_per_band per_band; +	union { +		struct iwl_dev_tx_power_cmd_v3 v3; +		struct iwl_dev_tx_power_cmd_v4 v4; +		struct iwl_dev_tx_power_cmd_v5 v5; +		struct iwl_dev_tx_power_cmd_v8 v8; +	}; +}; + +/** + * struct iwl_dev_tx_power_cmd_v9 - TX power reduction cmd + * @reserved: reserved (padding)   * @per_chain: per chain restrictions - * @enable_ack_reduction: enable or disable close range ack TX power - *	reduction.   * @per_chain_restriction_changed: is per_chain_restriction has changed   *	from last command. used if set_mode is   *	IWL_TX_POWER_MODE_SET_SAR_TIMER.   *	note: if not changed, the command is used for keep alive only. - * @reserved: reserved (padding) + * @reserved1: reserved (padding)   * @timer_period: timer in milliseconds. if expires FW will change to default   *	BIOS values. relevant if setMode is IWL_TX_POWER_MODE_SET_SAR_TIMER - * @flags: reduce power flags.   */ -struct iwl_dev_tx_power_cmd_v7 { -	__le16 per_chain[IWL_NUM_CHAIN_TABLES_V2][IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V2]; -	u8 enable_ack_reduction; +struct iwl_dev_tx_power_cmd_v9 { +	__le16 reserved; +	__le16 per_chain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V1];  	u8 per_chain_restriction_changed; -	u8 reserved[2]; +	u8 reserved1[3];  	__le32 timer_period; -	__le32 flags; -} __packed; /* TX_REDUCED_POWER_API_S_VER_7 */ +} __packed; /* TX_REDUCED_POWER_API_S_VER_9 */  /** - * struct iwl_dev_tx_power_cmd_v8 - TX power reduction command version 8 + * struct iwl_dev_tx_power_cmd_v10 - TX power reduction cmd   * @per_chain: per chain restrictions - * @enable_ack_reduction: enable or disable close range ack TX power - *	reduction.   * @per_chain_restriction_changed: is per_chain_restriction has changed   *	from last command. used if set_mode is   *	IWL_TX_POWER_MODE_SET_SAR_TIMER. @@ -399,40 +416,28 @@ struct iwl_dev_tx_power_cmd_v7 {   * @timer_period: timer in milliseconds. if expires FW will change to default   *	BIOS values. relevant if setMode is IWL_TX_POWER_MODE_SET_SAR_TIMER   * @flags: reduce power flags. - * @tpc_vlp_backoff_level: user backoff of UNII5,7 VLP channels in USA. - *	Not in use.   */ -struct iwl_dev_tx_power_cmd_v8 { +struct iwl_dev_tx_power_cmd_v10 {  	__le16 per_chain[IWL_NUM_CHAIN_TABLES_V2][IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V2]; -	u8 enable_ack_reduction;  	u8 per_chain_restriction_changed; -	u8 reserved[2]; +	u8 reserved;  	__le32 timer_period;  	__le32 flags; -	__le32 tpc_vlp_backoff_level; -} __packed; /* TX_REDUCED_POWER_API_S_VER_8 */ +} __packed; /* TX_REDUCED_POWER_API_S_VER_10 */ -/** +/*   * struct iwl_dev_tx_power_cmd - TX power reduction command (multiversion)   * @common: common part of the command - * @v3: version 3 part of the command - * @v4: version 4 part of the command - * @v5: version 5 part of the command - * @v6: version 6 part of the command - * @v7: version 7 part of the command - * @v8: version 8 part of the command + * @v9: version 9 part of the command + * @v10: version 10 part of the command   */  struct iwl_dev_tx_power_cmd {  	struct iwl_dev_tx_power_common common;  	union { -		struct iwl_dev_tx_power_cmd_v3 v3; -		struct iwl_dev_tx_power_cmd_v4 v4; -		struct iwl_dev_tx_power_cmd_v5 v5; -		struct iwl_dev_tx_power_cmd_v6 v6; -		struct iwl_dev_tx_power_cmd_v7 v7; -		struct iwl_dev_tx_power_cmd_v8 v8; +		struct iwl_dev_tx_power_cmd_v9 v9; +		struct iwl_dev_tx_power_cmd_v10 v10;  	}; -}; +} __packed; /* TX_REDUCED_POWER_API_S_VER_9_VER10 */  #define IWL_NUM_GEO_PROFILES		3  #define IWL_NUM_GEO_PROFILES_V3		8 @@ -565,28 +570,37 @@ enum iwl_ppag_flags {  /**   * union iwl_ppag_table_cmd - union for all versions of PPAG command - * @v1: version 1 - * @v2: version 2 - * version 3, 4, 5 and 6 are the same structure as v2, + * @v1: command version 1 structure. + * @v2: command version from 2 to 6 are same structure as v2.   *	but has a different format of the flags bitmap + * @v3: command version 7 structure.   * @v1.flags: values from &enum iwl_ppag_flags   * @v1.gain: table of antenna gain values per chain and sub-band   * @v1.reserved: reserved   * @v2.flags: values from &enum iwl_ppag_flags   * @v2.gain: table of antenna gain values per chain and sub-band - * @v2.reserved: reserved + * @v3.ppag_config_info: see @struct bios_value_u32 + * @v3.gain: table of antenna gain values per chain and sub-band + * @v3.reserved: reserved   */  union iwl_ppag_table_cmd {  	struct {  		__le32 flags;  		s8 gain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V1];  		s8 reserved[2]; -	} v1; +	} __packed v1; /* PER_PLAT_ANTENNA_GAIN_CMD_API_S_VER_1 */  	struct {  		__le32 flags;  		s8 gain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V2];  		s8 reserved[2]; -	} v2; +	} __packed v2; /* PER_PLAT_ANTENNA_GAIN_CMD_API_S_VER_2, VER3, VER4, +			* VER5, VER6 +			*/ +	struct { +		struct bios_value_u32 ppag_config_info; +		s8 gain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V2]; +		s8 reserved[2]; +	} __packed v3; /* PER_PLAT_ANTENNA_GAIN_CMD_API_S_VER_7 */  } __packed;  #define IWL_PPAG_CMD_V4_MASK (IWL_PPAG_ETSI_MASK | IWL_PPAG_CHINA_MASK) @@ -594,6 +608,15 @@ union iwl_ppag_table_cmd {  			      IWL_PPAG_ETSI_LPI_UHB_MASK | \  			      IWL_PPAG_USA_LPI_UHB_MASK) +#define IWL_PPAG_CMD_V6_MASK (IWL_PPAG_CMD_V5_MASK |		\ +			      IWL_PPAG_ETSI_VLP_UHB_MASK |	\ +			      IWL_PPAG_ETSI_SP_UHB_MASK |	\ +			      IWL_PPAG_USA_VLP_UHB_MASK |	\ +			      IWL_PPAG_USA_SP_UHB_MASK |	\ +			      IWL_PPAG_CANADA_LPI_UHB_MASK |	\ +			      IWL_PPAG_CANADA_VLP_UHB_MASK |	\ +			      IWL_PPAG_CANADA_SP_UHB_MASK) +  #define MCC_TO_SAR_OFFSET_TABLE_ROW_SIZE	26  #define MCC_TO_SAR_OFFSET_TABLE_COL_SIZE	13 @@ -627,7 +650,7 @@ struct iwl_sar_offset_mapping_cmd {   *      Roaming Energy Delta Threshold, otherwise use normal Energy Delta   *      Threshold. Typical energy threshold is -72dBm.   * @bf_temp_threshold: This threshold determines the type of temperature - *	filtering (Slow or Fast) that is selected (Units are in Celsuis): + *	filtering (Slow or Fast) that is selected (Units are in Celsius):   *	If the current temperature is above this threshold - Fast filter   *	will be used, If the current temperature is below this threshold -   *	Slow filter will be used. @@ -635,12 +658,12 @@ struct iwl_sar_offset_mapping_cmd {   *      calculated for this and the last passed beacon is greater than this   *      threshold. Zero value means that the temperature change is ignored for   *      beacon filtering; beacons will not be  forced to be sent to driver - *      regardless of whether its temerature has been changed. + *      regardless of whether its temperature has been changed.   * @bf_temp_slow_filter: Send Beacon to driver if delta in temperature values   *      calculated for this and the last passed beacon is greater than this   *      threshold. Zero value means that the temperature change is ignored for   *      beacon filtering; beacons will not be forced to be sent to driver - *      regardless of whether its temerature has been changed. + *      regardless of whether its temperature has been changed.   * @bf_enable_beacon_filter: 1, beacon filtering is enabled; 0, disabled.   * @bf_debug_flag: beacon filtering debug configuration   * @bf_escape_timer: Send beacons to to driver if no beacons were passed diff --git a/sys/contrib/dev/iwlwifi/fw/api/rs.h b/sys/contrib/dev/iwlwifi/fw/api/rs.h index 1a60f0cdf972..3222cbcbe1ab 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/rs.h +++ b/sys/contrib/dev/iwlwifi/fw/api/rs.h @@ -1,11 +1,13 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2012-2014, 2018-2022, 2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2022, 2024-2025 Intel Corporation   * Copyright (C) 2017 Intel Deutschland GmbH   */  #ifndef __iwl_fw_api_rs_h__  #define __iwl_fw_api_rs_h__ - +#include <linux/bitfield.h> +#include <linux/types.h> +#include <linux/bits.h>  #include "mac.h"  /** @@ -213,7 +215,8 @@ enum iwl_tlc_update_flags {   * @sta_id: station id   * @reserved: reserved   * @flags: bitmap of notifications reported - * @rate: current initial rate + * @rate: current initial rate, format depends on the notification + *	version   * @amsdu_size: Max AMSDU size, in bytes   * @amsdu_enabled: bitmap for per-TID AMSDU enablement   */ @@ -224,8 +227,60 @@ struct iwl_tlc_update_notif {  	__le32 rate;  	__le32 amsdu_size;  	__le32 amsdu_enabled; -} __packed; /* TLC_MNG_UPDATE_NTFY_API_S_VER_2 */ +} __packed; /* TLC_MNG_UPDATE_NTFY_API_S_VER_2, _VER_3, _VER_4 */ +/** + * enum iwl_tlc_debug_types - debug options + */ +enum iwl_tlc_debug_types { +	/** +	 *  @IWL_TLC_DEBUG_FIXED_RATE: set fixed rate for rate scaling +	 */ +	IWL_TLC_DEBUG_FIXED_RATE, +	/** +	 * @IWL_TLC_DEBUG_AGG_DURATION_LIM: time limit for a BA +	 * session, in usec +	 */ +	IWL_TLC_DEBUG_AGG_DURATION_LIM, +	/** +	 * @IWL_TLC_DEBUG_AGG_FRAME_CNT_LIM: set max number of frames +	 * in an aggregation +	 */ +	IWL_TLC_DEBUG_AGG_FRAME_CNT_LIM, +	/** +	 * @IWL_TLC_DEBUG_TPC_ENABLED: enable or disable tpc +	 */ +	IWL_TLC_DEBUG_TPC_ENABLED, +	/** +	 * @IWL_TLC_DEBUG_TPC_STATS: get number of frames Tx'ed in each +	 * tpc step +	 */ +	IWL_TLC_DEBUG_TPC_STATS, +	/** +	 * @IWL_TLC_DEBUG_RTS_DISABLE: disable RTS (bool true/false). +	 */ +	IWL_TLC_DEBUG_RTS_DISABLE, +	/** +	 * @IWL_TLC_DEBUG_PARTIAL_FIXED_RATE: set partial fixed rate to fw +	 */ +	IWL_TLC_DEBUG_PARTIAL_FIXED_RATE, +}; /* TLC_MNG_DEBUG_TYPES_API_E */ + +#define MAX_DATA_IN_DHC_TLC_CMD 10 + +/** + * struct iwl_dhc_tlc_cmd - fixed debug config + * @sta_id: bit 0 - enable/disable, bits 1 - 7 hold station id + * @reserved1: reserved + * @type: type id of %enum iwl_tlc_debug_types + * @data: data to send + */ +struct iwl_dhc_tlc_cmd { +	u8 sta_id; +	u8 reserved1[3]; +	__le32 type; +	__le32 data[MAX_DATA_IN_DHC_TLC_CMD]; +} __packed; /* TLC_MNG_DEBUG_CMD_S */  #define IWL_MAX_MCS_DISPLAY_SIZE        12 @@ -375,6 +430,7 @@ enum {  /* Bit 4-5: (0) SISO, (1) MIMO2 (2) MIMO3 */  #define RATE_VHT_MCS_RATE_CODE_MSK	0xf +#define RATE_VHT_MCS_NSS_MSK		0x30  /*   * Legacy OFDM rate format for bits 7:0 @@ -489,7 +545,7 @@ enum {  #define RATE_MCS_CTS_REQUIRED_POS  (31)  #define RATE_MCS_CTS_REQUIRED_MSK  (0x1 << RATE_MCS_CTS_REQUIRED_POS) -/* rate_n_flags bit field version 2 +/* rate_n_flags bit field version 2 and 3   *   * The 32-bit value has different layouts in the low 8 bits depending on the   * format. There are three formats, HT, VHT and legacy (11abg, with subformats @@ -501,23 +557,25 @@ enum {   * (0) Legacy CCK (1) Legacy OFDM (2) High-throughput (HT)   * (3) Very High-throughput (VHT) (4) High-efficiency (HE)   * (5) Extremely High-throughput (EHT) + * (6) Ultra High Reliability (UHR) (v3 rate format only)   */  #define RATE_MCS_MOD_TYPE_POS		8  #define RATE_MCS_MOD_TYPE_MSK		(0x7 << RATE_MCS_MOD_TYPE_POS) -#define RATE_MCS_CCK_MSK		(0 << RATE_MCS_MOD_TYPE_POS) -#define RATE_MCS_LEGACY_OFDM_MSK	(1 << RATE_MCS_MOD_TYPE_POS) -#define RATE_MCS_HT_MSK			(2 << RATE_MCS_MOD_TYPE_POS) -#define RATE_MCS_VHT_MSK		(3 << RATE_MCS_MOD_TYPE_POS) -#define RATE_MCS_HE_MSK			(4 << RATE_MCS_MOD_TYPE_POS) -#define RATE_MCS_EHT_MSK		(5 << RATE_MCS_MOD_TYPE_POS) +#define RATE_MCS_MOD_TYPE_CCK		(0 << RATE_MCS_MOD_TYPE_POS) +#define RATE_MCS_MOD_TYPE_LEGACY_OFDM	(1 << RATE_MCS_MOD_TYPE_POS) +#define RATE_MCS_MOD_TYPE_HT		(2 << RATE_MCS_MOD_TYPE_POS) +#define RATE_MCS_MOD_TYPE_VHT		(3 << RATE_MCS_MOD_TYPE_POS) +#define RATE_MCS_MOD_TYPE_HE		(4 << RATE_MCS_MOD_TYPE_POS) +#define RATE_MCS_MOD_TYPE_EHT		(5 << RATE_MCS_MOD_TYPE_POS) +#define RATE_MCS_MOD_TYPE_UHR		(6 << RATE_MCS_MOD_TYPE_POS)  /*   * Legacy CCK rate format for bits 0:3:   * - * (0) 0xa - 1 Mbps - * (1) 0x14 - 2 Mbps - * (2) 0x37 - 5.5 Mbps - * (3) 0x6e - 11 nbps + * (0) 1 Mbps + * (1) 2 Mbps + * (2) 5.5 Mbps + * (3) 11 Mbps   *   * Legacy OFDM rate format for bis 3:0:   * @@ -534,15 +592,19 @@ enum {  #define RATE_LEGACY_RATE_MSK		0x7  /* - * HT, VHT, HE, EHT rate format for bits 3:0 - * 3-0: MCS - * + * HT, VHT, HE, EHT, UHR rate format + * Version 2: (not applicable for UHR) + *   3-0: MCS + *   4: NSS==2 indicator + * Version 3: + *   4-0: MCS + *   5: NSS==2 indicator   */  #define RATE_HT_MCS_CODE_MSK		0x7 -#define RATE_MCS_NSS_POS		4 -#define RATE_MCS_NSS_MSK		(1 << RATE_MCS_NSS_POS) -#define RATE_MCS_CODE_MSK		0xf -#define RATE_HT_MCS_INDEX(r)		((((r) & RATE_MCS_NSS_MSK) >> 1) | \ +#define RATE_MCS_NSS_MSK_V2		0x10 +#define RATE_MCS_NSS_MSK		0x20 +#define RATE_MCS_CODE_MSK		0x1f +#define RATE_HT_MCS_INDEX(r)		((((r) & RATE_MCS_NSS_MSK) >> 2) | \  					 ((r) & RATE_HT_MCS_CODE_MSK))  /* Bits 7-5: reserved */ @@ -758,11 +820,38 @@ struct iwl_lq_cmd {  }; /* LINK_QUALITY_CMD_API_S_VER_1 */  u8 iwl_fw_rate_idx_to_plcp(int idx); -u32 iwl_new_rate_from_v1(u32 rate_v1);  const struct iwl_rate_mcs_info *iwl_rate_mcs(int idx);  const char *iwl_rs_pretty_ant(u8 ant);  const char *iwl_rs_pretty_bw(int bw);  int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate);  bool iwl_he_is_sgi(u32 rate_n_flags); +static inline u32 iwl_v3_rate_from_v2_v3(__le32 rate, bool fw_v3) +{ +	u32 val; + +	if (fw_v3) +		return le32_to_cpu(rate); + +	val = le32_to_cpu(rate) & ~RATE_MCS_NSS_MSK_V2; +	val |= u32_encode_bits(le32_get_bits(rate, RATE_MCS_NSS_MSK_V2), +			       RATE_MCS_NSS_MSK); + +	return val; +} + +static inline __le32 iwl_v3_rate_to_v2_v3(u32 rate, bool fw_v3) +{ +	__le32 val; + +	if (fw_v3) +		return cpu_to_le32(rate); + +	val = cpu_to_le32(rate & ~RATE_MCS_NSS_MSK); +	val |= le32_encode_bits(u32_get_bits(rate, RATE_MCS_NSS_MSK), +				RATE_MCS_NSS_MSK_V2); + +	return val; +} +  #endif /* __iwl_fw_api_rs_h__ */ diff --git a/sys/contrib/dev/iwlwifi/fw/api/rx.h b/sys/contrib/dev/iwlwifi/fw/api/rx.h index ec89e9576d2e..2024b11c80d0 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/rx.h +++ b/sys/contrib/dev/iwlwifi/fw/api/rx.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2015-2017 Intel Deutschland GmbH   */ @@ -193,10 +193,13 @@ enum iwl_rx_mpdu_amsdu_info {  	IWL_RX_MPDU_AMSDU_LAST_SUBFRAME		= 0x80,  }; -#define RX_MPDU_BAND_POS 6 -#define RX_MPDU_BAND_MASK 0xC0 -#define BAND_IN_RX_STATUS(_val) \ -	(((_val) & RX_MPDU_BAND_MASK) >> RX_MPDU_BAND_POS) +enum iwl_rx_mpdu_mac_phy_band { +	/* whether or not this is MAC or LINK depends on the API */ +	IWL_RX_MPDU_MAC_PHY_BAND_MAC_MASK	= 0x0f, +	IWL_RX_MPDU_MAC_PHY_BAND_LINK_MASK	= 0x0f, +	IWL_RX_MPDU_MAC_PHY_BAND_PHY_MASK	= 0x30, +	IWL_RX_MPDU_MAC_PHY_BAND_BAND_MASK	= 0xc0, +};  enum iwl_rx_l3_proto_values {  	IWL_RX_L3_TYPE_NONE, @@ -642,7 +645,9 @@ struct iwl_rx_mpdu_desc_v3 {  	 */  	__le32 reserved[1];  } __packed; /* RX_MPDU_RES_START_API_S_VER_3, -	       RX_MPDU_RES_START_API_S_VER_5 */ +	     * RX_MPDU_RES_START_API_S_VER_5, +	     * RX_MPDU_RES_START_API_S_VER_6 +	     */  /**   * struct iwl_rx_mpdu_desc - RX MPDU descriptor @@ -671,9 +676,10 @@ struct iwl_rx_mpdu_desc {  	 */  	__le16 phy_info;  	/** -	 * @mac_phy_idx: MAC/PHY index +	 * @mac_phy_band: MAC/link ID, PHY ID, band; +	 *	see &enum iwl_rx_mpdu_mac_phy_band  	 */ -	u8 mac_phy_idx; +	u8 mac_phy_band;  	/* DW4 */  	union {  		struct { @@ -725,8 +731,10 @@ struct iwl_rx_mpdu_desc {  		struct iwl_rx_mpdu_desc_v3 v3;  	};  } __packed; /* RX_MPDU_RES_START_API_S_VER_3, -	       RX_MPDU_RES_START_API_S_VER_4, -	       RX_MPDU_RES_START_API_S_VER_5 */ +	     * RX_MPDU_RES_START_API_S_VER_4, +	     * RX_MPDU_RES_START_API_S_VER_5, +	     * RX_MPDU_RES_START_API_S_VER_6 +	     */  #define IWL_RX_DESC_SIZE_V1 offsetofend(struct iwl_rx_mpdu_desc, v1) @@ -822,7 +830,7 @@ struct iwl_rx_no_data {   *	15:8 chain-B, measured at FINA time (FINA_ENERGY), 16:23 channel   * @on_air_rise_time: GP2 during on air rise   * @fr_time: frame time - * @rate: rate/mcs of frame + * @rate: rate/mcs of frame, format depends on the notification version   * @phy_info: &enum iwl_rx_phy_eht_data0 and &enum iwl_rx_phy_info_type   * @rx_vec: DW-12:9 raw RX vectors from DSP according to modulation type.   *	for VHT: OFDM_RX_VECTOR_SIGA1_OUT, OFDM_RX_VECTOR_SIGA2_OUT @@ -838,9 +846,7 @@ struct iwl_rx_no_data_ver_3 {  	__le32 rate;  	__le32 phy_info[2];  	__le32 rx_vec[4]; -} __packed; /* RX_NO_DATA_NTFY_API_S_VER_1, -	       RX_NO_DATA_NTFY_API_S_VER_2 -	       RX_NO_DATA_NTFY_API_S_VER_3 */ +} __packed; /* RX_NO_DATA_NTFY_API_S_VER_3, _VER_4 */  struct iwl_frame_release {  	u8 baid; @@ -1030,4 +1036,24 @@ struct iwl_rfh_queue_config {  #endif  } __packed; /* RFH_QUEUE_CONFIG_API_S_VER_1 */ +/** + * struct iwl_beacon_filter_notif_v1 - beacon filter notification + * @average_energy: average energy for the received beacon + * @mac_id: MAC ID the beacon was received for + */ +struct iwl_beacon_filter_notif_v1 { +	__le32 average_energy; +	__le32 mac_id; +} __packed; /* BEACON_FILTER_IN_NTFY_API_S_VER_1 */ + +/** + * struct iwl_beacon_filter_notif - beacon filter notification + * @average_energy: average energy for the received beacon + * @link_id: link ID the beacon was received for + */ +struct iwl_beacon_filter_notif { +	__le32 average_energy; +	__le32 link_id; +} __packed; /* BEACON_FILTER_IN_NTFY_API_S_VER_2 */ +  #endif /* __iwl_fw_api_rx_h__ */ diff --git a/sys/contrib/dev/iwlwifi/fw/api/scan.h b/sys/contrib/dev/iwlwifi/fw/api/scan.h index 8598031567bb..f486d624500b 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/scan.h +++ b/sys/contrib/dev/iwlwifi/fw/api/scan.h @@ -731,39 +731,46 @@ enum iwl_umac_scan_general_params_flags2 {   * struct iwl_scan_channel_cfg_umac   * @flags:		bitmap - 0-19:	directed scan to i'th ssid.   * @channel_num:	channel number 1-13 etc. - * @band:		band of channel: 0 for 2GHz, 1 for 5GHz - * @iter_count:		repetition count for the channel. - * @iter_interval:	interval between two scan iterations on one channel. + * @v1:			command version 1 + * @v1.iter_count:	repetition count for the channel. + * @v1.iter_interval:	interval between two scan iterations on one channel. + * @v2:			command versions 2-4 + * @v2.band:		band of channel: 0 for 2GHz, 1 for 5GHz + * @v2.iter_count:	repetition count for the channel. + * @v2.iter_interval:	interval between two scan iterations on one channel. + * @v5:			command versions 5 and up + * @v5.iter_count:	repetition count for the channel. + * @v5.iter_interval:	interval between two scan iterations on one channel. + * @v5.psd_20:		highest PSD value for all APs known so far + *			on this channel.   */  struct  iwl_scan_channel_cfg_umac {  #define IWL_CHAN_CFG_FLAGS_BAND_POS 30  	__le32 flags; +	u8 channel_num;  	/* All versions are of the same size, so use a union without adjusting  	 * the command size later  	 */  	union {  		struct { -			u8 channel_num;  			u8 iter_count;  			__le16 iter_interval; -		} v1;  /* SCAN_CHANNEL_CONFIG_API_S_VER_1 */ +		} __packed v1;  /* SCAN_CHANNEL_CONFIG_API_S_VER_1 */  		struct { -			u8 channel_num;  			u8 band;  			u8 iter_count;  			u8 iter_interval; -		 } v2; /* SCAN_CHANNEL_CONFIG_API_S_VER_2 -			* SCAN_CHANNEL_CONFIG_API_S_VER_3 -			* SCAN_CHANNEL_CONFIG_API_S_VER_4 -			*/ +		} __packed v2; /* SCAN_CHANNEL_CONFIG_API_S_VER_2 +				* SCAN_CHANNEL_CONFIG_API_S_VER_3 +				* SCAN_CHANNEL_CONFIG_API_S_VER_4 +				*/  		struct { -			u8 channel_num;  			u8 psd_20;  			u8 iter_count;  			u8 iter_interval; -		} v5;  /* SCAN_CHANNEL_CONFIG_API_S_VER_5 */ -	}; +		} __packed v5;  /* SCAN_CHANNEL_CONFIG_API_S_VER_5 */ +	} __packed;  } __packed;  /** @@ -1133,6 +1140,19 @@ struct iwl_umac_scan_abort {  } __packed; /* SCAN_ABORT_CMD_UMAC_API_S_VER_1 */  /** + * enum iwl_umac_scan_abort_status + * + * @IWL_UMAC_SCAN_ABORT_STATUS_SUCCESS: scan was successfully aborted + * @IWL_UMAC_SCAN_ABORT_STATUS_IN_PROGRESS: scan abort is in progress + * @IWL_UMAC_SCAN_ABORT_STATUS_NOT_FOUND: nothing to abort + */ +enum iwl_umac_scan_abort_status { +	IWL_UMAC_SCAN_ABORT_STATUS_SUCCESS = 0, +	IWL_UMAC_SCAN_ABORT_STATUS_IN_PROGRESS, +	IWL_UMAC_SCAN_ABORT_STATUS_NOT_FOUND, +}; + +/**   * struct iwl_umac_scan_complete   * @uid: scan id, &enum iwl_umac_scan_uid_offsets   * @last_schedule: last scheduling line diff --git a/sys/contrib/dev/iwlwifi/fw/api/sta.h b/sys/contrib/dev/iwlwifi/fw/api/sta.h index 893049edb4ae..b2a3fdb07280 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/sta.h +++ b/sys/contrib/dev/iwlwifi/fw/api/sta.h @@ -191,6 +191,7 @@ enum iwl_sta_sleep_flag {  #define STA_KEY_IDX_INVALID (0xff)  #define STA_KEY_MAX_DATA_KEY_NUM (4)  #define IWL_MAX_GLOBAL_KEYS (4) +#define IWL_MAX_NUM_IGTKS 2  #define STA_KEY_LEN_WEP40 (5)  #define STA_KEY_LEN_WEP104 (13) diff --git a/sys/contrib/dev/iwlwifi/fw/api/stats.h b/sys/contrib/dev/iwlwifi/fw/api/stats.h index 2271b19213fa..00713a991879 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/stats.h +++ b/sys/contrib/dev/iwlwifi/fw/api/stats.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2012-2014, 2018, 2020 - 2021, 2023 Intel Corporation + * Copyright (C) 2012-2014, 2018, 2020-2021, 2023-2025 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2016-2017 Intel Deutschland GmbH   */ @@ -327,14 +327,14 @@ struct mvm_statistics_load {  	__le32 air_time[MAC_INDEX_AUX];  	__le32 byte_count[MAC_INDEX_AUX];  	__le32 pkt_count[MAC_INDEX_AUX]; -	u8 avg_energy[IWL_MVM_STATION_COUNT_MAX]; +	u8 avg_energy[IWL_STATION_COUNT_MAX];  } __packed; /* STATISTICS_RX_MAC_STATION_S_VER_3 */  struct mvm_statistics_load_v1 {  	__le32 air_time[NUM_MAC_INDEX];  	__le32 byte_count[NUM_MAC_INDEX];  	__le32 pkt_count[NUM_MAC_INDEX]; -	u8 avg_energy[IWL_MVM_STATION_COUNT_MAX]; +	u8 avg_energy[IWL_STATION_COUNT_MAX];  } __packed; /* STATISTICS_RX_MAC_STATION_S_VER_1 */  struct mvm_statistics_rx { @@ -584,6 +584,9 @@ struct iwl_stats_ntfy_per_phy {  	__le32 last_tx_ch_width_indx;  } __packed; /* STATISTICS_NTFY_PER_PHY_API_S_VER_1 */ +/* unknown channel load (due to not being active on channel) */ +#define IWL_STATS_UNKNOWN_CHANNEL_LOAD	0xffffffff +  /**   * struct iwl_stats_ntfy_per_sta   * @@ -594,7 +597,7 @@ struct iwl_stats_ntfy_per_sta {  } __packed; /* STATISTICS_NTFY_PER_STA_API_S_VER_1 */  #define IWL_STATS_MAX_PHY_OPERATIONAL 3 -#define IWL_STATS_MAX_FW_LINKS	(IWL_MVM_FW_MAX_LINK_ID + 1) +#define IWL_STATS_MAX_FW_LINKS	(IWL_FW_MAX_LINK_ID + 1)  /**   * struct iwl_system_statistics_notif_oper @@ -608,7 +611,7 @@ struct iwl_system_statistics_notif_oper {  	__le32 time_stamp;  	struct iwl_stats_ntfy_per_link per_link[IWL_STATS_MAX_FW_LINKS];  	struct iwl_stats_ntfy_per_phy per_phy[IWL_STATS_MAX_PHY_OPERATIONAL]; -	struct iwl_stats_ntfy_per_sta per_sta[IWL_MVM_STATION_COUNT_MAX]; +	struct iwl_stats_ntfy_per_sta per_sta[IWL_STATION_COUNT_MAX];  } __packed; /* STATISTICS_FW_NTFY_OPERATIONAL_API_S_VER_3 */  /** @@ -651,7 +654,7 @@ struct iwl_statistics_operational_ntfy {  	__le32 flags;  	struct iwl_stats_ntfy_per_mac per_mac[MAC_INDEX_AUX];  	struct iwl_stats_ntfy_per_phy per_phy[IWL_STATS_MAX_PHY_OPERATIONAL]; -	struct iwl_stats_ntfy_per_sta per_sta[IWL_MVM_STATION_COUNT_MAX]; +	struct iwl_stats_ntfy_per_sta per_sta[IWL_STATION_COUNT_MAX];  	__le64 rx_time;  	__le64 tx_time;  	__le64 on_time_rf; @@ -699,7 +702,7 @@ struct iwl_statistics_operational_ntfy_ver_14 {  	__le64 tx_time;  	__le64 on_time_rf;  	__le64 on_time_scan; -	__le32 average_energy[IWL_MVM_STATION_COUNT_MAX]; +	__le32 average_energy[IWL_STATION_COUNT_MAX];  	__le32 reserved;  } __packed; /* STATISTICS_OPERATIONAL_NTFY_API_S_VER_14 */ diff --git a/sys/contrib/dev/iwlwifi/fw/api/tdls.h b/sys/contrib/dev/iwlwifi/fw/api/tdls.h index 893438aadab0..08edd1d99992 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/tdls.h +++ b/sys/contrib/dev/iwlwifi/fw/api/tdls.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2012-2014, 2018 Intel Corporation + * Copyright (C) 2012-2014, 2018, 2024-2025 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2016-2017 Intel Deutschland GmbH   */ @@ -10,7 +10,7 @@  #include "fw/api/tx.h"  #include "fw/api/phy-ctxt.h" -#define IWL_MVM_TDLS_STA_COUNT	4 +#define IWL_TDLS_STA_COUNT	4  /* Type of TDLS request */  enum iwl_tdls_channel_switch_type { @@ -50,7 +50,7 @@ struct iwl_tdls_channel_switch_timing {   */  struct iwl_tdls_channel_switch_frame {  	__le32 switch_time_offset; -	struct iwl_tx_cmd tx_cmd; +	struct iwl_tx_cmd_v6_params tx_cmd;  	u8 data[IWL_TDLS_CH_SW_FRAME_MAX_SIZE];  } __packed; /* TDLS_STA_CHANNEL_SWITCH_FRAME_API_S_VER_1 */ @@ -128,10 +128,10 @@ struct iwl_tdls_config_cmd {  	u8 tdls_peer_count;  	u8 tx_to_ap_tid;  	__le16 tx_to_ap_ssn; -	struct iwl_tdls_sta_info sta_info[IWL_MVM_TDLS_STA_COUNT]; +	struct iwl_tdls_sta_info sta_info[IWL_TDLS_STA_COUNT];  	__le32 pti_req_data_offset; -	struct iwl_tx_cmd pti_req_tx_cmd; +	struct iwl_tx_cmd_v6_params pti_req_tx_cmd;  	u8 pti_req_template[];  } __packed; /* TDLS_CONFIG_CMD_API_S_VER_1 */ @@ -155,7 +155,7 @@ struct iwl_tdls_config_sta_info_res {   */  struct iwl_tdls_config_res {  	__le32 tx_to_ap_last_seq; -	struct iwl_tdls_config_sta_info_res sta_info[IWL_MVM_TDLS_STA_COUNT]; +	struct iwl_tdls_config_sta_info_res sta_info[IWL_TDLS_STA_COUNT];  } __packed; /* TDLS_CONFIG_RSP_API_S_VER_1 */  #endif /* __iwl_fw_api_tdls_h__ */ diff --git a/sys/contrib/dev/iwlwifi/fw/api/time-event.h b/sys/contrib/dev/iwlwifi/fw/api/time-event.h index f4b827b58bd3..46d35ef4751e 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/time-event.h +++ b/sys/contrib/dev/iwlwifi/fw/api/time-event.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2012-2014, 2018-2020, 2022-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2020, 2022-2025 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2016-2017 Intel Deutschland GmbH   */ @@ -351,7 +351,7 @@ enum iwl_roc_activity {  }; /* ROC_ACTIVITY_API_E_VER_1 */  /* - * ROC command + * ROC command v5   *   * Command requests the firmware to remain on a channel for a certain duration.   * @@ -366,7 +366,7 @@ enum iwl_roc_activity {   * @max_delay: max delay the ROC can start in TU   * @duration: remain on channel duration in TU   */ -struct iwl_roc_req { +struct iwl_roc_req_v5 {  	__le32 action;  	__le32 activity;  	__le32 sta_id; @@ -375,7 +375,41 @@ struct iwl_roc_req {  	__le16 reserved;  	__le32 max_delay;  	__le32 duration; -} __packed; /* ROC_CMD_API_S_VER_3 */ +} __packed; /* ROC_CMD_API_S_VER_5 */ + +/* + * ROC command + * + * Command requests the firmware to remain on a channel for a certain duration. + * + * ( MAC_CONF_GROUP 0x3, ROC_CMD 0xE ) + * + * @action: action to perform, see &enum iwl_ctxt_action + * @activity: type of activity, see &enum iwl_roc_activity + * @sta_id: station id, resumed during "Remain On Channel" activity. + * @channel_info: &struct iwl_fw_channel_info + * @node_addr: node MAC address for Rx filtering + * @reserved1: align to a dword + * @max_delay: max delay the ROC can start in TU + * @duration: remain on channel duration in TU + * @interval: interval between repetitions (when repetitions > 1). + * @repetitions: number of repetitions + *	0xFF: infinite repetitions. 0 or 1: single repetition. + * @reserved2: align to a dword + */ +struct iwl_roc_req { +	__le32 action; +	__le32 activity; +	__le32 sta_id; +	struct iwl_fw_channel_info channel_info; +	u8 node_addr[ETH_ALEN]; +	__le16 reserved1; +	__le32 max_delay; +	__le32 duration; +	__le32 interval; +	u8 repetitions; +	u8 reserved2[3]; +} __packed; /* ROC_CMD_API_S_VER_6 */  /*   * ROC notification @@ -395,7 +429,7 @@ struct iwl_roc_notif {  } __packed; /* ROC_NOTIF_API_S_VER_1 */  /** - * enum iwl_mvm_session_prot_conf_id - session protection's configurations + * enum iwl_session_prot_conf_id - session protection's configurations   * @SESSION_PROTECT_CONF_ASSOC: Start a session protection for association.   *	The firmware will allocate two events.   *	Valid for BSS_STA and P2P_STA. @@ -418,13 +452,13 @@ struct iwl_roc_notif {   *	listen mode. Will be fragmented. Valid only on the P2P Device MAC.   *	Valid only on the P2P Device MAC. The firmware will take into account   *	the duration, the interval and the repetition count. - * @SESSION_PROTECT_CONF_P2P_GO_NEGOTIATION: Schedule the P2P Device to be be + * @SESSION_PROTECT_CONF_P2P_GO_NEGOTIATION: Schedule the P2P Device to be   *	able to run the GO Negotiation. Will not be fragmented and not   *	repetitive. Valid only on the P2P Device MAC. Only the duration will   *	be taken into account.   * @SESSION_PROTECT_CONF_MAX_ID: not used   */ -enum iwl_mvm_session_prot_conf_id { +enum iwl_session_prot_conf_id {  	SESSION_PROTECT_CONF_ASSOC,  	SESSION_PROTECT_CONF_GO_CLIENT_ASSOC,  	SESSION_PROTECT_CONF_P2P_DEVICE_DISCOV, @@ -433,12 +467,12 @@ enum iwl_mvm_session_prot_conf_id {  }; /* SESSION_PROTECTION_CONF_ID_E_VER_1 */  /** - * struct iwl_mvm_session_prot_cmd - configure a session protection + * struct iwl_session_prot_cmd - configure a session protection   * @id_and_color: the id and color of the link (or mac, for command version 1)   *	for which this session protection is sent   * @action: can be either FW_CTXT_ACTION_ADD or FW_CTXT_ACTION_REMOVE,   *	see &enum iwl_ctxt_action - * @conf_id: see &enum iwl_mvm_session_prot_conf_id + * @conf_id: see &enum iwl_session_prot_conf_id   * @duration_tu: the duration of the whole protection in TUs.   * @repetition_count: not used   * @interval: not used @@ -448,7 +482,7 @@ enum iwl_mvm_session_prot_conf_id {   * The firmware supports only one concurrent session protection per vif.   * Adding a new session protection will remove any currently running session.   */ -struct iwl_mvm_session_prot_cmd { +struct iwl_session_prot_cmd {  	/* COMMON_INDEX_HDR_API_S_VER_1 hdr */  	__le32 id_and_color;  	__le32 action; @@ -462,17 +496,17 @@ struct iwl_mvm_session_prot_cmd {   */  /** - * struct iwl_mvm_session_prot_notif - session protection started / ended + * struct iwl_session_prot_notif - session protection started / ended   * @mac_link_id: the mac id (or link id, for notif ver > 2) for which the   *	session protection started / ended   * @status: 1 means success, 0 means failure   * @start: 1 means the session protection started, 0 means it ended - * @conf_id: see &enum iwl_mvm_session_prot_conf_id + * @conf_id: see &enum iwl_session_prot_conf_id   *   * Note that any session protection will always get two notifications: start   * and end even the firmware could not schedule it.   */ -struct iwl_mvm_session_prot_notif { +struct iwl_session_prot_notif {  	__le32 mac_link_id;  	__le32 status;  	__le32 start; diff --git a/sys/contrib/dev/iwlwifi/fw/api/tx.h b/sys/contrib/dev/iwlwifi/fw/api/tx.h index c5277e2f8cd4..26d2013905ed 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/tx.h +++ b/sys/contrib/dev/iwlwifi/fw/api/tx.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation   * Copyright (C) 2016-2017 Intel Deutschland GmbH   */  #ifndef __iwl_fw_api_tx_h__ @@ -151,7 +151,7 @@ enum iwl_tx_cmd_sec_ctrl {  #define IWL_LOW_RETRY_LIMIT			7  /** - * enum iwl_tx_offload_assist_flags_pos -  set %iwl_tx_cmd offload_assist values + * enum iwl_tx_offload_assist_flags_pos -  set %iwl_tx_cmd_v6 offload_assist values   * @TX_CMD_OFFLD_IP_HDR: offset to start of IP header (in words)   *	from mac header end. For normal case it is 4 words for SNAP.   *	note: tx_cmd, mac header and pad are not counted in the offset. @@ -181,8 +181,8 @@ enum iwl_tx_offload_assist_flags_pos {  /* TODO: complete documentation for try_cnt and btkill_cnt */  /** - * struct iwl_tx_cmd - TX command struct to FW - * ( TX_CMD = 0x1c ) + * struct iwl_tx_cmd_v6_params - parameters of the TX + *   * @len: in bytes of the payload, see below for details   * @offload_assist: TX offload configuration   * @tx_flags: combination of TX_CMD_FLG_*, see &enum iwl_tx_flags @@ -191,7 +191,7 @@ enum iwl_tx_offload_assist_flags_pos {   *	cleared. Combination of RATE_MCS_*   * @sta_id: index of destination station in FW station table   * @sec_ctl: security control, TX_CMD_SEC_* - * @initial_rate_index: index into the the rate table for initial TX attempt. + * @initial_rate_index: index into the rate table for initial TX attempt.   *	Applied if TX_CMD_FLG_STA_RATE_MSK is set, normally 0 for data frames.   * @reserved2: reserved   * @key: security key @@ -205,8 +205,6 @@ enum iwl_tx_offload_assist_flags_pos {   * @tid_tspec: TID/tspec   * @pm_frame_timeout: PM TX frame timeout   * @reserved4: reserved - * @payload: payload (same as @hdr) - * @hdr: 802.11 header (same as @payload)   *   * The byte count (both len and next_frame_len) includes MAC header   * (24/26/30/32 bytes) @@ -217,11 +215,8 @@ enum iwl_tx_offload_assist_flags_pos {   * It does not include post-MAC padding, i.e.,   * MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.   * Range of len: 14-2342 bytes. - * - * After the struct fields the MAC header is placed, plus any padding, - * and then the actial payload.   */ -struct iwl_tx_cmd { +struct iwl_tx_cmd_v6_params {  	__le16 len;  	__le16 offload_assist;  	__le32 tx_flags; @@ -245,10 +240,20 @@ struct iwl_tx_cmd {  	u8 tid_tspec;  	__le16 pm_frame_timeout;  	__le16 reserved4; -	union { -		DECLARE_FLEX_ARRAY(u8, payload); -		DECLARE_FLEX_ARRAY(struct ieee80211_hdr, hdr); -	}; +} __packed; /* TX_CMD_API_S_VER_6 */ + +/** + * struct iwl_tx_cmd_v6 - TX command struct to FW + * ( TX_CMD = 0x1c ) + * @params: parameters of the TX, see &struct iwl_tx_cmd_v6_tx_params + * @hdr: 802.11 header + * + * After ¶ms, the MAC header is placed, plus any padding, + * and then the actual payload. + */ +struct iwl_tx_cmd_v6 { +	struct iwl_tx_cmd_v6_params params; +	struct ieee80211_hdr hdr[];  } __packed; /* TX_CMD_API_S_VER_6 */  struct iwl_dram_sec_info { @@ -258,7 +263,7 @@ struct iwl_dram_sec_info {  } __packed; /* DRAM_SEC_INFO_API_S_VER_1 */  /** - * struct iwl_tx_cmd_gen2 - TX command struct to FW for 22000 devices + * struct iwl_tx_cmd_v9 - TX command struct to FW for 22000 devices   * ( TX_CMD = 0x1c )   * @len: in bytes of the payload, see below for details   * @offload_assist: TX offload configuration @@ -268,7 +273,7 @@ struct iwl_dram_sec_info {   *	cleared. Combination of RATE_MCS_*   * @hdr: 802.11 header   */ -struct iwl_tx_cmd_gen2 { +struct iwl_tx_cmd_v9 {  	__le16 len;  	__le16 offload_assist;  	__le32 flags; @@ -279,18 +284,18 @@ struct iwl_tx_cmd_gen2 {  	       TX_CMD_API_S_VER_9 */  /** - * struct iwl_tx_cmd_gen3 - TX command struct to FW for AX210+ devices + * struct iwl_tx_cmd - TX command struct to FW for AX210+ devices   * ( TX_CMD = 0x1c )   * @len: in bytes of the payload, see below for details   * @flags: combination of &enum iwl_tx_cmd_flags   * @offload_assist: TX offload configuration   * @dram_info: FW internal DRAM storage   * @rate_n_flags: rate for *all* Tx attempts, if TX_CMD_FLG_STA_RATE_MSK is - *	cleared. Combination of RATE_MCS_* + *	cleared. Combination of RATE_MCS_*; format depends on version   * @reserved: reserved   * @hdr: 802.11 header   */ -struct iwl_tx_cmd_gen3 { +struct iwl_tx_cmd {  	__le16 len;  	__le16 flags;  	__le32 offload_assist; @@ -298,8 +303,9 @@ struct iwl_tx_cmd_gen3 {  	__le32 rate_n_flags;  	u8 reserved[8];  	struct ieee80211_hdr hdr[]; -} __packed; /* TX_CMD_API_S_VER_8, -	       TX_CMD_API_S_VER_10 */ +} __packed; /* TX_CMD_API_S_VER_10, +	     * TX_CMD_API_S_VER_11 +	     */  /*   * TX response related data @@ -482,11 +488,11 @@ struct agg_tx_status {  #define TX_RES_RATE_TABLE_COL_GET(_f) (((_f) & TX_RES_RATE_TABLE_COLOR_MSK) >>\  				       TX_RES_RATE_TABLE_COLOR_POS) -#define IWL_MVM_TX_RES_GET_TID(_ra_tid) ((_ra_tid) & 0x0f) -#define IWL_MVM_TX_RES_GET_RA(_ra_tid) ((_ra_tid) >> 4) +#define IWL_TX_RES_GET_TID(_ra_tid) ((_ra_tid) & 0x0f) +#define IWL_TX_RES_GET_RA(_ra_tid) ((_ra_tid) >> 4)  /** - * struct iwl_mvm_tx_resp_v3 - notifies that fw is TXing a packet + * struct iwl_tx_resp_v3 - notifies that fw is TXing a packet   * ( REPLY_TX = 0x1c )   * @frame_count: 1 no aggregation, >1 aggregation   * @bt_kill_count: num of times blocked by bluetooth (unused for agg) @@ -517,7 +523,7 @@ struct agg_tx_status {   * After the array of statuses comes the SSN of the SCD. Look at   * %iwl_mvm_get_scd_ssn for more details.   */ -struct iwl_mvm_tx_resp_v3 { +struct iwl_tx_resp_v3 {  	u8 frame_count;  	u8 bt_kill_count;  	u8 failure_rts; @@ -543,14 +549,14 @@ struct iwl_mvm_tx_resp_v3 {  } __packed; /* TX_RSP_API_S_VER_3 */  /** - * struct iwl_mvm_tx_resp - notifies that fw is TXing a packet + * struct iwl_tx_resp - notifies that fw is TXing a packet   * ( REPLY_TX = 0x1c )   * @frame_count: 1 no aggregation, >1 aggregation   * @bt_kill_count: num of times blocked by bluetooth (unused for agg)   * @failure_rts: num of failures due to unsuccessful RTS   * @failure_frame: num failures due to no ACK (unused for agg)   * @initial_rate: for non-agg: rate of the successful Tx. For agg: rate of the - *	Tx of all the batch. RATE_MCS_* + *	Tx of all the batch. RATE_MCS_*; format depends on command version   * @wireless_media_time: for non-agg: RTS + CTS + frame tx attempts time + ACK.   *	for agg: RTS + CTS + aggregation tx time + block-ack time.   *	in usec. @@ -575,7 +581,7 @@ struct iwl_mvm_tx_resp_v3 {   * After the array of statuses comes the SSN of the SCD. Look at   * %iwl_mvm_get_scd_ssn for more details.   */ -struct iwl_mvm_tx_resp { +struct iwl_tx_resp {  	u8 frame_count;  	u8 bt_kill_count;  	u8 failure_rts; @@ -601,7 +607,10 @@ struct iwl_mvm_tx_resp {  	__le16 reserved2;  	struct agg_tx_status status;  } __packed; /* TX_RSP_API_S_VER_6, -	       TX_RSP_API_S_VER_7 */ +	     * TX_RSP_API_S_VER_7, +	     * TX_RSP_API_S_VER_8, +	     * TX_RSP_API_S_VER_9 +	     */  /**   * struct iwl_mvm_ba_notif - notifies about reception of BA @@ -638,14 +647,14 @@ struct iwl_mvm_ba_notif {  } __packed;  /** - * struct iwl_mvm_compressed_ba_tfd - progress of a TFD queue + * struct iwl_compressed_ba_tfd - progress of a TFD queue   * @q_num: TFD queue number   * @tfd_index: Index of first un-acked frame in the  TFD queue   * @scd_queue: For debug only - the physical queue the TFD queue is bound to   * @tid: TID of the queue (0-7)   * @reserved: reserved for alignment   */ -struct iwl_mvm_compressed_ba_tfd { +struct iwl_compressed_ba_tfd {  	__le16 q_num;  	__le16 tfd_index;  	u8 scd_queue; @@ -654,12 +663,12 @@ struct iwl_mvm_compressed_ba_tfd {  } __packed; /* COMPRESSED_BA_TFD_API_S_VER_1 */  /** - * struct iwl_mvm_compressed_ba_ratid - progress of a RA TID queue + * struct iwl_compressed_ba_ratid - progress of a RA TID queue   * @q_num: RA TID queue number   * @tid: TID of the queue   * @ssn: BA window current SSN   */ -struct iwl_mvm_compressed_ba_ratid { +struct iwl_compressed_ba_ratid {  	u8 q_num;  	u8 tid;  	__le16 ssn; @@ -685,7 +694,7 @@ enum iwl_mvm_ba_resp_flags {  };  /** - * struct iwl_mvm_compressed_ba_notif - notifies about reception of BA + * struct iwl_compressed_ba_notif - notifies about reception of BA   * ( BA_NOTIF = 0xc5 )   * @flags: status flag, see the &iwl_mvm_ba_resp_flags   * @sta_id: Index of recipient (BA-sending) station in fw's station table @@ -701,15 +710,16 @@ enum iwl_mvm_ba_resp_flags {   * @rts_retry_cnt: RTS retry count   * @reserved: reserved (for alignment)   * @wireless_time: Wireless-media time - * @tx_rate: the rate the aggregation was sent at + * @tx_rate: the rate the aggregation was sent at. Format depends on command + *	version.   * @tfd_cnt: number of TFD-Q elements   * @ra_tid_cnt: number of RATID-Q elements - * @tfd: array of TFD queue status updates. See &iwl_mvm_compressed_ba_tfd + * @tfd: array of TFD queue status updates. See &iwl_compressed_ba_tfd   *	for details. Length in @tfd_cnt.   * @ra_tid: array of RA-TID queue status updates. For debug purposes only. See - *	&iwl_mvm_compressed_ba_ratid for more details. Length in @ra_tid_cnt. + *	&iwl_compressed_ba_ratid for more details. Length in @ra_tid_cnt.   */ -struct iwl_mvm_compressed_ba_notif { +struct iwl_compressed_ba_notif {  	__le32 flags;  	u8 sta_id;  	u8 reduced_txp; @@ -726,11 +736,12 @@ struct iwl_mvm_compressed_ba_notif {  	__le16 tfd_cnt;  	__le16 ra_tid_cnt;  	union { -		DECLARE_FLEX_ARRAY(struct iwl_mvm_compressed_ba_ratid, ra_tid); -		DECLARE_FLEX_ARRAY(struct iwl_mvm_compressed_ba_tfd, tfd); +		DECLARE_FLEX_ARRAY(struct iwl_compressed_ba_ratid, ra_tid); +		DECLARE_FLEX_ARRAY(struct iwl_compressed_ba_tfd, tfd);  	};  } __packed; /* COMPRESSED_BA_RES_API_S_VER_4, -	       COMPRESSED_BA_RES_API_S_VER_5 */ +	       COMPRESSED_BA_RES_API_S_VER_6, +	       COMPRESSED_BA_RES_API_S_VER_7 */  /**   * struct iwl_mac_beacon_cmd_v6 - beacon template command @@ -742,7 +753,7 @@ struct iwl_mvm_compressed_ba_notif {   * @frame: the template of the beacon frame   */  struct iwl_mac_beacon_cmd_v6 { -	struct iwl_tx_cmd tx; +	struct iwl_tx_cmd_v6_params tx;  	__le32 template_id;  	__le32 tim_idx;  	__le32 tim_size; @@ -761,7 +772,7 @@ struct iwl_mac_beacon_cmd_v6 {   * @frame: the template of the beacon frame   */  struct iwl_mac_beacon_cmd_v7 { -	struct iwl_tx_cmd tx; +	struct iwl_tx_cmd_v6_params tx;  	__le32 template_id;  	__le32 tim_idx;  	__le32 tim_size; @@ -823,7 +834,7 @@ struct iwl_mac_beacon_cmd {  	     */  struct iwl_beacon_notif { -	struct iwl_mvm_tx_resp beacon_notify_hdr; +	struct iwl_tx_resp beacon_notify_hdr;  	__le64 tsf;  	__le32 ibss_mgr_status;  } __packed; @@ -836,7 +847,7 @@ struct iwl_beacon_notif {   * @gp2: last beacon time in gp2   */  struct iwl_extended_beacon_notif_v5 { -	struct iwl_mvm_tx_resp beacon_notify_hdr; +	struct iwl_tx_resp beacon_notify_hdr;  	__le64 tsf;  	__le32 ibss_mgr_status;  	__le32 gp2; @@ -858,7 +869,7 @@ struct iwl_extended_beacon_notif {  /**   * enum iwl_dump_control - dump (flush) control flags - * @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty + * @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the FIFO is empty   *	and the TFD queues are empty.   */  enum iwl_dump_control { diff --git a/sys/contrib/dev/iwlwifi/fw/dbg.c b/sys/contrib/dev/iwlwifi/fw/dbg.c index 57e1cdec6b27..e3d7e484daeb 100644 --- a/sys/contrib/dev/iwlwifi/fw/dbg.c +++ b/sys/contrib/dev/iwlwifi/fw/dbg.c @@ -1,6 +1,6 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /* - * Copyright (C) 2005-2014, 2018-2024 Intel Corporation + * Copyright (C) 2005-2014, 2018-2025 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2015-2017 Intel Deutschland GmbH   */ @@ -190,7 +190,7 @@ static void iwl_fw_dump_rxf(struct iwl_fw_runtime *fwrt,  		/* Pull RXF2 */  		iwl_fwrt_dump_rxf(fwrt, dump_data, cfg->rxfifo2_size,  				  RXF_DIFF_FROM_PREV + -				  fwrt->trans->trans_cfg->umac_prph_offset, 1); +				  fwrt->trans->mac_cfg->umac_prph_offset, 1);  		/* Pull LMAC2 RXF1 */  		if (fwrt->smem_cfg.num_lmacs > 1)  			iwl_fwrt_dump_rxf(fwrt, dump_data, @@ -561,41 +561,71 @@ static void iwl_dump_prph(struct iwl_fw_runtime *fwrt,  }  /* - * alloc_sgtable - allocates scallerlist table in the given size, - * fills it with pages and returns it + * alloc_sgtable - allocates (chained) scatterlist in the given size, + *	fills it with pages and returns it   * @size: the size (in bytes) of the table -*/ -static struct scatterlist *alloc_sgtable(int size) + */ +static struct scatterlist *alloc_sgtable(ssize_t size)  { -	int alloc_size, nents, i; -	struct page *new_page; -	struct scatterlist *iter; -	struct scatterlist *table; +	struct scatterlist *result = NULL, *prev; +	int nents, i, n_prev;  	nents = DIV_ROUND_UP(size, PAGE_SIZE); -	table = kcalloc(nents, sizeof(*table), GFP_KERNEL); -	if (!table) -		return NULL; -	sg_init_table(table, nents); -	iter = table; -	for_each_sg(table, iter, sg_nents(table), i) { -		new_page = alloc_page(GFP_KERNEL); -		if (!new_page) { -			/* release all previous allocated pages in the table */ -			iter = table; -			for_each_sg(table, iter, sg_nents(table), i) { -				new_page = sg_page(iter); -				if (new_page) -					__free_page(new_page); -			} -			kfree(table); + +#define N_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(*result)) +	/* +	 * We need an additional entry for table chaining, +	 * this ensures the loop can finish i.e. we can +	 * fit at least two entries per page (obviously, +	 * many more really fit.) +	 */ +	BUILD_BUG_ON(N_ENTRIES_PER_PAGE < 2); + +	while (nents > 0) { +		struct scatterlist *new, *iter; +		int n_fill, n_alloc; + +		if (nents <= N_ENTRIES_PER_PAGE) { +			/* last needed table */ +			n_fill = nents; +			n_alloc = nents; +			nents = 0; +		} else { +			/* fill a page with entries */ +			n_alloc = N_ENTRIES_PER_PAGE; +			/* reserve one for chaining */ +			n_fill = n_alloc - 1; +			nents -= n_fill; +		} + +		new = kcalloc(n_alloc, sizeof(*new), GFP_KERNEL); +		if (!new) { +			if (result) +				_devcd_free_sgtable(result);  			return NULL;  		} -		alloc_size = min_t(int, size, PAGE_SIZE); -		size -= PAGE_SIZE; -		sg_set_page(iter, new_page, alloc_size, 0); +		sg_init_table(new, n_alloc); + +		if (!result) +			result = new; +		else +			sg_chain(prev, n_prev, new); +		prev = new; +		n_prev = n_alloc; + +		for_each_sg(new, iter, n_fill, i) { +			struct page *new_page = alloc_page(GFP_KERNEL); + +			if (!new_page) { +				_devcd_free_sgtable(result); +				return NULL; +			} + +			sg_set_page(iter, new_page, PAGE_SIZE, 0); +		}  	} -	return table; + +	return result;  }  static void iwl_fw_get_prph_len(struct iwl_fw_runtime *fwrt, @@ -627,10 +657,10 @@ static void iwl_fw_prph_handler(struct iwl_fw_runtime *fwrt, void *ptr,  {  	u32 range_len; -	if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { +	if (fwrt->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {  		range_len = ARRAY_SIZE(iwl_prph_dump_addr_ax210);  		handler(fwrt, iwl_prph_dump_addr_ax210, range_len, ptr); -	} else if (fwrt->trans->trans_cfg->device_family >= +	} else if (fwrt->trans->mac_cfg->device_family >=  		   IWL_DEVICE_FAMILY_22000) {  		range_len = ARRAY_SIZE(iwl_prph_dump_addr_22000);  		handler(fwrt, iwl_prph_dump_addr_22000, range_len, ptr); @@ -638,7 +668,7 @@ static void iwl_fw_prph_handler(struct iwl_fw_runtime *fwrt, void *ptr,  		range_len = ARRAY_SIZE(iwl_prph_dump_addr_comm);  		handler(fwrt, iwl_prph_dump_addr_comm, range_len, ptr); -		if (fwrt->trans->trans_cfg->mq_rx_supported) { +		if (fwrt->trans->mac_cfg->mq_rx_supported) {  			range_len = ARRAY_SIZE(iwl_prph_dump_addr_9000);  			handler(fwrt, iwl_prph_dump_addr_9000, range_len, ptr);  		} @@ -782,13 +812,14 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,  	const struct iwl_fw_dbg_mem_seg_tlv *fw_mem = fwrt->fw->dbg.mem_tlv;  	struct iwl_fwrt_shared_mem_cfg *mem_cfg = &fwrt->smem_cfg;  	u32 file_len, fifo_len = 0, prph_len = 0, radio_len = 0; -	u32 smem_len = fwrt->fw->dbg.n_mem_tlv ? 0 : fwrt->trans->cfg->smem_len; +	u32 smem_len = fwrt->fw->dbg.n_mem_tlv ? 0 : fwrt->trans->mac_cfg->base->smem_len;  	u32 sram2_len = fwrt->fw->dbg.n_mem_tlv ?  				0 : fwrt->trans->cfg->dccm2_len;  	int i;  	/* SRAM - include stack CCM if driver knows the values for it */ -	if (!fwrt->trans->cfg->dccm_offset || !fwrt->trans->cfg->dccm_len) { +	if (!fwrt->trans->cfg->dccm_offset || +	    !fwrt->trans->cfg->dccm_len) {  		const struct fw_img *img;  		if (fwrt->cur_fw_img >= IWL_UCODE_TYPE_MAX) @@ -811,7 +842,7 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,  			iwl_fw_prph_handler(fwrt, &prph_len,  					    iwl_fw_get_prph_len); -		if (fwrt->trans->trans_cfg->device_family == +		if (fwrt->trans->mac_cfg->device_family ==  		    IWL_DEVICE_FAMILY_7000 &&  		    iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_RADIO_REG))  			radio_len = sizeof(*dump_data) + RADIO_REG_MAX_READ; @@ -849,7 +880,7 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,  	if (iwl_fw_dbg_is_d3_debug_enabled(fwrt) && fwrt->dump.d3_debug_data) {  		file_len += sizeof(*dump_data) + -			fwrt->trans->cfg->d3_debug_data_length * 2; +			fwrt->trans->mac_cfg->base->d3_debug_data_length * 2;  	}  	/* If we only want a monitor dump, reset the file length */ @@ -877,13 +908,14 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,  		dump_data->len = cpu_to_le32(sizeof(*dump_info));  		dump_info = (void *)dump_data->data;  		dump_info->hw_type = -			cpu_to_le32(CSR_HW_REV_TYPE(fwrt->trans->hw_rev)); +			cpu_to_le32(CSR_HW_REV_TYPE(fwrt->trans->info.hw_rev));  		dump_info->hw_step = -			cpu_to_le32(fwrt->trans->hw_rev_step); +			cpu_to_le32(fwrt->trans->info.hw_rev_step);  		memcpy(dump_info->fw_human_readable, fwrt->fw->human_readable,  		       sizeof(dump_info->fw_human_readable)); -		strscpy_pad(dump_info->dev_human_readable, fwrt->trans->name, -			sizeof(dump_info->dev_human_readable)); +		strscpy_pad(dump_info->dev_human_readable, +			    fwrt->trans->info.name, +			    sizeof(dump_info->dev_human_readable));  #if defined(__linux__)  		strscpy_pad(dump_info->bus_human_readable, fwrt->dev->bus->name,  			sizeof(dump_info->bus_human_readable)); @@ -974,7 +1006,7 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,  		}  		iwl_fw_dump_mem(fwrt, &dump_data, smem_len, -				fwrt->trans->cfg->smem_offset, +				fwrt->trans->mac_cfg->base->smem_offset,  				IWL_FW_ERROR_DUMP_MEM_SMEM);  		iwl_fw_dump_mem(fwrt, &dump_data, sram2_len, @@ -983,8 +1015,8 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,  	}  	if (iwl_fw_dbg_is_d3_debug_enabled(fwrt) && fwrt->dump.d3_debug_data) { -		u32 addr = fwrt->trans->cfg->d3_debug_data_base_addr; -		size_t data_size = fwrt->trans->cfg->d3_debug_data_length; +		u32 addr = fwrt->trans->mac_cfg->base->d3_debug_data_base_addr; +		size_t data_size = fwrt->trans->mac_cfg->base->d3_debug_data_length;  		dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_D3_DEBUG_DATA);  		dump_data->len = cpu_to_le32(data_size * 2); @@ -1082,12 +1114,13 @@ static int iwl_dump_ini_prph_phy_iter_common(struct iwl_fw_runtime *fwrt,  	u32 prph_val;  	u32 dphy_state;  	u32 dphy_addr; +	u32 prph_stts;  	int i;  	range->internal_base_addr = cpu_to_le32(addr);  	range->range_data_size = size; -	if (fwrt->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) +	if (fwrt->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210)  		indirect_wr_addr = WMAL_INDRCT_CMD1;  	indirect_wr_addr += le32_to_cpu(offset); @@ -1109,6 +1142,21 @@ static int iwl_dump_ini_prph_phy_iter_common(struct iwl_fw_runtime *fwrt,  		iwl_write_prph_no_grab(fwrt->trans, indirect_wr_addr,  				       WMAL_INDRCT_CMD(addr + i)); + +		if (fwrt->trans->info.hw_rf_id != IWL_CFG_RF_TYPE_JF1 && +		    fwrt->trans->info.hw_rf_id != IWL_CFG_RF_TYPE_JF2 && +		    fwrt->trans->info.hw_rf_id != IWL_CFG_RF_TYPE_HR1 && +		    fwrt->trans->info.hw_rf_id != IWL_CFG_RF_TYPE_HR2) { +			udelay(2); +			prph_stts = iwl_read_prph_no_grab(fwrt->trans, +							  WMAL_MRSPF_STTS); + +			/* Abort dump if status is 0xA5A5A5A2 or FIFO1 empty */ +			if (prph_stts == WMAL_TIMEOUT_VAL || +			    !WMAL_MRSPF_STTS_IS_FIFO1_NOT_EMPTY(prph_stts)) +				break; +		} +  		prph_val = iwl_read_prph_no_grab(fwrt->trans,  						 indirect_rd_addr);  		*val++ = cpu_to_le32(prph_val); @@ -1244,7 +1292,7 @@ static int iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt,  	/* all paged index start from 1 to skip CSS section */  	idx++; -	if (!fwrt->trans->trans_cfg->gen2) +	if (!fwrt->trans->mac_cfg->gen2)  		return _iwl_dump_ini_paging_iter(fwrt, range_ptr, range_len, idx);  	range = range_ptr; @@ -1771,7 +1819,7 @@ iwl_dump_ini_mon_fill_header(struct iwl_fw_runtime *fwrt, u32 alloc_id,  	data->write_ptr = iwl_get_mon_reg(fwrt, alloc_id,  					  &addrs->write_ptr); -	if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { +	if (fwrt->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {  		u32 wrt_ptr = le32_to_cpu(data->write_ptr);  		data->write_ptr = cpu_to_le32(wrt_ptr >> 2); @@ -1798,7 +1846,7 @@ iwl_dump_ini_mon_dram_fill_header(struct iwl_fw_runtime *fwrt,  	u32 alloc_id = le32_to_cpu(reg->dram_alloc_id);  	return iwl_dump_ini_mon_fill_header(fwrt, alloc_id, mon_dump, -					    &fwrt->trans->cfg->mon_dram_regs); +					    &fwrt->trans->mac_cfg->base->mon_dram_regs);  }  static void * @@ -1811,7 +1859,7 @@ iwl_dump_ini_mon_smem_fill_header(struct iwl_fw_runtime *fwrt,  	u32 alloc_id = le32_to_cpu(reg->internal_buffer.alloc_id);  	return iwl_dump_ini_mon_fill_header(fwrt, alloc_id, mon_dump, -					    &fwrt->trans->cfg->mon_smem_regs); +					    &fwrt->trans->mac_cfg->base->mon_smem_regs);  }  static void * @@ -1825,7 +1873,7 @@ iwl_dump_ini_mon_dbgi_fill_header(struct iwl_fw_runtime *fwrt,  					    /* no offset calculation later */  					    IWL_FW_INI_ALLOCATION_ID_DBGC1,  					    mon_dump, -					    &fwrt->trans->cfg->mon_dbgi_regs); +					    &fwrt->trans->mac_cfg->base->mon_dbgi_regs);  }  static void * @@ -1890,7 +1938,7 @@ iwl_dump_ini_mem_block_ranges(struct iwl_fw_runtime *fwrt,  static u32 iwl_dump_ini_paging_ranges(struct iwl_fw_runtime *fwrt,  				      struct iwl_dump_ini_region_data *reg_data)  { -	if (fwrt->trans->trans_cfg->gen2) { +	if (fwrt->trans->mac_cfg->gen2) {  		if (fwrt->trans->init_dram.paging_cnt)  			return fwrt->trans->init_dram.paging_cnt - 1;  		else @@ -2002,7 +2050,7 @@ iwl_dump_ini_paging_get_size(struct iwl_fw_runtime *fwrt,  	/* start from 1 to skip CSS section */  	for (i = 1; i <= iwl_dump_ini_paging_ranges(fwrt, reg_data); i++) {  		size += range_header_len; -		if (fwrt->trans->trans_cfg->gen2) +		if (fwrt->trans->mac_cfg->gen2)  			size += fwrt->trans->init_dram.paging[i].size;  		else  			size += fwrt->fw_paging_db[i].fw_paging_size; @@ -2364,7 +2412,7 @@ static u32 iwl_dump_ini_info(struct iwl_fw_runtime *fwrt,  	struct iwl_fw_ini_dump_cfg_name *cfg_name;  	u32 size = sizeof(*tlv) + sizeof(*dump);  	u32 num_of_cfg_names = 0; -	u32 hw_type; +	u32 hw_type, is_cdb, is_jacket;  	list_for_each_entry(node, &fwrt->trans->dbg.debug_info_tlv_list, list) {  		size += sizeof(*cfg_name); @@ -2392,33 +2440,24 @@ static u32 iwl_dump_ini_info(struct iwl_fw_runtime *fwrt,  	dump->ver_type = cpu_to_le32(fwrt->dump.fw_ver.type);  	dump->ver_subtype = cpu_to_le32(fwrt->dump.fw_ver.subtype); -	dump->hw_step = cpu_to_le32(fwrt->trans->hw_rev_step); +	dump->hw_step = cpu_to_le32(fwrt->trans->info.hw_rev_step); -	/* -	 * Several HWs all have type == 0x42, so we'll override this value -	 * according to the detected HW -	 */ -	hw_type = CSR_HW_REV_TYPE(fwrt->trans->hw_rev); -	if (hw_type == IWL_AX210_HW_TYPE) { -		u32 prph_val = iwl_read_umac_prph(fwrt->trans, WFPM_OTP_CFG1_ADDR); -		u32 is_jacket = !!(prph_val & WFPM_OTP_CFG1_IS_JACKET_BIT); -		u32 is_cdb = !!(prph_val & WFPM_OTP_CFG1_IS_CDB_BIT); -		u32 masked_bits = is_jacket | (is_cdb << 1); +	hw_type = CSR_HW_REV_TYPE(fwrt->trans->info.hw_rev); + +	is_cdb = CSR_HW_RFID_IS_CDB(fwrt->trans->info.hw_rf_id); +	is_jacket = !!(iwl_read_umac_prph(fwrt->trans, WFPM_OTP_CFG1_ADDR) & +				WFPM_OTP_CFG1_IS_JACKET_BIT); + +	/* Use bits 12 and 13 to indicate jacket/CDB, respectively */ +	hw_type |= (is_jacket | (is_cdb << 1)) << IWL_JACKET_CDB_SHIFT; -		/* -		 * The HW type depends on certain bits in this case, so add -		 * these bits to the HW type. We won't have collisions since we -		 * add these bits after the highest possible bit in the mask. -		 */ -		hw_type |= masked_bits << IWL_AX210_HW_TYPE_ADDITION_SHIFT; -	}  	dump->hw_type = cpu_to_le32(hw_type);  	dump->rf_id_flavor = -		cpu_to_le32(CSR_HW_RFID_FLAVOR(fwrt->trans->hw_rf_id)); -	dump->rf_id_dash = cpu_to_le32(CSR_HW_RFID_DASH(fwrt->trans->hw_rf_id)); -	dump->rf_id_step = cpu_to_le32(CSR_HW_RFID_STEP(fwrt->trans->hw_rf_id)); -	dump->rf_id_type = cpu_to_le32(CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id)); +		cpu_to_le32(CSR_HW_RFID_FLAVOR(fwrt->trans->info.hw_rf_id)); +	dump->rf_id_dash = cpu_to_le32(CSR_HW_RFID_DASH(fwrt->trans->info.hw_rf_id)); +	dump->rf_id_step = cpu_to_le32(CSR_HW_RFID_STEP(fwrt->trans->info.hw_rf_id)); +	dump->rf_id_type = cpu_to_le32(CSR_HW_RFID_TYPE(fwrt->trans->info.hw_rf_id));  	dump->lmac_major = cpu_to_le32(fwrt->dump.fw_ver.lmac_major);  	dump->lmac_minor = cpu_to_le32(fwrt->dump.fw_ver.lmac_minor); @@ -2607,29 +2646,34 @@ static const struct iwl_dump_ini_mem_ops iwl_dump_ini_region_ops[] = {  	},  }; -static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt, -				struct iwl_fwrt_dump_data *dump_data, -				struct list_head *list) +enum iwl_dump_ini_region_selector { +	IWL_INI_DUMP_ALL_REGIONS, +	IWL_INI_DUMP_EARLY_REGIONS, +	IWL_INI_DUMP_LATE_REGIONS, +}; + +static bool iwl_dump_due_to_error(enum iwl_fw_ini_time_point tp_id)  { -	struct iwl_fw_ini_trigger_tlv *trigger = dump_data->trig; -	enum iwl_fw_ini_time_point tp_id = le32_to_cpu(trigger->time_point); -	struct iwl_dump_ini_region_data reg_data = { -		.dump_data = dump_data, -	}; -	struct iwl_dump_ini_region_data imr_reg_data = { -		.dump_data = dump_data, -	}; -	int i; -	u32 size = 0; -	u64 regions_mask = le64_to_cpu(trigger->regions_mask) & -			   ~(fwrt->trans->dbg.unsupported_region_msk); +	return tp_id == IWL_FW_INI_TIME_POINT_FW_ASSERT || +	       tp_id == IWL_FW_INI_TIME_POINT_FW_HW_ERROR; +} -	BUILD_BUG_ON(sizeof(trigger->regions_mask) != sizeof(regions_mask)); -	BUILD_BUG_ON((sizeof(trigger->regions_mask) * BITS_PER_BYTE) < -		     ARRAY_SIZE(fwrt->trans->dbg.active_regions)); +static u32 +iwl_dump_ini_dump_regions(struct iwl_fw_runtime *fwrt, +			  struct iwl_fwrt_dump_data *dump_data, +			  struct list_head *list, +			  enum iwl_fw_ini_time_point tp_id, +			  u64 regions_mask, +			  struct iwl_dump_ini_region_data *imr_reg_data, +			  enum iwl_dump_ini_region_selector which) +{ +	u32 size = 0; -	for (i = 0; i < ARRAY_SIZE(fwrt->trans->dbg.active_regions); i++) { -		u32 reg_type; +	for (int i = 0; i < ARRAY_SIZE(fwrt->trans->dbg.active_regions); i++) { +		struct iwl_dump_ini_region_data reg_data = { +			.dump_data = dump_data, +		}; +		u32 reg_type, dp;  		struct iwl_fw_ini_region_tlv *reg;  		if (!(BIT_ULL(i) & regions_mask)) @@ -2647,6 +2691,8 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt,  		if (reg_type >= ARRAY_SIZE(iwl_dump_ini_region_ops))  			continue; +		dp = le32_get_bits(reg->id, IWL_FW_INI_REGION_DUMP_POLICY_MASK); +  		if ((reg_type == IWL_FW_INI_REGION_PERIPHERY_PHY ||  		     reg_type == IWL_FW_INI_REGION_PERIPHERY_PHY_RANGE ||  		     reg_type == IWL_FW_INI_REGION_PERIPHERY_SNPS_DPHYIP) && @@ -2656,6 +2702,20 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt,  				 tp_id);  			continue;  		} + +		switch (which) { +		case IWL_INI_DUMP_ALL_REGIONS: +			break; +		case IWL_INI_DUMP_EARLY_REGIONS: +			if (!(dp & IWL_FW_IWL_DEBUG_DUMP_POLICY_BEFORE_RESET)) +				continue; +			break; +		case IWL_INI_DUMP_LATE_REGIONS: +			if (dp & IWL_FW_IWL_DEBUG_DUMP_POLICY_BEFORE_RESET) +				continue; +			break; +		} +  		/*  		 * DRAM_IMR can be collected only for FW/HW error timepoint  		 * when fw is not alive. In addition, it must be collected @@ -2663,9 +2723,9 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt,  		 * debug data which also need to be collected.  		 */  		if (reg_type == IWL_FW_INI_REGION_DRAM_IMR) { -			if (tp_id == IWL_FW_INI_TIME_POINT_FW_ASSERT || -			    tp_id == IWL_FW_INI_TIME_POINT_FW_HW_ERROR) -				imr_reg_data.reg_tlv = fwrt->trans->dbg.active_regions[i]; +			if (iwl_dump_due_to_error(tp_id)) +				imr_reg_data->reg_tlv = +					fwrt->trans->dbg.active_regions[i];  			else  				IWL_INFO(fwrt,  					 "WRT: trying to collect DRAM_IMR at time point: %d, skipping\n", @@ -2678,9 +2738,48 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt,  		size += iwl_dump_ini_mem(fwrt, list, ®_data,  					 &iwl_dump_ini_region_ops[reg_type]);  	} + +	return size; +} + +static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt, +				struct iwl_fwrt_dump_data *dump_data, +				struct list_head *list) +{ +	struct iwl_fw_ini_trigger_tlv *trigger = dump_data->trig; +	enum iwl_fw_ini_time_point tp_id = le32_to_cpu(trigger->time_point); +	struct iwl_dump_ini_region_data imr_reg_data = { +		.dump_data = dump_data, +	}; +	u32 size = 0; +	u64 regions_mask = le64_to_cpu(trigger->regions_mask) & +			   ~(fwrt->trans->dbg.unsupported_region_msk); + +	BUILD_BUG_ON(sizeof(trigger->regions_mask) != sizeof(regions_mask)); +	BUILD_BUG_ON((sizeof(trigger->regions_mask) * BITS_PER_BYTE) < +		     ARRAY_SIZE(fwrt->trans->dbg.active_regions)); + +	if (trigger->apply_policy & +			cpu_to_le32(IWL_FW_INI_APPLY_POLICY_SPLIT_DUMP_RESET)) { +		size += iwl_dump_ini_dump_regions(fwrt, dump_data, list, tp_id, +						  regions_mask, &imr_reg_data, +						  IWL_INI_DUMP_EARLY_REGIONS); +		iwl_trans_pcie_fw_reset_handshake(fwrt->trans); +		size += iwl_dump_ini_dump_regions(fwrt, dump_data, list, tp_id, +						  regions_mask, &imr_reg_data, +						  IWL_INI_DUMP_LATE_REGIONS); +	} else { +		if (fw_has_capa(&fwrt->fw->ucode_capa, +				IWL_UCODE_TLV_CAPA_RESET_DURING_ASSERT) && +		    iwl_dump_due_to_error(tp_id)) +			iwl_trans_pcie_fw_reset_handshake(fwrt->trans); +		size += iwl_dump_ini_dump_regions(fwrt, dump_data, list, tp_id, +						  regions_mask, &imr_reg_data, +						  IWL_INI_DUMP_ALL_REGIONS); +	}  	/* collect DRAM_IMR region in the last */  	if (imr_reg_data.reg_tlv) -		size += iwl_dump_ini_mem(fwrt, list, ®_data, +		size += iwl_dump_ini_mem(fwrt, list, &imr_reg_data,  					 &iwl_dump_ini_region_ops[IWL_FW_INI_REGION_DRAM_IMR]);  	if (size) { @@ -2902,7 +3001,7 @@ IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect_desc);  int iwl_fw_dbg_error_collect(struct iwl_fw_runtime *fwrt,  			     enum iwl_fw_dbg_trigger trig_type)  { -	if (!test_bit(STATUS_DEVICE_ENABLED, &fwrt->trans->status)) +	if (!iwl_trans_device_enabled(fwrt->trans))  		return -EIO;  	if (iwl_trans_dbg_ini_valid(fwrt->trans)) { @@ -2948,6 +3047,7 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,  	struct iwl_fw_dump_desc *desc;  	unsigned int delay = 0;  	bool monitor_only = false; +	int ret;  	if (trigger) {  		u16 occurrences = le16_to_cpu(trigger->occurrences) - 1; @@ -2978,7 +3078,11 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,  	desc->trig_desc.type = cpu_to_le32(trig);  	memcpy(desc->trig_desc.data, str, len); -	return iwl_fw_dbg_collect_desc(fwrt, desc, monitor_only, delay); +	ret = iwl_fw_dbg_collect_desc(fwrt, desc, monitor_only, delay); +	if (ret) +		kfree(desc); + +	return ret;  }  IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect); @@ -2986,7 +3090,7 @@ int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,  			    struct iwl_fw_dbg_trigger_tlv *trigger,  			    const char *fmt, ...)  { -	int ret, len = 0; +	int len = 0;  	char buf[64];  	if (iwl_trans_dbg_ini_valid(fwrt->trans)) @@ -3008,13 +3112,8 @@ int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,  		len = strlen(buf) + 1;  	} -	ret = iwl_fw_dbg_collect(fwrt, le32_to_cpu(trigger->id), buf, len, -				 trigger); - -	if (ret) -		return ret; - -	return 0; +	return iwl_fw_dbg_collect(fwrt, le32_to_cpu(trigger->id), buf, len, +				  trigger);  }  IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect_trig); @@ -3065,9 +3164,8 @@ int iwl_fw_start_dbg_conf(struct iwl_fw_runtime *fwrt, u8 conf_id)  }  IWL_EXPORT_SYMBOL(iwl_fw_start_dbg_conf); -void iwl_send_dbg_dump_complete_cmd(struct iwl_fw_runtime *fwrt, -				    u32 timepoint, -				    u32 timepoint_data) +static void iwl_send_dbg_dump_complete_cmd(struct iwl_fw_runtime *fwrt, +					   u32 timepoint, u32 timepoint_data)  {  	struct iwl_dbg_dump_complete_cmd hcmd_data;  	struct iwl_host_cmd hcmd = { @@ -3095,6 +3193,7 @@ static void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt, u8 wk_idx)  	struct iwl_fw_dbg_params params = {0};  	struct iwl_fwrt_dump_data *dump_data =  		&fwrt->dump.wks[wk_idx].dump_data; +  	if (!test_bit(wk_idx, &fwrt->dump.active_wks))  		return; @@ -3104,13 +3203,13 @@ static void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt, u8 wk_idx)  		goto out;  	} -	if (!test_bit(STATUS_DEVICE_ENABLED, &fwrt->trans->status)) { +	if (!iwl_trans_device_enabled(fwrt->trans)) {  		IWL_ERR(fwrt, "Device is not enabled - cannot dump error\n");  		goto out;  	}  	/* there's no point in fw dump if the bus is dead */ -	if (test_bit(STATUS_TRANS_DEAD, &fwrt->trans->status)) { +	if (iwl_trans_is_dead(fwrt->trans)) {  		IWL_ERR(fwrt, "Skip fw error dump since bus is dead\n");  		goto out;  	} @@ -3119,9 +3218,9 @@ static void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt, u8 wk_idx)  	IWL_DEBUG_FW_INFO(fwrt, "WRT: Data collection start\n");  	if (iwl_trans_dbg_ini_valid(fwrt->trans)) -		iwl_fw_error_ini_dump(fwrt, &fwrt->dump.wks[wk_idx].dump_data); +		iwl_fw_error_ini_dump(fwrt, dump_data);  	else -		iwl_fw_error_dump(fwrt, &fwrt->dump.wks[wk_idx].dump_data); +		iwl_fw_error_dump(fwrt, dump_data);  	IWL_DEBUG_FW_INFO(fwrt, "WRT: Data collection done\n");  	iwl_fw_dbg_stop_restart_recording(fwrt, ¶ms, false); @@ -3138,7 +3237,6 @@ static void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt, u8 wk_idx)  	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); @@ -3225,13 +3323,13 @@ void iwl_fw_error_dump_wk(struct work_struct *work)  void iwl_fw_dbg_read_d3_debug_data(struct iwl_fw_runtime *fwrt)  { -	const struct iwl_cfg *cfg = fwrt->trans->cfg; +	const struct iwl_mac_cfg *mac_cfg = fwrt->trans->mac_cfg;  	if (!iwl_fw_dbg_is_d3_debug_enabled(fwrt))  		return;  	if (!fwrt->dump.d3_debug_data) { -		fwrt->dump.d3_debug_data = kmalloc(cfg->d3_debug_data_length, +		fwrt->dump.d3_debug_data = kmalloc(mac_cfg->base->d3_debug_data_length,  						   GFP_KERNEL);  		if (!fwrt->dump.d3_debug_data) {  			IWL_ERR(fwrt, @@ -3241,15 +3339,15 @@ void iwl_fw_dbg_read_d3_debug_data(struct iwl_fw_runtime *fwrt)  	}  	/* if the buffer holds previous debug data it is overwritten */ -	iwl_trans_read_mem_bytes(fwrt->trans, cfg->d3_debug_data_base_addr, +	iwl_trans_read_mem_bytes(fwrt->trans, mac_cfg->base->d3_debug_data_base_addr,  				 fwrt->dump.d3_debug_data, -				 cfg->d3_debug_data_length); +				 mac_cfg->base->d3_debug_data_length);  	if (fwrt->sanitize_ops && fwrt->sanitize_ops->frob_mem)  		fwrt->sanitize_ops->frob_mem(fwrt->sanitize_ctx, -					     cfg->d3_debug_data_base_addr, +					     mac_cfg->base->d3_debug_data_base_addr,  					     fwrt->dump.d3_debug_data, -					     cfg->d3_debug_data_length); +					     mac_cfg->base->d3_debug_data_length);  }  IWL_EXPORT_SYMBOL(iwl_fw_dbg_read_d3_debug_data); @@ -3284,7 +3382,7 @@ static int iwl_fw_dbg_suspend_resume_hcmd(struct iwl_trans *trans, bool suspend)  static void iwl_fw_dbg_stop_recording(struct iwl_trans *trans,  				      struct iwl_fw_dbg_params *params)  { -	if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000) { +	if (trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_7000) {  		iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100);  		return;  	} @@ -3308,7 +3406,7 @@ static int iwl_fw_dbg_restart_recording(struct iwl_trans *trans,  	if (!params)  		return -EIO; -	if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000) { +	if (trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_7000) {  		iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100);  		iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1);  		iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1); @@ -3410,7 +3508,7 @@ void iwl_fw_disable_dbg_asserts(struct iwl_fw_runtime *fwrt)  				  GENMASK(31, IWL_FW_DBG_DOMAIN_POS + 1));  	/* supported starting from 9000 devices */ -	if (fwrt->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000) +	if (fwrt->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_9000)  		return;  	if (fwrt->trans->dbg.yoyo_bin_loaded || (preset && preset != 1)) diff --git a/sys/contrib/dev/iwlwifi/fw/dbg.h b/sys/contrib/dev/iwlwifi/fw/dbg.h index 7ef061e090c7..87ccfc174fdc 100644 --- a/sys/contrib/dev/iwlwifi/fw/dbg.h +++ b/sys/contrib/dev/iwlwifi/fw/dbg.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2005-2014, 2018-2019, 2021-2023 Intel Corporation + * Copyright (C) 2005-2014, 2018-2019, 2021-2025 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2015-2017 Intel Deutschland GmbH   */ @@ -205,7 +205,7 @@ static inline bool iwl_fw_dbg_is_d3_debug_enabled(struct iwl_fw_runtime *fwrt)  {  	return fw_has_capa(&fwrt->fw->ucode_capa,  			   IWL_UCODE_TLV_CAPA_D3_DEBUG) && -		fwrt->trans->cfg->d3_debug_data_length && fwrt->ops && +		fwrt->trans->mac_cfg->base->d3_debug_data_length && fwrt->ops &&  		fwrt->ops->d3_debug_enable &&  		fwrt->ops->d3_debug_enable(fwrt->ops_ctx) &&  		iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_D3_DEBUG_DATA); @@ -214,7 +214,7 @@ static inline bool iwl_fw_dbg_is_d3_debug_enabled(struct iwl_fw_runtime *fwrt)  static inline bool iwl_fw_dbg_is_paging_enabled(struct iwl_fw_runtime *fwrt)  {  	return iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_PAGING) && -		!fwrt->trans->trans_cfg->gen2 && +		!fwrt->trans->mac_cfg->gen2 &&  		fwrt->cur_fw_img < IWL_UCODE_TYPE_MAX &&  		fwrt->fw->img[fwrt->cur_fw_img].paging_mem_size &&  		fwrt->fw_paging_db[0].fw_paging_block; @@ -291,7 +291,7 @@ static inline void iwl_fw_umac_set_alive_err_table(struct iwl_trans *trans,  		trans->dbg.umac_error_event_table = umac_error_event_table;  } -static inline void iwl_fw_error_collect(struct iwl_fw_runtime *fwrt, bool sync) +static inline void iwl_fw_error_collect(struct iwl_fw_runtime *fwrt)  {  	enum iwl_fw_ini_time_point tp_id; @@ -307,7 +307,7 @@ static inline void iwl_fw_error_collect(struct iwl_fw_runtime *fwrt, bool sync)  		tp_id = IWL_FW_INI_TIME_POINT_FW_ASSERT;  	} -	_iwl_dbg_tlv_time_point(fwrt, tp_id, NULL, sync); +	iwl_dbg_tlv_time_point_sync(fwrt, tp_id, NULL);  }  static inline void iwl_fwrt_update_fw_versions(struct iwl_fw_runtime *fwrt, @@ -328,21 +328,19 @@ static inline void iwl_fwrt_update_fw_versions(struct iwl_fw_runtime *fwrt,  }  void iwl_fwrt_dump_error_logs(struct iwl_fw_runtime *fwrt); -void iwl_send_dbg_dump_complete_cmd(struct iwl_fw_runtime *fwrt, -				    u32 timepoint, -				    u32 timepoint_data); +bool iwl_fwrt_read_err_table(struct iwl_trans *trans, u32 base, u32 *err_id);  void iwl_fw_disable_dbg_asserts(struct iwl_fw_runtime *fwrt);  void iwl_fw_dbg_clear_monitor_buf(struct iwl_fw_runtime *fwrt); -#define IWL_FW_CHECK_FAILED(_obj, _fmt, ...)				\ -	IWL_ERR_LIMIT(_obj, _fmt, __VA_ARGS__) +#define IWL_FW_CHECK_FAILED(_obj, ...)					\ +	IWL_ERR_LIMIT(_obj, __VA_ARGS__)  #define IWL_FW_CHECK(_obj, _cond, _fmt, ...)				\  	({								\  		bool __cond = (_cond);					\  									\  		if (unlikely(__cond))					\ -			IWL_FW_CHECK_FAILED(_obj, _fmt, __VA_ARGS__);	\ +			IWL_FW_CHECK_FAILED(_obj, _fmt, ##__VA_ARGS__);	\  									\  		unlikely(__cond);					\  	}) diff --git a/sys/contrib/dev/iwlwifi/fw/debugfs.c b/sys/contrib/dev/iwlwifi/fw/debugfs.c index 893b21fcaf87..3b0e8c43ba4a 100644 --- a/sys/contrib/dev/iwlwifi/fw/debugfs.c +++ b/sys/contrib/dev/iwlwifi/fw/debugfs.c @@ -1,6 +1,6 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /* - * Copyright (C) 2012-2014, 2018-2023 Intel Corporation + * Copyright (C) 2012-2014, 2018-2024 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2016-2017 Intel Deutschland GmbH   */ @@ -123,6 +123,24 @@ static const struct file_operations iwl_dbgfs_##name##_ops = {		\  #define FWRT_DEBUGFS_ADD_FILE(name, parent, mode) \  	FWRT_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode) +static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_fw_runtime *fwrt, +					      char *buf, size_t count) +{ +	if (count == 0) +		return 0; + +	if (!iwl_trans_fw_running(fwrt->trans)) +		return count; + +	iwl_dbg_tlv_time_point(fwrt, IWL_FW_INI_TIME_POINT_USER_TRIGGER, NULL); + +	iwl_fw_dbg_collect(fwrt, FW_DBG_TRIGGER_USER, buf, (count - 1), NULL); + +	return count; +} + +FWRT_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 16); +  static int iwl_dbgfs_enabled_severities_write(struct iwl_fw_runtime *fwrt,  					      char *buf, size_t count)  { @@ -180,7 +198,7 @@ void iwl_fw_trigger_timestamp(struct iwl_fw_runtime *fwrt, u32 delay)  	iwl_fw_cancel_timestamp(fwrt); -	fwrt->timestamp.delay = msecs_to_jiffies(delay * 1000); +	fwrt->timestamp.delay = secs_to_jiffies(delay);  	schedule_delayed_work(&fwrt->timestamp.wk,  			      round_jiffies_relative(fwrt->timestamp.delay)); @@ -282,6 +300,26 @@ static ssize_t iwl_dbgfs_fw_dbg_domain_read(struct iwl_fw_runtime *fwrt,  FWRT_DEBUGFS_READ_FILE_OPS(fw_dbg_domain, 20); +static ssize_t iwl_dbgfs_fw_ver_read(struct iwl_fw_runtime *fwrt, +				     size_t size, char *buf) +{ +	char *pos = buf; +	char *endpos = buf + size; + +	pos += scnprintf(pos, endpos - pos, "FW id: %s\n", +			 fwrt->fw->fw_version); +	pos += scnprintf(pos, endpos - pos, "FW: %s\n", +			 fwrt->fw->human_readable); +	pos += scnprintf(pos, endpos - pos, "Device: %s\n", +			 fwrt->trans->info.name); +	pos += scnprintf(pos, endpos - pos, "Bus: %s\n", +			 fwrt->dev->bus->name); + +	return pos - buf; +} + +FWRT_DEBUGFS_READ_FILE_OPS(fw_ver, 1024); +  struct iwl_dbgfs_fw_info_priv {  	struct iwl_fw_runtime *fwrt;  }; @@ -351,6 +389,12 @@ static int iwl_dbgfs_fw_info_seq_show(struct seq_file *seq, void *v)  			   "    %d: %d\n",  			   IWL_UCODE_TLV_CAPA_CHINA_22_REG_SUPPORT,  			   has_capa); +		has_capa = fw_has_capa(&fw->ucode_capa, +				       IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE) ? 1 : 0; +		seq_printf(seq, +			   "    %d: %d\n", +			   IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE, +			   has_capa);  		seq_puts(seq, "fw_api_ver:\n");  	} @@ -403,5 +447,7 @@ void iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt,  	FWRT_DEBUGFS_ADD_FILE(fw_info, dbgfs_dir, 0200);  	FWRT_DEBUGFS_ADD_FILE(send_hcmd, dbgfs_dir, 0200);  	FWRT_DEBUGFS_ADD_FILE(enabled_severities, dbgfs_dir, 0200); +	FWRT_DEBUGFS_ADD_FILE(fw_dbg_collect, dbgfs_dir, 0200);  	FWRT_DEBUGFS_ADD_FILE(fw_dbg_domain, dbgfs_dir, 0400); +	FWRT_DEBUGFS_ADD_FILE(fw_ver, dbgfs_dir, 0400);  } diff --git a/sys/contrib/dev/iwlwifi/fw/dhc-utils.h b/sys/contrib/dev/iwlwifi/fw/dhc-utils.h new file mode 100644 index 000000000000..983acee5cd7d --- /dev/null +++ b/sys/contrib/dev/iwlwifi/fw/dhc-utils.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* + * Copyright (C) 2021, 2025 Intel Corporation + */ +#ifndef __iwl_fw_dhc_utils_h__ +#define __iwl_fw_dhc_utils_h__ + +#include <linux/types.h> +#include "fw/img.h" +#include "api/commands.h" +#include "api/dhc.h" + +/** + * iwl_dhc_resp_status - return status of DHC response + * @fw: firwmware image information + * @pkt: response packet, must not be %NULL + * + * Returns: the status value of the DHC command or (u32)-1 if the + *	    response was too short. + */ +static inline u32 iwl_dhc_resp_status(const struct iwl_fw *fw, +				      struct iwl_rx_packet *pkt) +{ +	if (iwl_fw_lookup_notif_ver(fw, IWL_ALWAYS_LONG_GROUP, +				    DEBUG_HOST_COMMAND, 1) >= 2) { +		struct iwl_dhc_cmd_resp *resp = (void *)pkt->data; + +		if (iwl_rx_packet_payload_len(pkt) < sizeof(*resp)) +			return (u32)-1; + +		return le32_to_cpu(resp->status); +	} else { +		struct iwl_dhc_cmd_resp_v1 *resp = (void *)pkt->data; + +		if (iwl_rx_packet_payload_len(pkt) < sizeof(*resp)) +			return (u32)-1; + +		return le32_to_cpu(resp->status); +	} +} + +/** + * iwl_dhc_resp_data - return data pointer of DHC response + * @fw: firwmware image information + * @pkt: response packet, must not be %NULL + * @len: where to store the length + * + * Returns: The data pointer, or an ERR_PTR() if the data was + *	    not valid (too short). + */ +static inline void *iwl_dhc_resp_data(const struct iwl_fw *fw, +				      struct iwl_rx_packet *pkt, +				      unsigned int *len) +{ +	if (iwl_fw_lookup_notif_ver(fw, IWL_ALWAYS_LONG_GROUP, +				    DEBUG_HOST_COMMAND, 1) >= 2) { +		struct iwl_dhc_cmd_resp *resp = (void *)pkt->data; + +		if (iwl_rx_packet_payload_len(pkt) < sizeof(*resp)) +			return ERR_PTR(-EINVAL); + +		*len = iwl_rx_packet_payload_len(pkt) - sizeof(*resp); +		return (void *)&resp->data; +	} else { +		struct iwl_dhc_cmd_resp_v1 *resp = (void *)pkt->data; + +		if (iwl_rx_packet_payload_len(pkt) < sizeof(*resp)) +			return ERR_PTR(-EINVAL); + +		*len = iwl_rx_packet_payload_len(pkt) - sizeof(*resp); +		return (void *)&resp->data; +	} +} + +#endif  /* __iwl_fw_dhc_utils_h__ */ diff --git a/sys/contrib/dev/iwlwifi/fw/dump.c b/sys/contrib/dev/iwlwifi/fw/dump.c index 8f107ceec407..f633124979ab 100644 --- a/sys/contrib/dev/iwlwifi/fw/dump.c +++ b/sys/contrib/dev/iwlwifi/fw/dump.c @@ -1,6 +1,6 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /* - * Copyright (C) 2012-2014, 2018-2023 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation   * Copyright (C) 2013-2014 Intel Mobile Communications GmbH   * Copyright (C) 2015-2017 Intel Deutschland GmbH   */ @@ -199,7 +199,7 @@ 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 */ -		err = iwl_trans_sw_reset(trans, true); +		err = iwl_trans_sw_reset(trans);  		if (err)  			return; @@ -417,10 +417,10 @@ static void iwl_fwrt_dump_iml_error_log(struct iwl_fw_runtime *fwrt)  	struct iwl_trans *trans = fwrt->trans;  	u32 error, data1; -	if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { +	if (fwrt->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_22000) {  		error = UMAG_SB_CPU_2_STATUS;  		data1 = UMAG_SB_CPU_1_STATUS; -	} else if (fwrt->trans->trans_cfg->device_family >= +	} else if (fwrt->trans->mac_cfg->device_family >=  		   IWL_DEVICE_FAMILY_8000) {  		error = SB_CPU_2_STATUS;  		data1 = SB_CPU_1_STATUS; @@ -439,7 +439,7 @@ static void iwl_fwrt_dump_iml_error_log(struct iwl_fw_runtime *fwrt)  	IWL_ERR(fwrt, "0x%08X | IML/ROM data1\n",  		iwl_read_umac_prph(trans, data1)); -	if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) +	if (fwrt->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_22000)  		IWL_ERR(fwrt, "0x%08X | IML/ROM WFPM_AUTH_KEY_0\n",  			iwl_read_umac_prph(trans, SB_MODIFY_CFG_FLAG));  } @@ -490,7 +490,7 @@ void iwl_fwrt_dump_error_logs(struct iwl_fw_runtime *fwrt)  	struct iwl_pc_data *pc_data;  	u8 count; -	if (!test_bit(STATUS_DEVICE_ENABLED, &fwrt->trans->status)) { +	if (!iwl_trans_device_enabled(fwrt->trans)) {  		IWL_ERR(fwrt,  			"DEVICE_ENABLED bit is not set. Aborting dump.\n");  		return; @@ -508,7 +508,7 @@ void iwl_fwrt_dump_error_logs(struct iwl_fw_runtime *fwrt)  		iwl_fwrt_dump_rcm_error_log(fwrt, 1);  	iwl_fwrt_dump_iml_error_log(fwrt);  	iwl_fwrt_dump_fseq_regs(fwrt); -	if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { +	if (fwrt->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_22000) {  		pc_data = fwrt->trans->dbg.pc_data;  		if (!iwl_trans_grab_nic_access(fwrt->trans)) @@ -522,7 +522,7 @@ void iwl_fwrt_dump_error_logs(struct iwl_fw_runtime *fwrt)  		iwl_trans_release_nic_access(fwrt->trans);  	} -	if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { +	if (fwrt->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {  		u32 scratch = iwl_read32(fwrt->trans, CSR_FUNC_SCRATCH);  		IWL_ERR(fwrt, "Function Scratch status:\n"); @@ -530,3 +530,31 @@ void iwl_fwrt_dump_error_logs(struct iwl_fw_runtime *fwrt)  	}  }  IWL_EXPORT_SYMBOL(iwl_fwrt_dump_error_logs); + +bool iwl_fwrt_read_err_table(struct iwl_trans *trans, u32 base, u32 *err_id) +{ +	struct error_table_start { +		/* cf. struct iwl_error_event_table */ +		u32 valid; +		__le32 err_id; +	} err_info = {}; +	int ret; + +	if (err_id) +		*err_id = 0; + +	if (!base) +		return false; + +	ret = iwl_trans_read_mem_bytes(trans, base, +				       &err_info, sizeof(err_info)); + +	if (ret) +		return true; + +	if (err_info.valid && err_id) +		*err_id = le32_to_cpu(err_info.err_id); + +	return !!err_info.valid; +} +IWL_EXPORT_SYMBOL(iwl_fwrt_read_err_table); diff --git a/sys/contrib/dev/iwlwifi/fw/error-dump.h b/sys/contrib/dev/iwlwifi/fw/error-dump.h index e63b08b7d336..cf41021d59ad 100644 --- a/sys/contrib/dev/iwlwifi/fw/error-dump.h +++ b/sys/contrib/dev/iwlwifi/fw/error-dump.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2014, 2018-2024 Intel Corporation + * Copyright (C) 2014, 2018-2025 Intel Corporation   * Copyright (C) 2014-2015 Intel Mobile Communications GmbH   * Copyright (C) 2016-2017 Intel Deutschland GmbH   */ @@ -169,7 +169,7 @@ struct iwl_fw_error_dump_info {   * @fw_mon_wr_ptr: the position of the write pointer in the cyclic buffer   * @fw_mon_base_ptr: base pointer of the data   * @fw_mon_cycle_cnt: number of wraparounds - * @fw_mon_base_high_ptr: used in AX210 devices, the base adderss is 64 bit + * @fw_mon_base_high_ptr: used in AX210 devices, the base address is 64 bit   *	so fw_mon_base_ptr holds LSB 32 bits and fw_mon_base_high_ptr hold   *	MSB 32 bits   * @reserved: for future use @@ -372,10 +372,7 @@ struct iwl_fw_ini_dump_cfg_name {  	u8 cfg_name[IWL_FW_INI_MAX_CFG_NAME];  } __packed; -/* AX210's HW type */ -#define IWL_AX210_HW_TYPE 0x42 -/* How many bits to roll when adding to the HW type of AX210 HW */ -#define IWL_AX210_HW_TYPE_ADDITION_SHIFT 12 +#define IWL_JACKET_CDB_SHIFT 12  /* struct iwl_fw_ini_dump_info - ini dump information   * @version: dump version diff --git a/sys/contrib/dev/iwlwifi/fw/file.h b/sys/contrib/dev/iwlwifi/fw/file.h index ae05227b6153..b7c1ab7a3006 100644 --- a/sys/contrib/dev/iwlwifi/fw/file.h +++ b/sys/contrib/dev/iwlwifi/fw/file.h @@ -102,8 +102,13 @@ enum iwl_ucode_tlv_type {  	IWL_UCODE_TLV_SEC_TABLE_ADDR		= 66,  	IWL_UCODE_TLV_D3_KEK_KCK_ADDR		= 67,  	IWL_UCODE_TLV_CURRENT_PC		= 68, +	IWL_UCODE_TLV_FSEQ_BIN_VERSION		= 72, + +	/* contains sub-sections like PNVM file does (did) */ +	IWL_UCODE_TLV_PNVM_DATA			= 74,  	IWL_UCODE_TLV_FW_NUM_STATIONS		= IWL_UCODE_TLV_CONST_BASE + 0, +	IWL_UCODE_TLV_FW_NUM_LINKS		= IWL_UCODE_TLV_CONST_BASE + 1,  	IWL_UCODE_TLV_FW_NUM_BEACONS		= IWL_UCODE_TLV_CONST_BASE + 2,  	IWL_UCODE_TLV_TYPE_DEBUG_INFO		= IWL_UCODE_TLV_DEBUG_BASE + 0, @@ -384,7 +389,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t;   *	to report the CSI information with (certain) RX frames   * @IWL_UCODE_TLV_CAPA_FTM_CALIBRATED: has FTM calibrated and thus supports both   *	initiator and responder - * @IWL_UCODE_TLV_CAPA_MLME_OFFLOAD: supports MLME offload + * @IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_UNII4_US_CA: supports (de)activating UNII-4 + *	for US/CA/WW from BIOS   * @IWL_UCODE_TLV_CAPA_PROTECTED_TWT: Supports protection of TWT action frames   * @IWL_UCODE_TLV_CAPA_FW_RESET_HANDSHAKE: Supports the firmware handshake in   *	reset flow @@ -397,6 +403,12 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t;   * @IWL_UCODE_TLV_CAPA_SECURE_LTF_SUPPORT: Support secure LTF measurement.   * @IWL_UCODE_TLV_CAPA_MONITOR_PASSIVE_CHANS: Support monitor mode on otherwise   *	passive channels + * @IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_5G9_FOR_CA: supports (de)activating 5G9 + *	for CA from BIOS. + * @IWL_UCODE_TLV_CAPA_UHB_CANADA_TAS_SUPPORT: supports %TAS_UHB_ALLOWED_CANADA + * @IWL_UCODE_TLV_CAPA_EXT_FSEQ_IMAGE_SUPPORT: external FSEQ image support + * @IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE: Firmware has capability of + *	handling raw DSM table data.   *   * @NUM_IWL_UCODE_TLV_CAPA: number of bits used   */ @@ -474,7 +486,7 @@ enum iwl_ucode_tlv_capa {  	IWL_UCODE_TLV_CAPA_DBG_BUF_ALLOC_CMD_SUPP	= (__force iwl_ucode_tlv_capa_t)93,  	/* set 3 */ -	IWL_UCODE_TLV_CAPA_MLME_OFFLOAD			= (__force iwl_ucode_tlv_capa_t)96, +	IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_UNII4_US_CA	= (__force iwl_ucode_tlv_capa_t)96,  	/*  	 * @IWL_UCODE_TLV_CAPA_PSC_CHAN_SUPPORT: supports PSC channels @@ -497,6 +509,17 @@ enum iwl_ucode_tlv_capa {  	IWL_UCODE_TLV_CAPA_CHINA_22_REG_SUPPORT		= (__force iwl_ucode_tlv_capa_t)117,  	IWL_UCODE_TLV_CAPA_SECURE_LTF_SUPPORT		= (__force iwl_ucode_tlv_capa_t)121,  	IWL_UCODE_TLV_CAPA_MONITOR_PASSIVE_CHANS	= (__force iwl_ucode_tlv_capa_t)122, +	IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_5G9_FOR_CA	= (__force iwl_ucode_tlv_capa_t)123, +	IWL_UCODE_TLV_CAPA_UHB_CANADA_TAS_SUPPORT	= (__force iwl_ucode_tlv_capa_t)124, +	IWL_UCODE_TLV_CAPA_EXT_FSEQ_IMAGE_SUPPORT	= (__force iwl_ucode_tlv_capa_t)125, + +	/* set 4 */ +	/** +	 * @IWL_UCODE_TLV_CAPA_RESET_DURING_ASSERT: FW reset handshake is needed +	 *	during assert handling even if the dump isn't split +	 */ +	IWL_UCODE_TLV_CAPA_RESET_DURING_ASSERT		= (__force iwl_ucode_tlv_capa_t)(4 * 32 +  0), +	IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE 	= (__force iwl_ucode_tlv_capa_t)(4 * 32 + 1),  	NUM_IWL_UCODE_TLV_CAPA  /*   * This construction make both sparse (which cannot increment the previous @@ -987,6 +1010,10 @@ struct iwl_fw_dump_exclude {  	__le32 addr, size;  }; +struct iwl_fw_fseq_bin_version { +	__le32 major, minor; +}; /* FW_TLV_FSEQ_BIN_VERSION_S */ +  static inline size_t _iwl_tlv_array_len(const struct iwl_ucode_tlv *tlv,  					size_t fixed_size, size_t var_size)  { @@ -1004,4 +1031,18 @@ static inline size_t _iwl_tlv_array_len(const struct iwl_ucode_tlv *tlv,  #define iwl_tlv_array_len_with_size(_tlv_ptr, _struct_ptr, _size)	\  	_iwl_tlv_array_len((_tlv_ptr), sizeof(*(_struct_ptr)), _size) + +/* external FSEQ file */ +#define IWL_FSEQ_FILE	"intel/fseq-%04x-%04x" +#define IWL_FSEQ_MAGIC	"INTEL-CNV-FSEQ\n\0" + +struct iwl_fseq_file { +	char magic[16]; +	char version[16]; +	__le32 bt_len; +	__le32 wifi_len; +	u8 reserved[8]; +	u8 data[]; +} __packed; +  #endif  /* __iwl_fw_file_h__ */ diff --git a/sys/contrib/dev/iwlwifi/fw/img.c b/sys/contrib/dev/iwlwifi/fw/img.c index b7deca05a953..c2f4fc83a22c 100644 --- a/sys/contrib/dev/iwlwifi/fw/img.c +++ b/sys/contrib/dev/iwlwifi/fw/img.c @@ -1,6 +1,7 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /*   * Copyright(c) 2019 - 2021 Intel Corporation + * Copyright(c) 2024 Intel Corporation   */  #include <fw/api/commands.h>  #include "img.h" @@ -75,6 +76,7 @@ static const struct {  	{ "NMI_INTERRUPT_ACTION_PT", 0x7C },  	{ "NMI_INTERRUPT_UNKNOWN", 0x84 },  	{ "NMI_INTERRUPT_INST_ACTION_PT", 0x86 }, +	{ "NMI_INTERRUPT_PREG", 0x88 },  	{ "PNVM_MISSING", FW_SYSASSERT_PNVM_MISSING },  	{ "ADVANCED_SYSASSERT", 0 },  }; diff --git a/sys/contrib/dev/iwlwifi/fw/img.h b/sys/contrib/dev/iwlwifi/fw/img.h index 96bda80632f3..5256f20623e9 100644 --- a/sys/contrib/dev/iwlwifi/fw/img.h +++ b/sys/contrib/dev/iwlwifi/fw/img.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2005-2014, 2018-2023 Intel Corporation + * Copyright (C) 2005-2014, 2018-2024 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2016 Intel Deutschland GmbH   */ @@ -51,9 +51,10 @@ struct iwl_ucode_capabilities {  	u32 error_log_addr;  	u32 error_log_size;  	u32 num_stations; +	u32 num_links;  	u32 num_beacons; -	unsigned long _api[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_API)]; -	unsigned long _capa[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_CAPA)]; +	DECLARE_BITMAP(_api, NUM_IWL_UCODE_TLV_API); +	DECLARE_BITMAP(_capa, NUM_IWL_UCODE_TLV_CAPA);  	const struct iwl_fw_cmd_version *cmd_versions;  	u32 n_cmd_versions; @@ -194,6 +195,8 @@ struct iwl_dump_exclude {   * @phy_integration_ver_len: length of @phy_integration_ver   * @dump_excl: image dump exclusion areas for RT image   * @dump_excl_wowlan: image dump exclusion areas for WoWLAN image + * @pnvm_data: PNVM data embedded in the .ucode file, if any + * @pnvm_size: size of the embedded PNVM data   */  struct iwl_fw {  	u32 ucode_ver; @@ -226,6 +229,9 @@ struct iwl_fw {  	u32 phy_integration_ver_len;  	struct iwl_dump_exclude dump_excl[2], dump_excl_wowlan[2]; + +	const void *pnvm_data; +	u32 pnvm_size;  };  static inline const char *get_fw_dbg_mode_string(int mode) diff --git a/sys/contrib/dev/iwlwifi/fw/init.c b/sys/contrib/dev/iwlwifi/fw/init.c index d8b083be5b6b..d1d8058ad29f 100644 --- a/sys/contrib/dev/iwlwifi/fw/init.c +++ b/sys/contrib/dev/iwlwifi/fw/init.c @@ -1,7 +1,7 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /*   * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2019-2021, 2024 Intel Corporation + * Copyright (C) 2019-2021, 2024-2025 Intel Corporation   */  #include "iwl-drv.h"  #include "runtime.h" @@ -39,10 +39,12 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,  }  IWL_EXPORT_SYMBOL(iwl_fw_runtime_init); +/* Assumes the appropriate lock is held by the caller */  void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt)  {  	iwl_fw_suspend_timestamp(fwrt); -	iwl_dbg_tlv_time_point(fwrt, IWL_FW_INI_TIME_POINT_HOST_D3_START, NULL); +	iwl_dbg_tlv_time_point_sync(fwrt, IWL_FW_INI_TIME_POINT_HOST_D3_START, +				    NULL);  }  IWL_EXPORT_SYMBOL(iwl_fw_runtime_suspend); @@ -70,7 +72,7 @@ int iwl_set_soc_latency(struct iwl_fw_runtime *fwrt)  	 * values in VER_1, this is backwards-compatible with VER_2,  	 * as long as we don't set any other bits.  	 */ -	if (!fwrt->trans->trans_cfg->integrated) +	if (!fwrt->trans->mac_cfg->integrated)  		cmd.flags = cpu_to_le32(SOC_CONFIG_CMD_FLAGS_DISCRETE);  	BUILD_BUG_ON(IWL_CFG_TRANS_LTR_DELAY_NONE != @@ -82,17 +84,17 @@ int iwl_set_soc_latency(struct iwl_fw_runtime *fwrt)  	BUILD_BUG_ON(IWL_CFG_TRANS_LTR_DELAY_1820US !=  		     SOC_FLAGS_LTR_APPLY_DELAY_1820); -	if (fwrt->trans->trans_cfg->ltr_delay != IWL_CFG_TRANS_LTR_DELAY_NONE && -	    !WARN_ON(!fwrt->trans->trans_cfg->integrated)) -		cmd.flags |= le32_encode_bits(fwrt->trans->trans_cfg->ltr_delay, +	if (fwrt->trans->mac_cfg->ltr_delay != IWL_CFG_TRANS_LTR_DELAY_NONE && +	    !WARN_ON(!fwrt->trans->mac_cfg->integrated)) +		cmd.flags |= le32_encode_bits(fwrt->trans->mac_cfg->ltr_delay,  					      SOC_FLAGS_LTR_APPLY_DELAY_MASK);  	if (iwl_fw_lookup_cmd_ver(fwrt->fw, SCAN_REQ_UMAC,  				  IWL_FW_CMD_VER_UNKNOWN) >= 2 && -	    fwrt->trans->trans_cfg->low_latency_xtal) +	    fwrt->trans->mac_cfg->low_latency_xtal)  		cmd.flags |= cpu_to_le32(SOC_CONFIG_CMD_FLAGS_LOW_LATENCY); -	cmd.latency = cpu_to_le32(fwrt->trans->trans_cfg->xtal_latency); +	cmd.latency = cpu_to_le32(fwrt->trans->mac_cfg->xtal_latency);  	ret = iwl_trans_send_cmd(fwrt->trans, &hcmd);  	if (ret) @@ -114,14 +116,14 @@ int iwl_configure_rxq(struct iwl_fw_runtime *fwrt)  	 * The default queue is configured via context info, so if we  	 * have a single queue, there's nothing to do here.  	 */ -	if (fwrt->trans->num_rx_queues == 1) +	if (fwrt->trans->info.num_rxqs == 1)  		return 0; -	if (fwrt->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_22000) +	if (fwrt->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_22000)  		return 0;  	/* skip the default queue */ -	num_queues = fwrt->trans->num_rx_queues - 1; +	num_queues = fwrt->trans->info.num_rxqs - 1;  	size = struct_size(cmd, data, num_queues); diff --git a/sys/contrib/dev/iwlwifi/fw/paging.c b/sys/contrib/dev/iwlwifi/fw/paging.c index 945bc4160cc9..826409f6f710 100644 --- a/sys/contrib/dev/iwlwifi/fw/paging.c +++ b/sys/contrib/dev/iwlwifi/fw/paging.c @@ -1,6 +1,6 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /* - * Copyright (C) 2012-2014, 2018-2019, 2021 Intel Corporation + * Copyright (C) 2012-2014, 2018-2019, 2021, 2025 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2016-2017 Intel Deutschland GmbH   */ @@ -249,7 +249,7 @@ static int iwl_send_paging_cmd(struct iwl_fw_runtime *fwrt,  	};  	int blk_idx; -	/* loop for for all paging blocks + CSS block */ +	/* loop for all paging blocks + CSS block */  	for (blk_idx = 0; blk_idx < fwrt->num_of_paging_blk + 1; blk_idx++) {  		dma_addr_t addr = fwrt->fw_paging_db[blk_idx].fw_paging_phys;  		__le32 phy_addr; @@ -267,7 +267,7 @@ int iwl_init_paging(struct iwl_fw_runtime *fwrt, enum iwl_ucode_type type)  	const struct fw_img *fw = &fwrt->fw->img[type];  	int ret; -	if (fwrt->trans->trans_cfg->gen2) +	if (fwrt->trans->mac_cfg->gen2)  		return 0;  	/* diff --git a/sys/contrib/dev/iwlwifi/fw/pnvm.c b/sys/contrib/dev/iwlwifi/fw/pnvm.c index 1195e708caa9..4d91ae065c8d 100644 --- a/sys/contrib/dev/iwlwifi/fw/pnvm.c +++ b/sys/contrib/dev/iwlwifi/fw/pnvm.c @@ -1,6 +1,6 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /* - * Copyright(c) 2020-2024 Intel Corporation + * Copyright(c) 2020-2025 Intel Corporation   */  #include "iwl-drv.h" @@ -11,6 +11,7 @@  #include "fw/api/nvm-reg.h"  #include "fw/api/alive.h"  #include "fw/uefi.h" +#include "fw/img.h"  #define IWL_PNVM_REDUCED_CAP_BIT BIT(25) @@ -96,8 +97,8 @@ static int iwl_pnvm_handle_section(struct iwl_trans *trans, const u8 *data,  				     "Got IWL_UCODE_TLV_HW_TYPE mac_type 0x%0x rf_id 0x%0x\n",  				     mac_type, rf_id); -			if (mac_type == CSR_HW_REV_TYPE(trans->hw_rev) && -			    rf_id == CSR_HW_RFID_TYPE(trans->hw_rf_id)) +			if (mac_type == CSR_HW_REV_TYPE(trans->info.hw_rev) && +			    rf_id == CSR_HW_RFID_TYPE(trans->info.hw_rf_id))  				hw_match = true;  			break;  		case IWL_UCODE_TLV_SEC_RT: { @@ -152,8 +153,8 @@ done:  	if (!hw_match) {  		IWL_DEBUG_FW(trans,  			     "HW mismatch, skipping PNVM section (need mac_type 0x%x rf_id 0x%x)\n", -			     CSR_HW_REV_TYPE(trans->hw_rev), -			     CSR_HW_RFID_TYPE(trans->hw_rf_id)); +			     CSR_HW_REV_TYPE(trans->info.hw_rev), +			     CSR_HW_RFID_TYPE(trans->info.hw_rf_id));  		return -ENOENT;  	} @@ -167,7 +168,8 @@ done:  static int iwl_pnvm_parse(struct iwl_trans *trans, const u8 *data,  			  size_t len, -			  struct iwl_pnvm_image *pnvm_data) +			  struct iwl_pnvm_image *pnvm_data, +			  __le32 sku_id[3])  {  	const struct iwl_ucode_tlv *tlv; @@ -190,23 +192,23 @@ static int iwl_pnvm_parse(struct iwl_trans *trans, const u8 *data,  		}  		if (tlv_type == IWL_UCODE_TLV_PNVM_SKU) { -			const struct iwl_sku_id *sku_id = +			const struct iwl_sku_id *tlv_sku_id =  				(const void *)(data + sizeof(*tlv));  			IWL_DEBUG_FW(trans,  				     "Got IWL_UCODE_TLV_PNVM_SKU len %d\n",  				     tlv_len);  			IWL_DEBUG_FW(trans, "sku_id 0x%0x 0x%0x 0x%0x\n", -				     le32_to_cpu(sku_id->data[0]), -				     le32_to_cpu(sku_id->data[1]), -				     le32_to_cpu(sku_id->data[2])); +				     le32_to_cpu(tlv_sku_id->data[0]), +				     le32_to_cpu(tlv_sku_id->data[1]), +				     le32_to_cpu(tlv_sku_id->data[2]));  			data += sizeof(*tlv) + ALIGN(tlv_len, 4);  			len -= ALIGN(tlv_len, 4);  			trans->reduced_cap_sku = false; -			rf_type = CSR_HW_RFID_TYPE(trans->hw_rf_id); -			if ((trans->sku_id[0] & IWL_PNVM_REDUCED_CAP_BIT) && +			rf_type = CSR_HW_RFID_TYPE(trans->info.hw_rf_id); +			if ((sku_id[0] & cpu_to_le32(IWL_PNVM_REDUCED_CAP_BIT)) &&  			    rf_type == IWL_CFG_RF_TYPE_FM)  				trans->reduced_cap_sku = true; @@ -214,9 +216,9 @@ static int iwl_pnvm_parse(struct iwl_trans *trans, const u8 *data,  				     "Reduced SKU device %d\n",  				     trans->reduced_cap_sku); -			if (trans->sku_id[0] == le32_to_cpu(sku_id->data[0]) && -			    trans->sku_id[1] == le32_to_cpu(sku_id->data[1]) && -			    trans->sku_id[2] == le32_to_cpu(sku_id->data[2])) { +			if (sku_id[0] == tlv_sku_id->data[0] && +			    sku_id[1] == tlv_sku_id->data[1] && +			    sku_id[2] == tlv_sku_id->data[2]) {  				int ret;  				ret = iwl_pnvm_handle_section(trans, data, len, @@ -263,13 +265,14 @@ static int iwl_pnvm_get_from_fs(struct iwl_trans *trans, u8 **data, size_t *len)  	return 0;  } -static u8 *iwl_get_pnvm_image(struct iwl_trans *trans_p, size_t *len) +static const u8 *iwl_get_pnvm_image(struct iwl_trans *trans_p, size_t *len, +				    __le32 sku_id[3], const struct iwl_fw *fw)  {  	struct pnvm_sku_package *package;  	u8 *image = NULL;  	/* Get PNVM from BIOS for non-Intel SKU */ -	if (trans_p->sku_id[2]) { +	if (sku_id[2]) {  		package = iwl_uefi_get_pnvm(trans_p, len);  		if (!IS_ERR_OR_NULL(package)) {  			if (*len >= sizeof(*package)) { @@ -288,17 +291,25 @@ static u8 *iwl_get_pnvm_image(struct iwl_trans *trans_p, size_t *len)  		}  	} +	if (fw->pnvm_data) { +		*len = fw->pnvm_size; + +		return fw->pnvm_data; +	} +  	/* If it's not available, or for Intel SKU, try from the filesystem */  	if (iwl_pnvm_get_from_fs(trans_p, &image, len))  		return NULL;  	return image;  } -static void iwl_pnvm_load_pnvm_to_trans(struct iwl_trans *trans, -					const struct iwl_ucode_capabilities *capa) +static void +iwl_pnvm_load_pnvm_to_trans(struct iwl_trans *trans, +			    const struct iwl_fw *fw, +			    __le32 sku_id[3])  {  	struct iwl_pnvm_image *pnvm_data = NULL; -	u8 *data = NULL; +	const u8 *data = NULL;  	size_t length;  	int ret; @@ -309,7 +320,7 @@ static void iwl_pnvm_load_pnvm_to_trans(struct iwl_trans *trans,  	if (trans->pnvm_loaded)  		goto set; -	data = iwl_get_pnvm_image(trans, &length); +	data = iwl_get_pnvm_image(trans, &length, sku_id, fw);  	if (!data) {  		trans->fail_to_parse_pnvm_image = true;  		return; @@ -319,27 +330,30 @@ static void iwl_pnvm_load_pnvm_to_trans(struct iwl_trans *trans,  	if (!pnvm_data)  		goto free; -	ret = iwl_pnvm_parse(trans, data, length, pnvm_data); +	ret = iwl_pnvm_parse(trans, data, length, pnvm_data, sku_id);  	if (ret) {  		trans->fail_to_parse_pnvm_image = true;  		goto free;  	} -	ret = iwl_trans_load_pnvm(trans, pnvm_data, capa); +	ret = iwl_trans_load_pnvm(trans, pnvm_data, &fw->ucode_capa);  	if (ret)  		goto free; -	IWL_INFO(trans, "loaded PNVM version %08x\n", pnvm_data->version); +	IWL_DEBUG_INFO(trans, "loaded PNVM version %08x\n", pnvm_data->version);  set: -	iwl_trans_set_pnvm(trans, capa); +	iwl_trans_set_pnvm(trans, &fw->ucode_capa);  free: -	kvfree(data); +	/* free only if it was allocated, i.e. not just embedded PNVM data */ +	if (data != fw->pnvm_data) +		kvfree(data);  	kfree(pnvm_data);  }  static void  iwl_pnvm_load_reduce_power_to_trans(struct iwl_trans *trans, -				    const struct iwl_ucode_capabilities *capa) +				    const struct iwl_ucode_capabilities *capa, +				    __le32 sku_id[3])  {  	struct iwl_pnvm_image *pnvm_data = NULL;  	u8 *data = NULL; @@ -362,7 +376,8 @@ iwl_pnvm_load_reduce_power_to_trans(struct iwl_trans *trans,  	if (!pnvm_data)  		goto free; -	ret = iwl_uefi_reduce_power_parse(trans, data, length, pnvm_data); +	ret = iwl_uefi_reduce_power_parse(trans, data, length, pnvm_data, +					  sku_id);  	if (ret) {  		trans->failed_to_load_reduce_power_image = true;  		goto free; @@ -386,18 +401,18 @@ free:  int iwl_pnvm_load(struct iwl_trans *trans,  		  struct iwl_notif_wait_data *notif_wait, -		  const struct iwl_ucode_capabilities *capa) +		  const struct iwl_fw *fw, __le32 sku_id[3])  {  	struct iwl_notification_wait pnvm_wait;  	static const u16 ntf_cmds[] = { WIDE_ID(REGULATORY_AND_NVM_GROUP,  						PNVM_INIT_COMPLETE_NTFY) };  	/* if the SKU_ID is empty, there's nothing to do */ -	if (!trans->sku_id[0] && !trans->sku_id[1] && !trans->sku_id[2]) +	if (!sku_id[0] && !sku_id[1] && !sku_id[2])  		return 0; -	iwl_pnvm_load_pnvm_to_trans(trans, capa); -	iwl_pnvm_load_reduce_power_to_trans(trans, capa); +	iwl_pnvm_load_pnvm_to_trans(trans, fw, sku_id); +	iwl_pnvm_load_reduce_power_to_trans(trans, &fw->ucode_capa, sku_id);  	iwl_init_notification_wait(notif_wait, &pnvm_wait,  				   ntf_cmds, ARRAY_SIZE(ntf_cmds), diff --git a/sys/contrib/dev/iwlwifi/fw/pnvm.h b/sys/contrib/dev/iwlwifi/fw/pnvm.h index 1bac3466154c..ad3b7e2423ac 100644 --- a/sys/contrib/dev/iwlwifi/fw/pnvm.h +++ b/sys/contrib/dev/iwlwifi/fw/pnvm.h @@ -1,12 +1,13 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright(c) 2020-2023 Intel Corporation + * Copyright(c) 2020-2023, 2025 Intel Corporation   */  #ifndef __IWL_PNVM_H__  #define __IWL_PNVM_H__  #include "iwl-drv.h"  #include "fw/notif-wait.h" +#include "fw/img.h"  #define MVM_UCODE_PNVM_TIMEOUT	(HZ / 4) @@ -14,7 +15,7 @@  int iwl_pnvm_load(struct iwl_trans *trans,  		  struct iwl_notif_wait_data *notif_wait, -		  const struct iwl_ucode_capabilities *capa); +		  const struct iwl_fw *fw, __le32 sku_id[3]);  static inline  void iwl_pnvm_get_fs_name(struct iwl_trans *trans, diff --git a/sys/contrib/dev/iwlwifi/fw/regulatory.c b/sys/contrib/dev/iwlwifi/fw/regulatory.c index 777564068166..768350086a06 100644 --- a/sys/contrib/dev/iwlwifi/fw/regulatory.c +++ b/sys/contrib/dev/iwlwifi/fw/regulatory.c @@ -1,6 +1,6 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /* - * Copyright (C) 2023 Intel Corporation + * Copyright (C) 2023, 2025 Intel Corporation   */  #if defined(__FreeBSD__)  #include <linux/bitfield.h> @@ -37,11 +37,13 @@ IWL_BIOS_TABLE_LOADER(wrds_table);  IWL_BIOS_TABLE_LOADER(ewrd_table);  IWL_BIOS_TABLE_LOADER(wgds_table);  IWL_BIOS_TABLE_LOADER(ppag_table); +IWL_BIOS_TABLE_LOADER(phy_filters);  IWL_BIOS_TABLE_LOADER_DATA(tas_table, struct iwl_tas_data);  IWL_BIOS_TABLE_LOADER_DATA(pwr_limit, u64);  IWL_BIOS_TABLE_LOADER_DATA(mcc, char);  IWL_BIOS_TABLE_LOADER_DATA(eckv, u32);  IWL_BIOS_TABLE_LOADER_DATA(wbem, u32); +IWL_BIOS_TABLE_LOADER_DATA(dsbr, u32);  static const struct dmi_system_id dmi_ppag_approved_list[] = { @@ -103,6 +105,11 @@ static const struct dmi_system_id dmi_ppag_approved_list[] = {  			DMI_MATCH(DMI_SYS_VENDOR, "HONOR"),  		},  	}, +	{ .ident = "WIKO", +	  .matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "WIKO"), +		}, +	},  	{}  }; @@ -177,9 +184,9 @@ bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt)  	 */  	return IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) >= 38 ||  		(IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 17 && -		 fwrt->trans->hw_rev != CSR_HW_REV_TYPE_3160) || +		 fwrt->trans->info.hw_rev != CSR_HW_REV_TYPE_3160) ||  		(IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 29 && -		 ((fwrt->trans->hw_rev & CSR_HW_REV_TYPE_MSK) == +		 ((fwrt->trans->info.hw_rev & CSR_HW_REV_TYPE_MSK) ==  		  CSR_HW_REV_TYPE_7265D));  }  IWL_EXPORT_SYMBOL(iwl_sar_geo_support); @@ -310,7 +317,7 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,  	bool send_ppag_always;  	/* many firmware images for JF lie about this */ -	if (CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id) == +	if (CSR_HW_RFID_TYPE(fwrt->trans->info.hw_rf_id) ==  	    CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_JF))  		return -EOPNOTSUPP; @@ -335,31 +342,35 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,  		return -EINVAL;  	} -	/* The 'flags' field is the same in v1 and in v2 so we can just -	 * use v1 to access it. -	 */ -	cmd->v1.flags = cpu_to_le32(fwrt->ppag_flags); -  	IWL_DEBUG_RADIO(fwrt, "PPAG cmd ver is %d\n", cmd_ver);  	if (cmd_ver == 1) {  		num_sub_bands = IWL_NUM_SUB_BANDS_V1;  		gain = cmd->v1.gain[0];  		*cmd_size = sizeof(cmd->v1); -		if (fwrt->ppag_ver >= 1) { +		cmd->v1.flags = cpu_to_le32(fwrt->ppag_flags); +		if (fwrt->ppag_bios_rev >= 1) {  			/* in this case FW supports revision 0 */  			IWL_DEBUG_RADIO(fwrt,  					"PPAG table rev is %d, send truncated table\n", -					fwrt->ppag_ver); +					fwrt->ppag_bios_rev);  		}  	} else if (cmd_ver >= 2 && cmd_ver <= 6) {  		num_sub_bands = IWL_NUM_SUB_BANDS_V2;  		gain = cmd->v2.gain[0];  		*cmd_size = sizeof(cmd->v2); -		if (fwrt->ppag_ver == 0) { +		cmd->v2.flags = cpu_to_le32(fwrt->ppag_flags); +		if (fwrt->ppag_bios_rev == 0) {  			/* in this case FW supports revisions 1,2 or 3 */  			IWL_DEBUG_RADIO(fwrt,  					"PPAG table rev is 0, send padded table\n");  		} +	} else if (cmd_ver == 7) { +		num_sub_bands = IWL_NUM_SUB_BANDS_V2; +		gain = cmd->v3.gain[0]; +		*cmd_size = sizeof(cmd->v3); +		cmd->v3.ppag_config_info.table_source = fwrt->ppag_bios_source; +		cmd->v3.ppag_config_info.table_revision = fwrt->ppag_bios_rev; +		cmd->v3.ppag_config_info.value = cpu_to_le32(fwrt->ppag_flags);  	} else {  		IWL_DEBUG_RADIO(fwrt, "Unsupported PPAG command version\n");  		return -EINVAL; @@ -368,9 +379,11 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,  	/* ppag mode */  	IWL_DEBUG_RADIO(fwrt,  			"PPAG MODE bits were read from bios: %d\n", -			le32_to_cpu(cmd->v1.flags)); +			fwrt->ppag_flags); -	if (cmd_ver == 5) +	if (cmd_ver == 6) +		cmd->v1.flags &= cpu_to_le32(IWL_PPAG_CMD_V6_MASK); +	else if (cmd_ver == 5)  		cmd->v1.flags &= cpu_to_le32(IWL_PPAG_CMD_V5_MASK);  	else if (cmd_ver < 5)  		cmd->v1.flags &= cpu_to_le32(IWL_PPAG_CMD_V4_MASK); @@ -378,16 +391,20 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,  	if ((cmd_ver == 1 &&  	     !fw_has_capa(&fwrt->fw->ucode_capa,  			  IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT)) || -	    (cmd_ver == 2 && fwrt->ppag_ver >= 2)) { +	    (cmd_ver == 2 && fwrt->ppag_bios_rev >= 2)) {  		cmd->v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK);  		IWL_DEBUG_RADIO(fwrt, "masking ppag China bit\n");  	} else {  		IWL_DEBUG_RADIO(fwrt, "isn't masking ppag China bit\n");  	} +	/* The 'flags' field is the same in v1 and v2 so we can just +	 * use v1 to access it. +	 */  	IWL_DEBUG_RADIO(fwrt,  			"PPAG MODE bits going to be sent: %d\n", -			le32_to_cpu(cmd->v1.flags)); +			(cmd_ver < 7) ? le32_to_cpu(cmd->v1.flags) : +					le32_to_cpu(cmd->v3.ppag_config_info.value));  	for (i = 0; i < IWL_NUM_CHAIN_LIMITS; i++) {  		for (j = 0; j < num_sub_bands; j++) { @@ -427,33 +444,57 @@ bool iwl_is_tas_approved(void)  }  IWL_EXPORT_SYMBOL(iwl_is_tas_approved); -int iwl_parse_tas_selection(struct iwl_fw_runtime *fwrt, -			    struct iwl_tas_data *tas_data, -			    const u32 tas_selection) +struct iwl_tas_selection_data +iwl_parse_tas_selection(const u32 tas_selection_in, const u8 tbl_rev)  { -	u8 override_iec = u32_get_bits(tas_selection, +	struct iwl_tas_selection_data tas_selection_out = {}; +	u8 override_iec = u32_get_bits(tas_selection_in,  				       IWL_WTAS_OVERRIDE_IEC_MSK); -	u8 enabled_iec = u32_get_bits(tas_selection, IWL_WTAS_ENABLE_IEC_MSK); -	u8 usa_tas_uhb = u32_get_bits(tas_selection, IWL_WTAS_USA_UHB_MSK); -	int enabled = tas_selection & IWL_WTAS_ENABLED_MSK; +	u8 canada_tas_uhb = u32_get_bits(tas_selection_in, +					 IWL_WTAS_CANADA_UHB_MSK); +	u8 enabled_iec = u32_get_bits(tas_selection_in, +				      IWL_WTAS_ENABLE_IEC_MSK); +	u8 usa_tas_uhb = u32_get_bits(tas_selection_in, +				      IWL_WTAS_USA_UHB_MSK); + +	if (tbl_rev > 0) { +		tas_selection_out.usa_tas_uhb_allowed = usa_tas_uhb; +		tas_selection_out.override_tas_iec = override_iec; +		tas_selection_out.enable_tas_iec = enabled_iec; +	} + +	if (tbl_rev > 1) +		tas_selection_out.canada_tas_uhb_allowed = canada_tas_uhb; + +	return tas_selection_out; +} +IWL_EXPORT_SYMBOL(iwl_parse_tas_selection); -	IWL_DEBUG_RADIO(fwrt, "TAS selection as read from BIOS: 0x%x\n", -			tas_selection); +bool iwl_add_mcc_to_tas_block_list(u16 *list, u8 *size, u16 mcc) +{ +	for (int i = 0; i < *size; i++) { +		if (list[i] == mcc) +			return true; +	} -	tas_data->usa_tas_uhb_allowed = usa_tas_uhb; -	tas_data->override_tas_iec = override_iec; -	tas_data->enable_tas_iec = enabled_iec; +	/* Verify that there is room for another country +	 * If *size == IWL_WTAS_BLACK_LIST_MAX, then the table is full. +	 */ +	if (*size >= IWL_WTAS_BLACK_LIST_MAX) +		return false; -	return enabled; +	list[*size++] = mcc; +	return true;  } +IWL_EXPORT_SYMBOL(iwl_add_mcc_to_tas_block_list); -static __le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt) +__le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt)  {  	int ret;  	u32 val;  	__le32 config_bitmap = 0; -	switch (CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id)) { +	switch (CSR_HW_RFID_TYPE(fwrt->trans->info.hw_rf_id)) {  	case IWL_CFG_RF_TYPE_HR1:  	case IWL_CFG_RF_TYPE_HR2:  	case IWL_CFG_RF_TYPE_JF1: @@ -494,6 +535,7 @@ static __le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt)  	return config_bitmap;  } +IWL_EXPORT_SYMBOL(iwl_get_lari_config_bitmap);  static size_t iwl_get_lari_config_cmd_size(u8 cmd_ver)  { @@ -540,34 +582,61 @@ int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt,  {  	int ret;  	u32 value; +	bool has_raw_dsm_capa = fw_has_capa(&fwrt->fw->ucode_capa, +					    IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE);  	u8 cmd_ver = iwl_fw_lookup_cmd_ver(fwrt->fw,  					   WIDE_ID(REGULATORY_AND_NVM_GROUP,  						   LARI_CONFIG_CHANGE), 1); +	if (WARN_ONCE(cmd_ver > 12, +		      "Don't add newer versions to this function\n")) +		return -EINVAL; +  	memset(cmd, 0, sizeof(*cmd));  	*cmd_size = iwl_get_lari_config_cmd_size(cmd_ver);  	cmd->config_bitmap = iwl_get_lari_config_bitmap(fwrt);  	ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_11AX_ENABLEMENT, &value); -	if (!ret) +	if (!ret) { +		if (!has_raw_dsm_capa) +			value &= DSM_11AX_ALLOW_BITMAP;  		cmd->oem_11ax_allow_bitmap = cpu_to_le32(value); +	}  	ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_UNII4_CHAN, &value);  	if (!ret) { -		if (cmd_ver < 9) -			value &= DSM_UNII4_ALLOW_BITMAP_CMD_V8; -		else +		if (!has_raw_dsm_capa)  			value &= DSM_UNII4_ALLOW_BITMAP; +		/* Since version 9, bits 4 and 5 are supported +		 * regardless of this capability, By pass this masking +		 * if firmware has capability of accepting raw DSM table. +		 */ +		if (!has_raw_dsm_capa && cmd_ver < 9 && +		    !fw_has_capa(&fwrt->fw->ucode_capa, +				 IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_5G9_FOR_CA)) +			value &= ~(DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK | +				   DSM_VALUE_UNII4_CANADA_EN_MSK); +  		cmd->oem_unii4_allow_bitmap = cpu_to_le32(value);  	}  	ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ACTIVATE_CHANNEL, &value);  	if (!ret) { -		if (cmd_ver < 8) +		if (!has_raw_dsm_capa) +			value &= CHAN_STATE_ACTIVE_BITMAP_CMD_V12; + +		if (!has_raw_dsm_capa && cmd_ver < 8)  			value &= ~ACTIVATE_5G2_IN_WW_MASK; -		if (cmd_ver < 12) + +		/* Since version 12, bits 5 and 6 are supported +		 * regardless of this capability, By pass this masking +		 * if firmware has capability of accepting raw DSM table. +		 */ +		if (!has_raw_dsm_capa && cmd_ver < 12 && +		    !fw_has_capa(&fwrt->fw->ucode_capa, +				 IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_UNII4_US_CA))  			value &= CHAN_STATE_ACTIVE_BITMAP_CMD_V11;  		cmd->chan_state_active_bitmap = cpu_to_le32(value); @@ -578,13 +647,19 @@ int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt,  		cmd->oem_uhb_allow_bitmap = cpu_to_le32(value);  	ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_FORCE_DISABLE_CHANNELS, &value); -	if (!ret) +	if (!ret) { +		if (!has_raw_dsm_capa) +			value &= DSM_FORCE_DISABLE_CHANNELS_ALLOWED_BITMAP;  		cmd->force_disable_channels_bitmap = cpu_to_le32(value); +	}  	ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENERGY_DETECTION_THRESHOLD,  			       &value); -	if (!ret) +	if (!ret) { +		if (!has_raw_dsm_capa) +			value &= DSM_EDT_ALLOWED_BITMAP;  		cmd->edt_bitmap = cpu_to_le32(value); +	}  	ret = iwl_bios_get_wbem(fwrt, &value);  	if (!ret) @@ -637,3 +712,50 @@ int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,  	GET_BIOS_TABLE(dsm, fwrt, func, value);  }  IWL_EXPORT_SYMBOL(iwl_bios_get_dsm); + +bool iwl_puncturing_is_allowed_in_bios(u32 puncturing, u16 mcc) +{ +	/* Some kind of regulatory mess means we need to currently disallow +	 * puncturing in the US and Canada unless enabled in BIOS. +	 */ +	switch (mcc) { +	case IWL_MCC_US: +		return puncturing & IWL_UEFI_CNV_PUNCTURING_USA_EN_MSK; +	case IWL_MCC_CANADA: +		return puncturing & IWL_UEFI_CNV_PUNCTURING_CANADA_EN_MSK; +	default: +		return true; +	} +} +IWL_EXPORT_SYMBOL(iwl_puncturing_is_allowed_in_bios); + +bool iwl_rfi_is_enabled_in_bios(struct iwl_fw_runtime *fwrt) +{ +	/* default behaviour is disabled */ +	u32 value = 0; +	int ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_RFI_CONFIG, &value); + +	if (ret < 0) { +		IWL_DEBUG_RADIO(fwrt, "Failed to get DSM RFI, ret=%d\n", ret); +		return false; +	} + +	value &= DSM_VALUE_RFI_DISABLE; +	/* RFI BIOS CONFIG value can be 0 or 3 only. +	 * i.e 0 means DDR and DLVR enabled. 3 means DDR and DLVR disabled. +	 * 1 and 2 are invalid BIOS configurations, So, it's not possible to +	 * disable ddr/dlvr separately. +	 */ +	if (!value) { +		IWL_DEBUG_RADIO(fwrt, "DSM RFI is evaluated to enable\n"); +		return true; +	} else if (value == DSM_VALUE_RFI_DISABLE) { +		IWL_DEBUG_RADIO(fwrt, "DSM RFI is evaluated to disable\n"); +	} else { +		IWL_DEBUG_RADIO(fwrt, +				"DSM RFI got invalid value, value=%d\n", value); +	} + +	return false; +} +IWL_EXPORT_SYMBOL(iwl_rfi_is_enabled_in_bios); diff --git a/sys/contrib/dev/iwlwifi/fw/regulatory.h b/sys/contrib/dev/iwlwifi/fw/regulatory.h index e2c056f483c1..a07c512b6ed4 100644 --- a/sys/contrib/dev/iwlwifi/fw/regulatory.h +++ b/sys/contrib/dev/iwlwifi/fw/regulatory.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright (C) 2023-2024 Intel Corporation + * Copyright (C) 2023-2025 Intel Corporation   */  #ifndef __fw_regulatory_h__ @@ -40,11 +40,21 @@  #define IWL_PPAG_ETSI_CHINA_MASK	3  #define IWL_PPAG_REV3_MASK		0x7FF -#define IWL_WTAS_ENABLED_MSK		0x1 -#define IWL_WTAS_OVERRIDE_IEC_MSK	0x2 -#define IWL_WTAS_ENABLE_IEC_MSK	0x4 +#define IWL_WTAS_ENABLED_MSK		BIT(0) +#define IWL_WTAS_OVERRIDE_IEC_MSK	BIT(1) +#define IWL_WTAS_ENABLE_IEC_MSK		BIT(2) +#define IWL_WTAS_CANADA_UHB_MSK		BIT(15)  #define IWL_WTAS_USA_UHB_MSK		BIT(16) +struct iwl_tas_selection_data { +	u8 override_tas_iec:1, +	   enable_tas_iec:1, +	   usa_tas_uhb_allowed:1, +	   canada_tas_uhb_allowed:1; +}; + +#define BIOS_MCC_CHINA 0x434e +  /*   * The profile for revision 2 is a superset of revision 1, which is in   * turn a superset of revision 0.  So we can store all revisions @@ -95,11 +105,11 @@ struct iwl_ppag_chain {  };  struct iwl_tas_data { -	__le32 block_list_size; -	__le32 block_list_array[IWL_WTAS_BLACK_LIST_MAX]; -	u8 override_tas_iec; -	u8 enable_tas_iec; -	u8 usa_tas_uhb_allowed; +	u8 block_list_size; +	u16 block_list_array[IWL_WTAS_BLACK_LIST_MAX]; +	u8 table_source; +	u8 table_revision; +	u32 tas_selection;  };  /* For DSM revision 0 and 4 */ @@ -142,14 +152,17 @@ enum iwl_dsm_unii4_bitmap {  	DSM_VALUE_UNII4_CANADA_EN_MSK		= BIT(5),  }; -#define DSM_UNII4_ALLOW_BITMAP_CMD_V8 (DSM_VALUE_UNII4_US_OVERRIDE_MSK | \ -				       DSM_VALUE_UNII4_US_EN_MSK | \ -				       DSM_VALUE_UNII4_ETSI_OVERRIDE_MSK | \ -				       DSM_VALUE_UNII4_ETSI_EN_MSK) -#define DSM_UNII4_ALLOW_BITMAP (DSM_UNII4_ALLOW_BITMAP_CMD_V8 | \ -				DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK | \ +#define DSM_UNII4_ALLOW_BITMAP (DSM_VALUE_UNII4_US_OVERRIDE_MSK		|\ +				DSM_VALUE_UNII4_US_EN_MSK		|\ +				DSM_VALUE_UNII4_ETSI_OVERRIDE_MSK	|\ +				DSM_VALUE_UNII4_ETSI_EN_MSK		|\ +				DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK	|\  				DSM_VALUE_UNII4_CANADA_EN_MSK) +#define DSM_11AX_ALLOW_BITMAP				0xF +#define DSM_EDT_ALLOWED_BITMAP				0x7ffff0 +#define DSM_FORCE_DISABLE_CHANNELS_ALLOWED_BITMAP	0x7FF +  enum iwl_dsm_values_rfi {  	DSM_VALUE_RFI_DLVR_DISABLE	= BIT(0),  	DSM_VALUE_RFI_DDR_DISABLE	= BIT(1), @@ -158,6 +171,8 @@ enum iwl_dsm_values_rfi {  #define DSM_VALUE_RFI_DISABLE	(DSM_VALUE_RFI_DLVR_DISABLE |\  				 DSM_VALUE_RFI_DDR_DISABLE) +bool iwl_rfi_is_enabled_in_bios(struct iwl_fw_runtime *fwrt); +  enum iwl_dsm_masks_reg {  	DSM_MASK_CHINA_22_REG = BIT(2)  }; @@ -181,10 +196,10 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,  bool iwl_is_ppag_approved(struct iwl_fw_runtime *fwrt);  bool iwl_is_tas_approved(void); +bool iwl_add_mcc_to_tas_block_list(u16 *list, u8 *size, u16 mcc); -int iwl_parse_tas_selection(struct iwl_fw_runtime *fwrt, -			    struct iwl_tas_data *tas_data, -			    const u32 tas_selection); +struct iwl_tas_selection_data +iwl_parse_tas_selection(const u32 tas_selection, const u8 tbl_rev);  int iwl_bios_get_wrds_table(struct iwl_fw_runtime *fwrt); @@ -204,6 +219,7 @@ int iwl_bios_get_mcc(struct iwl_fw_runtime *fwrt, char *mcc);  int iwl_bios_get_eckv(struct iwl_fw_runtime *fwrt, u32 *ext_clk);  int iwl_bios_get_wbem(struct iwl_fw_runtime *fwrt, u32 *value); +__le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt);  int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt,  			 struct iwl_lari_config_change_cmd *cmd,  			 size_t *cmd_size); @@ -212,9 +228,41 @@ int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,  		     u32 *value);  static inline u32 iwl_bios_get_ppag_flags(const u32 ppag_modes, -					  const u8 ppag_ver) +					  const u8 ppag_bios_rev) +{ +	/* For revision 4 and above driver is pipe */ +	if (ppag_bios_rev >= 4) +		return ppag_modes; + +	return ppag_modes & (ppag_bios_rev < 3 ? IWL_PPAG_ETSI_CHINA_MASK : +						 IWL_PPAG_REV3_MASK); +} + +bool iwl_puncturing_is_allowed_in_bios(u32 puncturing, u16 mcc); + +#define IWL_DSBR_FW_MODIFIED_URM_MASK	BIT(8) +#define IWL_DSBR_PERMANENT_URM_MASK	BIT(9) + +int iwl_bios_get_dsbr(struct iwl_fw_runtime *fwrt, u32 *value); +int iwl_bios_get_phy_filters(struct iwl_fw_runtime *fwrt); + +static inline void iwl_bios_setup_step(struct iwl_trans *trans, +				       struct iwl_fw_runtime *fwrt)  { -	return ppag_modes & (ppag_ver < 3 ? IWL_PPAG_ETSI_CHINA_MASK : -					    IWL_PPAG_REV3_MASK); +	u32 dsbr; + +	if (!trans->mac_cfg->integrated) +		return; + +	if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_BZ) +		return; + +	if (iwl_bios_get_dsbr(fwrt, &dsbr)) +		dsbr = 0; + +	trans->conf.dsbr_urm_fw_dependent = +		!!(dsbr & IWL_DSBR_FW_MODIFIED_URM_MASK); +	trans->conf.dsbr_urm_permanent = +		!!(dsbr & IWL_DSBR_PERMANENT_URM_MASK);  }  #endif /* __fw_regulatory_h__ */ diff --git a/sys/contrib/dev/iwlwifi/fw/rs.c b/sys/contrib/dev/iwlwifi/fw/rs.c index 8f99e501629e..746f2acffb8f 100644 --- a/sys/contrib/dev/iwlwifi/fw/rs.c +++ b/sys/contrib/dev/iwlwifi/fw/rs.c @@ -1,6 +1,6 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /* - * Copyright (C) 2021-2022 Intel Corporation + * Copyright (C) 2021-2022, 2025 Intel Corporation   */  #include <net/mac80211.h> @@ -91,104 +91,6 @@ const char *iwl_rs_pretty_bw(int bw)  }  IWL_EXPORT_SYMBOL(iwl_rs_pretty_bw); -static u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags) -{ -	int rate = rate_n_flags & RATE_LEGACY_RATE_MSK_V1; -	int idx; -	bool ofdm = !(rate_n_flags & RATE_MCS_CCK_MSK_V1); -	int offset = ofdm ? IWL_FIRST_OFDM_RATE : 0; -	int last = ofdm ? IWL_RATE_COUNT_LEGACY : IWL_FIRST_OFDM_RATE; - -	for (idx = offset; idx < last; idx++) -		if (iwl_fw_rate_idx_to_plcp(idx) == rate) -			return idx - offset; -	return IWL_RATE_INVALID; -} - -u32 iwl_new_rate_from_v1(u32 rate_v1) -{ -	u32 rate_v2 = 0; -	u32 dup = 0; - -	if (rate_v1 == 0) -		return rate_v1; -	/* convert rate */ -	if (rate_v1 & RATE_MCS_HT_MSK_V1) { -		u32 nss = 0; - -		rate_v2 |= RATE_MCS_HT_MSK; -		rate_v2 |= -			rate_v1 & RATE_HT_MCS_RATE_CODE_MSK_V1; -		nss = (rate_v1 & RATE_HT_MCS_MIMO2_MSK) >> -			RATE_HT_MCS_NSS_POS_V1; -		rate_v2 |= nss << RATE_MCS_NSS_POS; -	} else if (rate_v1 & RATE_MCS_VHT_MSK_V1 || -		   rate_v1 & RATE_MCS_HE_MSK_V1) { -		rate_v2 |= rate_v1 & RATE_VHT_MCS_RATE_CODE_MSK; - -		rate_v2 |= rate_v1 & RATE_MCS_NSS_MSK; - -		if (rate_v1 & RATE_MCS_HE_MSK_V1) { -			u32 he_type_bits = rate_v1 & RATE_MCS_HE_TYPE_MSK_V1; -			u32 he_type = he_type_bits >> RATE_MCS_HE_TYPE_POS_V1; -			u32 he_106t = (rate_v1 & RATE_MCS_HE_106T_MSK_V1) >> -				RATE_MCS_HE_106T_POS_V1; -			u32 he_gi_ltf = (rate_v1 & RATE_MCS_HE_GI_LTF_MSK_V1) >> -				RATE_MCS_HE_GI_LTF_POS; - -			if ((he_type_bits == RATE_MCS_HE_TYPE_SU || -			     he_type_bits == RATE_MCS_HE_TYPE_EXT_SU) && -			    he_gi_ltf == RATE_MCS_HE_SU_4_LTF) -				/* the new rate have an additional bit to -				 * represent the value 4 rather then using SGI -				 * bit for this purpose - as it was done in the old -				 * rate */ -				he_gi_ltf += (rate_v1 & RATE_MCS_SGI_MSK_V1) >> -					RATE_MCS_SGI_POS_V1; - -			rate_v2 |= he_gi_ltf << RATE_MCS_HE_GI_LTF_POS; -			rate_v2 |= he_type << RATE_MCS_HE_TYPE_POS; -			rate_v2 |= he_106t << RATE_MCS_HE_106T_POS; -			rate_v2 |= rate_v1 & RATE_HE_DUAL_CARRIER_MODE_MSK; -			rate_v2 |= RATE_MCS_HE_MSK; -		} else { -			rate_v2 |= RATE_MCS_VHT_MSK; -		} -	/* if legacy format */ -	} else { -		u32 legacy_rate = iwl_legacy_rate_to_fw_idx(rate_v1); - -		if (WARN_ON_ONCE(legacy_rate == IWL_RATE_INVALID)) -			legacy_rate = (rate_v1 & RATE_MCS_CCK_MSK_V1) ? -				IWL_FIRST_CCK_RATE : IWL_FIRST_OFDM_RATE; - -		rate_v2 |= legacy_rate; -		if (!(rate_v1 & RATE_MCS_CCK_MSK_V1)) -			rate_v2 |= RATE_MCS_LEGACY_OFDM_MSK; -	} - -	/* convert flags */ -	if (rate_v1 & RATE_MCS_LDPC_MSK_V1) -		rate_v2 |= RATE_MCS_LDPC_MSK; -	rate_v2 |= (rate_v1 & RATE_MCS_CHAN_WIDTH_MSK_V1) | -		(rate_v1 & RATE_MCS_ANT_AB_MSK) | -		(rate_v1 & RATE_MCS_STBC_MSK) | -		(rate_v1 & RATE_MCS_BF_MSK); - -	dup = (rate_v1 & RATE_MCS_DUP_MSK_V1) >> RATE_MCS_DUP_POS_V1; -	if (dup) { -		rate_v2 |= RATE_MCS_DUP_MSK; -		rate_v2 |= dup << RATE_MCS_CHAN_WIDTH_POS; -	} - -	if ((!(rate_v1 & RATE_MCS_HE_MSK_V1)) && -	    (rate_v1 & RATE_MCS_SGI_MSK_V1)) -		rate_v2 |= RATE_MCS_SGI_MSK; - -	return rate_v2; -} -IWL_EXPORT_SYMBOL(iwl_new_rate_from_v1); -  int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate)  {  	char *type; @@ -197,37 +99,40 @@ int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate)  	u32 bw = (rate & RATE_MCS_CHAN_WIDTH_MSK) >>  		RATE_MCS_CHAN_WIDTH_POS;  	u32 format = rate & RATE_MCS_MOD_TYPE_MSK; +	int index = 0;  	bool sgi; -	if (format == RATE_MCS_CCK_MSK || -	    format == RATE_MCS_LEGACY_OFDM_MSK) { -		int legacy_rate = rate & RATE_LEGACY_RATE_MSK; -		int index = format == RATE_MCS_CCK_MSK ? -			legacy_rate : -			legacy_rate + IWL_FIRST_OFDM_RATE; +	switch (format) { +	case RATE_MCS_MOD_TYPE_LEGACY_OFDM: +		index = IWL_FIRST_OFDM_RATE; +		fallthrough; +	case RATE_MCS_MOD_TYPE_CCK: +		index += rate & RATE_LEGACY_RATE_MSK;  		return scnprintf(buf, bufsz, "Legacy | ANT: %s Rate: %s Mbps",  				 iwl_rs_pretty_ant(ant),  				 iwl_rate_mcs(index)->mbps); -	} - -	if (format ==  RATE_MCS_VHT_MSK) +	case RATE_MCS_MOD_TYPE_VHT:  		type = "VHT"; -	else if (format ==  RATE_MCS_HT_MSK) +		break; +	case RATE_MCS_MOD_TYPE_HT:  		type = "HT"; -	else if (format == RATE_MCS_HE_MSK) +		break; +	case RATE_MCS_MOD_TYPE_HE:  		type = "HE"; -	else if (format == RATE_MCS_EHT_MSK) +		break; +	case RATE_MCS_MOD_TYPE_EHT:  		type = "EHT"; -	else +		break; +	default:  		type = "Unknown"; /* shouldn't happen */ +	} -	mcs = format == RATE_MCS_HT_MSK ? +	mcs = format == RATE_MCS_MOD_TYPE_HT ?  		RATE_HT_MCS_INDEX(rate) :  		rate & RATE_MCS_CODE_MSK; -	nss = ((rate & RATE_MCS_NSS_MSK) -	       >> RATE_MCS_NSS_POS) + 1; -	sgi = format == RATE_MCS_HE_MSK ? +	nss = u32_get_bits(rate, RATE_MCS_NSS_MSK); +	sgi = format == RATE_MCS_MOD_TYPE_HE ?  		iwl_he_is_sgi(rate) :  		rate & RATE_MCS_SGI_MSK; diff --git a/sys/contrib/dev/iwlwifi/fw/runtime.h b/sys/contrib/dev/iwlwifi/fw/runtime.h index 048877fa7c71..bd3bc2846cfa 100644 --- a/sys/contrib/dev/iwlwifi/fw/runtime.h +++ b/sys/contrib/dev/iwlwifi/fw/runtime.h @@ -1,7 +1,7 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /*   * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2018-2024 Intel Corporation + * Copyright (C) 2018-2025 Intel Corporation   */  #ifndef __iwl_fw_runtime_h__  #define __iwl_fw_runtime_h__ @@ -104,11 +104,19 @@ struct iwl_txf_iter_data {   *	the driver by calling &iwl_fw_set_current_image()   * @dump: debug dump data   * @uats_table: AP type table + * @uats_valid: is AP type table valid   * @uefi_tables_lock_status: The status of the WIFI GUID UEFI variables lock:   *	0: Unlocked, 1 and 2: Locked.   *	Only read the UEFI variables if locked.   * @sar_profiles: sar profiles as read from WRDS/EWRD BIOS tables   * @geo_profiles: geographic profiles as read from WGDS BIOS table + * @phy_filters: specific phy filters as read from WPFC BIOS table + * @ppag_bios_rev: PPAG BIOS revision + * @ppag_bios_source: see &enum bios_source + * @acpi_dsm_funcs_valid: bitmap indicating which DSM values are valid, + *	zero (default initialization) means it hasn't been read yet, + *	and BIT(0) is set when it has since function 0 also has this + *	bitmap and is always supported   */  struct iwl_fw_runtime {  	struct iwl_trans *trans; @@ -177,11 +185,18 @@ struct iwl_fw_runtime {  	bool geo_enabled;  	struct iwl_ppag_chain ppag_chains[IWL_NUM_CHAIN_LIMITS];  	u32 ppag_flags; -	u8 ppag_ver; +	u8 ppag_bios_rev; +	u8 ppag_bios_source;  	struct iwl_sar_offset_mapping_cmd sgom_table;  	bool sgom_enabled;  	struct iwl_mcc_allowed_ap_type_cmd uats_table; +	bool uats_valid;  	u8 uefi_tables_lock_status; +	struct iwl_phy_specific_cfg phy_filters; + +#ifdef CONFIG_ACPI +	u32 acpi_dsm_funcs_valid; +#endif  };  void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans, diff --git a/sys/contrib/dev/iwlwifi/fw/smem.c b/sys/contrib/dev/iwlwifi/fw/smem.c index 3f1272014daf..90fd69b4860c 100644 --- a/sys/contrib/dev/iwlwifi/fw/smem.c +++ b/sys/contrib/dev/iwlwifi/fw/smem.c @@ -1,6 +1,6 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /* - * Copyright (C) 2012-2014, 2018-2021 Intel Corporation + * Copyright (C) 2012-2014, 2018-2021, 2025 Intel Corporation   * Copyright (C) 2013-2015 Intel Mobile Communications GmbH   * Copyright (C) 2016-2017 Intel Deutschland GmbH   */ @@ -102,7 +102,7 @@ void iwl_get_shared_mem_conf(struct iwl_fw_runtime *fwrt)  	}  	pkt = cmd.resp_pkt; -	if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) +	if (fwrt->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_22000)  		iwl_parse_shared_mem_22000(fwrt, pkt);  	else  		iwl_parse_shared_mem(fwrt, pkt); diff --git a/sys/contrib/dev/iwlwifi/fw/uefi.c b/sys/contrib/dev/iwlwifi/fw/uefi.c index fb982d4fe851..99a17b9323e9 100644 --- a/sys/contrib/dev/iwlwifi/fw/uefi.c +++ b/sys/contrib/dev/iwlwifi/fw/uefi.c @@ -1,6 +1,6 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /* - * Copyright(c) 2021-2024 Intel Corporation + * Copyright(c) 2021-2025 Intel Corporation   */  #include "iwl-drv.h" @@ -13,9 +13,12 @@  #include <linux/efi.h>  #include "fw/runtime.h" -#define IWL_EFI_VAR_GUID EFI_GUID(0x92daaf2f, 0xc02b, 0x455b,	\ -				  0xb2, 0xec, 0xf5, 0xa3,	\ -				  0x59, 0x4f, 0x4a, 0xea) +#define IWL_EFI_WIFI_GUID	EFI_GUID(0x92daaf2f, 0xc02b, 0x455b,	\ +					 0xb2, 0xec, 0xf5, 0xa3,	\ +					 0x59, 0x4f, 0x4a, 0xea) +#define IWL_EFI_WIFI_BT_GUID	EFI_GUID(0xe65d8884, 0xd4af, 0x4b20,	\ +					 0x8d, 0x03, 0x77, 0x2e,	\ +					 0xcc, 0x3d, 0xa5, 0x31)  struct iwl_uefi_pnvm_mem_desc {  	__le32 addr; @@ -61,7 +64,7 @@ void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len)  	*len = 0; -	data = iwl_uefi_get_variable(IWL_UEFI_OEM_PNVM_NAME, &IWL_EFI_VAR_GUID, +	data = iwl_uefi_get_variable(IWL_UEFI_OEM_PNVM_NAME, &IWL_EFI_WIFI_GUID,  				     &package_size);  	if (IS_ERR(data)) {  		IWL_DEBUG_FW(trans, @@ -76,18 +79,18 @@ void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len)  	return data;  } -static -void *iwl_uefi_get_verified_variable(struct iwl_trans *trans, -				     efi_char16_t *uefi_var_name, -				     char *var_name, -				     unsigned int expected_size, -				     unsigned long *size) +static void * +iwl_uefi_get_verified_variable_guid(struct iwl_trans *trans, +				    efi_guid_t *guid, +				    efi_char16_t *uefi_var_name, +				    char *var_name, +				    unsigned int expected_size, +				    unsigned long *size)  {  	void *var;  	unsigned long var_size; -	var = iwl_uefi_get_variable(uefi_var_name, &IWL_EFI_VAR_GUID, -				    &var_size); +	var = iwl_uefi_get_variable(uefi_var_name, guid, &var_size);  	if (IS_ERR(var)) {  		IWL_DEBUG_RADIO(trans, @@ -112,6 +115,18 @@ void *iwl_uefi_get_verified_variable(struct iwl_trans *trans,  	return var;  } +static void * +iwl_uefi_get_verified_variable(struct iwl_trans *trans, +			       efi_char16_t *uefi_var_name, +			       char *var_name, +			       unsigned int expected_size, +			       unsigned long *size) +{ +	return iwl_uefi_get_verified_variable_guid(trans, &IWL_EFI_WIFI_GUID, +						   uefi_var_name, var_name, +						   expected_size, size); +} +  int iwl_uefi_handle_tlv_mem_desc(struct iwl_trans *trans, const u8 *data,  				 u32 tlv_len, struct iwl_pnvm_image *pnvm_data)  { @@ -204,7 +219,8 @@ done:  int iwl_uefi_reduce_power_parse(struct iwl_trans *trans,  				const u8 *data, size_t len, -				struct iwl_pnvm_image *pnvm_data) +				struct iwl_pnvm_image *pnvm_data, +				__le32 sku_id[3])  {  	const struct iwl_ucode_tlv *tlv; @@ -226,23 +242,23 @@ int iwl_uefi_reduce_power_parse(struct iwl_trans *trans,  		}  		if (tlv_type == IWL_UCODE_TLV_PNVM_SKU) { -			const struct iwl_sku_id *sku_id = +			const struct iwl_sku_id *tlv_sku_id =  				(const void *)(data + sizeof(*tlv));  			IWL_DEBUG_FW(trans,  				     "Got IWL_UCODE_TLV_PNVM_SKU len %d\n",  				     tlv_len);  			IWL_DEBUG_FW(trans, "sku_id 0x%0x 0x%0x 0x%0x\n", -				     le32_to_cpu(sku_id->data[0]), -				     le32_to_cpu(sku_id->data[1]), -				     le32_to_cpu(sku_id->data[2])); +				     le32_to_cpu(tlv_sku_id->data[0]), +				     le32_to_cpu(tlv_sku_id->data[1]), +				     le32_to_cpu(tlv_sku_id->data[2]));  			data += sizeof(*tlv) + ALIGN(tlv_len, 4);  			len -= ALIGN(tlv_len, 4); -			if (trans->sku_id[0] == le32_to_cpu(sku_id->data[0]) && -			    trans->sku_id[1] == le32_to_cpu(sku_id->data[1]) && -			    trans->sku_id[2] == le32_to_cpu(sku_id->data[2])) { +			if (sku_id[0] == tlv_sku_id->data[0] && +			    sku_id[1] == tlv_sku_id->data[1] && +			    sku_id[2] == tlv_sku_id->data[2]) {  				int ret = iwl_uefi_reduce_power_section(trans,  								    data, len,  								    pnvm_data); @@ -295,11 +311,12 @@ static int iwl_uefi_step_parse(struct uefi_cnv_common_step_data *common_step_dat  	if (common_step_data->revision != 1)  		return -EINVAL; -	trans->mbx_addr_0_step = (u32)common_step_data->revision | +	trans->conf.mbx_addr_0_step = +		(u32)common_step_data->revision |  		(u32)common_step_data->cnvi_eq_channel << 8 |  		(u32)common_step_data->cnvr_eq_channel << 16 |  		(u32)common_step_data->radio1 << 24; -	trans->mbx_addr_1_step = (u32)common_step_data->radio2; +	trans->conf.mbx_addr_1_step = (u32)common_step_data->radio2;  	return 0;  } @@ -308,11 +325,12 @@ void iwl_uefi_get_step_table(struct iwl_trans *trans)  	struct uefi_cnv_common_step_data *data;  	int ret; -	if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) +	if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210)  		return; -	data = iwl_uefi_get_verified_variable(trans, IWL_UEFI_STEP_NAME, -					      "STEP", sizeof(*data), NULL); +	data = iwl_uefi_get_verified_variable_guid(trans, &IWL_EFI_WIFI_BT_GUID, +						   IWL_UEFI_STEP_NAME, +						   "STEP", sizeof(*data), NULL);  	if (IS_ERR(data))  		return; @@ -386,11 +404,14 @@ static int iwl_uefi_uats_parse(struct uefi_cnv_wlan_uats_data *uats_data,  	memcpy(fwrt->uats_table.offset_map, uats_data->offset_map,  	       sizeof(fwrt->uats_table.offset_map)); + +	fwrt->uats_valid = true; +  	return 0;  } -int iwl_uefi_get_uats_table(struct iwl_trans *trans, -			    struct iwl_fw_runtime *fwrt) +void iwl_uefi_get_uats_table(struct iwl_trans *trans, +			     struct iwl_fw_runtime *fwrt)  {  	struct uefi_cnv_wlan_uats_data *data;  	int ret; @@ -398,17 +419,12 @@ int iwl_uefi_get_uats_table(struct iwl_trans *trans,  	data = iwl_uefi_get_verified_variable(trans, IWL_UEFI_UATS_NAME,  					      "UATS", sizeof(*data), NULL);  	if (IS_ERR(data)) -		return -EINVAL; +		return;  	ret = iwl_uefi_uats_parse(data, fwrt); -	if (ret < 0) { +	if (ret < 0)  		IWL_DEBUG_FW(trans, "Cannot read UATS table. rev is invalid\n"); -		kfree(data); -		return ret; -	} -  	kfree(data); -	return 0;  }  IWL_EXPORT_SYMBOL(iwl_uefi_get_uats_table); @@ -538,13 +554,14 @@ int iwl_uefi_get_ppag_table(struct iwl_fw_runtime *fwrt)  		goto out;  	} -	fwrt->ppag_ver = data->revision; +	fwrt->ppag_bios_rev = data->revision;  	fwrt->ppag_flags = iwl_bios_get_ppag_flags(data->ppag_modes, -						   fwrt->ppag_ver); +						   fwrt->ppag_bios_rev);  	BUILD_BUG_ON(sizeof(fwrt->ppag_chains) != sizeof(data->ppag_chains));  	memcpy(&fwrt->ppag_chains, &data->ppag_chains,  	       sizeof(data->ppag_chains)); +	fwrt->ppag_bios_source = BIOS_SOURCE_UEFI;  out:  	kfree(data);  	return ret; @@ -554,27 +571,31 @@ int iwl_uefi_get_tas_table(struct iwl_fw_runtime *fwrt,  			   struct iwl_tas_data *tas_data)  {  	struct uefi_cnv_var_wtas *uefi_tas; -	int ret = 0, enabled, i; +	int ret, enabled;  	uefi_tas = iwl_uefi_get_verified_variable(fwrt->trans, IWL_UEFI_WTAS_NAME,  						  "WTAS", sizeof(*uefi_tas), NULL);  	if (IS_ERR(uefi_tas))  		return -EINVAL; -	if (uefi_tas->revision != IWL_UEFI_WTAS_REVISION) { +	if (uefi_tas->revision < IWL_UEFI_MIN_WTAS_REVISION || +	    uefi_tas->revision > IWL_UEFI_MAX_WTAS_REVISION) {  		ret = -EINVAL;  		IWL_DEBUG_RADIO(fwrt, "Unsupported UEFI WTAS revision:%d\n",  				uefi_tas->revision);  		goto out;  	} -	enabled = iwl_parse_tas_selection(fwrt, tas_data, -					  uefi_tas->tas_selection); -	if (!enabled) { -		IWL_DEBUG_RADIO(fwrt, "TAS not enabled\n"); -		ret = 0; -		goto out; -	} +	IWL_DEBUG_RADIO(fwrt, "TAS selection as read from BIOS: 0x%x\n", +			uefi_tas->tas_selection); + +	enabled = uefi_tas->tas_selection & IWL_WTAS_ENABLED_MSK; +	tas_data->table_source = BIOS_SOURCE_UEFI; +	tas_data->table_revision = uefi_tas->revision; +	tas_data->tas_selection = uefi_tas->tas_selection; + +	IWL_DEBUG_RADIO(fwrt, "TAS %s enabled\n", +			enabled ? "is" : "not");  	IWL_DEBUG_RADIO(fwrt, "Reading TAS table revision %d\n",  			uefi_tas->revision); @@ -584,15 +605,16 @@ int iwl_uefi_get_tas_table(struct iwl_fw_runtime *fwrt,  		ret = -EINVAL;  		goto out;  	} -	tas_data->block_list_size = cpu_to_le32(uefi_tas->black_list_size); + +	tas_data->block_list_size = uefi_tas->black_list_size;  	IWL_DEBUG_RADIO(fwrt, "TAS array size %u\n", uefi_tas->black_list_size); -	for (i = 0; i < uefi_tas->black_list_size; i++) { -		tas_data->block_list_array[i] = -			cpu_to_le32(uefi_tas->black_list[i]); +	for (u8 i = 0; i < uefi_tas->black_list_size; i++) { +		tas_data->block_list_array[i] = uefi_tas->black_list[i];  		IWL_DEBUG_RADIO(fwrt, "TAS block list country %d\n",  				uefi_tas->black_list[i]);  	} +	ret = enabled;  out:  	kfree(uefi_tas);  	return ret; @@ -638,7 +660,7 @@ int iwl_uefi_get_mcc(struct iwl_fw_runtime *fwrt, char *mcc)  		goto out;  	} -	if (data->mcc != UEFI_MCC_CHINA) { +	if (data->mcc != BIOS_MCC_CHINA) {  		ret = -EINVAL;  		IWL_DEBUG_RADIO(fwrt, "UEFI WRDD is supported only for CN\n");  		goto out; @@ -657,14 +679,16 @@ int iwl_uefi_get_eckv(struct iwl_fw_runtime *fwrt, u32 *extl_clk)  	struct uefi_cnv_var_eckv *data;  	int ret = 0; -	data = iwl_uefi_get_verified_variable(fwrt->trans, IWL_UEFI_ECKV_NAME, -					      "ECKV", sizeof(*data), NULL); +	data = iwl_uefi_get_verified_variable_guid(fwrt->trans, +						   &IWL_EFI_WIFI_BT_GUID, +						   IWL_UEFI_ECKV_NAME, +						   "ECKV", sizeof(*data), NULL);  	if (IS_ERR(data))  		return -EINVAL;  	if (data->revision != IWL_UEFI_ECKV_REVISION) {  		ret = -EINVAL; -		IWL_DEBUG_RADIO(fwrt, "Unsupported UEFI WRDD revision:%d\n", +		IWL_DEBUG_RADIO(fwrt, "Unsupported UEFI ECKV revision:%d\n",  				data->revision);  		goto out;  	} @@ -723,9 +747,102 @@ int iwl_uefi_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,  		goto out;  	} +	if (!(data->functions[DSM_FUNC_QUERY] & BIT(func))) { +		IWL_DEBUG_RADIO(fwrt, "DSM func %d not in 0x%x\n", +				func, data->functions[DSM_FUNC_QUERY]); +		goto out; +	} +  	*value = data->functions[func]; + +	IWL_DEBUG_RADIO(fwrt, +			"UEFI: DSM func=%d: value=%d\n", func, *value); +  	ret = 0;  out:  	kfree(data);  	return ret;  } + +int iwl_uefi_get_puncturing(struct iwl_fw_runtime *fwrt) +{ +	struct uefi_cnv_var_puncturing_data *data; +	/* default value is not enabled if there is any issue in reading +	 * uefi variable or revision is not supported +	 */ +	int puncturing = 0; + +	data = iwl_uefi_get_verified_variable(fwrt->trans, +					      IWL_UEFI_PUNCTURING_NAME, +					      "UefiCnvWlanPuncturing", +					      sizeof(*data), NULL); +	if (IS_ERR(data)) +		return puncturing; + +	if (data->revision != IWL_UEFI_PUNCTURING_REVISION) { +		IWL_DEBUG_RADIO(fwrt, "Unsupported UEFI PUNCTURING rev:%d\n", +				data->revision); +	} else { +		puncturing = data->puncturing & IWL_UEFI_PUNCTURING_REV0_MASK; +		IWL_DEBUG_RADIO(fwrt, "Loaded puncturing bits from UEFI: %d\n", +				puncturing); +	} + +	kfree(data); +	return puncturing; +} +IWL_EXPORT_SYMBOL(iwl_uefi_get_puncturing); + +int iwl_uefi_get_dsbr(struct iwl_fw_runtime *fwrt, u32 *value) +{ +	struct uefi_cnv_wlan_dsbr_data *data; +	int ret = 0; + +	data = iwl_uefi_get_verified_variable_guid(fwrt->trans, +						   &IWL_EFI_WIFI_BT_GUID, +						   IWL_UEFI_DSBR_NAME, "DSBR", +						   sizeof(*data), NULL); +	if (IS_ERR(data)) +		return -EINVAL; + +	if (data->revision != IWL_UEFI_DSBR_REVISION) { +		ret = -EINVAL; +		IWL_DEBUG_RADIO(fwrt, "Unsupported UEFI DSBR revision:%d\n", +				data->revision); +		goto out; +	} +	*value = data->config; +	IWL_DEBUG_RADIO(fwrt, "Loaded DSBR config from UEFI value: 0x%x\n", +			*value); +out: +	kfree(data); +	return ret; +} + +int iwl_uefi_get_phy_filters(struct iwl_fw_runtime *fwrt) +{ +	struct uefi_cnv_wpfc_data *data __free(kfree); +	struct iwl_phy_specific_cfg *filters = &fwrt->phy_filters; + +	data = iwl_uefi_get_verified_variable(fwrt->trans, IWL_UEFI_WPFC_NAME, +					      "WPFC", sizeof(*data), NULL); +	if (IS_ERR(data)) +		return -EINVAL; + +	if (data->revision != 0) { +		IWL_DEBUG_RADIO(fwrt, "Unsupported UEFI WPFC revision:%d\n", +			data->revision); +		return -EINVAL; +	} + +	BUILD_BUG_ON(ARRAY_SIZE(filters->filter_cfg_chains) != +		     ARRAY_SIZE(data->chains)); + +	for (int i = 0; i < ARRAY_SIZE(filters->filter_cfg_chains); i++) { +		filters->filter_cfg_chains[i] = cpu_to_le32(data->chains[i]); +		IWL_DEBUG_RADIO(fwrt, "WPFC: chain %d: %u\n", i, data->chains[i]); +	} + +	IWL_DEBUG_RADIO(fwrt, "Loaded WPFC config from UEFI\n"); +	return 0; +} diff --git a/sys/contrib/dev/iwlwifi/fw/uefi.h b/sys/contrib/dev/iwlwifi/fw/uefi.h index 50327bb8c2d6..da9d242d85b6 100644 --- a/sys/contrib/dev/iwlwifi/fw/uefi.h +++ b/sys/contrib/dev/iwlwifi/fw/uefi.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */  /* - * Copyright(c) 2021-2024 Intel Corporation + * Copyright(c) 2021-2025 Intel Corporation   */  #ifndef __iwl_fw_uefi__  #define __iwl_fw_uefi__ @@ -19,9 +19,12 @@  #define IWL_UEFI_WTAS_NAME		L"UefiCnvWlanWTAS"  #define IWL_UEFI_SPLC_NAME		L"UefiCnvWlanSPLC"  #define IWL_UEFI_WRDD_NAME		L"UefiCnvWlanWRDD" -#define IWL_UEFI_ECKV_NAME		L"UefiCnvWlanECKV" +#define IWL_UEFI_ECKV_NAME		L"UefiCnvCommonECKV"  #define IWL_UEFI_DSM_NAME		L"UefiCnvWlanGeneralCfg"  #define IWL_UEFI_WBEM_NAME		L"UefiCnvWlanWBEM" +#define IWL_UEFI_PUNCTURING_NAME	L"UefiCnvWlanPuncturing" +#define IWL_UEFI_DSBR_NAME		L"UefiCnvCommonDSBR" +#define IWL_UEFI_WPFC_NAME		L"WPFC"  #define IWL_SGOM_MAP_SIZE		339 @@ -31,13 +34,16 @@  #define IWL_UEFI_EWRD_REVISION		2  #define IWL_UEFI_WGDS_REVISION		3  #define IWL_UEFI_MIN_PPAG_REV		1 -#define IWL_UEFI_MAX_PPAG_REV		3 -#define IWL_UEFI_WTAS_REVISION		1 +#define IWL_UEFI_MAX_PPAG_REV		4 +#define IWL_UEFI_MIN_WTAS_REVISION	1 +#define IWL_UEFI_MAX_WTAS_REVISION	2  #define IWL_UEFI_SPLC_REVISION		0  #define IWL_UEFI_WRDD_REVISION		0  #define IWL_UEFI_ECKV_REVISION		0  #define IWL_UEFI_WBEM_REVISION		0  #define IWL_UEFI_DSM_REVISION		4 +#define IWL_UEFI_PUNCTURING_REVISION	0 +#define IWL_UEFI_DSBR_REVISION		1  struct pnvm_sku_package {  	u8 rev; @@ -149,8 +155,6 @@ struct uefi_cnv_var_splc {  	u32 default_pwr_limit;  } __packed; -#define UEFI_MCC_CHINA 0x434e -  /* struct uefi_cnv_var_wrdd - WRDD table as defined in UEFI   * @revision: the revision of the table   * @mcc: country identifier as defined in ISO/IEC 3166-1 Alpha 2 code @@ -194,6 +198,51 @@ struct uefi_cnv_wlan_wbem_data {  	u32 wbem_320mhz_per_mcc;  } __packed; +enum iwl_uefi_cnv_puncturing_flags { +	IWL_UEFI_CNV_PUNCTURING_USA_EN_MSK	= BIT(0), +	IWL_UEFI_CNV_PUNCTURING_CANADA_EN_MSK	= BIT(1), +}; + +#define IWL_UEFI_PUNCTURING_REV0_MASK (IWL_UEFI_CNV_PUNCTURING_USA_EN_MSK | \ +				       IWL_UEFI_CNV_PUNCTURING_CANADA_EN_MSK) +/** + * struct uefi_cnv_var_puncturing_data - controlling channel + *	puncturing for few countries. + * @revision: the revision of the table + * @puncturing: enablement of channel puncturing per mcc + *	see &enum iwl_uefi_cnv_puncturing_flags. + */ +struct uefi_cnv_var_puncturing_data { +	u8 revision; +	u32 puncturing; +} __packed; + +/** + * struct uefi_cnv_wlan_dsbr_data - BIOS STEP configuration information + * @revision: the revision of the table + * @config: STEP configuration flags: + *	bit 8, switch to URM depending on FW setting + *	bit 9, switch to URM + * + * Platform information for STEP configuration/workarounds. + */ +struct uefi_cnv_wlan_dsbr_data { +	u8 revision; +	u32 config; +} __packed; + +/** + * struct uefi_cnv_wpfc_data - BIOS Wi-Fi PHY filter Configuration + * @revision: the revision of the table + * @chains: configuration of each of the chains (a-d) + * + * specific PHY filter configuration + */ +struct uefi_cnv_wpfc_data { +	u8 revision; +	u32 chains[4]; +} __packed; +  /*   * This is known to be broken on v4.19 and to work on v5.4.  Until we   * figure out why this is the case and how to make it work, simply @@ -204,7 +253,8 @@ void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len);  u8 *iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len);  int iwl_uefi_reduce_power_parse(struct iwl_trans *trans,  				const u8 *data, size_t len, -				struct iwl_pnvm_image *pnvm_data); +				struct iwl_pnvm_image *pnvm_data, +				__le32 sku_id[3]);  void iwl_uefi_get_step_table(struct iwl_trans *trans);  int iwl_uefi_handle_tlv_mem_desc(struct iwl_trans *trans, const u8 *data,  				 u32 tlv_len, struct iwl_pnvm_image *pnvm_data); @@ -222,8 +272,11 @@ int iwl_uefi_get_wbem(struct iwl_fw_runtime *fwrt, u32 *value);  int iwl_uefi_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,  		     u32 *value);  void iwl_uefi_get_sgom_table(struct iwl_trans *trans, struct iwl_fw_runtime *fwrt); -int iwl_uefi_get_uats_table(struct iwl_trans *trans, -			    struct iwl_fw_runtime *fwrt); +void iwl_uefi_get_uats_table(struct iwl_trans *trans, +			     struct iwl_fw_runtime *fwrt); +int iwl_uefi_get_puncturing(struct iwl_fw_runtime *fwrt); +int iwl_uefi_get_dsbr(struct iwl_fw_runtime *fwrt, u32 *value); +int iwl_uefi_get_phy_filters(struct iwl_fw_runtime *fwrt);  #else /* CONFIG_EFI */  static inline void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len)  { @@ -233,7 +286,8 @@ static inline void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len)  static inline int  iwl_uefi_reduce_power_parse(struct iwl_trans *trans,  			    const u8 *data, size_t len, -			    struct iwl_pnvm_image *pnvm_data) +			    struct iwl_pnvm_image *pnvm_data, +			    __le32 sku_id[3])  {  	return -EOPNOTSUPP;  } @@ -314,9 +368,13 @@ void iwl_uefi_get_sgom_table(struct iwl_trans *trans, struct iwl_fw_runtime *fwr  {  } +static inline void +iwl_uefi_get_uats_table(struct iwl_trans *trans, struct iwl_fw_runtime *fwrt) +{ +} +  static inline -int iwl_uefi_get_uats_table(struct iwl_trans *trans, -			    struct iwl_fw_runtime *fwrt) +int iwl_uefi_get_puncturing(struct iwl_fw_runtime *fwrt)  {  #if defined(__linux__)  	return 0; @@ -324,5 +382,16 @@ int iwl_uefi_get_uats_table(struct iwl_trans *trans,  	return -ENOENT;  #endif  } + +static inline +int iwl_uefi_get_dsbr(struct iwl_fw_runtime *fwrt, u32 *value) +{ +	return -ENOENT; +} + +static inline int iwl_uefi_get_phy_filters(struct iwl_fw_runtime *fwrt) +{ +	return -ENOENT; +}  #endif /* CONFIG_EFI */  #endif /* __iwl_fw_uefi__ */  | 
