drivers/net/ethernet/alibaba/eea/eea_tx.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/alibaba/eea/eea_tx.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/alibaba/eea/eea_tx.c
Extension
.c
Size
10849 bytes
Lines
501
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source 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

struct eea_sq_free_stats {
	u64 packets;
	u64 bytes;
};

struct eea_tx_meta {
	struct eea_tx_meta *next;

	u32 id;

	union {
		struct sk_buff *skb;
		void *data;
	};

	u32 num;

	dma_addr_t dma_addr;
	struct eea_tx_desc *desc;
	u32 dma_len;
	bool unmap;
	bool unmap_single;
};

static struct eea_tx_meta *eea_tx_meta_get(struct eea_net_tx *tx)
{
	struct eea_tx_meta *meta;

	if (!tx->free)
		return NULL;

	meta = tx->free;
	tx->free = meta->next;

	return meta;
}

static void eea_tx_meta_put_and_unmap(struct eea_net_tx *tx,
				      struct eea_tx_meta *meta)
{
	struct eea_tx_meta *head;

	head = meta;

	while (true) {
		if (meta->unmap) {
			if (meta->unmap_single)
				dma_unmap_single(tx->dma_dev, meta->dma_addr,
						 meta->dma_len, DMA_TO_DEVICE);
			else
				dma_unmap_page(tx->dma_dev, meta->dma_addr,
					       meta->dma_len, DMA_TO_DEVICE);
		}

		if (meta->next) {
			meta = meta->next;
			continue;
		}

		break;
	}

	meta->next = tx->free;
	tx->free = head;
}

static void eea_meta_free_xmit(struct eea_net_tx *tx,
			       struct eea_tx_meta *meta,
			       int budget,
			       struct eea_tx_cdesc *desc,
			       struct eea_sq_free_stats *stats)
{
	struct sk_buff *skb = meta->skb;

	if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && desc)) {
		struct skb_shared_hwtstamps ts = {};

		ts.hwtstamp = EEA_DESC_TS(desc) + tx->enet->hw_ts_offset;
		skb_tstamp_tx(skb, &ts);
	}

	++stats->packets;
	stats->bytes += meta->skb->len;
	napi_consume_skb(meta->skb, budget);

	meta->data = NULL;
}

static int eea_clean_tx(struct eea_net_tx *tx, int budget)
{

Annotation

Implementation Notes