drivers/net/xen-netfront.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/xen-netfront.c
Extension
.c
Size
68833 bytes
Lines
2721
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 xennet_netdev_ops = {
	.ndo_uninit          = xennet_uninit,
	.ndo_open            = xennet_open,
	.ndo_stop            = xennet_close,
	.ndo_start_xmit      = xennet_start_xmit,
	.ndo_change_mtu	     = xennet_change_mtu,
	.ndo_get_stats64     = xennet_get_stats64,
	.ndo_set_mac_address = eth_mac_addr,
	.ndo_validate_addr   = eth_validate_addr,
	.ndo_fix_features    = xennet_fix_features,
	.ndo_set_features    = xennet_set_features,
	.ndo_select_queue    = xennet_select_queue,
	.ndo_bpf            = xennet_xdp,
	.ndo_xdp_xmit	    = xennet_xdp_xmit,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller = xennet_poll_controller,
#endif
};

static void xennet_free_netdev(struct net_device *netdev)
{
	struct netfront_info *np = netdev_priv(netdev);

	free_percpu(np->rx_stats);
	free_percpu(np->tx_stats);
	free_netdev(netdev);
}

static struct net_device *xennet_create_dev(struct xenbus_device *dev)
{
	int err;
	struct net_device *netdev;
	struct netfront_info *np;

	netdev = alloc_etherdev_mq(sizeof(struct netfront_info), xennet_max_queues);
	if (!netdev)
		return ERR_PTR(-ENOMEM);

	np                   = netdev_priv(netdev);
	np->xbdev            = dev;

	np->queues = NULL;

	err = -ENOMEM;
	np->rx_stats = netdev_alloc_pcpu_stats(struct netfront_stats);
	if (np->rx_stats == NULL)
		goto exit;
	np->tx_stats = netdev_alloc_pcpu_stats(struct netfront_stats);
	if (np->tx_stats == NULL)
		goto exit;

	netdev->netdev_ops	= &xennet_netdev_ops;

	netdev->features        = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
				  NETIF_F_GSO_ROBUST;
	netdev->hw_features	= NETIF_F_SG |
				  NETIF_F_IPV6_CSUM |
				  NETIF_F_TSO | NETIF_F_TSO6;

	/*
         * Assume that all hw features are available for now. This set
         * will be adjusted by the call to netdev_update_features() in
         * xennet_connect() which is the earliest point where we can
         * negotiate with the backend regarding supported features.
         */
	netdev->features |= netdev->hw_features;
	netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
			       NETDEV_XDP_ACT_NDO_XMIT;

	netdev->ethtool_ops = &xennet_ethtool_ops;
	netdev->min_mtu = ETH_MIN_MTU;
	netdev->max_mtu = XEN_NETIF_MAX_TX_SIZE;
	SET_NETDEV_DEV(netdev, &dev->dev);

	np->netdev = netdev;
	np->netfront_xdp_enabled = false;

	netif_carrier_off(netdev);

	do {
		xenbus_switch_state(dev, XenbusStateInitialising);
		err = wait_event_timeout(module_wq,
				 xenbus_read_driver_state(dev, dev->otherend) !=
				 XenbusStateClosed &&
				 xenbus_read_driver_state(dev, dev->otherend) !=
				 XenbusStateUnknown, XENNET_TIMEOUT);
	} while (!err);

	return netdev;

Annotation

Implementation Notes