at master 39 kB view raw
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 12struct 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 20struct devlink_reload_combination { 21 enum devlink_reload_action action; 22 enum devlink_reload_limit limit; 23}; 24 25static 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 33static bool 34devlink_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 46static bool 47devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action) 48{ 49 return test_bit(action, &devlink->ops->reload_actions); 50} 51 52static bool 53devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_limit limit) 54{ 55 return test_bit(limit, &devlink->ops->reload_limits); 56} 57 58static 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 73nla_put_failure: 74 nla_nest_cancel(msg, reload_stats_entry); 75 return -EMSGSIZE; 76} 77 78static int 79devlink_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 133action_stats_nest_cancel: 134 nla_nest_cancel(msg, act_stats); 135action_info_nest_cancel: 136 nla_nest_cancel(msg, act_info); 137nla_put_failure: 138 nla_nest_cancel(msg, reload_stats_attr); 139 return -EMSGSIZE; 140} 141 142static 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 159static 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 192dev_stats_nest_cancel: 193 nla_nest_cancel(msg, dev_stats); 194nla_put_failure: 195 genlmsg_cancel(msg, hdr); 196 return -EMSGSIZE; 197} 198 199static 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 223int 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 243static int 244devlink_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 252int 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 257static void devlink_rel_notify_cb(struct devlink *devlink, u32 obj_index) 258{ 259 devlink_notify(devlink, DEVLINK_CMD_NEW); 260} 261 262static 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 268int 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} 283EXPORT_SYMBOL_GPL(devl_nested_devlink_set); 284 285void 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 298void 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 311static 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 320bool devlink_is_reload_failed(const struct devlink *devlink) 321{ 322 return devlink->reload_failed; 323} 324EXPORT_SYMBOL_GPL(devlink_is_reload_failed); 325 326static 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 341static void 342devlink_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 */ 363void 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} 376EXPORT_SYMBOL_GPL(devlink_remote_reload_actions_performed); 377 378static 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 415static 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 430static 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 442int 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 487static int 488devlink_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 512nla_put_failure: 513 genlmsg_cancel(msg, hdr); 514free_msg: 515 nlmsg_free(msg); 516 return -EMSGSIZE; 517} 518 519int 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 action = nla_get_u8_default(info->attrs[DEVLINK_ATTR_RELOAD_ACTION], 535 DEVLINK_RELOAD_ACTION_DRIVER_REINIT); 536 537 if (!devlink_reload_action_is_supported(devlink, action)) { 538 NL_SET_ERR_MSG(info->extack, "Requested reload action is not supported by the driver"); 539 return -EOPNOTSUPP; 540 } 541 542 limit = DEVLINK_RELOAD_LIMIT_UNSPEC; 543 if (info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) { 544 struct nla_bitfield32 limits; 545 u32 limits_selected; 546 547 limits = nla_get_bitfield32(info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]); 548 limits_selected = limits.value & limits.selector; 549 if (!limits_selected) { 550 NL_SET_ERR_MSG(info->extack, "Invalid limit selected"); 551 return -EINVAL; 552 } 553 for (limit = 0 ; limit <= DEVLINK_RELOAD_LIMIT_MAX ; limit++) 554 if (limits_selected & BIT(limit)) 555 break; 556 /* UAPI enables multiselection, but currently it is not used */ 557 if (limits_selected != BIT(limit)) { 558 NL_SET_ERR_MSG(info->extack, "Multiselection of limit is not supported"); 559 return -EOPNOTSUPP; 560 } 561 if (!devlink_reload_limit_is_supported(devlink, limit)) { 562 NL_SET_ERR_MSG(info->extack, "Requested limit is not supported by the driver"); 563 return -EOPNOTSUPP; 564 } 565 if (devlink_reload_combination_is_invalid(action, limit)) { 566 NL_SET_ERR_MSG(info->extack, "Requested limit is invalid for this action"); 567 return -EINVAL; 568 } 569 } 570 if (info->attrs[DEVLINK_ATTR_NETNS_PID] || 571 info->attrs[DEVLINK_ATTR_NETNS_FD] || 572 info->attrs[DEVLINK_ATTR_NETNS_ID]) { 573 dest_net = devlink_netns_get(skb, info); 574 if (IS_ERR(dest_net)) 575 return PTR_ERR(dest_net); 576 if (!net_eq(dest_net, devlink_net(devlink)) && 577 action != DEVLINK_RELOAD_ACTION_DRIVER_REINIT) { 578 NL_SET_ERR_MSG_MOD(info->extack, 579 "Changing namespace is only supported for reinit action"); 580 return -EOPNOTSUPP; 581 } 582 } 583 584 err = devlink_reload(devlink, dest_net, action, limit, &actions_performed, info->extack); 585 586 if (dest_net) 587 put_net(dest_net); 588 589 if (err) 590 return err; 591 /* For backward compatibility generate reply only if attributes used by user */ 592 if (!info->attrs[DEVLINK_ATTR_RELOAD_ACTION] && !info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) 593 return 0; 594 595 return devlink_nl_reload_actions_performed_snd(devlink, actions_performed, 596 DEVLINK_CMD_RELOAD, info); 597} 598 599bool devlink_reload_actions_valid(const struct devlink_ops *ops) 600{ 601 const struct devlink_reload_combination *comb; 602 int i; 603 604 if (!devlink_reload_supported(ops)) { 605 if (WARN_ON(ops->reload_actions)) 606 return false; 607 return true; 608 } 609 610 if (WARN_ON(!ops->reload_actions || 611 ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) || 612 ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX))) 613 return false; 614 615 if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) || 616 ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX))) 617 return false; 618 619 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) { 620 comb = &devlink_reload_invalid_combinations[i]; 621 if (ops->reload_actions == BIT(comb->action) && 622 ops->reload_limits == BIT(comb->limit)) 623 return false; 624 } 625 return true; 626} 627 628static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink, 629 enum devlink_command cmd, u32 portid, 630 u32 seq, int flags) 631{ 632 const struct devlink_ops *ops = devlink->ops; 633 enum devlink_eswitch_encap_mode encap_mode; 634 u8 inline_mode; 635 void *hdr; 636 int err = 0; 637 u16 mode; 638 639 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 640 if (!hdr) 641 return -EMSGSIZE; 642 643 err = devlink_nl_put_handle(msg, devlink); 644 if (err) 645 goto nla_put_failure; 646 647 if (ops->eswitch_mode_get) { 648 err = ops->eswitch_mode_get(devlink, &mode); 649 if (err) 650 goto nla_put_failure; 651 err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode); 652 if (err) 653 goto nla_put_failure; 654 } 655 656 if (ops->eswitch_inline_mode_get) { 657 err = ops->eswitch_inline_mode_get(devlink, &inline_mode); 658 if (err) 659 goto nla_put_failure; 660 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE, 661 inline_mode); 662 if (err) 663 goto nla_put_failure; 664 } 665 666 if (ops->eswitch_encap_mode_get) { 667 err = ops->eswitch_encap_mode_get(devlink, &encap_mode); 668 if (err) 669 goto nla_put_failure; 670 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode); 671 if (err) 672 goto nla_put_failure; 673 } 674 675 genlmsg_end(msg, hdr); 676 return 0; 677 678nla_put_failure: 679 genlmsg_cancel(msg, hdr); 680 return err; 681} 682 683int devlink_nl_eswitch_get_doit(struct sk_buff *skb, struct genl_info *info) 684{ 685 struct devlink *devlink = info->user_ptr[0]; 686 struct sk_buff *msg; 687 int err; 688 689 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 690 if (!msg) 691 return -ENOMEM; 692 693 err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET, 694 info->snd_portid, info->snd_seq, 0); 695 696 if (err) { 697 nlmsg_free(msg); 698 return err; 699 } 700 701 return genlmsg_reply(msg, info); 702} 703 704int devlink_nl_eswitch_set_doit(struct sk_buff *skb, struct genl_info *info) 705{ 706 struct devlink *devlink = info->user_ptr[0]; 707 const struct devlink_ops *ops = devlink->ops; 708 enum devlink_eswitch_encap_mode encap_mode; 709 u8 inline_mode; 710 int err = 0; 711 u16 mode; 712 713 if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) { 714 if (!ops->eswitch_mode_set) 715 return -EOPNOTSUPP; 716 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]); 717 err = devlink_rate_nodes_check(devlink, mode, info->extack); 718 if (err) 719 return err; 720 err = ops->eswitch_mode_set(devlink, mode, info->extack); 721 if (err) 722 return err; 723 } 724 725 if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) { 726 if (!ops->eswitch_inline_mode_set) 727 return -EOPNOTSUPP; 728 inline_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]); 729 err = ops->eswitch_inline_mode_set(devlink, inline_mode, 730 info->extack); 731 if (err) 732 return err; 733 } 734 735 if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) { 736 if (!ops->eswitch_encap_mode_set) 737 return -EOPNOTSUPP; 738 encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]); 739 err = ops->eswitch_encap_mode_set(devlink, encap_mode, 740 info->extack); 741 if (err) 742 return err; 743 } 744 745 return 0; 746} 747 748int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn) 749{ 750 if (!req->msg) 751 return 0; 752 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn); 753} 754EXPORT_SYMBOL_GPL(devlink_info_serial_number_put); 755 756int devlink_info_board_serial_number_put(struct devlink_info_req *req, 757 const char *bsn) 758{ 759 if (!req->msg) 760 return 0; 761 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER, 762 bsn); 763} 764EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put); 765 766static int devlink_info_version_put(struct devlink_info_req *req, int attr, 767 const char *version_name, 768 const char *version_value, 769 enum devlink_info_version_type version_type) 770{ 771 struct nlattr *nest; 772 int err; 773 774 if (req->version_cb) 775 req->version_cb(version_name, version_type, 776 req->version_cb_priv); 777 778 if (!req->msg || !*version_value) 779 return 0; 780 781 nest = nla_nest_start_noflag(req->msg, attr); 782 if (!nest) 783 return -EMSGSIZE; 784 785 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME, 786 version_name); 787 if (err) 788 goto nla_put_failure; 789 790 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE, 791 version_value); 792 if (err) 793 goto nla_put_failure; 794 795 nla_nest_end(req->msg, nest); 796 797 return 0; 798 799nla_put_failure: 800 nla_nest_cancel(req->msg, nest); 801 return err; 802} 803 804int devlink_info_version_fixed_put(struct devlink_info_req *req, 805 const char *version_name, 806 const char *version_value) 807{ 808 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED, 809 version_name, version_value, 810 DEVLINK_INFO_VERSION_TYPE_NONE); 811} 812EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put); 813 814int devlink_info_version_stored_put(struct devlink_info_req *req, 815 const char *version_name, 816 const char *version_value) 817{ 818 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED, 819 version_name, version_value, 820 DEVLINK_INFO_VERSION_TYPE_NONE); 821} 822EXPORT_SYMBOL_GPL(devlink_info_version_stored_put); 823 824int devlink_info_version_stored_put_ext(struct devlink_info_req *req, 825 const char *version_name, 826 const char *version_value, 827 enum devlink_info_version_type version_type) 828{ 829 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED, 830 version_name, version_value, 831 version_type); 832} 833EXPORT_SYMBOL_GPL(devlink_info_version_stored_put_ext); 834 835int devlink_info_version_running_put(struct devlink_info_req *req, 836 const char *version_name, 837 const char *version_value) 838{ 839 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING, 840 version_name, version_value, 841 DEVLINK_INFO_VERSION_TYPE_NONE); 842} 843EXPORT_SYMBOL_GPL(devlink_info_version_running_put); 844 845int devlink_info_version_running_put_ext(struct devlink_info_req *req, 846 const char *version_name, 847 const char *version_value, 848 enum devlink_info_version_type version_type) 849{ 850 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING, 851 version_name, version_value, 852 version_type); 853} 854EXPORT_SYMBOL_GPL(devlink_info_version_running_put_ext); 855 856static int devlink_nl_driver_info_get(struct device_driver *drv, 857 struct devlink_info_req *req) 858{ 859 if (!drv) 860 return 0; 861 862 if (drv->name[0]) 863 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, 864 drv->name); 865 866 return 0; 867} 868 869static int 870devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink, 871 enum devlink_command cmd, u32 portid, 872 u32 seq, int flags, struct netlink_ext_ack *extack) 873{ 874 struct device *dev = devlink_to_dev(devlink); 875 struct devlink_info_req req = {}; 876 void *hdr; 877 int err; 878 879 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 880 if (!hdr) 881 return -EMSGSIZE; 882 883 err = -EMSGSIZE; 884 if (devlink_nl_put_handle(msg, devlink)) 885 goto err_cancel_msg; 886 887 req.msg = msg; 888 if (devlink->ops->info_get) { 889 err = devlink->ops->info_get(devlink, &req, extack); 890 if (err) 891 goto err_cancel_msg; 892 } 893 894 err = devlink_nl_driver_info_get(dev->driver, &req); 895 if (err) 896 goto err_cancel_msg; 897 898 genlmsg_end(msg, hdr); 899 return 0; 900 901err_cancel_msg: 902 genlmsg_cancel(msg, hdr); 903 return err; 904} 905 906int devlink_nl_info_get_doit(struct sk_buff *skb, struct genl_info *info) 907{ 908 struct devlink *devlink = info->user_ptr[0]; 909 struct sk_buff *msg; 910 int err; 911 912 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 913 if (!msg) 914 return -ENOMEM; 915 916 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, 917 info->snd_portid, info->snd_seq, 0, 918 info->extack); 919 if (err) { 920 nlmsg_free(msg); 921 return err; 922 } 923 924 return genlmsg_reply(msg, info); 925} 926 927static int 928devlink_nl_info_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 929 struct netlink_callback *cb, int flags) 930{ 931 int err; 932 933 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, 934 NETLINK_CB(cb->skb).portid, 935 cb->nlh->nlmsg_seq, flags, 936 cb->extack); 937 if (err == -EOPNOTSUPP) 938 err = 0; 939 return err; 940} 941 942int devlink_nl_info_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb) 943{ 944 return devlink_nl_dumpit(msg, cb, devlink_nl_info_get_dump_one); 945} 946 947static int devlink_nl_flash_update_fill(struct sk_buff *msg, 948 struct devlink *devlink, 949 enum devlink_command cmd, 950 struct devlink_flash_notify *params) 951{ 952 void *hdr; 953 954 hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd); 955 if (!hdr) 956 return -EMSGSIZE; 957 958 if (devlink_nl_put_handle(msg, devlink)) 959 goto nla_put_failure; 960 961 if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS) 962 goto out; 963 964 if (params->status_msg && 965 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG, 966 params->status_msg)) 967 goto nla_put_failure; 968 if (params->component && 969 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT, 970 params->component)) 971 goto nla_put_failure; 972 if (devlink_nl_put_u64(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE, 973 params->done)) 974 goto nla_put_failure; 975 if (devlink_nl_put_u64(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL, 976 params->total)) 977 goto nla_put_failure; 978 if (devlink_nl_put_u64(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT, 979 params->timeout)) 980 goto nla_put_failure; 981 982out: 983 genlmsg_end(msg, hdr); 984 return 0; 985 986nla_put_failure: 987 genlmsg_cancel(msg, hdr); 988 return -EMSGSIZE; 989} 990 991static void __devlink_flash_update_notify(struct devlink *devlink, 992 enum devlink_command cmd, 993 struct devlink_flash_notify *params) 994{ 995 struct sk_buff *msg; 996 int err; 997 998 WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE && 999 cmd != DEVLINK_CMD_FLASH_UPDATE_END && 1000 cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS); 1001 1002 if (!devl_is_registered(devlink) || !devlink_nl_notify_need(devlink)) 1003 return; 1004 1005 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1006 if (!msg) 1007 return; 1008 1009 err = devlink_nl_flash_update_fill(msg, devlink, cmd, params); 1010 if (err) 1011 goto out_free_msg; 1012 1013 devlink_nl_notify_send(devlink, msg); 1014 return; 1015 1016out_free_msg: 1017 nlmsg_free(msg); 1018} 1019 1020static void devlink_flash_update_begin_notify(struct devlink *devlink) 1021{ 1022 struct devlink_flash_notify params = {}; 1023 1024 __devlink_flash_update_notify(devlink, 1025 DEVLINK_CMD_FLASH_UPDATE, 1026 &params); 1027} 1028 1029static void devlink_flash_update_end_notify(struct devlink *devlink) 1030{ 1031 struct devlink_flash_notify params = {}; 1032 1033 __devlink_flash_update_notify(devlink, 1034 DEVLINK_CMD_FLASH_UPDATE_END, 1035 &params); 1036} 1037 1038void devlink_flash_update_status_notify(struct devlink *devlink, 1039 const char *status_msg, 1040 const char *component, 1041 unsigned long done, 1042 unsigned long total) 1043{ 1044 struct devlink_flash_notify params = { 1045 .status_msg = status_msg, 1046 .component = component, 1047 .done = done, 1048 .total = total, 1049 }; 1050 1051 __devlink_flash_update_notify(devlink, 1052 DEVLINK_CMD_FLASH_UPDATE_STATUS, 1053 &params); 1054} 1055EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify); 1056 1057void devlink_flash_update_timeout_notify(struct devlink *devlink, 1058 const char *status_msg, 1059 const char *component, 1060 unsigned long timeout) 1061{ 1062 struct devlink_flash_notify params = { 1063 .status_msg = status_msg, 1064 .component = component, 1065 .timeout = timeout, 1066 }; 1067 1068 __devlink_flash_update_notify(devlink, 1069 DEVLINK_CMD_FLASH_UPDATE_STATUS, 1070 &params); 1071} 1072EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify); 1073 1074struct devlink_flash_component_lookup_ctx { 1075 const char *lookup_name; 1076 bool lookup_name_found; 1077}; 1078 1079static void 1080devlink_flash_component_lookup_cb(const char *version_name, 1081 enum devlink_info_version_type version_type, 1082 void *version_cb_priv) 1083{ 1084 struct devlink_flash_component_lookup_ctx *lookup_ctx = version_cb_priv; 1085 1086 if (version_type != DEVLINK_INFO_VERSION_TYPE_COMPONENT || 1087 lookup_ctx->lookup_name_found) 1088 return; 1089 1090 lookup_ctx->lookup_name_found = 1091 !strcmp(lookup_ctx->lookup_name, version_name); 1092} 1093 1094static int devlink_flash_component_get(struct devlink *devlink, 1095 struct nlattr *nla_component, 1096 const char **p_component, 1097 struct netlink_ext_ack *extack) 1098{ 1099 struct devlink_flash_component_lookup_ctx lookup_ctx = {}; 1100 struct devlink_info_req req = {}; 1101 const char *component; 1102 int ret; 1103 1104 if (!nla_component) 1105 return 0; 1106 1107 component = nla_data(nla_component); 1108 1109 if (!devlink->ops->info_get) { 1110 NL_SET_ERR_MSG_ATTR(extack, nla_component, 1111 "component update is not supported by this device"); 1112 return -EOPNOTSUPP; 1113 } 1114 1115 lookup_ctx.lookup_name = component; 1116 req.version_cb = devlink_flash_component_lookup_cb; 1117 req.version_cb_priv = &lookup_ctx; 1118 1119 ret = devlink->ops->info_get(devlink, &req, NULL); 1120 if (ret) 1121 return ret; 1122 1123 if (!lookup_ctx.lookup_name_found) { 1124 NL_SET_ERR_MSG_ATTR(extack, nla_component, 1125 "selected component is not supported by this device"); 1126 return -EINVAL; 1127 } 1128 *p_component = component; 1129 return 0; 1130} 1131 1132int devlink_nl_flash_update_doit(struct sk_buff *skb, struct genl_info *info) 1133{ 1134 struct nlattr *nla_overwrite_mask, *nla_file_name; 1135 struct devlink_flash_update_params params = {}; 1136 struct devlink *devlink = info->user_ptr[0]; 1137 const char *file_name; 1138 u32 supported_params; 1139 int ret; 1140 1141 if (!devlink->ops->flash_update) 1142 return -EOPNOTSUPP; 1143 1144 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME)) 1145 return -EINVAL; 1146 1147 ret = devlink_flash_component_get(devlink, 1148 info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT], 1149 &params.component, info->extack); 1150 if (ret) 1151 return ret; 1152 1153 supported_params = devlink->ops->supported_flash_update_params; 1154 1155 nla_overwrite_mask = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK]; 1156 if (nla_overwrite_mask) { 1157 struct nla_bitfield32 sections; 1158 1159 if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) { 1160 NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite_mask, 1161 "overwrite settings are not supported by this device"); 1162 return -EOPNOTSUPP; 1163 } 1164 sections = nla_get_bitfield32(nla_overwrite_mask); 1165 params.overwrite_mask = sections.value & sections.selector; 1166 } 1167 1168 nla_file_name = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]; 1169 file_name = nla_data(nla_file_name); 1170 ret = request_firmware(&params.fw, file_name, devlink->dev); 1171 if (ret) { 1172 NL_SET_ERR_MSG_ATTR(info->extack, nla_file_name, 1173 "failed to locate the requested firmware file"); 1174 return ret; 1175 } 1176 1177 devlink_flash_update_begin_notify(devlink); 1178 ret = devlink->ops->flash_update(devlink, &params, info->extack); 1179 devlink_flash_update_end_notify(devlink); 1180 1181 release_firmware(params.fw); 1182 1183 return ret; 1184} 1185 1186static void __devlink_compat_running_version(struct devlink *devlink, 1187 char *buf, size_t len) 1188{ 1189 struct devlink_info_req req = {}; 1190 const struct nlattr *nlattr; 1191 struct sk_buff *msg; 1192 int rem, err; 1193 1194 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1195 if (!msg) 1196 return; 1197 1198 req.msg = msg; 1199 err = devlink->ops->info_get(devlink, &req, NULL); 1200 if (err) 1201 goto free_msg; 1202 1203 nla_for_each_attr_type(nlattr, DEVLINK_ATTR_INFO_VERSION_RUNNING, 1204 (void *)msg->data, msg->len, rem) { 1205 const struct nlattr *kv; 1206 int rem_kv; 1207 1208 nla_for_each_nested_type(kv, DEVLINK_ATTR_INFO_VERSION_VALUE, 1209 nlattr, rem_kv) { 1210 strlcat(buf, nla_data(kv), len); 1211 strlcat(buf, " ", len); 1212 } 1213 } 1214free_msg: 1215 nlmsg_consume(msg); 1216} 1217 1218void devlink_compat_running_version(struct devlink *devlink, 1219 char *buf, size_t len) 1220{ 1221 if (!devlink->ops->info_get) 1222 return; 1223 1224 devl_lock(devlink); 1225 if (devl_is_registered(devlink)) 1226 __devlink_compat_running_version(devlink, buf, len); 1227 devl_unlock(devlink); 1228} 1229 1230int devlink_compat_flash_update(struct devlink *devlink, const char *file_name) 1231{ 1232 struct devlink_flash_update_params params = {}; 1233 int ret; 1234 1235 devl_lock(devlink); 1236 if (!devl_is_registered(devlink)) { 1237 ret = -ENODEV; 1238 goto out_unlock; 1239 } 1240 1241 if (!devlink->ops->flash_update) { 1242 ret = -EOPNOTSUPP; 1243 goto out_unlock; 1244 } 1245 1246 ret = request_firmware(&params.fw, file_name, devlink->dev); 1247 if (ret) 1248 goto out_unlock; 1249 1250 devlink_flash_update_begin_notify(devlink); 1251 ret = devlink->ops->flash_update(devlink, &params, NULL); 1252 devlink_flash_update_end_notify(devlink); 1253 1254 release_firmware(params.fw); 1255out_unlock: 1256 devl_unlock(devlink); 1257 1258 return ret; 1259} 1260 1261static int 1262devlink_nl_selftests_fill(struct sk_buff *msg, struct devlink *devlink, 1263 u32 portid, u32 seq, int flags, 1264 struct netlink_ext_ack *extack) 1265{ 1266 struct nlattr *selftests; 1267 void *hdr; 1268 int err; 1269 int i; 1270 1271 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, 1272 DEVLINK_CMD_SELFTESTS_GET); 1273 if (!hdr) 1274 return -EMSGSIZE; 1275 1276 err = -EMSGSIZE; 1277 if (devlink_nl_put_handle(msg, devlink)) 1278 goto err_cancel_msg; 1279 1280 selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS); 1281 if (!selftests) 1282 goto err_cancel_msg; 1283 1284 for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1; 1285 i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) { 1286 if (devlink->ops->selftest_check(devlink, i, extack)) { 1287 err = nla_put_flag(msg, i); 1288 if (err) 1289 goto err_cancel_msg; 1290 } 1291 } 1292 1293 nla_nest_end(msg, selftests); 1294 genlmsg_end(msg, hdr); 1295 return 0; 1296 1297err_cancel_msg: 1298 genlmsg_cancel(msg, hdr); 1299 return err; 1300} 1301 1302int devlink_nl_selftests_get_doit(struct sk_buff *skb, struct genl_info *info) 1303{ 1304 struct devlink *devlink = info->user_ptr[0]; 1305 struct sk_buff *msg; 1306 int err; 1307 1308 if (!devlink->ops->selftest_check) 1309 return -EOPNOTSUPP; 1310 1311 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1312 if (!msg) 1313 return -ENOMEM; 1314 1315 err = devlink_nl_selftests_fill(msg, devlink, info->snd_portid, 1316 info->snd_seq, 0, info->extack); 1317 if (err) { 1318 nlmsg_free(msg); 1319 return err; 1320 } 1321 1322 return genlmsg_reply(msg, info); 1323} 1324 1325static int devlink_nl_selftests_get_dump_one(struct sk_buff *msg, 1326 struct devlink *devlink, 1327 struct netlink_callback *cb, 1328 int flags) 1329{ 1330 if (!devlink->ops->selftest_check) 1331 return 0; 1332 1333 return devlink_nl_selftests_fill(msg, devlink, 1334 NETLINK_CB(cb->skb).portid, 1335 cb->nlh->nlmsg_seq, flags, 1336 cb->extack); 1337} 1338 1339int devlink_nl_selftests_get_dumpit(struct sk_buff *skb, 1340 struct netlink_callback *cb) 1341{ 1342 return devlink_nl_dumpit(skb, cb, devlink_nl_selftests_get_dump_one); 1343} 1344 1345static int devlink_selftest_result_put(struct sk_buff *skb, unsigned int id, 1346 enum devlink_selftest_status test_status) 1347{ 1348 struct nlattr *result_attr; 1349 1350 result_attr = nla_nest_start(skb, DEVLINK_ATTR_SELFTEST_RESULT); 1351 if (!result_attr) 1352 return -EMSGSIZE; 1353 1354 if (nla_put_u32(skb, DEVLINK_ATTR_SELFTEST_RESULT_ID, id) || 1355 nla_put_u8(skb, DEVLINK_ATTR_SELFTEST_RESULT_STATUS, 1356 test_status)) 1357 goto nla_put_failure; 1358 1359 nla_nest_end(skb, result_attr); 1360 return 0; 1361 1362nla_put_failure: 1363 nla_nest_cancel(skb, result_attr); 1364 return -EMSGSIZE; 1365} 1366 1367static const struct nla_policy devlink_selftest_nl_policy[DEVLINK_ATTR_SELFTEST_ID_MAX + 1] = { 1368 [DEVLINK_ATTR_SELFTEST_ID_FLASH] = { .type = NLA_FLAG }, 1369}; 1370 1371int devlink_nl_selftests_run_doit(struct sk_buff *skb, struct genl_info *info) 1372{ 1373 struct nlattr *tb[DEVLINK_ATTR_SELFTEST_ID_MAX + 1]; 1374 struct devlink *devlink = info->user_ptr[0]; 1375 struct nlattr *attrs, *selftests; 1376 struct sk_buff *msg; 1377 void *hdr; 1378 int err; 1379 int i; 1380 1381 if (!devlink->ops->selftest_run || !devlink->ops->selftest_check) 1382 return -EOPNOTSUPP; 1383 1384 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SELFTESTS)) 1385 return -EINVAL; 1386 1387 attrs = info->attrs[DEVLINK_ATTR_SELFTESTS]; 1388 1389 err = nla_parse_nested(tb, DEVLINK_ATTR_SELFTEST_ID_MAX, attrs, 1390 devlink_selftest_nl_policy, info->extack); 1391 if (err < 0) 1392 return err; 1393 1394 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1395 if (!msg) 1396 return -ENOMEM; 1397 1398 err = -EMSGSIZE; 1399 hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, 1400 &devlink_nl_family, 0, DEVLINK_CMD_SELFTESTS_RUN); 1401 if (!hdr) 1402 goto free_msg; 1403 1404 if (devlink_nl_put_handle(msg, devlink)) 1405 goto genlmsg_cancel; 1406 1407 selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS); 1408 if (!selftests) 1409 goto genlmsg_cancel; 1410 1411 for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1; 1412 i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) { 1413 enum devlink_selftest_status test_status; 1414 1415 if (nla_get_flag(tb[i])) { 1416 if (!devlink->ops->selftest_check(devlink, i, 1417 info->extack)) { 1418 if (devlink_selftest_result_put(msg, i, 1419 DEVLINK_SELFTEST_STATUS_SKIP)) 1420 goto selftests_nest_cancel; 1421 continue; 1422 } 1423 1424 test_status = devlink->ops->selftest_run(devlink, i, 1425 info->extack); 1426 if (devlink_selftest_result_put(msg, i, test_status)) 1427 goto selftests_nest_cancel; 1428 } 1429 } 1430 1431 nla_nest_end(msg, selftests); 1432 genlmsg_end(msg, hdr); 1433 return genlmsg_reply(msg, info); 1434 1435selftests_nest_cancel: 1436 nla_nest_cancel(msg, selftests); 1437genlmsg_cancel: 1438 genlmsg_cancel(msg, hdr); 1439free_msg: 1440 nlmsg_free(msg); 1441 return err; 1442}