blob: d9fe625be0937386e1bc69ff2308a499d418724c [file] [log] [blame]
developer7e2761e2023-10-12 08:11:13 +08001From d663fd304a7bd5701b2b3ac42b4743dabb252750 Mon Sep 17 00:00:00 2001
2From: "sujuan.chen" <sujuan.chen@mediatek.com>
3Date: Thu, 18 May 2023 15:01:47 +0800
4Subject: [PATCH 68/98] wifi: mt76: mt7996: reset addr_elem when delete ba
5
6The old addr element info may be used when the signature is not equel to
70xff, and sta will find error SDP cause the SDP/SDL=0 issue.
8
9Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
10---
11 mt76.h | 1 +
12 mt76_connac_mcu.h | 1 +
13 mt7996/init.c | 3 ++
14 mt7996/mac.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++
15 mt7996/mcu.c | 77 +++++++++++++++++++++++++++++++++++++
16 mt7996/mcu.h | 46 ++++++++++++++++++++++
17 mt7996/mt7996.h | 27 +++++++++++++
18 mt7996/regs.h | 6 +++
19 8 files changed, 258 insertions(+)
20
21diff --git a/mt76.h b/mt76.h
22index b960f3d..bea58ff 100644
23--- a/mt76.h
24+++ b/mt76.h
25@@ -434,6 +434,7 @@ struct mt76_rx_tid {
26 u16 nframes;
27
28 u8 num;
29+ u16 session_id;
30
31 u8 started:1, stopped:1, timer_pending:1;
32
33diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
34index e904ebc..f659d2e 100644
35--- a/mt76_connac_mcu.h
36+++ b/mt76_connac_mcu.h
37@@ -1038,6 +1038,7 @@ enum {
38 MCU_UNI_EVENT_THERMAL = 0x35,
39 MCU_UNI_EVENT_NIC_CAPAB = 0x43,
40 MCU_UNI_EVENT_TESTMODE_CTRL = 0x46,
41+ MCU_UNI_EVENT_RRO = 0x57,
42 MCU_UNI_EVENT_PER_STA_INFO = 0x6d,
43 MCU_UNI_EVENT_ALL_STA_INFO = 0x6e,
44 };
45diff --git a/mt7996/init.c b/mt7996/init.c
46index 4503482..1f01f24 100644
47--- a/mt7996/init.c
48+++ b/mt7996/init.c
49@@ -779,6 +779,9 @@ static int mt7996_wed_rro_init(struct mt7996_dev *dev)
50 mt76_wr(dev, MT_RRO_HOST_INT_ENA,
51 MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA);
52
53+ INIT_WORK(&dev->wed_rro.rro_del_work, mt7996_rro_delete_sessions);
54+ INIT_LIST_HEAD(&dev->wed_rro.rro_poll_list);
55+
56 /* rro ind cmd queue init */
57 return mt7996_dma_rro_init(dev);
58 #else
59diff --git a/mt7996/mac.c b/mt7996/mac.c
60index b24f237..60ca23b 100644
61--- a/mt7996/mac.c
62+++ b/mt7996/mac.c
63@@ -1450,6 +1450,96 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
64 }
65 }
66
67+static struct mt7996_wed_rro_addr *
68+mt7996_rro_get_addr_elem(struct mt7996_dev *dev, u16 seid, u16 sn)
69+{
70+ u32 idx;
71+ void *addr;
72+
73+ if (seid == MT7996_RRO_MAX_SESSION) {
74+ addr = dev->wed_rro.session.ptr;
75+ idx = sn % MT7996_RRO_WINDOW_MAX_LEN;
76+ } else {
77+ addr = dev->wed_rro.addr_elem[seid / MT7996_RRO_BA_BITMAP_SESSION_SIZE].ptr;
78+ idx = (seid % MT7996_RRO_BA_BITMAP_SESSION_SIZE) * MT7996_RRO_WINDOW_MAX_LEN
79+ + (sn % MT7996_RRO_WINDOW_MAX_LEN);
80+ }
81+ return addr + idx * sizeof(struct mt7996_wed_rro_addr);
82+}
83+
84+static bool mt7996_rro_reset_sessions(struct mt7996_dev *dev, u16 session_id)
85+{
86+ struct mt7996_wed_rro_addr *elem;
87+ int i;
88+
89+ for (i = 0; i < MT7996_RRO_WINDOW_MAX_LEN; i++) {
90+ elem = mt7996_rro_get_addr_elem(dev, session_id, i);
91+ elem->signature = 0xff;
92+ }
93+ return true;
94+
95+}
96+
97+void mt7996_rro_delete_sessions(struct work_struct *work)
98+{
99+ struct mt7996_dev *dev;
100+ struct mt7996_rro_ba_session_elem *e;
101+ int elem_nums;
102+ LIST_HEAD(rro_poll_list);
103+
104+ dev = (struct mt7996_dev *)container_of(work, struct mt7996_dev,
105+ wed_rro.rro_del_work);
106+ elem_nums = dev->wed_rro.elem_nums;
107+
108+ spin_lock_bh(&dev->wed_rro.rro_stbl_lock);
109+ list_splice_init(&dev->wed_rro.rro_poll_list, &rro_poll_list);
110+ spin_unlock_bh(&dev->wed_rro.rro_stbl_lock);
111+
112+ do {
113+ spin_lock_bh(&dev->wed_rro.rro_stbl_lock);
114+ if (list_empty(&rro_poll_list)) {
115+ spin_unlock_bh(&dev->wed_rro.rro_stbl_lock);
116+ break;
117+ }
118+
119+ e = list_first_entry(&rro_poll_list,
120+ struct mt7996_rro_ba_session_elem,
121+ poll_list);
122+ if (!e) {
123+ spin_unlock_bh(&dev->wed_rro.rro_stbl_lock);
124+ break;
125+ }
126+ list_del_init(&e->poll_list);
127+ spin_unlock_bh(&dev->wed_rro.rro_stbl_lock);
128+
129+ if (mt7996_rro_reset_sessions(dev, e->session_id)) {
130+ mt7996_mcu_reset_rro_sessions(dev, e->session_id);
131+ kfree(e);
132+ dev->wed_rro.elem_nums--;
133+ }
134+ elem_nums--;
135+ } while (elem_nums);
136+}
137+
138+int mt7996_rro_add_delete_elem(struct mt7996_dev *dev, u16 seid)
139+{
140+ struct mt7996_rro_ba_session_elem *e;
141+
142+ e = kzalloc(sizeof(*e), GFP_ATOMIC);
143+ if (!e)
144+ return -ENOMEM;
145+
146+ e->session_id = seid;
147+
148+ spin_lock_bh(&dev->wed_rro.rro_stbl_lock);
149+ list_add_tail(&e->poll_list, &dev->wed_rro.rro_poll_list);
150+ spin_unlock_bh(&dev->wed_rro.rro_stbl_lock);
151+ dev->wed_rro.elem_nums++;
152+
153+ ieee80211_queue_work(mt76_hw(dev), &dev->wed_rro.rro_del_work);
154+ return 0;
155+}
156+
157 void mt7996_mac_cca_stats_reset(struct mt7996_phy *phy)
158 {
159 struct mt7996_dev *dev = phy->dev;
160@@ -1774,6 +1864,9 @@ mt7996_mac_full_reset(struct mt7996_dev *dev)
161 if (phy3)
162 ieee80211_stop_queues(phy3->mt76->hw);
163
164+ if (dev->has_rro)
165+ cancel_work_sync(&dev->wed_rro.rro_del_work);
166+
167 cancel_delayed_work_sync(&dev->mphy.mac_work);
168 if (phy2)
169 cancel_delayed_work_sync(&phy2->mt76->mac_work);
170@@ -1865,6 +1958,10 @@ void mt7996_mac_reset_work(struct work_struct *work)
171 set_bit(MT76_RESET, &dev->mphy.state);
172 set_bit(MT76_MCU_RESET, &dev->mphy.state);
173 wake_up(&dev->mt76.mcu.wait);
174+
175+ if (dev->has_rro)
176+ cancel_work_sync(&dev->wed_rro.rro_del_work);
177+
178 cancel_delayed_work_sync(&dev->mphy.mac_work);
179 if (phy2) {
180 set_bit(MT76_RESET, &phy2->mt76->state);
181diff --git a/mt7996/mcu.c b/mt7996/mcu.c
182index 6589610..ce38a5e 100644
183--- a/mt7996/mcu.c
184+++ b/mt7996/mcu.c
185@@ -538,6 +538,60 @@ mt7996_mcu_update_tx_gi(struct rate_info *rate, struct all_sta_trx_rate *mcu_rat
186 return 0;
187 }
188
189+static void mt7996_mcu_rx_rro(struct mt7996_dev *dev, struct sk_buff *skb)
190+{
191+ struct mt7996_mcu_rro_event *event;
192+ struct mt7996_mcu_rro_ba *rro;
193+ struct mt7996_mcu_rro_ba_del_chk_done *delba;
194+ u16 len;
195+
196+ if (!dev->has_rro)
197+ return;
198+
199+ event = (struct mt7996_mcu_rro_event *)skb->data;
200+ skb_pull(skb, sizeof(struct mt7996_mcu_rxd) + 4);
201+
202+ switch (event->tag) {
203+ case UNI_RRO_BA_SESSION_STATUS: {
204+ len = sizeof(struct mt7996_mcu_rro_ba);
205+ while (unlikely(len > skb->len) ? NULL : true) {
206+ rro = (struct mt7996_mcu_rro_ba *)skb->data;
207+ u16 idx = cpu_to_le16(rro->wlan_id);
208+ struct mt76_rx_tid *tid;
209+ struct mt76_wcid *wcid;
210+
211+ wcid = rcu_dereference(dev->mt76.wcid[idx]);
212+ if (!wcid || !wcid->sta)
213+ return;
214+
215+ tid = rcu_dereference(wcid->aggr[rro->tid]);
216+ if (!tid)
217+ return;
218+ tid->session_id = cpu_to_le16(rro->session_id);
219+ skb_pull(skb, len);
220+ }
221+ break;
222+ }
223+ case UNI_RRO_BA_SESSION_DEL_CHK_DONE: {
224+ len = sizeof(struct mt7996_mcu_rro_ba_del_chk_done);
225+ while (unlikely(len > skb->len) ? NULL : true) {
226+ delba = (struct mt7996_mcu_rro_ba_del_chk_done *)skb->data;
227+ u16 session_id = cpu_to_le16(delba->session_id);
228+
229+ mt7996_rro_add_delete_elem(dev, session_id);
230+ skb_pull(skb, len);
231+ }
232+ break;
233+ }
234+
235+ default:
236+ dev_info(dev->mt76.dev, "%s: unknown rro event tag %d\n",
237+ __func__, event->tag);
238+ break;
239+ }
240+
241+}
242+
243 static void
244 mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
245 {
246@@ -663,6 +717,9 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
247 mt7996_tm_rf_test_event(dev, skb);
248 break;
249 #endif
250+ case MCU_UNI_EVENT_RRO:
251+ mt7996_mcu_rx_rro(dev, skb);
252+ break;
253 default:
254 break;
255 }
256@@ -4615,6 +4672,26 @@ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val)
257 sizeof(req), true);
258 }
259
260+int mt7996_mcu_reset_rro_sessions(struct mt7996_dev *dev, u16 seid)
261+{
262+ struct {
263+ /* fixed field */
264+ u8 __rsv[4];
265+
266+ __le16 tag;
267+ __le16 len;
268+ __le16 session_id;
269+ u8 pad[4];
270+ } __packed req = {
271+ .tag = cpu_to_le16(UNI_RRO_DEL_BA_SESSION),
272+ .len = cpu_to_le16(sizeof(req) - 4),
273+ .session_id = cpu_to_le16(seid),
274+ };
275+
276+ return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(RRO),
277+ &req, sizeof(req), true);
278+}
279+
280 int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag)
281 {
282 struct mt7996_dev *dev = phy->dev;
283diff --git a/mt7996/mcu.h b/mt7996/mcu.h
284index 666216a..0aa68f7 100644
285--- a/mt7996/mcu.h
286+++ b/mt7996/mcu.h
287@@ -239,6 +239,50 @@ struct mt7996_mcu_all_sta_info_event {
288 };
289 } __packed;
290
291+struct mt7996_mcu_rro_event {
292+ struct mt7996_mcu_rxd rxd;
293+
294+ u8 __rsv1[4];
295+
296+ __le16 tag;
297+ __le16 len;
298+} __packed;
299+
300+struct mt7996_mcu_rro_ba {
301+ __le16 tag;
302+ __le16 len;
303+
304+ __le16 wlan_id;
305+ u8 tid;
306+ u8 __rsv1;
307+ __le32 status;
308+ __le16 session_id;
309+ u8 __rsv2[2];
310+} __packed;
311+
312+struct mt7996_mcu_rro_ba_del_chk_done {
313+ __le16 tag;
314+ __le16 len;
315+
316+ __le16 session_id;
317+ u8 __rsv2[2];
318+} __packed;
319+
320+enum {
321+ UNI_RRO_BA_SESSION_STATUS = 0,
322+ UNI_RRO_BA_SESSION_TBL = 1,
323+ UNI_RRO_BA_SESSION_DEL_CHK_DONE = 2,
324+ UNI_RRO_BA_SESSION_MAX_NUM
325+};
326+
327+struct mt7996_mcu_rro_del_ba {
328+ struct mt7996_mcu_rro_event event;
329+
330+ u8 wlan_idx;
331+ u8 tid;
332+ u8 __rsv2[2];
333+};
334+
335 enum mt7996_chan_mib_offs {
336 UNI_MIB_OBSS_AIRTIME = 26,
337 UNI_MIB_NON_WIFI_TIME = 27,
338@@ -840,6 +884,8 @@ enum {
339 UNI_RRO_GET_BA_SESSION_TABLE,
340 UNI_RRO_SET_BYPASS_MODE,
341 UNI_RRO_SET_TXFREE_PATH,
342+ UNI_RRO_DEL_BA_SESSION,
343+ UNI_RRO_SET_FLUSH_TIMEOUT
344 };
345
346 enum{
347diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
348index bba1364..af67c59 100644
349--- a/mt7996/mt7996.h
350+++ b/mt7996/mt7996.h
351@@ -282,6 +282,26 @@ struct mt7996_wed_rro_addr {
352 u32 signature : 8;
353 };
354
355+struct mt7996_rro_ba_session {
356+ u32 ack_sn :12;
357+ u32 win_sz :3;
358+ u32 bn :1;
359+ u32 last_in_sn :12;
360+ u32 bc :1;
361+ u32 bd :1;
362+ u32 sat :1;
363+ u32 cn :1;
364+ u32 within_cnt :12;
365+ u32 to_sel :3;
366+ u32 rsv :1;
367+ u32 last_in_rxtime :12;
368+};
369+
370+struct mt7996_rro_ba_session_elem {
371+ struct list_head poll_list;
372+ u16 session_id;
373+};
374+
375 struct mt7996_phy {
376 struct mt76_phy *mt76;
377 struct mt7996_dev *dev;
378@@ -418,6 +438,10 @@ struct mt7996_dev {
379 void *ptr;
380 dma_addr_t phy_addr;
381 } session;
382+ struct work_struct rro_del_work;
383+ spinlock_t rro_stbl_lock;
384+ struct list_head rro_poll_list;
385+ u16 elem_nums;
386 } wed_rro;
387
388 bool testmode_enable;
389@@ -653,6 +677,7 @@ int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,
390 int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set);
391 int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans);
392 int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val);
393+int mt7996_mcu_reset_rro_sessions(struct mt7996_dev *dev, u16 seid);
394 int mt7996_mcu_wa_cmd(struct mt7996_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
395 int mt7996_mcu_red_config(struct mt7996_dev *dev, bool enable);
396 int mt7996_mcu_fw_log_2_host(struct mt7996_dev *dev, u8 type, u8 ctrl);
397@@ -757,6 +782,8 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
398 struct ieee80211_sta *sta,
399 struct mt76_tx_info *tx_info);
400 void mt7996_tx_token_put(struct mt7996_dev *dev);
401+void mt7996_rro_delete_sessions(struct work_struct *work);
402+int mt7996_rro_add_delete_elem(struct mt7996_dev *dev, u16 seid);
403 void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
404 struct sk_buff *skb, u32 *info);
405 bool mt7996_rx_check(struct mt76_dev *mdev, void *data, int len);
406diff --git a/mt7996/regs.h b/mt7996/regs.h
407index d305c25..38467d9 100644
408--- a/mt7996/regs.h
409+++ b/mt7996/regs.h
410@@ -101,6 +101,12 @@ enum offs_rev {
411 #define MT_RRO_ACK_SN_CTRL_SN_MASK GENMASK(27, 16)
412 #define MT_RRO_ACK_SN_CTRL_SESSION_MASK GENMASK(11, 0)
413
414+#define MT_RRO_DBG_RD_CTRL MT_RRO_TOP(0xe0)
415+#define MT_RRO_DBG_RD_ADDR GENMASK(15, 0)
416+#define MT_RRO_DBG_RD_EXEC BIT(31)
417+
418+#define MT_RRO_DBG_RDAT_DW(_n) MT_RRO_TOP(0xf0 + _n * 0x4)
419+
420 #define MT_MCU_INT_EVENT 0x2108
421 #define MT_MCU_INT_EVENT_DMA_STOPPED BIT(0)
422 #define MT_MCU_INT_EVENT_DMA_INIT BIT(1)
423--
4242.18.0
425