1 // SPDX-License-Identifier: ISC 2 /* Copyright (C) 2019 MediaTek Inc. 3 * 4 * Author: Ryder Lee <ryder.lee@mediatek.com> 5 * Felix Fietkau <nbd@nbd.name> 6 */ 7 8 #include <linux/kernel.h> 9 #include <linux/module.h> 10 #include <linux/pci.h> 11 12 #include "mt7615.h" 13 #include "mcu.h" 14 15 static const struct pci_device_id mt7615_pci_device_table[] = { 16 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7615) }, 17 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7663) }, 18 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7611) }, 19 { }, 20 }; 21 22 static int mt7615_pci_probe(struct pci_dev *pdev, 23 const struct pci_device_id *id) 24 { 25 const u32 *map; 26 int ret; 27 28 ret = pcim_enable_device(pdev); 29 if (ret) 30 return ret; 31 32 ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev)); 33 if (ret) 34 return ret; 35 36 pci_set_master(pdev); 37 38 ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); 39 if (ret < 0) 40 return ret; 41 42 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); 43 if (ret) 44 goto error; 45 46 mt76_pci_disable_aspm(pdev); 47 48 map = id->device == 0x7663 ? mt7663e_reg_map : mt7615e_reg_map; 49 ret = mt7615_mmio_probe(&pdev->dev, pcim_iomap_table(pdev)[0], 50 pdev->irq, map); 51 if (ret) 52 goto error; 53 54 return 0; 55 error: 56 pci_free_irq_vectors(pdev); 57 58 return ret; 59 } 60 61 static void mt7615_pci_remove(struct pci_dev *pdev) 62 { 63 struct mt76_dev *mdev = pci_get_drvdata(pdev); 64 struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76); 65 66 mt7615_unregister_device(dev); 67 devm_free_irq(&pdev->dev, pdev->irq, dev); 68 pci_free_irq_vectors(pdev); 69 } 70 71 #ifdef CONFIG_PM 72 static int mt7615_pci_suspend(struct pci_dev *pdev, pm_message_t state) 73 { 74 struct mt76_dev *mdev = pci_get_drvdata(pdev); 75 struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76); 76 bool hif_suspend; 77 int i, err; 78 79 err = mt76_connac_pm_wake(&dev->mphy, &dev->pm); 80 if (err < 0) 81 return err; 82 83 hif_suspend = !test_bit(MT76_STATE_SUSPEND, &dev->mphy.state) && 84 mt7615_firmware_offload(dev); 85 if (hif_suspend) { 86 err = mt76_connac_mcu_set_hif_suspend(mdev, true); 87 if (err) 88 return err; 89 } 90 91 napi_disable(&mdev->tx_napi); 92 mt76_worker_disable(&mdev->tx_worker); 93 94 mt76_for_each_q_rx(mdev, i) { 95 napi_disable(&mdev->napi[i]); 96 } 97 tasklet_kill(&dev->irq_tasklet); 98 99 mt7615_dma_reset(dev); 100 101 err = mt7615_wait_pdma_busy(dev); 102 if (err) 103 goto restore; 104 105 if (is_mt7663(mdev)) { 106 mt76_set(dev, MT_PDMA_SLP_PROT, MT_PDMA_AXI_SLPPROT_ENABLE); 107 if (!mt76_poll_msec(dev, MT_PDMA_SLP_PROT, 108 MT_PDMA_AXI_SLPPROT_RDY, 109 MT_PDMA_AXI_SLPPROT_RDY, 1000)) { 110 dev_err(mdev->dev, "PDMA sleep protection failed\n"); 111 err = -EIO; 112 goto restore; 113 } 114 } 115 116 pci_enable_wake(pdev, pci_choose_state(pdev, state), true); 117 pci_save_state(pdev); 118 err = pci_set_power_state(pdev, pci_choose_state(pdev, state)); 119 if (err) 120 goto restore; 121 122 err = mt7615_mcu_set_fw_ctrl(dev); 123 if (err) 124 goto restore; 125 126 return 0; 127 128 restore: 129 mt76_for_each_q_rx(mdev, i) { 130 napi_enable(&mdev->napi[i]); 131 } 132 napi_enable(&mdev->tx_napi); 133 if (hif_suspend) 134 mt76_connac_mcu_set_hif_suspend(mdev, false); 135 136 return err; 137 } 138 139 static int mt7615_pci_resume(struct pci_dev *pdev) 140 { 141 struct mt76_dev *mdev = pci_get_drvdata(pdev); 142 struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76); 143 bool pdma_reset; 144 int i, err; 145 146 err = mt7615_mcu_set_drv_ctrl(dev); 147 if (err < 0) 148 return err; 149 150 err = pci_set_power_state(pdev, PCI_D0); 151 if (err) 152 return err; 153 154 pci_restore_state(pdev); 155 156 if (is_mt7663(&dev->mt76)) { 157 mt76_clear(dev, MT_PDMA_SLP_PROT, MT_PDMA_AXI_SLPPROT_ENABLE); 158 mt76_wr(dev, MT_PCIE_IRQ_ENABLE, 1); 159 } 160 161 pdma_reset = !mt76_rr(dev, MT_WPDMA_TX_RING0_CTRL0) && 162 !mt76_rr(dev, MT_WPDMA_TX_RING0_CTRL1); 163 if (pdma_reset) 164 dev_err(mdev->dev, "PDMA engine must be reinitialized\n"); 165 166 mt76_worker_enable(&mdev->tx_worker); 167 mt76_for_each_q_rx(mdev, i) { 168 napi_enable(&mdev->napi[i]); 169 napi_schedule(&mdev->napi[i]); 170 } 171 napi_enable(&mdev->tx_napi); 172 napi_schedule(&mdev->tx_napi); 173 174 if (!test_bit(MT76_STATE_SUSPEND, &dev->mphy.state) && 175 mt7615_firmware_offload(dev)) 176 err = mt76_connac_mcu_set_hif_suspend(mdev, false); 177 178 return err; 179 } 180 #endif /* CONFIG_PM */ 181 182 struct pci_driver mt7615_pci_driver = { 183 .name = KBUILD_MODNAME, 184 .id_table = mt7615_pci_device_table, 185 .probe = mt7615_pci_probe, 186 .remove = mt7615_pci_remove, 187 #ifdef CONFIG_PM 188 .suspend = mt7615_pci_suspend, 189 .resume = mt7615_pci_resume, 190 #endif /* CONFIG_PM */ 191 }; 192 193 MODULE_DEVICE_TABLE(pci, mt7615_pci_device_table); 194 MODULE_FIRMWARE(MT7615_FIRMWARE_CR4); 195 MODULE_FIRMWARE(MT7615_FIRMWARE_N9); 196 MODULE_FIRMWARE(MT7615_ROM_PATCH); 197 MODULE_FIRMWARE(MT7663_OFFLOAD_FIRMWARE_N9); 198 MODULE_FIRMWARE(MT7663_OFFLOAD_ROM_PATCH); 199 MODULE_FIRMWARE(MT7663_FIRMWARE_N9); 200 MODULE_FIRMWARE(MT7663_ROM_PATCH); 201