1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2022 MediaTek Inc.
4 * Author: Lorenzo Bianconi <lorenzo@kernel.org>
7 #include <linux/kernel.h>
8 #include <linux/module.h>
13 #include "../mt76_connac2_mac.h"
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 /* Comfast CF-952AX */
19 { USB_DEVICE_AND_INTERFACE_INFO(0x3574, 0x6211, 0xff, 0xff, 0xff),
20 .driver_info
= (kernel_ulong_t
)MT7921_FIRMWARE_WM
},
21 /* Netgear, Inc. [A8000,AXE3000] */
22 { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9060, 0xff, 0xff, 0xff),
23 .driver_info
= (kernel_ulong_t
)MT7921_FIRMWARE_WM
},
28 mt7921u_mcu_send_message(struct mt76_dev
*mdev
, struct sk_buff
*skb
,
31 struct mt792x_dev
*dev
= container_of(mdev
, struct mt792x_dev
, mt76
);
35 ret
= mt76_connac2_mcu_fill_message(mdev
, skb
, cmd
, seq
);
39 mdev
->mcu
.timeout
= 3 * HZ
;
41 if (cmd
!= MCU_CMD(FW_SCATTER
))
42 ep
= MT_EP_OUT_INBAND_CMD
;
46 mt792x_skb_add_usb_sdio_hdr(dev
, skb
, 0);
47 pad
= round_up(skb
->len
, 4) + 4 - skb
->len
;
48 __skb_put_zero(skb
, pad
);
50 ret
= mt76u_bulk_msg(&dev
->mt76
, skb
->data
, skb
->len
, NULL
,
57 static int mt7921u_mcu_init(struct mt792x_dev
*dev
)
59 static const struct mt76_mcu_ops mcu_ops
= {
60 .headroom
= MT_SDIO_HDR_SIZE
+
61 sizeof(struct mt76_connac2_mcu_txd
),
62 .tailroom
= MT_USB_TAIL_SIZE
,
63 .mcu_skb_send_msg
= mt7921u_mcu_send_message
,
64 .mcu_parse_response
= mt7921_mcu_parse_response
,
68 dev
->mt76
.mcu_ops
= &mcu_ops
;
70 mt76_set(dev
, MT_UDMA_TX_QSEL
, MT_FW_DL_EN
);
71 ret
= mt7921_run_firmware(dev
);
75 set_bit(MT76_STATE_MCU_RUNNING
, &dev
->mphy
.state
);
76 mt76_clear(dev
, MT_UDMA_TX_QSEL
, MT_FW_DL_EN
);
81 static int mt7921u_mac_reset(struct mt792x_dev
*dev
)
85 mt76_txq_schedule_all(&dev
->mphy
);
86 mt76_worker_disable(&dev
->mt76
.tx_worker
);
88 set_bit(MT76_RESET
, &dev
->mphy
.state
);
89 set_bit(MT76_MCU_RESET
, &dev
->mphy
.state
);
91 wake_up(&dev
->mt76
.mcu
.wait
);
92 skb_queue_purge(&dev
->mt76
.mcu
.res_q
);
94 mt76u_stop_rx(&dev
->mt76
);
95 mt76u_stop_tx(&dev
->mt76
);
97 mt792xu_wfsys_reset(dev
);
99 clear_bit(MT76_MCU_RESET
, &dev
->mphy
.state
);
100 err
= mt76u_resume_rx(&dev
->mt76
);
104 err
= mt792xu_mcu_power_on(dev
);
108 err
= mt792xu_dma_init(dev
, false);
112 mt76_wr(dev
, MT_SWDEF_MODE
, MT_SWDEF_NORMAL_MODE
);
113 mt76_set(dev
, MT_UDMA_TX_QSEL
, MT_FW_DL_EN
);
115 err
= mt7921_run_firmware(dev
);
119 mt76_clear(dev
, MT_UDMA_TX_QSEL
, MT_FW_DL_EN
);
121 err
= mt7921_mcu_set_eeprom(dev
);
125 err
= mt7921_mac_init(dev
);
129 err
= __mt7921_start(&dev
->phy
);
131 clear_bit(MT76_RESET
, &dev
->mphy
.state
);
133 mt76_worker_enable(&dev
->mt76
.tx_worker
);
138 static int mt7921u_probe(struct usb_interface
*usb_intf
,
139 const struct usb_device_id
*id
)
141 static const struct mt76_driver_ops drv_ops
= {
142 .txwi_size
= MT_SDIO_TXD_SIZE
,
143 .drv_flags
= MT_DRV_RX_DMA_HDR
| MT_DRV_HW_MGMT_TXQ
|
144 MT_DRV_AMSDU_OFFLOAD
,
145 .survey_flags
= SURVEY_INFO_TIME_TX
|
146 SURVEY_INFO_TIME_RX
|
147 SURVEY_INFO_TIME_BSS_RX
,
148 .tx_prepare_skb
= mt7921_usb_sdio_tx_prepare_skb
,
149 .tx_complete_skb
= mt7921_usb_sdio_tx_complete_skb
,
150 .tx_status_data
= mt7921_usb_sdio_tx_status_data
,
151 .rx_skb
= mt7921_queue_rx_skb
,
152 .rx_check
= mt7921_rx_check
,
153 .sta_add
= mt7921_mac_sta_add
,
154 .sta_event
= mt7921_mac_sta_event
,
155 .sta_remove
= mt7921_mac_sta_remove
,
156 .update_survey
= mt792x_update_channel
,
157 .set_channel
= mt7921_set_channel
,
159 static const struct mt792x_hif_ops hif_ops
= {
160 .mcu_init
= mt7921u_mcu_init
,
161 .init_reset
= mt792xu_init_reset
,
162 .reset
= mt7921u_mac_reset
,
164 static struct mt76_bus_ops bus_ops
= {
168 .read_copy
= mt76u_read_copy
,
169 .write_copy
= mt792xu_copy
,
170 .type
= MT76_BUS_USB
,
172 struct usb_device
*udev
= interface_to_usbdev(usb_intf
);
173 struct ieee80211_ops
*ops
;
174 struct ieee80211_hw
*hw
;
175 struct mt792x_dev
*dev
;
176 struct mt76_dev
*mdev
;
180 ops
= mt792x_get_mac80211_ops(&usb_intf
->dev
, &mt7921_ops
,
181 (void *)id
->driver_info
, &features
);
185 ops
->stop
= mt792xu_stop
;
186 mdev
= mt76_alloc_device(&usb_intf
->dev
, sizeof(*dev
), ops
, &drv_ops
);
190 dev
= container_of(mdev
, struct mt792x_dev
, mt76
);
191 dev
->fw_features
= features
;
192 dev
->hif_ops
= &hif_ops
;
194 udev
= usb_get_dev(udev
);
195 usb_reset_device(udev
);
197 usb_set_intfdata(usb_intf
, dev
);
199 ret
= __mt76u_init(mdev
, usb_intf
, &bus_ops
);
203 mdev
->rev
= (mt76_rr(dev
, MT_HW_CHIPID
) << 16) |
204 (mt76_rr(dev
, MT_HW_REV
) & 0xff);
205 dev_dbg(mdev
->dev
, "ASIC revision: %04x\n", mdev
->rev
);
207 if (mt76_get_field(dev
, MT_CONN_ON_MISC
, MT_TOP_MISC2_FW_N9_RDY
)) {
208 ret
= mt792xu_wfsys_reset(dev
);
213 ret
= mt792xu_mcu_power_on(dev
);
217 ret
= mt76u_alloc_mcu_queue(&dev
->mt76
);
221 ret
= mt76u_alloc_queues(&dev
->mt76
);
225 ret
= mt792xu_dma_init(dev
, false);
230 /* check hw sg support in order to enable AMSDU */
231 hw
->max_tx_fragments
= mdev
->usb
.sg_en
? MT_HW_TXP_MAX_BUF_NUM
: 1;
233 ret
= mt7921_register_device(dev
);
240 mt76u_queues_deinit(&dev
->mt76
);
242 usb_set_intfdata(usb_intf
, NULL
);
243 usb_put_dev(interface_to_usbdev(usb_intf
));
245 mt76_free_device(&dev
->mt76
);
251 static int mt7921u_suspend(struct usb_interface
*intf
, pm_message_t state
)
253 struct mt792x_dev
*dev
= usb_get_intfdata(intf
);
254 struct mt76_connac_pm
*pm
= &dev
->pm
;
257 pm
->suspended
= true;
258 flush_work(&dev
->reset_work
);
260 err
= mt76_connac_mcu_set_hif_suspend(&dev
->mt76
, true);
264 mt76u_stop_rx(&dev
->mt76
);
265 mt76u_stop_tx(&dev
->mt76
);
270 pm
->suspended
= false;
273 mt792x_reset(&dev
->mt76
);
278 static int mt7921u_resume(struct usb_interface
*intf
)
280 struct mt792x_dev
*dev
= usb_get_intfdata(intf
);
281 struct mt76_connac_pm
*pm
= &dev
->pm
;
285 for (i
= 0; i
< 10; i
++) {
286 u32 val
= mt76_rr(dev
, MT_WF_SW_DEF_CR_USB_MCU_EVENT
);
288 if (!(val
& MT_WF_SW_SER_TRIGGER_SUSPEND
)) {
292 if (val
& MT_WF_SW_SER_DONE_SUSPEND
) {
293 mt76_wr(dev
, MT_WF_SW_DEF_CR_USB_MCU_EVENT
, 0);
300 if (reinit
|| mt792x_dma_need_reinit(dev
)) {
301 err
= mt792xu_dma_init(dev
, true);
306 err
= mt76u_resume_rx(&dev
->mt76
);
310 err
= mt76_connac_mcu_set_hif_suspend(&dev
->mt76
, false);
312 pm
->suspended
= false;
315 mt792x_reset(&dev
->mt76
);
319 #endif /* CONFIG_PM */
321 MODULE_DEVICE_TABLE(usb
, mt7921u_device_table
);
322 MODULE_FIRMWARE(MT7921_FIRMWARE_WM
);
323 MODULE_FIRMWARE(MT7921_ROM_PATCH
);
325 static struct usb_driver mt7921u_driver
= {
326 .name
= KBUILD_MODNAME
,
327 .id_table
= mt7921u_device_table
,
328 .probe
= mt7921u_probe
,
329 .disconnect
= mt792xu_disconnect
,
331 .suspend
= mt7921u_suspend
,
332 .resume
= mt7921u_resume
,
333 .reset_resume
= mt7921u_resume
,
334 #endif /* CONFIG_PM */
336 .disable_hub_initiated_lpm
= 1,
338 module_usb_driver(mt7921u_driver
);
340 MODULE_DESCRIPTION("MediaTek MT7921U (USB) wireless driver");
341 MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
342 MODULE_LICENSE("Dual BSD/GPL");