blob: 6cde16b50a2addb8887aea9f9773691dfb11c597 [file] [log] [blame]
From 6b6bfdf1f132cdd665b88613ed714b93604a03a0 Mon Sep 17 00:00:00 2001
From: Howard Hsu <howard-yh.hsu@mediatek.com>
Date: Mon, 4 Mar 2024 16:21:16 +0800
Subject: [PATCH 120/120] mtk: wifi: mt76: mt7996: support band_idx option for
set_mu/get_mu vendor command
The vendor command set_mu and get_mu should be executed with band_idx.
With band_idx, driver can access the corrsponding phy by band_idx.
CR-Id: WCNCR00240772
Change-Id: Id33d5efd3752e767fc11e852836d9939e4d6a088
Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
---
mt7996/mcu.c | 26 +++++++++++++++++++-------
mt7996/mcu.h | 1 +
mt7996/vendor.c | 40 +++++++++++++++++++++++++++++++++++-----
mt7996/vendor.h | 1 +
4 files changed, 56 insertions(+), 12 deletions(-)
diff --git a/mt7996/mcu.c b/mt7996/mcu.c
index e4d840599..fee2d35c4 100644
--- a/mt7996/mcu.c
+++ b/mt7996/mcu.c
@@ -5829,12 +5829,23 @@ int mt7996_mcu_set_vow_feature_ctrl(struct mt7996_phy *phy)
#ifdef CONFIG_MTK_VENDOR
void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
{
- u8 mode, val;
+ u8 mode, val, band_idx;
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
- struct mt7996_phy *phy = mvif->deflink.phy;
+ struct mt7996_phy *phy;
+ struct mt76_phy *mphy;
mode = FIELD_GET(RATE_CFG_MODE, *((u32 *)data));
val = FIELD_GET(RATE_CFG_VAL, *((u32 *)data));
+ band_idx = FIELD_GET(RATE_CFG_BAND_IDX, *((u32 *)data));
+
+ if (!mt7996_band_valid(mvif->dev, band_idx))
+ goto error;
+
+ mphy = mvif->dev->mt76.phys[band_idx];
+ if (!mphy)
+ goto error;
+
+ phy = (struct mt7996_phy *)mphy->priv;
switch (mode) {
case RATE_PARAM_FIXED_OFDMA:
@@ -5850,13 +5861,14 @@ void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
phy->muru_onoff = MUMIMO_UL;
break;
case RATE_PARAM_AUTO_MU:
- if (val < 0 || val > 15) {
- printk("Wrong value! The value is between 0-15.\n");
- break;
- }
- phy->muru_onoff = val;
+ phy->muru_onoff = val & GENMASK(3, 0);
break;
}
+
+ return;
+error:
+ dev_err(mvif->dev->mt76.dev, "Invalid band_idx to config\n");
+ return;
}
void mt7996_set_beacon_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
diff --git a/mt7996/mcu.h b/mt7996/mcu.h
index 7d200a334..016e6764e 100644
--- a/mt7996/mcu.h
+++ b/mt7996/mcu.h
@@ -887,6 +887,7 @@ enum {
#endif
};
+#define RATE_CFG_BAND_IDX GENMASK(17, 16)
#define RATE_CFG_MODE GENMASK(15, 8)
#define RATE_CFG_VAL GENMASK(7, 0)
diff --git a/mt7996/vendor.c b/mt7996/vendor.c
index c87cc5c1d..b46fd186e 100644
--- a/mt7996/vendor.c
+++ b/mt7996/vendor.c
@@ -16,6 +16,7 @@ mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL] = {
[MTK_VENDOR_ATTR_MU_CTRL_ONOFF] = {.type = NLA_U8 },
[MTK_VENDOR_ATTR_MU_CTRL_DUMP] = {.type = NLA_U8 },
[MTK_VENDOR_ATTR_MU_CTRL_STRUCT] = {.type = NLA_BINARY },
+ [MTK_VENDOR_ATTR_MU_CTRL_BAND_IDX] = {.type = NLA_U8 },
};
static const struct nla_policy
@@ -134,7 +135,7 @@ static int mt7996_vendor_mu_ctrl(struct wiphy *wiphy,
struct mt7996_phy *phy = mt7996_hw_phy(hw);
struct mt7996_muru *muru;
int err;
- u8 val8;
+ u8 val8, band_idx;
u32 val32 = 0;
err = nla_parse(tb, MTK_VENDOR_ATTR_MU_CTRL_MAX, data, data_len,
@@ -142,10 +143,13 @@ static int mt7996_vendor_mu_ctrl(struct wiphy *wiphy,
if (err)
return err;
- if (tb[MTK_VENDOR_ATTR_MU_CTRL_ONOFF]) {
+ if (tb[MTK_VENDOR_ATTR_MU_CTRL_ONOFF] &&
+ tb[MTK_VENDOR_ATTR_MU_CTRL_BAND_IDX]) {
val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_MU_CTRL_ONOFF]);
+ band_idx = nla_get_u8(tb[MTK_VENDOR_ATTR_MU_CTRL_BAND_IDX]);
val32 |= FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_AUTO_MU) |
- FIELD_PREP(RATE_CFG_VAL, val8);
+ FIELD_PREP(RATE_CFG_VAL, val8) |
+ FIELD_PREP(RATE_CFG_BAND_IDX, band_idx);
ieee80211_iterate_active_interfaces_atomic(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
mt7996_set_wireless_vif, &val32);
} else if (tb[MTK_VENDOR_ATTR_MU_CTRL_STRUCT]) {
@@ -167,18 +171,44 @@ mt7996_vendor_mu_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
unsigned long *storage)
{
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
- struct mt7996_phy *phy = mt7996_hw_phy(hw);
- int len = 0;
+ struct mt7996_dev *dev = mt7996_hw_dev(hw);
+ struct mt7996_phy *phy;
+ struct mt76_phy *mphy;
+ struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_MU_CTRL];
+ int len = 0, err;
+ u8 band_idx;
if (*storage == 1)
return -ENOENT;
*storage = 1;
+ err = nla_parse(tb, MTK_VENDOR_ATTR_MU_CTRL_MAX, data, data_len,
+ mu_ctrl_policy, NULL);
+ if (err)
+ return err;
+
+ if (!tb[MTK_VENDOR_ATTR_MU_CTRL_BAND_IDX])
+ return -EINVAL;
+
+ band_idx = nla_get_u8(tb[MTK_VENDOR_ATTR_MU_CTRL_BAND_IDX]);
+ if (!mt7996_band_valid(dev, band_idx))
+ goto error;
+
+ mphy = dev->mt76.phys[band_idx];
+ if (!mphy)
+ goto error;
+
+ phy = (struct mt7996_phy *)mphy->priv;
+
if (nla_put_u8(skb, MTK_VENDOR_ATTR_MU_CTRL_DUMP, phy->muru_onoff))
return -ENOMEM;
len += 1;
return len;
+
+error:
+ dev_err(dev->mt76.dev, "Invalid band idx to dump\n");
+ return -EINVAL;
}
void mt7996_set_wireless_rts_sigta(struct ieee80211_hw *hw, u8 value) {
diff --git a/mt7996/vendor.h b/mt7996/vendor.h
index e7d88828c..cb250ceff 100644
--- a/mt7996/vendor.h
+++ b/mt7996/vendor.h
@@ -68,6 +68,7 @@ enum mtk_vendor_attr_mu_ctrl {
MTK_VENDOR_ATTR_MU_CTRL_ONOFF,
MTK_VENDOR_ATTR_MU_CTRL_DUMP,
MTK_VENDOR_ATTR_MU_CTRL_STRUCT,
+ MTK_VENDOR_ATTR_MU_CTRL_BAND_IDX,
/* keep last */
NUM_MTK_VENDOR_ATTRS_MU_CTRL,
--
2.39.2