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