drivers/net/ethernet/broadcom/bcm4908_enet.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/broadcom/bcm4908_enet.c
Extension
.c
Size
21896 bytes
Lines
799
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 bcm4908_enet_netdev_ops = {
	.ndo_open = bcm4908_enet_open,
	.ndo_stop = bcm4908_enet_stop,
	.ndo_start_xmit = bcm4908_enet_start_xmit,
	.ndo_set_mac_address = eth_mac_addr,
	.ndo_change_mtu = bcm4908_enet_change_mtu,
};

static int bcm4908_enet_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct net_device *netdev;
	struct bcm4908_enet *enet;
	int err;

	netdev = devm_alloc_etherdev(dev, sizeof(*enet));
	if (!netdev)
		return -ENOMEM;

	enet = netdev_priv(netdev);
	enet->dev = dev;
	enet->netdev = netdev;

	enet->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(enet->base)) {
		dev_err(dev, "Failed to map registers: %ld\n", PTR_ERR(enet->base));
		return PTR_ERR(enet->base);
	}

	netdev->irq = platform_get_irq_byname(pdev, "rx");
	if (netdev->irq < 0)
		return netdev->irq;

	enet->irq_tx = platform_get_irq_byname(pdev, "tx");

	err = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
	if (err)
		return err;

	err = bcm4908_enet_dma_alloc(enet);
	if (err)
		return err;

	SET_NETDEV_DEV(netdev, &pdev->dev);
	err = of_get_ethdev_address(dev->of_node, netdev);
	if (err == -EPROBE_DEFER)
		goto err_dma_free;
	if (err)
		eth_hw_addr_random(netdev);
	netdev->netdev_ops = &bcm4908_enet_netdev_ops;
	netdev->min_mtu = ETH_ZLEN;
	netdev->mtu = ETH_DATA_LEN;
	netdev->max_mtu = ENET_MTU_MAX;
	netif_napi_add_tx(netdev, &enet->tx_ring.napi, bcm4908_enet_poll_tx);
	netif_napi_add(netdev, &enet->rx_ring.napi, bcm4908_enet_poll_rx);

	err = register_netdev(netdev);
	if (err)
		goto err_dma_free;

	platform_set_drvdata(pdev, enet);

	return 0;

err_dma_free:
	bcm4908_enet_dma_free(enet);

	return err;
}

static void bcm4908_enet_remove(struct platform_device *pdev)
{
	struct bcm4908_enet *enet = platform_get_drvdata(pdev);

	unregister_netdev(enet->netdev);
	netif_napi_del(&enet->rx_ring.napi);
	netif_napi_del(&enet->tx_ring.napi);
	bcm4908_enet_dma_free(enet);
}

static const struct of_device_id bcm4908_enet_of_match[] = {
	{ .compatible = "brcm,bcm4908-enet"},
	{},
};

static struct platform_driver bcm4908_enet_driver = {
	.driver = {
		.name = "bcm4908_enet",
		.of_match_table = bcm4908_enet_of_match,
	},

Annotation

Implementation Notes