drivers/net/vmxnet3/vmxnet3_drv.c

Source file repositories/reference/linux-study-clean/drivers/net/vmxnet3/vmxnet3_drv.c

File Facts

System
Linux kernel
Corpus path
drivers/net/vmxnet3/vmxnet3_drv.c
Extension
.c
Size
126786 bytes
Lines
4617
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 vmxnet3_netdev_ops = {
		.ndo_open = vmxnet3_open,
		.ndo_stop = vmxnet3_close,
		.ndo_start_xmit = vmxnet3_xmit_frame,
		.ndo_set_mac_address = vmxnet3_set_mac_addr,
		.ndo_change_mtu = vmxnet3_change_mtu,
		.ndo_fix_features = vmxnet3_fix_features,
		.ndo_set_features = vmxnet3_set_features,
		.ndo_features_check = vmxnet3_features_check,
		.ndo_get_stats64 = vmxnet3_get_stats64,
		.ndo_tx_timeout = vmxnet3_tx_timeout,
		.ndo_set_rx_mode = vmxnet3_set_mc,
		.ndo_vlan_rx_add_vid = vmxnet3_vlan_rx_add_vid,
		.ndo_vlan_rx_kill_vid = vmxnet3_vlan_rx_kill_vid,
#ifdef CONFIG_NET_POLL_CONTROLLER
		.ndo_poll_controller = vmxnet3_netpoll,
#endif
		.ndo_bpf = vmxnet3_xdp,
		.ndo_xdp_xmit = vmxnet3_xdp_xmit,
	};
	int err;
	u32 ver;
	struct net_device *netdev;
	struct vmxnet3_adapter *adapter;
	u8 mac[ETH_ALEN];
	int size, i;
	int num_tx_queues;
	int num_rx_queues;
	int queues;
	unsigned long flags;

	if (!pci_msi_enabled())
		enable_mq = 0;

#ifdef VMXNET3_RSS
	if (enable_mq)
		num_rx_queues = min(VMXNET3_DEVICE_MAX_RX_QUEUES,
				    (int)num_online_cpus());
	else
#endif
		num_rx_queues = 1;

	if (enable_mq)
		num_tx_queues = min(VMXNET3_DEVICE_MAX_TX_QUEUES,
				    (int)num_online_cpus());
	else
		num_tx_queues = 1;

	netdev = alloc_etherdev_mq(sizeof(struct vmxnet3_adapter),
				   max(num_tx_queues, num_rx_queues));
	if (!netdev)
		return -ENOMEM;

	pci_set_drvdata(pdev, netdev);
	adapter = netdev_priv(netdev);
	adapter->netdev = netdev;
	adapter->pdev = pdev;

	adapter->tx_ring_size = VMXNET3_DEF_TX_RING_SIZE;
	adapter->rx_ring_size = VMXNET3_DEF_RX_RING_SIZE;
	adapter->rx_ring2_size = VMXNET3_DEF_RX_RING2_SIZE;

	err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
	if (err) {
		dev_err(&pdev->dev, "dma_set_mask failed\n");
		goto err_set_mask;
	}

	spin_lock_init(&adapter->cmd_lock);
	adapter->adapter_pa = dma_map_single(&adapter->pdev->dev, adapter,
					     sizeof(struct vmxnet3_adapter),
					     DMA_TO_DEVICE);
	if (dma_mapping_error(&adapter->pdev->dev, adapter->adapter_pa)) {
		dev_err(&pdev->dev, "Failed to map dma\n");
		err = -EFAULT;
		goto err_set_mask;
	}
	adapter->shared = dma_alloc_coherent(
				&adapter->pdev->dev,
				sizeof(struct Vmxnet3_DriverShared),
				&adapter->shared_pa, GFP_KERNEL);
	if (!adapter->shared) {
		dev_err(&pdev->dev, "Failed to allocate memory\n");
		err = -ENOMEM;
		goto err_alloc_shared;
	}

	err = vmxnet3_alloc_pci_resources(adapter);
	if (err < 0)
		goto err_alloc_pci;

Annotation

Implementation Notes