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.

Merge branch 'devlink-net-mlx5-implement-swp_l4_csum_mode-via-devlink-params'

Daniel Zahka says:

====================
devlink: net/mlx5: implement swp_l4_csum_mode via devlink params

This series introduces a new devlink feature for querying param
default values, and resetting params to their default values. This
feature is then used to implement a new mlx5 driver param.

The series starts with two pure refactor patches: one that passes
through the extack to devlink_param::get() implementations. And a
second small refactor that prepares the netlink tlv handling code in
the devlink_param::get() path to better handle default parameter
values.

The third patch introduces the uapi and driver api for default
parameter values. The driver api is opt-in, and both the uapi and
driver api preserve existing behavior when not used by drivers or
userspace.

The fourth patch introduces a new mlx5 driver param, swp_l4_csum_mode,
for controlling tx csum behavior. The "l4_only" value of this param is
a dependency for PSP initialization on CX7 NICs.

Lastly, the series introduces a new driver param with cmode runtime to
netdevsim, and then uses this param in a new testcase for netdevsim
devlink params.

Here are some examples of using the default param uapi with the devlink
cli. Note the devlink cli binary I am using has changes which I am
posting in accompanying series targeting iproute2-next:

# netdevsim
./devlink dev param show netdevsim/netdevsim0
netdevsim/netdevsim0:
name max_macs type generic
values:
cmode driverinit value 32 default 32
name test1 type driver-specific
values:
cmode driverinit value true default true

# set to false
./devlink dev param set netdevsim/netdevsim0 name test1 value false cmode driverinit
./devlink dev param show netdevsim/netdevsim0
netdevsim/netdevsim0:
name max_macs type generic
values:
cmode driverinit value 32 default 32
name test1 type driver-specific
values:
cmode driverinit value false default true

# set back to default
./devlink dev param set netdevsim/netdevsim0 name test1 default cmode driverinit
./devlink dev param show netdevsim/netdevsim0
netdevsim/netdevsim0:
name max_macs type generic
values:
cmode driverinit value 32 default 32
name test1 type driver-specific
values:
cmode driverinit value true default true

# mlx5 params on cx7
./devlink dev param show pci/0000:01:00.0
pci/0000:01:00.0:
name max_macs type generic
values:
cmode driverinit value 128 default 128
...
name swp_l4_csum_mode type driver-specific
values:
cmode permanent value default default default

# set to l4_only
./devlink dev param set pci/0000:01:00.0 name swp_l4_csum_mode value l4_only cmode permanent
./devlink dev param show pci/0000:01:00.0 name swp_l4_csum_mode
pci/0000:01:00.0:
name swp_l4_csum_mode type driver-specific
values:
cmode permanent value l4_only default default

# reset to default
./devlink dev param set pci/0000:01:00.0 name swp_l4_csum_mode default cmode permanent
./devlink dev param show pci/0000:01:00.0 name swp_l4_csum_mode
pci/0000:01:00.0:
name swp_l4_csum_mode type driver-specific
values:
cmode permanent value default default default
====================

Link: https://patch.msgid.link/20251119025038.651131-1-daniel.zahka@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+695 -93
+9
Documentation/netlink/specs/devlink.yaml
··· 859 859 name: health-reporter-burst-period 860 860 type: u64 861 861 doc: Time (in msec) for recoveries before starting the grace period. 862 + 863 + # TODO: fill in the attributes in between 864 + 865 + - 866 + name: param-reset-default 867 + type: flag 868 + doc: Request restoring parameter to its default value. 869 + value: 183 862 870 - 863 871 name: dl-dev-stats 864 872 subset-of: devlink ··· 1801 1793 - param-type 1802 1794 # param-value-data is missing here as the type is variable 1803 1795 - param-value-cmode 1796 + - param-reset-default 1804 1797 1805 1798 - 1806 1799 name: region-get
+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
+4 -2
drivers/crypto/marvell/octeontx2/otx2_cpt_devlink.c
··· 24 24 } 25 25 26 26 static int otx2_cpt_dl_uc_info(struct devlink *dl, u32 id, 27 - struct devlink_param_gset_ctx *ctx) 27 + struct devlink_param_gset_ctx *ctx, 28 + struct netlink_ext_ack *extack) 28 29 { 29 30 ctx->val.vstr[0] = '\0'; 30 31 ··· 33 32 } 34 33 35 34 static int otx2_cpt_dl_t106_mode_get(struct devlink *dl, u32 id, 36 - struct devlink_param_gset_ctx *ctx) 35 + struct devlink_param_gset_ctx *ctx, 36 + struct netlink_ext_ack *extack) 37 37 { 38 38 struct otx2_cpt_devlink *cpt_dl = devlink_priv(dl); 39 39 struct otx2_cptpf_dev *cptpf = cpt_dl->cptpf;
+2 -1
drivers/net/ethernet/amd/pds_core/core.h
··· 255 255 struct devlink_flash_update_params *params, 256 256 struct netlink_ext_ack *extack); 257 257 int pdsc_dl_enable_get(struct devlink *dl, u32 id, 258 - struct devlink_param_gset_ctx *ctx); 258 + struct devlink_param_gset_ctx *ctx, 259 + struct netlink_ext_ack *extack); 259 260 int pdsc_dl_enable_set(struct devlink *dl, u32 id, 260 261 struct devlink_param_gset_ctx *ctx, 261 262 struct netlink_ext_ack *extack);
+2 -1
drivers/net/ethernet/amd/pds_core/devlink.c
··· 22 22 } 23 23 24 24 int pdsc_dl_enable_get(struct devlink *dl, u32 id, 25 - struct devlink_param_gset_ctx *ctx) 25 + struct devlink_param_gset_ctx *ctx, 26 + struct netlink_ext_ack *extack) 26 27 { 27 28 struct pdsc *pdsc = devlink_priv(dl); 28 29 struct pdsc_viftype *vt_entry;
+4 -2
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
··· 1086 1086 } 1087 1087 1088 1088 static int bnxt_dl_nvm_param_get(struct devlink *dl, u32 id, 1089 - struct devlink_param_gset_ctx *ctx) 1089 + struct devlink_param_gset_ctx *ctx, 1090 + struct netlink_ext_ack *extack) 1090 1091 { 1091 1092 struct bnxt *bp = bnxt_get_bp_from_dl(dl); 1092 1093 struct hwrm_nvm_get_variable_input *req; ··· 1169 1168 } 1170 1169 1171 1170 static int bnxt_remote_dev_reset_get(struct devlink *dl, u32 id, 1172 - struct devlink_param_gset_ctx *ctx) 1171 + struct devlink_param_gset_ctx *ctx, 1172 + struct netlink_ext_ack *extack) 1173 1173 { 1174 1174 struct bnxt *bp = bnxt_get_bp_from_dl(dl); 1175 1175
+2 -1
drivers/net/ethernet/intel/i40e/i40e_devlink.c
··· 24 24 25 25 static int i40e_max_mac_per_vf_get(struct devlink *devlink, 26 26 u32 id, 27 - struct devlink_param_gset_ctx *ctx) 27 + struct devlink_param_gset_ctx *ctx, 28 + struct netlink_ext_ack *extack) 28 29 { 29 30 struct i40e_pf *pf = devlink_priv(devlink); 30 31
+10 -4
drivers/net/ethernet/intel/ice/devlink/devlink.c
··· 610 610 * @devlink: pointer to the devlink instance 611 611 * @id: the parameter ID to set 612 612 * @ctx: context to store the parameter value 613 + * @extack: netlink extended ACK structure 613 614 * 614 615 * Return: zero on success and negative value on failure. 615 616 */ 616 617 static int ice_devlink_tx_sched_layers_get(struct devlink *devlink, u32 id, 617 - struct devlink_param_gset_ctx *ctx) 618 + struct devlink_param_gset_ctx *ctx, 619 + struct netlink_ext_ack *extack) 618 620 { 619 621 struct ice_pf *pf = devlink_priv(devlink); 620 622 int err; ··· 1351 1349 1352 1350 static int 1353 1351 ice_devlink_enable_roce_get(struct devlink *devlink, u32 id, 1354 - struct devlink_param_gset_ctx *ctx) 1352 + struct devlink_param_gset_ctx *ctx, 1353 + struct netlink_ext_ack *extack) 1355 1354 { 1356 1355 struct ice_pf *pf = devlink_priv(devlink); 1357 1356 struct iidc_rdma_core_dev_info *cdev; ··· 1418 1415 1419 1416 static int 1420 1417 ice_devlink_enable_iw_get(struct devlink *devlink, u32 id, 1421 - struct devlink_param_gset_ctx *ctx) 1418 + struct devlink_param_gset_ctx *ctx, 1419 + struct netlink_ext_ack *extack) 1422 1420 { 1423 1421 struct ice_pf *pf = devlink_priv(devlink); 1424 1422 struct iidc_rdma_core_dev_info *cdev; ··· 1526 1522 * @devlink: Pointer to the devlink instance. 1527 1523 * @id: The parameter ID to set. 1528 1524 * @ctx: Context to store the parameter value. 1525 + * @extack: netlink extended ACK structure 1529 1526 * 1530 1527 * Return: Zero. 1531 1528 */ 1532 1529 static int ice_devlink_local_fwd_get(struct devlink *devlink, u32 id, 1533 - struct devlink_param_gset_ctx *ctx) 1530 + struct devlink_param_gset_ctx *ctx, 1531 + struct netlink_ext_ack *extack) 1534 1532 { 1535 1533 struct ice_pf *pf = devlink_priv(devlink); 1536 1534 struct ice_port_info *pi;
+10 -5
drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
··· 1233 1233 } 1234 1234 1235 1235 static int rvu_af_dl_dwrr_mtu_get(struct devlink *devlink, u32 id, 1236 - struct devlink_param_gset_ctx *ctx) 1236 + struct devlink_param_gset_ctx *ctx, 1237 + struct netlink_ext_ack *extack) 1237 1238 { 1238 1239 struct rvu_devlink *rvu_dl = devlink_priv(devlink); 1239 1240 struct rvu *rvu = rvu_dl->rvu; ··· 1260 1259 }; 1261 1260 1262 1261 static int rvu_af_npc_exact_feature_get(struct devlink *devlink, u32 id, 1263 - struct devlink_param_gset_ctx *ctx) 1262 + struct devlink_param_gset_ctx *ctx, 1263 + struct netlink_ext_ack *extack) 1264 1264 { 1265 1265 struct rvu_devlink *rvu_dl = devlink_priv(devlink); 1266 1266 struct rvu *rvu = rvu_dl->rvu; ··· 1316 1314 } 1317 1315 1318 1316 static int rvu_af_dl_npc_mcam_high_zone_percent_get(struct devlink *devlink, u32 id, 1319 - struct devlink_param_gset_ctx *ctx) 1317 + struct devlink_param_gset_ctx *ctx, 1318 + struct netlink_ext_ack *extack) 1320 1319 { 1321 1320 struct rvu_devlink *rvu_dl = devlink_priv(devlink); 1322 1321 struct rvu *rvu = rvu_dl->rvu; ··· 1379 1376 } 1380 1377 1381 1378 static int rvu_af_dl_npc_def_rule_cntr_get(struct devlink *devlink, u32 id, 1382 - struct devlink_param_gset_ctx *ctx) 1379 + struct devlink_param_gset_ctx *ctx, 1380 + struct netlink_ext_ack *extack) 1383 1381 { 1384 1382 struct rvu_devlink *rvu_dl = devlink_priv(devlink); 1385 1383 struct rvu *rvu = rvu_dl->rvu; ··· 1406 1402 } 1407 1403 1408 1404 static int rvu_af_dl_nix_maxlf_get(struct devlink *devlink, u32 id, 1409 - struct devlink_param_gset_ctx *ctx) 1405 + struct devlink_param_gset_ctx *ctx, 1406 + struct netlink_ext_ack *extack) 1410 1407 { 1411 1408 struct rvu_devlink *rvu_dl = devlink_priv(devlink); 1412 1409 struct rvu *rvu = rvu_dl->rvu;
+4 -2
drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.c
··· 48 48 } 49 49 50 50 static int otx2_dl_mcam_count_get(struct devlink *devlink, u32 id, 51 - struct devlink_param_gset_ctx *ctx) 51 + struct devlink_param_gset_ctx *ctx, 52 + struct netlink_ext_ack *extack) 52 53 { 53 54 struct otx2_devlink *otx2_dl = devlink_priv(devlink); 54 55 struct otx2_nic *pfvf = otx2_dl->pfvf; ··· 85 84 } 86 85 87 86 static int otx2_dl_ucast_flt_cnt_get(struct devlink *devlink, u32 id, 88 - struct devlink_param_gset_ctx *ctx) 87 + struct devlink_param_gset_ctx *ctx, 88 + struct netlink_ext_ack *extack) 89 89 { 90 90 struct otx2_devlink *otx2_dl = devlink_priv(devlink); 91 91 struct otx2_nic *pfvf = otx2_dl->pfvf;
+4 -2
drivers/net/ethernet/mellanox/mlx4/main.c
··· 174 174 static atomic_t pf_loading = ATOMIC_INIT(0); 175 175 176 176 static int mlx4_devlink_ierr_reset_get(struct devlink *devlink, u32 id, 177 - struct devlink_param_gset_ctx *ctx) 177 + struct devlink_param_gset_ctx *ctx, 178 + struct netlink_ext_ack *extack) 178 179 { 179 180 ctx->val.vbool = !!mlx4_internal_err_reset; 180 181 return 0; ··· 190 189 } 191 190 192 191 static int mlx4_devlink_crdump_snapshot_get(struct devlink *devlink, u32 id, 193 - struct devlink_param_gset_ctx *ctx) 192 + struct devlink_param_gset_ctx *ctx, 193 + struct netlink_ext_ack *extack) 194 194 { 195 195 struct mlx4_priv *priv = devlink_priv(devlink); 196 196 struct mlx4_dev *dev = &priv->dev;
+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 {
+2 -1
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
··· 1969 1969 } 1970 1970 1971 1971 static int mlx5_devlink_esw_multiport_get(struct devlink *devlink, u32 id, 1972 - struct devlink_param_gset_ctx *ctx) 1972 + struct devlink_param_gset_ctx *ctx, 1973 + struct netlink_ext_ack *extack) 1973 1974 { 1974 1975 struct mlx5_core_dev *dev = devlink_priv(devlink); 1975 1976
+2 -1
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
··· 2618 2618 } 2619 2619 2620 2620 static int esw_port_metadata_get(struct devlink *devlink, u32 id, 2621 - struct devlink_param_gset_ctx *ctx) 2621 + struct devlink_param_gset_ctx *ctx, 2622 + struct netlink_ext_ack *extack) 2622 2623 { 2623 2624 struct mlx5_core_dev *dev = devlink_priv(devlink); 2624 2625
+2 -1
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
··· 3833 3833 } 3834 3834 3835 3835 static int mlx5_fs_mode_get(struct devlink *devlink, u32 id, 3836 - struct devlink_param_gset_ctx *ctx) 3836 + struct devlink_param_gset_ctx *ctx, 3837 + struct netlink_ext_ack *extack) 3837 3838 { 3838 3839 struct mlx5_core_dev *dev = devlink_priv(devlink); 3839 3840
+2 -1
drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
··· 73 73 } 74 74 75 75 static int mlx5_fw_reset_enable_remote_dev_reset_get(struct devlink *devlink, u32 id, 76 - struct devlink_param_gset_ctx *ctx) 76 + struct devlink_param_gset_ctx *ctx, 77 + struct netlink_ext_ack *extack) 77 78 { 78 79 struct mlx5_core_dev *dev = devlink_priv(devlink); 79 80 struct mlx5_fw_reset *fw_reset;
+235 -3
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)) ··· 214 195 return mlx5_nv_param_read(dev, mnvda, len); 215 196 } 216 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); 220 + 221 + return mlx5_nv_param_read(dev, mnvda, len); 222 + } 223 + 217 224 static const char *const 218 225 cqe_compress_str[] = { "balanced", "aggressive" }; 219 226 220 227 static int 221 228 mlx5_nv_param_devlink_cqe_compress_get(struct devlink *devlink, u32 id, 222 - struct devlink_param_gset_ctx *ctx) 229 + struct devlink_param_gset_ctx *ctx, 230 + struct netlink_ext_ack *extack) 223 231 { 224 232 struct mlx5_core_dev *dev = devlink_priv(devlink); 225 233 u32 mnvda[MLX5_ST_SZ_DW(mnvda_reg)] = {}; ··· 314 268 return mlx5_nv_param_write(dev, mnvda, sizeof(mnvda)); 315 269 } 316 270 271 + enum swp_l4_csum_mode { 272 + SWP_L4_CSUM_MODE_DEFAULT = 0, 273 + SWP_L4_CSUM_MODE_FULL_CSUM = 1, 274 + SWP_L4_CSUM_MODE_L4_ONLY = 2, 275 + }; 276 + 277 + static const char *const 278 + swp_l4_csum_mode_str[] = { "default", "full_csum", "l4_only" }; 279 + 280 + static int 281 + mlx5_swp_l4_csum_mode_get(struct devlink *devlink, u32 id, 282 + int access_mode, u8 *value, 283 + struct netlink_ext_ack *extack) 284 + { 285 + struct mlx5_core_dev *dev = devlink_priv(devlink); 286 + u32 mnvda[MLX5_ST_SZ_DW(mnvda_reg)] = {}; 287 + void *data; 288 + int err; 289 + 290 + err = mlx5_nv_param_read_sw_accelerate_conf(dev, mnvda, sizeof(mnvda), 291 + access_mode); 292 + if (err) { 293 + NL_SET_ERR_MSG_MOD(extack, 294 + "Failed to read sw_accelerate_conf mnvda reg"); 295 + return err; 296 + } 297 + 298 + data = MLX5_ADDR_OF(mnvda_reg, mnvda, configuration_item_data); 299 + *value = MLX5_GET(nv_sw_accelerate_conf, data, swp_l4_csum_mode); 300 + 301 + if (*value >= ARRAY_SIZE(swp_l4_csum_mode_str)) { 302 + NL_SET_ERR_MSG_FMT_MOD(extack, 303 + "Invalid swp_l4_csum_mode value %u read from device", 304 + *value); 305 + return -EINVAL; 306 + } 307 + 308 + return 0; 309 + } 310 + 311 + static int 312 + mlx5_devlink_swp_l4_csum_mode_get(struct devlink *devlink, u32 id, 313 + struct devlink_param_gset_ctx *ctx, 314 + struct netlink_ext_ack *extack) 315 + { 316 + u8 value; 317 + int err; 318 + 319 + err = mlx5_swp_l4_csum_mode_get(devlink, id, MLX5_ACCESS_MODE_NEXT, 320 + &value, extack); 321 + if (err) 322 + return err; 323 + 324 + strscpy(ctx->val.vstr, swp_l4_csum_mode_str[value], 325 + sizeof(ctx->val.vstr)); 326 + return 0; 327 + } 328 + 329 + static int 330 + mlx5_devlink_swp_l4_csum_mode_validate(struct devlink *devlink, u32 id, 331 + union devlink_param_value val, 332 + struct netlink_ext_ack *extack) 333 + { 334 + struct mlx5_core_dev *dev = devlink_priv(devlink); 335 + u32 cap[MLX5_ST_SZ_DW(mnvda_reg)] = {}; 336 + void *data; 337 + int err, i; 338 + 339 + for (i = 0; i < ARRAY_SIZE(swp_l4_csum_mode_str); i++) { 340 + if (!strcmp(val.vstr, swp_l4_csum_mode_str[i])) 341 + break; 342 + } 343 + 344 + if (i >= ARRAY_SIZE(swp_l4_csum_mode_str) || 345 + i == SWP_L4_CSUM_MODE_DEFAULT) { 346 + NL_SET_ERR_MSG_MOD(extack, 347 + "Invalid value, supported values are full_csum/l4_only"); 348 + return -EINVAL; 349 + } 350 + 351 + if (i == SWP_L4_CSUM_MODE_L4_ONLY) { 352 + err = mlx5_nv_param_read_sw_offload_cap(dev, cap, sizeof(cap)); 353 + if (err) { 354 + NL_SET_ERR_MSG_MOD(extack, 355 + "Failed to read sw_offload_cap"); 356 + return err; 357 + } 358 + 359 + data = MLX5_ADDR_OF(mnvda_reg, cap, configuration_item_data); 360 + if (!MLX5_GET(nv_sw_offload_cap, data, swp_l4_csum_mode_l4_only)) { 361 + NL_SET_ERR_MSG_MOD(extack, 362 + "l4_only mode is not supported on this device"); 363 + return -EOPNOTSUPP; 364 + } 365 + } 366 + 367 + return 0; 368 + } 369 + 370 + static int 371 + mlx5_swp_l4_csum_mode_set(struct devlink *devlink, u32 id, u8 value, 372 + struct netlink_ext_ack *extack) 373 + { 374 + struct mlx5_core_dev *dev = devlink_priv(devlink); 375 + u32 mnvda[MLX5_ST_SZ_DW(mnvda_reg)] = {}; 376 + void *data; 377 + int err; 378 + 379 + err = mlx5_nv_param_read_sw_accelerate_conf(dev, mnvda, sizeof(mnvda), 380 + MLX5_ACCESS_MODE_NEXT); 381 + if (err) { 382 + NL_SET_ERR_MSG_MOD(extack, 383 + "Failed to read sw_accelerate_conf mnvda reg"); 384 + return err; 385 + } 386 + 387 + data = MLX5_ADDR_OF(mnvda_reg, mnvda, configuration_item_data); 388 + MLX5_SET(nv_sw_accelerate_conf, data, swp_l4_csum_mode, value); 389 + 390 + err = mlx5_nv_param_write(dev, mnvda, sizeof(mnvda)); 391 + if (err) 392 + NL_SET_ERR_MSG_MOD(extack, 393 + "Failed to write sw_accelerate_conf mnvda reg"); 394 + 395 + return err; 396 + } 397 + 398 + static int 399 + mlx5_devlink_swp_l4_csum_mode_set(struct devlink *devlink, u32 id, 400 + struct devlink_param_gset_ctx *ctx, 401 + struct netlink_ext_ack *extack) 402 + { 403 + u8 value; 404 + 405 + if (!strcmp(ctx->val.vstr, "full_csum")) 406 + value = SWP_L4_CSUM_MODE_FULL_CSUM; 407 + else 408 + value = SWP_L4_CSUM_MODE_L4_ONLY; 409 + 410 + return mlx5_swp_l4_csum_mode_set(devlink, id, value, extack); 411 + } 412 + 413 + static int 414 + mlx5_devlink_swp_l4_csum_mode_get_default(struct devlink *devlink, u32 id, 415 + struct devlink_param_gset_ctx *ctx, 416 + struct netlink_ext_ack *extack) 417 + { 418 + u8 value; 419 + int err; 420 + 421 + err = mlx5_swp_l4_csum_mode_get(devlink, id, MLX5_ACCESS_MODE_DEFAULT, 422 + &value, extack); 423 + if (err) 424 + return err; 425 + 426 + strscpy(ctx->val.vstr, swp_l4_csum_mode_str[value], 427 + sizeof(ctx->val.vstr)); 428 + return 0; 429 + } 430 + 431 + static int 432 + mlx5_devlink_swp_l4_csum_mode_set_default(struct devlink *devlink, u32 id, 433 + enum devlink_param_cmode cmode, 434 + struct netlink_ext_ack *extack) 435 + { 436 + u8 value; 437 + int err; 438 + 439 + err = mlx5_swp_l4_csum_mode_get(devlink, id, MLX5_ACCESS_MODE_DEFAULT, 440 + &value, extack); 441 + if (err) 442 + return err; 443 + 444 + return mlx5_swp_l4_csum_mode_set(devlink, id, value, extack); 445 + } 446 + 317 447 static int mlx5_nv_param_read_global_pci_conf(struct mlx5_core_dev *dev, 318 448 void *mnvda, size_t len) 319 449 { ··· 524 302 } 525 303 526 304 static int mlx5_devlink_enable_sriov_get(struct devlink *devlink, u32 id, 527 - struct devlink_param_gset_ctx *ctx) 305 + struct devlink_param_gset_ctx *ctx, 306 + struct netlink_ext_ack *extack) 528 307 { 529 308 struct mlx5_core_dev *dev = devlink_priv(devlink); 530 309 u32 mnvda[MLX5_ST_SZ_DW(mnvda_reg)] = {}; ··· 636 413 } 637 414 638 415 static int mlx5_devlink_total_vfs_get(struct devlink *devlink, u32 id, 639 - struct devlink_param_gset_ctx *ctx) 416 + struct devlink_param_gset_ctx *ctx, 417 + struct netlink_ext_ack *extack) 640 418 { 641 419 struct mlx5_core_dev *dev = devlink_priv(devlink); 642 420 u32 mnvda[MLX5_ST_SZ_DW(mnvda_reg)] = {}; ··· 769 545 mlx5_nv_param_devlink_cqe_compress_get, 770 546 mlx5_nv_param_devlink_cqe_compress_set, 771 547 mlx5_nv_param_devlink_cqe_compress_validate), 548 + DEVLINK_PARAM_DRIVER_WITH_DEFAULTS(MLX5_DEVLINK_PARAM_ID_SWP_L4_CSUM_MODE, 549 + "swp_l4_csum_mode", DEVLINK_PARAM_TYPE_STRING, 550 + BIT(DEVLINK_PARAM_CMODE_PERMANENT), 551 + mlx5_devlink_swp_l4_csum_mode_get, 552 + mlx5_devlink_swp_l4_csum_mode_set, 553 + mlx5_devlink_swp_l4_csum_mode_validate, 554 + mlx5_devlink_swp_l4_csum_mode_get_default, 555 + mlx5_devlink_swp_l4_csum_mode_set_default), 772 556 }; 773 557 774 558 int mlx5_nv_param_register_dl_params(struct devlink *devlink)
+2 -1
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
··· 1489 1489 1490 1490 static int 1491 1491 mlxsw_sp_acl_tcam_region_rehash_intrvl_get(struct devlink *devlink, u32 id, 1492 - struct devlink_param_gset_ctx *ctx) 1492 + struct devlink_param_gset_ctx *ctx, 1493 + struct netlink_ext_ack *extack) 1493 1494 { 1494 1495 struct mlxsw_core *mlxsw_core = devlink_priv(devlink); 1495 1496 struct mlxsw_sp_acl_tcam *tcam;
+2 -1
drivers/net/ethernet/qlogic/qed/qed_devlink.c
··· 121 121 } 122 122 123 123 static int qed_dl_param_get(struct devlink *dl, u32 id, 124 - struct devlink_param_gset_ctx *ctx) 124 + struct devlink_param_gset_ctx *ctx, 125 + struct netlink_ext_ack *extack) 125 126 { 126 127 struct qed_devlink *qed_dl = devlink_priv(dl); 127 128 struct qed_dev *cdev;
+2 -1
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
··· 7531 7531 } 7532 7532 7533 7533 static int stmmac_dl_ts_coarse_get(struct devlink *dl, u32 id, 7534 - struct devlink_param_gset_ctx *ctx) 7534 + struct devlink_param_gset_ctx *ctx, 7535 + struct netlink_ext_ack *extack) 7535 7536 { 7536 7537 struct stmmac_devlink_priv *dl_priv = devlink_priv(dl); 7537 7538 struct stmmac_priv *priv = dl_priv->stmmac_priv;
+2 -1
drivers/net/ethernet/ti/am65-cpsw-nuss.c
··· 3068 3068 } 3069 3069 3070 3070 static int am65_cpsw_dl_switch_mode_get(struct devlink *dl, u32 id, 3071 - struct devlink_param_gset_ctx *ctx) 3071 + struct devlink_param_gset_ctx *ctx, 3072 + struct netlink_ext_ack *extack) 3072 3073 { 3073 3074 struct am65_cpsw_devlink *dl_priv = devlink_priv(dl); 3074 3075 struct am65_cpsw_common *common = dl_priv->common;
+4 -2
drivers/net/ethernet/ti/cpsw_new.c
··· 1618 1618 }; 1619 1619 1620 1620 static int cpsw_dl_switch_mode_get(struct devlink *dl, u32 id, 1621 - struct devlink_param_gset_ctx *ctx) 1621 + struct devlink_param_gset_ctx *ctx, 1622 + struct netlink_ext_ack *extack) 1622 1623 { 1623 1624 struct cpsw_devlink *dl_priv = devlink_priv(dl); 1624 1625 struct cpsw_common *cpsw = dl_priv->cpsw; ··· 1754 1753 } 1755 1754 1756 1755 static int cpsw_dl_ale_ctrl_get(struct devlink *dl, u32 id, 1757 - struct devlink_param_gset_ctx *ctx) 1756 + struct devlink_param_gset_ctx *ctx, 1757 + struct netlink_ext_ack *extack) 1758 1758 { 1759 1759 struct cpsw_devlink *dl_priv = devlink_priv(dl); 1760 1760 struct cpsw_common *cpsw = dl_priv->cpsw;
+56
drivers/net/netdevsim/dev.c
··· 320 320 &nsim_dev->max_macs); 321 321 debugfs_create_bool("test1", 0600, nsim_dev->ddir, 322 322 &nsim_dev->test1); 323 + debugfs_create_u32("test2", 0600, nsim_dev->ddir, 324 + &nsim_dev->test2); 323 325 nsim_dev->take_snapshot = debugfs_create_file("take_snapshot", 324 326 0200, 325 327 nsim_dev->ddir, ··· 523 521 enum nsim_devlink_param_id { 524 522 NSIM_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX, 525 523 NSIM_DEVLINK_PARAM_ID_TEST1, 524 + NSIM_DEVLINK_PARAM_ID_TEST2, 526 525 }; 526 + 527 + static int 528 + nsim_devlink_param_test2_get(struct devlink *devlink, u32 id, 529 + struct devlink_param_gset_ctx *ctx, 530 + struct netlink_ext_ack *extack) 531 + { 532 + struct nsim_dev *nsim_dev = devlink_priv(devlink); 533 + 534 + ctx->val.vu32 = nsim_dev->test2; 535 + return 0; 536 + } 537 + 538 + static int 539 + nsim_devlink_param_test2_set(struct devlink *devlink, u32 id, 540 + struct devlink_param_gset_ctx *ctx, 541 + struct netlink_ext_ack *extack) 542 + { 543 + struct nsim_dev *nsim_dev = devlink_priv(devlink); 544 + 545 + nsim_dev->test2 = ctx->val.vu32; 546 + return 0; 547 + } 548 + 549 + #define NSIM_DEV_TEST2_DEFAULT 1234 550 + 551 + static int 552 + nsim_devlink_param_test2_get_default(struct devlink *devlink, u32 id, 553 + struct devlink_param_gset_ctx *ctx, 554 + struct netlink_ext_ack *extack) 555 + { 556 + ctx->val.vu32 = NSIM_DEV_TEST2_DEFAULT; 557 + return 0; 558 + } 559 + 560 + static int 561 + nsim_devlink_param_test2_reset_default(struct devlink *devlink, u32 id, 562 + enum devlink_param_cmode cmode, 563 + struct netlink_ext_ack *extack) 564 + { 565 + struct nsim_dev *nsim_dev = devlink_priv(devlink); 566 + 567 + nsim_dev->test2 = NSIM_DEV_TEST2_DEFAULT; 568 + return 0; 569 + } 527 570 528 571 static const struct devlink_param nsim_devlink_params[] = { 529 572 DEVLINK_PARAM_GENERIC(MAX_MACS, ··· 578 531 "test1", DEVLINK_PARAM_TYPE_BOOL, 579 532 BIT(DEVLINK_PARAM_CMODE_DRIVERINIT), 580 533 NULL, NULL, NULL), 534 + DEVLINK_PARAM_DRIVER_WITH_DEFAULTS(NSIM_DEVLINK_PARAM_ID_TEST2, 535 + "test2", DEVLINK_PARAM_TYPE_U32, 536 + BIT(DEVLINK_PARAM_CMODE_RUNTIME), 537 + nsim_devlink_param_test2_get, 538 + nsim_devlink_param_test2_set, 539 + NULL, 540 + nsim_devlink_param_test2_get_default, 541 + nsim_devlink_param_test2_reset_default), 581 542 }; 582 543 583 544 static void nsim_devlink_set_params_init_values(struct nsim_dev *nsim_dev, ··· 1645 1590 nsim_dev->fw_update_flash_chunk_time_ms = NSIM_DEV_FLASH_CHUNK_TIME_MS_DEFAULT; 1646 1591 nsim_dev->max_macs = NSIM_DEV_MAX_MACS_DEFAULT; 1647 1592 nsim_dev->test1 = NSIM_DEV_TEST1_DEFAULT; 1593 + nsim_dev->test2 = NSIM_DEV_TEST2_DEFAULT; 1648 1594 spin_lock_init(&nsim_dev->fa_cookie_lock); 1649 1595 1650 1596 dev_set_drvdata(&nsim_bus_dev->dev, nsim_dev);
+1
drivers/net/netdevsim/netdevsim.h
··· 331 331 u32 fw_update_flash_chunk_time_ms; 332 332 u32 max_macs; 333 333 bool test1; 334 + u32 test2; 334 335 bool dont_allow_reload; 335 336 bool fail_reload; 336 337 struct devlink_region *dummy_region;
+2 -1
drivers/net/wwan/iosm/iosm_ipc_devlink.c
··· 21 21 22 22 /* Get the param values for the specific param ID's */ 23 23 static int ipc_devlink_get_param(struct devlink *dl, u32 id, 24 - struct devlink_param_gset_ctx *ctx) 24 + struct devlink_param_gset_ctx *ctx, 25 + struct netlink_ext_ack *extack) 25 26 { 26 27 struct iosm_devlink *ipc_devlink = devlink_priv(dl); 27 28
+44 -1
include/net/devlink.h
··· 479 479 * @set: set parameter value, used for runtime and permanent 480 480 * configuration modes 481 481 * @validate: validate input value is applicable (within value range, etc.) 482 + * @get_default: get parameter default value, used for runtime and permanent 483 + * configuration modes 484 + * @reset_default: reset parameter to default value, used for runtime and permanent 485 + * configuration modes 482 486 * 483 487 * This struct should be used by the driver to fill the data for 484 488 * a parameter it registers. ··· 494 490 enum devlink_param_type type; 495 491 unsigned long supported_cmodes; 496 492 int (*get)(struct devlink *devlink, u32 id, 497 - struct devlink_param_gset_ctx *ctx); 493 + struct devlink_param_gset_ctx *ctx, 494 + struct netlink_ext_ack *extack); 498 495 int (*set)(struct devlink *devlink, u32 id, 499 496 struct devlink_param_gset_ctx *ctx, 500 497 struct netlink_ext_ack *extack); 501 498 int (*validate)(struct devlink *devlink, u32 id, 502 499 union devlink_param_value val, 503 500 struct netlink_ext_ack *extack); 501 + int (*get_default)(struct devlink *devlink, u32 id, 502 + struct devlink_param_gset_ctx *ctx, 503 + struct netlink_ext_ack *extack); 504 + int (*reset_default)(struct devlink *devlink, u32 id, 505 + enum devlink_param_cmode cmode, 506 + struct netlink_ext_ack *extack); 504 507 }; 505 508 506 509 struct devlink_param_item { ··· 519 508 * until reload. 520 509 */ 521 510 bool driverinit_value_new_valid; 511 + union devlink_param_value driverinit_default; 522 512 }; 523 513 524 514 enum devlink_param_generic_id { ··· 639 627 .get = _get, \ 640 628 .set = _set, \ 641 629 .validate = _validate, \ 630 + } 631 + 632 + #define DEVLINK_PARAM_GENERIC_WITH_DEFAULTS(_id, _cmodes, _get, _set, \ 633 + _validate, _get_default, \ 634 + _reset_default) \ 635 + { \ 636 + .id = DEVLINK_PARAM_GENERIC_ID_##_id, \ 637 + .name = DEVLINK_PARAM_GENERIC_##_id##_NAME, \ 638 + .type = DEVLINK_PARAM_GENERIC_##_id##_TYPE, \ 639 + .generic = true, \ 640 + .supported_cmodes = _cmodes, \ 641 + .get = _get, \ 642 + .set = _set, \ 643 + .validate = _validate, \ 644 + .get_default = _get_default, \ 645 + .reset_default = _reset_default, \ 646 + } 647 + 648 + #define DEVLINK_PARAM_DRIVER_WITH_DEFAULTS(_id, _name, _type, _cmodes, \ 649 + _get, _set, _validate, \ 650 + _get_default, _reset_default) \ 651 + { \ 652 + .id = _id, \ 653 + .name = _name, \ 654 + .type = _type, \ 655 + .supported_cmodes = _cmodes, \ 656 + .get = _get, \ 657 + .set = _set, \ 658 + .validate = _validate, \ 659 + .get_default = _get_default, \ 660 + .reset_default = _reset_default, \ 642 661 } 643 662 644 663 /* Identifier of board design */
+2 -1
include/net/dsa.h
··· 1251 1251 dsa_devlink_param_get, dsa_devlink_param_set, NULL) 1252 1252 1253 1253 int dsa_devlink_param_get(struct devlink *dl, u32 id, 1254 - struct devlink_param_gset_ctx *ctx); 1254 + struct devlink_param_gset_ctx *ctx, 1255 + struct netlink_ext_ack *extack); 1255 1256 int dsa_devlink_param_set(struct devlink *dl, u32 id, 1256 1257 struct devlink_param_gset_ctx *ctx, 1257 1258 struct netlink_ext_ack *extack);
+3
include/uapi/linux/devlink.h
··· 639 639 640 640 DEVLINK_ATTR_HEALTH_REPORTER_BURST_PERIOD, /* u64 */ 641 641 642 + DEVLINK_ATTR_PARAM_VALUE_DEFAULT, /* dynamic */ 643 + DEVLINK_ATTR_PARAM_RESET_DEFAULT, /* flag */ 644 + 642 645 /* Add new attributes above here, update the spec in 643 646 * Documentation/netlink/specs/devlink.yaml and re-generate 644 647 * net/devlink/netlink_gen.c.
+138 -46
net/devlink/param.c
··· 174 174 175 175 static int devlink_param_get(struct devlink *devlink, 176 176 const struct devlink_param *param, 177 - struct devlink_param_gset_ctx *ctx) 177 + struct devlink_param_gset_ctx *ctx, 178 + struct netlink_ext_ack *extack) 178 179 { 179 180 if (!param->get) 180 181 return -EOPNOTSUPP; 181 - return param->get(devlink, param->id, ctx); 182 + return param->get(devlink, param->id, ctx, extack); 182 183 } 183 184 184 185 static int devlink_param_set(struct devlink *devlink, ··· 192 191 return param->set(devlink, param->id, ctx, extack); 193 192 } 194 193 194 + static int devlink_param_get_default(struct devlink *devlink, 195 + const struct devlink_param *param, 196 + struct devlink_param_gset_ctx *ctx, 197 + struct netlink_ext_ack *extack) 198 + { 199 + if (!param->get_default) 200 + return -EOPNOTSUPP; 201 + 202 + return param->get_default(devlink, param->id, ctx, extack); 203 + } 204 + 205 + static int devlink_param_reset_default(struct devlink *devlink, 206 + const struct devlink_param *param, 207 + enum devlink_param_cmode cmode, 208 + struct netlink_ext_ack *extack) 209 + { 210 + if (!param->reset_default) 211 + return -EOPNOTSUPP; 212 + 213 + return param->reset_default(devlink, param->id, cmode, extack); 214 + } 215 + 216 + static int 217 + devlink_nl_param_value_put(struct sk_buff *msg, enum devlink_param_type type, 218 + int nla_type, union devlink_param_value val, 219 + bool flag_as_u8) 220 + { 221 + switch (type) { 222 + case DEVLINK_PARAM_TYPE_U8: 223 + if (nla_put_u8(msg, nla_type, val.vu8)) 224 + return -EMSGSIZE; 225 + break; 226 + case DEVLINK_PARAM_TYPE_U16: 227 + if (nla_put_u16(msg, nla_type, val.vu16)) 228 + return -EMSGSIZE; 229 + break; 230 + case DEVLINK_PARAM_TYPE_U32: 231 + if (nla_put_u32(msg, nla_type, val.vu32)) 232 + return -EMSGSIZE; 233 + break; 234 + case DEVLINK_PARAM_TYPE_U64: 235 + if (devlink_nl_put_u64(msg, nla_type, val.vu64)) 236 + return -EMSGSIZE; 237 + break; 238 + case DEVLINK_PARAM_TYPE_STRING: 239 + if (nla_put_string(msg, nla_type, val.vstr)) 240 + return -EMSGSIZE; 241 + break; 242 + case DEVLINK_PARAM_TYPE_BOOL: 243 + /* default values of type bool are encoded with u8, so that 244 + * false can be distinguished from not present 245 + */ 246 + if (flag_as_u8) { 247 + if (nla_put_u8(msg, nla_type, val.vbool)) 248 + return -EMSGSIZE; 249 + } else { 250 + if (val.vbool && nla_put_flag(msg, nla_type)) 251 + return -EMSGSIZE; 252 + } 253 + break; 254 + } 255 + return 0; 256 + } 257 + 195 258 static int 196 259 devlink_nl_param_value_fill_one(struct sk_buff *msg, 197 260 enum devlink_param_type type, 198 261 enum devlink_param_cmode cmode, 199 - union devlink_param_value val) 262 + union devlink_param_value val, 263 + union devlink_param_value default_val, 264 + bool has_default) 200 265 { 201 266 struct nlattr *param_value_attr; 267 + int err = -EMSGSIZE; 202 268 203 269 param_value_attr = nla_nest_start_noflag(msg, 204 270 DEVLINK_ATTR_PARAM_VALUE); 205 271 if (!param_value_attr) 206 - goto nla_put_failure; 272 + return -EMSGSIZE; 207 273 208 274 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode)) 209 275 goto value_nest_cancel; 210 276 211 - switch (type) { 212 - case DEVLINK_PARAM_TYPE_U8: 213 - if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8)) 277 + err = devlink_nl_param_value_put(msg, type, 278 + DEVLINK_ATTR_PARAM_VALUE_DATA, 279 + val, false); 280 + if (err) 281 + goto value_nest_cancel; 282 + 283 + if (has_default) { 284 + err = devlink_nl_param_value_put(msg, type, 285 + DEVLINK_ATTR_PARAM_VALUE_DEFAULT, 286 + default_val, true); 287 + if (err) 214 288 goto value_nest_cancel; 215 - break; 216 - case DEVLINK_PARAM_TYPE_U16: 217 - if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16)) 218 - goto value_nest_cancel; 219 - break; 220 - case DEVLINK_PARAM_TYPE_U32: 221 - if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32)) 222 - goto value_nest_cancel; 223 - break; 224 - case DEVLINK_PARAM_TYPE_U64: 225 - if (devlink_nl_put_u64(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, 226 - val.vu64)) 227 - goto value_nest_cancel; 228 - break; 229 - case DEVLINK_PARAM_TYPE_STRING: 230 - if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, 231 - val.vstr)) 232 - goto value_nest_cancel; 233 - break; 234 - case DEVLINK_PARAM_TYPE_BOOL: 235 - if (val.vbool && 236 - nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA)) 237 - goto value_nest_cancel; 238 - break; 239 289 } 240 290 241 291 nla_nest_end(msg, param_value_attr); ··· 294 242 295 243 value_nest_cancel: 296 244 nla_nest_cancel(msg, param_value_attr); 297 - nla_put_failure: 298 - return -EMSGSIZE; 245 + return err; 299 246 } 300 247 301 248 static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink, 302 249 unsigned int port_index, 303 250 struct devlink_param_item *param_item, 304 251 enum devlink_command cmd, 305 - u32 portid, u32 seq, int flags) 252 + u32 portid, u32 seq, int flags, 253 + struct netlink_ext_ack *extack) 306 254 { 255 + union devlink_param_value default_value[DEVLINK_PARAM_CMODE_MAX + 1]; 307 256 union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1]; 257 + bool default_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {}; 308 258 bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {}; 309 259 const struct devlink_param *param = param_item->param; 310 260 struct devlink_param_gset_ctx ctx; ··· 327 273 param_value[i] = param_item->driverinit_value; 328 274 else 329 275 return -EOPNOTSUPP; 276 + 277 + if (param_item->driverinit_value_valid) { 278 + default_value[i] = param_item->driverinit_default; 279 + default_value_set[i] = true; 280 + } 330 281 } else { 331 282 ctx.cmode = i; 332 - err = devlink_param_get(devlink, param, &ctx); 283 + err = devlink_param_get(devlink, param, &ctx, extack); 333 284 if (err) 334 285 return err; 335 286 param_value[i] = ctx.val; 287 + 288 + err = devlink_param_get_default(devlink, param, &ctx, 289 + extack); 290 + if (!err) { 291 + default_value[i] = ctx.val; 292 + default_value_set[i] = true; 293 + } else if (err != -EOPNOTSUPP) { 294 + return err; 295 + } 336 296 } 337 297 param_value_set[i] = true; 338 298 } ··· 383 315 if (!param_value_set[i]) 384 316 continue; 385 317 err = devlink_nl_param_value_fill_one(msg, param->type, 386 - i, param_value[i]); 318 + i, param_value[i], 319 + default_value[i], 320 + default_value_set[i]); 387 321 if (err) 388 322 goto values_list_nest_cancel; 389 323 } ··· 427 357 if (!msg) 428 358 return; 429 359 err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd, 430 - 0, 0, 0); 360 + 0, 0, 0, NULL); 431 361 if (err) { 432 362 nlmsg_free(msg); 433 363 return; ··· 470 400 err = devlink_nl_param_fill(msg, devlink, 0, param_item, 471 401 DEVLINK_CMD_PARAM_GET, 472 402 NETLINK_CB(cb->skb).portid, 473 - cb->nlh->nlmsg_seq, flags); 403 + cb->nlh->nlmsg_seq, flags, 404 + cb->extack); 474 405 if (err == -EOPNOTSUPP) { 475 406 err = 0; 476 407 } else if (err) { ··· 580 509 return -ENOMEM; 581 510 582 511 err = devlink_nl_param_fill(msg, devlink, 0, param_item, 583 - DEVLINK_CMD_PARAM_GET, 584 - info->snd_portid, info->snd_seq, 0); 512 + DEVLINK_CMD_PARAM_GET, info->snd_portid, 513 + info->snd_seq, 0, info->extack); 585 514 if (err) { 586 515 nlmsg_free(msg); 587 516 return err; ··· 602 531 struct devlink_param_item *param_item; 603 532 const struct devlink_param *param; 604 533 union devlink_param_value value; 534 + bool reset_default; 605 535 int err = 0; 606 536 607 537 param_item = devlink_param_get_from_info(params, info); ··· 614 542 return err; 615 543 if (param_type != param->type) 616 544 return -EINVAL; 617 - err = devlink_param_value_get_from_info(param, info, &value); 618 - if (err) 619 - return err; 620 - if (param->validate) { 621 - err = param->validate(devlink, param->id, value, info->extack); 545 + 546 + reset_default = info->attrs[DEVLINK_ATTR_PARAM_RESET_DEFAULT]; 547 + if (!reset_default) { 548 + err = devlink_param_value_get_from_info(param, info, &value); 622 549 if (err) 623 550 return err; 551 + if (param->validate) { 552 + err = param->validate(devlink, param->id, value, 553 + info->extack); 554 + if (err) 555 + return err; 556 + } 624 557 } 625 558 626 559 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_VALUE_CMODE)) ··· 635 558 return -EOPNOTSUPP; 636 559 637 560 if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) { 561 + if (reset_default) { 562 + if (!param_item->driverinit_value_valid) { 563 + NL_SET_ERR_MSG(info->extack, 564 + "Default value not available"); 565 + return -EOPNOTSUPP; 566 + } 567 + value = param_item->driverinit_default; 568 + } 569 + 638 570 param_item->driverinit_value_new = value; 639 571 param_item->driverinit_value_new_valid = true; 640 572 } else { ··· 651 565 return -EOPNOTSUPP; 652 566 ctx.val = value; 653 567 ctx.cmode = cmode; 654 - err = devlink_param_set(devlink, param, &ctx, info->extack); 568 + if (reset_default) 569 + err = devlink_param_reset_default(devlink, param, cmode, 570 + info->extack); 571 + else 572 + err = devlink_param_set(devlink, param, &ctx, 573 + info->extack); 655 574 if (err) 656 575 return err; 657 576 } ··· 904 813 905 814 param_item->driverinit_value = init_val; 906 815 param_item->driverinit_value_valid = true; 816 + param_item->driverinit_default = init_val; 907 817 908 818 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW); 909 819 }
+2 -1
net/dsa/devlink.c
··· 182 182 }; 183 183 184 184 int dsa_devlink_param_get(struct devlink *dl, u32 id, 185 - struct devlink_param_gset_ctx *ctx) 185 + struct devlink_param_gset_ctx *ctx, 186 + struct netlink_ext_ack *extack) 186 187 { 187 188 struct dsa_switch *ds = dsa_devlink_to_ds(dl); 188 189
+110 -6
tools/testing/selftests/drivers/net/netdevsim/devlink.sh
··· 3 3 4 4 lib_dir=$(dirname $0)/../../../net/forwarding 5 5 6 - ALL_TESTS="fw_flash_test params_test regions_test reload_test \ 6 + ALL_TESTS="fw_flash_test params_test \ 7 + params_default_test regions_test reload_test \ 7 8 netns_reload_test resource_test dev_info_test \ 8 9 empty_reporter_test dummy_reporter_test rate_test" 9 10 NUM_NETIFS=0 ··· 79 78 param_get() 80 79 { 81 80 local name=$1 81 + local attr=${2:-value} 82 + local cmode=${3:-driverinit} 82 83 83 84 cmd_jq "devlink dev param show $DL_HANDLE name $name -j" \ 84 - '.[][][].values[] | select(.cmode == "driverinit").value' 85 + '.[][][].values[] | select(.cmode == "'"$cmode"'").'"$attr" 85 86 } 86 87 87 88 param_set() 88 89 { 89 90 local name=$1 90 91 local value=$2 92 + local cmode=${3:-driverinit} 91 93 92 - devlink dev param set $DL_HANDLE name $name cmode driverinit value $value 94 + devlink dev param set $DL_HANDLE name $name cmode $cmode value $value 95 + } 96 + 97 + param_set_default() 98 + { 99 + local name=$1 100 + local cmode=${2:-driverinit} 101 + 102 + devlink dev param set $DL_HANDLE name $name default cmode $cmode 93 103 } 94 104 95 105 check_value() ··· 109 97 local phase_name=$2 110 98 local expected_param_value=$3 111 99 local expected_debugfs_value=$4 100 + local cmode=${5:-driverinit} 112 101 local value 102 + local attr="value" 113 103 114 - value=$(param_get $name) 115 - check_err $? "Failed to get $name param value" 104 + if [[ "$phase_name" == *"default"* ]]; then 105 + attr="default" 106 + fi 107 + 108 + value=$(param_get $name $attr $cmode) 109 + check_err $? "Failed to get $name param $attr" 116 110 [ "$value" == "$expected_param_value" ] 117 - check_err $? "Unexpected $phase_name $name param value" 111 + check_err $? "Unexpected $phase_name $name param $attr" 118 112 value=$(<$DEBUGFS_DIR/$name) 119 113 check_err $? "Failed to get $name debugfs value" 120 114 [ "$value" == "$expected_debugfs_value" ] ··· 151 133 check_value test1 post-reload false N 152 134 153 135 log_test "params test" 136 + } 137 + 138 + value_to_debugfs() 139 + { 140 + local value=$1 141 + 142 + case "$value" in 143 + true) 144 + echo "Y" 145 + ;; 146 + false) 147 + echo "N" 148 + ;; 149 + *) 150 + echo "$value" 151 + ;; 152 + esac 153 + } 154 + 155 + test_default() 156 + { 157 + local param_name=$1 158 + local new_value=$2 159 + local expected_default=$3 160 + local cmode=${4:-driverinit} 161 + local default_debugfs 162 + local new_debugfs 163 + local expected_debugfs 164 + 165 + default_debugfs=$(value_to_debugfs $expected_default) 166 + new_debugfs=$(value_to_debugfs $new_value) 167 + 168 + expected_debugfs=$default_debugfs 169 + check_value $param_name initial-default $expected_default $expected_debugfs $cmode 170 + 171 + param_set $param_name $new_value $cmode 172 + check_err $? "Failed to set $param_name to $new_value" 173 + 174 + expected_debugfs=$([ "$cmode" == "runtime" ] && echo "$new_debugfs" || echo "$default_debugfs") 175 + check_value $param_name post-set $new_value $expected_debugfs $cmode 176 + 177 + devlink dev reload $DL_HANDLE 178 + check_err $? "Failed to reload device" 179 + 180 + expected_debugfs=$new_debugfs 181 + check_value $param_name post-reload-new-value $new_value $expected_debugfs $cmode 182 + 183 + param_set_default $param_name $cmode 184 + check_err $? "Failed to set $param_name to default" 185 + 186 + expected_debugfs=$([ "$cmode" == "runtime" ] && echo "$default_debugfs" || echo "$new_debugfs") 187 + check_value $param_name post-set-default $expected_default $expected_debugfs $cmode 188 + 189 + devlink dev reload $DL_HANDLE 190 + check_err $? "Failed to reload device" 191 + 192 + expected_debugfs=$default_debugfs 193 + check_value $param_name post-reload-default $expected_default $expected_debugfs $cmode 194 + } 195 + 196 + params_default_test() 197 + { 198 + RET=0 199 + 200 + if ! devlink dev param help 2>&1 | grep -q "value VALUE | default"; then 201 + echo "SKIP: devlink cli missing default feature" 202 + return 203 + fi 204 + 205 + # Remove side effects of previous tests. Use plain param_set, because 206 + # param_set_default is a feature under test here. 207 + param_set max_macs 32 driverinit 208 + check_err $? "Failed to reset max_macs to default value" 209 + param_set test1 true driverinit 210 + check_err $? "Failed to reset test1 to default value" 211 + param_set test2 1234 runtime 212 + check_err $? "Failed to reset test2 to default value" 213 + 214 + devlink dev reload $DL_HANDLE 215 + check_err $? "Failed to reload device for clean state" 216 + 217 + test_default max_macs 16 32 driverinit 218 + test_default test1 false true driverinit 219 + test_default test2 100 1234 runtime 220 + 221 + log_test "params default test" 154 222 } 155 223 156 224 check_region_size()