drivers/net/ethernet/amd/mvme147.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/amd/mvme147.c
Extension
.c
Size
5837 bytes
Lines
199
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		= m147lance_open,
	.ndo_stop		= m147lance_close,
	.ndo_start_xmit		= lance_start_xmit,
	.ndo_set_rx_mode	= lance_set_multicast,
	.ndo_tx_timeout		= lance_tx_timeout,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address	= eth_mac_addr,
};

/* Initialise the one and only on-board 7990 */
static struct net_device * __init mvme147lance_probe(void)
{
	struct net_device *dev;
	static int called;
	static const char name[] = "MVME147 LANCE";
	struct m147lance_private *lp;
	u8 macaddr[ETH_ALEN];
	u_long *addr;
	u_long address;
	int err;

	if (!MACH_IS_MVME147 || called)
		return ERR_PTR(-ENODEV);
	called++;

	dev = alloc_etherdev(sizeof(struct m147lance_private));
	if (!dev)
		return ERR_PTR(-ENOMEM);

	/* Fill the dev fields */
	dev->base_addr = (unsigned long)MVME147_LANCE_BASE;
	dev->netdev_ops = &lance_netdev_ops;
	dev->dma = 0;

	addr = (u_long *)ETHERNET_ADDRESS;
	address = *addr;
	macaddr[0] = 0x08;
	macaddr[1] = 0x00;
	macaddr[2] = 0x3e;
	address = address >> 8;
	macaddr[5] = address&0xff;
	address = address >> 8;
	macaddr[4] = address&0xff;
	address = address >> 8;
	macaddr[3] = address&0xff;
	eth_hw_addr_set(dev, macaddr);

	lp = netdev_priv(dev);
	lp->ram = __get_dma_pages(GFP_ATOMIC, 3);	/* 32K */
	if (!lp->ram) {
		printk("%s: No memory for LANCE buffers\n", dev->name);
		free_netdev(dev);
		return ERR_PTR(-ENOMEM);
	}

	lp->lance.name = name;
	lp->lance.base = dev->base_addr;
	lp->lance.init_block = (struct lance_init_block *)(lp->ram); /* CPU addr */
	lp->lance.lance_init_block = (struct lance_init_block *)(lp->ram);                 /* LANCE addr of same RAM */
	lp->lance.busmaster_regval = LE_C3_BSWP;        /* we're bigendian */
	lp->lance.irq = MVME147_LANCE_IRQ;
	lp->lance.writerap = (writerap_t)m147lance_writerap;
	lp->lance.writerdp = (writerdp_t)m147lance_writerdp;
	lp->lance.readrdp = (readrdp_t)m147lance_readrdp;
	lp->lance.lance_log_rx_bufs = LANCE_LOG_RX_BUFFERS;
	lp->lance.lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS;
	lp->lance.rx_ring_mod_mask = RX_RING_MOD_MASK;
	lp->lance.tx_ring_mod_mask = TX_RING_MOD_MASK;

	err = register_netdev(dev);
	if (err) {
		free_pages(lp->ram, 3);
		free_netdev(dev);
		return ERR_PTR(err);
	}

	netdev_info(dev, "MVME147 at 0x%08lx, irq %d, Hardware Address %pM\n",
		    dev->base_addr, MVME147_LANCE_IRQ, dev->dev_addr);

	return dev;
}

static void m147lance_writerap(struct lance_private *lp, unsigned short value)
{
	out_be16(lp->base + LANCE_RAP, value);
}

static void m147lance_writerdp(struct lance_private *lp, unsigned short value)
{

Annotation

Implementation Notes