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