drivers/net/ethernet/dlink/sundance.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/dlink/sundance.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/dlink/sundance.c
Extension
.c
Size
58426 bytes
Lines
1991
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 netdev_ops = {
	.ndo_open		= netdev_open,
	.ndo_stop		= netdev_close,
	.ndo_start_xmit		= start_tx,
	.ndo_get_stats 		= get_stats,
	.ndo_set_rx_mode	= set_rx_mode,
	.ndo_eth_ioctl		= netdev_ioctl,
	.ndo_tx_timeout		= tx_timeout,
	.ndo_change_mtu		= change_mtu,
	.ndo_set_mac_address 	= sundance_set_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller 	= sundance_poll_controller,
#endif
};

static int sundance_probe1(struct pci_dev *pdev,
			   const struct pci_device_id *ent)
{
	struct net_device *dev;
	struct netdev_private *np;
	static int card_idx;
	int chip_idx = ent->driver_data;
	int irq;
	int i;
	void __iomem *ioaddr;
	u16 mii_ctl;
	void *ring_space;
	dma_addr_t ring_dma;
#ifdef USE_IO_OPS
	int bar = 0;
#else
	int bar = 1;
#endif
	int phy, phy_end, phy_idx = 0;
	__le16 addr[ETH_ALEN / 2];

	if (pci_enable_device(pdev))
		return -EIO;
	pci_set_master(pdev);

	irq = pdev->irq;

	dev = alloc_etherdev(sizeof(*np));
	if (!dev)
		return -ENOMEM;
	SET_NETDEV_DEV(dev, &pdev->dev);

	if (pci_request_regions(pdev, DRV_NAME))
		goto err_out_netdev;

	ioaddr = pci_iomap(pdev, bar, netdev_io_size);
	if (!ioaddr)
		goto err_out_res;

	for (i = 0; i < 3; i++)
		addr[i] =
			cpu_to_le16(eeprom_read(ioaddr, i + EEPROM_SA_OFFSET));
	eth_hw_addr_set(dev, (u8 *)addr);

	np = netdev_priv(dev);
	np->ndev = dev;
	np->base = ioaddr;
	np->pci_dev = pdev;
	np->chip_id = chip_idx;
	np->msg_enable = (1 << debug) - 1;
	spin_lock_init(&np->lock);
	spin_lock_init(&np->statlock);
	tasklet_setup(&np->rx_tasklet, rx_poll);
	tasklet_setup(&np->tx_tasklet, tx_poll);

	ring_space = dma_alloc_coherent(&pdev->dev, TX_TOTAL_SIZE,
			&ring_dma, GFP_KERNEL);
	if (!ring_space)
		goto err_out_cleardev;
	np->tx_ring = (struct netdev_desc *)ring_space;
	np->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;
	np->rx_ring = (struct netdev_desc *)ring_space;
	np->rx_ring_dma = ring_dma;

	np->mii_if.dev = dev;
	np->mii_if.mdio_read = mdio_read;
	np->mii_if.mdio_write = mdio_write;
	np->mii_if.phy_id_mask = 0x1f;
	np->mii_if.reg_num_mask = 0x1f;

Annotation

Implementation Notes