2022-12-07 05:14:55

by Deren Wu

[permalink] [raw]
Subject: [PATCH] wifi: mt76: mt7921: add support to update fw capability with MTFG table

From: Quan Zhou <[email protected]>

In ACPI enabled devices, mt7921 should read MTFG table from platform
hardware. Apply necessary settings for firmware capabilities through CLC
command.

Co-developed-by: Deren Wu <[email protected]>
Signed-off-by: Deren Wu <[email protected]>
Signed-off-by: Quan Zhou <[email protected]>
---
.../wireless/mediatek/mt76/mt7921/acpi_sar.c | 55 +++++++++++++++++++
.../wireless/mediatek/mt76/mt7921/acpi_sar.h | 12 ++++
.../net/wireless/mediatek/mt76/mt7921/mcu.c | 4 +-
.../wireless/mediatek/mt76/mt7921/mt7921.h | 7 +++
4 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c b/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c
index 47e034a9b003..a98d0fb42d0a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c
@@ -135,6 +135,22 @@ mt7921_asar_acpi_read_mtgs(struct mt7921_dev *dev, u8 **table, u8 version)
return ret;
}

+/* MTFG : Flag Table */
+static int
+mt7921_asar_acpi_read_mtfg(struct mt7921_dev *dev, u8 **table)
+{
+ int len, ret;
+
+ ret = mt7921_acpi_read(dev, MT7921_ACPI_MTFG, table, &len);
+ if (ret)
+ return ret;
+
+ if (len < MT7921_ASAR_MIN_FG)
+ ret = -EINVAL;
+
+ return ret;
+}
+
int mt7921_init_acpi_sar(struct mt7921_dev *dev)
{
struct mt7921_acpi_sar *asar;
@@ -162,6 +178,12 @@ int mt7921_init_acpi_sar(struct mt7921_dev *dev)
asar->geo = NULL;
}

+ /* MTFG is optional */
+ ret = mt7921_asar_acpi_read_mtfg(dev, (u8 **)&asar->fg);
+ if (ret) {
+ devm_kfree(dev->mt76.dev, asar->fg);
+ asar->fg = NULL;
+ }
dev->phy.acpisar = asar;

return 0;
@@ -280,3 +302,36 @@ int mt7921_init_acpi_sar_power(struct mt7921_phy *phy, bool set_default)

return 0;
}
+
+u8 mt7921_acpi_get_flags(struct mt7921_phy *phy)
+{
+ struct mt7921_asar_fg *fg;
+ struct {
+ u8 acpi_idx;
+ u8 chip_idx;
+ } map[] = {
+ {1, 1},
+ {4, 2},
+ };
+ u8 flags = BIT(0);
+ int i, j;
+
+ if (!phy->acpisar)
+ return 0;
+
+ fg = phy->acpisar->fg;
+ if (!fg)
+ return flags;
+
+ /* pickup necessary settings per device and
+ * translate the index of bitmap for chip command.
+ */
+ for (i = 0; i < fg->nr_flag; i++)
+ for (j = 0; j < ARRAY_SIZE(map); j++)
+ if (fg->flag[i] == map[j].acpi_idx) {
+ flags |= BIT(map[j].chip_idx);
+ break;
+ }
+
+ return flags;
+}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.h b/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.h
index 23f86bfae0c0..35268b0890ad 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.h
@@ -8,10 +8,12 @@
#define MT7921_ASAR_MAX_DYN 8
#define MT7921_ASAR_MIN_GEO 3
#define MT7921_ASAR_MAX_GEO 8
+#define MT7921_ASAR_MIN_FG 8

#define MT7921_ACPI_MTCL "MTCL"
#define MT7921_ACPI_MTDS "MTDS"
#define MT7921_ACPI_MTGS "MTGS"
+#define MT7921_ACPI_MTFG "MTFG"

struct mt7921_asar_dyn_limit {
u8 idx;
@@ -77,6 +79,15 @@ struct mt7921_asar_cl {
u8 cl6g[6];
} __packed;

+struct mt7921_asar_fg {
+ u8 names[4];
+ u8 version;
+ u8 rsvd;
+ u8 nr_flag;
+ u8 rsvd1;
+ u8 flag[0];
+} __packed;
+
struct mt7921_acpi_sar {
u8 ver;
union {
@@ -88,6 +99,7 @@ struct mt7921_acpi_sar {
struct mt7921_asar_geo_v2 *geo_v2;
};
struct mt7921_asar_cl *countrylist;
+ struct mt7921_asar_fg *fg;
};

#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
index fb9c0f66cb27..8930b5a4467c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
@@ -1184,13 +1184,15 @@ int __mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2,
__le16 len;
u8 idx;
u8 env;
- u8 pad1[2];
+ u8 acpi_conf;
+ u8 pad1;
u8 alpha2[2];
u8 type[2];
u8 rsvd[64];
} __packed req = {
.idx = idx,
.env = env_cap,
+ .acpi_conf = mt7921_acpi_get_flags(&dev->phy),
};
int ret, valid_cnt = 0;
u8 i, *pos;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
index 15d6b7fe1c6c..efff4d43d796 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
@@ -554,6 +554,7 @@ int mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev,
#ifdef CONFIG_ACPI
int mt7921_init_acpi_sar(struct mt7921_dev *dev);
int mt7921_init_acpi_sar_power(struct mt7921_phy *phy, bool set_default);
+u8 mt7921_acpi_get_flags(struct mt7921_phy *phy);
#else
static inline int
mt7921_init_acpi_sar(struct mt7921_dev *dev)
@@ -566,6 +567,12 @@ mt7921_init_acpi_sar_power(struct mt7921_phy *phy, bool set_default)
{
return 0;
}
+
+static inline u8
+mt7921_acpi_get_flags(struct mt7921_phy *phy)
+{
+ return 0;
+}
#endif
int mt7921_set_tx_sar_pwr(struct ieee80211_hw *hw,
const struct cfg80211_sar_specs *sar);
--
2.18.0