Commit be83a7e2 authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Felix Fietkau

mt76: mt76u: rely on woker APIs for rx work

In order to improve parallelism, convert rx path in mt76-usb module to
mt76 workers APIs
Signed-off-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent faa72684
......@@ -430,7 +430,7 @@ struct mt76_usb {
u8 *data;
u16 data_len;
struct tasklet_struct rx_tasklet;
struct mt76_worker rx_worker;
struct work_struct stat_work;
u8 out_ep[__MT_EP_OUT_MAX];
......
......@@ -126,21 +126,20 @@ static int mt7663u_probe(struct usb_interface *usb_intf,
alloc_queues:
ret = mt76u_alloc_mcu_queue(&dev->mt76);
if (ret)
goto error_free_q;
goto error;
ret = mt76u_alloc_queues(&dev->mt76);
if (ret)
goto error_free_q;
goto error;
ret = mt7663_usb_sdio_register_device(dev);
if (ret)
goto error_free_q;
goto error;
return 0;
error_free_q:
mt76u_queues_deinit(&dev->mt76);
error:
mt76u_queues_deinit(&dev->mt76);
usb_set_intfdata(usb_intf, NULL);
usb_put_dev(interface_to_usbdev(usb_intf));
......
......@@ -277,6 +277,7 @@ static int mt76x0u_probe(struct usb_interface *usb_intf,
err:
usb_set_intfdata(usb_intf, NULL);
usb_put_dev(interface_to_usbdev(usb_intf));
mt76u_queues_deinit(&dev->mt76);
mt76_free_device(&dev->mt76);
return ret;
......
......@@ -75,6 +75,7 @@ static int mt76x2u_probe(struct usb_interface *intf,
return 0;
err:
mt76u_queues_deinit(&dev->mt76);
mt76_free_device(&dev->mt76);
usb_set_intfdata(intf, NULL);
usb_put_dev(udev);
......
......@@ -627,7 +627,7 @@ static void mt76u_complete_rx(struct urb *urb)
q->head = (q->head + 1) % q->ndesc;
q->queued++;
tasklet_schedule(&dev->usb.rx_tasklet);
mt76_worker_schedule(&dev->usb.rx_worker);
out:
spin_unlock_irqrestore(&q->lock, flags);
}
......@@ -665,13 +665,17 @@ mt76u_process_rx_queue(struct mt76_dev *dev, struct mt76_queue *q)
}
mt76u_submit_rx_buf(dev, qid, urb);
}
if (qid == MT_RXQ_MAIN)
if (qid == MT_RXQ_MAIN) {
local_bh_disable();
mt76_rx_poll_complete(dev, MT_RXQ_MAIN, NULL);
local_bh_enable();
}
}
static void mt76u_rx_tasklet(struct tasklet_struct *t)
static void mt76u_rx_worker(struct mt76_worker *w)
{
struct mt76_dev *dev = from_tasklet(dev, t, usb.rx_tasklet);
struct mt76_usb *usb = container_of(w, struct mt76_usb, rx_worker);
struct mt76_dev *dev = container_of(usb, struct mt76_dev, usb);
int i;
rcu_read_lock();
......@@ -737,8 +741,13 @@ mt76u_free_rx_queue(struct mt76_dev *dev, struct mt76_queue *q)
struct page *page;
int i;
for (i = 0; i < q->ndesc; i++)
for (i = 0; i < q->ndesc; i++) {
if (!q->entry[i].urb)
continue;
mt76u_urb_free(q->entry[i].urb);
q->entry[i].urb = NULL;
}
if (!q->rx_page.va)
return;
......@@ -752,6 +761,8 @@ static void mt76u_free_rx(struct mt76_dev *dev)
{
int i;
mt76_worker_teardown(&dev->usb.rx_worker);
mt76_for_each_q_rx(dev, i)
mt76u_free_rx_queue(dev, &dev->q_rx[i]);
}
......@@ -760,6 +771,8 @@ void mt76u_stop_rx(struct mt76_dev *dev)
{
int i;
mt76_worker_disable(&dev->usb.rx_worker);
mt76_for_each_q_rx(dev, i) {
struct mt76_queue *q = &dev->q_rx[i];
int j;
......@@ -767,8 +780,6 @@ void mt76u_stop_rx(struct mt76_dev *dev)
for (j = 0; j < q->ndesc; j++)
usb_poison_urb(q->entry[j].urb);
}
tasklet_kill(&dev->usb.rx_tasklet);
}
EXPORT_SYMBOL_GPL(mt76u_stop_rx);
......@@ -788,6 +799,8 @@ int mt76u_resume_rx(struct mt76_dev *dev)
return err;
}
mt76_worker_enable(&dev->usb.rx_worker);
return 0;
}
EXPORT_SYMBOL_GPL(mt76u_resume_rx);
......@@ -1011,8 +1024,10 @@ static void mt76u_free_tx(struct mt76_dev *dev)
if (!q)
continue;
for (j = 0; j < q->ndesc; j++)
for (j = 0; j < q->ndesc; j++) {
usb_free_urb(q->entry[j].urb);
q->entry[j].urb = NULL;
}
}
}
......@@ -1102,7 +1117,7 @@ int mt76u_init(struct mt76_dev *dev,
};
struct usb_device *udev = interface_to_usbdev(intf);
struct mt76_usb *usb = &dev->usb;
int err = -ENOMEM;
int err;
mt76u_ops.rr = ext ? mt76u_rr_ext : mt76u_rr;
mt76u_ops.wr = ext ? mt76u_wr_ext : mt76u_wr;
......@@ -1110,7 +1125,6 @@ int mt76u_init(struct mt76_dev *dev,
mt76u_ops.write_copy = ext ? mt76u_copy_ext : mt76u_copy;
dev->tx_worker.fn = mt76u_tx_worker;
tasklet_setup(&usb->rx_tasklet, mt76u_rx_tasklet);
INIT_WORK(&usb->stat_work, mt76u_tx_status_data);
usb->data_len = usb_maxpacket(udev, usb_sndctrlpipe(udev, 0), 1);
......@@ -1119,7 +1133,7 @@ int mt76u_init(struct mt76_dev *dev,
usb->data = devm_kmalloc(dev->dev, usb->data_len, GFP_KERNEL);
if (!usb->data)
goto error;
return -ENOMEM;
mutex_init(&usb->usb_ctrl_mtx);
dev->bus = &mt76u_ops;
......@@ -1131,14 +1145,16 @@ int mt76u_init(struct mt76_dev *dev,
err = mt76u_set_endpoints(intf, usb);
if (err < 0)
goto error;
return err;
return 0;
err = mt76_worker_setup(dev->hw, &usb->rx_worker, mt76u_rx_worker,
"usb-rx");
if (err)
return err;
error:
destroy_workqueue(dev->wq);
sched_set_fifo_low(usb->rx_worker.task);
return err;
return 0;
}
EXPORT_SYMBOL_GPL(mt76u_init);
......
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