drivers/net/ethernet/litex/litex_liteeth.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/litex/litex_liteeth.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/litex/litex_liteeth.c
Extension
.c
Size
7680 bytes
Lines
316
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 liteeth_netdev_ops = {
	.ndo_open		= liteeth_open,
	.ndo_stop		= liteeth_stop,
	.ndo_get_stats64	= liteeth_get_stats64,
	.ndo_start_xmit         = liteeth_start_xmit,
};

static void liteeth_setup_slots(struct liteeth *priv)
{
	struct device_node *np = priv->dev->of_node;
	int err;

	err = of_property_read_u32(np, "litex,rx-slots", &priv->num_rx_slots);
	if (err) {
		dev_dbg(priv->dev, "unable to get litex,rx-slots, using 2\n");
		priv->num_rx_slots = 2;
	}

	err = of_property_read_u32(np, "litex,tx-slots", &priv->num_tx_slots);
	if (err) {
		dev_dbg(priv->dev, "unable to get litex,tx-slots, using 2\n");
		priv->num_tx_slots = 2;
	}

	err = of_property_read_u32(np, "litex,slot-size", &priv->slot_size);
	if (err) {
		dev_dbg(priv->dev, "unable to get litex,slot-size, using 0x800\n");
		priv->slot_size = 0x800;
	}
}

static int liteeth_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct net_device *netdev;
	void __iomem *buf_base;
	struct liteeth *priv;
	int irq, err;

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

	SET_NETDEV_DEV(netdev, &pdev->dev);
	platform_set_drvdata(pdev, netdev);

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

	netdev->tstats = devm_netdev_alloc_pcpu_stats(dev,
						      struct pcpu_sw_netstats);
	if (!netdev->tstats)
		return -ENOMEM;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;
	netdev->irq = irq;

	priv->base = devm_platform_ioremap_resource_byname(pdev, "mac");
	if (IS_ERR(priv->base))
		return PTR_ERR(priv->base);

	buf_base = devm_platform_ioremap_resource_byname(pdev, "buffer");
	if (IS_ERR(buf_base))
		return PTR_ERR(buf_base);

	liteeth_setup_slots(priv);

	/* Rx slots */
	priv->rx_base = buf_base;
	priv->rx_slot = 0;

	/* Tx slots come after Rx slots */
	priv->tx_base = buf_base + priv->num_rx_slots * priv->slot_size;
	priv->tx_slot = 0;

	err = of_get_ethdev_address(dev->of_node, netdev);
	if (err)
		eth_hw_addr_random(netdev);

	netdev->netdev_ops = &liteeth_netdev_ops;

	err = devm_register_netdev(dev, netdev);
	if (err) {
		dev_err(dev, "Failed to register netdev %d\n", err);
		return err;
	}

Annotation

Implementation Notes