summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/wifi/generic/acpi.c81
-rw-r--r--src/drivers/wifi/generic/chip.h3
2 files changed, 80 insertions, 4 deletions
diff --git a/src/drivers/wifi/generic/acpi.c b/src/drivers/wifi/generic/acpi.c
index d3da51b116..e303589660 100644
--- a/src/drivers/wifi/generic/acpi.c
+++ b/src/drivers/wifi/generic/acpi.c
@@ -15,8 +15,9 @@
#include "wifi.h"
#include "wifi_private.h"
-/* WIFI Domain type */
+/* Domain type */
#define DOMAIN_TYPE_WIFI 0x7
+#define DOMAIN_TYPE_BLUETOOTH 0x12
/* Maximum number DSM UUID bifurcations in _DSM */
#define MAX_DSM_FUNCS 2
@@ -489,9 +490,59 @@ static void sar_emit_wtas(struct avg_profile *wtas)
acpigen_write_package_end();
}
-static void emit_sar_acpi_structures(const struct device *dev, struct dsm_profile *dsm)
+static void sar_emit_brds(const struct bsar_profile *bsar)
{
- union wifi_sar_limits sar_limits = {{NULL, NULL, NULL, NULL, NULL} };
+ size_t package_size, table_size;
+ const uint8_t *set;
+
+ /*
+ * Name ("BRDS", Package () {
+ * Revision,
+ * Package () {
+ * Domain Type, // 0x12:Bluetooth
+ * Bluetooth SAR BIOS, // BIOS SAR Enable/disable
+ * Bluetooth Increase Power Mode // SAR Limitation Enable/disable
+ * Bluetooth SAR Power Restriction, // 00000000 - 0dBm
+ * // 11111111 - 31.875dBm
+ * // (Step 0.125dBm)
+ * Bluetooth SAR Table // SAR Tx power limit table
+ * }
+ * })
+ */
+ if (bsar->revision != BSAR_REVISION) {
+ printk(BIOS_ERR, "Unsupported BSAR table revision: %d\n",
+ bsar->revision);
+ return;
+ }
+
+ acpigen_write_name("BRDS");
+ acpigen_write_package(2);
+ acpigen_write_dword(bsar->revision);
+
+ table_size = sizeof(*bsar) -
+ offsetof(struct bsar_profile, sar_lb_power_restriction);
+ /*
+ * Emit 'Domain Type' + 'Dynamic SAR Enable' + 'Increase Power Mode'
+ * + ('SAR Power Restriction' + SAR table).
+ */
+ package_size = 1 + 1 + 1 + table_size;
+ acpigen_write_package(package_size);
+ acpigen_write_dword(DOMAIN_TYPE_BLUETOOTH);
+ acpigen_write_dword(1);
+ acpigen_write_dword(bsar->increased_power_mode_limitation);
+
+ set = (const uint8_t *)&bsar->sar_lb_power_restriction;
+ for (int i = 0; i < table_size; i++)
+ acpigen_write_byte(set[i]);
+
+ acpigen_write_package_end();
+ acpigen_write_package_end();
+}
+
+static void emit_sar_acpi_structures(const struct device *dev, struct dsm_profile *dsm,
+ struct bsar_profile *bsar, bool *bsar_loaded)
+{
+ union wifi_sar_limits sar_limits = {0};
/*
* If device type is PCI, ensure that the device has Intel vendor ID. CBFS SAR and SAR
@@ -516,6 +567,12 @@ static void emit_sar_acpi_structures(const struct device *dev, struct dsm_profil
if (sar_limits.dsm != NULL)
memcpy(dsm, sar_limits.dsm, sizeof(struct dsm_profile));
+ /* copy the bsar data to be later used for creating Bluetooth BRDS method */
+ if (sar_limits.bsar != NULL) {
+ memcpy(bsar, sar_limits.bsar, sizeof(struct bsar_profile));
+ *bsar_loaded = true;
+ }
+
free(sar_limits.sar);
}
@@ -576,11 +633,14 @@ static void wifi_ssdt_write_properties(const struct device *dev, const char *sco
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};
+ /* We will need a copy of bsar data to be used later for creating BRDS function */
+ struct bsar_profile bsar = {0};
+ bool bsar_loaded = false;
uint8_t dsm_count = 0;
/* Fill Wifi SAR related ACPI structures */
if (CONFIG(USE_SAR)) {
- emit_sar_acpi_structures(dev, &dsm);
+ emit_sar_acpi_structures(dev, &dsm, &bsar, &bsar_loaded);
if (dsm.supported_functions != 0) {
for (int i = 1; i < ARRAY_SIZE(wifi_dsm_callbacks); i++)
@@ -618,6 +678,19 @@ static void wifi_ssdt_write_properties(const struct device *dev, const char *sco
acpigen_write_scope_end(); /* Scope */
+ /* Fill Bluetooth companion SAR related ACPI structures */
+ if (bsar_loaded && is_dev_enabled(config->bluetooth_companion)) {
+ const char *path = acpi_device_path(config->bluetooth_companion);
+ if (path) { /* Bluetooth device under USB Hub scope or PCIe root port */
+ acpigen_write_scope(path);
+ sar_emit_brds(&bsar);
+ acpigen_write_scope_end();
+ } else {
+ printk(BIOS_ERR, "Failed to get %s Bluetooth companion ACPI path\n",
+ dev_path(dev));
+ }
+ }
+
printk(BIOS_INFO, "%s: %s %s\n", scope, dev->chip_ops ? dev->chip_ops->name : "",
dev_path(dev));
}
diff --git a/src/drivers/wifi/generic/chip.h b/src/drivers/wifi/generic/chip.h
index 2729a35663..302dd144ef 100644
--- a/src/drivers/wifi/generic/chip.h
+++ b/src/drivers/wifi/generic/chip.h
@@ -19,6 +19,9 @@ struct drivers_wifi_generic_config {
* SoC code propagates this value the applicable FSP UPD.
*/
bool enable_cnvi_ddr_rfim;
+
+ /* Pointer to the Bluetooth companion device */
+ DEVTREE_CONST struct device *bluetooth_companion;
};
#endif /* _GENERIC_WIFI_H_ */