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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/mediatek/mt76/sdio.c
Extension
.c
Size
14573 bytes
Lines
682
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 (mcu) {
			dev_kfree_skb(entry.skb);
			entry.skb = NULL;
		}

		mt76_queue_tx_complete(dev, q, &entry);
		nframes++;
	}

	if (!q->queued)
		wake_up(&dev->tx_wait);

	return nframes;
}

static void mt76s_status_worker(struct mt76_worker *w)
{
	struct mt76_sdio *sdio = container_of(w, struct mt76_sdio,
					      status_worker);
	struct mt76_dev *dev = container_of(sdio, struct mt76_dev, sdio);
	bool resched = false;
	int i, nframes;

	do {
		int ndata_frames = 0;

		nframes = mt76s_process_tx_queue(dev, dev->q_mcu[MT_MCUQ_WM]);

		for (i = 0; i <= MT_TXQ_PSD; i++)
			ndata_frames += mt76s_process_tx_queue(dev,
							       dev->phy.q_tx[i]);
		nframes += ndata_frames;
		if (ndata_frames > 0)
			resched = true;

		if (dev->drv->tx_status_data && ndata_frames > 0 &&
		    !test_and_set_bit(MT76_READING_STATS, &dev->phy.state) &&
		    !test_bit(MT76_STATE_SUSPEND, &dev->phy.state))
			mt76_worker_schedule(&sdio->stat_worker);
	} while (nframes > 0);

	if (resched)
		mt76_worker_schedule(&dev->tx_worker);
}

static void mt76s_tx_status_data(struct mt76_worker *worker)
{
	struct mt76_sdio *sdio;
	struct mt76_dev *dev;
	u8 update = 1;
	u16 count = 0;

	sdio = container_of(worker, struct mt76_sdio, stat_worker);
	dev = container_of(sdio, struct mt76_dev, sdio);

	while (true) {
		if (test_bit(MT76_RESET, &dev->phy.state) ||
		    test_bit(MT76_REMOVED, &dev->phy.state))
			break;

		if (!dev->drv->tx_status_data(dev, &update))
			break;
		count++;
	}

	if (count && test_bit(MT76_STATE_RUNNING, &dev->phy.state))
		mt76_worker_schedule(&sdio->status_worker);
	else
		clear_bit(MT76_READING_STATS, &dev->phy.state);
}

static int
mt76s_tx_queue_skb(struct mt76_phy *phy, struct mt76_queue *q,
		   enum mt76_txq_id qid, struct sk_buff *skb,
		   struct mt76_wcid *wcid, struct ieee80211_sta *sta)
{
	struct mt76_tx_info tx_info = {
		.skb = skb,
	};
	struct mt76_dev *dev = phy->dev;
	int err, len = skb->len;
	u16 idx = q->head;

	if (q->queued == q->ndesc)
		return -ENOSPC;

	skb->prev = skb->next = NULL;
	err = dev->drv->tx_prepare_skb(dev, NULL, qid, wcid, sta, &tx_info);
	if (err < 0)
		return err;

Annotation

Implementation Notes