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