Skip to content

Commit

Permalink
mt76: mt76u: rely on woker APIs for rx work
Browse files Browse the repository at this point in the history
In order to improve parallelism, convert rx path in mt76-usb module to
mt76 workers APIs

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
  • Loading branch information
LorenzoBianconi authored and nbd168 committed Dec 4, 2020
1 parent faa7268 commit be83a7e
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 22 deletions.
2 changes: 1 addition & 1 deletion drivers/net/wireless/mediatek/mt76/mt76.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down
9 changes: 4 additions & 5 deletions drivers/net/wireless/mediatek/mt76/mt7615/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
48 changes: 32 additions & 16 deletions drivers/net/wireless/mediatek/mt76/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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;
Expand All @@ -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]);
}
Expand All @@ -760,15 +771,15 @@ 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;

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);

Expand All @@ -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);
Expand Down Expand Up @@ -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;
}
}
}

Expand Down Expand Up @@ -1102,15 +1117,14 @@ 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;
mt76u_ops.rmw = ext ? mt76u_rmw_ext : mt76u_rmw;
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);
Expand All @@ -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;
Expand All @@ -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);

Expand Down

0 comments on commit be83a7e

Please sign in to comment.