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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/amd/xgbe/xgbe-desc.c
Extension
.c
Size
13677 bytes
Lines
573
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

if (ret) {
			netdev_alert(pdata->netdev,
				     "error initializing Tx ring\n");
			goto err_ring;
		}

		netif_dbg(pdata, drv, pdata->netdev, "%s - Rx ring:\n",
			  channel->name);

		ret = xgbe_init_ring(pdata, channel->rx_ring,
				     pdata->rx_desc_count);
		if (ret) {
			netdev_alert(pdata->netdev,
				     "error initializing Rx ring\n");
			goto err_ring;
		}
	}

	return 0;

err_ring:
	xgbe_free_ring_resources(pdata);

	return ret;
}

static int xgbe_alloc_pages(struct xgbe_prv_data *pdata,
			    struct xgbe_page_alloc *pa, int alloc_order,
			    int node)
{
	struct page *pages = NULL;
	dma_addr_t pages_dma;
	gfp_t gfp;
	int order;

again:
	order = alloc_order;

	/* Try to obtain pages, decreasing order if necessary */
	gfp = GFP_ATOMIC | __GFP_COMP | __GFP_NOWARN;
	while (order >= 0) {
		pages = alloc_pages_node(node, gfp, order);
		if (pages)
			break;

		order--;
	}

	/* If we couldn't get local pages, try getting from anywhere */
	if (!pages && (node != NUMA_NO_NODE)) {
		node = NUMA_NO_NODE;
		goto again;
	}

	if (!pages)
		return -ENOMEM;

	/* Map the pages */
	pages_dma = dma_map_page(pdata->dev, pages, 0,
				 PAGE_SIZE << order, DMA_FROM_DEVICE);
	if (dma_mapping_error(pdata->dev, pages_dma)) {
		put_page(pages);
		return -ENOMEM;
	}

	pa->pages = pages;
	pa->pages_len = PAGE_SIZE << order;
	pa->pages_offset = 0;
	pa->pages_dma = pages_dma;

	return 0;
}

static void xgbe_set_buffer_data(struct xgbe_buffer_data *bd,
				 struct xgbe_page_alloc *pa,
				 unsigned int len)
{
	get_page(pa->pages);
	bd->pa = *pa;

	bd->dma_base = pa->pages_dma;
	bd->dma_off = pa->pages_offset;
	bd->dma_len = len;

	pa->pages_offset += len;
	if ((pa->pages_offset + len) > pa->pages_len) {
		/* This data descriptor is responsible for unmapping page(s) */
		bd->pa_unmap = *pa;

		/* Get a new allocation next time */

Annotation

Implementation Notes