drivers/net/ethernet/amd/xgbe/xgbe-selftest.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/amd/xgbe/xgbe-selftest.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/amd/xgbe/xgbe-selftest.c
Extension
.c
Size
7415 bytes
Lines
347
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 xgbe_test {
	char name[ETH_GSTRING_LEN];
	int lb;
	int (*fn)(struct xgbe_prv_data *pdata);
};

static u8 xgbe_test_id;

static int xgbe_test_loopback_validate(struct sk_buff *skb,
				       struct net_device *ndev,
				       struct packet_type *pt,
				       struct net_device *orig_ndev)
{
	struct net_test_priv *tdata = pt->af_packet_priv;
	const unsigned char *dst = tdata->packet->dst;
	const unsigned char *src = tdata->packet->src;
	struct netsfhdr *hdr;
	struct ethhdr *eh;
	struct tcphdr *th;
	struct udphdr *uh;
	struct iphdr *ih;
	int eat;

	skb = skb_unshare(skb, GFP_ATOMIC);
	if (!skb)
		goto out;

	eat = (skb->tail + skb->data_len) - skb->end;
	if (eat > 0 && skb_shared(skb)) {
		skb = skb_share_check(skb, GFP_ATOMIC);
		if (!skb)
			goto out;
	}

	if (skb_linearize(skb))
		goto out;

	if (skb_headlen(skb) < (NET_TEST_PKT_SIZE - ETH_HLEN))
		goto out;

	eh = (struct ethhdr *)skb_mac_header(skb);
	if (dst) {
		if (!ether_addr_equal_unaligned(eh->h_dest, dst))
			goto out;
	}
	if (src) {
		if (!ether_addr_equal_unaligned(eh->h_source, src))
			goto out;
	}

	ih = ip_hdr(skb);

	if (tdata->packet->tcp) {
		if (ih->protocol != IPPROTO_TCP)
			goto out;

		th = (struct tcphdr *)((u8 *)ih + 4 * ih->ihl);
		if (th->dest != htons(tdata->packet->dport))
			goto out;

		hdr = (struct netsfhdr *)((u8 *)th + sizeof(*th));
	} else {
		if (ih->protocol != IPPROTO_UDP)
			goto out;

		uh = (struct udphdr *)((u8 *)ih + 4 * ih->ihl);
		if (uh->dest != htons(tdata->packet->dport))
			goto out;

		hdr = (struct netsfhdr *)((u8 *)uh + sizeof(*uh));
	}

	if (hdr->magic != cpu_to_be64(NET_TEST_PKT_MAGIC))
		goto out;
	if (tdata->packet->id != hdr->id)
		goto out;

	tdata->ok = true;
	complete(&tdata->comp);
out:
	kfree_skb(skb);
	return 0;
}

static int __xgbe_test_loopback(struct xgbe_prv_data *pdata,
				struct net_packet_attrs *attr)
{
	struct net_test_priv *tdata;
	struct sk_buff *skb = NULL;
	int ret = 0;

Annotation

Implementation Notes