From b6ebcdfde58a77bea03a67b376401b9f0f3edefb Mon Sep 17 00:00:00 2001 From: Varshit B Pandya Date: Thu, 3 Feb 2022 18:35:18 +0530 Subject: [PATCH] driver/wifi: Add _DSM method for DDRRFIM coreboot needs to propagate the CnviDdrRfim value info of the feature enable/disable state into the CNVi via the WiFi DSM ACPI object. This will be consumed by the Wi-Fi driver and it will act according to CB enablement configuration. This patch adds _DSM method for that. Add support for following 2 functions in _DSM method - Function 0: Function Support Query Returns a bitmask of functions supported. - Function 3: RFI enablement 0 Feature Enable 1 Feature Disable Note: Wifi Dsm already has provision for SAR. This patch will add additional support to return RFIM structure based on UUID. BUG=b:201724512 TEST=Build, boot brya0 and dump SSDT entries Method (_DSM, 4, Serialized) // _DSM: Device-Specific Method { ToBuffer (Arg0, Local0) If ((Local0 == ToUUID ("7266172c-220b-4b29-814f-75e4dd26b5fd"))) { ToInteger (Arg2, Local1) If ((Local1 == Zero)) { Return (Buffer (One) { 0x09 }) } If ((Local1 == One)){} If ((Local1 == 0x02)){} If ((Local1 == 0x03)) { Return (Zero) } Return (Buffer (One) { 0x00 }) } Return (Buffer (One) { 0x00 }) } Signed-off-by: Varshit B Pandya Change-Id: I217b736df3d4224a6732d1941a160abcddbd8f37 Reviewed-on: https://review.coreboot.org/c/coreboot/+/61020 Tested-by: build bot (Jenkins) Reviewed-by: Tim Wawrzynczak Reviewed-by: Ronak Kanabar Reviewed-by: Maulik V Vaghela --- src/drivers/wifi/generic/acpi.c | 72 ++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 6 deletions(-) diff --git a/src/drivers/wifi/generic/acpi.c b/src/drivers/wifi/generic/acpi.c index ef18f6d68f..65940d6e9f 100644 --- a/src/drivers/wifi/generic/acpi.c +++ b/src/drivers/wifi/generic/acpi.c @@ -10,11 +10,15 @@ #include #include "chip.h" +#include "wifi.h" #include "wifi_private.h" /* WIFI Domain type */ #define DOMAIN_TYPE_WIFI 0x7 +/* Maximum number DSM UUID bifurcations in _DSM */ +#define MAX_DSM_FUNCS 2 + /* * WIFI ACPI NAME = "WF" + hex value of last 8 bits of dev_path_encode + '\0' * The above representation returns unique and consistent name every time @@ -29,6 +33,9 @@ /* ID for the Wifi DmaProperty _DSD */ #define ACPI_DSD_DMA_PROPERTY_UUID "70D24161-6DD5-4C9E-8070-705531292865" +/* Unique ID for CnviDdrRfim entry in WIFI _DSM */ +#define ACPI_DSM_RFIM_WIFI_UUID "7266172C-220B-4B29-814F-75E4DD26B5FD" + __weak int get_wifi_sar_limits(union wifi_sar_limits *sar_limits) { return -1; @@ -145,6 +152,12 @@ static void wifi_dsm_unii4_control_enable(void *args) acpigen_write_return_integer(dsm_config->unii_4); } +static void wifi_dsm_ddrrfim_func3_cb(void *ptr) +{ + const bool is_cnvi_ddr_rfim_enabled = *(bool *)ptr; + acpigen_write_return_integer(is_cnvi_ddr_rfim_enabled ? 1 : 0); +} + static void (*wifi_dsm_callbacks[])(void *) = { NULL, /* Function 0 */ wifi_dsm_srd_active_channels, /* Function 1 */ @@ -156,6 +169,17 @@ static void (*wifi_dsm_callbacks[])(void *) = { wifi_dsm_unii4_control_enable, /* Function 7 */ }; +/* + * The current DSM2 table is only exporting one function (function 3), some more + * functions are reserved so marking them NULL. +*/ +static void (*wifi_dsm2_callbacks[])(void *) = { + NULL, /* Function 0 */ + NULL, /* Function 1 */ + NULL, /* Function 2 */ + wifi_dsm_ddrrfim_func3_cb, /* Function 3 */ +}; + void wifi_emit_dsm(struct dsm_profile *dsm) { int i; @@ -462,9 +486,9 @@ static void sar_emit_wtas(struct avg_profile *wtas) acpigen_write_package_end(); } -static void emit_sar_acpi_structures(const struct device *dev) +static void emit_sar_acpi_structures(const struct device *dev, struct dsm_profile *dsm) { - union wifi_sar_limits sar_limits; + union wifi_sar_limits sar_limits = {{NULL, NULL, NULL, NULL, NULL} }; /* * If device type is PCI, ensure that the device has Intel vendor ID. CBFS SAR and SAR @@ -484,7 +508,10 @@ static void emit_sar_acpi_structures(const struct device *dev) sar_emit_wgds(sar_limits.wgds); sar_emit_ppag(sar_limits.ppag); sar_emit_wtas(sar_limits.wtas); - wifi_emit_dsm(sar_limits.dsm); + + /* copy the dsm data to be later used for creating _DSM function */ + if (sar_limits.dsm != NULL) + memcpy(dsm, &sar_limits.dsm, sizeof(struct dsm_profile)); free(sar_limits.sar); } @@ -506,11 +533,16 @@ static void wifi_ssdt_write_device(const struct device *dev, const char *path) static void wifi_ssdt_write_properties(const struct device *dev, const char *scope) { + bool is_cnvi_ddr_rfim_enabled = false; + + const struct drivers_wifi_generic_config *config = dev->chip_info; + if (dev && config) + is_cnvi_ddr_rfim_enabled = config->enable_cnvi_ddr_rfim; + /* Scope */ acpigen_write_scope(scope); if (dev->path.type == DEVICE_PATH_GENERIC) { - const struct drivers_wifi_generic_config *config = dev->chip_info; if (config) { /* Wake capabilities */ acpigen_write_PRW(config->wake, ACPI_S3); @@ -549,9 +581,37 @@ static void wifi_ssdt_write_properties(const struct device *dev, const char *sco acpigen_pop_len(); } + struct dsm_uuid dsm_ids[MAX_DSM_FUNCS]; + /* We will need a copy dsm data to be used later for creating _DSM function */ + struct dsm_profile dsm = {0}; + uint8_t dsm_count = 0; + /* Fill Wifi sar related ACPI structures */ - if (CONFIG(USE_SAR)) - emit_sar_acpi_structures(dev); + if (CONFIG(USE_SAR)) { + emit_sar_acpi_structures(dev, &dsm); + + if (dsm.supported_functions != 0) { + for (int i = 1; i < ARRAY_SIZE(wifi_dsm_callbacks); i++) + if (!(dsm.supported_functions & (1 << i))) + wifi_dsm_callbacks[i] = NULL; + + dsm_ids[dsm_count].uuid = ACPI_DSM_OEM_WIFI_UUID; + dsm_ids[dsm_count].callbacks = &wifi_dsm_callbacks[0]; + dsm_ids[dsm_count].count = ARRAY_SIZE(wifi_dsm_callbacks); + dsm_ids[dsm_count].arg = NULL; + dsm_count++; + } + } + + if (is_cnvi_ddr_rfim_enabled) { + dsm_ids[dsm_count].uuid = ACPI_DSM_RFIM_WIFI_UUID; + dsm_ids[dsm_count].callbacks = &wifi_dsm2_callbacks[0]; + dsm_ids[dsm_count].count = ARRAY_SIZE(wifi_dsm2_callbacks); + dsm_ids[dsm_count].arg = &is_cnvi_ddr_rfim_enabled; + dsm_count++; + } + + acpigen_write_dsm_uuid_arr(dsm_ids, dsm_count); acpigen_pop_len(); /* Scope */