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 },
246c92544dSBjoern A. Zeeb { },
256c92544dSBjoern A. Zeeb };
266c92544dSBjoern A. Zeeb
276c92544dSBjoern A. Zeeb static int
mt7921u_mcu_send_message(struct mt76_dev * mdev,struct sk_buff * skb,int cmd,int * seq)286c92544dSBjoern A. Zeeb mt7921u_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
296c92544dSBjoern A. Zeeb int cmd, int *seq)
306c92544dSBjoern A. Zeeb {
31cbb3ec25SBjoern A. Zeeb struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);
326c92544dSBjoern A. Zeeb u32 pad, ep;
336c92544dSBjoern A. Zeeb int ret;
346c92544dSBjoern A. Zeeb
356c92544dSBjoern A. Zeeb ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, seq);
366c92544dSBjoern A. Zeeb if (ret)
376c92544dSBjoern A. Zeeb return ret;
386c92544dSBjoern A. Zeeb
396c92544dSBjoern A. Zeeb mdev->mcu.timeout = 3 * HZ;
406c92544dSBjoern A. Zeeb
416c92544dSBjoern A. Zeeb if (cmd != MCU_CMD(FW_SCATTER))
426c92544dSBjoern A. Zeeb ep = MT_EP_OUT_INBAND_CMD;
436c92544dSBjoern A. Zeeb else
446c92544dSBjoern A. Zeeb ep = MT_EP_OUT_AC_BE;
456c92544dSBjoern A. Zeeb
466c92544dSBjoern A. Zeeb mt7921_skb_add_usb_sdio_hdr(dev, skb, 0);
476c92544dSBjoern A. Zeeb pad = round_up(skb->len, 4) + 4 - skb->len;
486c92544dSBjoern A. Zeeb __skb_put_zero(skb, pad);
496c92544dSBjoern A. Zeeb
506c92544dSBjoern A. Zeeb ret = mt76u_bulk_msg(&dev->mt76, skb->data, skb->len, NULL,
516c92544dSBjoern A. Zeeb 1000, ep);
526c92544dSBjoern A. Zeeb dev_kfree_skb(skb);
536c92544dSBjoern A. Zeeb
546c92544dSBjoern A. Zeeb return ret;
556c92544dSBjoern A. Zeeb }
566c92544dSBjoern A. Zeeb
mt7921u_mcu_init(struct mt792x_dev * dev)57cbb3ec25SBjoern A. Zeeb static int mt7921u_mcu_init(struct mt792x_dev *dev)
586c92544dSBjoern A. Zeeb {
596c92544dSBjoern A. Zeeb static const struct mt76_mcu_ops mcu_ops = {
606c92544dSBjoern A. Zeeb .headroom = MT_SDIO_HDR_SIZE +
616c92544dSBjoern A. Zeeb sizeof(struct mt76_connac2_mcu_txd),
626c92544dSBjoern A. Zeeb .tailroom = MT_USB_TAIL_SIZE,
636c92544dSBjoern A. Zeeb .mcu_skb_send_msg = mt7921u_mcu_send_message,
646c92544dSBjoern A. Zeeb .mcu_parse_response = mt7921_mcu_parse_response,
656c92544dSBjoern A. Zeeb };
666c92544dSBjoern A. Zeeb int ret;
676c92544dSBjoern A. Zeeb
686c92544dSBjoern A. Zeeb dev->mt76.mcu_ops = &mcu_ops;
696c92544dSBjoern A. Zeeb
706c92544dSBjoern A. Zeeb mt76_set(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
716c92544dSBjoern A. Zeeb ret = mt7921_run_firmware(dev);
726c92544dSBjoern A. Zeeb if (ret)
736c92544dSBjoern A. Zeeb return ret;
746c92544dSBjoern A. Zeeb
756c92544dSBjoern A. Zeeb set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
766c92544dSBjoern A. Zeeb mt76_clear(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
776c92544dSBjoern A. Zeeb
786c92544dSBjoern A. Zeeb return 0;
796c92544dSBjoern A. Zeeb }
806c92544dSBjoern A. Zeeb
mt7921u_mac_reset(struct mt792x_dev * dev)81cbb3ec25SBjoern A. Zeeb static int mt7921u_mac_reset(struct mt792x_dev *dev)
82cbb3ec25SBjoern A. Zeeb {
83cbb3ec25SBjoern A. Zeeb int err;
84cbb3ec25SBjoern A. Zeeb
85cbb3ec25SBjoern A. Zeeb mt76_txq_schedule_all(&dev->mphy);
86cbb3ec25SBjoern A. Zeeb mt76_worker_disable(&dev->mt76.tx_worker);
87cbb3ec25SBjoern A. Zeeb
88cbb3ec25SBjoern A. Zeeb set_bit(MT76_RESET, &dev->mphy.state);
89cbb3ec25SBjoern A. Zeeb set_bit(MT76_MCU_RESET, &dev->mphy.state);
90cbb3ec25SBjoern A. Zeeb
91cbb3ec25SBjoern A. Zeeb wake_up(&dev->mt76.mcu.wait);
92cbb3ec25SBjoern A. Zeeb skb_queue_purge(&dev->mt76.mcu.res_q);
93cbb3ec25SBjoern A. Zeeb
94cbb3ec25SBjoern A. Zeeb mt76u_stop_rx(&dev->mt76);
95cbb3ec25SBjoern A. Zeeb mt76u_stop_tx(&dev->mt76);
96cbb3ec25SBjoern A. Zeeb
97cbb3ec25SBjoern A. Zeeb mt792xu_wfsys_reset(dev);
98cbb3ec25SBjoern A. Zeeb
99cbb3ec25SBjoern A. Zeeb clear_bit(MT76_MCU_RESET, &dev->mphy.state);
100cbb3ec25SBjoern A. Zeeb err = mt76u_resume_rx(&dev->mt76);
101cbb3ec25SBjoern A. Zeeb if (err)
102cbb3ec25SBjoern A. Zeeb goto out;
103cbb3ec25SBjoern A. Zeeb
104cbb3ec25SBjoern A. Zeeb err = mt792xu_mcu_power_on(dev);
105cbb3ec25SBjoern A. Zeeb if (err)
106cbb3ec25SBjoern A. Zeeb goto out;
107cbb3ec25SBjoern A. Zeeb
108cbb3ec25SBjoern A. Zeeb err = mt792xu_dma_init(dev, false);
109cbb3ec25SBjoern A. Zeeb if (err)
110cbb3ec25SBjoern A. Zeeb goto out;
111cbb3ec25SBjoern A. Zeeb
112cbb3ec25SBjoern A. Zeeb mt76_wr(dev, MT_SWDEF_MODE, MT_SWDEF_NORMAL_MODE);
113cbb3ec25SBjoern A. Zeeb mt76_set(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
114cbb3ec25SBjoern A. Zeeb
115cbb3ec25SBjoern A. Zeeb err = mt7921_run_firmware(dev);
116cbb3ec25SBjoern A. Zeeb if (err)
117cbb3ec25SBjoern A. Zeeb goto out;
118cbb3ec25SBjoern A. Zeeb
119cbb3ec25SBjoern A. Zeeb mt76_clear(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
120cbb3ec25SBjoern A. Zeeb
121cbb3ec25SBjoern A. Zeeb err = mt7921_mcu_set_eeprom(dev);
122cbb3ec25SBjoern A. Zeeb if (err)
123cbb3ec25SBjoern A. Zeeb goto out;
124cbb3ec25SBjoern A. Zeeb
125cbb3ec25SBjoern A. Zeeb err = mt7921_mac_init(dev);
126cbb3ec25SBjoern A. Zeeb if (err)
127cbb3ec25SBjoern A. Zeeb goto out;
128cbb3ec25SBjoern A. Zeeb
129cbb3ec25SBjoern A. Zeeb err = __mt7921_start(&dev->phy);
130cbb3ec25SBjoern A. Zeeb out:
131cbb3ec25SBjoern A. Zeeb clear_bit(MT76_RESET, &dev->mphy.state);
132cbb3ec25SBjoern A. Zeeb
133cbb3ec25SBjoern A. Zeeb mt76_worker_enable(&dev->mt76.tx_worker);
134cbb3ec25SBjoern A. Zeeb
135cbb3ec25SBjoern A. Zeeb return err;
136cbb3ec25SBjoern A. Zeeb }
137cbb3ec25SBjoern A. Zeeb
mt7921u_stop(struct ieee80211_hw * hw)1386c92544dSBjoern A. Zeeb static void mt7921u_stop(struct ieee80211_hw *hw)
1396c92544dSBjoern A. Zeeb {
140cbb3ec25SBjoern A. Zeeb struct mt792x_dev *dev = mt792x_hw_dev(hw);
1416c92544dSBjoern A. Zeeb
1426c92544dSBjoern A. Zeeb mt76u_stop_tx(&dev->mt76);
1436c92544dSBjoern A. Zeeb mt7921_stop(hw);
1446c92544dSBjoern A. Zeeb }
1456c92544dSBjoern A. Zeeb
mt7921u_probe(struct usb_interface * usb_intf,const struct usb_device_id * id)1466c92544dSBjoern A. Zeeb static int mt7921u_probe(struct usb_interface *usb_intf,
1476c92544dSBjoern A. Zeeb const struct usb_device_id *id)
1486c92544dSBjoern A. Zeeb {
1496c92544dSBjoern A. Zeeb static const struct mt76_driver_ops drv_ops = {
1506c92544dSBjoern A. Zeeb .txwi_size = MT_SDIO_TXD_SIZE,
151cbb3ec25SBjoern A. Zeeb .drv_flags = MT_DRV_RX_DMA_HDR | MT_DRV_HW_MGMT_TXQ |
152cbb3ec25SBjoern A. Zeeb MT_DRV_AMSDU_OFFLOAD,
1536c92544dSBjoern A. Zeeb .survey_flags = SURVEY_INFO_TIME_TX |
1546c92544dSBjoern A. Zeeb SURVEY_INFO_TIME_RX |
1556c92544dSBjoern A. Zeeb SURVEY_INFO_TIME_BSS_RX,
1566c92544dSBjoern A. Zeeb .tx_prepare_skb = mt7921_usb_sdio_tx_prepare_skb,
1576c92544dSBjoern A. Zeeb .tx_complete_skb = mt7921_usb_sdio_tx_complete_skb,
1586c92544dSBjoern A. Zeeb .tx_status_data = mt7921_usb_sdio_tx_status_data,
1596c92544dSBjoern A. Zeeb .rx_skb = mt7921_queue_rx_skb,
1606c92544dSBjoern A. Zeeb .rx_check = mt7921_rx_check,
1616c92544dSBjoern A. Zeeb .sta_add = mt7921_mac_sta_add,
1626c92544dSBjoern A. Zeeb .sta_assoc = mt7921_mac_sta_assoc,
1636c92544dSBjoern A. Zeeb .sta_remove = mt7921_mac_sta_remove,
164cbb3ec25SBjoern A. Zeeb .update_survey = mt792x_update_channel,
1656c92544dSBjoern A. Zeeb };
166cbb3ec25SBjoern A. Zeeb static const struct mt792x_hif_ops hif_ops = {
1676c92544dSBjoern A. Zeeb .mcu_init = mt7921u_mcu_init,
168cbb3ec25SBjoern A. Zeeb .init_reset = mt792xu_init_reset,
1696c92544dSBjoern A. Zeeb .reset = mt7921u_mac_reset,
1706c92544dSBjoern A. Zeeb };
1716c92544dSBjoern A. Zeeb static struct mt76_bus_ops bus_ops = {
172cbb3ec25SBjoern A. Zeeb .rr = mt792xu_rr,
173cbb3ec25SBjoern A. Zeeb .wr = mt792xu_wr,
174cbb3ec25SBjoern A. Zeeb .rmw = mt792xu_rmw,
1756c92544dSBjoern A. Zeeb .read_copy = mt76u_read_copy,
176cbb3ec25SBjoern A. Zeeb .write_copy = mt792xu_copy,
1776c92544dSBjoern A. Zeeb .type = MT76_BUS_USB,
1786c92544dSBjoern A. Zeeb };
1796c92544dSBjoern A. Zeeb struct usb_device *udev = interface_to_usbdev(usb_intf);
1806c92544dSBjoern A. Zeeb struct ieee80211_ops *ops;
1816c92544dSBjoern A. Zeeb struct ieee80211_hw *hw;
182cbb3ec25SBjoern A. Zeeb struct mt792x_dev *dev;
1836c92544dSBjoern A. Zeeb struct mt76_dev *mdev;
184cbb3ec25SBjoern A. Zeeb u8 features;
1856c92544dSBjoern A. Zeeb int ret;
1866c92544dSBjoern A. Zeeb
187cbb3ec25SBjoern A. Zeeb ops = mt792x_get_mac80211_ops(&usb_intf->dev, &mt7921_ops,
188cbb3ec25SBjoern A. Zeeb (void *)id->driver_info, &features);
1896c92544dSBjoern A. Zeeb if (!ops)
1906c92544dSBjoern A. Zeeb return -ENOMEM;
1916c92544dSBjoern A. Zeeb
1926c92544dSBjoern A. Zeeb ops->stop = mt7921u_stop;
1936c92544dSBjoern A. Zeeb mdev = mt76_alloc_device(&usb_intf->dev, sizeof(*dev), ops, &drv_ops);
1946c92544dSBjoern A. Zeeb if (!mdev)
1956c92544dSBjoern A. Zeeb return -ENOMEM;
1966c92544dSBjoern A. Zeeb
197cbb3ec25SBjoern A. Zeeb dev = container_of(mdev, struct mt792x_dev, mt76);
198cbb3ec25SBjoern A. Zeeb dev->fw_features = features;
1996c92544dSBjoern A. Zeeb dev->hif_ops = &hif_ops;
2006c92544dSBjoern A. Zeeb
2016c92544dSBjoern A. Zeeb udev = usb_get_dev(udev);
2026c92544dSBjoern A. Zeeb usb_reset_device(udev);
2036c92544dSBjoern A. Zeeb
2046c92544dSBjoern A. Zeeb usb_set_intfdata(usb_intf, dev);
2056c92544dSBjoern A. Zeeb
2066c92544dSBjoern A. Zeeb ret = __mt76u_init(mdev, usb_intf, &bus_ops);
2076c92544dSBjoern A. Zeeb if (ret < 0)
2086c92544dSBjoern A. Zeeb goto error;
2096c92544dSBjoern A. Zeeb
2106c92544dSBjoern A. Zeeb mdev->rev = (mt76_rr(dev, MT_HW_CHIPID) << 16) |
2116c92544dSBjoern A. Zeeb (mt76_rr(dev, MT_HW_REV) & 0xff);
2126c92544dSBjoern A. Zeeb dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
2136c92544dSBjoern A. Zeeb
2146c92544dSBjoern A. Zeeb if (mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY)) {
215cbb3ec25SBjoern A. Zeeb ret = mt792xu_wfsys_reset(dev);
2166c92544dSBjoern A. Zeeb if (ret)
2176c92544dSBjoern A. Zeeb goto error;
2186c92544dSBjoern A. Zeeb }
2196c92544dSBjoern A. Zeeb
220cbb3ec25SBjoern A. Zeeb ret = mt792xu_mcu_power_on(dev);
2216c92544dSBjoern A. Zeeb if (ret)
2226c92544dSBjoern A. Zeeb goto error;
2236c92544dSBjoern A. Zeeb
2246c92544dSBjoern A. Zeeb ret = mt76u_alloc_mcu_queue(&dev->mt76);
2256c92544dSBjoern A. Zeeb if (ret)
2266c92544dSBjoern A. Zeeb goto error;
2276c92544dSBjoern A. Zeeb
2286c92544dSBjoern A. Zeeb ret = mt76u_alloc_queues(&dev->mt76);
2296c92544dSBjoern A. Zeeb if (ret)
2306c92544dSBjoern A. Zeeb goto error;
2316c92544dSBjoern A. Zeeb
232cbb3ec25SBjoern A. Zeeb ret = mt792xu_dma_init(dev, false);
2336c92544dSBjoern A. Zeeb if (ret)
234cbb3ec25SBjoern A. Zeeb goto error;
2356c92544dSBjoern A. Zeeb
2366c92544dSBjoern A. Zeeb hw = mt76_hw(dev);
2376c92544dSBjoern A. Zeeb /* check hw sg support in order to enable AMSDU */
2386c92544dSBjoern A. Zeeb hw->max_tx_fragments = mdev->usb.sg_en ? MT_HW_TXP_MAX_BUF_NUM : 1;
2396c92544dSBjoern A. Zeeb
2406c92544dSBjoern A. Zeeb ret = mt7921_register_device(dev);
2416c92544dSBjoern A. Zeeb if (ret)
2426c92544dSBjoern A. Zeeb goto error;
2436c92544dSBjoern A. Zeeb
2446c92544dSBjoern A. Zeeb return 0;
2456c92544dSBjoern A. Zeeb
2466c92544dSBjoern A. Zeeb error:
2476c92544dSBjoern A. Zeeb mt76u_queues_deinit(&dev->mt76);
2486c92544dSBjoern A. Zeeb
2496c92544dSBjoern A. Zeeb usb_set_intfdata(usb_intf, NULL);
2506c92544dSBjoern A. Zeeb usb_put_dev(interface_to_usbdev(usb_intf));
2516c92544dSBjoern A. Zeeb
2526c92544dSBjoern A. Zeeb mt76_free_device(&dev->mt76);
2536c92544dSBjoern A. Zeeb
2546c92544dSBjoern A. Zeeb return ret;
2556c92544dSBjoern A. Zeeb }
2566c92544dSBjoern A. Zeeb
2576c92544dSBjoern A. Zeeb #ifdef CONFIG_PM
mt7921u_suspend(struct usb_interface * intf,pm_message_t state)2586c92544dSBjoern A. Zeeb static int mt7921u_suspend(struct usb_interface *intf, pm_message_t state)
2596c92544dSBjoern A. Zeeb {
260cbb3ec25SBjoern A. Zeeb struct mt792x_dev *dev = usb_get_intfdata(intf);
2616c92544dSBjoern A. Zeeb struct mt76_connac_pm *pm = &dev->pm;
2626c92544dSBjoern A. Zeeb int err;
2636c92544dSBjoern A. Zeeb
2646c92544dSBjoern A. Zeeb pm->suspended = true;
2656c92544dSBjoern A. Zeeb flush_work(&dev->reset_work);
2666c92544dSBjoern A. Zeeb
2676c92544dSBjoern A. Zeeb err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true);
2686c92544dSBjoern A. Zeeb if (err)
2696c92544dSBjoern A. Zeeb goto failed;
2706c92544dSBjoern A. Zeeb
2716c92544dSBjoern A. Zeeb mt76u_stop_rx(&dev->mt76);
2726c92544dSBjoern A. Zeeb mt76u_stop_tx(&dev->mt76);
2736c92544dSBjoern A. Zeeb
2746c92544dSBjoern A. Zeeb return 0;
2756c92544dSBjoern A. Zeeb
2766c92544dSBjoern A. Zeeb failed:
2776c92544dSBjoern A. Zeeb pm->suspended = false;
2786c92544dSBjoern A. Zeeb
2796c92544dSBjoern A. Zeeb if (err < 0)
280cbb3ec25SBjoern A. Zeeb mt792x_reset(&dev->mt76);
2816c92544dSBjoern A. Zeeb
2826c92544dSBjoern A. Zeeb return err;
2836c92544dSBjoern A. Zeeb }
2846c92544dSBjoern A. Zeeb
mt7921u_resume(struct usb_interface * intf)2856c92544dSBjoern A. Zeeb static int mt7921u_resume(struct usb_interface *intf)
2866c92544dSBjoern A. Zeeb {
287cbb3ec25SBjoern A. Zeeb struct mt792x_dev *dev = usb_get_intfdata(intf);
2886c92544dSBjoern A. Zeeb struct mt76_connac_pm *pm = &dev->pm;
2896c92544dSBjoern A. Zeeb bool reinit = true;
2906c92544dSBjoern A. Zeeb int err, i;
2916c92544dSBjoern A. Zeeb
2926c92544dSBjoern A. Zeeb for (i = 0; i < 10; i++) {
2936c92544dSBjoern A. Zeeb u32 val = mt76_rr(dev, MT_WF_SW_DEF_CR_USB_MCU_EVENT);
2946c92544dSBjoern A. Zeeb
2956c92544dSBjoern A. Zeeb if (!(val & MT_WF_SW_SER_TRIGGER_SUSPEND)) {
2966c92544dSBjoern A. Zeeb reinit = false;
2976c92544dSBjoern A. Zeeb break;
2986c92544dSBjoern A. Zeeb }
2996c92544dSBjoern A. Zeeb if (val & MT_WF_SW_SER_DONE_SUSPEND) {
3006c92544dSBjoern A. Zeeb mt76_wr(dev, MT_WF_SW_DEF_CR_USB_MCU_EVENT, 0);
3016c92544dSBjoern A. Zeeb break;
3026c92544dSBjoern A. Zeeb }
3036c92544dSBjoern A. Zeeb
3046c92544dSBjoern A. Zeeb msleep(20);
3056c92544dSBjoern A. Zeeb }
3066c92544dSBjoern A. Zeeb
307cbb3ec25SBjoern A. Zeeb if (reinit || mt792x_dma_need_reinit(dev)) {
308cbb3ec25SBjoern A. Zeeb err = mt792xu_dma_init(dev, true);
3096c92544dSBjoern A. Zeeb if (err)
3106c92544dSBjoern A. Zeeb goto failed;
3116c92544dSBjoern A. Zeeb }
3126c92544dSBjoern A. Zeeb
3136c92544dSBjoern A. Zeeb err = mt76u_resume_rx(&dev->mt76);
3146c92544dSBjoern A. Zeeb if (err < 0)
3156c92544dSBjoern A. Zeeb goto failed;
3166c92544dSBjoern A. Zeeb
3176c92544dSBjoern A. Zeeb err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false);
3186c92544dSBjoern A. Zeeb failed:
3196c92544dSBjoern A. Zeeb pm->suspended = false;
3206c92544dSBjoern A. Zeeb
3216c92544dSBjoern A. Zeeb if (err < 0)
322cbb3ec25SBjoern A. Zeeb mt792x_reset(&dev->mt76);
3236c92544dSBjoern A. Zeeb
3246c92544dSBjoern A. Zeeb return err;
3256c92544dSBjoern A. Zeeb }
3266c92544dSBjoern A. Zeeb #endif /* CONFIG_PM */
3276c92544dSBjoern A. Zeeb
3286c92544dSBjoern A. Zeeb MODULE_DEVICE_TABLE(usb, mt7921u_device_table);
3296c92544dSBjoern A. Zeeb MODULE_FIRMWARE(MT7921_FIRMWARE_WM);
3306c92544dSBjoern A. Zeeb MODULE_FIRMWARE(MT7921_ROM_PATCH);
3316c92544dSBjoern A. Zeeb
3326c92544dSBjoern A. Zeeb static struct usb_driver mt7921u_driver = {
3336c92544dSBjoern A. Zeeb .name = KBUILD_MODNAME,
3346c92544dSBjoern A. Zeeb .id_table = mt7921u_device_table,
3356c92544dSBjoern A. Zeeb .probe = mt7921u_probe,
336cbb3ec25SBjoern A. Zeeb .disconnect = mt792xu_disconnect,
3376c92544dSBjoern A. Zeeb #ifdef CONFIG_PM
3386c92544dSBjoern A. Zeeb .suspend = mt7921u_suspend,
3396c92544dSBjoern A. Zeeb .resume = mt7921u_resume,
3406c92544dSBjoern A. Zeeb .reset_resume = mt7921u_resume,
3416c92544dSBjoern A. Zeeb #endif /* CONFIG_PM */
3426c92544dSBjoern A. Zeeb .soft_unbind = 1,
3436c92544dSBjoern A. Zeeb .disable_hub_initiated_lpm = 1,
3446c92544dSBjoern A. Zeeb };
3456c92544dSBjoern A. Zeeb module_usb_driver(mt7921u_driver);
3466c92544dSBjoern A. Zeeb
3476c92544dSBjoern A. Zeeb MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
3486c92544dSBjoern A. Zeeb MODULE_LICENSE("Dual BSD/GPL");
349