drivers/net/ethernet/sun/sunbmac.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/sun/sunbmac.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/sun/sunbmac.c
Extension
.c
Size
33479 bytes
Lines
1279
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 bigmac_ops = {
	.ndo_open		= bigmac_open,
	.ndo_stop		= bigmac_close,
	.ndo_start_xmit		= bigmac_start_xmit,
	.ndo_get_stats		= bigmac_get_stats,
	.ndo_set_rx_mode	= bigmac_set_multicast,
	.ndo_tx_timeout		= bigmac_tx_timeout,
	.ndo_set_mac_address	= eth_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
};

static int bigmac_ether_init(struct platform_device *op,
			     struct platform_device *qec_op)
{
	static int version_printed;
	struct net_device *dev;
	u8 bsizes, bsizes_more;
	struct bigmac *bp;

	/* Get a new device struct for this interface. */
	dev = alloc_etherdev(sizeof(struct bigmac));
	if (!dev)
		return -ENOMEM;

	if (version_printed++ == 0)
		printk(KERN_INFO "%s", version);

	eth_hw_addr_set(dev, idprom->id_ethaddr);

	/* Setup softc, with backpointers to QEC and BigMAC SBUS device structs. */
	bp = netdev_priv(dev);
	bp->qec_op = qec_op;
	bp->bigmac_op = op;

	SET_NETDEV_DEV(dev, &op->dev);

	spin_lock_init(&bp->lock);

	/* Map in QEC global control registers. */
	bp->gregs = of_ioremap(&qec_op->resource[0], 0,
			       GLOB_REG_SIZE, "BigMAC QEC GLobal Regs");
	if (!bp->gregs) {
		printk(KERN_ERR "BIGMAC: Cannot map QEC global registers.\n");
		goto fail_and_cleanup;
	}

	/* Make sure QEC is in BigMAC mode. */
	if ((sbus_readl(bp->gregs + GLOB_CTRL) & 0xf0000000) != GLOB_CTRL_BMODE) {
		printk(KERN_ERR "BigMAC: AIEEE, QEC is not in BigMAC mode!\n");
		goto fail_and_cleanup;
	}

	/* Reset the QEC. */
	if (qec_global_reset(bp->gregs))
		goto fail_and_cleanup;

	/* Get supported SBUS burst sizes. */
	bsizes = of_getintprop_default(qec_op->dev.of_node, "burst-sizes", 0xff);
	bsizes_more = of_getintprop_default(qec_op->dev.of_node, "burst-sizes", 0xff);

	bsizes &= 0xff;
	if (bsizes_more != 0xff)
		bsizes &= bsizes_more;
	if (bsizes == 0xff || (bsizes & DMA_BURST16) == 0 ||
	    (bsizes & DMA_BURST32) == 0)
		bsizes = (DMA_BURST32 - 1);
	bp->bigmac_bursts = bsizes;

	/* Perform QEC initialization. */
	qec_init(bp);

	/* Map in the BigMAC channel registers. */
	bp->creg = of_ioremap(&op->resource[0], 0,
			      CREG_REG_SIZE, "BigMAC QEC Channel Regs");
	if (!bp->creg) {
		printk(KERN_ERR "BIGMAC: Cannot map QEC channel registers.\n");
		goto fail_and_cleanup;
	}

	/* Map in the BigMAC control registers. */
	bp->bregs = of_ioremap(&op->resource[1], 0,
			       BMAC_REG_SIZE, "BigMAC Primary Regs");
	if (!bp->bregs) {
		printk(KERN_ERR "BIGMAC: Cannot map BigMAC primary registers.\n");
		goto fail_and_cleanup;
	}

	/* Map in the BigMAC transceiver registers, this is how you poke at
	 * the BigMAC's PHY.
	 */

Annotation

Implementation Notes