usb.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. // SPDX-License-Identifier: BSD-3-Clause-Clear
  2. /* Copyright (C) 2022 MediaTek Inc.
  3. *
  4. * Author: Lorenzo Bianconi <lorenzo@kernel.org>
  5. */
  6. #include <linux/kernel.h>
  7. #include <linux/module.h>
  8. #include <linux/usb.h>
  9. #include "mt7921.h"
  10. #include "mcu.h"
  11. #include "../mt76_connac2_mac.h"
  12. static const struct usb_device_id mt7921u_device_table[] = {
  13. { USB_DEVICE_AND_INTERFACE_INFO(0x0e8d, 0x7961, 0xff, 0xff, 0xff),
  14. .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM },
  15. /* Comfast CF-952AX */
  16. { USB_DEVICE_AND_INTERFACE_INFO(0x3574, 0x6211, 0xff, 0xff, 0xff),
  17. .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM },
  18. /* Netgear, Inc. [A8000,AXE3000] */
  19. { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9060, 0xff, 0xff, 0xff),
  20. .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM },
  21. /* Netgear, Inc. A7500 */
  22. { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9065, 0xff, 0xff, 0xff),
  23. .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM },
  24. /* TP-Link TXE50UH */
  25. { USB_DEVICE_AND_INTERFACE_INFO(0x35bc, 0x0107, 0xff, 0xff, 0xff),
  26. .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM },
  27. { },
  28. };
  29. static int
  30. mt7921u_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
  31. int cmd, int *seq)
  32. {
  33. struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);
  34. u32 pad, ep;
  35. int ret;
  36. ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, seq);
  37. if (ret)
  38. return ret;
  39. mdev->mcu.timeout = 3 * HZ;
  40. if (cmd != MCU_CMD(FW_SCATTER))
  41. ep = MT_EP_OUT_INBAND_CMD;
  42. else
  43. ep = MT_EP_OUT_AC_BE;
  44. mt792x_skb_add_usb_sdio_hdr(dev, skb, 0);
  45. pad = round_up(skb->len, 4) + 4 - skb->len;
  46. __skb_put_zero(skb, pad);
  47. ret = mt76u_bulk_msg(&dev->mt76, skb->data, skb->len, NULL,
  48. 1000, ep);
  49. dev_kfree_skb(skb);
  50. return ret;
  51. }
  52. static int mt7921u_mcu_init(struct mt792x_dev *dev)
  53. {
  54. static const struct mt76_mcu_ops mcu_ops = {
  55. .headroom = MT_SDIO_HDR_SIZE +
  56. sizeof(struct mt76_connac2_mcu_txd),
  57. .tailroom = MT_USB_TAIL_SIZE,
  58. .mcu_skb_send_msg = mt7921u_mcu_send_message,
  59. .mcu_parse_response = mt7921_mcu_parse_response,
  60. };
  61. int ret;
  62. dev->mt76.mcu_ops = &mcu_ops;
  63. mt76_set(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
  64. ret = mt7921_run_firmware(dev);
  65. if (ret)
  66. return ret;
  67. set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
  68. mt76_clear(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
  69. return 0;
  70. }
  71. static int mt7921u_mac_reset(struct mt792x_dev *dev)
  72. {
  73. int err;
  74. mt76_txq_schedule_all(&dev->mphy);
  75. mt76_worker_disable(&dev->mt76.tx_worker);
  76. set_bit(MT76_RESET, &dev->mphy.state);
  77. set_bit(MT76_MCU_RESET, &dev->mphy.state);
  78. wake_up(&dev->mt76.mcu.wait);
  79. skb_queue_purge(&dev->mt76.mcu.res_q);
  80. mt76u_stop_rx(&dev->mt76);
  81. mt76u_stop_tx(&dev->mt76);
  82. mt792xu_wfsys_reset(dev);
  83. clear_bit(MT76_MCU_RESET, &dev->mphy.state);
  84. err = mt76u_resume_rx(&dev->mt76);
  85. if (err)
  86. goto out;
  87. err = mt792xu_mcu_power_on(dev);
  88. if (err)
  89. goto out;
  90. err = mt792xu_dma_init(dev, false);
  91. if (err)
  92. goto out;
  93. mt76_wr(dev, MT_SWDEF_MODE, MT_SWDEF_NORMAL_MODE);
  94. mt76_set(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
  95. err = mt7921_run_firmware(dev);
  96. if (err)
  97. goto out;
  98. mt76_clear(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
  99. err = mt7921_mcu_set_eeprom(dev);
  100. if (err)
  101. goto out;
  102. err = mt7921_mac_init(dev);
  103. if (err)
  104. goto out;
  105. err = __mt7921_start(&dev->phy);
  106. out:
  107. clear_bit(MT76_RESET, &dev->mphy.state);
  108. mt76_worker_enable(&dev->mt76.tx_worker);
  109. return err;
  110. }
  111. static int mt7921u_probe(struct usb_interface *usb_intf,
  112. const struct usb_device_id *id)
  113. {
  114. static const struct mt76_driver_ops drv_ops = {
  115. .txwi_size = MT_SDIO_TXD_SIZE,
  116. .drv_flags = MT_DRV_RX_DMA_HDR | MT_DRV_HW_MGMT_TXQ |
  117. MT_DRV_AMSDU_OFFLOAD,
  118. .survey_flags = SURVEY_INFO_TIME_TX |
  119. SURVEY_INFO_TIME_RX |
  120. SURVEY_INFO_TIME_BSS_RX,
  121. .tx_prepare_skb = mt7921_usb_sdio_tx_prepare_skb,
  122. .tx_complete_skb = mt7921_usb_sdio_tx_complete_skb,
  123. .tx_status_data = mt7921_usb_sdio_tx_status_data,
  124. .rx_skb = mt7921_queue_rx_skb,
  125. .rx_check = mt7921_rx_check,
  126. .sta_add = mt7921_mac_sta_add,
  127. .sta_event = mt7921_mac_sta_event,
  128. .sta_remove = mt7921_mac_sta_remove,
  129. .update_survey = mt792x_update_channel,
  130. .set_channel = mt7921_set_channel,
  131. };
  132. static const struct mt792x_hif_ops hif_ops = {
  133. .mcu_init = mt7921u_mcu_init,
  134. .init_reset = mt792xu_init_reset,
  135. .reset = mt7921u_mac_reset,
  136. };
  137. static struct mt76_bus_ops bus_ops = {
  138. .rr = mt792xu_rr,
  139. .wr = mt792xu_wr,
  140. .rmw = mt792xu_rmw,
  141. .read_copy = mt76u_read_copy,
  142. .write_copy = mt792xu_copy,
  143. .type = MT76_BUS_USB,
  144. };
  145. struct usb_device *udev = interface_to_usbdev(usb_intf);
  146. struct ieee80211_ops *ops;
  147. struct ieee80211_hw *hw;
  148. struct mt792x_dev *dev;
  149. struct mt76_dev *mdev;
  150. u8 features;
  151. int ret;
  152. ops = mt792x_get_mac80211_ops(&usb_intf->dev, &mt7921_ops,
  153. (void *)id->driver_info, &features);
  154. if (!ops)
  155. return -ENOMEM;
  156. ops->stop = mt792xu_stop;
  157. mdev = mt76_alloc_device(&usb_intf->dev, sizeof(*dev), ops, &drv_ops);
  158. if (!mdev)
  159. return -ENOMEM;
  160. dev = container_of(mdev, struct mt792x_dev, mt76);
  161. dev->fw_features = features;
  162. dev->hif_ops = &hif_ops;
  163. udev = usb_get_dev(udev);
  164. usb_reset_device(udev);
  165. usb_set_intfdata(usb_intf, dev);
  166. ret = __mt76u_init(mdev, usb_intf, &bus_ops);
  167. if (ret < 0)
  168. goto error;
  169. mdev->rev = (mt76_rr(dev, MT_HW_CHIPID) << 16) |
  170. (mt76_rr(dev, MT_HW_REV) & 0xff);
  171. dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
  172. if (mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY)) {
  173. ret = mt792xu_wfsys_reset(dev);
  174. if (ret)
  175. goto error;
  176. }
  177. ret = mt792xu_mcu_power_on(dev);
  178. if (ret)
  179. goto error;
  180. ret = mt76u_alloc_mcu_queue(&dev->mt76);
  181. if (ret)
  182. goto error;
  183. ret = mt76u_alloc_queues(&dev->mt76);
  184. if (ret)
  185. goto error;
  186. ret = mt792xu_dma_init(dev, false);
  187. if (ret)
  188. goto error;
  189. hw = mt76_hw(dev);
  190. /* check hw sg support in order to enable AMSDU */
  191. hw->max_tx_fragments = mdev->usb.sg_en ? MT_HW_TXP_MAX_BUF_NUM : 1;
  192. ret = mt7921_register_device(dev);
  193. if (ret)
  194. goto error;
  195. return 0;
  196. error:
  197. mt76u_queues_deinit(&dev->mt76);
  198. usb_set_intfdata(usb_intf, NULL);
  199. usb_put_dev(interface_to_usbdev(usb_intf));
  200. mt76_free_device(&dev->mt76);
  201. return ret;
  202. }
  203. #ifdef CONFIG_PM
  204. static int mt7921u_suspend(struct usb_interface *intf, pm_message_t state)
  205. {
  206. struct mt792x_dev *dev = usb_get_intfdata(intf);
  207. struct mt76_connac_pm *pm = &dev->pm;
  208. int err;
  209. pm->suspended = true;
  210. flush_work(&dev->reset_work);
  211. err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true, true);
  212. if (err)
  213. goto failed;
  214. mt76u_stop_rx(&dev->mt76);
  215. mt76u_stop_tx(&dev->mt76);
  216. return 0;
  217. failed:
  218. pm->suspended = false;
  219. if (err < 0)
  220. mt792x_reset(&dev->mt76);
  221. return err;
  222. }
  223. static int mt7921u_resume(struct usb_interface *intf)
  224. {
  225. struct mt792x_dev *dev = usb_get_intfdata(intf);
  226. struct mt76_connac_pm *pm = &dev->pm;
  227. bool reinit = true;
  228. int err, i;
  229. for (i = 0; i < 10; i++) {
  230. u32 val = mt76_rr(dev, MT_WF_SW_DEF_CR_USB_MCU_EVENT);
  231. if (!(val & MT_WF_SW_SER_TRIGGER_SUSPEND)) {
  232. reinit = false;
  233. break;
  234. }
  235. if (val & MT_WF_SW_SER_DONE_SUSPEND) {
  236. mt76_wr(dev, MT_WF_SW_DEF_CR_USB_MCU_EVENT, 0);
  237. break;
  238. }
  239. msleep(20);
  240. }
  241. if (reinit || mt792x_dma_need_reinit(dev)) {
  242. err = mt792xu_dma_init(dev, true);
  243. if (err)
  244. goto failed;
  245. }
  246. err = mt76u_resume_rx(&dev->mt76);
  247. if (err < 0)
  248. goto failed;
  249. err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false, true);
  250. failed:
  251. pm->suspended = false;
  252. if (err < 0)
  253. mt792x_reset(&dev->mt76);
  254. return err;
  255. }
  256. #endif /* CONFIG_PM */
  257. MODULE_DEVICE_TABLE(usb, mt7921u_device_table);
  258. MODULE_FIRMWARE(MT7921_FIRMWARE_WM);
  259. MODULE_FIRMWARE(MT7921_ROM_PATCH);
  260. static struct usb_driver mt7921u_driver = {
  261. .name = KBUILD_MODNAME,
  262. .id_table = mt7921u_device_table,
  263. .probe = mt7921u_probe,
  264. .disconnect = mt792xu_disconnect,
  265. #ifdef CONFIG_PM
  266. .suspend = mt7921u_suspend,
  267. .resume = mt7921u_resume,
  268. .reset_resume = mt7921u_resume,
  269. #endif /* CONFIG_PM */
  270. .soft_unbind = 1,
  271. .disable_hub_initiated_lpm = 1,
  272. };
  273. module_usb_driver(mt7921u_driver);
  274. MODULE_DESCRIPTION("MediaTek MT7921U (USB) wireless driver");
  275. MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
  276. MODULE_LICENSE("Dual BSD/GPL");