drivers/net/ethernet/amd/sun3lance.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/amd/sun3lance.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/amd/sun3lance.c
Extension
.c
Size
25907 bytes
Lines
940
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 lance_netdev_ops = {
	.ndo_open		= lance_open,
	.ndo_stop		= lance_close,
	.ndo_start_xmit		= lance_start_xmit,
	.ndo_set_rx_mode	= set_multicast_list,
	.ndo_set_mac_address	= NULL,
	.ndo_validate_addr	= eth_validate_addr,
};

static int __init lance_probe( struct net_device *dev)
{
	unsigned long ioaddr;

	struct lance_private	*lp;
	static int 		did_version;
	volatile unsigned short *ioaddr_probe;
	unsigned short tmp1, tmp2;

#ifdef CONFIG_SUN3
	ioaddr = (unsigned long)ioremap(LANCE_OBIO, PAGE_SIZE);
	if (!ioaddr)
		return 0;
#else
	ioaddr = SUN3X_LANCE;
#endif

	/* test to see if there's really a lance here */
	/* (CSRO_INIT shouldn't be readable) */

	ioaddr_probe = (volatile unsigned short *)ioaddr;
	tmp1 = ioaddr_probe[0];
	tmp2 = ioaddr_probe[1];

	ioaddr_probe[1] = CSR0;
	ioaddr_probe[0] = CSR0_INIT | CSR0_STOP;

	if(ioaddr_probe[0] != CSR0_STOP) {
		ioaddr_probe[0] = tmp1;
		ioaddr_probe[1] = tmp2;

#ifdef CONFIG_SUN3
		iounmap((void __iomem *)ioaddr);
#endif
		return 0;
	}

	lp = netdev_priv(dev);

	/* XXX - leak? */
	MEM = dvma_malloc_align(sizeof(struct lance_memory), 0x10000);
	if (!MEM) {
#ifdef CONFIG_SUN3
		iounmap((void __iomem *)ioaddr);
#endif
		printk(KERN_WARNING "SUN3 Lance couldn't allocate DVMA memory\n");
		return 0;
	}

	lp->iobase = (volatile unsigned short *)ioaddr;
	dev->base_addr = (unsigned long)ioaddr; /* informational only */

	REGA(CSR0) = CSR0_STOP;

	if (request_irq(LANCE_IRQ, lance_interrupt, 0, "SUN3 Lance", dev) < 0) {
#ifdef CONFIG_SUN3
		iounmap((void __iomem *)ioaddr);
#endif
		dvma_free((void *)MEM);
		printk(KERN_WARNING "SUN3 Lance unable to allocate IRQ\n");
		return 0;
	}
	dev->irq = (unsigned short)LANCE_IRQ;


	printk("%s: SUN3 Lance at io %#lx, mem %#lx, irq %d, hwaddr ",
		   dev->name,
		   (unsigned long)ioaddr,
		   (unsigned long)MEM,
		   dev->irq);

	/* copy in the ethernet address from the prom */
	eth_hw_addr_set(dev, idprom->id_ethaddr);

	/* tell the card it's ether address, bytes swapped */
	MEM->init.hwaddr[0] = dev->dev_addr[1];
	MEM->init.hwaddr[1] = dev->dev_addr[0];
	MEM->init.hwaddr[2] = dev->dev_addr[3];
	MEM->init.hwaddr[3] = dev->dev_addr[2];
	MEM->init.hwaddr[4] = dev->dev_addr[5];
	MEM->init.hwaddr[5] = dev->dev_addr[4];

Annotation

Implementation Notes