blob: 16b085896ac48f766ced3871e7b764fd8cee088b [file] [log] [blame]
developerec4ebe42022-04-12 11:17:45 +08001From ced1d19944f5da249dfacc0a4ef3d5616efc4f87 Mon Sep 17 00:00:00 2001
2From: Shayne Chen <shayne.chen@mediatek.com>
3Date: Mon, 10 May 2021 20:50:43 +0800
4Subject: [PATCH 1106/1112] mt76: testmode: add virtual stations support
5
6Introduce a virtual station struct mt76_testmode_sta for the
7preparation of HE-MU and RU setting support in testmode.
8
9Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
10---
11 drivers/net/wireless/mediatek/mt76/mt76.h | 103 +++++++++++++++---
12 drivers/net/wireless/mediatek/mt76/testmode.c | 6 +-
13 drivers/net/wireless/mediatek/mt76/testmode.h | 5 +
14 drivers/net/wireless/mediatek/mt76/tx.c | 3 +-
15 4 files changed, 99 insertions(+), 18 deletions(-)
16
17diff --git a/mt76.h b/mt76.h
18index ab9482c..ce4a098 100644
19--- a/mt76.h
20+++ b/mt76.h
21@@ -586,6 +586,22 @@ struct mt76_testmode_ops {
22
23 #define MT_TM_FW_RX_COUNT BIT(0)
24
25+struct mt76_testmode_sta_data {
26+ u16 tx_mpdu_len;
27+ u8 tx_rate_idx;
28+ u8 tx_rate_nss;
29+ u8 tx_rate_ldpc;
30+
31+ u8 aid;
32+ u8 ru_alloc;
33+ u8 ru_idx;
34+};
35+
36+struct mt76_testmode_sta {
37+ struct sk_buff *tx_skb;
38+ struct mt76_testmode_sta_data sd;
39+};
40+
41 struct mt76_testmode_data {
42 enum mt76_testmode_state state;
43
44@@ -593,13 +609,9 @@ struct mt76_testmode_data {
45 struct sk_buff *tx_skb;
46
47 u32 tx_count;
48- u16 tx_mpdu_len;
49
50 u8 tx_rate_mode;
51- u8 tx_rate_idx;
52- u8 tx_rate_nss;
53 u8 tx_rate_sgi;
54- u8 tx_rate_ldpc;
55 u8 tx_rate_stbc;
56 u8 tx_ltf;
57
58@@ -629,6 +641,22 @@ struct mt76_testmode_data {
59 u8 off_ch_scan_bw;
60 u8 off_ch_scan_path;
61
62+ struct mt76_wcid *tm_wcid[MT76_TM_MAX_STA_NUM + 1];
63+ u16 tm_sta_mask;
64+ union {
65+ struct mt76_testmode_sta_data sd;
66+ struct {
67+ u16 tx_mpdu_len;
68+ u8 tx_rate_idx;
69+ u8 tx_rate_nss;
70+ u8 tx_rate_ldpc;
71+
72+ u8 aid;
73+ u8 ru_alloc;
74+ u8 ru_idx;
75+ };
76+ };
77+
78 u32 tx_pending;
79 u32 tx_queued;
80 u16 tx_queued_limit;
81@@ -1107,22 +1135,69 @@ static inline bool mt76_testmode_enabled(struct mt76_phy *phy)
82 #endif
83 }
84
85+#ifdef CONFIG_NL80211_TESTMODE
86+static inline bool
87+mt76_testmode_has_sta(struct mt76_phy *phy)
88+{
89+ return phy->test.tm_sta_mask != 0;
90+}
91+
92+static inline struct mt76_testmode_sta *
93+mt76_testmode_aid_get_sta(struct mt76_phy *phy, u8 aid)
94+{
95+ struct mt76_wcid *wcid = phy->test.tm_wcid[aid];
96+
97+ if (!wcid || !aid)
98+ return NULL;
99+
100+ return (struct mt76_testmode_sta *)((u8 *)wcid + phy->hw->sta_data_size);
101+}
102+
103+#define mt76_testmode_for_each_sta(phy, aid, tm_sta) \
104+ for (aid = 1, tm_sta = mt76_testmode_aid_get_sta(phy, 1); \
105+ aid <= hweight16(phy->test.tm_sta_mask); \
106+ aid = phy->test.tm_sta_mask >> aid ? \
107+ ffs(phy->test.tm_sta_mask >> aid) + aid : \
108+ aid + 1, \
109+ tm_sta = mt76_testmode_aid_get_sta(phy, aid))
110+
111+static inline bool
112+__mt76_testmode_check_skb(struct mt76_phy *phy, struct sk_buff *skb)
113+{
114+ struct mt76_testmode_sta *tm_sta;
115+ int i;
116+
117+ if (!mt76_testmode_has_sta(phy))
118+ return false;
119+
120+ mt76_testmode_for_each_sta(phy, i, tm_sta) {
121+ if (tm_sta->tx_skb == skb)
122+ return true;
123+ }
124+
125+ return false;
126+}
127+
128 static inline bool mt76_is_testmode_skb(struct mt76_dev *dev,
129 struct sk_buff *skb,
130 struct ieee80211_hw **hw)
131 {
132-#ifdef CONFIG_NL80211_TESTMODE
133- if (skb == dev->phy.test.tx_skb)
134- *hw = dev->phy.hw;
135- else if (dev->phy2 && skb == dev->phy2->test.tx_skb)
136- *hw = dev->phy2->hw;
137- else
138- return false;
139- return true;
140-#else
141+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
142+ struct mt76_phy *phy = &dev->phy;
143+
144+ if ((info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY) && dev->phy2)
145+ phy = dev->phy2;
146+
147+ if (mt76_testmode_enabled(phy) &&
148+ (skb == phy->test.tx_skb ||
149+ __mt76_testmode_check_skb(phy, skb))) {
150+ *hw = phy->hw;
151+ return true;
152+ }
153+
154 return false;
155-#endif
156 }
157+#endif
158
159 void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb);
160 void mt76_tx(struct mt76_phy *dev, struct ieee80211_sta *sta,
161diff --git a/testmode.c b/testmode.c
162index 2376e00..682ca3d 100644
163--- a/testmode.c
164+++ b/testmode.c
165@@ -382,7 +382,6 @@ int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state
166 }
167
168 return __mt76_testmode_set_state(phy, state);
169-
170 }
171 EXPORT_SYMBOL(mt76_testmode_set_state);
172
173@@ -495,7 +494,10 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
174 mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_DUTY_CYCLE],
175 &td->tx_duty_cycle, 0, 99) ||
176 mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_POWER_CONTROL],
177- &td->tx_power_control, 0, 1))
178+ &td->tx_power_control, 0, 1) ||
179+ mt76_tm_get_u8(tb[MT76_TM_ATTR_AID], &td->aid, 0, 16) ||
180+ mt76_tm_get_u8(tb[MT76_TM_ATTR_RU_ALLOC], &td->ru_alloc, 0, 0xff) ||
181+ mt76_tm_get_u8(tb[MT76_TM_ATTR_RU_IDX], &td->ru_idx, 0, 68))
182 goto out;
183
184 if (tb[MT76_TM_ATTR_TX_LENGTH]) {
185diff --git a/testmode.h b/testmode.h
186index 0fc0ddd..b360d7a 100644
187--- a/testmode.h
188+++ b/testmode.h
189@@ -7,6 +7,7 @@
190
191 #define MT76_TM_TIMEOUT 10
192 #define MT76_TM_EEPROM_BLOCK_SIZE 16
193+#define MT76_TM_MAX_STA_NUM 16
194
195 /**
196 * enum mt76_testmode_attr - testmode attributes inside NL80211_ATTR_TESTDATA
197@@ -111,6 +112,10 @@ enum mt76_testmode_attr {
198 MT76_TM_ATTR_OFF_CH_SCAN_BW,
199 MT76_TM_ATTR_OFF_CH_SCAN_PATH,
200
201+ MT76_TM_ATTR_AID,
202+ MT76_TM_ATTR_RU_ALLOC,
203+ MT76_TM_ATTR_RU_IDX,
204+
205 /* keep last */
206 NUM_MT76_TM_ATTRS,
207 MT76_TM_ATTR_MAX = NUM_MT76_TM_ATTRS - 1,
208diff --git a/tx.c b/tx.c
209index 6b8c9dc..ca5e6d9 100644
210--- a/tx.c
211+++ b/tx.c
212@@ -245,8 +245,7 @@ void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *
213 if (mt76_is_testmode_skb(dev, skb, &hw)) {
214 struct mt76_phy *phy = hw->priv;
215
216- if (skb == phy->test.tx_skb)
217- phy->test.tx_done++;
218+ phy->test.tx_done++;
219 if (phy->test.tx_queued == phy->test.tx_done)
220 wake_up(&dev->tx_wait);
221
222--
2232.25.1
224