drivers/net/ethernet/amd/sunlance.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/amd/sunlance.c
Extension
.c
Size
40355 bytes
Lines
1521
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 sparc_lance_ops = {
	.ndo_open		= lance_open,
	.ndo_stop		= lance_close,
	.ndo_start_xmit		= lance_start_xmit,
	.ndo_set_rx_mode	= lance_set_multicast,
	.ndo_tx_timeout		= lance_tx_timeout,
	.ndo_set_mac_address	= eth_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
};

static int sparc_lance_probe_one(struct platform_device *op,
				 struct platform_device *ledma,
				 struct platform_device *lebuffer)
{
	struct device_node *dp = op->dev.of_node;
	struct lance_private *lp;
	struct net_device *dev;

	dev = alloc_etherdev(sizeof(struct lance_private) + 8);
	if (!dev)
		return -ENOMEM;

	lp = netdev_priv(dev);

	spin_lock_init(&lp->lock);

	/* Copy the IDPROM ethernet address to the device structure, later we
	 * will copy the address in the device structure to the lance
	 * initialization block.
	 */
	eth_hw_addr_set(dev, idprom->id_ethaddr);

	/* Get the IO region */
	lp->lregs = of_ioremap(&op->resource[0], 0,
			       LANCE_REG_SIZE, lancestr);
	if (!lp->lregs) {
		printk(KERN_ERR "SunLance: Cannot map registers.\n");
		goto fail;
	}

	lp->ledma = ledma;
	if (lp->ledma) {
		lp->dregs = of_ioremap(&ledma->resource[0], 0,
				       resource_size(&ledma->resource[0]),
				       "ledma");
		if (!lp->dregs) {
			printk(KERN_ERR "SunLance: Cannot map "
			       "ledma registers.\n");
			goto fail;
		}
	}

	lp->op = op;
	lp->lebuffer = lebuffer;
	if (lebuffer) {
		/* sanity check */
		if (lebuffer->resource[0].start & 7) {
			printk(KERN_ERR "SunLance: ERROR: Rx and Tx rings not on even boundary.\n");
			goto fail;
		}
		lp->init_block_iomem =
			of_ioremap(&lebuffer->resource[0], 0,
				   sizeof(struct lance_init_block), "lebuffer");
		if (!lp->init_block_iomem) {
			printk(KERN_ERR "SunLance: Cannot map PIO buffer.\n");
			goto fail;
		}
		lp->init_block_dvma = 0;
		lp->pio_buffer = 1;
		lp->init_ring = lance_init_ring_pio;
		lp->rx = lance_rx_pio;
		lp->tx = lance_tx_pio;
	} else {
		lp->init_block_mem =
			dma_alloc_coherent(&op->dev,
					   sizeof(struct lance_init_block),
					   &lp->init_block_dvma, GFP_ATOMIC);
		if (!lp->init_block_mem)
			goto fail;

		lp->pio_buffer = 0;
		lp->init_ring = lance_init_ring_dvma;
		lp->rx = lance_rx_dvma;
		lp->tx = lance_tx_dvma;
	}
	lp->busmaster_regval = of_getintprop_default(dp,  "busmaster-regval",
						     (LE_C3_BSWP |
						      LE_C3_ACON |
						      LE_C3_BCON));

Annotation

Implementation Notes