aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2025-01-29 15:45:18 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2025-03-13 15:58:53 +0000
commit02fe38b92175cb8f3a77f7a2bb72afb83836ebd2 (patch)
treef03ae44e53de6a9e118f1dc6ccdd748ef1f84ce4 /sys/dev
parent98071573638a1f31e4007894ce20a4fdc8e33a1d (diff)
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/mlx5/mlx5_en/en.h1
-rw-r--r--sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c3
-rw-r--r--sys/dev/mlx5/mlx5_en/mlx5_en_main.c83
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
@@ -2945,6 +2945,73 @@ mlx5e_get_rss_key(void *key_ptr)
}
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)
{
void *hfso = MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_outer);
@@ -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);