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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/amd/xgbe/xgbe-drv.c
Extension
.c
Size
67996 bytes
Lines
2586
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct net_device_ops xgbe_netdev_ops = {
	.ndo_open		= xgbe_open,
	.ndo_stop		= xgbe_close,
	.ndo_start_xmit		= xgbe_xmit,
	.ndo_set_rx_mode	= xgbe_set_rx_mode,
	.ndo_set_mac_address	= xgbe_set_mac_address,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_change_mtu		= xgbe_change_mtu,
	.ndo_tx_timeout		= xgbe_tx_timeout,
	.ndo_get_stats64	= xgbe_get_stats64,
	.ndo_vlan_rx_add_vid	= xgbe_vlan_rx_add_vid,
	.ndo_vlan_rx_kill_vid	= xgbe_vlan_rx_kill_vid,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= xgbe_poll_controller,
#endif
	.ndo_setup_tc		= xgbe_setup_tc,
	.ndo_fix_features	= xgbe_fix_features,
	.ndo_set_features	= xgbe_set_features,
	.ndo_features_check	= xgbe_features_check,
	.ndo_hwtstamp_get	= xgbe_get_hwtstamp_settings,
	.ndo_hwtstamp_set	= xgbe_set_hwtstamp_settings,
};

const struct net_device_ops *xgbe_get_netdev_ops(void)
{
	return &xgbe_netdev_ops;
}

static void xgbe_rx_refresh(struct xgbe_channel *channel)
{
	struct xgbe_prv_data *pdata = channel->pdata;
	struct xgbe_hw_if *hw_if = &pdata->hw_if;
	struct xgbe_desc_if *desc_if = &pdata->desc_if;
	struct xgbe_ring *ring = channel->rx_ring;
	struct xgbe_ring_data *rdata;

	while (ring->dirty != ring->cur) {
		rdata = XGBE_GET_DESC_DATA(ring, ring->dirty);

		/* Reset rdata values */
		desc_if->unmap_rdata(pdata, rdata);

		if (desc_if->map_rx_buffer(pdata, ring, rdata))
			break;

		hw_if->rx_desc_reset(pdata, rdata, ring->dirty);

		ring->dirty++;
	}

	/* Make sure everything is written before the register write */
	wmb();

	/* Update the Rx Tail Pointer Register with address of
	 * the last cleaned entry */
	rdata = XGBE_GET_DESC_DATA(ring, ring->dirty - 1);
	XGMAC_DMA_IOWRITE(channel, DMA_CH_RDTR_LO,
			  lower_32_bits(rdata->rdesc_dma));
}

static struct sk_buff *xgbe_create_skb(struct xgbe_prv_data *pdata,
				       struct napi_struct *napi,
				       struct xgbe_ring_data *rdata,
				       unsigned int len)
{
	struct sk_buff *skb;
	u8 *packet;

	skb = napi_alloc_skb(napi, rdata->rx.hdr.dma_len);
	if (!skb)
		return NULL;

	/* Pull in the header buffer which may contain just the header
	 * or the header plus data
	 */
	dma_sync_single_range_for_cpu(pdata->dev, rdata->rx.hdr.dma_base,
				      rdata->rx.hdr.dma_off,
				      rdata->rx.hdr.dma_len, DMA_FROM_DEVICE);

	packet = page_address(rdata->rx.hdr.pa.pages) +
		 rdata->rx.hdr.pa.pages_offset;
	skb_copy_to_linear_data(skb, packet, len);
	skb_put(skb, len);

	return skb;
}

static unsigned int xgbe_rx_buf1_len(struct xgbe_ring_data *rdata,
				     struct xgbe_packet_data *packet)
{

Annotation

Implementation Notes