1 /* 2 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include <linux/kernel.h> 18 #include <linux/module.h> 19 #include <linux/pci.h> 20 21 #include "mt76x0.h" 22 #include "mcu.h" 23 24 static int mt76x0e_start(struct ieee80211_hw *hw) 25 { 26 struct mt76x02_dev *dev = hw->priv; 27 28 mutex_lock(&dev->mt76.mutex); 29 30 mt76x02_mac_start(dev); 31 ieee80211_queue_delayed_work(dev->mt76.hw, &dev->mac_work, 32 MT_CALIBRATE_INTERVAL); 33 ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work, 34 MT_CALIBRATE_INTERVAL); 35 set_bit(MT76_STATE_RUNNING, &dev->mt76.state); 36 37 mutex_unlock(&dev->mt76.mutex); 38 39 return 0; 40 } 41 42 static void mt76x0e_stop_hw(struct mt76x02_dev *dev) 43 { 44 cancel_delayed_work_sync(&dev->cal_work); 45 cancel_delayed_work_sync(&dev->mac_work); 46 47 if (!mt76_poll(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_TX_DMA_BUSY, 48 0, 1000)) 49 dev_warn(dev->mt76.dev, "TX DMA did not stop\n"); 50 mt76_clear(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_TX_DMA_EN); 51 52 mt76x0_mac_stop(dev); 53 54 if (!mt76_poll(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_RX_DMA_BUSY, 55 0, 1000)) 56 dev_warn(dev->mt76.dev, "TX DMA did not stop\n"); 57 mt76_clear(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_RX_DMA_EN); 58 } 59 60 static void mt76x0e_stop(struct ieee80211_hw *hw) 61 { 62 struct mt76x02_dev *dev = hw->priv; 63 64 mutex_lock(&dev->mt76.mutex); 65 clear_bit(MT76_STATE_RUNNING, &dev->mt76.state); 66 mt76x0e_stop_hw(dev); 67 mutex_unlock(&dev->mt76.mutex); 68 } 69 70 static const struct ieee80211_ops mt76x0e_ops = { 71 .tx = mt76x02_tx, 72 .start = mt76x0e_start, 73 .stop = mt76x0e_stop, 74 .config = mt76x0_config, 75 .add_interface = mt76x02_add_interface, 76 .remove_interface = mt76x02_remove_interface, 77 .configure_filter = mt76x02_configure_filter, 78 }; 79 80 static int mt76x0e_register_device(struct mt76x02_dev *dev) 81 { 82 int err; 83 84 mt76x0_chip_onoff(dev, true, false); 85 if (!mt76x02_wait_for_mac(&dev->mt76)) 86 return -ETIMEDOUT; 87 88 mt76x02_dma_disable(dev); 89 err = mt76x0e_mcu_init(dev); 90 if (err < 0) 91 return err; 92 93 err = mt76x02_dma_init(dev); 94 if (err < 0) 95 return err; 96 97 err = mt76x0_init_hardware(dev); 98 if (err < 0) 99 return err; 100 101 if (mt76_chip(&dev->mt76) == 0x7610) { 102 u16 val; 103 104 mt76_clear(dev, MT_COEXCFG0, BIT(0)); 105 val = mt76x02_eeprom_get(&dev->mt76, MT_EE_NIC_CONF_0); 106 if (val & MT_EE_NIC_CONF_0_PA_IO_CURRENT) { 107 u32 data; 108 109 /* set external external PA I/O 110 * current to 16mA 111 */ 112 data = mt76_rr(dev, 0x11c); 113 val |= 0xc03; 114 mt76_wr(dev, 0x11c, val); 115 } 116 } 117 118 mt76_clear(dev, 0x110, BIT(9)); 119 mt76_set(dev, MT_MAX_LEN_CFG, BIT(13)); 120 121 return 0; 122 } 123 124 static int 125 mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id) 126 { 127 struct mt76x02_dev *dev; 128 int ret; 129 130 ret = pcim_enable_device(pdev); 131 if (ret) 132 return ret; 133 134 ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev)); 135 if (ret) 136 return ret; 137 138 pci_set_master(pdev); 139 140 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); 141 if (ret) 142 return ret; 143 144 dev = mt76x0_alloc_device(&pdev->dev, NULL, &mt76x0e_ops); 145 if (!dev) 146 return -ENOMEM; 147 148 mt76_mmio_init(&dev->mt76, pcim_iomap_table(pdev)[0]); 149 150 dev->mt76.rev = mt76_rr(dev, MT_ASIC_VERSION); 151 dev_info(dev->mt76.dev, "ASIC revision: %08x\n", dev->mt76.rev); 152 153 ret = mt76x0e_register_device(dev); 154 if (ret < 0) 155 goto error; 156 157 return 0; 158 159 error: 160 ieee80211_free_hw(mt76_hw(dev)); 161 return ret; 162 } 163 164 static void mt76x0e_cleanup(struct mt76x02_dev *dev) 165 { 166 clear_bit(MT76_STATE_INITIALIZED, &dev->mt76.state); 167 mt76x0_chip_onoff(dev, false, false); 168 mt76x0e_stop_hw(dev); 169 mt76x02_dma_cleanup(dev); 170 mt76x02_mcu_cleanup(&dev->mt76); 171 } 172 173 static void 174 mt76x0e_remove(struct pci_dev *pdev) 175 { 176 struct mt76_dev *mdev = pci_get_drvdata(pdev); 177 struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76); 178 179 mt76_unregister_device(mdev); 180 mt76x0e_cleanup(dev); 181 ieee80211_free_hw(mdev->hw); 182 } 183 184 static const struct pci_device_id mt76x0e_device_table[] = { 185 { PCI_DEVICE(0x14c3, 0x7630) }, 186 { PCI_DEVICE(0x14c3, 0x7650) }, 187 { }, 188 }; 189 190 MODULE_DEVICE_TABLE(pci, mt76x0e_device_table); 191 MODULE_LICENSE("Dual BSD/GPL"); 192 193 static struct pci_driver mt76x0e_driver = { 194 .name = KBUILD_MODNAME, 195 .id_table = mt76x0e_device_table, 196 .probe = mt76x0e_probe, 197 .remove = mt76x0e_remove, 198 }; 199 200 module_pci_driver(mt76x0e_driver); 201