drivers/net/ethernet/dec/tulip/winbond-840.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/dec/tulip/winbond-840.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/dec/tulip/winbond-840.c
Extension
.c
Size
48243 bytes
Lines
1637
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_set_mac_address	= eth_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
};

static int w840_probe1(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	struct net_device *dev;
	struct netdev_private *np;
	static int find_cnt;
	int chip_idx = ent->driver_data;
	int irq;
	int i, option = find_cnt < MAX_UNITS ? options[find_cnt] : 0;
	__le16 addr[ETH_ALEN / 2];
	void __iomem *ioaddr;

	i = pcim_enable_device(pdev);
	if (i) return i;

	pci_set_master(pdev);

	irq = pdev->irq;

	if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
		pr_warn("Device %s disabled due to DMA limitations\n",
			pci_name(pdev));
		return -EIO;
	}
	dev = alloc_etherdev(sizeof(*np));
	if (!dev)
		return -ENOMEM;
	SET_NETDEV_DEV(dev, &pdev->dev);

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

	ioaddr = pci_iomap(pdev, TULIP_BAR, netdev_res_size);
	if (!ioaddr)
		goto err_out_netdev;

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

	/* Reset the chip to erase previous misconfiguration.
	   No hold time required! */
	iowrite32(0x00000001, ioaddr + PCIBusCfg);

	np = netdev_priv(dev);
	np->pci_dev = pdev;
	np->chip_id = chip_idx;
	np->drv_flags = pci_id_tbl[chip_idx].drv_flags;
	spin_lock_init(&np->lock);
	np->mii_if.dev = dev;
	np->mii_if.mdio_read = mdio_read;
	np->mii_if.mdio_write = mdio_write;
	np->base_addr = ioaddr;

	pci_set_drvdata(pdev, dev);

	if (dev->mem_start)
		option = dev->mem_start;

	/* The lower four bits are the media type. */
	if (option > 0) {
		if (option & 0x200)
			np->mii_if.full_duplex = 1;
		if (option & 15)
			dev_info(&dev->dev,
				 "ignoring user supplied media type %d",
				 option & 15);
	}
	if (find_cnt < MAX_UNITS  &&  full_duplex[find_cnt] > 0)
		np->mii_if.full_duplex = 1;

	if (np->mii_if.full_duplex)
		np->mii_if.force_media = 1;

	/* The chip-specific entries in the device structure. */
	dev->netdev_ops = &netdev_ops;
	dev->ethtool_ops = &netdev_ethtool_ops;
	dev->watchdog_timeo = TX_TIMEOUT;

Annotation

Implementation Notes