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