16c92544dSBjoern A. Zeeb // SPDX-License-Identifier: ISC
26c92544dSBjoern A. Zeeb /* Copyright (C) 2022 MediaTek Inc.
36c92544dSBjoern A. Zeeb *
46c92544dSBjoern A. Zeeb * Author: Lorenzo Bianconi <lorenzo@kernel.org>
56c92544dSBjoern A. Zeeb */
66c92544dSBjoern A. Zeeb
76c92544dSBjoern A. Zeeb #include <linux/kernel.h>
86c92544dSBjoern A. Zeeb #include <linux/module.h>
96c92544dSBjoern A. Zeeb #include <linux/usb.h>
106c92544dSBjoern A. Zeeb
116c92544dSBjoern A. Zeeb #include "mt7921.h"
126c92544dSBjoern A. Zeeb #include "mcu.h"
13cbb3ec25SBjoern A. Zeeb #include "../mt76_connac2_mac.h"
146c92544dSBjoern A. Zeeb
156c92544dSBjoern A. Zeeb static const struct usb_device_id mt7921u_device_table[] = {
16cbb3ec25SBjoern A. Zeeb { USB_DEVICE_AND_INTERFACE_INFO(0x0e8d, 0x7961, 0xff, 0xff, 0xff),
17cbb3ec25SBjoern A. Zeeb .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM },
18cbb3ec25SBjoern A. Zeeb /* Comfast CF-952AX */
19cbb3ec25SBjoern A. Zeeb { USB_DEVICE_AND_INTERFACE_INFO(0x3574, 0x6211, 0xff, 0xff, 0xff),
20cbb3ec25SBjoern A. Zeeb .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM },
21cbb3ec25SBjoern A. Zeeb /* Netgear, Inc. [A8000,AXE3000] */
22cbb3ec25SBjoern A. Zeeb { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9060, 0xff, 0xff, 0xff),
23cbb3ec25SBjoern A. Zeeb .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM },
24*8ba4d145SBjoern A. Zeeb /* TP-Link TXE50UH */
25*8ba4d145SBjoern A. Zeeb { USB_DEVICE_AND_INTERFACE_INFO(0x35bc, 0x0107, 0xff, 0xff, 0xff),
26*8ba4d145SBjoern A. Zeeb .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM },
276c92544dSBjoern A. Zeeb { },
286c92544dSBjoern A. Zeeb };
296c92544dSBjoern A. Zeeb
306c92544dSBjoern A. Zeeb static int
mt7921u_mcu_send_message(struct mt76_dev * mdev,struct sk_buff * skb,int cmd,int * seq)316c92544dSBjoern A. Zeeb mt7921u_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
326c92544dSBjoern A. Zeeb int cmd, int *seq)
336c92544dSBjoern A. Zeeb {
34cbb3ec25SBjoern A. Zeeb struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);
356c92544dSBjoern A. Zeeb u32 pad, ep;
366c92544dSBjoern A. Zeeb int ret;
376c92544dSBjoern A. Zeeb
386c92544dSBjoern A. Zeeb ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, seq);
396c92544dSBjoern A. Zeeb if (ret)
406c92544dSBjoern A. Zeeb return ret;
416c92544dSBjoern A. Zeeb
426c92544dSBjoern A. Zeeb mdev->mcu.timeout = 3 * HZ;
436c92544dSBjoern A. Zeeb
446c92544dSBjoern A. Zeeb if (cmd != MCU_CMD(FW_SCATTER))
456c92544dSBjoern A. Zeeb ep = MT_EP_OUT_INBAND_CMD;
466c92544dSBjoern A. Zeeb else
476c92544dSBjoern A. Zeeb ep = MT_EP_OUT_AC_BE;
486c92544dSBjoern A. Zeeb
49*8ba4d145SBjoern A. Zeeb mt792x_skb_add_usb_sdio_hdr(dev, skb, 0);
506c92544dSBjoern A. Zeeb pad = round_up(skb->len, 4) + 4 - skb->len;
516c92544dSBjoern A. Zeeb __skb_put_zero(skb, pad);
526c92544dSBjoern A. Zeeb
536c92544dSBjoern A. Zeeb ret = mt76u_bulk_msg(&dev->mt76, skb->data, skb->len, NULL,
546c92544dSBjoern A. Zeeb 1000, ep);
556c92544dSBjoern A. Zeeb dev_kfree_skb(skb);
566c92544dSBjoern A. Zeeb
576c92544dSBjoern A. Zeeb return ret;
586c92544dSBjoern A. Zeeb }
596c92544dSBjoern A. Zeeb
mt7921u_mcu_init(struct mt792x_dev * dev)60cbb3ec25SBjoern A. Zeeb static int mt7921u_mcu_init(struct mt792x_dev *dev)
616c92544dSBjoern A. Zeeb {
626c92544dSBjoern A. Zeeb static const struct mt76_mcu_ops mcu_ops = {
636c92544dSBjoern A. Zeeb .headroom = MT_SDIO_HDR_SIZE +
646c92544dSBjoern A. Zeeb sizeof(struct mt76_connac2_mcu_txd),
656c92544dSBjoern A. Zeeb .tailroom = MT_USB_TAIL_SIZE,
666c92544dSBjoern A. Zeeb .mcu_skb_send_msg = mt7921u_mcu_send_message,
676c92544dSBjoern A. Zeeb .mcu_parse_response = mt7921_mcu_parse_response,
686c92544dSBjoern A. Zeeb };
696c92544dSBjoern A. Zeeb int ret;
706c92544dSBjoern A. Zeeb
716c92544dSBjoern A. Zeeb dev->mt76.mcu_ops = &mcu_ops;
726c92544dSBjoern A. Zeeb
736c92544dSBjoern A. Zeeb mt76_set(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
746c92544dSBjoern A. Zeeb ret = mt7921_run_firmware(dev);
756c92544dSBjoern A. Zeeb if (ret)
766c92544dSBjoern A. Zeeb return ret;
776c92544dSBjoern A. Zeeb
786c92544dSBjoern A. Zeeb set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
796c92544dSBjoern A. Zeeb mt76_clear(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
806c92544dSBjoern A. Zeeb
816c92544dSBjoern A. Zeeb return 0;
826c92544dSBjoern A. Zeeb }
836c92544dSBjoern A. Zeeb
mt7921u_mac_reset(struct mt792x_dev * dev)84cbb3ec25SBjoern A. Zeeb static int mt7921u_mac_reset(struct mt792x_dev *dev)
85cbb3ec25SBjoern A. Zeeb {
86cbb3ec25SBjoern A. Zeeb int err;
87cbb3ec25SBjoern A. Zeeb
88cbb3ec25SBjoern A. Zeeb mt76_txq_schedule_all(&dev->mphy);
89cbb3ec25SBjoern A. Zeeb mt76_worker_disable(&dev->mt76.tx_worker);
90cbb3ec25SBjoern A. Zeeb
91cbb3ec25SBjoern A. Zeeb set_bit(MT76_RESET, &dev->mphy.state);
92cbb3ec25SBjoern A. Zeeb set_bit(MT76_MCU_RESET, &dev->mphy.state);
93cbb3ec25SBjoern A. Zeeb
94cbb3ec25SBjoern A. Zeeb wake_up(&dev->mt76.mcu.wait);
95cbb3ec25SBjoern A. Zeeb skb_queue_purge(&dev->mt76.mcu.res_q);
96cbb3ec25SBjoern A. Zeeb
97cbb3ec25SBjoern A. Zeeb mt76u_stop_rx(&dev->mt76);
98cbb3ec25SBjoern A. Zeeb mt76u_stop_tx(&dev->mt76);
99cbb3ec25SBjoern A. Zeeb
100cbb3ec25SBjoern A. Zeeb mt792xu_wfsys_reset(dev);
101cbb3ec25SBjoern A. Zeeb
102cbb3ec25SBjoern A. Zeeb clear_bit(MT76_MCU_RESET, &dev->mphy.state);
103cbb3ec25SBjoern A. Zeeb err = mt76u_resume_rx(&dev->mt76);
104cbb3ec25SBjoern A. Zeeb if (err)
105cbb3ec25SBjoern A. Zeeb goto out;
106cbb3ec25SBjoern A. Zeeb
107cbb3ec25SBjoern A. Zeeb err = mt792xu_mcu_power_on(dev);
108cbb3ec25SBjoern A. Zeeb if (err)
109cbb3ec25SBjoern A. Zeeb goto out;
110cbb3ec25SBjoern A. Zeeb
111cbb3ec25SBjoern A. Zeeb err = mt792xu_dma_init(dev, false);
112cbb3ec25SBjoern A. Zeeb if (err)
113cbb3ec25SBjoern A. Zeeb goto out;
114cbb3ec25SBjoern A. Zeeb
115cbb3ec25SBjoern A. Zeeb mt76_wr(dev, MT_SWDEF_MODE, MT_SWDEF_NORMAL_MODE);
116cbb3ec25SBjoern A. Zeeb mt76_set(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
117cbb3ec25SBjoern A. Zeeb
118cbb3ec25SBjoern A. Zeeb err = mt7921_run_firmware(dev);
119cbb3ec25SBjoern A. Zeeb if (err)
120cbb3ec25SBjoern A. Zeeb goto out;
121cbb3ec25SBjoern A. Zeeb
122cbb3ec25SBjoern A. Zeeb mt76_clear(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
123cbb3ec25SBjoern A. Zeeb
124cbb3ec25SBjoern A. Zeeb err = mt7921_mcu_set_eeprom(dev);
125cbb3ec25SBjoern A. Zeeb if (err)
126cbb3ec25SBjoern A. Zeeb goto out;
127cbb3ec25SBjoern A. Zeeb
128cbb3ec25SBjoern A. Zeeb err = mt7921_mac_init(dev);
129cbb3ec25SBjoern A. Zeeb if (err)
130cbb3ec25SBjoern A. Zeeb goto out;
131cbb3ec25SBjoern A. Zeeb
132cbb3ec25SBjoern A. Zeeb err = __mt7921_start(&dev->phy);
133cbb3ec25SBjoern A. Zeeb out:
134cbb3ec25SBjoern A. Zeeb clear_bit(MT76_RESET, &dev->mphy.state);
135cbb3ec25SBjoern A. Zeeb
136cbb3ec25SBjoern A. Zeeb mt76_worker_enable(&dev->mt76.tx_worker);
137cbb3ec25SBjoern A. Zeeb
138cbb3ec25SBjoern A. Zeeb return err;
139cbb3ec25SBjoern A. Zeeb }
140cbb3ec25SBjoern A. Zeeb
mt7921u_probe(struct usb_interface * usb_intf,const struct usb_device_id * id)1416c92544dSBjoern A. Zeeb static int mt7921u_probe(struct usb_interface *usb_intf,
1426c92544dSBjoern A. Zeeb const struct usb_device_id *id)
1436c92544dSBjoern A. Zeeb {
1446c92544dSBjoern A. Zeeb static const struct mt76_driver_ops drv_ops = {
1456c92544dSBjoern A. Zeeb .txwi_size = MT_SDIO_TXD_SIZE,
146cbb3ec25SBjoern A. Zeeb .drv_flags = MT_DRV_RX_DMA_HDR | MT_DRV_HW_MGMT_TXQ |
147cbb3ec25SBjoern A. Zeeb MT_DRV_AMSDU_OFFLOAD,
1486c92544dSBjoern A. Zeeb .survey_flags = SURVEY_INFO_TIME_TX |
1496c92544dSBjoern A. Zeeb SURVEY_INFO_TIME_RX |
1506c92544dSBjoern A. Zeeb SURVEY_INFO_TIME_BSS_RX,
1516c92544dSBjoern A. Zeeb .tx_prepare_skb = mt7921_usb_sdio_tx_prepare_skb,
1526c92544dSBjoern A. Zeeb .tx_complete_skb = mt7921_usb_sdio_tx_complete_skb,
1536c92544dSBjoern A. Zeeb .tx_status_data = mt7921_usb_sdio_tx_status_data,
1546c92544dSBjoern A. Zeeb .rx_skb = mt7921_queue_rx_skb,
1556c92544dSBjoern A. Zeeb .rx_check = mt7921_rx_check,
1566c92544dSBjoern A. Zeeb .sta_add = mt7921_mac_sta_add,
157*8ba4d145SBjoern A. Zeeb .sta_event = mt7921_mac_sta_event,
1586c92544dSBjoern A. Zeeb .sta_remove = mt7921_mac_sta_remove,
159cbb3ec25SBjoern A. Zeeb .update_survey = mt792x_update_channel,
160*8ba4d145SBjoern A. Zeeb .set_channel = mt7921_set_channel,
1616c92544dSBjoern A. Zeeb };
162cbb3ec25SBjoern A. Zeeb static const struct mt792x_hif_ops hif_ops = {
1636c92544dSBjoern A. Zeeb .mcu_init = mt7921u_mcu_init,
164cbb3ec25SBjoern A. Zeeb .init_reset = mt792xu_init_reset,
1656c92544dSBjoern A. Zeeb .reset = mt7921u_mac_reset,
1666c92544dSBjoern A. Zeeb };
1676c92544dSBjoern A. Zeeb static struct mt76_bus_ops bus_ops = {
168cbb3ec25SBjoern A. Zeeb .rr = mt792xu_rr,
169cbb3ec25SBjoern A. Zeeb .wr = mt792xu_wr,
170cbb3ec25SBjoern A. Zeeb .rmw = mt792xu_rmw,
1716c92544dSBjoern A. Zeeb .read_copy = mt76u_read_copy,
172cbb3ec25SBjoern A. Zeeb .write_copy = mt792xu_copy,
1736c92544dSBjoern A. Zeeb .type = MT76_BUS_USB,
1746c92544dSBjoern A. Zeeb };
1756c92544dSBjoern A. Zeeb struct usb_device *udev = interface_to_usbdev(usb_intf);
1766c92544dSBjoern A. Zeeb struct ieee80211_ops *ops;
1776c92544dSBjoern A. Zeeb struct ieee80211_hw *hw;
178cbb3ec25SBjoern A. Zeeb struct mt792x_dev *dev;
1796c92544dSBjoern A. Zeeb struct mt76_dev *mdev;
180cbb3ec25SBjoern A. Zeeb u8 features;
1816c92544dSBjoern A. Zeeb int ret;
1826c92544dSBjoern A. Zeeb
183cbb3ec25SBjoern A. Zeeb ops = mt792x_get_mac80211_ops(&usb_intf->dev, &mt7921_ops,
184cbb3ec25SBjoern A. Zeeb (void *)id->driver_info, &features);
1856c92544dSBjoern A. Zeeb if (!ops)
1866c92544dSBjoern A. Zeeb return -ENOMEM;
1876c92544dSBjoern A. Zeeb
188*8ba4d145SBjoern A. Zeeb ops->stop = mt792xu_stop;
1896c92544dSBjoern A. Zeeb mdev = mt76_alloc_device(&usb_intf->dev, sizeof(*dev), ops, &drv_ops);
1906c92544dSBjoern A. Zeeb if (!mdev)
1916c92544dSBjoern A. Zeeb return -ENOMEM;
1926c92544dSBjoern A. Zeeb
193cbb3ec25SBjoern A. Zeeb dev = container_of(mdev, struct mt792x_dev, mt76);
194cbb3ec25SBjoern A. Zeeb dev->fw_features = features;
1956c92544dSBjoern A. Zeeb dev->hif_ops = &hif_ops;
1966c92544dSBjoern A. Zeeb
1976c92544dSBjoern A. Zeeb udev = usb_get_dev(udev);
1986c92544dSBjoern A. Zeeb usb_reset_device(udev);
1996c92544dSBjoern A. Zeeb
2006c92544dSBjoern A. Zeeb usb_set_intfdata(usb_intf, dev);
2016c92544dSBjoern A. Zeeb
2026c92544dSBjoern A. Zeeb ret = __mt76u_init(mdev, usb_intf, &bus_ops);
2036c92544dSBjoern A. Zeeb if (ret < 0)
2046c92544dSBjoern A. Zeeb goto error;
2056c92544dSBjoern A. Zeeb
2066c92544dSBjoern A. Zeeb mdev->rev = (mt76_rr(dev, MT_HW_CHIPID) << 16) |
2076c92544dSBjoern A. Zeeb (mt76_rr(dev, MT_HW_REV) & 0xff);
2086c92544dSBjoern A. Zeeb dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
2096c92544dSBjoern A. Zeeb
2106c92544dSBjoern A. Zeeb if (mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY)) {
211cbb3ec25SBjoern A. Zeeb ret = mt792xu_wfsys_reset(dev);
2126c92544dSBjoern A. Zeeb if (ret)
2136c92544dSBjoern A. Zeeb goto error;
2146c92544dSBjoern A. Zeeb }
2156c92544dSBjoern A. Zeeb
216cbb3ec25SBjoern A. Zeeb ret = mt792xu_mcu_power_on(dev);
2176c92544dSBjoern A. Zeeb if (ret)
2186c92544dSBjoern A. Zeeb goto error;
2196c92544dSBjoern A. Zeeb
2206c92544dSBjoern A. Zeeb ret = mt76u_alloc_mcu_queue(&dev->mt76);
2216c92544dSBjoern A. Zeeb if (ret)
2226c92544dSBjoern A. Zeeb goto error;
2236c92544dSBjoern A. Zeeb
2246c92544dSBjoern A. Zeeb ret = mt76u_alloc_queues(&dev->mt76);
2256c92544dSBjoern A. Zeeb if (ret)
2266c92544dSBjoern A. Zeeb goto error;
2276c92544dSBjoern A. Zeeb
228cbb3ec25SBjoern A. Zeeb ret = mt792xu_dma_init(dev, false);
2296c92544dSBjoern A. Zeeb if (ret)
230cbb3ec25SBjoern A. Zeeb goto error;
2316c92544dSBjoern A. Zeeb
2326c92544dSBjoern A. Zeeb hw = mt76_hw(dev);
2336c92544dSBjoern A. Zeeb /* check hw sg support in order to enable AMSDU */
2346c92544dSBjoern A. Zeeb hw->max_tx_fragments = mdev->usb.sg_en ? MT_HW_TXP_MAX_BUF_NUM : 1;
2356c92544dSBjoern A. Zeeb
2366c92544dSBjoern A. Zeeb ret = mt7921_register_device(dev);
2376c92544dSBjoern A. Zeeb if (ret)
2386c92544dSBjoern A. Zeeb goto error;
2396c92544dSBjoern A. Zeeb
2406c92544dSBjoern A. Zeeb return 0;
2416c92544dSBjoern A. Zeeb
2426c92544dSBjoern A. Zeeb error:
2436c92544dSBjoern A. Zeeb mt76u_queues_deinit(&dev->mt76);
2446c92544dSBjoern A. Zeeb
2456c92544dSBjoern A. Zeeb usb_set_intfdata(usb_intf, NULL);
2466c92544dSBjoern A. Zeeb usb_put_dev(interface_to_usbdev(usb_intf));
2476c92544dSBjoern A. Zeeb
2486c92544dSBjoern A. Zeeb mt76_free_device(&dev->mt76);
2496c92544dSBjoern A. Zeeb
2506c92544dSBjoern A. Zeeb return ret;
2516c92544dSBjoern A. Zeeb }
2526c92544dSBjoern A. Zeeb
2536c92544dSBjoern A. Zeeb #ifdef CONFIG_PM
mt7921u_suspend(struct usb_interface * intf,pm_message_t state)2546c92544dSBjoern A. Zeeb static int mt7921u_suspend(struct usb_interface *intf, pm_message_t state)
2556c92544dSBjoern A. Zeeb {
256cbb3ec25SBjoern A. Zeeb struct mt792x_dev *dev = usb_get_intfdata(intf);
2576c92544dSBjoern A. Zeeb struct mt76_connac_pm *pm = &dev->pm;
2586c92544dSBjoern A. Zeeb int err;
2596c92544dSBjoern A. Zeeb
2606c92544dSBjoern A. Zeeb pm->suspended = true;
2616c92544dSBjoern A. Zeeb flush_work(&dev->reset_work);
2626c92544dSBjoern A. Zeeb
263*8ba4d145SBjoern A. Zeeb err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true, true);
2646c92544dSBjoern A. Zeeb if (err)
2656c92544dSBjoern A. Zeeb goto failed;
2666c92544dSBjoern A. Zeeb
2676c92544dSBjoern A. Zeeb mt76u_stop_rx(&dev->mt76);
2686c92544dSBjoern A. Zeeb mt76u_stop_tx(&dev->mt76);
2696c92544dSBjoern A. Zeeb
2706c92544dSBjoern A. Zeeb return 0;
2716c92544dSBjoern A. Zeeb
2726c92544dSBjoern A. Zeeb failed:
2736c92544dSBjoern A. Zeeb pm->suspended = false;
2746c92544dSBjoern A. Zeeb
2756c92544dSBjoern A. Zeeb if (err < 0)
276cbb3ec25SBjoern A. Zeeb mt792x_reset(&dev->mt76);
2776c92544dSBjoern A. Zeeb
2786c92544dSBjoern A. Zeeb return err;
2796c92544dSBjoern A. Zeeb }
2806c92544dSBjoern A. Zeeb
mt7921u_resume(struct usb_interface * intf)2816c92544dSBjoern A. Zeeb static int mt7921u_resume(struct usb_interface *intf)
2826c92544dSBjoern A. Zeeb {
283cbb3ec25SBjoern A. Zeeb struct mt792x_dev *dev = usb_get_intfdata(intf);
2846c92544dSBjoern A. Zeeb struct mt76_connac_pm *pm = &dev->pm;
2856c92544dSBjoern A. Zeeb bool reinit = true;
2866c92544dSBjoern A. Zeeb int err, i;
2876c92544dSBjoern A. Zeeb
2886c92544dSBjoern A. Zeeb for (i = 0; i < 10; i++) {
2896c92544dSBjoern A. Zeeb u32 val = mt76_rr(dev, MT_WF_SW_DEF_CR_USB_MCU_EVENT);
2906c92544dSBjoern A. Zeeb
2916c92544dSBjoern A. Zeeb if (!(val & MT_WF_SW_SER_TRIGGER_SUSPEND)) {
2926c92544dSBjoern A. Zeeb reinit = false;
2936c92544dSBjoern A. Zeeb break;
2946c92544dSBjoern A. Zeeb }
2956c92544dSBjoern A. Zeeb if (val & MT_WF_SW_SER_DONE_SUSPEND) {
2966c92544dSBjoern A. Zeeb mt76_wr(dev, MT_WF_SW_DEF_CR_USB_MCU_EVENT, 0);
2976c92544dSBjoern A. Zeeb break;
2986c92544dSBjoern A. Zeeb }
2996c92544dSBjoern A. Zeeb
3006c92544dSBjoern A. Zeeb msleep(20);
3016c92544dSBjoern A. Zeeb }
3026c92544dSBjoern A. Zeeb
303cbb3ec25SBjoern A. Zeeb if (reinit || mt792x_dma_need_reinit(dev)) {
304cbb3ec25SBjoern A. Zeeb err = mt792xu_dma_init(dev, true);
3056c92544dSBjoern A. Zeeb if (err)
3066c92544dSBjoern A. Zeeb goto failed;
3076c92544dSBjoern A. Zeeb }
3086c92544dSBjoern A. Zeeb
3096c92544dSBjoern A. Zeeb err = mt76u_resume_rx(&dev->mt76);
3106c92544dSBjoern A. Zeeb if (err < 0)
3116c92544dSBjoern A. Zeeb goto failed;
3126c92544dSBjoern A. Zeeb
313*8ba4d145SBjoern A. Zeeb err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false, true);
3146c92544dSBjoern A. Zeeb failed:
3156c92544dSBjoern A. Zeeb pm->suspended = false;
3166c92544dSBjoern A. Zeeb
3176c92544dSBjoern A. Zeeb if (err < 0)
318cbb3ec25SBjoern A. Zeeb mt792x_reset(&dev->mt76);
3196c92544dSBjoern A. Zeeb
3206c92544dSBjoern A. Zeeb return err;
3216c92544dSBjoern A. Zeeb }
3226c92544dSBjoern A. Zeeb #endif /* CONFIG_PM */
3236c92544dSBjoern A. Zeeb
3246c92544dSBjoern A. Zeeb MODULE_DEVICE_TABLE(usb, mt7921u_device_table);
3256c92544dSBjoern A. Zeeb MODULE_FIRMWARE(MT7921_FIRMWARE_WM);
3266c92544dSBjoern A. Zeeb MODULE_FIRMWARE(MT7921_ROM_PATCH);
3276c92544dSBjoern A. Zeeb
3286c92544dSBjoern A. Zeeb static struct usb_driver mt7921u_driver = {
3296c92544dSBjoern A. Zeeb .name = KBUILD_MODNAME,
3306c92544dSBjoern A. Zeeb .id_table = mt7921u_device_table,
3316c92544dSBjoern A. Zeeb .probe = mt7921u_probe,
332cbb3ec25SBjoern A. Zeeb .disconnect = mt792xu_disconnect,
3336c92544dSBjoern A. Zeeb #ifdef CONFIG_PM
3346c92544dSBjoern A. Zeeb .suspend = mt7921u_suspend,
3356c92544dSBjoern A. Zeeb .resume = mt7921u_resume,
3366c92544dSBjoern A. Zeeb .reset_resume = mt7921u_resume,
3376c92544dSBjoern A. Zeeb #endif /* CONFIG_PM */
3386c92544dSBjoern A. Zeeb .soft_unbind = 1,
3396c92544dSBjoern A. Zeeb .disable_hub_initiated_lpm = 1,
3406c92544dSBjoern A. Zeeb };
3416c92544dSBjoern A. Zeeb module_usb_driver(mt7921u_driver);
3426c92544dSBjoern A. Zeeb
343*8ba4d145SBjoern A. Zeeb MODULE_DESCRIPTION("MediaTek MT7921U (USB) wireless driver");
3446c92544dSBjoern A. Zeeb MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
3456c92544dSBjoern A. Zeeb MODULE_LICENSE("Dual BSD/GPL");
346