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