static void vector_eth_configure()

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(&uml_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);
}