blob: c07333f3ce13b7c97205da3b98227cb225bb862b [file] [log] [blame]
developer617abbd2024-04-23 14:50:01 +08001From e9b712d9fa71f982a52ee20eb86929d8938ec7ca Mon Sep 17 00:00:00 2001
2From: Howard Hsu <howard-yh.hsu@mediatek.com>
3Date: Mon, 4 Mar 2024 16:21:16 +0800
4Subject: [PATCH 110/116] mtk: wifi: mt76: mt7996: support band_idx option for
5 set_mu/get_mu vendor command
6
7The vendor command set_mu and get_mu should be executed with band_idx.
8With band_idx, driver can access the corrsponding phy by band_idx.
9
10CR-Id: WCNCR00240772
11Change-Id: Id33d5efd3752e767fc11e852836d9939e4d6a088
12Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
13---
14 mt7996/mcu.c | 26 +++++++++++++++++++-------
15 mt7996/mcu.h | 1 +
16 mt7996/vendor.c | 40 +++++++++++++++++++++++++++++++++++-----
17 mt7996/vendor.h | 1 +
18 4 files changed, 56 insertions(+), 12 deletions(-)
19
20diff --git a/mt7996/mcu.c b/mt7996/mcu.c
21index dc719ecbe..cd49f7058 100644
22--- a/mt7996/mcu.c
23+++ b/mt7996/mcu.c
24@@ -5853,12 +5853,23 @@ int mt7996_mcu_set_vow_feature_ctrl(struct mt7996_phy *phy)
25 #ifdef CONFIG_MTK_VENDOR
26 void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
27 {
28- u8 mode, val;
29+ u8 mode, val, band_idx;
30 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
31- struct mt7996_phy *phy = mvif->deflink.phy;
32+ struct mt7996_phy *phy;
33+ struct mt76_phy *mphy;
34
35 mode = FIELD_GET(RATE_CFG_MODE, *((u32 *)data));
36 val = FIELD_GET(RATE_CFG_VAL, *((u32 *)data));
37+ band_idx = FIELD_GET(RATE_CFG_BAND_IDX, *((u32 *)data));
38+
39+ if (!mt7996_band_valid(mvif->dev, band_idx))
40+ goto error;
41+
42+ mphy = mvif->dev->mt76.phys[band_idx];
43+ if (!mphy)
44+ goto error;
45+
46+ phy = (struct mt7996_phy *)mphy->priv;
47
48 switch (mode) {
49 case RATE_PARAM_FIXED_OFDMA:
50@@ -5874,13 +5885,14 @@ void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
51 phy->muru_onoff = MUMIMO_UL;
52 break;
53 case RATE_PARAM_AUTO_MU:
54- if (val < 0 || val > 15) {
55- printk("Wrong value! The value is between 0-15.\n");
56- break;
57- }
58- phy->muru_onoff = val;
59+ phy->muru_onoff = val & GENMASK(3, 0);
60 break;
61 }
62+
63+ return;
64+error:
65+ dev_err(mvif->dev->mt76.dev, "Invalid band_idx to config\n");
66+ return;
67 }
68
69 void mt7996_set_beacon_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
70diff --git a/mt7996/mcu.h b/mt7996/mcu.h
71index ee36cf5ed..3d5a0c3c2 100644
72--- a/mt7996/mcu.h
73+++ b/mt7996/mcu.h
74@@ -888,6 +888,7 @@ enum {
75 #endif
76 };
77
78+#define RATE_CFG_BAND_IDX GENMASK(17, 16)
79 #define RATE_CFG_MODE GENMASK(15, 8)
80 #define RATE_CFG_VAL GENMASK(7, 0)
81
82diff --git a/mt7996/vendor.c b/mt7996/vendor.c
83index 31688c373..64ef5515c 100644
84--- a/mt7996/vendor.c
85+++ b/mt7996/vendor.c
86@@ -16,6 +16,7 @@ mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL] = {
87 [MTK_VENDOR_ATTR_MU_CTRL_ONOFF] = {.type = NLA_U8 },
88 [MTK_VENDOR_ATTR_MU_CTRL_DUMP] = {.type = NLA_U8 },
89 [MTK_VENDOR_ATTR_MU_CTRL_STRUCT] = {.type = NLA_BINARY },
90+ [MTK_VENDOR_ATTR_MU_CTRL_BAND_IDX] = {.type = NLA_U8 },
91 };
92
93 static const struct nla_policy
94@@ -135,7 +136,7 @@ static int mt7996_vendor_mu_ctrl(struct wiphy *wiphy,
95 struct mt7996_phy *phy = mt7996_hw_phy(hw);
96 struct mt7996_muru *muru;
97 int err;
98- u8 val8;
99+ u8 val8, band_idx;
100 u32 val32 = 0;
101
102 err = nla_parse(tb, MTK_VENDOR_ATTR_MU_CTRL_MAX, data, data_len,
103@@ -143,10 +144,13 @@ static int mt7996_vendor_mu_ctrl(struct wiphy *wiphy,
104 if (err)
105 return err;
106
107- if (tb[MTK_VENDOR_ATTR_MU_CTRL_ONOFF]) {
108+ if (tb[MTK_VENDOR_ATTR_MU_CTRL_ONOFF] &&
109+ tb[MTK_VENDOR_ATTR_MU_CTRL_BAND_IDX]) {
110 val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_MU_CTRL_ONOFF]);
111+ band_idx = nla_get_u8(tb[MTK_VENDOR_ATTR_MU_CTRL_BAND_IDX]);
112 val32 |= FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_AUTO_MU) |
113- FIELD_PREP(RATE_CFG_VAL, val8);
114+ FIELD_PREP(RATE_CFG_VAL, val8) |
115+ FIELD_PREP(RATE_CFG_BAND_IDX, band_idx);
116 ieee80211_iterate_active_interfaces_atomic(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
117 mt7996_set_wireless_vif, &val32);
118 } else if (tb[MTK_VENDOR_ATTR_MU_CTRL_STRUCT]) {
119@@ -168,18 +172,44 @@ mt7996_vendor_mu_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
120 unsigned long *storage)
121 {
122 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
123- struct mt7996_phy *phy = mt7996_hw_phy(hw);
124- int len = 0;
125+ struct mt7996_dev *dev = mt7996_hw_dev(hw);
126+ struct mt7996_phy *phy;
127+ struct mt76_phy *mphy;
128+ struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_MU_CTRL];
129+ int len = 0, err;
130+ u8 band_idx;
131
132 if (*storage == 1)
133 return -ENOENT;
134 *storage = 1;
135
136+ err = nla_parse(tb, MTK_VENDOR_ATTR_MU_CTRL_MAX, data, data_len,
137+ mu_ctrl_policy, NULL);
138+ if (err)
139+ return err;
140+
141+ if (!tb[MTK_VENDOR_ATTR_MU_CTRL_BAND_IDX])
142+ return -EINVAL;
143+
144+ band_idx = nla_get_u8(tb[MTK_VENDOR_ATTR_MU_CTRL_BAND_IDX]);
145+ if (!mt7996_band_valid(dev, band_idx))
146+ goto error;
147+
148+ mphy = dev->mt76.phys[band_idx];
149+ if (!mphy)
150+ goto error;
151+
152+ phy = (struct mt7996_phy *)mphy->priv;
153+
154 if (nla_put_u8(skb, MTK_VENDOR_ATTR_MU_CTRL_DUMP, phy->muru_onoff))
155 return -ENOMEM;
156 len += 1;
157
158 return len;
159+
160+error:
161+ dev_err(dev->mt76.dev, "Invalid band idx to dump\n");
162+ return -EINVAL;
163 }
164
165 void mt7996_set_wireless_rts_sigta(struct ieee80211_hw *hw, u8 value) {
166diff --git a/mt7996/vendor.h b/mt7996/vendor.h
167index 0d1ef3228..323467756 100644
168--- a/mt7996/vendor.h
169+++ b/mt7996/vendor.h
170@@ -68,6 +68,7 @@ enum mtk_vendor_attr_mu_ctrl {
171 MTK_VENDOR_ATTR_MU_CTRL_ONOFF,
172 MTK_VENDOR_ATTR_MU_CTRL_DUMP,
173 MTK_VENDOR_ATTR_MU_CTRL_STRUCT,
174+ MTK_VENDOR_ATTR_MU_CTRL_BAND_IDX,
175
176 /* keep last */
177 NUM_MTK_VENDOR_ATTRS_MU_CTRL,
178--
1792.39.2
180