diff options
| author | Ingo Molnar <mingo@kernel.org> | 2024-11-13 03:41:59 +0100 | 
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2024-11-13 03:42:14 +0100 | 
| commit | abe949ce0f9be943d8762f91e04b8588255f2f70 (patch) | |
| tree | d479865f75acaa95fefbb20dccc502ca3cbd5d8d /drivers/net/wireless/intel/iwlwifi/fw/acpi.c | |
| parent | 035c5e2143f3edceeede1e99ff9cf8979c548dd5 (diff) | |
| parent | 2d5404caa8c7bb5c4e0435f94b28834ae5456623 (diff) | |
Merge tag 'v6.12-rc7' into x86/mm, to pick up fixes before applying new patches
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/fw/acpi.c')
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 96 | 
1 files changed, 58 insertions, 38 deletions
| diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c index a7cea0a55b35..0bc32291815e 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c @@ -429,38 +429,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;  } @@ -543,9 +533,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; @@ -557,7 +549,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)) @@ -573,7 +565,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; @@ -589,7 +580,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; @@ -605,7 +595,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; @@ -637,23 +626,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; | 
