diff options
-rw-r--r-- | src/drivers/intel/wifi/Kconfig | 24 | ||||
-rw-r--r-- | src/drivers/intel/wifi/chip.h | 32 | ||||
-rw-r--r-- | src/drivers/intel/wifi/wifi.c | 71 |
3 files changed, 127 insertions, 0 deletions
diff --git a/src/drivers/intel/wifi/Kconfig b/src/drivers/intel/wifi/Kconfig index 330de6c6dc..1e6be6dfd0 100644 --- a/src/drivers/intel/wifi/Kconfig +++ b/src/drivers/intel/wifi/Kconfig @@ -5,3 +5,27 @@ config DRIVERS_INTEL_WIFI help When enabled, add identifiers in ACPI and SMBIOS tables to make OS drivers work with certain Intel PCI-e WiFi chipsets. + +config USE_SAR + bool + default n + help + Enable it when wifi driver uses SAR configuration feature. + VPD entry "wifi_sar" is required to support it. + +config SAR_ENABLE + bool + default n + depends on USE_SAR + +config DSAR_ENABLE + bool + default n + depends on USE_SAR + +config DSAR_SET_NUM + hex "Number of SAR sets when D-SAR is enabled" + default 0x3 + depends on USE_SAR + help + There can be up to 3 optional SAR table sets. diff --git a/src/drivers/intel/wifi/chip.h b/src/drivers/intel/wifi/chip.h index 117d39caf0..0871874ba7 100644 --- a/src/drivers/intel/wifi/chip.h +++ b/src/drivers/intel/wifi/chip.h @@ -1,3 +1,35 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016-2017 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _WIFI_CHIP_H_ +#define _WIFI_CHIP_H_ + +/* WRDS Spec Revision */ +#define WRDS_REVISION 0x0 + +/* EWRD Spec Revision */ +#define EWRD_REVISION 0x0 + +/* WRDS Domain type */ +#define WRDS_DOMAIN_TYPE_WIFI 0x7 + +/* EWRD Domain type */ +#define EWRD_DOMAIN_TYPE_WIFI 0x7 + struct drivers_intel_wifi_config { unsigned wake; /* Wake pin for ACPI _PRW */ }; + +#endif /* _WIFI_CHIP_H_ */ diff --git a/src/drivers/intel/wifi/wifi.c b/src/drivers/intel/wifi/wifi.c index 789d0d5431..06bc54c788 100644 --- a/src/drivers/intel/wifi/wifi.c +++ b/src/drivers/intel/wifi/wifi.c @@ -20,6 +20,7 @@ #include <device/device.h> #include <device/pci.h> #include <device/pci_ids.h> +#include <sar.h> #include <smbios.h> #include <string.h> #include <wrdd.h> @@ -59,6 +60,72 @@ static int smbios_write_wifi(struct device *dev, int *handle, #endif #if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES) +static void emit_sar_acpi_structures(void) +{ + int i, j, package_size; + struct wifi_sar_limits sar_limits; + + /* Retrieve the sar limits data */ + if (get_wifi_sar_limits(&sar_limits) < 0) { + printk(BIOS_ERR, "Error: failed from getting SAR limits!\n"); + return; + } + + /* + * Name ("WRDS", Package () { + * Revision, + * Package () { + * Domain Type, // 0x7:WiFi + * WiFi SAR BIOS, // BIOS SAR Enable/disable + * SAR Table Set // Set#1 of SAR Table (10 bytes) + * } + * }) + */ + acpigen_write_name("WRDS"); + acpigen_write_package(2); + acpigen_write_dword(WRDS_REVISION); + /* Emit 'Domain Type' + 'WiFi SAR BIOS' + 10 bytes for Set#1 */ + package_size = 1 + 1 + BYTES_PER_SAR_LIMIT; + acpigen_write_package(package_size); + acpigen_write_dword(WRDS_DOMAIN_TYPE_WIFI); + acpigen_write_dword(CONFIG_SAR_ENABLE); + for (i = 0; i < BYTES_PER_SAR_LIMIT; i++) + acpigen_write_byte(sar_limits.sar_limit[0][i]); + acpigen_pop_len(); + acpigen_pop_len(); + + /* + * Name ("EWRD", Package () { + * Revision, + * Package () { + * Domain Type, // 0x7:WiFi + * Dynamic SAR Enable, // Dynamic SAR Enable/disable + * Extended SAR sets, // Number of optional SAR table sets + * SAR Table Set, // Set#2 of SAR Table (10 bytes) + * SAR Table Set, // Set#3 of SAR Table (10 bytes) + * SAR Table Set // Set#4 of SAR Table (10 bytes) + * } + * }) + */ + acpigen_write_name("EWRD"); + acpigen_write_package(2); + acpigen_write_dword(EWRD_REVISION); + /* + * Emit 'Domain Type' + "Dynamic SAR Enable' + 'Extended SAR sets' + * + number of bytes for Set#2 & 3 & 4 + */ + package_size = 1 + 1 + 1 + (NUM_SAR_LIMITS - 1) * BYTES_PER_SAR_LIMIT; + acpigen_write_package(package_size); + acpigen_write_dword(EWRD_DOMAIN_TYPE_WIFI); + acpigen_write_dword(CONFIG_DSAR_ENABLE); + acpigen_write_dword(CONFIG_DSAR_SET_NUM); + for (i = 1; i < NUM_SAR_LIMITS; i++) + for (j = 0; j < BYTES_PER_SAR_LIMIT; j++) + acpigen_write_byte(sar_limits.sar_limit[i][j]); + acpigen_pop_len(); + acpigen_pop_len(); +} + static void intel_wifi_fill_ssdt(struct device *dev) { struct drivers_intel_wifi_config *config = dev->chip_info; @@ -105,6 +172,10 @@ static void intel_wifi_fill_ssdt(struct device *dev) acpigen_pop_len(); } + /* Fill Wifi sar related ACPI structures */ + if (IS_ENABLED(CONFIG_USE_SAR)) + emit_sar_acpi_structures(); + acpigen_pop_len(); /* Device */ acpigen_pop_len(); /* Scope */ |