usb.c (7002B)
1// SPDX-License-Identifier: ISC 2/* Copyright (C) 2019 MediaTek Inc. 3 * 4 * Author: Felix Fietkau <nbd@nbd.name> 5 * Lorenzo Bianconi <lorenzo@kernel.org> 6 * Sean Wang <sean.wang@mediatek.com> 7 */ 8 9#include <linux/kernel.h> 10#include <linux/module.h> 11#include <linux/usb.h> 12 13#include "mt7615.h" 14#include "mac.h" 15#include "mcu.h" 16#include "regs.h" 17 18static const struct usb_device_id mt7615_device_table[] = { 19 { USB_DEVICE_AND_INTERFACE_INFO(0x0e8d, 0x7663, 0xff, 0xff, 0xff) }, 20 { USB_DEVICE_AND_INTERFACE_INFO(0x043e, 0x310c, 0xff, 0xff, 0xff) }, 21 { }, 22}; 23 24static u32 mt7663u_rr(struct mt76_dev *dev, u32 addr) 25{ 26 u32 ret; 27 28 mutex_lock(&dev->usb.usb_ctrl_mtx); 29 ret = ___mt76u_rr(dev, MT_VEND_READ_EXT, 30 USB_DIR_IN | USB_TYPE_VENDOR, addr); 31 mutex_unlock(&dev->usb.usb_ctrl_mtx); 32 33 return ret; 34} 35 36static void mt7663u_wr(struct mt76_dev *dev, u32 addr, u32 val) 37{ 38 mutex_lock(&dev->usb.usb_ctrl_mtx); 39 ___mt76u_wr(dev, MT_VEND_WRITE_EXT, 40 USB_DIR_OUT | USB_TYPE_VENDOR, addr, val); 41 mutex_unlock(&dev->usb.usb_ctrl_mtx); 42} 43 44static u32 mt7663u_rmw(struct mt76_dev *dev, u32 addr, 45 u32 mask, u32 val) 46{ 47 mutex_lock(&dev->usb.usb_ctrl_mtx); 48 val |= ___mt76u_rr(dev, MT_VEND_READ_EXT, 49 USB_DIR_IN | USB_TYPE_VENDOR, addr) & ~mask; 50 ___mt76u_wr(dev, MT_VEND_WRITE_EXT, 51 USB_DIR_OUT | USB_TYPE_VENDOR, addr, val); 52 mutex_unlock(&dev->usb.usb_ctrl_mtx); 53 54 return val; 55} 56 57static void mt7663u_copy(struct mt76_dev *dev, u32 offset, 58 const void *data, int len) 59{ 60 struct mt76_usb *usb = &dev->usb; 61 int ret, i = 0, batch_len; 62 const u8 *val = data; 63 64 len = round_up(len, 4); 65 66 mutex_lock(&usb->usb_ctrl_mtx); 67 while (i < len) { 68 batch_len = min_t(int, usb->data_len, len - i); 69 memcpy(usb->data, val + i, batch_len); 70 ret = __mt76u_vendor_request(dev, MT_VEND_WRITE_EXT, 71 USB_DIR_OUT | USB_TYPE_VENDOR, 72 (offset + i) >> 16, offset + i, 73 usb->data, batch_len); 74 if (ret < 0) 75 break; 76 77 i += batch_len; 78 } 79 mutex_unlock(&usb->usb_ctrl_mtx); 80} 81 82static void mt7663u_stop(struct ieee80211_hw *hw) 83{ 84 struct mt7615_phy *phy = mt7615_hw_phy(hw); 85 struct mt7615_dev *dev = hw->priv; 86 87 clear_bit(MT76_STATE_RUNNING, &dev->mphy.state); 88 del_timer_sync(&phy->roc_timer); 89 cancel_work_sync(&phy->roc_work); 90 cancel_delayed_work_sync(&phy->scan_work); 91 cancel_delayed_work_sync(&phy->mt76->mac_work); 92 mt76u_stop_tx(&dev->mt76); 93} 94 95static void mt7663u_cleanup(struct mt7615_dev *dev) 96{ 97 clear_bit(MT76_STATE_INITIALIZED, &dev->mphy.state); 98 mt76u_queues_deinit(&dev->mt76); 99} 100 101static void mt7663u_init_work(struct work_struct *work) 102{ 103 struct mt7615_dev *dev; 104 105 dev = container_of(work, struct mt7615_dev, mcu_work); 106 if (mt7663u_mcu_init(dev)) 107 return; 108 109 mt7615_init_work(dev); 110} 111 112static int mt7663u_probe(struct usb_interface *usb_intf, 113 const struct usb_device_id *id) 114{ 115 static const struct mt76_driver_ops drv_ops = { 116 .txwi_size = MT_USB_TXD_SIZE, 117 .drv_flags = MT_DRV_RX_DMA_HDR | MT_DRV_HW_MGMT_TXQ, 118 .tx_prepare_skb = mt7663_usb_sdio_tx_prepare_skb, 119 .tx_complete_skb = mt7663_usb_sdio_tx_complete_skb, 120 .tx_status_data = mt7663_usb_sdio_tx_status_data, 121 .rx_skb = mt7615_queue_rx_skb, 122 .sta_ps = mt7615_sta_ps, 123 .sta_add = mt7615_mac_sta_add, 124 .sta_remove = mt7615_mac_sta_remove, 125 .update_survey = mt7615_update_channel, 126 }; 127 static struct mt76_bus_ops bus_ops = { 128 .rr = mt7663u_rr, 129 .wr = mt7663u_wr, 130 .rmw = mt7663u_rmw, 131 .read_copy = mt76u_read_copy, 132 .write_copy = mt7663u_copy, 133 .type = MT76_BUS_USB, 134 }; 135 struct usb_device *udev = interface_to_usbdev(usb_intf); 136 struct ieee80211_ops *ops; 137 struct mt7615_dev *dev; 138 struct mt76_dev *mdev; 139 int ret; 140 141 ops = devm_kmemdup(&usb_intf->dev, &mt7615_ops, sizeof(mt7615_ops), 142 GFP_KERNEL); 143 if (!ops) 144 return -ENOMEM; 145 146 ops->stop = mt7663u_stop; 147 148 mdev = mt76_alloc_device(&usb_intf->dev, sizeof(*dev), ops, &drv_ops); 149 if (!mdev) 150 return -ENOMEM; 151 152 dev = container_of(mdev, struct mt7615_dev, mt76); 153 udev = usb_get_dev(udev); 154 usb_reset_device(udev); 155 156 usb_set_intfdata(usb_intf, dev); 157 158 INIT_WORK(&dev->mcu_work, mt7663u_init_work); 159 dev->reg_map = mt7663_usb_sdio_reg_map; 160 dev->ops = ops; 161 ret = __mt76u_init(mdev, usb_intf, &bus_ops); 162 if (ret < 0) 163 goto error; 164 165 mdev->rev = (mt76_rr(dev, MT_HW_CHIPID) << 16) | 166 (mt76_rr(dev, MT_HW_REV) & 0xff); 167 dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev); 168 169 if (!mt76_poll_msec(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_PWR_ON, 170 FW_STATE_PWR_ON << 1, 500)) { 171 ret = mt7663u_mcu_power_on(dev); 172 if (ret) 173 goto error; 174 } else { 175 set_bit(MT76_STATE_POWER_OFF, &dev->mphy.state); 176 } 177 178 ret = mt76u_alloc_mcu_queue(&dev->mt76); 179 if (ret) 180 goto error; 181 182 ret = mt76u_alloc_queues(&dev->mt76); 183 if (ret) 184 goto error; 185 186 ret = mt7663_usb_sdio_register_device(dev); 187 if (ret) 188 goto error; 189 190 return 0; 191 192error: 193 mt76u_queues_deinit(&dev->mt76); 194 usb_set_intfdata(usb_intf, NULL); 195 usb_put_dev(interface_to_usbdev(usb_intf)); 196 197 mt76_free_device(&dev->mt76); 198 199 return ret; 200} 201 202static void mt7663u_disconnect(struct usb_interface *usb_intf) 203{ 204 struct mt7615_dev *dev = usb_get_intfdata(usb_intf); 205 206 if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state)) 207 return; 208 209 ieee80211_unregister_hw(dev->mt76.hw); 210 mt7663u_cleanup(dev); 211 212 usb_set_intfdata(usb_intf, NULL); 213 usb_put_dev(interface_to_usbdev(usb_intf)); 214 215 mt76_free_device(&dev->mt76); 216} 217 218#ifdef CONFIG_PM 219static int mt7663u_suspend(struct usb_interface *intf, pm_message_t state) 220{ 221 struct mt7615_dev *dev = usb_get_intfdata(intf); 222 223 if (!test_bit(MT76_STATE_SUSPEND, &dev->mphy.state) && 224 mt7615_firmware_offload(dev)) { 225 int err; 226 227 err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true); 228 if (err < 0) 229 return err; 230 } 231 232 mt76u_stop_rx(&dev->mt76); 233 mt76u_stop_tx(&dev->mt76); 234 235 return 0; 236} 237 238static int mt7663u_resume(struct usb_interface *intf) 239{ 240 struct mt7615_dev *dev = usb_get_intfdata(intf); 241 int err; 242 243 err = mt76u_vendor_request(&dev->mt76, MT_VEND_FEATURE_SET, 244 USB_DIR_OUT | USB_TYPE_VENDOR, 245 0x5, 0x0, NULL, 0); 246 if (err) 247 return err; 248 249 err = mt76u_resume_rx(&dev->mt76); 250 if (err < 0) 251 return err; 252 253 if (!test_bit(MT76_STATE_SUSPEND, &dev->mphy.state) && 254 mt7615_firmware_offload(dev)) 255 err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false); 256 257 return err; 258} 259#endif /* CONFIG_PM */ 260 261MODULE_DEVICE_TABLE(usb, mt7615_device_table); 262MODULE_FIRMWARE(MT7663_OFFLOAD_FIRMWARE_N9); 263MODULE_FIRMWARE(MT7663_OFFLOAD_ROM_PATCH); 264MODULE_FIRMWARE(MT7663_FIRMWARE_N9); 265MODULE_FIRMWARE(MT7663_ROM_PATCH); 266 267static struct usb_driver mt7663u_driver = { 268 .name = KBUILD_MODNAME, 269 .id_table = mt7615_device_table, 270 .probe = mt7663u_probe, 271 .disconnect = mt7663u_disconnect, 272#ifdef CONFIG_PM 273 .suspend = mt7663u_suspend, 274 .resume = mt7663u_resume, 275 .reset_resume = mt7663u_resume, 276#endif /* CONFIG_PM */ 277 .soft_unbind = 1, 278 .disable_hub_initiated_lpm = 1, 279}; 280module_usb_driver(mt7663u_driver); 281 282MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); 283MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); 284MODULE_LICENSE("Dual BSD/GPL");