1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2023 MediaTek Inc. */
4 #include <linux/kernel.h>
5 #include <linux/module.h>
12 static const struct usb_device_id mt7925u_device_table
[] = {
13 { USB_DEVICE_AND_INTERFACE_INFO(0x0e8d, 0x7925, 0xff, 0xff, 0xff),
14 .driver_info
= (kernel_ulong_t
)MT7925_FIRMWARE_WM
},
19 mt7925u_mcu_send_message(struct mt76_dev
*mdev
, struct sk_buff
*skb
,
22 struct mt792x_dev
*dev
= container_of(mdev
, struct mt792x_dev
, mt76
);
26 ret
= mt7925_mcu_fill_message(mdev
, skb
, cmd
, seq
);
30 mdev
->mcu
.timeout
= 3 * HZ
;
32 if (cmd
!= MCU_CMD(FW_SCATTER
))
33 ep
= MT_EP_OUT_INBAND_CMD
;
37 mt792x_skb_add_usb_sdio_hdr(dev
, skb
, 0);
38 pad
= round_up(skb
->len
, 4) + 4 - skb
->len
;
39 __skb_put_zero(skb
, pad
);
41 ret
= mt76u_bulk_msg(&dev
->mt76
, skb
->data
, skb
->len
, NULL
,
48 static int mt7925u_mcu_init(struct mt792x_dev
*dev
)
50 static const struct mt76_mcu_ops mcu_ops
= {
51 .headroom
= MT_SDIO_HDR_SIZE
+
52 sizeof(struct mt76_connac2_mcu_txd
),
53 .tailroom
= MT_USB_TAIL_SIZE
,
54 .mcu_skb_send_msg
= mt7925u_mcu_send_message
,
55 .mcu_parse_response
= mt7925_mcu_parse_response
,
59 dev
->mt76
.mcu_ops
= &mcu_ops
;
61 mt76_set(dev
, MT_UDMA_TX_QSEL
, MT_FW_DL_EN
);
62 ret
= mt7925_run_firmware(dev
);
66 set_bit(MT76_STATE_MCU_RUNNING
, &dev
->mphy
.state
);
67 mt76_clear(dev
, MT_UDMA_TX_QSEL
, MT_FW_DL_EN
);
72 static int mt7925u_mac_reset(struct mt792x_dev
*dev
)
76 mt76_txq_schedule_all(&dev
->mphy
);
77 mt76_worker_disable(&dev
->mt76
.tx_worker
);
79 set_bit(MT76_RESET
, &dev
->mphy
.state
);
80 set_bit(MT76_MCU_RESET
, &dev
->mphy
.state
);
82 wake_up(&dev
->mt76
.mcu
.wait
);
83 skb_queue_purge(&dev
->mt76
.mcu
.res_q
);
85 mt76u_stop_rx(&dev
->mt76
);
86 mt76u_stop_tx(&dev
->mt76
);
88 mt792xu_wfsys_reset(dev
);
90 clear_bit(MT76_MCU_RESET
, &dev
->mphy
.state
);
91 err
= mt76u_resume_rx(&dev
->mt76
);
95 err
= mt792xu_mcu_power_on(dev
);
99 err
= mt792xu_dma_init(dev
, false);
103 mt76_wr(dev
, MT_SWDEF_MODE
, MT_SWDEF_NORMAL_MODE
);
104 mt76_set(dev
, MT_UDMA_TX_QSEL
, MT_FW_DL_EN
);
106 err
= mt7925_run_firmware(dev
);
110 mt76_clear(dev
, MT_UDMA_TX_QSEL
, MT_FW_DL_EN
);
112 err
= mt7925_mcu_set_eeprom(dev
);
116 err
= mt7925_mac_init(dev
);
120 err
= __mt7925_start(&dev
->phy
);
122 clear_bit(MT76_RESET
, &dev
->mphy
.state
);
124 mt76_worker_enable(&dev
->mt76
.tx_worker
);
129 static int mt7925u_probe(struct usb_interface
*usb_intf
,
130 const struct usb_device_id
*id
)
132 static const struct mt76_driver_ops drv_ops
= {
133 .txwi_size
= MT_SDIO_TXD_SIZE
,
134 .drv_flags
= MT_DRV_RX_DMA_HDR
| MT_DRV_HW_MGMT_TXQ
|
135 MT_DRV_AMSDU_OFFLOAD
,
136 .survey_flags
= SURVEY_INFO_TIME_TX
|
137 SURVEY_INFO_TIME_RX
|
138 SURVEY_INFO_TIME_BSS_RX
,
139 .tx_prepare_skb
= mt7925_usb_sdio_tx_prepare_skb
,
140 .tx_complete_skb
= mt7925_usb_sdio_tx_complete_skb
,
141 .tx_status_data
= mt7925_usb_sdio_tx_status_data
,
142 .rx_skb
= mt7925_queue_rx_skb
,
143 .rx_check
= mt7925_rx_check
,
144 .sta_add
= mt7925_mac_sta_add
,
145 .sta_event
= mt7925_mac_sta_event
,
146 .sta_remove
= mt7925_mac_sta_remove
,
147 .update_survey
= mt792x_update_channel
,
149 static const struct mt792x_hif_ops hif_ops
= {
150 .mcu_init
= mt7925u_mcu_init
,
151 .init_reset
= mt792xu_init_reset
,
152 .reset
= mt7925u_mac_reset
,
154 static struct mt76_bus_ops bus_ops
= {
158 .read_copy
= mt76u_read_copy
,
159 .write_copy
= mt792xu_copy
,
160 .type
= MT76_BUS_USB
,
162 struct usb_device
*udev
= interface_to_usbdev(usb_intf
);
163 struct ieee80211_ops
*ops
;
164 struct ieee80211_hw
*hw
;
165 struct mt792x_dev
*dev
;
166 struct mt76_dev
*mdev
;
170 ops
= mt792x_get_mac80211_ops(&usb_intf
->dev
, &mt7925_ops
,
171 (void *)id
->driver_info
, &features
);
175 ops
->stop
= mt792xu_stop
;
177 mdev
= mt76_alloc_device(&usb_intf
->dev
, sizeof(*dev
), ops
, &drv_ops
);
181 dev
= container_of(mdev
, struct mt792x_dev
, mt76
);
182 dev
->fw_features
= features
;
183 dev
->hif_ops
= &hif_ops
;
185 udev
= usb_get_dev(udev
);
186 usb_reset_device(udev
);
188 usb_set_intfdata(usb_intf
, dev
);
190 ret
= __mt76u_init(mdev
, usb_intf
, &bus_ops
);
194 mdev
->rev
= (mt76_rr(dev
, MT_HW_CHIPID
) << 16) |
195 (mt76_rr(dev
, MT_HW_REV
) & 0xff);
196 dev_dbg(mdev
->dev
, "ASIC revision: %04x\n", mdev
->rev
);
198 if (mt76_get_field(dev
, MT_CONN_ON_MISC
, MT_TOP_MISC2_FW_N9_RDY
)) {
199 ret
= mt792xu_wfsys_reset(dev
);
204 ret
= mt792xu_mcu_power_on(dev
);
208 ret
= mt76u_alloc_mcu_queue(&dev
->mt76
);
212 ret
= mt76u_alloc_queues(&dev
->mt76
);
216 ret
= mt792xu_dma_init(dev
, false);
221 /* check hw sg support in order to enable AMSDU */
222 hw
->max_tx_fragments
= mdev
->usb
.sg_en
? MT_HW_TXP_MAX_BUF_NUM
: 1;
224 ret
= mt7925_register_device(dev
);
231 mt76u_queues_deinit(&dev
->mt76
);
233 usb_set_intfdata(usb_intf
, NULL
);
234 usb_put_dev(interface_to_usbdev(usb_intf
));
236 mt76_free_device(&dev
->mt76
);
242 static int mt7925u_suspend(struct usb_interface
*intf
, pm_message_t state
)
244 struct mt792x_dev
*dev
= usb_get_intfdata(intf
);
245 struct mt76_connac_pm
*pm
= &dev
->pm
;
248 pm
->suspended
= true;
249 flush_work(&dev
->reset_work
);
251 err
= mt76_connac_mcu_set_hif_suspend(&dev
->mt76
, true);
255 mt76u_stop_rx(&dev
->mt76
);
256 mt76u_stop_tx(&dev
->mt76
);
261 pm
->suspended
= false;
264 mt792x_reset(&dev
->mt76
);
269 static int mt7925u_resume(struct usb_interface
*intf
)
271 struct mt792x_dev
*dev
= usb_get_intfdata(intf
);
272 struct mt76_connac_pm
*pm
= &dev
->pm
;
276 for (i
= 0; i
< 10; i
++) {
277 u32 val
= mt76_rr(dev
, MT_WF_SW_DEF_CR_USB_MCU_EVENT
);
279 if (!(val
& MT_WF_SW_SER_TRIGGER_SUSPEND
)) {
283 if (val
& MT_WF_SW_SER_DONE_SUSPEND
) {
284 mt76_wr(dev
, MT_WF_SW_DEF_CR_USB_MCU_EVENT
, 0);
291 if (reinit
|| mt792x_dma_need_reinit(dev
)) {
292 err
= mt792xu_dma_init(dev
, true);
297 err
= mt76u_resume_rx(&dev
->mt76
);
301 err
= mt76_connac_mcu_set_hif_suspend(&dev
->mt76
, false);
303 pm
->suspended
= false;
306 mt792x_reset(&dev
->mt76
);
310 #endif /* CONFIG_PM */
312 MODULE_DEVICE_TABLE(usb
, mt7925u_device_table
);
313 MODULE_FIRMWARE(MT7925_FIRMWARE_WM
);
314 MODULE_FIRMWARE(MT7925_ROM_PATCH
);
316 static struct usb_driver mt7925u_driver
= {
317 .name
= KBUILD_MODNAME
,
318 .id_table
= mt7925u_device_table
,
319 .probe
= mt7925u_probe
,
320 .disconnect
= mt792xu_disconnect
,
322 .suspend
= mt7925u_suspend
,
323 .resume
= mt7925u_resume
,
324 .reset_resume
= mt7925u_resume
,
325 #endif /* CONFIG_PM */
327 .disable_hub_initiated_lpm
= 1,
329 module_usb_driver(mt7925u_driver
);
331 MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
332 MODULE_DESCRIPTION("MediaTek MT7925U (USB) wireless driver");
333 MODULE_LICENSE("Dual BSD/GPL");