drivers/net/ethernet/lantiq_etop.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/lantiq_etop.c
Extension
.c
Size
17824 bytes
Lines
746
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 ltq_eth_netdev_ops = {
	.ndo_open = ltq_etop_open,
	.ndo_stop = ltq_etop_stop,
	.ndo_start_xmit = ltq_etop_tx,
	.ndo_change_mtu = ltq_etop_change_mtu,
	.ndo_eth_ioctl = phy_do_ioctl,
	.ndo_set_mac_address = ltq_etop_set_mac_address,
	.ndo_validate_addr = eth_validate_addr,
	.ndo_set_rx_mode = ltq_etop_set_multicast_list,
	.ndo_select_queue = dev_pick_tx_zero,
	.ndo_init = ltq_etop_init,
	.ndo_tx_timeout = ltq_etop_tx_timeout,
};

static int __init
ltq_etop_probe(struct platform_device *pdev)
{
	struct net_device *dev;
	struct ltq_etop_priv *priv;
	int err;
	int i;

	ltq_etop_membase = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(ltq_etop_membase)) {
		dev_err(&pdev->dev, "failed to remap etop engine %d\n",
			pdev->id);
		err = PTR_ERR(ltq_etop_membase);
		goto err_out;
	}

	dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
	if (!dev) {
		err = -ENOMEM;
		goto err_out;
	}
	dev->netdev_ops = &ltq_eth_netdev_ops;
	dev->ethtool_ops = &ltq_etop_ethtool_ops;
	priv = netdev_priv(dev);
	priv->pdev = pdev;
	priv->pldata = dev_get_platdata(&pdev->dev);
	priv->netdev = dev;
	spin_lock_init(&priv->lock);
	SET_NETDEV_DEV(dev, &pdev->dev);

	err = device_property_read_u32(&pdev->dev, "lantiq,tx-burst-length", &priv->tx_burst_len);
	if (err < 0) {
		dev_err(&pdev->dev, "unable to read tx-burst-length property\n");
		goto err_free;
	}

	err = device_property_read_u32(&pdev->dev, "lantiq,rx-burst-length", &priv->rx_burst_len);
	if (err < 0) {
		dev_err(&pdev->dev, "unable to read rx-burst-length property\n");
		goto err_free;
	}

	for (i = 0; i < MAX_DMA_CHAN; i++) {
		if (IS_TX(i))
			netif_napi_add_weight(dev, &priv->ch[i].napi,
					      ltq_etop_poll_tx, 8);
		else if (IS_RX(i))
			netif_napi_add_weight(dev, &priv->ch[i].napi,
					      ltq_etop_poll_rx, 32);
		priv->ch[i].netdev = dev;
	}

	err = register_netdev(dev);
	if (err)
		goto err_free;

	platform_set_drvdata(pdev, dev);
	return 0;

err_free:
	free_netdev(dev);
err_out:
	return err;
}

static void ltq_etop_remove(struct platform_device *pdev)
{
	struct net_device *dev = platform_get_drvdata(pdev);

	if (dev) {
		netif_tx_stop_all_queues(dev);
		ltq_etop_hw_exit(dev);
		ltq_etop_mdio_cleanup(dev);
		unregister_netdev(dev);
	}
}

Annotation

Implementation Notes