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 112 static int devlink_param_generic_verify(const struct devlink_param *param) 113 { 114 /* verify it match generic parameter by id and name */ 115 if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX) 116 return -EINVAL; 117 if (strcmp(param->name, devlink_param_generic[param->id].name)) 118 return -ENOENT; 119 120 WARN_ON(param->type != devlink_param_generic[param->id].type); 121 122 return 0; 123 } 124 125 static int devlink_param_driver_verify(const struct devlink_param *param) 126 { 127 int i; 128 129 if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX) 130 return -EINVAL; 131 /* verify no such name in generic params */ 132 for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++) 133 if (!strcmp(param->name, devlink_param_generic[i].name)) 134 return -EEXIST; 135 136 return 0; 137 } 138 139 static struct devlink_param_item * 140 devlink_param_find_by_name(struct xarray *params, const char *param_name) 141 { 142 struct devlink_param_item *param_item; 143 unsigned long param_id; 144 145 xa_for_each(params, param_id, param_item) { 146 if (!strcmp(param_item->param->name, param_name)) 147 return param_item; 148 } 149 return NULL; 150 } 151 152 static struct devlink_param_item * 153 devlink_param_find_by_id(struct xarray *params, u32 param_id) 154 { 155 return xa_load(params, param_id); 156 } 157 158 static bool 159 devlink_param_cmode_is_supported(const struct devlink_param *param, 160 enum devlink_param_cmode cmode) 161 { 162 return test_bit(cmode, ¶m->supported_cmodes); 163 } 164 165 static int devlink_param_get(struct devlink *devlink, 166 const struct devlink_param *param, 167 struct devlink_param_gset_ctx *ctx) 168 { 169 if (!param->get) 170 return -EOPNOTSUPP; 171 return param->get(devlink, param->id, ctx); 172 } 173 174 static int devlink_param_set(struct devlink *devlink, 175 const struct devlink_param *param, 176 struct devlink_param_gset_ctx *ctx, 177 struct netlink_ext_ack *extack) 178 { 179 if (!param->set) 180 return -EOPNOTSUPP; 181 return param->set(devlink, param->id, ctx, extack); 182 } 183 184 static int 185 devlink_nl_param_value_fill_one(struct sk_buff *msg, 186 enum devlink_param_type type, 187 enum devlink_param_cmode cmode, 188 union devlink_param_value val) 189 { 190 struct nlattr *param_value_attr; 191 192 param_value_attr = nla_nest_start_noflag(msg, 193 DEVLINK_ATTR_PARAM_VALUE); 194 if (!param_value_attr) 195 goto nla_put_failure; 196 197 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode)) 198 goto value_nest_cancel; 199 200 switch (type) { 201 case DEVLINK_PARAM_TYPE_U8: 202 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8)) 203 goto value_nest_cancel; 204 break; 205 case DEVLINK_PARAM_TYPE_U16: 206 if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16)) 207 goto value_nest_cancel; 208 break; 209 case DEVLINK_PARAM_TYPE_U32: 210 if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32)) 211 goto value_nest_cancel; 212 break; 213 case DEVLINK_PARAM_TYPE_U64: 214 if (devlink_nl_put_u64(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, 215 val.vu64)) 216 goto value_nest_cancel; 217 break; 218 case DEVLINK_PARAM_TYPE_STRING: 219 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, 220 val.vstr)) 221 goto value_nest_cancel; 222 break; 223 case DEVLINK_PARAM_TYPE_BOOL: 224 if (val.vbool && 225 nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA)) 226 goto value_nest_cancel; 227 break; 228 } 229 230 nla_nest_end(msg, param_value_attr); 231 return 0; 232 233 value_nest_cancel: 234 nla_nest_cancel(msg, param_value_attr); 235 nla_put_failure: 236 return -EMSGSIZE; 237 } 238 239 static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink, 240 unsigned int port_index, 241 struct devlink_param_item *param_item, 242 enum devlink_command cmd, 243 u32 portid, u32 seq, int flags) 244 { 245 union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1]; 246 bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {}; 247 const struct devlink_param *param = param_item->param; 248 struct devlink_param_gset_ctx ctx; 249 struct nlattr *param_values_list; 250 struct nlattr *param_attr; 251 void *hdr; 252 int err; 253 int i; 254 255 /* Get value from driver part to driverinit configuration mode */ 256 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) { 257 if (!devlink_param_cmode_is_supported(param, i)) 258 continue; 259 if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) { 260 if (param_item->driverinit_value_new_valid) 261 param_value[i] = param_item->driverinit_value_new; 262 else if (param_item->driverinit_value_valid) 263 param_value[i] = param_item->driverinit_value; 264 else 265 return -EOPNOTSUPP; 266 } else { 267 ctx.cmode = i; 268 err = devlink_param_get(devlink, param, &ctx); 269 if (err) 270 return err; 271 param_value[i] = ctx.val; 272 } 273 param_value_set[i] = true; 274 } 275 276 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 277 if (!hdr) 278 return -EMSGSIZE; 279 280 if (devlink_nl_put_handle(msg, devlink)) 281 goto genlmsg_cancel; 282 283 if (cmd == DEVLINK_CMD_PORT_PARAM_GET || 284 cmd == DEVLINK_CMD_PORT_PARAM_NEW || 285 cmd == DEVLINK_CMD_PORT_PARAM_DEL) 286 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index)) 287 goto genlmsg_cancel; 288 289 param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM); 290 if (!param_attr) 291 goto genlmsg_cancel; 292 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name)) 293 goto param_nest_cancel; 294 if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC)) 295 goto param_nest_cancel; 296 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, param->type)) 297 goto param_nest_cancel; 298 299 param_values_list = nla_nest_start_noflag(msg, 300 DEVLINK_ATTR_PARAM_VALUES_LIST); 301 if (!param_values_list) 302 goto param_nest_cancel; 303 304 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) { 305 if (!param_value_set[i]) 306 continue; 307 err = devlink_nl_param_value_fill_one(msg, param->type, 308 i, param_value[i]); 309 if (err) 310 goto values_list_nest_cancel; 311 } 312 313 nla_nest_end(msg, param_values_list); 314 nla_nest_end(msg, param_attr); 315 genlmsg_end(msg, hdr); 316 return 0; 317 318 values_list_nest_cancel: 319 nla_nest_end(msg, param_values_list); 320 param_nest_cancel: 321 nla_nest_cancel(msg, param_attr); 322 genlmsg_cancel: 323 genlmsg_cancel(msg, hdr); 324 return -EMSGSIZE; 325 } 326 327 static void devlink_param_notify(struct devlink *devlink, 328 unsigned int port_index, 329 struct devlink_param_item *param_item, 330 enum devlink_command cmd) 331 { 332 struct sk_buff *msg; 333 int err; 334 335 WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL && 336 cmd != DEVLINK_CMD_PORT_PARAM_NEW && 337 cmd != DEVLINK_CMD_PORT_PARAM_DEL); 338 339 /* devlink_notify_register() / devlink_notify_unregister() 340 * will replay the notifications if the params are added/removed 341 * outside of the lifetime of the instance. 342 */ 343 if (!devl_is_registered(devlink) || !devlink_nl_notify_need(devlink)) 344 return; 345 346 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 347 if (!msg) 348 return; 349 err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd, 350 0, 0, 0); 351 if (err) { 352 nlmsg_free(msg); 353 return; 354 } 355 356 devlink_nl_notify_send(devlink, msg); 357 } 358 359 static void devlink_params_notify(struct devlink *devlink, 360 enum devlink_command cmd) 361 { 362 struct devlink_param_item *param_item; 363 unsigned long param_id; 364 365 xa_for_each(&devlink->params, param_id, param_item) 366 devlink_param_notify(devlink, 0, param_item, cmd); 367 } 368 369 void devlink_params_notify_register(struct devlink *devlink) 370 { 371 devlink_params_notify(devlink, DEVLINK_CMD_PARAM_NEW); 372 } 373 374 void devlink_params_notify_unregister(struct devlink *devlink) 375 { 376 devlink_params_notify(devlink, DEVLINK_CMD_PARAM_DEL); 377 } 378 379 static int devlink_nl_param_get_dump_one(struct sk_buff *msg, 380 struct devlink *devlink, 381 struct netlink_callback *cb, 382 int flags) 383 { 384 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 385 struct devlink_param_item *param_item; 386 unsigned long param_id; 387 int err = 0; 388 389 xa_for_each_start(&devlink->params, param_id, param_item, state->idx) { 390 err = devlink_nl_param_fill(msg, devlink, 0, param_item, 391 DEVLINK_CMD_PARAM_GET, 392 NETLINK_CB(cb->skb).portid, 393 cb->nlh->nlmsg_seq, flags); 394 if (err == -EOPNOTSUPP) { 395 err = 0; 396 } else if (err) { 397 state->idx = param_id; 398 break; 399 } 400 } 401 402 return err; 403 } 404 405 int devlink_nl_param_get_dumpit(struct sk_buff *skb, 406 struct netlink_callback *cb) 407 { 408 return devlink_nl_dumpit(skb, cb, devlink_nl_param_get_dump_one); 409 } 410 411 static int 412 devlink_param_type_get_from_info(struct genl_info *info, 413 enum devlink_param_type *param_type) 414 { 415 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_TYPE)) 416 return -EINVAL; 417 418 *param_type = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE]); 419 420 return 0; 421 } 422 423 static int 424 devlink_param_value_get_from_info(const struct devlink_param *param, 425 struct genl_info *info, 426 union devlink_param_value *value) 427 { 428 struct nlattr *param_data; 429 int len; 430 431 param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]; 432 433 if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data) 434 return -EINVAL; 435 436 switch (param->type) { 437 case DEVLINK_PARAM_TYPE_U8: 438 if (nla_len(param_data) != sizeof(u8)) 439 return -EINVAL; 440 value->vu8 = nla_get_u8(param_data); 441 break; 442 case DEVLINK_PARAM_TYPE_U16: 443 if (nla_len(param_data) != sizeof(u16)) 444 return -EINVAL; 445 value->vu16 = nla_get_u16(param_data); 446 break; 447 case DEVLINK_PARAM_TYPE_U32: 448 if (nla_len(param_data) != sizeof(u32)) 449 return -EINVAL; 450 value->vu32 = nla_get_u32(param_data); 451 break; 452 case DEVLINK_PARAM_TYPE_U64: 453 if (nla_len(param_data) != sizeof(u64)) 454 return -EINVAL; 455 value->vu64 = nla_get_u64(param_data); 456 break; 457 case DEVLINK_PARAM_TYPE_STRING: 458 len = strnlen(nla_data(param_data), nla_len(param_data)); 459 if (len == nla_len(param_data) || 460 len >= __DEVLINK_PARAM_MAX_STRING_VALUE) 461 return -EINVAL; 462 strcpy(value->vstr, nla_data(param_data)); 463 break; 464 case DEVLINK_PARAM_TYPE_BOOL: 465 if (param_data && nla_len(param_data)) 466 return -EINVAL; 467 value->vbool = nla_get_flag(param_data); 468 break; 469 } 470 return 0; 471 } 472 473 static struct devlink_param_item * 474 devlink_param_get_from_info(struct xarray *params, struct genl_info *info) 475 { 476 char *param_name; 477 478 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_NAME)) 479 return NULL; 480 481 param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]); 482 return devlink_param_find_by_name(params, param_name); 483 } 484 485 int devlink_nl_param_get_doit(struct sk_buff *skb, 486 struct genl_info *info) 487 { 488 struct devlink *devlink = info->user_ptr[0]; 489 struct devlink_param_item *param_item; 490 struct sk_buff *msg; 491 int err; 492 493 param_item = devlink_param_get_from_info(&devlink->params, info); 494 if (!param_item) 495 return -EINVAL; 496 497 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 498 if (!msg) 499 return -ENOMEM; 500 501 err = devlink_nl_param_fill(msg, devlink, 0, param_item, 502 DEVLINK_CMD_PARAM_GET, 503 info->snd_portid, info->snd_seq, 0); 504 if (err) { 505 nlmsg_free(msg); 506 return err; 507 } 508 509 return genlmsg_reply(msg, info); 510 } 511 512 static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink, 513 unsigned int port_index, 514 struct xarray *params, 515 struct genl_info *info, 516 enum devlink_command cmd) 517 { 518 enum devlink_param_type param_type; 519 struct devlink_param_gset_ctx ctx; 520 enum devlink_param_cmode cmode; 521 struct devlink_param_item *param_item; 522 const struct devlink_param *param; 523 union devlink_param_value value; 524 int err = 0; 525 526 param_item = devlink_param_get_from_info(params, info); 527 if (!param_item) 528 return -EINVAL; 529 param = param_item->param; 530 err = devlink_param_type_get_from_info(info, ¶m_type); 531 if (err) 532 return err; 533 if (param_type != param->type) 534 return -EINVAL; 535 err = devlink_param_value_get_from_info(param, info, &value); 536 if (err) 537 return err; 538 if (param->validate) { 539 err = param->validate(devlink, param->id, value, info->extack); 540 if (err) 541 return err; 542 } 543 544 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_VALUE_CMODE)) 545 return -EINVAL; 546 cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]); 547 if (!devlink_param_cmode_is_supported(param, cmode)) 548 return -EOPNOTSUPP; 549 550 if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) { 551 param_item->driverinit_value_new = value; 552 param_item->driverinit_value_new_valid = true; 553 } else { 554 if (!param->set) 555 return -EOPNOTSUPP; 556 ctx.val = value; 557 ctx.cmode = cmode; 558 err = devlink_param_set(devlink, param, &ctx, info->extack); 559 if (err) 560 return err; 561 } 562 563 devlink_param_notify(devlink, port_index, param_item, cmd); 564 return 0; 565 } 566 567 int devlink_nl_param_set_doit(struct sk_buff *skb, struct genl_info *info) 568 { 569 struct devlink *devlink = info->user_ptr[0]; 570 571 return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->params, 572 info, DEVLINK_CMD_PARAM_NEW); 573 } 574 575 int devlink_nl_port_param_get_dumpit(struct sk_buff *msg, 576 struct netlink_callback *cb) 577 { 578 NL_SET_ERR_MSG(cb->extack, "Port params are not supported"); 579 return msg->len; 580 } 581 582 int devlink_nl_port_param_get_doit(struct sk_buff *skb, 583 struct genl_info *info) 584 { 585 NL_SET_ERR_MSG(info->extack, "Port params are not supported"); 586 return -EINVAL; 587 } 588 589 int devlink_nl_port_param_set_doit(struct sk_buff *skb, 590 struct genl_info *info) 591 { 592 NL_SET_ERR_MSG(info->extack, "Port params are not supported"); 593 return -EINVAL; 594 } 595 596 static int devlink_param_verify(const struct devlink_param *param) 597 { 598 if (!param || !param->name || !param->supported_cmodes) 599 return -EINVAL; 600 if (param->generic) 601 return devlink_param_generic_verify(param); 602 else 603 return devlink_param_driver_verify(param); 604 } 605 606 static int devlink_param_register(struct devlink *devlink, 607 const struct devlink_param *param) 608 { 609 struct devlink_param_item *param_item; 610 int err; 611 612 WARN_ON(devlink_param_verify(param)); 613 WARN_ON(devlink_param_find_by_name(&devlink->params, param->name)); 614 615 if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT)) 616 WARN_ON(param->get || param->set); 617 else 618 WARN_ON(!param->get || !param->set); 619 620 param_item = kzalloc(sizeof(*param_item), GFP_KERNEL); 621 if (!param_item) 622 return -ENOMEM; 623 624 param_item->param = param; 625 626 err = xa_insert(&devlink->params, param->id, param_item, GFP_KERNEL); 627 if (err) 628 goto err_xa_insert; 629 630 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW); 631 return 0; 632 633 err_xa_insert: 634 kfree(param_item); 635 return err; 636 } 637 638 static void devlink_param_unregister(struct devlink *devlink, 639 const struct devlink_param *param) 640 { 641 struct devlink_param_item *param_item; 642 643 param_item = devlink_param_find_by_id(&devlink->params, param->id); 644 if (WARN_ON(!param_item)) 645 return; 646 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_DEL); 647 xa_erase(&devlink->params, param->id); 648 kfree(param_item); 649 } 650 651 /** 652 * devl_params_register - register configuration parameters 653 * 654 * @devlink: devlink 655 * @params: configuration parameters array 656 * @params_count: number of parameters provided 657 * 658 * Register the configuration parameters supported by the driver. 659 */ 660 int devl_params_register(struct devlink *devlink, 661 const struct devlink_param *params, 662 size_t params_count) 663 { 664 const struct devlink_param *param = params; 665 int i, err; 666 667 lockdep_assert_held(&devlink->lock); 668 669 for (i = 0; i < params_count; i++, param++) { 670 err = devlink_param_register(devlink, param); 671 if (err) 672 goto rollback; 673 } 674 return 0; 675 676 rollback: 677 if (!i) 678 return err; 679 680 for (param--; i > 0; i--, param--) 681 devlink_param_unregister(devlink, param); 682 return err; 683 } 684 EXPORT_SYMBOL_GPL(devl_params_register); 685 686 int devlink_params_register(struct devlink *devlink, 687 const struct devlink_param *params, 688 size_t params_count) 689 { 690 int err; 691 692 devl_lock(devlink); 693 err = devl_params_register(devlink, params, params_count); 694 devl_unlock(devlink); 695 return err; 696 } 697 EXPORT_SYMBOL_GPL(devlink_params_register); 698 699 /** 700 * devl_params_unregister - unregister configuration parameters 701 * @devlink: devlink 702 * @params: configuration parameters to unregister 703 * @params_count: number of parameters provided 704 */ 705 void devl_params_unregister(struct devlink *devlink, 706 const struct devlink_param *params, 707 size_t params_count) 708 { 709 const struct devlink_param *param = params; 710 int i; 711 712 lockdep_assert_held(&devlink->lock); 713 714 for (i = 0; i < params_count; i++, param++) 715 devlink_param_unregister(devlink, param); 716 } 717 EXPORT_SYMBOL_GPL(devl_params_unregister); 718 719 void devlink_params_unregister(struct devlink *devlink, 720 const struct devlink_param *params, 721 size_t params_count) 722 { 723 devl_lock(devlink); 724 devl_params_unregister(devlink, params, params_count); 725 devl_unlock(devlink); 726 } 727 EXPORT_SYMBOL_GPL(devlink_params_unregister); 728 729 /** 730 * devl_param_driverinit_value_get - get configuration parameter 731 * value for driver initializing 732 * 733 * @devlink: devlink 734 * @param_id: parameter ID 735 * @val: pointer to store the value of parameter in driverinit 736 * configuration mode 737 * 738 * This function should be used by the driver to get driverinit 739 * configuration for initialization after reload command. 740 * 741 * Note that lockless call of this function relies on the 742 * driver to maintain following basic sane behavior: 743 * 1) Driver ensures a call to this function cannot race with 744 * registering/unregistering the parameter with the same parameter ID. 745 * 2) Driver ensures a call to this function cannot race with 746 * devl_param_driverinit_value_set() call with the same parameter ID. 747 * 3) Driver ensures a call to this function cannot race with 748 * reload operation. 749 * If the driver is not able to comply, it has to take the devlink->lock 750 * while calling this. 751 */ 752 int devl_param_driverinit_value_get(struct devlink *devlink, u32 param_id, 753 union devlink_param_value *val) 754 { 755 struct devlink_param_item *param_item; 756 757 if (WARN_ON(!devlink_reload_supported(devlink->ops))) 758 return -EOPNOTSUPP; 759 760 param_item = devlink_param_find_by_id(&devlink->params, param_id); 761 if (!param_item) 762 return -EINVAL; 763 764 if (!param_item->driverinit_value_valid) 765 return -EOPNOTSUPP; 766 767 if (WARN_ON(!devlink_param_cmode_is_supported(param_item->param, 768 DEVLINK_PARAM_CMODE_DRIVERINIT))) 769 return -EOPNOTSUPP; 770 771 *val = param_item->driverinit_value; 772 773 return 0; 774 } 775 EXPORT_SYMBOL_GPL(devl_param_driverinit_value_get); 776 777 /** 778 * devl_param_driverinit_value_set - set value of configuration 779 * parameter for driverinit 780 * configuration mode 781 * 782 * @devlink: devlink 783 * @param_id: parameter ID 784 * @init_val: value of parameter to set for driverinit configuration mode 785 * 786 * This function should be used by the driver to set driverinit 787 * configuration mode default value. 788 */ 789 void devl_param_driverinit_value_set(struct devlink *devlink, u32 param_id, 790 union devlink_param_value init_val) 791 { 792 struct devlink_param_item *param_item; 793 794 devl_assert_locked(devlink); 795 796 param_item = devlink_param_find_by_id(&devlink->params, param_id); 797 if (WARN_ON(!param_item)) 798 return; 799 800 if (WARN_ON(!devlink_param_cmode_is_supported(param_item->param, 801 DEVLINK_PARAM_CMODE_DRIVERINIT))) 802 return; 803 804 param_item->driverinit_value = init_val; 805 param_item->driverinit_value_valid = true; 806 807 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW); 808 } 809 EXPORT_SYMBOL_GPL(devl_param_driverinit_value_set); 810 811 void devlink_params_driverinit_load_new(struct devlink *devlink) 812 { 813 struct devlink_param_item *param_item; 814 unsigned long param_id; 815 816 xa_for_each(&devlink->params, param_id, param_item) { 817 if (!devlink_param_cmode_is_supported(param_item->param, 818 DEVLINK_PARAM_CMODE_DRIVERINIT) || 819 !param_item->driverinit_value_new_valid) 820 continue; 821 param_item->driverinit_value = param_item->driverinit_value_new; 822 param_item->driverinit_value_valid = true; 823 param_item->driverinit_value_new_valid = false; 824 } 825 } 826 827 /** 828 * devl_param_value_changed - notify devlink on a parameter's value 829 * change. Should be called by the driver 830 * right after the change. 831 * 832 * @devlink: devlink 833 * @param_id: parameter ID 834 * 835 * This function should be used by the driver to notify devlink on value 836 * change, excluding driverinit configuration mode. 837 * For driverinit configuration mode driver should use the function 838 */ 839 void devl_param_value_changed(struct devlink *devlink, u32 param_id) 840 { 841 struct devlink_param_item *param_item; 842 843 param_item = devlink_param_find_by_id(&devlink->params, param_id); 844 WARN_ON(!param_item); 845 846 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW); 847 } 848 EXPORT_SYMBOL_GPL(devl_param_value_changed); 849