in drivers/vector_kern.c [1555:1668]
static void vector_eth_configure(
int n,
struct arglist *def
)
{
struct vector_device *device;
struct net_device *dev;
struct vector_private *vp;
int err;
device = kzalloc(sizeof(*device), GFP_KERNEL);
if (device == NULL) {
printk(KERN_ERR "eth_configure failed to allocate struct "
"vector_device\n");
return;
}
dev = alloc_etherdev(sizeof(struct vector_private));
if (dev == NULL) {
printk(KERN_ERR "eth_configure: failed to allocate struct "
"net_device for vec%d\n", n);
goto out_free_device;
}
dev->mtu = get_mtu(def);
INIT_LIST_HEAD(&device->list);
device->unit = n;
/* 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), "vec%d", n);
uml_net_setup_etheraddr(dev, uml_vector_fetch_arg(def, "mac"));
vp = netdev_priv(dev);
/* sysfs register */
if (!driver_registered) {
platform_driver_register(¨_net_driver);
driver_registered = 1;
}
device->pdev.id = n;
device->pdev.name = DRIVER_NAME;
device->pdev.dev.release = vector_device_release;
dev_set_drvdata(&device->pdev.dev, device);
if (platform_device_register(&device->pdev))
goto out_free_netdev;
SET_NETDEV_DEV(dev, &device->pdev.dev);
device->dev = dev;
*vp = ((struct vector_private)
{
.list = LIST_HEAD_INIT(vp->list),
.dev = dev,
.unit = n,
.options = get_transport_options(def),
.rx_irq = 0,
.tx_irq = 0,
.parsed = def,
.max_packet = get_mtu(def) + ETH_HEADER_OTHER,
/* TODO - we need to calculate headroom so that ip header
* is 16 byte aligned all the time
*/
.headroom = get_headroom(def),
.form_header = NULL,
.verify_header = NULL,
.header_rxbuffer = NULL,
.header_txbuffer = NULL,
.header_size = 0,
.rx_header_size = 0,
.rexmit_scheduled = false,
.opened = false,
.transport_data = NULL,
.in_write_poll = false,
.coalesce = 2,
.req_size = get_req_size(def),
.in_error = false,
.bpf = NULL
});
dev->features = dev->hw_features = (NETIF_F_SG | NETIF_F_FRAGLIST);
tasklet_setup(&vp->tx_poll, vector_tx_poll);
INIT_WORK(&vp->reset_tx, vector_reset_tx);
timer_setup(&vp->tl, vector_timer_expire, 0);
spin_lock_init(&vp->lock);
/* FIXME */
dev->netdev_ops = &vector_netdev_ops;
dev->ethtool_ops = &vector_net_ethtool_ops;
dev->watchdog_timeo = (HZ >> 1);
/* primary IRQ - fixme */
dev->irq = 0; /* we will adjust this once opened */
rtnl_lock();
err = register_netdevice(dev);
rtnl_unlock();
if (err)
goto out_undo_user_init;
spin_lock(&vector_devices_lock);
list_add(&device->list, &vector_devices);
spin_unlock(&vector_devices_lock);
return;
out_undo_user_init:
return;
out_free_netdev:
free_netdev(dev);
out_free_device:
kfree(device);
}