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 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 599 bool 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 628 static 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 678 nla_put_failure: 679 genlmsg_cancel(msg, hdr); 680 return err; 681 } 682 683 int 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 704 int 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 748 int 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 } 754 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put); 755 756 int 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 } 764 EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put); 765 766 static 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) 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 799 nla_put_failure: 800 nla_nest_cancel(req->msg, nest); 801 return err; 802 } 803 804 int 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 } 812 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put); 813 814 int 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 } 822 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put); 823 824 int 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 } 833 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put_ext); 834 835 int 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 } 843 EXPORT_SYMBOL_GPL(devlink_info_version_running_put); 844 845 int 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 } 854 EXPORT_SYMBOL_GPL(devlink_info_version_running_put_ext); 855 856 static 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 869 static int 870 devlink_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 901 err_cancel_msg: 902 genlmsg_cancel(msg, hdr); 903 return err; 904 } 905 906 int 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 927 static int 928 devlink_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 942 int 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 947 static 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 982 out: 983 genlmsg_end(msg, hdr); 984 return 0; 985 986 nla_put_failure: 987 genlmsg_cancel(msg, hdr); 988 return -EMSGSIZE; 989 } 990 991 static 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 1016 out_free_msg: 1017 nlmsg_free(msg); 1018 } 1019 1020 static 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 ¶ms); 1027 } 1028 1029 static 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 ¶ms); 1036 } 1037 1038 void 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 ¶ms); 1054 } 1055 EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify); 1056 1057 void 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 ¶ms); 1071 } 1072 EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify); 1073 1074 struct devlink_flash_component_lookup_ctx { 1075 const char *lookup_name; 1076 bool lookup_name_found; 1077 }; 1078 1079 static void 1080 devlink_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 1094 static 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 1132 int 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 ¶ms.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(¶ms.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, ¶ms, info->extack); 1179 devlink_flash_update_end_notify(devlink); 1180 1181 release_firmware(params.fw); 1182 1183 return ret; 1184 } 1185 1186 static 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 } 1214 free_msg: 1215 nlmsg_consume(msg); 1216 } 1217 1218 void 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 1230 int 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(¶ms.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, ¶ms, NULL); 1252 devlink_flash_update_end_notify(devlink); 1253 1254 release_firmware(params.fw); 1255 out_unlock: 1256 devl_unlock(devlink); 1257 1258 return ret; 1259 } 1260 1261 static int 1262 devlink_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 1297 err_cancel_msg: 1298 genlmsg_cancel(msg, hdr); 1299 return err; 1300 } 1301 1302 int 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 1325 static 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 1339 int 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 1345 static 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 1362 nla_put_failure: 1363 nla_nest_cancel(skb, result_attr); 1364 return -EMSGSIZE; 1365 } 1366 1367 static 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 1371 int 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 1435 selftests_nest_cancel: 1436 nla_nest_cancel(msg, selftests); 1437 genlmsg_cancel: 1438 genlmsg_cancel(msg, hdr); 1439 free_msg: 1440 nlmsg_free(msg); 1441 return err; 1442 } 1443