1 // SPDX-License-Identifier: ISC 2 /* Copyright (C) 2022 MediaTek Inc. 3 * 4 * Author: Lorenzo Bianconi <lorenzo@kernel.org> 5 */ 6 7 #include <linux/kernel.h> 8 #include <linux/module.h> 9 #include <linux/usb.h> 10 11 #include "mt7921.h" 12 #include "mcu.h" 13 #include "mac.h" 14 15 static const struct usb_device_id mt7921u_device_table[] = { 16 { USB_DEVICE_AND_INTERFACE_INFO(0x0e8d, 0x7961, 0xff, 0xff, 0xff), 17 .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM }, 18 /* Comfast CF-952AX */ 19 { USB_DEVICE_AND_INTERFACE_INFO(0x3574, 0x6211, 0xff, 0xff, 0xff), 20 .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM }, 21 { }, 22 }; 23 24 static u32 mt7921u_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 | MT_USB_TYPE_VENDOR, addr); 31 mutex_unlock(&dev->usb.usb_ctrl_mtx); 32 33 return ret; 34 } 35 36 static void mt7921u_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 | MT_USB_TYPE_VENDOR, addr, val); 41 mutex_unlock(&dev->usb.usb_ctrl_mtx); 42 } 43 44 static u32 mt7921u_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 | MT_USB_TYPE_VENDOR, addr) & ~mask; 50 ___mt76u_wr(dev, MT_VEND_WRITE_EXT, 51 USB_DIR_OUT | MT_USB_TYPE_VENDOR, addr, val); 52 mutex_unlock(&dev->usb.usb_ctrl_mtx); 53 54 return val; 55 } 56 57 static void mt7921u_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 | MT_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 82 int mt7921u_mcu_power_on(struct mt7921_dev *dev) 83 { 84 int ret; 85 86 ret = mt76u_vendor_request(&dev->mt76, MT_VEND_POWER_ON, 87 USB_DIR_OUT | MT_USB_TYPE_VENDOR, 88 0x0, 0x1, NULL, 0); 89 if (ret) 90 return ret; 91 92 if (!mt76_poll_msec(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_PWR_ON, 93 MT_TOP_MISC2_FW_PWR_ON, 500)) { 94 dev_err(dev->mt76.dev, "Timeout for power on\n"); 95 ret = -EIO; 96 } 97 98 return ret; 99 } 100 101 static int 102 mt7921u_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, 103 int cmd, int *seq) 104 { 105 struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); 106 u32 pad, ep; 107 int ret; 108 109 ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, seq); 110 if (ret) 111 return ret; 112 113 mdev->mcu.timeout = 3 * HZ; 114 115 if (cmd != MCU_CMD(FW_SCATTER)) 116 ep = MT_EP_OUT_INBAND_CMD; 117 else 118 ep = MT_EP_OUT_AC_BE; 119 120 mt7921_skb_add_usb_sdio_hdr(dev, skb, 0); 121 pad = round_up(skb->len, 4) + 4 - skb->len; 122 __skb_put_zero(skb, pad); 123 124 ret = mt76u_bulk_msg(&dev->mt76, skb->data, skb->len, NULL, 125 1000, ep); 126 dev_kfree_skb(skb); 127 128 return ret; 129 } 130 131 static int mt7921u_mcu_init(struct mt7921_dev *dev) 132 { 133 static const struct mt76_mcu_ops mcu_ops = { 134 .headroom = MT_SDIO_HDR_SIZE + 135 sizeof(struct mt76_connac2_mcu_txd), 136 .tailroom = MT_USB_TAIL_SIZE, 137 .mcu_skb_send_msg = mt7921u_mcu_send_message, 138 .mcu_parse_response = mt7921_mcu_parse_response, 139 }; 140 int ret; 141 142 dev->mt76.mcu_ops = &mcu_ops; 143 144 mt76_set(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN); 145 ret = mt7921_run_firmware(dev); 146 if (ret) 147 return ret; 148 149 set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); 150 mt76_clear(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN); 151 152 return 0; 153 } 154 155 static void mt7921u_stop(struct ieee80211_hw *hw) 156 { 157 struct mt7921_dev *dev = mt7921_hw_dev(hw); 158 159 mt76u_stop_tx(&dev->mt76); 160 mt7921_stop(hw); 161 } 162 163 static void mt7921u_cleanup(struct mt7921_dev *dev) 164 { 165 clear_bit(MT76_STATE_INITIALIZED, &dev->mphy.state); 166 mt7921u_wfsys_reset(dev); 167 skb_queue_purge(&dev->mt76.mcu.res_q); 168 mt76u_queues_deinit(&dev->mt76); 169 } 170 171 static int mt7921u_probe(struct usb_interface *usb_intf, 172 const struct usb_device_id *id) 173 { 174 static const struct mt76_driver_ops drv_ops = { 175 .txwi_size = MT_SDIO_TXD_SIZE, 176 .drv_flags = MT_DRV_RX_DMA_HDR | MT_DRV_HW_MGMT_TXQ | 177 MT_DRV_AMSDU_OFFLOAD, 178 .survey_flags = SURVEY_INFO_TIME_TX | 179 SURVEY_INFO_TIME_RX | 180 SURVEY_INFO_TIME_BSS_RX, 181 .tx_prepare_skb = mt7921_usb_sdio_tx_prepare_skb, 182 .tx_complete_skb = mt7921_usb_sdio_tx_complete_skb, 183 .tx_status_data = mt7921_usb_sdio_tx_status_data, 184 .rx_skb = mt7921_queue_rx_skb, 185 .rx_check = mt7921_rx_check, 186 .sta_ps = mt7921_sta_ps, 187 .sta_add = mt7921_mac_sta_add, 188 .sta_assoc = mt7921_mac_sta_assoc, 189 .sta_remove = mt7921_mac_sta_remove, 190 .update_survey = mt7921_update_channel, 191 }; 192 static const struct mt7921_hif_ops hif_ops = { 193 .mcu_init = mt7921u_mcu_init, 194 .init_reset = mt7921u_init_reset, 195 .reset = mt7921u_mac_reset, 196 }; 197 static struct mt76_bus_ops bus_ops = { 198 .rr = mt7921u_rr, 199 .wr = mt7921u_wr, 200 .rmw = mt7921u_rmw, 201 .read_copy = mt76u_read_copy, 202 .write_copy = mt7921u_copy, 203 .type = MT76_BUS_USB, 204 }; 205 struct usb_device *udev = interface_to_usbdev(usb_intf); 206 struct ieee80211_ops *ops; 207 struct ieee80211_hw *hw; 208 struct mt7921_dev *dev; 209 struct mt76_dev *mdev; 210 u8 features; 211 int ret; 212 213 features = mt7921_check_offload_capability(&usb_intf->dev, (const char *) 214 id->driver_info); 215 ops = devm_kmemdup(&usb_intf->dev, &mt7921_ops, sizeof(mt7921_ops), 216 GFP_KERNEL); 217 if (!ops) 218 return -ENOMEM; 219 220 if (!(features & MT7921_FW_CAP_CNM)) { 221 ops->remain_on_channel = NULL; 222 ops->cancel_remain_on_channel = NULL; 223 ops->add_chanctx = NULL; 224 ops->remove_chanctx = NULL; 225 ops->change_chanctx = NULL; 226 ops->assign_vif_chanctx = NULL; 227 ops->unassign_vif_chanctx = NULL; 228 ops->mgd_prepare_tx = NULL; 229 ops->mgd_complete_tx = NULL; 230 } 231 232 ops->stop = mt7921u_stop; 233 234 mdev = mt76_alloc_device(&usb_intf->dev, sizeof(*dev), ops, &drv_ops); 235 if (!mdev) 236 return -ENOMEM; 237 238 dev = container_of(mdev, struct mt7921_dev, mt76); 239 dev->fw_features = features; 240 dev->hif_ops = &hif_ops; 241 242 udev = usb_get_dev(udev); 243 usb_reset_device(udev); 244 245 usb_set_intfdata(usb_intf, dev); 246 247 ret = __mt76u_init(mdev, usb_intf, &bus_ops); 248 if (ret < 0) 249 goto error; 250 251 mdev->rev = (mt76_rr(dev, MT_HW_CHIPID) << 16) | 252 (mt76_rr(dev, MT_HW_REV) & 0xff); 253 dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev); 254 255 if (mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY)) { 256 ret = mt7921u_wfsys_reset(dev); 257 if (ret) 258 goto error; 259 } 260 261 ret = mt7921u_mcu_power_on(dev); 262 if (ret) 263 goto error; 264 265 ret = mt76u_alloc_mcu_queue(&dev->mt76); 266 if (ret) 267 goto error; 268 269 ret = mt76u_alloc_queues(&dev->mt76); 270 if (ret) 271 goto error; 272 273 ret = mt7921u_dma_init(dev, false); 274 if (ret) 275 return ret; 276 277 hw = mt76_hw(dev); 278 /* check hw sg support in order to enable AMSDU */ 279 hw->max_tx_fragments = mdev->usb.sg_en ? MT_HW_TXP_MAX_BUF_NUM : 1; 280 281 ret = mt7921_register_device(dev); 282 if (ret) 283 goto error; 284 285 return 0; 286 287 error: 288 mt76u_queues_deinit(&dev->mt76); 289 290 usb_set_intfdata(usb_intf, NULL); 291 usb_put_dev(interface_to_usbdev(usb_intf)); 292 293 mt76_free_device(&dev->mt76); 294 295 return ret; 296 } 297 298 static void mt7921u_disconnect(struct usb_interface *usb_intf) 299 { 300 struct mt7921_dev *dev = usb_get_intfdata(usb_intf); 301 302 cancel_work_sync(&dev->init_work); 303 if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state)) 304 return; 305 306 mt76_unregister_device(&dev->mt76); 307 mt7921u_cleanup(dev); 308 309 usb_set_intfdata(usb_intf, NULL); 310 usb_put_dev(interface_to_usbdev(usb_intf)); 311 312 mt76_free_device(&dev->mt76); 313 } 314 315 #ifdef CONFIG_PM 316 static int mt7921u_suspend(struct usb_interface *intf, pm_message_t state) 317 { 318 struct mt7921_dev *dev = usb_get_intfdata(intf); 319 struct mt76_connac_pm *pm = &dev->pm; 320 int err; 321 322 pm->suspended = true; 323 flush_work(&dev->reset_work); 324 325 err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true); 326 if (err) 327 goto failed; 328 329 mt76u_stop_rx(&dev->mt76); 330 mt76u_stop_tx(&dev->mt76); 331 332 return 0; 333 334 failed: 335 pm->suspended = false; 336 337 if (err < 0) 338 mt7921_reset(&dev->mt76); 339 340 return err; 341 } 342 343 static int mt7921u_resume(struct usb_interface *intf) 344 { 345 struct mt7921_dev *dev = usb_get_intfdata(intf); 346 struct mt76_connac_pm *pm = &dev->pm; 347 bool reinit = true; 348 int err, i; 349 350 for (i = 0; i < 10; i++) { 351 u32 val = mt76_rr(dev, MT_WF_SW_DEF_CR_USB_MCU_EVENT); 352 353 if (!(val & MT_WF_SW_SER_TRIGGER_SUSPEND)) { 354 reinit = false; 355 break; 356 } 357 if (val & MT_WF_SW_SER_DONE_SUSPEND) { 358 mt76_wr(dev, MT_WF_SW_DEF_CR_USB_MCU_EVENT, 0); 359 break; 360 } 361 362 msleep(20); 363 } 364 365 if (reinit || mt7921_dma_need_reinit(dev)) { 366 err = mt7921u_dma_init(dev, true); 367 if (err) 368 goto failed; 369 } 370 371 err = mt76u_resume_rx(&dev->mt76); 372 if (err < 0) 373 goto failed; 374 375 err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false); 376 failed: 377 pm->suspended = false; 378 379 if (err < 0) 380 mt7921_reset(&dev->mt76); 381 382 return err; 383 } 384 #endif /* CONFIG_PM */ 385 386 MODULE_DEVICE_TABLE(usb, mt7921u_device_table); 387 MODULE_FIRMWARE(MT7921_FIRMWARE_WM); 388 MODULE_FIRMWARE(MT7921_ROM_PATCH); 389 390 static struct usb_driver mt7921u_driver = { 391 .name = KBUILD_MODNAME, 392 .id_table = mt7921u_device_table, 393 .probe = mt7921u_probe, 394 .disconnect = mt7921u_disconnect, 395 #ifdef CONFIG_PM 396 .suspend = mt7921u_suspend, 397 .resume = mt7921u_resume, 398 .reset_resume = mt7921u_resume, 399 #endif /* CONFIG_PM */ 400 .soft_unbind = 1, 401 .disable_hub_initiated_lpm = 1, 402 }; 403 module_usb_driver(mt7921u_driver); 404 405 MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); 406 MODULE_LICENSE("Dual BSD/GPL"); 407