net/mlx5e: Update rx ring hw mtu upon each rx-fcs flag change
authorAdham Faris <afaris@nvidia.com>
Sun, 8 Jan 2023 16:09:32 +0000 (18:09 +0200)
committerSaeed Mahameed <saeedm@nvidia.com>
Wed, 8 Feb 2023 03:01:04 +0000 (19:01 -0800)
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: 102722fc6832 ("net/mlx5e: Add support for RXFCS feature flag")
Signed-off-by: Adham Faris <afaris@nvidia.com>
Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
drivers/net/ethernet/mellanox/mlx5/core/en_main.c

index abcc614..f8b5e59 100644 (file)
@@ -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;
 }