1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2025 AIROHA Inc 4 * Author: Lorenzo Bianconi <lorenzo@kernel.org> 5 */ 6 #include <linux/kernel.h> 7 #include <linux/soc/airoha/airoha_offload.h> 8 9 #include "mt7996.h" 10 11 static int mt7996_npu_offload_init(struct mt7996_dev *dev, 12 struct airoha_npu *npu) 13 { 14 phys_addr_t phy_addr = dev->mt76.mmio.phy_addr; 15 u32 val, hif1_ofs = 0, dma_addr; 16 int i, err; 17 18 err = mt76_npu_get_msg(npu, 0, WLAN_FUNC_GET_WAIT_NPU_VERSION, 19 &val, GFP_KERNEL); 20 if (err) { 21 dev_warn(dev->mt76.dev, "failed getting NPU fw version\n"); 22 return err; 23 } 24 25 dev_info(dev->mt76.dev, "NPU version: %0d.%d\n", 26 (val >> 16) & 0xffff, val & 0xffff); 27 28 err = mt76_npu_send_msg(npu, 0, WLAN_FUNC_SET_WAIT_PCIE_PORT_TYPE, 29 dev->mt76.mmio.npu_type, GFP_KERNEL); 30 if (err) { 31 dev_warn(dev->mt76.dev, 32 "failed setting NPU wlan PCIe port type\n"); 33 return err; 34 } 35 36 if (dev->hif2) 37 hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0); 38 39 for (i = MT_BAND0; i < MT_BAND2; i++) { 40 dma_addr = phy_addr; 41 if (i) 42 dma_addr += MT_RXQ_RING_BASE(MT_RXQ_RRO_BAND1) + 0x90 + 43 hif1_ofs; 44 else 45 dma_addr += MT_RXQ_RING_BASE(MT_RXQ_RRO_BAND0) + 0x80; 46 47 err = mt76_npu_send_msg(npu, i, WLAN_FUNC_SET_WAIT_PCIE_ADDR, 48 dma_addr, GFP_KERNEL); 49 if (err) { 50 dev_warn(dev->mt76.dev, 51 "failed setting NPU wlan PCIe desc addr\n"); 52 return err; 53 } 54 55 err = mt76_npu_send_msg(npu, i, WLAN_FUNC_SET_WAIT_DESC, 56 MT7996_RX_RING_SIZE, GFP_KERNEL); 57 if (err) { 58 dev_warn(dev->mt76.dev, 59 "failed setting NPU wlan PCIe desc size\n"); 60 return err; 61 } 62 63 dma_addr = phy_addr; 64 if (i) 65 dma_addr += MT_TXQ_RING_BASE(0) + 0x150 + hif1_ofs; 66 else 67 dma_addr += MT_TXQ_RING_BASE(0) + 0x120; 68 69 err = mt76_npu_send_msg(npu, i, 70 WLAN_FUNC_SET_WAIT_TX_RING_PCIE_ADDR, 71 dma_addr, GFP_KERNEL); 72 if (err) { 73 dev_warn(dev->mt76.dev, 74 "failed setting NPU wlan tx desc addr\n"); 75 return err; 76 } 77 } 78 79 err = mt76_npu_send_msg(npu, 9, WLAN_FUNC_SET_WAIT_PCIE_ADDR, 80 phy_addr + MT_RXQ_RRO_AP_RING_BASE, 81 GFP_KERNEL); 82 if (err) { 83 dev_warn(dev->mt76.dev, 84 "failed setting NPU wlan rxdmad_c addr\n"); 85 return err; 86 } 87 88 err = mt76_npu_send_msg(npu, 9, WLAN_FUNC_SET_WAIT_DESC, 89 MT7996_RX_RING_SIZE, GFP_KERNEL); 90 if (err) { 91 dev_warn(dev->mt76.dev, 92 "failed setting NPU wlan rxdmad_c desc size\n"); 93 return err; 94 } 95 96 err = mt76_npu_send_msg(npu, 2, WLAN_FUNC_SET_WAIT_TX_RING_PCIE_ADDR, 97 phy_addr + MT_RRO_ACK_SN_CTRL, GFP_KERNEL); 98 if (err) { 99 dev_warn(dev->mt76.dev, 100 "failed setting NPU wlan rro_ack_sn desc addr\n"); 101 return err; 102 } 103 104 err = mt76_npu_send_msg(npu, 0, WLAN_FUNC_SET_WAIT_TOKEN_ID_SIZE, 105 MT7996_HW_TOKEN_SIZE, GFP_KERNEL); 106 if (err) 107 return err; 108 109 dev->mt76.token_start = MT7996_HW_TOKEN_SIZE; 110 111 return 0; 112 } 113 114 static int mt7996_npu_rxd_init(struct mt7996_dev *dev, struct airoha_npu *npu) 115 { 116 u32 val; 117 int err; 118 119 err = mt76_npu_get_msg(npu, 0, WLAN_FUNC_GET_WAIT_RXDESC_BASE, 120 &val, GFP_KERNEL); 121 if (err) { 122 dev_warn(dev->mt76.dev, 123 "failed retriving NPU wlan rx ring0 addr\n"); 124 return err; 125 } 126 writel(val, &dev->mt76.q_rx[MT_RXQ_RRO_BAND0].regs->desc_base); 127 128 err = mt76_npu_get_msg(npu, 1, WLAN_FUNC_GET_WAIT_RXDESC_BASE, 129 &val, GFP_KERNEL); 130 if (err) { 131 dev_warn(dev->mt76.dev, 132 "failed retriving NPU wlan rx ring1 addr\n"); 133 return err; 134 } 135 writel(val, &dev->mt76.q_rx[MT_RXQ_RRO_BAND1].regs->desc_base); 136 137 err = mt76_npu_get_msg(npu, 9, WLAN_FUNC_GET_WAIT_RXDESC_BASE, 138 &val, GFP_KERNEL); 139 if (err) { 140 dev_warn(dev->mt76.dev, 141 "failed retriving NPU wlan rxdmad_c ring addr\n"); 142 return err; 143 } 144 writel(val, &dev->mt76.q_rx[MT_RXQ_RRO_RXDMAD_C].regs->desc_base); 145 146 return 0; 147 } 148 149 static int mt7996_npu_txd_init(struct mt7996_dev *dev, struct airoha_npu *npu) 150 { 151 int i, err; 152 153 for (i = MT_BAND0; i < MT_BAND2; i++) { 154 dma_addr_t dma_addr; 155 u32 val; 156 157 err = mt76_npu_get_msg(npu, i + 5, 158 WLAN_FUNC_GET_WAIT_RXDESC_BASE, 159 &val, GFP_KERNEL); 160 if (err) { 161 dev_warn(dev->mt76.dev, 162 "failed retriving NPU wlan tx ring addr\n"); 163 return err; 164 } 165 writel(val, &dev->mt76.phys[i]->q_tx[0]->regs->desc_base); 166 167 if (!dmam_alloc_coherent(dev->mt76.dma_dev, 168 256 * MT7996_TX_RING_SIZE, 169 &dma_addr, GFP_KERNEL)) 170 return -ENOMEM; 171 172 err = mt76_npu_send_msg(npu, i, 173 WLAN_FUNC_SET_WAIT_TX_BUF_SPACE_HW_BASE, 174 dma_addr, GFP_KERNEL); 175 if (err) { 176 dev_warn(dev->mt76.dev, 177 "failed setting NPU wlan queue buf addr\n"); 178 return err; 179 } 180 181 if (!dmam_alloc_coherent(dev->mt76.dma_dev, 182 256 * MT7996_TX_RING_SIZE, 183 &dma_addr, GFP_KERNEL)) 184 return -ENOMEM; 185 186 err = mt76_npu_send_msg(npu, i + 5, 187 WLAN_FUNC_SET_WAIT_TX_BUF_SPACE_HW_BASE, 188 dma_addr, GFP_KERNEL); 189 if (err) { 190 dev_warn(dev->mt76.dev, 191 "failed setting NPU wlan tx buf addr\n"); 192 return err; 193 } 194 195 if (!dmam_alloc_coherent(dev->mt76.dma_dev, 256 * 1024, 196 &dma_addr, GFP_KERNEL)) 197 return -ENOMEM; 198 199 err = mt76_npu_send_msg(npu, i + 10, 200 WLAN_FUNC_SET_WAIT_TX_BUF_SPACE_HW_BASE, 201 dma_addr, GFP_KERNEL); 202 if (err) { 203 dev_warn(dev->mt76.dev, 204 "failed setting NPU wlan tx buf base\n"); 205 return err; 206 } 207 } 208 209 return 0; 210 } 211 212 static int mt7996_npu_rx_event_init(struct mt7996_dev *dev, 213 struct airoha_npu *npu) 214 { 215 struct mt76_queue *q = &dev->mt76.q_rx[MT_RXQ_MAIN_WA]; 216 phys_addr_t phy_addr = dev->mt76.mmio.phy_addr; 217 int err; 218 219 err = mt76_npu_send_msg(npu, 0, 220 WLAN_FUNC_SET_WAIT_RX_RING_FOR_TXDONE_HW_BASE, 221 q->desc_dma, GFP_KERNEL); 222 if (err) { 223 dev_warn(dev->mt76.dev, 224 "failed setting NPU wlan tx-done ring\n"); 225 return err; 226 } 227 228 err = mt76_npu_send_msg(npu, 10, WLAN_FUNC_SET_WAIT_DESC, 229 MT7996_RX_MCU_RING_SIZE, GFP_KERNEL); 230 if (err) { 231 dev_warn(dev->mt76.dev, 232 "failed setting NPU wlan descriptors\n"); 233 return err; 234 } 235 236 phy_addr += MT_RXQ_RING_BASE(MT_RXQ_MAIN_WA) + 0x20; 237 err = mt76_npu_send_msg(npu, 10, WLAN_FUNC_SET_WAIT_PCIE_ADDR, 238 phy_addr, GFP_KERNEL); 239 if (err) 240 dev_warn(dev->mt76.dev, 241 "failed setting NPU wlan rx pcie address\n"); 242 return err; 243 } 244 245 static int mt7996_npu_tx_done_init(struct mt7996_dev *dev, 246 struct airoha_npu *npu) 247 { 248 int err; 249 250 err = mt76_npu_send_msg(npu, 2, WLAN_FUNC_SET_WAIT_INODE_TXRX_REG_ADDR, 251 0, GFP_KERNEL); 252 if (err) { 253 dev_warn(dev->mt76.dev, "failed setting NPU wlan txrx addr2\n"); 254 return err; 255 } 256 257 err = mt76_npu_send_msg(npu, 7, WLAN_FUNC_SET_WAIT_INODE_TXRX_REG_ADDR, 258 0, GFP_KERNEL); 259 if (err) 260 dev_warn(dev->mt76.dev, "failed setting NPU wlan txrx addr7\n"); 261 262 return err; 263 } 264 265 int mt7996_npu_rx_queues_init(struct mt7996_dev *dev) 266 { 267 int err; 268 269 if (!mt76_npu_device_active(&dev->mt76)) 270 return 0; 271 272 err = mt76_npu_rx_queue_init(&dev->mt76, 273 &dev->mt76.q_rx[MT_RXQ_NPU0]); 274 if (err) 275 return err; 276 277 return mt76_npu_rx_queue_init(&dev->mt76, 278 &dev->mt76.q_rx[MT_RXQ_NPU1]); 279 } 280 281 int mt7996_npu_hw_init(struct mt7996_dev *dev) 282 { 283 struct airoha_npu *npu; 284 int i, err = 0; 285 286 mutex_lock(&dev->mt76.mutex); 287 288 npu = rcu_dereference_protected(dev->mt76.mmio.npu, &dev->mt76.mutex); 289 if (!npu) 290 goto unlock; 291 292 err = mt7996_npu_offload_init(dev, npu); 293 if (err) 294 goto unlock; 295 296 err = mt7996_npu_rxd_init(dev, npu); 297 if (err) 298 goto unlock; 299 300 err = mt7996_npu_txd_init(dev, npu); 301 if (err) 302 goto unlock; 303 304 err = mt7996_npu_rx_event_init(dev, npu); 305 if (err) 306 goto unlock; 307 308 err = mt7996_npu_tx_done_init(dev, npu); 309 if (err) 310 goto unlock; 311 312 for (i = MT_RXQ_NPU0; i <= MT_RXQ_NPU1; i++) 313 airoha_npu_wlan_enable_irq(npu, i - MT_RXQ_NPU0); 314 unlock: 315 mutex_unlock(&dev->mt76.mutex); 316 317 return err; 318 } 319 320 int mt7996_npu_hw_stop(struct mt7996_dev *dev) 321 { 322 struct airoha_npu *npu; 323 int i, err; 324 u32 info; 325 326 npu = rcu_dereference_protected(dev->mt76.mmio.npu, &dev->mt76.mutex); 327 if (!npu) 328 return 0; 329 330 err = mt76_npu_send_msg(npu, 4, WLAN_FUNC_SET_WAIT_INODE_TXRX_REG_ADDR, 331 0, GFP_KERNEL); 332 if (err) 333 return err; 334 335 for (i = 0; i < 10; i++) { 336 err = mt76_npu_get_msg(npu, 3, WLAN_FUNC_GET_WAIT_NPU_INFO, 337 &info, GFP_KERNEL); 338 if (err) 339 continue; 340 341 if (info) { 342 err = -ETIMEDOUT; 343 continue; 344 } 345 } 346 347 if (!err) 348 err = mt76_npu_send_msg(npu, 6, 349 WLAN_FUNC_SET_WAIT_INODE_TXRX_REG_ADDR, 350 0, GFP_KERNEL); 351 return err; 352 } 353