1 // SPDX-License-Identifier: GPL-2.0-or-later 1 2 /* 3 * Copyright (c) 2016 Mellanox Technologies. A 4 * Copyright (c) 2016 Jiri Pirko <jiri@mellano 5 */ 6 7 #include "devl_internal.h" 8 9 struct devlink_sb { 10 struct list_head list; 11 unsigned int index; 12 u32 size; 13 u16 ingress_pools_count; 14 u16 egress_pools_count; 15 u16 ingress_tc_count; 16 u16 egress_tc_count; 17 }; 18 19 static u16 devlink_sb_pool_count(struct devlin 20 { 21 return devlink_sb->ingress_pools_count 22 } 23 24 static struct devlink_sb *devlink_sb_get_by_in 25 26 { 27 struct devlink_sb *devlink_sb; 28 29 list_for_each_entry(devlink_sb, &devli 30 if (devlink_sb->index == sb_in 31 return devlink_sb; 32 } 33 return NULL; 34 } 35 36 static bool devlink_sb_index_exists(struct dev 37 unsigned i 38 { 39 return devlink_sb_get_by_index(devlink 40 } 41 42 static struct devlink_sb *devlink_sb_get_from_ 43 44 { 45 if (attrs[DEVLINK_ATTR_SB_INDEX]) { 46 u32 sb_index = nla_get_u32(att 47 struct devlink_sb *devlink_sb; 48 49 devlink_sb = devlink_sb_get_by 50 if (!devlink_sb) 51 return ERR_PTR(-ENODEV 52 return devlink_sb; 53 } 54 return ERR_PTR(-EINVAL); 55 } 56 57 static struct devlink_sb *devlink_sb_get_from_ 58 59 { 60 return devlink_sb_get_from_attrs(devli 61 } 62 63 static int devlink_sb_pool_index_get_from_attr 64 65 66 { 67 u16 val; 68 69 if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX] 70 return -EINVAL; 71 72 val = nla_get_u16(attrs[DEVLINK_ATTR_S 73 if (val >= devlink_sb_pool_count(devli 74 return -EINVAL; 75 *p_pool_index = val; 76 return 0; 77 } 78 79 static int devlink_sb_pool_index_get_from_info 80 81 82 { 83 return devlink_sb_pool_index_get_from_ 84 85 } 86 87 static int 88 devlink_sb_pool_type_get_from_attrs(struct nla 89 enum devli 90 { 91 u8 val; 92 93 if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE]) 94 return -EINVAL; 95 96 val = nla_get_u8(attrs[DEVLINK_ATTR_SB 97 if (val != DEVLINK_SB_POOL_TYPE_INGRES 98 val != DEVLINK_SB_POOL_TYPE_EGRESS 99 return -EINVAL; 100 *p_pool_type = val; 101 return 0; 102 } 103 104 static int 105 devlink_sb_pool_type_get_from_info(struct genl 106 enum devlin 107 { 108 return devlink_sb_pool_type_get_from_a 109 } 110 111 static int 112 devlink_sb_th_type_get_from_attrs(struct nlatt 113 enum devlink 114 { 115 u8 val; 116 117 if (!attrs[DEVLINK_ATTR_SB_POOL_THRESH 118 return -EINVAL; 119 120 val = nla_get_u8(attrs[DEVLINK_ATTR_SB 121 if (val != DEVLINK_SB_THRESHOLD_TYPE_S 122 val != DEVLINK_SB_THRESHOLD_TYPE_D 123 return -EINVAL; 124 *p_th_type = val; 125 return 0; 126 } 127 128 static int 129 devlink_sb_th_type_get_from_info(struct genl_i 130 enum devlink_ 131 { 132 return devlink_sb_th_type_get_from_att 133 } 134 135 static int 136 devlink_sb_tc_index_get_from_attrs(struct devl 137 struct nlat 138 enum devlin 139 u16 *p_tc_i 140 { 141 u16 val; 142 143 if (!attrs[DEVLINK_ATTR_SB_TC_INDEX]) 144 return -EINVAL; 145 146 val = nla_get_u16(attrs[DEVLINK_ATTR_S 147 if (pool_type == DEVLINK_SB_POOL_TYPE_ 148 val >= devlink_sb->ingress_tc_coun 149 return -EINVAL; 150 if (pool_type == DEVLINK_SB_POOL_TYPE_ 151 val >= devlink_sb->egress_tc_count 152 return -EINVAL; 153 *p_tc_index = val; 154 return 0; 155 } 156 157 static int 158 devlink_sb_tc_index_get_from_info(struct devli 159 struct genl_ 160 enum devlink 161 u16 *p_tc_in 162 { 163 return devlink_sb_tc_index_get_from_at 164 165 } 166 167 static int devlink_nl_sb_fill(struct sk_buff * 168 struct devlink_s 169 enum devlink_com 170 u32 seq, int fla 171 { 172 void *hdr; 173 174 hdr = genlmsg_put(msg, portid, seq, &d 175 if (!hdr) 176 return -EMSGSIZE; 177 178 if (devlink_nl_put_handle(msg, devlink 179 goto nla_put_failure; 180 if (nla_put_u32(msg, DEVLINK_ATTR_SB_I 181 goto nla_put_failure; 182 if (nla_put_u32(msg, DEVLINK_ATTR_SB_S 183 goto nla_put_failure; 184 if (nla_put_u16(msg, DEVLINK_ATTR_SB_I 185 devlink_sb->ingress_po 186 goto nla_put_failure; 187 if (nla_put_u16(msg, DEVLINK_ATTR_SB_E 188 devlink_sb->egress_poo 189 goto nla_put_failure; 190 if (nla_put_u16(msg, DEVLINK_ATTR_SB_I 191 devlink_sb->ingress_tc 192 goto nla_put_failure; 193 if (nla_put_u16(msg, DEVLINK_ATTR_SB_E 194 devlink_sb->egress_tc_ 195 goto nla_put_failure; 196 197 genlmsg_end(msg, hdr); 198 return 0; 199 200 nla_put_failure: 201 genlmsg_cancel(msg, hdr); 202 return -EMSGSIZE; 203 } 204 205 int devlink_nl_sb_get_doit(struct sk_buff *skb 206 { 207 struct devlink *devlink = info->user_p 208 struct devlink_sb *devlink_sb; 209 struct sk_buff *msg; 210 int err; 211 212 devlink_sb = devlink_sb_get_from_info( 213 if (IS_ERR(devlink_sb)) 214 return PTR_ERR(devlink_sb); 215 216 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GF 217 if (!msg) 218 return -ENOMEM; 219 220 err = devlink_nl_sb_fill(msg, devlink, 221 DEVLINK_CMD_S 222 info->snd_por 223 if (err) { 224 nlmsg_free(msg); 225 return err; 226 } 227 228 return genlmsg_reply(msg, info); 229 } 230 231 static int 232 devlink_nl_sb_get_dump_one(struct sk_buff *msg 233 struct netlink_call 234 { 235 struct devlink_nl_dump_state *state = 236 struct devlink_sb *devlink_sb; 237 int idx = 0; 238 int err = 0; 239 240 list_for_each_entry(devlink_sb, &devli 241 if (idx < state->idx) { 242 idx++; 243 continue; 244 } 245 err = devlink_nl_sb_fill(msg, 246 DEVLI 247 NETLI 248 cb->n 249 if (err) { 250 state->idx = idx; 251 break; 252 } 253 idx++; 254 } 255 256 return err; 257 } 258 259 int devlink_nl_sb_get_dumpit(struct sk_buff *s 260 { 261 return devlink_nl_dumpit(skb, cb, devl 262 } 263 264 static int devlink_nl_sb_pool_fill(struct sk_b 265 struct devl 266 u16 pool_in 267 u32 portid, 268 { 269 struct devlink_sb_pool_info pool_info; 270 void *hdr; 271 int err; 272 273 err = devlink->ops->sb_pool_get(devlin 274 pool_i 275 if (err) 276 return err; 277 278 hdr = genlmsg_put(msg, portid, seq, &d 279 if (!hdr) 280 return -EMSGSIZE; 281 282 if (devlink_nl_put_handle(msg, devlink 283 goto nla_put_failure; 284 if (nla_put_u32(msg, DEVLINK_ATTR_SB_I 285 goto nla_put_failure; 286 if (nla_put_u16(msg, DEVLINK_ATTR_SB_P 287 goto nla_put_failure; 288 if (nla_put_u8(msg, DEVLINK_ATTR_SB_PO 289 goto nla_put_failure; 290 if (nla_put_u32(msg, DEVLINK_ATTR_SB_P 291 goto nla_put_failure; 292 if (nla_put_u8(msg, DEVLINK_ATTR_SB_PO 293 pool_info.threshold_typ 294 goto nla_put_failure; 295 if (nla_put_u32(msg, DEVLINK_ATTR_SB_P 296 pool_info.cell_size)) 297 goto nla_put_failure; 298 299 genlmsg_end(msg, hdr); 300 return 0; 301 302 nla_put_failure: 303 genlmsg_cancel(msg, hdr); 304 return -EMSGSIZE; 305 } 306 307 int devlink_nl_sb_pool_get_doit(struct sk_buff 308 { 309 struct devlink *devlink = info->user_p 310 struct devlink_sb *devlink_sb; 311 struct sk_buff *msg; 312 u16 pool_index; 313 int err; 314 315 devlink_sb = devlink_sb_get_from_info( 316 if (IS_ERR(devlink_sb)) 317 return PTR_ERR(devlink_sb); 318 319 err = devlink_sb_pool_index_get_from_i 320 321 if (err) 322 return err; 323 324 if (!devlink->ops->sb_pool_get) 325 return -EOPNOTSUPP; 326 327 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GF 328 if (!msg) 329 return -ENOMEM; 330 331 err = devlink_nl_sb_pool_fill(msg, dev 332 DEVLINK_ 333 info->sn 334 if (err) { 335 nlmsg_free(msg); 336 return err; 337 } 338 339 return genlmsg_reply(msg, info); 340 } 341 342 static int __sb_pool_get_dumpit(struct sk_buff 343 struct devlink 344 struct devlink 345 u32 portid, u3 346 { 347 u16 pool_count = devlink_sb_pool_count 348 u16 pool_index; 349 int err; 350 351 for (pool_index = 0; pool_index < pool 352 if (*p_idx < start) { 353 (*p_idx)++; 354 continue; 355 } 356 err = devlink_nl_sb_pool_fill( 357 358 359 360 361 if (err) 362 return err; 363 (*p_idx)++; 364 } 365 return 0; 366 } 367 368 static int 369 devlink_nl_sb_pool_get_dump_one(struct sk_buff 370 struct netlink 371 { 372 struct devlink_nl_dump_state *state = 373 struct devlink_sb *devlink_sb; 374 int err = 0; 375 int idx = 0; 376 377 if (!devlink->ops->sb_pool_get) 378 return 0; 379 380 list_for_each_entry(devlink_sb, &devli 381 err = __sb_pool_get_dumpit(msg 382 dev 383 NET 384 cb- 385 if (err == -EOPNOTSUPP) { 386 err = 0; 387 } else if (err) { 388 state->idx = idx; 389 break; 390 } 391 } 392 393 return err; 394 } 395 396 int devlink_nl_sb_pool_get_dumpit(struct sk_bu 397 struct netli 398 { 399 return devlink_nl_dumpit(skb, cb, devl 400 } 401 402 static int devlink_sb_pool_set(struct devlink 403 u16 pool_index, 404 enum devlink_sb 405 struct netlink_ 406 407 { 408 const struct devlink_ops *ops = devlin 409 410 if (ops->sb_pool_set) 411 return ops->sb_pool_set(devlin 412 size, 413 return -EOPNOTSUPP; 414 } 415 416 int devlink_nl_sb_pool_set_doit(struct sk_buff 417 { 418 struct devlink *devlink = info->user_p 419 enum devlink_sb_threshold_type thresho 420 struct devlink_sb *devlink_sb; 421 u16 pool_index; 422 u32 size; 423 int err; 424 425 devlink_sb = devlink_sb_get_from_info( 426 if (IS_ERR(devlink_sb)) 427 return PTR_ERR(devlink_sb); 428 429 err = devlink_sb_pool_index_get_from_i 430 431 if (err) 432 return err; 433 434 err = devlink_sb_th_type_get_from_info 435 if (err) 436 return err; 437 438 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ 439 return -EINVAL; 440 441 size = nla_get_u32(info->attrs[DEVLINK 442 return devlink_sb_pool_set(devlink, de 443 pool_index, 444 info->extac 445 } 446 447 static int devlink_nl_sb_port_pool_fill(struct 448 struct 449 struct 450 struct 451 u16 po 452 enum d 453 u32 po 454 { 455 const struct devlink_ops *ops = devlin 456 u32 threshold; 457 void *hdr; 458 int err; 459 460 err = ops->sb_port_pool_get(devlink_po 461 pool_index 462 if (err) 463 return err; 464 465 hdr = genlmsg_put(msg, portid, seq, &d 466 if (!hdr) 467 return -EMSGSIZE; 468 469 if (devlink_nl_put_handle(msg, devlink 470 goto nla_put_failure; 471 if (nla_put_u32(msg, DEVLINK_ATTR_PORT 472 goto nla_put_failure; 473 if (nla_put_u32(msg, DEVLINK_ATTR_SB_I 474 goto nla_put_failure; 475 if (nla_put_u16(msg, DEVLINK_ATTR_SB_P 476 goto nla_put_failure; 477 if (nla_put_u32(msg, DEVLINK_ATTR_SB_T 478 goto nla_put_failure; 479 480 if (ops->sb_occ_port_pool_get) { 481 u32 cur; 482 u32 max; 483 484 err = ops->sb_occ_port_pool_ge 485 486 if (err && err != -EOPNOTSUPP) 487 goto sb_occ_get_failur 488 if (!err) { 489 if (nla_put_u32(msg, D 490 goto nla_put_f 491 if (nla_put_u32(msg, D 492 goto nla_put_f 493 } 494 } 495 496 genlmsg_end(msg, hdr); 497 return 0; 498 499 nla_put_failure: 500 err = -EMSGSIZE; 501 sb_occ_get_failure: 502 genlmsg_cancel(msg, hdr); 503 return err; 504 } 505 506 int devlink_nl_sb_port_pool_get_doit(struct sk 507 struct ge 508 { 509 struct devlink_port *devlink_port = in 510 struct devlink *devlink = devlink_port 511 struct devlink_sb *devlink_sb; 512 struct sk_buff *msg; 513 u16 pool_index; 514 int err; 515 516 devlink_sb = devlink_sb_get_from_info( 517 if (IS_ERR(devlink_sb)) 518 return PTR_ERR(devlink_sb); 519 520 err = devlink_sb_pool_index_get_from_i 521 522 if (err) 523 return err; 524 525 if (!devlink->ops->sb_port_pool_get) 526 return -EOPNOTSUPP; 527 528 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GF 529 if (!msg) 530 return -ENOMEM; 531 532 err = devlink_nl_sb_port_pool_fill(msg 533 dev 534 DEV 535 inf 536 if (err) { 537 nlmsg_free(msg); 538 return err; 539 } 540 541 return genlmsg_reply(msg, info); 542 } 543 544 static int __sb_port_pool_get_dumpit(struct sk 545 struct de 546 struct de 547 u32 porti 548 { 549 struct devlink_port *devlink_port; 550 u16 pool_count = devlink_sb_pool_count 551 unsigned long port_index; 552 u16 pool_index; 553 int err; 554 555 xa_for_each(&devlink->ports, port_inde 556 for (pool_index = 0; pool_inde 557 if (*p_idx < start) { 558 (*p_idx)++; 559 continue; 560 } 561 err = devlink_nl_sb_po 562 563 564 565 566 567 if (err) 568 return err; 569 (*p_idx)++; 570 } 571 } 572 return 0; 573 } 574 575 static int 576 devlink_nl_sb_port_pool_get_dump_one(struct sk 577 struct de 578 struct ne 579 { 580 struct devlink_nl_dump_state *state = 581 struct devlink_sb *devlink_sb; 582 int idx = 0; 583 int err = 0; 584 585 if (!devlink->ops->sb_port_pool_get) 586 return 0; 587 588 list_for_each_entry(devlink_sb, &devli 589 err = __sb_port_pool_get_dumpi 590 591 592 593 if (err == -EOPNOTSUPP) { 594 err = 0; 595 } else if (err) { 596 state->idx = idx; 597 break; 598 } 599 } 600 601 return err; 602 } 603 604 int devlink_nl_sb_port_pool_get_dumpit(struct 605 struct 606 { 607 return devlink_nl_dumpit(skb, cb, devl 608 } 609 610 static int devlink_sb_port_pool_set(struct dev 611 unsigned i 612 u32 thresh 613 struct net 614 615 { 616 const struct devlink_ops *ops = devlin 617 618 if (ops->sb_port_pool_set) 619 return ops->sb_port_pool_set(d 620 p 621 return -EOPNOTSUPP; 622 } 623 624 int devlink_nl_sb_port_pool_set_doit(struct sk 625 struct ge 626 { 627 struct devlink_port *devlink_port = in 628 struct devlink *devlink = info->user_p 629 struct devlink_sb *devlink_sb; 630 u16 pool_index; 631 u32 threshold; 632 int err; 633 634 devlink_sb = devlink_sb_get_from_info( 635 if (IS_ERR(devlink_sb)) 636 return PTR_ERR(devlink_sb); 637 638 err = devlink_sb_pool_index_get_from_i 639 640 if (err) 641 return err; 642 643 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ 644 return -EINVAL; 645 646 threshold = nla_get_u32(info->attrs[DE 647 return devlink_sb_port_pool_set(devlin 648 pool_i 649 } 650 651 static int 652 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff 653 struct devlink 654 struct devlink 655 enum devlink_s 656 enum devlink_c 657 u32 portid, u3 658 { 659 const struct devlink_ops *ops = devlin 660 u16 pool_index; 661 u32 threshold; 662 void *hdr; 663 int err; 664 665 err = ops->sb_tc_pool_bind_get(devlink 666 tc_inde 667 &pool_i 668 if (err) 669 return err; 670 671 hdr = genlmsg_put(msg, portid, seq, &d 672 if (!hdr) 673 return -EMSGSIZE; 674 675 if (devlink_nl_put_handle(msg, devlink 676 goto nla_put_failure; 677 if (nla_put_u32(msg, DEVLINK_ATTR_PORT 678 goto nla_put_failure; 679 if (nla_put_u32(msg, DEVLINK_ATTR_SB_I 680 goto nla_put_failure; 681 if (nla_put_u16(msg, DEVLINK_ATTR_SB_T 682 goto nla_put_failure; 683 if (nla_put_u8(msg, DEVLINK_ATTR_SB_PO 684 goto nla_put_failure; 685 if (nla_put_u16(msg, DEVLINK_ATTR_SB_P 686 goto nla_put_failure; 687 if (nla_put_u32(msg, DEVLINK_ATTR_SB_T 688 goto nla_put_failure; 689 690 if (ops->sb_occ_tc_port_bind_get) { 691 u32 cur; 692 u32 max; 693 694 err = ops->sb_occ_tc_port_bind 695 696 697 698 if (err && err != -EOPNOTSUPP) 699 return err; 700 if (!err) { 701 if (nla_put_u32(msg, D 702 goto nla_put_f 703 if (nla_put_u32(msg, D 704 goto nla_put_f 705 } 706 } 707 708 genlmsg_end(msg, hdr); 709 return 0; 710 711 nla_put_failure: 712 genlmsg_cancel(msg, hdr); 713 return -EMSGSIZE; 714 } 715 716 int devlink_nl_sb_tc_pool_bind_get_doit(struct 717 struct 718 { 719 struct devlink_port *devlink_port = in 720 struct devlink *devlink = devlink_port 721 struct devlink_sb *devlink_sb; 722 struct sk_buff *msg; 723 enum devlink_sb_pool_type pool_type; 724 u16 tc_index; 725 int err; 726 727 devlink_sb = devlink_sb_get_from_info( 728 if (IS_ERR(devlink_sb)) 729 return PTR_ERR(devlink_sb); 730 731 err = devlink_sb_pool_type_get_from_in 732 if (err) 733 return err; 734 735 err = devlink_sb_tc_index_get_from_inf 736 737 if (err) 738 return err; 739 740 if (!devlink->ops->sb_tc_pool_bind_get 741 return -EOPNOTSUPP; 742 743 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GF 744 if (!msg) 745 return -ENOMEM; 746 747 err = devlink_nl_sb_tc_pool_bind_fill( 748 749 750 751 752 if (err) { 753 nlmsg_free(msg); 754 return err; 755 } 756 757 return genlmsg_reply(msg, info); 758 } 759 760 static int __sb_tc_pool_bind_get_dumpit(struct 761 int st 762 struct 763 struct 764 u32 po 765 { 766 struct devlink_port *devlink_port; 767 unsigned long port_index; 768 u16 tc_index; 769 int err; 770 771 xa_for_each(&devlink->ports, port_inde 772 for (tc_index = 0; 773 tc_index < devlink_sb->in 774 if (*p_idx < start) { 775 (*p_idx)++; 776 continue; 777 } 778 err = devlink_nl_sb_tc 779 780 781 782 783 784 785 786 if (err) 787 return err; 788 (*p_idx)++; 789 } 790 for (tc_index = 0; 791 tc_index < devlink_sb->eg 792 if (*p_idx < start) { 793 (*p_idx)++; 794 continue; 795 } 796 err = devlink_nl_sb_tc 797 798 799 800 801 802 803 804 if (err) 805 return err; 806 (*p_idx)++; 807 } 808 } 809 return 0; 810 } 811 812 static int devlink_nl_sb_tc_pool_bind_get_dump 813 814 815 816 { 817 struct devlink_nl_dump_state *state = 818 struct devlink_sb *devlink_sb; 819 int idx = 0; 820 int err = 0; 821 822 if (!devlink->ops->sb_tc_pool_bind_get 823 return 0; 824 825 list_for_each_entry(devlink_sb, &devli 826 err = __sb_tc_pool_bind_get_du 827 828 829 830 if (err == -EOPNOTSUPP) { 831 err = 0; 832 } else if (err) { 833 state->idx = idx; 834 break; 835 } 836 } 837 838 return err; 839 } 840 841 int devlink_nl_sb_tc_pool_bind_get_dumpit(stru 842 stru 843 { 844 return devlink_nl_dumpit(skb, cb, 845 devlink_nl_sb 846 } 847 848 static int devlink_sb_tc_pool_bind_set(struct 849 unsigne 850 enum de 851 u16 poo 852 struct 853 854 { 855 const struct devlink_ops *ops = devlin 856 857 if (ops->sb_tc_pool_bind_set) 858 return ops->sb_tc_pool_bind_se 859 860 861 return -EOPNOTSUPP; 862 } 863 864 int devlink_nl_sb_tc_pool_bind_set_doit(struct 865 struct 866 { 867 struct devlink_port *devlink_port = in 868 struct devlink *devlink = info->user_p 869 enum devlink_sb_pool_type pool_type; 870 struct devlink_sb *devlink_sb; 871 u16 tc_index; 872 u16 pool_index; 873 u32 threshold; 874 int err; 875 876 devlink_sb = devlink_sb_get_from_info( 877 if (IS_ERR(devlink_sb)) 878 return PTR_ERR(devlink_sb); 879 880 err = devlink_sb_pool_type_get_from_in 881 if (err) 882 return err; 883 884 err = devlink_sb_tc_index_get_from_inf 885 886 if (err) 887 return err; 888 889 err = devlink_sb_pool_index_get_from_i 890 891 if (err) 892 return err; 893 894 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ 895 return -EINVAL; 896 897 threshold = nla_get_u32(info->attrs[DE 898 return devlink_sb_tc_pool_bind_set(dev 899 tc_ 900 poo 901 } 902 903 int devlink_nl_sb_occ_snapshot_doit(struct sk_ 904 { 905 struct devlink *devlink = info->user_p 906 const struct devlink_ops *ops = devlin 907 struct devlink_sb *devlink_sb; 908 909 devlink_sb = devlink_sb_get_from_info( 910 if (IS_ERR(devlink_sb)) 911 return PTR_ERR(devlink_sb); 912 913 if (ops->sb_occ_snapshot) 914 return ops->sb_occ_snapshot(de 915 return -EOPNOTSUPP; 916 } 917 918 int devlink_nl_sb_occ_max_clear_doit(struct sk 919 struct ge 920 { 921 struct devlink *devlink = info->user_p 922 const struct devlink_ops *ops = devlin 923 struct devlink_sb *devlink_sb; 924 925 devlink_sb = devlink_sb_get_from_info( 926 if (IS_ERR(devlink_sb)) 927 return PTR_ERR(devlink_sb); 928 929 if (ops->sb_occ_max_clear) 930 return ops->sb_occ_max_clear(d 931 return -EOPNOTSUPP; 932 } 933 934 int devl_sb_register(struct devlink *devlink, 935 u32 size, u16 ingress_poo 936 u16 egress_pools_count, u 937 u16 egress_tc_count) 938 { 939 struct devlink_sb *devlink_sb; 940 941 lockdep_assert_held(&devlink->lock); 942 943 if (devlink_sb_index_exists(devlink, s 944 return -EEXIST; 945 946 devlink_sb = kzalloc(sizeof(*devlink_s 947 if (!devlink_sb) 948 return -ENOMEM; 949 devlink_sb->index = sb_index; 950 devlink_sb->size = size; 951 devlink_sb->ingress_pools_count = ingr 952 devlink_sb->egress_pools_count = egres 953 devlink_sb->ingress_tc_count = ingress 954 devlink_sb->egress_tc_count = egress_t 955 list_add_tail(&devlink_sb->list, &devl 956 return 0; 957 } 958 EXPORT_SYMBOL_GPL(devl_sb_register); 959 960 int devlink_sb_register(struct devlink *devlin 961 u32 size, u16 ingress_ 962 u16 egress_pools_count 963 u16 egress_tc_count) 964 { 965 int err; 966 967 devl_lock(devlink); 968 err = devl_sb_register(devlink, sb_ind 969 egress_pools_co 970 egress_tc_count 971 devl_unlock(devlink); 972 return err; 973 } 974 EXPORT_SYMBOL_GPL(devlink_sb_register); 975 976 void devl_sb_unregister(struct devlink *devlin 977 { 978 struct devlink_sb *devlink_sb; 979 980 lockdep_assert_held(&devlink->lock); 981 982 devlink_sb = devlink_sb_get_by_index(d 983 WARN_ON(!devlink_sb); 984 list_del(&devlink_sb->list); 985 kfree(devlink_sb); 986 } 987 EXPORT_SYMBOL_GPL(devl_sb_unregister); 988 989 void devlink_sb_unregister(struct devlink *dev 990 { 991 devl_lock(devlink); 992 devl_sb_unregister(devlink, sb_index); 993 devl_unlock(devlink); 994 } 995 EXPORT_SYMBOL_GPL(devlink_sb_unregister); 996
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.