drivers/net/wireless/mediatek/mt76/usb.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/mediatek/mt76/usb.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/mediatek/mt76/usb.c
Extension
.c
Size
25578 bytes
Lines
1142
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (count > 0) {
			err = mt76u_refill_rx(dev, q, urb, count);
			if (err < 0)
				break;
		}
		mt76u_submit_rx_buf(dev, qid, urb);
	}
	if (qid == MT_RXQ_MAIN) {
		local_bh_disable();
		mt76_rx_poll_complete(dev, MT_RXQ_MAIN, NULL);
		local_bh_enable();
	}
}

static void mt76u_rx_worker(struct mt76_worker *w)
{
	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();
	mt76_for_each_q_rx(dev, i)
		mt76u_process_rx_queue(dev, &dev->q_rx[i]);
	rcu_read_unlock();
}

static int
mt76u_submit_rx_buffers(struct mt76_dev *dev, enum mt76_rxq_id qid)
{
	struct mt76_queue *q = &dev->q_rx[qid];
	unsigned long flags;
	int i, err = 0;

	spin_lock_irqsave(&q->lock, flags);
	for (i = 0; i < q->ndesc; i++) {
		err = mt76u_submit_rx_buf(dev, qid, q->entry[i].urb);
		if (err < 0)
			break;
	}
	q->head = q->tail = 0;
	q->queued = 0;
	spin_unlock_irqrestore(&q->lock, flags);

	return err;
}

static int
mt76u_alloc_rx_queue(struct mt76_dev *dev, enum mt76_rxq_id qid)
{
	struct mt76_queue *q = &dev->q_rx[qid];
	int i, err;

	err = mt76_create_page_pool(dev, q);
	if (err)
		return err;

	spin_lock_init(&q->lock);
	q->entry = devm_kcalloc(dev->dev,
				MT_NUM_RX_ENTRIES, sizeof(*q->entry),
				GFP_KERNEL);
	if (!q->entry)
		return -ENOMEM;

	q->ndesc = MT_NUM_RX_ENTRIES;
	q->buf_size = PAGE_SIZE;

	for (i = 0; i < q->ndesc; i++) {
		err = mt76u_rx_urb_alloc(dev, q, &q->entry[i]);
		if (err < 0)
			return err;
	}

	return mt76u_submit_rx_buffers(dev, qid);
}

int mt76u_alloc_mcu_queue(struct mt76_dev *dev)
{
	return mt76u_alloc_rx_queue(dev, MT_RXQ_MCU);
}
EXPORT_SYMBOL_GPL(mt76u_alloc_mcu_queue);

static void
mt76u_free_rx_queue(struct mt76_dev *dev, struct mt76_queue *q)
{
	int i;

	for (i = 0; i < q->ndesc; i++) {
		if (!q->entry[i].urb)
			continue;

Annotation

Implementation Notes