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 <linux/device.h> 8 #include <net/genetlink.h> 9 #include <net/sock.h> 10 #include "devl_internal.h" 11 12 struct devlink_info_req { 13 struct sk_buff *msg; 14 void (*version_cb)(const char *version_name, 15 enum devlink_info_version_type version_type, 16 void *version_cb_priv); 17 void *version_cb_priv; 18 }; 19 20 struct devlink_reload_combination { 21 enum devlink_reload_action action; 22 enum devlink_reload_limit limit; 23 }; 24 25 static const struct devlink_reload_combination devlink_reload_invalid_combinations[] = { 26 { 27 /* can't reinitialize driver with no down time */ 28 .action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT, 29 .limit = DEVLINK_RELOAD_LIMIT_NO_RESET, 30 }, 31 }; 32 33 static bool 34 devlink_reload_combination_is_invalid(enum devlink_reload_action action, 35 enum devlink_reload_limit limit) 36 { 37 int i; 38 39 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) 40 if (devlink_reload_invalid_combinations[i].action == action && 41 devlink_reload_invalid_combinations[i].limit == limit) 42 return true; 43 return false; 44 } 45 46 static bool 47 devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action) 48 { 49 return test_bit(action, &devlink->ops->reload_actions); 50 } 51 52 static bool 53 devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_limit limit) 54 { 55 return test_bit(limit, &devlink->ops->reload_limits); 56 } 57 58 static int devlink_reload_stat_put(struct sk_buff *msg, 59 enum devlink_reload_limit limit, u32 value) 60 { 61 struct nlattr *reload_stats_entry; 62 63 reload_stats_entry = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS_ENTRY); 64 if (!reload_stats_entry) 65 return -EMSGSIZE; 66 67 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) || 68 nla_put_u32(msg, DEVLINK_ATTR_RELOAD_STATS_VALUE, value)) 69 goto nla_put_failure; 70 nla_nest_end(msg, reload_stats_entry); 71 return 0; 72 73 nla_put_failure: 74 nla_nest_cancel(msg, reload_stats_entry); 75 return -EMSGSIZE; 76 } 77 78 static int 79 devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink, bool is_remote) 80 { 81 struct nlattr *reload_stats_attr, *act_info, *act_stats; 82 int i, j, stat_idx; 83 u32 value; 84 85 if (!is_remote) 86 reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS); 87 else 88 reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_REMOTE_RELOAD_STATS); 89 90 if (!reload_stats_attr) 91 return -EMSGSIZE; 92 93 for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) { 94 if ((!is_remote && 95 !devlink_reload_action_is_supported(devlink, i)) || 96 i == DEVLINK_RELOAD_ACTION_UNSPEC) 97 continue; 98 act_info = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_INFO); 99 if (!act_info) 100 goto nla_put_failure; 101 102 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, i)) 103 goto action_info_nest_cancel; 104 act_stats = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_STATS); 105 if (!act_stats) 106 goto action_info_nest_cancel; 107 108 for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) { 109 /* Remote stats are shown even if not locally supported. 110 * Stats of actions with unspecified limit are shown 111 * though drivers don't need to register unspecified 112 * limit. 113 */ 114 if ((!is_remote && j != DEVLINK_RELOAD_LIMIT_UNSPEC && 115 !devlink_reload_limit_is_supported(devlink, j)) || 116 devlink_reload_combination_is_invalid(i, j)) 117 continue; 118 119 stat_idx = j * __DEVLINK_RELOAD_ACTION_MAX + i; 120 if (!is_remote) 121 value = devlink->stats.reload_stats[stat_idx]; 122 else 123 value = devlink->stats.remote_reload_stats[stat_idx]; 124 if (devlink_reload_stat_put(msg, j, value)) 125 goto action_stats_nest_cancel; 126 } 127 nla_nest_end(msg, act_stats); 128 nla_nest_end(msg, act_info); 129 } 130 nla_nest_end(msg, reload_stats_attr); 131 return 0; 132 133 action_stats_nest_cancel: 134 nla_nest_cancel(msg, act_stats); 135 action_info_nest_cancel: 136 nla_nest_cancel(msg, act_info); 137 nla_put_failure: 138 nla_nest_cancel(msg, reload_stats_attr); 139 return -EMSGSIZE; 140 } 141 142 static int devlink_nl_nested_fill(struct sk_buff *msg, struct devlink *devlink) 143 { 144 unsigned long rel_index; 145 void *unused; 146 int err; 147 148 xa_for_each(&devlink->nested_rels, rel_index, unused) { 149 err = devlink_rel_devlink_handle_put(msg, devlink, 150 rel_index, 151 DEVLINK_ATTR_NESTED_DEVLINK, 152 NULL); 153 if (err) 154 return err; 155 } 156 return 0; 157 } 158 159 static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink, 160 enum devlink_command cmd, u32 portid, 161 u32 seq, int flags) 162 { 163 struct nlattr *dev_stats; 164 void *hdr; 165 166 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 167 if (!hdr) 168 return -EMSGSIZE; 169 170 if (devlink_nl_put_handle(msg, devlink)) 171 goto nla_put_failure; 172 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed)) 173 goto nla_put_failure; 174 175 dev_stats = nla_nest_start(msg, DEVLINK_ATTR_DEV_STATS); 176 if (!dev_stats) 177 goto nla_put_failure; 178 179 if (devlink_reload_stats_put(msg, devlink, false)) 180 goto dev_stats_nest_cancel; 181 if (devlink_reload_stats_put(msg, devlink, true)) 182 goto dev_stats_nest_cancel; 183 184 nla_nest_end(msg, dev_stats); 185 186 if (devlink_nl_nested_fill(msg, devlink)) 187 goto nla_put_failure; 188 189 genlmsg_end(msg, hdr); 190 return 0; 191 192 dev_stats_nest_cancel: 193 nla_nest_cancel(msg, dev_stats); 194 nla_put_failure: 195 genlmsg_cancel(msg, hdr); 196 return -EMSGSIZE; 197 } 198 199 static void devlink_notify(struct devlink *devlink, enum devlink_command cmd) 200 { 201 struct sk_buff *msg; 202 int err; 203 204 WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL); 205 WARN_ON(!devl_is_registered(devlink)); 206 207 if (!devlink_nl_notify_need(devlink)) 208 return; 209 210 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 211 if (!msg) 212 return; 213 214 err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0); 215 if (err) { 216 nlmsg_free(msg); 217 return; 218 } 219 220 devlink_nl_notify_send(devlink, msg); 221 } 222 223 int devlink_nl_get_doit(struct sk_buff *skb, struct genl_info *info) 224 { 225 struct devlink *devlink = info->user_ptr[0]; 226 struct sk_buff *msg; 227 int err; 228 229 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 230 if (!msg) 231 return -ENOMEM; 232 233 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW, 234 info->snd_portid, info->snd_seq, 0); 235 if (err) { 236 nlmsg_free(msg); 237 return err; 238 } 239 240 return genlmsg_reply(msg, info); 241 } 242 243 static int 244 devlink_nl_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 245 struct netlink_callback *cb, int flags) 246 { 247 return devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW, 248 NETLINK_CB(cb->skb).portid, 249 cb->nlh->nlmsg_seq, flags); 250 } 251 252 int devlink_nl_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb) 253 { 254 return devlink_nl_dumpit(msg, cb, devlink_nl_get_dump_one); 255 } 256 257 static void devlink_rel_notify_cb(struct devlink *devlink, u32 obj_index) 258 { 259 devlink_notify(devlink, DEVLINK_CMD_NEW); 260 } 261 262 static void devlink_rel_cleanup_cb(struct devlink *devlink, u32 obj_index, 263 u32 rel_index) 264 { 265 xa_erase(&devlink->nested_rels, rel_index); 266 } 267 268 int devl_nested_devlink_set(struct devlink *devlink, 269 struct devlink *nested_devlink) 270 { 271 u32 rel_index; 272 int err; 273 274 err = devlink_rel_nested_in_add(&rel_index, devlink->index, 0, 275 devlink_rel_notify_cb, 276 devlink_rel_cleanup_cb, 277 nested_devlink); 278 if (err) 279 return err; 280 return xa_insert(&devlink->nested_rels, rel_index, 281 xa_mk_value(0), GFP_KERNEL); 282 } 283 EXPORT_SYMBOL_GPL(devl_nested_devlink_set); 284 285 void devlink_notify_register(struct devlink *devlink) 286 { 287 devlink_notify(devlink, DEVLINK_CMD_NEW); 288 devlink_linecards_notify_register(devlink); 289 devlink_ports_notify_register(devlink); 290 devlink_trap_policers_notify_register(devlink); 291 devlink_trap_groups_notify_register(devlink); 292 devlink_traps_notify_register(devlink); 293 devlink_rates_notify_register(devlink); 294 devlink_regions_notify_register(devlink); 295 devlink_params_notify_register(devlink); 296 } 297 298 void devlink_notify_unregister(struct devlink *devlink) 299 { 300 devlink_params_notify_unregister(devlink); 301 devlink_regions_notify_unregister(devlink); 302 devlink_rates_notify_unregister(devlink); 303 devlink_traps_notify_unregister(devlink); 304 devlink_trap_groups_notify_unregister(devlink); 305 devlink_trap_policers_notify_unregister(devlink); 306 devlink_ports_notify_unregister(devlink); 307 devlink_linecards_notify_unregister(devlink); 308 devlink_notify(devlink, DEVLINK_CMD_DEL); 309 } 310 311 static void devlink_reload_failed_set(struct devlink *devlink, 312 bool reload_failed) 313 { 314 if (devlink->reload_failed == reload_failed) 315 return; 316 devlink->reload_failed = reload_failed; 317 devlink_notify(devlink, DEVLINK_CMD_NEW); 318 } 319 320 bool devlink_is_reload_failed(const struct devlink *devlink) 321 { 322 return devlink->reload_failed; 323 } 324 EXPORT_SYMBOL_GPL(devlink_is_reload_failed); 325 326 static void 327 __devlink_reload_stats_update(struct devlink *devlink, u32 *reload_stats, 328 enum devlink_reload_limit limit, u32 actions_performed) 329 { 330 unsigned long actions = actions_performed; 331 int stat_idx; 332 int action; 333 334 for_each_set_bit(action, &actions, __DEVLINK_RELOAD_ACTION_MAX) { 335 stat_idx = limit * __DEVLINK_RELOAD_ACTION_MAX + action; 336 reload_stats[stat_idx]++; 337 } 338 devlink_notify(devlink, DEVLINK_CMD_NEW); 339 } 340 341 static void 342 devlink_reload_stats_update(struct devlink *devlink, enum devlink_reload_limit limit, 343 u32 actions_performed) 344 { 345 __devlink_reload_stats_update(devlink, devlink->stats.reload_stats, limit, 346 actions_performed); 347 } 348 349 /** 350 * devlink_remote_reload_actions_performed - Update devlink on reload actions 351 * performed which are not a direct result of devlink reload call. 352 * 353 * This should be called by a driver after performing reload actions in case it was not 354 * a result of devlink reload call. For example fw_activate was performed as a result 355 * of devlink reload triggered fw_activate on another host. 356 * The motivation for this function is to keep data on reload actions performed on this 357 * function whether it was done due to direct devlink reload call or not. 358 * 359 * @devlink: devlink 360 * @limit: reload limit 361 * @actions_performed: bitmask of actions performed 362 */ 363 void devlink_remote_reload_actions_performed(struct devlink *devlink, 364 enum devlink_reload_limit limit, 365 u32 actions_performed) 366 { 367 if (WARN_ON(!actions_performed || 368 actions_performed & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) || 369 actions_performed >= BIT(__DEVLINK_RELOAD_ACTION_MAX) || 370 limit > DEVLINK_RELOAD_LIMIT_MAX)) 371 return; 372 373 __devlink_reload_stats_update(devlink, devlink->stats.remote_reload_stats, limit, 374 actions_performed); 375 } 376 EXPORT_SYMBOL_GPL(devlink_remote_reload_actions_performed); 377 378 static struct net *devlink_netns_get(struct sk_buff *skb, 379 struct genl_info *info) 380 { 381 struct nlattr *netns_pid_attr = info->attrs[DEVLINK_ATTR_NETNS_PID]; 382 struct nlattr *netns_fd_attr = info->attrs[DEVLINK_ATTR_NETNS_FD]; 383 struct nlattr *netns_id_attr = info->attrs[DEVLINK_ATTR_NETNS_ID]; 384 struct net *net; 385 386 if (!!netns_pid_attr + !!netns_fd_attr + !!netns_id_attr > 1) { 387 NL_SET_ERR_MSG(info->extack, "multiple netns identifying attributes specified"); 388 return ERR_PTR(-EINVAL); 389 } 390 391 if (netns_pid_attr) { 392 net = get_net_ns_by_pid(nla_get_u32(netns_pid_attr)); 393 } else if (netns_fd_attr) { 394 net = get_net_ns_by_fd(nla_get_u32(netns_fd_attr)); 395 } else if (netns_id_attr) { 396 net = get_net_ns_by_id(sock_net(skb->sk), 397 nla_get_u32(netns_id_attr)); 398 if (!net) 399 net = ERR_PTR(-EINVAL); 400 } else { 401 WARN_ON(1); 402 net = ERR_PTR(-EINVAL); 403 } 404 if (IS_ERR(net)) { 405 NL_SET_ERR_MSG(info->extack, "Unknown network namespace"); 406 return ERR_PTR(-EINVAL); 407 } 408 if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) { 409 put_net(net); 410 return ERR_PTR(-EPERM); 411 } 412 return net; 413 } 414 415 static void devlink_reload_netns_change(struct devlink *devlink, 416 struct net *curr_net, 417 struct net *dest_net) 418 { 419 /* Userspace needs to be notified about devlink objects 420 * removed from original and entering new network namespace. 421 * The rest of the devlink objects are re-created during 422 * reload process so the notifications are generated separatelly. 423 */ 424 devlink_notify_unregister(devlink); 425 write_pnet(&devlink->_net, dest_net); 426 devlink_notify_register(devlink); 427 devlink_rel_nested_in_notify(devlink); 428 } 429 430 static void devlink_reload_reinit_sanity_check(struct devlink *devlink) 431 { 432 WARN_ON(!list_empty(&devlink->trap_policer_list)); 433 WARN_ON(!list_empty(&devlink->trap_group_list)); 434 WARN_ON(!list_empty(&devlink->trap_list)); 435 WARN_ON(!list_empty(&devlink->dpipe_table_list)); 436 WARN_ON(!list_empty(&devlink->sb_list)); 437 WARN_ON(!list_empty(&devlink->rate_list)); 438 WARN_ON(!list_empty(&devlink->linecard_list)); 439 WARN_ON(!xa_empty(&devlink->ports)); 440 } 441 442 int devlink_reload(struct devlink *devlink, struct net *dest_net, 443 enum devlink_reload_action action, 444 enum devlink_reload_limit limit, 445 u32 *actions_performed, struct netlink_ext_ack *extack) 446 { 447 u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE]; 448 struct net *curr_net; 449 int err; 450 451 /* Make sure the reload operations are invoked with the device lock 452 * held to allow drivers to trigger functionality that expects it 453 * (e.g., PCI reset) and to close possible races between these 454 * operations and probe/remove. 455 */ 456 device_lock_assert(devlink->dev); 457 458 memcpy(remote_reload_stats, devlink->stats.remote_reload_stats, 459 sizeof(remote_reload_stats)); 460 461 err = devlink->ops->reload_down(devlink, !!dest_net, action, limit, extack); 462 if (err) 463 return err; 464 465 curr_net = devlink_net(devlink); 466 if (dest_net && !net_eq(dest_net, curr_net)) 467 devlink_reload_netns_change(devlink, curr_net, dest_net); 468 469 if (action == DEVLINK_RELOAD_ACTION_DRIVER_REINIT) { 470 devlink_params_driverinit_load_new(devlink); 471 devlink_reload_reinit_sanity_check(devlink); 472 } 473 474 err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack); 475 devlink_reload_failed_set(devlink, !!err); 476 if (err) 477 return err; 478 479 WARN_ON(!(*actions_performed & BIT(action))); 480 /* Catch driver on updating the remote action within devlink reload */ 481 WARN_ON(memcmp(remote_reload_stats, devlink->stats.remote_reload_stats, 482 sizeof(remote_reload_stats))); 483 devlink_reload_stats_update(devlink, limit, *actions_performed); 484 return 0; 485 } 486 487 static int 488 devlink_nl_reload_actions_performed_snd(struct devlink *devlink, u32 actions_performed, 489 enum devlink_command cmd, struct genl_info *info) 490 { 491 struct sk_buff *msg; 492 void *hdr; 493 494 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 495 if (!msg) 496 return -ENOMEM; 497 498 hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, &devlink_nl_family, 0, cmd); 499 if (!hdr) 500 goto free_msg; 501 502 if (devlink_nl_put_handle(msg, devlink)) 503 goto nla_put_failure; 504 505 if (nla_put_bitfield32(msg, DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, actions_performed, 506 actions_performed)) 507 goto nla_put_failure; 508 genlmsg_end(msg, hdr); 509 510 return genlmsg_reply(msg, info); 511 512 nla_put_failure: 513 genlmsg_cancel(msg, hdr); 514 free_msg: 515 nlmsg_free(msg); 516 return -EMSGSIZE; 517 } 518 519 int devlink_nl_reload_doit(struct sk_buff *skb, struct genl_info *info) 520 { 521 struct devlink *devlink = info->user_ptr[0]; 522 enum devlink_reload_action action; 523 enum devlink_reload_limit limit; 524 struct net *dest_net = NULL; 525 u32 actions_performed; 526 int err; 527 528 err = devlink_resources_validate(devlink, NULL, info); 529 if (err) { 530 NL_SET_ERR_MSG(info->extack, "resources size validation failed"); 531 return err; 532 } 533 534 if (info->attrs[DEVLINK_ATTR_RELOAD_ACTION]) 535 action = nla_get_u8(info->attrs[DEVLINK_ATTR_RELOAD_ACTION]); 536 else 537 action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT; 538 539 if (!devlink_reload_action_is_supported(devlink, action)) { 540 NL_SET_ERR_MSG(info->extack, "Requested reload action is not supported by the driver"); 541 return -EOPNOTSUPP; 542 } 543 544 limit = DEVLINK_RELOAD_LIMIT_UNSPEC; 545 if (info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) { 546 struct nla_bitfield32 limits; 547 u32 limits_selected; 548 549 limits = nla_get_bitfield32(info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]); 550 limits_selected = limits.value & limits.selector; 551 if (!limits_selected) { 552 NL_SET_ERR_MSG(info->extack, "Invalid limit selected"); 553 return -EINVAL; 554 } 555 for (limit = 0 ; limit <= DEVLINK_RELOAD_LIMIT_MAX ; limit++) 556 if (limits_selected & BIT(limit)) 557 break; 558 /* UAPI enables multiselection, but currently it is not used */ 559 if (limits_selected != BIT(limit)) { 560 NL_SET_ERR_MSG(info->extack, "Multiselection of limit is not supported"); 561 return -EOPNOTSUPP; 562 } 563 if (!devlink_reload_limit_is_supported(devlink, limit)) { 564 NL_SET_ERR_MSG(info->extack, "Requested limit is not supported by the driver"); 565 return -EOPNOTSUPP; 566 } 567 if (devlink_reload_combination_is_invalid(action, limit)) { 568 NL_SET_ERR_MSG(info->extack, "Requested limit is invalid for this action"); 569 return -EINVAL; 570 } 571 } 572 if (info->attrs[DEVLINK_ATTR_NETNS_PID] || 573 info->attrs[DEVLINK_ATTR_NETNS_FD] || 574 info->attrs[DEVLINK_ATTR_NETNS_ID]) { 575 dest_net = devlink_netns_get(skb, info); 576 if (IS_ERR(dest_net)) 577 return PTR_ERR(dest_net); 578 if (!net_eq(dest_net, devlink_net(devlink)) && 579 action != DEVLINK_RELOAD_ACTION_DRIVER_REINIT) { 580 NL_SET_ERR_MSG_MOD(info->extack, 581 "Changing namespace is only supported for reinit action"); 582 return -EOPNOTSUPP; 583 } 584 } 585 586 err = devlink_reload(devlink, dest_net, action, limit, &actions_performed, info->extack); 587 588 if (dest_net) 589 put_net(dest_net); 590 591 if (err) 592 return err; 593 /* For backward compatibility generate reply only if attributes used by user */ 594 if (!info->attrs[DEVLINK_ATTR_RELOAD_ACTION] && !info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) 595 return 0; 596 597 return devlink_nl_reload_actions_performed_snd(devlink, actions_performed, 598 DEVLINK_CMD_RELOAD, info); 599 } 600 601 bool devlink_reload_actions_valid(const struct devlink_ops *ops) 602 { 603 const struct devlink_reload_combination *comb; 604 int i; 605 606 if (!devlink_reload_supported(ops)) { 607 if (WARN_ON(ops->reload_actions)) 608 return false; 609 return true; 610 } 611 612 if (WARN_ON(!ops->reload_actions || 613 ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) || 614 ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX))) 615 return false; 616 617 if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) || 618 ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX))) 619 return false; 620 621 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) { 622 comb = &devlink_reload_invalid_combinations[i]; 623 if (ops->reload_actions == BIT(comb->action) && 624 ops->reload_limits == BIT(comb->limit)) 625 return false; 626 } 627 return true; 628 } 629 630 static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink, 631 enum devlink_command cmd, u32 portid, 632 u32 seq, int flags) 633 { 634 const struct devlink_ops *ops = devlink->ops; 635 enum devlink_eswitch_encap_mode encap_mode; 636 u8 inline_mode; 637 void *hdr; 638 int err = 0; 639 u16 mode; 640 641 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 642 if (!hdr) 643 return -EMSGSIZE; 644 645 err = devlink_nl_put_handle(msg, devlink); 646 if (err) 647 goto nla_put_failure; 648 649 if (ops->eswitch_mode_get) { 650 err = ops->eswitch_mode_get(devlink, &mode); 651 if (err) 652 goto nla_put_failure; 653 err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode); 654 if (err) 655 goto nla_put_failure; 656 } 657 658 if (ops->eswitch_inline_mode_get) { 659 err = ops->eswitch_inline_mode_get(devlink, &inline_mode); 660 if (err) 661 goto nla_put_failure; 662 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE, 663 inline_mode); 664 if (err) 665 goto nla_put_failure; 666 } 667 668 if (ops->eswitch_encap_mode_get) { 669 err = ops->eswitch_encap_mode_get(devlink, &encap_mode); 670 if (err) 671 goto nla_put_failure; 672 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode); 673 if (err) 674 goto nla_put_failure; 675 } 676 677 genlmsg_end(msg, hdr); 678 return 0; 679 680 nla_put_failure: 681 genlmsg_cancel(msg, hdr); 682 return err; 683 } 684 685 int devlink_nl_eswitch_get_doit(struct sk_buff *skb, struct genl_info *info) 686 { 687 struct devlink *devlink = info->user_ptr[0]; 688 struct sk_buff *msg; 689 int err; 690 691 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 692 if (!msg) 693 return -ENOMEM; 694 695 err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET, 696 info->snd_portid, info->snd_seq, 0); 697 698 if (err) { 699 nlmsg_free(msg); 700 return err; 701 } 702 703 return genlmsg_reply(msg, info); 704 } 705 706 int devlink_nl_eswitch_set_doit(struct sk_buff *skb, struct genl_info *info) 707 { 708 struct devlink *devlink = info->user_ptr[0]; 709 const struct devlink_ops *ops = devlink->ops; 710 enum devlink_eswitch_encap_mode encap_mode; 711 u8 inline_mode; 712 int err = 0; 713 u16 mode; 714 715 if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) { 716 if (!ops->eswitch_mode_set) 717 return -EOPNOTSUPP; 718 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]); 719 err = devlink_rate_nodes_check(devlink, mode, info->extack); 720 if (err) 721 return err; 722 err = ops->eswitch_mode_set(devlink, mode, info->extack); 723 if (err) 724 return err; 725 } 726 727 if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) { 728 if (!ops->eswitch_inline_mode_set) 729 return -EOPNOTSUPP; 730 inline_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]); 731 err = ops->eswitch_inline_mode_set(devlink, inline_mode, 732 info->extack); 733 if (err) 734 return err; 735 } 736 737 if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) { 738 if (!ops->eswitch_encap_mode_set) 739 return -EOPNOTSUPP; 740 encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]); 741 err = ops->eswitch_encap_mode_set(devlink, encap_mode, 742 info->extack); 743 if (err) 744 return err; 745 } 746 747 return 0; 748 } 749 750 int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn) 751 { 752 if (!req->msg) 753 return 0; 754 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn); 755 } 756 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put); 757 758 int devlink_info_board_serial_number_put(struct devlink_info_req *req, 759 const char *bsn) 760 { 761 if (!req->msg) 762 return 0; 763 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER, 764 bsn); 765 } 766 EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put); 767 768 static int devlink_info_version_put(struct devlink_info_req *req, int attr, 769 const char *version_name, 770 const char *version_value, 771 enum devlink_info_version_type version_type) 772 { 773 struct nlattr *nest; 774 int err; 775 776 if (req->version_cb) 777 req->version_cb(version_name, version_type, 778 req->version_cb_priv); 779 780 if (!req->msg) 781 return 0; 782 783 nest = nla_nest_start_noflag(req->msg, attr); 784 if (!nest) 785 return -EMSGSIZE; 786 787 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME, 788 version_name); 789 if (err) 790 goto nla_put_failure; 791 792 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE, 793 version_value); 794 if (err) 795 goto nla_put_failure; 796 797 nla_nest_end(req->msg, nest); 798 799 return 0; 800 801 nla_put_failure: 802 nla_nest_cancel(req->msg, nest); 803 return err; 804 } 805 806 int devlink_info_version_fixed_put(struct devlink_info_req *req, 807 const char *version_name, 808 const char *version_value) 809 { 810 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED, 811 version_name, version_value, 812 DEVLINK_INFO_VERSION_TYPE_NONE); 813 } 814 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put); 815 816 int devlink_info_version_stored_put(struct devlink_info_req *req, 817 const char *version_name, 818 const char *version_value) 819 { 820 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED, 821 version_name, version_value, 822 DEVLINK_INFO_VERSION_TYPE_NONE); 823 } 824 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put); 825 826 int devlink_info_version_stored_put_ext(struct devlink_info_req *req, 827 const char *version_name, 828 const char *version_value, 829 enum devlink_info_version_type version_type) 830 { 831 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED, 832 version_name, version_value, 833 version_type); 834 } 835 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put_ext); 836 837 int devlink_info_version_running_put(struct devlink_info_req *req, 838 const char *version_name, 839 const char *version_value) 840 { 841 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING, 842 version_name, version_value, 843 DEVLINK_INFO_VERSION_TYPE_NONE); 844 } 845 EXPORT_SYMBOL_GPL(devlink_info_version_running_put); 846 847 int devlink_info_version_running_put_ext(struct devlink_info_req *req, 848 const char *version_name, 849 const char *version_value, 850 enum devlink_info_version_type version_type) 851 { 852 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING, 853 version_name, version_value, 854 version_type); 855 } 856 EXPORT_SYMBOL_GPL(devlink_info_version_running_put_ext); 857 858 static int devlink_nl_driver_info_get(struct device_driver *drv, 859 struct devlink_info_req *req) 860 { 861 if (!drv) 862 return 0; 863 864 if (drv->name[0]) 865 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, 866 drv->name); 867 868 return 0; 869 } 870 871 static int 872 devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink, 873 enum devlink_command cmd, u32 portid, 874 u32 seq, int flags, struct netlink_ext_ack *extack) 875 { 876 struct device *dev = devlink_to_dev(devlink); 877 struct devlink_info_req req = {}; 878 void *hdr; 879 int err; 880 881 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 882 if (!hdr) 883 return -EMSGSIZE; 884 885 err = -EMSGSIZE; 886 if (devlink_nl_put_handle(msg, devlink)) 887 goto err_cancel_msg; 888 889 req.msg = msg; 890 if (devlink->ops->info_get) { 891 err = devlink->ops->info_get(devlink, &req, extack); 892 if (err) 893 goto err_cancel_msg; 894 } 895 896 err = devlink_nl_driver_info_get(dev->driver, &req); 897 if (err) 898 goto err_cancel_msg; 899 900 genlmsg_end(msg, hdr); 901 return 0; 902 903 err_cancel_msg: 904 genlmsg_cancel(msg, hdr); 905 return err; 906 } 907 908 int devlink_nl_info_get_doit(struct sk_buff *skb, struct genl_info *info) 909 { 910 struct devlink *devlink = info->user_ptr[0]; 911 struct sk_buff *msg; 912 int err; 913 914 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 915 if (!msg) 916 return -ENOMEM; 917 918 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, 919 info->snd_portid, info->snd_seq, 0, 920 info->extack); 921 if (err) { 922 nlmsg_free(msg); 923 return err; 924 } 925 926 return genlmsg_reply(msg, info); 927 } 928 929 static int 930 devlink_nl_info_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 931 struct netlink_callback *cb, int flags) 932 { 933 int err; 934 935 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, 936 NETLINK_CB(cb->skb).portid, 937 cb->nlh->nlmsg_seq, flags, 938 cb->extack); 939 if (err == -EOPNOTSUPP) 940 err = 0; 941 return err; 942 } 943 944 int devlink_nl_info_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb) 945 { 946 return devlink_nl_dumpit(msg, cb, devlink_nl_info_get_dump_one); 947 } 948 949 static int devlink_nl_flash_update_fill(struct sk_buff *msg, 950 struct devlink *devlink, 951 enum devlink_command cmd, 952 struct devlink_flash_notify *params) 953 { 954 void *hdr; 955 956 hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd); 957 if (!hdr) 958 return -EMSGSIZE; 959 960 if (devlink_nl_put_handle(msg, devlink)) 961 goto nla_put_failure; 962 963 if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS) 964 goto out; 965 966 if (params->status_msg && 967 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG, 968 params->status_msg)) 969 goto nla_put_failure; 970 if (params->component && 971 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT, 972 params->component)) 973 goto nla_put_failure; 974 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE, 975 params->done, DEVLINK_ATTR_PAD)) 976 goto nla_put_failure; 977 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL, 978 params->total, DEVLINK_ATTR_PAD)) 979 goto nla_put_failure; 980 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT, 981 params->timeout, DEVLINK_ATTR_PAD)) 982 goto nla_put_failure; 983 984 out: 985 genlmsg_end(msg, hdr); 986 return 0; 987 988 nla_put_failure: 989 genlmsg_cancel(msg, hdr); 990 return -EMSGSIZE; 991 } 992 993 static void __devlink_flash_update_notify(struct devlink *devlink, 994 enum devlink_command cmd, 995 struct devlink_flash_notify *params) 996 { 997 struct sk_buff *msg; 998 int err; 999 1000 WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE && 1001 cmd != DEVLINK_CMD_FLASH_UPDATE_END && 1002 cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS); 1003 1004 if (!devl_is_registered(devlink) || !devlink_nl_notify_need(devlink)) 1005 return; 1006 1007 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1008 if (!msg) 1009 return; 1010 1011 err = devlink_nl_flash_update_fill(msg, devlink, cmd, params); 1012 if (err) 1013 goto out_free_msg; 1014 1015 devlink_nl_notify_send(devlink, msg); 1016 return; 1017 1018 out_free_msg: 1019 nlmsg_free(msg); 1020 } 1021 1022 static void devlink_flash_update_begin_notify(struct devlink *devlink) 1023 { 1024 struct devlink_flash_notify params = {}; 1025 1026 __devlink_flash_update_notify(devlink, 1027 DEVLINK_CMD_FLASH_UPDATE, 1028 ¶ms); 1029 } 1030 1031 static void devlink_flash_update_end_notify(struct devlink *devlink) 1032 { 1033 struct devlink_flash_notify params = {}; 1034 1035 __devlink_flash_update_notify(devlink, 1036 DEVLINK_CMD_FLASH_UPDATE_END, 1037 ¶ms); 1038 } 1039 1040 void devlink_flash_update_status_notify(struct devlink *devlink, 1041 const char *status_msg, 1042 const char *component, 1043 unsigned long done, 1044 unsigned long total) 1045 { 1046 struct devlink_flash_notify params = { 1047 .status_msg = status_msg, 1048 .component = component, 1049 .done = done, 1050 .total = total, 1051 }; 1052 1053 __devlink_flash_update_notify(devlink, 1054 DEVLINK_CMD_FLASH_UPDATE_STATUS, 1055 ¶ms); 1056 } 1057 EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify); 1058 1059 void devlink_flash_update_timeout_notify(struct devlink *devlink, 1060 const char *status_msg, 1061 const char *component, 1062 unsigned long timeout) 1063 { 1064 struct devlink_flash_notify params = { 1065 .status_msg = status_msg, 1066 .component = component, 1067 .timeout = timeout, 1068 }; 1069 1070 __devlink_flash_update_notify(devlink, 1071 DEVLINK_CMD_FLASH_UPDATE_STATUS, 1072 ¶ms); 1073 } 1074 EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify); 1075 1076 struct devlink_flash_component_lookup_ctx { 1077 const char *lookup_name; 1078 bool lookup_name_found; 1079 }; 1080 1081 static void 1082 devlink_flash_component_lookup_cb(const char *version_name, 1083 enum devlink_info_version_type version_type, 1084 void *version_cb_priv) 1085 { 1086 struct devlink_flash_component_lookup_ctx *lookup_ctx = version_cb_priv; 1087 1088 if (version_type != DEVLINK_INFO_VERSION_TYPE_COMPONENT || 1089 lookup_ctx->lookup_name_found) 1090 return; 1091 1092 lookup_ctx->lookup_name_found = 1093 !strcmp(lookup_ctx->lookup_name, version_name); 1094 } 1095 1096 static int devlink_flash_component_get(struct devlink *devlink, 1097 struct nlattr *nla_component, 1098 const char **p_component, 1099 struct netlink_ext_ack *extack) 1100 { 1101 struct devlink_flash_component_lookup_ctx lookup_ctx = {}; 1102 struct devlink_info_req req = {}; 1103 const char *component; 1104 int ret; 1105 1106 if (!nla_component) 1107 return 0; 1108 1109 component = nla_data(nla_component); 1110 1111 if (!devlink->ops->info_get) { 1112 NL_SET_ERR_MSG_ATTR(extack, nla_component, 1113 "component update is not supported by this device"); 1114 return -EOPNOTSUPP; 1115 } 1116 1117 lookup_ctx.lookup_name = component; 1118 req.version_cb = devlink_flash_component_lookup_cb; 1119 req.version_cb_priv = &lookup_ctx; 1120 1121 ret = devlink->ops->info_get(devlink, &req, NULL); 1122 if (ret) 1123 return ret; 1124 1125 if (!lookup_ctx.lookup_name_found) { 1126 NL_SET_ERR_MSG_ATTR(extack, nla_component, 1127 "selected component is not supported by this device"); 1128 return -EINVAL; 1129 } 1130 *p_component = component; 1131 return 0; 1132 } 1133 1134 int devlink_nl_flash_update_doit(struct sk_buff *skb, struct genl_info *info) 1135 { 1136 struct nlattr *nla_overwrite_mask, *nla_file_name; 1137 struct devlink_flash_update_params params = {}; 1138 struct devlink *devlink = info->user_ptr[0]; 1139 const char *file_name; 1140 u32 supported_params; 1141 int ret; 1142 1143 if (!devlink->ops->flash_update) 1144 return -EOPNOTSUPP; 1145 1146 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME)) 1147 return -EINVAL; 1148 1149 ret = devlink_flash_component_get(devlink, 1150 info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT], 1151 ¶ms.component, info->extack); 1152 if (ret) 1153 return ret; 1154 1155 supported_params = devlink->ops->supported_flash_update_params; 1156 1157 nla_overwrite_mask = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK]; 1158 if (nla_overwrite_mask) { 1159 struct nla_bitfield32 sections; 1160 1161 if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) { 1162 NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite_mask, 1163 "overwrite settings are not supported by this device"); 1164 return -EOPNOTSUPP; 1165 } 1166 sections = nla_get_bitfield32(nla_overwrite_mask); 1167 params.overwrite_mask = sections.value & sections.selector; 1168 } 1169 1170 nla_file_name = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]; 1171 file_name = nla_data(nla_file_name); 1172 ret = request_firmware(¶ms.fw, file_name, devlink->dev); 1173 if (ret) { 1174 NL_SET_ERR_MSG_ATTR(info->extack, nla_file_name, 1175 "failed to locate the requested firmware file"); 1176 return ret; 1177 } 1178 1179 devlink_flash_update_begin_notify(devlink); 1180 ret = devlink->ops->flash_update(devlink, ¶ms, info->extack); 1181 devlink_flash_update_end_notify(devlink); 1182 1183 release_firmware(params.fw); 1184 1185 return ret; 1186 } 1187 1188 static void __devlink_compat_running_version(struct devlink *devlink, 1189 char *buf, size_t len) 1190 { 1191 struct devlink_info_req req = {}; 1192 const struct nlattr *nlattr; 1193 struct sk_buff *msg; 1194 int rem, err; 1195 1196 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1197 if (!msg) 1198 return; 1199 1200 req.msg = msg; 1201 err = devlink->ops->info_get(devlink, &req, NULL); 1202 if (err) 1203 goto free_msg; 1204 1205 nla_for_each_attr_type(nlattr, DEVLINK_ATTR_INFO_VERSION_RUNNING, 1206 (void *)msg->data, msg->len, rem) { 1207 const struct nlattr *kv; 1208 int rem_kv; 1209 1210 nla_for_each_nested_type(kv, DEVLINK_ATTR_INFO_VERSION_VALUE, 1211 nlattr, rem_kv) { 1212 strlcat(buf, nla_data(kv), len); 1213 strlcat(buf, " ", len); 1214 } 1215 } 1216 free_msg: 1217 nlmsg_consume(msg); 1218 } 1219 1220 void devlink_compat_running_version(struct devlink *devlink, 1221 char *buf, size_t len) 1222 { 1223 if (!devlink->ops->info_get) 1224 return; 1225 1226 devl_lock(devlink); 1227 if (devl_is_registered(devlink)) 1228 __devlink_compat_running_version(devlink, buf, len); 1229 devl_unlock(devlink); 1230 } 1231 1232 int devlink_compat_flash_update(struct devlink *devlink, const char *file_name) 1233 { 1234 struct devlink_flash_update_params params = {}; 1235 int ret; 1236 1237 devl_lock(devlink); 1238 if (!devl_is_registered(devlink)) { 1239 ret = -ENODEV; 1240 goto out_unlock; 1241 } 1242 1243 if (!devlink->ops->flash_update) { 1244 ret = -EOPNOTSUPP; 1245 goto out_unlock; 1246 } 1247 1248 ret = request_firmware(¶ms.fw, file_name, devlink->dev); 1249 if (ret) 1250 goto out_unlock; 1251 1252 devlink_flash_update_begin_notify(devlink); 1253 ret = devlink->ops->flash_update(devlink, ¶ms, NULL); 1254 devlink_flash_update_end_notify(devlink); 1255 1256 release_firmware(params.fw); 1257 out_unlock: 1258 devl_unlock(devlink); 1259 1260 return ret; 1261 } 1262 1263 static int 1264 devlink_nl_selftests_fill(struct sk_buff *msg, struct devlink *devlink, 1265 u32 portid, u32 seq, int flags, 1266 struct netlink_ext_ack *extack) 1267 { 1268 struct nlattr *selftests; 1269 void *hdr; 1270 int err; 1271 int i; 1272 1273 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, 1274 DEVLINK_CMD_SELFTESTS_GET); 1275 if (!hdr) 1276 return -EMSGSIZE; 1277 1278 err = -EMSGSIZE; 1279 if (devlink_nl_put_handle(msg, devlink)) 1280 goto err_cancel_msg; 1281 1282 selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS); 1283 if (!selftests) 1284 goto err_cancel_msg; 1285 1286 for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1; 1287 i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) { 1288 if (devlink->ops->selftest_check(devlink, i, extack)) { 1289 err = nla_put_flag(msg, i); 1290 if (err) 1291 goto err_cancel_msg; 1292 } 1293 } 1294 1295 nla_nest_end(msg, selftests); 1296 genlmsg_end(msg, hdr); 1297 return 0; 1298 1299 err_cancel_msg: 1300 genlmsg_cancel(msg, hdr); 1301 return err; 1302 } 1303 1304 int devlink_nl_selftests_get_doit(struct sk_buff *skb, struct genl_info *info) 1305 { 1306 struct devlink *devlink = info->user_ptr[0]; 1307 struct sk_buff *msg; 1308 int err; 1309 1310 if (!devlink->ops->selftest_check) 1311 return -EOPNOTSUPP; 1312 1313 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1314 if (!msg) 1315 return -ENOMEM; 1316 1317 err = devlink_nl_selftests_fill(msg, devlink, info->snd_portid, 1318 info->snd_seq, 0, info->extack); 1319 if (err) { 1320 nlmsg_free(msg); 1321 return err; 1322 } 1323 1324 return genlmsg_reply(msg, info); 1325 } 1326 1327 static int devlink_nl_selftests_get_dump_one(struct sk_buff *msg, 1328 struct devlink *devlink, 1329 struct netlink_callback *cb, 1330 int flags) 1331 { 1332 if (!devlink->ops->selftest_check) 1333 return 0; 1334 1335 return devlink_nl_selftests_fill(msg, devlink, 1336 NETLINK_CB(cb->skb).portid, 1337 cb->nlh->nlmsg_seq, flags, 1338 cb->extack); 1339 } 1340 1341 int devlink_nl_selftests_get_dumpit(struct sk_buff *skb, 1342 struct netlink_callback *cb) 1343 { 1344 return devlink_nl_dumpit(skb, cb, devlink_nl_selftests_get_dump_one); 1345 } 1346 1347 static int devlink_selftest_result_put(struct sk_buff *skb, unsigned int id, 1348 enum devlink_selftest_status test_status) 1349 { 1350 struct nlattr *result_attr; 1351 1352 result_attr = nla_nest_start(skb, DEVLINK_ATTR_SELFTEST_RESULT); 1353 if (!result_attr) 1354 return -EMSGSIZE; 1355 1356 if (nla_put_u32(skb, DEVLINK_ATTR_SELFTEST_RESULT_ID, id) || 1357 nla_put_u8(skb, DEVLINK_ATTR_SELFTEST_RESULT_STATUS, 1358 test_status)) 1359 goto nla_put_failure; 1360 1361 nla_nest_end(skb, result_attr); 1362 return 0; 1363 1364 nla_put_failure: 1365 nla_nest_cancel(skb, result_attr); 1366 return -EMSGSIZE; 1367 } 1368 1369 static const struct nla_policy devlink_selftest_nl_policy[DEVLINK_ATTR_SELFTEST_ID_MAX + 1] = { 1370 [DEVLINK_ATTR_SELFTEST_ID_FLASH] = { .type = NLA_FLAG }, 1371 }; 1372 1373 int devlink_nl_selftests_run_doit(struct sk_buff *skb, struct genl_info *info) 1374 { 1375 struct nlattr *tb[DEVLINK_ATTR_SELFTEST_ID_MAX + 1]; 1376 struct devlink *devlink = info->user_ptr[0]; 1377 struct nlattr *attrs, *selftests; 1378 struct sk_buff *msg; 1379 void *hdr; 1380 int err; 1381 int i; 1382 1383 if (!devlink->ops->selftest_run || !devlink->ops->selftest_check) 1384 return -EOPNOTSUPP; 1385 1386 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SELFTESTS)) 1387 return -EINVAL; 1388 1389 attrs = info->attrs[DEVLINK_ATTR_SELFTESTS]; 1390 1391 err = nla_parse_nested(tb, DEVLINK_ATTR_SELFTEST_ID_MAX, attrs, 1392 devlink_selftest_nl_policy, info->extack); 1393 if (err < 0) 1394 return err; 1395 1396 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1397 if (!msg) 1398 return -ENOMEM; 1399 1400 err = -EMSGSIZE; 1401 hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, 1402 &devlink_nl_family, 0, DEVLINK_CMD_SELFTESTS_RUN); 1403 if (!hdr) 1404 goto free_msg; 1405 1406 if (devlink_nl_put_handle(msg, devlink)) 1407 goto genlmsg_cancel; 1408 1409 selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS); 1410 if (!selftests) 1411 goto genlmsg_cancel; 1412 1413 for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1; 1414 i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) { 1415 enum devlink_selftest_status test_status; 1416 1417 if (nla_get_flag(tb[i])) { 1418 if (!devlink->ops->selftest_check(devlink, i, 1419 info->extack)) { 1420 if (devlink_selftest_result_put(msg, i, 1421 DEVLINK_SELFTEST_STATUS_SKIP)) 1422 goto selftests_nest_cancel; 1423 continue; 1424 } 1425 1426 test_status = devlink->ops->selftest_run(devlink, i, 1427 info->extack); 1428 if (devlink_selftest_result_put(msg, i, test_status)) 1429 goto selftests_nest_cancel; 1430 } 1431 } 1432 1433 nla_nest_end(msg, selftests); 1434 genlmsg_end(msg, hdr); 1435 return genlmsg_reply(msg, info); 1436 1437 selftests_nest_cancel: 1438 nla_nest_cancel(msg, selftests); 1439 genlmsg_cancel: 1440 genlmsg_cancel(msg, hdr); 1441 free_msg: 1442 nlmsg_free(msg); 1443 return err; 1444 } 1445