1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved */ 3 4 #include <linux/etherdevice.h> 5 #include <linux/if_bridge.h> 6 #include <linux/ethtool.h> 7 #include <linux/list.h> 8 9 #include "prestera.h" 10 #include "prestera_hw.h" 11 #include "prestera_acl.h" 12 #include "prestera_counter.h" 13 #include "prestera_router_hw.h" 14 15 #define PRESTERA_SWITCH_INIT_TIMEOUT_MS (30 * 1000) 16 17 #define PRESTERA_MIN_MTU 64 18 19 #define PRESTERA_MSG_CHUNK_SIZE 1024 20 21 enum prestera_cmd_type_t { 22 PRESTERA_CMD_TYPE_SWITCH_INIT = 0x1, 23 PRESTERA_CMD_TYPE_SWITCH_ATTR_SET = 0x2, 24 25 PRESTERA_CMD_TYPE_PORT_ATTR_SET = 0x100, 26 PRESTERA_CMD_TYPE_PORT_ATTR_GET = 0x101, 27 PRESTERA_CMD_TYPE_PORT_INFO_GET = 0x110, 28 29 PRESTERA_CMD_TYPE_VLAN_CREATE = 0x200, 30 PRESTERA_CMD_TYPE_VLAN_DELETE = 0x201, 31 PRESTERA_CMD_TYPE_VLAN_PORT_SET = 0x202, 32 PRESTERA_CMD_TYPE_VLAN_PVID_SET = 0x203, 33 34 PRESTERA_CMD_TYPE_FDB_ADD = 0x300, 35 PRESTERA_CMD_TYPE_FDB_DELETE = 0x301, 36 PRESTERA_CMD_TYPE_FDB_FLUSH_PORT = 0x310, 37 PRESTERA_CMD_TYPE_FDB_FLUSH_VLAN = 0x311, 38 PRESTERA_CMD_TYPE_FDB_FLUSH_PORT_VLAN = 0x312, 39 40 PRESTERA_CMD_TYPE_BRIDGE_CREATE = 0x400, 41 PRESTERA_CMD_TYPE_BRIDGE_DELETE = 0x401, 42 PRESTERA_CMD_TYPE_BRIDGE_PORT_ADD = 0x402, 43 PRESTERA_CMD_TYPE_BRIDGE_PORT_DELETE = 0x403, 44 45 PRESTERA_CMD_TYPE_COUNTER_GET = 0x510, 46 PRESTERA_CMD_TYPE_COUNTER_ABORT = 0x511, 47 PRESTERA_CMD_TYPE_COUNTER_TRIGGER = 0x512, 48 PRESTERA_CMD_TYPE_COUNTER_BLOCK_GET = 0x513, 49 PRESTERA_CMD_TYPE_COUNTER_BLOCK_RELEASE = 0x514, 50 PRESTERA_CMD_TYPE_COUNTER_CLEAR = 0x515, 51 52 PRESTERA_CMD_TYPE_VTCAM_CREATE = 0x540, 53 PRESTERA_CMD_TYPE_VTCAM_DESTROY = 0x541, 54 PRESTERA_CMD_TYPE_VTCAM_RULE_ADD = 0x550, 55 PRESTERA_CMD_TYPE_VTCAM_RULE_DELETE = 0x551, 56 PRESTERA_CMD_TYPE_VTCAM_IFACE_BIND = 0x560, 57 PRESTERA_CMD_TYPE_VTCAM_IFACE_UNBIND = 0x561, 58 59 PRESTERA_CMD_TYPE_ROUTER_RIF_CREATE = 0x600, 60 PRESTERA_CMD_TYPE_ROUTER_RIF_DELETE = 0x601, 61 PRESTERA_CMD_TYPE_ROUTER_LPM_ADD = 0x610, 62 PRESTERA_CMD_TYPE_ROUTER_LPM_DELETE = 0x611, 63 PRESTERA_CMD_TYPE_ROUTER_NH_GRP_SET = 0x622, 64 PRESTERA_CMD_TYPE_ROUTER_NH_GRP_BLK_GET = 0x645, 65 PRESTERA_CMD_TYPE_ROUTER_NH_GRP_ADD = 0x623, 66 PRESTERA_CMD_TYPE_ROUTER_NH_GRP_DELETE = 0x624, 67 PRESTERA_CMD_TYPE_ROUTER_VR_CREATE = 0x630, 68 PRESTERA_CMD_TYPE_ROUTER_VR_DELETE = 0x631, 69 70 PRESTERA_CMD_TYPE_FLOOD_DOMAIN_CREATE = 0x700, 71 PRESTERA_CMD_TYPE_FLOOD_DOMAIN_DESTROY = 0x701, 72 PRESTERA_CMD_TYPE_FLOOD_DOMAIN_PORTS_SET = 0x702, 73 PRESTERA_CMD_TYPE_FLOOD_DOMAIN_PORTS_RESET = 0x703, 74 75 PRESTERA_CMD_TYPE_MDB_CREATE = 0x704, 76 PRESTERA_CMD_TYPE_MDB_DESTROY = 0x705, 77 78 PRESTERA_CMD_TYPE_RXTX_INIT = 0x800, 79 80 PRESTERA_CMD_TYPE_LAG_MEMBER_ADD = 0x900, 81 PRESTERA_CMD_TYPE_LAG_MEMBER_DELETE = 0x901, 82 PRESTERA_CMD_TYPE_LAG_MEMBER_ENABLE = 0x902, 83 PRESTERA_CMD_TYPE_LAG_MEMBER_DISABLE = 0x903, 84 85 PRESTERA_CMD_TYPE_STP_PORT_SET = 0x1000, 86 87 PRESTERA_CMD_TYPE_SPAN_GET = 0x1100, 88 PRESTERA_CMD_TYPE_SPAN_INGRESS_BIND = 0x1101, 89 PRESTERA_CMD_TYPE_SPAN_INGRESS_UNBIND = 0x1102, 90 PRESTERA_CMD_TYPE_SPAN_RELEASE = 0x1103, 91 PRESTERA_CMD_TYPE_SPAN_EGRESS_BIND = 0x1104, 92 PRESTERA_CMD_TYPE_SPAN_EGRESS_UNBIND = 0x1105, 93 94 PRESTERA_CMD_TYPE_POLICER_CREATE = 0x1500, 95 PRESTERA_CMD_TYPE_POLICER_RELEASE = 0x1501, 96 PRESTERA_CMD_TYPE_POLICER_SET = 0x1502, 97 98 PRESTERA_CMD_TYPE_CPU_CODE_COUNTERS_GET = 0x2000, 99 100 PRESTERA_CMD_TYPE_ACK = 0x10000, 101 PRESTERA_CMD_TYPE_MAX 102 }; 103 104 enum { 105 PRESTERA_CMD_PORT_ATTR_ADMIN_STATE = 1, 106 PRESTERA_CMD_PORT_ATTR_MTU = 3, 107 PRESTERA_CMD_PORT_ATTR_MAC = 4, 108 PRESTERA_CMD_PORT_ATTR_SPEED = 5, 109 PRESTERA_CMD_PORT_ATTR_ACCEPT_FRAME_TYPE = 6, 110 PRESTERA_CMD_PORT_ATTR_LEARNING = 7, 111 PRESTERA_CMD_PORT_ATTR_FLOOD = 8, 112 PRESTERA_CMD_PORT_ATTR_CAPABILITY = 9, 113 PRESTERA_CMD_PORT_ATTR_LOCKED = 10, 114 PRESTERA_CMD_PORT_ATTR_PHY_MODE = 12, 115 PRESTERA_CMD_PORT_ATTR_TYPE = 13, 116 PRESTERA_CMD_PORT_ATTR_STATS = 17, 117 PRESTERA_CMD_PORT_ATTR_MAC_AUTONEG_RESTART = 18, 118 PRESTERA_CMD_PORT_ATTR_PHY_AUTONEG_RESTART = 19, 119 PRESTERA_CMD_PORT_ATTR_MAC_MODE = 22, 120 }; 121 122 enum { 123 PRESTERA_CMD_SWITCH_ATTR_MAC = 1, 124 PRESTERA_CMD_SWITCH_ATTR_AGEING = 2, 125 }; 126 127 enum { 128 PRESTERA_CMD_ACK_OK, 129 PRESTERA_CMD_ACK_FAILED, 130 131 PRESTERA_CMD_ACK_MAX 132 }; 133 134 enum { 135 PRESTERA_PORT_TP_NA, 136 PRESTERA_PORT_TP_MDI, 137 PRESTERA_PORT_TP_MDIX, 138 PRESTERA_PORT_TP_AUTO, 139 }; 140 141 enum { 142 PRESTERA_PORT_FLOOD_TYPE_UC = 0, 143 PRESTERA_PORT_FLOOD_TYPE_MC = 1, 144 }; 145 146 enum { 147 PRESTERA_PORT_GOOD_OCTETS_RCV_CNT, 148 PRESTERA_PORT_BAD_OCTETS_RCV_CNT, 149 PRESTERA_PORT_MAC_TRANSMIT_ERR_CNT, 150 PRESTERA_PORT_BRDC_PKTS_RCV_CNT, 151 PRESTERA_PORT_MC_PKTS_RCV_CNT, 152 PRESTERA_PORT_PKTS_64L_CNT, 153 PRESTERA_PORT_PKTS_65TO127L_CNT, 154 PRESTERA_PORT_PKTS_128TO255L_CNT, 155 PRESTERA_PORT_PKTS_256TO511L_CNT, 156 PRESTERA_PORT_PKTS_512TO1023L_CNT, 157 PRESTERA_PORT_PKTS_1024TOMAXL_CNT, 158 PRESTERA_PORT_EXCESSIVE_COLLISIONS_CNT, 159 PRESTERA_PORT_MC_PKTS_SENT_CNT, 160 PRESTERA_PORT_BRDC_PKTS_SENT_CNT, 161 PRESTERA_PORT_FC_SENT_CNT, 162 PRESTERA_PORT_GOOD_FC_RCV_CNT, 163 PRESTERA_PORT_DROP_EVENTS_CNT, 164 PRESTERA_PORT_UNDERSIZE_PKTS_CNT, 165 PRESTERA_PORT_FRAGMENTS_PKTS_CNT, 166 PRESTERA_PORT_OVERSIZE_PKTS_CNT, 167 PRESTERA_PORT_JABBER_PKTS_CNT, 168 PRESTERA_PORT_MAC_RCV_ERROR_CNT, 169 PRESTERA_PORT_BAD_CRC_CNT, 170 PRESTERA_PORT_COLLISIONS_CNT, 171 PRESTERA_PORT_LATE_COLLISIONS_CNT, 172 PRESTERA_PORT_GOOD_UC_PKTS_RCV_CNT, 173 PRESTERA_PORT_GOOD_UC_PKTS_SENT_CNT, 174 PRESTERA_PORT_MULTIPLE_PKTS_SENT_CNT, 175 PRESTERA_PORT_DEFERRED_PKTS_SENT_CNT, 176 PRESTERA_PORT_GOOD_OCTETS_SENT_CNT, 177 178 PRESTERA_PORT_CNT_MAX 179 }; 180 181 enum { 182 PRESTERA_FC_NONE, 183 PRESTERA_FC_SYMMETRIC, 184 PRESTERA_FC_ASYMMETRIC, 185 PRESTERA_FC_SYMM_ASYMM, 186 }; 187 188 enum { 189 PRESTERA_POLICER_MODE_SR_TCM 190 }; 191 192 enum { 193 PRESTERA_HW_FDB_ENTRY_TYPE_REG_PORT = 0, 194 PRESTERA_HW_FDB_ENTRY_TYPE_LAG = 1, 195 PRESTERA_HW_FDB_ENTRY_TYPE_MAX = 2, 196 }; 197 198 struct prestera_fw_event_handler { 199 struct list_head list; 200 struct rcu_head rcu; 201 enum prestera_event_type type; 202 prestera_event_cb_t func; 203 void *arg; 204 }; 205 206 enum { 207 PRESTERA_HW_FLOOD_DOMAIN_PORT_TYPE_REG_PORT = 0, 208 PRESTERA_HW_FLOOD_DOMAIN_PORT_TYPE_LAG = 1, 209 PRESTERA_HW_FLOOD_DOMAIN_PORT_TYPE_MAX = 2, 210 }; 211 212 struct prestera_msg_cmd { 213 __le32 type; 214 }; 215 216 struct prestera_msg_ret { 217 struct prestera_msg_cmd cmd; 218 __le32 status; 219 }; 220 221 struct prestera_msg_common_req { 222 struct prestera_msg_cmd cmd; 223 }; 224 225 struct prestera_msg_common_resp { 226 struct prestera_msg_ret ret; 227 }; 228 229 struct prestera_msg_switch_attr_req { 230 struct prestera_msg_cmd cmd; 231 __le32 attr; 232 union { 233 __le32 ageing_timeout_ms; 234 struct { 235 u8 mac[ETH_ALEN]; 236 u8 __pad[2]; 237 }; 238 } param; 239 }; 240 241 struct prestera_msg_switch_init_resp { 242 struct prestera_msg_ret ret; 243 __le32 port_count; 244 __le32 mtu_max; 245 __le32 size_tbl_router_nexthop; 246 u8 switch_id; 247 u8 lag_max; 248 u8 lag_member_max; 249 }; 250 251 struct prestera_msg_event_port_param { 252 union { 253 struct { 254 __le32 mode; 255 __le32 speed; 256 u8 oper; 257 u8 duplex; 258 u8 fc; 259 u8 fec; 260 } mac; 261 struct { 262 __le64 lmode_bmap; 263 u8 mdix; 264 u8 fc; 265 u8 __pad[2]; 266 } __packed phy; /* make sure always 12 bytes size */ 267 }; 268 }; 269 270 struct prestera_msg_port_cap_param { 271 __le64 link_mode; 272 u8 type; 273 u8 fec; 274 u8 fc; 275 u8 transceiver; 276 }; 277 278 struct prestera_msg_port_flood_param { 279 u8 type; 280 u8 enable; 281 u8 __pad[2]; 282 }; 283 284 union prestera_msg_port_param { 285 __le32 mtu; 286 __le32 speed; 287 __le32 link_mode; 288 u8 admin_state; 289 u8 oper_state; 290 u8 mac[ETH_ALEN]; 291 u8 accept_frm_type; 292 u8 learning; 293 u8 flood; 294 u8 type; 295 u8 duplex; 296 u8 fec; 297 u8 fc; 298 u8 br_locked; 299 union { 300 struct { 301 u8 admin; 302 u8 fc; 303 u8 ap_enable; 304 u8 __reserved[5]; 305 union { 306 struct { 307 __le32 mode; 308 __le32 speed; 309 u8 inband; 310 u8 duplex; 311 u8 fec; 312 u8 fec_supp; 313 } reg_mode; 314 struct { 315 __le32 mode; 316 __le32 speed; 317 u8 fec; 318 u8 fec_supp; 319 u8 __pad[2]; 320 } ap_modes[PRESTERA_AP_PORT_MAX]; 321 }; 322 } mac; 323 struct { 324 __le64 modes; 325 __le32 mode; 326 u8 admin; 327 u8 adv_enable; 328 u8 mdix; 329 u8 __pad; 330 } phy; 331 } link; 332 333 struct prestera_msg_port_cap_param cap; 334 struct prestera_msg_port_flood_param flood_ext; 335 struct prestera_msg_event_port_param link_evt; 336 }; 337 338 struct prestera_msg_port_attr_req { 339 struct prestera_msg_cmd cmd; 340 __le32 attr; 341 __le32 port; 342 __le32 dev; 343 union prestera_msg_port_param param; 344 }; 345 346 struct prestera_msg_port_attr_resp { 347 struct prestera_msg_ret ret; 348 union prestera_msg_port_param param; 349 }; 350 351 struct prestera_msg_port_stats_resp { 352 struct prestera_msg_ret ret; 353 __le64 stats[PRESTERA_PORT_CNT_MAX]; 354 }; 355 356 struct prestera_msg_port_info_req { 357 struct prestera_msg_cmd cmd; 358 __le32 port; 359 }; 360 361 struct prestera_msg_port_info_resp { 362 struct prestera_msg_ret ret; 363 __le32 hw_id; 364 __le32 dev_id; 365 __le16 fp_id; 366 u8 pad[2]; 367 }; 368 369 struct prestera_msg_vlan_req { 370 struct prestera_msg_cmd cmd; 371 __le32 port; 372 __le32 dev; 373 __le16 vid; 374 u8 is_member; 375 u8 is_tagged; 376 }; 377 378 struct prestera_msg_fdb_req { 379 struct prestera_msg_cmd cmd; 380 __le32 flush_mode; 381 union { 382 struct { 383 __le32 port; 384 __le32 dev; 385 }; 386 __le16 lag_id; 387 } dest; 388 __le16 vid; 389 u8 dest_type; 390 u8 dynamic; 391 u8 mac[ETH_ALEN]; 392 u8 __pad[2]; 393 }; 394 395 struct prestera_msg_bridge_req { 396 struct prestera_msg_cmd cmd; 397 __le32 port; 398 __le32 dev; 399 __le16 bridge; 400 u8 pad[2]; 401 }; 402 403 struct prestera_msg_bridge_resp { 404 struct prestera_msg_ret ret; 405 __le16 bridge; 406 u8 pad[2]; 407 }; 408 409 struct prestera_msg_vtcam_create_req { 410 struct prestera_msg_cmd cmd; 411 __le32 keymask[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX]; 412 u8 direction; 413 u8 lookup; 414 u8 pad[2]; 415 }; 416 417 struct prestera_msg_vtcam_destroy_req { 418 struct prestera_msg_cmd cmd; 419 __le32 vtcam_id; 420 }; 421 422 struct prestera_msg_vtcam_rule_add_req { 423 struct prestera_msg_cmd cmd; 424 __le32 key[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX]; 425 __le32 keymask[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX]; 426 __le32 vtcam_id; 427 __le32 prio; 428 __le32 n_act; 429 }; 430 431 struct prestera_msg_vtcam_rule_del_req { 432 struct prestera_msg_cmd cmd; 433 __le32 vtcam_id; 434 __le32 id; 435 }; 436 437 struct prestera_msg_vtcam_bind_req { 438 struct prestera_msg_cmd cmd; 439 union { 440 struct { 441 __le32 hw_id; 442 __le32 dev_id; 443 } port; 444 __le32 index; 445 }; 446 __le32 vtcam_id; 447 __le16 pcl_id; 448 __le16 type; 449 }; 450 451 struct prestera_msg_vtcam_resp { 452 struct prestera_msg_ret ret; 453 __le32 vtcam_id; 454 __le32 rule_id; 455 }; 456 457 struct prestera_msg_acl_action { 458 __le32 id; 459 __le32 __reserved; 460 union { 461 struct { 462 __le32 index; 463 } jump; 464 struct { 465 __le32 id; 466 } police; 467 struct { 468 __le32 id; 469 } count; 470 __le32 reserved[6]; 471 }; 472 }; 473 474 struct prestera_msg_counter_req { 475 struct prestera_msg_cmd cmd; 476 __le32 client; 477 __le32 block_id; 478 __le32 num_counters; 479 }; 480 481 struct prestera_msg_counter_stats { 482 __le64 packets; 483 __le64 bytes; 484 }; 485 486 struct prestera_msg_counter_resp { 487 struct prestera_msg_ret ret; 488 __le32 block_id; 489 __le32 offset; 490 __le32 num_counters; 491 __le32 done; 492 struct prestera_msg_counter_stats stats[]; 493 }; 494 495 struct prestera_msg_span_req { 496 struct prestera_msg_cmd cmd; 497 __le32 port; 498 __le32 dev; 499 u8 id; 500 u8 pad[3]; 501 }; 502 503 struct prestera_msg_span_resp { 504 struct prestera_msg_ret ret; 505 u8 id; 506 u8 pad[3]; 507 }; 508 509 struct prestera_msg_stp_req { 510 struct prestera_msg_cmd cmd; 511 __le32 port; 512 __le32 dev; 513 __le16 vid; 514 u8 state; 515 u8 __pad; 516 }; 517 518 struct prestera_msg_rxtx_req { 519 struct prestera_msg_cmd cmd; 520 u8 use_sdma; 521 u8 pad[3]; 522 }; 523 524 struct prestera_msg_rxtx_resp { 525 struct prestera_msg_ret ret; 526 __le32 map_addr; 527 }; 528 529 struct prestera_msg_iface { 530 union { 531 struct { 532 __le32 dev; 533 __le32 port; 534 }; 535 __le16 lag_id; 536 }; 537 __le16 vr_id; 538 __le16 vid; 539 u8 type; 540 u8 __pad[3]; 541 }; 542 543 struct prestera_msg_ip_addr { 544 union { 545 __be32 ipv4; 546 __be32 ipv6[4]; 547 } u; 548 u8 v; /* e.g. PRESTERA_IPV4 */ 549 u8 __pad[3]; 550 }; 551 552 struct prestera_msg_nh { 553 struct prestera_msg_iface oif; 554 __le32 hw_id; 555 u8 mac[ETH_ALEN]; 556 u8 is_active; 557 u8 pad; 558 }; 559 560 struct prestera_msg_rif_req { 561 struct prestera_msg_cmd cmd; 562 struct prestera_msg_iface iif; 563 __le32 mtu; 564 __le16 rif_id; 565 __le16 __reserved; 566 u8 mac[ETH_ALEN]; 567 u8 __pad[2]; 568 }; 569 570 struct prestera_msg_rif_resp { 571 struct prestera_msg_ret ret; 572 __le16 rif_id; 573 u8 __pad[2]; 574 }; 575 576 struct prestera_msg_lpm_req { 577 struct prestera_msg_cmd cmd; 578 struct prestera_msg_ip_addr dst; 579 __le32 grp_id; 580 __le32 dst_len; 581 __le16 vr_id; 582 u8 __pad[2]; 583 }; 584 585 struct prestera_msg_nh_req { 586 struct prestera_msg_cmd cmd; 587 struct prestera_msg_nh nh[PRESTERA_NHGR_SIZE_MAX]; 588 __le32 size; 589 __le32 grp_id; 590 }; 591 592 struct prestera_msg_nh_chunk_req { 593 struct prestera_msg_cmd cmd; 594 __le32 offset; 595 }; 596 597 struct prestera_msg_nh_chunk_resp { 598 struct prestera_msg_ret ret; 599 u8 hw_state[PRESTERA_MSG_CHUNK_SIZE]; 600 }; 601 602 struct prestera_msg_nh_grp_req { 603 struct prestera_msg_cmd cmd; 604 __le32 grp_id; 605 __le32 size; 606 }; 607 608 struct prestera_msg_nh_grp_resp { 609 struct prestera_msg_ret ret; 610 __le32 grp_id; 611 }; 612 613 struct prestera_msg_vr_req { 614 struct prestera_msg_cmd cmd; 615 __le16 vr_id; 616 u8 __pad[2]; 617 }; 618 619 struct prestera_msg_vr_resp { 620 struct prestera_msg_ret ret; 621 __le16 vr_id; 622 u8 __pad[2]; 623 }; 624 625 struct prestera_msg_lag_req { 626 struct prestera_msg_cmd cmd; 627 __le32 port; 628 __le32 dev; 629 __le16 lag_id; 630 u8 pad[2]; 631 }; 632 633 struct prestera_msg_cpu_code_counter_req { 634 struct prestera_msg_cmd cmd; 635 u8 counter_type; 636 u8 code; 637 u8 pad[2]; 638 }; 639 640 struct mvsw_msg_cpu_code_counter_ret { 641 struct prestera_msg_ret ret; 642 __le64 packet_count; 643 }; 644 645 struct prestera_msg_policer_req { 646 struct prestera_msg_cmd cmd; 647 __le32 id; 648 union { 649 struct { 650 __le64 cir; 651 __le32 cbs; 652 } __packed sr_tcm; /* make sure always 12 bytes size */ 653 __le32 reserved[6]; 654 }; 655 u8 mode; 656 u8 type; 657 u8 pad[2]; 658 }; 659 660 struct prestera_msg_policer_resp { 661 struct prestera_msg_ret ret; 662 __le32 id; 663 }; 664 665 struct prestera_msg_event { 666 __le16 type; 667 __le16 id; 668 }; 669 670 struct prestera_msg_event_port { 671 struct prestera_msg_event id; 672 __le32 port_id; 673 struct prestera_msg_event_port_param param; 674 }; 675 676 union prestera_msg_event_fdb_param { 677 u8 mac[ETH_ALEN]; 678 }; 679 680 struct prestera_msg_event_fdb { 681 struct prestera_msg_event id; 682 __le32 vid; 683 union { 684 __le32 port_id; 685 __le16 lag_id; 686 } dest; 687 union prestera_msg_event_fdb_param param; 688 u8 dest_type; 689 }; 690 691 struct prestera_msg_flood_domain_create_req { 692 struct prestera_msg_cmd cmd; 693 }; 694 695 struct prestera_msg_flood_domain_create_resp { 696 struct prestera_msg_ret ret; 697 __le32 flood_domain_idx; 698 }; 699 700 struct prestera_msg_flood_domain_destroy_req { 701 struct prestera_msg_cmd cmd; 702 __le32 flood_domain_idx; 703 }; 704 705 struct prestera_msg_flood_domain_ports_set_req { 706 struct prestera_msg_cmd cmd; 707 __le32 flood_domain_idx; 708 __le32 ports_num; 709 }; 710 711 struct prestera_msg_flood_domain_ports_reset_req { 712 struct prestera_msg_cmd cmd; 713 __le32 flood_domain_idx; 714 }; 715 716 struct prestera_msg_flood_domain_port { 717 union { 718 struct { 719 __le32 port_num; 720 __le32 dev_num; 721 }; 722 __le16 lag_id; 723 }; 724 __le16 vid; 725 __le16 port_type; 726 }; 727 728 struct prestera_msg_mdb_create_req { 729 struct prestera_msg_cmd cmd; 730 __le32 flood_domain_idx; 731 __le16 vid; 732 u8 mac[ETH_ALEN]; 733 }; 734 735 struct prestera_msg_mdb_destroy_req { 736 struct prestera_msg_cmd cmd; 737 __le32 flood_domain_idx; 738 __le16 vid; 739 u8 mac[ETH_ALEN]; 740 }; 741 742 static void prestera_hw_build_tests(void) 743 { 744 /* check requests */ 745 BUILD_BUG_ON(sizeof(struct prestera_msg_common_req) != 4); 746 BUILD_BUG_ON(sizeof(struct prestera_msg_switch_attr_req) != 16); 747 BUILD_BUG_ON(sizeof(struct prestera_msg_port_attr_req) != 144); 748 BUILD_BUG_ON(sizeof(struct prestera_msg_port_info_req) != 8); 749 BUILD_BUG_ON(sizeof(struct prestera_msg_vlan_req) != 16); 750 BUILD_BUG_ON(sizeof(struct prestera_msg_fdb_req) != 28); 751 BUILD_BUG_ON(sizeof(struct prestera_msg_bridge_req) != 16); 752 BUILD_BUG_ON(sizeof(struct prestera_msg_span_req) != 16); 753 BUILD_BUG_ON(sizeof(struct prestera_msg_stp_req) != 16); 754 BUILD_BUG_ON(sizeof(struct prestera_msg_rxtx_req) != 8); 755 BUILD_BUG_ON(sizeof(struct prestera_msg_lag_req) != 16); 756 BUILD_BUG_ON(sizeof(struct prestera_msg_cpu_code_counter_req) != 8); 757 BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_create_req) != 84); 758 BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_destroy_req) != 8); 759 BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_rule_add_req) != 168); 760 BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_rule_del_req) != 12); 761 BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_bind_req) != 20); 762 BUILD_BUG_ON(sizeof(struct prestera_msg_acl_action) != 32); 763 BUILD_BUG_ON(sizeof(struct prestera_msg_counter_req) != 16); 764 BUILD_BUG_ON(sizeof(struct prestera_msg_counter_stats) != 16); 765 BUILD_BUG_ON(sizeof(struct prestera_msg_rif_req) != 36); 766 BUILD_BUG_ON(sizeof(struct prestera_msg_vr_req) != 8); 767 BUILD_BUG_ON(sizeof(struct prestera_msg_lpm_req) != 36); 768 BUILD_BUG_ON(sizeof(struct prestera_msg_policer_req) != 36); 769 BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_create_req) != 4); 770 BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_destroy_req) != 8); 771 BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_ports_set_req) != 12); 772 BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_ports_reset_req) != 8); 773 BUILD_BUG_ON(sizeof(struct prestera_msg_mdb_create_req) != 16); 774 BUILD_BUG_ON(sizeof(struct prestera_msg_mdb_destroy_req) != 16); 775 BUILD_BUG_ON(sizeof(struct prestera_msg_nh_req) != 124); 776 BUILD_BUG_ON(sizeof(struct prestera_msg_nh_chunk_req) != 8); 777 BUILD_BUG_ON(sizeof(struct prestera_msg_nh_grp_req) != 12); 778 779 /* structure that are part of req/resp fw messages */ 780 BUILD_BUG_ON(sizeof(struct prestera_msg_iface) != 16); 781 BUILD_BUG_ON(sizeof(struct prestera_msg_ip_addr) != 20); 782 BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_port) != 12); 783 BUILD_BUG_ON(sizeof(struct prestera_msg_nh) != 28); 784 785 /* check responses */ 786 BUILD_BUG_ON(sizeof(struct prestera_msg_common_resp) != 8); 787 BUILD_BUG_ON(sizeof(struct prestera_msg_switch_init_resp) != 24); 788 BUILD_BUG_ON(sizeof(struct prestera_msg_port_attr_resp) != 136); 789 BUILD_BUG_ON(sizeof(struct prestera_msg_port_stats_resp) != 248); 790 BUILD_BUG_ON(sizeof(struct prestera_msg_port_info_resp) != 20); 791 BUILD_BUG_ON(sizeof(struct prestera_msg_bridge_resp) != 12); 792 BUILD_BUG_ON(sizeof(struct prestera_msg_span_resp) != 12); 793 BUILD_BUG_ON(sizeof(struct prestera_msg_rxtx_resp) != 12); 794 BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_resp) != 16); 795 BUILD_BUG_ON(sizeof(struct prestera_msg_counter_resp) != 24); 796 BUILD_BUG_ON(sizeof(struct prestera_msg_rif_resp) != 12); 797 BUILD_BUG_ON(sizeof(struct prestera_msg_vr_resp) != 12); 798 BUILD_BUG_ON(sizeof(struct prestera_msg_policer_resp) != 12); 799 BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_create_resp) != 12); 800 BUILD_BUG_ON(sizeof(struct prestera_msg_nh_chunk_resp) != 1032); 801 BUILD_BUG_ON(sizeof(struct prestera_msg_nh_grp_resp) != 12); 802 803 /* check events */ 804 BUILD_BUG_ON(sizeof(struct prestera_msg_event_port) != 20); 805 BUILD_BUG_ON(sizeof(struct prestera_msg_event_fdb) != 20); 806 } 807 808 static u8 prestera_hw_mdix_to_eth(u8 mode); 809 static void prestera_hw_remote_fc_to_eth(u8 fc, bool *pause, bool *asym_pause); 810 811 static int __prestera_cmd_ret(struct prestera_switch *sw, 812 enum prestera_cmd_type_t type, 813 struct prestera_msg_cmd *cmd, size_t clen, 814 struct prestera_msg_ret *ret, size_t rlen, 815 int waitms) 816 { 817 struct prestera_device *dev = sw->dev; 818 int err; 819 820 cmd->type = __cpu_to_le32(type); 821 822 err = dev->send_req(dev, 0, cmd, clen, ret, rlen, waitms); 823 if (err) 824 return err; 825 826 if (ret->cmd.type != __cpu_to_le32(PRESTERA_CMD_TYPE_ACK)) 827 return -EBADE; 828 if (ret->status != __cpu_to_le32(PRESTERA_CMD_ACK_OK)) 829 return -EINVAL; 830 831 return 0; 832 } 833 834 static int prestera_cmd_ret(struct prestera_switch *sw, 835 enum prestera_cmd_type_t type, 836 struct prestera_msg_cmd *cmd, size_t clen, 837 struct prestera_msg_ret *ret, size_t rlen) 838 { 839 return __prestera_cmd_ret(sw, type, cmd, clen, ret, rlen, 0); 840 } 841 842 static int prestera_cmd_ret_wait(struct prestera_switch *sw, 843 enum prestera_cmd_type_t type, 844 struct prestera_msg_cmd *cmd, size_t clen, 845 struct prestera_msg_ret *ret, size_t rlen, 846 int waitms) 847 { 848 return __prestera_cmd_ret(sw, type, cmd, clen, ret, rlen, waitms); 849 } 850 851 static int prestera_cmd(struct prestera_switch *sw, 852 enum prestera_cmd_type_t type, 853 struct prestera_msg_cmd *cmd, size_t clen) 854 { 855 struct prestera_msg_common_resp resp; 856 857 return prestera_cmd_ret(sw, type, cmd, clen, &resp.ret, sizeof(resp)); 858 } 859 860 static int prestera_fw_parse_port_evt(void *msg, struct prestera_event *evt) 861 { 862 struct prestera_msg_event_port *hw_evt; 863 864 hw_evt = (struct prestera_msg_event_port *)msg; 865 866 evt->port_evt.port_id = __le32_to_cpu(hw_evt->port_id); 867 868 if (evt->id == PRESTERA_PORT_EVENT_MAC_STATE_CHANGED) { 869 evt->port_evt.data.mac.oper = hw_evt->param.mac.oper; 870 evt->port_evt.data.mac.mode = 871 __le32_to_cpu(hw_evt->param.mac.mode); 872 evt->port_evt.data.mac.speed = 873 __le32_to_cpu(hw_evt->param.mac.speed); 874 evt->port_evt.data.mac.duplex = hw_evt->param.mac.duplex; 875 evt->port_evt.data.mac.fc = hw_evt->param.mac.fc; 876 evt->port_evt.data.mac.fec = hw_evt->param.mac.fec; 877 } else { 878 return -EINVAL; 879 } 880 881 return 0; 882 } 883 884 static int prestera_fw_parse_fdb_evt(void *msg, struct prestera_event *evt) 885 { 886 struct prestera_msg_event_fdb *hw_evt = msg; 887 888 switch (hw_evt->dest_type) { 889 case PRESTERA_HW_FDB_ENTRY_TYPE_REG_PORT: 890 evt->fdb_evt.type = PRESTERA_FDB_ENTRY_TYPE_REG_PORT; 891 evt->fdb_evt.dest.port_id = __le32_to_cpu(hw_evt->dest.port_id); 892 break; 893 case PRESTERA_HW_FDB_ENTRY_TYPE_LAG: 894 evt->fdb_evt.type = PRESTERA_FDB_ENTRY_TYPE_LAG; 895 evt->fdb_evt.dest.lag_id = __le16_to_cpu(hw_evt->dest.lag_id); 896 break; 897 default: 898 return -EINVAL; 899 } 900 901 evt->fdb_evt.vid = __le32_to_cpu(hw_evt->vid); 902 903 ether_addr_copy(evt->fdb_evt.data.mac, hw_evt->param.mac); 904 905 return 0; 906 } 907 908 static struct prestera_fw_evt_parser { 909 int (*func)(void *msg, struct prestera_event *evt); 910 } fw_event_parsers[PRESTERA_EVENT_TYPE_MAX] = { 911 [PRESTERA_EVENT_TYPE_PORT] = { .func = prestera_fw_parse_port_evt }, 912 [PRESTERA_EVENT_TYPE_FDB] = { .func = prestera_fw_parse_fdb_evt }, 913 }; 914 915 static struct prestera_fw_event_handler * 916 __find_event_handler(const struct prestera_switch *sw, 917 enum prestera_event_type type) 918 { 919 struct prestera_fw_event_handler *eh; 920 921 list_for_each_entry_rcu(eh, &sw->event_handlers, list) { 922 if (eh->type == type) 923 return eh; 924 } 925 926 return NULL; 927 } 928 929 static int prestera_find_event_handler(const struct prestera_switch *sw, 930 enum prestera_event_type type, 931 struct prestera_fw_event_handler *eh) 932 { 933 struct prestera_fw_event_handler *tmp; 934 int err = 0; 935 936 rcu_read_lock(); 937 tmp = __find_event_handler(sw, type); 938 if (tmp) 939 *eh = *tmp; 940 else 941 err = -ENOENT; 942 rcu_read_unlock(); 943 944 return err; 945 } 946 947 static int prestera_evt_recv(struct prestera_device *dev, void *buf, size_t size) 948 { 949 struct prestera_switch *sw = dev->priv; 950 struct prestera_msg_event *msg = buf; 951 struct prestera_fw_event_handler eh; 952 struct prestera_event evt; 953 u16 msg_type; 954 int err; 955 956 msg_type = __le16_to_cpu(msg->type); 957 if (msg_type >= PRESTERA_EVENT_TYPE_MAX) 958 return -EINVAL; 959 if (!fw_event_parsers[msg_type].func) 960 return -ENOENT; 961 962 err = prestera_find_event_handler(sw, msg_type, &eh); 963 if (err) 964 return err; 965 966 evt.id = __le16_to_cpu(msg->id); 967 968 err = fw_event_parsers[msg_type].func(buf, &evt); 969 if (err) 970 return err; 971 972 eh.func(sw, &evt, eh.arg); 973 974 return 0; 975 } 976 977 static void prestera_pkt_recv(struct prestera_device *dev) 978 { 979 struct prestera_switch *sw = dev->priv; 980 struct prestera_fw_event_handler eh; 981 struct prestera_event ev; 982 int err; 983 984 ev.id = PRESTERA_RXTX_EVENT_RCV_PKT; 985 986 err = prestera_find_event_handler(sw, PRESTERA_EVENT_TYPE_RXTX, &eh); 987 if (err) 988 return; 989 990 eh.func(sw, &ev, eh.arg); 991 } 992 993 static u8 prestera_hw_mdix_to_eth(u8 mode) 994 { 995 switch (mode) { 996 case PRESTERA_PORT_TP_MDI: 997 return ETH_TP_MDI; 998 case PRESTERA_PORT_TP_MDIX: 999 return ETH_TP_MDI_X; 1000 case PRESTERA_PORT_TP_AUTO: 1001 return ETH_TP_MDI_AUTO; 1002 default: 1003 return ETH_TP_MDI_INVALID; 1004 } 1005 } 1006 1007 static u8 prestera_hw_mdix_from_eth(u8 mode) 1008 { 1009 switch (mode) { 1010 case ETH_TP_MDI: 1011 return PRESTERA_PORT_TP_MDI; 1012 case ETH_TP_MDI_X: 1013 return PRESTERA_PORT_TP_MDIX; 1014 case ETH_TP_MDI_AUTO: 1015 return PRESTERA_PORT_TP_AUTO; 1016 default: 1017 return PRESTERA_PORT_TP_NA; 1018 } 1019 } 1020 1021 int prestera_hw_port_info_get(const struct prestera_port *port, 1022 u32 *dev_id, u32 *hw_id, u16 *fp_id) 1023 { 1024 struct prestera_msg_port_info_req req = { 1025 .port = __cpu_to_le32(port->id), 1026 }; 1027 struct prestera_msg_port_info_resp resp; 1028 int err; 1029 1030 err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_INFO_GET, 1031 &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 1032 if (err) 1033 return err; 1034 1035 *dev_id = __le32_to_cpu(resp.dev_id); 1036 *hw_id = __le32_to_cpu(resp.hw_id); 1037 *fp_id = __le16_to_cpu(resp.fp_id); 1038 1039 return 0; 1040 } 1041 1042 int prestera_hw_switch_mac_set(struct prestera_switch *sw, const char *mac) 1043 { 1044 struct prestera_msg_switch_attr_req req = { 1045 .attr = __cpu_to_le32(PRESTERA_CMD_SWITCH_ATTR_MAC), 1046 }; 1047 1048 ether_addr_copy(req.param.mac, mac); 1049 1050 return prestera_cmd(sw, PRESTERA_CMD_TYPE_SWITCH_ATTR_SET, 1051 &req.cmd, sizeof(req)); 1052 } 1053 1054 int prestera_hw_switch_init(struct prestera_switch *sw) 1055 { 1056 struct prestera_msg_switch_init_resp resp; 1057 struct prestera_msg_common_req req; 1058 int err; 1059 1060 INIT_LIST_HEAD(&sw->event_handlers); 1061 1062 prestera_hw_build_tests(); 1063 1064 err = prestera_cmd_ret_wait(sw, PRESTERA_CMD_TYPE_SWITCH_INIT, 1065 &req.cmd, sizeof(req), 1066 &resp.ret, sizeof(resp), 1067 PRESTERA_SWITCH_INIT_TIMEOUT_MS); 1068 if (err) 1069 return err; 1070 1071 sw->dev->recv_msg = prestera_evt_recv; 1072 sw->dev->recv_pkt = prestera_pkt_recv; 1073 sw->port_count = __le32_to_cpu(resp.port_count); 1074 sw->mtu_min = PRESTERA_MIN_MTU; 1075 sw->mtu_max = __le32_to_cpu(resp.mtu_max); 1076 sw->id = resp.switch_id; 1077 sw->lag_member_max = resp.lag_member_max; 1078 sw->lag_max = resp.lag_max; 1079 sw->size_tbl_router_nexthop = 1080 __le32_to_cpu(resp.size_tbl_router_nexthop); 1081 1082 return 0; 1083 } 1084 1085 void prestera_hw_switch_fini(struct prestera_switch *sw) 1086 { 1087 WARN_ON(!list_empty(&sw->event_handlers)); 1088 } 1089 1090 int prestera_hw_switch_ageing_set(struct prestera_switch *sw, u32 ageing_ms) 1091 { 1092 struct prestera_msg_switch_attr_req req = { 1093 .attr = __cpu_to_le32(PRESTERA_CMD_SWITCH_ATTR_AGEING), 1094 .param = { 1095 .ageing_timeout_ms = __cpu_to_le32(ageing_ms), 1096 }, 1097 }; 1098 1099 return prestera_cmd(sw, PRESTERA_CMD_TYPE_SWITCH_ATTR_SET, 1100 &req.cmd, sizeof(req)); 1101 } 1102 1103 int prestera_hw_port_mac_mode_get(const struct prestera_port *port, 1104 u32 *mode, u32 *speed, u8 *duplex, u8 *fec) 1105 { 1106 struct prestera_msg_port_attr_resp resp; 1107 struct prestera_msg_port_attr_req req = { 1108 .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_MAC_MODE), 1109 .port = __cpu_to_le32(port->hw_id), 1110 .dev = __cpu_to_le32(port->dev_id) 1111 }; 1112 int err; 1113 1114 err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET, 1115 &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 1116 if (err) 1117 return err; 1118 1119 if (mode) 1120 *mode = __le32_to_cpu(resp.param.link_evt.mac.mode); 1121 1122 if (speed) 1123 *speed = __le32_to_cpu(resp.param.link_evt.mac.speed); 1124 1125 if (duplex) 1126 *duplex = resp.param.link_evt.mac.duplex; 1127 1128 if (fec) 1129 *fec = resp.param.link_evt.mac.fec; 1130 1131 return err; 1132 } 1133 1134 int prestera_hw_port_mac_mode_set(const struct prestera_port *port, 1135 bool admin, u32 mode, u8 inband, 1136 u32 speed, u8 duplex, u8 fec) 1137 { 1138 struct prestera_msg_port_attr_req req = { 1139 .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_MAC_MODE), 1140 .port = __cpu_to_le32(port->hw_id), 1141 .dev = __cpu_to_le32(port->dev_id), 1142 .param = { 1143 .link = { 1144 .mac = { 1145 .admin = admin, 1146 .reg_mode.mode = __cpu_to_le32(mode), 1147 .reg_mode.inband = inband, 1148 .reg_mode.speed = __cpu_to_le32(speed), 1149 .reg_mode.duplex = duplex, 1150 .reg_mode.fec = fec 1151 } 1152 } 1153 } 1154 }; 1155 1156 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, 1157 &req.cmd, sizeof(req)); 1158 } 1159 1160 int prestera_hw_port_phy_mode_get(const struct prestera_port *port, 1161 u8 *mdix, u64 *lmode_bmap, 1162 bool *fc_pause, bool *fc_asym) 1163 { 1164 struct prestera_msg_port_attr_resp resp; 1165 struct prestera_msg_port_attr_req req = { 1166 .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_PHY_MODE), 1167 .port = __cpu_to_le32(port->hw_id), 1168 .dev = __cpu_to_le32(port->dev_id) 1169 }; 1170 int err; 1171 1172 err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET, 1173 &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 1174 if (err) 1175 return err; 1176 1177 if (mdix) 1178 *mdix = prestera_hw_mdix_to_eth(resp.param.link_evt.phy.mdix); 1179 1180 if (lmode_bmap) 1181 *lmode_bmap = __le64_to_cpu(resp.param.link_evt.phy.lmode_bmap); 1182 1183 if (fc_pause && fc_asym) 1184 prestera_hw_remote_fc_to_eth(resp.param.link_evt.phy.fc, 1185 fc_pause, fc_asym); 1186 1187 return err; 1188 } 1189 1190 int prestera_hw_port_phy_mode_set(const struct prestera_port *port, 1191 bool admin, bool adv, u32 mode, u64 modes, 1192 u8 mdix) 1193 { 1194 struct prestera_msg_port_attr_req req = { 1195 .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_PHY_MODE), 1196 .port = __cpu_to_le32(port->hw_id), 1197 .dev = __cpu_to_le32(port->dev_id), 1198 .param = { 1199 .link = { 1200 .phy = { 1201 .admin = admin, 1202 .adv_enable = adv ? 1 : 0, 1203 .mode = __cpu_to_le32(mode), 1204 .modes = __cpu_to_le64(modes), 1205 } 1206 } 1207 } 1208 }; 1209 1210 req.param.link.phy.mdix = prestera_hw_mdix_from_eth(mdix); 1211 1212 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, 1213 &req.cmd, sizeof(req)); 1214 } 1215 1216 int prestera_hw_port_mtu_set(const struct prestera_port *port, u32 mtu) 1217 { 1218 struct prestera_msg_port_attr_req req = { 1219 .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_MTU), 1220 .port = __cpu_to_le32(port->hw_id), 1221 .dev = __cpu_to_le32(port->dev_id), 1222 .param = { 1223 .mtu = __cpu_to_le32(mtu), 1224 } 1225 }; 1226 1227 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, 1228 &req.cmd, sizeof(req)); 1229 } 1230 1231 int prestera_hw_port_mac_set(const struct prestera_port *port, const char *mac) 1232 { 1233 struct prestera_msg_port_attr_req req = { 1234 .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_MAC), 1235 .port = __cpu_to_le32(port->hw_id), 1236 .dev = __cpu_to_le32(port->dev_id), 1237 }; 1238 1239 ether_addr_copy(req.param.mac, mac); 1240 1241 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, 1242 &req.cmd, sizeof(req)); 1243 } 1244 1245 int prestera_hw_port_accept_frm_type(struct prestera_port *port, 1246 enum prestera_accept_frm_type type) 1247 { 1248 struct prestera_msg_port_attr_req req = { 1249 .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_ACCEPT_FRAME_TYPE), 1250 .port = __cpu_to_le32(port->hw_id), 1251 .dev = __cpu_to_le32(port->dev_id), 1252 .param = { 1253 .accept_frm_type = type, 1254 } 1255 }; 1256 1257 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, 1258 &req.cmd, sizeof(req)); 1259 } 1260 1261 int prestera_hw_port_cap_get(const struct prestera_port *port, 1262 struct prestera_port_caps *caps) 1263 { 1264 struct prestera_msg_port_attr_req req = { 1265 .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_CAPABILITY), 1266 .port = __cpu_to_le32(port->hw_id), 1267 .dev = __cpu_to_le32(port->dev_id), 1268 }; 1269 struct prestera_msg_port_attr_resp resp; 1270 int err; 1271 1272 err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET, 1273 &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 1274 if (err) 1275 return err; 1276 1277 caps->supp_link_modes = __le64_to_cpu(resp.param.cap.link_mode); 1278 caps->transceiver = resp.param.cap.transceiver; 1279 caps->supp_fec = resp.param.cap.fec; 1280 caps->type = resp.param.cap.type; 1281 1282 return err; 1283 } 1284 1285 static void prestera_hw_remote_fc_to_eth(u8 fc, bool *pause, bool *asym_pause) 1286 { 1287 switch (fc) { 1288 case PRESTERA_FC_SYMMETRIC: 1289 *pause = true; 1290 *asym_pause = false; 1291 break; 1292 case PRESTERA_FC_ASYMMETRIC: 1293 *pause = false; 1294 *asym_pause = true; 1295 break; 1296 case PRESTERA_FC_SYMM_ASYMM: 1297 *pause = true; 1298 *asym_pause = true; 1299 break; 1300 default: 1301 *pause = false; 1302 *asym_pause = false; 1303 } 1304 } 1305 1306 int prestera_hw_vtcam_create(struct prestera_switch *sw, 1307 u8 lookup, const u32 *keymask, u32 *vtcam_id, 1308 enum prestera_hw_vtcam_direction_t dir) 1309 { 1310 int err; 1311 struct prestera_msg_vtcam_resp resp; 1312 struct prestera_msg_vtcam_create_req req = { 1313 .lookup = lookup, 1314 .direction = dir, 1315 }; 1316 1317 if (keymask) 1318 memcpy(req.keymask, keymask, sizeof(req.keymask)); 1319 else 1320 memset(req.keymask, 0, sizeof(req.keymask)); 1321 1322 err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_VTCAM_CREATE, 1323 &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 1324 if (err) 1325 return err; 1326 1327 *vtcam_id = __le32_to_cpu(resp.vtcam_id); 1328 return 0; 1329 } 1330 1331 int prestera_hw_vtcam_destroy(struct prestera_switch *sw, u32 vtcam_id) 1332 { 1333 struct prestera_msg_vtcam_destroy_req req = { 1334 .vtcam_id = __cpu_to_le32(vtcam_id), 1335 }; 1336 1337 return prestera_cmd(sw, PRESTERA_CMD_TYPE_VTCAM_DESTROY, 1338 &req.cmd, sizeof(req)); 1339 } 1340 1341 static int 1342 prestera_acl_rule_add_put_action(struct prestera_msg_acl_action *action, 1343 struct prestera_acl_hw_action_info *info) 1344 { 1345 action->id = __cpu_to_le32(info->id); 1346 1347 switch (info->id) { 1348 case PRESTERA_ACL_RULE_ACTION_ACCEPT: 1349 case PRESTERA_ACL_RULE_ACTION_DROP: 1350 case PRESTERA_ACL_RULE_ACTION_TRAP: 1351 /* just rule action id, no specific data */ 1352 break; 1353 case PRESTERA_ACL_RULE_ACTION_JUMP: 1354 action->jump.index = __cpu_to_le32(info->jump.index); 1355 break; 1356 case PRESTERA_ACL_RULE_ACTION_POLICE: 1357 action->police.id = __cpu_to_le32(info->police.id); 1358 break; 1359 case PRESTERA_ACL_RULE_ACTION_COUNT: 1360 action->count.id = __cpu_to_le32(info->count.id); 1361 break; 1362 default: 1363 return -EINVAL; 1364 } 1365 1366 return 0; 1367 } 1368 1369 int prestera_hw_vtcam_rule_add(struct prestera_switch *sw, 1370 u32 vtcam_id, u32 prio, void *key, void *keymask, 1371 struct prestera_acl_hw_action_info *act, 1372 u8 n_act, u32 *rule_id) 1373 { 1374 struct prestera_msg_acl_action *actions_msg; 1375 struct prestera_msg_vtcam_rule_add_req *req; 1376 struct prestera_msg_vtcam_resp resp; 1377 void *buff; 1378 u32 size; 1379 int err; 1380 u8 i; 1381 1382 size = sizeof(*req) + sizeof(*actions_msg) * n_act; 1383 1384 buff = kzalloc(size, GFP_KERNEL); 1385 if (!buff) 1386 return -ENOMEM; 1387 1388 req = buff; 1389 req->n_act = __cpu_to_le32(n_act); 1390 actions_msg = buff + sizeof(*req); 1391 1392 /* put acl matches into the message */ 1393 memcpy(req->key, key, sizeof(req->key)); 1394 memcpy(req->keymask, keymask, sizeof(req->keymask)); 1395 1396 /* put acl actions into the message */ 1397 for (i = 0; i < n_act; i++) { 1398 err = prestera_acl_rule_add_put_action(&actions_msg[i], 1399 &act[i]); 1400 if (err) 1401 goto free_buff; 1402 } 1403 1404 req->vtcam_id = __cpu_to_le32(vtcam_id); 1405 req->prio = __cpu_to_le32(prio); 1406 1407 err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_VTCAM_RULE_ADD, 1408 &req->cmd, size, &resp.ret, sizeof(resp)); 1409 if (err) 1410 goto free_buff; 1411 1412 *rule_id = __le32_to_cpu(resp.rule_id); 1413 free_buff: 1414 kfree(buff); 1415 return err; 1416 } 1417 1418 int prestera_hw_vtcam_rule_del(struct prestera_switch *sw, 1419 u32 vtcam_id, u32 rule_id) 1420 { 1421 struct prestera_msg_vtcam_rule_del_req req = { 1422 .vtcam_id = __cpu_to_le32(vtcam_id), 1423 .id = __cpu_to_le32(rule_id) 1424 }; 1425 1426 return prestera_cmd(sw, PRESTERA_CMD_TYPE_VTCAM_RULE_DELETE, 1427 &req.cmd, sizeof(req)); 1428 } 1429 1430 int prestera_hw_vtcam_iface_bind(struct prestera_switch *sw, 1431 struct prestera_acl_iface *iface, 1432 u32 vtcam_id, u16 pcl_id) 1433 { 1434 struct prestera_msg_vtcam_bind_req req = { 1435 .vtcam_id = __cpu_to_le32(vtcam_id), 1436 .type = __cpu_to_le16(iface->type), 1437 .pcl_id = __cpu_to_le16(pcl_id) 1438 }; 1439 1440 if (iface->type == PRESTERA_ACL_IFACE_TYPE_PORT) { 1441 req.port.dev_id = __cpu_to_le32(iface->port->dev_id); 1442 req.port.hw_id = __cpu_to_le32(iface->port->hw_id); 1443 } else { 1444 req.index = __cpu_to_le32(iface->index); 1445 } 1446 1447 return prestera_cmd(sw, PRESTERA_CMD_TYPE_VTCAM_IFACE_BIND, 1448 &req.cmd, sizeof(req)); 1449 } 1450 1451 int prestera_hw_vtcam_iface_unbind(struct prestera_switch *sw, 1452 struct prestera_acl_iface *iface, 1453 u32 vtcam_id) 1454 { 1455 struct prestera_msg_vtcam_bind_req req = { 1456 .vtcam_id = __cpu_to_le32(vtcam_id), 1457 .type = __cpu_to_le16(iface->type) 1458 }; 1459 1460 if (iface->type == PRESTERA_ACL_IFACE_TYPE_PORT) { 1461 req.port.dev_id = __cpu_to_le32(iface->port->dev_id); 1462 req.port.hw_id = __cpu_to_le32(iface->port->hw_id); 1463 } else { 1464 req.index = __cpu_to_le32(iface->index); 1465 } 1466 1467 return prestera_cmd(sw, PRESTERA_CMD_TYPE_VTCAM_IFACE_UNBIND, 1468 &req.cmd, sizeof(req)); 1469 } 1470 1471 int prestera_hw_span_get(const struct prestera_port *port, u8 *span_id) 1472 { 1473 struct prestera_msg_span_resp resp; 1474 struct prestera_msg_span_req req = { 1475 .port = __cpu_to_le32(port->hw_id), 1476 .dev = __cpu_to_le32(port->dev_id), 1477 }; 1478 int err; 1479 1480 err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_SPAN_GET, 1481 &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 1482 if (err) 1483 return err; 1484 1485 *span_id = resp.id; 1486 1487 return 0; 1488 } 1489 1490 int prestera_hw_span_bind(const struct prestera_port *port, u8 span_id, 1491 bool ingress) 1492 { 1493 struct prestera_msg_span_req req = { 1494 .port = __cpu_to_le32(port->hw_id), 1495 .dev = __cpu_to_le32(port->dev_id), 1496 .id = span_id, 1497 }; 1498 enum prestera_cmd_type_t cmd_type; 1499 1500 if (ingress) 1501 cmd_type = PRESTERA_CMD_TYPE_SPAN_INGRESS_BIND; 1502 else 1503 cmd_type = PRESTERA_CMD_TYPE_SPAN_EGRESS_BIND; 1504 1505 return prestera_cmd(port->sw, cmd_type, &req.cmd, sizeof(req)); 1506 1507 } 1508 1509 int prestera_hw_span_unbind(const struct prestera_port *port, bool ingress) 1510 { 1511 struct prestera_msg_span_req req = { 1512 .port = __cpu_to_le32(port->hw_id), 1513 .dev = __cpu_to_le32(port->dev_id), 1514 }; 1515 enum prestera_cmd_type_t cmd_type; 1516 1517 if (ingress) 1518 cmd_type = PRESTERA_CMD_TYPE_SPAN_INGRESS_UNBIND; 1519 else 1520 cmd_type = PRESTERA_CMD_TYPE_SPAN_EGRESS_UNBIND; 1521 1522 return prestera_cmd(port->sw, cmd_type, &req.cmd, sizeof(req)); 1523 } 1524 1525 int prestera_hw_span_release(struct prestera_switch *sw, u8 span_id) 1526 { 1527 struct prestera_msg_span_req req = { 1528 .id = span_id 1529 }; 1530 1531 return prestera_cmd(sw, PRESTERA_CMD_TYPE_SPAN_RELEASE, 1532 &req.cmd, sizeof(req)); 1533 } 1534 1535 int prestera_hw_port_type_get(const struct prestera_port *port, u8 *type) 1536 { 1537 struct prestera_msg_port_attr_req req = { 1538 .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_TYPE), 1539 .port = __cpu_to_le32(port->hw_id), 1540 .dev = __cpu_to_le32(port->dev_id), 1541 }; 1542 struct prestera_msg_port_attr_resp resp; 1543 int err; 1544 1545 err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET, 1546 &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 1547 if (err) 1548 return err; 1549 1550 *type = resp.param.type; 1551 1552 return 0; 1553 } 1554 1555 int prestera_hw_port_speed_get(const struct prestera_port *port, u32 *speed) 1556 { 1557 struct prestera_msg_port_attr_req req = { 1558 .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_SPEED), 1559 .port = __cpu_to_le32(port->hw_id), 1560 .dev = __cpu_to_le32(port->dev_id), 1561 }; 1562 struct prestera_msg_port_attr_resp resp; 1563 int err; 1564 1565 err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET, 1566 &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 1567 if (err) 1568 return err; 1569 1570 *speed = __le32_to_cpu(resp.param.speed); 1571 1572 return 0; 1573 } 1574 1575 int prestera_hw_port_autoneg_restart(struct prestera_port *port) 1576 { 1577 struct prestera_msg_port_attr_req req = { 1578 .attr = 1579 __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_PHY_AUTONEG_RESTART), 1580 .port = __cpu_to_le32(port->hw_id), 1581 .dev = __cpu_to_le32(port->dev_id), 1582 }; 1583 1584 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, 1585 &req.cmd, sizeof(req)); 1586 } 1587 1588 int prestera_hw_port_stats_get(const struct prestera_port *port, 1589 struct prestera_port_stats *st) 1590 { 1591 struct prestera_msg_port_attr_req req = { 1592 .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_STATS), 1593 .port = __cpu_to_le32(port->hw_id), 1594 .dev = __cpu_to_le32(port->dev_id), 1595 }; 1596 struct prestera_msg_port_stats_resp resp; 1597 __le64 *hw = resp.stats; 1598 int err; 1599 1600 err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET, 1601 &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 1602 if (err) 1603 return err; 1604 1605 st->good_octets_received = 1606 __le64_to_cpu(hw[PRESTERA_PORT_GOOD_OCTETS_RCV_CNT]); 1607 st->bad_octets_received = 1608 __le64_to_cpu(hw[PRESTERA_PORT_BAD_OCTETS_RCV_CNT]); 1609 st->mac_trans_error = 1610 __le64_to_cpu(hw[PRESTERA_PORT_MAC_TRANSMIT_ERR_CNT]); 1611 st->broadcast_frames_received = 1612 __le64_to_cpu(hw[PRESTERA_PORT_BRDC_PKTS_RCV_CNT]); 1613 st->multicast_frames_received = 1614 __le64_to_cpu(hw[PRESTERA_PORT_MC_PKTS_RCV_CNT]); 1615 st->frames_64_octets = __le64_to_cpu(hw[PRESTERA_PORT_PKTS_64L_CNT]); 1616 st->frames_65_to_127_octets = 1617 __le64_to_cpu(hw[PRESTERA_PORT_PKTS_65TO127L_CNT]); 1618 st->frames_128_to_255_octets = 1619 __le64_to_cpu(hw[PRESTERA_PORT_PKTS_128TO255L_CNT]); 1620 st->frames_256_to_511_octets = 1621 __le64_to_cpu(hw[PRESTERA_PORT_PKTS_256TO511L_CNT]); 1622 st->frames_512_to_1023_octets = 1623 __le64_to_cpu(hw[PRESTERA_PORT_PKTS_512TO1023L_CNT]); 1624 st->frames_1024_to_max_octets = 1625 __le64_to_cpu(hw[PRESTERA_PORT_PKTS_1024TOMAXL_CNT]); 1626 st->excessive_collision = 1627 __le64_to_cpu(hw[PRESTERA_PORT_EXCESSIVE_COLLISIONS_CNT]); 1628 st->multicast_frames_sent = 1629 __le64_to_cpu(hw[PRESTERA_PORT_MC_PKTS_SENT_CNT]); 1630 st->broadcast_frames_sent = 1631 __le64_to_cpu(hw[PRESTERA_PORT_BRDC_PKTS_SENT_CNT]); 1632 st->fc_sent = __le64_to_cpu(hw[PRESTERA_PORT_FC_SENT_CNT]); 1633 st->fc_received = __le64_to_cpu(hw[PRESTERA_PORT_GOOD_FC_RCV_CNT]); 1634 st->buffer_overrun = __le64_to_cpu(hw[PRESTERA_PORT_DROP_EVENTS_CNT]); 1635 st->undersize = __le64_to_cpu(hw[PRESTERA_PORT_UNDERSIZE_PKTS_CNT]); 1636 st->fragments = __le64_to_cpu(hw[PRESTERA_PORT_FRAGMENTS_PKTS_CNT]); 1637 st->oversize = __le64_to_cpu(hw[PRESTERA_PORT_OVERSIZE_PKTS_CNT]); 1638 st->jabber = __le64_to_cpu(hw[PRESTERA_PORT_JABBER_PKTS_CNT]); 1639 st->rx_error_frame_received = 1640 __le64_to_cpu(hw[PRESTERA_PORT_MAC_RCV_ERROR_CNT]); 1641 st->bad_crc = __le64_to_cpu(hw[PRESTERA_PORT_BAD_CRC_CNT]); 1642 st->collisions = __le64_to_cpu(hw[PRESTERA_PORT_COLLISIONS_CNT]); 1643 st->late_collision = 1644 __le64_to_cpu(hw[PRESTERA_PORT_LATE_COLLISIONS_CNT]); 1645 st->unicast_frames_received = 1646 __le64_to_cpu(hw[PRESTERA_PORT_GOOD_UC_PKTS_RCV_CNT]); 1647 st->unicast_frames_sent = 1648 __le64_to_cpu(hw[PRESTERA_PORT_GOOD_UC_PKTS_SENT_CNT]); 1649 st->sent_multiple = 1650 __le64_to_cpu(hw[PRESTERA_PORT_MULTIPLE_PKTS_SENT_CNT]); 1651 st->sent_deferred = 1652 __le64_to_cpu(hw[PRESTERA_PORT_DEFERRED_PKTS_SENT_CNT]); 1653 st->good_octets_sent = 1654 __le64_to_cpu(hw[PRESTERA_PORT_GOOD_OCTETS_SENT_CNT]); 1655 1656 return 0; 1657 } 1658 1659 int prestera_hw_port_learning_set(struct prestera_port *port, bool enable) 1660 { 1661 struct prestera_msg_port_attr_req req = { 1662 .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_LEARNING), 1663 .port = __cpu_to_le32(port->hw_id), 1664 .dev = __cpu_to_le32(port->dev_id), 1665 .param = { 1666 .learning = enable, 1667 } 1668 }; 1669 1670 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, 1671 &req.cmd, sizeof(req)); 1672 } 1673 1674 int prestera_hw_port_uc_flood_set(const struct prestera_port *port, bool flood) 1675 { 1676 struct prestera_msg_port_attr_req req = { 1677 .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_FLOOD), 1678 .port = __cpu_to_le32(port->hw_id), 1679 .dev = __cpu_to_le32(port->dev_id), 1680 .param = { 1681 .flood_ext = { 1682 .type = PRESTERA_PORT_FLOOD_TYPE_UC, 1683 .enable = flood, 1684 } 1685 } 1686 }; 1687 1688 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, 1689 &req.cmd, sizeof(req)); 1690 } 1691 1692 int prestera_hw_port_mc_flood_set(const struct prestera_port *port, bool flood) 1693 { 1694 struct prestera_msg_port_attr_req req = { 1695 .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_FLOOD), 1696 .port = __cpu_to_le32(port->hw_id), 1697 .dev = __cpu_to_le32(port->dev_id), 1698 .param = { 1699 .flood_ext = { 1700 .type = PRESTERA_PORT_FLOOD_TYPE_MC, 1701 .enable = flood, 1702 } 1703 } 1704 }; 1705 1706 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, 1707 &req.cmd, sizeof(req)); 1708 } 1709 1710 int prestera_hw_port_br_locked_set(const struct prestera_port *port, 1711 bool br_locked) 1712 { 1713 struct prestera_msg_port_attr_req req = { 1714 .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_LOCKED), 1715 .port = __cpu_to_le32(port->hw_id), 1716 .dev = __cpu_to_le32(port->dev_id), 1717 .param = { 1718 .br_locked = br_locked, 1719 } 1720 }; 1721 1722 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, 1723 &req.cmd, sizeof(req)); 1724 } 1725 1726 int prestera_hw_vlan_create(struct prestera_switch *sw, u16 vid) 1727 { 1728 struct prestera_msg_vlan_req req = { 1729 .vid = __cpu_to_le16(vid), 1730 }; 1731 1732 return prestera_cmd(sw, PRESTERA_CMD_TYPE_VLAN_CREATE, 1733 &req.cmd, sizeof(req)); 1734 } 1735 1736 int prestera_hw_vlan_delete(struct prestera_switch *sw, u16 vid) 1737 { 1738 struct prestera_msg_vlan_req req = { 1739 .vid = __cpu_to_le16(vid), 1740 }; 1741 1742 return prestera_cmd(sw, PRESTERA_CMD_TYPE_VLAN_DELETE, 1743 &req.cmd, sizeof(req)); 1744 } 1745 1746 int prestera_hw_vlan_port_set(struct prestera_port *port, u16 vid, 1747 bool is_member, bool untagged) 1748 { 1749 struct prestera_msg_vlan_req req = { 1750 .port = __cpu_to_le32(port->hw_id), 1751 .dev = __cpu_to_le32(port->dev_id), 1752 .vid = __cpu_to_le16(vid), 1753 .is_member = is_member, 1754 .is_tagged = !untagged, 1755 }; 1756 1757 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_VLAN_PORT_SET, 1758 &req.cmd, sizeof(req)); 1759 } 1760 1761 int prestera_hw_vlan_port_vid_set(struct prestera_port *port, u16 vid) 1762 { 1763 struct prestera_msg_vlan_req req = { 1764 .port = __cpu_to_le32(port->hw_id), 1765 .dev = __cpu_to_le32(port->dev_id), 1766 .vid = __cpu_to_le16(vid), 1767 }; 1768 1769 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_VLAN_PVID_SET, 1770 &req.cmd, sizeof(req)); 1771 } 1772 1773 int prestera_hw_vlan_port_stp_set(struct prestera_port *port, u16 vid, u8 state) 1774 { 1775 struct prestera_msg_stp_req req = { 1776 .port = __cpu_to_le32(port->hw_id), 1777 .dev = __cpu_to_le32(port->dev_id), 1778 .vid = __cpu_to_le16(vid), 1779 .state = state, 1780 }; 1781 1782 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_STP_PORT_SET, 1783 &req.cmd, sizeof(req)); 1784 } 1785 1786 int prestera_hw_fdb_add(struct prestera_port *port, const unsigned char *mac, 1787 u16 vid, bool dynamic) 1788 { 1789 struct prestera_msg_fdb_req req = { 1790 .dest = { 1791 .dev = __cpu_to_le32(port->dev_id), 1792 .port = __cpu_to_le32(port->hw_id), 1793 }, 1794 .vid = __cpu_to_le16(vid), 1795 .dynamic = dynamic, 1796 }; 1797 1798 ether_addr_copy(req.mac, mac); 1799 1800 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_FDB_ADD, 1801 &req.cmd, sizeof(req)); 1802 } 1803 1804 int prestera_hw_fdb_del(struct prestera_port *port, const unsigned char *mac, 1805 u16 vid) 1806 { 1807 struct prestera_msg_fdb_req req = { 1808 .dest = { 1809 .dev = __cpu_to_le32(port->dev_id), 1810 .port = __cpu_to_le32(port->hw_id), 1811 }, 1812 .vid = __cpu_to_le16(vid), 1813 }; 1814 1815 ether_addr_copy(req.mac, mac); 1816 1817 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_FDB_DELETE, 1818 &req.cmd, sizeof(req)); 1819 } 1820 1821 int prestera_hw_lag_fdb_add(struct prestera_switch *sw, u16 lag_id, 1822 const unsigned char *mac, u16 vid, bool dynamic) 1823 { 1824 struct prestera_msg_fdb_req req = { 1825 .dest_type = PRESTERA_HW_FDB_ENTRY_TYPE_LAG, 1826 .dest = { 1827 .lag_id = __cpu_to_le16(lag_id), 1828 }, 1829 .vid = __cpu_to_le16(vid), 1830 .dynamic = dynamic, 1831 }; 1832 1833 ether_addr_copy(req.mac, mac); 1834 1835 return prestera_cmd(sw, PRESTERA_CMD_TYPE_FDB_ADD, 1836 &req.cmd, sizeof(req)); 1837 } 1838 1839 int prestera_hw_lag_fdb_del(struct prestera_switch *sw, u16 lag_id, 1840 const unsigned char *mac, u16 vid) 1841 { 1842 struct prestera_msg_fdb_req req = { 1843 .dest_type = PRESTERA_HW_FDB_ENTRY_TYPE_LAG, 1844 .dest = { 1845 .lag_id = __cpu_to_le16(lag_id), 1846 }, 1847 .vid = __cpu_to_le16(vid), 1848 }; 1849 1850 ether_addr_copy(req.mac, mac); 1851 1852 return prestera_cmd(sw, PRESTERA_CMD_TYPE_FDB_DELETE, 1853 &req.cmd, sizeof(req)); 1854 } 1855 1856 int prestera_hw_fdb_flush_port(struct prestera_port *port, u32 mode) 1857 { 1858 struct prestera_msg_fdb_req req = { 1859 .dest = { 1860 .dev = __cpu_to_le32(port->dev_id), 1861 .port = __cpu_to_le32(port->hw_id), 1862 }, 1863 .flush_mode = __cpu_to_le32(mode), 1864 }; 1865 1866 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_FDB_FLUSH_PORT, 1867 &req.cmd, sizeof(req)); 1868 } 1869 1870 int prestera_hw_fdb_flush_vlan(struct prestera_switch *sw, u16 vid, u32 mode) 1871 { 1872 struct prestera_msg_fdb_req req = { 1873 .vid = __cpu_to_le16(vid), 1874 .flush_mode = __cpu_to_le32(mode), 1875 }; 1876 1877 return prestera_cmd(sw, PRESTERA_CMD_TYPE_FDB_FLUSH_VLAN, 1878 &req.cmd, sizeof(req)); 1879 } 1880 1881 int prestera_hw_fdb_flush_port_vlan(struct prestera_port *port, u16 vid, 1882 u32 mode) 1883 { 1884 struct prestera_msg_fdb_req req = { 1885 .dest = { 1886 .dev = __cpu_to_le32(port->dev_id), 1887 .port = __cpu_to_le32(port->hw_id), 1888 }, 1889 .vid = __cpu_to_le16(vid), 1890 .flush_mode = __cpu_to_le32(mode), 1891 }; 1892 1893 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_FDB_FLUSH_PORT_VLAN, 1894 &req.cmd, sizeof(req)); 1895 } 1896 1897 int prestera_hw_fdb_flush_lag(struct prestera_switch *sw, u16 lag_id, 1898 u32 mode) 1899 { 1900 struct prestera_msg_fdb_req req = { 1901 .dest_type = PRESTERA_HW_FDB_ENTRY_TYPE_LAG, 1902 .dest = { 1903 .lag_id = __cpu_to_le16(lag_id), 1904 }, 1905 .flush_mode = __cpu_to_le32(mode), 1906 }; 1907 1908 return prestera_cmd(sw, PRESTERA_CMD_TYPE_FDB_FLUSH_PORT, 1909 &req.cmd, sizeof(req)); 1910 } 1911 1912 int prestera_hw_fdb_flush_lag_vlan(struct prestera_switch *sw, 1913 u16 lag_id, u16 vid, u32 mode) 1914 { 1915 struct prestera_msg_fdb_req req = { 1916 .dest_type = PRESTERA_HW_FDB_ENTRY_TYPE_LAG, 1917 .dest = { 1918 .lag_id = __cpu_to_le16(lag_id), 1919 }, 1920 .vid = __cpu_to_le16(vid), 1921 .flush_mode = __cpu_to_le32(mode), 1922 }; 1923 1924 return prestera_cmd(sw, PRESTERA_CMD_TYPE_FDB_FLUSH_PORT_VLAN, 1925 &req.cmd, sizeof(req)); 1926 } 1927 1928 int prestera_hw_bridge_create(struct prestera_switch *sw, u16 *bridge_id) 1929 { 1930 struct prestera_msg_bridge_resp resp; 1931 struct prestera_msg_bridge_req req; 1932 int err; 1933 1934 err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_BRIDGE_CREATE, 1935 &req.cmd, sizeof(req), 1936 &resp.ret, sizeof(resp)); 1937 if (err) 1938 return err; 1939 1940 *bridge_id = __le16_to_cpu(resp.bridge); 1941 1942 return 0; 1943 } 1944 1945 int prestera_hw_bridge_delete(struct prestera_switch *sw, u16 bridge_id) 1946 { 1947 struct prestera_msg_bridge_req req = { 1948 .bridge = __cpu_to_le16(bridge_id), 1949 }; 1950 1951 return prestera_cmd(sw, PRESTERA_CMD_TYPE_BRIDGE_DELETE, 1952 &req.cmd, sizeof(req)); 1953 } 1954 1955 int prestera_hw_bridge_port_add(struct prestera_port *port, u16 bridge_id) 1956 { 1957 struct prestera_msg_bridge_req req = { 1958 .bridge = __cpu_to_le16(bridge_id), 1959 .port = __cpu_to_le32(port->hw_id), 1960 .dev = __cpu_to_le32(port->dev_id), 1961 }; 1962 1963 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_BRIDGE_PORT_ADD, 1964 &req.cmd, sizeof(req)); 1965 } 1966 1967 int prestera_hw_bridge_port_delete(struct prestera_port *port, u16 bridge_id) 1968 { 1969 struct prestera_msg_bridge_req req = { 1970 .bridge = __cpu_to_le16(bridge_id), 1971 .port = __cpu_to_le32(port->hw_id), 1972 .dev = __cpu_to_le32(port->dev_id), 1973 }; 1974 1975 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_BRIDGE_PORT_DELETE, 1976 &req.cmd, sizeof(req)); 1977 } 1978 1979 static int prestera_iface_to_msg(struct prestera_iface *iface, 1980 struct prestera_msg_iface *msg_if) 1981 { 1982 switch (iface->type) { 1983 case PRESTERA_IF_PORT_E: 1984 case PRESTERA_IF_VID_E: 1985 msg_if->port = __cpu_to_le32(iface->dev_port.port_num); 1986 msg_if->dev = __cpu_to_le32(iface->dev_port.hw_dev_num); 1987 break; 1988 case PRESTERA_IF_LAG_E: 1989 msg_if->lag_id = __cpu_to_le16(iface->lag_id); 1990 break; 1991 default: 1992 return -EOPNOTSUPP; 1993 } 1994 1995 msg_if->vr_id = __cpu_to_le16(iface->vr_id); 1996 msg_if->vid = __cpu_to_le16(iface->vlan_id); 1997 msg_if->type = iface->type; 1998 return 0; 1999 } 2000 2001 int prestera_hw_rif_create(struct prestera_switch *sw, 2002 struct prestera_iface *iif, u8 *mac, u16 *rif_id) 2003 { 2004 struct prestera_msg_rif_resp resp; 2005 struct prestera_msg_rif_req req; 2006 int err; 2007 2008 memcpy(req.mac, mac, ETH_ALEN); 2009 2010 err = prestera_iface_to_msg(iif, &req.iif); 2011 if (err) 2012 return err; 2013 2014 err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_ROUTER_RIF_CREATE, 2015 &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 2016 if (err) 2017 return err; 2018 2019 *rif_id = __le16_to_cpu(resp.rif_id); 2020 return err; 2021 } 2022 2023 int prestera_hw_rif_delete(struct prestera_switch *sw, u16 rif_id, 2024 struct prestera_iface *iif) 2025 { 2026 struct prestera_msg_rif_req req = { 2027 .rif_id = __cpu_to_le16(rif_id), 2028 }; 2029 int err; 2030 2031 err = prestera_iface_to_msg(iif, &req.iif); 2032 if (err) 2033 return err; 2034 2035 return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_RIF_DELETE, &req.cmd, 2036 sizeof(req)); 2037 } 2038 2039 int prestera_hw_vr_create(struct prestera_switch *sw, u16 *vr_id) 2040 { 2041 struct prestera_msg_vr_resp resp; 2042 struct prestera_msg_vr_req req; 2043 int err; 2044 2045 err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_ROUTER_VR_CREATE, 2046 &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 2047 if (err) 2048 return err; 2049 2050 *vr_id = __le16_to_cpu(resp.vr_id); 2051 return err; 2052 } 2053 2054 int prestera_hw_vr_delete(struct prestera_switch *sw, u16 vr_id) 2055 { 2056 struct prestera_msg_vr_req req = { 2057 .vr_id = __cpu_to_le16(vr_id), 2058 }; 2059 2060 return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_VR_DELETE, &req.cmd, 2061 sizeof(req)); 2062 } 2063 2064 int prestera_hw_lpm_add(struct prestera_switch *sw, u16 vr_id, 2065 __be32 dst, u32 dst_len, u32 grp_id) 2066 { 2067 struct prestera_msg_lpm_req req = { 2068 .dst_len = __cpu_to_le32(dst_len), 2069 .vr_id = __cpu_to_le16(vr_id), 2070 .grp_id = __cpu_to_le32(grp_id), 2071 .dst.u.ipv4 = dst 2072 }; 2073 2074 return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_LPM_ADD, &req.cmd, 2075 sizeof(req)); 2076 } 2077 2078 int prestera_hw_lpm_del(struct prestera_switch *sw, u16 vr_id, 2079 __be32 dst, u32 dst_len) 2080 { 2081 struct prestera_msg_lpm_req req = { 2082 .dst_len = __cpu_to_le32(dst_len), 2083 .vr_id = __cpu_to_le16(vr_id), 2084 .dst.u.ipv4 = dst 2085 }; 2086 2087 return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_LPM_DELETE, &req.cmd, 2088 sizeof(req)); 2089 } 2090 2091 int prestera_hw_nh_entries_set(struct prestera_switch *sw, int count, 2092 struct prestera_neigh_info *nhs, u32 grp_id) 2093 { 2094 struct prestera_msg_nh_req req = { .size = __cpu_to_le32((u32)count), 2095 .grp_id = __cpu_to_le32(grp_id) }; 2096 int i, err; 2097 2098 for (i = 0; i < count; i++) { 2099 req.nh[i].is_active = nhs[i].connected; 2100 memcpy(&req.nh[i].mac, nhs[i].ha, ETH_ALEN); 2101 err = prestera_iface_to_msg(&nhs[i].iface, &req.nh[i].oif); 2102 if (err) 2103 return err; 2104 } 2105 2106 return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_NH_GRP_SET, &req.cmd, 2107 sizeof(req)); 2108 } 2109 2110 int prestera_hw_nhgrp_blk_get(struct prestera_switch *sw, 2111 u8 *hw_state, u32 buf_size /* Buffer in bytes */) 2112 { 2113 static struct prestera_msg_nh_chunk_resp resp; 2114 struct prestera_msg_nh_chunk_req req; 2115 u32 buf_offset; 2116 int err; 2117 2118 memset(&hw_state[0], 0, buf_size); 2119 buf_offset = 0; 2120 while (1) { 2121 if (buf_offset >= buf_size) 2122 break; 2123 2124 memset(&req, 0, sizeof(req)); 2125 req.offset = __cpu_to_le32(buf_offset * 8); /* 8 bits in u8 */ 2126 err = prestera_cmd_ret(sw, 2127 PRESTERA_CMD_TYPE_ROUTER_NH_GRP_BLK_GET, 2128 &req.cmd, sizeof(req), &resp.ret, 2129 sizeof(resp)); 2130 if (err) 2131 return err; 2132 2133 memcpy(&hw_state[buf_offset], &resp.hw_state[0], 2134 buf_offset + PRESTERA_MSG_CHUNK_SIZE > buf_size ? 2135 buf_size - buf_offset : PRESTERA_MSG_CHUNK_SIZE); 2136 buf_offset += PRESTERA_MSG_CHUNK_SIZE; 2137 } 2138 2139 return 0; 2140 } 2141 2142 int prestera_hw_nh_group_create(struct prestera_switch *sw, u16 nh_count, 2143 u32 *grp_id) 2144 { 2145 struct prestera_msg_nh_grp_req req = { .size = __cpu_to_le32((u32)nh_count) }; 2146 struct prestera_msg_nh_grp_resp resp; 2147 int err; 2148 2149 err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_ROUTER_NH_GRP_ADD, 2150 &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 2151 if (err) 2152 return err; 2153 2154 *grp_id = __le32_to_cpu(resp.grp_id); 2155 return err; 2156 } 2157 2158 int prestera_hw_nh_group_delete(struct prestera_switch *sw, u16 nh_count, 2159 u32 grp_id) 2160 { 2161 struct prestera_msg_nh_grp_req req = { 2162 .grp_id = __cpu_to_le32(grp_id), 2163 .size = __cpu_to_le32(nh_count) 2164 }; 2165 2166 return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_NH_GRP_DELETE, 2167 &req.cmd, sizeof(req)); 2168 } 2169 2170 int prestera_hw_rxtx_init(struct prestera_switch *sw, 2171 struct prestera_rxtx_params *params) 2172 { 2173 struct prestera_msg_rxtx_resp resp; 2174 struct prestera_msg_rxtx_req req; 2175 int err; 2176 2177 req.use_sdma = params->use_sdma; 2178 2179 err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_RXTX_INIT, 2180 &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 2181 if (err) 2182 return err; 2183 2184 params->map_addr = __le32_to_cpu(resp.map_addr); 2185 2186 return 0; 2187 } 2188 2189 int prestera_hw_lag_member_add(struct prestera_port *port, u16 lag_id) 2190 { 2191 struct prestera_msg_lag_req req = { 2192 .port = __cpu_to_le32(port->hw_id), 2193 .dev = __cpu_to_le32(port->dev_id), 2194 .lag_id = __cpu_to_le16(lag_id), 2195 }; 2196 2197 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_LAG_MEMBER_ADD, 2198 &req.cmd, sizeof(req)); 2199 } 2200 2201 int prestera_hw_lag_member_del(struct prestera_port *port, u16 lag_id) 2202 { 2203 struct prestera_msg_lag_req req = { 2204 .port = __cpu_to_le32(port->hw_id), 2205 .dev = __cpu_to_le32(port->dev_id), 2206 .lag_id = __cpu_to_le16(lag_id), 2207 }; 2208 2209 return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_LAG_MEMBER_DELETE, 2210 &req.cmd, sizeof(req)); 2211 } 2212 2213 int prestera_hw_lag_member_enable(struct prestera_port *port, u16 lag_id, 2214 bool enable) 2215 { 2216 struct prestera_msg_lag_req req = { 2217 .port = __cpu_to_le32(port->hw_id), 2218 .dev = __cpu_to_le32(port->dev_id), 2219 .lag_id = __cpu_to_le16(lag_id), 2220 }; 2221 u32 cmd; 2222 2223 cmd = enable ? PRESTERA_CMD_TYPE_LAG_MEMBER_ENABLE : 2224 PRESTERA_CMD_TYPE_LAG_MEMBER_DISABLE; 2225 2226 return prestera_cmd(port->sw, cmd, &req.cmd, sizeof(req)); 2227 } 2228 2229 int 2230 prestera_hw_cpu_code_counters_get(struct prestera_switch *sw, u8 code, 2231 enum prestera_hw_cpu_code_cnt_t counter_type, 2232 u64 *packet_count) 2233 { 2234 struct prestera_msg_cpu_code_counter_req req = { 2235 .counter_type = counter_type, 2236 .code = code, 2237 }; 2238 struct mvsw_msg_cpu_code_counter_ret resp; 2239 int err; 2240 2241 err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_CPU_CODE_COUNTERS_GET, 2242 &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 2243 if (err) 2244 return err; 2245 2246 *packet_count = __le64_to_cpu(resp.packet_count); 2247 2248 return 0; 2249 } 2250 2251 int prestera_hw_event_handler_register(struct prestera_switch *sw, 2252 enum prestera_event_type type, 2253 prestera_event_cb_t fn, 2254 void *arg) 2255 { 2256 struct prestera_fw_event_handler *eh; 2257 2258 eh = __find_event_handler(sw, type); 2259 if (eh) 2260 return -EEXIST; 2261 2262 eh = kmalloc(sizeof(*eh), GFP_KERNEL); 2263 if (!eh) 2264 return -ENOMEM; 2265 2266 eh->type = type; 2267 eh->func = fn; 2268 eh->arg = arg; 2269 2270 INIT_LIST_HEAD(&eh->list); 2271 2272 list_add_rcu(&eh->list, &sw->event_handlers); 2273 2274 return 0; 2275 } 2276 2277 void prestera_hw_event_handler_unregister(struct prestera_switch *sw, 2278 enum prestera_event_type type, 2279 prestera_event_cb_t fn) 2280 { 2281 struct prestera_fw_event_handler *eh; 2282 2283 eh = __find_event_handler(sw, type); 2284 if (!eh) 2285 return; 2286 2287 list_del_rcu(&eh->list); 2288 kfree_rcu(eh, rcu); 2289 } 2290 2291 int prestera_hw_counter_trigger(struct prestera_switch *sw, u32 block_id) 2292 { 2293 struct prestera_msg_counter_req req = { 2294 .block_id = __cpu_to_le32(block_id) 2295 }; 2296 2297 return prestera_cmd(sw, PRESTERA_CMD_TYPE_COUNTER_TRIGGER, 2298 &req.cmd, sizeof(req)); 2299 } 2300 2301 int prestera_hw_counter_abort(struct prestera_switch *sw) 2302 { 2303 struct prestera_msg_counter_req req; 2304 2305 return prestera_cmd(sw, PRESTERA_CMD_TYPE_COUNTER_ABORT, 2306 &req.cmd, sizeof(req)); 2307 } 2308 2309 int prestera_hw_counters_get(struct prestera_switch *sw, u32 idx, 2310 u32 *len, bool *done, 2311 struct prestera_counter_stats *stats) 2312 { 2313 struct prestera_msg_counter_resp *resp; 2314 struct prestera_msg_counter_req req = { 2315 .block_id = __cpu_to_le32(idx), 2316 .num_counters = __cpu_to_le32(*len), 2317 }; 2318 size_t size = struct_size(resp, stats, *len); 2319 int err, i; 2320 2321 resp = kmalloc(size, GFP_KERNEL); 2322 if (!resp) 2323 return -ENOMEM; 2324 2325 err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_COUNTER_GET, 2326 &req.cmd, sizeof(req), &resp->ret, size); 2327 if (err) 2328 goto free_buff; 2329 2330 for (i = 0; i < __le32_to_cpu(resp->num_counters); i++) { 2331 stats[i].packets += __le64_to_cpu(resp->stats[i].packets); 2332 stats[i].bytes += __le64_to_cpu(resp->stats[i].bytes); 2333 } 2334 2335 *len = __le32_to_cpu(resp->num_counters); 2336 *done = __le32_to_cpu(resp->done); 2337 2338 free_buff: 2339 kfree(resp); 2340 return err; 2341 } 2342 2343 int prestera_hw_counter_block_get(struct prestera_switch *sw, 2344 u32 client, u32 *block_id, u32 *offset, 2345 u32 *num_counters) 2346 { 2347 struct prestera_msg_counter_resp resp; 2348 struct prestera_msg_counter_req req = { 2349 .client = __cpu_to_le32(client) 2350 }; 2351 int err; 2352 2353 err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_COUNTER_BLOCK_GET, 2354 &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 2355 if (err) 2356 return err; 2357 2358 *block_id = __le32_to_cpu(resp.block_id); 2359 *offset = __le32_to_cpu(resp.offset); 2360 *num_counters = __le32_to_cpu(resp.num_counters); 2361 2362 return 0; 2363 } 2364 2365 int prestera_hw_counter_block_release(struct prestera_switch *sw, 2366 u32 block_id) 2367 { 2368 struct prestera_msg_counter_req req = { 2369 .block_id = __cpu_to_le32(block_id) 2370 }; 2371 2372 return prestera_cmd(sw, PRESTERA_CMD_TYPE_COUNTER_BLOCK_RELEASE, 2373 &req.cmd, sizeof(req)); 2374 } 2375 2376 int prestera_hw_counter_clear(struct prestera_switch *sw, u32 block_id, 2377 u32 counter_id) 2378 { 2379 struct prestera_msg_counter_req req = { 2380 .block_id = __cpu_to_le32(block_id), 2381 .num_counters = __cpu_to_le32(counter_id) 2382 }; 2383 2384 return prestera_cmd(sw, PRESTERA_CMD_TYPE_COUNTER_CLEAR, 2385 &req.cmd, sizeof(req)); 2386 } 2387 2388 int prestera_hw_policer_create(struct prestera_switch *sw, u8 type, 2389 u32 *policer_id) 2390 { 2391 struct prestera_msg_policer_resp resp; 2392 struct prestera_msg_policer_req req = { 2393 .type = type 2394 }; 2395 int err; 2396 2397 err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_POLICER_CREATE, 2398 &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 2399 if (err) 2400 return err; 2401 2402 *policer_id = __le32_to_cpu(resp.id); 2403 return 0; 2404 } 2405 2406 int prestera_hw_policer_release(struct prestera_switch *sw, 2407 u32 policer_id) 2408 { 2409 struct prestera_msg_policer_req req = { 2410 .id = __cpu_to_le32(policer_id) 2411 }; 2412 2413 return prestera_cmd(sw, PRESTERA_CMD_TYPE_POLICER_RELEASE, 2414 &req.cmd, sizeof(req)); 2415 } 2416 2417 int prestera_hw_policer_sr_tcm_set(struct prestera_switch *sw, 2418 u32 policer_id, u64 cir, u32 cbs) 2419 { 2420 struct prestera_msg_policer_req req = { 2421 .mode = PRESTERA_POLICER_MODE_SR_TCM, 2422 .id = __cpu_to_le32(policer_id), 2423 .sr_tcm = { 2424 .cir = __cpu_to_le64(cir), 2425 .cbs = __cpu_to_le32(cbs) 2426 } 2427 }; 2428 2429 return prestera_cmd(sw, PRESTERA_CMD_TYPE_POLICER_SET, 2430 &req.cmd, sizeof(req)); 2431 } 2432 2433 int prestera_hw_flood_domain_create(struct prestera_flood_domain *domain) 2434 { 2435 struct prestera_msg_flood_domain_create_resp resp; 2436 struct prestera_msg_flood_domain_create_req req; 2437 int err; 2438 2439 err = prestera_cmd_ret(domain->sw, 2440 PRESTERA_CMD_TYPE_FLOOD_DOMAIN_CREATE, &req.cmd, 2441 sizeof(req), &resp.ret, sizeof(resp)); 2442 if (err) 2443 return err; 2444 2445 domain->idx = __le32_to_cpu(resp.flood_domain_idx); 2446 2447 return 0; 2448 } 2449 2450 int prestera_hw_flood_domain_destroy(struct prestera_flood_domain *domain) 2451 { 2452 struct prestera_msg_flood_domain_destroy_req req = { 2453 .flood_domain_idx = __cpu_to_le32(domain->idx), 2454 }; 2455 2456 return prestera_cmd(domain->sw, PRESTERA_CMD_TYPE_FLOOD_DOMAIN_DESTROY, 2457 &req.cmd, sizeof(req)); 2458 } 2459 2460 int prestera_hw_flood_domain_ports_set(struct prestera_flood_domain *domain) 2461 { 2462 struct prestera_flood_domain_port *flood_domain_port; 2463 struct prestera_msg_flood_domain_ports_set_req *req; 2464 struct prestera_msg_flood_domain_port *ports; 2465 struct prestera_switch *sw = domain->sw; 2466 struct prestera_port *port; 2467 u32 ports_num = 0; 2468 int buf_size; 2469 void *buff; 2470 u16 lag_id; 2471 int err; 2472 2473 list_for_each_entry(flood_domain_port, &domain->flood_domain_port_list, 2474 flood_domain_port_node) 2475 ports_num++; 2476 2477 if (!ports_num) 2478 return -EINVAL; 2479 2480 buf_size = sizeof(*req) + sizeof(*ports) * ports_num; 2481 2482 buff = kmalloc(buf_size, GFP_KERNEL); 2483 if (!buff) 2484 return -ENOMEM; 2485 2486 req = buff; 2487 ports = buff + sizeof(*req); 2488 2489 req->flood_domain_idx = __cpu_to_le32(domain->idx); 2490 req->ports_num = __cpu_to_le32(ports_num); 2491 2492 list_for_each_entry(flood_domain_port, &domain->flood_domain_port_list, 2493 flood_domain_port_node) { 2494 if (netif_is_lag_master(flood_domain_port->dev)) { 2495 if (prestera_lag_id(sw, flood_domain_port->dev, 2496 &lag_id)) { 2497 kfree(buff); 2498 return -EINVAL; 2499 } 2500 2501 ports->port_type = 2502 __cpu_to_le16(PRESTERA_HW_FLOOD_DOMAIN_PORT_TYPE_LAG); 2503 ports->lag_id = __cpu_to_le16(lag_id); 2504 } else { 2505 port = prestera_port_dev_lower_find(flood_domain_port->dev); 2506 2507 ports->port_type = 2508 __cpu_to_le16(PRESTERA_HW_FDB_ENTRY_TYPE_REG_PORT); 2509 ports->dev_num = __cpu_to_le32(port->dev_id); 2510 ports->port_num = __cpu_to_le32(port->hw_id); 2511 } 2512 2513 ports->vid = __cpu_to_le16(flood_domain_port->vid); 2514 2515 ports++; 2516 } 2517 2518 err = prestera_cmd(sw, PRESTERA_CMD_TYPE_FLOOD_DOMAIN_PORTS_SET, 2519 &req->cmd, buf_size); 2520 2521 kfree(buff); 2522 2523 return err; 2524 } 2525 2526 int prestera_hw_flood_domain_ports_reset(struct prestera_flood_domain *domain) 2527 { 2528 struct prestera_msg_flood_domain_ports_reset_req req = { 2529 .flood_domain_idx = __cpu_to_le32(domain->idx), 2530 }; 2531 2532 return prestera_cmd(domain->sw, 2533 PRESTERA_CMD_TYPE_FLOOD_DOMAIN_PORTS_RESET, &req.cmd, 2534 sizeof(req)); 2535 } 2536 2537 int prestera_hw_mdb_create(struct prestera_mdb_entry *mdb) 2538 { 2539 struct prestera_msg_mdb_create_req req = { 2540 .flood_domain_idx = __cpu_to_le32(mdb->flood_domain->idx), 2541 .vid = __cpu_to_le16(mdb->vid), 2542 }; 2543 2544 memcpy(req.mac, mdb->addr, ETH_ALEN); 2545 2546 return prestera_cmd(mdb->sw, PRESTERA_CMD_TYPE_MDB_CREATE, &req.cmd, 2547 sizeof(req)); 2548 } 2549 2550 int prestera_hw_mdb_destroy(struct prestera_mdb_entry *mdb) 2551 { 2552 struct prestera_msg_mdb_destroy_req req = { 2553 .flood_domain_idx = __cpu_to_le32(mdb->flood_domain->idx), 2554 .vid = __cpu_to_le16(mdb->vid), 2555 }; 2556 2557 memcpy(req.mac, mdb->addr, ETH_ALEN); 2558 2559 return prestera_cmd(mdb->sw, PRESTERA_CMD_TYPE_MDB_DESTROY, &req.cmd, 2560 sizeof(req)); 2561 } 2562