1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) 2016 Mellanox Technologies. All rights reserved. 4 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com> 5 */ 6 7 #include "devl_internal.h" 8 9 static const struct devlink_param devlink_param_generic[] = { 10 { 11 .id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET, 12 .name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME, 13 .type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE, 14 }, 15 { 16 .id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS, 17 .name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME, 18 .type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE, 19 }, 20 { 21 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV, 22 .name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME, 23 .type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE, 24 }, 25 { 26 .id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT, 27 .name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME, 28 .type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE, 29 }, 30 { 31 .id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI, 32 .name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME, 33 .type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE, 34 }, 35 { 36 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX, 37 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME, 38 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE, 39 }, 40 { 41 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN, 42 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME, 43 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE, 44 }, 45 { 46 .id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY, 47 .name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME, 48 .type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE, 49 }, 50 { 51 .id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE, 52 .name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME, 53 .type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE, 54 }, 55 { 56 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE, 57 .name = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME, 58 .type = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE, 59 }, 60 { 61 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_REMOTE_DEV_RESET, 62 .name = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_NAME, 63 .type = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_TYPE, 64 }, 65 { 66 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ETH, 67 .name = DEVLINK_PARAM_GENERIC_ENABLE_ETH_NAME, 68 .type = DEVLINK_PARAM_GENERIC_ENABLE_ETH_TYPE, 69 }, 70 { 71 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_RDMA, 72 .name = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_NAME, 73 .type = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_TYPE, 74 }, 75 { 76 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_VNET, 77 .name = DEVLINK_PARAM_GENERIC_ENABLE_VNET_NAME, 78 .type = DEVLINK_PARAM_GENERIC_ENABLE_VNET_TYPE, 79 }, 80 { 81 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_IWARP, 82 .name = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_NAME, 83 .type = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_TYPE, 84 }, 85 { 86 .id = DEVLINK_PARAM_GENERIC_ID_IO_EQ_SIZE, 87 .name = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_NAME, 88 .type = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_TYPE, 89 }, 90 { 91 .id = DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE, 92 .name = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_NAME, 93 .type = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_TYPE, 94 }, 95 { 96 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_PHC, 97 .name = DEVLINK_PARAM_GENERIC_ENABLE_PHC_NAME, 98 .type = DEVLINK_PARAM_GENERIC_ENABLE_PHC_TYPE, 99 }, 100 { 101 .id = DEVLINK_PARAM_GENERIC_ID_CLOCK_ID, 102 .name = DEVLINK_PARAM_GENERIC_CLOCK_ID_NAME, 103 .type = DEVLINK_PARAM_GENERIC_CLOCK_ID_TYPE, 104 }, 105 { 106 .id = DEVLINK_PARAM_GENERIC_ID_TOTAL_VFS, 107 .name = DEVLINK_PARAM_GENERIC_TOTAL_VFS_NAME, 108 .type = DEVLINK_PARAM_GENERIC_TOTAL_VFS_TYPE, 109 }, 110 { 111 .id = DEVLINK_PARAM_GENERIC_ID_NUM_DOORBELLS, 112 .name = DEVLINK_PARAM_GENERIC_NUM_DOORBELLS_NAME, 113 .type = DEVLINK_PARAM_GENERIC_NUM_DOORBELLS_TYPE, 114 }, 115 { 116 .id = DEVLINK_PARAM_GENERIC_ID_MAX_MAC_PER_VF, 117 .name = DEVLINK_PARAM_GENERIC_MAX_MAC_PER_VF_NAME, 118 .type = DEVLINK_PARAM_GENERIC_MAX_MAC_PER_VF_TYPE, 119 }, 120 }; 121 122 static int devlink_param_generic_verify(const struct devlink_param *param) 123 { 124 /* verify it match generic parameter by id and name */ 125 if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX) 126 return -EINVAL; 127 if (strcmp(param->name, devlink_param_generic[param->id].name)) 128 return -ENOENT; 129 130 WARN_ON(param->type != devlink_param_generic[param->id].type); 131 132 return 0; 133 } 134 135 static int devlink_param_driver_verify(const struct devlink_param *param) 136 { 137 int i; 138 139 if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX) 140 return -EINVAL; 141 /* verify no such name in generic params */ 142 for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++) 143 if (!strcmp(param->name, devlink_param_generic[i].name)) 144 return -EEXIST; 145 146 return 0; 147 } 148 149 static struct devlink_param_item * 150 devlink_param_find_by_name(struct xarray *params, const char *param_name) 151 { 152 struct devlink_param_item *param_item; 153 unsigned long param_id; 154 155 xa_for_each(params, param_id, param_item) { 156 if (!strcmp(param_item->param->name, param_name)) 157 return param_item; 158 } 159 return NULL; 160 } 161 162 static struct devlink_param_item * 163 devlink_param_find_by_id(struct xarray *params, u32 param_id) 164 { 165 return xa_load(params, param_id); 166 } 167 168 static bool 169 devlink_param_cmode_is_supported(const struct devlink_param *param, 170 enum devlink_param_cmode cmode) 171 { 172 return test_bit(cmode, ¶m->supported_cmodes); 173 } 174 175 static int devlink_param_get(struct devlink *devlink, 176 const struct devlink_param *param, 177 struct devlink_param_gset_ctx *ctx, 178 struct netlink_ext_ack *extack) 179 { 180 if (!param->get) 181 return -EOPNOTSUPP; 182 return param->get(devlink, param->id, ctx, extack); 183 } 184 185 static int devlink_param_set(struct devlink *devlink, 186 const struct devlink_param *param, 187 struct devlink_param_gset_ctx *ctx, 188 struct netlink_ext_ack *extack) 189 { 190 if (!param->set) 191 return -EOPNOTSUPP; 192 return param->set(devlink, param->id, ctx, extack); 193 } 194 195 static int devlink_param_get_default(struct devlink *devlink, 196 const struct devlink_param *param, 197 struct devlink_param_gset_ctx *ctx, 198 struct netlink_ext_ack *extack) 199 { 200 if (!param->get_default) 201 return -EOPNOTSUPP; 202 203 return param->get_default(devlink, param->id, ctx, extack); 204 } 205 206 static int devlink_param_reset_default(struct devlink *devlink, 207 const struct devlink_param *param, 208 enum devlink_param_cmode cmode, 209 struct netlink_ext_ack *extack) 210 { 211 if (!param->reset_default) 212 return -EOPNOTSUPP; 213 214 return param->reset_default(devlink, param->id, cmode, extack); 215 } 216 217 static int 218 devlink_nl_param_value_put(struct sk_buff *msg, enum devlink_param_type type, 219 int nla_type, union devlink_param_value val, 220 bool flag_as_u8) 221 { 222 switch (type) { 223 case DEVLINK_PARAM_TYPE_U8: 224 if (nla_put_u8(msg, nla_type, val.vu8)) 225 return -EMSGSIZE; 226 break; 227 case DEVLINK_PARAM_TYPE_U16: 228 if (nla_put_u16(msg, nla_type, val.vu16)) 229 return -EMSGSIZE; 230 break; 231 case DEVLINK_PARAM_TYPE_U32: 232 if (nla_put_u32(msg, nla_type, val.vu32)) 233 return -EMSGSIZE; 234 break; 235 case DEVLINK_PARAM_TYPE_U64: 236 if (devlink_nl_put_u64(msg, nla_type, val.vu64)) 237 return -EMSGSIZE; 238 break; 239 case DEVLINK_PARAM_TYPE_STRING: 240 if (nla_put_string(msg, nla_type, val.vstr)) 241 return -EMSGSIZE; 242 break; 243 case DEVLINK_PARAM_TYPE_BOOL: 244 /* default values of type bool are encoded with u8, so that 245 * false can be distinguished from not present 246 */ 247 if (flag_as_u8) { 248 if (nla_put_u8(msg, nla_type, val.vbool)) 249 return -EMSGSIZE; 250 } else { 251 if (val.vbool && nla_put_flag(msg, nla_type)) 252 return -EMSGSIZE; 253 } 254 break; 255 } 256 return 0; 257 } 258 259 static int 260 devlink_nl_param_value_fill_one(struct sk_buff *msg, 261 enum devlink_param_type type, 262 enum devlink_param_cmode cmode, 263 union devlink_param_value val, 264 union devlink_param_value default_val, 265 bool has_default) 266 { 267 struct nlattr *param_value_attr; 268 int err = -EMSGSIZE; 269 270 param_value_attr = nla_nest_start_noflag(msg, 271 DEVLINK_ATTR_PARAM_VALUE); 272 if (!param_value_attr) 273 return -EMSGSIZE; 274 275 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode)) 276 goto value_nest_cancel; 277 278 err = devlink_nl_param_value_put(msg, type, 279 DEVLINK_ATTR_PARAM_VALUE_DATA, 280 val, false); 281 if (err) 282 goto value_nest_cancel; 283 284 if (has_default) { 285 err = devlink_nl_param_value_put(msg, type, 286 DEVLINK_ATTR_PARAM_VALUE_DEFAULT, 287 default_val, true); 288 if (err) 289 goto value_nest_cancel; 290 } 291 292 nla_nest_end(msg, param_value_attr); 293 return 0; 294 295 value_nest_cancel: 296 nla_nest_cancel(msg, param_value_attr); 297 return err; 298 } 299 300 static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink, 301 unsigned int port_index, 302 struct devlink_param_item *param_item, 303 enum devlink_command cmd, 304 u32 portid, u32 seq, int flags, 305 struct netlink_ext_ack *extack) 306 { 307 union devlink_param_value default_value[DEVLINK_PARAM_CMODE_MAX + 1]; 308 union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1]; 309 bool default_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {}; 310 bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {}; 311 const struct devlink_param *param = param_item->param; 312 struct devlink_param_gset_ctx ctx; 313 struct nlattr *param_values_list; 314 struct nlattr *param_attr; 315 void *hdr; 316 int err; 317 int i; 318 319 /* Get value from driver part to driverinit configuration mode */ 320 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) { 321 if (!devlink_param_cmode_is_supported(param, i)) 322 continue; 323 if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) { 324 if (param_item->driverinit_value_new_valid) 325 param_value[i] = param_item->driverinit_value_new; 326 else if (param_item->driverinit_value_valid) 327 param_value[i] = param_item->driverinit_value; 328 else 329 return -EOPNOTSUPP; 330 331 if (param_item->driverinit_value_valid) { 332 default_value[i] = param_item->driverinit_default; 333 default_value_set[i] = true; 334 } 335 } else { 336 ctx.cmode = i; 337 err = devlink_param_get(devlink, param, &ctx, extack); 338 if (err) 339 return err; 340 param_value[i] = ctx.val; 341 342 err = devlink_param_get_default(devlink, param, &ctx, 343 extack); 344 if (!err) { 345 default_value[i] = ctx.val; 346 default_value_set[i] = true; 347 } else if (err != -EOPNOTSUPP) { 348 return err; 349 } 350 } 351 param_value_set[i] = true; 352 } 353 354 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 355 if (!hdr) 356 return -EMSGSIZE; 357 358 if (devlink_nl_put_handle(msg, devlink)) 359 goto genlmsg_cancel; 360 361 if (cmd == DEVLINK_CMD_PORT_PARAM_GET || 362 cmd == DEVLINK_CMD_PORT_PARAM_NEW || 363 cmd == DEVLINK_CMD_PORT_PARAM_DEL) 364 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index)) 365 goto genlmsg_cancel; 366 367 param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM); 368 if (!param_attr) 369 goto genlmsg_cancel; 370 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name)) 371 goto param_nest_cancel; 372 if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC)) 373 goto param_nest_cancel; 374 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, param->type)) 375 goto param_nest_cancel; 376 377 param_values_list = nla_nest_start_noflag(msg, 378 DEVLINK_ATTR_PARAM_VALUES_LIST); 379 if (!param_values_list) 380 goto param_nest_cancel; 381 382 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) { 383 if (!param_value_set[i]) 384 continue; 385 err = devlink_nl_param_value_fill_one(msg, param->type, 386 i, param_value[i], 387 default_value[i], 388 default_value_set[i]); 389 if (err) 390 goto values_list_nest_cancel; 391 } 392 393 nla_nest_end(msg, param_values_list); 394 nla_nest_end(msg, param_attr); 395 genlmsg_end(msg, hdr); 396 return 0; 397 398 values_list_nest_cancel: 399 nla_nest_end(msg, param_values_list); 400 param_nest_cancel: 401 nla_nest_cancel(msg, param_attr); 402 genlmsg_cancel: 403 genlmsg_cancel(msg, hdr); 404 return -EMSGSIZE; 405 } 406 407 static void devlink_param_notify(struct devlink *devlink, 408 unsigned int port_index, 409 struct devlink_param_item *param_item, 410 enum devlink_command cmd) 411 { 412 struct sk_buff *msg; 413 int err; 414 415 WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL && 416 cmd != DEVLINK_CMD_PORT_PARAM_NEW && 417 cmd != DEVLINK_CMD_PORT_PARAM_DEL); 418 419 /* devlink_notify_register() / devlink_notify_unregister() 420 * will replay the notifications if the params are added/removed 421 * outside of the lifetime of the instance. 422 */ 423 if (!devl_is_registered(devlink) || !devlink_nl_notify_need(devlink)) 424 return; 425 426 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 427 if (!msg) 428 return; 429 err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd, 430 0, 0, 0, NULL); 431 if (err) { 432 nlmsg_free(msg); 433 return; 434 } 435 436 devlink_nl_notify_send(devlink, msg); 437 } 438 439 static void devlink_params_notify(struct devlink *devlink, 440 enum devlink_command cmd) 441 { 442 struct devlink_param_item *param_item; 443 unsigned long param_id; 444 445 xa_for_each(&devlink->params, param_id, param_item) 446 devlink_param_notify(devlink, 0, param_item, cmd); 447 } 448 449 void devlink_params_notify_register(struct devlink *devlink) 450 { 451 devlink_params_notify(devlink, DEVLINK_CMD_PARAM_NEW); 452 } 453 454 void devlink_params_notify_unregister(struct devlink *devlink) 455 { 456 devlink_params_notify(devlink, DEVLINK_CMD_PARAM_DEL); 457 } 458 459 static int devlink_nl_param_get_dump_one(struct sk_buff *msg, 460 struct devlink *devlink, 461 struct netlink_callback *cb, 462 int flags) 463 { 464 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 465 struct devlink_param_item *param_item; 466 unsigned long param_id; 467 int err = 0; 468 469 xa_for_each_start(&devlink->params, param_id, param_item, state->idx) { 470 err = devlink_nl_param_fill(msg, devlink, 0, param_item, 471 DEVLINK_CMD_PARAM_GET, 472 NETLINK_CB(cb->skb).portid, 473 cb->nlh->nlmsg_seq, flags, 474 cb->extack); 475 if (err == -EOPNOTSUPP) { 476 err = 0; 477 } else if (err) { 478 state->idx = param_id; 479 break; 480 } 481 } 482 483 return err; 484 } 485 486 int devlink_nl_param_get_dumpit(struct sk_buff *skb, 487 struct netlink_callback *cb) 488 { 489 return devlink_nl_dumpit(skb, cb, devlink_nl_param_get_dump_one); 490 } 491 492 static int 493 devlink_param_type_get_from_info(struct genl_info *info, 494 enum devlink_param_type *param_type) 495 { 496 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_TYPE)) 497 return -EINVAL; 498 499 *param_type = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE]); 500 501 return 0; 502 } 503 504 static int 505 devlink_param_value_get_from_info(const struct devlink_param *param, 506 struct genl_info *info, 507 union devlink_param_value *value) 508 { 509 struct nlattr *param_data; 510 int len; 511 512 param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]; 513 514 if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data) 515 return -EINVAL; 516 517 switch (param->type) { 518 case DEVLINK_PARAM_TYPE_U8: 519 if (nla_len(param_data) != sizeof(u8)) 520 return -EINVAL; 521 value->vu8 = nla_get_u8(param_data); 522 break; 523 case DEVLINK_PARAM_TYPE_U16: 524 if (nla_len(param_data) != sizeof(u16)) 525 return -EINVAL; 526 value->vu16 = nla_get_u16(param_data); 527 break; 528 case DEVLINK_PARAM_TYPE_U32: 529 if (nla_len(param_data) != sizeof(u32)) 530 return -EINVAL; 531 value->vu32 = nla_get_u32(param_data); 532 break; 533 case DEVLINK_PARAM_TYPE_U64: 534 if (nla_len(param_data) != sizeof(u64)) 535 return -EINVAL; 536 value->vu64 = nla_get_u64(param_data); 537 break; 538 case DEVLINK_PARAM_TYPE_STRING: 539 len = strnlen(nla_data(param_data), nla_len(param_data)); 540 if (len == nla_len(param_data) || 541 len >= __DEVLINK_PARAM_MAX_STRING_VALUE) 542 return -EINVAL; 543 strcpy(value->vstr, nla_data(param_data)); 544 break; 545 case DEVLINK_PARAM_TYPE_BOOL: 546 if (param_data && nla_len(param_data)) 547 return -EINVAL; 548 value->vbool = nla_get_flag(param_data); 549 break; 550 } 551 return 0; 552 } 553 554 static struct devlink_param_item * 555 devlink_param_get_from_info(struct xarray *params, struct genl_info *info) 556 { 557 char *param_name; 558 559 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_NAME)) 560 return NULL; 561 562 param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]); 563 return devlink_param_find_by_name(params, param_name); 564 } 565 566 int devlink_nl_param_get_doit(struct sk_buff *skb, 567 struct genl_info *info) 568 { 569 struct devlink *devlink = info->user_ptr[0]; 570 struct devlink_param_item *param_item; 571 struct sk_buff *msg; 572 int err; 573 574 param_item = devlink_param_get_from_info(&devlink->params, info); 575 if (!param_item) 576 return -EINVAL; 577 578 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 579 if (!msg) 580 return -ENOMEM; 581 582 err = devlink_nl_param_fill(msg, devlink, 0, param_item, 583 DEVLINK_CMD_PARAM_GET, info->snd_portid, 584 info->snd_seq, 0, info->extack); 585 if (err) { 586 nlmsg_free(msg); 587 return err; 588 } 589 590 return genlmsg_reply(msg, info); 591 } 592 593 static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink, 594 unsigned int port_index, 595 struct xarray *params, 596 struct genl_info *info, 597 enum devlink_command cmd) 598 { 599 enum devlink_param_type param_type; 600 struct devlink_param_gset_ctx ctx; 601 enum devlink_param_cmode cmode; 602 struct devlink_param_item *param_item; 603 const struct devlink_param *param; 604 union devlink_param_value value; 605 bool reset_default; 606 int err = 0; 607 608 param_item = devlink_param_get_from_info(params, info); 609 if (!param_item) 610 return -EINVAL; 611 param = param_item->param; 612 err = devlink_param_type_get_from_info(info, ¶m_type); 613 if (err) 614 return err; 615 if (param_type != param->type) 616 return -EINVAL; 617 618 reset_default = info->attrs[DEVLINK_ATTR_PARAM_RESET_DEFAULT]; 619 if (!reset_default) { 620 err = devlink_param_value_get_from_info(param, info, &value); 621 if (err) 622 return err; 623 if (param->validate) { 624 err = param->validate(devlink, param->id, value, 625 info->extack); 626 if (err) 627 return err; 628 } 629 } 630 631 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_VALUE_CMODE)) 632 return -EINVAL; 633 cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]); 634 if (!devlink_param_cmode_is_supported(param, cmode)) 635 return -EOPNOTSUPP; 636 637 if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) { 638 if (reset_default) { 639 if (!param_item->driverinit_value_valid) { 640 NL_SET_ERR_MSG(info->extack, 641 "Default value not available"); 642 return -EOPNOTSUPP; 643 } 644 value = param_item->driverinit_default; 645 } 646 647 param_item->driverinit_value_new = value; 648 param_item->driverinit_value_new_valid = true; 649 } else { 650 if (!param->set) 651 return -EOPNOTSUPP; 652 ctx.val = value; 653 ctx.cmode = cmode; 654 if (reset_default) 655 err = devlink_param_reset_default(devlink, param, cmode, 656 info->extack); 657 else 658 err = devlink_param_set(devlink, param, &ctx, 659 info->extack); 660 if (err) 661 return err; 662 } 663 664 devlink_param_notify(devlink, port_index, param_item, cmd); 665 return 0; 666 } 667 668 int devlink_nl_param_set_doit(struct sk_buff *skb, struct genl_info *info) 669 { 670 struct devlink *devlink = info->user_ptr[0]; 671 672 return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->params, 673 info, DEVLINK_CMD_PARAM_NEW); 674 } 675 676 int devlink_nl_port_param_get_dumpit(struct sk_buff *msg, 677 struct netlink_callback *cb) 678 { 679 NL_SET_ERR_MSG(cb->extack, "Port params are not supported"); 680 return msg->len; 681 } 682 683 int devlink_nl_port_param_get_doit(struct sk_buff *skb, 684 struct genl_info *info) 685 { 686 NL_SET_ERR_MSG(info->extack, "Port params are not supported"); 687 return -EINVAL; 688 } 689 690 int devlink_nl_port_param_set_doit(struct sk_buff *skb, 691 struct genl_info *info) 692 { 693 NL_SET_ERR_MSG(info->extack, "Port params are not supported"); 694 return -EINVAL; 695 } 696 697 static int devlink_param_verify(const struct devlink_param *param) 698 { 699 if (!param || !param->name || !param->supported_cmodes) 700 return -EINVAL; 701 if (param->generic) 702 return devlink_param_generic_verify(param); 703 else 704 return devlink_param_driver_verify(param); 705 } 706 707 static int devlink_param_register(struct devlink *devlink, 708 const struct devlink_param *param) 709 { 710 struct devlink_param_item *param_item; 711 int err; 712 713 WARN_ON(devlink_param_verify(param)); 714 WARN_ON(devlink_param_find_by_name(&devlink->params, param->name)); 715 716 if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT)) 717 WARN_ON(param->get || param->set); 718 else 719 WARN_ON(!param->get || !param->set); 720 721 param_item = kzalloc(sizeof(*param_item), GFP_KERNEL); 722 if (!param_item) 723 return -ENOMEM; 724 725 param_item->param = param; 726 727 err = xa_insert(&devlink->params, param->id, param_item, GFP_KERNEL); 728 if (err) 729 goto err_xa_insert; 730 731 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW); 732 return 0; 733 734 err_xa_insert: 735 kfree(param_item); 736 return err; 737 } 738 739 static void devlink_param_unregister(struct devlink *devlink, 740 const struct devlink_param *param) 741 { 742 struct devlink_param_item *param_item; 743 744 param_item = devlink_param_find_by_id(&devlink->params, param->id); 745 if (WARN_ON(!param_item)) 746 return; 747 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_DEL); 748 xa_erase(&devlink->params, param->id); 749 kfree(param_item); 750 } 751 752 /** 753 * devl_params_register - register configuration parameters 754 * 755 * @devlink: devlink 756 * @params: configuration parameters array 757 * @params_count: number of parameters provided 758 * 759 * Register the configuration parameters supported by the driver. 760 */ 761 int devl_params_register(struct devlink *devlink, 762 const struct devlink_param *params, 763 size_t params_count) 764 { 765 const struct devlink_param *param = params; 766 int i, err; 767 768 lockdep_assert_held(&devlink->lock); 769 770 for (i = 0; i < params_count; i++, param++) { 771 err = devlink_param_register(devlink, param); 772 if (err) 773 goto rollback; 774 } 775 return 0; 776 777 rollback: 778 if (!i) 779 return err; 780 781 for (param--; i > 0; i--, param--) 782 devlink_param_unregister(devlink, param); 783 return err; 784 } 785 EXPORT_SYMBOL_GPL(devl_params_register); 786 787 int devlink_params_register(struct devlink *devlink, 788 const struct devlink_param *params, 789 size_t params_count) 790 { 791 int err; 792 793 devl_lock(devlink); 794 err = devl_params_register(devlink, params, params_count); 795 devl_unlock(devlink); 796 return err; 797 } 798 EXPORT_SYMBOL_GPL(devlink_params_register); 799 800 /** 801 * devl_params_unregister - unregister configuration parameters 802 * @devlink: devlink 803 * @params: configuration parameters to unregister 804 * @params_count: number of parameters provided 805 */ 806 void devl_params_unregister(struct devlink *devlink, 807 const struct devlink_param *params, 808 size_t params_count) 809 { 810 const struct devlink_param *param = params; 811 int i; 812 813 lockdep_assert_held(&devlink->lock); 814 815 for (i = 0; i < params_count; i++, param++) 816 devlink_param_unregister(devlink, param); 817 } 818 EXPORT_SYMBOL_GPL(devl_params_unregister); 819 820 void devlink_params_unregister(struct devlink *devlink, 821 const struct devlink_param *params, 822 size_t params_count) 823 { 824 devl_lock(devlink); 825 devl_params_unregister(devlink, params, params_count); 826 devl_unlock(devlink); 827 } 828 EXPORT_SYMBOL_GPL(devlink_params_unregister); 829 830 /** 831 * devl_param_driverinit_value_get - get configuration parameter 832 * value for driver initializing 833 * 834 * @devlink: devlink 835 * @param_id: parameter ID 836 * @val: pointer to store the value of parameter in driverinit 837 * configuration mode 838 * 839 * This function should be used by the driver to get driverinit 840 * configuration for initialization after reload command. 841 * 842 * Note that lockless call of this function relies on the 843 * driver to maintain following basic sane behavior: 844 * 1) Driver ensures a call to this function cannot race with 845 * registering/unregistering the parameter with the same parameter ID. 846 * 2) Driver ensures a call to this function cannot race with 847 * devl_param_driverinit_value_set() call with the same parameter ID. 848 * 3) Driver ensures a call to this function cannot race with 849 * reload operation. 850 * If the driver is not able to comply, it has to take the devlink->lock 851 * while calling this. 852 */ 853 int devl_param_driverinit_value_get(struct devlink *devlink, u32 param_id, 854 union devlink_param_value *val) 855 { 856 struct devlink_param_item *param_item; 857 858 if (WARN_ON(!devlink_reload_supported(devlink->ops))) 859 return -EOPNOTSUPP; 860 861 param_item = devlink_param_find_by_id(&devlink->params, param_id); 862 if (!param_item) 863 return -EINVAL; 864 865 if (!param_item->driverinit_value_valid) 866 return -EOPNOTSUPP; 867 868 if (WARN_ON(!devlink_param_cmode_is_supported(param_item->param, 869 DEVLINK_PARAM_CMODE_DRIVERINIT))) 870 return -EOPNOTSUPP; 871 872 *val = param_item->driverinit_value; 873 874 return 0; 875 } 876 EXPORT_SYMBOL_GPL(devl_param_driverinit_value_get); 877 878 /** 879 * devl_param_driverinit_value_set - set value of configuration 880 * parameter for driverinit 881 * configuration mode 882 * 883 * @devlink: devlink 884 * @param_id: parameter ID 885 * @init_val: value of parameter to set for driverinit configuration mode 886 * 887 * This function should be used by the driver to set driverinit 888 * configuration mode default value. 889 */ 890 void devl_param_driverinit_value_set(struct devlink *devlink, u32 param_id, 891 union devlink_param_value init_val) 892 { 893 struct devlink_param_item *param_item; 894 895 devl_assert_locked(devlink); 896 897 param_item = devlink_param_find_by_id(&devlink->params, param_id); 898 if (WARN_ON(!param_item)) 899 return; 900 901 if (WARN_ON(!devlink_param_cmode_is_supported(param_item->param, 902 DEVLINK_PARAM_CMODE_DRIVERINIT))) 903 return; 904 905 param_item->driverinit_value = init_val; 906 param_item->driverinit_value_valid = true; 907 param_item->driverinit_default = init_val; 908 909 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW); 910 } 911 EXPORT_SYMBOL_GPL(devl_param_driverinit_value_set); 912 913 void devlink_params_driverinit_load_new(struct devlink *devlink) 914 { 915 struct devlink_param_item *param_item; 916 unsigned long param_id; 917 918 xa_for_each(&devlink->params, param_id, param_item) { 919 if (!devlink_param_cmode_is_supported(param_item->param, 920 DEVLINK_PARAM_CMODE_DRIVERINIT) || 921 !param_item->driverinit_value_new_valid) 922 continue; 923 param_item->driverinit_value = param_item->driverinit_value_new; 924 param_item->driverinit_value_valid = true; 925 param_item->driverinit_value_new_valid = false; 926 } 927 } 928 929 /** 930 * devl_param_value_changed - notify devlink on a parameter's value 931 * change. Should be called by the driver 932 * right after the change. 933 * 934 * @devlink: devlink 935 * @param_id: parameter ID 936 * 937 * This function should be used by the driver to notify devlink on value 938 * change, excluding driverinit configuration mode. 939 * For driverinit configuration mode driver should use the function 940 */ 941 void devl_param_value_changed(struct devlink *devlink, u32 param_id) 942 { 943 struct devlink_param_item *param_item; 944 945 param_item = devlink_param_find_by_id(&devlink->params, param_id); 946 WARN_ON(!param_item); 947 948 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW); 949 } 950 EXPORT_SYMBOL_GPL(devl_param_value_changed); 951