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