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