Commit 1e662209 authored by Adham Faris's avatar Adham Faris Committed by Saeed Mahameed
Browse files

net/mlx5e: Update rx ring hw mtu upon each rx-fcs flag change



rq->hw_mtu is used in function en_rx.c/mlx5e_skb_from_cqe_mpwrq_linear()
to catch oversized packets. If FCS is concatenated to the end of the
packet then the check should be updated accordingly.

Rx rings initialization (mlx5e_init_rxq_rq()) invoked for every new set
of channels, as part of mlx5e_safe_switch_params(), unknowingly if it
runs with default configuration or not. Current rq->hw_mtu
initialization assumes default configuration and ignores
params->scatter_fcs_en flag state.
Fix this, by accounting for params->scatter_fcs_en flag state during
rq->hw_mtu initialization.

In addition, updating rq->hw_mtu value during ingress traffic might
lead to packets drop and oversize_pkts_sw_drop counter increase with no
good reason. Hence we remove this optimization and switch the set of
channels with a new one, to make sure we don't get false positives on
the oversize_pkts_sw_drop counter.

Fixes: 102722fc ("net/mlx5e: Add support for RXFCS feature flag")
Signed-off-by: default avatarAdham Faris <afaris@nvidia.com>
Reviewed-by: default avatarTariq Toukan <tariqt@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent 565b4824
Loading
Loading
Loading
Loading
+15 −71
Original line number Diff line number Diff line
@@ -591,7 +591,8 @@ static int mlx5e_init_rxq_rq(struct mlx5e_channel *c, struct mlx5e_params *param
	rq->ix           = c->ix;
	rq->channel      = c;
	rq->mdev         = mdev;
	rq->hw_mtu       = MLX5E_SW2HW_MTU(params, params->sw_mtu);
	rq->hw_mtu =
		MLX5E_SW2HW_MTU(params, params->sw_mtu) - ETH_FCS_LEN * !params->scatter_fcs_en;
	rq->xdpsq        = &c->rq_xdpsq;
	rq->stats        = &c->priv->channel_stats[c->ix]->rq;
	rq->ptp_cyc2time = mlx5_rq_ts_translator(mdev);
@@ -1014,35 +1015,6 @@ int mlx5e_flush_rq(struct mlx5e_rq *rq, int curr_state)
	return mlx5e_rq_to_ready(rq, curr_state);
}

static int mlx5e_modify_rq_scatter_fcs(struct mlx5e_rq *rq, bool enable)
{
	struct mlx5_core_dev *mdev = rq->mdev;

	void *in;
	void *rqc;
	int inlen;
	int err;

	inlen = MLX5_ST_SZ_BYTES(modify_rq_in);
	in = kvzalloc(inlen, GFP_KERNEL);
	if (!in)
		return -ENOMEM;

	rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx);

	MLX5_SET(modify_rq_in, in, rq_state, MLX5_RQC_STATE_RDY);
	MLX5_SET64(modify_rq_in, in, modify_bitmask,
		   MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_SCATTER_FCS);
	MLX5_SET(rqc, rqc, scatter_fcs, enable);
	MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RDY);

	err = mlx5_core_modify_rq(mdev, rq->rqn, in);

	kvfree(in);

	return err;
}

static int mlx5e_modify_rq_vsd(struct mlx5e_rq *rq, bool vsd)
{
	struct mlx5_core_dev *mdev = rq->mdev;
@@ -3314,20 +3286,6 @@ static void mlx5e_cleanup_nic_tx(struct mlx5e_priv *priv)
	mlx5e_destroy_tises(priv);
}

static int mlx5e_modify_channels_scatter_fcs(struct mlx5e_channels *chs, bool enable)
{
	int err = 0;
	int i;

	for (i = 0; i < chs->num; i++) {
		err = mlx5e_modify_rq_scatter_fcs(&chs->c[i]->rq, enable);
		if (err)
			return err;
	}

	return 0;
}

static int mlx5e_modify_channels_vsd(struct mlx5e_channels *chs, bool vsd)
{
	int err;
@@ -3903,41 +3861,27 @@ static int mlx5e_set_rx_port_ts(struct mlx5_core_dev *mdev, bool enable)
	return mlx5_set_ports_check(mdev, in, sizeof(in));
}

static int mlx5e_set_rx_port_ts_wrap(struct mlx5e_priv *priv, void *ctx)
{
	struct mlx5_core_dev *mdev = priv->mdev;
	bool enable = *(bool *)ctx;

	return mlx5e_set_rx_port_ts(mdev, enable);
}

static int set_feature_rx_fcs(struct net_device *netdev, bool enable)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
	struct mlx5e_channels *chs = &priv->channels;
	struct mlx5_core_dev *mdev = priv->mdev;
	struct mlx5e_params new_params;
	int err;

	mutex_lock(&priv->state_lock);

	if (enable) {
		err = mlx5e_set_rx_port_ts(mdev, false);
		if (err)
			goto out;

		chs->params.scatter_fcs_en = true;
		err = mlx5e_modify_channels_scatter_fcs(chs, true);
		if (err) {
			chs->params.scatter_fcs_en = false;
			mlx5e_set_rx_port_ts(mdev, true);
		}
	} else {
		chs->params.scatter_fcs_en = false;
		err = mlx5e_modify_channels_scatter_fcs(chs, false);
		if (err) {
			chs->params.scatter_fcs_en = true;
			goto out;
		}
		err = mlx5e_set_rx_port_ts(mdev, true);
		if (err) {
			mlx5_core_warn(mdev, "Failed to set RX port timestamp %d\n", err);
			err = 0;
		}
	}

out:
	new_params = chs->params;
	new_params.scatter_fcs_en = enable;
	err = mlx5e_safe_switch_params(priv, &new_params, mlx5e_set_rx_port_ts_wrap,
				       &new_params.scatter_fcs_en, true);
	mutex_unlock(&priv->state_lock);
	return err;
}