From nobody Sun Feb 8 04:31:00 2026 Received: from mail-yw1-f170.google.com (mail-yw1-f170.google.com [209.85.128.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C7BE82D9786 for ; Wed, 22 Oct 2025 19:09:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761160176; cv=none; b=eiuX6S4jNUGzPlX534q/3I/sCDEBgz+bB75juOm8POsHAm8k+7MglHvxPFQK0K7Imz3PskdjZwIPMmeFufgAizbXGSI6NYzTO/qH3hoeB5ek5AKJlP+iaqav5cj4gKAuV70tbYDEnN3Y+Cwc7Csmgp0YFkdDwNLYgHat7d5ZLV8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761160176; c=relaxed/simple; bh=3VROX7oYWFgfXwv1tuulpG3URc0xaVThq+McA4Nkwwk=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=qL4iAQuyOMeEd35SLmhIDsdhjj+isTiZVdE38DiX2nDeluxgn92G4juZA6NW6RxcsVrtqZZoUAJtiBXvI5Fu31AK2xdS7PAgiRXTlg2iaj3o6xnXgUw/LW4cQdR0w0eFc+Gr5lCyyy30EFn3LHnMcKxmqfGzIf/E5eH4p8+Ywpw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=JzgGgL9t; arc=none smtp.client-ip=209.85.128.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="JzgGgL9t" Received: by mail-yw1-f170.google.com with SMTP id 00721157ae682-7847f4265e3so52175397b3.3 for ; Wed, 22 Oct 2025 12:09:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1761160174; x=1761764974; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=xzTmRaie4StC1dGzPSKJ0L/pPh8vFC7i5HLcbKg6U3w=; b=JzgGgL9tKApy2KWE/BcEiNGXkYXAi5j6me1UXBFNxhjYSK2PgsSBM+P1Q8sSrotod+ 9j4ZkslKR5eaGwetnEfRrNl/HtTBXyZltTqCHAz66fiuWOjMWVkoCaM7DWigSAyRKN68 CyzsHfice8G9wpTnN18eFAMpMn3fdHvVdjJ+I0igqR1XBcLXKzHB02NqH4ebeJuW3ixo KcfL59Vhgmg+mRTjiT6RT/XOL0F22UByilT3vm1jfdnOV5wc7iUQJWPQHui3XNWzn4Za sZ6IoF7fqbHKbATHr1SyGZDVj6vQSoBLVthX/FOUK+yrFX7DyOOlcDyLgSxUgAAe+4OS /DxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761160174; x=1761764974; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=xzTmRaie4StC1dGzPSKJ0L/pPh8vFC7i5HLcbKg6U3w=; b=FpQqJ3u/h0V+SBQgwskc1Blj85fXJsBBX3zDOg7nE8dGMKWpDRIRBlMpv2Wc71sHlP iULPHioIftCKAEia3f4mXFl8cjyRvncZRQ5xitUtsW1o3rXykkbaMfv6eVQ1bAWNqnVI O9L9FBLbb6dIrwMFHL0TgyN72xBOCO0u/EUFB57PioxlPcXnmtDY/W4cXil99PJrxRxt s+ZeA9JN2C5YnJ1Yn6996HvFExRYbk/xrQDyxbadqHLTEgHttBOAU1BqxKrEwld5URqk x9wghwwYktIFl3B8L4g5JBIGtyd4uxchPqzduUoy2AClfaxIgWTTZYcPZ1gIzlv2rJzL FFCQ== X-Forwarded-Encrypted: i=1; AJvYcCVnTRAU8QDg5O7VlmiCpe7y5+WkJwwkErUAF86VVRRTEJeI6xajGtX9WO/C5cHPTYSCflS7w6kHO1dyZwc=@vger.kernel.org X-Gm-Message-State: AOJu0YyX6RMr4QlQgiX7G3HCfWdXVgHmUrP6ZYDkzUaLZsnHX1XxVmHQ Xu9JLp9XrT1Md6jZZ9n6CkjvFL1/4VTV0yiyKWWSYtEMnJh3iRjsg8cD X-Gm-Gg: ASbGncutBPNOz++cGQeh25dabHEI7iLgwn67Jm4W1rN2dDYaZzJcDwyPTKz8Gfhis8S MzlLZQAc0WlMLxQy+Sgx3kqjs2FaLogMjnFtUhB0yaQcYYmjPXN0e/y89T9Z+/PtBC2kAEq/M3E K/5hvcALqouSpqHYId6+yRce4J9kIGRsz2/gTqSMcP/By5QpCaWw9wPrt1Y358mD5VqB6Irpg0g R4DO+MB13keBbEM7eXGOo74YtT0wwo8SckT3Zeu4hUu/CWDOsZEpL7nlN/TbW7qpFhs0Ge6xols rRcGIyjVPjaMvRk2GMdg1aj077Q1eHEd/H6rxuCSvOLNkp+lVA6GiDSjf6swDyMDg9OxMOVpLFu TjLdi90kWBog5WGua+MEUqmM6/Hxpo0777IXVnymt19/6pDk0oU8dnO0Wl5cGa2aEFZtaMBPpFG gyaKnscxmxFw== X-Google-Smtp-Source: AGHT+IFLQTLJQyjspIyGqUq/yqC1W5RgRAenuW9qYN36aVJfjtQDXjWYUcesxNEH2cwFI0pnRQWVWg== X-Received: by 2002:a05:690c:67c5:b0:780:d2cc:3c2d with SMTP id 00721157ae682-7836d4cdb4dmr176165967b3.1.1761160173725; Wed, 22 Oct 2025 12:09:33 -0700 (PDT) Received: from localhost ([2a03:2880:25ff:50::]) by smtp.gmail.com with ESMTPSA id 00721157ae682-785cd5e23e4sm199907b3.22.2025.10.22.12.09.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Oct 2025 12:09:33 -0700 (PDT) From: Daniel Zahka To: Jiri Pirko , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Saeed Mahameed , Tariq Toukan Cc: Simon Horman , Jonathan Corbet , Leon Romanovsky , Mark Bloch , Andrew Lunn , Vlad Dumitrescu , netdev@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-rdma@vger.kernel.org Subject: [PATCH net-next] net/mlx5: Implement swp_l4_csum_mode via devlink params Date: Wed, 22 Oct 2025 12:09:31 -0700 Message-ID: <20251022190932.1073898-1-daniel.zahka@gmail.com> X-Mailer: git-send-email 2.47.3 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" swp_l4_csum_mode controls how L4 transmit checksums are computed when using Software Parser (SWP) hints for header locations. Supported values: 1. device_default: use device default setting. 2. full_csum: calculate L4 checksum with the psuedo-header. 3. l4_only: calculate L4 checksum without the psuedo-header. Only available when swp_l4_csum_mode_l4_only is set in mlx5_ifc_nv_sw_offload_cap_bits. The l4_only setting is a dependency for PSP initialization in mlx5e_psp_init(). Signed-off-by: Daniel Zahka --- Documentation/networking/devlink/mlx5.rst | 9 ++ .../net/ethernet/mellanox/mlx5/core/devlink.h | 3 +- .../mellanox/mlx5/core/lib/nv_param.c | 148 ++++++++++++++++++ 3 files changed, 159 insertions(+), 1 deletion(-) diff --git a/Documentation/networking/devlink/mlx5.rst b/Documentation/netw= orking/devlink/mlx5.rst index 0e5f9c76e514..f366e551b2f7 100644 --- a/Documentation/networking/devlink/mlx5.rst +++ b/Documentation/networking/devlink/mlx5.rst @@ -218,6 +218,15 @@ parameters. * ``balanced`` : Merges fewer CQEs, resulting in a moderate compres= sion ratio but maintaining a balance between bandwidth savings and performa= nce * ``aggressive`` : Merges more CQEs into a single entry, achieving = a higher compression rate and maximizing performance, particularly under hi= gh traffic loads =20 + * - ``swp_l4_csum_mode`` + - string + - permanent + - Configure how the L4 checksum is calculated by the device when usi= ng + Software Parser (SWP) hints for header locations. + * ``device_default`` : Use the device's default checksum calculati= on mode + * ``full_csum`` : Calculate full checksum including the pseudo-hea= der + * ``l4_only`` : Calculate L4-only checksum, excluding the pseudo-h= eader + The ``mlx5`` driver supports reloading via ``DEVLINK_CMD_RELOAD`` =20 Info versions diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.h b/drivers/ne= t/ethernet/mellanox/mlx5/core/devlink.h index c9555119a661..43b9bf8829cf 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.h @@ -26,7 +26,8 @@ enum mlx5_devlink_param_id { MLX5_DEVLINK_PARAM_ID_PCIE_CONG_IN_HIGH, MLX5_DEVLINK_PARAM_ID_PCIE_CONG_OUT_LOW, MLX5_DEVLINK_PARAM_ID_PCIE_CONG_OUT_HIGH, - MLX5_DEVLINK_PARAM_ID_CQE_COMPRESSION_TYPE + MLX5_DEVLINK_PARAM_ID_CQE_COMPRESSION_TYPE, + MLX5_DEVLINK_PARAM_ID_SWP_L4_CSUM_MODE, }; =20 struct mlx5_trap_ctx { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/nv_param.c b/drive= rs/net/ethernet/mellanox/mlx5/core/lib/nv_param.c index 459a0b4d08e6..fac3d9801b3b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/nv_param.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/nv_param.c @@ -8,6 +8,8 @@ enum { MLX5_CLASS_0_CTRL_ID_NV_GLOBAL_PCI_CONF =3D 0x80, MLX5_CLASS_0_CTRL_ID_NV_GLOBAL_PCI_CAP =3D 0x81, MLX5_CLASS_0_CTRL_ID_NV_SW_OFFLOAD_CONFIG =3D 0x10a, + MLX5_CLASS_0_CTRL_ID_NV_SW_OFFLOAD_CAP =3D 0x10b, + MLX5_CLASS_0_CTRL_ID_NV_SW_ACCELERATE_CONF =3D 0x11d, =20 MLX5_CLASS_3_CTRL_ID_NV_PF_PCI_CONF =3D 0x80, }; @@ -123,6 +125,17 @@ struct mlx5_ifc_nv_sw_offload_conf_bits { u8 lro_log_timeout0[0x4]; }; =20 +struct mlx5_ifc_nv_sw_offload_cap_bits { + u8 reserved_at_0[0x19]; + u8 swp_l4_csum_mode_l4_only[0x1]; + u8 reserved_at_1a[0x6]; +}; + +struct mlx5_ifc_nv_sw_accelerate_conf_bits { + u8 swp_l4_csum_mode[0x2]; + u8 reserved_at_2[0x3e]; +}; + #define MNVDA_HDR_SZ \ (MLX5_ST_SZ_BYTES(mnvda_reg) - \ MLX5_BYTE_OFF(mnvda_reg, configuration_item_data)) @@ -195,9 +208,42 @@ mlx5_nv_param_read_sw_offload_conf(struct mlx5_core_de= v *dev, void *mnvda, return mlx5_nv_param_read(dev, mnvda, len); } =20 +static int +mlx5_nv_param_read_sw_offload_cap(struct mlx5_core_dev *dev, void *mnvda, + size_t len) +{ + MLX5_SET_CFG_ITEM_TYPE(global, mnvda, type_class, 0); + MLX5_SET_CFG_ITEM_TYPE(global, mnvda, parameter_index, + MLX5_CLASS_0_CTRL_ID_NV_SW_OFFLOAD_CAP); + MLX5_SET_CFG_HDR_LEN(mnvda, nv_sw_offload_cap); + + return mlx5_nv_param_read(dev, mnvda, len); +} + +static int +mlx5_nv_param_read_sw_accelerate_conf(struct mlx5_core_dev *dev, void *mnv= da, + size_t len) +{ + MLX5_SET_CFG_ITEM_TYPE(global, mnvda, type_class, 0); + MLX5_SET_CFG_ITEM_TYPE(global, mnvda, parameter_index, + MLX5_CLASS_0_CTRL_ID_NV_SW_ACCELERATE_CONF); + MLX5_SET_CFG_HDR_LEN(mnvda, nv_sw_accelerate_conf); + + return mlx5_nv_param_read(dev, mnvda, len); +} + static const char *const cqe_compress_str[] =3D { "balanced", "aggressive" }; =20 +enum swp_l4_csum_mode { + SWP_L4_CSUM_MODE_DEVICE_DEFAULT =3D 0, + SWP_L4_CSUM_MODE_FULL_CSUM =3D 1, + SWP_L4_CSUM_MODE_L4_ONLY =3D 2, +}; + +static const char *const + swp_l4_csum_mode_str[] =3D { "device_default", "full_csum", "l4_only" }; + static int mlx5_nv_param_devlink_cqe_compress_get(struct devlink *devlink, u32 id, struct devlink_param_gset_ctx *ctx) @@ -268,6 +314,102 @@ mlx5_nv_param_devlink_cqe_compress_set(struct devlink= *devlink, u32 id, return mlx5_nv_param_write(dev, mnvda, sizeof(mnvda)); } =20 +static int +mlx5_nv_param_devlink_swp_l4_csum_mode_get(struct devlink *devlink, u32 id, + struct devlink_param_gset_ctx *ctx) +{ + struct mlx5_core_dev *dev =3D devlink_priv(devlink); + u32 mnvda[MLX5_ST_SZ_DW(mnvda_reg)] =3D {}; + u8 value =3D U8_MAX; + void *data; + int err; + + err =3D mlx5_nv_param_read_sw_accelerate_conf(dev, mnvda, sizeof(mnvda)); + if (err) + return err; + + data =3D MLX5_ADDR_OF(mnvda_reg, mnvda, configuration_item_data); + value =3D MLX5_GET(nv_sw_accelerate_conf, data, swp_l4_csum_mode); + + if (value >=3D ARRAY_SIZE(swp_l4_csum_mode_str)) + return -EOPNOTSUPP; + + strscpy(ctx->val.vstr, swp_l4_csum_mode_str[value], + sizeof(ctx->val.vstr)); + return 0; +} + +static int +mlx5_nv_param_devlink_swp_l4_csum_mode_validate(struct devlink *devlink, u= 32 id, + union devlink_param_value val, + struct netlink_ext_ack *extack) +{ + struct mlx5_core_dev *dev =3D devlink_priv(devlink); + u32 cap[MLX5_ST_SZ_DW(mnvda_reg)] =3D {}; + void *data; + int err, i; + + for (i =3D 0; i < ARRAY_SIZE(swp_l4_csum_mode_str); i++) { + if (!strcmp(val.vstr, swp_l4_csum_mode_str[i])) + break; + } + + if (i >=3D ARRAY_SIZE(swp_l4_csum_mode_str)) { + NL_SET_ERR_MSG_MOD(extack, + "Invalid value, supported values are device_default/full_csum/l4_on= ly"); + return -EINVAL; + } + + if (i =3D=3D SWP_L4_CSUM_MODE_L4_ONLY) { + err =3D mlx5_nv_param_read_sw_offload_cap(dev, cap, sizeof(cap)); + if (err) { + NL_SET_ERR_MSG_MOD(extack, + "Failed to read sw_offload_cap"); + return err; + } + + data =3D MLX5_ADDR_OF(mnvda_reg, cap, configuration_item_data); + if (!MLX5_GET(nv_sw_offload_cap, data, swp_l4_csum_mode_l4_only)) { + NL_SET_ERR_MSG_MOD(extack, + "l4_only mode is not supported on this device"); + return -EOPNOTSUPP; + } + } + + return 0; +} + +static int +mlx5_nv_param_devlink_swp_l4_csum_mode_set(struct devlink *devlink, u32 id, + struct devlink_param_gset_ctx *ctx, + struct netlink_ext_ack *extack) +{ + struct mlx5_core_dev *dev =3D devlink_priv(devlink); + u32 mnvda[MLX5_ST_SZ_DW(mnvda_reg)] =3D {}; + void *data; + u8 value; + int err; + + if (!strcmp(ctx->val.vstr, "device_default")) + value =3D SWP_L4_CSUM_MODE_DEVICE_DEFAULT; + else if (!strcmp(ctx->val.vstr, "full_csum")) + value =3D SWP_L4_CSUM_MODE_FULL_CSUM; + else + value =3D SWP_L4_CSUM_MODE_L4_ONLY; + + err =3D mlx5_nv_param_read_sw_accelerate_conf(dev, mnvda, sizeof(mnvda)); + if (err) { + NL_SET_ERR_MSG_MOD(extack, + "Failed to read sw_accelerate_conf mnvda reg"); + return err; + } + + data =3D MLX5_ADDR_OF(mnvda_reg, mnvda, configuration_item_data); + MLX5_SET(nv_sw_accelerate_conf, data, swp_l4_csum_mode, value); + + return mlx5_nv_param_write(dev, mnvda, sizeof(mnvda)); +} + static int mlx5_nv_param_read_global_pci_conf(struct mlx5_core_dev *dev, void *mnvda, size_t len) { @@ -545,6 +687,12 @@ static const struct devlink_param mlx5_nv_param_devlin= k_params[] =3D { mlx5_nv_param_devlink_cqe_compress_get, mlx5_nv_param_devlink_cqe_compress_set, mlx5_nv_param_devlink_cqe_compress_validate), + DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_SWP_L4_CSUM_MODE, + "swp_l4_csum_mode", DEVLINK_PARAM_TYPE_STRING, + BIT(DEVLINK_PARAM_CMODE_PERMANENT), + mlx5_nv_param_devlink_swp_l4_csum_mode_get, + mlx5_nv_param_devlink_swp_l4_csum_mode_set, + mlx5_nv_param_devlink_swp_l4_csum_mode_validate), }; =20 int mlx5_nv_param_register_dl_params(struct devlink *devlink) --=20 2.47.3