drivers/net/ethernet/apple/macmace.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/apple/macmace.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/apple/macmace.c
Extension
.c
Size
17931 bytes
Lines
769
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 mace_netdev_ops = {
	.ndo_open		= mace_open,
	.ndo_stop		= mace_close,
	.ndo_start_xmit		= mace_xmit_start,
	.ndo_tx_timeout		= mace_tx_timeout,
	.ndo_set_rx_mode	= mace_set_multicast,
	.ndo_set_mac_address	= mace_set_address,
	.ndo_validate_addr	= eth_validate_addr,
};

/*
 * Not really much of a probe. The hardware table tells us if this
 * model of Macintrash has a MACE (AV macintoshes)
 */

static int mace_probe(struct platform_device *pdev)
{
	int j;
	struct mace_data *mp;
	unsigned char *addr;
	struct net_device *dev;
	unsigned char checksum = 0;
	u8 macaddr[ETH_ALEN];
	int err;

	dev = alloc_etherdev(PRIV_BYTES);
	if (!dev)
		return -ENOMEM;

	mp = netdev_priv(dev);

	mp->device = &pdev->dev;
	platform_set_drvdata(pdev, dev);
	SET_NETDEV_DEV(dev, &pdev->dev);

	dev->base_addr = (u32)MACE_BASE;
	mp->mace = MACE_BASE;

	dev->irq = IRQ_MAC_MACE;
	mp->dma_intr = IRQ_MAC_MACE_DMA;

	mp->chipid = mp->mace->chipid_hi << 8 | mp->mace->chipid_lo;

	/*
	 * The PROM contains 8 bytes which total 0xFF when XOR'd
	 * together. Due to the usual peculiar apple brain damage
	 * the bytes are spaced out in a strange boundary and the
	 * bits are reversed.
	 */

	addr = MACE_PROM;

	for (j = 0; j < 6; ++j) {
		u8 v = bitrev8(addr[j<<4]);
		checksum ^= v;
		macaddr[j] = v;
	}
	eth_hw_addr_set(dev, macaddr);
	for (; j < 8; ++j) {
		checksum ^= bitrev8(addr[j<<4]);
	}

	if (checksum != 0xFF) {
		free_netdev(dev);
		return -ENODEV;
	}

	dev->netdev_ops		= &mace_netdev_ops;
	dev->watchdog_timeo	= TX_TIMEOUT;

	pr_info("Onboard MACE, hardware address %pM, chip revision 0x%04X\n",
		dev->dev_addr, mp->chipid);

	err = register_netdev(dev);
	if (!err)
		return 0;

	free_netdev(dev);
	return err;
}

/*
 * Reset the chip.
 */

static void mace_reset(struct net_device *dev)
{
	struct mace_data *mp = netdev_priv(dev);
	volatile struct mace *mb = mp->mace;
	int i;

Annotation

Implementation Notes