Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net/mlx5: implement swp_l4_csum_mode via devlink params

swp_l4_csum_mode controls how L4 transmit checksums are computed when
using Software Parser (SWP) hints for header locations.

Supported values:
1. default: device will choose between full_csum or l4_only. Driver
will discover the device's choice during initialization.
2. full_csum: calculate L4 checksum with the pseudo-header.
3. l4_only: calculate L4 checksum without the pseudo-header. Only
available when swp_l4_csum_mode_l4_only is set in
mlx5_ifc_nv_sw_offload_cap_bits.

Note that 'default' might be returned from the device and passed to
userspace, and it might also be set during a
devlink_param::reset_default() call, but attempts to set a value of
default directly with param-set will be rejected.

The l4_only setting is a dependency for PSP initialization in
mlx5e_psp_init().

Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Signed-off-by: Daniel Zahka <daniel.zahka@gmail.com>
Link: https://patch.msgid.link/20251119025038.651131-5-daniel.zahka@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Daniel Zahka and committed by
Jakub Kicinski
b11d358b 2a367002

+245 -1
+14
Documentation/networking/devlink/mlx5.rst
··· 218 218 * ``balanced`` : Merges fewer CQEs, resulting in a moderate compression ratio but maintaining a balance between bandwidth savings and performance 219 219 * ``aggressive`` : Merges more CQEs into a single entry, achieving a higher compression rate and maximizing performance, particularly under high traffic loads 220 220 221 + * - ``swp_l4_csum_mode`` 222 + - string 223 + - permanent 224 + - Configure how the L4 checksum is calculated by the device when using 225 + Software Parser (SWP) hints for header locations. 226 + 227 + * ``default`` : Use the device's default checksum calculation 228 + mode. The driver will discover during init whether or 229 + full_csum or l4_only is in use. Setting this value explicitly 230 + from userspace is not allowed, but some firmware versions may 231 + return this value on param read. 232 + * ``full_csum`` : Calculate full checksum including the pseudo-header 233 + * ``l4_only`` : Calculate L4-only checksum, excluding the pseudo-header 234 + 221 235 The ``mlx5`` driver supports reloading via ``DEVLINK_CMD_RELOAD`` 222 236 223 237 Info versions
+2 -1
drivers/net/ethernet/mellanox/mlx5/core/devlink.h
··· 26 26 MLX5_DEVLINK_PARAM_ID_PCIE_CONG_IN_HIGH, 27 27 MLX5_DEVLINK_PARAM_ID_PCIE_CONG_OUT_LOW, 28 28 MLX5_DEVLINK_PARAM_ID_PCIE_CONG_OUT_HIGH, 29 - MLX5_DEVLINK_PARAM_ID_CQE_COMPRESSION_TYPE 29 + MLX5_DEVLINK_PARAM_ID_CQE_COMPRESSION_TYPE, 30 + MLX5_DEVLINK_PARAM_ID_SWP_L4_CSUM_MODE, 30 31 }; 31 32 32 33 struct mlx5_trap_ctx {
+229
drivers/net/ethernet/mellanox/mlx5/core/lib/nv_param.c
··· 8 8 MLX5_CLASS_0_CTRL_ID_NV_GLOBAL_PCI_CONF = 0x80, 9 9 MLX5_CLASS_0_CTRL_ID_NV_GLOBAL_PCI_CAP = 0x81, 10 10 MLX5_CLASS_0_CTRL_ID_NV_SW_OFFLOAD_CONFIG = 0x10a, 11 + MLX5_CLASS_0_CTRL_ID_NV_SW_OFFLOAD_CAP = 0x10b, 12 + MLX5_CLASS_0_CTRL_ID_NV_SW_ACCELERATE_CONF = 0x11d, 11 13 12 14 MLX5_CLASS_3_CTRL_ID_NV_PF_PCI_CONF = 0x80, 13 15 }; ··· 32 30 struct mlx5_ifc_configuration_item_type_class_per_host_pf_bits 33 31 configuration_item_type_class_per_host_pf; 34 32 u8 reserved_at_0[0x20]; 33 + }; 34 + 35 + enum { 36 + MLX5_ACCESS_MODE_NEXT = 0, 37 + MLX5_ACCESS_MODE_CURRENT, 38 + MLX5_ACCESS_MODE_DEFAULT, 35 39 }; 36 40 37 41 struct mlx5_ifc_config_item_bits { ··· 131 123 u8 lro_log_timeout0[0x4]; 132 124 }; 133 125 126 + struct mlx5_ifc_nv_sw_offload_cap_bits { 127 + u8 reserved_at_0[0x19]; 128 + u8 swp_l4_csum_mode_l4_only[0x1]; 129 + u8 reserved_at_1a[0x6]; 130 + }; 131 + 132 + struct mlx5_ifc_nv_sw_accelerate_conf_bits { 133 + u8 swp_l4_csum_mode[0x2]; 134 + u8 reserved_at_2[0x3e]; 135 + }; 136 + 134 137 #define MNVDA_HDR_SZ \ 135 138 (MLX5_ST_SZ_BYTES(mnvda_reg) - \ 136 139 MLX5_BYTE_OFF(mnvda_reg, configuration_item_data)) ··· 210 191 MLX5_SET_CFG_ITEM_TYPE(global, mnvda, parameter_index, 211 192 MLX5_CLASS_0_CTRL_ID_NV_SW_OFFLOAD_CONFIG); 212 193 MLX5_SET_CFG_HDR_LEN(mnvda, nv_sw_offload_conf); 194 + 195 + return mlx5_nv_param_read(dev, mnvda, len); 196 + } 197 + 198 + static int 199 + mlx5_nv_param_read_sw_offload_cap(struct mlx5_core_dev *dev, void *mnvda, 200 + size_t len) 201 + { 202 + MLX5_SET_CFG_ITEM_TYPE(global, mnvda, type_class, 0); 203 + MLX5_SET_CFG_ITEM_TYPE(global, mnvda, parameter_index, 204 + MLX5_CLASS_0_CTRL_ID_NV_SW_OFFLOAD_CAP); 205 + MLX5_SET_CFG_HDR_LEN(mnvda, nv_sw_offload_cap); 206 + 207 + return mlx5_nv_param_read(dev, mnvda, len); 208 + } 209 + 210 + static int 211 + mlx5_nv_param_read_sw_accelerate_conf(struct mlx5_core_dev *dev, void *mnvda, 212 + size_t len, int access_mode) 213 + { 214 + MLX5_SET_CFG_ITEM_TYPE(global, mnvda, type_class, 0); 215 + MLX5_SET_CFG_ITEM_TYPE(global, mnvda, parameter_index, 216 + MLX5_CLASS_0_CTRL_ID_NV_SW_ACCELERATE_CONF); 217 + MLX5_SET_CFG_HDR_LEN(mnvda, nv_sw_accelerate_conf); 218 + MLX5_SET(mnvda_reg, mnvda, configuration_item_header.access_mode, 219 + access_mode); 213 220 214 221 return mlx5_nv_param_read(dev, mnvda, len); 215 222 } ··· 312 267 MLX5_SET(nv_sw_offload_conf, data, cqe_compression, value); 313 268 314 269 return mlx5_nv_param_write(dev, mnvda, sizeof(mnvda)); 270 + } 271 + 272 + enum swp_l4_csum_mode { 273 + SWP_L4_CSUM_MODE_DEFAULT = 0, 274 + SWP_L4_CSUM_MODE_FULL_CSUM = 1, 275 + SWP_L4_CSUM_MODE_L4_ONLY = 2, 276 + }; 277 + 278 + static const char *const 279 + swp_l4_csum_mode_str[] = { "default", "full_csum", "l4_only" }; 280 + 281 + static int 282 + mlx5_swp_l4_csum_mode_get(struct devlink *devlink, u32 id, 283 + int access_mode, u8 *value, 284 + struct netlink_ext_ack *extack) 285 + { 286 + struct mlx5_core_dev *dev = devlink_priv(devlink); 287 + u32 mnvda[MLX5_ST_SZ_DW(mnvda_reg)] = {}; 288 + void *data; 289 + int err; 290 + 291 + err = mlx5_nv_param_read_sw_accelerate_conf(dev, mnvda, sizeof(mnvda), 292 + access_mode); 293 + if (err) { 294 + NL_SET_ERR_MSG_MOD(extack, 295 + "Failed to read sw_accelerate_conf mnvda reg"); 296 + return err; 297 + } 298 + 299 + data = MLX5_ADDR_OF(mnvda_reg, mnvda, configuration_item_data); 300 + *value = MLX5_GET(nv_sw_accelerate_conf, data, swp_l4_csum_mode); 301 + 302 + if (*value >= ARRAY_SIZE(swp_l4_csum_mode_str)) { 303 + NL_SET_ERR_MSG_FMT_MOD(extack, 304 + "Invalid swp_l4_csum_mode value %u read from device", 305 + *value); 306 + return -EINVAL; 307 + } 308 + 309 + return 0; 310 + } 311 + 312 + static int 313 + mlx5_devlink_swp_l4_csum_mode_get(struct devlink *devlink, u32 id, 314 + struct devlink_param_gset_ctx *ctx, 315 + struct netlink_ext_ack *extack) 316 + { 317 + u8 value; 318 + int err; 319 + 320 + err = mlx5_swp_l4_csum_mode_get(devlink, id, MLX5_ACCESS_MODE_NEXT, 321 + &value, extack); 322 + if (err) 323 + return err; 324 + 325 + strscpy(ctx->val.vstr, swp_l4_csum_mode_str[value], 326 + sizeof(ctx->val.vstr)); 327 + return 0; 328 + } 329 + 330 + static int 331 + mlx5_devlink_swp_l4_csum_mode_validate(struct devlink *devlink, u32 id, 332 + union devlink_param_value val, 333 + struct netlink_ext_ack *extack) 334 + { 335 + struct mlx5_core_dev *dev = devlink_priv(devlink); 336 + u32 cap[MLX5_ST_SZ_DW(mnvda_reg)] = {}; 337 + void *data; 338 + int err, i; 339 + 340 + for (i = 0; i < ARRAY_SIZE(swp_l4_csum_mode_str); i++) { 341 + if (!strcmp(val.vstr, swp_l4_csum_mode_str[i])) 342 + break; 343 + } 344 + 345 + if (i >= ARRAY_SIZE(swp_l4_csum_mode_str) || 346 + i == SWP_L4_CSUM_MODE_DEFAULT) { 347 + NL_SET_ERR_MSG_MOD(extack, 348 + "Invalid value, supported values are full_csum/l4_only"); 349 + return -EINVAL; 350 + } 351 + 352 + if (i == SWP_L4_CSUM_MODE_L4_ONLY) { 353 + err = mlx5_nv_param_read_sw_offload_cap(dev, cap, sizeof(cap)); 354 + if (err) { 355 + NL_SET_ERR_MSG_MOD(extack, 356 + "Failed to read sw_offload_cap"); 357 + return err; 358 + } 359 + 360 + data = MLX5_ADDR_OF(mnvda_reg, cap, configuration_item_data); 361 + if (!MLX5_GET(nv_sw_offload_cap, data, swp_l4_csum_mode_l4_only)) { 362 + NL_SET_ERR_MSG_MOD(extack, 363 + "l4_only mode is not supported on this device"); 364 + return -EOPNOTSUPP; 365 + } 366 + } 367 + 368 + return 0; 369 + } 370 + 371 + static int 372 + mlx5_swp_l4_csum_mode_set(struct devlink *devlink, u32 id, u8 value, 373 + struct netlink_ext_ack *extack) 374 + { 375 + struct mlx5_core_dev *dev = devlink_priv(devlink); 376 + u32 mnvda[MLX5_ST_SZ_DW(mnvda_reg)] = {}; 377 + void *data; 378 + int err; 379 + 380 + err = mlx5_nv_param_read_sw_accelerate_conf(dev, mnvda, sizeof(mnvda), 381 + MLX5_ACCESS_MODE_NEXT); 382 + if (err) { 383 + NL_SET_ERR_MSG_MOD(extack, 384 + "Failed to read sw_accelerate_conf mnvda reg"); 385 + return err; 386 + } 387 + 388 + data = MLX5_ADDR_OF(mnvda_reg, mnvda, configuration_item_data); 389 + MLX5_SET(nv_sw_accelerate_conf, data, swp_l4_csum_mode, value); 390 + 391 + err = mlx5_nv_param_write(dev, mnvda, sizeof(mnvda)); 392 + if (err) 393 + NL_SET_ERR_MSG_MOD(extack, 394 + "Failed to write sw_accelerate_conf mnvda reg"); 395 + 396 + return err; 397 + } 398 + 399 + static int 400 + mlx5_devlink_swp_l4_csum_mode_set(struct devlink *devlink, u32 id, 401 + struct devlink_param_gset_ctx *ctx, 402 + struct netlink_ext_ack *extack) 403 + { 404 + u8 value; 405 + 406 + if (!strcmp(ctx->val.vstr, "full_csum")) 407 + value = SWP_L4_CSUM_MODE_FULL_CSUM; 408 + else 409 + value = SWP_L4_CSUM_MODE_L4_ONLY; 410 + 411 + return mlx5_swp_l4_csum_mode_set(devlink, id, value, extack); 412 + } 413 + 414 + static int 415 + mlx5_devlink_swp_l4_csum_mode_get_default(struct devlink *devlink, u32 id, 416 + struct devlink_param_gset_ctx *ctx, 417 + struct netlink_ext_ack *extack) 418 + { 419 + u8 value; 420 + int err; 421 + 422 + err = mlx5_swp_l4_csum_mode_get(devlink, id, MLX5_ACCESS_MODE_DEFAULT, 423 + &value, extack); 424 + if (err) 425 + return err; 426 + 427 + strscpy(ctx->val.vstr, swp_l4_csum_mode_str[value], 428 + sizeof(ctx->val.vstr)); 429 + return 0; 430 + } 431 + 432 + static int 433 + mlx5_devlink_swp_l4_csum_mode_set_default(struct devlink *devlink, u32 id, 434 + enum devlink_param_cmode cmode, 435 + struct netlink_ext_ack *extack) 436 + { 437 + u8 value; 438 + int err; 439 + 440 + err = mlx5_swp_l4_csum_mode_get(devlink, id, MLX5_ACCESS_MODE_DEFAULT, 441 + &value, extack); 442 + if (err) 443 + return err; 444 + 445 + return mlx5_swp_l4_csum_mode_set(devlink, id, value, extack); 315 446 } 316 447 317 448 static int mlx5_nv_param_read_global_pci_conf(struct mlx5_core_dev *dev, ··· 769 548 mlx5_nv_param_devlink_cqe_compress_get, 770 549 mlx5_nv_param_devlink_cqe_compress_set, 771 550 mlx5_nv_param_devlink_cqe_compress_validate), 551 + DEVLINK_PARAM_DRIVER_WITH_DEFAULTS(MLX5_DEVLINK_PARAM_ID_SWP_L4_CSUM_MODE, 552 + "swp_l4_csum_mode", DEVLINK_PARAM_TYPE_STRING, 553 + BIT(DEVLINK_PARAM_CMODE_PERMANENT), 554 + mlx5_devlink_swp_l4_csum_mode_get, 555 + mlx5_devlink_swp_l4_csum_mode_set, 556 + mlx5_devlink_swp_l4_csum_mode_validate, 557 + mlx5_devlink_swp_l4_csum_mode_get_default, 558 + mlx5_devlink_swp_l4_csum_mode_set_default), 772 559 }; 773 560 774 561 int mlx5_nv_param_register_dl_params(struct devlink *devlink)