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