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