1 // SPDX-License-Identifier: ISC 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 4 #include "mt7915.h" 5 #include "../dma.h" 6 #include "mac.h" 7 8 int mt7915_init_tx_queues(struct mt7915_phy *phy, int idx, int n_desc) 9 { 10 int i, err; 11 12 err = mt76_init_tx_queue(phy->mt76, 0, idx, n_desc, MT_TX_RING_BASE); 13 if (err < 0) 14 return err; 15 16 for (i = 0; i <= MT_TXQ_PSD; i++) 17 phy->mt76->q_tx[i] = phy->mt76->q_tx[0]; 18 19 return 0; 20 } 21 22 static void 23 mt7915_tx_cleanup(struct mt7915_dev *dev) 24 { 25 mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WM], false); 26 mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WA], false); 27 } 28 29 static int mt7915_poll_tx(struct napi_struct *napi, int budget) 30 { 31 struct mt7915_dev *dev; 32 33 dev = container_of(napi, struct mt7915_dev, mt76.tx_napi); 34 35 mt7915_tx_cleanup(dev); 36 37 if (napi_complete_done(napi, 0)) 38 mt7915_irq_enable(dev, MT_INT_TX_DONE_MCU); 39 40 return 0; 41 } 42 43 static void __mt7915_dma_prefetch(struct mt7915_dev *dev, u32 ofs) 44 { 45 #define PREFETCH(base, depth) ((base) << 16 | (depth)) 46 47 mt76_wr(dev, MT_WFDMA0_RX_RING0_EXT_CTRL + ofs, PREFETCH(0x0, 0x4)); 48 mt76_wr(dev, MT_WFDMA0_RX_RING1_EXT_CTRL + ofs, PREFETCH(0x40, 0x4)); 49 mt76_wr(dev, MT_WFDMA0_RX_RING2_EXT_CTRL + ofs, PREFETCH(0x80, 0x0)); 50 51 mt76_wr(dev, MT_WFDMA1_TX_RING0_EXT_CTRL + ofs, PREFETCH(0x80, 0x4)); 52 mt76_wr(dev, MT_WFDMA1_TX_RING1_EXT_CTRL + ofs, PREFETCH(0xc0, 0x4)); 53 mt76_wr(dev, MT_WFDMA1_TX_RING2_EXT_CTRL + ofs, PREFETCH(0x100, 0x4)); 54 mt76_wr(dev, MT_WFDMA1_TX_RING3_EXT_CTRL + ofs, PREFETCH(0x140, 0x4)); 55 mt76_wr(dev, MT_WFDMA1_TX_RING4_EXT_CTRL + ofs, PREFETCH(0x180, 0x4)); 56 mt76_wr(dev, MT_WFDMA1_TX_RING5_EXT_CTRL + ofs, PREFETCH(0x1c0, 0x4)); 57 mt76_wr(dev, MT_WFDMA1_TX_RING6_EXT_CTRL + ofs, PREFETCH(0x200, 0x4)); 58 mt76_wr(dev, MT_WFDMA1_TX_RING7_EXT_CTRL + ofs, PREFETCH(0x240, 0x4)); 59 60 mt76_wr(dev, MT_WFDMA1_TX_RING16_EXT_CTRL + ofs, PREFETCH(0x280, 0x4)); 61 mt76_wr(dev, MT_WFDMA1_TX_RING17_EXT_CTRL + ofs, PREFETCH(0x2c0, 0x4)); 62 mt76_wr(dev, MT_WFDMA1_TX_RING18_EXT_CTRL + ofs, PREFETCH(0x300, 0x4)); 63 mt76_wr(dev, MT_WFDMA1_TX_RING19_EXT_CTRL + ofs, PREFETCH(0x340, 0x4)); 64 mt76_wr(dev, MT_WFDMA1_TX_RING20_EXT_CTRL + ofs, PREFETCH(0x380, 0x4)); 65 mt76_wr(dev, MT_WFDMA1_TX_RING21_EXT_CTRL + ofs, PREFETCH(0x3c0, 0x0)); 66 67 mt76_wr(dev, MT_WFDMA1_RX_RING0_EXT_CTRL + ofs, PREFETCH(0x3c0, 0x4)); 68 mt76_wr(dev, MT_WFDMA1_RX_RING1_EXT_CTRL + ofs, PREFETCH(0x400, 0x4)); 69 mt76_wr(dev, MT_WFDMA1_RX_RING2_EXT_CTRL + ofs, PREFETCH(0x440, 0x4)); 70 mt76_wr(dev, MT_WFDMA1_RX_RING3_EXT_CTRL + ofs, PREFETCH(0x480, 0x0)); 71 } 72 73 void mt7915_dma_prefetch(struct mt7915_dev *dev) 74 { 75 __mt7915_dma_prefetch(dev, 0); 76 if (dev->hif2) 77 __mt7915_dma_prefetch(dev, MT_WFDMA1_PCIE1_BASE - MT_WFDMA1_BASE); 78 } 79 80 int mt7915_dma_init(struct mt7915_dev *dev) 81 { 82 u32 hif1_ofs = 0; 83 int ret; 84 85 mt76_dma_attach(&dev->mt76); 86 87 if (dev->hif2) 88 hif1_ofs = MT_WFDMA1_PCIE1_BASE - MT_WFDMA1_BASE; 89 90 /* configure global setting */ 91 mt76_set(dev, MT_WFDMA1_GLO_CFG, 92 MT_WFDMA1_GLO_CFG_OMIT_TX_INFO | 93 MT_WFDMA1_GLO_CFG_OMIT_RX_INFO); 94 95 /* reset dma idx */ 96 mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR, ~0); 97 mt76_wr(dev, MT_WFDMA1_RST_DTX_PTR, ~0); 98 99 /* configure delay interrupt */ 100 mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG0, 0); 101 mt76_wr(dev, MT_WFDMA1_PRI_DLY_INT_CFG0, 0); 102 103 if (dev->hif2) { 104 mt76_set(dev, MT_WFDMA1_GLO_CFG + hif1_ofs, 105 MT_WFDMA1_GLO_CFG_OMIT_TX_INFO | 106 MT_WFDMA1_GLO_CFG_OMIT_RX_INFO); 107 108 mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR + hif1_ofs, ~0); 109 mt76_wr(dev, MT_WFDMA1_RST_DTX_PTR + hif1_ofs, ~0); 110 111 mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG0 + hif1_ofs, 0); 112 mt76_wr(dev, MT_WFDMA1_PRI_DLY_INT_CFG0 + hif1_ofs, 0); 113 } 114 115 /* configure perfetch settings */ 116 mt7915_dma_prefetch(dev); 117 118 /* init tx queue */ 119 ret = mt7915_init_tx_queues(&dev->phy, MT7915_TXQ_BAND0, 120 MT7915_TX_RING_SIZE); 121 if (ret) 122 return ret; 123 124 /* command to WM */ 125 ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WM, MT7915_TXQ_MCU_WM, 126 MT7915_TX_MCU_RING_SIZE, MT_TX_RING_BASE); 127 if (ret) 128 return ret; 129 130 /* command to WA */ 131 ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WA, MT7915_TXQ_MCU_WA, 132 MT7915_TX_MCU_RING_SIZE, MT_TX_RING_BASE); 133 if (ret) 134 return ret; 135 136 /* firmware download */ 137 ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_FWDL, MT7915_TXQ_FWDL, 138 MT7915_TX_FWDL_RING_SIZE, MT_TX_RING_BASE); 139 if (ret) 140 return ret; 141 142 /* event from WM */ 143 ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU], 144 MT7915_RXQ_MCU_WM, MT7915_RX_MCU_RING_SIZE, 145 MT_RX_BUF_SIZE, MT_RX_EVENT_RING_BASE); 146 if (ret) 147 return ret; 148 149 /* event from WA */ 150 ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA], 151 MT7915_RXQ_MCU_WA, MT7915_RX_MCU_RING_SIZE, 152 MT_RX_BUF_SIZE, MT_RX_EVENT_RING_BASE); 153 if (ret) 154 return ret; 155 156 /* rx data queue */ 157 ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN], 158 MT7915_RXQ_BAND0, MT7915_RX_RING_SIZE, 159 MT_RX_BUF_SIZE, MT_RX_DATA_RING_BASE); 160 if (ret) 161 return ret; 162 163 if (dev->dbdc_support) { 164 ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_EXT], 165 MT7915_RXQ_BAND1, MT7915_RX_RING_SIZE, 166 MT_RX_BUF_SIZE, 167 MT_RX_DATA_RING_BASE + hif1_ofs); 168 if (ret) 169 return ret; 170 171 /* event from WA */ 172 ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_EXT_WA], 173 MT7915_RXQ_MCU_WA_EXT, 174 MT7915_RX_MCU_RING_SIZE, 175 MT_RX_BUF_SIZE, 176 MT_RX_EVENT_RING_BASE + hif1_ofs); 177 if (ret) 178 return ret; 179 } 180 181 ret = mt76_init_queues(dev, mt76_dma_rx_poll); 182 if (ret < 0) 183 return ret; 184 185 netif_tx_napi_add(&dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, 186 mt7915_poll_tx, NAPI_POLL_WEIGHT); 187 napi_enable(&dev->mt76.tx_napi); 188 189 /* hif wait WFDMA idle */ 190 mt76_set(dev, MT_WFDMA0_BUSY_ENA, 191 MT_WFDMA0_BUSY_ENA_TX_FIFO0 | 192 MT_WFDMA0_BUSY_ENA_TX_FIFO1 | 193 MT_WFDMA0_BUSY_ENA_RX_FIFO); 194 195 mt76_set(dev, MT_WFDMA1_BUSY_ENA, 196 MT_WFDMA1_BUSY_ENA_TX_FIFO0 | 197 MT_WFDMA1_BUSY_ENA_TX_FIFO1 | 198 MT_WFDMA1_BUSY_ENA_RX_FIFO); 199 200 mt76_set(dev, MT_WFDMA0_PCIE1_BUSY_ENA, 201 MT_WFDMA0_PCIE1_BUSY_ENA_TX_FIFO0 | 202 MT_WFDMA0_PCIE1_BUSY_ENA_TX_FIFO1 | 203 MT_WFDMA0_PCIE1_BUSY_ENA_RX_FIFO); 204 205 mt76_set(dev, MT_WFDMA1_PCIE1_BUSY_ENA, 206 MT_WFDMA1_PCIE1_BUSY_ENA_TX_FIFO0 | 207 MT_WFDMA1_PCIE1_BUSY_ENA_TX_FIFO1 | 208 MT_WFDMA1_PCIE1_BUSY_ENA_RX_FIFO); 209 210 mt76_poll(dev, MT_WFDMA_EXT_CSR_HIF_MISC, 211 MT_WFDMA_EXT_CSR_HIF_MISC_BUSY, 0, 1000); 212 213 /* set WFDMA Tx/Rx */ 214 mt76_set(dev, MT_WFDMA0_GLO_CFG, 215 MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN); 216 mt76_set(dev, MT_WFDMA1_GLO_CFG, 217 MT_WFDMA1_GLO_CFG_TX_DMA_EN | MT_WFDMA1_GLO_CFG_RX_DMA_EN); 218 219 if (dev->hif2) { 220 mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs, 221 (MT_WFDMA0_GLO_CFG_TX_DMA_EN | 222 MT_WFDMA0_GLO_CFG_RX_DMA_EN)); 223 mt76_set(dev, MT_WFDMA1_GLO_CFG + hif1_ofs, 224 (MT_WFDMA1_GLO_CFG_TX_DMA_EN | 225 MT_WFDMA1_GLO_CFG_RX_DMA_EN)); 226 mt76_set(dev, MT_WFDMA_HOST_CONFIG, 227 MT_WFDMA_HOST_CONFIG_PDMA_BAND); 228 } 229 230 /* enable interrupts for TX/RX rings */ 231 mt7915_irq_enable(dev, MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_MCU | 232 MT_INT_MCU_CMD); 233 234 return 0; 235 } 236 237 void mt7915_dma_cleanup(struct mt7915_dev *dev) 238 { 239 /* disable */ 240 mt76_clear(dev, MT_WFDMA0_GLO_CFG, 241 MT_WFDMA0_GLO_CFG_TX_DMA_EN | 242 MT_WFDMA0_GLO_CFG_RX_DMA_EN); 243 mt76_clear(dev, MT_WFDMA1_GLO_CFG, 244 MT_WFDMA1_GLO_CFG_TX_DMA_EN | 245 MT_WFDMA1_GLO_CFG_RX_DMA_EN); 246 247 /* reset */ 248 mt76_clear(dev, MT_WFDMA1_RST, 249 MT_WFDMA1_RST_DMASHDL_ALL_RST | 250 MT_WFDMA1_RST_LOGIC_RST); 251 252 mt76_set(dev, MT_WFDMA1_RST, 253 MT_WFDMA1_RST_DMASHDL_ALL_RST | 254 MT_WFDMA1_RST_LOGIC_RST); 255 256 mt76_clear(dev, MT_WFDMA0_RST, 257 MT_WFDMA0_RST_DMASHDL_ALL_RST | 258 MT_WFDMA0_RST_LOGIC_RST); 259 260 mt76_set(dev, MT_WFDMA0_RST, 261 MT_WFDMA0_RST_DMASHDL_ALL_RST | 262 MT_WFDMA0_RST_LOGIC_RST); 263 264 mt76_dma_cleanup(&dev->mt76); 265 } 266