blob: e92177ae6f0898c41b54f1797a39ea1456e751b5 [file] [log] [blame]
From 19e0036562d574c6ffe6a47790dbfa953b35050c Mon Sep 17 00:00:00 2001
From: Shayne Chen <shayne.chen@mediatek.com>
Date: Tue, 11 May 2021 15:17:31 +0800
Subject: [PATCH 1109/1112] mt76: testmode: add support to queue skb of
multiple stations
Rework queue skb flow to support sending packet for multiple virtual
stations.
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 1 +
drivers/net/wireless/mediatek/mt76/testmode.c | 70 ++++++++++++++++---
2 files changed, 63 insertions(+), 8 deletions(-)
diff --git a/mt76.h b/mt76.h
index b5f1367..4b502c6 100644
--- a/mt76.h
+++ b/mt76.h
@@ -642,6 +642,7 @@ struct mt76_testmode_data {
u8 off_ch_scan_path;
struct mt76_wcid *tm_wcid[MT76_TM_MAX_STA_NUM + 1];
+ u8 cur_aid;
u16 tm_sta_mask;
union {
struct mt76_testmode_sta_data sd;
diff --git a/testmode.c b/testmode.c
index 0f93338..9da490c 100644
--- a/testmode.c
+++ b/testmode.c
@@ -25,18 +25,18 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
};
EXPORT_SYMBOL_GPL(mt76_tm_policy);
-void mt76_testmode_tx_pending(struct mt76_phy *phy)
+static u16
+mt76_testmode_queue_tx(struct mt76_phy *phy, struct mt76_wcid *wcid,
+ struct sk_buff *skb, u32 limit)
{
struct mt76_testmode_data *td = &phy->test;
struct mt76_dev *dev = phy->dev;
- struct mt76_wcid *wcid = &dev->global_wcid;
- struct sk_buff *skb = td->tx_skb;
struct mt76_queue *q;
- u16 tx_queued_limit;
+ u16 tx_queued_limit, count = 0;
int qid;
- if (!skb || !td->tx_pending)
- return;
+ if (!skb)
+ return 0;
qid = skb_get_queue_mapping(skb);
q = phy->q_tx[qid];
@@ -45,7 +45,7 @@ void mt76_testmode_tx_pending(struct mt76_phy *phy)
spin_lock_bh(&q->lock);
- while (td->tx_pending > 0 &&
+ while (count < limit &&
td->tx_queued - td->tx_done < tx_queued_limit &&
q->queued < q->ndesc / 2) {
int ret;
@@ -55,13 +55,56 @@ void mt76_testmode_tx_pending(struct mt76_phy *phy)
if (ret < 0)
break;
- td->tx_pending--;
td->tx_queued++;
+ count++;
}
dev->queue_ops->kick(dev, q);
spin_unlock_bh(&q->lock);
+
+ return count;
+}
+
+void mt76_testmode_tx_pending(struct mt76_phy *phy)
+{
+ struct mt76_testmode_data *td = &phy->test;
+ u16 count;
+
+ if (!td->tx_pending)
+ return;
+
+ if (!mt76_testmode_has_sta(phy)) {
+ count = mt76_testmode_queue_tx(phy, &phy->dev->global_wcid,
+ td->tx_skb, td->tx_pending);
+ td->tx_pending -= count;
+
+ return;
+ }
+
+ while (true) {
+ struct mt76_testmode_sta *tm_sta;
+ struct mt76_wcid *wcid;
+ u32 limit, per_sta_cnt = 1;
+
+ if (td->tx_rate_mode != MT76_TM_TX_MODE_HE_MU)
+ per_sta_cnt = td->tx_count / hweight16(phy->test.tm_sta_mask);
+
+ limit = td->tx_pending % per_sta_cnt;
+ if (limit == 0)
+ limit = per_sta_cnt;
+
+ tm_sta = mt76_testmode_aid_get_sta(phy, td->cur_aid);
+ wcid = td->tm_wcid[td->cur_aid];
+ count = mt76_testmode_queue_tx(phy, wcid, tm_sta->tx_skb, limit);
+
+ td->tx_pending -= count;
+
+ if (td->tx_pending && (td->tx_pending % per_sta_cnt == 0))
+ td->cur_aid = ffs(td->tm_sta_mask >> td->cur_aid) + td->cur_aid;
+ else
+ break;
+ }
}
static u32
@@ -318,6 +361,17 @@ mt76_testmode_tx_start(struct mt76_phy *phy)
td->tx_queued = 0;
td->tx_done = 0;
td->tx_pending = td->tx_count;
+
+ if (mt76_testmode_has_sta(phy)) {
+ td->cur_aid = ffs(td->tm_sta_mask);
+
+ /* The actual tx count of MU packets will be pass to FW
+ * by a mcu command in testmode.
+ */
+ if (td->tx_rate_mode == MT76_TM_TX_MODE_HE_MU)
+ td->tx_pending = hweight16(phy->test.tm_sta_mask);
+ }
+
mt76_worker_schedule(&dev->tx_worker);
}
--
2.25.1