git: 02fe38b92175 - main - mlx5en: make the hw lro control dynamic
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 13 Mar 2025 16:03:13 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=02fe38b92175cb8f3a77f7a2bb72afb83836ebd2
commit 02fe38b92175cb8f3a77f7a2bb72afb83836ebd2
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-01-29 15:45:18 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-03-13 15:58:53 +0000
mlx5en: make the hw lro control dynamic
Reviewed by: Ariel Ehrenberg <aehrenberg@nvidia.com>, Slava Shwartsman <slavash@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);