drivers/net/ethernet/mellanox/mlx5/core/en_rep.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
Extension
.c
Size
50115 bytes
Lines
1826
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 mlx5e_netdev_ops_rep = {
	.ndo_open                = mlx5e_rep_open,
	.ndo_stop                = mlx5e_rep_close,
	.ndo_start_xmit          = mlx5e_xmit,
	.ndo_setup_tc            = mlx5e_rep_setup_tc,
	.ndo_set_mac_address	 = eth_mac_addr,
	.ndo_get_stats64         = mlx5e_rep_get_stats,
	.ndo_has_offload_stats	 = mlx5e_rep_has_offload_stats,
	.ndo_get_offload_stats	 = mlx5e_rep_get_offload_stats,
	.ndo_change_mtu          = mlx5e_rep_change_mtu,
	.ndo_change_carrier      = mlx5e_rep_change_carrier,
};

bool mlx5e_eswitch_uplink_rep(const struct net_device *netdev)
{
	return netdev->netdev_ops == &mlx5e_netdev_ops &&
	       mlx5e_is_uplink_rep(netdev_priv(netdev));
}

bool mlx5e_eswitch_vf_rep(const struct net_device *netdev)
{
	return netdev->netdev_ops == &mlx5e_netdev_ops_rep;
}

/* One indirect TIR set for outer. Inner not supported in reps. */
#define REP_NUM_INDIR_TIRS MLX5E_NUM_INDIR_TIRS

static int mlx5e_rep_max_nch_limit(struct mlx5_core_dev *mdev)
{
	int max_tir_num = 1 << MLX5_CAP_GEN(mdev, log_max_tir);
	int num_vports = mlx5_eswitch_get_total_vports(mdev);

	return (max_tir_num - mlx5e_get_pf_num_tirs(mdev)
		- (num_vports * REP_NUM_INDIR_TIRS)) / num_vports;
}

static void mlx5e_build_rep_params(struct net_device *netdev)
{
	const bool take_rtnl = netdev->reg_state == NETREG_REGISTERED;
	struct mlx5e_priv *priv = netdev_priv(netdev);
	struct mlx5e_rep_priv *rpriv = priv->ppriv;
	struct mlx5_eswitch_rep *rep = rpriv->rep;
	struct mlx5_core_dev *mdev = priv->mdev;
	struct mlx5e_params *params;

	params = &priv->channels.params;

	params->num_channels = MLX5E_REP_PARAMS_DEF_NUM_CHANNELS;
	params->hard_mtu    = MLX5E_ETH_HARD_MTU;
	params->sw_mtu      = netdev->mtu;

	/* SQ */
	if (rep->vport == MLX5_VPORT_UPLINK)
		params->log_sq_size = MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE;
	else
		params->log_sq_size = MLX5E_REP_PARAMS_DEF_LOG_SQ_SIZE;

	/* RQ */
	mlx5e_build_rq_params(mdev, params);
	if (!mlx5e_is_uplink_rep(priv) && mlx5_core_is_ecpf(mdev))
		params->log_rq_mtu_frames = MLX5E_REP_PARAMS_DEF_LOG_RQ_SIZE;

	/* If netdev is already registered (e.g. move from nic profile to uplink,
	 * RTNL lock must be held before triggering netdev notifiers.
	 */
	if (take_rtnl)
		rtnl_lock();
	/* update XDP supported features */
	mlx5e_set_xdp_feature(priv);
	if (take_rtnl)
		rtnl_unlock();

	/* CQ moderation params */
	params->rx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
	params->rx_moder_use_cqe_mode = !!MLX5_CAP_GEN(mdev, cq_period_start_from_cqe);

	params->mqprio.num_tc       = 1;
	if (rep->vport != MLX5_VPORT_UPLINK)
		params->vlan_strip_disable = true;

	mlx5_query_min_inline(mdev, &params->tx_min_inline_mode);
}

static void mlx5e_build_rep_netdev(struct net_device *netdev,
				   struct mlx5_core_dev *mdev)
{
	SET_NETDEV_DEV(netdev, mdev->device);
	netdev->netdev_ops = &mlx5e_netdev_ops_rep;
	netdev->request_ops_lock = true;
	netdev_lockdep_set_classes(netdev);

Annotation

Implementation Notes