drivers/infiniband/hw/mlx5/ib_rep.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/mlx5/ib_rep.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/mlx5/ib_rep.c
Extension
.c
Size
8832 bytes
Lines
364
Domain
Driver Families
Bucket
drivers/infiniband
Inferred role
Driver Families: implementation source
Status
source 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

if (ret) {
			mlx5_ib_release_transport(dev);
			return ret;
		}
	}

	return 0;
}

static int
mlx5_ib_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
{
	u32 num_ports = mlx5_eswitch_get_total_vports(dev);
	struct mlx5_core_dev *lag_master = dev;
	const struct mlx5_ib_profile *profile;
	struct mlx5_core_dev *peer_dev;
	struct mlx5_ib_dev *ibdev;
	int new_uplink = false;
	int vport_index;
	int ret;
	int i;

	vport_index = rep->vport_index;

	if (mlx5_lag_is_shared_fdb(dev)) {
		if (mlx5_lag_is_master(dev)) {
			mlx5_ib_num_ports_update(dev, &num_ports);
		} else {
			if (rep->vport == MLX5_VPORT_UPLINK) {
				if (!mlx5_lag_is_mpesw(dev))
					return 0;
				new_uplink = true;
			}
			mlx5_lag_for_each_peer_mdev(dev, peer_dev, i) {
				u32 peer_n_ports = mlx5_eswitch_get_total_vports(peer_dev);

				if (mlx5_lag_is_master(peer_dev))
					lag_master = peer_dev;
				else if (!mlx5_lag_is_mpesw(peer_dev))
				/* Only 1 ib port is the representor for all uplinks */
					peer_n_ports--;

				if (mlx5_lag_get_dev_seq(peer_dev) <
				    mlx5_lag_get_dev_seq(dev))
					vport_index += peer_n_ports;
			}
		}
	}

	if (rep->vport == MLX5_VPORT_UPLINK && !new_uplink)
		profile = &raw_eth_profile;
	else
		return mlx5_ib_set_vport_rep(lag_master, dev, rep, vport_index);

	if (mlx5_lag_is_shared_fdb(dev)) {
		ret = mlx5_ib_take_transport(lag_master);
		if (ret)
			return ret;
	}

	ibdev = ib_alloc_device_with_net(mlx5_ib_dev, ib_dev,
					 mlx5_core_net(lag_master));
	if (!ibdev) {
		ret = -ENOMEM;
		goto release_transport;
	}

	ibdev->port = kzalloc_objs(*ibdev->port, num_ports);
	if (!ibdev->port) {
		ret = -ENOMEM;
		goto fail_port;
	}

	ibdev->is_rep = true;
	vport_index = rep->vport_index;
	ibdev->port[vport_index].rep = rep;
	ibdev->mdev = lag_master;
	ibdev->num_ports = num_ports;
	ibdev->ib_dev.phys_port_cnt = num_ports;
	ret = ib_device_set_netdev(&ibdev->ib_dev,
			mlx5_ib_get_rep_netdev(lag_master->priv.eswitch,
					       rep->vport),
			vport_index + 1);
	if (ret)
		goto fail_add;

	ret = __mlx5_ib_add(ibdev, profile);
	if (ret)
		goto fail_add;

Annotation

Implementation Notes