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

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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];
+4 −5
Original line number Diff line number Diff line
@@ -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));

+1 −0
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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);
+32 −16
Original line number Diff line number Diff line
@@ -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);