1 // SPDX-License-Identifier: ISC 2 /* Copyright (C) 2020 MediaTek Inc. 3 * 4 */ 5 6 #include <linux/kernel.h> 7 #include <linux/module.h> 8 #include <linux/pci.h> 9 10 #include "mt7921.h" 11 #include "mac.h" 12 #include "mcu.h" 13 #include "../trace.h" 14 15 static const struct pci_device_id mt7921_pci_device_table[] = { 16 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7961) }, 17 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7922) }, 18 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x0608) }, 19 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x0616) }, 20 { }, 21 }; 22 23 static bool mt7921_disable_aspm; 24 module_param_named(disable_aspm, mt7921_disable_aspm, bool, 0644); 25 MODULE_PARM_DESC(disable_aspm, "disable PCI ASPM support"); 26 27 static void 28 mt7921_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q) 29 { 30 struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); 31 32 if (q == MT_RXQ_MAIN) 33 mt7921_irq_enable(dev, MT_INT_RX_DONE_DATA); 34 else if (q == MT_RXQ_MCU_WA) 35 mt7921_irq_enable(dev, MT_INT_RX_DONE_WM2); 36 else 37 mt7921_irq_enable(dev, MT_INT_RX_DONE_WM); 38 } 39 40 static irqreturn_t mt7921_irq_handler(int irq, void *dev_instance) 41 { 42 struct mt7921_dev *dev = dev_instance; 43 44 mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0); 45 46 if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state)) 47 return IRQ_NONE; 48 49 tasklet_schedule(&dev->irq_tasklet); 50 51 return IRQ_HANDLED; 52 } 53 54 static void mt7921_irq_tasklet(unsigned long data) 55 { 56 struct mt7921_dev *dev = (struct mt7921_dev *)data; 57 u32 intr, mask = 0; 58 59 mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0); 60 61 intr = mt76_rr(dev, MT_WFDMA0_HOST_INT_STA); 62 intr &= dev->mt76.mmio.irqmask; 63 mt76_wr(dev, MT_WFDMA0_HOST_INT_STA, intr); 64 65 trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask); 66 67 mask |= intr & MT_INT_RX_DONE_ALL; 68 if (intr & MT_INT_TX_DONE_MCU) 69 mask |= MT_INT_TX_DONE_MCU; 70 71 if (intr & MT_INT_MCU_CMD) { 72 u32 intr_sw; 73 74 intr_sw = mt76_rr(dev, MT_MCU_CMD); 75 /* ack MCU2HOST_SW_INT_STA */ 76 mt76_wr(dev, MT_MCU_CMD, intr_sw); 77 if (intr_sw & MT_MCU_CMD_WAKE_RX_PCIE) { 78 mask |= MT_INT_RX_DONE_DATA; 79 intr |= MT_INT_RX_DONE_DATA; 80 } 81 } 82 83 mt76_set_irq_mask(&dev->mt76, MT_WFDMA0_HOST_INT_ENA, mask, 0); 84 85 if (intr & MT_INT_TX_DONE_ALL) 86 napi_schedule(&dev->mt76.tx_napi); 87 88 if (intr & MT_INT_RX_DONE_WM) 89 napi_schedule(&dev->mt76.napi[MT_RXQ_MCU]); 90 91 if (intr & MT_INT_RX_DONE_WM2) 92 napi_schedule(&dev->mt76.napi[MT_RXQ_MCU_WA]); 93 94 if (intr & MT_INT_RX_DONE_DATA) 95 napi_schedule(&dev->mt76.napi[MT_RXQ_MAIN]); 96 } 97 98 static int mt7921e_init_reset(struct mt7921_dev *dev) 99 { 100 return mt7921_wpdma_reset(dev, true); 101 } 102 103 static void mt7921e_unregister_device(struct mt7921_dev *dev) 104 { 105 int i; 106 struct mt76_connac_pm *pm = &dev->pm; 107 108 mt76_unregister_device(&dev->mt76); 109 mt76_for_each_q_rx(&dev->mt76, i) 110 napi_disable(&dev->mt76.napi[i]); 111 cancel_delayed_work_sync(&pm->ps_work); 112 cancel_work_sync(&pm->wake_work); 113 114 mt7921_tx_token_put(dev); 115 mt7921_mcu_drv_pmctrl(dev); 116 mt7921_dma_cleanup(dev); 117 mt7921_wfsys_reset(dev); 118 mt7921_mcu_exit(dev); 119 120 tasklet_disable(&dev->irq_tasklet); 121 mt76_free_device(&dev->mt76); 122 } 123 124 static int mt7921_pci_probe(struct pci_dev *pdev, 125 const struct pci_device_id *id) 126 { 127 static const struct mt76_driver_ops drv_ops = { 128 /* txwi_size = txd size + txp size */ 129 .txwi_size = MT_TXD_SIZE + sizeof(struct mt7921_txp_common), 130 .drv_flags = MT_DRV_TXWI_NO_FREE | MT_DRV_HW_MGMT_TXQ, 131 .survey_flags = SURVEY_INFO_TIME_TX | 132 SURVEY_INFO_TIME_RX | 133 SURVEY_INFO_TIME_BSS_RX, 134 .token_size = MT7921_TOKEN_SIZE, 135 .tx_prepare_skb = mt7921e_tx_prepare_skb, 136 .tx_complete_skb = mt7921e_tx_complete_skb, 137 .rx_skb = mt7921e_queue_rx_skb, 138 .rx_poll_complete = mt7921_rx_poll_complete, 139 .sta_ps = mt7921_sta_ps, 140 .sta_add = mt7921_mac_sta_add, 141 .sta_assoc = mt7921_mac_sta_assoc, 142 .sta_remove = mt7921_mac_sta_remove, 143 .update_survey = mt7921_update_channel, 144 }; 145 146 static const struct mt7921_hif_ops mt7921_pcie_ops = { 147 .init_reset = mt7921e_init_reset, 148 .reset = mt7921e_mac_reset, 149 .mcu_init = mt7921e_mcu_init, 150 .drv_own = mt7921e_mcu_drv_pmctrl, 151 .fw_own = mt7921e_mcu_fw_pmctrl, 152 }; 153 154 struct mt7921_dev *dev; 155 struct mt76_dev *mdev; 156 int ret; 157 158 ret = pcim_enable_device(pdev); 159 if (ret) 160 return ret; 161 162 ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev)); 163 if (ret) 164 return ret; 165 166 pci_set_master(pdev); 167 168 ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); 169 if (ret < 0) 170 return ret; 171 172 ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); 173 if (ret) 174 goto err_free_pci_vec; 175 176 if (mt7921_disable_aspm) 177 mt76_pci_disable_aspm(pdev); 178 179 mdev = mt76_alloc_device(&pdev->dev, sizeof(*dev), &mt7921_ops, 180 &drv_ops); 181 if (!mdev) { 182 ret = -ENOMEM; 183 goto err_free_pci_vec; 184 } 185 186 dev = container_of(mdev, struct mt7921_dev, mt76); 187 dev->hif_ops = &mt7921_pcie_ops; 188 189 mt76_mmio_init(&dev->mt76, pcim_iomap_table(pdev)[0]); 190 tasklet_init(&dev->irq_tasklet, mt7921_irq_tasklet, (unsigned long)dev); 191 mdev->rev = (mt7921_l1_rr(dev, MT_HW_CHIPID) << 16) | 192 (mt7921_l1_rr(dev, MT_HW_REV) & 0xff); 193 dev_info(mdev->dev, "ASIC revision: %04x\n", mdev->rev); 194 195 mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0); 196 197 mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff); 198 199 ret = devm_request_irq(mdev->dev, pdev->irq, mt7921_irq_handler, 200 IRQF_SHARED, KBUILD_MODNAME, dev); 201 if (ret) 202 goto err_free_dev; 203 204 ret = mt7921_dma_init(dev); 205 if (ret) 206 goto err_free_irq; 207 208 ret = mt7921_register_device(dev); 209 if (ret) 210 goto err_free_irq; 211 212 return 0; 213 214 err_free_irq: 215 devm_free_irq(&pdev->dev, pdev->irq, dev); 216 err_free_dev: 217 mt76_free_device(&dev->mt76); 218 err_free_pci_vec: 219 pci_free_irq_vectors(pdev); 220 221 return ret; 222 } 223 224 static void mt7921_pci_remove(struct pci_dev *pdev) 225 { 226 struct mt76_dev *mdev = pci_get_drvdata(pdev); 227 struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); 228 229 mt7921e_unregister_device(dev); 230 devm_free_irq(&pdev->dev, pdev->irq, dev); 231 pci_free_irq_vectors(pdev); 232 } 233 234 #ifdef CONFIG_PM 235 static int mt7921_pci_suspend(struct pci_dev *pdev, pm_message_t state) 236 { 237 struct mt76_dev *mdev = pci_get_drvdata(pdev); 238 struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); 239 struct mt76_connac_pm *pm = &dev->pm; 240 int i, err; 241 242 pm->suspended = true; 243 cancel_delayed_work_sync(&pm->ps_work); 244 cancel_work_sync(&pm->wake_work); 245 246 err = mt7921_mcu_drv_pmctrl(dev); 247 if (err < 0) 248 goto restore_suspend; 249 250 err = mt76_connac_mcu_set_hif_suspend(mdev, true); 251 if (err) 252 goto restore_suspend; 253 254 /* always enable deep sleep during suspend to reduce 255 * power consumption 256 */ 257 mt76_connac_mcu_set_deep_sleep(&dev->mt76, true); 258 259 napi_disable(&mdev->tx_napi); 260 mt76_worker_disable(&mdev->tx_worker); 261 262 mt76_for_each_q_rx(mdev, i) { 263 napi_disable(&mdev->napi[i]); 264 } 265 266 pci_enable_wake(pdev, pci_choose_state(pdev, state), true); 267 268 /* wait until dma is idle */ 269 mt76_poll(dev, MT_WFDMA0_GLO_CFG, 270 MT_WFDMA0_GLO_CFG_TX_DMA_BUSY | 271 MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000); 272 273 /* put dma disabled */ 274 mt76_clear(dev, MT_WFDMA0_GLO_CFG, 275 MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN); 276 277 /* disable interrupt */ 278 mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0); 279 mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0); 280 synchronize_irq(pdev->irq); 281 tasklet_kill(&dev->irq_tasklet); 282 283 err = mt7921_mcu_fw_pmctrl(dev); 284 if (err) 285 goto restore_napi; 286 287 pci_save_state(pdev); 288 err = pci_set_power_state(pdev, pci_choose_state(pdev, state)); 289 if (err) 290 goto restore_napi; 291 292 return 0; 293 294 restore_napi: 295 mt76_for_each_q_rx(mdev, i) { 296 napi_enable(&mdev->napi[i]); 297 } 298 napi_enable(&mdev->tx_napi); 299 300 if (!pm->ds_enable) 301 mt76_connac_mcu_set_deep_sleep(&dev->mt76, false); 302 303 mt76_connac_mcu_set_hif_suspend(mdev, false); 304 305 restore_suspend: 306 pm->suspended = false; 307 308 return err; 309 } 310 311 static int mt7921_pci_resume(struct pci_dev *pdev) 312 { 313 struct mt76_dev *mdev = pci_get_drvdata(pdev); 314 struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); 315 struct mt76_connac_pm *pm = &dev->pm; 316 int i, err; 317 318 err = pci_set_power_state(pdev, PCI_D0); 319 if (err) 320 return err; 321 322 pci_restore_state(pdev); 323 324 err = mt7921_mcu_drv_pmctrl(dev); 325 if (err < 0) 326 return err; 327 328 mt7921_wpdma_reinit_cond(dev); 329 330 /* enable interrupt */ 331 mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff); 332 mt7921_irq_enable(dev, MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL | 333 MT_INT_MCU_CMD); 334 mt76_set(dev, MT_MCU2HOST_SW_INT_ENA, MT_MCU_CMD_WAKE_RX_PCIE); 335 336 /* put dma enabled */ 337 mt76_set(dev, MT_WFDMA0_GLO_CFG, 338 MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN); 339 340 mt76_worker_enable(&mdev->tx_worker); 341 342 local_bh_disable(); 343 mt76_for_each_q_rx(mdev, i) { 344 napi_enable(&mdev->napi[i]); 345 napi_schedule(&mdev->napi[i]); 346 } 347 napi_enable(&mdev->tx_napi); 348 napi_schedule(&mdev->tx_napi); 349 local_bh_enable(); 350 351 /* restore previous ds setting */ 352 if (!pm->ds_enable) 353 mt76_connac_mcu_set_deep_sleep(&dev->mt76, false); 354 355 err = mt76_connac_mcu_set_hif_suspend(mdev, false); 356 if (err) 357 return err; 358 359 pm->suspended = false; 360 361 return err; 362 } 363 #endif /* CONFIG_PM */ 364 365 struct pci_driver mt7921_pci_driver = { 366 .name = KBUILD_MODNAME, 367 .id_table = mt7921_pci_device_table, 368 .probe = mt7921_pci_probe, 369 .remove = mt7921_pci_remove, 370 #ifdef CONFIG_PM 371 .suspend = mt7921_pci_suspend, 372 .resume = mt7921_pci_resume, 373 #endif /* CONFIG_PM */ 374 }; 375 376 module_pci_driver(mt7921_pci_driver); 377 378 MODULE_DEVICE_TABLE(pci, mt7921_pci_device_table); 379 MODULE_FIRMWARE(MT7921_FIRMWARE_WM); 380 MODULE_FIRMWARE(MT7921_ROM_PATCH); 381 MODULE_FIRMWARE(MT7922_FIRMWARE_WM); 382 MODULE_FIRMWARE(MT7922_ROM_PATCH); 383 MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); 384 MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); 385 MODULE_LICENSE("Dual BSD/GPL"); 386