示例#1
0
struct net_device *
nfp_repr_alloc_mqs(struct nfp_app *app, unsigned int txqs, unsigned int rxqs)
{
	struct net_device *netdev;
	struct nfp_repr *repr;

	netdev = alloc_etherdev_mqs(sizeof(*repr), txqs, rxqs);
	if (!netdev)
		return NULL;

	netif_carrier_off(netdev);

	repr = netdev_priv(netdev);
	repr->netdev = netdev;
	repr->app = app;

	repr->stats = netdev_alloc_pcpu_stats(struct nfp_repr_pcpu_stats);
	if (!repr->stats)
		goto err_free_netdev;

	return netdev;

err_free_netdev:
	free_netdev(netdev);
	return NULL;
}
示例#2
0
文件: eth.c 项目: krzk/linux
struct net_device *devm_alloc_etherdev_mqs(struct device *dev, int sizeof_priv,
					   unsigned int txqs, unsigned int rxqs)
{
	struct net_device **dr;
	struct net_device *netdev;

	dr = devres_alloc(devm_free_netdev, sizeof(*dr), GFP_KERNEL);
	if (!dr)
		return NULL;

	netdev = alloc_etherdev_mqs(sizeof_priv, txqs, rxqs);
	if (!netdev) {
		devres_free(dr);
		return NULL;
	}

	*dr = netdev;
	devres_add(dev, dr);

	return netdev;
}
示例#3
0
文件: sn_netdev.c 项目: NetSys/bess
/* bar must be a virtual address (whether it's host or guest),
 * where the kernel can directly access to */
int sn_create_netdev(void *bar, struct sn_device **dev_ret)
{
	struct sn_conf_space *conf = bar;
	struct sn_device *dev;
	struct net_device *netdev;

	char *name;

	int ret;

	*dev_ret = NULL;

	if (conf->bar_size < sizeof(struct sn_conf_space)) {
		log_err("invalid BAR size %llu\n", conf->bar_size);
		return -EINVAL;
	}

	if (conf->num_txq < 1 || conf->num_rxq < 1 ||
			conf->num_txq > MAX_QUEUES ||
			conf->num_rxq > MAX_QUEUES)
	{
		log_err("invalid ioctl arguments: num_txq=%d, num_rxq=%d\n",
				conf->num_txq, conf->num_rxq);
		return -EINVAL;
	}

	netdev = alloc_etherdev_mqs(sizeof(struct sn_device),
			conf->num_txq, conf->num_rxq);
	if (!netdev) {
		log_err("alloc_netdev_mqs() failed\n");
		return -ENOMEM;
	}

	if (strcmp(conf->ifname, "") == 0)
		name = "sn%d";
	else
		name = conf->ifname;

	ret = dev_alloc_name(netdev, name);
	if (ret < 0) {
		log_err("failed to alloc name %s\n", name);
		free_netdev(netdev);
		return ret;
	}

	dev = netdev_priv(netdev);
	dev->netdev = netdev;
	dev->num_txq = conf->num_txq;
	dev->num_rxq = conf->num_rxq;

	sn_set_default_queue_mapping(dev);

	/* This will disable the default qdisc (mq or pfifo_fast) on the
	 * interface. We don't need qdisc since BESS already has its own.
	 * Also see attach_default_qdiscs() in sch_generic.c */
	netdev->tx_queue_len = 0;

	netdev->destructor = sn_netdev_destructor;

	sn_set_offloads(netdev);

	netdev->netdev_ops = &sn_netdev_ops;
	netdev->ethtool_ops = &sn_ethtool_ops;

	memcpy(netdev->dev_addr, conf->mac_addr, ETH_ALEN);

	ret = sn_alloc_queues(dev, conf + 1,
			conf->bar_size - sizeof(struct sn_conf_space),
			&conf->txq_opts, &conf->rxq_opts);
	if (ret) {
		log_err("sn_alloc_queues() failed\n");
		free_netdev(netdev);
		return ret;
	}

	*dev_ret = dev;
	return 0;
}