[2/9] mt76: Add support to the Mediatek MT7921 for ACPI WBRF

Message ID 20230530024227.2139632-3-evan.quan@amd.com
State New
Headers
Series Support Wifi RFI interference mitigation feature |

Commit Message

Evan Quan May 30, 2023, 2:42 a.m. UTC
  From: Mario Limonciello <mario.limonciello@amd.com>

Mediatek wifi adapters are utilized in systems that support AMD's WBRF
interference mitigation mechanism. For this mechanism to work frequencies
utilized use must be notified to an ACPI device.

If the kernel is configured with CONFIG_ACPI_WBRF then notify this ACPI
device accordingly.

Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Anson Taso <anson.tsao@amd.com>
Co-developed-by: Anson Taso <anson.tsao@amd.com>
--
v1->v2:
  - Fix build errors below for mt76 w/ WBRF enabled
    ERROR: modpost: "mt76_add_wbrf" [drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2e.ko] undefined!
    ERROR: modpost: "mt76_remove_wbrf" [drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2e.ko] undefined!
    ERROR: modpost: "mt76_init_acpi_wbrf" [drivers/net/wireless/mediatek/mt76/mt7921/mt7921-common.ko] undefined!
v2->v3:
  - add support to the real driver(mt7921/main.c) which supports
    Mediatek MT7921
---
 drivers/net/wireless/mediatek/mt76/Makefile   |  1 +
 .../net/wireless/mediatek/mt76/acpi_wbrf.c    | 36 +++++++++++++++++++
 drivers/net/wireless/mediatek/mt76/mt76.h     | 19 ++++++++++
 .../net/wireless/mediatek/mt76/mt7921/init.c  |  2 ++
 .../net/wireless/mediatek/mt76/mt7921/main.c  |  3 ++
 5 files changed, 61 insertions(+)
 create mode 100644 drivers/net/wireless/mediatek/mt76/acpi_wbrf.c
  

Patch

diff --git a/drivers/net/wireless/mediatek/mt76/Makefile b/drivers/net/wireless/mediatek/mt76/Makefile
index 84c99b7e57f9..c016c71f23bd 100644
--- a/drivers/net/wireless/mediatek/mt76/Makefile
+++ b/drivers/net/wireless/mediatek/mt76/Makefile
@@ -12,6 +12,7 @@  mt76-y := \
 
 mt76-$(CONFIG_PCI) += pci.o
 mt76-$(CONFIG_NL80211_TESTMODE) += testmode.o
+mt76-$(CONFIG_ACPI_WBRF) += acpi_wbrf.o
 
 mt76-usb-y := usb.o usb_trace.o
 mt76-sdio-y := sdio.o sdio_txrx.o
diff --git a/drivers/net/wireless/mediatek/mt76/acpi_wbrf.c b/drivers/net/wireless/mediatek/mt76/acpi_wbrf.c
new file mode 100644
index 000000000000..ceef57bddc6f
--- /dev/null
+++ b/drivers/net/wireless/mediatek/mt76/acpi_wbrf.c
@@ -0,0 +1,36 @@ 
+// SPDX-License-Identifier: ISC
+/* Copyright (C) 2023 Advanced Micro Devices */
+
+#include <linux/wbrf.h>
+#include "mt76.h"
+
+#if defined(CONFIG_ACPI_WBRF)
+void mt76_init_acpi_wbrf(struct mt76_dev *dev)
+{
+	struct acpi_device *acpi_dev = ACPI_COMPANION(dev->dev);
+
+	if (!acpi_dev) {
+		dev_dbg(dev->dev, "ACPI companion not found\n");
+		return;
+	}
+
+	dev->phy.wbrf = wbrf_supported_producer(acpi_dev);
+	dev_dbg(dev->dev, "WBRF is %s supported\n",
+		dev->phy.wbrf ? "" : "not");
+}
+EXPORT_SYMBOL_GPL(mt76_init_acpi_wbrf);
+int mt76_add_wbrf(struct mt76_dev *dev, struct cfg80211_chan_def *chandef)
+{
+	if (!dev->phy.wbrf)
+		return 0;
+	return wbrf_add_exclusion_wlan(ACPI_COMPANION(dev->dev), chandef);
+}
+EXPORT_SYMBOL_GPL(mt76_add_wbrf);
+int mt76_remove_wbrf(struct mt76_dev *dev, struct cfg80211_chan_def *chandef)
+{
+	if (!dev->phy.wbrf)
+		return 0;
+	return wbrf_remove_exclusion_wlan(ACPI_COMPANION(dev->dev), chandef);
+}
+EXPORT_SYMBOL_GPL(mt76_remove_wbrf);
+#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 6b07b8fafec2..fd33a553ba2e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -733,6 +733,7 @@  struct mt76_phy {
 	int txpower_cur;
 	u8 antenna_mask;
 	u16 chainmask;
+	bool wbrf;
 
 #ifdef CONFIG_NL80211_TESTMODE
 	struct mt76_testmode_data test;
@@ -1511,4 +1512,22 @@  mt76_packet_id_flush(struct mt76_dev *dev, struct mt76_wcid *wcid)
 	idr_destroy(&wcid->pktid);
 }
 
+#ifdef CONFIG_ACPI_WBRF
+void mt76_init_acpi_wbrf(struct mt76_dev *dev);
+int mt76_add_wbrf(struct mt76_dev *dev, struct cfg80211_chan_def *chandef);
+int mt76_remove_wbrf(struct mt76_dev *dev, struct cfg80211_chan_def *chandef);
+#else
+static inline void mt76_init_acpi_wbrf(struct mt76_dev *dev) { };
+static inline int
+mt76_add_wbrf(struct mt76_dev *dev, struct cfg80211_chan_def *chandef)
+{
+	return 0;
+}
+static inline int
+mt76_remove_wbrf(struct mt76_dev *dev, struct cfg80211_chan_def *chandef)
+{
+	return 0;
+}
+#endif /* CONFIG_ACPI_WBRF */
+
 #endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
index bf1da9fddfab..91396139a177 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
@@ -420,6 +420,8 @@  int mt7921_register_device(struct mt7921_dev *dev)
 
 	mt7921_init_acpi_sar(dev);
 
+	mt76_init_acpi_wbrf(&dev->mt76);
+
 	ret = mt7921_init_wcid(dev);
 	if (ret)
 		return ret;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
index 3b6adb29cbef..241d5b1729dd 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
@@ -480,6 +480,8 @@  static int mt7921_set_channel(struct mt7921_phy *phy)
 	mt7921_mutex_acquire(dev);
 	set_bit(MT76_RESET, &phy->mt76->state);
 
+	mt76_remove_wbrf(phy->mt76->dev, &phy->mt76->chandef);
+
 	mt76_set_channel(phy->mt76);
 
 	ret = mt7921_mcu_set_chan_info(phy, MCU_EXT_CMD(CHANNEL_SWITCH));
@@ -493,6 +495,7 @@  static int mt7921_set_channel(struct mt7921_phy *phy)
 
 out:
 	clear_bit(MT76_RESET, &phy->mt76->state);
+	mt76_add_wbrf(phy->mt76->dev, &phy->mt76->chandef);
 	mt7921_mutex_release(dev);
 
 	mt76_worker_schedule(&dev->mt76.tx_worker);