16c92544dSBjoern A. Zeeb // SPDX-License-Identifier: ISC 26c92544dSBjoern A. Zeeb /* Copyright (C) 2019 MediaTek Inc. 36c92544dSBjoern A. Zeeb * 46c92544dSBjoern A. Zeeb * Author: Ryder Lee <ryder.lee@mediatek.com> 56c92544dSBjoern A. Zeeb * Roy Luo <royluo@google.com> 66c92544dSBjoern A. Zeeb * Lorenzo Bianconi <lorenzo@kernel.org> 76c92544dSBjoern A. Zeeb * Felix Fietkau <nbd@nbd.name> 86c92544dSBjoern A. Zeeb */ 96c92544dSBjoern A. Zeeb 106c92544dSBjoern A. Zeeb #include "mt7615.h" 116c92544dSBjoern A. Zeeb #include "../dma.h" 126c92544dSBjoern A. Zeeb #include "mac.h" 136c92544dSBjoern A. Zeeb 146c92544dSBjoern A. Zeeb static int 156c92544dSBjoern A. Zeeb mt7622_init_tx_queues_multi(struct mt7615_dev *dev) 166c92544dSBjoern A. Zeeb { 176c92544dSBjoern A. Zeeb static const u8 wmm_queue_map[] = { 186c92544dSBjoern A. Zeeb [IEEE80211_AC_BK] = MT7622_TXQ_AC0, 196c92544dSBjoern A. Zeeb [IEEE80211_AC_BE] = MT7622_TXQ_AC1, 206c92544dSBjoern A. Zeeb [IEEE80211_AC_VI] = MT7622_TXQ_AC2, 216c92544dSBjoern A. Zeeb [IEEE80211_AC_VO] = MT7622_TXQ_AC3, 226c92544dSBjoern A. Zeeb }; 236c92544dSBjoern A. Zeeb int ret; 246c92544dSBjoern A. Zeeb int i; 256c92544dSBjoern A. Zeeb 266c92544dSBjoern A. Zeeb for (i = 0; i < ARRAY_SIZE(wmm_queue_map); i++) { 276c92544dSBjoern A. Zeeb ret = mt76_init_tx_queue(&dev->mphy, i, wmm_queue_map[i], 286c92544dSBjoern A. Zeeb MT7615_TX_RING_SIZE / 2, 296c92544dSBjoern A. Zeeb MT_TX_RING_BASE, 0); 306c92544dSBjoern A. Zeeb if (ret) 316c92544dSBjoern A. Zeeb return ret; 326c92544dSBjoern A. Zeeb } 336c92544dSBjoern A. Zeeb 346c92544dSBjoern A. Zeeb ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_PSD, MT7622_TXQ_MGMT, 356c92544dSBjoern A. Zeeb MT7615_TX_MGMT_RING_SIZE, 366c92544dSBjoern A. Zeeb MT_TX_RING_BASE, 0); 376c92544dSBjoern A. Zeeb if (ret) 386c92544dSBjoern A. Zeeb return ret; 396c92544dSBjoern A. Zeeb 406c92544dSBjoern A. Zeeb return mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WM, MT7622_TXQ_MCU, 416c92544dSBjoern A. Zeeb MT7615_TX_MCU_RING_SIZE, MT_TX_RING_BASE); 426c92544dSBjoern A. Zeeb } 436c92544dSBjoern A. Zeeb 446c92544dSBjoern A. Zeeb static int 456c92544dSBjoern A. Zeeb mt7615_init_tx_queues(struct mt7615_dev *dev) 466c92544dSBjoern A. Zeeb { 476c92544dSBjoern A. Zeeb int ret; 486c92544dSBjoern A. Zeeb 496c92544dSBjoern A. Zeeb ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_FWDL, MT7615_TXQ_FWDL, 506c92544dSBjoern A. Zeeb MT7615_TX_FWDL_RING_SIZE, MT_TX_RING_BASE); 516c92544dSBjoern A. Zeeb if (ret) 526c92544dSBjoern A. Zeeb return ret; 536c92544dSBjoern A. Zeeb 546c92544dSBjoern A. Zeeb if (!is_mt7615(&dev->mt76)) 556c92544dSBjoern A. Zeeb return mt7622_init_tx_queues_multi(dev); 566c92544dSBjoern A. Zeeb 576c92544dSBjoern A. Zeeb ret = mt76_connac_init_tx_queues(&dev->mphy, 0, MT7615_TX_RING_SIZE, 586c92544dSBjoern A. Zeeb MT_TX_RING_BASE, 0); 596c92544dSBjoern A. Zeeb if (ret) 606c92544dSBjoern A. Zeeb return ret; 616c92544dSBjoern A. Zeeb 626c92544dSBjoern A. Zeeb return mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WM, MT7615_TXQ_MCU, 636c92544dSBjoern A. Zeeb MT7615_TX_MCU_RING_SIZE, MT_TX_RING_BASE); 646c92544dSBjoern A. Zeeb } 656c92544dSBjoern A. Zeeb 666c92544dSBjoern A. Zeeb static int mt7615_poll_tx(struct napi_struct *napi, int budget) 676c92544dSBjoern A. Zeeb { 686c92544dSBjoern A. Zeeb struct mt7615_dev *dev; 696c92544dSBjoern A. Zeeb 706c92544dSBjoern A. Zeeb dev = container_of(napi, struct mt7615_dev, mt76.tx_napi); 716c92544dSBjoern A. Zeeb if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) { 726c92544dSBjoern A. Zeeb napi_complete(napi); 736c92544dSBjoern A. Zeeb queue_work(dev->mt76.wq, &dev->pm.wake_work); 746c92544dSBjoern A. Zeeb return 0; 756c92544dSBjoern A. Zeeb } 766c92544dSBjoern A. Zeeb 776c92544dSBjoern A. Zeeb mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WM], false); 786c92544dSBjoern A. Zeeb if (napi_complete(napi)) 79*cbb3ec25SBjoern A. Zeeb mt76_connac_irq_enable(&dev->mt76, 80*cbb3ec25SBjoern A. Zeeb mt7615_tx_mcu_int_mask(dev)); 816c92544dSBjoern A. Zeeb 826c92544dSBjoern A. Zeeb mt76_connac_pm_unref(&dev->mphy, &dev->pm); 836c92544dSBjoern A. Zeeb 846c92544dSBjoern A. Zeeb return 0; 856c92544dSBjoern A. Zeeb } 866c92544dSBjoern A. Zeeb 876c92544dSBjoern A. Zeeb static int mt7615_poll_rx(struct napi_struct *napi, int budget) 886c92544dSBjoern A. Zeeb { 896c92544dSBjoern A. Zeeb struct mt7615_dev *dev; 906c92544dSBjoern A. Zeeb int done; 916c92544dSBjoern A. Zeeb 926c92544dSBjoern A. Zeeb dev = container_of(napi->dev, struct mt7615_dev, mt76.napi_dev); 936c92544dSBjoern A. Zeeb 946c92544dSBjoern A. Zeeb if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) { 956c92544dSBjoern A. Zeeb napi_complete(napi); 966c92544dSBjoern A. Zeeb queue_work(dev->mt76.wq, &dev->pm.wake_work); 976c92544dSBjoern A. Zeeb return 0; 986c92544dSBjoern A. Zeeb } 996c92544dSBjoern A. Zeeb done = mt76_dma_rx_poll(napi, budget); 1006c92544dSBjoern A. Zeeb mt76_connac_pm_unref(&dev->mphy, &dev->pm); 1016c92544dSBjoern A. Zeeb 1026c92544dSBjoern A. Zeeb return done; 1036c92544dSBjoern A. Zeeb } 1046c92544dSBjoern A. Zeeb 1056c92544dSBjoern A. Zeeb int mt7615_wait_pdma_busy(struct mt7615_dev *dev) 1066c92544dSBjoern A. Zeeb { 1076c92544dSBjoern A. Zeeb struct mt76_dev *mdev = &dev->mt76; 1086c92544dSBjoern A. Zeeb 1096c92544dSBjoern A. Zeeb if (!is_mt7663(mdev)) { 1106c92544dSBjoern A. Zeeb u32 mask = MT_PDMA_TX_BUSY | MT_PDMA_RX_BUSY; 1116c92544dSBjoern A. Zeeb u32 reg = mt7615_reg_map(dev, MT_PDMA_BUSY); 1126c92544dSBjoern A. Zeeb 1136c92544dSBjoern A. Zeeb if (!mt76_poll_msec(dev, reg, mask, 0, 1000)) { 1146c92544dSBjoern A. Zeeb dev_err(mdev->dev, "PDMA engine busy\n"); 1156c92544dSBjoern A. Zeeb return -EIO; 1166c92544dSBjoern A. Zeeb } 1176c92544dSBjoern A. Zeeb 1186c92544dSBjoern A. Zeeb return 0; 1196c92544dSBjoern A. Zeeb } 1206c92544dSBjoern A. Zeeb 1216c92544dSBjoern A. Zeeb if (!mt76_poll_msec(dev, MT_PDMA_BUSY_STATUS, 1226c92544dSBjoern A. Zeeb MT_PDMA_TX_IDX_BUSY, 0, 1000)) { 1236c92544dSBjoern A. Zeeb dev_err(mdev->dev, "PDMA engine tx busy\n"); 1246c92544dSBjoern A. Zeeb return -EIO; 1256c92544dSBjoern A. Zeeb } 1266c92544dSBjoern A. Zeeb 1276c92544dSBjoern A. Zeeb if (!mt76_poll_msec(dev, MT_PSE_PG_INFO, 1286c92544dSBjoern A. Zeeb MT_PSE_SRC_CNT, 0, 1000)) { 1296c92544dSBjoern A. Zeeb dev_err(mdev->dev, "PSE engine busy\n"); 1306c92544dSBjoern A. Zeeb return -EIO; 1316c92544dSBjoern A. Zeeb } 1326c92544dSBjoern A. Zeeb 1336c92544dSBjoern A. Zeeb if (!mt76_poll_msec(dev, MT_PDMA_BUSY_STATUS, 1346c92544dSBjoern A. Zeeb MT_PDMA_BUSY_IDX, 0, 1000)) { 1356c92544dSBjoern A. Zeeb dev_err(mdev->dev, "PDMA engine busy\n"); 1366c92544dSBjoern A. Zeeb return -EIO; 1376c92544dSBjoern A. Zeeb } 1386c92544dSBjoern A. Zeeb 1396c92544dSBjoern A. Zeeb return 0; 1406c92544dSBjoern A. Zeeb } 1416c92544dSBjoern A. Zeeb 1426c92544dSBjoern A. Zeeb static void mt7622_dma_sched_init(struct mt7615_dev *dev) 1436c92544dSBjoern A. Zeeb { 1446c92544dSBjoern A. Zeeb u32 reg = mt7615_reg_map(dev, MT_DMASHDL_BASE); 1456c92544dSBjoern A. Zeeb int i; 1466c92544dSBjoern A. Zeeb 1476c92544dSBjoern A. Zeeb mt76_rmw(dev, reg + MT_DMASHDL_PKT_MAX_SIZE, 1486c92544dSBjoern A. Zeeb MT_DMASHDL_PKT_MAX_SIZE_PLE | MT_DMASHDL_PKT_MAX_SIZE_PSE, 1496c92544dSBjoern A. Zeeb FIELD_PREP(MT_DMASHDL_PKT_MAX_SIZE_PLE, 1) | 1506c92544dSBjoern A. Zeeb FIELD_PREP(MT_DMASHDL_PKT_MAX_SIZE_PSE, 8)); 1516c92544dSBjoern A. Zeeb 1526c92544dSBjoern A. Zeeb for (i = 0; i <= 5; i++) 1536c92544dSBjoern A. Zeeb mt76_wr(dev, reg + MT_DMASHDL_GROUP_QUOTA(i), 1546c92544dSBjoern A. Zeeb FIELD_PREP(MT_DMASHDL_GROUP_QUOTA_MIN, 0x10) | 1556c92544dSBjoern A. Zeeb FIELD_PREP(MT_DMASHDL_GROUP_QUOTA_MAX, 0x800)); 1566c92544dSBjoern A. Zeeb 1576c92544dSBjoern A. Zeeb mt76_wr(dev, reg + MT_DMASHDL_Q_MAP(0), 0x42104210); 1586c92544dSBjoern A. Zeeb mt76_wr(dev, reg + MT_DMASHDL_Q_MAP(1), 0x42104210); 1596c92544dSBjoern A. Zeeb mt76_wr(dev, reg + MT_DMASHDL_Q_MAP(2), 0x5); 1606c92544dSBjoern A. Zeeb mt76_wr(dev, reg + MT_DMASHDL_Q_MAP(3), 0); 1616c92544dSBjoern A. Zeeb 1626c92544dSBjoern A. Zeeb mt76_wr(dev, reg + MT_DMASHDL_SCHED_SET0, 0x6012345f); 1636c92544dSBjoern A. Zeeb mt76_wr(dev, reg + MT_DMASHDL_SCHED_SET1, 0xedcba987); 1646c92544dSBjoern A. Zeeb } 1656c92544dSBjoern A. Zeeb 1666c92544dSBjoern A. Zeeb static void mt7663_dma_sched_init(struct mt7615_dev *dev) 1676c92544dSBjoern A. Zeeb { 1686c92544dSBjoern A. Zeeb int i; 1696c92544dSBjoern A. Zeeb 1706c92544dSBjoern A. Zeeb mt76_rmw(dev, MT_DMA_SHDL(MT_DMASHDL_PKT_MAX_SIZE), 1716c92544dSBjoern A. Zeeb MT_DMASHDL_PKT_MAX_SIZE_PLE | MT_DMASHDL_PKT_MAX_SIZE_PSE, 1726c92544dSBjoern A. Zeeb FIELD_PREP(MT_DMASHDL_PKT_MAX_SIZE_PLE, 1) | 1736c92544dSBjoern A. Zeeb FIELD_PREP(MT_DMASHDL_PKT_MAX_SIZE_PSE, 8)); 1746c92544dSBjoern A. Zeeb 1756c92544dSBjoern A. Zeeb /* enable refill control group 0, 1, 2, 4, 5 */ 1766c92544dSBjoern A. Zeeb mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_REFILL), 0xffc80000); 1776c92544dSBjoern A. Zeeb /* enable group 0, 1, 2, 4, 5, 15 */ 1786c92544dSBjoern A. Zeeb mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_OPTIONAL), 0x70068037); 1796c92544dSBjoern A. Zeeb 1806c92544dSBjoern A. Zeeb /* each group min quota must larger then PLE_PKT_MAX_SIZE_NUM */ 1816c92544dSBjoern A. Zeeb for (i = 0; i < 5; i++) 1826c92544dSBjoern A. Zeeb mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_GROUP_QUOTA(i)), 1836c92544dSBjoern A. Zeeb FIELD_PREP(MT_DMASHDL_GROUP_QUOTA_MIN, 0x40) | 1846c92544dSBjoern A. Zeeb FIELD_PREP(MT_DMASHDL_GROUP_QUOTA_MAX, 0x800)); 1856c92544dSBjoern A. Zeeb mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_GROUP_QUOTA(5)), 1866c92544dSBjoern A. Zeeb FIELD_PREP(MT_DMASHDL_GROUP_QUOTA_MIN, 0x40) | 1876c92544dSBjoern A. Zeeb FIELD_PREP(MT_DMASHDL_GROUP_QUOTA_MAX, 0x40)); 1886c92544dSBjoern A. Zeeb mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_GROUP_QUOTA(15)), 1896c92544dSBjoern A. Zeeb FIELD_PREP(MT_DMASHDL_GROUP_QUOTA_MIN, 0x20) | 1906c92544dSBjoern A. Zeeb FIELD_PREP(MT_DMASHDL_GROUP_QUOTA_MAX, 0x20)); 1916c92544dSBjoern A. Zeeb 1926c92544dSBjoern A. Zeeb mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_Q_MAP(0)), 0x42104210); 1936c92544dSBjoern A. Zeeb mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_Q_MAP(1)), 0x42104210); 1946c92544dSBjoern A. Zeeb mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_Q_MAP(2)), 0x00050005); 1956c92544dSBjoern A. Zeeb mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_Q_MAP(3)), 0); 1966c92544dSBjoern A. Zeeb /* ALTX0 and ALTX1 QID mapping to group 5 */ 1976c92544dSBjoern A. Zeeb mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_SCHED_SET0), 0x6012345f); 1986c92544dSBjoern A. Zeeb mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_SCHED_SET1), 0xedcba987); 1996c92544dSBjoern A. Zeeb } 2006c92544dSBjoern A. Zeeb 2016c92544dSBjoern A. Zeeb void mt7615_dma_start(struct mt7615_dev *dev) 2026c92544dSBjoern A. Zeeb { 2036c92544dSBjoern A. Zeeb /* start dma engine */ 2046c92544dSBjoern A. Zeeb mt76_set(dev, MT_WPDMA_GLO_CFG, 2056c92544dSBjoern A. Zeeb MT_WPDMA_GLO_CFG_TX_DMA_EN | 2066c92544dSBjoern A. Zeeb MT_WPDMA_GLO_CFG_RX_DMA_EN | 2076c92544dSBjoern A. Zeeb MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE); 2086c92544dSBjoern A. Zeeb 2096c92544dSBjoern A. Zeeb if (is_mt7622(&dev->mt76)) 2106c92544dSBjoern A. Zeeb mt7622_dma_sched_init(dev); 2116c92544dSBjoern A. Zeeb 2126c92544dSBjoern A. Zeeb if (is_mt7663(&dev->mt76)) { 2136c92544dSBjoern A. Zeeb mt7663_dma_sched_init(dev); 2146c92544dSBjoern A. Zeeb 2156c92544dSBjoern A. Zeeb mt76_wr(dev, MT_MCU2HOST_INT_ENABLE, MT7663_MCU_CMD_ERROR_MASK); 2166c92544dSBjoern A. Zeeb } 2176c92544dSBjoern A. Zeeb 2186c92544dSBjoern A. Zeeb } 2196c92544dSBjoern A. Zeeb 2206c92544dSBjoern A. Zeeb int mt7615_dma_init(struct mt7615_dev *dev) 2216c92544dSBjoern A. Zeeb { 2226c92544dSBjoern A. Zeeb int rx_ring_size = MT7615_RX_RING_SIZE; 2236c92544dSBjoern A. Zeeb u32 mask; 2246c92544dSBjoern A. Zeeb int ret; 2256c92544dSBjoern A. Zeeb 2266c92544dSBjoern A. Zeeb mt76_dma_attach(&dev->mt76); 2276c92544dSBjoern A. Zeeb 2286c92544dSBjoern A. Zeeb mt76_wr(dev, MT_WPDMA_GLO_CFG, 2296c92544dSBjoern A. Zeeb MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE | 2306c92544dSBjoern A. Zeeb MT_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN | 2316c92544dSBjoern A. Zeeb MT_WPDMA_GLO_CFG_OMIT_TX_INFO); 2326c92544dSBjoern A. Zeeb 2336c92544dSBjoern A. Zeeb mt76_rmw_field(dev, MT_WPDMA_GLO_CFG, 2346c92544dSBjoern A. Zeeb MT_WPDMA_GLO_CFG_TX_BT_SIZE_BIT0, 0x1); 2356c92544dSBjoern A. Zeeb 2366c92544dSBjoern A. Zeeb mt76_rmw_field(dev, MT_WPDMA_GLO_CFG, 2376c92544dSBjoern A. Zeeb MT_WPDMA_GLO_CFG_TX_BT_SIZE_BIT21, 0x1); 2386c92544dSBjoern A. Zeeb 2396c92544dSBjoern A. Zeeb mt76_rmw_field(dev, MT_WPDMA_GLO_CFG, 2406c92544dSBjoern A. Zeeb MT_WPDMA_GLO_CFG_DMA_BURST_SIZE, 0x3); 2416c92544dSBjoern A. Zeeb 2426c92544dSBjoern A. Zeeb mt76_rmw_field(dev, MT_WPDMA_GLO_CFG, 2436c92544dSBjoern A. Zeeb MT_WPDMA_GLO_CFG_MULTI_DMA_EN, 0x3); 2446c92544dSBjoern A. Zeeb 2456c92544dSBjoern A. Zeeb if (is_mt7615(&dev->mt76)) { 2466c92544dSBjoern A. Zeeb mt76_set(dev, MT_WPDMA_GLO_CFG, 2476c92544dSBjoern A. Zeeb MT_WPDMA_GLO_CFG_FIRST_TOKEN_ONLY); 2486c92544dSBjoern A. Zeeb 2496c92544dSBjoern A. Zeeb mt76_wr(dev, MT_WPDMA_GLO_CFG1, 0x1); 2506c92544dSBjoern A. Zeeb mt76_wr(dev, MT_WPDMA_TX_PRE_CFG, 0xf0000); 2516c92544dSBjoern A. Zeeb mt76_wr(dev, MT_WPDMA_RX_PRE_CFG, 0xf7f0000); 2526c92544dSBjoern A. Zeeb mt76_wr(dev, MT_WPDMA_ABT_CFG, 0x4000026); 2536c92544dSBjoern A. Zeeb mt76_wr(dev, MT_WPDMA_ABT_CFG1, 0x18811881); 2546c92544dSBjoern A. Zeeb mt76_set(dev, 0x7158, BIT(16)); 2556c92544dSBjoern A. Zeeb mt76_clear(dev, 0x7000, BIT(23)); 2566c92544dSBjoern A. Zeeb } 2576c92544dSBjoern A. Zeeb 2586c92544dSBjoern A. Zeeb mt76_wr(dev, MT_WPDMA_RST_IDX, ~0); 2596c92544dSBjoern A. Zeeb 2606c92544dSBjoern A. Zeeb ret = mt7615_init_tx_queues(dev); 2616c92544dSBjoern A. Zeeb if (ret) 2626c92544dSBjoern A. Zeeb return ret; 2636c92544dSBjoern A. Zeeb 2646c92544dSBjoern A. Zeeb /* init rx queues */ 2656c92544dSBjoern A. Zeeb ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU], 1, 2666c92544dSBjoern A. Zeeb MT7615_RX_MCU_RING_SIZE, MT_RX_BUF_SIZE, 2676c92544dSBjoern A. Zeeb MT_RX_RING_BASE); 2686c92544dSBjoern A. Zeeb if (ret) 2696c92544dSBjoern A. Zeeb return ret; 2706c92544dSBjoern A. Zeeb 2716c92544dSBjoern A. Zeeb if (!is_mt7615(&dev->mt76)) 2726c92544dSBjoern A. Zeeb rx_ring_size /= 2; 2736c92544dSBjoern A. Zeeb 2746c92544dSBjoern A. Zeeb ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN], 0, 2756c92544dSBjoern A. Zeeb rx_ring_size, MT_RX_BUF_SIZE, MT_RX_RING_BASE); 2766c92544dSBjoern A. Zeeb if (ret) 2776c92544dSBjoern A. Zeeb return ret; 2786c92544dSBjoern A. Zeeb 2796c92544dSBjoern A. Zeeb mt76_wr(dev, MT_DELAY_INT_CFG, 0); 2806c92544dSBjoern A. Zeeb 2816c92544dSBjoern A. Zeeb ret = mt76_init_queues(dev, mt7615_poll_rx); 2826c92544dSBjoern A. Zeeb if (ret < 0) 2836c92544dSBjoern A. Zeeb return ret; 2846c92544dSBjoern A. Zeeb 2856c92544dSBjoern A. Zeeb netif_napi_add_tx(&dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, 2866c92544dSBjoern A. Zeeb mt7615_poll_tx); 2876c92544dSBjoern A. Zeeb napi_enable(&dev->mt76.tx_napi); 2886c92544dSBjoern A. Zeeb 2896c92544dSBjoern A. Zeeb mt76_poll(dev, MT_WPDMA_GLO_CFG, 2906c92544dSBjoern A. Zeeb MT_WPDMA_GLO_CFG_TX_DMA_BUSY | 2916c92544dSBjoern A. Zeeb MT_WPDMA_GLO_CFG_RX_DMA_BUSY, 0, 1000); 2926c92544dSBjoern A. Zeeb 2936c92544dSBjoern A. Zeeb /* enable interrupts for TX/RX rings */ 2946c92544dSBjoern A. Zeeb 2956c92544dSBjoern A. Zeeb mask = MT_INT_RX_DONE_ALL | mt7615_tx_mcu_int_mask(dev); 2966c92544dSBjoern A. Zeeb if (is_mt7663(&dev->mt76)) 2976c92544dSBjoern A. Zeeb mask |= MT7663_INT_MCU_CMD; 2986c92544dSBjoern A. Zeeb else 2996c92544dSBjoern A. Zeeb mask |= MT_INT_MCU_CMD; 3006c92544dSBjoern A. Zeeb 301*cbb3ec25SBjoern A. Zeeb mt76_connac_irq_enable(&dev->mt76, mask); 3026c92544dSBjoern A. Zeeb 3036c92544dSBjoern A. Zeeb mt7615_dma_start(dev); 3046c92544dSBjoern A. Zeeb 3056c92544dSBjoern A. Zeeb return 0; 3066c92544dSBjoern A. Zeeb } 3076c92544dSBjoern A. Zeeb 3086c92544dSBjoern A. Zeeb void mt7615_dma_cleanup(struct mt7615_dev *dev) 3096c92544dSBjoern A. Zeeb { 3106c92544dSBjoern A. Zeeb mt76_clear(dev, MT_WPDMA_GLO_CFG, 3116c92544dSBjoern A. Zeeb MT_WPDMA_GLO_CFG_TX_DMA_EN | 3126c92544dSBjoern A. Zeeb MT_WPDMA_GLO_CFG_RX_DMA_EN); 3136c92544dSBjoern A. Zeeb mt76_set(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_SW_RESET); 3146c92544dSBjoern A. Zeeb 3156c92544dSBjoern A. Zeeb mt76_dma_cleanup(&dev->mt76); 3166c92544dSBjoern A. Zeeb } 317