162306a36Sopenharmony_ci// SPDX-License-Identifier: ISC 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2022 MediaTek Inc. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include "mt7996.h" 762306a36Sopenharmony_ci#include "../dma.h" 862306a36Sopenharmony_ci#include "mac.h" 962306a36Sopenharmony_ci 1062306a36Sopenharmony_cistatic int mt7996_poll_tx(struct napi_struct *napi, int budget) 1162306a36Sopenharmony_ci{ 1262306a36Sopenharmony_ci struct mt7996_dev *dev; 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci dev = container_of(napi, struct mt7996_dev, mt76.tx_napi); 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci mt76_connac_tx_cleanup(&dev->mt76); 1762306a36Sopenharmony_ci if (napi_complete_done(napi, 0)) 1862306a36Sopenharmony_ci mt7996_irq_enable(dev, MT_INT_TX_DONE_MCU); 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci return 0; 2162306a36Sopenharmony_ci} 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cistatic void mt7996_dma_config(struct mt7996_dev *dev) 2462306a36Sopenharmony_ci{ 2562306a36Sopenharmony_ci#define Q_CONFIG(q, wfdma, int, id) do { \ 2662306a36Sopenharmony_ci if (wfdma) \ 2762306a36Sopenharmony_ci dev->q_wfdma_mask |= (1 << (q)); \ 2862306a36Sopenharmony_ci dev->q_int_mask[(q)] = int; \ 2962306a36Sopenharmony_ci dev->q_id[(q)] = id; \ 3062306a36Sopenharmony_ci} while (0) 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci#define MCUQ_CONFIG(q, wfdma, int, id) Q_CONFIG(q, (wfdma), (int), (id)) 3362306a36Sopenharmony_ci#define RXQ_CONFIG(q, wfdma, int, id) Q_CONFIG(__RXQ(q), (wfdma), (int), (id)) 3462306a36Sopenharmony_ci#define TXQ_CONFIG(q, wfdma, int, id) Q_CONFIG(__TXQ(q), (wfdma), (int), (id)) 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci /* rx queue */ 3762306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_MCU, WFDMA0, MT_INT_RX_DONE_WM, MT7996_RXQ_MCU_WM); 3862306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_MCU_WA, WFDMA0, MT_INT_RX_DONE_WA, MT7996_RXQ_MCU_WA); 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci /* band0/band1 */ 4162306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_MAIN, WFDMA0, MT_INT_RX_DONE_BAND0, MT7996_RXQ_BAND0); 4262306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_MAIN_WA, WFDMA0, MT_INT_RX_DONE_WA_MAIN, MT7996_RXQ_MCU_WA_MAIN); 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci /* band2 */ 4562306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_BAND2, WFDMA0, MT_INT_RX_DONE_BAND2, MT7996_RXQ_BAND2); 4662306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_BAND2_WA, WFDMA0, MT_INT_RX_DONE_WA_TRI, MT7996_RXQ_MCU_WA_TRI); 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci /* data tx queue */ 4962306a36Sopenharmony_ci TXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND0, MT7996_TXQ_BAND0); 5062306a36Sopenharmony_ci TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND1, MT7996_TXQ_BAND1); 5162306a36Sopenharmony_ci TXQ_CONFIG(2, WFDMA0, MT_INT_TX_DONE_BAND2, MT7996_TXQ_BAND2); 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci /* mcu tx queue */ 5462306a36Sopenharmony_ci MCUQ_CONFIG(MT_MCUQ_WM, WFDMA0, MT_INT_TX_DONE_MCU_WM, MT7996_TXQ_MCU_WM); 5562306a36Sopenharmony_ci MCUQ_CONFIG(MT_MCUQ_WA, WFDMA0, MT_INT_TX_DONE_MCU_WA, MT7996_TXQ_MCU_WA); 5662306a36Sopenharmony_ci MCUQ_CONFIG(MT_MCUQ_FWDL, WFDMA0, MT_INT_TX_DONE_FWDL, MT7996_TXQ_FWDL); 5762306a36Sopenharmony_ci} 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cistatic void __mt7996_dma_prefetch(struct mt7996_dev *dev, u32 ofs) 6062306a36Sopenharmony_ci{ 6162306a36Sopenharmony_ci#define PREFETCH(_base, _depth) ((_base) << 16 | (_depth)) 6262306a36Sopenharmony_ci /* prefetch SRAM wrapping boundary for tx/rx ring. */ 6362306a36Sopenharmony_ci mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_FWDL) + ofs, PREFETCH(0x0, 0x2)); 6462306a36Sopenharmony_ci mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_WM) + ofs, PREFETCH(0x20, 0x2)); 6562306a36Sopenharmony_ci mt76_wr(dev, MT_TXQ_EXT_CTRL(0) + ofs, PREFETCH(0x40, 0x4)); 6662306a36Sopenharmony_ci mt76_wr(dev, MT_TXQ_EXT_CTRL(1) + ofs, PREFETCH(0x80, 0x4)); 6762306a36Sopenharmony_ci mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_WA) + ofs, PREFETCH(0xc0, 0x2)); 6862306a36Sopenharmony_ci mt76_wr(dev, MT_TXQ_EXT_CTRL(2) + ofs, PREFETCH(0xe0, 0x4)); 6962306a36Sopenharmony_ci mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MCU) + ofs, PREFETCH(0x120, 0x2)); 7062306a36Sopenharmony_ci mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MCU_WA) + ofs, PREFETCH(0x140, 0x2)); 7162306a36Sopenharmony_ci mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN_WA) + ofs, PREFETCH(0x160, 0x2)); 7262306a36Sopenharmony_ci mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2_WA) + ofs, PREFETCH(0x180, 0x2)); 7362306a36Sopenharmony_ci mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN) + ofs, PREFETCH(0x1a0, 0x10)); 7462306a36Sopenharmony_ci mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2) + ofs, PREFETCH(0x2a0, 0x10)); 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT1 + ofs, WF_WFDMA0_GLO_CFG_EXT1_CALC_MODE); 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_civoid mt7996_dma_prefetch(struct mt7996_dev *dev) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci __mt7996_dma_prefetch(dev, 0); 8262306a36Sopenharmony_ci if (dev->hif2) 8362306a36Sopenharmony_ci __mt7996_dma_prefetch(dev, MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0)); 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_cistatic void mt7996_dma_disable(struct mt7996_dev *dev, bool reset) 8762306a36Sopenharmony_ci{ 8862306a36Sopenharmony_ci u32 hif1_ofs = 0; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci if (dev->hif2) 9162306a36Sopenharmony_ci hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0); 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci if (reset) { 9462306a36Sopenharmony_ci mt76_clear(dev, MT_WFDMA0_RST, 9562306a36Sopenharmony_ci MT_WFDMA0_RST_DMASHDL_ALL_RST | 9662306a36Sopenharmony_ci MT_WFDMA0_RST_LOGIC_RST); 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA0_RST, 9962306a36Sopenharmony_ci MT_WFDMA0_RST_DMASHDL_ALL_RST | 10062306a36Sopenharmony_ci MT_WFDMA0_RST_LOGIC_RST); 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci if (dev->hif2) { 10362306a36Sopenharmony_ci mt76_clear(dev, MT_WFDMA0_RST + hif1_ofs, 10462306a36Sopenharmony_ci MT_WFDMA0_RST_DMASHDL_ALL_RST | 10562306a36Sopenharmony_ci MT_WFDMA0_RST_LOGIC_RST); 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA0_RST + hif1_ofs, 10862306a36Sopenharmony_ci MT_WFDMA0_RST_DMASHDL_ALL_RST | 10962306a36Sopenharmony_ci MT_WFDMA0_RST_LOGIC_RST); 11062306a36Sopenharmony_ci } 11162306a36Sopenharmony_ci } 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci /* disable */ 11462306a36Sopenharmony_ci mt76_clear(dev, MT_WFDMA0_GLO_CFG, 11562306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_TX_DMA_EN | 11662306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_RX_DMA_EN | 11762306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | 11862306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_OMIT_RX_INFO | 11962306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci if (dev->hif2) { 12262306a36Sopenharmony_ci mt76_clear(dev, MT_WFDMA0_GLO_CFG + hif1_ofs, 12362306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_TX_DMA_EN | 12462306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_RX_DMA_EN | 12562306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | 12662306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_OMIT_RX_INFO | 12762306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); 12862306a36Sopenharmony_ci } 12962306a36Sopenharmony_ci} 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_civoid mt7996_dma_start(struct mt7996_dev *dev, bool reset) 13262306a36Sopenharmony_ci{ 13362306a36Sopenharmony_ci u32 hif1_ofs = 0; 13462306a36Sopenharmony_ci u32 irq_mask; 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci if (dev->hif2) 13762306a36Sopenharmony_ci hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0); 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci /* enable WFDMA Tx/Rx */ 14062306a36Sopenharmony_ci if (!reset) { 14162306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA0_GLO_CFG, 14262306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_TX_DMA_EN | 14362306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_RX_DMA_EN | 14462306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | 14562306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci if (dev->hif2) 14862306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs, 14962306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_TX_DMA_EN | 15062306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_RX_DMA_EN | 15162306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | 15262306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); 15362306a36Sopenharmony_ci } 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci /* enable interrupts for TX/RX rings */ 15662306a36Sopenharmony_ci irq_mask = MT_INT_MCU_CMD; 15762306a36Sopenharmony_ci if (reset) 15862306a36Sopenharmony_ci goto done; 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci irq_mask = MT_INT_RX_DONE_MCU | MT_INT_TX_DONE_MCU; 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci if (!dev->mphy.band_idx) 16362306a36Sopenharmony_ci irq_mask |= MT_INT_BAND0_RX_DONE; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci if (dev->dbdc_support) 16662306a36Sopenharmony_ci irq_mask |= MT_INT_BAND1_RX_DONE; 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci if (dev->tbtc_support) 16962306a36Sopenharmony_ci irq_mask |= MT_INT_BAND2_RX_DONE; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_cidone: 17262306a36Sopenharmony_ci mt7996_irq_enable(dev, irq_mask); 17362306a36Sopenharmony_ci mt7996_irq_disable(dev, 0); 17462306a36Sopenharmony_ci} 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_cistatic void mt7996_dma_enable(struct mt7996_dev *dev, bool reset) 17762306a36Sopenharmony_ci{ 17862306a36Sopenharmony_ci u32 hif1_ofs = 0; 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci if (dev->hif2) 18162306a36Sopenharmony_ci hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0); 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci /* reset dma idx */ 18462306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR, ~0); 18562306a36Sopenharmony_ci if (dev->hif2) 18662306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR + hif1_ofs, ~0); 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci /* configure delay interrupt off */ 18962306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG0, 0); 19062306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG1, 0); 19162306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG2, 0); 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci if (dev->hif2) { 19462306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG0 + hif1_ofs, 0); 19562306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG1 + hif1_ofs, 0); 19662306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG2 + hif1_ofs, 0); 19762306a36Sopenharmony_ci } 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci /* configure perfetch settings */ 20062306a36Sopenharmony_ci mt7996_dma_prefetch(dev); 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci /* hif wait WFDMA idle */ 20362306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA0_BUSY_ENA, 20462306a36Sopenharmony_ci MT_WFDMA0_BUSY_ENA_TX_FIFO0 | 20562306a36Sopenharmony_ci MT_WFDMA0_BUSY_ENA_TX_FIFO1 | 20662306a36Sopenharmony_ci MT_WFDMA0_BUSY_ENA_RX_FIFO); 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci if (dev->hif2) 20962306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA0_BUSY_ENA + hif1_ofs, 21062306a36Sopenharmony_ci MT_WFDMA0_PCIE1_BUSY_ENA_TX_FIFO0 | 21162306a36Sopenharmony_ci MT_WFDMA0_PCIE1_BUSY_ENA_TX_FIFO1 | 21262306a36Sopenharmony_ci MT_WFDMA0_PCIE1_BUSY_ENA_RX_FIFO); 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci mt76_poll(dev, MT_WFDMA_EXT_CSR_HIF_MISC, 21562306a36Sopenharmony_ci MT_WFDMA_EXT_CSR_HIF_MISC_BUSY, 0, 1000); 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci /* GLO_CFG_EXT0 */ 21862306a36Sopenharmony_ci mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0, 21962306a36Sopenharmony_ci WF_WFDMA0_GLO_CFG_EXT0_RX_WB_RXD | 22062306a36Sopenharmony_ci WF_WFDMA0_GLO_CFG_EXT0_WED_MERGE_MODE); 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci /* GLO_CFG_EXT1 */ 22362306a36Sopenharmony_ci mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT1, 22462306a36Sopenharmony_ci WF_WFDMA0_GLO_CFG_EXT1_TX_FCTRL_MODE); 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci if (dev->hif2) { 22762306a36Sopenharmony_ci /* GLO_CFG_EXT0 */ 22862306a36Sopenharmony_ci mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0 + hif1_ofs, 22962306a36Sopenharmony_ci WF_WFDMA0_GLO_CFG_EXT0_RX_WB_RXD | 23062306a36Sopenharmony_ci WF_WFDMA0_GLO_CFG_EXT0_WED_MERGE_MODE); 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci /* GLO_CFG_EXT1 */ 23362306a36Sopenharmony_ci mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT1 + hif1_ofs, 23462306a36Sopenharmony_ci WF_WFDMA0_GLO_CFG_EXT1_TX_FCTRL_MODE); 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA_HOST_CONFIG, 23762306a36Sopenharmony_ci MT_WFDMA_HOST_CONFIG_PDMA_BAND); 23862306a36Sopenharmony_ci } 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci if (dev->hif2) { 24162306a36Sopenharmony_ci /* fix hardware limitation, pcie1's rx ring3 is not available 24262306a36Sopenharmony_ci * so, redirect pcie0 rx ring3 interrupt to pcie1 24362306a36Sopenharmony_ci */ 24462306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL, 24562306a36Sopenharmony_ci MT_WFDMA0_RX_INT_SEL_RING3); 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci /* TODO: redirect rx ring6 interrupt to pcie0 for wed function */ 24862306a36Sopenharmony_ci } 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci mt7996_dma_start(dev, reset); 25162306a36Sopenharmony_ci} 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ciint mt7996_dma_init(struct mt7996_dev *dev) 25462306a36Sopenharmony_ci{ 25562306a36Sopenharmony_ci u32 hif1_ofs = 0; 25662306a36Sopenharmony_ci int ret; 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci mt7996_dma_config(dev); 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci mt76_dma_attach(&dev->mt76); 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci if (dev->hif2) 26362306a36Sopenharmony_ci hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0); 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci mt7996_dma_disable(dev, true); 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci /* init tx queue */ 26862306a36Sopenharmony_ci ret = mt76_connac_init_tx_queues(dev->phy.mt76, 26962306a36Sopenharmony_ci MT_TXQ_ID(dev->mphy.band_idx), 27062306a36Sopenharmony_ci MT7996_TX_RING_SIZE, 27162306a36Sopenharmony_ci MT_TXQ_RING_BASE(0), 0); 27262306a36Sopenharmony_ci if (ret) 27362306a36Sopenharmony_ci return ret; 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci /* command to WM */ 27662306a36Sopenharmony_ci ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WM, 27762306a36Sopenharmony_ci MT_MCUQ_ID(MT_MCUQ_WM), 27862306a36Sopenharmony_ci MT7996_TX_MCU_RING_SIZE, 27962306a36Sopenharmony_ci MT_MCUQ_RING_BASE(MT_MCUQ_WM)); 28062306a36Sopenharmony_ci if (ret) 28162306a36Sopenharmony_ci return ret; 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci /* command to WA */ 28462306a36Sopenharmony_ci ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WA, 28562306a36Sopenharmony_ci MT_MCUQ_ID(MT_MCUQ_WA), 28662306a36Sopenharmony_ci MT7996_TX_MCU_RING_SIZE, 28762306a36Sopenharmony_ci MT_MCUQ_RING_BASE(MT_MCUQ_WA)); 28862306a36Sopenharmony_ci if (ret) 28962306a36Sopenharmony_ci return ret; 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci /* firmware download */ 29262306a36Sopenharmony_ci ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_FWDL, 29362306a36Sopenharmony_ci MT_MCUQ_ID(MT_MCUQ_FWDL), 29462306a36Sopenharmony_ci MT7996_TX_FWDL_RING_SIZE, 29562306a36Sopenharmony_ci MT_MCUQ_RING_BASE(MT_MCUQ_FWDL)); 29662306a36Sopenharmony_ci if (ret) 29762306a36Sopenharmony_ci return ret; 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci /* event from WM */ 30062306a36Sopenharmony_ci ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU], 30162306a36Sopenharmony_ci MT_RXQ_ID(MT_RXQ_MCU), 30262306a36Sopenharmony_ci MT7996_RX_MCU_RING_SIZE, 30362306a36Sopenharmony_ci MT_RX_BUF_SIZE, 30462306a36Sopenharmony_ci MT_RXQ_RING_BASE(MT_RXQ_MCU)); 30562306a36Sopenharmony_ci if (ret) 30662306a36Sopenharmony_ci return ret; 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci /* event from WA */ 30962306a36Sopenharmony_ci ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA], 31062306a36Sopenharmony_ci MT_RXQ_ID(MT_RXQ_MCU_WA), 31162306a36Sopenharmony_ci MT7996_RX_MCU_RING_SIZE_WA, 31262306a36Sopenharmony_ci MT_RX_BUF_SIZE, 31362306a36Sopenharmony_ci MT_RXQ_RING_BASE(MT_RXQ_MCU_WA)); 31462306a36Sopenharmony_ci if (ret) 31562306a36Sopenharmony_ci return ret; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci /* rx data queue for band0 and band1 */ 31862306a36Sopenharmony_ci ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN], 31962306a36Sopenharmony_ci MT_RXQ_ID(MT_RXQ_MAIN), 32062306a36Sopenharmony_ci MT7996_RX_RING_SIZE, 32162306a36Sopenharmony_ci MT_RX_BUF_SIZE, 32262306a36Sopenharmony_ci MT_RXQ_RING_BASE(MT_RXQ_MAIN)); 32362306a36Sopenharmony_ci if (ret) 32462306a36Sopenharmony_ci return ret; 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci /* tx free notify event from WA for band0 */ 32762306a36Sopenharmony_ci ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN_WA], 32862306a36Sopenharmony_ci MT_RXQ_ID(MT_RXQ_MAIN_WA), 32962306a36Sopenharmony_ci MT7996_RX_MCU_RING_SIZE, 33062306a36Sopenharmony_ci MT_RX_BUF_SIZE, 33162306a36Sopenharmony_ci MT_RXQ_RING_BASE(MT_RXQ_MAIN_WA)); 33262306a36Sopenharmony_ci if (ret) 33362306a36Sopenharmony_ci return ret; 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci if (dev->tbtc_support || dev->mphy.band_idx == MT_BAND2) { 33662306a36Sopenharmony_ci /* rx data queue for band2 */ 33762306a36Sopenharmony_ci ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2], 33862306a36Sopenharmony_ci MT_RXQ_ID(MT_RXQ_BAND2), 33962306a36Sopenharmony_ci MT7996_RX_RING_SIZE, 34062306a36Sopenharmony_ci MT_RX_BUF_SIZE, 34162306a36Sopenharmony_ci MT_RXQ_RING_BASE(MT_RXQ_BAND2) + hif1_ofs); 34262306a36Sopenharmony_ci if (ret) 34362306a36Sopenharmony_ci return ret; 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci /* tx free notify event from WA for band2 34662306a36Sopenharmony_ci * use pcie0's rx ring3, but, redirect pcie0 rx ring3 interrupt to pcie1 34762306a36Sopenharmony_ci */ 34862306a36Sopenharmony_ci ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2_WA], 34962306a36Sopenharmony_ci MT_RXQ_ID(MT_RXQ_BAND2_WA), 35062306a36Sopenharmony_ci MT7996_RX_MCU_RING_SIZE, 35162306a36Sopenharmony_ci MT_RX_BUF_SIZE, 35262306a36Sopenharmony_ci MT_RXQ_RING_BASE(MT_RXQ_BAND2_WA)); 35362306a36Sopenharmony_ci if (ret) 35462306a36Sopenharmony_ci return ret; 35562306a36Sopenharmony_ci } 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci ret = mt76_init_queues(dev, mt76_dma_rx_poll); 35862306a36Sopenharmony_ci if (ret < 0) 35962306a36Sopenharmony_ci return ret; 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci netif_napi_add_tx(&dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, 36262306a36Sopenharmony_ci mt7996_poll_tx); 36362306a36Sopenharmony_ci napi_enable(&dev->mt76.tx_napi); 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci mt7996_dma_enable(dev, false); 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci return 0; 36862306a36Sopenharmony_ci} 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_civoid mt7996_dma_reset(struct mt7996_dev *dev, bool force) 37162306a36Sopenharmony_ci{ 37262306a36Sopenharmony_ci struct mt76_phy *phy2 = dev->mt76.phys[MT_BAND1]; 37362306a36Sopenharmony_ci struct mt76_phy *phy3 = dev->mt76.phys[MT_BAND2]; 37462306a36Sopenharmony_ci u32 hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0); 37562306a36Sopenharmony_ci int i; 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci mt76_clear(dev, MT_WFDMA0_GLO_CFG, 37862306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_TX_DMA_EN | 37962306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_RX_DMA_EN); 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci if (dev->hif2) 38262306a36Sopenharmony_ci mt76_clear(dev, MT_WFDMA0_GLO_CFG + hif1_ofs, 38362306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_TX_DMA_EN | 38462306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_RX_DMA_EN); 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci usleep_range(1000, 2000); 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci for (i = 0; i < __MT_TXQ_MAX; i++) { 38962306a36Sopenharmony_ci mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[i], true); 39062306a36Sopenharmony_ci if (phy2) 39162306a36Sopenharmony_ci mt76_queue_tx_cleanup(dev, phy2->q_tx[i], true); 39262306a36Sopenharmony_ci if (phy3) 39362306a36Sopenharmony_ci mt76_queue_tx_cleanup(dev, phy3->q_tx[i], true); 39462306a36Sopenharmony_ci } 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci for (i = 0; i < __MT_MCUQ_MAX; i++) 39762306a36Sopenharmony_ci mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[i], true); 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ci mt76_for_each_q_rx(&dev->mt76, i) 40062306a36Sopenharmony_ci mt76_queue_rx_cleanup(dev, &dev->mt76.q_rx[i]); 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci mt76_tx_status_check(&dev->mt76, true); 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci /* reset wfsys */ 40562306a36Sopenharmony_ci if (force) 40662306a36Sopenharmony_ci mt7996_wfsys_reset(dev); 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_ci mt7996_dma_disable(dev, force); 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ci /* reset hw queues */ 41162306a36Sopenharmony_ci for (i = 0; i < __MT_TXQ_MAX; i++) { 41262306a36Sopenharmony_ci mt76_queue_reset(dev, dev->mphy.q_tx[i]); 41362306a36Sopenharmony_ci if (phy2) 41462306a36Sopenharmony_ci mt76_queue_reset(dev, phy2->q_tx[i]); 41562306a36Sopenharmony_ci if (phy3) 41662306a36Sopenharmony_ci mt76_queue_reset(dev, phy3->q_tx[i]); 41762306a36Sopenharmony_ci } 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci for (i = 0; i < __MT_MCUQ_MAX; i++) 42062306a36Sopenharmony_ci mt76_queue_reset(dev, dev->mt76.q_mcu[i]); 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci mt76_for_each_q_rx(&dev->mt76, i) { 42362306a36Sopenharmony_ci mt76_queue_reset(dev, &dev->mt76.q_rx[i]); 42462306a36Sopenharmony_ci } 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci mt76_tx_status_check(&dev->mt76, true); 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ci mt76_for_each_q_rx(&dev->mt76, i) 42962306a36Sopenharmony_ci mt76_queue_rx_reset(dev, i); 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci mt7996_dma_enable(dev, !force); 43262306a36Sopenharmony_ci} 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_civoid mt7996_dma_cleanup(struct mt7996_dev *dev) 43562306a36Sopenharmony_ci{ 43662306a36Sopenharmony_ci mt7996_dma_disable(dev, true); 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci mt76_dma_cleanup(&dev->mt76); 43962306a36Sopenharmony_ci} 440