drivers/net/ethernet/dec/tulip/de2104x.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/dec/tulip/de2104x.c
Extension
.c
Size
54346 bytes
Lines
2196
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 de_netdev_ops = {
	.ndo_open		= de_open,
	.ndo_stop		= de_close,
	.ndo_set_rx_mode	= de_set_rx_mode,
	.ndo_start_xmit		= de_start_xmit,
	.ndo_get_stats		= de_get_stats,
	.ndo_tx_timeout 	= de_tx_timeout,
	.ndo_set_mac_address 	= eth_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
};

static int de_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	struct net_device *dev;
	struct de_private *de;
	int rc;
	void __iomem *regs;
	unsigned long pciaddr;
	static int board_idx = -1;

	board_idx++;

	/* allocate a new ethernet device structure, and fill in defaults */
	dev = alloc_etherdev(sizeof(struct de_private));
	if (!dev)
		return -ENOMEM;

	dev->netdev_ops = &de_netdev_ops;
	SET_NETDEV_DEV(dev, &pdev->dev);
	dev->ethtool_ops = &de_ethtool_ops;
	dev->watchdog_timeo = TX_TIMEOUT;

	de = netdev_priv(dev);
	de->de21040 = ent->driver_data == 0 ? 1 : 0;
	de->pdev = pdev;
	de->dev = dev;
	de->msg_enable = (debug < 0 ? DE_DEF_MSG_ENABLE : debug);
	de->board_idx = board_idx;
	spin_lock_init (&de->lock);
	timer_setup(&de->media_timer,
		    de->de21040 ? de21040_media_timer : de21041_media_timer,
		    0);

	netif_carrier_off(dev);

	/* wake up device, assign resources */
	rc = pci_enable_device(pdev);
	if (rc)
		goto err_out_free;

	/* reserve PCI resources to ensure driver atomicity */
	rc = pci_request_regions(pdev, DRV_NAME);
	if (rc)
		goto err_out_disable;

	/* check for invalid IRQ value */
	if (pdev->irq < 2) {
		rc = -EIO;
		pr_err("invalid irq (%d) for pci dev %s\n",
		       pdev->irq, pci_name(pdev));
		goto err_out_res;
	}

	/* obtain and check validity of PCI I/O address */
	pciaddr = pci_resource_start(pdev, 1);
	if (!pciaddr) {
		rc = -EIO;
		pr_err("no MMIO resource for pci dev %s\n", pci_name(pdev));
		goto err_out_res;
	}
	if (pci_resource_len(pdev, 1) < DE_REGS_SIZE) {
		rc = -EIO;
		pr_err("MMIO resource (%llx) too small on pci dev %s\n",
		       (unsigned long long)pci_resource_len(pdev, 1),
		       pci_name(pdev));
		goto err_out_res;
	}

	/* remap CSR registers */
	regs = ioremap(pciaddr, DE_REGS_SIZE);
	if (!regs) {
		rc = -EIO;
		pr_err("Cannot map PCI MMIO (%llx@%lx) on pci dev %s\n",
		       (unsigned long long)pci_resource_len(pdev, 1),
		       pciaddr, pci_name(pdev));
		goto err_out_res;
	}
	de->regs = regs;

	de_adapter_wake(de);

Annotation

Implementation Notes