drivers/net/ethernet/smsc/epic100.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/smsc/epic100.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/smsc/epic100.c
Extension
.c
Size
44168 bytes
Lines
1562
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 epic_netdev_ops = {
	.ndo_open		= epic_open,
	.ndo_stop		= epic_close,
	.ndo_start_xmit		= epic_start_xmit,
	.ndo_tx_timeout 	= epic_tx_timeout,
	.ndo_get_stats		= epic_get_stats,
	.ndo_set_rx_mode	= set_rx_mode,
	.ndo_eth_ioctl		= netdev_ioctl,
	.ndo_set_mac_address 	= eth_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
};

static int epic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	static int card_idx = -1;
	void __iomem *ioaddr;
	int chip_idx = (int) ent->driver_data;
	struct net_device *dev;
	struct epic_private *ep;
	int i, ret, option = 0, duplex = 0;
	__le16 addr[ETH_ALEN / 2];
	void *ring_space;
	dma_addr_t ring_dma;

	card_idx++;

	ret = pci_enable_device(pdev);
	if (ret)
		goto out;

	if (pci_resource_len(pdev, 0) < EPIC_TOTAL_SIZE) {
		dev_err(&pdev->dev, "no PCI region space\n");
		ret = -ENODEV;
		goto err_out_disable;
	}

	pci_set_master(pdev);

	ret = pci_request_regions(pdev, DRV_NAME);
	if (ret < 0)
		goto err_out_disable;

	ret = -ENOMEM;

	dev = alloc_etherdev(sizeof (*ep));
	if (!dev)
		goto err_out_free_res;

	SET_NETDEV_DEV(dev, &pdev->dev);

	ioaddr = pci_iomap(pdev, EPIC_BAR, 0);
	if (!ioaddr) {
		dev_err(&pdev->dev, "ioremap failed\n");
		goto err_out_free_netdev;
	}

	pci_set_drvdata(pdev, dev);
	ep = netdev_priv(dev);
	ep->ioaddr = ioaddr;
	ep->mii.dev = dev;
	ep->mii.mdio_read = mdio_read;
	ep->mii.mdio_write = mdio_write;
	ep->mii.phy_id_mask = 0x1f;
	ep->mii.reg_num_mask = 0x1f;

	ring_space = dma_alloc_coherent(&pdev->dev, TX_TOTAL_SIZE, &ring_dma,
					GFP_KERNEL);
	if (!ring_space)
		goto err_out_iounmap;
	ep->tx_ring = ring_space;
	ep->tx_ring_dma = ring_dma;

	ring_space = dma_alloc_coherent(&pdev->dev, RX_TOTAL_SIZE, &ring_dma,
					GFP_KERNEL);
	if (!ring_space)
		goto err_out_unmap_tx;
	ep->rx_ring = ring_space;
	ep->rx_ring_dma = ring_dma;

	if (dev->mem_start) {
		option = dev->mem_start;
		duplex = (dev->mem_start & 16) ? 1 : 0;
	} else if (card_idx >= 0  &&  card_idx < MAX_UNITS) {
		if (options[card_idx] >= 0)
			option = options[card_idx];
		if (full_duplex[card_idx] >= 0)
			duplex = full_duplex[card_idx];
	}

	spin_lock_init(&ep->lock);

Annotation

Implementation Notes