in platforms/iss/network.c [506:588]
static int iss_net_configure(int index, char *init)
{
struct net_device *dev;
struct iss_net_private *lp;
int err;
dev = alloc_etherdev(sizeof(*lp));
if (dev == NULL) {
pr_err("eth_configure: failed to allocate device\n");
return 1;
}
/* Initialize private element. */
lp = netdev_priv(dev);
*lp = (struct iss_net_private) {
.device_list = LIST_HEAD_INIT(lp->device_list),
.opened_list = LIST_HEAD_INIT(lp->opened_list),
.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 errout;
}
pr_info("Netdevice %d (%pM)\n", index, dev->dev_addr);
/* sysfs register */
if (!driver_registered) {
platform_driver_register(&iss_net_driver);
driver_registered = 1;
}
spin_lock(&devices_lock);
list_add(&lp->device_list, &devices);
spin_unlock(&devices_lock);
lp->pdev.id = index;
lp->pdev.name = DRIVER_NAME;
platform_device_register(&lp->pdev);
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();
err = register_netdevice(dev);
rtnl_unlock();
if (err) {
pr_err("%s: error registering net device!\n", dev->name);
/* XXX: should we call ->remove() here? */
free_netdev(dev);
return 1;
}
timer_setup(&lp->tl, iss_net_user_timer_expire, 0);
return 0;
errout:
/* FIXME: unregister; free, etc.. */
return -EIO;
}