162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 262306a36Sopenharmony_ci/* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include <linux/etherdevice.h> 562306a36Sopenharmony_ci#include <linux/if_bridge.h> 662306a36Sopenharmony_ci#include <linux/ethtool.h> 762306a36Sopenharmony_ci#include <linux/list.h> 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include "prestera.h" 1062306a36Sopenharmony_ci#include "prestera_hw.h" 1162306a36Sopenharmony_ci#include "prestera_acl.h" 1262306a36Sopenharmony_ci#include "prestera_counter.h" 1362306a36Sopenharmony_ci#include "prestera_router_hw.h" 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#define PRESTERA_SWITCH_INIT_TIMEOUT_MS (30 * 1000) 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#define PRESTERA_MIN_MTU 64 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#define PRESTERA_MSG_CHUNK_SIZE 1024 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_cienum prestera_cmd_type_t { 2262306a36Sopenharmony_ci PRESTERA_CMD_TYPE_SWITCH_INIT = 0x1, 2362306a36Sopenharmony_ci PRESTERA_CMD_TYPE_SWITCH_ATTR_SET = 0x2, 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci PRESTERA_CMD_TYPE_PORT_ATTR_SET = 0x100, 2662306a36Sopenharmony_ci PRESTERA_CMD_TYPE_PORT_ATTR_GET = 0x101, 2762306a36Sopenharmony_ci PRESTERA_CMD_TYPE_PORT_INFO_GET = 0x110, 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci PRESTERA_CMD_TYPE_VLAN_CREATE = 0x200, 3062306a36Sopenharmony_ci PRESTERA_CMD_TYPE_VLAN_DELETE = 0x201, 3162306a36Sopenharmony_ci PRESTERA_CMD_TYPE_VLAN_PORT_SET = 0x202, 3262306a36Sopenharmony_ci PRESTERA_CMD_TYPE_VLAN_PVID_SET = 0x203, 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci PRESTERA_CMD_TYPE_FDB_ADD = 0x300, 3562306a36Sopenharmony_ci PRESTERA_CMD_TYPE_FDB_DELETE = 0x301, 3662306a36Sopenharmony_ci PRESTERA_CMD_TYPE_FDB_FLUSH_PORT = 0x310, 3762306a36Sopenharmony_ci PRESTERA_CMD_TYPE_FDB_FLUSH_VLAN = 0x311, 3862306a36Sopenharmony_ci PRESTERA_CMD_TYPE_FDB_FLUSH_PORT_VLAN = 0x312, 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci PRESTERA_CMD_TYPE_BRIDGE_CREATE = 0x400, 4162306a36Sopenharmony_ci PRESTERA_CMD_TYPE_BRIDGE_DELETE = 0x401, 4262306a36Sopenharmony_ci PRESTERA_CMD_TYPE_BRIDGE_PORT_ADD = 0x402, 4362306a36Sopenharmony_ci PRESTERA_CMD_TYPE_BRIDGE_PORT_DELETE = 0x403, 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci PRESTERA_CMD_TYPE_COUNTER_GET = 0x510, 4662306a36Sopenharmony_ci PRESTERA_CMD_TYPE_COUNTER_ABORT = 0x511, 4762306a36Sopenharmony_ci PRESTERA_CMD_TYPE_COUNTER_TRIGGER = 0x512, 4862306a36Sopenharmony_ci PRESTERA_CMD_TYPE_COUNTER_BLOCK_GET = 0x513, 4962306a36Sopenharmony_ci PRESTERA_CMD_TYPE_COUNTER_BLOCK_RELEASE = 0x514, 5062306a36Sopenharmony_ci PRESTERA_CMD_TYPE_COUNTER_CLEAR = 0x515, 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci PRESTERA_CMD_TYPE_VTCAM_CREATE = 0x540, 5362306a36Sopenharmony_ci PRESTERA_CMD_TYPE_VTCAM_DESTROY = 0x541, 5462306a36Sopenharmony_ci PRESTERA_CMD_TYPE_VTCAM_RULE_ADD = 0x550, 5562306a36Sopenharmony_ci PRESTERA_CMD_TYPE_VTCAM_RULE_DELETE = 0x551, 5662306a36Sopenharmony_ci PRESTERA_CMD_TYPE_VTCAM_IFACE_BIND = 0x560, 5762306a36Sopenharmony_ci PRESTERA_CMD_TYPE_VTCAM_IFACE_UNBIND = 0x561, 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci PRESTERA_CMD_TYPE_ROUTER_RIF_CREATE = 0x600, 6062306a36Sopenharmony_ci PRESTERA_CMD_TYPE_ROUTER_RIF_DELETE = 0x601, 6162306a36Sopenharmony_ci PRESTERA_CMD_TYPE_ROUTER_LPM_ADD = 0x610, 6262306a36Sopenharmony_ci PRESTERA_CMD_TYPE_ROUTER_LPM_DELETE = 0x611, 6362306a36Sopenharmony_ci PRESTERA_CMD_TYPE_ROUTER_NH_GRP_SET = 0x622, 6462306a36Sopenharmony_ci PRESTERA_CMD_TYPE_ROUTER_NH_GRP_BLK_GET = 0x645, 6562306a36Sopenharmony_ci PRESTERA_CMD_TYPE_ROUTER_NH_GRP_ADD = 0x623, 6662306a36Sopenharmony_ci PRESTERA_CMD_TYPE_ROUTER_NH_GRP_DELETE = 0x624, 6762306a36Sopenharmony_ci PRESTERA_CMD_TYPE_ROUTER_VR_CREATE = 0x630, 6862306a36Sopenharmony_ci PRESTERA_CMD_TYPE_ROUTER_VR_DELETE = 0x631, 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci PRESTERA_CMD_TYPE_FLOOD_DOMAIN_CREATE = 0x700, 7162306a36Sopenharmony_ci PRESTERA_CMD_TYPE_FLOOD_DOMAIN_DESTROY = 0x701, 7262306a36Sopenharmony_ci PRESTERA_CMD_TYPE_FLOOD_DOMAIN_PORTS_SET = 0x702, 7362306a36Sopenharmony_ci PRESTERA_CMD_TYPE_FLOOD_DOMAIN_PORTS_RESET = 0x703, 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci PRESTERA_CMD_TYPE_MDB_CREATE = 0x704, 7662306a36Sopenharmony_ci PRESTERA_CMD_TYPE_MDB_DESTROY = 0x705, 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci PRESTERA_CMD_TYPE_RXTX_INIT = 0x800, 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci PRESTERA_CMD_TYPE_LAG_MEMBER_ADD = 0x900, 8162306a36Sopenharmony_ci PRESTERA_CMD_TYPE_LAG_MEMBER_DELETE = 0x901, 8262306a36Sopenharmony_ci PRESTERA_CMD_TYPE_LAG_MEMBER_ENABLE = 0x902, 8362306a36Sopenharmony_ci PRESTERA_CMD_TYPE_LAG_MEMBER_DISABLE = 0x903, 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci PRESTERA_CMD_TYPE_STP_PORT_SET = 0x1000, 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci PRESTERA_CMD_TYPE_SPAN_GET = 0x1100, 8862306a36Sopenharmony_ci PRESTERA_CMD_TYPE_SPAN_INGRESS_BIND = 0x1101, 8962306a36Sopenharmony_ci PRESTERA_CMD_TYPE_SPAN_INGRESS_UNBIND = 0x1102, 9062306a36Sopenharmony_ci PRESTERA_CMD_TYPE_SPAN_RELEASE = 0x1103, 9162306a36Sopenharmony_ci PRESTERA_CMD_TYPE_SPAN_EGRESS_BIND = 0x1104, 9262306a36Sopenharmony_ci PRESTERA_CMD_TYPE_SPAN_EGRESS_UNBIND = 0x1105, 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci PRESTERA_CMD_TYPE_POLICER_CREATE = 0x1500, 9562306a36Sopenharmony_ci PRESTERA_CMD_TYPE_POLICER_RELEASE = 0x1501, 9662306a36Sopenharmony_ci PRESTERA_CMD_TYPE_POLICER_SET = 0x1502, 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci PRESTERA_CMD_TYPE_CPU_CODE_COUNTERS_GET = 0x2000, 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci PRESTERA_CMD_TYPE_ACK = 0x10000, 10162306a36Sopenharmony_ci PRESTERA_CMD_TYPE_MAX 10262306a36Sopenharmony_ci}; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_cienum { 10562306a36Sopenharmony_ci PRESTERA_CMD_PORT_ATTR_ADMIN_STATE = 1, 10662306a36Sopenharmony_ci PRESTERA_CMD_PORT_ATTR_MTU = 3, 10762306a36Sopenharmony_ci PRESTERA_CMD_PORT_ATTR_MAC = 4, 10862306a36Sopenharmony_ci PRESTERA_CMD_PORT_ATTR_SPEED = 5, 10962306a36Sopenharmony_ci PRESTERA_CMD_PORT_ATTR_ACCEPT_FRAME_TYPE = 6, 11062306a36Sopenharmony_ci PRESTERA_CMD_PORT_ATTR_LEARNING = 7, 11162306a36Sopenharmony_ci PRESTERA_CMD_PORT_ATTR_FLOOD = 8, 11262306a36Sopenharmony_ci PRESTERA_CMD_PORT_ATTR_CAPABILITY = 9, 11362306a36Sopenharmony_ci PRESTERA_CMD_PORT_ATTR_LOCKED = 10, 11462306a36Sopenharmony_ci PRESTERA_CMD_PORT_ATTR_PHY_MODE = 12, 11562306a36Sopenharmony_ci PRESTERA_CMD_PORT_ATTR_TYPE = 13, 11662306a36Sopenharmony_ci PRESTERA_CMD_PORT_ATTR_STATS = 17, 11762306a36Sopenharmony_ci PRESTERA_CMD_PORT_ATTR_MAC_AUTONEG_RESTART = 18, 11862306a36Sopenharmony_ci PRESTERA_CMD_PORT_ATTR_PHY_AUTONEG_RESTART = 19, 11962306a36Sopenharmony_ci PRESTERA_CMD_PORT_ATTR_MAC_MODE = 22, 12062306a36Sopenharmony_ci}; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_cienum { 12362306a36Sopenharmony_ci PRESTERA_CMD_SWITCH_ATTR_MAC = 1, 12462306a36Sopenharmony_ci PRESTERA_CMD_SWITCH_ATTR_AGEING = 2, 12562306a36Sopenharmony_ci}; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_cienum { 12862306a36Sopenharmony_ci PRESTERA_CMD_ACK_OK, 12962306a36Sopenharmony_ci PRESTERA_CMD_ACK_FAILED, 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci PRESTERA_CMD_ACK_MAX 13262306a36Sopenharmony_ci}; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_cienum { 13562306a36Sopenharmony_ci PRESTERA_PORT_TP_NA, 13662306a36Sopenharmony_ci PRESTERA_PORT_TP_MDI, 13762306a36Sopenharmony_ci PRESTERA_PORT_TP_MDIX, 13862306a36Sopenharmony_ci PRESTERA_PORT_TP_AUTO, 13962306a36Sopenharmony_ci}; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cienum { 14262306a36Sopenharmony_ci PRESTERA_PORT_FLOOD_TYPE_UC = 0, 14362306a36Sopenharmony_ci PRESTERA_PORT_FLOOD_TYPE_MC = 1, 14462306a36Sopenharmony_ci}; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_cienum { 14762306a36Sopenharmony_ci PRESTERA_PORT_GOOD_OCTETS_RCV_CNT, 14862306a36Sopenharmony_ci PRESTERA_PORT_BAD_OCTETS_RCV_CNT, 14962306a36Sopenharmony_ci PRESTERA_PORT_MAC_TRANSMIT_ERR_CNT, 15062306a36Sopenharmony_ci PRESTERA_PORT_BRDC_PKTS_RCV_CNT, 15162306a36Sopenharmony_ci PRESTERA_PORT_MC_PKTS_RCV_CNT, 15262306a36Sopenharmony_ci PRESTERA_PORT_PKTS_64L_CNT, 15362306a36Sopenharmony_ci PRESTERA_PORT_PKTS_65TO127L_CNT, 15462306a36Sopenharmony_ci PRESTERA_PORT_PKTS_128TO255L_CNT, 15562306a36Sopenharmony_ci PRESTERA_PORT_PKTS_256TO511L_CNT, 15662306a36Sopenharmony_ci PRESTERA_PORT_PKTS_512TO1023L_CNT, 15762306a36Sopenharmony_ci PRESTERA_PORT_PKTS_1024TOMAXL_CNT, 15862306a36Sopenharmony_ci PRESTERA_PORT_EXCESSIVE_COLLISIONS_CNT, 15962306a36Sopenharmony_ci PRESTERA_PORT_MC_PKTS_SENT_CNT, 16062306a36Sopenharmony_ci PRESTERA_PORT_BRDC_PKTS_SENT_CNT, 16162306a36Sopenharmony_ci PRESTERA_PORT_FC_SENT_CNT, 16262306a36Sopenharmony_ci PRESTERA_PORT_GOOD_FC_RCV_CNT, 16362306a36Sopenharmony_ci PRESTERA_PORT_DROP_EVENTS_CNT, 16462306a36Sopenharmony_ci PRESTERA_PORT_UNDERSIZE_PKTS_CNT, 16562306a36Sopenharmony_ci PRESTERA_PORT_FRAGMENTS_PKTS_CNT, 16662306a36Sopenharmony_ci PRESTERA_PORT_OVERSIZE_PKTS_CNT, 16762306a36Sopenharmony_ci PRESTERA_PORT_JABBER_PKTS_CNT, 16862306a36Sopenharmony_ci PRESTERA_PORT_MAC_RCV_ERROR_CNT, 16962306a36Sopenharmony_ci PRESTERA_PORT_BAD_CRC_CNT, 17062306a36Sopenharmony_ci PRESTERA_PORT_COLLISIONS_CNT, 17162306a36Sopenharmony_ci PRESTERA_PORT_LATE_COLLISIONS_CNT, 17262306a36Sopenharmony_ci PRESTERA_PORT_GOOD_UC_PKTS_RCV_CNT, 17362306a36Sopenharmony_ci PRESTERA_PORT_GOOD_UC_PKTS_SENT_CNT, 17462306a36Sopenharmony_ci PRESTERA_PORT_MULTIPLE_PKTS_SENT_CNT, 17562306a36Sopenharmony_ci PRESTERA_PORT_DEFERRED_PKTS_SENT_CNT, 17662306a36Sopenharmony_ci PRESTERA_PORT_GOOD_OCTETS_SENT_CNT, 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci PRESTERA_PORT_CNT_MAX 17962306a36Sopenharmony_ci}; 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_cienum { 18262306a36Sopenharmony_ci PRESTERA_FC_NONE, 18362306a36Sopenharmony_ci PRESTERA_FC_SYMMETRIC, 18462306a36Sopenharmony_ci PRESTERA_FC_ASYMMETRIC, 18562306a36Sopenharmony_ci PRESTERA_FC_SYMM_ASYMM, 18662306a36Sopenharmony_ci}; 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_cienum { 18962306a36Sopenharmony_ci PRESTERA_POLICER_MODE_SR_TCM 19062306a36Sopenharmony_ci}; 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_cienum { 19362306a36Sopenharmony_ci PRESTERA_HW_FDB_ENTRY_TYPE_REG_PORT = 0, 19462306a36Sopenharmony_ci PRESTERA_HW_FDB_ENTRY_TYPE_LAG = 1, 19562306a36Sopenharmony_ci PRESTERA_HW_FDB_ENTRY_TYPE_MAX = 2, 19662306a36Sopenharmony_ci}; 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_cistruct prestera_fw_event_handler { 19962306a36Sopenharmony_ci struct list_head list; 20062306a36Sopenharmony_ci struct rcu_head rcu; 20162306a36Sopenharmony_ci enum prestera_event_type type; 20262306a36Sopenharmony_ci prestera_event_cb_t func; 20362306a36Sopenharmony_ci void *arg; 20462306a36Sopenharmony_ci}; 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_cienum { 20762306a36Sopenharmony_ci PRESTERA_HW_FLOOD_DOMAIN_PORT_TYPE_REG_PORT = 0, 20862306a36Sopenharmony_ci PRESTERA_HW_FLOOD_DOMAIN_PORT_TYPE_LAG = 1, 20962306a36Sopenharmony_ci PRESTERA_HW_FLOOD_DOMAIN_PORT_TYPE_MAX = 2, 21062306a36Sopenharmony_ci}; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_cistruct prestera_msg_cmd { 21362306a36Sopenharmony_ci __le32 type; 21462306a36Sopenharmony_ci}; 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_cistruct prestera_msg_ret { 21762306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 21862306a36Sopenharmony_ci __le32 status; 21962306a36Sopenharmony_ci}; 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_cistruct prestera_msg_common_req { 22262306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 22362306a36Sopenharmony_ci}; 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_cistruct prestera_msg_common_resp { 22662306a36Sopenharmony_ci struct prestera_msg_ret ret; 22762306a36Sopenharmony_ci}; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_cistruct prestera_msg_switch_attr_req { 23062306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 23162306a36Sopenharmony_ci __le32 attr; 23262306a36Sopenharmony_ci union { 23362306a36Sopenharmony_ci __le32 ageing_timeout_ms; 23462306a36Sopenharmony_ci struct { 23562306a36Sopenharmony_ci u8 mac[ETH_ALEN]; 23662306a36Sopenharmony_ci u8 __pad[2]; 23762306a36Sopenharmony_ci }; 23862306a36Sopenharmony_ci } param; 23962306a36Sopenharmony_ci}; 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_cistruct prestera_msg_switch_init_resp { 24262306a36Sopenharmony_ci struct prestera_msg_ret ret; 24362306a36Sopenharmony_ci __le32 port_count; 24462306a36Sopenharmony_ci __le32 mtu_max; 24562306a36Sopenharmony_ci __le32 size_tbl_router_nexthop; 24662306a36Sopenharmony_ci u8 switch_id; 24762306a36Sopenharmony_ci u8 lag_max; 24862306a36Sopenharmony_ci u8 lag_member_max; 24962306a36Sopenharmony_ci}; 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_cistruct prestera_msg_event_port_param { 25262306a36Sopenharmony_ci union { 25362306a36Sopenharmony_ci struct { 25462306a36Sopenharmony_ci __le32 mode; 25562306a36Sopenharmony_ci __le32 speed; 25662306a36Sopenharmony_ci u8 oper; 25762306a36Sopenharmony_ci u8 duplex; 25862306a36Sopenharmony_ci u8 fc; 25962306a36Sopenharmony_ci u8 fec; 26062306a36Sopenharmony_ci } mac; 26162306a36Sopenharmony_ci struct { 26262306a36Sopenharmony_ci __le64 lmode_bmap; 26362306a36Sopenharmony_ci u8 mdix; 26462306a36Sopenharmony_ci u8 fc; 26562306a36Sopenharmony_ci u8 __pad[2]; 26662306a36Sopenharmony_ci } __packed phy; /* make sure always 12 bytes size */ 26762306a36Sopenharmony_ci }; 26862306a36Sopenharmony_ci}; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_cistruct prestera_msg_port_cap_param { 27162306a36Sopenharmony_ci __le64 link_mode; 27262306a36Sopenharmony_ci u8 type; 27362306a36Sopenharmony_ci u8 fec; 27462306a36Sopenharmony_ci u8 fc; 27562306a36Sopenharmony_ci u8 transceiver; 27662306a36Sopenharmony_ci}; 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_cistruct prestera_msg_port_flood_param { 27962306a36Sopenharmony_ci u8 type; 28062306a36Sopenharmony_ci u8 enable; 28162306a36Sopenharmony_ci u8 __pad[2]; 28262306a36Sopenharmony_ci}; 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ciunion prestera_msg_port_param { 28562306a36Sopenharmony_ci __le32 mtu; 28662306a36Sopenharmony_ci __le32 speed; 28762306a36Sopenharmony_ci __le32 link_mode; 28862306a36Sopenharmony_ci u8 admin_state; 28962306a36Sopenharmony_ci u8 oper_state; 29062306a36Sopenharmony_ci u8 mac[ETH_ALEN]; 29162306a36Sopenharmony_ci u8 accept_frm_type; 29262306a36Sopenharmony_ci u8 learning; 29362306a36Sopenharmony_ci u8 flood; 29462306a36Sopenharmony_ci u8 type; 29562306a36Sopenharmony_ci u8 duplex; 29662306a36Sopenharmony_ci u8 fec; 29762306a36Sopenharmony_ci u8 fc; 29862306a36Sopenharmony_ci u8 br_locked; 29962306a36Sopenharmony_ci union { 30062306a36Sopenharmony_ci struct { 30162306a36Sopenharmony_ci u8 admin; 30262306a36Sopenharmony_ci u8 fc; 30362306a36Sopenharmony_ci u8 ap_enable; 30462306a36Sopenharmony_ci u8 __reserved[5]; 30562306a36Sopenharmony_ci union { 30662306a36Sopenharmony_ci struct { 30762306a36Sopenharmony_ci __le32 mode; 30862306a36Sopenharmony_ci __le32 speed; 30962306a36Sopenharmony_ci u8 inband; 31062306a36Sopenharmony_ci u8 duplex; 31162306a36Sopenharmony_ci u8 fec; 31262306a36Sopenharmony_ci u8 fec_supp; 31362306a36Sopenharmony_ci } reg_mode; 31462306a36Sopenharmony_ci struct { 31562306a36Sopenharmony_ci __le32 mode; 31662306a36Sopenharmony_ci __le32 speed; 31762306a36Sopenharmony_ci u8 fec; 31862306a36Sopenharmony_ci u8 fec_supp; 31962306a36Sopenharmony_ci u8 __pad[2]; 32062306a36Sopenharmony_ci } ap_modes[PRESTERA_AP_PORT_MAX]; 32162306a36Sopenharmony_ci }; 32262306a36Sopenharmony_ci } mac; 32362306a36Sopenharmony_ci struct { 32462306a36Sopenharmony_ci __le64 modes; 32562306a36Sopenharmony_ci __le32 mode; 32662306a36Sopenharmony_ci u8 admin; 32762306a36Sopenharmony_ci u8 adv_enable; 32862306a36Sopenharmony_ci u8 mdix; 32962306a36Sopenharmony_ci u8 __pad; 33062306a36Sopenharmony_ci } phy; 33162306a36Sopenharmony_ci } link; 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci struct prestera_msg_port_cap_param cap; 33462306a36Sopenharmony_ci struct prestera_msg_port_flood_param flood_ext; 33562306a36Sopenharmony_ci struct prestera_msg_event_port_param link_evt; 33662306a36Sopenharmony_ci}; 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_cistruct prestera_msg_port_attr_req { 33962306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 34062306a36Sopenharmony_ci __le32 attr; 34162306a36Sopenharmony_ci __le32 port; 34262306a36Sopenharmony_ci __le32 dev; 34362306a36Sopenharmony_ci union prestera_msg_port_param param; 34462306a36Sopenharmony_ci}; 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_cistruct prestera_msg_port_attr_resp { 34762306a36Sopenharmony_ci struct prestera_msg_ret ret; 34862306a36Sopenharmony_ci union prestera_msg_port_param param; 34962306a36Sopenharmony_ci}; 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_cistruct prestera_msg_port_stats_resp { 35262306a36Sopenharmony_ci struct prestera_msg_ret ret; 35362306a36Sopenharmony_ci __le64 stats[PRESTERA_PORT_CNT_MAX]; 35462306a36Sopenharmony_ci}; 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_cistruct prestera_msg_port_info_req { 35762306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 35862306a36Sopenharmony_ci __le32 port; 35962306a36Sopenharmony_ci}; 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_cistruct prestera_msg_port_info_resp { 36262306a36Sopenharmony_ci struct prestera_msg_ret ret; 36362306a36Sopenharmony_ci __le32 hw_id; 36462306a36Sopenharmony_ci __le32 dev_id; 36562306a36Sopenharmony_ci __le16 fp_id; 36662306a36Sopenharmony_ci u8 pad[2]; 36762306a36Sopenharmony_ci}; 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_cistruct prestera_msg_vlan_req { 37062306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 37162306a36Sopenharmony_ci __le32 port; 37262306a36Sopenharmony_ci __le32 dev; 37362306a36Sopenharmony_ci __le16 vid; 37462306a36Sopenharmony_ci u8 is_member; 37562306a36Sopenharmony_ci u8 is_tagged; 37662306a36Sopenharmony_ci}; 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_cistruct prestera_msg_fdb_req { 37962306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 38062306a36Sopenharmony_ci __le32 flush_mode; 38162306a36Sopenharmony_ci union { 38262306a36Sopenharmony_ci struct { 38362306a36Sopenharmony_ci __le32 port; 38462306a36Sopenharmony_ci __le32 dev; 38562306a36Sopenharmony_ci }; 38662306a36Sopenharmony_ci __le16 lag_id; 38762306a36Sopenharmony_ci } dest; 38862306a36Sopenharmony_ci __le16 vid; 38962306a36Sopenharmony_ci u8 dest_type; 39062306a36Sopenharmony_ci u8 dynamic; 39162306a36Sopenharmony_ci u8 mac[ETH_ALEN]; 39262306a36Sopenharmony_ci u8 __pad[2]; 39362306a36Sopenharmony_ci}; 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_cistruct prestera_msg_bridge_req { 39662306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 39762306a36Sopenharmony_ci __le32 port; 39862306a36Sopenharmony_ci __le32 dev; 39962306a36Sopenharmony_ci __le16 bridge; 40062306a36Sopenharmony_ci u8 pad[2]; 40162306a36Sopenharmony_ci}; 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_cistruct prestera_msg_bridge_resp { 40462306a36Sopenharmony_ci struct prestera_msg_ret ret; 40562306a36Sopenharmony_ci __le16 bridge; 40662306a36Sopenharmony_ci u8 pad[2]; 40762306a36Sopenharmony_ci}; 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_cistruct prestera_msg_vtcam_create_req { 41062306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 41162306a36Sopenharmony_ci __le32 keymask[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX]; 41262306a36Sopenharmony_ci u8 direction; 41362306a36Sopenharmony_ci u8 lookup; 41462306a36Sopenharmony_ci u8 pad[2]; 41562306a36Sopenharmony_ci}; 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_cistruct prestera_msg_vtcam_destroy_req { 41862306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 41962306a36Sopenharmony_ci __le32 vtcam_id; 42062306a36Sopenharmony_ci}; 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_cistruct prestera_msg_vtcam_rule_add_req { 42362306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 42462306a36Sopenharmony_ci __le32 key[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX]; 42562306a36Sopenharmony_ci __le32 keymask[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX]; 42662306a36Sopenharmony_ci __le32 vtcam_id; 42762306a36Sopenharmony_ci __le32 prio; 42862306a36Sopenharmony_ci __le32 n_act; 42962306a36Sopenharmony_ci}; 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_cistruct prestera_msg_vtcam_rule_del_req { 43262306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 43362306a36Sopenharmony_ci __le32 vtcam_id; 43462306a36Sopenharmony_ci __le32 id; 43562306a36Sopenharmony_ci}; 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_cistruct prestera_msg_vtcam_bind_req { 43862306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 43962306a36Sopenharmony_ci union { 44062306a36Sopenharmony_ci struct { 44162306a36Sopenharmony_ci __le32 hw_id; 44262306a36Sopenharmony_ci __le32 dev_id; 44362306a36Sopenharmony_ci } port; 44462306a36Sopenharmony_ci __le32 index; 44562306a36Sopenharmony_ci }; 44662306a36Sopenharmony_ci __le32 vtcam_id; 44762306a36Sopenharmony_ci __le16 pcl_id; 44862306a36Sopenharmony_ci __le16 type; 44962306a36Sopenharmony_ci}; 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_cistruct prestera_msg_vtcam_resp { 45262306a36Sopenharmony_ci struct prestera_msg_ret ret; 45362306a36Sopenharmony_ci __le32 vtcam_id; 45462306a36Sopenharmony_ci __le32 rule_id; 45562306a36Sopenharmony_ci}; 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_cistruct prestera_msg_acl_action { 45862306a36Sopenharmony_ci __le32 id; 45962306a36Sopenharmony_ci __le32 __reserved; 46062306a36Sopenharmony_ci union { 46162306a36Sopenharmony_ci struct { 46262306a36Sopenharmony_ci __le32 index; 46362306a36Sopenharmony_ci } jump; 46462306a36Sopenharmony_ci struct { 46562306a36Sopenharmony_ci __le32 id; 46662306a36Sopenharmony_ci } police; 46762306a36Sopenharmony_ci struct { 46862306a36Sopenharmony_ci __le32 id; 46962306a36Sopenharmony_ci } count; 47062306a36Sopenharmony_ci __le32 reserved[6]; 47162306a36Sopenharmony_ci }; 47262306a36Sopenharmony_ci}; 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_cistruct prestera_msg_counter_req { 47562306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 47662306a36Sopenharmony_ci __le32 client; 47762306a36Sopenharmony_ci __le32 block_id; 47862306a36Sopenharmony_ci __le32 num_counters; 47962306a36Sopenharmony_ci}; 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_cistruct prestera_msg_counter_stats { 48262306a36Sopenharmony_ci __le64 packets; 48362306a36Sopenharmony_ci __le64 bytes; 48462306a36Sopenharmony_ci}; 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_cistruct prestera_msg_counter_resp { 48762306a36Sopenharmony_ci struct prestera_msg_ret ret; 48862306a36Sopenharmony_ci __le32 block_id; 48962306a36Sopenharmony_ci __le32 offset; 49062306a36Sopenharmony_ci __le32 num_counters; 49162306a36Sopenharmony_ci __le32 done; 49262306a36Sopenharmony_ci struct prestera_msg_counter_stats stats[]; 49362306a36Sopenharmony_ci}; 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_cistruct prestera_msg_span_req { 49662306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 49762306a36Sopenharmony_ci __le32 port; 49862306a36Sopenharmony_ci __le32 dev; 49962306a36Sopenharmony_ci u8 id; 50062306a36Sopenharmony_ci u8 pad[3]; 50162306a36Sopenharmony_ci}; 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_cistruct prestera_msg_span_resp { 50462306a36Sopenharmony_ci struct prestera_msg_ret ret; 50562306a36Sopenharmony_ci u8 id; 50662306a36Sopenharmony_ci u8 pad[3]; 50762306a36Sopenharmony_ci}; 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_cistruct prestera_msg_stp_req { 51062306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 51162306a36Sopenharmony_ci __le32 port; 51262306a36Sopenharmony_ci __le32 dev; 51362306a36Sopenharmony_ci __le16 vid; 51462306a36Sopenharmony_ci u8 state; 51562306a36Sopenharmony_ci u8 __pad; 51662306a36Sopenharmony_ci}; 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_cistruct prestera_msg_rxtx_req { 51962306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 52062306a36Sopenharmony_ci u8 use_sdma; 52162306a36Sopenharmony_ci u8 pad[3]; 52262306a36Sopenharmony_ci}; 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_cistruct prestera_msg_rxtx_resp { 52562306a36Sopenharmony_ci struct prestera_msg_ret ret; 52662306a36Sopenharmony_ci __le32 map_addr; 52762306a36Sopenharmony_ci}; 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_cistruct prestera_msg_iface { 53062306a36Sopenharmony_ci union { 53162306a36Sopenharmony_ci struct { 53262306a36Sopenharmony_ci __le32 dev; 53362306a36Sopenharmony_ci __le32 port; 53462306a36Sopenharmony_ci }; 53562306a36Sopenharmony_ci __le16 lag_id; 53662306a36Sopenharmony_ci }; 53762306a36Sopenharmony_ci __le16 vr_id; 53862306a36Sopenharmony_ci __le16 vid; 53962306a36Sopenharmony_ci u8 type; 54062306a36Sopenharmony_ci u8 __pad[3]; 54162306a36Sopenharmony_ci}; 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_cistruct prestera_msg_ip_addr { 54462306a36Sopenharmony_ci union { 54562306a36Sopenharmony_ci __be32 ipv4; 54662306a36Sopenharmony_ci __be32 ipv6[4]; 54762306a36Sopenharmony_ci } u; 54862306a36Sopenharmony_ci u8 v; /* e.g. PRESTERA_IPV4 */ 54962306a36Sopenharmony_ci u8 __pad[3]; 55062306a36Sopenharmony_ci}; 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_cistruct prestera_msg_nh { 55362306a36Sopenharmony_ci struct prestera_msg_iface oif; 55462306a36Sopenharmony_ci __le32 hw_id; 55562306a36Sopenharmony_ci u8 mac[ETH_ALEN]; 55662306a36Sopenharmony_ci u8 is_active; 55762306a36Sopenharmony_ci u8 pad; 55862306a36Sopenharmony_ci}; 55962306a36Sopenharmony_ci 56062306a36Sopenharmony_cistruct prestera_msg_rif_req { 56162306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 56262306a36Sopenharmony_ci struct prestera_msg_iface iif; 56362306a36Sopenharmony_ci __le32 mtu; 56462306a36Sopenharmony_ci __le16 rif_id; 56562306a36Sopenharmony_ci __le16 __reserved; 56662306a36Sopenharmony_ci u8 mac[ETH_ALEN]; 56762306a36Sopenharmony_ci u8 __pad[2]; 56862306a36Sopenharmony_ci}; 56962306a36Sopenharmony_ci 57062306a36Sopenharmony_cistruct prestera_msg_rif_resp { 57162306a36Sopenharmony_ci struct prestera_msg_ret ret; 57262306a36Sopenharmony_ci __le16 rif_id; 57362306a36Sopenharmony_ci u8 __pad[2]; 57462306a36Sopenharmony_ci}; 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_cistruct prestera_msg_lpm_req { 57762306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 57862306a36Sopenharmony_ci struct prestera_msg_ip_addr dst; 57962306a36Sopenharmony_ci __le32 grp_id; 58062306a36Sopenharmony_ci __le32 dst_len; 58162306a36Sopenharmony_ci __le16 vr_id; 58262306a36Sopenharmony_ci u8 __pad[2]; 58362306a36Sopenharmony_ci}; 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_cistruct prestera_msg_nh_req { 58662306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 58762306a36Sopenharmony_ci struct prestera_msg_nh nh[PRESTERA_NHGR_SIZE_MAX]; 58862306a36Sopenharmony_ci __le32 size; 58962306a36Sopenharmony_ci __le32 grp_id; 59062306a36Sopenharmony_ci}; 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_cistruct prestera_msg_nh_chunk_req { 59362306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 59462306a36Sopenharmony_ci __le32 offset; 59562306a36Sopenharmony_ci}; 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_cistruct prestera_msg_nh_chunk_resp { 59862306a36Sopenharmony_ci struct prestera_msg_ret ret; 59962306a36Sopenharmony_ci u8 hw_state[PRESTERA_MSG_CHUNK_SIZE]; 60062306a36Sopenharmony_ci}; 60162306a36Sopenharmony_ci 60262306a36Sopenharmony_cistruct prestera_msg_nh_grp_req { 60362306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 60462306a36Sopenharmony_ci __le32 grp_id; 60562306a36Sopenharmony_ci __le32 size; 60662306a36Sopenharmony_ci}; 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_cistruct prestera_msg_nh_grp_resp { 60962306a36Sopenharmony_ci struct prestera_msg_ret ret; 61062306a36Sopenharmony_ci __le32 grp_id; 61162306a36Sopenharmony_ci}; 61262306a36Sopenharmony_ci 61362306a36Sopenharmony_cistruct prestera_msg_vr_req { 61462306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 61562306a36Sopenharmony_ci __le16 vr_id; 61662306a36Sopenharmony_ci u8 __pad[2]; 61762306a36Sopenharmony_ci}; 61862306a36Sopenharmony_ci 61962306a36Sopenharmony_cistruct prestera_msg_vr_resp { 62062306a36Sopenharmony_ci struct prestera_msg_ret ret; 62162306a36Sopenharmony_ci __le16 vr_id; 62262306a36Sopenharmony_ci u8 __pad[2]; 62362306a36Sopenharmony_ci}; 62462306a36Sopenharmony_ci 62562306a36Sopenharmony_cistruct prestera_msg_lag_req { 62662306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 62762306a36Sopenharmony_ci __le32 port; 62862306a36Sopenharmony_ci __le32 dev; 62962306a36Sopenharmony_ci __le16 lag_id; 63062306a36Sopenharmony_ci u8 pad[2]; 63162306a36Sopenharmony_ci}; 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_cistruct prestera_msg_cpu_code_counter_req { 63462306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 63562306a36Sopenharmony_ci u8 counter_type; 63662306a36Sopenharmony_ci u8 code; 63762306a36Sopenharmony_ci u8 pad[2]; 63862306a36Sopenharmony_ci}; 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_cistruct mvsw_msg_cpu_code_counter_ret { 64162306a36Sopenharmony_ci struct prestera_msg_ret ret; 64262306a36Sopenharmony_ci __le64 packet_count; 64362306a36Sopenharmony_ci}; 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_cistruct prestera_msg_policer_req { 64662306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 64762306a36Sopenharmony_ci __le32 id; 64862306a36Sopenharmony_ci union { 64962306a36Sopenharmony_ci struct { 65062306a36Sopenharmony_ci __le64 cir; 65162306a36Sopenharmony_ci __le32 cbs; 65262306a36Sopenharmony_ci } __packed sr_tcm; /* make sure always 12 bytes size */ 65362306a36Sopenharmony_ci __le32 reserved[6]; 65462306a36Sopenharmony_ci }; 65562306a36Sopenharmony_ci u8 mode; 65662306a36Sopenharmony_ci u8 type; 65762306a36Sopenharmony_ci u8 pad[2]; 65862306a36Sopenharmony_ci}; 65962306a36Sopenharmony_ci 66062306a36Sopenharmony_cistruct prestera_msg_policer_resp { 66162306a36Sopenharmony_ci struct prestera_msg_ret ret; 66262306a36Sopenharmony_ci __le32 id; 66362306a36Sopenharmony_ci}; 66462306a36Sopenharmony_ci 66562306a36Sopenharmony_cistruct prestera_msg_event { 66662306a36Sopenharmony_ci __le16 type; 66762306a36Sopenharmony_ci __le16 id; 66862306a36Sopenharmony_ci}; 66962306a36Sopenharmony_ci 67062306a36Sopenharmony_cistruct prestera_msg_event_port { 67162306a36Sopenharmony_ci struct prestera_msg_event id; 67262306a36Sopenharmony_ci __le32 port_id; 67362306a36Sopenharmony_ci struct prestera_msg_event_port_param param; 67462306a36Sopenharmony_ci}; 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ciunion prestera_msg_event_fdb_param { 67762306a36Sopenharmony_ci u8 mac[ETH_ALEN]; 67862306a36Sopenharmony_ci}; 67962306a36Sopenharmony_ci 68062306a36Sopenharmony_cistruct prestera_msg_event_fdb { 68162306a36Sopenharmony_ci struct prestera_msg_event id; 68262306a36Sopenharmony_ci __le32 vid; 68362306a36Sopenharmony_ci union { 68462306a36Sopenharmony_ci __le32 port_id; 68562306a36Sopenharmony_ci __le16 lag_id; 68662306a36Sopenharmony_ci } dest; 68762306a36Sopenharmony_ci union prestera_msg_event_fdb_param param; 68862306a36Sopenharmony_ci u8 dest_type; 68962306a36Sopenharmony_ci}; 69062306a36Sopenharmony_ci 69162306a36Sopenharmony_cistruct prestera_msg_flood_domain_create_req { 69262306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 69362306a36Sopenharmony_ci}; 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_cistruct prestera_msg_flood_domain_create_resp { 69662306a36Sopenharmony_ci struct prestera_msg_ret ret; 69762306a36Sopenharmony_ci __le32 flood_domain_idx; 69862306a36Sopenharmony_ci}; 69962306a36Sopenharmony_ci 70062306a36Sopenharmony_cistruct prestera_msg_flood_domain_destroy_req { 70162306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 70262306a36Sopenharmony_ci __le32 flood_domain_idx; 70362306a36Sopenharmony_ci}; 70462306a36Sopenharmony_ci 70562306a36Sopenharmony_cistruct prestera_msg_flood_domain_ports_set_req { 70662306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 70762306a36Sopenharmony_ci __le32 flood_domain_idx; 70862306a36Sopenharmony_ci __le32 ports_num; 70962306a36Sopenharmony_ci}; 71062306a36Sopenharmony_ci 71162306a36Sopenharmony_cistruct prestera_msg_flood_domain_ports_reset_req { 71262306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 71362306a36Sopenharmony_ci __le32 flood_domain_idx; 71462306a36Sopenharmony_ci}; 71562306a36Sopenharmony_ci 71662306a36Sopenharmony_cistruct prestera_msg_flood_domain_port { 71762306a36Sopenharmony_ci union { 71862306a36Sopenharmony_ci struct { 71962306a36Sopenharmony_ci __le32 port_num; 72062306a36Sopenharmony_ci __le32 dev_num; 72162306a36Sopenharmony_ci }; 72262306a36Sopenharmony_ci __le16 lag_id; 72362306a36Sopenharmony_ci }; 72462306a36Sopenharmony_ci __le16 vid; 72562306a36Sopenharmony_ci __le16 port_type; 72662306a36Sopenharmony_ci}; 72762306a36Sopenharmony_ci 72862306a36Sopenharmony_cistruct prestera_msg_mdb_create_req { 72962306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 73062306a36Sopenharmony_ci __le32 flood_domain_idx; 73162306a36Sopenharmony_ci __le16 vid; 73262306a36Sopenharmony_ci u8 mac[ETH_ALEN]; 73362306a36Sopenharmony_ci}; 73462306a36Sopenharmony_ci 73562306a36Sopenharmony_cistruct prestera_msg_mdb_destroy_req { 73662306a36Sopenharmony_ci struct prestera_msg_cmd cmd; 73762306a36Sopenharmony_ci __le32 flood_domain_idx; 73862306a36Sopenharmony_ci __le16 vid; 73962306a36Sopenharmony_ci u8 mac[ETH_ALEN]; 74062306a36Sopenharmony_ci}; 74162306a36Sopenharmony_ci 74262306a36Sopenharmony_cistatic void prestera_hw_build_tests(void) 74362306a36Sopenharmony_ci{ 74462306a36Sopenharmony_ci /* check requests */ 74562306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_common_req) != 4); 74662306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_switch_attr_req) != 16); 74762306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_port_attr_req) != 144); 74862306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_port_info_req) != 8); 74962306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_vlan_req) != 16); 75062306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_fdb_req) != 28); 75162306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_bridge_req) != 16); 75262306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_span_req) != 16); 75362306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_stp_req) != 16); 75462306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_rxtx_req) != 8); 75562306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_lag_req) != 16); 75662306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_cpu_code_counter_req) != 8); 75762306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_create_req) != 84); 75862306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_destroy_req) != 8); 75962306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_rule_add_req) != 168); 76062306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_rule_del_req) != 12); 76162306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_bind_req) != 20); 76262306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_acl_action) != 32); 76362306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_counter_req) != 16); 76462306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_counter_stats) != 16); 76562306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_rif_req) != 36); 76662306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_vr_req) != 8); 76762306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_lpm_req) != 36); 76862306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_policer_req) != 36); 76962306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_create_req) != 4); 77062306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_destroy_req) != 8); 77162306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_ports_set_req) != 12); 77262306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_ports_reset_req) != 8); 77362306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_mdb_create_req) != 16); 77462306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_mdb_destroy_req) != 16); 77562306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_nh_req) != 124); 77662306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_nh_chunk_req) != 8); 77762306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_nh_grp_req) != 12); 77862306a36Sopenharmony_ci 77962306a36Sopenharmony_ci /* structure that are part of req/resp fw messages */ 78062306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_iface) != 16); 78162306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_ip_addr) != 20); 78262306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_port) != 12); 78362306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_nh) != 28); 78462306a36Sopenharmony_ci 78562306a36Sopenharmony_ci /* check responses */ 78662306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_common_resp) != 8); 78762306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_switch_init_resp) != 24); 78862306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_port_attr_resp) != 136); 78962306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_port_stats_resp) != 248); 79062306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_port_info_resp) != 20); 79162306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_bridge_resp) != 12); 79262306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_span_resp) != 12); 79362306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_rxtx_resp) != 12); 79462306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_resp) != 16); 79562306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_counter_resp) != 24); 79662306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_rif_resp) != 12); 79762306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_vr_resp) != 12); 79862306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_policer_resp) != 12); 79962306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_create_resp) != 12); 80062306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_nh_chunk_resp) != 1032); 80162306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_nh_grp_resp) != 12); 80262306a36Sopenharmony_ci 80362306a36Sopenharmony_ci /* check events */ 80462306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_event_port) != 20); 80562306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct prestera_msg_event_fdb) != 20); 80662306a36Sopenharmony_ci} 80762306a36Sopenharmony_ci 80862306a36Sopenharmony_cistatic u8 prestera_hw_mdix_to_eth(u8 mode); 80962306a36Sopenharmony_cistatic void prestera_hw_remote_fc_to_eth(u8 fc, bool *pause, bool *asym_pause); 81062306a36Sopenharmony_ci 81162306a36Sopenharmony_cistatic int __prestera_cmd_ret(struct prestera_switch *sw, 81262306a36Sopenharmony_ci enum prestera_cmd_type_t type, 81362306a36Sopenharmony_ci struct prestera_msg_cmd *cmd, size_t clen, 81462306a36Sopenharmony_ci struct prestera_msg_ret *ret, size_t rlen, 81562306a36Sopenharmony_ci int waitms) 81662306a36Sopenharmony_ci{ 81762306a36Sopenharmony_ci struct prestera_device *dev = sw->dev; 81862306a36Sopenharmony_ci int err; 81962306a36Sopenharmony_ci 82062306a36Sopenharmony_ci cmd->type = __cpu_to_le32(type); 82162306a36Sopenharmony_ci 82262306a36Sopenharmony_ci err = dev->send_req(dev, 0, cmd, clen, ret, rlen, waitms); 82362306a36Sopenharmony_ci if (err) 82462306a36Sopenharmony_ci return err; 82562306a36Sopenharmony_ci 82662306a36Sopenharmony_ci if (ret->cmd.type != __cpu_to_le32(PRESTERA_CMD_TYPE_ACK)) 82762306a36Sopenharmony_ci return -EBADE; 82862306a36Sopenharmony_ci if (ret->status != __cpu_to_le32(PRESTERA_CMD_ACK_OK)) 82962306a36Sopenharmony_ci return -EINVAL; 83062306a36Sopenharmony_ci 83162306a36Sopenharmony_ci return 0; 83262306a36Sopenharmony_ci} 83362306a36Sopenharmony_ci 83462306a36Sopenharmony_cistatic int prestera_cmd_ret(struct prestera_switch *sw, 83562306a36Sopenharmony_ci enum prestera_cmd_type_t type, 83662306a36Sopenharmony_ci struct prestera_msg_cmd *cmd, size_t clen, 83762306a36Sopenharmony_ci struct prestera_msg_ret *ret, size_t rlen) 83862306a36Sopenharmony_ci{ 83962306a36Sopenharmony_ci return __prestera_cmd_ret(sw, type, cmd, clen, ret, rlen, 0); 84062306a36Sopenharmony_ci} 84162306a36Sopenharmony_ci 84262306a36Sopenharmony_cistatic int prestera_cmd_ret_wait(struct prestera_switch *sw, 84362306a36Sopenharmony_ci enum prestera_cmd_type_t type, 84462306a36Sopenharmony_ci struct prestera_msg_cmd *cmd, size_t clen, 84562306a36Sopenharmony_ci struct prestera_msg_ret *ret, size_t rlen, 84662306a36Sopenharmony_ci int waitms) 84762306a36Sopenharmony_ci{ 84862306a36Sopenharmony_ci return __prestera_cmd_ret(sw, type, cmd, clen, ret, rlen, waitms); 84962306a36Sopenharmony_ci} 85062306a36Sopenharmony_ci 85162306a36Sopenharmony_cistatic int prestera_cmd(struct prestera_switch *sw, 85262306a36Sopenharmony_ci enum prestera_cmd_type_t type, 85362306a36Sopenharmony_ci struct prestera_msg_cmd *cmd, size_t clen) 85462306a36Sopenharmony_ci{ 85562306a36Sopenharmony_ci struct prestera_msg_common_resp resp; 85662306a36Sopenharmony_ci 85762306a36Sopenharmony_ci return prestera_cmd_ret(sw, type, cmd, clen, &resp.ret, sizeof(resp)); 85862306a36Sopenharmony_ci} 85962306a36Sopenharmony_ci 86062306a36Sopenharmony_cistatic int prestera_fw_parse_port_evt(void *msg, struct prestera_event *evt) 86162306a36Sopenharmony_ci{ 86262306a36Sopenharmony_ci struct prestera_msg_event_port *hw_evt; 86362306a36Sopenharmony_ci 86462306a36Sopenharmony_ci hw_evt = (struct prestera_msg_event_port *)msg; 86562306a36Sopenharmony_ci 86662306a36Sopenharmony_ci evt->port_evt.port_id = __le32_to_cpu(hw_evt->port_id); 86762306a36Sopenharmony_ci 86862306a36Sopenharmony_ci if (evt->id == PRESTERA_PORT_EVENT_MAC_STATE_CHANGED) { 86962306a36Sopenharmony_ci evt->port_evt.data.mac.oper = hw_evt->param.mac.oper; 87062306a36Sopenharmony_ci evt->port_evt.data.mac.mode = 87162306a36Sopenharmony_ci __le32_to_cpu(hw_evt->param.mac.mode); 87262306a36Sopenharmony_ci evt->port_evt.data.mac.speed = 87362306a36Sopenharmony_ci __le32_to_cpu(hw_evt->param.mac.speed); 87462306a36Sopenharmony_ci evt->port_evt.data.mac.duplex = hw_evt->param.mac.duplex; 87562306a36Sopenharmony_ci evt->port_evt.data.mac.fc = hw_evt->param.mac.fc; 87662306a36Sopenharmony_ci evt->port_evt.data.mac.fec = hw_evt->param.mac.fec; 87762306a36Sopenharmony_ci } else { 87862306a36Sopenharmony_ci return -EINVAL; 87962306a36Sopenharmony_ci } 88062306a36Sopenharmony_ci 88162306a36Sopenharmony_ci return 0; 88262306a36Sopenharmony_ci} 88362306a36Sopenharmony_ci 88462306a36Sopenharmony_cistatic int prestera_fw_parse_fdb_evt(void *msg, struct prestera_event *evt) 88562306a36Sopenharmony_ci{ 88662306a36Sopenharmony_ci struct prestera_msg_event_fdb *hw_evt = msg; 88762306a36Sopenharmony_ci 88862306a36Sopenharmony_ci switch (hw_evt->dest_type) { 88962306a36Sopenharmony_ci case PRESTERA_HW_FDB_ENTRY_TYPE_REG_PORT: 89062306a36Sopenharmony_ci evt->fdb_evt.type = PRESTERA_FDB_ENTRY_TYPE_REG_PORT; 89162306a36Sopenharmony_ci evt->fdb_evt.dest.port_id = __le32_to_cpu(hw_evt->dest.port_id); 89262306a36Sopenharmony_ci break; 89362306a36Sopenharmony_ci case PRESTERA_HW_FDB_ENTRY_TYPE_LAG: 89462306a36Sopenharmony_ci evt->fdb_evt.type = PRESTERA_FDB_ENTRY_TYPE_LAG; 89562306a36Sopenharmony_ci evt->fdb_evt.dest.lag_id = __le16_to_cpu(hw_evt->dest.lag_id); 89662306a36Sopenharmony_ci break; 89762306a36Sopenharmony_ci default: 89862306a36Sopenharmony_ci return -EINVAL; 89962306a36Sopenharmony_ci } 90062306a36Sopenharmony_ci 90162306a36Sopenharmony_ci evt->fdb_evt.vid = __le32_to_cpu(hw_evt->vid); 90262306a36Sopenharmony_ci 90362306a36Sopenharmony_ci ether_addr_copy(evt->fdb_evt.data.mac, hw_evt->param.mac); 90462306a36Sopenharmony_ci 90562306a36Sopenharmony_ci return 0; 90662306a36Sopenharmony_ci} 90762306a36Sopenharmony_ci 90862306a36Sopenharmony_cistatic struct prestera_fw_evt_parser { 90962306a36Sopenharmony_ci int (*func)(void *msg, struct prestera_event *evt); 91062306a36Sopenharmony_ci} fw_event_parsers[PRESTERA_EVENT_TYPE_MAX] = { 91162306a36Sopenharmony_ci [PRESTERA_EVENT_TYPE_PORT] = { .func = prestera_fw_parse_port_evt }, 91262306a36Sopenharmony_ci [PRESTERA_EVENT_TYPE_FDB] = { .func = prestera_fw_parse_fdb_evt }, 91362306a36Sopenharmony_ci}; 91462306a36Sopenharmony_ci 91562306a36Sopenharmony_cistatic struct prestera_fw_event_handler * 91662306a36Sopenharmony_ci__find_event_handler(const struct prestera_switch *sw, 91762306a36Sopenharmony_ci enum prestera_event_type type) 91862306a36Sopenharmony_ci{ 91962306a36Sopenharmony_ci struct prestera_fw_event_handler *eh; 92062306a36Sopenharmony_ci 92162306a36Sopenharmony_ci list_for_each_entry_rcu(eh, &sw->event_handlers, list) { 92262306a36Sopenharmony_ci if (eh->type == type) 92362306a36Sopenharmony_ci return eh; 92462306a36Sopenharmony_ci } 92562306a36Sopenharmony_ci 92662306a36Sopenharmony_ci return NULL; 92762306a36Sopenharmony_ci} 92862306a36Sopenharmony_ci 92962306a36Sopenharmony_cistatic int prestera_find_event_handler(const struct prestera_switch *sw, 93062306a36Sopenharmony_ci enum prestera_event_type type, 93162306a36Sopenharmony_ci struct prestera_fw_event_handler *eh) 93262306a36Sopenharmony_ci{ 93362306a36Sopenharmony_ci struct prestera_fw_event_handler *tmp; 93462306a36Sopenharmony_ci int err = 0; 93562306a36Sopenharmony_ci 93662306a36Sopenharmony_ci rcu_read_lock(); 93762306a36Sopenharmony_ci tmp = __find_event_handler(sw, type); 93862306a36Sopenharmony_ci if (tmp) 93962306a36Sopenharmony_ci *eh = *tmp; 94062306a36Sopenharmony_ci else 94162306a36Sopenharmony_ci err = -ENOENT; 94262306a36Sopenharmony_ci rcu_read_unlock(); 94362306a36Sopenharmony_ci 94462306a36Sopenharmony_ci return err; 94562306a36Sopenharmony_ci} 94662306a36Sopenharmony_ci 94762306a36Sopenharmony_cistatic int prestera_evt_recv(struct prestera_device *dev, void *buf, size_t size) 94862306a36Sopenharmony_ci{ 94962306a36Sopenharmony_ci struct prestera_switch *sw = dev->priv; 95062306a36Sopenharmony_ci struct prestera_msg_event *msg = buf; 95162306a36Sopenharmony_ci struct prestera_fw_event_handler eh; 95262306a36Sopenharmony_ci struct prestera_event evt; 95362306a36Sopenharmony_ci u16 msg_type; 95462306a36Sopenharmony_ci int err; 95562306a36Sopenharmony_ci 95662306a36Sopenharmony_ci msg_type = __le16_to_cpu(msg->type); 95762306a36Sopenharmony_ci if (msg_type >= PRESTERA_EVENT_TYPE_MAX) 95862306a36Sopenharmony_ci return -EINVAL; 95962306a36Sopenharmony_ci if (!fw_event_parsers[msg_type].func) 96062306a36Sopenharmony_ci return -ENOENT; 96162306a36Sopenharmony_ci 96262306a36Sopenharmony_ci err = prestera_find_event_handler(sw, msg_type, &eh); 96362306a36Sopenharmony_ci if (err) 96462306a36Sopenharmony_ci return err; 96562306a36Sopenharmony_ci 96662306a36Sopenharmony_ci evt.id = __le16_to_cpu(msg->id); 96762306a36Sopenharmony_ci 96862306a36Sopenharmony_ci err = fw_event_parsers[msg_type].func(buf, &evt); 96962306a36Sopenharmony_ci if (err) 97062306a36Sopenharmony_ci return err; 97162306a36Sopenharmony_ci 97262306a36Sopenharmony_ci eh.func(sw, &evt, eh.arg); 97362306a36Sopenharmony_ci 97462306a36Sopenharmony_ci return 0; 97562306a36Sopenharmony_ci} 97662306a36Sopenharmony_ci 97762306a36Sopenharmony_cistatic void prestera_pkt_recv(struct prestera_device *dev) 97862306a36Sopenharmony_ci{ 97962306a36Sopenharmony_ci struct prestera_switch *sw = dev->priv; 98062306a36Sopenharmony_ci struct prestera_fw_event_handler eh; 98162306a36Sopenharmony_ci struct prestera_event ev; 98262306a36Sopenharmony_ci int err; 98362306a36Sopenharmony_ci 98462306a36Sopenharmony_ci ev.id = PRESTERA_RXTX_EVENT_RCV_PKT; 98562306a36Sopenharmony_ci 98662306a36Sopenharmony_ci err = prestera_find_event_handler(sw, PRESTERA_EVENT_TYPE_RXTX, &eh); 98762306a36Sopenharmony_ci if (err) 98862306a36Sopenharmony_ci return; 98962306a36Sopenharmony_ci 99062306a36Sopenharmony_ci eh.func(sw, &ev, eh.arg); 99162306a36Sopenharmony_ci} 99262306a36Sopenharmony_ci 99362306a36Sopenharmony_cistatic u8 prestera_hw_mdix_to_eth(u8 mode) 99462306a36Sopenharmony_ci{ 99562306a36Sopenharmony_ci switch (mode) { 99662306a36Sopenharmony_ci case PRESTERA_PORT_TP_MDI: 99762306a36Sopenharmony_ci return ETH_TP_MDI; 99862306a36Sopenharmony_ci case PRESTERA_PORT_TP_MDIX: 99962306a36Sopenharmony_ci return ETH_TP_MDI_X; 100062306a36Sopenharmony_ci case PRESTERA_PORT_TP_AUTO: 100162306a36Sopenharmony_ci return ETH_TP_MDI_AUTO; 100262306a36Sopenharmony_ci default: 100362306a36Sopenharmony_ci return ETH_TP_MDI_INVALID; 100462306a36Sopenharmony_ci } 100562306a36Sopenharmony_ci} 100662306a36Sopenharmony_ci 100762306a36Sopenharmony_cistatic u8 prestera_hw_mdix_from_eth(u8 mode) 100862306a36Sopenharmony_ci{ 100962306a36Sopenharmony_ci switch (mode) { 101062306a36Sopenharmony_ci case ETH_TP_MDI: 101162306a36Sopenharmony_ci return PRESTERA_PORT_TP_MDI; 101262306a36Sopenharmony_ci case ETH_TP_MDI_X: 101362306a36Sopenharmony_ci return PRESTERA_PORT_TP_MDIX; 101462306a36Sopenharmony_ci case ETH_TP_MDI_AUTO: 101562306a36Sopenharmony_ci return PRESTERA_PORT_TP_AUTO; 101662306a36Sopenharmony_ci default: 101762306a36Sopenharmony_ci return PRESTERA_PORT_TP_NA; 101862306a36Sopenharmony_ci } 101962306a36Sopenharmony_ci} 102062306a36Sopenharmony_ci 102162306a36Sopenharmony_ciint prestera_hw_port_info_get(const struct prestera_port *port, 102262306a36Sopenharmony_ci u32 *dev_id, u32 *hw_id, u16 *fp_id) 102362306a36Sopenharmony_ci{ 102462306a36Sopenharmony_ci struct prestera_msg_port_info_req req = { 102562306a36Sopenharmony_ci .port = __cpu_to_le32(port->id), 102662306a36Sopenharmony_ci }; 102762306a36Sopenharmony_ci struct prestera_msg_port_info_resp resp; 102862306a36Sopenharmony_ci int err; 102962306a36Sopenharmony_ci 103062306a36Sopenharmony_ci err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_INFO_GET, 103162306a36Sopenharmony_ci &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 103262306a36Sopenharmony_ci if (err) 103362306a36Sopenharmony_ci return err; 103462306a36Sopenharmony_ci 103562306a36Sopenharmony_ci *dev_id = __le32_to_cpu(resp.dev_id); 103662306a36Sopenharmony_ci *hw_id = __le32_to_cpu(resp.hw_id); 103762306a36Sopenharmony_ci *fp_id = __le16_to_cpu(resp.fp_id); 103862306a36Sopenharmony_ci 103962306a36Sopenharmony_ci return 0; 104062306a36Sopenharmony_ci} 104162306a36Sopenharmony_ci 104262306a36Sopenharmony_ciint prestera_hw_switch_mac_set(struct prestera_switch *sw, const char *mac) 104362306a36Sopenharmony_ci{ 104462306a36Sopenharmony_ci struct prestera_msg_switch_attr_req req = { 104562306a36Sopenharmony_ci .attr = __cpu_to_le32(PRESTERA_CMD_SWITCH_ATTR_MAC), 104662306a36Sopenharmony_ci }; 104762306a36Sopenharmony_ci 104862306a36Sopenharmony_ci ether_addr_copy(req.param.mac, mac); 104962306a36Sopenharmony_ci 105062306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_SWITCH_ATTR_SET, 105162306a36Sopenharmony_ci &req.cmd, sizeof(req)); 105262306a36Sopenharmony_ci} 105362306a36Sopenharmony_ci 105462306a36Sopenharmony_ciint prestera_hw_switch_init(struct prestera_switch *sw) 105562306a36Sopenharmony_ci{ 105662306a36Sopenharmony_ci struct prestera_msg_switch_init_resp resp; 105762306a36Sopenharmony_ci struct prestera_msg_common_req req; 105862306a36Sopenharmony_ci int err; 105962306a36Sopenharmony_ci 106062306a36Sopenharmony_ci INIT_LIST_HEAD(&sw->event_handlers); 106162306a36Sopenharmony_ci 106262306a36Sopenharmony_ci prestera_hw_build_tests(); 106362306a36Sopenharmony_ci 106462306a36Sopenharmony_ci err = prestera_cmd_ret_wait(sw, PRESTERA_CMD_TYPE_SWITCH_INIT, 106562306a36Sopenharmony_ci &req.cmd, sizeof(req), 106662306a36Sopenharmony_ci &resp.ret, sizeof(resp), 106762306a36Sopenharmony_ci PRESTERA_SWITCH_INIT_TIMEOUT_MS); 106862306a36Sopenharmony_ci if (err) 106962306a36Sopenharmony_ci return err; 107062306a36Sopenharmony_ci 107162306a36Sopenharmony_ci sw->dev->recv_msg = prestera_evt_recv; 107262306a36Sopenharmony_ci sw->dev->recv_pkt = prestera_pkt_recv; 107362306a36Sopenharmony_ci sw->port_count = __le32_to_cpu(resp.port_count); 107462306a36Sopenharmony_ci sw->mtu_min = PRESTERA_MIN_MTU; 107562306a36Sopenharmony_ci sw->mtu_max = __le32_to_cpu(resp.mtu_max); 107662306a36Sopenharmony_ci sw->id = resp.switch_id; 107762306a36Sopenharmony_ci sw->lag_member_max = resp.lag_member_max; 107862306a36Sopenharmony_ci sw->lag_max = resp.lag_max; 107962306a36Sopenharmony_ci sw->size_tbl_router_nexthop = 108062306a36Sopenharmony_ci __le32_to_cpu(resp.size_tbl_router_nexthop); 108162306a36Sopenharmony_ci 108262306a36Sopenharmony_ci return 0; 108362306a36Sopenharmony_ci} 108462306a36Sopenharmony_ci 108562306a36Sopenharmony_civoid prestera_hw_switch_fini(struct prestera_switch *sw) 108662306a36Sopenharmony_ci{ 108762306a36Sopenharmony_ci WARN_ON(!list_empty(&sw->event_handlers)); 108862306a36Sopenharmony_ci} 108962306a36Sopenharmony_ci 109062306a36Sopenharmony_ciint prestera_hw_switch_ageing_set(struct prestera_switch *sw, u32 ageing_ms) 109162306a36Sopenharmony_ci{ 109262306a36Sopenharmony_ci struct prestera_msg_switch_attr_req req = { 109362306a36Sopenharmony_ci .attr = __cpu_to_le32(PRESTERA_CMD_SWITCH_ATTR_AGEING), 109462306a36Sopenharmony_ci .param = { 109562306a36Sopenharmony_ci .ageing_timeout_ms = __cpu_to_le32(ageing_ms), 109662306a36Sopenharmony_ci }, 109762306a36Sopenharmony_ci }; 109862306a36Sopenharmony_ci 109962306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_SWITCH_ATTR_SET, 110062306a36Sopenharmony_ci &req.cmd, sizeof(req)); 110162306a36Sopenharmony_ci} 110262306a36Sopenharmony_ci 110362306a36Sopenharmony_ciint prestera_hw_port_mac_mode_get(const struct prestera_port *port, 110462306a36Sopenharmony_ci u32 *mode, u32 *speed, u8 *duplex, u8 *fec) 110562306a36Sopenharmony_ci{ 110662306a36Sopenharmony_ci struct prestera_msg_port_attr_resp resp; 110762306a36Sopenharmony_ci struct prestera_msg_port_attr_req req = { 110862306a36Sopenharmony_ci .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_MAC_MODE), 110962306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 111062306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id) 111162306a36Sopenharmony_ci }; 111262306a36Sopenharmony_ci int err; 111362306a36Sopenharmony_ci 111462306a36Sopenharmony_ci err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET, 111562306a36Sopenharmony_ci &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 111662306a36Sopenharmony_ci if (err) 111762306a36Sopenharmony_ci return err; 111862306a36Sopenharmony_ci 111962306a36Sopenharmony_ci if (mode) 112062306a36Sopenharmony_ci *mode = __le32_to_cpu(resp.param.link_evt.mac.mode); 112162306a36Sopenharmony_ci 112262306a36Sopenharmony_ci if (speed) 112362306a36Sopenharmony_ci *speed = __le32_to_cpu(resp.param.link_evt.mac.speed); 112462306a36Sopenharmony_ci 112562306a36Sopenharmony_ci if (duplex) 112662306a36Sopenharmony_ci *duplex = resp.param.link_evt.mac.duplex; 112762306a36Sopenharmony_ci 112862306a36Sopenharmony_ci if (fec) 112962306a36Sopenharmony_ci *fec = resp.param.link_evt.mac.fec; 113062306a36Sopenharmony_ci 113162306a36Sopenharmony_ci return err; 113262306a36Sopenharmony_ci} 113362306a36Sopenharmony_ci 113462306a36Sopenharmony_ciint prestera_hw_port_mac_mode_set(const struct prestera_port *port, 113562306a36Sopenharmony_ci bool admin, u32 mode, u8 inband, 113662306a36Sopenharmony_ci u32 speed, u8 duplex, u8 fec) 113762306a36Sopenharmony_ci{ 113862306a36Sopenharmony_ci struct prestera_msg_port_attr_req req = { 113962306a36Sopenharmony_ci .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_MAC_MODE), 114062306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 114162306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 114262306a36Sopenharmony_ci .param = { 114362306a36Sopenharmony_ci .link = { 114462306a36Sopenharmony_ci .mac = { 114562306a36Sopenharmony_ci .admin = admin, 114662306a36Sopenharmony_ci .reg_mode.mode = __cpu_to_le32(mode), 114762306a36Sopenharmony_ci .reg_mode.inband = inband, 114862306a36Sopenharmony_ci .reg_mode.speed = __cpu_to_le32(speed), 114962306a36Sopenharmony_ci .reg_mode.duplex = duplex, 115062306a36Sopenharmony_ci .reg_mode.fec = fec 115162306a36Sopenharmony_ci } 115262306a36Sopenharmony_ci } 115362306a36Sopenharmony_ci } 115462306a36Sopenharmony_ci }; 115562306a36Sopenharmony_ci 115662306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, 115762306a36Sopenharmony_ci &req.cmd, sizeof(req)); 115862306a36Sopenharmony_ci} 115962306a36Sopenharmony_ci 116062306a36Sopenharmony_ciint prestera_hw_port_phy_mode_get(const struct prestera_port *port, 116162306a36Sopenharmony_ci u8 *mdix, u64 *lmode_bmap, 116262306a36Sopenharmony_ci bool *fc_pause, bool *fc_asym) 116362306a36Sopenharmony_ci{ 116462306a36Sopenharmony_ci struct prestera_msg_port_attr_resp resp; 116562306a36Sopenharmony_ci struct prestera_msg_port_attr_req req = { 116662306a36Sopenharmony_ci .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_PHY_MODE), 116762306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 116862306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id) 116962306a36Sopenharmony_ci }; 117062306a36Sopenharmony_ci int err; 117162306a36Sopenharmony_ci 117262306a36Sopenharmony_ci err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET, 117362306a36Sopenharmony_ci &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 117462306a36Sopenharmony_ci if (err) 117562306a36Sopenharmony_ci return err; 117662306a36Sopenharmony_ci 117762306a36Sopenharmony_ci if (mdix) 117862306a36Sopenharmony_ci *mdix = prestera_hw_mdix_to_eth(resp.param.link_evt.phy.mdix); 117962306a36Sopenharmony_ci 118062306a36Sopenharmony_ci if (lmode_bmap) 118162306a36Sopenharmony_ci *lmode_bmap = __le64_to_cpu(resp.param.link_evt.phy.lmode_bmap); 118262306a36Sopenharmony_ci 118362306a36Sopenharmony_ci if (fc_pause && fc_asym) 118462306a36Sopenharmony_ci prestera_hw_remote_fc_to_eth(resp.param.link_evt.phy.fc, 118562306a36Sopenharmony_ci fc_pause, fc_asym); 118662306a36Sopenharmony_ci 118762306a36Sopenharmony_ci return err; 118862306a36Sopenharmony_ci} 118962306a36Sopenharmony_ci 119062306a36Sopenharmony_ciint prestera_hw_port_phy_mode_set(const struct prestera_port *port, 119162306a36Sopenharmony_ci bool admin, bool adv, u32 mode, u64 modes, 119262306a36Sopenharmony_ci u8 mdix) 119362306a36Sopenharmony_ci{ 119462306a36Sopenharmony_ci struct prestera_msg_port_attr_req req = { 119562306a36Sopenharmony_ci .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_PHY_MODE), 119662306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 119762306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 119862306a36Sopenharmony_ci .param = { 119962306a36Sopenharmony_ci .link = { 120062306a36Sopenharmony_ci .phy = { 120162306a36Sopenharmony_ci .admin = admin, 120262306a36Sopenharmony_ci .adv_enable = adv ? 1 : 0, 120362306a36Sopenharmony_ci .mode = __cpu_to_le32(mode), 120462306a36Sopenharmony_ci .modes = __cpu_to_le64(modes), 120562306a36Sopenharmony_ci } 120662306a36Sopenharmony_ci } 120762306a36Sopenharmony_ci } 120862306a36Sopenharmony_ci }; 120962306a36Sopenharmony_ci 121062306a36Sopenharmony_ci req.param.link.phy.mdix = prestera_hw_mdix_from_eth(mdix); 121162306a36Sopenharmony_ci 121262306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, 121362306a36Sopenharmony_ci &req.cmd, sizeof(req)); 121462306a36Sopenharmony_ci} 121562306a36Sopenharmony_ci 121662306a36Sopenharmony_ciint prestera_hw_port_mtu_set(const struct prestera_port *port, u32 mtu) 121762306a36Sopenharmony_ci{ 121862306a36Sopenharmony_ci struct prestera_msg_port_attr_req req = { 121962306a36Sopenharmony_ci .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_MTU), 122062306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 122162306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 122262306a36Sopenharmony_ci .param = { 122362306a36Sopenharmony_ci .mtu = __cpu_to_le32(mtu), 122462306a36Sopenharmony_ci } 122562306a36Sopenharmony_ci }; 122662306a36Sopenharmony_ci 122762306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, 122862306a36Sopenharmony_ci &req.cmd, sizeof(req)); 122962306a36Sopenharmony_ci} 123062306a36Sopenharmony_ci 123162306a36Sopenharmony_ciint prestera_hw_port_mac_set(const struct prestera_port *port, const char *mac) 123262306a36Sopenharmony_ci{ 123362306a36Sopenharmony_ci struct prestera_msg_port_attr_req req = { 123462306a36Sopenharmony_ci .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_MAC), 123562306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 123662306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 123762306a36Sopenharmony_ci }; 123862306a36Sopenharmony_ci 123962306a36Sopenharmony_ci ether_addr_copy(req.param.mac, mac); 124062306a36Sopenharmony_ci 124162306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, 124262306a36Sopenharmony_ci &req.cmd, sizeof(req)); 124362306a36Sopenharmony_ci} 124462306a36Sopenharmony_ci 124562306a36Sopenharmony_ciint prestera_hw_port_accept_frm_type(struct prestera_port *port, 124662306a36Sopenharmony_ci enum prestera_accept_frm_type type) 124762306a36Sopenharmony_ci{ 124862306a36Sopenharmony_ci struct prestera_msg_port_attr_req req = { 124962306a36Sopenharmony_ci .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_ACCEPT_FRAME_TYPE), 125062306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 125162306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 125262306a36Sopenharmony_ci .param = { 125362306a36Sopenharmony_ci .accept_frm_type = type, 125462306a36Sopenharmony_ci } 125562306a36Sopenharmony_ci }; 125662306a36Sopenharmony_ci 125762306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, 125862306a36Sopenharmony_ci &req.cmd, sizeof(req)); 125962306a36Sopenharmony_ci} 126062306a36Sopenharmony_ci 126162306a36Sopenharmony_ciint prestera_hw_port_cap_get(const struct prestera_port *port, 126262306a36Sopenharmony_ci struct prestera_port_caps *caps) 126362306a36Sopenharmony_ci{ 126462306a36Sopenharmony_ci struct prestera_msg_port_attr_req req = { 126562306a36Sopenharmony_ci .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_CAPABILITY), 126662306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 126762306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 126862306a36Sopenharmony_ci }; 126962306a36Sopenharmony_ci struct prestera_msg_port_attr_resp resp; 127062306a36Sopenharmony_ci int err; 127162306a36Sopenharmony_ci 127262306a36Sopenharmony_ci err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET, 127362306a36Sopenharmony_ci &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 127462306a36Sopenharmony_ci if (err) 127562306a36Sopenharmony_ci return err; 127662306a36Sopenharmony_ci 127762306a36Sopenharmony_ci caps->supp_link_modes = __le64_to_cpu(resp.param.cap.link_mode); 127862306a36Sopenharmony_ci caps->transceiver = resp.param.cap.transceiver; 127962306a36Sopenharmony_ci caps->supp_fec = resp.param.cap.fec; 128062306a36Sopenharmony_ci caps->type = resp.param.cap.type; 128162306a36Sopenharmony_ci 128262306a36Sopenharmony_ci return err; 128362306a36Sopenharmony_ci} 128462306a36Sopenharmony_ci 128562306a36Sopenharmony_cistatic void prestera_hw_remote_fc_to_eth(u8 fc, bool *pause, bool *asym_pause) 128662306a36Sopenharmony_ci{ 128762306a36Sopenharmony_ci switch (fc) { 128862306a36Sopenharmony_ci case PRESTERA_FC_SYMMETRIC: 128962306a36Sopenharmony_ci *pause = true; 129062306a36Sopenharmony_ci *asym_pause = false; 129162306a36Sopenharmony_ci break; 129262306a36Sopenharmony_ci case PRESTERA_FC_ASYMMETRIC: 129362306a36Sopenharmony_ci *pause = false; 129462306a36Sopenharmony_ci *asym_pause = true; 129562306a36Sopenharmony_ci break; 129662306a36Sopenharmony_ci case PRESTERA_FC_SYMM_ASYMM: 129762306a36Sopenharmony_ci *pause = true; 129862306a36Sopenharmony_ci *asym_pause = true; 129962306a36Sopenharmony_ci break; 130062306a36Sopenharmony_ci default: 130162306a36Sopenharmony_ci *pause = false; 130262306a36Sopenharmony_ci *asym_pause = false; 130362306a36Sopenharmony_ci } 130462306a36Sopenharmony_ci} 130562306a36Sopenharmony_ci 130662306a36Sopenharmony_ciint prestera_hw_vtcam_create(struct prestera_switch *sw, 130762306a36Sopenharmony_ci u8 lookup, const u32 *keymask, u32 *vtcam_id, 130862306a36Sopenharmony_ci enum prestera_hw_vtcam_direction_t dir) 130962306a36Sopenharmony_ci{ 131062306a36Sopenharmony_ci int err; 131162306a36Sopenharmony_ci struct prestera_msg_vtcam_resp resp; 131262306a36Sopenharmony_ci struct prestera_msg_vtcam_create_req req = { 131362306a36Sopenharmony_ci .lookup = lookup, 131462306a36Sopenharmony_ci .direction = dir, 131562306a36Sopenharmony_ci }; 131662306a36Sopenharmony_ci 131762306a36Sopenharmony_ci if (keymask) 131862306a36Sopenharmony_ci memcpy(req.keymask, keymask, sizeof(req.keymask)); 131962306a36Sopenharmony_ci else 132062306a36Sopenharmony_ci memset(req.keymask, 0, sizeof(req.keymask)); 132162306a36Sopenharmony_ci 132262306a36Sopenharmony_ci err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_VTCAM_CREATE, 132362306a36Sopenharmony_ci &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 132462306a36Sopenharmony_ci if (err) 132562306a36Sopenharmony_ci return err; 132662306a36Sopenharmony_ci 132762306a36Sopenharmony_ci *vtcam_id = __le32_to_cpu(resp.vtcam_id); 132862306a36Sopenharmony_ci return 0; 132962306a36Sopenharmony_ci} 133062306a36Sopenharmony_ci 133162306a36Sopenharmony_ciint prestera_hw_vtcam_destroy(struct prestera_switch *sw, u32 vtcam_id) 133262306a36Sopenharmony_ci{ 133362306a36Sopenharmony_ci struct prestera_msg_vtcam_destroy_req req = { 133462306a36Sopenharmony_ci .vtcam_id = __cpu_to_le32(vtcam_id), 133562306a36Sopenharmony_ci }; 133662306a36Sopenharmony_ci 133762306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_VTCAM_DESTROY, 133862306a36Sopenharmony_ci &req.cmd, sizeof(req)); 133962306a36Sopenharmony_ci} 134062306a36Sopenharmony_ci 134162306a36Sopenharmony_cistatic int 134262306a36Sopenharmony_ciprestera_acl_rule_add_put_action(struct prestera_msg_acl_action *action, 134362306a36Sopenharmony_ci struct prestera_acl_hw_action_info *info) 134462306a36Sopenharmony_ci{ 134562306a36Sopenharmony_ci action->id = __cpu_to_le32(info->id); 134662306a36Sopenharmony_ci 134762306a36Sopenharmony_ci switch (info->id) { 134862306a36Sopenharmony_ci case PRESTERA_ACL_RULE_ACTION_ACCEPT: 134962306a36Sopenharmony_ci case PRESTERA_ACL_RULE_ACTION_DROP: 135062306a36Sopenharmony_ci case PRESTERA_ACL_RULE_ACTION_TRAP: 135162306a36Sopenharmony_ci /* just rule action id, no specific data */ 135262306a36Sopenharmony_ci break; 135362306a36Sopenharmony_ci case PRESTERA_ACL_RULE_ACTION_JUMP: 135462306a36Sopenharmony_ci action->jump.index = __cpu_to_le32(info->jump.index); 135562306a36Sopenharmony_ci break; 135662306a36Sopenharmony_ci case PRESTERA_ACL_RULE_ACTION_POLICE: 135762306a36Sopenharmony_ci action->police.id = __cpu_to_le32(info->police.id); 135862306a36Sopenharmony_ci break; 135962306a36Sopenharmony_ci case PRESTERA_ACL_RULE_ACTION_COUNT: 136062306a36Sopenharmony_ci action->count.id = __cpu_to_le32(info->count.id); 136162306a36Sopenharmony_ci break; 136262306a36Sopenharmony_ci default: 136362306a36Sopenharmony_ci return -EINVAL; 136462306a36Sopenharmony_ci } 136562306a36Sopenharmony_ci 136662306a36Sopenharmony_ci return 0; 136762306a36Sopenharmony_ci} 136862306a36Sopenharmony_ci 136962306a36Sopenharmony_ciint prestera_hw_vtcam_rule_add(struct prestera_switch *sw, 137062306a36Sopenharmony_ci u32 vtcam_id, u32 prio, void *key, void *keymask, 137162306a36Sopenharmony_ci struct prestera_acl_hw_action_info *act, 137262306a36Sopenharmony_ci u8 n_act, u32 *rule_id) 137362306a36Sopenharmony_ci{ 137462306a36Sopenharmony_ci struct prestera_msg_acl_action *actions_msg; 137562306a36Sopenharmony_ci struct prestera_msg_vtcam_rule_add_req *req; 137662306a36Sopenharmony_ci struct prestera_msg_vtcam_resp resp; 137762306a36Sopenharmony_ci void *buff; 137862306a36Sopenharmony_ci u32 size; 137962306a36Sopenharmony_ci int err; 138062306a36Sopenharmony_ci u8 i; 138162306a36Sopenharmony_ci 138262306a36Sopenharmony_ci size = sizeof(*req) + sizeof(*actions_msg) * n_act; 138362306a36Sopenharmony_ci 138462306a36Sopenharmony_ci buff = kzalloc(size, GFP_KERNEL); 138562306a36Sopenharmony_ci if (!buff) 138662306a36Sopenharmony_ci return -ENOMEM; 138762306a36Sopenharmony_ci 138862306a36Sopenharmony_ci req = buff; 138962306a36Sopenharmony_ci req->n_act = __cpu_to_le32(n_act); 139062306a36Sopenharmony_ci actions_msg = buff + sizeof(*req); 139162306a36Sopenharmony_ci 139262306a36Sopenharmony_ci /* put acl matches into the message */ 139362306a36Sopenharmony_ci memcpy(req->key, key, sizeof(req->key)); 139462306a36Sopenharmony_ci memcpy(req->keymask, keymask, sizeof(req->keymask)); 139562306a36Sopenharmony_ci 139662306a36Sopenharmony_ci /* put acl actions into the message */ 139762306a36Sopenharmony_ci for (i = 0; i < n_act; i++) { 139862306a36Sopenharmony_ci err = prestera_acl_rule_add_put_action(&actions_msg[i], 139962306a36Sopenharmony_ci &act[i]); 140062306a36Sopenharmony_ci if (err) 140162306a36Sopenharmony_ci goto free_buff; 140262306a36Sopenharmony_ci } 140362306a36Sopenharmony_ci 140462306a36Sopenharmony_ci req->vtcam_id = __cpu_to_le32(vtcam_id); 140562306a36Sopenharmony_ci req->prio = __cpu_to_le32(prio); 140662306a36Sopenharmony_ci 140762306a36Sopenharmony_ci err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_VTCAM_RULE_ADD, 140862306a36Sopenharmony_ci &req->cmd, size, &resp.ret, sizeof(resp)); 140962306a36Sopenharmony_ci if (err) 141062306a36Sopenharmony_ci goto free_buff; 141162306a36Sopenharmony_ci 141262306a36Sopenharmony_ci *rule_id = __le32_to_cpu(resp.rule_id); 141362306a36Sopenharmony_cifree_buff: 141462306a36Sopenharmony_ci kfree(buff); 141562306a36Sopenharmony_ci return err; 141662306a36Sopenharmony_ci} 141762306a36Sopenharmony_ci 141862306a36Sopenharmony_ciint prestera_hw_vtcam_rule_del(struct prestera_switch *sw, 141962306a36Sopenharmony_ci u32 vtcam_id, u32 rule_id) 142062306a36Sopenharmony_ci{ 142162306a36Sopenharmony_ci struct prestera_msg_vtcam_rule_del_req req = { 142262306a36Sopenharmony_ci .vtcam_id = __cpu_to_le32(vtcam_id), 142362306a36Sopenharmony_ci .id = __cpu_to_le32(rule_id) 142462306a36Sopenharmony_ci }; 142562306a36Sopenharmony_ci 142662306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_VTCAM_RULE_DELETE, 142762306a36Sopenharmony_ci &req.cmd, sizeof(req)); 142862306a36Sopenharmony_ci} 142962306a36Sopenharmony_ci 143062306a36Sopenharmony_ciint prestera_hw_vtcam_iface_bind(struct prestera_switch *sw, 143162306a36Sopenharmony_ci struct prestera_acl_iface *iface, 143262306a36Sopenharmony_ci u32 vtcam_id, u16 pcl_id) 143362306a36Sopenharmony_ci{ 143462306a36Sopenharmony_ci struct prestera_msg_vtcam_bind_req req = { 143562306a36Sopenharmony_ci .vtcam_id = __cpu_to_le32(vtcam_id), 143662306a36Sopenharmony_ci .type = __cpu_to_le16(iface->type), 143762306a36Sopenharmony_ci .pcl_id = __cpu_to_le16(pcl_id) 143862306a36Sopenharmony_ci }; 143962306a36Sopenharmony_ci 144062306a36Sopenharmony_ci if (iface->type == PRESTERA_ACL_IFACE_TYPE_PORT) { 144162306a36Sopenharmony_ci req.port.dev_id = __cpu_to_le32(iface->port->dev_id); 144262306a36Sopenharmony_ci req.port.hw_id = __cpu_to_le32(iface->port->hw_id); 144362306a36Sopenharmony_ci } else { 144462306a36Sopenharmony_ci req.index = __cpu_to_le32(iface->index); 144562306a36Sopenharmony_ci } 144662306a36Sopenharmony_ci 144762306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_VTCAM_IFACE_BIND, 144862306a36Sopenharmony_ci &req.cmd, sizeof(req)); 144962306a36Sopenharmony_ci} 145062306a36Sopenharmony_ci 145162306a36Sopenharmony_ciint prestera_hw_vtcam_iface_unbind(struct prestera_switch *sw, 145262306a36Sopenharmony_ci struct prestera_acl_iface *iface, 145362306a36Sopenharmony_ci u32 vtcam_id) 145462306a36Sopenharmony_ci{ 145562306a36Sopenharmony_ci struct prestera_msg_vtcam_bind_req req = { 145662306a36Sopenharmony_ci .vtcam_id = __cpu_to_le32(vtcam_id), 145762306a36Sopenharmony_ci .type = __cpu_to_le16(iface->type) 145862306a36Sopenharmony_ci }; 145962306a36Sopenharmony_ci 146062306a36Sopenharmony_ci if (iface->type == PRESTERA_ACL_IFACE_TYPE_PORT) { 146162306a36Sopenharmony_ci req.port.dev_id = __cpu_to_le32(iface->port->dev_id); 146262306a36Sopenharmony_ci req.port.hw_id = __cpu_to_le32(iface->port->hw_id); 146362306a36Sopenharmony_ci } else { 146462306a36Sopenharmony_ci req.index = __cpu_to_le32(iface->index); 146562306a36Sopenharmony_ci } 146662306a36Sopenharmony_ci 146762306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_VTCAM_IFACE_UNBIND, 146862306a36Sopenharmony_ci &req.cmd, sizeof(req)); 146962306a36Sopenharmony_ci} 147062306a36Sopenharmony_ci 147162306a36Sopenharmony_ciint prestera_hw_span_get(const struct prestera_port *port, u8 *span_id) 147262306a36Sopenharmony_ci{ 147362306a36Sopenharmony_ci struct prestera_msg_span_resp resp; 147462306a36Sopenharmony_ci struct prestera_msg_span_req req = { 147562306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 147662306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 147762306a36Sopenharmony_ci }; 147862306a36Sopenharmony_ci int err; 147962306a36Sopenharmony_ci 148062306a36Sopenharmony_ci err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_SPAN_GET, 148162306a36Sopenharmony_ci &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 148262306a36Sopenharmony_ci if (err) 148362306a36Sopenharmony_ci return err; 148462306a36Sopenharmony_ci 148562306a36Sopenharmony_ci *span_id = resp.id; 148662306a36Sopenharmony_ci 148762306a36Sopenharmony_ci return 0; 148862306a36Sopenharmony_ci} 148962306a36Sopenharmony_ci 149062306a36Sopenharmony_ciint prestera_hw_span_bind(const struct prestera_port *port, u8 span_id, 149162306a36Sopenharmony_ci bool ingress) 149262306a36Sopenharmony_ci{ 149362306a36Sopenharmony_ci struct prestera_msg_span_req req = { 149462306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 149562306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 149662306a36Sopenharmony_ci .id = span_id, 149762306a36Sopenharmony_ci }; 149862306a36Sopenharmony_ci enum prestera_cmd_type_t cmd_type; 149962306a36Sopenharmony_ci 150062306a36Sopenharmony_ci if (ingress) 150162306a36Sopenharmony_ci cmd_type = PRESTERA_CMD_TYPE_SPAN_INGRESS_BIND; 150262306a36Sopenharmony_ci else 150362306a36Sopenharmony_ci cmd_type = PRESTERA_CMD_TYPE_SPAN_EGRESS_BIND; 150462306a36Sopenharmony_ci 150562306a36Sopenharmony_ci return prestera_cmd(port->sw, cmd_type, &req.cmd, sizeof(req)); 150662306a36Sopenharmony_ci 150762306a36Sopenharmony_ci} 150862306a36Sopenharmony_ci 150962306a36Sopenharmony_ciint prestera_hw_span_unbind(const struct prestera_port *port, bool ingress) 151062306a36Sopenharmony_ci{ 151162306a36Sopenharmony_ci struct prestera_msg_span_req req = { 151262306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 151362306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 151462306a36Sopenharmony_ci }; 151562306a36Sopenharmony_ci enum prestera_cmd_type_t cmd_type; 151662306a36Sopenharmony_ci 151762306a36Sopenharmony_ci if (ingress) 151862306a36Sopenharmony_ci cmd_type = PRESTERA_CMD_TYPE_SPAN_INGRESS_UNBIND; 151962306a36Sopenharmony_ci else 152062306a36Sopenharmony_ci cmd_type = PRESTERA_CMD_TYPE_SPAN_EGRESS_UNBIND; 152162306a36Sopenharmony_ci 152262306a36Sopenharmony_ci return prestera_cmd(port->sw, cmd_type, &req.cmd, sizeof(req)); 152362306a36Sopenharmony_ci} 152462306a36Sopenharmony_ci 152562306a36Sopenharmony_ciint prestera_hw_span_release(struct prestera_switch *sw, u8 span_id) 152662306a36Sopenharmony_ci{ 152762306a36Sopenharmony_ci struct prestera_msg_span_req req = { 152862306a36Sopenharmony_ci .id = span_id 152962306a36Sopenharmony_ci }; 153062306a36Sopenharmony_ci 153162306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_SPAN_RELEASE, 153262306a36Sopenharmony_ci &req.cmd, sizeof(req)); 153362306a36Sopenharmony_ci} 153462306a36Sopenharmony_ci 153562306a36Sopenharmony_ciint prestera_hw_port_type_get(const struct prestera_port *port, u8 *type) 153662306a36Sopenharmony_ci{ 153762306a36Sopenharmony_ci struct prestera_msg_port_attr_req req = { 153862306a36Sopenharmony_ci .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_TYPE), 153962306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 154062306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 154162306a36Sopenharmony_ci }; 154262306a36Sopenharmony_ci struct prestera_msg_port_attr_resp resp; 154362306a36Sopenharmony_ci int err; 154462306a36Sopenharmony_ci 154562306a36Sopenharmony_ci err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET, 154662306a36Sopenharmony_ci &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 154762306a36Sopenharmony_ci if (err) 154862306a36Sopenharmony_ci return err; 154962306a36Sopenharmony_ci 155062306a36Sopenharmony_ci *type = resp.param.type; 155162306a36Sopenharmony_ci 155262306a36Sopenharmony_ci return 0; 155362306a36Sopenharmony_ci} 155462306a36Sopenharmony_ci 155562306a36Sopenharmony_ciint prestera_hw_port_speed_get(const struct prestera_port *port, u32 *speed) 155662306a36Sopenharmony_ci{ 155762306a36Sopenharmony_ci struct prestera_msg_port_attr_req req = { 155862306a36Sopenharmony_ci .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_SPEED), 155962306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 156062306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 156162306a36Sopenharmony_ci }; 156262306a36Sopenharmony_ci struct prestera_msg_port_attr_resp resp; 156362306a36Sopenharmony_ci int err; 156462306a36Sopenharmony_ci 156562306a36Sopenharmony_ci err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET, 156662306a36Sopenharmony_ci &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 156762306a36Sopenharmony_ci if (err) 156862306a36Sopenharmony_ci return err; 156962306a36Sopenharmony_ci 157062306a36Sopenharmony_ci *speed = __le32_to_cpu(resp.param.speed); 157162306a36Sopenharmony_ci 157262306a36Sopenharmony_ci return 0; 157362306a36Sopenharmony_ci} 157462306a36Sopenharmony_ci 157562306a36Sopenharmony_ciint prestera_hw_port_autoneg_restart(struct prestera_port *port) 157662306a36Sopenharmony_ci{ 157762306a36Sopenharmony_ci struct prestera_msg_port_attr_req req = { 157862306a36Sopenharmony_ci .attr = 157962306a36Sopenharmony_ci __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_PHY_AUTONEG_RESTART), 158062306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 158162306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 158262306a36Sopenharmony_ci }; 158362306a36Sopenharmony_ci 158462306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, 158562306a36Sopenharmony_ci &req.cmd, sizeof(req)); 158662306a36Sopenharmony_ci} 158762306a36Sopenharmony_ci 158862306a36Sopenharmony_ciint prestera_hw_port_stats_get(const struct prestera_port *port, 158962306a36Sopenharmony_ci struct prestera_port_stats *st) 159062306a36Sopenharmony_ci{ 159162306a36Sopenharmony_ci struct prestera_msg_port_attr_req req = { 159262306a36Sopenharmony_ci .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_STATS), 159362306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 159462306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 159562306a36Sopenharmony_ci }; 159662306a36Sopenharmony_ci struct prestera_msg_port_stats_resp resp; 159762306a36Sopenharmony_ci __le64 *hw = resp.stats; 159862306a36Sopenharmony_ci int err; 159962306a36Sopenharmony_ci 160062306a36Sopenharmony_ci err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET, 160162306a36Sopenharmony_ci &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 160262306a36Sopenharmony_ci if (err) 160362306a36Sopenharmony_ci return err; 160462306a36Sopenharmony_ci 160562306a36Sopenharmony_ci st->good_octets_received = 160662306a36Sopenharmony_ci __le64_to_cpu(hw[PRESTERA_PORT_GOOD_OCTETS_RCV_CNT]); 160762306a36Sopenharmony_ci st->bad_octets_received = 160862306a36Sopenharmony_ci __le64_to_cpu(hw[PRESTERA_PORT_BAD_OCTETS_RCV_CNT]); 160962306a36Sopenharmony_ci st->mac_trans_error = 161062306a36Sopenharmony_ci __le64_to_cpu(hw[PRESTERA_PORT_MAC_TRANSMIT_ERR_CNT]); 161162306a36Sopenharmony_ci st->broadcast_frames_received = 161262306a36Sopenharmony_ci __le64_to_cpu(hw[PRESTERA_PORT_BRDC_PKTS_RCV_CNT]); 161362306a36Sopenharmony_ci st->multicast_frames_received = 161462306a36Sopenharmony_ci __le64_to_cpu(hw[PRESTERA_PORT_MC_PKTS_RCV_CNT]); 161562306a36Sopenharmony_ci st->frames_64_octets = __le64_to_cpu(hw[PRESTERA_PORT_PKTS_64L_CNT]); 161662306a36Sopenharmony_ci st->frames_65_to_127_octets = 161762306a36Sopenharmony_ci __le64_to_cpu(hw[PRESTERA_PORT_PKTS_65TO127L_CNT]); 161862306a36Sopenharmony_ci st->frames_128_to_255_octets = 161962306a36Sopenharmony_ci __le64_to_cpu(hw[PRESTERA_PORT_PKTS_128TO255L_CNT]); 162062306a36Sopenharmony_ci st->frames_256_to_511_octets = 162162306a36Sopenharmony_ci __le64_to_cpu(hw[PRESTERA_PORT_PKTS_256TO511L_CNT]); 162262306a36Sopenharmony_ci st->frames_512_to_1023_octets = 162362306a36Sopenharmony_ci __le64_to_cpu(hw[PRESTERA_PORT_PKTS_512TO1023L_CNT]); 162462306a36Sopenharmony_ci st->frames_1024_to_max_octets = 162562306a36Sopenharmony_ci __le64_to_cpu(hw[PRESTERA_PORT_PKTS_1024TOMAXL_CNT]); 162662306a36Sopenharmony_ci st->excessive_collision = 162762306a36Sopenharmony_ci __le64_to_cpu(hw[PRESTERA_PORT_EXCESSIVE_COLLISIONS_CNT]); 162862306a36Sopenharmony_ci st->multicast_frames_sent = 162962306a36Sopenharmony_ci __le64_to_cpu(hw[PRESTERA_PORT_MC_PKTS_SENT_CNT]); 163062306a36Sopenharmony_ci st->broadcast_frames_sent = 163162306a36Sopenharmony_ci __le64_to_cpu(hw[PRESTERA_PORT_BRDC_PKTS_SENT_CNT]); 163262306a36Sopenharmony_ci st->fc_sent = __le64_to_cpu(hw[PRESTERA_PORT_FC_SENT_CNT]); 163362306a36Sopenharmony_ci st->fc_received = __le64_to_cpu(hw[PRESTERA_PORT_GOOD_FC_RCV_CNT]); 163462306a36Sopenharmony_ci st->buffer_overrun = __le64_to_cpu(hw[PRESTERA_PORT_DROP_EVENTS_CNT]); 163562306a36Sopenharmony_ci st->undersize = __le64_to_cpu(hw[PRESTERA_PORT_UNDERSIZE_PKTS_CNT]); 163662306a36Sopenharmony_ci st->fragments = __le64_to_cpu(hw[PRESTERA_PORT_FRAGMENTS_PKTS_CNT]); 163762306a36Sopenharmony_ci st->oversize = __le64_to_cpu(hw[PRESTERA_PORT_OVERSIZE_PKTS_CNT]); 163862306a36Sopenharmony_ci st->jabber = __le64_to_cpu(hw[PRESTERA_PORT_JABBER_PKTS_CNT]); 163962306a36Sopenharmony_ci st->rx_error_frame_received = 164062306a36Sopenharmony_ci __le64_to_cpu(hw[PRESTERA_PORT_MAC_RCV_ERROR_CNT]); 164162306a36Sopenharmony_ci st->bad_crc = __le64_to_cpu(hw[PRESTERA_PORT_BAD_CRC_CNT]); 164262306a36Sopenharmony_ci st->collisions = __le64_to_cpu(hw[PRESTERA_PORT_COLLISIONS_CNT]); 164362306a36Sopenharmony_ci st->late_collision = 164462306a36Sopenharmony_ci __le64_to_cpu(hw[PRESTERA_PORT_LATE_COLLISIONS_CNT]); 164562306a36Sopenharmony_ci st->unicast_frames_received = 164662306a36Sopenharmony_ci __le64_to_cpu(hw[PRESTERA_PORT_GOOD_UC_PKTS_RCV_CNT]); 164762306a36Sopenharmony_ci st->unicast_frames_sent = 164862306a36Sopenharmony_ci __le64_to_cpu(hw[PRESTERA_PORT_GOOD_UC_PKTS_SENT_CNT]); 164962306a36Sopenharmony_ci st->sent_multiple = 165062306a36Sopenharmony_ci __le64_to_cpu(hw[PRESTERA_PORT_MULTIPLE_PKTS_SENT_CNT]); 165162306a36Sopenharmony_ci st->sent_deferred = 165262306a36Sopenharmony_ci __le64_to_cpu(hw[PRESTERA_PORT_DEFERRED_PKTS_SENT_CNT]); 165362306a36Sopenharmony_ci st->good_octets_sent = 165462306a36Sopenharmony_ci __le64_to_cpu(hw[PRESTERA_PORT_GOOD_OCTETS_SENT_CNT]); 165562306a36Sopenharmony_ci 165662306a36Sopenharmony_ci return 0; 165762306a36Sopenharmony_ci} 165862306a36Sopenharmony_ci 165962306a36Sopenharmony_ciint prestera_hw_port_learning_set(struct prestera_port *port, bool enable) 166062306a36Sopenharmony_ci{ 166162306a36Sopenharmony_ci struct prestera_msg_port_attr_req req = { 166262306a36Sopenharmony_ci .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_LEARNING), 166362306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 166462306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 166562306a36Sopenharmony_ci .param = { 166662306a36Sopenharmony_ci .learning = enable, 166762306a36Sopenharmony_ci } 166862306a36Sopenharmony_ci }; 166962306a36Sopenharmony_ci 167062306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, 167162306a36Sopenharmony_ci &req.cmd, sizeof(req)); 167262306a36Sopenharmony_ci} 167362306a36Sopenharmony_ci 167462306a36Sopenharmony_ciint prestera_hw_port_uc_flood_set(const struct prestera_port *port, bool flood) 167562306a36Sopenharmony_ci{ 167662306a36Sopenharmony_ci struct prestera_msg_port_attr_req req = { 167762306a36Sopenharmony_ci .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_FLOOD), 167862306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 167962306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 168062306a36Sopenharmony_ci .param = { 168162306a36Sopenharmony_ci .flood_ext = { 168262306a36Sopenharmony_ci .type = PRESTERA_PORT_FLOOD_TYPE_UC, 168362306a36Sopenharmony_ci .enable = flood, 168462306a36Sopenharmony_ci } 168562306a36Sopenharmony_ci } 168662306a36Sopenharmony_ci }; 168762306a36Sopenharmony_ci 168862306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, 168962306a36Sopenharmony_ci &req.cmd, sizeof(req)); 169062306a36Sopenharmony_ci} 169162306a36Sopenharmony_ci 169262306a36Sopenharmony_ciint prestera_hw_port_mc_flood_set(const struct prestera_port *port, bool flood) 169362306a36Sopenharmony_ci{ 169462306a36Sopenharmony_ci struct prestera_msg_port_attr_req req = { 169562306a36Sopenharmony_ci .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_FLOOD), 169662306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 169762306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 169862306a36Sopenharmony_ci .param = { 169962306a36Sopenharmony_ci .flood_ext = { 170062306a36Sopenharmony_ci .type = PRESTERA_PORT_FLOOD_TYPE_MC, 170162306a36Sopenharmony_ci .enable = flood, 170262306a36Sopenharmony_ci } 170362306a36Sopenharmony_ci } 170462306a36Sopenharmony_ci }; 170562306a36Sopenharmony_ci 170662306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, 170762306a36Sopenharmony_ci &req.cmd, sizeof(req)); 170862306a36Sopenharmony_ci} 170962306a36Sopenharmony_ci 171062306a36Sopenharmony_ciint prestera_hw_port_br_locked_set(const struct prestera_port *port, 171162306a36Sopenharmony_ci bool br_locked) 171262306a36Sopenharmony_ci{ 171362306a36Sopenharmony_ci struct prestera_msg_port_attr_req req = { 171462306a36Sopenharmony_ci .attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_LOCKED), 171562306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 171662306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 171762306a36Sopenharmony_ci .param = { 171862306a36Sopenharmony_ci .br_locked = br_locked, 171962306a36Sopenharmony_ci } 172062306a36Sopenharmony_ci }; 172162306a36Sopenharmony_ci 172262306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET, 172362306a36Sopenharmony_ci &req.cmd, sizeof(req)); 172462306a36Sopenharmony_ci} 172562306a36Sopenharmony_ci 172662306a36Sopenharmony_ciint prestera_hw_vlan_create(struct prestera_switch *sw, u16 vid) 172762306a36Sopenharmony_ci{ 172862306a36Sopenharmony_ci struct prestera_msg_vlan_req req = { 172962306a36Sopenharmony_ci .vid = __cpu_to_le16(vid), 173062306a36Sopenharmony_ci }; 173162306a36Sopenharmony_ci 173262306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_VLAN_CREATE, 173362306a36Sopenharmony_ci &req.cmd, sizeof(req)); 173462306a36Sopenharmony_ci} 173562306a36Sopenharmony_ci 173662306a36Sopenharmony_ciint prestera_hw_vlan_delete(struct prestera_switch *sw, u16 vid) 173762306a36Sopenharmony_ci{ 173862306a36Sopenharmony_ci struct prestera_msg_vlan_req req = { 173962306a36Sopenharmony_ci .vid = __cpu_to_le16(vid), 174062306a36Sopenharmony_ci }; 174162306a36Sopenharmony_ci 174262306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_VLAN_DELETE, 174362306a36Sopenharmony_ci &req.cmd, sizeof(req)); 174462306a36Sopenharmony_ci} 174562306a36Sopenharmony_ci 174662306a36Sopenharmony_ciint prestera_hw_vlan_port_set(struct prestera_port *port, u16 vid, 174762306a36Sopenharmony_ci bool is_member, bool untagged) 174862306a36Sopenharmony_ci{ 174962306a36Sopenharmony_ci struct prestera_msg_vlan_req req = { 175062306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 175162306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 175262306a36Sopenharmony_ci .vid = __cpu_to_le16(vid), 175362306a36Sopenharmony_ci .is_member = is_member, 175462306a36Sopenharmony_ci .is_tagged = !untagged, 175562306a36Sopenharmony_ci }; 175662306a36Sopenharmony_ci 175762306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_VLAN_PORT_SET, 175862306a36Sopenharmony_ci &req.cmd, sizeof(req)); 175962306a36Sopenharmony_ci} 176062306a36Sopenharmony_ci 176162306a36Sopenharmony_ciint prestera_hw_vlan_port_vid_set(struct prestera_port *port, u16 vid) 176262306a36Sopenharmony_ci{ 176362306a36Sopenharmony_ci struct prestera_msg_vlan_req req = { 176462306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 176562306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 176662306a36Sopenharmony_ci .vid = __cpu_to_le16(vid), 176762306a36Sopenharmony_ci }; 176862306a36Sopenharmony_ci 176962306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_VLAN_PVID_SET, 177062306a36Sopenharmony_ci &req.cmd, sizeof(req)); 177162306a36Sopenharmony_ci} 177262306a36Sopenharmony_ci 177362306a36Sopenharmony_ciint prestera_hw_vlan_port_stp_set(struct prestera_port *port, u16 vid, u8 state) 177462306a36Sopenharmony_ci{ 177562306a36Sopenharmony_ci struct prestera_msg_stp_req req = { 177662306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 177762306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 177862306a36Sopenharmony_ci .vid = __cpu_to_le16(vid), 177962306a36Sopenharmony_ci .state = state, 178062306a36Sopenharmony_ci }; 178162306a36Sopenharmony_ci 178262306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_STP_PORT_SET, 178362306a36Sopenharmony_ci &req.cmd, sizeof(req)); 178462306a36Sopenharmony_ci} 178562306a36Sopenharmony_ci 178662306a36Sopenharmony_ciint prestera_hw_fdb_add(struct prestera_port *port, const unsigned char *mac, 178762306a36Sopenharmony_ci u16 vid, bool dynamic) 178862306a36Sopenharmony_ci{ 178962306a36Sopenharmony_ci struct prestera_msg_fdb_req req = { 179062306a36Sopenharmony_ci .dest = { 179162306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 179262306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 179362306a36Sopenharmony_ci }, 179462306a36Sopenharmony_ci .vid = __cpu_to_le16(vid), 179562306a36Sopenharmony_ci .dynamic = dynamic, 179662306a36Sopenharmony_ci }; 179762306a36Sopenharmony_ci 179862306a36Sopenharmony_ci ether_addr_copy(req.mac, mac); 179962306a36Sopenharmony_ci 180062306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_FDB_ADD, 180162306a36Sopenharmony_ci &req.cmd, sizeof(req)); 180262306a36Sopenharmony_ci} 180362306a36Sopenharmony_ci 180462306a36Sopenharmony_ciint prestera_hw_fdb_del(struct prestera_port *port, const unsigned char *mac, 180562306a36Sopenharmony_ci u16 vid) 180662306a36Sopenharmony_ci{ 180762306a36Sopenharmony_ci struct prestera_msg_fdb_req req = { 180862306a36Sopenharmony_ci .dest = { 180962306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 181062306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 181162306a36Sopenharmony_ci }, 181262306a36Sopenharmony_ci .vid = __cpu_to_le16(vid), 181362306a36Sopenharmony_ci }; 181462306a36Sopenharmony_ci 181562306a36Sopenharmony_ci ether_addr_copy(req.mac, mac); 181662306a36Sopenharmony_ci 181762306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_FDB_DELETE, 181862306a36Sopenharmony_ci &req.cmd, sizeof(req)); 181962306a36Sopenharmony_ci} 182062306a36Sopenharmony_ci 182162306a36Sopenharmony_ciint prestera_hw_lag_fdb_add(struct prestera_switch *sw, u16 lag_id, 182262306a36Sopenharmony_ci const unsigned char *mac, u16 vid, bool dynamic) 182362306a36Sopenharmony_ci{ 182462306a36Sopenharmony_ci struct prestera_msg_fdb_req req = { 182562306a36Sopenharmony_ci .dest_type = PRESTERA_HW_FDB_ENTRY_TYPE_LAG, 182662306a36Sopenharmony_ci .dest = { 182762306a36Sopenharmony_ci .lag_id = __cpu_to_le16(lag_id), 182862306a36Sopenharmony_ci }, 182962306a36Sopenharmony_ci .vid = __cpu_to_le16(vid), 183062306a36Sopenharmony_ci .dynamic = dynamic, 183162306a36Sopenharmony_ci }; 183262306a36Sopenharmony_ci 183362306a36Sopenharmony_ci ether_addr_copy(req.mac, mac); 183462306a36Sopenharmony_ci 183562306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_FDB_ADD, 183662306a36Sopenharmony_ci &req.cmd, sizeof(req)); 183762306a36Sopenharmony_ci} 183862306a36Sopenharmony_ci 183962306a36Sopenharmony_ciint prestera_hw_lag_fdb_del(struct prestera_switch *sw, u16 lag_id, 184062306a36Sopenharmony_ci const unsigned char *mac, u16 vid) 184162306a36Sopenharmony_ci{ 184262306a36Sopenharmony_ci struct prestera_msg_fdb_req req = { 184362306a36Sopenharmony_ci .dest_type = PRESTERA_HW_FDB_ENTRY_TYPE_LAG, 184462306a36Sopenharmony_ci .dest = { 184562306a36Sopenharmony_ci .lag_id = __cpu_to_le16(lag_id), 184662306a36Sopenharmony_ci }, 184762306a36Sopenharmony_ci .vid = __cpu_to_le16(vid), 184862306a36Sopenharmony_ci }; 184962306a36Sopenharmony_ci 185062306a36Sopenharmony_ci ether_addr_copy(req.mac, mac); 185162306a36Sopenharmony_ci 185262306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_FDB_DELETE, 185362306a36Sopenharmony_ci &req.cmd, sizeof(req)); 185462306a36Sopenharmony_ci} 185562306a36Sopenharmony_ci 185662306a36Sopenharmony_ciint prestera_hw_fdb_flush_port(struct prestera_port *port, u32 mode) 185762306a36Sopenharmony_ci{ 185862306a36Sopenharmony_ci struct prestera_msg_fdb_req req = { 185962306a36Sopenharmony_ci .dest = { 186062306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 186162306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 186262306a36Sopenharmony_ci }, 186362306a36Sopenharmony_ci .flush_mode = __cpu_to_le32(mode), 186462306a36Sopenharmony_ci }; 186562306a36Sopenharmony_ci 186662306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_FDB_FLUSH_PORT, 186762306a36Sopenharmony_ci &req.cmd, sizeof(req)); 186862306a36Sopenharmony_ci} 186962306a36Sopenharmony_ci 187062306a36Sopenharmony_ciint prestera_hw_fdb_flush_vlan(struct prestera_switch *sw, u16 vid, u32 mode) 187162306a36Sopenharmony_ci{ 187262306a36Sopenharmony_ci struct prestera_msg_fdb_req req = { 187362306a36Sopenharmony_ci .vid = __cpu_to_le16(vid), 187462306a36Sopenharmony_ci .flush_mode = __cpu_to_le32(mode), 187562306a36Sopenharmony_ci }; 187662306a36Sopenharmony_ci 187762306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_FDB_FLUSH_VLAN, 187862306a36Sopenharmony_ci &req.cmd, sizeof(req)); 187962306a36Sopenharmony_ci} 188062306a36Sopenharmony_ci 188162306a36Sopenharmony_ciint prestera_hw_fdb_flush_port_vlan(struct prestera_port *port, u16 vid, 188262306a36Sopenharmony_ci u32 mode) 188362306a36Sopenharmony_ci{ 188462306a36Sopenharmony_ci struct prestera_msg_fdb_req req = { 188562306a36Sopenharmony_ci .dest = { 188662306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 188762306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 188862306a36Sopenharmony_ci }, 188962306a36Sopenharmony_ci .vid = __cpu_to_le16(vid), 189062306a36Sopenharmony_ci .flush_mode = __cpu_to_le32(mode), 189162306a36Sopenharmony_ci }; 189262306a36Sopenharmony_ci 189362306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_FDB_FLUSH_PORT_VLAN, 189462306a36Sopenharmony_ci &req.cmd, sizeof(req)); 189562306a36Sopenharmony_ci} 189662306a36Sopenharmony_ci 189762306a36Sopenharmony_ciint prestera_hw_fdb_flush_lag(struct prestera_switch *sw, u16 lag_id, 189862306a36Sopenharmony_ci u32 mode) 189962306a36Sopenharmony_ci{ 190062306a36Sopenharmony_ci struct prestera_msg_fdb_req req = { 190162306a36Sopenharmony_ci .dest_type = PRESTERA_HW_FDB_ENTRY_TYPE_LAG, 190262306a36Sopenharmony_ci .dest = { 190362306a36Sopenharmony_ci .lag_id = __cpu_to_le16(lag_id), 190462306a36Sopenharmony_ci }, 190562306a36Sopenharmony_ci .flush_mode = __cpu_to_le32(mode), 190662306a36Sopenharmony_ci }; 190762306a36Sopenharmony_ci 190862306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_FDB_FLUSH_PORT, 190962306a36Sopenharmony_ci &req.cmd, sizeof(req)); 191062306a36Sopenharmony_ci} 191162306a36Sopenharmony_ci 191262306a36Sopenharmony_ciint prestera_hw_fdb_flush_lag_vlan(struct prestera_switch *sw, 191362306a36Sopenharmony_ci u16 lag_id, u16 vid, u32 mode) 191462306a36Sopenharmony_ci{ 191562306a36Sopenharmony_ci struct prestera_msg_fdb_req req = { 191662306a36Sopenharmony_ci .dest_type = PRESTERA_HW_FDB_ENTRY_TYPE_LAG, 191762306a36Sopenharmony_ci .dest = { 191862306a36Sopenharmony_ci .lag_id = __cpu_to_le16(lag_id), 191962306a36Sopenharmony_ci }, 192062306a36Sopenharmony_ci .vid = __cpu_to_le16(vid), 192162306a36Sopenharmony_ci .flush_mode = __cpu_to_le32(mode), 192262306a36Sopenharmony_ci }; 192362306a36Sopenharmony_ci 192462306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_FDB_FLUSH_PORT_VLAN, 192562306a36Sopenharmony_ci &req.cmd, sizeof(req)); 192662306a36Sopenharmony_ci} 192762306a36Sopenharmony_ci 192862306a36Sopenharmony_ciint prestera_hw_bridge_create(struct prestera_switch *sw, u16 *bridge_id) 192962306a36Sopenharmony_ci{ 193062306a36Sopenharmony_ci struct prestera_msg_bridge_resp resp; 193162306a36Sopenharmony_ci struct prestera_msg_bridge_req req; 193262306a36Sopenharmony_ci int err; 193362306a36Sopenharmony_ci 193462306a36Sopenharmony_ci err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_BRIDGE_CREATE, 193562306a36Sopenharmony_ci &req.cmd, sizeof(req), 193662306a36Sopenharmony_ci &resp.ret, sizeof(resp)); 193762306a36Sopenharmony_ci if (err) 193862306a36Sopenharmony_ci return err; 193962306a36Sopenharmony_ci 194062306a36Sopenharmony_ci *bridge_id = __le16_to_cpu(resp.bridge); 194162306a36Sopenharmony_ci 194262306a36Sopenharmony_ci return 0; 194362306a36Sopenharmony_ci} 194462306a36Sopenharmony_ci 194562306a36Sopenharmony_ciint prestera_hw_bridge_delete(struct prestera_switch *sw, u16 bridge_id) 194662306a36Sopenharmony_ci{ 194762306a36Sopenharmony_ci struct prestera_msg_bridge_req req = { 194862306a36Sopenharmony_ci .bridge = __cpu_to_le16(bridge_id), 194962306a36Sopenharmony_ci }; 195062306a36Sopenharmony_ci 195162306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_BRIDGE_DELETE, 195262306a36Sopenharmony_ci &req.cmd, sizeof(req)); 195362306a36Sopenharmony_ci} 195462306a36Sopenharmony_ci 195562306a36Sopenharmony_ciint prestera_hw_bridge_port_add(struct prestera_port *port, u16 bridge_id) 195662306a36Sopenharmony_ci{ 195762306a36Sopenharmony_ci struct prestera_msg_bridge_req req = { 195862306a36Sopenharmony_ci .bridge = __cpu_to_le16(bridge_id), 195962306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 196062306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 196162306a36Sopenharmony_ci }; 196262306a36Sopenharmony_ci 196362306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_BRIDGE_PORT_ADD, 196462306a36Sopenharmony_ci &req.cmd, sizeof(req)); 196562306a36Sopenharmony_ci} 196662306a36Sopenharmony_ci 196762306a36Sopenharmony_ciint prestera_hw_bridge_port_delete(struct prestera_port *port, u16 bridge_id) 196862306a36Sopenharmony_ci{ 196962306a36Sopenharmony_ci struct prestera_msg_bridge_req req = { 197062306a36Sopenharmony_ci .bridge = __cpu_to_le16(bridge_id), 197162306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 197262306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 197362306a36Sopenharmony_ci }; 197462306a36Sopenharmony_ci 197562306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_BRIDGE_PORT_DELETE, 197662306a36Sopenharmony_ci &req.cmd, sizeof(req)); 197762306a36Sopenharmony_ci} 197862306a36Sopenharmony_ci 197962306a36Sopenharmony_cistatic int prestera_iface_to_msg(struct prestera_iface *iface, 198062306a36Sopenharmony_ci struct prestera_msg_iface *msg_if) 198162306a36Sopenharmony_ci{ 198262306a36Sopenharmony_ci switch (iface->type) { 198362306a36Sopenharmony_ci case PRESTERA_IF_PORT_E: 198462306a36Sopenharmony_ci case PRESTERA_IF_VID_E: 198562306a36Sopenharmony_ci msg_if->port = __cpu_to_le32(iface->dev_port.port_num); 198662306a36Sopenharmony_ci msg_if->dev = __cpu_to_le32(iface->dev_port.hw_dev_num); 198762306a36Sopenharmony_ci break; 198862306a36Sopenharmony_ci case PRESTERA_IF_LAG_E: 198962306a36Sopenharmony_ci msg_if->lag_id = __cpu_to_le16(iface->lag_id); 199062306a36Sopenharmony_ci break; 199162306a36Sopenharmony_ci default: 199262306a36Sopenharmony_ci return -EOPNOTSUPP; 199362306a36Sopenharmony_ci } 199462306a36Sopenharmony_ci 199562306a36Sopenharmony_ci msg_if->vr_id = __cpu_to_le16(iface->vr_id); 199662306a36Sopenharmony_ci msg_if->vid = __cpu_to_le16(iface->vlan_id); 199762306a36Sopenharmony_ci msg_if->type = iface->type; 199862306a36Sopenharmony_ci return 0; 199962306a36Sopenharmony_ci} 200062306a36Sopenharmony_ci 200162306a36Sopenharmony_ciint prestera_hw_rif_create(struct prestera_switch *sw, 200262306a36Sopenharmony_ci struct prestera_iface *iif, u8 *mac, u16 *rif_id) 200362306a36Sopenharmony_ci{ 200462306a36Sopenharmony_ci struct prestera_msg_rif_resp resp; 200562306a36Sopenharmony_ci struct prestera_msg_rif_req req; 200662306a36Sopenharmony_ci int err; 200762306a36Sopenharmony_ci 200862306a36Sopenharmony_ci memcpy(req.mac, mac, ETH_ALEN); 200962306a36Sopenharmony_ci 201062306a36Sopenharmony_ci err = prestera_iface_to_msg(iif, &req.iif); 201162306a36Sopenharmony_ci if (err) 201262306a36Sopenharmony_ci return err; 201362306a36Sopenharmony_ci 201462306a36Sopenharmony_ci err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_ROUTER_RIF_CREATE, 201562306a36Sopenharmony_ci &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 201662306a36Sopenharmony_ci if (err) 201762306a36Sopenharmony_ci return err; 201862306a36Sopenharmony_ci 201962306a36Sopenharmony_ci *rif_id = __le16_to_cpu(resp.rif_id); 202062306a36Sopenharmony_ci return err; 202162306a36Sopenharmony_ci} 202262306a36Sopenharmony_ci 202362306a36Sopenharmony_ciint prestera_hw_rif_delete(struct prestera_switch *sw, u16 rif_id, 202462306a36Sopenharmony_ci struct prestera_iface *iif) 202562306a36Sopenharmony_ci{ 202662306a36Sopenharmony_ci struct prestera_msg_rif_req req = { 202762306a36Sopenharmony_ci .rif_id = __cpu_to_le16(rif_id), 202862306a36Sopenharmony_ci }; 202962306a36Sopenharmony_ci int err; 203062306a36Sopenharmony_ci 203162306a36Sopenharmony_ci err = prestera_iface_to_msg(iif, &req.iif); 203262306a36Sopenharmony_ci if (err) 203362306a36Sopenharmony_ci return err; 203462306a36Sopenharmony_ci 203562306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_RIF_DELETE, &req.cmd, 203662306a36Sopenharmony_ci sizeof(req)); 203762306a36Sopenharmony_ci} 203862306a36Sopenharmony_ci 203962306a36Sopenharmony_ciint prestera_hw_vr_create(struct prestera_switch *sw, u16 *vr_id) 204062306a36Sopenharmony_ci{ 204162306a36Sopenharmony_ci struct prestera_msg_vr_resp resp; 204262306a36Sopenharmony_ci struct prestera_msg_vr_req req; 204362306a36Sopenharmony_ci int err; 204462306a36Sopenharmony_ci 204562306a36Sopenharmony_ci err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_ROUTER_VR_CREATE, 204662306a36Sopenharmony_ci &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 204762306a36Sopenharmony_ci if (err) 204862306a36Sopenharmony_ci return err; 204962306a36Sopenharmony_ci 205062306a36Sopenharmony_ci *vr_id = __le16_to_cpu(resp.vr_id); 205162306a36Sopenharmony_ci return err; 205262306a36Sopenharmony_ci} 205362306a36Sopenharmony_ci 205462306a36Sopenharmony_ciint prestera_hw_vr_delete(struct prestera_switch *sw, u16 vr_id) 205562306a36Sopenharmony_ci{ 205662306a36Sopenharmony_ci struct prestera_msg_vr_req req = { 205762306a36Sopenharmony_ci .vr_id = __cpu_to_le16(vr_id), 205862306a36Sopenharmony_ci }; 205962306a36Sopenharmony_ci 206062306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_VR_DELETE, &req.cmd, 206162306a36Sopenharmony_ci sizeof(req)); 206262306a36Sopenharmony_ci} 206362306a36Sopenharmony_ci 206462306a36Sopenharmony_ciint prestera_hw_lpm_add(struct prestera_switch *sw, u16 vr_id, 206562306a36Sopenharmony_ci __be32 dst, u32 dst_len, u32 grp_id) 206662306a36Sopenharmony_ci{ 206762306a36Sopenharmony_ci struct prestera_msg_lpm_req req = { 206862306a36Sopenharmony_ci .dst_len = __cpu_to_le32(dst_len), 206962306a36Sopenharmony_ci .vr_id = __cpu_to_le16(vr_id), 207062306a36Sopenharmony_ci .grp_id = __cpu_to_le32(grp_id), 207162306a36Sopenharmony_ci .dst.u.ipv4 = dst 207262306a36Sopenharmony_ci }; 207362306a36Sopenharmony_ci 207462306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_LPM_ADD, &req.cmd, 207562306a36Sopenharmony_ci sizeof(req)); 207662306a36Sopenharmony_ci} 207762306a36Sopenharmony_ci 207862306a36Sopenharmony_ciint prestera_hw_lpm_del(struct prestera_switch *sw, u16 vr_id, 207962306a36Sopenharmony_ci __be32 dst, u32 dst_len) 208062306a36Sopenharmony_ci{ 208162306a36Sopenharmony_ci struct prestera_msg_lpm_req req = { 208262306a36Sopenharmony_ci .dst_len = __cpu_to_le32(dst_len), 208362306a36Sopenharmony_ci .vr_id = __cpu_to_le16(vr_id), 208462306a36Sopenharmony_ci .dst.u.ipv4 = dst 208562306a36Sopenharmony_ci }; 208662306a36Sopenharmony_ci 208762306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_LPM_DELETE, &req.cmd, 208862306a36Sopenharmony_ci sizeof(req)); 208962306a36Sopenharmony_ci} 209062306a36Sopenharmony_ci 209162306a36Sopenharmony_ciint prestera_hw_nh_entries_set(struct prestera_switch *sw, int count, 209262306a36Sopenharmony_ci struct prestera_neigh_info *nhs, u32 grp_id) 209362306a36Sopenharmony_ci{ 209462306a36Sopenharmony_ci struct prestera_msg_nh_req req = { .size = __cpu_to_le32((u32)count), 209562306a36Sopenharmony_ci .grp_id = __cpu_to_le32(grp_id) }; 209662306a36Sopenharmony_ci int i, err; 209762306a36Sopenharmony_ci 209862306a36Sopenharmony_ci for (i = 0; i < count; i++) { 209962306a36Sopenharmony_ci req.nh[i].is_active = nhs[i].connected; 210062306a36Sopenharmony_ci memcpy(&req.nh[i].mac, nhs[i].ha, ETH_ALEN); 210162306a36Sopenharmony_ci err = prestera_iface_to_msg(&nhs[i].iface, &req.nh[i].oif); 210262306a36Sopenharmony_ci if (err) 210362306a36Sopenharmony_ci return err; 210462306a36Sopenharmony_ci } 210562306a36Sopenharmony_ci 210662306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_NH_GRP_SET, &req.cmd, 210762306a36Sopenharmony_ci sizeof(req)); 210862306a36Sopenharmony_ci} 210962306a36Sopenharmony_ci 211062306a36Sopenharmony_ciint prestera_hw_nhgrp_blk_get(struct prestera_switch *sw, 211162306a36Sopenharmony_ci u8 *hw_state, u32 buf_size /* Buffer in bytes */) 211262306a36Sopenharmony_ci{ 211362306a36Sopenharmony_ci static struct prestera_msg_nh_chunk_resp resp; 211462306a36Sopenharmony_ci struct prestera_msg_nh_chunk_req req; 211562306a36Sopenharmony_ci u32 buf_offset; 211662306a36Sopenharmony_ci int err; 211762306a36Sopenharmony_ci 211862306a36Sopenharmony_ci memset(&hw_state[0], 0, buf_size); 211962306a36Sopenharmony_ci buf_offset = 0; 212062306a36Sopenharmony_ci while (1) { 212162306a36Sopenharmony_ci if (buf_offset >= buf_size) 212262306a36Sopenharmony_ci break; 212362306a36Sopenharmony_ci 212462306a36Sopenharmony_ci memset(&req, 0, sizeof(req)); 212562306a36Sopenharmony_ci req.offset = __cpu_to_le32(buf_offset * 8); /* 8 bits in u8 */ 212662306a36Sopenharmony_ci err = prestera_cmd_ret(sw, 212762306a36Sopenharmony_ci PRESTERA_CMD_TYPE_ROUTER_NH_GRP_BLK_GET, 212862306a36Sopenharmony_ci &req.cmd, sizeof(req), &resp.ret, 212962306a36Sopenharmony_ci sizeof(resp)); 213062306a36Sopenharmony_ci if (err) 213162306a36Sopenharmony_ci return err; 213262306a36Sopenharmony_ci 213362306a36Sopenharmony_ci memcpy(&hw_state[buf_offset], &resp.hw_state[0], 213462306a36Sopenharmony_ci buf_offset + PRESTERA_MSG_CHUNK_SIZE > buf_size ? 213562306a36Sopenharmony_ci buf_size - buf_offset : PRESTERA_MSG_CHUNK_SIZE); 213662306a36Sopenharmony_ci buf_offset += PRESTERA_MSG_CHUNK_SIZE; 213762306a36Sopenharmony_ci } 213862306a36Sopenharmony_ci 213962306a36Sopenharmony_ci return 0; 214062306a36Sopenharmony_ci} 214162306a36Sopenharmony_ci 214262306a36Sopenharmony_ciint prestera_hw_nh_group_create(struct prestera_switch *sw, u16 nh_count, 214362306a36Sopenharmony_ci u32 *grp_id) 214462306a36Sopenharmony_ci{ 214562306a36Sopenharmony_ci struct prestera_msg_nh_grp_req req = { .size = __cpu_to_le32((u32)nh_count) }; 214662306a36Sopenharmony_ci struct prestera_msg_nh_grp_resp resp; 214762306a36Sopenharmony_ci int err; 214862306a36Sopenharmony_ci 214962306a36Sopenharmony_ci err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_ROUTER_NH_GRP_ADD, 215062306a36Sopenharmony_ci &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 215162306a36Sopenharmony_ci if (err) 215262306a36Sopenharmony_ci return err; 215362306a36Sopenharmony_ci 215462306a36Sopenharmony_ci *grp_id = __le32_to_cpu(resp.grp_id); 215562306a36Sopenharmony_ci return err; 215662306a36Sopenharmony_ci} 215762306a36Sopenharmony_ci 215862306a36Sopenharmony_ciint prestera_hw_nh_group_delete(struct prestera_switch *sw, u16 nh_count, 215962306a36Sopenharmony_ci u32 grp_id) 216062306a36Sopenharmony_ci{ 216162306a36Sopenharmony_ci struct prestera_msg_nh_grp_req req = { 216262306a36Sopenharmony_ci .grp_id = __cpu_to_le32(grp_id), 216362306a36Sopenharmony_ci .size = __cpu_to_le32(nh_count) 216462306a36Sopenharmony_ci }; 216562306a36Sopenharmony_ci 216662306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_NH_GRP_DELETE, 216762306a36Sopenharmony_ci &req.cmd, sizeof(req)); 216862306a36Sopenharmony_ci} 216962306a36Sopenharmony_ci 217062306a36Sopenharmony_ciint prestera_hw_rxtx_init(struct prestera_switch *sw, 217162306a36Sopenharmony_ci struct prestera_rxtx_params *params) 217262306a36Sopenharmony_ci{ 217362306a36Sopenharmony_ci struct prestera_msg_rxtx_resp resp; 217462306a36Sopenharmony_ci struct prestera_msg_rxtx_req req; 217562306a36Sopenharmony_ci int err; 217662306a36Sopenharmony_ci 217762306a36Sopenharmony_ci req.use_sdma = params->use_sdma; 217862306a36Sopenharmony_ci 217962306a36Sopenharmony_ci err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_RXTX_INIT, 218062306a36Sopenharmony_ci &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 218162306a36Sopenharmony_ci if (err) 218262306a36Sopenharmony_ci return err; 218362306a36Sopenharmony_ci 218462306a36Sopenharmony_ci params->map_addr = __le32_to_cpu(resp.map_addr); 218562306a36Sopenharmony_ci 218662306a36Sopenharmony_ci return 0; 218762306a36Sopenharmony_ci} 218862306a36Sopenharmony_ci 218962306a36Sopenharmony_ciint prestera_hw_lag_member_add(struct prestera_port *port, u16 lag_id) 219062306a36Sopenharmony_ci{ 219162306a36Sopenharmony_ci struct prestera_msg_lag_req req = { 219262306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 219362306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 219462306a36Sopenharmony_ci .lag_id = __cpu_to_le16(lag_id), 219562306a36Sopenharmony_ci }; 219662306a36Sopenharmony_ci 219762306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_LAG_MEMBER_ADD, 219862306a36Sopenharmony_ci &req.cmd, sizeof(req)); 219962306a36Sopenharmony_ci} 220062306a36Sopenharmony_ci 220162306a36Sopenharmony_ciint prestera_hw_lag_member_del(struct prestera_port *port, u16 lag_id) 220262306a36Sopenharmony_ci{ 220362306a36Sopenharmony_ci struct prestera_msg_lag_req req = { 220462306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 220562306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 220662306a36Sopenharmony_ci .lag_id = __cpu_to_le16(lag_id), 220762306a36Sopenharmony_ci }; 220862306a36Sopenharmony_ci 220962306a36Sopenharmony_ci return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_LAG_MEMBER_DELETE, 221062306a36Sopenharmony_ci &req.cmd, sizeof(req)); 221162306a36Sopenharmony_ci} 221262306a36Sopenharmony_ci 221362306a36Sopenharmony_ciint prestera_hw_lag_member_enable(struct prestera_port *port, u16 lag_id, 221462306a36Sopenharmony_ci bool enable) 221562306a36Sopenharmony_ci{ 221662306a36Sopenharmony_ci struct prestera_msg_lag_req req = { 221762306a36Sopenharmony_ci .port = __cpu_to_le32(port->hw_id), 221862306a36Sopenharmony_ci .dev = __cpu_to_le32(port->dev_id), 221962306a36Sopenharmony_ci .lag_id = __cpu_to_le16(lag_id), 222062306a36Sopenharmony_ci }; 222162306a36Sopenharmony_ci u32 cmd; 222262306a36Sopenharmony_ci 222362306a36Sopenharmony_ci cmd = enable ? PRESTERA_CMD_TYPE_LAG_MEMBER_ENABLE : 222462306a36Sopenharmony_ci PRESTERA_CMD_TYPE_LAG_MEMBER_DISABLE; 222562306a36Sopenharmony_ci 222662306a36Sopenharmony_ci return prestera_cmd(port->sw, cmd, &req.cmd, sizeof(req)); 222762306a36Sopenharmony_ci} 222862306a36Sopenharmony_ci 222962306a36Sopenharmony_ciint 223062306a36Sopenharmony_ciprestera_hw_cpu_code_counters_get(struct prestera_switch *sw, u8 code, 223162306a36Sopenharmony_ci enum prestera_hw_cpu_code_cnt_t counter_type, 223262306a36Sopenharmony_ci u64 *packet_count) 223362306a36Sopenharmony_ci{ 223462306a36Sopenharmony_ci struct prestera_msg_cpu_code_counter_req req = { 223562306a36Sopenharmony_ci .counter_type = counter_type, 223662306a36Sopenharmony_ci .code = code, 223762306a36Sopenharmony_ci }; 223862306a36Sopenharmony_ci struct mvsw_msg_cpu_code_counter_ret resp; 223962306a36Sopenharmony_ci int err; 224062306a36Sopenharmony_ci 224162306a36Sopenharmony_ci err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_CPU_CODE_COUNTERS_GET, 224262306a36Sopenharmony_ci &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 224362306a36Sopenharmony_ci if (err) 224462306a36Sopenharmony_ci return err; 224562306a36Sopenharmony_ci 224662306a36Sopenharmony_ci *packet_count = __le64_to_cpu(resp.packet_count); 224762306a36Sopenharmony_ci 224862306a36Sopenharmony_ci return 0; 224962306a36Sopenharmony_ci} 225062306a36Sopenharmony_ci 225162306a36Sopenharmony_ciint prestera_hw_event_handler_register(struct prestera_switch *sw, 225262306a36Sopenharmony_ci enum prestera_event_type type, 225362306a36Sopenharmony_ci prestera_event_cb_t fn, 225462306a36Sopenharmony_ci void *arg) 225562306a36Sopenharmony_ci{ 225662306a36Sopenharmony_ci struct prestera_fw_event_handler *eh; 225762306a36Sopenharmony_ci 225862306a36Sopenharmony_ci eh = __find_event_handler(sw, type); 225962306a36Sopenharmony_ci if (eh) 226062306a36Sopenharmony_ci return -EEXIST; 226162306a36Sopenharmony_ci 226262306a36Sopenharmony_ci eh = kmalloc(sizeof(*eh), GFP_KERNEL); 226362306a36Sopenharmony_ci if (!eh) 226462306a36Sopenharmony_ci return -ENOMEM; 226562306a36Sopenharmony_ci 226662306a36Sopenharmony_ci eh->type = type; 226762306a36Sopenharmony_ci eh->func = fn; 226862306a36Sopenharmony_ci eh->arg = arg; 226962306a36Sopenharmony_ci 227062306a36Sopenharmony_ci INIT_LIST_HEAD(&eh->list); 227162306a36Sopenharmony_ci 227262306a36Sopenharmony_ci list_add_rcu(&eh->list, &sw->event_handlers); 227362306a36Sopenharmony_ci 227462306a36Sopenharmony_ci return 0; 227562306a36Sopenharmony_ci} 227662306a36Sopenharmony_ci 227762306a36Sopenharmony_civoid prestera_hw_event_handler_unregister(struct prestera_switch *sw, 227862306a36Sopenharmony_ci enum prestera_event_type type, 227962306a36Sopenharmony_ci prestera_event_cb_t fn) 228062306a36Sopenharmony_ci{ 228162306a36Sopenharmony_ci struct prestera_fw_event_handler *eh; 228262306a36Sopenharmony_ci 228362306a36Sopenharmony_ci eh = __find_event_handler(sw, type); 228462306a36Sopenharmony_ci if (!eh) 228562306a36Sopenharmony_ci return; 228662306a36Sopenharmony_ci 228762306a36Sopenharmony_ci list_del_rcu(&eh->list); 228862306a36Sopenharmony_ci kfree_rcu(eh, rcu); 228962306a36Sopenharmony_ci} 229062306a36Sopenharmony_ci 229162306a36Sopenharmony_ciint prestera_hw_counter_trigger(struct prestera_switch *sw, u32 block_id) 229262306a36Sopenharmony_ci{ 229362306a36Sopenharmony_ci struct prestera_msg_counter_req req = { 229462306a36Sopenharmony_ci .block_id = __cpu_to_le32(block_id) 229562306a36Sopenharmony_ci }; 229662306a36Sopenharmony_ci 229762306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_COUNTER_TRIGGER, 229862306a36Sopenharmony_ci &req.cmd, sizeof(req)); 229962306a36Sopenharmony_ci} 230062306a36Sopenharmony_ci 230162306a36Sopenharmony_ciint prestera_hw_counter_abort(struct prestera_switch *sw) 230262306a36Sopenharmony_ci{ 230362306a36Sopenharmony_ci struct prestera_msg_counter_req req; 230462306a36Sopenharmony_ci 230562306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_COUNTER_ABORT, 230662306a36Sopenharmony_ci &req.cmd, sizeof(req)); 230762306a36Sopenharmony_ci} 230862306a36Sopenharmony_ci 230962306a36Sopenharmony_ciint prestera_hw_counters_get(struct prestera_switch *sw, u32 idx, 231062306a36Sopenharmony_ci u32 *len, bool *done, 231162306a36Sopenharmony_ci struct prestera_counter_stats *stats) 231262306a36Sopenharmony_ci{ 231362306a36Sopenharmony_ci struct prestera_msg_counter_resp *resp; 231462306a36Sopenharmony_ci struct prestera_msg_counter_req req = { 231562306a36Sopenharmony_ci .block_id = __cpu_to_le32(idx), 231662306a36Sopenharmony_ci .num_counters = __cpu_to_le32(*len), 231762306a36Sopenharmony_ci }; 231862306a36Sopenharmony_ci size_t size = struct_size(resp, stats, *len); 231962306a36Sopenharmony_ci int err, i; 232062306a36Sopenharmony_ci 232162306a36Sopenharmony_ci resp = kmalloc(size, GFP_KERNEL); 232262306a36Sopenharmony_ci if (!resp) 232362306a36Sopenharmony_ci return -ENOMEM; 232462306a36Sopenharmony_ci 232562306a36Sopenharmony_ci err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_COUNTER_GET, 232662306a36Sopenharmony_ci &req.cmd, sizeof(req), &resp->ret, size); 232762306a36Sopenharmony_ci if (err) 232862306a36Sopenharmony_ci goto free_buff; 232962306a36Sopenharmony_ci 233062306a36Sopenharmony_ci for (i = 0; i < __le32_to_cpu(resp->num_counters); i++) { 233162306a36Sopenharmony_ci stats[i].packets += __le64_to_cpu(resp->stats[i].packets); 233262306a36Sopenharmony_ci stats[i].bytes += __le64_to_cpu(resp->stats[i].bytes); 233362306a36Sopenharmony_ci } 233462306a36Sopenharmony_ci 233562306a36Sopenharmony_ci *len = __le32_to_cpu(resp->num_counters); 233662306a36Sopenharmony_ci *done = __le32_to_cpu(resp->done); 233762306a36Sopenharmony_ci 233862306a36Sopenharmony_cifree_buff: 233962306a36Sopenharmony_ci kfree(resp); 234062306a36Sopenharmony_ci return err; 234162306a36Sopenharmony_ci} 234262306a36Sopenharmony_ci 234362306a36Sopenharmony_ciint prestera_hw_counter_block_get(struct prestera_switch *sw, 234462306a36Sopenharmony_ci u32 client, u32 *block_id, u32 *offset, 234562306a36Sopenharmony_ci u32 *num_counters) 234662306a36Sopenharmony_ci{ 234762306a36Sopenharmony_ci struct prestera_msg_counter_resp resp; 234862306a36Sopenharmony_ci struct prestera_msg_counter_req req = { 234962306a36Sopenharmony_ci .client = __cpu_to_le32(client) 235062306a36Sopenharmony_ci }; 235162306a36Sopenharmony_ci int err; 235262306a36Sopenharmony_ci 235362306a36Sopenharmony_ci err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_COUNTER_BLOCK_GET, 235462306a36Sopenharmony_ci &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 235562306a36Sopenharmony_ci if (err) 235662306a36Sopenharmony_ci return err; 235762306a36Sopenharmony_ci 235862306a36Sopenharmony_ci *block_id = __le32_to_cpu(resp.block_id); 235962306a36Sopenharmony_ci *offset = __le32_to_cpu(resp.offset); 236062306a36Sopenharmony_ci *num_counters = __le32_to_cpu(resp.num_counters); 236162306a36Sopenharmony_ci 236262306a36Sopenharmony_ci return 0; 236362306a36Sopenharmony_ci} 236462306a36Sopenharmony_ci 236562306a36Sopenharmony_ciint prestera_hw_counter_block_release(struct prestera_switch *sw, 236662306a36Sopenharmony_ci u32 block_id) 236762306a36Sopenharmony_ci{ 236862306a36Sopenharmony_ci struct prestera_msg_counter_req req = { 236962306a36Sopenharmony_ci .block_id = __cpu_to_le32(block_id) 237062306a36Sopenharmony_ci }; 237162306a36Sopenharmony_ci 237262306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_COUNTER_BLOCK_RELEASE, 237362306a36Sopenharmony_ci &req.cmd, sizeof(req)); 237462306a36Sopenharmony_ci} 237562306a36Sopenharmony_ci 237662306a36Sopenharmony_ciint prestera_hw_counter_clear(struct prestera_switch *sw, u32 block_id, 237762306a36Sopenharmony_ci u32 counter_id) 237862306a36Sopenharmony_ci{ 237962306a36Sopenharmony_ci struct prestera_msg_counter_req req = { 238062306a36Sopenharmony_ci .block_id = __cpu_to_le32(block_id), 238162306a36Sopenharmony_ci .num_counters = __cpu_to_le32(counter_id) 238262306a36Sopenharmony_ci }; 238362306a36Sopenharmony_ci 238462306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_COUNTER_CLEAR, 238562306a36Sopenharmony_ci &req.cmd, sizeof(req)); 238662306a36Sopenharmony_ci} 238762306a36Sopenharmony_ci 238862306a36Sopenharmony_ciint prestera_hw_policer_create(struct prestera_switch *sw, u8 type, 238962306a36Sopenharmony_ci u32 *policer_id) 239062306a36Sopenharmony_ci{ 239162306a36Sopenharmony_ci struct prestera_msg_policer_resp resp; 239262306a36Sopenharmony_ci struct prestera_msg_policer_req req = { 239362306a36Sopenharmony_ci .type = type 239462306a36Sopenharmony_ci }; 239562306a36Sopenharmony_ci int err; 239662306a36Sopenharmony_ci 239762306a36Sopenharmony_ci err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_POLICER_CREATE, 239862306a36Sopenharmony_ci &req.cmd, sizeof(req), &resp.ret, sizeof(resp)); 239962306a36Sopenharmony_ci if (err) 240062306a36Sopenharmony_ci return err; 240162306a36Sopenharmony_ci 240262306a36Sopenharmony_ci *policer_id = __le32_to_cpu(resp.id); 240362306a36Sopenharmony_ci return 0; 240462306a36Sopenharmony_ci} 240562306a36Sopenharmony_ci 240662306a36Sopenharmony_ciint prestera_hw_policer_release(struct prestera_switch *sw, 240762306a36Sopenharmony_ci u32 policer_id) 240862306a36Sopenharmony_ci{ 240962306a36Sopenharmony_ci struct prestera_msg_policer_req req = { 241062306a36Sopenharmony_ci .id = __cpu_to_le32(policer_id) 241162306a36Sopenharmony_ci }; 241262306a36Sopenharmony_ci 241362306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_POLICER_RELEASE, 241462306a36Sopenharmony_ci &req.cmd, sizeof(req)); 241562306a36Sopenharmony_ci} 241662306a36Sopenharmony_ci 241762306a36Sopenharmony_ciint prestera_hw_policer_sr_tcm_set(struct prestera_switch *sw, 241862306a36Sopenharmony_ci u32 policer_id, u64 cir, u32 cbs) 241962306a36Sopenharmony_ci{ 242062306a36Sopenharmony_ci struct prestera_msg_policer_req req = { 242162306a36Sopenharmony_ci .mode = PRESTERA_POLICER_MODE_SR_TCM, 242262306a36Sopenharmony_ci .id = __cpu_to_le32(policer_id), 242362306a36Sopenharmony_ci .sr_tcm = { 242462306a36Sopenharmony_ci .cir = __cpu_to_le64(cir), 242562306a36Sopenharmony_ci .cbs = __cpu_to_le32(cbs) 242662306a36Sopenharmony_ci } 242762306a36Sopenharmony_ci }; 242862306a36Sopenharmony_ci 242962306a36Sopenharmony_ci return prestera_cmd(sw, PRESTERA_CMD_TYPE_POLICER_SET, 243062306a36Sopenharmony_ci &req.cmd, sizeof(req)); 243162306a36Sopenharmony_ci} 243262306a36Sopenharmony_ci 243362306a36Sopenharmony_ciint prestera_hw_flood_domain_create(struct prestera_flood_domain *domain) 243462306a36Sopenharmony_ci{ 243562306a36Sopenharmony_ci struct prestera_msg_flood_domain_create_resp resp; 243662306a36Sopenharmony_ci struct prestera_msg_flood_domain_create_req req; 243762306a36Sopenharmony_ci int err; 243862306a36Sopenharmony_ci 243962306a36Sopenharmony_ci err = prestera_cmd_ret(domain->sw, 244062306a36Sopenharmony_ci PRESTERA_CMD_TYPE_FLOOD_DOMAIN_CREATE, &req.cmd, 244162306a36Sopenharmony_ci sizeof(req), &resp.ret, sizeof(resp)); 244262306a36Sopenharmony_ci if (err) 244362306a36Sopenharmony_ci return err; 244462306a36Sopenharmony_ci 244562306a36Sopenharmony_ci domain->idx = __le32_to_cpu(resp.flood_domain_idx); 244662306a36Sopenharmony_ci 244762306a36Sopenharmony_ci return 0; 244862306a36Sopenharmony_ci} 244962306a36Sopenharmony_ci 245062306a36Sopenharmony_ciint prestera_hw_flood_domain_destroy(struct prestera_flood_domain *domain) 245162306a36Sopenharmony_ci{ 245262306a36Sopenharmony_ci struct prestera_msg_flood_domain_destroy_req req = { 245362306a36Sopenharmony_ci .flood_domain_idx = __cpu_to_le32(domain->idx), 245462306a36Sopenharmony_ci }; 245562306a36Sopenharmony_ci 245662306a36Sopenharmony_ci return prestera_cmd(domain->sw, PRESTERA_CMD_TYPE_FLOOD_DOMAIN_DESTROY, 245762306a36Sopenharmony_ci &req.cmd, sizeof(req)); 245862306a36Sopenharmony_ci} 245962306a36Sopenharmony_ci 246062306a36Sopenharmony_ciint prestera_hw_flood_domain_ports_set(struct prestera_flood_domain *domain) 246162306a36Sopenharmony_ci{ 246262306a36Sopenharmony_ci struct prestera_flood_domain_port *flood_domain_port; 246362306a36Sopenharmony_ci struct prestera_msg_flood_domain_ports_set_req *req; 246462306a36Sopenharmony_ci struct prestera_msg_flood_domain_port *ports; 246562306a36Sopenharmony_ci struct prestera_switch *sw = domain->sw; 246662306a36Sopenharmony_ci struct prestera_port *port; 246762306a36Sopenharmony_ci u32 ports_num = 0; 246862306a36Sopenharmony_ci int buf_size; 246962306a36Sopenharmony_ci void *buff; 247062306a36Sopenharmony_ci u16 lag_id; 247162306a36Sopenharmony_ci int err; 247262306a36Sopenharmony_ci 247362306a36Sopenharmony_ci list_for_each_entry(flood_domain_port, &domain->flood_domain_port_list, 247462306a36Sopenharmony_ci flood_domain_port_node) 247562306a36Sopenharmony_ci ports_num++; 247662306a36Sopenharmony_ci 247762306a36Sopenharmony_ci if (!ports_num) 247862306a36Sopenharmony_ci return -EINVAL; 247962306a36Sopenharmony_ci 248062306a36Sopenharmony_ci buf_size = sizeof(*req) + sizeof(*ports) * ports_num; 248162306a36Sopenharmony_ci 248262306a36Sopenharmony_ci buff = kmalloc(buf_size, GFP_KERNEL); 248362306a36Sopenharmony_ci if (!buff) 248462306a36Sopenharmony_ci return -ENOMEM; 248562306a36Sopenharmony_ci 248662306a36Sopenharmony_ci req = buff; 248762306a36Sopenharmony_ci ports = buff + sizeof(*req); 248862306a36Sopenharmony_ci 248962306a36Sopenharmony_ci req->flood_domain_idx = __cpu_to_le32(domain->idx); 249062306a36Sopenharmony_ci req->ports_num = __cpu_to_le32(ports_num); 249162306a36Sopenharmony_ci 249262306a36Sopenharmony_ci list_for_each_entry(flood_domain_port, &domain->flood_domain_port_list, 249362306a36Sopenharmony_ci flood_domain_port_node) { 249462306a36Sopenharmony_ci if (netif_is_lag_master(flood_domain_port->dev)) { 249562306a36Sopenharmony_ci if (prestera_lag_id(sw, flood_domain_port->dev, 249662306a36Sopenharmony_ci &lag_id)) { 249762306a36Sopenharmony_ci kfree(buff); 249862306a36Sopenharmony_ci return -EINVAL; 249962306a36Sopenharmony_ci } 250062306a36Sopenharmony_ci 250162306a36Sopenharmony_ci ports->port_type = 250262306a36Sopenharmony_ci __cpu_to_le16(PRESTERA_HW_FLOOD_DOMAIN_PORT_TYPE_LAG); 250362306a36Sopenharmony_ci ports->lag_id = __cpu_to_le16(lag_id); 250462306a36Sopenharmony_ci } else { 250562306a36Sopenharmony_ci port = prestera_port_dev_lower_find(flood_domain_port->dev); 250662306a36Sopenharmony_ci 250762306a36Sopenharmony_ci ports->port_type = 250862306a36Sopenharmony_ci __cpu_to_le16(PRESTERA_HW_FDB_ENTRY_TYPE_REG_PORT); 250962306a36Sopenharmony_ci ports->dev_num = __cpu_to_le32(port->dev_id); 251062306a36Sopenharmony_ci ports->port_num = __cpu_to_le32(port->hw_id); 251162306a36Sopenharmony_ci } 251262306a36Sopenharmony_ci 251362306a36Sopenharmony_ci ports->vid = __cpu_to_le16(flood_domain_port->vid); 251462306a36Sopenharmony_ci 251562306a36Sopenharmony_ci ports++; 251662306a36Sopenharmony_ci } 251762306a36Sopenharmony_ci 251862306a36Sopenharmony_ci err = prestera_cmd(sw, PRESTERA_CMD_TYPE_FLOOD_DOMAIN_PORTS_SET, 251962306a36Sopenharmony_ci &req->cmd, buf_size); 252062306a36Sopenharmony_ci 252162306a36Sopenharmony_ci kfree(buff); 252262306a36Sopenharmony_ci 252362306a36Sopenharmony_ci return err; 252462306a36Sopenharmony_ci} 252562306a36Sopenharmony_ci 252662306a36Sopenharmony_ciint prestera_hw_flood_domain_ports_reset(struct prestera_flood_domain *domain) 252762306a36Sopenharmony_ci{ 252862306a36Sopenharmony_ci struct prestera_msg_flood_domain_ports_reset_req req = { 252962306a36Sopenharmony_ci .flood_domain_idx = __cpu_to_le32(domain->idx), 253062306a36Sopenharmony_ci }; 253162306a36Sopenharmony_ci 253262306a36Sopenharmony_ci return prestera_cmd(domain->sw, 253362306a36Sopenharmony_ci PRESTERA_CMD_TYPE_FLOOD_DOMAIN_PORTS_RESET, &req.cmd, 253462306a36Sopenharmony_ci sizeof(req)); 253562306a36Sopenharmony_ci} 253662306a36Sopenharmony_ci 253762306a36Sopenharmony_ciint prestera_hw_mdb_create(struct prestera_mdb_entry *mdb) 253862306a36Sopenharmony_ci{ 253962306a36Sopenharmony_ci struct prestera_msg_mdb_create_req req = { 254062306a36Sopenharmony_ci .flood_domain_idx = __cpu_to_le32(mdb->flood_domain->idx), 254162306a36Sopenharmony_ci .vid = __cpu_to_le16(mdb->vid), 254262306a36Sopenharmony_ci }; 254362306a36Sopenharmony_ci 254462306a36Sopenharmony_ci memcpy(req.mac, mdb->addr, ETH_ALEN); 254562306a36Sopenharmony_ci 254662306a36Sopenharmony_ci return prestera_cmd(mdb->sw, PRESTERA_CMD_TYPE_MDB_CREATE, &req.cmd, 254762306a36Sopenharmony_ci sizeof(req)); 254862306a36Sopenharmony_ci} 254962306a36Sopenharmony_ci 255062306a36Sopenharmony_ciint prestera_hw_mdb_destroy(struct prestera_mdb_entry *mdb) 255162306a36Sopenharmony_ci{ 255262306a36Sopenharmony_ci struct prestera_msg_mdb_destroy_req req = { 255362306a36Sopenharmony_ci .flood_domain_idx = __cpu_to_le32(mdb->flood_domain->idx), 255462306a36Sopenharmony_ci .vid = __cpu_to_le16(mdb->vid), 255562306a36Sopenharmony_ci }; 255662306a36Sopenharmony_ci 255762306a36Sopenharmony_ci memcpy(req.mac, mdb->addr, ETH_ALEN); 255862306a36Sopenharmony_ci 255962306a36Sopenharmony_ci return prestera_cmd(mdb->sw, PRESTERA_CMD_TYPE_MDB_DESTROY, &req.cmd, 256062306a36Sopenharmony_ci sizeof(req)); 256162306a36Sopenharmony_ci} 2562