drivers/net/xen-netback/rx.c

Source file repositories/reference/linux-study-clean/drivers/net/xen-netback/rx.c

File Facts

System
Linux kernel
Corpus path
drivers/net/xen-netback/rx.c
Extension
.c
Size
16859 bytes
Lines
681
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 xenvif_pkt_state {
	struct sk_buff *skb;
	size_t remaining_len;
	struct sk_buff *frag_iter;
	int frag; /* frag == -1 => frag_iter->head */
	unsigned int frag_offset;
	struct xen_netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1];
	unsigned int extra_count;
	unsigned int slot;
};

static void xenvif_rx_next_skb(struct xenvif_queue *queue,
			       struct xenvif_pkt_state *pkt)
{
	struct sk_buff *skb;
	unsigned int gso_type;

	skb = xenvif_rx_dequeue(queue);

	queue->stats.tx_bytes += skb->len;
	queue->stats.tx_packets++;

	/* Reset packet state. */
	memset(pkt, 0, sizeof(struct xenvif_pkt_state));

	pkt->skb = skb;
	pkt->frag_iter = skb;
	pkt->remaining_len = skb->len;
	pkt->frag = -1;

	gso_type = xenvif_gso_type(skb);
	if ((1 << gso_type) & queue->vif->gso_mask) {
		struct xen_netif_extra_info *extra;

		extra = &pkt->extras[XEN_NETIF_EXTRA_TYPE_GSO - 1];

		extra->u.gso.type = gso_type;
		extra->u.gso.size = skb_shinfo(skb)->gso_size;
		extra->u.gso.pad = 0;
		extra->u.gso.features = 0;
		extra->type = XEN_NETIF_EXTRA_TYPE_GSO;
		extra->flags = 0;

		pkt->extra_count++;
	}

	if (queue->vif->xdp_headroom) {
		struct xen_netif_extra_info *extra;

		extra = &pkt->extras[XEN_NETIF_EXTRA_TYPE_XDP - 1];

		memset(extra, 0, sizeof(struct xen_netif_extra_info));
		extra->u.xdp.headroom = queue->vif->xdp_headroom;
		extra->type = XEN_NETIF_EXTRA_TYPE_XDP;
		extra->flags = 0;

		pkt->extra_count++;
	}

	if (skb->sw_hash) {
		struct xen_netif_extra_info *extra;

		extra = &pkt->extras[XEN_NETIF_EXTRA_TYPE_HASH - 1];

		extra->u.hash.algorithm =
			XEN_NETIF_CTRL_HASH_ALGORITHM_TOEPLITZ;

		if (skb->l4_hash)
			extra->u.hash.type =
				skb->protocol == htons(ETH_P_IP) ?
				_XEN_NETIF_CTRL_HASH_TYPE_IPV4_TCP :
				_XEN_NETIF_CTRL_HASH_TYPE_IPV6_TCP;
		else
			extra->u.hash.type =
				skb->protocol == htons(ETH_P_IP) ?
				_XEN_NETIF_CTRL_HASH_TYPE_IPV4 :
				_XEN_NETIF_CTRL_HASH_TYPE_IPV6;

		*(uint32_t *)extra->u.hash.value = skb_get_hash_raw(skb);

		extra->type = XEN_NETIF_EXTRA_TYPE_HASH;
		extra->flags = 0;

		pkt->extra_count++;
	}
}

static void xenvif_rx_complete(struct xenvif_queue *queue,
			       struct xenvif_pkt_state *pkt)
{

Annotation

Implementation Notes