wifi: mt76: mt792x: add common USB transport reset helpers

Add per-device USB reset work and a control-path access check helper
for mt7921u and mt7925u.

This prepares common infrastructure for transport-level recovery while
keeping the reset state per-device for correct lifetime handling.

No functional change intended.

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260401190632.147042-1-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
Sean Wang 2026-04-01 14:06:31 -05:00 committed by Felix Fietkau
parent 879d754e48
commit d23353688d
4 changed files with 59 additions and 0 deletions

View File

@ -198,6 +198,7 @@ static int mt7921u_probe(struct usb_interface *usb_intf,
dev = container_of(mdev, struct mt792x_dev, mt76);
dev->fw_features = features;
dev->hif_ops = &hif_ops;
mt792xu_reset_work_init(dev);
usb_reset_device(udev);
@ -245,6 +246,7 @@ static int mt7921u_probe(struct usb_interface *usb_intf,
error:
mt76u_queues_deinit(&dev->mt76);
mt792xu_reset_work_cleanup(dev);
usb_set_intfdata(usb_intf, NULL);

View File

@ -195,6 +195,7 @@ static int mt7925u_probe(struct usb_interface *usb_intf,
dev = container_of(mdev, struct mt792x_dev, mt76);
dev->fw_features = features;
dev->hif_ops = &hif_ops;
mt792xu_reset_work_init(dev);
usb_reset_device(udev);
@ -249,6 +250,7 @@ static int mt7925u_probe(struct usb_interface *usb_intf,
error:
mt76u_queues_deinit(&dev->mt76);
mt792xu_reset_work_cleanup(dev);
usb_set_intfdata(usb_intf, NULL);

View File

@ -262,6 +262,8 @@ struct mt792x_dev {
wait_queue_head_t wait;
struct work_struct init_work;
struct work_struct usb_reset_work;
atomic_t usb_reset_pending;
u8 fw_debug;
u8 fw_features;
@ -516,6 +518,9 @@ int mt792xu_dma_init(struct mt792x_dev *dev, bool resume);
int mt792xu_mcu_power_on(struct mt792x_dev *dev);
int mt792xu_wfsys_reset(struct mt792x_dev *dev);
int mt792xu_init_reset(struct mt792x_dev *dev);
void mt792xu_reset_work_init(struct mt792x_dev *dev);
void mt792xu_reset_work_cleanup(struct mt792x_dev *dev);
int mt792xu_check_bus(struct mt792x_dev *dev);
u32 mt792xu_rr(struct mt76_dev *dev, u32 addr);
void mt792xu_wr(struct mt76_dev *dev, u32 addr, u32 val);
u32 mt792xu_rmw(struct mt76_dev *dev, u32 addr, u32 mask, u32 val);

View File

@ -11,6 +11,55 @@
#include "mt792x.h"
#include "mt76_connac2_mac.h"
static int mt792xu_read32(struct mt76_dev *dev, u32 addr, void *buf)
{
return __mt76u_vendor_request(dev, MT_VEND_READ_EXT,
USB_DIR_IN | MT_USB_TYPE_VENDOR,
(u16)(addr >> 16), (u16)addr,
buf, sizeof(__le32));
}
static void mt792xu_reset_work(struct work_struct *work)
{
struct mt792x_dev *dev =
container_of(work, struct mt792x_dev, usb_reset_work);
struct usb_interface *usb_intf = to_usb_interface(dev->mt76.dev);
if (usb_intf && usb_get_intfdata(usb_intf) == dev)
usb_queue_reset_device(usb_intf);
atomic_set(&dev->usb_reset_pending, 0);
}
void mt792xu_reset_work_init(struct mt792x_dev *dev)
{
INIT_WORK(&dev->usb_reset_work, mt792xu_reset_work);
atomic_set(&dev->usb_reset_pending, 0);
}
EXPORT_SYMBOL_GPL(mt792xu_reset_work_init);
void mt792xu_reset_work_cleanup(struct mt792x_dev *dev)
{
cancel_work_sync(&dev->usb_reset_work);
atomic_set(&dev->usb_reset_pending, 0);
}
EXPORT_SYMBOL_GPL(mt792xu_reset_work_cleanup);
int mt792xu_check_bus(struct mt792x_dev *dev)
{
int ret;
mutex_lock(&dev->mt76.usb.usb_ctrl_mtx);
ret = mt792xu_read32(&dev->mt76, MT_HW_CHIPID, dev->mt76.usb.data);
mutex_unlock(&dev->mt76.usb.usb_ctrl_mtx);
if (ret == sizeof(__le32))
return 0;
return ret < 0 ? ret : -EIO;
}
EXPORT_SYMBOL_GPL(mt792xu_check_bus);
u32 mt792xu_rr(struct mt76_dev *dev, u32 addr)
{
u32 ret;
@ -333,6 +382,7 @@ void mt792xu_disconnect(struct usb_interface *usb_intf)
{
struct mt792x_dev *dev = usb_get_intfdata(usb_intf);
mt792xu_reset_work_cleanup(dev);
cancel_work_sync(&dev->init_work);
if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state))
return;