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