Exemple #1
0
int mlx5e_vport_rep_load(struct mlx5_eswitch *esw,
			 struct mlx5_eswitch_rep *rep)
{
	struct net_device *netdev;
	int err;

	netdev = mlx5e_create_netdev(esw->dev, &mlx5e_rep_profile, rep);
	if (!netdev) {
		pr_warn("Failed to create representor netdev for vport %d\n",
			rep->vport);
		return -EINVAL;
	}

	rep->priv_data = netdev_priv(netdev);

	err = mlx5e_attach_netdev(esw->dev, netdev);
	if (err) {
		pr_warn("Failed to attach representor netdev for vport %d\n",
			rep->vport);
		goto err_destroy_netdev;
	}

	err = register_netdev(netdev);
	if (err) {
		pr_warn("Failed to register representor netdev for vport %d\n",
			rep->vport);
		goto err_detach_netdev;
	}

	return 0;

err_detach_netdev:
	mlx5e_detach_netdev(esw->dev, netdev);

err_destroy_netdev:
	mlx5e_destroy_netdev(esw->dev, rep->priv_data);

	return err;

}
Exemple #2
0
struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev,
					  struct ib_device *ibdev,
					  const char *name,
					  void (*setup)(struct net_device *))
{
	const struct mlx5e_profile *profile;
	struct net_device *netdev;
	struct mlx5i_priv *ipriv;
	struct mlx5e_priv *epriv;
	struct rdma_netdev *rn;
	bool sub_interface;
	int nch;
	int err;

	if (mlx5i_check_required_hca_cap(mdev)) {
		mlx5_core_warn(mdev, "Accelerated mode is not supported\n");
		return ERR_PTR(-EOPNOTSUPP);
	}

	/* TODO: Need to find a better way to check if child device*/
	sub_interface = (mdev->mlx5e_res.pdn != 0);

	if (sub_interface)
		profile = mlx5i_pkey_get_profile();
	else
		profile = &mlx5i_nic_profile;

	nch = profile->max_nch(mdev);

	netdev = alloc_netdev_mqs(sizeof(struct mlx5i_priv) + sizeof(struct mlx5e_priv),
				  name, NET_NAME_UNKNOWN,
				  setup,
				  nch * MLX5E_MAX_NUM_TC,
				  nch);
	if (!netdev) {
		mlx5_core_warn(mdev, "alloc_netdev_mqs failed\n");
		return NULL;
	}

	ipriv = netdev_priv(netdev);
	epriv = mlx5i_epriv(netdev);

	epriv->wq = create_singlethread_workqueue("mlx5i");
	if (!epriv->wq)
		goto err_free_netdev;

	ipriv->sub_interface = sub_interface;
	if (!ipriv->sub_interface) {
		err = mlx5i_pkey_qpn_ht_init(netdev);
		if (err) {
			mlx5_core_warn(mdev, "allocate qpn_to_netdev ht failed\n");
			goto destroy_wq;
		}

		/* This should only be called once per mdev */
		err = mlx5e_create_mdev_resources(mdev);
		if (err)
			goto destroy_ht;
	}

	profile->init(mdev, netdev, profile, ipriv);

	mlx5e_attach_netdev(epriv);
	netif_carrier_off(netdev);

	/* set rdma_netdev func pointers */
	rn = &ipriv->rn;
	rn->hca  = ibdev;
	rn->send = mlx5i_xmit;
	rn->attach_mcast = mlx5i_attach_mcast;
	rn->detach_mcast = mlx5i_detach_mcast;
	rn->set_id = mlx5i_set_pkey_index;

	return netdev;

destroy_ht:
	mlx5i_pkey_qpn_ht_cleanup(netdev);
destroy_wq:
	destroy_workqueue(epriv->wq);
err_free_netdev:
	free_netdev(netdev);

	return NULL;
}