blob: eb0dbbc3be217df7e71e2325057df941ec2ec8e5 [file] [log] [blame]
developer05f3b2b2024-08-19 19:17:34 +08001From c9cc947b2922dde53c71ce871ac869039d740999 Mon Sep 17 00:00:00 2001
2From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
3Date: Thu, 4 Jul 2024 14:00:16 +0800
4Subject: [PATCH 178/199] mtk: mt76: mt7996: add per-STA TX MSDU failed and
5 retried counts
6
7Record per-STA TX MSDU failed and retried counts for debugging.
8
9Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
10---
11 mt76.h | 2 ++
12 mt76_connac_mcu.h | 3 ++
13 mt7996/mac.c | 39 ++++++++++++++++++++++++-
14 mt7996/mcu.c | 74 +++++++++++------------------------------------
15 mt7996/mcu.h | 8 +++++
16 mt7996/mt7996.h | 1 -
17 6 files changed, 68 insertions(+), 59 deletions(-)
18
19diff --git a/mt76.h b/mt76.h
20index feb7bf16..fa4a3e70 100644
21--- a/mt76.h
22+++ b/mt76.h
23@@ -360,6 +360,8 @@ struct mt76_sta_stats {
24 u64 tx_bytes;
25 /* WED TX */
26 u32 tx_packets; /* unit: MSDU */
27+ u32 tx_packets_retried;
28+ u32 tx_packets_failed;
29 u32 tx_mpdus;
30 u32 tx_retries;
31 u32 tx_failed;
32diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
33index c1becf7e..545de4ae 100644
34--- a/mt76_connac_mcu.h
35+++ b/mt76_connac_mcu.h
36@@ -1402,6 +1402,8 @@ enum {
37 UNI_OFFLOAD_OFFLOAD_BMC_RPY_DETECT,
38 };
39
40+#define PER_STA_INFO_MAX_NUM 90
41+
42 enum UNI_PER_STA_INFO_TAG {
43 UNI_PER_STA_RSSI,
44 UNI_PER_STA_CONTENTION_RX_RATE,
45@@ -1411,6 +1413,7 @@ enum UNI_PER_STA_INFO_TAG {
46 UNI_PER_STA_TX_CNT,
47 UNI_PER_STA_TID_SN_GET,
48 UNI_PER_STA_TID_SN_SET,
49+ UNI_PER_STA_PKT_CNT,
50 UNI_PER_STA_MAX_NUM
51 };
52
53diff --git a/mt7996/mac.c b/mt7996/mac.c
54index a8985a3b..fae24cad 100644
55--- a/mt7996/mac.c
56+++ b/mt7996/mac.c
57@@ -2431,6 +2431,43 @@ void mt7996_mac_sta_rc_work(struct work_struct *work)
58 rcu_read_unlock();
59 }
60
61+static int mt7996_mac_sta_poll(struct mt76_dev *dev)
62+{
63+ u16 sta_list[PER_STA_INFO_MAX_NUM];
64+ struct mt7996_link_sta *mlink;
65+ int i, ret;
66+
67+ spin_lock_bh(&dev->sta_poll_lock);
68+ for (i = 0; i < PER_STA_INFO_MAX_NUM; ++i) {
69+ if (list_empty(&dev->sta_poll_list))
70+ break;
71+
72+ mlink = list_first_entry(&dev->sta_poll_list,
73+ struct mt7996_link_sta,
74+ wcid.poll_list);
75+ list_del_init(&mlink->wcid.poll_list);
76+ sta_list[i] = mlink->wcid.idx;
77+ }
78+ spin_unlock_bh(&dev->sta_poll_lock);
79+
80+ if (i == 0)
81+ return 0;
82+
83+ ret = mt7996_mcu_get_per_sta_info(dev, UNI_PER_STA_RSSI, i, sta_list);
84+ if (ret)
85+ dev_err(dev->dev, "Failed to update RSSI of polled STAs.\n");
86+
87+ ret = mt7996_mcu_get_per_sta_info(dev, UNI_PER_STA_SNR, i, sta_list);
88+ if (ret)
89+ dev_err(dev->dev, "Failed to update SNR of polled STAs.\n");
90+
91+ ret = mt7996_mcu_get_per_sta_info(dev, UNI_PER_STA_PKT_CNT, i, sta_list);
92+ if (ret)
93+ dev_err(dev->dev, "Failed to update MSDU counts of polled STAs.\n");
94+
95+ return ret;
96+}
97+
98 void mt7996_mac_work(struct work_struct *work)
99 {
100 struct mt76_phy *mphy = (struct mt76_phy *)container_of(work, struct mt76_phy,
101@@ -2453,7 +2490,7 @@ void mt7996_mac_work(struct work_struct *work)
102 if (i == mphy->band_idx) {
103 mt7996_mcu_get_all_sta_info(mdev, UNI_ALL_STA_TXRX_RATE);
104 mt7996_mcu_get_all_sta_info(mdev, UNI_ALL_STA_TXRX_AIRTIME);
105- mt7996_mcu_get_signal_status(mdev);
106+ mt7996_mac_sta_poll(mdev);
107 // if (mtk_wed_device_active(&mdev->mmio.wed)) {
108 mt7996_mcu_get_all_sta_info(mdev, UNI_ALL_STA_TXRX_ADM_STAT);
109 mt7996_mcu_get_all_sta_info(mdev, UNI_ALL_STA_TXRX_MSDU_COUNT);
110diff --git a/mt7996/mcu.c b/mt7996/mcu.c
111index 00bc675e..857d2826 100644
112--- a/mt7996/mcu.c
113+++ b/mt7996/mcu.c
114@@ -6017,7 +6017,6 @@ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u16 val)
115 int mt7996_mcu_get_per_sta_info(struct mt76_dev *dev, u16 tag,
116 u16 sta_num, u16 *sta_list)
117 {
118-#define PER_STA_INFO_MAX_NUM 90
119 struct mt7996_mcu_per_sta_info_event *res;
120 struct mt7996_link_sta *mlink;
121 struct mt76_wcid *wcid;
122@@ -6097,6 +6096,23 @@ int mt7996_mcu_get_per_sta_info(struct mt76_dev *dev, u16 tag,
123 }
124 }
125 break;
126+ case UNI_PER_STA_PKT_CNT:
127+ for (i = 0; i < sta_num; ++i) {
128+ wlan_idx = le16_to_cpu(res->msdu_cnt[i].wlan_idx);
129+ wcid = rcu_dereference(dev->wcid[wlan_idx]);
130+ if (wcid) {
131+ u32 retries = le32_to_cpu(res->msdu_cnt[i].tx_retries),
132+ drops = le32_to_cpu(res->msdu_cnt[i].tx_drops);
133+
134+ wcid->stats.tx_packets_retried += retries;
135+ wcid->stats.tx_packets_failed += retries + drops;
136+ } else {
137+ ret = -EINVAL;
138+ dev_err(dev->dev, "Failed to update MSDU counts for "
139+ "invalid WCID: %hu\n", wlan_idx);
140+ }
141+ }
142+ break;
143 default:
144 ret = -EINVAL;
145 dev_err(dev->dev, "Unknown UNI_PER_STA_INFO_TAG: %d\n", tag);
146@@ -6107,62 +6123,6 @@ out:
147 return ret;
148 }
149
150-int mt7996_mcu_get_signal_status(struct mt76_dev *dev)
151-{
152- u16 sta_list[PER_STA_INFO_MAX_NUM];
153- LIST_HEAD(sta_poll_list);
154- struct mt7996_link_sta *mlink;
155- int i, ret;
156- bool empty = false;
157-
158- spin_lock_bh(&dev->sta_poll_lock);
159- list_splice_init(&dev->sta_poll_list, &sta_poll_list);
160- spin_unlock_bh(&dev->sta_poll_lock);
161-
162- while (!empty) {
163- for (i = 0; i < PER_STA_INFO_MAX_NUM; ++i) {
164- spin_lock_bh(&dev->sta_poll_lock);
165- if (list_empty(&sta_poll_list)) {
166- spin_unlock_bh(&dev->sta_poll_lock);
167-
168- if (i == 0)
169- return 0;
170-
171- empty = true;
172- break;
173- }
174- mlink = list_first_entry(&sta_poll_list,
175- struct mt7996_link_sta,
176- wcid.poll_list);
177- list_del_init(&mlink->wcid.poll_list);
178- spin_unlock_bh(&dev->sta_poll_lock);
179-
180- sta_list[i] = mlink->wcid.idx;
181- }
182-
183- ret = mt7996_mcu_get_per_sta_info(dev, UNI_PER_STA_RSSI,
184- i, sta_list);
185- if (ret)
186- break;
187-
188- ret = mt7996_mcu_get_per_sta_info(dev, UNI_PER_STA_SNR,
189- i, sta_list);
190- if (ret)
191- break;
192- }
193-
194- if (ret) {
195- /* Add STAs, whose signal statuses have not been updated,
196- * back to polling list.
197- */
198- spin_lock_bh(&dev->sta_poll_lock);
199- list_splice(&sta_poll_list, &dev->sta_poll_list);
200- spin_unlock_bh(&dev->sta_poll_lock);
201- }
202-
203- return ret;
204-}
205-
206 int mt7996_mcu_get_all_sta_info(struct mt76_dev *dev, u16 tag)
207 {
208 struct {
209diff --git a/mt7996/mcu.h b/mt7996/mcu.h
210index 01eb0ea1..739e357c 100644
211--- a/mt7996/mcu.h
212+++ b/mt7996/mcu.h
213@@ -211,6 +211,13 @@ struct per_sta_snr {
214 s8 val[IEEE80211_MAX_CHAINS];
215 } __packed;
216
217+struct per_sta_msdu_cnt {
218+ __le16 wlan_idx;
219+ u8 __rsv[2];
220+ __le32 tx_drops;
221+ __le32 tx_retries;
222+} __packed;
223+
224 struct mt7996_mcu_per_sta_info_event {
225 u8 __rsv[4];
226
227@@ -220,6 +227,7 @@ struct mt7996_mcu_per_sta_info_event {
228 union {
229 struct per_sta_rssi rssi[0];
230 struct per_sta_snr snr[0];
231+ struct per_sta_msdu_cnt msdu_cnt[0];
232 };
233 } __packed;
234
235diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
236index 74c32827..8b00b05b 100644
237--- a/mt7996/mt7996.h
238+++ b/mt7996/mt7996.h
239@@ -1134,7 +1134,6 @@ void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
240 void mt7996_mcu_exit(struct mt7996_dev *dev);
241 int mt7996_mcu_get_per_sta_info(struct mt76_dev *dev, u16 tag,
242 u16 sta_num, u16 *sta_list);
243-int mt7996_mcu_get_signal_status(struct mt76_dev *dev);
244 int mt7996_mcu_get_all_sta_info(struct mt76_dev *dev, u16 tag);
245 int mt7996_mcu_wed_rro_reset_sessions(struct mt7996_dev *dev, u16 id);
246 int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data);
247--
2482.18.0
249