drivers/net/ethernet/broadcom/sb1250-mac.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/broadcom/sb1250-mac.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/broadcom/sb1250-mac.c
Extension
.c
Size
64460 bytes
Lines
2617
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 sbmac_netdev_ops = {
	.ndo_open		= sbmac_open,
	.ndo_stop		= sbmac_close,
	.ndo_start_xmit		= sbmac_start_tx,
	.ndo_set_rx_mode	= sbmac_set_rx_mode,
	.ndo_tx_timeout		= sbmac_tx_timeout,
	.ndo_eth_ioctl		= sbmac_mii_ioctl,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address	= eth_mac_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= sbmac_netpoll,
#endif
};

/**********************************************************************
 *  SBMAC_INIT(dev)
 *
 *  Attach routine - init hardware and hook ourselves into linux
 *
 *  Input parameters:
 *  	   dev - net_device structure
 *
 *  Return value:
 *  	   status
 ********************************************************************* */

static int sbmac_init(struct platform_device *pldev, long long base)
{
	struct net_device *dev = platform_get_drvdata(pldev);
	int idx = pldev->id;
	struct sbmac_softc *sc = netdev_priv(dev);
	unsigned char *eaddr;
	uint64_t ea_reg;
	int i;
	int err;

	sc->sbm_dev = dev;
	sc->sbe_idx = idx;

	eaddr = sc->sbm_hwaddr;

	/*
	 * Read the ethernet address.  The firmware left this programmed
	 * for us in the ethernet address register for each mac.
	 */

	ea_reg = __raw_readq(sc->sbm_base + R_MAC_ETHERNET_ADDR);
	__raw_writeq(0, sc->sbm_base + R_MAC_ETHERNET_ADDR);
	for (i = 0; i < 6; i++) {
		eaddr[i] = (uint8_t) (ea_reg & 0xFF);
		ea_reg >>= 8;
	}

	eth_hw_addr_set(dev, eaddr);

	/*
	 * Initialize context (get pointers to registers and stuff), then
	 * allocate the memory for the descriptor tables.
	 */

	sbmac_initctx(sc);

	/*
	 * Set up Linux device callins
	 */

	spin_lock_init(&(sc->sbm_lock));

	dev->netdev_ops = &sbmac_netdev_ops;
	dev->watchdog_timeo = TX_TIMEOUT;
	dev->min_mtu = 0;
	dev->max_mtu = ENET_PACKET_SIZE;

	netif_napi_add_weight(dev, &sc->napi, sbmac_poll, 16);

	dev->irq		= UNIT_INT(idx);

	/* This is needed for PASS2 for Rx H/W checksum feature */
	sbmac_set_iphdr_offset(sc);

	sc->mii_bus = mdiobus_alloc();
	if (sc->mii_bus == NULL) {
		err = -ENOMEM;
		goto uninit_ctx;
	}

	sc->mii_bus->name = sbmac_mdio_string;
	snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
		pldev->name, idx);
	sc->mii_bus->priv = sc;

Annotation

Implementation Notes