162306a36Sopenharmony_ci// SPDX-License-Identifier: ISC 262306a36Sopenharmony_ci/* Copyright (C) 2020 MediaTek Inc. */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include "mt7915.h" 562306a36Sopenharmony_ci#include "../dma.h" 662306a36Sopenharmony_ci#include "mac.h" 762306a36Sopenharmony_ci 862306a36Sopenharmony_cistatic int 962306a36Sopenharmony_cimt7915_init_tx_queues(struct mt7915_phy *phy, int idx, int n_desc, int ring_base) 1062306a36Sopenharmony_ci{ 1162306a36Sopenharmony_ci struct mt7915_dev *dev = phy->dev; 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) { 1462306a36Sopenharmony_ci if (is_mt798x(&dev->mt76)) 1562306a36Sopenharmony_ci ring_base += MT_TXQ_ID(0) * MT_RING_SIZE; 1662306a36Sopenharmony_ci else 1762306a36Sopenharmony_ci ring_base = MT_WED_TX_RING_BASE; 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci idx -= MT_TXQ_ID(0); 2062306a36Sopenharmony_ci } 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci return mt76_connac_init_tx_queues(phy->mt76, idx, n_desc, ring_base, 2362306a36Sopenharmony_ci MT_WED_Q_TX(idx)); 2462306a36Sopenharmony_ci} 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_cistatic int mt7915_poll_tx(struct napi_struct *napi, int budget) 2762306a36Sopenharmony_ci{ 2862306a36Sopenharmony_ci struct mt7915_dev *dev; 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci dev = container_of(napi, struct mt7915_dev, mt76.tx_napi); 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci mt76_connac_tx_cleanup(&dev->mt76); 3362306a36Sopenharmony_ci if (napi_complete_done(napi, 0)) 3462306a36Sopenharmony_ci mt7915_irq_enable(dev, MT_INT_TX_DONE_MCU); 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci return 0; 3762306a36Sopenharmony_ci} 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistatic void mt7915_dma_config(struct mt7915_dev *dev) 4062306a36Sopenharmony_ci{ 4162306a36Sopenharmony_ci#define Q_CONFIG(q, wfdma, int, id) do { \ 4262306a36Sopenharmony_ci if (wfdma) \ 4362306a36Sopenharmony_ci dev->wfdma_mask |= (1 << (q)); \ 4462306a36Sopenharmony_ci dev->q_int_mask[(q)] = int; \ 4562306a36Sopenharmony_ci dev->q_id[(q)] = id; \ 4662306a36Sopenharmony_ci } while (0) 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci#define MCUQ_CONFIG(q, wfdma, int, id) Q_CONFIG(q, (wfdma), (int), (id)) 4962306a36Sopenharmony_ci#define RXQ_CONFIG(q, wfdma, int, id) Q_CONFIG(__RXQ(q), (wfdma), (int), (id)) 5062306a36Sopenharmony_ci#define TXQ_CONFIG(q, wfdma, int, id) Q_CONFIG(__TXQ(q), (wfdma), (int), (id)) 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci if (is_mt7915(&dev->mt76)) { 5362306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_MAIN, WFDMA0, MT_INT_RX_DONE_BAND0, 5462306a36Sopenharmony_ci MT7915_RXQ_BAND0); 5562306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_MCU, WFDMA1, MT_INT_RX_DONE_WM, 5662306a36Sopenharmony_ci MT7915_RXQ_MCU_WM); 5762306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_MCU_WA, WFDMA1, MT_INT_RX_DONE_WA, 5862306a36Sopenharmony_ci MT7915_RXQ_MCU_WA); 5962306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_BAND1, WFDMA0, MT_INT_RX_DONE_BAND1, 6062306a36Sopenharmony_ci MT7915_RXQ_BAND1); 6162306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_BAND1_WA, WFDMA1, MT_INT_RX_DONE_WA_EXT, 6262306a36Sopenharmony_ci MT7915_RXQ_MCU_WA_EXT); 6362306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_MAIN_WA, WFDMA1, MT_INT_RX_DONE_WA_MAIN, 6462306a36Sopenharmony_ci MT7915_RXQ_MCU_WA); 6562306a36Sopenharmony_ci TXQ_CONFIG(0, WFDMA1, MT_INT_TX_DONE_BAND0, MT7915_TXQ_BAND0); 6662306a36Sopenharmony_ci TXQ_CONFIG(1, WFDMA1, MT_INT_TX_DONE_BAND1, MT7915_TXQ_BAND1); 6762306a36Sopenharmony_ci MCUQ_CONFIG(MT_MCUQ_WM, WFDMA1, MT_INT_TX_DONE_MCU_WM, 6862306a36Sopenharmony_ci MT7915_TXQ_MCU_WM); 6962306a36Sopenharmony_ci MCUQ_CONFIG(MT_MCUQ_WA, WFDMA1, MT_INT_TX_DONE_MCU_WA, 7062306a36Sopenharmony_ci MT7915_TXQ_MCU_WA); 7162306a36Sopenharmony_ci MCUQ_CONFIG(MT_MCUQ_FWDL, WFDMA1, MT_INT_TX_DONE_FWDL, 7262306a36Sopenharmony_ci MT7915_TXQ_FWDL); 7362306a36Sopenharmony_ci } else { 7462306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_MCU, WFDMA0, MT_INT_RX_DONE_WM, 7562306a36Sopenharmony_ci MT7916_RXQ_MCU_WM); 7662306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_BAND1_WA, WFDMA0, MT_INT_RX_DONE_WA_EXT_MT7916, 7762306a36Sopenharmony_ci MT7916_RXQ_MCU_WA_EXT); 7862306a36Sopenharmony_ci MCUQ_CONFIG(MT_MCUQ_WM, WFDMA0, MT_INT_TX_DONE_MCU_WM, 7962306a36Sopenharmony_ci MT7915_TXQ_MCU_WM); 8062306a36Sopenharmony_ci MCUQ_CONFIG(MT_MCUQ_WA, WFDMA0, MT_INT_TX_DONE_MCU_WA_MT7916, 8162306a36Sopenharmony_ci MT7915_TXQ_MCU_WA); 8262306a36Sopenharmony_ci MCUQ_CONFIG(MT_MCUQ_FWDL, WFDMA0, MT_INT_TX_DONE_FWDL, 8362306a36Sopenharmony_ci MT7915_TXQ_FWDL); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci if (is_mt7916(&dev->mt76) && mtk_wed_device_active(&dev->mt76.mmio.wed)) { 8662306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_MAIN, WFDMA0, MT_INT_WED_RX_DONE_BAND0_MT7916, 8762306a36Sopenharmony_ci MT7916_RXQ_BAND0); 8862306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_MCU_WA, WFDMA0, MT_INT_WED_RX_DONE_WA_MT7916, 8962306a36Sopenharmony_ci MT7916_RXQ_MCU_WA); 9062306a36Sopenharmony_ci if (dev->hif2) 9162306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_BAND1, WFDMA0, 9262306a36Sopenharmony_ci MT_INT_RX_DONE_BAND1_MT7916, 9362306a36Sopenharmony_ci MT7916_RXQ_BAND1); 9462306a36Sopenharmony_ci else 9562306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_BAND1, WFDMA0, 9662306a36Sopenharmony_ci MT_INT_WED_RX_DONE_BAND1_MT7916, 9762306a36Sopenharmony_ci MT7916_RXQ_BAND1); 9862306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_MAIN_WA, WFDMA0, MT_INT_WED_RX_DONE_WA_MAIN_MT7916, 9962306a36Sopenharmony_ci MT7916_RXQ_MCU_WA_MAIN); 10062306a36Sopenharmony_ci TXQ_CONFIG(0, WFDMA0, MT_INT_WED_TX_DONE_BAND0, 10162306a36Sopenharmony_ci MT7915_TXQ_BAND0); 10262306a36Sopenharmony_ci TXQ_CONFIG(1, WFDMA0, MT_INT_WED_TX_DONE_BAND1, 10362306a36Sopenharmony_ci MT7915_TXQ_BAND1); 10462306a36Sopenharmony_ci } else { 10562306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_MAIN, WFDMA0, MT_INT_RX_DONE_BAND0_MT7916, 10662306a36Sopenharmony_ci MT7916_RXQ_BAND0); 10762306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_MCU_WA, WFDMA0, MT_INT_RX_DONE_WA, 10862306a36Sopenharmony_ci MT7916_RXQ_MCU_WA); 10962306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_BAND1, WFDMA0, MT_INT_RX_DONE_BAND1_MT7916, 11062306a36Sopenharmony_ci MT7916_RXQ_BAND1); 11162306a36Sopenharmony_ci RXQ_CONFIG(MT_RXQ_MAIN_WA, WFDMA0, MT_INT_RX_DONE_WA_MAIN_MT7916, 11262306a36Sopenharmony_ci MT7916_RXQ_MCU_WA_MAIN); 11362306a36Sopenharmony_ci TXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND0, 11462306a36Sopenharmony_ci MT7915_TXQ_BAND0); 11562306a36Sopenharmony_ci TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND1, 11662306a36Sopenharmony_ci MT7915_TXQ_BAND1); 11762306a36Sopenharmony_ci } 11862306a36Sopenharmony_ci } 11962306a36Sopenharmony_ci} 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_cistatic void __mt7915_dma_prefetch(struct mt7915_dev *dev, u32 ofs) 12262306a36Sopenharmony_ci{ 12362306a36Sopenharmony_ci#define PREFETCH(_base, _depth) ((_base) << 16 | (_depth)) 12462306a36Sopenharmony_ci u32 base = 0; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci /* prefetch SRAM wrapping boundary for tx/rx ring. */ 12762306a36Sopenharmony_ci mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_FWDL) + ofs, PREFETCH(0x0, 0x4)); 12862306a36Sopenharmony_ci mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_WM) + ofs, PREFETCH(0x40, 0x4)); 12962306a36Sopenharmony_ci mt76_wr(dev, MT_TXQ_EXT_CTRL(0) + ofs, PREFETCH(0x80, 0x4)); 13062306a36Sopenharmony_ci mt76_wr(dev, MT_TXQ_EXT_CTRL(1) + ofs, PREFETCH(0xc0, 0x4)); 13162306a36Sopenharmony_ci mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_WA) + ofs, PREFETCH(0x100, 0x4)); 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MCU) + ofs, 13462306a36Sopenharmony_ci PREFETCH(0x140, 0x4)); 13562306a36Sopenharmony_ci mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MCU_WA) + ofs, 13662306a36Sopenharmony_ci PREFETCH(0x180, 0x4)); 13762306a36Sopenharmony_ci if (!is_mt7915(&dev->mt76)) { 13862306a36Sopenharmony_ci mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN_WA) + ofs, 13962306a36Sopenharmony_ci PREFETCH(0x1c0, 0x4)); 14062306a36Sopenharmony_ci base = 0x40; 14162306a36Sopenharmony_ci } 14262306a36Sopenharmony_ci mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND1_WA) + ofs, 14362306a36Sopenharmony_ci PREFETCH(0x1c0 + base, 0x4)); 14462306a36Sopenharmony_ci mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN) + ofs, 14562306a36Sopenharmony_ci PREFETCH(0x200 + base, 0x4)); 14662306a36Sopenharmony_ci mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND1) + ofs, 14762306a36Sopenharmony_ci PREFETCH(0x240 + base, 0x4)); 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci /* for mt7915, the ring which is next the last 15062306a36Sopenharmony_ci * used ring must be initialized. 15162306a36Sopenharmony_ci */ 15262306a36Sopenharmony_ci if (is_mt7915(&dev->mt76)) { 15362306a36Sopenharmony_ci ofs += 0x4; 15462306a36Sopenharmony_ci mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_WA) + ofs, 15562306a36Sopenharmony_ci PREFETCH(0x140, 0x0)); 15662306a36Sopenharmony_ci mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND1_WA) + ofs, 15762306a36Sopenharmony_ci PREFETCH(0x200 + base, 0x0)); 15862306a36Sopenharmony_ci mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND1) + ofs, 15962306a36Sopenharmony_ci PREFETCH(0x280 + base, 0x0)); 16062306a36Sopenharmony_ci } 16162306a36Sopenharmony_ci} 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_civoid mt7915_dma_prefetch(struct mt7915_dev *dev) 16462306a36Sopenharmony_ci{ 16562306a36Sopenharmony_ci __mt7915_dma_prefetch(dev, 0); 16662306a36Sopenharmony_ci if (dev->hif2) 16762306a36Sopenharmony_ci __mt7915_dma_prefetch(dev, MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0)); 16862306a36Sopenharmony_ci} 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_cistatic void mt7915_dma_disable(struct mt7915_dev *dev, bool rst) 17162306a36Sopenharmony_ci{ 17262306a36Sopenharmony_ci struct mt76_dev *mdev = &dev->mt76; 17362306a36Sopenharmony_ci u32 hif1_ofs = 0; 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci if (dev->hif2) 17662306a36Sopenharmony_ci hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0); 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci /* reset */ 17962306a36Sopenharmony_ci if (rst) { 18062306a36Sopenharmony_ci mt76_clear(dev, MT_WFDMA0_RST, 18162306a36Sopenharmony_ci MT_WFDMA0_RST_DMASHDL_ALL_RST | 18262306a36Sopenharmony_ci MT_WFDMA0_RST_LOGIC_RST); 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA0_RST, 18562306a36Sopenharmony_ci MT_WFDMA0_RST_DMASHDL_ALL_RST | 18662306a36Sopenharmony_ci MT_WFDMA0_RST_LOGIC_RST); 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci if (is_mt7915(mdev)) { 18962306a36Sopenharmony_ci mt76_clear(dev, MT_WFDMA1_RST, 19062306a36Sopenharmony_ci MT_WFDMA1_RST_DMASHDL_ALL_RST | 19162306a36Sopenharmony_ci MT_WFDMA1_RST_LOGIC_RST); 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA1_RST, 19462306a36Sopenharmony_ci MT_WFDMA1_RST_DMASHDL_ALL_RST | 19562306a36Sopenharmony_ci MT_WFDMA1_RST_LOGIC_RST); 19662306a36Sopenharmony_ci } 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci if (dev->hif2) { 19962306a36Sopenharmony_ci mt76_clear(dev, MT_WFDMA0_RST + hif1_ofs, 20062306a36Sopenharmony_ci MT_WFDMA0_RST_DMASHDL_ALL_RST | 20162306a36Sopenharmony_ci MT_WFDMA0_RST_LOGIC_RST); 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA0_RST + hif1_ofs, 20462306a36Sopenharmony_ci MT_WFDMA0_RST_DMASHDL_ALL_RST | 20562306a36Sopenharmony_ci MT_WFDMA0_RST_LOGIC_RST); 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci if (is_mt7915(mdev)) { 20862306a36Sopenharmony_ci mt76_clear(dev, MT_WFDMA1_RST + hif1_ofs, 20962306a36Sopenharmony_ci MT_WFDMA1_RST_DMASHDL_ALL_RST | 21062306a36Sopenharmony_ci MT_WFDMA1_RST_LOGIC_RST); 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA1_RST + hif1_ofs, 21362306a36Sopenharmony_ci MT_WFDMA1_RST_DMASHDL_ALL_RST | 21462306a36Sopenharmony_ci MT_WFDMA1_RST_LOGIC_RST); 21562306a36Sopenharmony_ci } 21662306a36Sopenharmony_ci } 21762306a36Sopenharmony_ci } 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci /* disable */ 22062306a36Sopenharmony_ci mt76_clear(dev, MT_WFDMA0_GLO_CFG, 22162306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_TX_DMA_EN | 22262306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_RX_DMA_EN | 22362306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | 22462306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_OMIT_RX_INFO | 22562306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci if (is_mt7915(mdev)) 22862306a36Sopenharmony_ci mt76_clear(dev, MT_WFDMA1_GLO_CFG, 22962306a36Sopenharmony_ci MT_WFDMA1_GLO_CFG_TX_DMA_EN | 23062306a36Sopenharmony_ci MT_WFDMA1_GLO_CFG_RX_DMA_EN | 23162306a36Sopenharmony_ci MT_WFDMA1_GLO_CFG_OMIT_TX_INFO | 23262306a36Sopenharmony_ci MT_WFDMA1_GLO_CFG_OMIT_RX_INFO | 23362306a36Sopenharmony_ci MT_WFDMA1_GLO_CFG_OMIT_RX_INFO_PFET2); 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci if (dev->hif2) { 23662306a36Sopenharmony_ci mt76_clear(dev, MT_WFDMA0_GLO_CFG + hif1_ofs, 23762306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_TX_DMA_EN | 23862306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_RX_DMA_EN | 23962306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | 24062306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_OMIT_RX_INFO | 24162306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci if (is_mt7915(mdev)) 24462306a36Sopenharmony_ci mt76_clear(dev, MT_WFDMA1_GLO_CFG + hif1_ofs, 24562306a36Sopenharmony_ci MT_WFDMA1_GLO_CFG_TX_DMA_EN | 24662306a36Sopenharmony_ci MT_WFDMA1_GLO_CFG_RX_DMA_EN | 24762306a36Sopenharmony_ci MT_WFDMA1_GLO_CFG_OMIT_TX_INFO | 24862306a36Sopenharmony_ci MT_WFDMA1_GLO_CFG_OMIT_RX_INFO | 24962306a36Sopenharmony_ci MT_WFDMA1_GLO_CFG_OMIT_RX_INFO_PFET2); 25062306a36Sopenharmony_ci } 25162306a36Sopenharmony_ci} 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ciint mt7915_dma_start(struct mt7915_dev *dev, bool reset, bool wed_reset) 25462306a36Sopenharmony_ci{ 25562306a36Sopenharmony_ci struct mt76_dev *mdev = &dev->mt76; 25662306a36Sopenharmony_ci u32 hif1_ofs = 0; 25762306a36Sopenharmony_ci u32 irq_mask; 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci if (dev->hif2) 26062306a36Sopenharmony_ci hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0); 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci /* enable wpdma tx/rx */ 26362306a36Sopenharmony_ci if (!reset) { 26462306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA0_GLO_CFG, 26562306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_TX_DMA_EN | 26662306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_RX_DMA_EN | 26762306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | 26862306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci if (is_mt7915(mdev)) 27162306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA1_GLO_CFG, 27262306a36Sopenharmony_ci MT_WFDMA1_GLO_CFG_TX_DMA_EN | 27362306a36Sopenharmony_ci MT_WFDMA1_GLO_CFG_RX_DMA_EN | 27462306a36Sopenharmony_ci MT_WFDMA1_GLO_CFG_OMIT_TX_INFO | 27562306a36Sopenharmony_ci MT_WFDMA1_GLO_CFG_OMIT_RX_INFO); 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci if (dev->hif2) { 27862306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs, 27962306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_TX_DMA_EN | 28062306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_RX_DMA_EN | 28162306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | 28262306a36Sopenharmony_ci MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci if (is_mt7915(mdev)) 28562306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA1_GLO_CFG + hif1_ofs, 28662306a36Sopenharmony_ci MT_WFDMA1_GLO_CFG_TX_DMA_EN | 28762306a36Sopenharmony_ci MT_WFDMA1_GLO_CFG_RX_DMA_EN | 28862306a36Sopenharmony_ci MT_WFDMA1_GLO_CFG_OMIT_TX_INFO | 28962306a36Sopenharmony_ci MT_WFDMA1_GLO_CFG_OMIT_RX_INFO); 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA_HOST_CONFIG, 29262306a36Sopenharmony_ci MT_WFDMA_HOST_CONFIG_PDMA_BAND); 29362306a36Sopenharmony_ci } 29462306a36Sopenharmony_ci } 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci /* enable interrupts for TX/RX rings */ 29762306a36Sopenharmony_ci irq_mask = MT_INT_RX_DONE_MCU | 29862306a36Sopenharmony_ci MT_INT_TX_DONE_MCU | 29962306a36Sopenharmony_ci MT_INT_MCU_CMD; 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci if (!dev->phy.mt76->band_idx) 30262306a36Sopenharmony_ci irq_mask |= MT_INT_BAND0_RX_DONE; 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci if (dev->dbdc_support || dev->phy.mt76->band_idx) 30562306a36Sopenharmony_ci irq_mask |= MT_INT_BAND1_RX_DONE; 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci if (mtk_wed_device_active(&dev->mt76.mmio.wed) && wed_reset) { 30862306a36Sopenharmony_ci u32 wed_irq_mask = irq_mask; 30962306a36Sopenharmony_ci int ret; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci wed_irq_mask |= MT_INT_TX_DONE_BAND0 | MT_INT_TX_DONE_BAND1; 31262306a36Sopenharmony_ci if (!is_mt798x(&dev->mt76)) 31362306a36Sopenharmony_ci mt76_wr(dev, MT_INT_WED_MASK_CSR, wed_irq_mask); 31462306a36Sopenharmony_ci else 31562306a36Sopenharmony_ci mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask); 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci ret = mt7915_mcu_wed_enable_rx_stats(dev); 31862306a36Sopenharmony_ci if (ret) 31962306a36Sopenharmony_ci return ret; 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci mtk_wed_device_start(&dev->mt76.mmio.wed, wed_irq_mask); 32262306a36Sopenharmony_ci } 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci irq_mask = reset ? MT_INT_MCU_CMD : irq_mask; 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci mt7915_irq_enable(dev, irq_mask); 32762306a36Sopenharmony_ci mt7915_irq_disable(dev, 0); 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci return 0; 33062306a36Sopenharmony_ci} 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_cistatic int mt7915_dma_enable(struct mt7915_dev *dev, bool reset) 33362306a36Sopenharmony_ci{ 33462306a36Sopenharmony_ci struct mt76_dev *mdev = &dev->mt76; 33562306a36Sopenharmony_ci u32 hif1_ofs = 0; 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci if (dev->hif2) 33862306a36Sopenharmony_ci hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0); 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci /* reset dma idx */ 34162306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR, ~0); 34262306a36Sopenharmony_ci if (is_mt7915(mdev)) 34362306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA1_RST_DTX_PTR, ~0); 34462306a36Sopenharmony_ci if (dev->hif2) { 34562306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR + hif1_ofs, ~0); 34662306a36Sopenharmony_ci if (is_mt7915(mdev)) 34762306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA1_RST_DTX_PTR + hif1_ofs, ~0); 34862306a36Sopenharmony_ci } 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci /* configure delay interrupt off */ 35162306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG0, 0); 35262306a36Sopenharmony_ci if (is_mt7915(mdev)) { 35362306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA1_PRI_DLY_INT_CFG0, 0); 35462306a36Sopenharmony_ci } else { 35562306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG1, 0); 35662306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG2, 0); 35762306a36Sopenharmony_ci } 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci if (dev->hif2) { 36062306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG0 + hif1_ofs, 0); 36162306a36Sopenharmony_ci if (is_mt7915(mdev)) { 36262306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA1_PRI_DLY_INT_CFG0 + 36362306a36Sopenharmony_ci hif1_ofs, 0); 36462306a36Sopenharmony_ci } else { 36562306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG1 + 36662306a36Sopenharmony_ci hif1_ofs, 0); 36762306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG2 + 36862306a36Sopenharmony_ci hif1_ofs, 0); 36962306a36Sopenharmony_ci } 37062306a36Sopenharmony_ci } 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci /* configure perfetch settings */ 37362306a36Sopenharmony_ci mt7915_dma_prefetch(dev); 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci /* hif wait WFDMA idle */ 37662306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA0_BUSY_ENA, 37762306a36Sopenharmony_ci MT_WFDMA0_BUSY_ENA_TX_FIFO0 | 37862306a36Sopenharmony_ci MT_WFDMA0_BUSY_ENA_TX_FIFO1 | 37962306a36Sopenharmony_ci MT_WFDMA0_BUSY_ENA_RX_FIFO); 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci if (is_mt7915(mdev)) 38262306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA1_BUSY_ENA, 38362306a36Sopenharmony_ci MT_WFDMA1_BUSY_ENA_TX_FIFO0 | 38462306a36Sopenharmony_ci MT_WFDMA1_BUSY_ENA_TX_FIFO1 | 38562306a36Sopenharmony_ci MT_WFDMA1_BUSY_ENA_RX_FIFO); 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci if (dev->hif2) { 38862306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA0_BUSY_ENA + hif1_ofs, 38962306a36Sopenharmony_ci MT_WFDMA0_PCIE1_BUSY_ENA_TX_FIFO0 | 39062306a36Sopenharmony_ci MT_WFDMA0_PCIE1_BUSY_ENA_TX_FIFO1 | 39162306a36Sopenharmony_ci MT_WFDMA0_PCIE1_BUSY_ENA_RX_FIFO); 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci if (is_mt7915(mdev)) 39462306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA1_BUSY_ENA + hif1_ofs, 39562306a36Sopenharmony_ci MT_WFDMA1_PCIE1_BUSY_ENA_TX_FIFO0 | 39662306a36Sopenharmony_ci MT_WFDMA1_PCIE1_BUSY_ENA_TX_FIFO1 | 39762306a36Sopenharmony_ci MT_WFDMA1_PCIE1_BUSY_ENA_RX_FIFO); 39862306a36Sopenharmony_ci } 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci mt76_poll(dev, MT_WFDMA_EXT_CSR_HIF_MISC, 40162306a36Sopenharmony_ci MT_WFDMA_EXT_CSR_HIF_MISC_BUSY, 0, 1000); 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci return mt7915_dma_start(dev, reset, true); 40462306a36Sopenharmony_ci} 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ciint mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2) 40762306a36Sopenharmony_ci{ 40862306a36Sopenharmony_ci struct mt76_dev *mdev = &dev->mt76; 40962306a36Sopenharmony_ci u32 wa_rx_base, wa_rx_idx; 41062306a36Sopenharmony_ci u32 hif1_ofs = 0; 41162306a36Sopenharmony_ci int ret; 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci mt7915_dma_config(dev); 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_ci mt76_dma_attach(&dev->mt76); 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci if (dev->hif2) 41862306a36Sopenharmony_ci hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0); 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci mt7915_dma_disable(dev, true); 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci if (mtk_wed_device_active(&mdev->mmio.wed)) { 42362306a36Sopenharmony_ci if (!is_mt798x(mdev)) { 42462306a36Sopenharmony_ci u8 wed_control_rx1 = is_mt7915(mdev) ? 1 : 2; 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci mt76_set(dev, MT_WFDMA_HOST_CONFIG, 42762306a36Sopenharmony_ci MT_WFDMA_HOST_CONFIG_WED); 42862306a36Sopenharmony_ci mt76_wr(dev, MT_WFDMA_WED_RING_CONTROL, 42962306a36Sopenharmony_ci FIELD_PREP(MT_WFDMA_WED_RING_CONTROL_TX0, 18) | 43062306a36Sopenharmony_ci FIELD_PREP(MT_WFDMA_WED_RING_CONTROL_TX1, 19) | 43162306a36Sopenharmony_ci FIELD_PREP(MT_WFDMA_WED_RING_CONTROL_RX1, 43262306a36Sopenharmony_ci wed_control_rx1)); 43362306a36Sopenharmony_ci if (is_mt7915(mdev)) 43462306a36Sopenharmony_ci mt76_rmw(dev, MT_WFDMA0_EXT0_CFG, MT_WFDMA0_EXT0_RXWB_KEEP, 43562306a36Sopenharmony_ci MT_WFDMA0_EXT0_RXWB_KEEP); 43662306a36Sopenharmony_ci } 43762306a36Sopenharmony_ci } else { 43862306a36Sopenharmony_ci mt76_clear(dev, MT_WFDMA_HOST_CONFIG, MT_WFDMA_HOST_CONFIG_WED); 43962306a36Sopenharmony_ci } 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci /* init tx queue */ 44262306a36Sopenharmony_ci ret = mt7915_init_tx_queues(&dev->phy, 44362306a36Sopenharmony_ci MT_TXQ_ID(dev->phy.mt76->band_idx), 44462306a36Sopenharmony_ci MT7915_TX_RING_SIZE, 44562306a36Sopenharmony_ci MT_TXQ_RING_BASE(0)); 44662306a36Sopenharmony_ci if (ret) 44762306a36Sopenharmony_ci return ret; 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_ci if (phy2) { 45062306a36Sopenharmony_ci ret = mt7915_init_tx_queues(phy2, 45162306a36Sopenharmony_ci MT_TXQ_ID(phy2->mt76->band_idx), 45262306a36Sopenharmony_ci MT7915_TX_RING_SIZE, 45362306a36Sopenharmony_ci MT_TXQ_RING_BASE(1)); 45462306a36Sopenharmony_ci if (ret) 45562306a36Sopenharmony_ci return ret; 45662306a36Sopenharmony_ci } 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ci /* command to WM */ 45962306a36Sopenharmony_ci ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WM, 46062306a36Sopenharmony_ci MT_MCUQ_ID(MT_MCUQ_WM), 46162306a36Sopenharmony_ci MT7915_TX_MCU_RING_SIZE, 46262306a36Sopenharmony_ci MT_MCUQ_RING_BASE(MT_MCUQ_WM)); 46362306a36Sopenharmony_ci if (ret) 46462306a36Sopenharmony_ci return ret; 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci /* command to WA */ 46762306a36Sopenharmony_ci ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WA, 46862306a36Sopenharmony_ci MT_MCUQ_ID(MT_MCUQ_WA), 46962306a36Sopenharmony_ci MT7915_TX_MCU_RING_SIZE, 47062306a36Sopenharmony_ci MT_MCUQ_RING_BASE(MT_MCUQ_WA)); 47162306a36Sopenharmony_ci if (ret) 47262306a36Sopenharmony_ci return ret; 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci /* firmware download */ 47562306a36Sopenharmony_ci ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_FWDL, 47662306a36Sopenharmony_ci MT_MCUQ_ID(MT_MCUQ_FWDL), 47762306a36Sopenharmony_ci MT7915_TX_FWDL_RING_SIZE, 47862306a36Sopenharmony_ci MT_MCUQ_RING_BASE(MT_MCUQ_FWDL)); 47962306a36Sopenharmony_ci if (ret) 48062306a36Sopenharmony_ci return ret; 48162306a36Sopenharmony_ci 48262306a36Sopenharmony_ci /* event from WM */ 48362306a36Sopenharmony_ci ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU], 48462306a36Sopenharmony_ci MT_RXQ_ID(MT_RXQ_MCU), 48562306a36Sopenharmony_ci MT7915_RX_MCU_RING_SIZE, 48662306a36Sopenharmony_ci MT_RX_BUF_SIZE, 48762306a36Sopenharmony_ci MT_RXQ_RING_BASE(MT_RXQ_MCU)); 48862306a36Sopenharmony_ci if (ret) 48962306a36Sopenharmony_ci return ret; 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci /* event from WA */ 49262306a36Sopenharmony_ci if (mtk_wed_device_active(&mdev->mmio.wed) && is_mt7915(mdev)) { 49362306a36Sopenharmony_ci wa_rx_base = MT_WED_RX_RING_BASE; 49462306a36Sopenharmony_ci wa_rx_idx = MT7915_RXQ_MCU_WA; 49562306a36Sopenharmony_ci dev->mt76.q_rx[MT_RXQ_MCU_WA].flags = MT_WED_Q_TXFREE; 49662306a36Sopenharmony_ci } else { 49762306a36Sopenharmony_ci wa_rx_base = MT_RXQ_RING_BASE(MT_RXQ_MCU_WA); 49862306a36Sopenharmony_ci wa_rx_idx = MT_RXQ_ID(MT_RXQ_MCU_WA); 49962306a36Sopenharmony_ci } 50062306a36Sopenharmony_ci ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA], 50162306a36Sopenharmony_ci wa_rx_idx, MT7915_RX_MCU_RING_SIZE, 50262306a36Sopenharmony_ci MT_RX_BUF_SIZE, wa_rx_base); 50362306a36Sopenharmony_ci if (ret) 50462306a36Sopenharmony_ci return ret; 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_ci /* rx data queue for band0 */ 50762306a36Sopenharmony_ci if (!dev->phy.mt76->band_idx) { 50862306a36Sopenharmony_ci if (mtk_wed_device_active(&mdev->mmio.wed) && 50962306a36Sopenharmony_ci mtk_wed_get_rx_capa(&mdev->mmio.wed)) { 51062306a36Sopenharmony_ci dev->mt76.q_rx[MT_RXQ_MAIN].flags = 51162306a36Sopenharmony_ci MT_WED_Q_RX(MT7915_RXQ_BAND0); 51262306a36Sopenharmony_ci dev->mt76.rx_token_size += MT7915_RX_RING_SIZE; 51362306a36Sopenharmony_ci } 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN], 51662306a36Sopenharmony_ci MT_RXQ_ID(MT_RXQ_MAIN), 51762306a36Sopenharmony_ci MT7915_RX_RING_SIZE, 51862306a36Sopenharmony_ci MT_RX_BUF_SIZE, 51962306a36Sopenharmony_ci MT_RXQ_RING_BASE(MT_RXQ_MAIN)); 52062306a36Sopenharmony_ci if (ret) 52162306a36Sopenharmony_ci return ret; 52262306a36Sopenharmony_ci } 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_ci /* tx free notify event from WA for band0 */ 52562306a36Sopenharmony_ci if (!is_mt7915(mdev)) { 52662306a36Sopenharmony_ci wa_rx_base = MT_RXQ_RING_BASE(MT_RXQ_MAIN_WA); 52762306a36Sopenharmony_ci wa_rx_idx = MT_RXQ_ID(MT_RXQ_MAIN_WA); 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci if (mtk_wed_device_active(&mdev->mmio.wed)) { 53062306a36Sopenharmony_ci mdev->q_rx[MT_RXQ_MAIN_WA].flags = MT_WED_Q_TXFREE; 53162306a36Sopenharmony_ci if (is_mt7916(mdev)) { 53262306a36Sopenharmony_ci wa_rx_base = MT_WED_RX_RING_BASE; 53362306a36Sopenharmony_ci wa_rx_idx = MT7915_RXQ_MCU_WA; 53462306a36Sopenharmony_ci } 53562306a36Sopenharmony_ci } 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ci ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN_WA], 53862306a36Sopenharmony_ci wa_rx_idx, MT7915_RX_MCU_RING_SIZE, 53962306a36Sopenharmony_ci MT_RX_BUF_SIZE, wa_rx_base); 54062306a36Sopenharmony_ci if (ret) 54162306a36Sopenharmony_ci return ret; 54262306a36Sopenharmony_ci } 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_ci if (dev->dbdc_support || dev->phy.mt76->band_idx) { 54562306a36Sopenharmony_ci if (mtk_wed_device_active(&mdev->mmio.wed) && 54662306a36Sopenharmony_ci mtk_wed_get_rx_capa(&mdev->mmio.wed)) { 54762306a36Sopenharmony_ci dev->mt76.q_rx[MT_RXQ_BAND1].flags = 54862306a36Sopenharmony_ci MT_WED_Q_RX(MT7915_RXQ_BAND1); 54962306a36Sopenharmony_ci dev->mt76.rx_token_size += MT7915_RX_RING_SIZE; 55062306a36Sopenharmony_ci } 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci /* rx data queue for band1 */ 55362306a36Sopenharmony_ci ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND1], 55462306a36Sopenharmony_ci MT_RXQ_ID(MT_RXQ_BAND1), 55562306a36Sopenharmony_ci MT7915_RX_RING_SIZE, 55662306a36Sopenharmony_ci MT_RX_BUF_SIZE, 55762306a36Sopenharmony_ci MT_RXQ_RING_BASE(MT_RXQ_BAND1) + hif1_ofs); 55862306a36Sopenharmony_ci if (ret) 55962306a36Sopenharmony_ci return ret; 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci /* tx free notify event from WA for band1 */ 56262306a36Sopenharmony_ci ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND1_WA], 56362306a36Sopenharmony_ci MT_RXQ_ID(MT_RXQ_BAND1_WA), 56462306a36Sopenharmony_ci MT7915_RX_MCU_RING_SIZE, 56562306a36Sopenharmony_ci MT_RX_BUF_SIZE, 56662306a36Sopenharmony_ci MT_RXQ_RING_BASE(MT_RXQ_BAND1_WA) + hif1_ofs); 56762306a36Sopenharmony_ci if (ret) 56862306a36Sopenharmony_ci return ret; 56962306a36Sopenharmony_ci } 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_ci ret = mt76_init_queues(dev, mt76_dma_rx_poll); 57262306a36Sopenharmony_ci if (ret < 0) 57362306a36Sopenharmony_ci return ret; 57462306a36Sopenharmony_ci 57562306a36Sopenharmony_ci netif_napi_add_tx(&dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, 57662306a36Sopenharmony_ci mt7915_poll_tx); 57762306a36Sopenharmony_ci napi_enable(&dev->mt76.tx_napi); 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci mt7915_dma_enable(dev, false); 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci return 0; 58262306a36Sopenharmony_ci} 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_cistatic void mt7915_dma_wed_reset(struct mt7915_dev *dev) 58562306a36Sopenharmony_ci{ 58662306a36Sopenharmony_ci struct mt76_dev *mdev = &dev->mt76; 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_ci if (!test_bit(MT76_STATE_WED_RESET, &dev->mphy.state)) 58962306a36Sopenharmony_ci return; 59062306a36Sopenharmony_ci 59162306a36Sopenharmony_ci complete(&mdev->mmio.wed_reset); 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ci if (!wait_for_completion_timeout(&dev->mt76.mmio.wed_reset_complete, 59462306a36Sopenharmony_ci 3 * HZ)) 59562306a36Sopenharmony_ci dev_err(dev->mt76.dev, "wed reset complete timeout\n"); 59662306a36Sopenharmony_ci} 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_cistatic void 59962306a36Sopenharmony_cimt7915_dma_reset_tx_queue(struct mt7915_dev *dev, struct mt76_queue *q) 60062306a36Sopenharmony_ci{ 60162306a36Sopenharmony_ci mt76_queue_reset(dev, q); 60262306a36Sopenharmony_ci if (mtk_wed_device_active(&dev->mt76.mmio.wed)) 60362306a36Sopenharmony_ci mt76_dma_wed_setup(&dev->mt76, q, true); 60462306a36Sopenharmony_ci} 60562306a36Sopenharmony_ci 60662306a36Sopenharmony_ciint mt7915_dma_reset(struct mt7915_dev *dev, bool force) 60762306a36Sopenharmony_ci{ 60862306a36Sopenharmony_ci struct mt76_phy *mphy_ext = dev->mt76.phys[MT_BAND1]; 60962306a36Sopenharmony_ci struct mtk_wed_device *wed = &dev->mt76.mmio.wed; 61062306a36Sopenharmony_ci int i; 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_ci /* clean up hw queues */ 61362306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(dev->mt76.phy.q_tx); i++) { 61462306a36Sopenharmony_ci mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[i], true); 61562306a36Sopenharmony_ci if (mphy_ext) 61662306a36Sopenharmony_ci mt76_queue_tx_cleanup(dev, mphy_ext->q_tx[i], true); 61762306a36Sopenharmony_ci } 61862306a36Sopenharmony_ci 61962306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(dev->mt76.q_mcu); i++) 62062306a36Sopenharmony_ci mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[i], true); 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_ci mt76_for_each_q_rx(&dev->mt76, i) 62362306a36Sopenharmony_ci mt76_queue_rx_cleanup(dev, &dev->mt76.q_rx[i]); 62462306a36Sopenharmony_ci 62562306a36Sopenharmony_ci /* reset wfsys */ 62662306a36Sopenharmony_ci if (force) 62762306a36Sopenharmony_ci mt7915_wfsys_reset(dev); 62862306a36Sopenharmony_ci 62962306a36Sopenharmony_ci if (mtk_wed_device_active(wed)) 63062306a36Sopenharmony_ci mtk_wed_device_dma_reset(wed); 63162306a36Sopenharmony_ci 63262306a36Sopenharmony_ci mt7915_dma_disable(dev, force); 63362306a36Sopenharmony_ci mt7915_dma_wed_reset(dev); 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci /* reset hw queues */ 63662306a36Sopenharmony_ci for (i = 0; i < __MT_TXQ_MAX; i++) { 63762306a36Sopenharmony_ci mt7915_dma_reset_tx_queue(dev, dev->mphy.q_tx[i]); 63862306a36Sopenharmony_ci if (mphy_ext) 63962306a36Sopenharmony_ci mt7915_dma_reset_tx_queue(dev, mphy_ext->q_tx[i]); 64062306a36Sopenharmony_ci } 64162306a36Sopenharmony_ci 64262306a36Sopenharmony_ci for (i = 0; i < __MT_MCUQ_MAX; i++) 64362306a36Sopenharmony_ci mt76_queue_reset(dev, dev->mt76.q_mcu[i]); 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci mt76_for_each_q_rx(&dev->mt76, i) { 64662306a36Sopenharmony_ci if (dev->mt76.q_rx[i].flags == MT_WED_Q_TXFREE) 64762306a36Sopenharmony_ci continue; 64862306a36Sopenharmony_ci 64962306a36Sopenharmony_ci mt76_queue_reset(dev, &dev->mt76.q_rx[i]); 65062306a36Sopenharmony_ci } 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_ci mt76_tx_status_check(&dev->mt76, true); 65362306a36Sopenharmony_ci 65462306a36Sopenharmony_ci mt76_for_each_q_rx(&dev->mt76, i) 65562306a36Sopenharmony_ci mt76_queue_rx_reset(dev, i); 65662306a36Sopenharmony_ci 65762306a36Sopenharmony_ci if (mtk_wed_device_active(wed) && is_mt7915(&dev->mt76)) 65862306a36Sopenharmony_ci mt76_rmw(dev, MT_WFDMA0_EXT0_CFG, MT_WFDMA0_EXT0_RXWB_KEEP, 65962306a36Sopenharmony_ci MT_WFDMA0_EXT0_RXWB_KEEP); 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_ci mt7915_dma_enable(dev, !force); 66262306a36Sopenharmony_ci 66362306a36Sopenharmony_ci return 0; 66462306a36Sopenharmony_ci} 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_civoid mt7915_dma_cleanup(struct mt7915_dev *dev) 66762306a36Sopenharmony_ci{ 66862306a36Sopenharmony_ci mt7915_dma_disable(dev, true); 66962306a36Sopenharmony_ci 67062306a36Sopenharmony_ci mt76_dma_cleanup(&dev->mt76); 67162306a36Sopenharmony_ci} 672