linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/8] mt76: mt7915: cache sgi in wcid.
@ 2021-11-18 16:45 greearb
  2021-11-18 16:45 ` [PATCH 2/8] mt76: mt7915: allow processing TXS for 'NO_SKB' pkt-ids greearb
                   ` (7 more replies)
  0 siblings, 8 replies; 16+ messages in thread
From: greearb @ 2021-11-18 16:45 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

Explicitly cache short_gi and he_gi in wcid, don't try to store
it in the wcid.rate object.  Slightly less confusing and less fragile
when TXS starts parsing lots of frames.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---

This is actually the first series, not that one I posted a few minutes
ago.  txs, tx overrides and other things.  Rebased on top of 5.16

 drivers/net/wireless/mediatek/mt76/mt76.h       |  5 +++++
 drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 17 +++++++++++++----
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index e2da720a91b6..7234703b3c60 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -245,7 +245,12 @@ struct mt76_wcid {
 	struct ewma_signal rssi;
 	int inactive_count;
 
+	/* cached rate, updated from mac_sta_poll() and from TXS callback logic,
+	 * in 7915 at least.
+	 */
 	struct rate_info rate;
+	bool rate_short_gi; /* cached HT/VHT short_gi, from mac_sta_poll() */
+	u8 rate_he_gi; /* cached HE GI, from mac_sta_poll() */
 
 	u16 idx;
 	u8 hw_key_idx;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index 5fcf35f2d9fb..61ade279b35d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -206,13 +206,19 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
 			u8 offs = 24 + 2 * bw;
 
 			rate->he_gi = (val & (0x3 << offs)) >> offs;
+			msta->wcid.rate_he_gi = rate->he_gi; /* cache for later */
 		} else if (rate->flags &
 			   (RATE_INFO_FLAGS_VHT_MCS | RATE_INFO_FLAGS_MCS)) {
-			if (val & BIT(12 + bw))
+			if (val & BIT(12 + bw)) {
 				rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
-			else
+				msta->wcid.rate_short_gi = 1;
+			}
+			else {
 				rate->flags &= ~RATE_INFO_FLAGS_SHORT_GI;
+				msta->wcid.rate_short_gi = 0;
+			}
 		}
+		/* TODO:  Deal with HT_MCS */
 	}
 
 	rcu_read_unlock();
@@ -1411,7 +1417,7 @@ mt7915_mac_add_txs_skb(struct mt7915_dev *dev, struct mt76_wcid *wcid, int pid,
 			goto out;
 
 		rate.flags = RATE_INFO_FLAGS_MCS;
-		if (wcid->rate.flags & RATE_INFO_FLAGS_SHORT_GI)
+		if (wcid->rate_short_gi)
 			rate.flags |= RATE_INFO_FLAGS_SHORT_GI;
 		break;
 	case MT_PHY_TYPE_VHT:
@@ -1419,6 +1425,8 @@ mt7915_mac_add_txs_skb(struct mt7915_dev *dev, struct mt76_wcid *wcid, int pid,
 			goto out;
 
 		rate.flags = RATE_INFO_FLAGS_VHT_MCS;
+		if (wcid->rate_short_gi)
+			rate.flags |= RATE_INFO_FLAGS_SHORT_GI;
 		break;
 	case MT_PHY_TYPE_HE_SU:
 	case MT_PHY_TYPE_HE_EXT_SU:
@@ -1427,11 +1435,12 @@ mt7915_mac_add_txs_skb(struct mt7915_dev *dev, struct mt76_wcid *wcid, int pid,
 		if (rate.mcs > 11)
 			goto out;
 
-		rate.he_gi = wcid->rate.he_gi;
+		rate.he_gi = wcid->rate_he_gi;
 		rate.he_dcm = FIELD_GET(MT_TX_RATE_DCM, txrate);
 		rate.flags = RATE_INFO_FLAGS_HE_MCS;
 		break;
 	default:
+		WARN_ON_ONCE(true);
 		goto out;
 	}
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/8] mt76: mt7915: allow processing TXS for 'NO_SKB' pkt-ids
  2021-11-18 16:45 [PATCH 1/8] mt76: mt7915: cache sgi in wcid greearb
@ 2021-11-18 16:45 ` greearb
  2021-11-18 16:45 ` [PATCH 3/8] mt76: mt7915: debugfs hook to enable TXS for NO_SKB pkt-ids greearb
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: greearb @ 2021-11-18 16:45 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

This will let us update stats and wcid.rate for every TXS
callback we receive for a particular wcid.

For now, the TXS is not requested for NO_SKB frames, however.
That will be allowed in next patch.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 .../net/wireless/mediatek/mt76/mt7915/mac.c   | 38 +++++++++++--------
 1 file changed, 22 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index 61ade279b35d..adc6d4ddbccf 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -1361,26 +1361,31 @@ mt7915_mac_add_txs_skb(struct mt7915_dev *dev, struct mt76_wcid *wcid, int pid,
 	struct ieee80211_tx_info *info;
 	struct sk_buff_head list;
 	struct rate_info rate = {};
-	struct sk_buff *skb;
+	struct sk_buff *skb = NULL;
+	bool check_status;
 	bool cck = false;
 	u32 txrate, txs, mode;
 
-	mt76_tx_status_lock(mdev, &list);
-	skb = mt76_tx_status_skb_get(mdev, wcid, pid, &list);
-	if (!skb)
-		goto out_no_skb;
+	check_status = (pid >= MT_PACKET_ID_FIRST);
+
+	if (check_status) {
+		mt76_tx_status_lock(mdev, &list);
+		skb = mt76_tx_status_skb_get(mdev, wcid, pid, &list);
+	}
 
 	txs = le32_to_cpu(txs_data[0]);
 
-	info = IEEE80211_SKB_CB(skb);
-	if (!(txs & MT_TXS0_ACK_ERROR_MASK))
-		info->flags |= IEEE80211_TX_STAT_ACK;
+	if (skb) {
+		info = IEEE80211_SKB_CB(skb);
+		if (!(txs & MT_TXS0_ACK_ERROR_MASK))
+			info->flags |= IEEE80211_TX_STAT_ACK;
 
-	info->status.ampdu_len = 1;
-	info->status.ampdu_ack_len = !!(info->flags &
-					IEEE80211_TX_STAT_ACK);
+		info->status.ampdu_len = 1;
+		info->status.ampdu_ack_len = !!(info->flags &
+						IEEE80211_TX_STAT_ACK);
 
-	info->status.rates[0].idx = -1;
+		info->status.rates[0].idx = -1;
+	}
 
 	txrate = FIELD_GET(MT_TXS0_TX_RATE, txs);
 
@@ -1467,10 +1472,11 @@ mt7915_mac_add_txs_skb(struct mt7915_dev *dev, struct mt76_wcid *wcid, int pid,
 	wcid->rate = rate;
 
 out:
-	mt76_tx_status_skb_done(mdev, skb, &list);
+	if (skb)
+		mt76_tx_status_skb_done(mdev, skb, &list);
 
-out_no_skb:
-	mt76_tx_status_unlock(mdev, &list);
+	if (check_status)
+		mt76_tx_status_unlock(mdev, &list);
 
 	return !!skb;
 }
@@ -1494,7 +1500,7 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data)
 	txs = le32_to_cpu(txs_data[3]);
 	pid = FIELD_GET(MT_TXS3_PID, txs);
 
-	if (pid < MT_PACKET_ID_FIRST)
+	if (pid < MT_PACKET_ID_NO_SKB)
 		return;
 
 	if (wcidx >= MT7915_WTBL_SIZE)
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 3/8] mt76: mt7915: debugfs hook to enable TXS for NO_SKB pkt-ids
  2021-11-18 16:45 [PATCH 1/8] mt76: mt7915: cache sgi in wcid greearb
  2021-11-18 16:45 ` [PATCH 2/8] mt76: mt7915: allow processing TXS for 'NO_SKB' pkt-ids greearb
@ 2021-11-18 16:45 ` greearb
  2021-11-18 16:45 ` [PATCH 4/8] mt76: mt7915: add note about TXSFM 0x2 greearb
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: greearb @ 2021-11-18 16:45 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

This lets user turn on/off this feature.  Enabling gives better
tx-rate related stats, but will cause extra driver and (maybe)
firmware work.  Not sure if it actually affects performance or
not.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 .../wireless/mediatek/mt76/mt7915/debugfs.c   | 24 +++++++++++++++++++
 .../net/wireless/mediatek/mt76/mt7915/mac.c   |  3 ++-
 .../wireless/mediatek/mt76/mt7915/mt7915.h    |  5 ++++
 3 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
index a15aa256d0cf..c5ed02cd2afc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
@@ -190,6 +190,29 @@ mt7915_fw_util_wa_show(struct seq_file *file, void *data)
 
 DEFINE_SHOW_ATTRIBUTE(mt7915_fw_util_wa);
 
+static int
+mt7915_txs_for_no_skb_set(void *data, u64 val)
+{
+	struct mt7915_dev *dev = data;
+
+	dev->txs_for_no_skb_enabled = !!val;
+
+	return 0;
+}
+
+static int
+mt7915_txs_for_no_skb_get(void *data, u64 *val)
+{
+	struct mt7915_dev *dev = data;
+
+	*val = dev->txs_for_no_skb_enabled;
+
+	return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_txs_for_no_skb, mt7915_txs_for_no_skb_get,
+			 mt7915_txs_for_no_skb_set, "%lld\n");
+
 static void
 mt7915_ampdu_stat_read_phy(struct mt7915_phy *phy,
 			   struct seq_file *file)
@@ -540,6 +563,7 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
 			    &mt7915_fw_util_wm_fops);
 	debugfs_create_file("fw_util_wa", 0400, dir, dev,
 			    &mt7915_fw_util_wa_fops);
+	debugfs_create_file("force_txs", 0600, dir, dev, &fops_txs_for_no_skb);
 	debugfs_create_file("implicit_txbf", 0600, dir, dev,
 			    &fops_implicit_txbf);
 	debugfs_create_file("txpower_sku", 0400, dir, phy,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index adc6d4ddbccf..e37e6b05c7a4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -1096,7 +1096,8 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
 	txwi[4] = 0;
 
 	val = FIELD_PREP(MT_TXD5_PID, pid);
-	if (pid >= MT_PACKET_ID_FIRST)
+	if (pid >= MT_PACKET_ID_FIRST ||
+	    (pid == MT_PACKET_ID_NO_SKB && dev->txs_for_no_skb_enabled))
 		val |= MT_TXD5_TX_STATUS_HOST;
 	txwi[5] = cpu_to_le32(val);
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index e69b4c8974ee..8b1d4664562a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -254,6 +254,11 @@ struct mt7915_dev {
 
 	u16 chainmask;
 	u32 hif_idx;
+	/* Should we request TXS for MT_PACKET_ID_NO_SKB?  Doing so gives better
+	 * costs but causes a great deal more TXS packet processing by driver and
+	 * creation by firmware, so may be a performance drag.
+	 */
+	bool txs_for_no_skb_enabled;
 
 	struct work_struct init_work;
 	struct work_struct rc_work;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 4/8] mt76: mt7915: add note about TXSFM 0x2
  2021-11-18 16:45 [PATCH 1/8] mt76: mt7915: cache sgi in wcid greearb
  2021-11-18 16:45 ` [PATCH 2/8] mt76: mt7915: allow processing TXS for 'NO_SKB' pkt-ids greearb
  2021-11-18 16:45 ` [PATCH 3/8] mt76: mt7915: debugfs hook to enable TXS for NO_SKB pkt-ids greearb
@ 2021-11-18 16:45 ` greearb
  2021-11-18 17:02   ` Ryder Lee
  2021-11-18 16:45 ` [PATCH 5/8] mt76: mt7915: txfree status to show txcount instead of latency greearb
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 16+ messages in thread
From: greearb @ 2021-11-18 16:45 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

This format needs a special command to enable, and is not enabled
by default.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 drivers/net/wireless/mediatek/mt76/mt7915/mac.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
index 7a2c740d1464..b66e740832e4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
@@ -348,6 +348,9 @@ struct mt7915_tx_free {
 
 #define MT_TXS4_TIMESTAMP		GENMASK(31, 0)
 
+/* The F0 variables are for TXSFM 0x0 and 0x1.  The F1 variables
+ * are for TXSFM 0x2 aka PPDU format.
+ */
 #define MT_TXS5_F0_FINAL_MPDU		BIT(31)
 #define MT_TXS5_F0_QOS			BIT(30)
 #define MT_TXS5_F0_TX_COUNT		GENMASK(29, 25)
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 5/8] mt76: mt7915: txfree status to show txcount instead of latency
  2021-11-18 16:45 [PATCH 1/8] mt76: mt7915: cache sgi in wcid greearb
                   ` (2 preceding siblings ...)
  2021-11-18 16:45 ` [PATCH 4/8] mt76: mt7915: add note about TXSFM 0x2 greearb
@ 2021-11-18 16:45 ` greearb
  2021-11-18 16:45 ` [PATCH 6/8] mt76: mt7915: report tx-retries greearb
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: greearb @ 2021-11-18 16:45 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

Latency is not obviously that useful, but txcount can let us deduce
retries, which may be more interesting.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 drivers/net/wireless/mediatek/mt76/mt7915/init.c | 3 +++
 drivers/net/wireless/mediatek/mt76/mt7915/mac.h  | 8 +++++---
 drivers/net/wireless/mediatek/mt76/mt7915/regs.h | 8 ++++++++
 3 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
index 0c41ea23d6b3..3b35ea245b33 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -401,6 +401,9 @@ static void mt7915_mac_init(struct mt7915_dev *dev)
 	/* enable hardware de-agg */
 	mt76_set(dev, MT_MDP_DCR0, MT_MDP_DCR0_DAMSDU_EN);
 
+	/* disable Tx latency report to enable Tx count in txfree path */
+	mt76_clear(dev, MT_PLE_HOST_RPT0, MT_PLE_HOST_RPT0_TX_LATENCY);
+
 	for (i = 0; i < MT7915_WTBL_SIZE; i++)
 		mt7915_mac_wtbl_update(dev, i,
 				       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
index b66e740832e4..4ba5574cc6f3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
@@ -305,13 +305,15 @@ struct mt7915_tx_free {
 
 #define MT_TX_FREE_MSDU_CNT		GENMASK(9, 0)
 #define MT_TX_FREE_WLAN_ID		GENMASK(23, 14)
+/* when configured for txfree latency mode.  See MT_PLE_HOST_RPT0_TX_LATENCY
+ * Not enabled by default now.
+ */
 #define MT_TX_FREE_LATENCY		GENMASK(12, 0)
-/* 0: success, others: dropped */
+/* when configured for txcount mode.  See MT_PLE_HOST_RPT0_TX_LATENCY. */
+#define MT_TX_FREE_TXCNT		GENMASK(12, 0)
 #define MT_TX_FREE_STATUS		GENMASK(14, 13)
 #define MT_TX_FREE_MSDU_ID		GENMASK(30, 16)
 #define MT_TX_FREE_PAIR			BIT(31)
-/* will support this field in further revision */
-#define MT_TX_FREE_RATE			GENMASK(13, 0)
 
 #define MT_TXS0_FIXED_RATE		BIT(31)
 #define MT_TXS0_BW			GENMASK(30, 29)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
index 59693535b098..d23c669cc933 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
@@ -22,6 +22,14 @@
 #define MT_PLE_BASE			0x8000
 #define MT_PLE(ofs)			(MT_PLE_BASE + (ofs))
 
+/* Modify whether txfree struct returns latency or txcount. */
+#define MT_PLE_HOST_RPT0               MT_PLE(0x030)
+#define MT_PLE_HOST_RPT0_TX_LATENCY    BIT(3)
+
+#define MT_PLE_FL_Q0_CTRL		MT_PLE(0x1b0)
+#define MT_PLE_FL_Q1_CTRL		MT_PLE(0x1b4)
+#define MT_PLE_FL_Q2_CTRL		MT_PLE(0x1b8)
+
 #define MT_FL_Q_EMPTY			0x0b0
 #define MT_FL_Q0_CTRL			0x1b0
 #define MT_FL_Q2_CTRL			0x1b8
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 6/8] mt76: mt7915: report tx-retries
  2021-11-18 16:45 [PATCH 1/8] mt76: mt7915: cache sgi in wcid greearb
                   ` (3 preceding siblings ...)
  2021-11-18 16:45 ` [PATCH 5/8] mt76: mt7915: txfree status to show txcount instead of latency greearb
@ 2021-11-18 16:45 ` greearb
  2021-11-18 17:19   ` Ryder Lee
  2021-11-18 16:45 ` [PATCH 7/8] mt76: mt7915: add support for tx-overrides greearb
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 16+ messages in thread
From: greearb @ 2021-11-18 16:45 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

mac80211 stack will only report tx-status for skb claiming to be ampdu heads,
so lie a bit in mt7915 and set the flag so that mac80211 will record status
for each skb.

mt7915 appears to report retry status on an individual per-skb manner,
so that method above seems to work.

Re-constitute the txinfo status rate info so that the rix and flags
is also at least close to correct.  No direct way to report HE
rates that way, so mac80211 might could use some tweaking in
the ieee80211_tx_status_ext to take both info and status->rate
into account.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 drivers/net/wireless/mediatek/mt76/mac80211.c |  4 +
 drivers/net/wireless/mediatek/mt76/mt76.h     |  5 +
 .../net/wireless/mediatek/mt76/mt7915/init.c  |  1 +
 .../net/wireless/mediatek/mt76/mt7915/mac.c   | 93 ++++++++++++++++++-
 .../net/wireless/mediatek/mt76/mt7915/mac.h   |  4 +-
 .../net/wireless/mediatek/mt76/mt7915/main.c  |  4 +
 drivers/net/wireless/mediatek/mt76/tx.c       |  6 +-
 7 files changed, 110 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 62807dc311c1..a385c1850c61 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -1517,6 +1517,10 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
 
 	wi->sta_count++;
 
+	data[ei++] += stats->tx_mpdu_attempts;
+	data[ei++] += stats->tx_mpdu_fail;
+	data[ei++] += stats->tx_mpdu_retry;
+	data[ei++] += stats->tx_mpdu_ok;
 	data[ei++] += stats->tx_mode[MT_PHY_TYPE_CCK];
 	data[ei++] += stats->tx_mode[MT_PHY_TYPE_OFDM];
 	data[ei++] += stats->tx_mode[MT_PHY_TYPE_HT];
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 7234703b3c60..5a431b39d5c1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -785,6 +785,11 @@ enum mt76_phy_type {
 };
 
 struct mt76_sta_stats {
+	unsigned long tx_mpdu_attempts; /* counting any retries */
+	unsigned long tx_mpdu_fail; /* frames that failed even after retry */
+	unsigned long tx_mpdu_ok; /* frames that succeeded,
+				     perhaps after retry */
+	unsigned long tx_mpdu_retry; /* number of times frames were retried */
 	u64 tx_mode[__MT_PHY_TYPE_HE_MAX];
 	u64 tx_bw[4];		/* 20, 40, 80, 160 */
 	u64 tx_nss[4];		/* 1, 2, 3, 4 */
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
index 3b35ea245b33..90aa62c64f3e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -311,6 +311,7 @@ mt7915_init_wiphy(struct ieee80211_hw *hw)
 	struct wiphy *wiphy = hw->wiphy;
 
 	hw->queues = 4;
+	hw->max_report_rates = 1;
 	hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
 	hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
 	hw->netdev_features = NETIF_F_RXCSUM;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index e37e6b05c7a4..4f565a77770c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -1246,17 +1246,22 @@ mt7915_txp_skb_unmap(struct mt76_dev *dev, struct mt76_txwi_cache *t)
 
 static void
 mt7915_txwi_free(struct mt7915_dev *dev, struct mt76_txwi_cache *t,
-		 struct ieee80211_sta *sta, struct list_head *free_list)
+		 struct ieee80211_sta *sta, struct list_head *free_list,
+		 u32 tx_cnt, u32 tx_status, u32 ampdu)
 {
 	struct mt76_dev *mdev = &dev->mt76;
 	struct mt76_wcid *wcid;
 	__le32 *txwi;
 	u16 wcid_idx;
+	struct ieee80211_tx_info *info;
+	struct ieee80211_tx_rate *rate;
 
 	mt7915_txp_skb_unmap(mdev, t);
 	if (!t->skb)
 		goto out;
 
+	rcu_read_lock(); /* protect wcid access */
+
 	txwi = (__le32 *)mt76_get_txwi_ptr(mdev, t);
 	if (sta) {
 		wcid = (struct mt76_wcid *)sta->drv_priv;
@@ -1266,6 +1271,75 @@ mt7915_txwi_free(struct mt7915_dev *dev, struct mt76_txwi_cache *t,
 			mt7915_tx_check_aggr(sta, txwi);
 	} else {
 		wcid_idx = FIELD_GET(MT_TXD1_WLAN_IDX, le32_to_cpu(txwi[1]));
+		wcid = rcu_dereference(mdev->wcid[wcid_idx]);
+	}
+
+	info = IEEE80211_SKB_CB(t->skb);
+
+	/* Cannot clear all of info->status, we need the driver private
+	 * status intact.
+	 */
+	info->status.is_valid_ack_signal = 0;
+
+	rate = &info->status.rates[0];
+	rate->idx = -1; /* will over-write below if we found wcid */
+	info->status.rates[1].idx = -1; /* terminate rate list */
+
+	/* force TX_STAT_AMPDU to be set, or mac80211 will ignore status */
+	if (ampdu || (info->flags & IEEE80211_TX_CTL_AMPDU)) {
+		info->flags |= IEEE80211_TX_STAT_AMPDU | IEEE80211_TX_CTL_AMPDU;
+		info->status.ampdu_len = 1;
+	}
+
+	/* update info status based on cached wcid rate info since
+	 * txfree path doesn't give us a lot of info.
+	 */
+	if (wcid) {
+		struct mt7915_sta *msta = container_of(wcid, struct mt7915_sta, wcid);
+		struct mt76_sta_stats *stats = &msta->stats;
+
+		if (wcid->rate.flags & RATE_INFO_FLAGS_MCS) {
+			rate->flags |= IEEE80211_TX_RC_MCS;
+			rate->idx = wcid->rate.mcs + wcid->rate.nss * 8;
+		} else if (wcid->rate.flags & RATE_INFO_FLAGS_VHT_MCS) {
+			rate->flags |= IEEE80211_TX_RC_VHT_MCS;
+			rate->idx = (wcid->rate.nss << 4) | wcid->rate.mcs;
+		} else if (wcid->rate.flags & RATE_INFO_FLAGS_HE_MCS) {
+			rate->idx = (wcid->rate.nss << 4) | wcid->rate.mcs;
+		} else {
+			rate->idx = wcid->rate.mcs;
+		}
+
+		switch (wcid->rate.bw) {
+		case RATE_INFO_BW_160:
+			rate->flags |= IEEE80211_TX_RC_160_MHZ_WIDTH;
+			break;
+		case RATE_INFO_BW_80:
+			rate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH;
+			break;
+		case RATE_INFO_BW_40:
+			rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+			break;
+		}
+
+		stats->tx_mpdu_attempts += tx_cnt;
+		stats->tx_mpdu_retry += tx_cnt - 1;
+
+		if (tx_status == 0)
+			stats->tx_mpdu_ok++;
+		else
+			stats->tx_mpdu_fail++;
+	}
+
+	rcu_read_unlock();
+
+	/* Apply the values that this txfree path reports */
+	rate->count = tx_cnt;
+	if (tx_status == 0) {
+		info->flags |= IEEE80211_TX_STAT_ACK;
+		info->status.ampdu_ack_len = 1;
+	} else {
+		info->flags &= ~IEEE80211_TX_STAT_ACK;
 	}
 
 	__mt76_tx_complete_skb(mdev, wcid_idx, t->skb, free_list);
@@ -1285,7 +1359,8 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, struct sk_buff *skb)
 	struct ieee80211_sta *sta = NULL;
 	LIST_HEAD(free_list);
 	struct sk_buff *tmp;
-	u8 i, count;
+	u8 i;
+	u16 count;
 	bool wake = false;
 
 	/* clean DMA queues and unmap buffers first */
@@ -1301,9 +1376,12 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, struct sk_buff *skb)
 	 * to the time ack is received or dropped by hw (air + hw queue time).
 	 * Should avoid accessing WTBL to get Tx airtime, and use it instead.
 	 */
+	/* free->ctrl is high u16 of first DW in the txfree struct */
 	count = FIELD_GET(MT_TX_FREE_MSDU_CNT, le16_to_cpu(free->ctrl));
 	for (i = 0; i < count; i++) {
-		u32 msdu, info = le32_to_cpu(free->info[i]);
+		u32 msdu, tx_cnt, tx_status;
+		u32 info = le32_to_cpu(free->info[i]); /* DW3+ */
+		u32 ampdu;
 
 		/*
 		 * 1'b1: new wcid pair.
@@ -1334,7 +1412,12 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, struct sk_buff *skb)
 		if (!txwi)
 			continue;
 
-		mt7915_txwi_free(dev, txwi, sta, &free_list);
+		tx_cnt = FIELD_GET(MT_TX_FREE_TXCNT, info);
+		/* 0 = success, 1 dropped-by-hw, 2 dropped-by-cpu */
+		tx_status = FIELD_GET(MT_TX_FREE_STATUS, info);
+		ampdu = FIELD_GET(MT_TX_FREE_HEAD_OF_PAGE, info);
+
+		mt7915_txwi_free(dev, txwi, sta, &free_list, tx_cnt, tx_status, ampdu);
 	}
 
 	mt7915_mac_sta_poll(dev);
@@ -1839,7 +1922,7 @@ void mt7915_tx_token_put(struct mt7915_dev *dev)
 
 	spin_lock_bh(&dev->mt76.token_lock);
 	idr_for_each_entry(&dev->mt76.token, txwi, id) {
-		mt7915_txwi_free(dev, txwi, NULL, NULL);
+		mt7915_txwi_free(dev, txwi, NULL, NULL, 0, 1, 0);
 		dev->mt76.token_count--;
 	}
 	spin_unlock_bh(&dev->mt76.token_lock);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
index 4ba5574cc6f3..1b08bbe769c4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
@@ -300,7 +300,7 @@ struct mt7915_tx_free {
 	__le16 ctrl;
 	u8 txd_cnt;
 	u8 rsv[3];
-	__le32 info[];
+	__le32 info[]; /* DW3+ */
 } __packed __aligned(4);
 
 #define MT_TX_FREE_MSDU_CNT		GENMASK(9, 0)
@@ -312,6 +312,8 @@ struct mt7915_tx_free {
 /* when configured for txcount mode.  See MT_PLE_HOST_RPT0_TX_LATENCY. */
 #define MT_TX_FREE_TXCNT		GENMASK(12, 0)
 #define MT_TX_FREE_STATUS		GENMASK(14, 13)
+/* 0:  not MPDU, 1:  MSDU is head pkt of TXD page (MPDU) */
+#define MT_TX_FREE_HEAD_OF_PAGE		BIT(15)
 #define MT_TX_FREE_MSDU_ID		GENMASK(30, 16)
 #define MT_TX_FREE_PAIR			BIT(31)
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index 057ab27b7083..3d702dc899ba 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -1140,6 +1140,10 @@ static const char mt7915_gstrings_stats[][ETH_GSTRING_LEN] = {
 	"rx_ba_cnt",
 
 	/* per vif counters */
+	"v_tx_mpdu_attempts", /* counting any retries */
+	"v_tx_mpdu_fail",  /* frames that failed even after retry */
+	"v_tx_mpdu_retry", /* number of times frames were retried */
+	"v_tx_mpdu_ok", /* frames that succeeded, perhaps after retry */
 	"v_tx_mode_cck",
 	"v_tx_mode_ofdm",
 	"v_tx_mode_ht",
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index 11719ef034d8..be3227008f57 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -229,6 +229,7 @@ void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *
 	struct ieee80211_tx_status status = {
 		.skb = skb,
 		.free_list = free_list,
+		.info = IEEE80211_SKB_CB(skb),
 	};
 	struct mt76_wcid *wcid = NULL;
 	struct ieee80211_hw *hw;
@@ -236,8 +237,11 @@ void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *
 
 	rcu_read_lock();
 
-	if (wcid_idx < ARRAY_SIZE(dev->wcid))
+	if (wcid_idx < ARRAY_SIZE(dev->wcid)) {
 		wcid = rcu_dereference(dev->wcid[wcid_idx]);
+		if (wcid)
+			status.rate = &wcid->rate;
+	}
 
 	mt76_tx_check_non_aql(dev, wcid, skb);
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 7/8] mt76: mt7915: add support for tx-overrides
  2021-11-18 16:45 [PATCH 1/8] mt76: mt7915: cache sgi in wcid greearb
                   ` (4 preceding siblings ...)
  2021-11-18 16:45 ` [PATCH 6/8] mt76: mt7915: report tx-retries greearb
@ 2021-11-18 16:45 ` greearb
  2021-11-19  7:16   ` kernel test robot
  2021-11-18 16:45 ` [PATCH 8/8] mt76: mt7915: fix SGI reporting when using tx-overrides greearb
  2021-11-18 17:06 ` [PATCH 1/8] mt76: mt7915: cache sgi in wcid Ryder Lee
  7 siblings, 1 reply; 16+ messages in thread
From: greearb @ 2021-11-18 16:45 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

Allow setting fix rate on transmit without using full testmode
logic.

txpower, dynbw, retry count is not currently supported.
And, probably later need additional logic to not apply this
txo to non-data frames and to smaller frames, to allow
ARP and such to go through while also forcing test data frames
to arbitrary tx-rates (rates which very well may not be
received by peer.)

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 drivers/net/wireless/mediatek/mt76/mt76.h     |   4 +
 .../wireless/mediatek/mt76/mt7915/debugfs.c   | 224 ++++++++++++++++++
 .../net/wireless/mediatek/mt76/mt7915/mac.c   |  98 ++++++--
 .../wireless/mediatek/mt76/mt7915/mt7915.h    |   2 +
 4 files changed, 302 insertions(+), 26 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 5a431b39d5c1..7bcdfef3c983 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -577,6 +577,7 @@ struct mt76_testmode_ops {
 
 struct mt76_testmode_data {
 	enum mt76_testmode_state state;
+	u8 txo_active; /* tx overrides are active */
 
 	u32 param_set[DIV_ROUND_UP(NUM_MT76_TM_ATTRS, 32)];
 	struct sk_buff *tx_skb;
@@ -591,6 +592,9 @@ struct mt76_testmode_data {
 	u8 tx_rate_ldpc;
 	u8 tx_rate_stbc;
 	u8 tx_ltf;
+	u8 txbw; /* specify TX bandwidth: 0 20Mhz, 1 40Mhz, 2 80Mhz, 3 160Mhz */
+	u8 tx_xmit_count; /* 0 means no-ack, 1 means one transmit, etc */
+	u8 tx_dynbw; /* 0:  dynamic bw disabled, 1: dynamic bw enabled */
 
 	u8 tx_antenna_mask;
 	u8 tx_spe_idx;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
index c5ed02cd2afc..e3f6cd18e30a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
@@ -190,6 +190,228 @@ mt7915_fw_util_wa_show(struct seq_file *file, void *data)
 
 DEFINE_SHOW_ATTRIBUTE(mt7915_fw_util_wa);
 
+struct mt7915_txo_worker_info {
+	char* buf;
+	int sofar;
+	int size;
+};
+
+static void mt7915_txo_worker(void *wi_data, struct ieee80211_sta *sta)
+{
+	struct mt7915_txo_worker_info *wi = wi_data;
+	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
+	struct mt76_testmode_data *td = &msta->test;
+	struct ieee80211_vif *vif;
+	struct wireless_dev *wdev;
+
+	if (wi->sofar >= wi->size)
+		return; /* buffer is full */
+
+	vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);
+	wdev = ieee80211_vif_to_wdev(vif);
+
+	wi->sofar += scnprintf(wi->buf + wi->sofar, wi->size - wi->sofar,
+			       "vdev (%s) active=%d tpc=%d sgi=%d mcs=%d nss=%d"
+			       " pream=%d retries=%d dynbw=%d bw=%d\n",
+			       wdev->netdev->name,
+			       td->txo_active, td->tx_power[0],
+			       td->tx_rate_sgi, td->tx_rate_idx,
+			       td->tx_rate_nss, td->tx_rate_mode,
+			       td->tx_xmit_count, td->tx_dynbw,
+			       td->txbw);
+}
+
+static ssize_t mt7915_read_set_rate_override(struct file *file,
+					     char __user *user_buf,
+					     size_t count, loff_t *ppos)
+{
+	struct mt7915_dev *dev = file->private_data;
+        struct ieee80211_hw *hw = dev->mphy.hw;
+	char *buf2;
+	int size = 8000;
+	int rv, sofar;
+	struct mt7915_txo_worker_info wi;
+	const char buf[] =
+		"This allows specify specif tx rate parameters for all DATA"
+		" frames on a vdev\n"
+		"To set a value, you specify the dev-name and key-value pairs:\n"
+		"tpc=10 sgi=1 mcs=x nss=x pream=x retries=x dynbw=0|1 bw=x enable=0|1\n"
+		"pream: 0=cck, 1=ofdm, 2=HT, 3=VHT, 4=HE_SU\n"
+		"cck-mcs: 0=1Mbps, 1=2Mbps, 3=5.5Mbps, 3=11Mbps\n"
+		"ofdm-mcs: 0=6Mbps, 1=9Mbps, 2=12Mbps, 3=18Mbps, 4=24Mbps, 5=36Mbps,"
+		" 6=48Mbps, 7=54Mbps\n"
+		"tpc is not implemented currently, bw is 0-3 for 20-160\n"
+		" For example, wlan0:\n"
+		"echo \"wlan0 tpc=255 sgi=1 mcs=0 nss=1 pream=3 retries=1 dynbw=0 bw=0"
+		" active=1\" > ...mt76/set_rate_override\n";
+
+	buf2 = kzalloc(size, GFP_KERNEL);
+	if (!buf2)
+		return -ENOMEM;
+	strcpy(buf2, buf);
+	sofar = strlen(buf2);
+
+	wi.sofar = sofar;
+	wi.buf = buf2;
+	wi.size = size;
+
+	ieee80211_iterate_stations_atomic(hw, mt7915_txo_worker, &wi);
+
+	rv = simple_read_from_buffer(user_buf, count, ppos, buf2, wi.sofar);
+	kfree(buf2);
+	return rv;
+}
+
+/* Set the rates for specific types of traffic.
+ */
+static ssize_t mt7915_write_set_rate_override(struct file *file,
+					      const char __user *user_buf,
+					      size_t count, loff_t *ppos)
+{
+	struct mt7915_dev *dev = file->private_data;
+	struct mt7915_sta *msta;
+	struct ieee80211_vif *vif;
+	struct mt76_testmode_data *td = NULL;
+	struct wireless_dev *wdev;
+	struct mt76_wcid *wcid;
+	struct mt76_phy *mphy = &dev->mt76.phy;
+	char buf[180];
+	char tmp[20];
+	char *tok;
+	int ret, i, j;
+	unsigned int vdev_id = 0xFFFF;
+	char *bufptr = buf;
+	long rc;
+	char dev_name_match[IFNAMSIZ + 2];
+
+	memset(buf, 0, sizeof(buf));
+
+	simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
+
+	/* make sure that buf is null terminated */
+	buf[sizeof(buf) - 1] = 0;
+
+	/* drop the possible '\n' from the end */
+	if (buf[count - 1] == '\n')
+		buf[count - 1] = 0;
+
+	mutex_lock(&mphy->dev->mutex);
+
+	/* Ignore empty lines, 'echo' appends them sometimes at least. */
+	if (buf[0] == 0) {
+		ret = count;
+		goto exit;
+	}
+
+	/* String starts with vdev name, ie 'wlan0'  Find the proper vif that
+	 * matches the name.
+	 */
+	for (i = 0; i < ARRAY_SIZE(dev->mt76.wcid_mask); i++) {
+		u32 mask = dev->mt76.wcid_mask[i];
+		u32 phy_mask = dev->mt76.wcid_phy_mask[i];
+
+		if (!mask)
+			continue;
+
+		for (j = i * 32; mask; j++, mask >>= 1, phy_mask >>= 1) {
+			if (!(mask & 1))
+				continue;
+
+			wcid = rcu_dereference(dev->mt76.wcid[j]);
+			if (!wcid)
+				continue;
+
+			msta = container_of(wcid, struct mt7915_sta, wcid);
+
+			vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);
+
+			wdev = ieee80211_vif_to_wdev(vif);
+
+			if (!wdev)
+				continue;
+
+			snprintf(dev_name_match, sizeof(dev_name_match) - 1, "%s ",
+				 wdev->netdev->name);
+
+			if (strncmp(dev_name_match, buf, strlen(dev_name_match)) == 0) {
+				vdev_id = j;
+				td = &msta->test;
+				bufptr = buf + strlen(dev_name_match) - 1;
+				break;
+			}
+		}
+	}
+
+	if (vdev_id == 0xFFFF) {
+		if (strstr(buf, "active=0")) {
+			/* Ignore, we are disabling it anyway */
+			ret = count;
+			goto exit;
+		} else {
+			dev_info(dev->mt76.dev,
+				 "mt7915: set-rate-override, unknown netdev name: %s\n", buf);
+		}
+		ret = -EINVAL;
+		goto exit;
+	}
+
+#define MT7915_PARSE_LTOK(a, b)					\
+	do {								\
+		tok = strstr(bufptr, " " #a "=");			\
+		if (tok) {						\
+			char *tspace;					\
+			tok += 1; /* move past initial space */		\
+			strncpy(tmp, tok + strlen(#a "="), sizeof(tmp) - 1); \
+			tmp[sizeof(tmp) - 1] = 0;			\
+			tspace = strstr(tmp, " ");			\
+			if (tspace)					\
+				*tspace = 0;				\
+			if (kstrtol(tmp, 0, &rc) != 0)			\
+				dev_info(dev->mt76.dev,			\
+					 "mt7915: set-rate-override: " #a \
+					 "= could not be parsed, tmp: %s\n", \
+					 tmp);				\
+			else						\
+				td->b = rc;				\
+		}							\
+	} while (0)
+
+	/* TODO:  Allow configuring LTF? */
+	td->tx_ltf = 1; /* 0: HTLTF 3.2us, 1: HELTF, 6.4us, 2 HELTF 12,8us */
+
+	MT7915_PARSE_LTOK(tpc, tx_power[0]);
+	MT7915_PARSE_LTOK(sgi, tx_rate_sgi);
+	MT7915_PARSE_LTOK(mcs, tx_rate_idx);
+	MT7915_PARSE_LTOK(nss, tx_rate_nss);
+	MT7915_PARSE_LTOK(pream, tx_rate_mode);
+	MT7915_PARSE_LTOK(retries, tx_xmit_count);
+	MT7915_PARSE_LTOK(dynbw, tx_dynbw);
+	MT7915_PARSE_LTOK(bw, txbw);
+	MT7915_PARSE_LTOK(active, txo_active);
+
+	dev_info(dev->mt76.dev,
+		 "mt7915: set-rate-overrides, vdev %i(%s) active=%d tpc=%d sgi=%d mcs=%d"
+		 " nss=%d pream=%d retries=%d dynbw=%d bw=%d\n",
+		 vdev_id, dev_name_match,
+		 td->txo_active, td->tx_power[0], td->tx_rate_sgi, td->tx_rate_idx,
+		 td->tx_rate_nss, td->tx_rate_mode, td->tx_xmit_count, td->tx_dynbw,
+		 td->txbw);
+
+	ret = count;
+
+exit:
+	mutex_unlock(&mphy->dev->mutex);
+	return ret;
+}
+
+static const struct file_operations fops_set_rate_override = {
+	.read = mt7915_read_set_rate_override,
+	.write = mt7915_write_set_rate_override,
+	.open = simple_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
 static int
 mt7915_txs_for_no_skb_set(void *data, u64 val)
 {
@@ -577,6 +799,8 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
 		debugfs_create_file("radar_trigger", 0200, dir, dev,
 				    &fops_radar_trigger);
 	}
+	debugfs_create_file("set_rate_override", 0600, dir,
+			    dev, &fops_set_rate_override);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index 4f565a77770c..c3dfd22d4978 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -757,21 +757,31 @@ mt7915_mac_fill_rx_vector(struct mt7915_dev *dev, struct sk_buff *skb)
 }
 
 static void
-mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
+mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, struct mt76_wcid *wcid, __le32 *txwi,
 			 struct sk_buff *skb)
 {
-#ifdef CONFIG_NL80211_TESTMODE
-	struct mt76_testmode_data *td = &phy->mt76->test;
+	struct mt76_testmode_data *td;
 	const struct ieee80211_rate *r;
-	u8 bw, mode, nss = td->tx_rate_nss;
-	u8 rate_idx = td->tx_rate_idx;
+	struct mt7915_sta *msta;
+	u8 bw, mode, nss;
+	u8 rate_idx;
 	u16 rateval = 0;
 	u32 val;
 	bool cck = false;
 	int band;
 
-	if (skb != phy->mt76->test.tx_skb)
-		return;
+	msta = container_of(wcid, struct mt7915_sta, wcid);
+
+	if (msta->test.txo_active) {
+		td = &msta->test;
+	} else {
+		if (skb != phy->mt76->test.tx_skb)
+			return;
+		td = &phy->mt76->test;
+	}
+
+	nss = td->tx_rate_nss;
+	rate_idx = td->tx_rate_idx;
 
 	switch (td->tx_rate_mode) {
 	case MT76_TM_TX_MODE_HT:
@@ -812,20 +822,24 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
 		break;
 	}
 
-	switch (phy->mt76->chandef.width) {
-	case NL80211_CHAN_WIDTH_40:
-		bw = 1;
-		break;
-	case NL80211_CHAN_WIDTH_80:
-		bw = 2;
-		break;
-	case NL80211_CHAN_WIDTH_80P80:
-	case NL80211_CHAN_WIDTH_160:
-		bw = 3;
-		break;
-	default:
-		bw = 0;
-		break;
+	if (msta->test.txo_active) {
+		bw = td->txbw;
+	} else {
+		switch (phy->mt76->chandef.width) {
+		case NL80211_CHAN_WIDTH_40:
+			bw = 1;
+			break;
+		case NL80211_CHAN_WIDTH_80:
+			bw = 2;
+			break;
+		case NL80211_CHAN_WIDTH_80P80:
+		case NL80211_CHAN_WIDTH_160:
+			bw = 3;
+			break;
+		default:
+			bw = 0;
+			break;
+		}
 	}
 
 	if (td->tx_rate_stbc && nss == 1) {
@@ -837,12 +851,17 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
 		   FIELD_PREP(MT_TX_RATE_MODE, mode) |
 		   FIELD_PREP(MT_TX_RATE_NSS, nss - 1);
 
+	/* TODO:  Support per-skb txpower, p.15 of txpower doc, DW2 29:24. */
 	txwi[2] |= cpu_to_le32(MT_TXD2_FIX_RATE);
 
+	/* Looks like this sets tx attempt to exactly 1.
+	 * TODO:  Use td->tx_xmit_count, if in txo mode.
+	 */
 	le32p_replace_bits(&txwi[3], 1, MT_TXD3_REM_TX_COUNT);
 	if (td->tx_rate_mode < MT76_TM_TX_MODE_HT)
 		txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
 
+	/* TODO:  Take tx_dynbw into account in txo mode. */
 	val = MT_TXD6_FIXED_BW |
 	      FIELD_PREP(MT_TXD6_BW, bw) |
 	      FIELD_PREP(MT_TXD6_TX_RATE, rateval) |
@@ -866,9 +885,29 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
 
 	txwi[3] &= ~cpu_to_le32(MT_TXD3_SN_VALID);
 	txwi[6] |= cpu_to_le32(val);
-	txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX,
-					  phy->test.spe_idx));
-#endif
+
+	if (msta->test.txo_active) {
+		/* see mt7915_tm_set_tx_frames */
+		static const u8 spe_idx_map[] = {0, 0, 1, 0, 3, 2, 4, 0,
+						 9, 8, 6, 10, 16, 12, 18, 0};
+		u32 spe_idx;
+
+		if (td->tx_spe_idx) {
+			spe_idx = td->tx_spe_idx;
+		} else {
+			u8 tx_ant = td->tx_antenna_mask;
+
+			if (!tx_ant) {
+				/* use antenna mask that matches our nss */
+				tx_ant = GENMASK(nss - 1, 0);
+			}
+			spe_idx = spe_idx_map[tx_ant];
+		}
+		txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX, spe_idx));
+	} else {
+		txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX,
+						  phy->test.spe_idx));
+	}
 }
 
 static void
@@ -1121,8 +1160,15 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
 		txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
 	}
 
-	if (mt76_testmode_enabled(mphy))
-		mt7915_mac_write_txwi_tm(mphy->priv, txwi, skb);
+#ifdef CONFIG_NL80211_TESTMODE
+	{
+		struct mt7915_sta *msta;
+
+		msta = container_of(wcid, struct mt7915_sta, wcid);
+		if (mt76_testmode_enabled(mphy) || msta->test.txo_active)
+			mt7915_mac_write_txwi_tm(mphy->priv, wcid, txwi, skb);
+	}
+#endif
 }
 
 int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index 8b1d4664562a..86cd0fc8e9de 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -103,6 +103,8 @@ struct mt7915_sta {
 
 	struct mt7915_sta_key_conf bip;
 
+	struct mt76_testmode_data test;
+
 	struct {
 		u8 flowid_mask;
 		struct mt7915_twt_flow flow[MT7915_MAX_STA_TWT_AGRT];
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 8/8] mt76: mt7915: fix SGI reporting when using tx-overrides
  2021-11-18 16:45 [PATCH 1/8] mt76: mt7915: cache sgi in wcid greearb
                   ` (5 preceding siblings ...)
  2021-11-18 16:45 ` [PATCH 7/8] mt76: mt7915: add support for tx-overrides greearb
@ 2021-11-18 16:45 ` greearb
  2021-11-18 17:06 ` [PATCH 1/8] mt76: mt7915: cache sgi in wcid Ryder Lee
  7 siblings, 0 replies; 16+ messages in thread
From: greearb @ 2021-11-18 16:45 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

The station wtbl logic to read rate-ctrl settings does not work when
fixed rates are used.  So, read sgi settings from the txo configuration
in this case.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index c3dfd22d4978..8e5b87af2efb 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -177,6 +177,15 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
 						       rx_cur);
 		}
 
+		/* If we are in tx-override mode, then wtbl doesn't provide useful report
+		 * for the SGI/LGI stuff, so just get it from the override struct.
+		 */
+		if (msta->test.txo_active) {
+			msta->wcid.rate_he_gi = msta->test.tx_rate_sgi;
+			msta->wcid.rate_short_gi = msta->test.tx_rate_sgi;
+			continue;
+		}
+
 		/*
 		 * We don't support reading GI info from txs packets.
 		 * For accurate tx status reporting and AQL improvement,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH 4/8] mt76: mt7915: add note about TXSFM 0x2
  2021-11-18 16:45 ` [PATCH 4/8] mt76: mt7915: add note about TXSFM 0x2 greearb
@ 2021-11-18 17:02   ` Ryder Lee
  2021-11-18 17:06     ` Ben Greear
  0 siblings, 1 reply; 16+ messages in thread
From: Ryder Lee @ 2021-11-18 17:02 UTC (permalink / raw)
  To: greearb, linux-wireless

On Thu, 2021-11-18 at 08:45 -0800, greearb@candelatech.com wrote:
> From: Ben Greear <greearb@candelatech.com>
> 
> This format needs a special command to enable, and is not enabled
> by default.
> 
> Signed-off-by: Ben Greear <greearb@candelatech.com>
> ---
>  drivers/net/wireless/mediatek/mt76/mt7915/mac.h | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
> b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
> index 7a2c740d1464..b66e740832e4 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
> @@ -348,6 +348,9 @@ struct mt7915_tx_free {
>  
>  #define MT_TXS4_TIMESTAMP		GENMASK(31, 0)
>  
> +/* The F0 variables are for TXSFM 0x0 and 0x1.  The F1 variables
> + * are for TXSFM 0x2 aka PPDU format.
> + */
>  #define MT_TXS5_F0_FINAL_MPDU		BIT(31)
>  #define MT_TXS5_F0_QOS			BIT(30)
>  #define MT_TXS5_F0_TX_COUNT		GENMASK(29, 25)

Now that we don't need it why should it needs a special command.

Ryder


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 4/8] mt76: mt7915: add note about TXSFM 0x2
  2021-11-18 17:02   ` Ryder Lee
@ 2021-11-18 17:06     ` Ben Greear
  0 siblings, 0 replies; 16+ messages in thread
From: Ben Greear @ 2021-11-18 17:06 UTC (permalink / raw)
  To: Ryder Lee, linux-wireless

On 11/18/21 9:02 AM, Ryder Lee wrote:
> On Thu, 2021-11-18 at 08:45 -0800, greearb@candelatech.com wrote:
>> From: Ben Greear <greearb@candelatech.com>
>>
>> This format needs a special command to enable, and is not enabled
>> by default.
>>
>> Signed-off-by: Ben Greear <greearb@candelatech.com>
>> ---
>>   drivers/net/wireless/mediatek/mt76/mt7915/mac.h | 3 +++
>>   1 file changed, 3 insertions(+)
>>
>> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
>> b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
>> index 7a2c740d1464..b66e740832e4 100644
>> --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
>> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
>> @@ -348,6 +348,9 @@ struct mt7915_tx_free {
>>   
>>   #define MT_TXS4_TIMESTAMP		GENMASK(31, 0)
>>   
>> +/* The F0 variables are for TXSFM 0x0 and 0x1.  The F1 variables
>> + * are for TXSFM 0x2 aka PPDU format.
>> + */
>>   #define MT_TXS5_F0_FINAL_MPDU		BIT(31)
>>   #define MT_TXS5_F0_QOS			BIT(30)
>>   #define MT_TXS5_F0_TX_COUNT		GENMASK(29, 25)
> 
> Now that we don't need it why should it needs a special command.

It can be hard for a new developer to the driver to understand
the firmware API, so a comment could save the next person to look
at this some time and trouble.

Thanks,
Ben

> 
> Ryder
> 


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/8] mt76: mt7915: cache sgi in wcid.
  2021-11-18 16:45 [PATCH 1/8] mt76: mt7915: cache sgi in wcid greearb
                   ` (6 preceding siblings ...)
  2021-11-18 16:45 ` [PATCH 8/8] mt76: mt7915: fix SGI reporting when using tx-overrides greearb
@ 2021-11-18 17:06 ` Ryder Lee
  2021-11-18 17:10   ` Ben Greear
  7 siblings, 1 reply; 16+ messages in thread
From: Ryder Lee @ 2021-11-18 17:06 UTC (permalink / raw)
  To: greearb, linux-wireless

On Thu, 2021-11-18 at 08:45 -0800, greearb@candelatech.com wrote:
> From: Ben Greear <greearb@candelatech.com>
> 
> Explicitly cache short_gi and he_gi in wcid, don't try to store
> it in the wcid.rate object.  Slightly less confusing and less fragile
> when TXS starts parsing lots of frames.
> 
> Signed-off-by: Ben Greear <greearb@candelatech.com>
> ---
> 
> This is actually the first series, not that one I posted a few
> minutes
> ago.  txs, tx overrides and other things.  Rebased on top of 5.16
> 
>  drivers/net/wireless/mediatek/mt76/mt76.h       |  5 +++++
>  drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 17 +++++++++++++
> ----
>  2 files changed, 18 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h
> b/drivers/net/wireless/mediatek/mt76/mt76.h
> index e2da720a91b6..7234703b3c60 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
> @@ -245,7 +245,12 @@ struct mt76_wcid {
>  	struct ewma_signal rssi;
>  	int inactive_count;
>  
> +	/* cached rate, updated from mac_sta_poll() and from TXS
> callback logic,
> +	 * in 7915 at least.
> +	 */
>  	struct rate_info rate;
> +	bool rate_short_gi; /* cached HT/VHT short_gi, from
> mac_sta_poll() */
> +	u8 rate_he_gi; /* cached HE GI, from mac_sta_poll() */
>  
>  	u16 idx;
>  	u8 hw_key_idx;
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> index 5fcf35f2d9fb..61ade279b35d 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> @@ -206,13 +206,19 @@ static void mt7915_mac_sta_poll(struct
> mt7915_dev *dev)
>  			u8 offs = 24 + 2 * bw;
>  
>  			rate->he_gi = (val & (0x3 << offs)) >> offs;
> +			msta->wcid.rate_he_gi = rate->he_gi; /* cache
> for later */
>  		} else if (rate->flags &
>  			   (RATE_INFO_FLAGS_VHT_MCS |
> RATE_INFO_FLAGS_MCS)) {
> -			if (val & BIT(12 + bw))
> +			if (val & BIT(12 + bw)) {
>  				rate->flags |=
> RATE_INFO_FLAGS_SHORT_GI;
> -			else
> +				msta->wcid.rate_short_gi = 1;
> +			}
> +			else {
>  				rate->flags &=
> ~RATE_INFO_FLAGS_SHORT_GI;
> +				msta->wcid.rate_short_gi = 0;
> +			}
>  		}
> +		/* TODO:  Deal with HT_MCS */
>  	}
>  
>  	rcu_read_unlock();
> @@ -1411,7 +1417,7 @@ mt7915_mac_add_txs_skb(struct mt7915_dev *dev,
> struct mt76_wcid *wcid, int pid,
>  			goto out;
>  
>  		rate.flags = RATE_INFO_FLAGS_MCS;
> -		if (wcid->rate.flags & RATE_INFO_FLAGS_SHORT_GI)
> +		if (wcid->rate_short_gi)
>  			rate.flags |= RATE_INFO_FLAGS_SHORT_GI;
>  		break;
>  	case MT_PHY_TYPE_VHT:
> @@ -1419,6 +1425,8 @@ mt7915_mac_add_txs_skb(struct mt7915_dev *dev,
> struct mt76_wcid *wcid, int pid,
>  			goto out;
>  
>  		rate.flags = RATE_INFO_FLAGS_VHT_MCS;
> +		if (wcid->rate_short_gi)
> +			rate.flags |= RATE_INFO_FLAGS_SHORT_GI;
>  		break;
>  	case MT_PHY_TYPE_HE_SU:
>  	case MT_PHY_TYPE_HE_EXT_SU:
> @@ -1427,11 +1435,12 @@ mt7915_mac_add_txs_skb(struct mt7915_dev
> *dev, struct mt76_wcid *wcid, int pid,
>  		if (rate.mcs > 11)
>  			goto out;
>  
> -		rate.he_gi = wcid->rate.he_gi;
> +		rate.he_gi = wcid->rate_he_gi;
>  		rate.he_dcm = FIELD_GET(MT_TX_RATE_DCM, txrate);
>  		rate.flags = RATE_INFO_FLAGS_HE_MCS;
>  		break;
>  	default:
> +		WARN_ON_ONCE(true);
>  		goto out;
>  	}

Maybe we can consider switching to use existing fixed-rate method in
debugfs? On th other hand, that's the only way to configure HE MU UL
fixed-rate.

Ryder


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/8] mt76: mt7915: cache sgi in wcid.
  2021-11-18 17:06 ` [PATCH 1/8] mt76: mt7915: cache sgi in wcid Ryder Lee
@ 2021-11-18 17:10   ` Ben Greear
  2021-11-18 17:20     ` Ryder Lee
  0 siblings, 1 reply; 16+ messages in thread
From: Ben Greear @ 2021-11-18 17:10 UTC (permalink / raw)
  To: Ryder Lee, linux-wireless

On 11/18/21 9:06 AM, Ryder Lee wrote:
> On Thu, 2021-11-18 at 08:45 -0800, greearb@candelatech.com wrote:
>> From: Ben Greear <greearb@candelatech.com>
>>
>> Explicitly cache short_gi and he_gi in wcid, don't try to store
>> it in the wcid.rate object.  Slightly less confusing and less fragile
>> when TXS starts parsing lots of frames.
>>
>> Signed-off-by: Ben Greear <greearb@candelatech.com>
>> ---
>>
>> This is actually the first series, not that one I posted a few
>> minutes
>> ago.  txs, tx overrides and other things.  Rebased on top of 5.16

> 
> Maybe we can consider switching to use existing fixed-rate method in
> debugfs? On th other hand, that's the only way to configure HE MU UL
> fixed-rate.

This patch is to improve reported tx rates, not to control tx rates.

Thanks,
Ben

-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 6/8] mt76: mt7915: report tx-retries
  2021-11-18 16:45 ` [PATCH 6/8] mt76: mt7915: report tx-retries greearb
@ 2021-11-18 17:19   ` Ryder Lee
  2021-11-18 17:26     ` Ben Greear
  0 siblings, 1 reply; 16+ messages in thread
From: Ryder Lee @ 2021-11-18 17:19 UTC (permalink / raw)
  To: greearb, linux-wireless

On Thu, 2021-11-18 at 08:45 -0800, greearb@candelatech.com wrote:
> From: Ben Greear <greearb@candelatech.com>
> 
> mac80211 stack will only report tx-status for skb claiming to be
> ampdu heads,
> so lie a bit in mt7915 and set the flag so that mac80211 will record
> status
> for each skb.
> 
> mt7915 appears to report retry status on an individual per-skb
> manner,
> so that method above seems to work.
> 
> Re-constitute the txinfo status rate info so that the rix and flags
> is also at least close to correct.  No direct way to report HE
> rates that way, so mac80211 might could use some tweaking in
> the ieee80211_tx_status_ext to take both info and status->rate
> into account.
> 
> Signed-off-by: Ben Greear <greearb@candelatech.com>
> ---
>  drivers/net/wireless/mediatek/mt76/mac80211.c |  4 +
>  drivers/net/wireless/mediatek/mt76/mt76.h     |  5 +
>  .../net/wireless/mediatek/mt76/mt7915/init.c  |  1 +
>  .../net/wireless/mediatek/mt76/mt7915/mac.c   | 93
> ++++++++++++++++++-
>  .../net/wireless/mediatek/mt76/mt7915/mac.h   |  4 +-
>  .../net/wireless/mediatek/mt76/mt7915/main.c  |  4 +
>  drivers/net/wireless/mediatek/mt76/tx.c       |  6 +-
>  7 files changed, 110 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c
> b/drivers/net/wireless/mediatek/mt76/mac80211.c
> index 62807dc311c1..a385c1850c61 100644
> --- a/drivers/net/wireless/mediatek/mt76/mac80211.c
> +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
> @@ -1517,6 +1517,10 @@ void mt76_ethtool_worker(struct
> mt76_ethtool_worker_info *wi,
>  
>  	wi->sta_count++;
>  
> +	data[ei++] += stats->tx_mpdu_attempts;
> +	data[ei++] += stats->tx_mpdu_fail;
> +	data[ei++] += stats->tx_mpdu_retry;
> +	data[ei++] += stats->tx_mpdu_ok;
>  	data[ei++] += stats->tx_mode[MT_PHY_TYPE_CCK];
>  	data[ei++] += stats->tx_mode[MT_PHY_TYPE_OFDM];
>  	data[ei++] += stats->tx_mode[MT_PHY_TYPE_HT];
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h
> b/drivers/net/wireless/mediatek/mt76/mt76.h
> index 7234703b3c60..5a431b39d5c1 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
> @@ -785,6 +785,11 @@ enum mt76_phy_type {
>  };
>  
>  struct mt76_sta_stats {
> +	unsigned long tx_mpdu_attempts; /* counting any retries */
> +	unsigned long tx_mpdu_fail; /* frames that failed even after
> retry */
> +	unsigned long tx_mpdu_ok; /* frames that succeeded,
> +				     perhaps after retry */
> +	unsigned long tx_mpdu_retry; /* number of times frames were
> retried */
>  	u64 tx_mode[__MT_PHY_TYPE_HE_MAX];
>  	u64 tx_bw[4];		/* 20, 40, 80, 160 */
>  	u64 tx_nss[4];		/* 1, 2, 3, 4 */
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
> b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
> index 3b35ea245b33..90aa62c64f3e 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
> @@ -311,6 +311,7 @@ mt7915_init_wiphy(struct ieee80211_hw *hw)
>  	struct wiphy *wiphy = hw->wiphy;
>  
>  	hw->queues = 4;
> +	hw->max_report_rates = 1;
>  	hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
>  	hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
>  	hw->netdev_features = NETIF_F_RXCSUM;
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> index e37e6b05c7a4..4f565a77770c 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> @@ -1246,17 +1246,22 @@ mt7915_txp_skb_unmap(struct mt76_dev *dev,
> struct mt76_txwi_cache *t)
>  
>  static void
>  mt7915_txwi_free(struct mt7915_dev *dev, struct mt76_txwi_cache *t,
> -		 struct ieee80211_sta *sta, struct list_head
> *free_list)
> +		 struct ieee80211_sta *sta, struct list_head
> *free_list,
> +		 u32 tx_cnt, u32 tx_status, u32 ampdu)
>  {
>  	struct mt76_dev *mdev = &dev->mt76;
>  	struct mt76_wcid *wcid;
>  	__le32 *txwi;
>  	u16 wcid_idx;
> +	struct ieee80211_tx_info *info;
> +	struct ieee80211_tx_rate *rate;
>  
>  	mt7915_txp_skb_unmap(mdev, t);
>  	if (!t->skb)
>  		goto out;
>  
> +	rcu_read_lock(); /* protect wcid access */
> +
>  	txwi = (__le32 *)mt76_get_txwi_ptr(mdev, t);
>  	if (sta) {
>  		wcid = (struct mt76_wcid *)sta->drv_priv;
> @@ -1266,6 +1271,75 @@ mt7915_txwi_free(struct mt7915_dev *dev,
> struct mt76_txwi_cache *t,
>  			mt7915_tx_check_aggr(sta, txwi);
>  	} else {
>  		wcid_idx = FIELD_GET(MT_TXD1_WLAN_IDX,
> le32_to_cpu(txwi[1]));
> +		wcid = rcu_dereference(mdev->wcid[wcid_idx]);
> +	}
> +
> +	info = IEEE80211_SKB_CB(t->skb);
> +
> +	/* Cannot clear all of info->status, we need the driver private
> +	 * status intact.
> +	 */
> +	info->status.is_valid_ack_signal = 0;
> +
> +	rate = &info->status.rates[0];
> +	rate->idx = -1; /* will over-write below if we found wcid */
> +	info->status.rates[1].idx = -1; /* terminate rate list */
> +
> +	/* force TX_STAT_AMPDU to be set, or mac80211 will ignore
> status */
> +	if (ampdu || (info->flags & IEEE80211_TX_CTL_AMPDU)) {
> +		info->flags |= IEEE80211_TX_STAT_AMPDU |
> IEEE80211_TX_CTL_AMPDU;
> +		info->status.ampdu_len = 1;
> +	}
> +
> +	/* update info status based on cached wcid rate info since
> +	 * txfree path doesn't give us a lot of info.
> +	 */
> +	if (wcid) {
> +		struct mt7915_sta *msta = container_of(wcid, struct
> mt7915_sta, wcid);
> +		struct mt76_sta_stats *stats = &msta->stats;
> +
> +		if (wcid->rate.flags & RATE_INFO_FLAGS_MCS) {
> +			rate->flags |= IEEE80211_TX_RC_MCS;
> +			rate->idx = wcid->rate.mcs + wcid->rate.nss *
> 8;
> +		} else if (wcid->rate.flags & RATE_INFO_FLAGS_VHT_MCS)
> {
> +			rate->flags |= IEEE80211_TX_RC_VHT_MCS;
> +			rate->idx = (wcid->rate.nss << 4) | wcid-
> >rate.mcs;
> +		} else if (wcid->rate.flags & RATE_INFO_FLAGS_HE_MCS) {
> +			rate->idx = (wcid->rate.nss << 4) | wcid-
> >rate.mcs;

Can ieee80211_tx_rate tell HE rate apart now?

Ryder



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/8] mt76: mt7915: cache sgi in wcid.
  2021-11-18 17:10   ` Ben Greear
@ 2021-11-18 17:20     ` Ryder Lee
  0 siblings, 0 replies; 16+ messages in thread
From: Ryder Lee @ 2021-11-18 17:20 UTC (permalink / raw)
  To: Ben Greear, linux-wireless

 * On Thu, 2021-11-18 at 09:10 -0800, Ben Greear wrote:
> On 11/18/21 9:06 AM, Ryder Lee wrote:
> > On Thu, 2021-11-18 at 08:45 -0800, greearb@candelatech.com wrote:
> > > From: Ben Greear <greearb@candelatech.com>
> > > 
> > > Explicitly cache short_gi and he_gi in wcid, don't try to store
> > > it in the wcid.rate object.  Slightly less confusing and less
> > > fragile
> > > when TXS starts parsing lots of frames.
> > > 
> > > Signed-off-by: Ben Greear <greearb@candelatech.com>
> > > ---
> > > 
> > > This is actually the first series, not that one I posted a few
> > > minutes
> > > ago.  txs, tx overrides and other things.  Rebased on top of 5.16
> > 
> > Maybe we can consider switching to use existing fixed-rate method
> > in
> > debugfs? On th other hand, that's the only way to configure HE MU
> > UL
> > fixed-rate.
> 
> This patch is to improve reported tx rates, not to control tx rates.
> 

Ah.  I shall reply [PATCH 8/8] mt76: mt7915: fix SGI reporting when
using tx-overrides.


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 6/8] mt76: mt7915: report tx-retries
  2021-11-18 17:19   ` Ryder Lee
@ 2021-11-18 17:26     ` Ben Greear
  0 siblings, 0 replies; 16+ messages in thread
From: Ben Greear @ 2021-11-18 17:26 UTC (permalink / raw)
  To: Ryder Lee, linux-wireless

On 11/18/21 9:19 AM, Ryder Lee wrote:
> On Thu, 2021-11-18 at 08:45 -0800, greearb@candelatech.com wrote:
>> From: Ben Greear <greearb@candelatech.com>
>>
>> mac80211 stack will only report tx-status for skb claiming to be
>> ampdu heads,
>> so lie a bit in mt7915 and set the flag so that mac80211 will record
>> status
>> for each skb.
>>
>> mt7915 appears to report retry status on an individual per-skb
>> manner,
>> so that method above seems to work.
>>
>> Re-constitute the txinfo status rate info so that the rix and flags
>> is also at least close to correct.  No direct way to report HE
>> rates that way, so mac80211 might could use some tweaking in
>> the ieee80211_tx_status_ext to take both info and status->rate
>> into account.
>>
>> Signed-off-by: Ben Greear <greearb@candelatech.com>

>> +			rate->flags |= IEEE80211_TX_RC_VHT_MCS;
>> +			rate->idx = (wcid->rate.nss << 4) | wcid-
>>> rate.mcs;
>> +		} else if (wcid->rate.flags & RATE_INFO_FLAGS_HE_MCS) {
>> +			rate->idx = (wcid->rate.nss << 4) | wcid-
>>> rate.mcs;
> 
> Can ieee80211_tx_rate tell HE rate apart now?
Upstream code cannot, but it has other ways of dealing with HE
rates, and this patch does not break that as far as I can tell.

Thanks,
Ben

> 
> Ryder
> 
> 


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 7/8] mt76: mt7915: add support for tx-overrides
  2021-11-18 16:45 ` [PATCH 7/8] mt76: mt7915: add support for tx-overrides greearb
@ 2021-11-19  7:16   ` kernel test robot
  0 siblings, 0 replies; 16+ messages in thread
From: kernel test robot @ 2021-11-19  7:16 UTC (permalink / raw)
  To: greearb, linux-wireless; +Cc: kbuild-all, Ben Greear

[-- Attachment #1: Type: text/plain, Size: 18053 bytes --]

Hi,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on kvalo-wireless-drivers-next/master]
[also build test ERROR on v5.16-rc1 next-20211118]
[cannot apply to kvalo-wireless-drivers/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/greearb-candelatech-com/mt76-mt7915-cache-sgi-in-wcid/20211119-005421
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git master
config: microblaze-buildonly-randconfig-r005-20211119 (attached as .config)
compiler: microblaze-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/c742cd1ffffaeff7ab79835466b08fd5616cdce3
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review greearb-candelatech-com/mt76-mt7915-cache-sgi-in-wcid/20211119-005421
        git checkout c742cd1ffffaeff7ab79835466b08fd5616cdce3
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=microblaze SHELL=/bin/bash drivers/net/wireless/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/net/wireless/mediatek/mt76/mt7915/mac.c: In function 'mt7915_mac_write_txwi_tm':
>> drivers/net/wireless/mediatek/mt76/mt7915/mac.c:778:37: error: 'struct mt76_phy' has no member named 'test'
     778 |                 if (skb != phy->mt76->test.tx_skb)
         |                                     ^~
   drivers/net/wireless/mediatek/mt76/mt7915/mac.c:780:32: error: 'struct mt76_phy' has no member named 'test'
     780 |                 td = &phy->mt76->test;
         |                                ^~
   In file included from include/linux/byteorder/little_endian.h:5,
                    from arch/microblaze/include/uapi/asm/byteorder.h:6,
                    from include/asm-generic/bitops/le.h:7,
                    from include/asm-generic/bitops.h:36,
                    from ./arch/microblaze/include/generated/asm/bitops.h:1,
                    from include/linux/bitops.h:33,
                    from include/linux/kernel.h:12,
                    from include/linux/skbuff.h:13,
                    from include/linux/if_ether.h:19,
                    from include/linux/etherdevice.h:20,
                    from drivers/net/wireless/mediatek/mt76/mt7915/mac.c:4:
>> drivers/net/wireless/mediatek/mt76/mt7915/mac.c:909:54: error: 'struct mt7915_phy' has no member named 'test'
     909 |                                                   phy->test.spe_idx));
         |                                                      ^~
   include/uapi/linux/byteorder/little_endian.h:33:51: note: in definition of macro '__cpu_to_le32'
      33 | #define __cpu_to_le32(x) ((__force __le32)(__u32)(x))
         |                                                   ^
   include/linux/compiler_types.h:310:9: note: in expansion of macro '__compiletime_assert'
     310 |         __compiletime_assert(condition, msg, prefix, suffix)
         |         ^~~~~~~~~~~~~~~~~~~~
   include/linux/compiler_types.h:322:9: note: in expansion of macro '_compiletime_assert'
     322 |         _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
         |         ^~~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
      39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
         |                                     ^~~~~~~~~~~~~~~~~~
   include/linux/bitfield.h:49:17: note: in expansion of macro 'BUILD_BUG_ON_MSG'
      49 |                 BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ?           \
         |                 ^~~~~~~~~~~~~~~~
   include/linux/bitfield.h:94:17: note: in expansion of macro '__BF_FIELD_CHECK'
      94 |                 __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: ");    \
         |                 ^~~~~~~~~~~~~~~~
   drivers/net/wireless/mediatek/mt76/mt7915/mac.c:908:40: note: in expansion of macro 'FIELD_PREP'
     908 |                 txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX,
         |                                        ^~~~~~~~~~
>> drivers/net/wireless/mediatek/mt76/mt7915/mac.c:909:54: error: 'struct mt7915_phy' has no member named 'test'
     909 |                                                   phy->test.spe_idx));
         |                                                      ^~
   include/uapi/linux/byteorder/little_endian.h:33:51: note: in definition of macro '__cpu_to_le32'
      33 | #define __cpu_to_le32(x) ((__force __le32)(__u32)(x))
         |                                                   ^
   include/linux/compiler_types.h:310:9: note: in expansion of macro '__compiletime_assert'
     310 |         __compiletime_assert(condition, msg, prefix, suffix)
         |         ^~~~~~~~~~~~~~~~~~~~
   include/linux/compiler_types.h:322:9: note: in expansion of macro '_compiletime_assert'
     322 |         _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
         |         ^~~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
      39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
         |                                     ^~~~~~~~~~~~~~~~~~
   include/linux/bitfield.h:49:17: note: in expansion of macro 'BUILD_BUG_ON_MSG'
      49 |                 BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ?           \
         |                 ^~~~~~~~~~~~~~~~
   include/linux/bitfield.h:94:17: note: in expansion of macro '__BF_FIELD_CHECK'
      94 |                 __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: ");    \
         |                 ^~~~~~~~~~~~~~~~
   drivers/net/wireless/mediatek/mt76/mt7915/mac.c:908:40: note: in expansion of macro 'FIELD_PREP'
     908 |                 txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX,
         |                                        ^~~~~~~~~~
>> drivers/net/wireless/mediatek/mt76/mt7915/mac.c:909:54: error: 'struct mt7915_phy' has no member named 'test'
     909 |                                                   phy->test.spe_idx));
         |                                                      ^~
   include/uapi/linux/byteorder/little_endian.h:33:51: note: in definition of macro '__cpu_to_le32'
      33 | #define __cpu_to_le32(x) ((__force __le32)(__u32)(x))
         |                                                   ^
   drivers/net/wireless/mediatek/mt76/mt7915/mac.c:908:40: note: in expansion of macro 'FIELD_PREP'
     908 |                 txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX,
         |                                        ^~~~~~~~~~
   At top level:
   drivers/net/wireless/mediatek/mt76/mt7915/mac.c:760:1: warning: 'mt7915_mac_write_txwi_tm' defined but not used [-Wunused-function]
     760 | mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, struct mt76_wcid *wcid, __le32 *txwi,
         | ^~~~~~~~~~~~~~~~~~~~~~~~


vim +778 drivers/net/wireless/mediatek/mt76/mt7915/mac.c

5d8a83f0994134 Shayne Chen 2020-10-22  758  
aadf09537c575d Shayne Chen 2020-10-22  759  static void
c742cd1ffffaef Ben Greear  2021-11-18  760  mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, struct mt76_wcid *wcid, __le32 *txwi,
c918c74d06457e Shayne Chen 2020-12-04  761  			 struct sk_buff *skb)
aadf09537c575d Shayne Chen 2020-10-22  762  {
c742cd1ffffaef Ben Greear  2021-11-18  763  	struct mt76_testmode_data *td;
cc91747be98f2a Shayne Chen 2021-04-12  764  	const struct ieee80211_rate *r;
c742cd1ffffaef Ben Greear  2021-11-18  765  	struct mt7915_sta *msta;
c742cd1ffffaef Ben Greear  2021-11-18  766  	u8 bw, mode, nss;
c742cd1ffffaef Ben Greear  2021-11-18  767  	u8 rate_idx;
aadf09537c575d Shayne Chen 2020-10-22  768  	u16 rateval = 0;
aadf09537c575d Shayne Chen 2020-10-22  769  	u32 val;
cc91747be98f2a Shayne Chen 2021-04-12  770  	bool cck = false;
cc91747be98f2a Shayne Chen 2021-04-12  771  	int band;
aadf09537c575d Shayne Chen 2020-10-22  772  
c742cd1ffffaef Ben Greear  2021-11-18  773  	msta = container_of(wcid, struct mt7915_sta, wcid);
c742cd1ffffaef Ben Greear  2021-11-18  774  
c742cd1ffffaef Ben Greear  2021-11-18  775  	if (msta->test.txo_active) {
c742cd1ffffaef Ben Greear  2021-11-18  776  		td = &msta->test;
c742cd1ffffaef Ben Greear  2021-11-18  777  	} else {
c918c74d06457e Shayne Chen 2020-12-04 @778  		if (skb != phy->mt76->test.tx_skb)
aadf09537c575d Shayne Chen 2020-10-22  779  			return;
c742cd1ffffaef Ben Greear  2021-11-18  780  		td = &phy->mt76->test;
c742cd1ffffaef Ben Greear  2021-11-18  781  	}
c742cd1ffffaef Ben Greear  2021-11-18  782  
c742cd1ffffaef Ben Greear  2021-11-18  783  	nss = td->tx_rate_nss;
c742cd1ffffaef Ben Greear  2021-11-18  784  	rate_idx = td->tx_rate_idx;
aadf09537c575d Shayne Chen 2020-10-22  785  
aadf09537c575d Shayne Chen 2020-10-22  786  	switch (td->tx_rate_mode) {
aadf09537c575d Shayne Chen 2020-10-22  787  	case MT76_TM_TX_MODE_HT:
aadf09537c575d Shayne Chen 2020-10-22  788  		nss = 1 + (rate_idx >> 3);
aadf09537c575d Shayne Chen 2020-10-22  789  		mode = MT_PHY_TYPE_HT;
aadf09537c575d Shayne Chen 2020-10-22  790  		break;
aadf09537c575d Shayne Chen 2020-10-22  791  	case MT76_TM_TX_MODE_VHT:
aadf09537c575d Shayne Chen 2020-10-22  792  		mode = MT_PHY_TYPE_VHT;
aadf09537c575d Shayne Chen 2020-10-22  793  		break;
aadf09537c575d Shayne Chen 2020-10-22  794  	case MT76_TM_TX_MODE_HE_SU:
aadf09537c575d Shayne Chen 2020-10-22  795  		mode = MT_PHY_TYPE_HE_SU;
aadf09537c575d Shayne Chen 2020-10-22  796  		break;
aadf09537c575d Shayne Chen 2020-10-22  797  	case MT76_TM_TX_MODE_HE_EXT_SU:
aadf09537c575d Shayne Chen 2020-10-22  798  		mode = MT_PHY_TYPE_HE_EXT_SU;
aadf09537c575d Shayne Chen 2020-10-22  799  		break;
aadf09537c575d Shayne Chen 2020-10-22  800  	case MT76_TM_TX_MODE_HE_TB:
aadf09537c575d Shayne Chen 2020-10-22  801  		mode = MT_PHY_TYPE_HE_TB;
aadf09537c575d Shayne Chen 2020-10-22  802  		break;
aadf09537c575d Shayne Chen 2020-10-22  803  	case MT76_TM_TX_MODE_HE_MU:
aadf09537c575d Shayne Chen 2020-10-22  804  		mode = MT_PHY_TYPE_HE_MU;
aadf09537c575d Shayne Chen 2020-10-22  805  		break;
cc91747be98f2a Shayne Chen 2021-04-12  806  	case MT76_TM_TX_MODE_CCK:
cc91747be98f2a Shayne Chen 2021-04-12  807  		cck = true;
cc91747be98f2a Shayne Chen 2021-04-12  808  		fallthrough;
aadf09537c575d Shayne Chen 2020-10-22  809  	case MT76_TM_TX_MODE_OFDM:
cc91747be98f2a Shayne Chen 2021-04-12  810  		band = phy->mt76->chandef.chan->band;
cc91747be98f2a Shayne Chen 2021-04-12  811  		if (band == NL80211_BAND_2GHZ && !cck)
cc91747be98f2a Shayne Chen 2021-04-12  812  			rate_idx += 4;
cc91747be98f2a Shayne Chen 2021-04-12  813  
cc91747be98f2a Shayne Chen 2021-04-12  814  		r = &phy->mt76->hw->wiphy->bands[band]->bitrates[rate_idx];
cc91747be98f2a Shayne Chen 2021-04-12  815  		val = cck ? r->hw_value_short : r->hw_value;
cc91747be98f2a Shayne Chen 2021-04-12  816  
cc91747be98f2a Shayne Chen 2021-04-12  817  		mode = val >> 8;
cc91747be98f2a Shayne Chen 2021-04-12  818  		rate_idx = val & 0xff;
cc91747be98f2a Shayne Chen 2021-04-12  819  		break;
aadf09537c575d Shayne Chen 2020-10-22  820  	default:
aadf09537c575d Shayne Chen 2020-10-22  821  		mode = MT_PHY_TYPE_OFDM;
aadf09537c575d Shayne Chen 2020-10-22  822  		break;
aadf09537c575d Shayne Chen 2020-10-22  823  	}
aadf09537c575d Shayne Chen 2020-10-22  824  
c742cd1ffffaef Ben Greear  2021-11-18  825  	if (msta->test.txo_active) {
c742cd1ffffaef Ben Greear  2021-11-18  826  		bw = td->txbw;
c742cd1ffffaef Ben Greear  2021-11-18  827  	} else {
c918c74d06457e Shayne Chen 2020-12-04  828  		switch (phy->mt76->chandef.width) {
aadf09537c575d Shayne Chen 2020-10-22  829  		case NL80211_CHAN_WIDTH_40:
aadf09537c575d Shayne Chen 2020-10-22  830  			bw = 1;
aadf09537c575d Shayne Chen 2020-10-22  831  			break;
aadf09537c575d Shayne Chen 2020-10-22  832  		case NL80211_CHAN_WIDTH_80:
aadf09537c575d Shayne Chen 2020-10-22  833  			bw = 2;
aadf09537c575d Shayne Chen 2020-10-22  834  			break;
aadf09537c575d Shayne Chen 2020-10-22  835  		case NL80211_CHAN_WIDTH_80P80:
aadf09537c575d Shayne Chen 2020-10-22  836  		case NL80211_CHAN_WIDTH_160:
aadf09537c575d Shayne Chen 2020-10-22  837  			bw = 3;
aadf09537c575d Shayne Chen 2020-10-22  838  			break;
aadf09537c575d Shayne Chen 2020-10-22  839  		default:
aadf09537c575d Shayne Chen 2020-10-22  840  			bw = 0;
aadf09537c575d Shayne Chen 2020-10-22  841  			break;
aadf09537c575d Shayne Chen 2020-10-22  842  		}
c742cd1ffffaef Ben Greear  2021-11-18  843  	}
aadf09537c575d Shayne Chen 2020-10-22  844  
aadf09537c575d Shayne Chen 2020-10-22  845  	if (td->tx_rate_stbc && nss == 1) {
aadf09537c575d Shayne Chen 2020-10-22  846  		nss++;
aadf09537c575d Shayne Chen 2020-10-22  847  		rateval |= MT_TX_RATE_STBC;
aadf09537c575d Shayne Chen 2020-10-22  848  	}
aadf09537c575d Shayne Chen 2020-10-22  849  
aadf09537c575d Shayne Chen 2020-10-22  850  	rateval |= FIELD_PREP(MT_TX_RATE_IDX, rate_idx) |
aadf09537c575d Shayne Chen 2020-10-22  851  		   FIELD_PREP(MT_TX_RATE_MODE, mode) |
aadf09537c575d Shayne Chen 2020-10-22  852  		   FIELD_PREP(MT_TX_RATE_NSS, nss - 1);
aadf09537c575d Shayne Chen 2020-10-22  853  
c742cd1ffffaef Ben Greear  2021-11-18  854  	/* TODO:  Support per-skb txpower, p.15 of txpower doc, DW2 29:24. */
aadf09537c575d Shayne Chen 2020-10-22  855  	txwi[2] |= cpu_to_le32(MT_TXD2_FIX_RATE);
aadf09537c575d Shayne Chen 2020-10-22  856  
c742cd1ffffaef Ben Greear  2021-11-18  857  	/* Looks like this sets tx attempt to exactly 1.
c742cd1ffffaef Ben Greear  2021-11-18  858  	 * TODO:  Use td->tx_xmit_count, if in txo mode.
c742cd1ffffaef Ben Greear  2021-11-18  859  	 */
aadf09537c575d Shayne Chen 2020-10-22  860  	le32p_replace_bits(&txwi[3], 1, MT_TXD3_REM_TX_COUNT);
aadf09537c575d Shayne Chen 2020-10-22  861  	if (td->tx_rate_mode < MT76_TM_TX_MODE_HT)
aadf09537c575d Shayne Chen 2020-10-22  862  		txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
aadf09537c575d Shayne Chen 2020-10-22  863  
c742cd1ffffaef Ben Greear  2021-11-18  864  	/* TODO:  Take tx_dynbw into account in txo mode. */
aadf09537c575d Shayne Chen 2020-10-22  865  	val = MT_TXD6_FIXED_BW |
aadf09537c575d Shayne Chen 2020-10-22  866  	      FIELD_PREP(MT_TXD6_BW, bw) |
aadf09537c575d Shayne Chen 2020-10-22  867  	      FIELD_PREP(MT_TXD6_TX_RATE, rateval) |
aadf09537c575d Shayne Chen 2020-10-22  868  	      FIELD_PREP(MT_TXD6_SGI, td->tx_rate_sgi);
aadf09537c575d Shayne Chen 2020-10-22  869  
aadf09537c575d Shayne Chen 2020-10-22  870  	/* for HE_SU/HE_EXT_SU PPDU
aadf09537c575d Shayne Chen 2020-10-22  871  	 * - 1x, 2x, 4x LTF + 0.8us GI
aadf09537c575d Shayne Chen 2020-10-22  872  	 * - 2x LTF + 1.6us GI, 4x LTF + 3.2us GI
aadf09537c575d Shayne Chen 2020-10-22  873  	 * for HE_MU PPDU
aadf09537c575d Shayne Chen 2020-10-22  874  	 * - 2x, 4x LTF + 0.8us GI
aadf09537c575d Shayne Chen 2020-10-22  875  	 * - 2x LTF + 1.6us GI, 4x LTF + 3.2us GI
aadf09537c575d Shayne Chen 2020-10-22  876  	 * for HE_TB PPDU
aadf09537c575d Shayne Chen 2020-10-22  877  	 * - 1x, 2x LTF + 1.6us GI
aadf09537c575d Shayne Chen 2020-10-22  878  	 * - 4x LTF + 3.2us GI
aadf09537c575d Shayne Chen 2020-10-22  879  	 */
aadf09537c575d Shayne Chen 2020-10-22  880  	if (mode >= MT_PHY_TYPE_HE_SU)
aadf09537c575d Shayne Chen 2020-10-22  881  		val |= FIELD_PREP(MT_TXD6_HELTF, td->tx_ltf);
aadf09537c575d Shayne Chen 2020-10-22  882  
cc91747be98f2a Shayne Chen 2021-04-12  883  	if (td->tx_rate_ldpc || (bw > 0 && mode >= MT_PHY_TYPE_HE_SU))
aadf09537c575d Shayne Chen 2020-10-22  884  		val |= MT_TXD6_LDPC;
aadf09537c575d Shayne Chen 2020-10-22  885  
cc91747be98f2a Shayne Chen 2021-04-12  886  	txwi[3] &= ~cpu_to_le32(MT_TXD3_SN_VALID);
aadf09537c575d Shayne Chen 2020-10-22  887  	txwi[6] |= cpu_to_le32(val);
c742cd1ffffaef Ben Greear  2021-11-18  888  
c742cd1ffffaef Ben Greear  2021-11-18  889  	if (msta->test.txo_active) {
c742cd1ffffaef Ben Greear  2021-11-18  890  		/* see mt7915_tm_set_tx_frames */
c742cd1ffffaef Ben Greear  2021-11-18  891  		static const u8 spe_idx_map[] = {0, 0, 1, 0, 3, 2, 4, 0,
c742cd1ffffaef Ben Greear  2021-11-18  892  						 9, 8, 6, 10, 16, 12, 18, 0};
c742cd1ffffaef Ben Greear  2021-11-18  893  		u32 spe_idx;
c742cd1ffffaef Ben Greear  2021-11-18  894  
c742cd1ffffaef Ben Greear  2021-11-18  895  		if (td->tx_spe_idx) {
c742cd1ffffaef Ben Greear  2021-11-18  896  			spe_idx = td->tx_spe_idx;
c742cd1ffffaef Ben Greear  2021-11-18  897  		} else {
c742cd1ffffaef Ben Greear  2021-11-18  898  			u8 tx_ant = td->tx_antenna_mask;
c742cd1ffffaef Ben Greear  2021-11-18  899  
c742cd1ffffaef Ben Greear  2021-11-18  900  			if (!tx_ant) {
c742cd1ffffaef Ben Greear  2021-11-18  901  				/* use antenna mask that matches our nss */
c742cd1ffffaef Ben Greear  2021-11-18  902  				tx_ant = GENMASK(nss - 1, 0);
c742cd1ffffaef Ben Greear  2021-11-18  903  			}
c742cd1ffffaef Ben Greear  2021-11-18  904  			spe_idx = spe_idx_map[tx_ant];
c742cd1ffffaef Ben Greear  2021-11-18  905  		}
c742cd1ffffaef Ben Greear  2021-11-18  906  		txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX, spe_idx));
c742cd1ffffaef Ben Greear  2021-11-18  907  	} else {
aadf09537c575d Shayne Chen 2020-10-22  908  		txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX,
78fc30a21cf117 Shayne Chen 2020-12-04 @909  						  phy->test.spe_idx));
c742cd1ffffaef Ben Greear  2021-11-18  910  	}
aadf09537c575d Shayne Chen 2020-10-22  911  }
aadf09537c575d Shayne Chen 2020-10-22  912  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 34036 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2021-11-19  7:17 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-18 16:45 [PATCH 1/8] mt76: mt7915: cache sgi in wcid greearb
2021-11-18 16:45 ` [PATCH 2/8] mt76: mt7915: allow processing TXS for 'NO_SKB' pkt-ids greearb
2021-11-18 16:45 ` [PATCH 3/8] mt76: mt7915: debugfs hook to enable TXS for NO_SKB pkt-ids greearb
2021-11-18 16:45 ` [PATCH 4/8] mt76: mt7915: add note about TXSFM 0x2 greearb
2021-11-18 17:02   ` Ryder Lee
2021-11-18 17:06     ` Ben Greear
2021-11-18 16:45 ` [PATCH 5/8] mt76: mt7915: txfree status to show txcount instead of latency greearb
2021-11-18 16:45 ` [PATCH 6/8] mt76: mt7915: report tx-retries greearb
2021-11-18 17:19   ` Ryder Lee
2021-11-18 17:26     ` Ben Greear
2021-11-18 16:45 ` [PATCH 7/8] mt76: mt7915: add support for tx-overrides greearb
2021-11-19  7:16   ` kernel test robot
2021-11-18 16:45 ` [PATCH 8/8] mt76: mt7915: fix SGI reporting when using tx-overrides greearb
2021-11-18 17:06 ` [PATCH 1/8] mt76: mt7915: cache sgi in wcid Ryder Lee
2021-11-18 17:10   ` Ben Greear
2021-11-18 17:20     ` Ryder Lee

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).