wifi: Add support for DSM methods for intel wifi card
Add support for DSM methods as per the connectivity document 559910_Intel_Connectivity_Platforms_BIOS_Guidelines_Rev6_4.pdf BUG=b:191720858 TEST=Check the generated SSDT tables for DSM methods Change-Id: Ie154edf188531fe6c260274edaa694cf3b3605d3 Signed-off-by: Sugnan Prabhu S <sugnan.prabhu.s@intel.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/56751 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
This commit is contained in:
parent
cc50770cd0
commit
d70f481891
|
@ -23,11 +23,151 @@
|
||||||
*/
|
*/
|
||||||
#define WIFI_ACPI_NAME_MAX_LEN 5
|
#define WIFI_ACPI_NAME_MAX_LEN 5
|
||||||
|
|
||||||
|
/* Unique ID for the WIFI _DSM */
|
||||||
|
#define ACPI_DSM_OEM_WIFI_UUID "F21202BF-8F78-4DC6-A5B3-1F738E285ADE"
|
||||||
|
|
||||||
__weak int get_wifi_sar_limits(union wifi_sar_limits *sar_limits)
|
__weak int get_wifi_sar_limits(union wifi_sar_limits *sar_limits)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate ACPI AML code for _DSM method.
|
||||||
|
* This function takes as input uuid for the device, set of callbacks and
|
||||||
|
* argument to pass into the callbacks. Callbacks should ensure that Local0 and
|
||||||
|
* Local1 are left untouched. Use of Local2-Local7 is permitted in callbacks.
|
||||||
|
*/
|
||||||
|
void wifi_emit_dsm(struct dsm_profile *dsm);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function 1: Allow PC OEMs to set ETSI 5.8GHz SRD in Passive/Disabled ESTI SRD
|
||||||
|
* Channels: 149, 153, 157, 161, 165
|
||||||
|
* 0 - ETSI 5.8GHz SRD active scan
|
||||||
|
* 1 - ETSI 5.8GHz SRD passive scan
|
||||||
|
* 2 - ETSI 5.8GHz SRD disabled
|
||||||
|
*/
|
||||||
|
static void wifi_dsm_srd_active_channels(void *args)
|
||||||
|
{
|
||||||
|
struct dsm_profile *dsm_config = (struct dsm_profile *)args;
|
||||||
|
|
||||||
|
acpigen_write_return_integer(dsm_config->disable_active_sdr_channels);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function 2 : Supported Indonesia 5.15-5.35 GHz Band
|
||||||
|
* 0 - Set 5.115-5.35GHz to Disable in Indonesia
|
||||||
|
* 1 - Set 5.115-5.35GHz to Enable (Passive) in Indonesia
|
||||||
|
* 2 - Reserved
|
||||||
|
*/
|
||||||
|
static void wifi_dsm_indonasia_5Ghz_band_enable(void *args)
|
||||||
|
{
|
||||||
|
struct dsm_profile *dsm_config = (struct dsm_profile *)args;
|
||||||
|
|
||||||
|
acpigen_write_return_integer(dsm_config->support_indonesia_5g_band);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function 3: Support Wi-Fi 6 11ax Rev 2 new channels on 6-7 GHz.
|
||||||
|
* Bit 0:
|
||||||
|
* 0 - No override; use device settings 0
|
||||||
|
* 1 - Force disable all countries that are not defined in the following bits
|
||||||
|
*
|
||||||
|
* Bit 1:
|
||||||
|
* 0 No override; USA 6GHz disable 0
|
||||||
|
* 1 6GHz allowed in the USA (enabled only if the device is certified to the USA)
|
||||||
|
*/
|
||||||
|
static void wifi_dsm_supported_ultra_high_band(void *args)
|
||||||
|
{
|
||||||
|
struct dsm_profile *dsm_config = (struct dsm_profile *)args;
|
||||||
|
|
||||||
|
acpigen_write_return_integer(dsm_config->support_ultra_high_band);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function 4: Regulatory Special Configurations Enablements
|
||||||
|
*/
|
||||||
|
static void wifi_dsm_regulatory_configurations(void *args)
|
||||||
|
{
|
||||||
|
struct dsm_profile *dsm_config = (struct dsm_profile *)args;
|
||||||
|
|
||||||
|
acpigen_write_return_integer(dsm_config->regulatory_configurations);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function 5: M.2 UART Interface Configuration
|
||||||
|
*/
|
||||||
|
static void wifi_dsm_uart_configurations(void *args)
|
||||||
|
{
|
||||||
|
struct dsm_profile *dsm_config = (struct dsm_profile *)args;
|
||||||
|
|
||||||
|
acpigen_write_return_integer(dsm_config->uart_configurations);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function 6: Control Enablement 11ax on certificated modules
|
||||||
|
* Bit 0 - Apply changes to country Ukraine. 11Ax Setting within module certification
|
||||||
|
* 0 - None. Work with Wi-Fi FW/OTP definitions [Default]
|
||||||
|
* 1 - Apply changes.
|
||||||
|
*
|
||||||
|
* Bit 1 - 11Ax Mode. Effective only if Bit 0 set to 1
|
||||||
|
* 0 - Disable 11Ax on country Ukraine [Default]
|
||||||
|
* 1 - Enable 11Ax on country Ukraine
|
||||||
|
*
|
||||||
|
* Bit 2 - Apply changes to country Russia. 11Ax Setting within module certification
|
||||||
|
* 0 - None. Work with Wi-Fi FW/OTP definitions [Default]
|
||||||
|
* 1 - Apply changes.
|
||||||
|
*
|
||||||
|
* Bit 3 - 11Ax Mode. Effective only if Bit 2 set to 1
|
||||||
|
* 0 - Disable 11Ax on country Russia [Default]
|
||||||
|
* 1 - Enable 11Ax on country Russia
|
||||||
|
*
|
||||||
|
* Bit 31:04 - Reserved
|
||||||
|
*
|
||||||
|
* Note: Assumed Russia Work with Wi-Fi FW/OTP definitions
|
||||||
|
*/
|
||||||
|
static void wifi_dsm_ukrane_russia_11ax_enable(void *args)
|
||||||
|
{
|
||||||
|
struct dsm_profile *dsm_config = (struct dsm_profile *)args;
|
||||||
|
|
||||||
|
acpigen_write_return_integer(dsm_config->enablement_11ax);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function 7: Control Enablement UNII-4 over certificate modules
|
||||||
|
*/
|
||||||
|
static void wifi_dsm_unii4_control_enable(void *args)
|
||||||
|
{
|
||||||
|
struct dsm_profile *dsm_config = (struct dsm_profile *)args;
|
||||||
|
|
||||||
|
acpigen_write_return_integer(dsm_config->unii_4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void (*wifi_dsm_callbacks[])(void *) = {
|
||||||
|
NULL, /* Function 0 */
|
||||||
|
wifi_dsm_srd_active_channels, /* Function 1 */
|
||||||
|
wifi_dsm_indonasia_5Ghz_band_enable, /* Function 2 */
|
||||||
|
wifi_dsm_supported_ultra_high_band, /* Function 3 */
|
||||||
|
wifi_dsm_regulatory_configurations, /* Function 4 */
|
||||||
|
wifi_dsm_uart_configurations, /* Function 5 */
|
||||||
|
wifi_dsm_ukrane_russia_11ax_enable, /* Function 6 */
|
||||||
|
wifi_dsm_unii4_control_enable, /* Function 7 */
|
||||||
|
};
|
||||||
|
|
||||||
|
void wifi_emit_dsm(struct dsm_profile *dsm)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
size_t count = ARRAY_SIZE(wifi_dsm_callbacks);
|
||||||
|
|
||||||
|
if (dsm == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 1; i < count; i++)
|
||||||
|
if (!(dsm->supported_functions & (1 << i)))
|
||||||
|
wifi_dsm_callbacks[i] = NULL;
|
||||||
|
|
||||||
|
acpigen_write_dsm(ACPI_DSM_OEM_WIFI_UUID, wifi_dsm_callbacks, count, dsm);
|
||||||
|
}
|
||||||
|
|
||||||
static const uint8_t *sar_fetch_set(const struct sar_profile *sar, size_t set_num)
|
static const uint8_t *sar_fetch_set(const struct sar_profile *sar, size_t set_num)
|
||||||
{
|
{
|
||||||
const uint8_t *sar_table = &sar->sar_table[0];
|
const uint8_t *sar_table = &sar->sar_table[0];
|
||||||
|
@ -341,6 +481,7 @@ static void emit_sar_acpi_structures(const struct device *dev)
|
||||||
sar_emit_wgds(sar_limits.wgds);
|
sar_emit_wgds(sar_limits.wgds);
|
||||||
sar_emit_ppag(sar_limits.ppag);
|
sar_emit_ppag(sar_limits.ppag);
|
||||||
sar_emit_wtas(sar_limits.wtas);
|
sar_emit_wtas(sar_limits.wtas);
|
||||||
|
wifi_emit_dsm(sar_limits.dsm);
|
||||||
|
|
||||||
free(sar_limits.sar);
|
free(sar_limits.sar);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#define MAX_DENYLIST_ENTRY 16
|
#define MAX_DENYLIST_ENTRY 16
|
||||||
#define MAX_DSAR_SET_COUNT 3
|
#define MAX_DSAR_SET_COUNT 3
|
||||||
#define MAX_GEO_OFFSET_REVISION 3
|
#define MAX_GEO_OFFSET_REVISION 3
|
||||||
#define MAX_PROFILE_COUNT 4
|
#define MAX_PROFILE_COUNT 5
|
||||||
#define MAX_SAR_REVISION 2
|
#define MAX_SAR_REVISION 2
|
||||||
#define REVISION_SIZE 1
|
#define REVISION_SIZE 1
|
||||||
#define SAR_REV0_CHAINS_COUNT 2
|
#define SAR_REV0_CHAINS_COUNT 2
|
||||||
|
@ -47,6 +47,17 @@ struct avg_profile {
|
||||||
uint8_t deny_list_entry[MAX_DENYLIST_ENTRY];
|
uint8_t deny_list_entry[MAX_DENYLIST_ENTRY];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
struct dsm_profile {
|
||||||
|
uint32_t supported_functions;
|
||||||
|
uint32_t disable_active_sdr_channels;
|
||||||
|
uint32_t support_indonesia_5g_band;
|
||||||
|
uint32_t support_ultra_high_band;
|
||||||
|
uint32_t regulatory_configurations;
|
||||||
|
uint32_t uart_configurations;
|
||||||
|
uint32_t enablement_11ax;
|
||||||
|
uint32_t unii_4;
|
||||||
|
};
|
||||||
|
|
||||||
struct sar_header {
|
struct sar_header {
|
||||||
char marker[SAR_STR_PREFIX_SIZE];
|
char marker[SAR_STR_PREFIX_SIZE];
|
||||||
uint8_t version;
|
uint8_t version;
|
||||||
|
@ -60,6 +71,7 @@ union wifi_sar_limits {
|
||||||
struct geo_profile *wgds;
|
struct geo_profile *wgds;
|
||||||
struct gain_profile *ppag;
|
struct gain_profile *ppag;
|
||||||
struct avg_profile *wtas;
|
struct avg_profile *wtas;
|
||||||
|
struct dsm_profile *dsm;
|
||||||
};
|
};
|
||||||
void *profile[MAX_PROFILE_COUNT];
|
void *profile[MAX_PROFILE_COUNT];
|
||||||
};
|
};
|
||||||
|
|
|
@ -84,6 +84,14 @@ static int sar_avg_table_size(const struct avg_profile *sar_avg)
|
||||||
return sizeof(struct avg_profile);
|
return sizeof(struct avg_profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dsm_table_size(const struct dsm_profile *dsm)
|
||||||
|
{
|
||||||
|
if (dsm == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return sizeof(struct dsm_profile);
|
||||||
|
}
|
||||||
|
|
||||||
static bool valid_legacy_length(size_t bin_len)
|
static bool valid_legacy_length(size_t bin_len)
|
||||||
{
|
{
|
||||||
if (bin_len == LEGACY_SAR_WGDS_BIN_SIZE)
|
if (bin_len == LEGACY_SAR_WGDS_BIN_SIZE)
|
||||||
|
@ -134,6 +142,7 @@ static int fill_wifi_sar_limits(union wifi_sar_limits *sar_limits, const uint8_t
|
||||||
expected_sar_bin_size += wgds_table_size(sar_limits->wgds);
|
expected_sar_bin_size += wgds_table_size(sar_limits->wgds);
|
||||||
expected_sar_bin_size += gain_table_size(sar_limits->ppag);
|
expected_sar_bin_size += gain_table_size(sar_limits->ppag);
|
||||||
expected_sar_bin_size += sar_avg_table_size(sar_limits->wtas);
|
expected_sar_bin_size += sar_avg_table_size(sar_limits->wtas);
|
||||||
|
expected_sar_bin_size += dsm_table_size(sar_limits->dsm);
|
||||||
|
|
||||||
if (sar_bin_size != expected_sar_bin_size) {
|
if (sar_bin_size != expected_sar_bin_size) {
|
||||||
printk(BIOS_ERR, "ERROR: Invalid SAR size, expected: %ld, obtained: %ld\n",
|
printk(BIOS_ERR, "ERROR: Invalid SAR size, expected: %ld, obtained: %ld\n",
|
||||||
|
@ -198,6 +207,7 @@ static int fill_wifi_sar_limits_legacy(union wifi_sar_limits *sar_limits,
|
||||||
* [WGDS_REVISION,CHAINS_COUNT,SUBBANDS_COUNT<WGDS_DATA>]
|
* [WGDS_REVISION,CHAINS_COUNT,SUBBANDS_COUNT<WGDS_DATA>]
|
||||||
* [PPAG_REVISION,MODE,CHAINS_COUNT,SUBBANDS_COUNT<PPAG_DATA>]
|
* [PPAG_REVISION,MODE,CHAINS_COUNT,SUBBANDS_COUNT<PPAG_DATA>]
|
||||||
* [WTAS_REVISION, WTAS_DATA]
|
* [WTAS_REVISION, WTAS_DATA]
|
||||||
|
* [DSM_RETURN_VALUES]
|
||||||
*
|
*
|
||||||
* The configuration data will always have the revision added in the file for each of the
|
* The configuration data will always have the revision added in the file for each of the
|
||||||
* block, based on the revision number and validity, size of the specific block will be
|
* block, based on the revision number and validity, size of the specific block will be
|
||||||
|
|
Loading…
Reference in New Issue