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