drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c
Extension
.c
Size
10005 bytes
Lines
366
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct net_device_ops mlx5i_pkey_netdev_ops = {
	.ndo_open                = mlx5i_pkey_open,
	.ndo_stop                = mlx5i_pkey_close,
	.ndo_init                = mlx5i_pkey_dev_init,
	.ndo_get_stats64         = mlx5i_get_stats,
	.ndo_uninit              = mlx5i_pkey_dev_cleanup,
	.ndo_change_mtu          = mlx5i_pkey_change_mtu,
	.ndo_hwtstamp_get        = mlx5i_hwtstamp_get,
	.ndo_hwtstamp_set        = mlx5i_hwtstamp_set,
};

/* Child NDOs */
static int mlx5i_pkey_dev_init(struct net_device *dev)
{
	struct mlx5e_priv *priv = mlx5i_epriv(dev);
	struct mlx5i_priv *ipriv, *parent_ipriv;
	struct net_device *parent_dev;

	ipriv = priv->ppriv;

	/* Link to parent */
	parent_dev = mlx5i_parent_get(dev);
	if (!parent_dev) {
		mlx5_core_warn(priv->mdev, "failed to get parent device\n");
		return -EINVAL;
	}

	if (dev->num_rx_queues < parent_dev->real_num_rx_queues) {
		mlx5_core_warn(priv->mdev,
			       "failed to create child device with rx queues [%d] less than parent's [%d]\n",
			       dev->num_rx_queues,
			       parent_dev->real_num_rx_queues);
		mlx5i_parent_put(dev);
		return -EINVAL;
	}

	/* Get QPN to netdevice hash table from parent */
	parent_ipriv = netdev_priv(parent_dev);
	ipriv->qpn_htbl = parent_ipriv->qpn_htbl;

	return mlx5i_dev_init(dev);
}

static void mlx5i_pkey_dev_cleanup(struct net_device *netdev)
{
	mlx5i_parent_put(netdev);
	return mlx5i_dev_cleanup(netdev);
}

static int mlx5i_pkey_open(struct net_device *netdev)
{
	struct mlx5e_priv *epriv = mlx5i_epriv(netdev);
	struct mlx5i_priv *ipriv = epriv->ppriv;
	struct mlx5_core_dev *mdev = epriv->mdev;
	int err;

	mutex_lock(&epriv->state_lock);

	set_bit(MLX5E_STATE_OPENED, &epriv->state);

	err = mlx5i_init_underlay_qp(epriv);
	if (err) {
		mlx5_core_warn(mdev, "prepare child underlay qp state failed, %d\n", err);
		goto err_release_lock;
	}

	err = mlx5_fs_add_rx_underlay_qpn(mdev, ipriv->qpn);
	if (err) {
		mlx5_core_warn(mdev, "attach child underlay qp to ft failed, %d\n", err);
		goto err_unint_underlay_qp;
	}

	err = mlx5i_create_tis(mdev, ipriv->qpn, &ipriv->tisn);
	if (err) {
		mlx5_core_warn(mdev, "create child tis failed, %d\n", err);
		goto err_remove_rx_uderlay_qp;
	}

	err = mlx5e_open_channels(epriv, &epriv->channels);
	if (err) {
		mlx5_core_warn(mdev, "opening child channels failed, %d\n", err);
		goto err_clear_state_opened_flag;
	}
	err = epriv->profile->update_rx(epriv);
	if (err)
		goto err_close_channels;
	mlx5e_activate_priv_channels(epriv);
	mutex_unlock(&epriv->state_lock);

	return 0;

Annotation

Implementation Notes