Commit 6cb596ba authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Felix Fietkau

mt76: usb: introduce __mt76u_init utility routine

Introduce __mt76u_init unitility routine and move mt7615 usb bus ops
into mt7615 module in order to allow specifying driver specific
parameter.
This is a preliminary patch to add usb support to mt7921 driver.
Tested-by: default avatarSean Wang <sean.wang@mediatek.com>
Signed-off-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent e0daf14d
...@@ -1274,13 +1274,21 @@ mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len, ...@@ -1274,13 +1274,21 @@ mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len,
void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi, void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
struct mt76_sta_stats *stats); struct mt76_sta_stats *stats);
int mt76_skb_adjust_pad(struct sk_buff *skb, int pad); int mt76_skb_adjust_pad(struct sk_buff *skb, int pad);
int __mt76u_vendor_request(struct mt76_dev *dev, u8 req, u8 req_type,
u16 val, u16 offset, void *buf, size_t len);
int mt76u_vendor_request(struct mt76_dev *dev, u8 req, int mt76u_vendor_request(struct mt76_dev *dev, u8 req,
u8 req_type, u16 val, u16 offset, u8 req_type, u16 val, u16 offset,
void *buf, size_t len); void *buf, size_t len);
void mt76u_single_wr(struct mt76_dev *dev, const u8 req, void mt76u_single_wr(struct mt76_dev *dev, const u8 req,
const u16 offset, const u32 val); const u16 offset, const u32 val);
int mt76u_init(struct mt76_dev *dev, struct usb_interface *intf, void mt76u_read_copy(struct mt76_dev *dev, u32 offset,
bool ext); void *data, int len);
u32 ___mt76u_rr(struct mt76_dev *dev, u8 req, u8 req_type, u32 addr);
void ___mt76u_wr(struct mt76_dev *dev, u8 req, u8 req_type,
u32 addr, u32 val);
int __mt76u_init(struct mt76_dev *dev, struct usb_interface *intf,
struct mt76_bus_ops *ops);
int mt76u_init(struct mt76_dev *dev, struct usb_interface *intf);
int mt76u_alloc_mcu_queue(struct mt76_dev *dev); int mt76u_alloc_mcu_queue(struct mt76_dev *dev);
int mt76u_alloc_queues(struct mt76_dev *dev); int mt76u_alloc_queues(struct mt76_dev *dev);
void mt76u_stop_tx(struct mt76_dev *dev); void mt76u_stop_tx(struct mt76_dev *dev);
......
...@@ -21,6 +21,64 @@ static const struct usb_device_id mt7615_device_table[] = { ...@@ -21,6 +21,64 @@ static const struct usb_device_id mt7615_device_table[] = {
{ }, { },
}; };
static u32 mt7663u_rr(struct mt76_dev *dev, u32 addr)
{
u32 ret;
mutex_lock(&dev->usb.usb_ctrl_mtx);
ret = ___mt76u_rr(dev, MT_VEND_READ_EXT,
USB_DIR_IN | USB_TYPE_VENDOR, addr);
mutex_unlock(&dev->usb.usb_ctrl_mtx);
return ret;
}
static void mt7663u_wr(struct mt76_dev *dev, u32 addr, u32 val)
{
mutex_lock(&dev->usb.usb_ctrl_mtx);
___mt76u_wr(dev, MT_VEND_WRITE_EXT,
USB_DIR_OUT | USB_TYPE_VENDOR, addr, val);
mutex_unlock(&dev->usb.usb_ctrl_mtx);
}
static u32 mt7663u_rmw(struct mt76_dev *dev, u32 addr,
u32 mask, u32 val)
{
mutex_lock(&dev->usb.usb_ctrl_mtx);
val |= ___mt76u_rr(dev, MT_VEND_READ_EXT,
USB_DIR_IN | USB_TYPE_VENDOR, addr) & ~mask;
___mt76u_wr(dev, MT_VEND_WRITE_EXT,
USB_DIR_OUT | USB_TYPE_VENDOR, addr, val);
mutex_unlock(&dev->usb.usb_ctrl_mtx);
return val;
}
static void mt7663u_copy(struct mt76_dev *dev, u32 offset,
const void *data, int len)
{
struct mt76_usb *usb = &dev->usb;
int ret, i = 0, batch_len;
const u8 *val = data;
len = round_up(len, 4);
mutex_lock(&usb->usb_ctrl_mtx);
while (i < len) {
batch_len = min_t(int, usb->data_len, len - i);
memcpy(usb->data, val + i, batch_len);
ret = __mt76u_vendor_request(dev, MT_VEND_WRITE_EXT,
USB_DIR_OUT | USB_TYPE_VENDOR,
(offset + i) >> 16, offset + i,
usb->data, batch_len);
if (ret < 0)
break;
i += batch_len;
}
mutex_unlock(&usb->usb_ctrl_mtx);
}
static void mt7663u_stop(struct ieee80211_hw *hw) static void mt7663u_stop(struct ieee80211_hw *hw)
{ {
struct mt7615_phy *phy = mt7615_hw_phy(hw); struct mt7615_phy *phy = mt7615_hw_phy(hw);
...@@ -66,6 +124,14 @@ static int mt7663u_probe(struct usb_interface *usb_intf, ...@@ -66,6 +124,14 @@ static int mt7663u_probe(struct usb_interface *usb_intf,
.sta_remove = mt7615_mac_sta_remove, .sta_remove = mt7615_mac_sta_remove,
.update_survey = mt7615_update_channel, .update_survey = mt7615_update_channel,
}; };
static struct mt76_bus_ops bus_ops = {
.rr = mt7663u_rr,
.wr = mt7663u_wr,
.rmw = mt7663u_rmw,
.read_copy = mt76u_read_copy,
.write_copy = mt7663u_copy,
.type = MT76_BUS_USB,
};
struct usb_device *udev = interface_to_usbdev(usb_intf); struct usb_device *udev = interface_to_usbdev(usb_intf);
struct ieee80211_ops *ops; struct ieee80211_ops *ops;
struct mt7615_dev *dev; struct mt7615_dev *dev;
...@@ -92,7 +158,7 @@ static int mt7663u_probe(struct usb_interface *usb_intf, ...@@ -92,7 +158,7 @@ static int mt7663u_probe(struct usb_interface *usb_intf,
INIT_WORK(&dev->mcu_work, mt7663u_init_work); INIT_WORK(&dev->mcu_work, mt7663u_init_work);
dev->reg_map = mt7663_usb_sdio_reg_map; dev->reg_map = mt7663_usb_sdio_reg_map;
dev->ops = ops; dev->ops = ops;
ret = mt76u_init(mdev, usb_intf, true); ret = __mt76u_init(mdev, usb_intf, &bus_ops);
if (ret < 0) if (ret < 0)
goto error; goto error;
......
...@@ -245,7 +245,7 @@ static int mt76x0u_probe(struct usb_interface *usb_intf, ...@@ -245,7 +245,7 @@ static int mt76x0u_probe(struct usb_interface *usb_intf,
usb_set_intfdata(usb_intf, dev); usb_set_intfdata(usb_intf, dev);
mt76x02u_init_mcu(mdev); mt76x02u_init_mcu(mdev);
ret = mt76u_init(mdev, usb_intf, false); ret = mt76u_init(mdev, usb_intf);
if (ret) if (ret)
goto err; goto err;
......
...@@ -57,7 +57,7 @@ static int mt76x2u_probe(struct usb_interface *intf, ...@@ -57,7 +57,7 @@ static int mt76x2u_probe(struct usb_interface *intf,
usb_set_intfdata(intf, dev); usb_set_intfdata(intf, dev);
mt76x02u_init_mcu(mdev); mt76x02u_init_mcu(mdev);
err = mt76u_init(mdev, intf, false); err = mt76u_init(mdev, intf);
if (err < 0) if (err < 0)
goto err; goto err;
......
...@@ -15,9 +15,8 @@ static bool disable_usb_sg; ...@@ -15,9 +15,8 @@ static bool disable_usb_sg;
module_param_named(disable_usb_sg, disable_usb_sg, bool, 0644); module_param_named(disable_usb_sg, disable_usb_sg, bool, 0644);
MODULE_PARM_DESC(disable_usb_sg, "Disable usb scatter-gather support"); MODULE_PARM_DESC(disable_usb_sg, "Disable usb scatter-gather support");
static int __mt76u_vendor_request(struct mt76_dev *dev, u8 req, int __mt76u_vendor_request(struct mt76_dev *dev, u8 req, u8 req_type,
u8 req_type, u16 val, u16 offset, u16 val, u16 offset, void *buf, size_t len)
void *buf, size_t len)
{ {
struct usb_interface *uintf = to_usb_interface(dev->dev); struct usb_interface *uintf = to_usb_interface(dev->dev);
struct usb_device *udev = interface_to_usbdev(uintf); struct usb_device *udev = interface_to_usbdev(uintf);
...@@ -45,6 +44,7 @@ static int __mt76u_vendor_request(struct mt76_dev *dev, u8 req, ...@@ -45,6 +44,7 @@ static int __mt76u_vendor_request(struct mt76_dev *dev, u8 req,
req, offset, ret); req, offset, ret);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(__mt76u_vendor_request);
int mt76u_vendor_request(struct mt76_dev *dev, u8 req, int mt76u_vendor_request(struct mt76_dev *dev, u8 req,
u8 req_type, u16 val, u16 offset, u8 req_type, u16 val, u16 offset,
...@@ -62,8 +62,7 @@ int mt76u_vendor_request(struct mt76_dev *dev, u8 req, ...@@ -62,8 +62,7 @@ int mt76u_vendor_request(struct mt76_dev *dev, u8 req,
} }
EXPORT_SYMBOL_GPL(mt76u_vendor_request); EXPORT_SYMBOL_GPL(mt76u_vendor_request);
static u32 ___mt76u_rr(struct mt76_dev *dev, u8 req, u8 req_type, u32 ___mt76u_rr(struct mt76_dev *dev, u8 req, u8 req_type, u32 addr)
u32 addr)
{ {
struct mt76_usb *usb = &dev->usb; struct mt76_usb *usb = &dev->usb;
u32 data = ~0; u32 data = ~0;
...@@ -77,6 +76,7 @@ static u32 ___mt76u_rr(struct mt76_dev *dev, u8 req, u8 req_type, ...@@ -77,6 +76,7 @@ static u32 ___mt76u_rr(struct mt76_dev *dev, u8 req, u8 req_type,
return data; return data;
} }
EXPORT_SYMBOL_GPL(___mt76u_rr);
static u32 __mt76u_rr(struct mt76_dev *dev, u32 addr) static u32 __mt76u_rr(struct mt76_dev *dev, u32 addr)
{ {
...@@ -109,20 +109,8 @@ static u32 mt76u_rr(struct mt76_dev *dev, u32 addr) ...@@ -109,20 +109,8 @@ static u32 mt76u_rr(struct mt76_dev *dev, u32 addr)
return ret; return ret;
} }
static u32 mt76u_rr_ext(struct mt76_dev *dev, u32 addr) void ___mt76u_wr(struct mt76_dev *dev, u8 req, u8 req_type,
{ u32 addr, u32 val)
u32 ret;
mutex_lock(&dev->usb.usb_ctrl_mtx);
ret = ___mt76u_rr(dev, MT_VEND_READ_EXT,
USB_DIR_IN | USB_TYPE_VENDOR, addr);
mutex_unlock(&dev->usb.usb_ctrl_mtx);
return ret;
}
static void ___mt76u_wr(struct mt76_dev *dev, u8 req, u8 req_type,
u32 addr, u32 val)
{ {
struct mt76_usb *usb = &dev->usb; struct mt76_usb *usb = &dev->usb;
...@@ -131,6 +119,7 @@ static void ___mt76u_wr(struct mt76_dev *dev, u8 req, u8 req_type, ...@@ -131,6 +119,7 @@ static void ___mt76u_wr(struct mt76_dev *dev, u8 req, u8 req_type,
addr, usb->data, sizeof(__le32)); addr, usb->data, sizeof(__le32));
trace_usb_reg_wr(dev, addr, val); trace_usb_reg_wr(dev, addr, val);
} }
EXPORT_SYMBOL_GPL(___mt76u_wr);
static void __mt76u_wr(struct mt76_dev *dev, u32 addr, u32 val) static void __mt76u_wr(struct mt76_dev *dev, u32 addr, u32 val)
{ {
...@@ -155,14 +144,6 @@ static void mt76u_wr(struct mt76_dev *dev, u32 addr, u32 val) ...@@ -155,14 +144,6 @@ static void mt76u_wr(struct mt76_dev *dev, u32 addr, u32 val)
mutex_unlock(&dev->usb.usb_ctrl_mtx); mutex_unlock(&dev->usb.usb_ctrl_mtx);
} }
static void mt76u_wr_ext(struct mt76_dev *dev, u32 addr, u32 val)
{
mutex_lock(&dev->usb.usb_ctrl_mtx);
___mt76u_wr(dev, MT_VEND_WRITE_EXT,
USB_DIR_OUT | USB_TYPE_VENDOR, addr, val);
mutex_unlock(&dev->usb.usb_ctrl_mtx);
}
static u32 mt76u_rmw(struct mt76_dev *dev, u32 addr, static u32 mt76u_rmw(struct mt76_dev *dev, u32 addr,
u32 mask, u32 val) u32 mask, u32 val)
{ {
...@@ -174,19 +155,6 @@ static u32 mt76u_rmw(struct mt76_dev *dev, u32 addr, ...@@ -174,19 +155,6 @@ static u32 mt76u_rmw(struct mt76_dev *dev, u32 addr,
return val; return val;
} }
static u32 mt76u_rmw_ext(struct mt76_dev *dev, u32 addr,
u32 mask, u32 val)
{
mutex_lock(&dev->usb.usb_ctrl_mtx);
val |= ___mt76u_rr(dev, MT_VEND_READ_EXT,
USB_DIR_IN | USB_TYPE_VENDOR, addr) & ~mask;
___mt76u_wr(dev, MT_VEND_WRITE_EXT,
USB_DIR_OUT | USB_TYPE_VENDOR, addr, val);
mutex_unlock(&dev->usb.usb_ctrl_mtx);
return val;
}
static void mt76u_copy(struct mt76_dev *dev, u32 offset, static void mt76u_copy(struct mt76_dev *dev, u32 offset,
const void *data, int len) const void *data, int len)
{ {
...@@ -219,33 +187,8 @@ static void mt76u_copy(struct mt76_dev *dev, u32 offset, ...@@ -219,33 +187,8 @@ static void mt76u_copy(struct mt76_dev *dev, u32 offset,
mutex_unlock(&usb->usb_ctrl_mtx); mutex_unlock(&usb->usb_ctrl_mtx);
} }
static void mt76u_copy_ext(struct mt76_dev *dev, u32 offset, void mt76u_read_copy(struct mt76_dev *dev, u32 offset,
const void *data, int len) void *data, int len)
{
struct mt76_usb *usb = &dev->usb;
int ret, i = 0, batch_len;
const u8 *val = data;
len = round_up(len, 4);
mutex_lock(&usb->usb_ctrl_mtx);
while (i < len) {
batch_len = min_t(int, usb->data_len, len - i);
memcpy(usb->data, val + i, batch_len);
ret = __mt76u_vendor_request(dev, MT_VEND_WRITE_EXT,
USB_DIR_OUT | USB_TYPE_VENDOR,
(offset + i) >> 16, offset + i,
usb->data, batch_len);
if (ret < 0)
break;
i += batch_len;
}
mutex_unlock(&usb->usb_ctrl_mtx);
}
static void
mt76u_read_copy_ext(struct mt76_dev *dev, u32 offset,
void *data, int len)
{ {
struct mt76_usb *usb = &dev->usb; struct mt76_usb *usb = &dev->usb;
int i = 0, batch_len, ret; int i = 0, batch_len, ret;
...@@ -267,6 +210,7 @@ mt76u_read_copy_ext(struct mt76_dev *dev, u32 offset, ...@@ -267,6 +210,7 @@ mt76u_read_copy_ext(struct mt76_dev *dev, u32 offset,
} }
mutex_unlock(&usb->usb_ctrl_mtx); mutex_unlock(&usb->usb_ctrl_mtx);
} }
EXPORT_SYMBOL_GPL(mt76u_read_copy);
void mt76u_single_wr(struct mt76_dev *dev, const u8 req, void mt76u_single_wr(struct mt76_dev *dev, const u8 req,
const u16 offset, const u32 val) const u16 offset, const u32 val)
...@@ -1115,24 +1059,13 @@ static const struct mt76_queue_ops usb_queue_ops = { ...@@ -1115,24 +1059,13 @@ static const struct mt76_queue_ops usb_queue_ops = {
.kick = mt76u_tx_kick, .kick = mt76u_tx_kick,
}; };
int mt76u_init(struct mt76_dev *dev, int __mt76u_init(struct mt76_dev *dev, struct usb_interface *intf,
struct usb_interface *intf, bool ext) struct mt76_bus_ops *ops)
{ {
static struct mt76_bus_ops mt76u_ops = {
.read_copy = mt76u_read_copy_ext,
.wr_rp = mt76u_wr_rp,
.rd_rp = mt76u_rd_rp,
.type = MT76_BUS_USB,
};
struct usb_device *udev = interface_to_usbdev(intf); struct usb_device *udev = interface_to_usbdev(intf);
struct mt76_usb *usb = &dev->usb; struct mt76_usb *usb = &dev->usb;
int err; int err;
mt76u_ops.rr = ext ? mt76u_rr_ext : mt76u_rr;
mt76u_ops.wr = ext ? mt76u_wr_ext : mt76u_wr;
mt76u_ops.rmw = ext ? mt76u_rmw_ext : mt76u_rmw;
mt76u_ops.write_copy = ext ? mt76u_copy_ext : mt76u_copy;
INIT_WORK(&usb->stat_work, mt76u_tx_status_data); INIT_WORK(&usb->stat_work, mt76u_tx_status_data);
usb->data_len = usb_maxpacket(udev, usb_sndctrlpipe(udev, 0), 1); usb->data_len = usb_maxpacket(udev, usb_sndctrlpipe(udev, 0), 1);
...@@ -1144,7 +1077,7 @@ int mt76u_init(struct mt76_dev *dev, ...@@ -1144,7 +1077,7 @@ int mt76u_init(struct mt76_dev *dev,
return -ENOMEM; return -ENOMEM;
mutex_init(&usb->usb_ctrl_mtx); mutex_init(&usb->usb_ctrl_mtx);
dev->bus = &mt76u_ops; dev->bus = ops;
dev->queue_ops = &usb_queue_ops; dev->queue_ops = &usb_queue_ops;
dev_set_drvdata(&udev->dev, dev); dev_set_drvdata(&udev->dev, dev);
...@@ -1170,6 +1103,23 @@ int mt76u_init(struct mt76_dev *dev, ...@@ -1170,6 +1103,23 @@ int mt76u_init(struct mt76_dev *dev,
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(__mt76u_init);
int mt76u_init(struct mt76_dev *dev, struct usb_interface *intf)
{
static struct mt76_bus_ops bus_ops = {
.rr = mt76u_rr,
.wr = mt76u_wr,
.rmw = mt76u_rmw,
.read_copy = mt76u_read_copy,
.write_copy = mt76u_copy,
.wr_rp = mt76u_wr_rp,
.rd_rp = mt76u_rd_rp,
.type = MT76_BUS_USB,
};
return __mt76u_init(dev, intf, &bus_ops);
}
EXPORT_SYMBOL_GPL(mt76u_init); EXPORT_SYMBOL_GPL(mt76u_init);
MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>"); MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment