arch/xtensa/platforms/iss/network.c

Source file repositories/reference/linux-study-clean/arch/xtensa/platforms/iss/network.c

File Facts

System
Linux kernel
Corpus path
arch/xtensa/platforms/iss/network.c
Extension
.c
Size
13989 bytes
Lines
643
Domain
Architecture Layer
Bucket
arch/xtensa
Inferred role
Architecture Layer: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct net_device_ops iss_netdev_ops = {
	.ndo_open		= iss_net_open,
	.ndo_stop		= iss_net_close,
	.ndo_get_stats64	= iss_net_get_stats64,
	.ndo_start_xmit		= iss_net_start_xmit,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_change_mtu		= iss_net_change_mtu,
	.ndo_set_mac_address	= eth_mac_addr,
	.ndo_tx_timeout		= iss_net_tx_timeout,
	.ndo_set_rx_mode	= iss_net_set_multicast_list,
};

static void iss_net_pdev_release(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct iss_net_private *lp =
		container_of(pdev, struct iss_net_private, pdev);

	free_netdev(lp->dev);
}

static void iss_net_configure(int index, char *init)
{
	struct net_device *dev;
	struct iss_net_private *lp;

	dev = alloc_etherdev(sizeof(*lp));
	if (dev == NULL) {
		pr_err("eth_configure: failed to allocate device\n");
		return;
	}

	/* Initialize private element. */

	lp = netdev_priv(dev);
	*lp = (struct iss_net_private) {
		.dev			= dev,
		.index			= index,
	};

	spin_lock_init(&lp->lock);
	/*
	 * If this name ends up conflicting with an existing registered
	 * netdevice, that is OK, register_netdev{,ice}() will notice this
	 * and fail.
	 */
	snprintf(dev->name, sizeof(dev->name), "eth%d", index);

	/*
	 * Try all transport protocols.
	 * Note: more protocols can be added by adding '&& !X_init(lp, eth)'.
	 */

	if (!tuntap_probe(lp, index, init)) {
		pr_err("%s: invalid arguments. Skipping device!\n",
		       dev->name);
		goto err_free_netdev;
	}

	pr_info("Netdevice %d (%pM)\n", index, dev->dev_addr);

	/* sysfs register */

	if (!driver_registered) {
		if (platform_driver_register(&iss_net_driver))
			goto err_free_netdev;
		driver_registered = 1;
	}

	lp->pdev.id = index;
	lp->pdev.name = DRIVER_NAME;
	lp->pdev.dev.release = iss_net_pdev_release;
	if (platform_device_register(&lp->pdev))
		goto err_free_netdev;
	SET_NETDEV_DEV(dev, &lp->pdev.dev);

	dev->netdev_ops = &iss_netdev_ops;
	dev->mtu = lp->mtu;
	dev->watchdog_timeo = (HZ >> 1);
	dev->irq = -1;

	rtnl_lock();
	if (register_netdevice(dev)) {
		rtnl_unlock();
		pr_err("%s: error registering net device!\n", dev->name);
		platform_device_unregister(&lp->pdev);
		/* dev is freed by the iss_net_pdev_release callback */
		return;
	}
	rtnl_unlock();

Annotation

Implementation Notes