10d2afe09SLorenzo Bianconi // SPDX-License-Identifier: ISC
20d2afe09SLorenzo Bianconi /* Copyright (C) 2022 MediaTek Inc.
30d2afe09SLorenzo Bianconi *
40d2afe09SLorenzo Bianconi * Author: Lorenzo Bianconi <lorenzo@kernel.org>
50d2afe09SLorenzo Bianconi */
60d2afe09SLorenzo Bianconi
70d2afe09SLorenzo Bianconi #include <linux/kernel.h>
80d2afe09SLorenzo Bianconi #include <linux/module.h>
90d2afe09SLorenzo Bianconi #include <linux/usb.h>
100d2afe09SLorenzo Bianconi
110d2afe09SLorenzo Bianconi #include "mt7921.h"
120d2afe09SLorenzo Bianconi #include "mcu.h"
13140efef3SLorenzo Bianconi #include "../mt76_connac2_mac.h"
140d2afe09SLorenzo Bianconi
150d2afe09SLorenzo Bianconi static const struct usb_device_id mt7921u_device_table[] = {
16034ae28bSSean Wang { USB_DEVICE_AND_INTERFACE_INFO(0x0e8d, 0x7961, 0xff, 0xff, 0xff),
17034ae28bSSean Wang .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM },
18e766b7fdSChuanhong Guo /* Comfast CF-952AX */
19e766b7fdSChuanhong Guo { USB_DEVICE_AND_INTERFACE_INFO(0x3574, 0x6211, 0xff, 0xff, 0xff),
20e766b7fdSChuanhong Guo .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM },
2103eb52ddSReese Russell /* Netgear, Inc. [A8000,AXE3000] */
2203eb52ddSReese Russell { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9060, 0xff, 0xff, 0xff),
2303eb52ddSReese Russell .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM },
24*7b279f96SNick Morrow /* TP-Link TXE50UH */
25*7b279f96SNick Morrow { USB_DEVICE_AND_INTERFACE_INFO(0x35bc, 0x0107, 0xff, 0xff, 0xff),
26*7b279f96SNick Morrow .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM },
270d2afe09SLorenzo Bianconi { },
280d2afe09SLorenzo Bianconi };
290d2afe09SLorenzo Bianconi
300d2afe09SLorenzo Bianconi static int
mt7921u_mcu_send_message(struct mt76_dev * mdev,struct sk_buff * skb,int cmd,int * seq)310d2afe09SLorenzo Bianconi mt7921u_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
320d2afe09SLorenzo Bianconi int cmd, int *seq)
330d2afe09SLorenzo Bianconi {
34975e122dSLorenzo Bianconi struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);
350d2afe09SLorenzo Bianconi u32 pad, ep;
360d2afe09SLorenzo Bianconi int ret;
370d2afe09SLorenzo Bianconi
38d2f5c8edSLorenzo Bianconi ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, seq);
390d2afe09SLorenzo Bianconi if (ret)
400d2afe09SLorenzo Bianconi return ret;
410d2afe09SLorenzo Bianconi
42d2f5c8edSLorenzo Bianconi mdev->mcu.timeout = 3 * HZ;
43d2f5c8edSLorenzo Bianconi
440d2afe09SLorenzo Bianconi if (cmd != MCU_CMD(FW_SCATTER))
450d2afe09SLorenzo Bianconi ep = MT_EP_OUT_INBAND_CMD;
460d2afe09SLorenzo Bianconi else
470d2afe09SLorenzo Bianconi ep = MT_EP_OUT_AC_BE;
480d2afe09SLorenzo Bianconi
490d2afe09SLorenzo Bianconi mt7921_skb_add_usb_sdio_hdr(dev, skb, 0);
500d2afe09SLorenzo Bianconi pad = round_up(skb->len, 4) + 4 - skb->len;
510d2afe09SLorenzo Bianconi __skb_put_zero(skb, pad);
520d2afe09SLorenzo Bianconi
530d2afe09SLorenzo Bianconi ret = mt76u_bulk_msg(&dev->mt76, skb->data, skb->len, NULL,
540d2afe09SLorenzo Bianconi 1000, ep);
550d2afe09SLorenzo Bianconi dev_kfree_skb(skb);
560d2afe09SLorenzo Bianconi
570d2afe09SLorenzo Bianconi return ret;
580d2afe09SLorenzo Bianconi }
590d2afe09SLorenzo Bianconi
mt7921u_mcu_init(struct mt792x_dev * dev)60975e122dSLorenzo Bianconi static int mt7921u_mcu_init(struct mt792x_dev *dev)
610d2afe09SLorenzo Bianconi {
620d2afe09SLorenzo Bianconi static const struct mt76_mcu_ops mcu_ops = {
63fc6ee71aSLorenzo Bianconi .headroom = MT_SDIO_HDR_SIZE +
64fc6ee71aSLorenzo Bianconi sizeof(struct mt76_connac2_mcu_txd),
650d2afe09SLorenzo Bianconi .tailroom = MT_USB_TAIL_SIZE,
660d2afe09SLorenzo Bianconi .mcu_skb_send_msg = mt7921u_mcu_send_message,
670d2afe09SLorenzo Bianconi .mcu_parse_response = mt7921_mcu_parse_response,
680d2afe09SLorenzo Bianconi };
690d2afe09SLorenzo Bianconi int ret;
700d2afe09SLorenzo Bianconi
710d2afe09SLorenzo Bianconi dev->mt76.mcu_ops = &mcu_ops;
720d2afe09SLorenzo Bianconi
730d2afe09SLorenzo Bianconi mt76_set(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
740d2afe09SLorenzo Bianconi ret = mt7921_run_firmware(dev);
750d2afe09SLorenzo Bianconi if (ret)
760d2afe09SLorenzo Bianconi return ret;
770d2afe09SLorenzo Bianconi
780d2afe09SLorenzo Bianconi set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
790d2afe09SLorenzo Bianconi mt76_clear(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
800d2afe09SLorenzo Bianconi
810d2afe09SLorenzo Bianconi return 0;
820d2afe09SLorenzo Bianconi }
830d2afe09SLorenzo Bianconi
mt7921u_mac_reset(struct mt792x_dev * dev)84d28e1a48SLorenzo Bianconi static int mt7921u_mac_reset(struct mt792x_dev *dev)
85d28e1a48SLorenzo Bianconi {
86d28e1a48SLorenzo Bianconi int err;
87d28e1a48SLorenzo Bianconi
88d28e1a48SLorenzo Bianconi mt76_txq_schedule_all(&dev->mphy);
89d28e1a48SLorenzo Bianconi mt76_worker_disable(&dev->mt76.tx_worker);
90d28e1a48SLorenzo Bianconi
91d28e1a48SLorenzo Bianconi set_bit(MT76_RESET, &dev->mphy.state);
92d28e1a48SLorenzo Bianconi set_bit(MT76_MCU_RESET, &dev->mphy.state);
93d28e1a48SLorenzo Bianconi
94d28e1a48SLorenzo Bianconi wake_up(&dev->mt76.mcu.wait);
95d28e1a48SLorenzo Bianconi skb_queue_purge(&dev->mt76.mcu.res_q);
96d28e1a48SLorenzo Bianconi
97d28e1a48SLorenzo Bianconi mt76u_stop_rx(&dev->mt76);
98d28e1a48SLorenzo Bianconi mt76u_stop_tx(&dev->mt76);
99d28e1a48SLorenzo Bianconi
100d28e1a48SLorenzo Bianconi mt792xu_wfsys_reset(dev);
101d28e1a48SLorenzo Bianconi
102d28e1a48SLorenzo Bianconi clear_bit(MT76_MCU_RESET, &dev->mphy.state);
103d28e1a48SLorenzo Bianconi err = mt76u_resume_rx(&dev->mt76);
104d28e1a48SLorenzo Bianconi if (err)
105d28e1a48SLorenzo Bianconi goto out;
106d28e1a48SLorenzo Bianconi
107d28e1a48SLorenzo Bianconi err = mt792xu_mcu_power_on(dev);
108d28e1a48SLorenzo Bianconi if (err)
109d28e1a48SLorenzo Bianconi goto out;
110d28e1a48SLorenzo Bianconi
111d28e1a48SLorenzo Bianconi err = mt792xu_dma_init(dev, false);
112d28e1a48SLorenzo Bianconi if (err)
113d28e1a48SLorenzo Bianconi goto out;
114d28e1a48SLorenzo Bianconi
115d28e1a48SLorenzo Bianconi mt76_wr(dev, MT_SWDEF_MODE, MT_SWDEF_NORMAL_MODE);
116d28e1a48SLorenzo Bianconi mt76_set(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
117d28e1a48SLorenzo Bianconi
118d28e1a48SLorenzo Bianconi err = mt7921_run_firmware(dev);
119d28e1a48SLorenzo Bianconi if (err)
120d28e1a48SLorenzo Bianconi goto out;
121d28e1a48SLorenzo Bianconi
122d28e1a48SLorenzo Bianconi mt76_clear(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
123d28e1a48SLorenzo Bianconi
124d28e1a48SLorenzo Bianconi err = mt7921_mcu_set_eeprom(dev);
125d28e1a48SLorenzo Bianconi if (err)
126d28e1a48SLorenzo Bianconi goto out;
127d28e1a48SLorenzo Bianconi
128d28e1a48SLorenzo Bianconi err = mt7921_mac_init(dev);
129d28e1a48SLorenzo Bianconi if (err)
130d28e1a48SLorenzo Bianconi goto out;
131d28e1a48SLorenzo Bianconi
132d28e1a48SLorenzo Bianconi err = __mt7921_start(&dev->phy);
133d28e1a48SLorenzo Bianconi out:
134d28e1a48SLorenzo Bianconi clear_bit(MT76_RESET, &dev->mphy.state);
135d28e1a48SLorenzo Bianconi
136d28e1a48SLorenzo Bianconi mt76_worker_enable(&dev->mt76.tx_worker);
137d28e1a48SLorenzo Bianconi
138d28e1a48SLorenzo Bianconi return err;
139d28e1a48SLorenzo Bianconi }
140d28e1a48SLorenzo Bianconi
mt7921u_stop(struct ieee80211_hw * hw)1410d2afe09SLorenzo Bianconi static void mt7921u_stop(struct ieee80211_hw *hw)
1420d2afe09SLorenzo Bianconi {
14320249e1aSLorenzo Bianconi struct mt792x_dev *dev = mt792x_hw_dev(hw);
1440d2afe09SLorenzo Bianconi
1450d2afe09SLorenzo Bianconi mt76u_stop_tx(&dev->mt76);
1460d2afe09SLorenzo Bianconi mt7921_stop(hw);
1470d2afe09SLorenzo Bianconi }
1480d2afe09SLorenzo Bianconi
mt7921u_probe(struct usb_interface * usb_intf,const struct usb_device_id * id)1490d2afe09SLorenzo Bianconi static int mt7921u_probe(struct usb_interface *usb_intf,
1500d2afe09SLorenzo Bianconi const struct usb_device_id *id)
1510d2afe09SLorenzo Bianconi {
1520d2afe09SLorenzo Bianconi static const struct mt76_driver_ops drv_ops = {
1530d2afe09SLorenzo Bianconi .txwi_size = MT_SDIO_TXD_SIZE,
1545b0fb852SBen Greear .drv_flags = MT_DRV_RX_DMA_HDR | MT_DRV_HW_MGMT_TXQ |
1555b0fb852SBen Greear MT_DRV_AMSDU_OFFLOAD,
1560d2afe09SLorenzo Bianconi .survey_flags = SURVEY_INFO_TIME_TX |
1570d2afe09SLorenzo Bianconi SURVEY_INFO_TIME_RX |
1580d2afe09SLorenzo Bianconi SURVEY_INFO_TIME_BSS_RX,
1590d2afe09SLorenzo Bianconi .tx_prepare_skb = mt7921_usb_sdio_tx_prepare_skb,
1600d2afe09SLorenzo Bianconi .tx_complete_skb = mt7921_usb_sdio_tx_complete_skb,
1610d2afe09SLorenzo Bianconi .tx_status_data = mt7921_usb_sdio_tx_status_data,
1620d2afe09SLorenzo Bianconi .rx_skb = mt7921_queue_rx_skb,
16312d7440eSLorenzo Bianconi .rx_check = mt7921_rx_check,
1640d2afe09SLorenzo Bianconi .sta_add = mt7921_mac_sta_add,
1650d2afe09SLorenzo Bianconi .sta_assoc = mt7921_mac_sta_assoc,
1660d2afe09SLorenzo Bianconi .sta_remove = mt7921_mac_sta_remove,
167311f121cSLorenzo Bianconi .update_survey = mt792x_update_channel,
1680d2afe09SLorenzo Bianconi };
169838cc667SLorenzo Bianconi static const struct mt792x_hif_ops hif_ops = {
1700d2afe09SLorenzo Bianconi .mcu_init = mt7921u_mcu_init,
171d28e1a48SLorenzo Bianconi .init_reset = mt792xu_init_reset,
1720d2afe09SLorenzo Bianconi .reset = mt7921u_mac_reset,
1730d2afe09SLorenzo Bianconi };
1740d2afe09SLorenzo Bianconi static struct mt76_bus_ops bus_ops = {
175d28e1a48SLorenzo Bianconi .rr = mt792xu_rr,
176d28e1a48SLorenzo Bianconi .wr = mt792xu_wr,
177d28e1a48SLorenzo Bianconi .rmw = mt792xu_rmw,
1780d2afe09SLorenzo Bianconi .read_copy = mt76u_read_copy,
179d28e1a48SLorenzo Bianconi .write_copy = mt792xu_copy,
1800d2afe09SLorenzo Bianconi .type = MT76_BUS_USB,
1810d2afe09SLorenzo Bianconi };
1820d2afe09SLorenzo Bianconi struct usb_device *udev = interface_to_usbdev(usb_intf);
1830d2afe09SLorenzo Bianconi struct ieee80211_ops *ops;
1840d2afe09SLorenzo Bianconi struct ieee80211_hw *hw;
185975e122dSLorenzo Bianconi struct mt792x_dev *dev;
1860d2afe09SLorenzo Bianconi struct mt76_dev *mdev;
187034ae28bSSean Wang u8 features;
1880d2afe09SLorenzo Bianconi int ret;
1890d2afe09SLorenzo Bianconi
190e8a264ccSLorenzo Bianconi ops = mt792x_get_mac80211_ops(&usb_intf->dev, &mt7921_ops,
191e8a264ccSLorenzo Bianconi (void *)id->driver_info, &features);
1920d2afe09SLorenzo Bianconi if (!ops)
1930d2afe09SLorenzo Bianconi return -ENOMEM;
1940d2afe09SLorenzo Bianconi
1950d2afe09SLorenzo Bianconi ops->stop = mt7921u_stop;
1960d2afe09SLorenzo Bianconi mdev = mt76_alloc_device(&usb_intf->dev, sizeof(*dev), ops, &drv_ops);
1970d2afe09SLorenzo Bianconi if (!mdev)
1980d2afe09SLorenzo Bianconi return -ENOMEM;
1990d2afe09SLorenzo Bianconi
200975e122dSLorenzo Bianconi dev = container_of(mdev, struct mt792x_dev, mt76);
201034ae28bSSean Wang dev->fw_features = features;
2020d2afe09SLorenzo Bianconi dev->hif_ops = &hif_ops;
2030d2afe09SLorenzo Bianconi
2040d2afe09SLorenzo Bianconi udev = usb_get_dev(udev);
2050d2afe09SLorenzo Bianconi usb_reset_device(udev);
2060d2afe09SLorenzo Bianconi
2070d2afe09SLorenzo Bianconi usb_set_intfdata(usb_intf, dev);
2080d2afe09SLorenzo Bianconi
2090d2afe09SLorenzo Bianconi ret = __mt76u_init(mdev, usb_intf, &bus_ops);
2100d2afe09SLorenzo Bianconi if (ret < 0)
2110d2afe09SLorenzo Bianconi goto error;
2120d2afe09SLorenzo Bianconi
2130d2afe09SLorenzo Bianconi mdev->rev = (mt76_rr(dev, MT_HW_CHIPID) << 16) |
2140d2afe09SLorenzo Bianconi (mt76_rr(dev, MT_HW_REV) & 0xff);
2150d2afe09SLorenzo Bianconi dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
2160d2afe09SLorenzo Bianconi
2170d2afe09SLorenzo Bianconi if (mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY)) {
218d28e1a48SLorenzo Bianconi ret = mt792xu_wfsys_reset(dev);
2190d2afe09SLorenzo Bianconi if (ret)
2200d2afe09SLorenzo Bianconi goto error;
2210d2afe09SLorenzo Bianconi }
2220d2afe09SLorenzo Bianconi
223d28e1a48SLorenzo Bianconi ret = mt792xu_mcu_power_on(dev);
2240d2afe09SLorenzo Bianconi if (ret)
2250d2afe09SLorenzo Bianconi goto error;
2260d2afe09SLorenzo Bianconi
2270d2afe09SLorenzo Bianconi ret = mt76u_alloc_mcu_queue(&dev->mt76);
2280d2afe09SLorenzo Bianconi if (ret)
2290d2afe09SLorenzo Bianconi goto error;
2300d2afe09SLorenzo Bianconi
2310d2afe09SLorenzo Bianconi ret = mt76u_alloc_queues(&dev->mt76);
2320d2afe09SLorenzo Bianconi if (ret)
2330d2afe09SLorenzo Bianconi goto error;
2340d2afe09SLorenzo Bianconi
235d28e1a48SLorenzo Bianconi ret = mt792xu_dma_init(dev, false);
2360d2afe09SLorenzo Bianconi if (ret)
2375c47cdebSJiefeng Li goto error;
2380d2afe09SLorenzo Bianconi
2390d2afe09SLorenzo Bianconi hw = mt76_hw(dev);
2400d2afe09SLorenzo Bianconi /* check hw sg support in order to enable AMSDU */
2410d2afe09SLorenzo Bianconi hw->max_tx_fragments = mdev->usb.sg_en ? MT_HW_TXP_MAX_BUF_NUM : 1;
2420d2afe09SLorenzo Bianconi
2430d2afe09SLorenzo Bianconi ret = mt7921_register_device(dev);
2440d2afe09SLorenzo Bianconi if (ret)
2450d2afe09SLorenzo Bianconi goto error;
2460d2afe09SLorenzo Bianconi
2470d2afe09SLorenzo Bianconi return 0;
2480d2afe09SLorenzo Bianconi
2490d2afe09SLorenzo Bianconi error:
2500d2afe09SLorenzo Bianconi mt76u_queues_deinit(&dev->mt76);
2510d2afe09SLorenzo Bianconi
2520d2afe09SLorenzo Bianconi usb_set_intfdata(usb_intf, NULL);
2530d2afe09SLorenzo Bianconi usb_put_dev(interface_to_usbdev(usb_intf));
2540d2afe09SLorenzo Bianconi
2550d2afe09SLorenzo Bianconi mt76_free_device(&dev->mt76);
2560d2afe09SLorenzo Bianconi
2570d2afe09SLorenzo Bianconi return ret;
2580d2afe09SLorenzo Bianconi }
2590d2afe09SLorenzo Bianconi
260df3e4143SLorenzo Bianconi #ifdef CONFIG_PM
mt7921u_suspend(struct usb_interface * intf,pm_message_t state)261df3e4143SLorenzo Bianconi static int mt7921u_suspend(struct usb_interface *intf, pm_message_t state)
262df3e4143SLorenzo Bianconi {
263975e122dSLorenzo Bianconi struct mt792x_dev *dev = usb_get_intfdata(intf);
26486f15d04SSean Wang struct mt76_connac_pm *pm = &dev->pm;
265df3e4143SLorenzo Bianconi int err;
266df3e4143SLorenzo Bianconi
26786f15d04SSean Wang pm->suspended = true;
26886f15d04SSean Wang flush_work(&dev->reset_work);
26986f15d04SSean Wang
270df3e4143SLorenzo Bianconi err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true);
271df3e4143SLorenzo Bianconi if (err)
27286f15d04SSean Wang goto failed;
273df3e4143SLorenzo Bianconi
274df3e4143SLorenzo Bianconi mt76u_stop_rx(&dev->mt76);
275df3e4143SLorenzo Bianconi mt76u_stop_tx(&dev->mt76);
276df3e4143SLorenzo Bianconi
277df3e4143SLorenzo Bianconi return 0;
27886f15d04SSean Wang
27986f15d04SSean Wang failed:
28086f15d04SSean Wang pm->suspended = false;
28186f15d04SSean Wang
28286f15d04SSean Wang if (err < 0)
283311f121cSLorenzo Bianconi mt792x_reset(&dev->mt76);
28486f15d04SSean Wang
28586f15d04SSean Wang return err;
286df3e4143SLorenzo Bianconi }
287df3e4143SLorenzo Bianconi
mt7921u_resume(struct usb_interface * intf)288df3e4143SLorenzo Bianconi static int mt7921u_resume(struct usb_interface *intf)
289df3e4143SLorenzo Bianconi {
290975e122dSLorenzo Bianconi struct mt792x_dev *dev = usb_get_intfdata(intf);
29186f15d04SSean Wang struct mt76_connac_pm *pm = &dev->pm;
292df3e4143SLorenzo Bianconi bool reinit = true;
293df3e4143SLorenzo Bianconi int err, i;
294df3e4143SLorenzo Bianconi
295df3e4143SLorenzo Bianconi for (i = 0; i < 10; i++) {
296df3e4143SLorenzo Bianconi u32 val = mt76_rr(dev, MT_WF_SW_DEF_CR_USB_MCU_EVENT);
297df3e4143SLorenzo Bianconi
298df3e4143SLorenzo Bianconi if (!(val & MT_WF_SW_SER_TRIGGER_SUSPEND)) {
299df3e4143SLorenzo Bianconi reinit = false;
300df3e4143SLorenzo Bianconi break;
301df3e4143SLorenzo Bianconi }
302df3e4143SLorenzo Bianconi if (val & MT_WF_SW_SER_DONE_SUSPEND) {
303df3e4143SLorenzo Bianconi mt76_wr(dev, MT_WF_SW_DEF_CR_USB_MCU_EVENT, 0);
304df3e4143SLorenzo Bianconi break;
305df3e4143SLorenzo Bianconi }
306df3e4143SLorenzo Bianconi
307df3e4143SLorenzo Bianconi msleep(20);
308df3e4143SLorenzo Bianconi }
309df3e4143SLorenzo Bianconi
310c693f2f0SLorenzo Bianconi if (reinit || mt792x_dma_need_reinit(dev)) {
311d28e1a48SLorenzo Bianconi err = mt792xu_dma_init(dev, true);
312df3e4143SLorenzo Bianconi if (err)
31386f15d04SSean Wang goto failed;
314df3e4143SLorenzo Bianconi }
315df3e4143SLorenzo Bianconi
316df3e4143SLorenzo Bianconi err = mt76u_resume_rx(&dev->mt76);
317df3e4143SLorenzo Bianconi if (err < 0)
31886f15d04SSean Wang goto failed;
319df3e4143SLorenzo Bianconi
32086f15d04SSean Wang err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false);
32186f15d04SSean Wang failed:
32286f15d04SSean Wang pm->suspended = false;
32386f15d04SSean Wang
32486f15d04SSean Wang if (err < 0)
325311f121cSLorenzo Bianconi mt792x_reset(&dev->mt76);
32686f15d04SSean Wang
32786f15d04SSean Wang return err;
328df3e4143SLorenzo Bianconi }
329df3e4143SLorenzo Bianconi #endif /* CONFIG_PM */
330df3e4143SLorenzo Bianconi
3310d2afe09SLorenzo Bianconi MODULE_DEVICE_TABLE(usb, mt7921u_device_table);
3320d2afe09SLorenzo Bianconi MODULE_FIRMWARE(MT7921_FIRMWARE_WM);
3330d2afe09SLorenzo Bianconi MODULE_FIRMWARE(MT7921_ROM_PATCH);
3340d2afe09SLorenzo Bianconi
3350d2afe09SLorenzo Bianconi static struct usb_driver mt7921u_driver = {
3360d2afe09SLorenzo Bianconi .name = KBUILD_MODNAME,
3370d2afe09SLorenzo Bianconi .id_table = mt7921u_device_table,
3380d2afe09SLorenzo Bianconi .probe = mt7921u_probe,
339fc80731bSLorenzo Bianconi .disconnect = mt792xu_disconnect,
340df3e4143SLorenzo Bianconi #ifdef CONFIG_PM
341df3e4143SLorenzo Bianconi .suspend = mt7921u_suspend,
342df3e4143SLorenzo Bianconi .resume = mt7921u_resume,
343df3e4143SLorenzo Bianconi .reset_resume = mt7921u_resume,
344df3e4143SLorenzo Bianconi #endif /* CONFIG_PM */
3450d2afe09SLorenzo Bianconi .soft_unbind = 1,
3460d2afe09SLorenzo Bianconi .disable_hub_initiated_lpm = 1,
3470d2afe09SLorenzo Bianconi };
3480d2afe09SLorenzo Bianconi module_usb_driver(mt7921u_driver);
3490d2afe09SLorenzo Bianconi
3500d2afe09SLorenzo Bianconi MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
3510d2afe09SLorenzo Bianconi MODULE_LICENSE("Dual BSD/GPL");
352