drivers/net/ethernet/8390/zorro8390.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/8390/zorro8390.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/8390/zorro8390.c
Extension
.c
Size
12718 bytes
Lines
448
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 zorro8390_netdev_ops = {
	.ndo_open		= zorro8390_open,
	.ndo_stop		= zorro8390_close,
	.ndo_start_xmit		= __ei_start_xmit,
	.ndo_tx_timeout		= __ei_tx_timeout,
	.ndo_get_stats		= __ei_get_stats,
	.ndo_set_rx_mode	= __ei_set_multicast_list,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address	= eth_mac_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= __ei_poll,
#endif
};

static int zorro8390_init(struct net_device *dev, unsigned long board,
			  const char *name, void __iomem *ioaddr)
{
	int i;
	int err;
	unsigned char SA_prom[32];
	int start_page, stop_page;
	static u32 zorro8390_offsets[16] = {
		0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
		0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
	};

	/* Reset card. Who knows what dain-bramaged state it was left in. */
	{
		unsigned long reset_start_time = jiffies;

		z_writeb(z_readb(ioaddr + NE_RESET), ioaddr + NE_RESET);

		while ((z_readb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0)
			if (time_after(jiffies,
				       reset_start_time + 2 * HZ / 100)) {
				netdev_warn(dev, "not found (no reset ack)\n");
				return -ENODEV;
			}

		z_writeb(0xff, ioaddr + NE_EN0_ISR);	/* Ack all intr. */
	}

	/* Read the 16 bytes of station address PROM.
	 * We must first initialize registers,
	 * similar to NS8390_init(eifdev, 0).
	 * We can't reliably read the SAPROM address without this.
	 * (I learned the hard way!).
	 */
	{
		static const struct {
			u32 value;
			u32 offset;
		} program_seq[] = {
			{E8390_NODMA + E8390_PAGE0 + E8390_STOP, NE_CMD},
						/* Select page 0 */
			{0x48,	NE_EN0_DCFG},	/* 0x48: Set byte-wide access */
			{0x00,	NE_EN0_RCNTLO},	/* Clear the count regs */
			{0x00,	NE_EN0_RCNTHI},
			{0x00,	NE_EN0_IMR},	/* Mask completion irq */
			{0xFF,	NE_EN0_ISR},
			{E8390_RXOFF, NE_EN0_RXCR}, /* 0x20 Set to monitor */
			{E8390_TXOFF, NE_EN0_TXCR}, /* 0x02 and loopback mode */
			{32,	NE_EN0_RCNTLO},
			{0x00,	NE_EN0_RCNTHI},
			{0x00,	NE_EN0_RSARLO},	/* DMA starting at 0x0000 */
			{0x00,	NE_EN0_RSARHI},
			{E8390_RREAD + E8390_START, NE_CMD},
		};
		for (i = 0; i < ARRAY_SIZE(program_seq); i++)
			z_writeb(program_seq[i].value,
				 ioaddr + program_seq[i].offset);
	}
	for (i = 0; i < 16; i++) {
		SA_prom[i] = z_readb(ioaddr + NE_DATAPORT);
		(void)z_readb(ioaddr + NE_DATAPORT);
	}

	/* We must set the 8390 for word mode. */
	z_writeb(0x49, ioaddr + NE_EN0_DCFG);
	start_page = NESM_START_PG;
	stop_page = NESM_STOP_PG;

	dev->base_addr = (unsigned long)ioaddr;
	dev->irq = IRQ_AMIGA_PORTS;

	/* Install the Interrupt handler */
	i = request_irq(IRQ_AMIGA_PORTS, __ei_interrupt,
			IRQF_SHARED, DRV_NAME, dev);
	if (i)
		return i;

Annotation

Implementation Notes