The branch main has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=02fe38b92175cb8f3a77f7a2bb72afb83836ebd2

commit 02fe38b92175cb8f3a77f7a2bb72afb83836ebd2
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2025-01-29 15:45:18 +0000
Commit:     Konstantin Belousov <k...@freebsd.org>
CommitDate: 2025-03-13 15:58:53 +0000

    mlx5en: make the hw lro control dynamic
    
    Reviewed by:    Ariel Ehrenberg <aehrenb...@nvidia.com>, Slava Shwartsman 
<slav...@nvidia.com>
    Sponsored by:   NVidia networking
    MFC after:      1 week
---
 sys/dev/mlx5/mlx5_en/en.h              |  1 +
 sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c |  3 ++
 sys/dev/mlx5/mlx5_en/mlx5_en_main.c    | 83 ++++++++++++++++++++++++++++------
 3 files changed, 73 insertions(+), 14 deletions(-)

diff --git a/sys/dev/mlx5/mlx5_en/en.h b/sys/dev/mlx5/mlx5_en/en.h
index 80e0b7fbdedb..bcc33824a5f5 100644
--- a/sys/dev/mlx5/mlx5_en/en.h
+++ b/sys/dev/mlx5/mlx5_en/en.h
@@ -1301,6 +1301,7 @@ void      mlx5e_refresh_sq_inline(struct mlx5e_priv 
*priv);
 int    mlx5e_update_buf_lossy(struct mlx5e_priv *priv);
 int    mlx5e_fec_update(struct mlx5e_priv *priv);
 int    mlx5e_hw_temperature_update(struct mlx5e_priv *priv);
+int    mlx5e_hw_lro_update_tirs(struct mlx5e_priv *priv);
 
 /* Internal Queue, IQ, API functions */
 void   mlx5e_iq_send_nop(struct mlx5e_iq *, u32);
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c 
b/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
index 459801cdf27d..b0b7a175a1b6 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
@@ -1133,6 +1133,9 @@ mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS)
                        priv->params.hw_lro_en = false;
                        priv->params_ethtool.hw_lro = 0;
                }
+
+               error = mlx5e_hw_lro_update_tirs(priv);
+
                /* restart network interface, if any */
                if (was_opened)
                        mlx5e_open_locked(priv->ifp);
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c 
b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
index 67583afc21c7..321ed8ac9976 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
@@ -2944,6 +2944,73 @@ mlx5e_get_rss_key(void *key_ptr)
 #endif
 }
 
+static void
+mlx5e_hw_lro_set_tir_ctx_lro_max_msg_sz(struct mlx5e_priv *priv, u32 *tirc)
+{
+#define        ROUGH_MAX_L2_L3_HDR_SZ 256
+
+       MLX5_SET(tirc, tirc, lro_max_msg_sz, (priv->params.lro_wqe_sz -
+           ROUGH_MAX_L2_L3_HDR_SZ) >> 8);
+}
+
+static void
+mlx5e_hw_lro_set_tir_ctx(struct mlx5e_priv *priv, u32 *tirc)
+{
+       MLX5_SET(tirc, tirc, lro_enable_mask,
+           MLX5_TIRC_LRO_ENABLE_MASK_IPV4_LRO |
+           MLX5_TIRC_LRO_ENABLE_MASK_IPV6_LRO);
+       /* TODO: add the option to choose timer value dynamically */
+       MLX5_SET(tirc, tirc, lro_timeout_period_usecs,
+           MLX5_CAP_ETH(priv->mdev, lro_timer_supported_periods[2]));
+       mlx5e_hw_lro_set_tir_ctx_lro_max_msg_sz(priv, tirc);
+}
+
+static int
+mlx5e_hw_lro_update_tir(struct mlx5e_priv *priv, int tt, bool inner_vxlan)
+{
+       struct mlx5_core_dev *mdev = priv->mdev;
+       u32 *in;
+       void *tirc;
+       int inlen;
+       int err;
+
+       inlen = MLX5_ST_SZ_BYTES(modify_tir_in);
+       in = mlx5_vzalloc(inlen);
+       if (in == NULL)
+               return (-ENOMEM);
+       tirc = MLX5_ADDR_OF(modify_tir_in, in, tir_context);
+
+       /* fill the command part */
+       MLX5_SET(modify_tir_in, in, tirn, inner_vxlan ?
+           priv->tirn_inner_vxlan[tt] : priv->tirn[tt]);
+       MLX5_SET64(modify_tir_in, in, modify_bitmask,
+           (1 << MLX5_MODIFY_TIR_BITMASK_LRO));
+
+       /* fill the context */
+       if (priv->params.hw_lro_en)
+               mlx5e_hw_lro_set_tir_ctx(priv, tirc);
+
+       err = mlx5_core_modify_tir(mdev, in, inlen);
+
+       kvfree(in);
+       return (err);
+}
+
+int
+mlx5e_hw_lro_update_tirs(struct mlx5e_priv *priv)
+{
+       int err, err1, i;
+
+       err = 0;
+       for (i = 0; i != 2 * MLX5E_NUM_TT; i++) {
+               err1 = mlx5e_hw_lro_update_tir(priv, i / 2, (i % 2) ? true :
+                   false);
+               if (err1 != 0 && err == 0)
+                       err = err1;
+       }
+       return (-err);
+}
+
 static void
 mlx5e_build_tir_ctx(struct mlx5e_priv *priv, u32 * tirc, int tt, bool 
inner_vxlan)
 {
@@ -2954,8 +3021,6 @@ mlx5e_build_tir_ctx(struct mlx5e_priv *priv, u32 * tirc, 
int tt, bool inner_vxla
 
        MLX5_SET(tirc, tirc, transport_domain, priv->tdn);
 
-#define        ROUGH_MAX_L2_L3_HDR_SZ 256
-
 #define        MLX5_HASH_IP     (MLX5_HASH_FIELD_SEL_SRC_IP   |\
                          MLX5_HASH_FIELD_SEL_DST_IP)
 
@@ -2968,18 +3033,8 @@ mlx5e_build_tir_ctx(struct mlx5e_priv *priv, u32 * tirc, 
int tt, bool inner_vxla
                                 MLX5_HASH_FIELD_SEL_DST_IP   |\
                                 MLX5_HASH_FIELD_SEL_IPSEC_SPI)
 
-       if (priv->params.hw_lro_en) {
-               MLX5_SET(tirc, tirc, lro_enable_mask,
-                   MLX5_TIRC_LRO_ENABLE_MASK_IPV4_LRO |
-                   MLX5_TIRC_LRO_ENABLE_MASK_IPV6_LRO);
-               MLX5_SET(tirc, tirc, lro_max_msg_sz,
-                   (priv->params.lro_wqe_sz -
-                   ROUGH_MAX_L2_L3_HDR_SZ) >> 8);
-               /* TODO: add the option to choose timer value dynamically */
-               MLX5_SET(tirc, tirc, lro_timeout_period_usecs,
-                   MLX5_CAP_ETH(priv->mdev,
-                   lro_timer_supported_periods[2]));
-       }
+       if (priv->params.hw_lro_en)
+               mlx5e_hw_lro_set_tir_ctx(priv, tirc);
 
        if (inner_vxlan)
                MLX5_SET(tirc, tirc, tunneled_offload_en, 1);

Reply via email to