mt76: mt76u: rely on woker APIs for rx work
authorLorenzo Bianconi <lorenzo@kernel.org>
Tue, 20 Oct 2020 09:13:10 +0000 (11:13 +0200)
committerFelix Fietkau <nbd@nbd.name>
Fri, 4 Dec 2020 13:31:12 +0000 (14:31 +0100)
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>
drivers/net/wireless/mediatek/mt76/mt76.h
drivers/net/wireless/mediatek/mt76/mt7615/usb.c
drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
drivers/net/wireless/mediatek/mt76/usb.c

index 49d61ce..4046ac0 100644 (file)
@@ -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];
index f0ad83a..a60cfa3 100644 (file)
@@ -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));
 
index ce6b286..b12cb17 100644 (file)
@@ -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;
index 4e003c7..2575369 100644 (file)
@@ -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);
index 911fb61..63f55ab 100644 (file)
@@ -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);