21a4e0759f0b90c469330f8b427a832df793e55d
[openwrt/staging/xback.git] /
1 From: Sujuan Chen <sujuan.chen@mediatek.com>
2 Date: Mon, 18 Sep 2023 12:29:15 +0200
3 Subject: [PATCH] net: ethernet: mtk_wed: introduce partial AMSDU offload
4 support for MT7988
5
6 Introduce partial AMSDU offload support for MT7988 SoC in order to merge
7 in hw packets belonging to the same AMSDU before passing them to the
8 WLAN nic.
9
10 Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
11 Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
12 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
13 Signed-off-by: Paolo Abeni <pabeni@redhat.com>
14 ---
15
16 --- a/drivers/net/ethernet/mediatek/mtk_ppe.c
17 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
18 @@ -438,7 +438,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_e
19 }
20
21 int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry,
22 - int wdma_idx, int txq, int bss, int wcid)
23 + int wdma_idx, int txq, int bss, int wcid,
24 + bool amsdu_en)
25 {
26 struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry);
27 u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
28 @@ -450,6 +451,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et
29 MTK_FOE_IB2_WDMA_WINFO_V2;
30 l2->w3info = FIELD_PREP(MTK_FOE_WINFO_WCID_V3, wcid) |
31 FIELD_PREP(MTK_FOE_WINFO_BSS_V3, bss);
32 + l2->amsdu = FIELD_PREP(MTK_FOE_WINFO_AMSDU_EN, amsdu_en);
33 break;
34 case 2:
35 *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2;
36 --- a/drivers/net/ethernet/mediatek/mtk_ppe.h
37 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
38 @@ -88,13 +88,13 @@ enum {
39 #define MTK_FOE_WINFO_BSS_V3 GENMASK(23, 16)
40 #define MTK_FOE_WINFO_WCID_V3 GENMASK(15, 0)
41
42 -#define MTK_FOE_WINFO_PAO_USR_INFO GENMASK(15, 0)
43 -#define MTK_FOE_WINFO_PAO_TID GENMASK(19, 16)
44 -#define MTK_FOE_WINFO_PAO_IS_FIXEDRATE BIT(20)
45 -#define MTK_FOE_WINFO_PAO_IS_PRIOR BIT(21)
46 -#define MTK_FOE_WINFO_PAO_IS_SP BIT(22)
47 -#define MTK_FOE_WINFO_PAO_HF BIT(23)
48 -#define MTK_FOE_WINFO_PAO_AMSDU_EN BIT(24)
49 +#define MTK_FOE_WINFO_AMSDU_USR_INFO GENMASK(15, 0)
50 +#define MTK_FOE_WINFO_AMSDU_TID GENMASK(19, 16)
51 +#define MTK_FOE_WINFO_AMSDU_IS_FIXEDRATE BIT(20)
52 +#define MTK_FOE_WINFO_AMSDU_IS_PRIOR BIT(21)
53 +#define MTK_FOE_WINFO_AMSDU_IS_SP BIT(22)
54 +#define MTK_FOE_WINFO_AMSDU_HF BIT(23)
55 +#define MTK_FOE_WINFO_AMSDU_EN BIT(24)
56
57 enum {
58 MTK_FOE_STATE_INVALID,
59 @@ -123,7 +123,7 @@ struct mtk_foe_mac_info {
60
61 /* netsys_v3 */
62 u32 w3info;
63 - u32 wpao;
64 + u32 amsdu;
65 };
66
67 /* software-only entry type */
68 @@ -393,7 +393,8 @@ int mtk_foe_entry_set_vlan(struct mtk_et
69 int mtk_foe_entry_set_pppoe(struct mtk_eth *eth, struct mtk_foe_entry *entry,
70 int sid);
71 int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry,
72 - int wdma_idx, int txq, int bss, int wcid);
73 + int wdma_idx, int txq, int bss, int wcid,
74 + bool amsdu_en);
75 int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry,
76 unsigned int queue);
77 int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
78 --- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
79 +++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
80 @@ -111,6 +111,7 @@ mtk_flow_get_wdma_info(struct net_device
81 info->queue = path->mtk_wdma.queue;
82 info->bss = path->mtk_wdma.bss;
83 info->wcid = path->mtk_wdma.wcid;
84 + info->amsdu = path->mtk_wdma.amsdu;
85
86 return 0;
87 }
88 @@ -192,7 +193,7 @@ mtk_flow_set_output_device(struct mtk_et
89
90 if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) {
91 mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue,
92 - info.bss, info.wcid);
93 + info.bss, info.wcid, info.amsdu);
94 if (mtk_is_netsys_v2_or_greater(eth)) {
95 switch (info.wdma_idx) {
96 case 0:
97 --- a/drivers/net/ethernet/mediatek/mtk_wed.c
98 +++ b/drivers/net/ethernet/mediatek/mtk_wed.c
99 @@ -29,6 +29,8 @@
100 #define MTK_WED_RX_PAGE_BUF_PER_PAGE (PAGE_SIZE / 128)
101 #define MTK_WED_RX_RING_SIZE 1536
102 #define MTK_WED_RX_PG_BM_CNT 8192
103 +#define MTK_WED_AMSDU_BUF_SIZE (PAGE_SIZE << 4)
104 +#define MTK_WED_AMSDU_NPAGES 32
105
106 #define MTK_WED_TX_RING_SIZE 2048
107 #define MTK_WED_WDMA_RING_SIZE 1024
108 @@ -172,6 +174,23 @@ mtk_wdma_rx_reset(struct mtk_wed_device
109 return ret;
110 }
111
112 +static u32
113 +mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
114 +{
115 + return !!(wed_r32(dev, reg) & mask);
116 +}
117 +
118 +static int
119 +mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
120 +{
121 + int sleep = 15000;
122 + int timeout = 100 * sleep;
123 + u32 val;
124 +
125 + return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep,
126 + timeout, false, dev, reg, mask);
127 +}
128 +
129 static void
130 mtk_wdma_tx_reset(struct mtk_wed_device *dev)
131 {
132 @@ -335,6 +354,118 @@ out:
133 }
134
135 static int
136 +mtk_wed_amsdu_buffer_alloc(struct mtk_wed_device *dev)
137 +{
138 + struct mtk_wed_hw *hw = dev->hw;
139 + struct mtk_wed_amsdu *wed_amsdu;
140 + int i;
141 +
142 + if (!mtk_wed_is_v3_or_greater(hw))
143 + return 0;
144 +
145 + wed_amsdu = devm_kcalloc(hw->dev, MTK_WED_AMSDU_NPAGES,
146 + sizeof(*wed_amsdu), GFP_KERNEL);
147 + if (!wed_amsdu)
148 + return -ENOMEM;
149 +
150 + for (i = 0; i < MTK_WED_AMSDU_NPAGES; i++) {
151 + void *ptr;
152 +
153 + /* each segment is 64K */
154 + ptr = (void *)__get_free_pages(GFP_KERNEL | __GFP_NOWARN |
155 + __GFP_ZERO | __GFP_COMP |
156 + GFP_DMA32,
157 + get_order(MTK_WED_AMSDU_BUF_SIZE));
158 + if (!ptr)
159 + goto error;
160 +
161 + wed_amsdu[i].txd = ptr;
162 + wed_amsdu[i].txd_phy = dma_map_single(hw->dev, ptr,
163 + MTK_WED_AMSDU_BUF_SIZE,
164 + DMA_TO_DEVICE);
165 + if (dma_mapping_error(hw->dev, wed_amsdu[i].txd_phy))
166 + goto error;
167 + }
168 + dev->hw->wed_amsdu = wed_amsdu;
169 +
170 + return 0;
171 +
172 +error:
173 + for (i--; i >= 0; i--)
174 + dma_unmap_single(hw->dev, wed_amsdu[i].txd_phy,
175 + MTK_WED_AMSDU_BUF_SIZE, DMA_TO_DEVICE);
176 + return -ENOMEM;
177 +}
178 +
179 +static void
180 +mtk_wed_amsdu_free_buffer(struct mtk_wed_device *dev)
181 +{
182 + struct mtk_wed_amsdu *wed_amsdu = dev->hw->wed_amsdu;
183 + int i;
184 +
185 + if (!wed_amsdu)
186 + return;
187 +
188 + for (i = 0; i < MTK_WED_AMSDU_NPAGES; i++) {
189 + dma_unmap_single(dev->hw->dev, wed_amsdu[i].txd_phy,
190 + MTK_WED_AMSDU_BUF_SIZE, DMA_TO_DEVICE);
191 + free_pages((unsigned long)wed_amsdu[i].txd,
192 + get_order(MTK_WED_AMSDU_BUF_SIZE));
193 + }
194 +}
195 +
196 +static int
197 +mtk_wed_amsdu_init(struct mtk_wed_device *dev)
198 +{
199 + struct mtk_wed_amsdu *wed_amsdu = dev->hw->wed_amsdu;
200 + int i, ret;
201 +
202 + if (!wed_amsdu)
203 + return 0;
204 +
205 + for (i = 0; i < MTK_WED_AMSDU_NPAGES; i++)
206 + wed_w32(dev, MTK_WED_AMSDU_HIFTXD_BASE_L(i),
207 + wed_amsdu[i].txd_phy);
208 +
209 + /* init all sta parameter */
210 + wed_w32(dev, MTK_WED_AMSDU_STA_INFO_INIT, MTK_WED_AMSDU_STA_RMVL |
211 + MTK_WED_AMSDU_STA_WTBL_HDRT_MODE |
212 + FIELD_PREP(MTK_WED_AMSDU_STA_MAX_AMSDU_LEN,
213 + dev->wlan.amsdu_max_len >> 8) |
214 + FIELD_PREP(MTK_WED_AMSDU_STA_MAX_AMSDU_NUM,
215 + dev->wlan.amsdu_max_subframes));
216 +
217 + wed_w32(dev, MTK_WED_AMSDU_STA_INFO, MTK_WED_AMSDU_STA_INFO_DO_INIT);
218 +
219 + ret = mtk_wed_poll_busy(dev, MTK_WED_AMSDU_STA_INFO,
220 + MTK_WED_AMSDU_STA_INFO_DO_INIT);
221 + if (ret) {
222 + dev_err(dev->hw->dev, "amsdu initialization failed\n");
223 + return ret;
224 + }
225 +
226 + /* init partial amsdu offload txd src */
227 + wed_set(dev, MTK_WED_AMSDU_HIFTXD_CFG,
228 + FIELD_PREP(MTK_WED_AMSDU_HIFTXD_SRC, dev->hw->index));
229 +
230 + /* init qmem */
231 + wed_set(dev, MTK_WED_AMSDU_PSE, MTK_WED_AMSDU_PSE_RESET);
232 + ret = mtk_wed_poll_busy(dev, MTK_WED_MON_AMSDU_QMEM_STS1, BIT(29));
233 + if (ret) {
234 + pr_info("%s: amsdu qmem initialization failed\n", __func__);
235 + return ret;
236 + }
237 +
238 + /* eagle E1 PCIE1 tx ring 22 flow control issue */
239 + if (dev->wlan.id == 0x7991)
240 + wed_clr(dev, MTK_WED_AMSDU_FIFO, MTK_WED_AMSDU_IS_PRIOR0_RING);
241 +
242 + wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_AMSDU_EN);
243 +
244 + return 0;
245 +}
246 +
247 +static int
248 mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev)
249 {
250 u32 desc_size = dev->hw->soc->tx_ring_desc_size;
251 @@ -708,6 +839,7 @@ __mtk_wed_detach(struct mtk_wed_device *
252
253 mtk_wdma_rx_reset(dev);
254 mtk_wed_reset(dev, MTK_WED_RESET_WED);
255 + mtk_wed_amsdu_free_buffer(dev);
256 mtk_wed_free_tx_buffer(dev);
257 mtk_wed_free_tx_rings(dev);
258
259 @@ -1128,23 +1260,6 @@ mtk_wed_ring_reset(struct mtk_wed_ring *
260 }
261 }
262
263 -static u32
264 -mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
265 -{
266 - return !!(wed_r32(dev, reg) & mask);
267 -}
268 -
269 -static int
270 -mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
271 -{
272 - int sleep = 15000;
273 - int timeout = 100 * sleep;
274 - u32 val;
275 -
276 - return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep,
277 - timeout, false, dev, reg, mask);
278 -}
279 -
280 static int
281 mtk_wed_rx_reset(struct mtk_wed_device *dev)
282 {
283 @@ -1691,6 +1806,7 @@ mtk_wed_start(struct mtk_wed_device *dev
284 }
285
286 mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
287 + mtk_wed_amsdu_init(dev);
288
289 mtk_wed_dma_enable(dev);
290 dev->running = true;
291 @@ -1747,6 +1863,10 @@ mtk_wed_attach(struct mtk_wed_device *de
292 if (ret)
293 goto out;
294
295 + ret = mtk_wed_amsdu_buffer_alloc(dev);
296 + if (ret)
297 + goto out;
298 +
299 if (mtk_wed_get_rx_capa(dev)) {
300 ret = mtk_wed_rro_alloc(dev);
301 if (ret)
302 --- a/drivers/net/ethernet/mediatek/mtk_wed.h
303 +++ b/drivers/net/ethernet/mediatek/mtk_wed.h
304 @@ -25,6 +25,11 @@ struct mtk_wed_soc_data {
305 u32 wdma_desc_size;
306 };
307
308 +struct mtk_wed_amsdu {
309 + void *txd;
310 + dma_addr_t txd_phy;
311 +};
312 +
313 struct mtk_wed_hw {
314 const struct mtk_wed_soc_data *soc;
315 struct device_node *node;
316 @@ -38,6 +43,7 @@ struct mtk_wed_hw {
317 struct dentry *debugfs_dir;
318 struct mtk_wed_device *wed_dev;
319 struct mtk_wed_wo *wed_wo;
320 + struct mtk_wed_amsdu *wed_amsdu;
321 u32 pcie_base;
322 u32 debugfs_reg;
323 u32 num_flows;
324 @@ -52,6 +58,7 @@ struct mtk_wdma_info {
325 u8 queue;
326 u16 wcid;
327 u8 bss;
328 + u8 amsdu;
329 };
330
331 #ifdef CONFIG_NET_MEDIATEK_SOC_WED
332 --- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
333 +++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
334 @@ -672,6 +672,82 @@ struct mtk_wdma_desc {
335 #define MTK_WED_WOCPU_VIEW_MIOD_BASE 0x8000
336 #define MTK_WED_PCIE_INT_MASK 0x0
337
338 +#define MTK_WED_AMSDU_FIFO 0x1800
339 +#define MTK_WED_AMSDU_IS_PRIOR0_RING BIT(10)
340 +
341 +#define MTK_WED_AMSDU_STA_INFO 0x01810
342 +#define MTK_WED_AMSDU_STA_INFO_DO_INIT BIT(0)
343 +#define MTK_WED_AMSDU_STA_INFO_SET_INIT BIT(1)
344 +
345 +#define MTK_WED_AMSDU_STA_INFO_INIT 0x01814
346 +#define MTK_WED_AMSDU_STA_WTBL_HDRT_MODE BIT(0)
347 +#define MTK_WED_AMSDU_STA_RMVL BIT(1)
348 +#define MTK_WED_AMSDU_STA_MAX_AMSDU_LEN GENMASK(7, 2)
349 +#define MTK_WED_AMSDU_STA_MAX_AMSDU_NUM GENMASK(11, 8)
350 +
351 +#define MTK_WED_AMSDU_HIFTXD_BASE_L(_n) (0x1980 + (_n) * 0x4)
352 +
353 +#define MTK_WED_AMSDU_PSE 0x1910
354 +#define MTK_WED_AMSDU_PSE_RESET BIT(16)
355 +
356 +#define MTK_WED_AMSDU_HIFTXD_CFG 0x1968
357 +#define MTK_WED_AMSDU_HIFTXD_SRC GENMASK(16, 15)
358 +
359 +#define MTK_WED_MON_AMSDU_FIFO_DMAD 0x1a34
360 +
361 +#define MTK_WED_MON_AMSDU_ENG_DMAD(_n) (0x1a80 + (_n) * 0x50)
362 +#define MTK_WED_MON_AMSDU_ENG_QFPL(_n) (0x1a84 + (_n) * 0x50)
363 +#define MTK_WED_MON_AMSDU_ENG_QENI(_n) (0x1a88 + (_n) * 0x50)
364 +#define MTK_WED_MON_AMSDU_ENG_QENO(_n) (0x1a8c + (_n) * 0x50)
365 +#define MTK_WED_MON_AMSDU_ENG_MERG(_n) (0x1a90 + (_n) * 0x50)
366 +
367 +#define MTK_WED_MON_AMSDU_ENG_CNT8(_n) (0x1a94 + (_n) * 0x50)
368 +#define MTK_WED_AMSDU_ENG_MAX_QGPP_CNT GENMASK(10, 0)
369 +#define MTK_WED_AMSDU_ENG_MAX_PL_CNT GENMASK(27, 16)
370 +
371 +#define MTK_WED_MON_AMSDU_ENG_CNT9(_n) (0x1a98 + (_n) * 0x50)
372 +#define MTK_WED_AMSDU_ENG_CUR_ENTRY GENMASK(10, 0)
373 +#define MTK_WED_AMSDU_ENG_MAX_BUF_MERGED GENMASK(20, 16)
374 +#define MTK_WED_AMSDU_ENG_MAX_MSDU_MERGED GENMASK(28, 24)
375 +
376 +#define MTK_WED_MON_AMSDU_QMEM_STS1 0x1e04
377 +
378 +#define MTK_WED_MON_AMSDU_QMEM_CNT(_n) (0x1e0c + (_n) * 0x4)
379 +#define MTK_WED_AMSDU_QMEM_FQ_CNT GENMASK(27, 16)
380 +#define MTK_WED_AMSDU_QMEM_SP_QCNT GENMASK(11, 0)
381 +#define MTK_WED_AMSDU_QMEM_TID0_QCNT GENMASK(27, 16)
382 +#define MTK_WED_AMSDU_QMEM_TID1_QCNT GENMASK(11, 0)
383 +#define MTK_WED_AMSDU_QMEM_TID2_QCNT GENMASK(27, 16)
384 +#define MTK_WED_AMSDU_QMEM_TID3_QCNT GENMASK(11, 0)
385 +#define MTK_WED_AMSDU_QMEM_TID4_QCNT GENMASK(27, 16)
386 +#define MTK_WED_AMSDU_QMEM_TID5_QCNT GENMASK(11, 0)
387 +#define MTK_WED_AMSDU_QMEM_TID6_QCNT GENMASK(27, 16)
388 +#define MTK_WED_AMSDU_QMEM_TID7_QCNT GENMASK(11, 0)
389 +
390 +#define MTK_WED_MON_AMSDU_QMEM_PTR(_n) (0x1e20 + (_n) * 0x4)
391 +#define MTK_WED_AMSDU_QMEM_FQ_HEAD GENMASK(27, 16)
392 +#define MTK_WED_AMSDU_QMEM_SP_QHEAD GENMASK(11, 0)
393 +#define MTK_WED_AMSDU_QMEM_TID0_QHEAD GENMASK(27, 16)
394 +#define MTK_WED_AMSDU_QMEM_TID1_QHEAD GENMASK(11, 0)
395 +#define MTK_WED_AMSDU_QMEM_TID2_QHEAD GENMASK(27, 16)
396 +#define MTK_WED_AMSDU_QMEM_TID3_QHEAD GENMASK(11, 0)
397 +#define MTK_WED_AMSDU_QMEM_TID4_QHEAD GENMASK(27, 16)
398 +#define MTK_WED_AMSDU_QMEM_TID5_QHEAD GENMASK(11, 0)
399 +#define MTK_WED_AMSDU_QMEM_TID6_QHEAD GENMASK(27, 16)
400 +#define MTK_WED_AMSDU_QMEM_TID7_QHEAD GENMASK(11, 0)
401 +#define MTK_WED_AMSDU_QMEM_FQ_TAIL GENMASK(27, 16)
402 +#define MTK_WED_AMSDU_QMEM_SP_QTAIL GENMASK(11, 0)
403 +#define MTK_WED_AMSDU_QMEM_TID0_QTAIL GENMASK(27, 16)
404 +#define MTK_WED_AMSDU_QMEM_TID1_QTAIL GENMASK(11, 0)
405 +#define MTK_WED_AMSDU_QMEM_TID2_QTAIL GENMASK(27, 16)
406 +#define MTK_WED_AMSDU_QMEM_TID3_QTAIL GENMASK(11, 0)
407 +#define MTK_WED_AMSDU_QMEM_TID4_QTAIL GENMASK(27, 16)
408 +#define MTK_WED_AMSDU_QMEM_TID5_QTAIL GENMASK(11, 0)
409 +#define MTK_WED_AMSDU_QMEM_TID6_QTAIL GENMASK(27, 16)
410 +#define MTK_WED_AMSDU_QMEM_TID7_QTAIL GENMASK(11, 0)
411 +
412 +#define MTK_WED_MON_AMSDU_HIFTXD_FETCH_MSDU(_n) (0x1ec4 + (_n) * 0x4)
413 +
414 #define MTK_WED_PCIE_BASE 0x11280000
415 #define MTK_WED_PCIE_BASE0 0x11300000
416 #define MTK_WED_PCIE_BASE1 0x11310000
417 --- a/include/linux/netdevice.h
418 +++ b/include/linux/netdevice.h
419 @@ -906,6 +906,7 @@ struct net_device_path {
420 u8 queue;
421 u16 wcid;
422 u8 bss;
423 + u8 amsdu;
424 } mtk_wdma;
425 };
426 };
427 --- a/include/linux/soc/mediatek/mtk_wed.h
428 +++ b/include/linux/soc/mediatek/mtk_wed.h
429 @@ -129,6 +129,7 @@ struct mtk_wed_device {
430 enum mtk_wed_bus_tye bus_type;
431 void __iomem *base;
432 u32 phy_base;
433 + u32 id;
434
435 u32 wpdma_phys;
436 u32 wpdma_int;
437 @@ -147,10 +148,12 @@ struct mtk_wed_device {
438 unsigned int rx_nbuf;
439 unsigned int rx_npkt;
440 unsigned int rx_size;
441 + unsigned int amsdu_max_len;
442
443 u8 tx_tbit[MTK_WED_TX_QUEUES];
444 u8 rx_tbit[MTK_WED_RX_QUEUES];
445 u8 txfree_tbit;
446 + u8 amsdu_max_subframes;
447
448 u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id);
449 int (*offload_enable)(struct mtk_wed_device *wed);
450 @@ -224,6 +227,15 @@ static inline bool mtk_wed_get_rx_capa(s
451 #else
452 return false;
453 #endif
454 +}
455 +
456 +static inline bool mtk_wed_is_amsdu_supported(struct mtk_wed_device *dev)
457 +{
458 +#ifdef CONFIG_NET_MEDIATEK_SOC_WED
459 + return dev->version == 3;
460 +#else
461 + return false;
462 +#endif
463 }
464
465 #ifdef CONFIG_NET_MEDIATEK_SOC_WED