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