blob: b3442f4c4c0b18bd9ba7243fd5d93e321434a356 [file] [log] [blame]
developer57c8f1a2022-12-15 14:09:45 +08001From 2d158600e7c9b18069111d5935e9dbaf8c9277f3 Mon Sep 17 00:00:00 2001
2From: Sujuan Chen <sujuan.chen@mediatek.com>
3Date: Tue, 13 Dec 2022 17:51:26 +0800
4Subject: [PATCH 3002/3012] mt76: mt7915: wed: add wds support when wed is
5 enabled
6
7Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
8---
9 mt76.h | 6 ++++++
10 mt7915/main.c | 22 ++++++++++++++++++++--
11 mt7915/mcu.c | 13 +++++++++++--
12 mt7915/mcu.h | 1 +
13 util.c | 40 +++++++++++++++++++++++++++++++++++++---
14 util.h | 7 ++++++-
15 6 files changed, 81 insertions(+), 8 deletions(-)
16
17diff --git a/mt76.h b/mt76.h
18index 01baceaf..7b222e73 100644
19--- a/mt76.h
20+++ b/mt76.h
21@@ -60,6 +60,12 @@ enum mt76_wed_type {
22 MT76_WED_Q_RX,
23 };
24
25+enum mt76_wed_state {
26+ MT76_WED_DEFAULT,
27+ MT76_WED_ACTIVE,
28+ MT76_WED_WDS_ACTIVE,
29+};
30+
31 struct mt76_bus_ops {
32 u32 (*rr)(struct mt76_dev *dev, u32 offset);
33 void (*wr)(struct mt76_dev *dev, u32 offset, u32 val);
34diff --git a/mt7915/main.c b/mt7915/main.c
35index 370bfad7..75c78b8e 100644
36--- a/mt7915/main.c
37+++ b/mt7915/main.c
38@@ -675,8 +675,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
39 #endif
40 int ret, idx;
41 u32 addr;
42+ u8 flags = MT76_WED_DEFAULT;
43
44- idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA);
45+ if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
46+ !is_mt7915(&dev->mt76)) {
47+ flags = test_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags) ?
48+ MT76_WED_WDS_ACTIVE : MT76_WED_ACTIVE;
49+ }
50+
51+ idx = __mt76_wcid_alloc(mdev->wcid_mask, MT7915_WTBL_STA, flags);
52 if (idx < 0)
53 return -ENOSPC;
54
55@@ -1148,6 +1155,13 @@ static void mt7915_sta_set_4addr(struct ieee80211_hw *hw,
56 else
57 clear_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags);
58
59+ if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
60+ !is_mt7915(&dev->mt76)) {
61+ mt7915_sta_remove(hw, vif, sta);
62+ mt76_sta_pre_rcu_remove(hw, vif, sta);
63+ mt7915_sta_add(hw, vif, sta);
64+ }
65+
66 mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta);
67 }
68
69@@ -1519,8 +1533,12 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
70 path->dev = ctx->dev;
71 path->mtk_wdma.wdma_idx = wed->wdma_idx;
72 path->mtk_wdma.bss = mvif->mt76.idx;
73- path->mtk_wdma.wcid = is_mt7915(&dev->mt76) ? 0xff : 0x3ff;
74 path->mtk_wdma.queue = phy != &dev->phy;
75+ if (test_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags) ||
76+ is_mt7915(&dev->mt76))
77+ path->mtk_wdma.wcid = msta->wcid.idx;
78+ else
79+ path->mtk_wdma.wcid = 0x3ff;
80
81 ctx->dev = NULL;
82
83diff --git a/mt7915/mcu.c b/mt7915/mcu.c
84index 4b7ad450..bdfb71e2 100644
85--- a/mt7915/mcu.c
86+++ b/mt7915/mcu.c
87@@ -2350,8 +2350,17 @@ int mt7915_mcu_init_firmware(struct mt7915_dev *dev)
88 if (ret)
89 return ret;
90
91- if (mtk_wed_device_active(&dev->mt76.mmio.wed) && is_mt7915(&dev->mt76))
92- mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(CAPABILITY), 0, 0, 0);
93+ if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
94+ if (is_mt7915(&dev->mt76))
95+ ret = mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(CAPABILITY),
96+ 0, 0, 0);
97+ else
98+ ret = mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET),
99+ MCU_WA_PARAM_WED_VERSION,
100+ dev->mt76.mmio.wed.rev_id, 0);
101+ if (ret)
102+ return ret;
103+ }
104
105 ret = mt7915_mcu_set_mwds(dev, 1);
106 if (ret)
107diff --git a/mt7915/mcu.h b/mt7915/mcu.h
108index d110e210..edb8b510 100644
109--- a/mt7915/mcu.h
110+++ b/mt7915/mcu.h
111@@ -284,6 +284,7 @@ enum {
112 MCU_WA_PARAM_PDMA_RX = 0x04,
113 MCU_WA_PARAM_CPU_UTIL = 0x0b,
114 MCU_WA_PARAM_RED = 0x0e,
115+ MCU_WA_PARAM_WED_VERSION = 0x32,
116 #ifdef MTK_DEBUG
117 MCU_WA_PARAM_RED_SHOW_STA = 0xf,
118 MCU_WA_PARAM_RED_TARGET_DELAY = 0x10,
119diff --git a/util.c b/util.c
120index 58196442..5cd5ede0 100644
121--- a/util.c
122+++ b/util.c
123@@ -42,9 +42,14 @@ bool __mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val,
124 }
125 EXPORT_SYMBOL_GPL(__mt76_poll_msec);
126
127-int mt76_wcid_alloc(u32 *mask, int size)
128+int __mt76_wcid_alloc(u32 *mask, int size, u8 flag)
129 {
130+#define MT76_WED_WDS_MIN 256
131+#define MT76_WED_WDS_CNT 16
132+
133 int i, idx = 0, cur;
134+ int min = MT76_WED_WDS_MIN;
135+ int max = min + MT76_WED_WDS_CNT;
136
137 for (i = 0; i < DIV_ROUND_UP(size, 32); i++) {
138 idx = ffs(~mask[i]);
139@@ -53,16 +58,45 @@ int mt76_wcid_alloc(u32 *mask, int size)
140
141 idx--;
142 cur = i * 32 + idx;
143- if (cur >= size)
144+
145+ switch (flag) {
146+ case MT76_WED_ACTIVE:
147+ if (cur >= min && cur < max)
148+ continue;
149+
150+ if (cur >= size) {
151+ u32 end = MT76_WED_WDS_CNT - 1;
152+
153+ i = min / 32;
154+ idx = ffs(~mask[i] & GENMASK(end, 0));
155+ if (!idx)
156+ goto error;
157+ idx--;
158+ cur = min + idx;
159+ }
160+
161 break;
162+ case MT76_WED_WDS_ACTIVE:
163+ if (cur < min)
164+ continue;
165+ if (cur >= max)
166+ goto error;
167+
168+ break;
169+ default:
170+ if (cur >= size)
171+ goto error;
172+ break;
173+ }
174
175 mask[i] |= BIT(idx);
176 return cur;
177 }
178
179+error:
180 return -1;
181 }
182-EXPORT_SYMBOL_GPL(mt76_wcid_alloc);
183+EXPORT_SYMBOL_GPL(__mt76_wcid_alloc);
184
185 int mt76_get_min_avg_rssi(struct mt76_dev *dev, bool ext_phy)
186 {
187diff --git a/util.h b/util.h
188index 260965dd..99b7263c 100644
189--- a/util.h
190+++ b/util.h
191@@ -27,7 +27,12 @@ enum {
192 #define MT76_INCR(_var, _size) \
193 (_var = (((_var) + 1) % (_size)))
194
195-int mt76_wcid_alloc(u32 *mask, int size);
196+int __mt76_wcid_alloc(u32 *mask, int size, u8 flags);
197+
198+static inline int mt76_wcid_alloc(u32 *mask, int size)
199+{
200+ return __mt76_wcid_alloc(mask, size, 0);
201+}
202
203 static inline void
204 mt76_wcid_mask_set(u32 *mask, int idx)
205--
2062.18.0
207