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