drivers/net/ethernet/i825xx/82596.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/i825xx/82596.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/i825xx/82596.c
Extension
.c
Size
39224 bytes
Lines
1537
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 i596_netdev_ops = {
	.ndo_open 		= i596_open,
	.ndo_stop		= i596_close,
	.ndo_start_xmit		= i596_start_xmit,
	.ndo_set_rx_mode	= set_multicast_list,
	.ndo_tx_timeout		= i596_tx_timeout,
	.ndo_set_mac_address 	= eth_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
};

static struct net_device * __init i82596_probe(void)
{
	struct net_device *dev;
	int i;
	struct i596_private *lp;
	char eth_addr[8];
	static int probed;
	int err;

	if (probed)
		return ERR_PTR(-ENODEV);
	probed++;

	dev = alloc_etherdev(0);
	if (!dev)
		return ERR_PTR(-ENOMEM);

#ifdef ENABLE_MVME16x_NET
	if (MACH_IS_MVME16x) {
		if (mvme16x_config & MVME16x_CONFIG_NO_ETHERNET) {
			printk(KERN_NOTICE "Ethernet probe disabled - chip not present\n");
			err = -ENODEV;
			goto out;
		}
		memcpy(eth_addr, absolute_pointer(0xfffc1f2c), ETH_ALEN); /* YUCK! Get addr from NOVRAM */
		dev->base_addr = MVME_I596_BASE;
		dev->irq = (unsigned) MVME16x_IRQ_I596;
		goto found;
	}
#endif
#ifdef ENABLE_BVME6000_NET
	if (MACH_IS_BVME6000) {
		volatile unsigned char *rtc = (unsigned char *) BVME_RTC_BASE;
		unsigned char msr = rtc[3];
		int i;

		rtc[3] |= 0x80;
		for (i = 0; i < 6; i++)
			eth_addr[i] = rtc[i * 4 + 7];	/* Stored in RTC RAM at offset 1 */
		rtc[3] = msr;
		dev->base_addr = BVME_I596_BASE;
		dev->irq = (unsigned) BVME_IRQ_I596;
		goto found;
	}
#endif
	err = -ENODEV;
	goto out;

found:
	dev->mem_start = (int)__get_free_pages(GFP_ATOMIC, 0);
	if (!dev->mem_start) {
		err = -ENOMEM;
		goto out1;
	}

	DEB(DEB_PROBE,printk(KERN_INFO "%s: 82596 at %#3lx,", dev->name, dev->base_addr));

	for (i = 0; i < 6; i++)
		DEB(DEB_PROBE,printk(" %2.2X", eth_addr[i]));
	eth_hw_addr_set(dev, eth_addr);

	DEB(DEB_PROBE,printk(" IRQ %d.\n", dev->irq));

	DEB(DEB_PROBE,printk(KERN_INFO "%s", version));

	/* The 82596-specific entries in the device structure. */
	dev->netdev_ops = &i596_netdev_ops;
	dev->watchdog_timeo = TX_TIMEOUT;

	dev->ml_priv = (void *)(dev->mem_start);

	lp = dev->ml_priv;
	DEB(DEB_INIT,printk(KERN_DEBUG "%s: lp at 0x%08lx (%zd bytes), "
			"lp->scb at 0x%08lx\n",
			dev->name, (unsigned long)lp,
			sizeof(struct i596_private), (unsigned long)&lp->scb));
	memset((void *) lp, 0, sizeof(struct i596_private));

#ifdef __mc68000__
	cache_push(virt_to_phys((void *)(dev->mem_start)), 4096);

Annotation

Implementation Notes