1501ef306SVadym Kochan // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2501ef306SVadym Kochan /* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved */
3501ef306SVadym Kochan 
4501ef306SVadym Kochan #include <linux/etherdevice.h>
5c00e8a69SVadym Kochan #include <linux/if_bridge.h>
6501ef306SVadym Kochan #include <linux/ethtool.h>
7501ef306SVadym Kochan #include <linux/list.h>
8501ef306SVadym Kochan 
9501ef306SVadym Kochan #include "prestera.h"
10501ef306SVadym Kochan #include "prestera_hw.h"
118b474a9fSSerhiy Boiko #include "prestera_acl.h"
126e36c7bcSVolodymyr Mytnyk #include "prestera_counter.h"
130a23ae23SYevhen Orlov #include "prestera_router_hw.h"
14501ef306SVadym Kochan 
15501ef306SVadym Kochan #define PRESTERA_SWITCH_INIT_TIMEOUT_MS (30 * 1000)
16501ef306SVadym Kochan 
17501ef306SVadym Kochan #define PRESTERA_MIN_MTU 64
18501ef306SVadym Kochan 
190a23ae23SYevhen Orlov #define PRESTERA_MSG_CHUNK_SIZE 1024
200a23ae23SYevhen Orlov 
21501ef306SVadym Kochan enum prestera_cmd_type_t {
22501ef306SVadym Kochan 	PRESTERA_CMD_TYPE_SWITCH_INIT = 0x1,
23501ef306SVadym Kochan 	PRESTERA_CMD_TYPE_SWITCH_ATTR_SET = 0x2,
24501ef306SVadym Kochan 
25501ef306SVadym Kochan 	PRESTERA_CMD_TYPE_PORT_ATTR_SET = 0x100,
26501ef306SVadym Kochan 	PRESTERA_CMD_TYPE_PORT_ATTR_GET = 0x101,
27501ef306SVadym Kochan 	PRESTERA_CMD_TYPE_PORT_INFO_GET = 0x110,
28501ef306SVadym Kochan 
29e1189d9aSVadym Kochan 	PRESTERA_CMD_TYPE_VLAN_CREATE = 0x200,
30e1189d9aSVadym Kochan 	PRESTERA_CMD_TYPE_VLAN_DELETE = 0x201,
31e1189d9aSVadym Kochan 	PRESTERA_CMD_TYPE_VLAN_PORT_SET = 0x202,
32e1189d9aSVadym Kochan 	PRESTERA_CMD_TYPE_VLAN_PVID_SET = 0x203,
33e1189d9aSVadym Kochan 
34e1189d9aSVadym Kochan 	PRESTERA_CMD_TYPE_FDB_ADD = 0x300,
35e1189d9aSVadym Kochan 	PRESTERA_CMD_TYPE_FDB_DELETE = 0x301,
36e1189d9aSVadym Kochan 	PRESTERA_CMD_TYPE_FDB_FLUSH_PORT = 0x310,
37e1189d9aSVadym Kochan 	PRESTERA_CMD_TYPE_FDB_FLUSH_VLAN = 0x311,
38e1189d9aSVadym Kochan 	PRESTERA_CMD_TYPE_FDB_FLUSH_PORT_VLAN = 0x312,
39e1189d9aSVadym Kochan 
40e1189d9aSVadym Kochan 	PRESTERA_CMD_TYPE_BRIDGE_CREATE = 0x400,
41e1189d9aSVadym Kochan 	PRESTERA_CMD_TYPE_BRIDGE_DELETE = 0x401,
42e1189d9aSVadym Kochan 	PRESTERA_CMD_TYPE_BRIDGE_PORT_ADD = 0x402,
43e1189d9aSVadym Kochan 	PRESTERA_CMD_TYPE_BRIDGE_PORT_DELETE = 0x403,
44e1189d9aSVadym Kochan 
456e36c7bcSVolodymyr Mytnyk 	PRESTERA_CMD_TYPE_COUNTER_GET = 0x510,
466e36c7bcSVolodymyr Mytnyk 	PRESTERA_CMD_TYPE_COUNTER_ABORT = 0x511,
476e36c7bcSVolodymyr Mytnyk 	PRESTERA_CMD_TYPE_COUNTER_TRIGGER = 0x512,
486e36c7bcSVolodymyr Mytnyk 	PRESTERA_CMD_TYPE_COUNTER_BLOCK_GET = 0x513,
496e36c7bcSVolodymyr Mytnyk 	PRESTERA_CMD_TYPE_COUNTER_BLOCK_RELEASE = 0x514,
506e36c7bcSVolodymyr Mytnyk 	PRESTERA_CMD_TYPE_COUNTER_CLEAR = 0x515,
516e36c7bcSVolodymyr Mytnyk 
5247327e19SVolodymyr Mytnyk 	PRESTERA_CMD_TYPE_VTCAM_CREATE = 0x540,
5347327e19SVolodymyr Mytnyk 	PRESTERA_CMD_TYPE_VTCAM_DESTROY = 0x541,
5447327e19SVolodymyr Mytnyk 	PRESTERA_CMD_TYPE_VTCAM_RULE_ADD = 0x550,
5547327e19SVolodymyr Mytnyk 	PRESTERA_CMD_TYPE_VTCAM_RULE_DELETE = 0x551,
5647327e19SVolodymyr Mytnyk 	PRESTERA_CMD_TYPE_VTCAM_IFACE_BIND = 0x560,
5747327e19SVolodymyr Mytnyk 	PRESTERA_CMD_TYPE_VTCAM_IFACE_UNBIND = 0x561,
588b474a9fSSerhiy Boiko 
590f07bd6bSYevhen Orlov 	PRESTERA_CMD_TYPE_ROUTER_RIF_CREATE = 0x600,
600f07bd6bSYevhen Orlov 	PRESTERA_CMD_TYPE_ROUTER_RIF_DELETE = 0x601,
6119787b93SYevhen Orlov 	PRESTERA_CMD_TYPE_ROUTER_LPM_ADD = 0x610,
6219787b93SYevhen Orlov 	PRESTERA_CMD_TYPE_ROUTER_LPM_DELETE = 0x611,
630a23ae23SYevhen Orlov 	PRESTERA_CMD_TYPE_ROUTER_NH_GRP_SET = 0x622,
640a23ae23SYevhen Orlov 	PRESTERA_CMD_TYPE_ROUTER_NH_GRP_BLK_GET = 0x645,
650a23ae23SYevhen Orlov 	PRESTERA_CMD_TYPE_ROUTER_NH_GRP_ADD = 0x623,
660a23ae23SYevhen Orlov 	PRESTERA_CMD_TYPE_ROUTER_NH_GRP_DELETE = 0x624,
676d1b3eb5SYevhen Orlov 	PRESTERA_CMD_TYPE_ROUTER_VR_CREATE = 0x630,
686d1b3eb5SYevhen Orlov 	PRESTERA_CMD_TYPE_ROUTER_VR_DELETE = 0x631,
696d1b3eb5SYevhen Orlov 
70fec7c9c7SOleksandr Mazur 	PRESTERA_CMD_TYPE_FLOOD_DOMAIN_CREATE = 0x700,
71fec7c9c7SOleksandr Mazur 	PRESTERA_CMD_TYPE_FLOOD_DOMAIN_DESTROY = 0x701,
72fec7c9c7SOleksandr Mazur 	PRESTERA_CMD_TYPE_FLOOD_DOMAIN_PORTS_SET = 0x702,
73fec7c9c7SOleksandr Mazur 	PRESTERA_CMD_TYPE_FLOOD_DOMAIN_PORTS_RESET = 0x703,
74fec7c9c7SOleksandr Mazur 
75fec7c9c7SOleksandr Mazur 	PRESTERA_CMD_TYPE_MDB_CREATE = 0x704,
76fec7c9c7SOleksandr Mazur 	PRESTERA_CMD_TYPE_MDB_DESTROY = 0x705,
77fec7c9c7SOleksandr Mazur 
78501ef306SVadym Kochan 	PRESTERA_CMD_TYPE_RXTX_INIT = 0x800,
79501ef306SVadym Kochan 
80255213caSSerhiy Boiko 	PRESTERA_CMD_TYPE_LAG_MEMBER_ADD = 0x900,
81255213caSSerhiy Boiko 	PRESTERA_CMD_TYPE_LAG_MEMBER_DELETE = 0x901,
82255213caSSerhiy Boiko 	PRESTERA_CMD_TYPE_LAG_MEMBER_ENABLE = 0x902,
83255213caSSerhiy Boiko 	PRESTERA_CMD_TYPE_LAG_MEMBER_DISABLE = 0x903,
84255213caSSerhiy Boiko 
85e1189d9aSVadym Kochan 	PRESTERA_CMD_TYPE_STP_PORT_SET = 0x1000,
86e1189d9aSVadym Kochan 
8713defa27SSerhiy Boiko 	PRESTERA_CMD_TYPE_SPAN_GET = 0x1100,
888c448c2bSSerhiy Boiko 	PRESTERA_CMD_TYPE_SPAN_INGRESS_BIND = 0x1101,
898c448c2bSSerhiy Boiko 	PRESTERA_CMD_TYPE_SPAN_INGRESS_UNBIND = 0x1102,
9013defa27SSerhiy Boiko 	PRESTERA_CMD_TYPE_SPAN_RELEASE = 0x1103,
918c448c2bSSerhiy Boiko 	PRESTERA_CMD_TYPE_SPAN_EGRESS_BIND = 0x1104,
928c448c2bSSerhiy Boiko 	PRESTERA_CMD_TYPE_SPAN_EGRESS_UNBIND = 0x1105,
9313defa27SSerhiy Boiko 
94dde2daa0SVolodymyr Mytnyk 	PRESTERA_CMD_TYPE_POLICER_CREATE = 0x1500,
95dde2daa0SVolodymyr Mytnyk 	PRESTERA_CMD_TYPE_POLICER_RELEASE = 0x1501,
96dde2daa0SVolodymyr Mytnyk 	PRESTERA_CMD_TYPE_POLICER_SET = 0x1502,
97dde2daa0SVolodymyr Mytnyk 
98a80cf955SOleksandr Mazur 	PRESTERA_CMD_TYPE_CPU_CODE_COUNTERS_GET = 0x2000,
99a80cf955SOleksandr Mazur 
100501ef306SVadym Kochan 	PRESTERA_CMD_TYPE_ACK = 0x10000,
101501ef306SVadym Kochan 	PRESTERA_CMD_TYPE_MAX
102501ef306SVadym Kochan };
103501ef306SVadym Kochan 
104501ef306SVadym Kochan enum {
105501ef306SVadym Kochan 	PRESTERA_CMD_PORT_ATTR_ADMIN_STATE = 1,
106501ef306SVadym Kochan 	PRESTERA_CMD_PORT_ATTR_MTU = 3,
107501ef306SVadym Kochan 	PRESTERA_CMD_PORT_ATTR_MAC = 4,
108a97d3c69SVadym Kochan 	PRESTERA_CMD_PORT_ATTR_SPEED = 5,
109e1189d9aSVadym Kochan 	PRESTERA_CMD_PORT_ATTR_ACCEPT_FRAME_TYPE = 6,
110e1189d9aSVadym Kochan 	PRESTERA_CMD_PORT_ATTR_LEARNING = 7,
111e1189d9aSVadym Kochan 	PRESTERA_CMD_PORT_ATTR_FLOOD = 8,
112501ef306SVadym Kochan 	PRESTERA_CMD_PORT_ATTR_CAPABILITY = 9,
11373ef239cSOleksandr Mazur 	PRESTERA_CMD_PORT_ATTR_LOCKED = 10,
114bb5dbf2cSVolodymyr Mytnyk 	PRESTERA_CMD_PORT_ATTR_PHY_MODE = 12,
115a97d3c69SVadym Kochan 	PRESTERA_CMD_PORT_ATTR_TYPE = 13,
116501ef306SVadym Kochan 	PRESTERA_CMD_PORT_ATTR_STATS = 17,
117bb5dbf2cSVolodymyr Mytnyk 	PRESTERA_CMD_PORT_ATTR_MAC_AUTONEG_RESTART = 18,
118bb5dbf2cSVolodymyr Mytnyk 	PRESTERA_CMD_PORT_ATTR_PHY_AUTONEG_RESTART = 19,
119bb5dbf2cSVolodymyr Mytnyk 	PRESTERA_CMD_PORT_ATTR_MAC_MODE = 22,
120501ef306SVadym Kochan };
121501ef306SVadym Kochan 
122501ef306SVadym Kochan enum {
123501ef306SVadym Kochan 	PRESTERA_CMD_SWITCH_ATTR_MAC = 1,
124e1189d9aSVadym Kochan 	PRESTERA_CMD_SWITCH_ATTR_AGEING = 2,
125501ef306SVadym Kochan };
126501ef306SVadym Kochan 
127501ef306SVadym Kochan enum {
128501ef306SVadym Kochan 	PRESTERA_CMD_ACK_OK,
129501ef306SVadym Kochan 	PRESTERA_CMD_ACK_FAILED,
130501ef306SVadym Kochan 
131501ef306SVadym Kochan 	PRESTERA_CMD_ACK_MAX
132501ef306SVadym Kochan };
133501ef306SVadym Kochan 
134501ef306SVadym Kochan enum {
135a97d3c69SVadym Kochan 	PRESTERA_PORT_TP_NA,
136a97d3c69SVadym Kochan 	PRESTERA_PORT_TP_MDI,
137a97d3c69SVadym Kochan 	PRESTERA_PORT_TP_MDIX,
138a97d3c69SVadym Kochan 	PRESTERA_PORT_TP_AUTO,
139a97d3c69SVadym Kochan };
140a97d3c69SVadym Kochan 
141a97d3c69SVadym Kochan enum {
142c00e8a69SVadym Kochan 	PRESTERA_PORT_FLOOD_TYPE_UC = 0,
143c00e8a69SVadym Kochan 	PRESTERA_PORT_FLOOD_TYPE_MC = 1,
144c00e8a69SVadym Kochan };
145c00e8a69SVadym Kochan 
146c00e8a69SVadym Kochan enum {
147501ef306SVadym Kochan 	PRESTERA_PORT_GOOD_OCTETS_RCV_CNT,
148501ef306SVadym Kochan 	PRESTERA_PORT_BAD_OCTETS_RCV_CNT,
149501ef306SVadym Kochan 	PRESTERA_PORT_MAC_TRANSMIT_ERR_CNT,
150501ef306SVadym Kochan 	PRESTERA_PORT_BRDC_PKTS_RCV_CNT,
151501ef306SVadym Kochan 	PRESTERA_PORT_MC_PKTS_RCV_CNT,
152501ef306SVadym Kochan 	PRESTERA_PORT_PKTS_64L_CNT,
153501ef306SVadym Kochan 	PRESTERA_PORT_PKTS_65TO127L_CNT,
154501ef306SVadym Kochan 	PRESTERA_PORT_PKTS_128TO255L_CNT,
155501ef306SVadym Kochan 	PRESTERA_PORT_PKTS_256TO511L_CNT,
156501ef306SVadym Kochan 	PRESTERA_PORT_PKTS_512TO1023L_CNT,
157501ef306SVadym Kochan 	PRESTERA_PORT_PKTS_1024TOMAXL_CNT,
158501ef306SVadym Kochan 	PRESTERA_PORT_EXCESSIVE_COLLISIONS_CNT,
159501ef306SVadym Kochan 	PRESTERA_PORT_MC_PKTS_SENT_CNT,
160501ef306SVadym Kochan 	PRESTERA_PORT_BRDC_PKTS_SENT_CNT,
161501ef306SVadym Kochan 	PRESTERA_PORT_FC_SENT_CNT,
162501ef306SVadym Kochan 	PRESTERA_PORT_GOOD_FC_RCV_CNT,
163501ef306SVadym Kochan 	PRESTERA_PORT_DROP_EVENTS_CNT,
164501ef306SVadym Kochan 	PRESTERA_PORT_UNDERSIZE_PKTS_CNT,
165501ef306SVadym Kochan 	PRESTERA_PORT_FRAGMENTS_PKTS_CNT,
166501ef306SVadym Kochan 	PRESTERA_PORT_OVERSIZE_PKTS_CNT,
167501ef306SVadym Kochan 	PRESTERA_PORT_JABBER_PKTS_CNT,
168501ef306SVadym Kochan 	PRESTERA_PORT_MAC_RCV_ERROR_CNT,
169501ef306SVadym Kochan 	PRESTERA_PORT_BAD_CRC_CNT,
170501ef306SVadym Kochan 	PRESTERA_PORT_COLLISIONS_CNT,
171501ef306SVadym Kochan 	PRESTERA_PORT_LATE_COLLISIONS_CNT,
172501ef306SVadym Kochan 	PRESTERA_PORT_GOOD_UC_PKTS_RCV_CNT,
173501ef306SVadym Kochan 	PRESTERA_PORT_GOOD_UC_PKTS_SENT_CNT,
174501ef306SVadym Kochan 	PRESTERA_PORT_MULTIPLE_PKTS_SENT_CNT,
175501ef306SVadym Kochan 	PRESTERA_PORT_DEFERRED_PKTS_SENT_CNT,
176501ef306SVadym Kochan 	PRESTERA_PORT_GOOD_OCTETS_SENT_CNT,
177501ef306SVadym Kochan 
178501ef306SVadym Kochan 	PRESTERA_PORT_CNT_MAX
179501ef306SVadym Kochan };
180501ef306SVadym Kochan 
181a97d3c69SVadym Kochan enum {
182a97d3c69SVadym Kochan 	PRESTERA_FC_NONE,
183a97d3c69SVadym Kochan 	PRESTERA_FC_SYMMETRIC,
184a97d3c69SVadym Kochan 	PRESTERA_FC_ASYMMETRIC,
185a97d3c69SVadym Kochan 	PRESTERA_FC_SYMM_ASYMM,
186a97d3c69SVadym Kochan };
187a97d3c69SVadym Kochan 
188255213caSSerhiy Boiko enum {
189dde2daa0SVolodymyr Mytnyk 	PRESTERA_POLICER_MODE_SR_TCM
190dde2daa0SVolodymyr Mytnyk };
191dde2daa0SVolodymyr Mytnyk 
192dde2daa0SVolodymyr Mytnyk enum {
193255213caSSerhiy Boiko 	PRESTERA_HW_FDB_ENTRY_TYPE_REG_PORT = 0,
194255213caSSerhiy Boiko 	PRESTERA_HW_FDB_ENTRY_TYPE_LAG = 1,
195255213caSSerhiy Boiko 	PRESTERA_HW_FDB_ENTRY_TYPE_MAX = 2,
196255213caSSerhiy Boiko };
197255213caSSerhiy Boiko 
198501ef306SVadym Kochan struct prestera_fw_event_handler {
199501ef306SVadym Kochan 	struct list_head list;
200501ef306SVadym Kochan 	struct rcu_head rcu;
201501ef306SVadym Kochan 	enum prestera_event_type type;
202501ef306SVadym Kochan 	prestera_event_cb_t func;
203501ef306SVadym Kochan 	void *arg;
204501ef306SVadym Kochan };
205501ef306SVadym Kochan 
206fec7c9c7SOleksandr Mazur enum {
207fec7c9c7SOleksandr Mazur 	PRESTERA_HW_FLOOD_DOMAIN_PORT_TYPE_REG_PORT = 0,
208fec7c9c7SOleksandr Mazur 	PRESTERA_HW_FLOOD_DOMAIN_PORT_TYPE_LAG = 1,
209fec7c9c7SOleksandr Mazur 	PRESTERA_HW_FLOOD_DOMAIN_PORT_TYPE_MAX = 2,
210fec7c9c7SOleksandr Mazur };
211fec7c9c7SOleksandr Mazur 
212501ef306SVadym Kochan struct prestera_msg_cmd {
213bb5dbf2cSVolodymyr Mytnyk 	__le32 type;
214501ef306SVadym Kochan };
215501ef306SVadym Kochan 
216501ef306SVadym Kochan struct prestera_msg_ret {
217501ef306SVadym Kochan 	struct prestera_msg_cmd cmd;
218bb5dbf2cSVolodymyr Mytnyk 	__le32 status;
219501ef306SVadym Kochan };
220501ef306SVadym Kochan 
221501ef306SVadym Kochan struct prestera_msg_common_req {
222501ef306SVadym Kochan 	struct prestera_msg_cmd cmd;
223501ef306SVadym Kochan };
224501ef306SVadym Kochan 
225501ef306SVadym Kochan struct prestera_msg_common_resp {
226501ef306SVadym Kochan 	struct prestera_msg_ret ret;
227501ef306SVadym Kochan };
228501ef306SVadym Kochan 
229501ef306SVadym Kochan struct prestera_msg_switch_attr_req {
230501ef306SVadym Kochan 	struct prestera_msg_cmd cmd;
231bb5dbf2cSVolodymyr Mytnyk 	__le32 attr;
232e1464db5SVolodymyr Mytnyk 	union {
233e1464db5SVolodymyr Mytnyk 		__le32 ageing_timeout_ms;
234e1464db5SVolodymyr Mytnyk 		struct {
235e1464db5SVolodymyr Mytnyk 			u8 mac[ETH_ALEN];
236e1464db5SVolodymyr Mytnyk 			u8 __pad[2];
237e1464db5SVolodymyr Mytnyk 		};
238e1464db5SVolodymyr Mytnyk 	} param;
239501ef306SVadym Kochan };
240501ef306SVadym Kochan 
241501ef306SVadym Kochan struct prestera_msg_switch_init_resp {
242501ef306SVadym Kochan 	struct prestera_msg_ret ret;
243bb5dbf2cSVolodymyr Mytnyk 	__le32 port_count;
244bb5dbf2cSVolodymyr Mytnyk 	__le32 mtu_max;
245e1464db5SVolodymyr Mytnyk 	__le32 size_tbl_router_nexthop;
246501ef306SVadym Kochan 	u8 switch_id;
247255213caSSerhiy Boiko 	u8 lag_max;
248255213caSSerhiy Boiko 	u8 lag_member_max;
249e1464db5SVolodymyr Mytnyk };
250501ef306SVadym Kochan 
251bb5dbf2cSVolodymyr Mytnyk struct prestera_msg_event_port_param {
252bb5dbf2cSVolodymyr Mytnyk 	union {
253bb5dbf2cSVolodymyr Mytnyk 		struct {
254bb5dbf2cSVolodymyr Mytnyk 			__le32 mode;
255bb5dbf2cSVolodymyr Mytnyk 			__le32 speed;
256e1464db5SVolodymyr Mytnyk 			u8 oper;
257bb5dbf2cSVolodymyr Mytnyk 			u8 duplex;
258bb5dbf2cSVolodymyr Mytnyk 			u8 fc;
259501ef306SVadym Kochan 			u8 fec;
260e1464db5SVolodymyr Mytnyk 		} mac;
261bb5dbf2cSVolodymyr Mytnyk 		struct {
262bb5dbf2cSVolodymyr Mytnyk 			__le64 lmode_bmap;
263e1464db5SVolodymyr Mytnyk 			u8 mdix;
264bb5dbf2cSVolodymyr Mytnyk 			u8 fc;
265e1464db5SVolodymyr Mytnyk 			u8 __pad[2];
266e1464db5SVolodymyr Mytnyk 		} __packed phy; /* make sure always 12 bytes size */
267e1464db5SVolodymyr Mytnyk 	};
268e1464db5SVolodymyr Mytnyk };
269501ef306SVadym Kochan 
270501ef306SVadym Kochan struct prestera_msg_port_cap_param {
271bb5dbf2cSVolodymyr Mytnyk 	__le64 link_mode;
272501ef306SVadym Kochan 	u8 type;
273501ef306SVadym Kochan 	u8 fec;
274bb5dbf2cSVolodymyr Mytnyk 	u8 fc;
275501ef306SVadym Kochan 	u8 transceiver;
276501ef306SVadym Kochan };
277501ef306SVadym Kochan 
278c00e8a69SVadym Kochan struct prestera_msg_port_flood_param {
279c00e8a69SVadym Kochan 	u8 type;
280c00e8a69SVadym Kochan 	u8 enable;
281e1464db5SVolodymyr Mytnyk 	u8 __pad[2];
282c00e8a69SVadym Kochan };
283c00e8a69SVadym Kochan 
284501ef306SVadym Kochan union prestera_msg_port_param {
285e1464db5SVolodymyr Mytnyk 	__le32 mtu;
286e1464db5SVolodymyr Mytnyk 	__le32 speed;
287e1464db5SVolodymyr Mytnyk 	__le32 link_mode;
288501ef306SVadym Kochan 	u8 admin_state;
289501ef306SVadym Kochan 	u8 oper_state;
290501ef306SVadym Kochan 	u8 mac[ETH_ALEN];
291e1189d9aSVadym Kochan 	u8 accept_frm_type;
292e1189d9aSVadym Kochan 	u8 learning;
293e1189d9aSVadym Kochan 	u8 flood;
294a97d3c69SVadym Kochan 	u8 type;
295a97d3c69SVadym Kochan 	u8 duplex;
296a97d3c69SVadym Kochan 	u8 fec;
297a97d3c69SVadym Kochan 	u8 fc;
29873ef239cSOleksandr Mazur 	u8 br_locked;
299bb5dbf2cSVolodymyr Mytnyk 	union {
300bb5dbf2cSVolodymyr Mytnyk 		struct {
301e1464db5SVolodymyr Mytnyk 			u8 admin;
302bb5dbf2cSVolodymyr Mytnyk 			u8 fc;
303bb5dbf2cSVolodymyr Mytnyk 			u8 ap_enable;
304e1464db5SVolodymyr Mytnyk 			u8 __reserved[5];
305bb5dbf2cSVolodymyr Mytnyk 			union {
306bb5dbf2cSVolodymyr Mytnyk 				struct {
307bb5dbf2cSVolodymyr Mytnyk 					__le32 mode;
308bb5dbf2cSVolodymyr Mytnyk 					__le32 speed;
309e1464db5SVolodymyr Mytnyk 					u8 inband;
310bb5dbf2cSVolodymyr Mytnyk 					u8 duplex;
311bb5dbf2cSVolodymyr Mytnyk 					u8 fec;
312bb5dbf2cSVolodymyr Mytnyk 					u8 fec_supp;
313e1464db5SVolodymyr Mytnyk 				} reg_mode;
314bb5dbf2cSVolodymyr Mytnyk 				struct {
315bb5dbf2cSVolodymyr Mytnyk 					__le32 mode;
316bb5dbf2cSVolodymyr Mytnyk 					__le32 speed;
317bb5dbf2cSVolodymyr Mytnyk 					u8 fec;
318bb5dbf2cSVolodymyr Mytnyk 					u8 fec_supp;
319e1464db5SVolodymyr Mytnyk 					u8 __pad[2];
320e1464db5SVolodymyr Mytnyk 				} ap_modes[PRESTERA_AP_PORT_MAX];
321e1464db5SVolodymyr Mytnyk 			};
322e1464db5SVolodymyr Mytnyk 		} mac;
323bb5dbf2cSVolodymyr Mytnyk 		struct {
324bb5dbf2cSVolodymyr Mytnyk 			__le64 modes;
325bb5dbf2cSVolodymyr Mytnyk 			__le32 mode;
326e1464db5SVolodymyr Mytnyk 			u8 admin;
327e1464db5SVolodymyr Mytnyk 			u8 adv_enable;
328bb5dbf2cSVolodymyr Mytnyk 			u8 mdix;
329e1464db5SVolodymyr Mytnyk 			u8 __pad;
330e1464db5SVolodymyr Mytnyk 		} phy;
331e1464db5SVolodymyr Mytnyk 	} link;
332bb5dbf2cSVolodymyr Mytnyk 
333501ef306SVadym Kochan 	struct prestera_msg_port_cap_param cap;
334c00e8a69SVadym Kochan 	struct prestera_msg_port_flood_param flood_ext;
335bb5dbf2cSVolodymyr Mytnyk 	struct prestera_msg_event_port_param link_evt;
336e1464db5SVolodymyr Mytnyk };
337501ef306SVadym Kochan 
338501ef306SVadym Kochan struct prestera_msg_port_attr_req {
339501ef306SVadym Kochan 	struct prestera_msg_cmd cmd;
340bb5dbf2cSVolodymyr Mytnyk 	__le32 attr;
341bb5dbf2cSVolodymyr Mytnyk 	__le32 port;
342bb5dbf2cSVolodymyr Mytnyk 	__le32 dev;
343501ef306SVadym Kochan 	union prestera_msg_port_param param;
344e1464db5SVolodymyr Mytnyk };
345501ef306SVadym Kochan 
346501ef306SVadym Kochan struct prestera_msg_port_attr_resp {
347501ef306SVadym Kochan 	struct prestera_msg_ret ret;
348501ef306SVadym Kochan 	union prestera_msg_port_param param;
349e1464db5SVolodymyr Mytnyk };
350501ef306SVadym Kochan 
351501ef306SVadym Kochan struct prestera_msg_port_stats_resp {
352501ef306SVadym Kochan 	struct prestera_msg_ret ret;
353bb5dbf2cSVolodymyr Mytnyk 	__le64 stats[PRESTERA_PORT_CNT_MAX];
354501ef306SVadym Kochan };
355501ef306SVadym Kochan 
356501ef306SVadym Kochan struct prestera_msg_port_info_req {
357501ef306SVadym Kochan 	struct prestera_msg_cmd cmd;
358bb5dbf2cSVolodymyr Mytnyk 	__le32 port;
359501ef306SVadym Kochan };
360501ef306SVadym Kochan 
361501ef306SVadym Kochan struct prestera_msg_port_info_resp {
362501ef306SVadym Kochan 	struct prestera_msg_ret ret;
363bb5dbf2cSVolodymyr Mytnyk 	__le32 hw_id;
364bb5dbf2cSVolodymyr Mytnyk 	__le32 dev_id;
365bb5dbf2cSVolodymyr Mytnyk 	__le16 fp_id;
366236f57feSGeert Uytterhoeven 	u8 pad[2];
367501ef306SVadym Kochan };
368501ef306SVadym Kochan 
369e1189d9aSVadym Kochan struct prestera_msg_vlan_req {
370e1189d9aSVadym Kochan 	struct prestera_msg_cmd cmd;
371bb5dbf2cSVolodymyr Mytnyk 	__le32 port;
372bb5dbf2cSVolodymyr Mytnyk 	__le32 dev;
373bb5dbf2cSVolodymyr Mytnyk 	__le16 vid;
374e1189d9aSVadym Kochan 	u8 is_member;
375e1189d9aSVadym Kochan 	u8 is_tagged;
376e1189d9aSVadym Kochan };
377e1189d9aSVadym Kochan 
378e1189d9aSVadym Kochan struct prestera_msg_fdb_req {
379e1189d9aSVadym Kochan 	struct prestera_msg_cmd cmd;
380e1464db5SVolodymyr Mytnyk 	__le32 flush_mode;
381255213caSSerhiy Boiko 	union {
382255213caSSerhiy Boiko 		struct {
383bb5dbf2cSVolodymyr Mytnyk 			__le32 port;
384bb5dbf2cSVolodymyr Mytnyk 			__le32 dev;
385255213caSSerhiy Boiko 		};
386bb5dbf2cSVolodymyr Mytnyk 		__le16 lag_id;
387255213caSSerhiy Boiko 	} dest;
388bb5dbf2cSVolodymyr Mytnyk 	__le16 vid;
389e1464db5SVolodymyr Mytnyk 	u8 dest_type;
390e1189d9aSVadym Kochan 	u8 dynamic;
391e1464db5SVolodymyr Mytnyk 	u8 mac[ETH_ALEN];
392e1464db5SVolodymyr Mytnyk 	u8 __pad[2];
393e1464db5SVolodymyr Mytnyk };
394e1189d9aSVadym Kochan 
395e1189d9aSVadym Kochan struct prestera_msg_bridge_req {
396e1189d9aSVadym Kochan 	struct prestera_msg_cmd cmd;
397bb5dbf2cSVolodymyr Mytnyk 	__le32 port;
398bb5dbf2cSVolodymyr Mytnyk 	__le32 dev;
399bb5dbf2cSVolodymyr Mytnyk 	__le16 bridge;
400236f57feSGeert Uytterhoeven 	u8 pad[2];
401e1189d9aSVadym Kochan };
402e1189d9aSVadym Kochan 
403e1189d9aSVadym Kochan struct prestera_msg_bridge_resp {
404e1189d9aSVadym Kochan 	struct prestera_msg_ret ret;
405bb5dbf2cSVolodymyr Mytnyk 	__le16 bridge;
406236f57feSGeert Uytterhoeven 	u8 pad[2];
407e1189d9aSVadym Kochan };
408e1189d9aSVadym Kochan 
40947327e19SVolodymyr Mytnyk struct prestera_msg_vtcam_create_req {
41047327e19SVolodymyr Mytnyk 	struct prestera_msg_cmd cmd;
41147327e19SVolodymyr Mytnyk 	__le32 keymask[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX];
41247327e19SVolodymyr Mytnyk 	u8 direction;
41347327e19SVolodymyr Mytnyk 	u8 lookup;
41447327e19SVolodymyr Mytnyk 	u8 pad[2];
4158b474a9fSSerhiy Boiko };
4168b474a9fSSerhiy Boiko 
41747327e19SVolodymyr Mytnyk struct prestera_msg_vtcam_destroy_req {
41847327e19SVolodymyr Mytnyk 	struct prestera_msg_cmd cmd;
41947327e19SVolodymyr Mytnyk 	__le32 vtcam_id;
42047327e19SVolodymyr Mytnyk };
42147327e19SVolodymyr Mytnyk 
42247327e19SVolodymyr Mytnyk struct prestera_msg_vtcam_rule_del_req {
42347327e19SVolodymyr Mytnyk 	struct prestera_msg_cmd cmd;
42447327e19SVolodymyr Mytnyk 	__le32 vtcam_id;
42547327e19SVolodymyr Mytnyk 	__le32 id;
42647327e19SVolodymyr Mytnyk };
42747327e19SVolodymyr Mytnyk 
42847327e19SVolodymyr Mytnyk struct prestera_msg_vtcam_bind_req {
42947327e19SVolodymyr Mytnyk 	struct prestera_msg_cmd cmd;
4308b474a9fSSerhiy Boiko 	union {
4318b474a9fSSerhiy Boiko 		struct {
43247327e19SVolodymyr Mytnyk 			__le32 hw_id;
43347327e19SVolodymyr Mytnyk 			__le32 dev_id;
43447327e19SVolodymyr Mytnyk 		} port;
43547327e19SVolodymyr Mytnyk 		__le32 index;
43647327e19SVolodymyr Mytnyk 	};
43747327e19SVolodymyr Mytnyk 	__le32 vtcam_id;
43847327e19SVolodymyr Mytnyk 	__le16 pcl_id;
43947327e19SVolodymyr Mytnyk 	__le16 type;
4408b474a9fSSerhiy Boiko };
4418b474a9fSSerhiy Boiko 
44247327e19SVolodymyr Mytnyk struct prestera_msg_vtcam_resp {
44347327e19SVolodymyr Mytnyk 	struct prestera_msg_ret ret;
44447327e19SVolodymyr Mytnyk 	__le32 vtcam_id;
44547327e19SVolodymyr Mytnyk 	__le32 rule_id;
44647327e19SVolodymyr Mytnyk };
44747327e19SVolodymyr Mytnyk 
44847327e19SVolodymyr Mytnyk struct prestera_msg_acl_action {
449bb5dbf2cSVolodymyr Mytnyk 	__le32 id;
4506e36c7bcSVolodymyr Mytnyk 	__le32 __reserved;
4516e36c7bcSVolodymyr Mytnyk 	union {
4526e36c7bcSVolodymyr Mytnyk 		struct {
453fa5d824cSVolodymyr Mytnyk 			__le32 index;
454fa5d824cSVolodymyr Mytnyk 		} jump;
455fa5d824cSVolodymyr Mytnyk 		struct {
4566e36c7bcSVolodymyr Mytnyk 			__le32 id;
457dde2daa0SVolodymyr Mytnyk 		} police;
458dde2daa0SVolodymyr Mytnyk 		struct {
459dde2daa0SVolodymyr Mytnyk 			__le32 id;
4606e36c7bcSVolodymyr Mytnyk 		} count;
4616e36c7bcSVolodymyr Mytnyk 		__le32 reserved[6];
4626e36c7bcSVolodymyr Mytnyk 	};
4636e36c7bcSVolodymyr Mytnyk };
4646e36c7bcSVolodymyr Mytnyk 
465*86348d21SErick Archer struct prestera_msg_vtcam_rule_add_req {
466*86348d21SErick Archer 	struct prestera_msg_cmd cmd;
467*86348d21SErick Archer 	__le32 key[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX];
468*86348d21SErick Archer 	__le32 keymask[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX];
469*86348d21SErick Archer 	__le32 vtcam_id;
470*86348d21SErick Archer 	__le32 prio;
471*86348d21SErick Archer 	__le32 n_act;
472*86348d21SErick Archer 	struct prestera_msg_acl_action actions_msg[] __counted_by_le(n_act);
473*86348d21SErick Archer };
474*86348d21SErick Archer 
4756e36c7bcSVolodymyr Mytnyk struct prestera_msg_counter_req {
4766e36c7bcSVolodymyr Mytnyk 	struct prestera_msg_cmd cmd;
4776e36c7bcSVolodymyr Mytnyk 	__le32 client;
4786e36c7bcSVolodymyr Mytnyk 	__le32 block_id;
4796e36c7bcSVolodymyr Mytnyk 	__le32 num_counters;
4806e36c7bcSVolodymyr Mytnyk };
4816e36c7bcSVolodymyr Mytnyk 
4826e36c7bcSVolodymyr Mytnyk struct prestera_msg_counter_stats {
4836e36c7bcSVolodymyr Mytnyk 	__le64 packets;
4846e36c7bcSVolodymyr Mytnyk 	__le64 bytes;
4856e36c7bcSVolodymyr Mytnyk };
4866e36c7bcSVolodymyr Mytnyk 
4876e36c7bcSVolodymyr Mytnyk struct prestera_msg_counter_resp {
4886e36c7bcSVolodymyr Mytnyk 	struct prestera_msg_ret ret;
4896e36c7bcSVolodymyr Mytnyk 	__le32 block_id;
4906e36c7bcSVolodymyr Mytnyk 	__le32 offset;
4916e36c7bcSVolodymyr Mytnyk 	__le32 num_counters;
4926e36c7bcSVolodymyr Mytnyk 	__le32 done;
49301081be1SJosé Expósito 	struct prestera_msg_counter_stats stats[];
4948b474a9fSSerhiy Boiko };
4958b474a9fSSerhiy Boiko 
49613defa27SSerhiy Boiko struct prestera_msg_span_req {
49713defa27SSerhiy Boiko 	struct prestera_msg_cmd cmd;
498bb5dbf2cSVolodymyr Mytnyk 	__le32 port;
499bb5dbf2cSVolodymyr Mytnyk 	__le32 dev;
50013defa27SSerhiy Boiko 	u8 id;
501236f57feSGeert Uytterhoeven 	u8 pad[3];
502bb5dbf2cSVolodymyr Mytnyk };
50313defa27SSerhiy Boiko 
50413defa27SSerhiy Boiko struct prestera_msg_span_resp {
50513defa27SSerhiy Boiko 	struct prestera_msg_ret ret;
50613defa27SSerhiy Boiko 	u8 id;
507236f57feSGeert Uytterhoeven 	u8 pad[3];
508bb5dbf2cSVolodymyr Mytnyk };
50913defa27SSerhiy Boiko 
510e1189d9aSVadym Kochan struct prestera_msg_stp_req {
511e1189d9aSVadym Kochan 	struct prestera_msg_cmd cmd;
512bb5dbf2cSVolodymyr Mytnyk 	__le32 port;
513bb5dbf2cSVolodymyr Mytnyk 	__le32 dev;
514bb5dbf2cSVolodymyr Mytnyk 	__le16 vid;
515e1189d9aSVadym Kochan 	u8 state;
516e1464db5SVolodymyr Mytnyk 	u8 __pad;
517e1189d9aSVadym Kochan };
518e1189d9aSVadym Kochan 
519501ef306SVadym Kochan struct prestera_msg_rxtx_req {
520501ef306SVadym Kochan 	struct prestera_msg_cmd cmd;
521501ef306SVadym Kochan 	u8 use_sdma;
522236f57feSGeert Uytterhoeven 	u8 pad[3];
523501ef306SVadym Kochan };
524501ef306SVadym Kochan 
525501ef306SVadym Kochan struct prestera_msg_rxtx_resp {
526501ef306SVadym Kochan 	struct prestera_msg_ret ret;
527bb5dbf2cSVolodymyr Mytnyk 	__le32 map_addr;
528501ef306SVadym Kochan };
529501ef306SVadym Kochan 
5300f07bd6bSYevhen Orlov struct prestera_msg_iface {
5310f07bd6bSYevhen Orlov 	union {
5320f07bd6bSYevhen Orlov 		struct {
5330f07bd6bSYevhen Orlov 			__le32 dev;
5340f07bd6bSYevhen Orlov 			__le32 port;
5350f07bd6bSYevhen Orlov 		};
5360f07bd6bSYevhen Orlov 		__le16 lag_id;
5370f07bd6bSYevhen Orlov 	};
5380f07bd6bSYevhen Orlov 	__le16 vr_id;
5390f07bd6bSYevhen Orlov 	__le16 vid;
5400f07bd6bSYevhen Orlov 	u8 type;
5410f07bd6bSYevhen Orlov 	u8 __pad[3];
5420f07bd6bSYevhen Orlov };
5430f07bd6bSYevhen Orlov 
54419787b93SYevhen Orlov struct prestera_msg_ip_addr {
54519787b93SYevhen Orlov 	union {
54619787b93SYevhen Orlov 		__be32 ipv4;
54719787b93SYevhen Orlov 		__be32 ipv6[4];
54819787b93SYevhen Orlov 	} u;
54919787b93SYevhen Orlov 	u8 v; /* e.g. PRESTERA_IPV4 */
55019787b93SYevhen Orlov 	u8 __pad[3];
55119787b93SYevhen Orlov };
55219787b93SYevhen Orlov 
5530a23ae23SYevhen Orlov struct prestera_msg_nh {
5540a23ae23SYevhen Orlov 	struct prestera_msg_iface oif;
5550a23ae23SYevhen Orlov 	__le32 hw_id;
5560a23ae23SYevhen Orlov 	u8 mac[ETH_ALEN];
5570a23ae23SYevhen Orlov 	u8 is_active;
5580a23ae23SYevhen Orlov 	u8 pad;
5590a23ae23SYevhen Orlov };
5600a23ae23SYevhen Orlov 
5610f07bd6bSYevhen Orlov struct prestera_msg_rif_req {
5620f07bd6bSYevhen Orlov 	struct prestera_msg_cmd cmd;
5630f07bd6bSYevhen Orlov 	struct prestera_msg_iface iif;
5640f07bd6bSYevhen Orlov 	__le32 mtu;
5650f07bd6bSYevhen Orlov 	__le16 rif_id;
5660f07bd6bSYevhen Orlov 	__le16 __reserved;
5670f07bd6bSYevhen Orlov 	u8 mac[ETH_ALEN];
5680f07bd6bSYevhen Orlov 	u8 __pad[2];
5690f07bd6bSYevhen Orlov };
5700f07bd6bSYevhen Orlov 
5710f07bd6bSYevhen Orlov struct prestera_msg_rif_resp {
5720f07bd6bSYevhen Orlov 	struct prestera_msg_ret ret;
5730f07bd6bSYevhen Orlov 	__le16 rif_id;
5740f07bd6bSYevhen Orlov 	u8 __pad[2];
5750f07bd6bSYevhen Orlov };
5760f07bd6bSYevhen Orlov 
57719787b93SYevhen Orlov struct prestera_msg_lpm_req {
57819787b93SYevhen Orlov 	struct prestera_msg_cmd cmd;
57919787b93SYevhen Orlov 	struct prestera_msg_ip_addr dst;
58019787b93SYevhen Orlov 	__le32 grp_id;
58119787b93SYevhen Orlov 	__le32 dst_len;
58219787b93SYevhen Orlov 	__le16 vr_id;
58319787b93SYevhen Orlov 	u8 __pad[2];
58419787b93SYevhen Orlov };
58519787b93SYevhen Orlov 
5860a23ae23SYevhen Orlov struct prestera_msg_nh_req {
5870a23ae23SYevhen Orlov 	struct prestera_msg_cmd cmd;
5880a23ae23SYevhen Orlov 	struct prestera_msg_nh nh[PRESTERA_NHGR_SIZE_MAX];
5890a23ae23SYevhen Orlov 	__le32 size;
5900a23ae23SYevhen Orlov 	__le32 grp_id;
5910a23ae23SYevhen Orlov };
5920a23ae23SYevhen Orlov 
5930a23ae23SYevhen Orlov struct prestera_msg_nh_chunk_req {
5940a23ae23SYevhen Orlov 	struct prestera_msg_cmd cmd;
5950a23ae23SYevhen Orlov 	__le32 offset;
5960a23ae23SYevhen Orlov };
5970a23ae23SYevhen Orlov 
5980a23ae23SYevhen Orlov struct prestera_msg_nh_chunk_resp {
5990a23ae23SYevhen Orlov 	struct prestera_msg_ret ret;
6000a23ae23SYevhen Orlov 	u8 hw_state[PRESTERA_MSG_CHUNK_SIZE];
6010a23ae23SYevhen Orlov };
6020a23ae23SYevhen Orlov 
6030a23ae23SYevhen Orlov struct prestera_msg_nh_grp_req {
6040a23ae23SYevhen Orlov 	struct prestera_msg_cmd cmd;
6050a23ae23SYevhen Orlov 	__le32 grp_id;
6060a23ae23SYevhen Orlov 	__le32 size;
6070a23ae23SYevhen Orlov };
6080a23ae23SYevhen Orlov 
6090a23ae23SYevhen Orlov struct prestera_msg_nh_grp_resp {
6100a23ae23SYevhen Orlov 	struct prestera_msg_ret ret;
6110a23ae23SYevhen Orlov 	__le32 grp_id;
6120a23ae23SYevhen Orlov };
6130a23ae23SYevhen Orlov 
6146d1b3eb5SYevhen Orlov struct prestera_msg_vr_req {
6156d1b3eb5SYevhen Orlov 	struct prestera_msg_cmd cmd;
6166d1b3eb5SYevhen Orlov 	__le16 vr_id;
6176d1b3eb5SYevhen Orlov 	u8 __pad[2];
6186d1b3eb5SYevhen Orlov };
6196d1b3eb5SYevhen Orlov 
6206d1b3eb5SYevhen Orlov struct prestera_msg_vr_resp {
6216d1b3eb5SYevhen Orlov 	struct prestera_msg_ret ret;
6226d1b3eb5SYevhen Orlov 	__le16 vr_id;
6236d1b3eb5SYevhen Orlov 	u8 __pad[2];
6246d1b3eb5SYevhen Orlov };
6256d1b3eb5SYevhen Orlov 
626255213caSSerhiy Boiko struct prestera_msg_lag_req {
627255213caSSerhiy Boiko 	struct prestera_msg_cmd cmd;
628bb5dbf2cSVolodymyr Mytnyk 	__le32 port;
629bb5dbf2cSVolodymyr Mytnyk 	__le32 dev;
630bb5dbf2cSVolodymyr Mytnyk 	__le16 lag_id;
631236f57feSGeert Uytterhoeven 	u8 pad[2];
632255213caSSerhiy Boiko };
633255213caSSerhiy Boiko 
634a80cf955SOleksandr Mazur struct prestera_msg_cpu_code_counter_req {
635a80cf955SOleksandr Mazur 	struct prestera_msg_cmd cmd;
636a80cf955SOleksandr Mazur 	u8 counter_type;
637a80cf955SOleksandr Mazur 	u8 code;
638236f57feSGeert Uytterhoeven 	u8 pad[2];
639a80cf955SOleksandr Mazur };
640a80cf955SOleksandr Mazur 
641a80cf955SOleksandr Mazur struct mvsw_msg_cpu_code_counter_ret {
642a80cf955SOleksandr Mazur 	struct prestera_msg_ret ret;
643bb5dbf2cSVolodymyr Mytnyk 	__le64 packet_count;
644a80cf955SOleksandr Mazur };
645a80cf955SOleksandr Mazur 
646dde2daa0SVolodymyr Mytnyk struct prestera_msg_policer_req {
647dde2daa0SVolodymyr Mytnyk 	struct prestera_msg_cmd cmd;
648dde2daa0SVolodymyr Mytnyk 	__le32 id;
649dde2daa0SVolodymyr Mytnyk 	union {
650dde2daa0SVolodymyr Mytnyk 		struct {
651dde2daa0SVolodymyr Mytnyk 			__le64 cir;
652dde2daa0SVolodymyr Mytnyk 			__le32 cbs;
653dde2daa0SVolodymyr Mytnyk 		} __packed sr_tcm; /* make sure always 12 bytes size */
654dde2daa0SVolodymyr Mytnyk 		__le32 reserved[6];
655dde2daa0SVolodymyr Mytnyk 	};
656dde2daa0SVolodymyr Mytnyk 	u8 mode;
657dde2daa0SVolodymyr Mytnyk 	u8 type;
658dde2daa0SVolodymyr Mytnyk 	u8 pad[2];
659dde2daa0SVolodymyr Mytnyk };
660dde2daa0SVolodymyr Mytnyk 
661dde2daa0SVolodymyr Mytnyk struct prestera_msg_policer_resp {
662dde2daa0SVolodymyr Mytnyk 	struct prestera_msg_ret ret;
663dde2daa0SVolodymyr Mytnyk 	__le32 id;
664dde2daa0SVolodymyr Mytnyk };
665dde2daa0SVolodymyr Mytnyk 
666501ef306SVadym Kochan struct prestera_msg_event {
667bb5dbf2cSVolodymyr Mytnyk 	__le16 type;
668bb5dbf2cSVolodymyr Mytnyk 	__le16 id;
669501ef306SVadym Kochan };
670501ef306SVadym Kochan 
671501ef306SVadym Kochan struct prestera_msg_event_port {
672501ef306SVadym Kochan 	struct prestera_msg_event id;
673bb5dbf2cSVolodymyr Mytnyk 	__le32 port_id;
674bb5dbf2cSVolodymyr Mytnyk 	struct prestera_msg_event_port_param param;
675501ef306SVadym Kochan };
676501ef306SVadym Kochan 
677e1189d9aSVadym Kochan union prestera_msg_event_fdb_param {
678e1189d9aSVadym Kochan 	u8 mac[ETH_ALEN];
679e1189d9aSVadym Kochan };
680e1189d9aSVadym Kochan 
681e1189d9aSVadym Kochan struct prestera_msg_event_fdb {
682e1189d9aSVadym Kochan 	struct prestera_msg_event id;
683e1464db5SVolodymyr Mytnyk 	__le32 vid;
684255213caSSerhiy Boiko 	union {
685bb5dbf2cSVolodymyr Mytnyk 		__le32 port_id;
686bb5dbf2cSVolodymyr Mytnyk 		__le16 lag_id;
687255213caSSerhiy Boiko 	} dest;
688e1189d9aSVadym Kochan 	union prestera_msg_event_fdb_param param;
689e1464db5SVolodymyr Mytnyk 	u8 dest_type;
690e1464db5SVolodymyr Mytnyk };
691bb5dbf2cSVolodymyr Mytnyk 
692fec7c9c7SOleksandr Mazur struct prestera_msg_flood_domain_create_req {
693fec7c9c7SOleksandr Mazur 	struct prestera_msg_cmd cmd;
694fec7c9c7SOleksandr Mazur };
695fec7c9c7SOleksandr Mazur 
696fec7c9c7SOleksandr Mazur struct prestera_msg_flood_domain_create_resp {
697fec7c9c7SOleksandr Mazur 	struct prestera_msg_ret ret;
698fec7c9c7SOleksandr Mazur 	__le32 flood_domain_idx;
699fec7c9c7SOleksandr Mazur };
700fec7c9c7SOleksandr Mazur 
701fec7c9c7SOleksandr Mazur struct prestera_msg_flood_domain_destroy_req {
702fec7c9c7SOleksandr Mazur 	struct prestera_msg_cmd cmd;
703fec7c9c7SOleksandr Mazur 	__le32 flood_domain_idx;
704fec7c9c7SOleksandr Mazur };
705fec7c9c7SOleksandr Mazur 
706fec7c9c7SOleksandr Mazur struct prestera_msg_flood_domain_ports_reset_req {
707fec7c9c7SOleksandr Mazur 	struct prestera_msg_cmd cmd;
708fec7c9c7SOleksandr Mazur 	__le32 flood_domain_idx;
709fec7c9c7SOleksandr Mazur };
710fec7c9c7SOleksandr Mazur 
711fec7c9c7SOleksandr Mazur struct prestera_msg_flood_domain_port {
712fec7c9c7SOleksandr Mazur 	union {
713fec7c9c7SOleksandr Mazur 		struct {
714fec7c9c7SOleksandr Mazur 			__le32 port_num;
715fec7c9c7SOleksandr Mazur 			__le32 dev_num;
716fec7c9c7SOleksandr Mazur 		};
717fec7c9c7SOleksandr Mazur 		__le16 lag_id;
718fec7c9c7SOleksandr Mazur 	};
719fec7c9c7SOleksandr Mazur 	__le16 vid;
720fec7c9c7SOleksandr Mazur 	__le16 port_type;
721fec7c9c7SOleksandr Mazur };
722fec7c9c7SOleksandr Mazur 
723*86348d21SErick Archer struct prestera_msg_flood_domain_ports_set_req {
724*86348d21SErick Archer 	struct prestera_msg_cmd cmd;
725*86348d21SErick Archer 	__le32 flood_domain_idx;
726*86348d21SErick Archer 	__le32 ports_num;
727*86348d21SErick Archer 	struct prestera_msg_flood_domain_port ports[] __counted_by_le(ports_num);
728*86348d21SErick Archer };
729*86348d21SErick Archer 
730fec7c9c7SOleksandr Mazur struct prestera_msg_mdb_create_req {
731fec7c9c7SOleksandr Mazur 	struct prestera_msg_cmd cmd;
732fec7c9c7SOleksandr Mazur 	__le32 flood_domain_idx;
733fec7c9c7SOleksandr Mazur 	__le16 vid;
734fec7c9c7SOleksandr Mazur 	u8 mac[ETH_ALEN];
735fec7c9c7SOleksandr Mazur };
736fec7c9c7SOleksandr Mazur 
737fec7c9c7SOleksandr Mazur struct prestera_msg_mdb_destroy_req {
738fec7c9c7SOleksandr Mazur 	struct prestera_msg_cmd cmd;
739fec7c9c7SOleksandr Mazur 	__le32 flood_domain_idx;
740fec7c9c7SOleksandr Mazur 	__le16 vid;
741fec7c9c7SOleksandr Mazur 	u8 mac[ETH_ALEN];
742fec7c9c7SOleksandr Mazur };
743fec7c9c7SOleksandr Mazur 
prestera_hw_build_tests(void)744e1464db5SVolodymyr Mytnyk static void prestera_hw_build_tests(void)
745bb5dbf2cSVolodymyr Mytnyk {
746bb5dbf2cSVolodymyr Mytnyk 	/* check requests */
747bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_common_req) != 4);
748bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_switch_attr_req) != 16);
749e1464db5SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_port_attr_req) != 144);
750bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_port_info_req) != 8);
751bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_vlan_req) != 16);
752bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_fdb_req) != 28);
753bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_bridge_req) != 16);
754bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_span_req) != 16);
755bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_stp_req) != 16);
756bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_rxtx_req) != 8);
757bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_lag_req) != 16);
758bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_cpu_code_counter_req) != 8);
75947327e19SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_create_req) != 84);
76047327e19SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_destroy_req) != 8);
76147327e19SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_rule_add_req) != 168);
76247327e19SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_rule_del_req) != 12);
76347327e19SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_bind_req) != 20);
76447327e19SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_acl_action) != 32);
7656e36c7bcSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_counter_req) != 16);
7666e36c7bcSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_counter_stats) != 16);
7670f07bd6bSYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_rif_req) != 36);
7686d1b3eb5SYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_vr_req) != 8);
76919787b93SYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_lpm_req) != 36);
770dde2daa0SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_policer_req) != 36);
771fec7c9c7SOleksandr Mazur 	BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_create_req) != 4);
772fec7c9c7SOleksandr Mazur 	BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_destroy_req) != 8);
773fec7c9c7SOleksandr Mazur 	BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_ports_set_req) != 12);
774fec7c9c7SOleksandr Mazur 	BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_ports_reset_req) != 8);
775fec7c9c7SOleksandr Mazur 	BUILD_BUG_ON(sizeof(struct prestera_msg_mdb_create_req) != 16);
776fec7c9c7SOleksandr Mazur 	BUILD_BUG_ON(sizeof(struct prestera_msg_mdb_destroy_req) != 16);
7770a23ae23SYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_nh_req) != 124);
7780a23ae23SYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_nh_chunk_req) != 8);
7790a23ae23SYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_nh_grp_req) != 12);
780bb5dbf2cSVolodymyr Mytnyk 
7810f07bd6bSYevhen Orlov 	/*  structure that are part of req/resp fw messages */
7820f07bd6bSYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_iface) != 16);
78319787b93SYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_ip_addr) != 20);
784fec7c9c7SOleksandr Mazur 	BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_port) != 12);
7850a23ae23SYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_nh) != 28);
7860f07bd6bSYevhen Orlov 
787bb5dbf2cSVolodymyr Mytnyk 	/* check responses */
788bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_common_resp) != 8);
789bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_switch_init_resp) != 24);
790e1464db5SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_port_attr_resp) != 136);
791bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_port_stats_resp) != 248);
792bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_port_info_resp) != 20);
793bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_bridge_resp) != 12);
794bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_span_resp) != 12);
795bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_rxtx_resp) != 12);
79647327e19SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_resp) != 16);
7976e36c7bcSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_counter_resp) != 24);
7980f07bd6bSYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_rif_resp) != 12);
7996d1b3eb5SYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_vr_resp) != 12);
800dde2daa0SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_policer_resp) != 12);
801917edfb9SMaksym Glubokiy 	BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_create_resp) != 12);
8020a23ae23SYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_nh_chunk_resp) != 1032);
8030a23ae23SYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_nh_grp_resp) != 12);
804bb5dbf2cSVolodymyr Mytnyk 
805bb5dbf2cSVolodymyr Mytnyk 	/* check events */
806bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_event_port) != 20);
807bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_event_fdb) != 20);
808bb5dbf2cSVolodymyr Mytnyk }
809bb5dbf2cSVolodymyr Mytnyk 
810bb5dbf2cSVolodymyr Mytnyk static u8 prestera_hw_mdix_to_eth(u8 mode);
811bb5dbf2cSVolodymyr Mytnyk static void prestera_hw_remote_fc_to_eth(u8 fc, bool *pause, bool *asym_pause);
812e1189d9aSVadym Kochan 
__prestera_cmd_ret(struct prestera_switch * sw,enum prestera_cmd_type_t type,struct prestera_msg_cmd * cmd,size_t clen,struct prestera_msg_ret * ret,size_t rlen,int waitms)813501ef306SVadym Kochan static int __prestera_cmd_ret(struct prestera_switch *sw,
814501ef306SVadym Kochan 			      enum prestera_cmd_type_t type,
815501ef306SVadym Kochan 			      struct prestera_msg_cmd *cmd, size_t clen,
816501ef306SVadym Kochan 			      struct prestera_msg_ret *ret, size_t rlen,
817501ef306SVadym Kochan 			      int waitms)
818501ef306SVadym Kochan {
819501ef306SVadym Kochan 	struct prestera_device *dev = sw->dev;
820501ef306SVadym Kochan 	int err;
821501ef306SVadym Kochan 
822bb5dbf2cSVolodymyr Mytnyk 	cmd->type = __cpu_to_le32(type);
823501ef306SVadym Kochan 
824bb5dbf2cSVolodymyr Mytnyk 	err = dev->send_req(dev, 0, cmd, clen, ret, rlen, waitms);
825501ef306SVadym Kochan 	if (err)
826501ef306SVadym Kochan 		return err;
827501ef306SVadym Kochan 
828e1464db5SVolodymyr Mytnyk 	if (ret->cmd.type != __cpu_to_le32(PRESTERA_CMD_TYPE_ACK))
829501ef306SVadym Kochan 		return -EBADE;
830e1464db5SVolodymyr Mytnyk 	if (ret->status != __cpu_to_le32(PRESTERA_CMD_ACK_OK))
831501ef306SVadym Kochan 		return -EINVAL;
832501ef306SVadym Kochan 
833501ef306SVadym Kochan 	return 0;
834501ef306SVadym Kochan }
835501ef306SVadym Kochan 
prestera_cmd_ret(struct prestera_switch * sw,enum prestera_cmd_type_t type,struct prestera_msg_cmd * cmd,size_t clen,struct prestera_msg_ret * ret,size_t rlen)836501ef306SVadym Kochan static int prestera_cmd_ret(struct prestera_switch *sw,
837501ef306SVadym Kochan 			    enum prestera_cmd_type_t type,
838501ef306SVadym Kochan 			    struct prestera_msg_cmd *cmd, size_t clen,
839501ef306SVadym Kochan 			    struct prestera_msg_ret *ret, size_t rlen)
840501ef306SVadym Kochan {
841501ef306SVadym Kochan 	return __prestera_cmd_ret(sw, type, cmd, clen, ret, rlen, 0);
842501ef306SVadym Kochan }
843501ef306SVadym Kochan 
prestera_cmd_ret_wait(struct prestera_switch * sw,enum prestera_cmd_type_t type,struct prestera_msg_cmd * cmd,size_t clen,struct prestera_msg_ret * ret,size_t rlen,int waitms)844501ef306SVadym Kochan static int prestera_cmd_ret_wait(struct prestera_switch *sw,
845501ef306SVadym Kochan 				 enum prestera_cmd_type_t type,
846501ef306SVadym Kochan 				 struct prestera_msg_cmd *cmd, size_t clen,
847501ef306SVadym Kochan 				 struct prestera_msg_ret *ret, size_t rlen,
848501ef306SVadym Kochan 				 int waitms)
849501ef306SVadym Kochan {
850501ef306SVadym Kochan 	return __prestera_cmd_ret(sw, type, cmd, clen, ret, rlen, waitms);
851501ef306SVadym Kochan }
852501ef306SVadym Kochan 
prestera_cmd(struct prestera_switch * sw,enum prestera_cmd_type_t type,struct prestera_msg_cmd * cmd,size_t clen)853501ef306SVadym Kochan static int prestera_cmd(struct prestera_switch *sw,
854501ef306SVadym Kochan 			enum prestera_cmd_type_t type,
855501ef306SVadym Kochan 			struct prestera_msg_cmd *cmd, size_t clen)
856501ef306SVadym Kochan {
857501ef306SVadym Kochan 	struct prestera_msg_common_resp resp;
858501ef306SVadym Kochan 
859501ef306SVadym Kochan 	return prestera_cmd_ret(sw, type, cmd, clen, &resp.ret, sizeof(resp));
860501ef306SVadym Kochan }
861501ef306SVadym Kochan 
prestera_fw_parse_port_evt(void * msg,struct prestera_event * evt)862501ef306SVadym Kochan static int prestera_fw_parse_port_evt(void *msg, struct prestera_event *evt)
863501ef306SVadym Kochan {
864bb5dbf2cSVolodymyr Mytnyk 	struct prestera_msg_event_port *hw_evt;
865501ef306SVadym Kochan 
866bb5dbf2cSVolodymyr Mytnyk 	hw_evt = (struct prestera_msg_event_port *)msg;
867bb5dbf2cSVolodymyr Mytnyk 
868bb5dbf2cSVolodymyr Mytnyk 	evt->port_evt.port_id = __le32_to_cpu(hw_evt->port_id);
869bb5dbf2cSVolodymyr Mytnyk 
870bb5dbf2cSVolodymyr Mytnyk 	if (evt->id == PRESTERA_PORT_EVENT_MAC_STATE_CHANGED) {
871bb5dbf2cSVolodymyr Mytnyk 		evt->port_evt.data.mac.oper = hw_evt->param.mac.oper;
872bb5dbf2cSVolodymyr Mytnyk 		evt->port_evt.data.mac.mode =
873bb5dbf2cSVolodymyr Mytnyk 			__le32_to_cpu(hw_evt->param.mac.mode);
874bb5dbf2cSVolodymyr Mytnyk 		evt->port_evt.data.mac.speed =
875bb5dbf2cSVolodymyr Mytnyk 			__le32_to_cpu(hw_evt->param.mac.speed);
876bb5dbf2cSVolodymyr Mytnyk 		evt->port_evt.data.mac.duplex = hw_evt->param.mac.duplex;
877bb5dbf2cSVolodymyr Mytnyk 		evt->port_evt.data.mac.fc = hw_evt->param.mac.fc;
878bb5dbf2cSVolodymyr Mytnyk 		evt->port_evt.data.mac.fec = hw_evt->param.mac.fec;
879bb5dbf2cSVolodymyr Mytnyk 	} else {
880501ef306SVadym Kochan 		return -EINVAL;
881bb5dbf2cSVolodymyr Mytnyk 	}
882501ef306SVadym Kochan 
883501ef306SVadym Kochan 	return 0;
884501ef306SVadym Kochan }
885501ef306SVadym Kochan 
prestera_fw_parse_fdb_evt(void * msg,struct prestera_event * evt)886e1189d9aSVadym Kochan static int prestera_fw_parse_fdb_evt(void *msg, struct prestera_event *evt)
887e1189d9aSVadym Kochan {
888e1189d9aSVadym Kochan 	struct prestera_msg_event_fdb *hw_evt = msg;
889e1189d9aSVadym Kochan 
890255213caSSerhiy Boiko 	switch (hw_evt->dest_type) {
891255213caSSerhiy Boiko 	case PRESTERA_HW_FDB_ENTRY_TYPE_REG_PORT:
892255213caSSerhiy Boiko 		evt->fdb_evt.type = PRESTERA_FDB_ENTRY_TYPE_REG_PORT;
893bb5dbf2cSVolodymyr Mytnyk 		evt->fdb_evt.dest.port_id = __le32_to_cpu(hw_evt->dest.port_id);
894255213caSSerhiy Boiko 		break;
895255213caSSerhiy Boiko 	case PRESTERA_HW_FDB_ENTRY_TYPE_LAG:
896255213caSSerhiy Boiko 		evt->fdb_evt.type = PRESTERA_FDB_ENTRY_TYPE_LAG;
897bb5dbf2cSVolodymyr Mytnyk 		evt->fdb_evt.dest.lag_id = __le16_to_cpu(hw_evt->dest.lag_id);
898255213caSSerhiy Boiko 		break;
899255213caSSerhiy Boiko 	default:
900255213caSSerhiy Boiko 		return -EINVAL;
901255213caSSerhiy Boiko 	}
902255213caSSerhiy Boiko 
903bb5dbf2cSVolodymyr Mytnyk 	evt->fdb_evt.vid = __le32_to_cpu(hw_evt->vid);
904e1189d9aSVadym Kochan 
905e1189d9aSVadym Kochan 	ether_addr_copy(evt->fdb_evt.data.mac, hw_evt->param.mac);
906e1189d9aSVadym Kochan 
907e1189d9aSVadym Kochan 	return 0;
908e1189d9aSVadym Kochan }
909e1189d9aSVadym Kochan 
910501ef306SVadym Kochan static struct prestera_fw_evt_parser {
911501ef306SVadym Kochan 	int (*func)(void *msg, struct prestera_event *evt);
912501ef306SVadym Kochan } fw_event_parsers[PRESTERA_EVENT_TYPE_MAX] = {
913501ef306SVadym Kochan 	[PRESTERA_EVENT_TYPE_PORT] = { .func = prestera_fw_parse_port_evt },
914e1189d9aSVadym Kochan 	[PRESTERA_EVENT_TYPE_FDB] = { .func = prestera_fw_parse_fdb_evt },
915501ef306SVadym Kochan };
916501ef306SVadym Kochan 
917501ef306SVadym Kochan static struct prestera_fw_event_handler *
__find_event_handler(const struct prestera_switch * sw,enum prestera_event_type type)918501ef306SVadym Kochan __find_event_handler(const struct prestera_switch *sw,
919501ef306SVadym Kochan 		     enum prestera_event_type type)
920501ef306SVadym Kochan {
921501ef306SVadym Kochan 	struct prestera_fw_event_handler *eh;
922501ef306SVadym Kochan 
923501ef306SVadym Kochan 	list_for_each_entry_rcu(eh, &sw->event_handlers, list) {
924501ef306SVadym Kochan 		if (eh->type == type)
925501ef306SVadym Kochan 			return eh;
926501ef306SVadym Kochan 	}
927501ef306SVadym Kochan 
928501ef306SVadym Kochan 	return NULL;
929501ef306SVadym Kochan }
930501ef306SVadym Kochan 
prestera_find_event_handler(const struct prestera_switch * sw,enum prestera_event_type type,struct prestera_fw_event_handler * eh)931501ef306SVadym Kochan static int prestera_find_event_handler(const struct prestera_switch *sw,
932501ef306SVadym Kochan 				       enum prestera_event_type type,
933501ef306SVadym Kochan 				       struct prestera_fw_event_handler *eh)
934501ef306SVadym Kochan {
935501ef306SVadym Kochan 	struct prestera_fw_event_handler *tmp;
936501ef306SVadym Kochan 	int err = 0;
937501ef306SVadym Kochan 
938501ef306SVadym Kochan 	rcu_read_lock();
939501ef306SVadym Kochan 	tmp = __find_event_handler(sw, type);
940501ef306SVadym Kochan 	if (tmp)
941501ef306SVadym Kochan 		*eh = *tmp;
942501ef306SVadym Kochan 	else
943501ef306SVadym Kochan 		err = -ENOENT;
944501ef306SVadym Kochan 	rcu_read_unlock();
945501ef306SVadym Kochan 
946501ef306SVadym Kochan 	return err;
947501ef306SVadym Kochan }
948501ef306SVadym Kochan 
prestera_evt_recv(struct prestera_device * dev,void * buf,size_t size)949501ef306SVadym Kochan static int prestera_evt_recv(struct prestera_device *dev, void *buf, size_t size)
950501ef306SVadym Kochan {
951501ef306SVadym Kochan 	struct prestera_switch *sw = dev->priv;
952501ef306SVadym Kochan 	struct prestera_msg_event *msg = buf;
953501ef306SVadym Kochan 	struct prestera_fw_event_handler eh;
954501ef306SVadym Kochan 	struct prestera_event evt;
955bb5dbf2cSVolodymyr Mytnyk 	u16 msg_type;
956501ef306SVadym Kochan 	int err;
957501ef306SVadym Kochan 
958bb5dbf2cSVolodymyr Mytnyk 	msg_type = __le16_to_cpu(msg->type);
959bb5dbf2cSVolodymyr Mytnyk 	if (msg_type >= PRESTERA_EVENT_TYPE_MAX)
960501ef306SVadym Kochan 		return -EINVAL;
961bb5dbf2cSVolodymyr Mytnyk 	if (!fw_event_parsers[msg_type].func)
962501ef306SVadym Kochan 		return -ENOENT;
963501ef306SVadym Kochan 
964bb5dbf2cSVolodymyr Mytnyk 	err = prestera_find_event_handler(sw, msg_type, &eh);
965501ef306SVadym Kochan 	if (err)
966501ef306SVadym Kochan 		return err;
967501ef306SVadym Kochan 
968bb5dbf2cSVolodymyr Mytnyk 	evt.id = __le16_to_cpu(msg->id);
969501ef306SVadym Kochan 
970bb5dbf2cSVolodymyr Mytnyk 	err = fw_event_parsers[msg_type].func(buf, &evt);
971501ef306SVadym Kochan 	if (err)
972501ef306SVadym Kochan 		return err;
973501ef306SVadym Kochan 
974501ef306SVadym Kochan 	eh.func(sw, &evt, eh.arg);
975501ef306SVadym Kochan 
976501ef306SVadym Kochan 	return 0;
977501ef306SVadym Kochan }
978501ef306SVadym Kochan 
prestera_pkt_recv(struct prestera_device * dev)979501ef306SVadym Kochan static void prestera_pkt_recv(struct prestera_device *dev)
980501ef306SVadym Kochan {
981501ef306SVadym Kochan 	struct prestera_switch *sw = dev->priv;
982501ef306SVadym Kochan 	struct prestera_fw_event_handler eh;
983501ef306SVadym Kochan 	struct prestera_event ev;
984501ef306SVadym Kochan 	int err;
985501ef306SVadym Kochan 
986501ef306SVadym Kochan 	ev.id = PRESTERA_RXTX_EVENT_RCV_PKT;
987501ef306SVadym Kochan 
988501ef306SVadym Kochan 	err = prestera_find_event_handler(sw, PRESTERA_EVENT_TYPE_RXTX, &eh);
989501ef306SVadym Kochan 	if (err)
990501ef306SVadym Kochan 		return;
991501ef306SVadym Kochan 
992501ef306SVadym Kochan 	eh.func(sw, &ev, eh.arg);
993501ef306SVadym Kochan }
994501ef306SVadym Kochan 
prestera_hw_mdix_to_eth(u8 mode)995bb5dbf2cSVolodymyr Mytnyk static u8 prestera_hw_mdix_to_eth(u8 mode)
996bb5dbf2cSVolodymyr Mytnyk {
997bb5dbf2cSVolodymyr Mytnyk 	switch (mode) {
998bb5dbf2cSVolodymyr Mytnyk 	case PRESTERA_PORT_TP_MDI:
999bb5dbf2cSVolodymyr Mytnyk 		return ETH_TP_MDI;
1000bb5dbf2cSVolodymyr Mytnyk 	case PRESTERA_PORT_TP_MDIX:
1001bb5dbf2cSVolodymyr Mytnyk 		return ETH_TP_MDI_X;
1002bb5dbf2cSVolodymyr Mytnyk 	case PRESTERA_PORT_TP_AUTO:
1003bb5dbf2cSVolodymyr Mytnyk 		return ETH_TP_MDI_AUTO;
1004bb5dbf2cSVolodymyr Mytnyk 	default:
1005bb5dbf2cSVolodymyr Mytnyk 		return ETH_TP_MDI_INVALID;
1006bb5dbf2cSVolodymyr Mytnyk 	}
1007bb5dbf2cSVolodymyr Mytnyk }
1008bb5dbf2cSVolodymyr Mytnyk 
prestera_hw_mdix_from_eth(u8 mode)1009bb5dbf2cSVolodymyr Mytnyk static u8 prestera_hw_mdix_from_eth(u8 mode)
1010bb5dbf2cSVolodymyr Mytnyk {
1011bb5dbf2cSVolodymyr Mytnyk 	switch (mode) {
1012bb5dbf2cSVolodymyr Mytnyk 	case ETH_TP_MDI:
1013bb5dbf2cSVolodymyr Mytnyk 		return PRESTERA_PORT_TP_MDI;
1014bb5dbf2cSVolodymyr Mytnyk 	case ETH_TP_MDI_X:
1015bb5dbf2cSVolodymyr Mytnyk 		return PRESTERA_PORT_TP_MDIX;
1016bb5dbf2cSVolodymyr Mytnyk 	case ETH_TP_MDI_AUTO:
1017bb5dbf2cSVolodymyr Mytnyk 		return PRESTERA_PORT_TP_AUTO;
1018bb5dbf2cSVolodymyr Mytnyk 	default:
1019bb5dbf2cSVolodymyr Mytnyk 		return PRESTERA_PORT_TP_NA;
1020bb5dbf2cSVolodymyr Mytnyk 	}
1021bb5dbf2cSVolodymyr Mytnyk }
1022bb5dbf2cSVolodymyr Mytnyk 
prestera_hw_port_info_get(const struct prestera_port * port,u32 * dev_id,u32 * hw_id,u16 * fp_id)1023501ef306SVadym Kochan int prestera_hw_port_info_get(const struct prestera_port *port,
1024501ef306SVadym Kochan 			      u32 *dev_id, u32 *hw_id, u16 *fp_id)
1025501ef306SVadym Kochan {
1026501ef306SVadym Kochan 	struct prestera_msg_port_info_req req = {
1027bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->id),
1028501ef306SVadym Kochan 	};
1029501ef306SVadym Kochan 	struct prestera_msg_port_info_resp resp;
1030501ef306SVadym Kochan 	int err;
1031501ef306SVadym Kochan 
1032501ef306SVadym Kochan 	err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_INFO_GET,
1033501ef306SVadym Kochan 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
1034501ef306SVadym Kochan 	if (err)
1035501ef306SVadym Kochan 		return err;
1036501ef306SVadym Kochan 
1037bb5dbf2cSVolodymyr Mytnyk 	*dev_id = __le32_to_cpu(resp.dev_id);
1038bb5dbf2cSVolodymyr Mytnyk 	*hw_id = __le32_to_cpu(resp.hw_id);
1039bb5dbf2cSVolodymyr Mytnyk 	*fp_id = __le16_to_cpu(resp.fp_id);
1040501ef306SVadym Kochan 
1041501ef306SVadym Kochan 	return 0;
1042501ef306SVadym Kochan }
1043501ef306SVadym Kochan 
prestera_hw_switch_mac_set(struct prestera_switch * sw,const char * mac)1044501ef306SVadym Kochan int prestera_hw_switch_mac_set(struct prestera_switch *sw, const char *mac)
1045501ef306SVadym Kochan {
1046501ef306SVadym Kochan 	struct prestera_msg_switch_attr_req req = {
1047bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_SWITCH_ATTR_MAC),
1048501ef306SVadym Kochan 	};
1049501ef306SVadym Kochan 
1050501ef306SVadym Kochan 	ether_addr_copy(req.param.mac, mac);
1051501ef306SVadym Kochan 
1052501ef306SVadym Kochan 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_SWITCH_ATTR_SET,
1053501ef306SVadym Kochan 			    &req.cmd, sizeof(req));
1054501ef306SVadym Kochan }
1055501ef306SVadym Kochan 
prestera_hw_switch_init(struct prestera_switch * sw)1056501ef306SVadym Kochan int prestera_hw_switch_init(struct prestera_switch *sw)
1057501ef306SVadym Kochan {
1058501ef306SVadym Kochan 	struct prestera_msg_switch_init_resp resp;
1059501ef306SVadym Kochan 	struct prestera_msg_common_req req;
1060501ef306SVadym Kochan 	int err;
1061501ef306SVadym Kochan 
1062501ef306SVadym Kochan 	INIT_LIST_HEAD(&sw->event_handlers);
1063501ef306SVadym Kochan 
1064bb5dbf2cSVolodymyr Mytnyk 	prestera_hw_build_tests();
1065bb5dbf2cSVolodymyr Mytnyk 
1066501ef306SVadym Kochan 	err = prestera_cmd_ret_wait(sw, PRESTERA_CMD_TYPE_SWITCH_INIT,
1067501ef306SVadym Kochan 				    &req.cmd, sizeof(req),
1068501ef306SVadym Kochan 				    &resp.ret, sizeof(resp),
1069501ef306SVadym Kochan 				    PRESTERA_SWITCH_INIT_TIMEOUT_MS);
1070501ef306SVadym Kochan 	if (err)
1071501ef306SVadym Kochan 		return err;
1072501ef306SVadym Kochan 
1073501ef306SVadym Kochan 	sw->dev->recv_msg = prestera_evt_recv;
1074501ef306SVadym Kochan 	sw->dev->recv_pkt = prestera_pkt_recv;
1075bb5dbf2cSVolodymyr Mytnyk 	sw->port_count = __le32_to_cpu(resp.port_count);
1076501ef306SVadym Kochan 	sw->mtu_min = PRESTERA_MIN_MTU;
1077bb5dbf2cSVolodymyr Mytnyk 	sw->mtu_max = __le32_to_cpu(resp.mtu_max);
1078501ef306SVadym Kochan 	sw->id = resp.switch_id;
1079255213caSSerhiy Boiko 	sw->lag_member_max = resp.lag_member_max;
1080255213caSSerhiy Boiko 	sw->lag_max = resp.lag_max;
10810a23ae23SYevhen Orlov 	sw->size_tbl_router_nexthop =
10820a23ae23SYevhen Orlov 		__le32_to_cpu(resp.size_tbl_router_nexthop);
1083501ef306SVadym Kochan 
1084501ef306SVadym Kochan 	return 0;
1085501ef306SVadym Kochan }
1086501ef306SVadym Kochan 
prestera_hw_switch_fini(struct prestera_switch * sw)1087501ef306SVadym Kochan void prestera_hw_switch_fini(struct prestera_switch *sw)
1088501ef306SVadym Kochan {
1089501ef306SVadym Kochan 	WARN_ON(!list_empty(&sw->event_handlers));
1090501ef306SVadym Kochan }
1091501ef306SVadym Kochan 
prestera_hw_switch_ageing_set(struct prestera_switch * sw,u32 ageing_ms)1092e1189d9aSVadym Kochan int prestera_hw_switch_ageing_set(struct prestera_switch *sw, u32 ageing_ms)
1093e1189d9aSVadym Kochan {
1094e1189d9aSVadym Kochan 	struct prestera_msg_switch_attr_req req = {
1095bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_SWITCH_ATTR_AGEING),
1096e1189d9aSVadym Kochan 		.param = {
1097bb5dbf2cSVolodymyr Mytnyk 			.ageing_timeout_ms = __cpu_to_le32(ageing_ms),
1098e1189d9aSVadym Kochan 		},
1099e1189d9aSVadym Kochan 	};
1100e1189d9aSVadym Kochan 
1101e1189d9aSVadym Kochan 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_SWITCH_ATTR_SET,
1102e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1103e1189d9aSVadym Kochan }
1104e1189d9aSVadym Kochan 
prestera_hw_port_mac_mode_get(const struct prestera_port * port,u32 * mode,u32 * speed,u8 * duplex,u8 * fec)1105bb5dbf2cSVolodymyr Mytnyk int prestera_hw_port_mac_mode_get(const struct prestera_port *port,
1106bb5dbf2cSVolodymyr Mytnyk 				  u32 *mode, u32 *speed, u8 *duplex, u8 *fec)
1107bb5dbf2cSVolodymyr Mytnyk {
1108bb5dbf2cSVolodymyr Mytnyk 	struct prestera_msg_port_attr_resp resp;
1109bb5dbf2cSVolodymyr Mytnyk 	struct prestera_msg_port_attr_req req = {
1110bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_MAC_MODE),
1111bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1112bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id)
1113bb5dbf2cSVolodymyr Mytnyk 	};
1114bb5dbf2cSVolodymyr Mytnyk 	int err;
1115bb5dbf2cSVolodymyr Mytnyk 
1116bb5dbf2cSVolodymyr Mytnyk 	err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET,
1117bb5dbf2cSVolodymyr Mytnyk 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
1118bb5dbf2cSVolodymyr Mytnyk 	if (err)
1119bb5dbf2cSVolodymyr Mytnyk 		return err;
1120bb5dbf2cSVolodymyr Mytnyk 
1121bb5dbf2cSVolodymyr Mytnyk 	if (mode)
1122bb5dbf2cSVolodymyr Mytnyk 		*mode = __le32_to_cpu(resp.param.link_evt.mac.mode);
1123bb5dbf2cSVolodymyr Mytnyk 
1124bb5dbf2cSVolodymyr Mytnyk 	if (speed)
1125bb5dbf2cSVolodymyr Mytnyk 		*speed = __le32_to_cpu(resp.param.link_evt.mac.speed);
1126bb5dbf2cSVolodymyr Mytnyk 
1127bb5dbf2cSVolodymyr Mytnyk 	if (duplex)
1128bb5dbf2cSVolodymyr Mytnyk 		*duplex = resp.param.link_evt.mac.duplex;
1129bb5dbf2cSVolodymyr Mytnyk 
1130bb5dbf2cSVolodymyr Mytnyk 	if (fec)
1131bb5dbf2cSVolodymyr Mytnyk 		*fec = resp.param.link_evt.mac.fec;
1132bb5dbf2cSVolodymyr Mytnyk 
1133bb5dbf2cSVolodymyr Mytnyk 	return err;
1134bb5dbf2cSVolodymyr Mytnyk }
1135bb5dbf2cSVolodymyr Mytnyk 
prestera_hw_port_mac_mode_set(const struct prestera_port * port,bool admin,u32 mode,u8 inband,u32 speed,u8 duplex,u8 fec)1136bb5dbf2cSVolodymyr Mytnyk int prestera_hw_port_mac_mode_set(const struct prestera_port *port,
1137bb5dbf2cSVolodymyr Mytnyk 				  bool admin, u32 mode, u8 inband,
1138bb5dbf2cSVolodymyr Mytnyk 				  u32 speed, u8 duplex, u8 fec)
1139501ef306SVadym Kochan {
1140501ef306SVadym Kochan 	struct prestera_msg_port_attr_req req = {
1141bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_MAC_MODE),
1142bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1143bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1144501ef306SVadym Kochan 		.param = {
1145bb5dbf2cSVolodymyr Mytnyk 			.link = {
1146bb5dbf2cSVolodymyr Mytnyk 				.mac = {
1147bb5dbf2cSVolodymyr Mytnyk 					.admin = admin,
1148bb5dbf2cSVolodymyr Mytnyk 					.reg_mode.mode = __cpu_to_le32(mode),
1149bb5dbf2cSVolodymyr Mytnyk 					.reg_mode.inband = inband,
1150bb5dbf2cSVolodymyr Mytnyk 					.reg_mode.speed = __cpu_to_le32(speed),
1151bb5dbf2cSVolodymyr Mytnyk 					.reg_mode.duplex = duplex,
1152bb5dbf2cSVolodymyr Mytnyk 					.reg_mode.fec = fec
1153bb5dbf2cSVolodymyr Mytnyk 				}
1154bb5dbf2cSVolodymyr Mytnyk 			}
1155501ef306SVadym Kochan 		}
1156501ef306SVadym Kochan 	};
1157501ef306SVadym Kochan 
1158501ef306SVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET,
1159501ef306SVadym Kochan 			    &req.cmd, sizeof(req));
1160501ef306SVadym Kochan }
1161501ef306SVadym Kochan 
prestera_hw_port_phy_mode_get(const struct prestera_port * port,u8 * mdix,u64 * lmode_bmap,bool * fc_pause,bool * fc_asym)1162bb5dbf2cSVolodymyr Mytnyk int prestera_hw_port_phy_mode_get(const struct prestera_port *port,
1163bb5dbf2cSVolodymyr Mytnyk 				  u8 *mdix, u64 *lmode_bmap,
1164bb5dbf2cSVolodymyr Mytnyk 				  bool *fc_pause, bool *fc_asym)
1165bb5dbf2cSVolodymyr Mytnyk {
1166bb5dbf2cSVolodymyr Mytnyk 	struct prestera_msg_port_attr_resp resp;
1167bb5dbf2cSVolodymyr Mytnyk 	struct prestera_msg_port_attr_req req = {
1168bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_PHY_MODE),
1169bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1170bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id)
1171bb5dbf2cSVolodymyr Mytnyk 	};
1172bb5dbf2cSVolodymyr Mytnyk 	int err;
1173bb5dbf2cSVolodymyr Mytnyk 
1174bb5dbf2cSVolodymyr Mytnyk 	err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET,
1175bb5dbf2cSVolodymyr Mytnyk 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
1176bb5dbf2cSVolodymyr Mytnyk 	if (err)
1177bb5dbf2cSVolodymyr Mytnyk 		return err;
1178bb5dbf2cSVolodymyr Mytnyk 
1179bb5dbf2cSVolodymyr Mytnyk 	if (mdix)
1180bb5dbf2cSVolodymyr Mytnyk 		*mdix = prestera_hw_mdix_to_eth(resp.param.link_evt.phy.mdix);
1181bb5dbf2cSVolodymyr Mytnyk 
1182bb5dbf2cSVolodymyr Mytnyk 	if (lmode_bmap)
1183bb5dbf2cSVolodymyr Mytnyk 		*lmode_bmap = __le64_to_cpu(resp.param.link_evt.phy.lmode_bmap);
1184bb5dbf2cSVolodymyr Mytnyk 
1185bb5dbf2cSVolodymyr Mytnyk 	if (fc_pause && fc_asym)
1186bb5dbf2cSVolodymyr Mytnyk 		prestera_hw_remote_fc_to_eth(resp.param.link_evt.phy.fc,
1187bb5dbf2cSVolodymyr Mytnyk 					     fc_pause, fc_asym);
1188bb5dbf2cSVolodymyr Mytnyk 
1189bb5dbf2cSVolodymyr Mytnyk 	return err;
1190bb5dbf2cSVolodymyr Mytnyk }
1191bb5dbf2cSVolodymyr Mytnyk 
prestera_hw_port_phy_mode_set(const struct prestera_port * port,bool admin,bool adv,u32 mode,u64 modes,u8 mdix)1192bb5dbf2cSVolodymyr Mytnyk int prestera_hw_port_phy_mode_set(const struct prestera_port *port,
1193bb5dbf2cSVolodymyr Mytnyk 				  bool admin, bool adv, u32 mode, u64 modes,
1194bb5dbf2cSVolodymyr Mytnyk 				  u8 mdix)
1195bb5dbf2cSVolodymyr Mytnyk {
1196bb5dbf2cSVolodymyr Mytnyk 	struct prestera_msg_port_attr_req req = {
1197bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_PHY_MODE),
1198bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1199bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1200bb5dbf2cSVolodymyr Mytnyk 		.param = {
1201bb5dbf2cSVolodymyr Mytnyk 			.link = {
1202bb5dbf2cSVolodymyr Mytnyk 				.phy = {
1203bb5dbf2cSVolodymyr Mytnyk 					.admin = admin,
1204bb5dbf2cSVolodymyr Mytnyk 					.adv_enable = adv ? 1 : 0,
1205bb5dbf2cSVolodymyr Mytnyk 					.mode = __cpu_to_le32(mode),
1206bb5dbf2cSVolodymyr Mytnyk 					.modes = __cpu_to_le64(modes),
1207bb5dbf2cSVolodymyr Mytnyk 				}
1208bb5dbf2cSVolodymyr Mytnyk 			}
1209bb5dbf2cSVolodymyr Mytnyk 		}
1210bb5dbf2cSVolodymyr Mytnyk 	};
1211bb5dbf2cSVolodymyr Mytnyk 
1212bb5dbf2cSVolodymyr Mytnyk 	req.param.link.phy.mdix = prestera_hw_mdix_from_eth(mdix);
1213bb5dbf2cSVolodymyr Mytnyk 
1214bb5dbf2cSVolodymyr Mytnyk 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET,
1215bb5dbf2cSVolodymyr Mytnyk 			    &req.cmd, sizeof(req));
1216bb5dbf2cSVolodymyr Mytnyk }
1217bb5dbf2cSVolodymyr Mytnyk 
prestera_hw_port_mtu_set(const struct prestera_port * port,u32 mtu)1218501ef306SVadym Kochan int prestera_hw_port_mtu_set(const struct prestera_port *port, u32 mtu)
1219501ef306SVadym Kochan {
1220501ef306SVadym Kochan 	struct prestera_msg_port_attr_req req = {
1221bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_MTU),
1222bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1223bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1224501ef306SVadym Kochan 		.param = {
1225bb5dbf2cSVolodymyr Mytnyk 			.mtu = __cpu_to_le32(mtu),
1226501ef306SVadym Kochan 		}
1227501ef306SVadym Kochan 	};
1228501ef306SVadym Kochan 
1229501ef306SVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET,
1230501ef306SVadym Kochan 			    &req.cmd, sizeof(req));
1231501ef306SVadym Kochan }
1232501ef306SVadym Kochan 
prestera_hw_port_mac_set(const struct prestera_port * port,const char * mac)1233501ef306SVadym Kochan int prestera_hw_port_mac_set(const struct prestera_port *port, const char *mac)
1234501ef306SVadym Kochan {
1235501ef306SVadym Kochan 	struct prestera_msg_port_attr_req req = {
1236bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_MAC),
1237bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1238bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1239501ef306SVadym Kochan 	};
1240501ef306SVadym Kochan 
1241501ef306SVadym Kochan 	ether_addr_copy(req.param.mac, mac);
1242501ef306SVadym Kochan 
1243501ef306SVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET,
1244501ef306SVadym Kochan 			    &req.cmd, sizeof(req));
1245501ef306SVadym Kochan }
1246501ef306SVadym Kochan 
prestera_hw_port_accept_frm_type(struct prestera_port * port,enum prestera_accept_frm_type type)1247e1189d9aSVadym Kochan int prestera_hw_port_accept_frm_type(struct prestera_port *port,
1248e1189d9aSVadym Kochan 				     enum prestera_accept_frm_type type)
1249e1189d9aSVadym Kochan {
1250e1189d9aSVadym Kochan 	struct prestera_msg_port_attr_req req = {
1251bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_ACCEPT_FRAME_TYPE),
1252bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1253bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1254e1189d9aSVadym Kochan 		.param = {
1255e1189d9aSVadym Kochan 			.accept_frm_type = type,
1256e1189d9aSVadym Kochan 		}
1257e1189d9aSVadym Kochan 	};
1258e1189d9aSVadym Kochan 
1259e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET,
1260e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1261e1189d9aSVadym Kochan }
1262e1189d9aSVadym Kochan 
prestera_hw_port_cap_get(const struct prestera_port * port,struct prestera_port_caps * caps)1263501ef306SVadym Kochan int prestera_hw_port_cap_get(const struct prestera_port *port,
1264501ef306SVadym Kochan 			     struct prestera_port_caps *caps)
1265501ef306SVadym Kochan {
1266501ef306SVadym Kochan 	struct prestera_msg_port_attr_req req = {
1267bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_CAPABILITY),
1268bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1269bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1270501ef306SVadym Kochan 	};
1271501ef306SVadym Kochan 	struct prestera_msg_port_attr_resp resp;
1272501ef306SVadym Kochan 	int err;
1273501ef306SVadym Kochan 
1274501ef306SVadym Kochan 	err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET,
1275501ef306SVadym Kochan 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
1276501ef306SVadym Kochan 	if (err)
1277501ef306SVadym Kochan 		return err;
1278501ef306SVadym Kochan 
1279bb5dbf2cSVolodymyr Mytnyk 	caps->supp_link_modes = __le64_to_cpu(resp.param.cap.link_mode);
1280501ef306SVadym Kochan 	caps->transceiver = resp.param.cap.transceiver;
1281501ef306SVadym Kochan 	caps->supp_fec = resp.param.cap.fec;
1282501ef306SVadym Kochan 	caps->type = resp.param.cap.type;
1283501ef306SVadym Kochan 
1284501ef306SVadym Kochan 	return err;
1285501ef306SVadym Kochan }
1286501ef306SVadym Kochan 
prestera_hw_remote_fc_to_eth(u8 fc,bool * pause,bool * asym_pause)1287bb5dbf2cSVolodymyr Mytnyk static void prestera_hw_remote_fc_to_eth(u8 fc, bool *pause, bool *asym_pause)
1288a97d3c69SVadym Kochan {
1289bb5dbf2cSVolodymyr Mytnyk 	switch (fc) {
1290a97d3c69SVadym Kochan 	case PRESTERA_FC_SYMMETRIC:
1291a97d3c69SVadym Kochan 		*pause = true;
1292a97d3c69SVadym Kochan 		*asym_pause = false;
1293a97d3c69SVadym Kochan 		break;
1294a97d3c69SVadym Kochan 	case PRESTERA_FC_ASYMMETRIC:
1295a97d3c69SVadym Kochan 		*pause = false;
1296a97d3c69SVadym Kochan 		*asym_pause = true;
1297a97d3c69SVadym Kochan 		break;
1298a97d3c69SVadym Kochan 	case PRESTERA_FC_SYMM_ASYMM:
1299a97d3c69SVadym Kochan 		*pause = true;
1300a97d3c69SVadym Kochan 		*asym_pause = true;
1301a97d3c69SVadym Kochan 		break;
1302a97d3c69SVadym Kochan 	default:
1303a97d3c69SVadym Kochan 		*pause = false;
1304a97d3c69SVadym Kochan 		*asym_pause = false;
1305a97d3c69SVadym Kochan 	}
1306a97d3c69SVadym Kochan }
1307a97d3c69SVadym Kochan 
prestera_hw_vtcam_create(struct prestera_switch * sw,u8 lookup,const u32 * keymask,u32 * vtcam_id,enum prestera_hw_vtcam_direction_t dir)130847327e19SVolodymyr Mytnyk int prestera_hw_vtcam_create(struct prestera_switch *sw,
130947327e19SVolodymyr Mytnyk 			     u8 lookup, const u32 *keymask, u32 *vtcam_id,
131047327e19SVolodymyr Mytnyk 			     enum prestera_hw_vtcam_direction_t dir)
13118b474a9fSSerhiy Boiko {
13128b474a9fSSerhiy Boiko 	int err;
131347327e19SVolodymyr Mytnyk 	struct prestera_msg_vtcam_resp resp;
131447327e19SVolodymyr Mytnyk 	struct prestera_msg_vtcam_create_req req = {
131547327e19SVolodymyr Mytnyk 		.lookup = lookup,
131647327e19SVolodymyr Mytnyk 		.direction = dir,
131747327e19SVolodymyr Mytnyk 	};
13188b474a9fSSerhiy Boiko 
131947327e19SVolodymyr Mytnyk 	if (keymask)
132047327e19SVolodymyr Mytnyk 		memcpy(req.keymask, keymask, sizeof(req.keymask));
132147327e19SVolodymyr Mytnyk 	else
132247327e19SVolodymyr Mytnyk 		memset(req.keymask, 0, sizeof(req.keymask));
132347327e19SVolodymyr Mytnyk 
132447327e19SVolodymyr Mytnyk 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_VTCAM_CREATE,
13258b474a9fSSerhiy Boiko 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
13268b474a9fSSerhiy Boiko 	if (err)
13278b474a9fSSerhiy Boiko 		return err;
13288b474a9fSSerhiy Boiko 
132947327e19SVolodymyr Mytnyk 	*vtcam_id = __le32_to_cpu(resp.vtcam_id);
13308b474a9fSSerhiy Boiko 	return 0;
13318b474a9fSSerhiy Boiko }
13328b474a9fSSerhiy Boiko 
prestera_hw_vtcam_destroy(struct prestera_switch * sw,u32 vtcam_id)133347327e19SVolodymyr Mytnyk int prestera_hw_vtcam_destroy(struct prestera_switch *sw, u32 vtcam_id)
13348b474a9fSSerhiy Boiko {
133547327e19SVolodymyr Mytnyk 	struct prestera_msg_vtcam_destroy_req req = {
133647327e19SVolodymyr Mytnyk 		.vtcam_id = __cpu_to_le32(vtcam_id),
13378b474a9fSSerhiy Boiko 	};
13388b474a9fSSerhiy Boiko 
133947327e19SVolodymyr Mytnyk 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_VTCAM_DESTROY,
13408b474a9fSSerhiy Boiko 			    &req.cmd, sizeof(req));
13418b474a9fSSerhiy Boiko }
13428b474a9fSSerhiy Boiko 
134347327e19SVolodymyr Mytnyk static int
prestera_acl_rule_add_put_action(struct prestera_msg_acl_action * action,struct prestera_acl_hw_action_info * info)134447327e19SVolodymyr Mytnyk prestera_acl_rule_add_put_action(struct prestera_msg_acl_action *action,
134547327e19SVolodymyr Mytnyk 				 struct prestera_acl_hw_action_info *info)
13468b474a9fSSerhiy Boiko {
134747327e19SVolodymyr Mytnyk 	action->id = __cpu_to_le32(info->id);
13488b474a9fSSerhiy Boiko 
134947327e19SVolodymyr Mytnyk 	switch (info->id) {
13508b474a9fSSerhiy Boiko 	case PRESTERA_ACL_RULE_ACTION_ACCEPT:
13518b474a9fSSerhiy Boiko 	case PRESTERA_ACL_RULE_ACTION_DROP:
13528b474a9fSSerhiy Boiko 	case PRESTERA_ACL_RULE_ACTION_TRAP:
13538b474a9fSSerhiy Boiko 		/* just rule action id, no specific data */
13548b474a9fSSerhiy Boiko 		break;
1355fa5d824cSVolodymyr Mytnyk 	case PRESTERA_ACL_RULE_ACTION_JUMP:
1356fa5d824cSVolodymyr Mytnyk 		action->jump.index = __cpu_to_le32(info->jump.index);
1357fa5d824cSVolodymyr Mytnyk 		break;
1358dde2daa0SVolodymyr Mytnyk 	case PRESTERA_ACL_RULE_ACTION_POLICE:
1359dde2daa0SVolodymyr Mytnyk 		action->police.id = __cpu_to_le32(info->police.id);
1360dde2daa0SVolodymyr Mytnyk 		break;
13616e36c7bcSVolodymyr Mytnyk 	case PRESTERA_ACL_RULE_ACTION_COUNT:
13626e36c7bcSVolodymyr Mytnyk 		action->count.id = __cpu_to_le32(info->count.id);
13636e36c7bcSVolodymyr Mytnyk 		break;
13648b474a9fSSerhiy Boiko 	default:
13658b474a9fSSerhiy Boiko 		return -EINVAL;
13668b474a9fSSerhiy Boiko 	}
13678b474a9fSSerhiy Boiko 
13688b474a9fSSerhiy Boiko 	return 0;
13698b474a9fSSerhiy Boiko }
13708b474a9fSSerhiy Boiko 
prestera_hw_vtcam_rule_add(struct prestera_switch * sw,u32 vtcam_id,u32 prio,void * key,void * keymask,struct prestera_acl_hw_action_info * act,u8 n_act,u32 * rule_id)137147327e19SVolodymyr Mytnyk int prestera_hw_vtcam_rule_add(struct prestera_switch *sw,
137247327e19SVolodymyr Mytnyk 			       u32 vtcam_id, u32 prio, void *key, void *keymask,
137347327e19SVolodymyr Mytnyk 			       struct prestera_acl_hw_action_info *act,
137447327e19SVolodymyr Mytnyk 			       u8 n_act, u32 *rule_id)
13758b474a9fSSerhiy Boiko {
137647327e19SVolodymyr Mytnyk 	struct prestera_msg_vtcam_rule_add_req *req;
137747327e19SVolodymyr Mytnyk 	struct prestera_msg_vtcam_resp resp;
1378*86348d21SErick Archer 	size_t size;
13798b474a9fSSerhiy Boiko 	int err;
138047327e19SVolodymyr Mytnyk 	u8 i;
13818b474a9fSSerhiy Boiko 
1382*86348d21SErick Archer 	size = struct_size(req, actions_msg, n_act);
1383*86348d21SErick Archer 	req = kzalloc(size, GFP_KERNEL);
1384*86348d21SErick Archer 	if (!req)
13858b474a9fSSerhiy Boiko 		return -ENOMEM;
13868b474a9fSSerhiy Boiko 
138747327e19SVolodymyr Mytnyk 	req->n_act = __cpu_to_le32(n_act);
13888b474a9fSSerhiy Boiko 
13898b474a9fSSerhiy Boiko 	/* put acl matches into the message */
139047327e19SVolodymyr Mytnyk 	memcpy(req->key, key, sizeof(req->key));
139147327e19SVolodymyr Mytnyk 	memcpy(req->keymask, keymask, sizeof(req->keymask));
139247327e19SVolodymyr Mytnyk 
139347327e19SVolodymyr Mytnyk 	/* put acl actions into the message */
139447327e19SVolodymyr Mytnyk 	for (i = 0; i < n_act; i++) {
1395*86348d21SErick Archer 		err = prestera_acl_rule_add_put_action(&req->actions_msg[i],
139647327e19SVolodymyr Mytnyk 						       &act[i]);
13978b474a9fSSerhiy Boiko 		if (err)
13988b474a9fSSerhiy Boiko 			goto free_buff;
139947327e19SVolodymyr Mytnyk 	}
14008b474a9fSSerhiy Boiko 
140147327e19SVolodymyr Mytnyk 	req->vtcam_id = __cpu_to_le32(vtcam_id);
140247327e19SVolodymyr Mytnyk 	req->prio = __cpu_to_le32(prio);
14038b474a9fSSerhiy Boiko 
140447327e19SVolodymyr Mytnyk 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_VTCAM_RULE_ADD,
14058b474a9fSSerhiy Boiko 			       &req->cmd, size, &resp.ret, sizeof(resp));
14068b474a9fSSerhiy Boiko 	if (err)
14078b474a9fSSerhiy Boiko 		goto free_buff;
14088b474a9fSSerhiy Boiko 
140947327e19SVolodymyr Mytnyk 	*rule_id = __le32_to_cpu(resp.rule_id);
14108b474a9fSSerhiy Boiko free_buff:
1411*86348d21SErick Archer 	kfree(req);
14128b474a9fSSerhiy Boiko 	return err;
14138b474a9fSSerhiy Boiko }
14148b474a9fSSerhiy Boiko 
prestera_hw_vtcam_rule_del(struct prestera_switch * sw,u32 vtcam_id,u32 rule_id)141547327e19SVolodymyr Mytnyk int prestera_hw_vtcam_rule_del(struct prestera_switch *sw,
141647327e19SVolodymyr Mytnyk 			       u32 vtcam_id, u32 rule_id)
14178b474a9fSSerhiy Boiko {
141847327e19SVolodymyr Mytnyk 	struct prestera_msg_vtcam_rule_del_req req = {
141947327e19SVolodymyr Mytnyk 		.vtcam_id = __cpu_to_le32(vtcam_id),
1420bb5dbf2cSVolodymyr Mytnyk 		.id = __cpu_to_le32(rule_id)
14218b474a9fSSerhiy Boiko 	};
14228b474a9fSSerhiy Boiko 
142347327e19SVolodymyr Mytnyk 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_VTCAM_RULE_DELETE,
14248b474a9fSSerhiy Boiko 			    &req.cmd, sizeof(req));
14258b474a9fSSerhiy Boiko }
14268b474a9fSSerhiy Boiko 
prestera_hw_vtcam_iface_bind(struct prestera_switch * sw,struct prestera_acl_iface * iface,u32 vtcam_id,u16 pcl_id)142747327e19SVolodymyr Mytnyk int prestera_hw_vtcam_iface_bind(struct prestera_switch *sw,
142847327e19SVolodymyr Mytnyk 				 struct prestera_acl_iface *iface,
142947327e19SVolodymyr Mytnyk 				 u32 vtcam_id, u16 pcl_id)
14308b474a9fSSerhiy Boiko {
143147327e19SVolodymyr Mytnyk 	struct prestera_msg_vtcam_bind_req req = {
143247327e19SVolodymyr Mytnyk 		.vtcam_id = __cpu_to_le32(vtcam_id),
143347327e19SVolodymyr Mytnyk 		.type = __cpu_to_le16(iface->type),
143447327e19SVolodymyr Mytnyk 		.pcl_id = __cpu_to_le16(pcl_id)
14358b474a9fSSerhiy Boiko 	};
14368b474a9fSSerhiy Boiko 
143747327e19SVolodymyr Mytnyk 	if (iface->type == PRESTERA_ACL_IFACE_TYPE_PORT) {
143847327e19SVolodymyr Mytnyk 		req.port.dev_id = __cpu_to_le32(iface->port->dev_id);
143947327e19SVolodymyr Mytnyk 		req.port.hw_id = __cpu_to_le32(iface->port->hw_id);
144047327e19SVolodymyr Mytnyk 	} else {
144147327e19SVolodymyr Mytnyk 		req.index = __cpu_to_le32(iface->index);
14428b474a9fSSerhiy Boiko 	}
14438b474a9fSSerhiy Boiko 
144447327e19SVolodymyr Mytnyk 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_VTCAM_IFACE_BIND,
14458b474a9fSSerhiy Boiko 			    &req.cmd, sizeof(req));
14468b474a9fSSerhiy Boiko }
14478b474a9fSSerhiy Boiko 
prestera_hw_vtcam_iface_unbind(struct prestera_switch * sw,struct prestera_acl_iface * iface,u32 vtcam_id)144847327e19SVolodymyr Mytnyk int prestera_hw_vtcam_iface_unbind(struct prestera_switch *sw,
144947327e19SVolodymyr Mytnyk 				   struct prestera_acl_iface *iface,
145047327e19SVolodymyr Mytnyk 				   u32 vtcam_id)
14518b474a9fSSerhiy Boiko {
145247327e19SVolodymyr Mytnyk 	struct prestera_msg_vtcam_bind_req req = {
145347327e19SVolodymyr Mytnyk 		.vtcam_id = __cpu_to_le32(vtcam_id),
145447327e19SVolodymyr Mytnyk 		.type = __cpu_to_le16(iface->type)
14558b474a9fSSerhiy Boiko 	};
14568b474a9fSSerhiy Boiko 
145747327e19SVolodymyr Mytnyk 	if (iface->type == PRESTERA_ACL_IFACE_TYPE_PORT) {
145847327e19SVolodymyr Mytnyk 		req.port.dev_id = __cpu_to_le32(iface->port->dev_id);
145947327e19SVolodymyr Mytnyk 		req.port.hw_id = __cpu_to_le32(iface->port->hw_id);
146047327e19SVolodymyr Mytnyk 	} else {
146147327e19SVolodymyr Mytnyk 		req.index = __cpu_to_le32(iface->index);
146247327e19SVolodymyr Mytnyk 	}
146347327e19SVolodymyr Mytnyk 
146447327e19SVolodymyr Mytnyk 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_VTCAM_IFACE_UNBIND,
14658b474a9fSSerhiy Boiko 			    &req.cmd, sizeof(req));
14668b474a9fSSerhiy Boiko }
14678b474a9fSSerhiy Boiko 
prestera_hw_span_get(const struct prestera_port * port,u8 * span_id)146813defa27SSerhiy Boiko int prestera_hw_span_get(const struct prestera_port *port, u8 *span_id)
146913defa27SSerhiy Boiko {
147013defa27SSerhiy Boiko 	struct prestera_msg_span_resp resp;
147113defa27SSerhiy Boiko 	struct prestera_msg_span_req req = {
1472bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1473bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
147413defa27SSerhiy Boiko 	};
147513defa27SSerhiy Boiko 	int err;
147613defa27SSerhiy Boiko 
147713defa27SSerhiy Boiko 	err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_SPAN_GET,
147813defa27SSerhiy Boiko 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
147913defa27SSerhiy Boiko 	if (err)
148013defa27SSerhiy Boiko 		return err;
148113defa27SSerhiy Boiko 
148213defa27SSerhiy Boiko 	*span_id = resp.id;
148313defa27SSerhiy Boiko 
148413defa27SSerhiy Boiko 	return 0;
148513defa27SSerhiy Boiko }
148613defa27SSerhiy Boiko 
prestera_hw_span_bind(const struct prestera_port * port,u8 span_id,bool ingress)14878c448c2bSSerhiy Boiko int prestera_hw_span_bind(const struct prestera_port *port, u8 span_id,
14888c448c2bSSerhiy Boiko 			  bool ingress)
148913defa27SSerhiy Boiko {
149013defa27SSerhiy Boiko 	struct prestera_msg_span_req req = {
1491bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1492bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
149313defa27SSerhiy Boiko 		.id = span_id,
149413defa27SSerhiy Boiko 	};
14958c448c2bSSerhiy Boiko 	enum prestera_cmd_type_t cmd_type;
149613defa27SSerhiy Boiko 
14978c448c2bSSerhiy Boiko 	if (ingress)
14988c448c2bSSerhiy Boiko 		cmd_type = PRESTERA_CMD_TYPE_SPAN_INGRESS_BIND;
14998c448c2bSSerhiy Boiko 	else
15008c448c2bSSerhiy Boiko 		cmd_type = PRESTERA_CMD_TYPE_SPAN_EGRESS_BIND;
15018c448c2bSSerhiy Boiko 
15028c448c2bSSerhiy Boiko 	return prestera_cmd(port->sw, cmd_type, &req.cmd, sizeof(req));
15038c448c2bSSerhiy Boiko 
150413defa27SSerhiy Boiko }
150513defa27SSerhiy Boiko 
prestera_hw_span_unbind(const struct prestera_port * port,bool ingress)15068c448c2bSSerhiy Boiko int prestera_hw_span_unbind(const struct prestera_port *port, bool ingress)
150713defa27SSerhiy Boiko {
150813defa27SSerhiy Boiko 	struct prestera_msg_span_req req = {
1509bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1510bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
151113defa27SSerhiy Boiko 	};
15128c448c2bSSerhiy Boiko 	enum prestera_cmd_type_t cmd_type;
151313defa27SSerhiy Boiko 
15148c448c2bSSerhiy Boiko 	if (ingress)
15158c448c2bSSerhiy Boiko 		cmd_type = PRESTERA_CMD_TYPE_SPAN_INGRESS_UNBIND;
15168c448c2bSSerhiy Boiko 	else
15178c448c2bSSerhiy Boiko 		cmd_type = PRESTERA_CMD_TYPE_SPAN_EGRESS_UNBIND;
15188c448c2bSSerhiy Boiko 
15198c448c2bSSerhiy Boiko 	return prestera_cmd(port->sw, cmd_type, &req.cmd, sizeof(req));
152013defa27SSerhiy Boiko }
152113defa27SSerhiy Boiko 
prestera_hw_span_release(struct prestera_switch * sw,u8 span_id)152213defa27SSerhiy Boiko int prestera_hw_span_release(struct prestera_switch *sw, u8 span_id)
152313defa27SSerhiy Boiko {
152413defa27SSerhiy Boiko 	struct prestera_msg_span_req req = {
152513defa27SSerhiy Boiko 		.id = span_id
152613defa27SSerhiy Boiko 	};
152713defa27SSerhiy Boiko 
152813defa27SSerhiy Boiko 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_SPAN_RELEASE,
152913defa27SSerhiy Boiko 			    &req.cmd, sizeof(req));
153013defa27SSerhiy Boiko }
153113defa27SSerhiy Boiko 
prestera_hw_port_type_get(const struct prestera_port * port,u8 * type)1532a97d3c69SVadym Kochan int prestera_hw_port_type_get(const struct prestera_port *port, u8 *type)
1533a97d3c69SVadym Kochan {
1534a97d3c69SVadym Kochan 	struct prestera_msg_port_attr_req req = {
1535bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_TYPE),
1536bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1537bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1538a97d3c69SVadym Kochan 	};
1539a97d3c69SVadym Kochan 	struct prestera_msg_port_attr_resp resp;
1540a97d3c69SVadym Kochan 	int err;
1541a97d3c69SVadym Kochan 
1542a97d3c69SVadym Kochan 	err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET,
1543a97d3c69SVadym Kochan 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
1544a97d3c69SVadym Kochan 	if (err)
1545a97d3c69SVadym Kochan 		return err;
1546a97d3c69SVadym Kochan 
1547a97d3c69SVadym Kochan 	*type = resp.param.type;
1548a97d3c69SVadym Kochan 
1549a97d3c69SVadym Kochan 	return 0;
1550a97d3c69SVadym Kochan }
1551a97d3c69SVadym Kochan 
prestera_hw_port_speed_get(const struct prestera_port * port,u32 * speed)1552a97d3c69SVadym Kochan int prestera_hw_port_speed_get(const struct prestera_port *port, u32 *speed)
1553a97d3c69SVadym Kochan {
1554a97d3c69SVadym Kochan 	struct prestera_msg_port_attr_req req = {
1555bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_SPEED),
1556bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1557bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1558a97d3c69SVadym Kochan 	};
1559a97d3c69SVadym Kochan 	struct prestera_msg_port_attr_resp resp;
1560a97d3c69SVadym Kochan 	int err;
1561a97d3c69SVadym Kochan 
1562a97d3c69SVadym Kochan 	err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET,
1563a97d3c69SVadym Kochan 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
1564a97d3c69SVadym Kochan 	if (err)
1565a97d3c69SVadym Kochan 		return err;
1566a97d3c69SVadym Kochan 
1567bb5dbf2cSVolodymyr Mytnyk 	*speed = __le32_to_cpu(resp.param.speed);
1568a97d3c69SVadym Kochan 
1569a97d3c69SVadym Kochan 	return 0;
1570a97d3c69SVadym Kochan }
1571a97d3c69SVadym Kochan 
prestera_hw_port_autoneg_restart(struct prestera_port * port)1572a97d3c69SVadym Kochan int prestera_hw_port_autoneg_restart(struct prestera_port *port)
1573a97d3c69SVadym Kochan {
1574a97d3c69SVadym Kochan 	struct prestera_msg_port_attr_req req = {
1575a46a5036SVolodymyr Mytnyk 		.attr =
1576a46a5036SVolodymyr Mytnyk 		    __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_PHY_AUTONEG_RESTART),
1577bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1578bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1579a97d3c69SVadym Kochan 	};
1580a97d3c69SVadym Kochan 
1581a97d3c69SVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET,
1582a97d3c69SVadym Kochan 			    &req.cmd, sizeof(req));
1583a97d3c69SVadym Kochan }
1584a97d3c69SVadym Kochan 
prestera_hw_port_stats_get(const struct prestera_port * port,struct prestera_port_stats * st)1585501ef306SVadym Kochan int prestera_hw_port_stats_get(const struct prestera_port *port,
1586501ef306SVadym Kochan 			       struct prestera_port_stats *st)
1587501ef306SVadym Kochan {
1588501ef306SVadym Kochan 	struct prestera_msg_port_attr_req req = {
1589bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_STATS),
1590bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1591bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1592501ef306SVadym Kochan 	};
1593501ef306SVadym Kochan 	struct prestera_msg_port_stats_resp resp;
1594bb5dbf2cSVolodymyr Mytnyk 	__le64 *hw = resp.stats;
1595501ef306SVadym Kochan 	int err;
1596501ef306SVadym Kochan 
1597501ef306SVadym Kochan 	err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET,
1598501ef306SVadym Kochan 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
1599501ef306SVadym Kochan 	if (err)
1600501ef306SVadym Kochan 		return err;
1601501ef306SVadym Kochan 
1602bb5dbf2cSVolodymyr Mytnyk 	st->good_octets_received =
1603bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_GOOD_OCTETS_RCV_CNT]);
1604bb5dbf2cSVolodymyr Mytnyk 	st->bad_octets_received =
1605bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_BAD_OCTETS_RCV_CNT]);
1606bb5dbf2cSVolodymyr Mytnyk 	st->mac_trans_error =
1607bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_MAC_TRANSMIT_ERR_CNT]);
1608bb5dbf2cSVolodymyr Mytnyk 	st->broadcast_frames_received =
1609bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_BRDC_PKTS_RCV_CNT]);
1610bb5dbf2cSVolodymyr Mytnyk 	st->multicast_frames_received =
1611bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_MC_PKTS_RCV_CNT]);
1612bb5dbf2cSVolodymyr Mytnyk 	st->frames_64_octets = __le64_to_cpu(hw[PRESTERA_PORT_PKTS_64L_CNT]);
1613bb5dbf2cSVolodymyr Mytnyk 	st->frames_65_to_127_octets =
1614bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_PKTS_65TO127L_CNT]);
1615bb5dbf2cSVolodymyr Mytnyk 	st->frames_128_to_255_octets =
1616bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_PKTS_128TO255L_CNT]);
1617bb5dbf2cSVolodymyr Mytnyk 	st->frames_256_to_511_octets =
1618bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_PKTS_256TO511L_CNT]);
1619bb5dbf2cSVolodymyr Mytnyk 	st->frames_512_to_1023_octets =
1620bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_PKTS_512TO1023L_CNT]);
1621bb5dbf2cSVolodymyr Mytnyk 	st->frames_1024_to_max_octets =
1622bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_PKTS_1024TOMAXL_CNT]);
1623bb5dbf2cSVolodymyr Mytnyk 	st->excessive_collision =
1624bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_EXCESSIVE_COLLISIONS_CNT]);
1625bb5dbf2cSVolodymyr Mytnyk 	st->multicast_frames_sent =
1626bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_MC_PKTS_SENT_CNT]);
1627bb5dbf2cSVolodymyr Mytnyk 	st->broadcast_frames_sent =
1628bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_BRDC_PKTS_SENT_CNT]);
1629bb5dbf2cSVolodymyr Mytnyk 	st->fc_sent = __le64_to_cpu(hw[PRESTERA_PORT_FC_SENT_CNT]);
1630bb5dbf2cSVolodymyr Mytnyk 	st->fc_received = __le64_to_cpu(hw[PRESTERA_PORT_GOOD_FC_RCV_CNT]);
1631bb5dbf2cSVolodymyr Mytnyk 	st->buffer_overrun = __le64_to_cpu(hw[PRESTERA_PORT_DROP_EVENTS_CNT]);
1632bb5dbf2cSVolodymyr Mytnyk 	st->undersize = __le64_to_cpu(hw[PRESTERA_PORT_UNDERSIZE_PKTS_CNT]);
1633bb5dbf2cSVolodymyr Mytnyk 	st->fragments = __le64_to_cpu(hw[PRESTERA_PORT_FRAGMENTS_PKTS_CNT]);
1634bb5dbf2cSVolodymyr Mytnyk 	st->oversize = __le64_to_cpu(hw[PRESTERA_PORT_OVERSIZE_PKTS_CNT]);
1635bb5dbf2cSVolodymyr Mytnyk 	st->jabber = __le64_to_cpu(hw[PRESTERA_PORT_JABBER_PKTS_CNT]);
1636bb5dbf2cSVolodymyr Mytnyk 	st->rx_error_frame_received =
1637bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_MAC_RCV_ERROR_CNT]);
1638bb5dbf2cSVolodymyr Mytnyk 	st->bad_crc = __le64_to_cpu(hw[PRESTERA_PORT_BAD_CRC_CNT]);
1639bb5dbf2cSVolodymyr Mytnyk 	st->collisions = __le64_to_cpu(hw[PRESTERA_PORT_COLLISIONS_CNT]);
1640bb5dbf2cSVolodymyr Mytnyk 	st->late_collision =
1641bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_LATE_COLLISIONS_CNT]);
1642bb5dbf2cSVolodymyr Mytnyk 	st->unicast_frames_received =
1643bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_GOOD_UC_PKTS_RCV_CNT]);
1644bb5dbf2cSVolodymyr Mytnyk 	st->unicast_frames_sent =
1645bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_GOOD_UC_PKTS_SENT_CNT]);
1646bb5dbf2cSVolodymyr Mytnyk 	st->sent_multiple =
1647bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_MULTIPLE_PKTS_SENT_CNT]);
1648bb5dbf2cSVolodymyr Mytnyk 	st->sent_deferred =
1649bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_DEFERRED_PKTS_SENT_CNT]);
1650bb5dbf2cSVolodymyr Mytnyk 	st->good_octets_sent =
1651bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_GOOD_OCTETS_SENT_CNT]);
1652501ef306SVadym Kochan 
1653501ef306SVadym Kochan 	return 0;
1654501ef306SVadym Kochan }
1655501ef306SVadym Kochan 
prestera_hw_port_learning_set(struct prestera_port * port,bool enable)1656e1189d9aSVadym Kochan int prestera_hw_port_learning_set(struct prestera_port *port, bool enable)
1657e1189d9aSVadym Kochan {
1658e1189d9aSVadym Kochan 	struct prestera_msg_port_attr_req req = {
1659bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_LEARNING),
1660bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1661bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1662e1189d9aSVadym Kochan 		.param = {
1663e1189d9aSVadym Kochan 			.learning = enable,
1664e1189d9aSVadym Kochan 		}
1665e1189d9aSVadym Kochan 	};
1666e1189d9aSVadym Kochan 
1667e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET,
1668e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1669e1189d9aSVadym Kochan }
1670e1189d9aSVadym Kochan 
prestera_hw_port_uc_flood_set(const struct prestera_port * port,bool flood)1671116f5af7SOleksandr Mazur int prestera_hw_port_uc_flood_set(const struct prestera_port *port, bool flood)
1672c00e8a69SVadym Kochan {
1673c00e8a69SVadym Kochan 	struct prestera_msg_port_attr_req req = {
1674bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_FLOOD),
1675bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1676bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1677c00e8a69SVadym Kochan 		.param = {
1678c00e8a69SVadym Kochan 			.flood_ext = {
1679c00e8a69SVadym Kochan 				.type = PRESTERA_PORT_FLOOD_TYPE_UC,
1680c00e8a69SVadym Kochan 				.enable = flood,
1681c00e8a69SVadym Kochan 			}
1682c00e8a69SVadym Kochan 		}
1683c00e8a69SVadym Kochan 	};
1684c00e8a69SVadym Kochan 
1685c00e8a69SVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET,
1686c00e8a69SVadym Kochan 			    &req.cmd, sizeof(req));
1687c00e8a69SVadym Kochan }
1688c00e8a69SVadym Kochan 
prestera_hw_port_mc_flood_set(const struct prestera_port * port,bool flood)1689116f5af7SOleksandr Mazur int prestera_hw_port_mc_flood_set(const struct prestera_port *port, bool flood)
1690c00e8a69SVadym Kochan {
1691c00e8a69SVadym Kochan 	struct prestera_msg_port_attr_req req = {
1692bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_FLOOD),
1693bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1694bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1695c00e8a69SVadym Kochan 		.param = {
1696c00e8a69SVadym Kochan 			.flood_ext = {
1697c00e8a69SVadym Kochan 				.type = PRESTERA_PORT_FLOOD_TYPE_MC,
1698c00e8a69SVadym Kochan 				.enable = flood,
1699c00e8a69SVadym Kochan 			}
1700c00e8a69SVadym Kochan 		}
1701c00e8a69SVadym Kochan 	};
1702c00e8a69SVadym Kochan 
1703c00e8a69SVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET,
1704c00e8a69SVadym Kochan 			    &req.cmd, sizeof(req));
1705c00e8a69SVadym Kochan }
1706c00e8a69SVadym Kochan 
prestera_hw_port_br_locked_set(const struct prestera_port * port,bool br_locked)170773ef239cSOleksandr Mazur int prestera_hw_port_br_locked_set(const struct prestera_port *port,
170873ef239cSOleksandr Mazur 				   bool br_locked)
170973ef239cSOleksandr Mazur {
171073ef239cSOleksandr Mazur 	struct prestera_msg_port_attr_req req = {
171173ef239cSOleksandr Mazur 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_LOCKED),
171273ef239cSOleksandr Mazur 		.port = __cpu_to_le32(port->hw_id),
171373ef239cSOleksandr Mazur 		.dev = __cpu_to_le32(port->dev_id),
171473ef239cSOleksandr Mazur 		.param = {
171573ef239cSOleksandr Mazur 			.br_locked = br_locked,
171673ef239cSOleksandr Mazur 		}
171773ef239cSOleksandr Mazur 	};
171873ef239cSOleksandr Mazur 
171973ef239cSOleksandr Mazur 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET,
172073ef239cSOleksandr Mazur 			    &req.cmd, sizeof(req));
172173ef239cSOleksandr Mazur }
172273ef239cSOleksandr Mazur 
prestera_hw_vlan_create(struct prestera_switch * sw,u16 vid)1723e1189d9aSVadym Kochan int prestera_hw_vlan_create(struct prestera_switch *sw, u16 vid)
1724e1189d9aSVadym Kochan {
1725e1189d9aSVadym Kochan 	struct prestera_msg_vlan_req req = {
1726bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1727e1189d9aSVadym Kochan 	};
1728e1189d9aSVadym Kochan 
1729e1189d9aSVadym Kochan 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_VLAN_CREATE,
1730e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1731e1189d9aSVadym Kochan }
1732e1189d9aSVadym Kochan 
prestera_hw_vlan_delete(struct prestera_switch * sw,u16 vid)1733e1189d9aSVadym Kochan int prestera_hw_vlan_delete(struct prestera_switch *sw, u16 vid)
1734e1189d9aSVadym Kochan {
1735e1189d9aSVadym Kochan 	struct prestera_msg_vlan_req req = {
1736bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1737e1189d9aSVadym Kochan 	};
1738e1189d9aSVadym Kochan 
1739e1189d9aSVadym Kochan 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_VLAN_DELETE,
1740e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1741e1189d9aSVadym Kochan }
1742e1189d9aSVadym Kochan 
prestera_hw_vlan_port_set(struct prestera_port * port,u16 vid,bool is_member,bool untagged)1743e1189d9aSVadym Kochan int prestera_hw_vlan_port_set(struct prestera_port *port, u16 vid,
1744e1189d9aSVadym Kochan 			      bool is_member, bool untagged)
1745e1189d9aSVadym Kochan {
1746e1189d9aSVadym Kochan 	struct prestera_msg_vlan_req req = {
1747bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1748bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1749bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1750e1189d9aSVadym Kochan 		.is_member = is_member,
1751e1189d9aSVadym Kochan 		.is_tagged = !untagged,
1752e1189d9aSVadym Kochan 	};
1753e1189d9aSVadym Kochan 
1754e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_VLAN_PORT_SET,
1755e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1756e1189d9aSVadym Kochan }
1757e1189d9aSVadym Kochan 
prestera_hw_vlan_port_vid_set(struct prestera_port * port,u16 vid)1758e1189d9aSVadym Kochan int prestera_hw_vlan_port_vid_set(struct prestera_port *port, u16 vid)
1759e1189d9aSVadym Kochan {
1760e1189d9aSVadym Kochan 	struct prestera_msg_vlan_req req = {
1761bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1762bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1763bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1764e1189d9aSVadym Kochan 	};
1765e1189d9aSVadym Kochan 
1766e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_VLAN_PVID_SET,
1767e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1768e1189d9aSVadym Kochan }
1769e1189d9aSVadym Kochan 
prestera_hw_vlan_port_stp_set(struct prestera_port * port,u16 vid,u8 state)1770e1189d9aSVadym Kochan int prestera_hw_vlan_port_stp_set(struct prestera_port *port, u16 vid, u8 state)
1771e1189d9aSVadym Kochan {
1772e1189d9aSVadym Kochan 	struct prestera_msg_stp_req req = {
1773bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1774bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1775bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1776e1189d9aSVadym Kochan 		.state = state,
1777e1189d9aSVadym Kochan 	};
1778e1189d9aSVadym Kochan 
1779e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_STP_PORT_SET,
1780e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1781e1189d9aSVadym Kochan }
1782e1189d9aSVadym Kochan 
prestera_hw_fdb_add(struct prestera_port * port,const unsigned char * mac,u16 vid,bool dynamic)1783e1189d9aSVadym Kochan int prestera_hw_fdb_add(struct prestera_port *port, const unsigned char *mac,
1784e1189d9aSVadym Kochan 			u16 vid, bool dynamic)
1785e1189d9aSVadym Kochan {
1786e1189d9aSVadym Kochan 	struct prestera_msg_fdb_req req = {
1787255213caSSerhiy Boiko 		.dest = {
1788bb5dbf2cSVolodymyr Mytnyk 			.dev = __cpu_to_le32(port->dev_id),
1789bb5dbf2cSVolodymyr Mytnyk 			.port = __cpu_to_le32(port->hw_id),
1790255213caSSerhiy Boiko 		},
1791bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1792e1189d9aSVadym Kochan 		.dynamic = dynamic,
1793e1189d9aSVadym Kochan 	};
1794e1189d9aSVadym Kochan 
1795e1189d9aSVadym Kochan 	ether_addr_copy(req.mac, mac);
1796e1189d9aSVadym Kochan 
1797e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_FDB_ADD,
1798e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1799e1189d9aSVadym Kochan }
1800e1189d9aSVadym Kochan 
prestera_hw_fdb_del(struct prestera_port * port,const unsigned char * mac,u16 vid)1801e1189d9aSVadym Kochan int prestera_hw_fdb_del(struct prestera_port *port, const unsigned char *mac,
1802e1189d9aSVadym Kochan 			u16 vid)
1803e1189d9aSVadym Kochan {
1804e1189d9aSVadym Kochan 	struct prestera_msg_fdb_req req = {
1805255213caSSerhiy Boiko 		.dest = {
1806bb5dbf2cSVolodymyr Mytnyk 			.dev = __cpu_to_le32(port->dev_id),
1807bb5dbf2cSVolodymyr Mytnyk 			.port = __cpu_to_le32(port->hw_id),
1808255213caSSerhiy Boiko 		},
1809bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1810e1189d9aSVadym Kochan 	};
1811e1189d9aSVadym Kochan 
1812e1189d9aSVadym Kochan 	ether_addr_copy(req.mac, mac);
1813e1189d9aSVadym Kochan 
1814e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_FDB_DELETE,
1815e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1816e1189d9aSVadym Kochan }
1817e1189d9aSVadym Kochan 
prestera_hw_lag_fdb_add(struct prestera_switch * sw,u16 lag_id,const unsigned char * mac,u16 vid,bool dynamic)1818255213caSSerhiy Boiko int prestera_hw_lag_fdb_add(struct prestera_switch *sw, u16 lag_id,
1819255213caSSerhiy Boiko 			    const unsigned char *mac, u16 vid, bool dynamic)
1820255213caSSerhiy Boiko {
1821255213caSSerhiy Boiko 	struct prestera_msg_fdb_req req = {
1822255213caSSerhiy Boiko 		.dest_type = PRESTERA_HW_FDB_ENTRY_TYPE_LAG,
1823255213caSSerhiy Boiko 		.dest = {
1824bb5dbf2cSVolodymyr Mytnyk 			.lag_id = __cpu_to_le16(lag_id),
1825255213caSSerhiy Boiko 		},
1826bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1827255213caSSerhiy Boiko 		.dynamic = dynamic,
1828255213caSSerhiy Boiko 	};
1829255213caSSerhiy Boiko 
1830255213caSSerhiy Boiko 	ether_addr_copy(req.mac, mac);
1831255213caSSerhiy Boiko 
1832255213caSSerhiy Boiko 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_FDB_ADD,
1833255213caSSerhiy Boiko 			    &req.cmd, sizeof(req));
1834255213caSSerhiy Boiko }
1835255213caSSerhiy Boiko 
prestera_hw_lag_fdb_del(struct prestera_switch * sw,u16 lag_id,const unsigned char * mac,u16 vid)1836255213caSSerhiy Boiko int prestera_hw_lag_fdb_del(struct prestera_switch *sw, u16 lag_id,
1837255213caSSerhiy Boiko 			    const unsigned char *mac, u16 vid)
1838255213caSSerhiy Boiko {
1839255213caSSerhiy Boiko 	struct prestera_msg_fdb_req req = {
1840255213caSSerhiy Boiko 		.dest_type = PRESTERA_HW_FDB_ENTRY_TYPE_LAG,
1841255213caSSerhiy Boiko 		.dest = {
1842bb5dbf2cSVolodymyr Mytnyk 			.lag_id = __cpu_to_le16(lag_id),
1843255213caSSerhiy Boiko 		},
1844bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1845255213caSSerhiy Boiko 	};
1846255213caSSerhiy Boiko 
1847255213caSSerhiy Boiko 	ether_addr_copy(req.mac, mac);
1848255213caSSerhiy Boiko 
1849255213caSSerhiy Boiko 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_FDB_DELETE,
1850255213caSSerhiy Boiko 			    &req.cmd, sizeof(req));
1851255213caSSerhiy Boiko }
1852255213caSSerhiy Boiko 
prestera_hw_fdb_flush_port(struct prestera_port * port,u32 mode)1853e1189d9aSVadym Kochan int prestera_hw_fdb_flush_port(struct prestera_port *port, u32 mode)
1854e1189d9aSVadym Kochan {
1855e1189d9aSVadym Kochan 	struct prestera_msg_fdb_req req = {
1856255213caSSerhiy Boiko 		.dest = {
1857bb5dbf2cSVolodymyr Mytnyk 			.dev = __cpu_to_le32(port->dev_id),
1858bb5dbf2cSVolodymyr Mytnyk 			.port = __cpu_to_le32(port->hw_id),
1859255213caSSerhiy Boiko 		},
1860bb5dbf2cSVolodymyr Mytnyk 		.flush_mode = __cpu_to_le32(mode),
1861e1189d9aSVadym Kochan 	};
1862e1189d9aSVadym Kochan 
1863e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_FDB_FLUSH_PORT,
1864e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1865e1189d9aSVadym Kochan }
1866e1189d9aSVadym Kochan 
prestera_hw_fdb_flush_vlan(struct prestera_switch * sw,u16 vid,u32 mode)1867e1189d9aSVadym Kochan int prestera_hw_fdb_flush_vlan(struct prestera_switch *sw, u16 vid, u32 mode)
1868e1189d9aSVadym Kochan {
1869e1189d9aSVadym Kochan 	struct prestera_msg_fdb_req req = {
1870bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1871bb5dbf2cSVolodymyr Mytnyk 		.flush_mode = __cpu_to_le32(mode),
1872e1189d9aSVadym Kochan 	};
1873e1189d9aSVadym Kochan 
1874e1189d9aSVadym Kochan 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_FDB_FLUSH_VLAN,
1875e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1876e1189d9aSVadym Kochan }
1877e1189d9aSVadym Kochan 
prestera_hw_fdb_flush_port_vlan(struct prestera_port * port,u16 vid,u32 mode)1878e1189d9aSVadym Kochan int prestera_hw_fdb_flush_port_vlan(struct prestera_port *port, u16 vid,
1879e1189d9aSVadym Kochan 				    u32 mode)
1880e1189d9aSVadym Kochan {
1881e1189d9aSVadym Kochan 	struct prestera_msg_fdb_req req = {
1882255213caSSerhiy Boiko 		.dest = {
1883bb5dbf2cSVolodymyr Mytnyk 			.dev = __cpu_to_le32(port->dev_id),
1884bb5dbf2cSVolodymyr Mytnyk 			.port = __cpu_to_le32(port->hw_id),
1885255213caSSerhiy Boiko 		},
1886bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1887bb5dbf2cSVolodymyr Mytnyk 		.flush_mode = __cpu_to_le32(mode),
1888e1189d9aSVadym Kochan 	};
1889e1189d9aSVadym Kochan 
1890e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_FDB_FLUSH_PORT_VLAN,
1891e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1892e1189d9aSVadym Kochan }
1893e1189d9aSVadym Kochan 
prestera_hw_fdb_flush_lag(struct prestera_switch * sw,u16 lag_id,u32 mode)1894255213caSSerhiy Boiko int prestera_hw_fdb_flush_lag(struct prestera_switch *sw, u16 lag_id,
1895255213caSSerhiy Boiko 			      u32 mode)
1896255213caSSerhiy Boiko {
1897255213caSSerhiy Boiko 	struct prestera_msg_fdb_req req = {
1898255213caSSerhiy Boiko 		.dest_type = PRESTERA_HW_FDB_ENTRY_TYPE_LAG,
1899255213caSSerhiy Boiko 		.dest = {
1900bb5dbf2cSVolodymyr Mytnyk 			.lag_id = __cpu_to_le16(lag_id),
1901255213caSSerhiy Boiko 		},
1902bb5dbf2cSVolodymyr Mytnyk 		.flush_mode = __cpu_to_le32(mode),
1903255213caSSerhiy Boiko 	};
1904255213caSSerhiy Boiko 
1905255213caSSerhiy Boiko 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_FDB_FLUSH_PORT,
1906255213caSSerhiy Boiko 			    &req.cmd, sizeof(req));
1907255213caSSerhiy Boiko }
1908255213caSSerhiy Boiko 
prestera_hw_fdb_flush_lag_vlan(struct prestera_switch * sw,u16 lag_id,u16 vid,u32 mode)1909255213caSSerhiy Boiko int prestera_hw_fdb_flush_lag_vlan(struct prestera_switch *sw,
1910255213caSSerhiy Boiko 				   u16 lag_id, u16 vid, u32 mode)
1911255213caSSerhiy Boiko {
1912255213caSSerhiy Boiko 	struct prestera_msg_fdb_req req = {
1913255213caSSerhiy Boiko 		.dest_type = PRESTERA_HW_FDB_ENTRY_TYPE_LAG,
1914255213caSSerhiy Boiko 		.dest = {
1915bb5dbf2cSVolodymyr Mytnyk 			.lag_id = __cpu_to_le16(lag_id),
1916255213caSSerhiy Boiko 		},
1917bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1918bb5dbf2cSVolodymyr Mytnyk 		.flush_mode = __cpu_to_le32(mode),
1919255213caSSerhiy Boiko 	};
1920255213caSSerhiy Boiko 
1921255213caSSerhiy Boiko 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_FDB_FLUSH_PORT_VLAN,
1922255213caSSerhiy Boiko 			    &req.cmd, sizeof(req));
1923255213caSSerhiy Boiko }
1924255213caSSerhiy Boiko 
prestera_hw_bridge_create(struct prestera_switch * sw,u16 * bridge_id)1925e1189d9aSVadym Kochan int prestera_hw_bridge_create(struct prestera_switch *sw, u16 *bridge_id)
1926e1189d9aSVadym Kochan {
1927e1189d9aSVadym Kochan 	struct prestera_msg_bridge_resp resp;
1928e1189d9aSVadym Kochan 	struct prestera_msg_bridge_req req;
1929e1189d9aSVadym Kochan 	int err;
1930e1189d9aSVadym Kochan 
1931e1189d9aSVadym Kochan 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_BRIDGE_CREATE,
1932e1189d9aSVadym Kochan 			       &req.cmd, sizeof(req),
1933e1189d9aSVadym Kochan 			       &resp.ret, sizeof(resp));
1934e1189d9aSVadym Kochan 	if (err)
1935e1189d9aSVadym Kochan 		return err;
1936e1189d9aSVadym Kochan 
1937bb5dbf2cSVolodymyr Mytnyk 	*bridge_id = __le16_to_cpu(resp.bridge);
1938e1189d9aSVadym Kochan 
1939e1189d9aSVadym Kochan 	return 0;
1940e1189d9aSVadym Kochan }
1941e1189d9aSVadym Kochan 
prestera_hw_bridge_delete(struct prestera_switch * sw,u16 bridge_id)1942e1189d9aSVadym Kochan int prestera_hw_bridge_delete(struct prestera_switch *sw, u16 bridge_id)
1943e1189d9aSVadym Kochan {
1944e1189d9aSVadym Kochan 	struct prestera_msg_bridge_req req = {
1945bb5dbf2cSVolodymyr Mytnyk 		.bridge = __cpu_to_le16(bridge_id),
1946e1189d9aSVadym Kochan 	};
1947e1189d9aSVadym Kochan 
1948e1189d9aSVadym Kochan 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_BRIDGE_DELETE,
1949e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1950e1189d9aSVadym Kochan }
1951e1189d9aSVadym Kochan 
prestera_hw_bridge_port_add(struct prestera_port * port,u16 bridge_id)1952e1189d9aSVadym Kochan int prestera_hw_bridge_port_add(struct prestera_port *port, u16 bridge_id)
1953e1189d9aSVadym Kochan {
1954e1189d9aSVadym Kochan 	struct prestera_msg_bridge_req req = {
1955bb5dbf2cSVolodymyr Mytnyk 		.bridge = __cpu_to_le16(bridge_id),
1956bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1957bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1958e1189d9aSVadym Kochan 	};
1959e1189d9aSVadym Kochan 
1960e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_BRIDGE_PORT_ADD,
1961e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1962e1189d9aSVadym Kochan }
1963e1189d9aSVadym Kochan 
prestera_hw_bridge_port_delete(struct prestera_port * port,u16 bridge_id)1964e1189d9aSVadym Kochan int prestera_hw_bridge_port_delete(struct prestera_port *port, u16 bridge_id)
1965e1189d9aSVadym Kochan {
1966e1189d9aSVadym Kochan 	struct prestera_msg_bridge_req req = {
1967bb5dbf2cSVolodymyr Mytnyk 		.bridge = __cpu_to_le16(bridge_id),
1968bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1969bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1970e1189d9aSVadym Kochan 	};
1971e1189d9aSVadym Kochan 
1972e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_BRIDGE_PORT_DELETE,
1973e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1974e1189d9aSVadym Kochan }
1975e1189d9aSVadym Kochan 
prestera_iface_to_msg(struct prestera_iface * iface,struct prestera_msg_iface * msg_if)19760f07bd6bSYevhen Orlov static int prestera_iface_to_msg(struct prestera_iface *iface,
19770f07bd6bSYevhen Orlov 				 struct prestera_msg_iface *msg_if)
19780f07bd6bSYevhen Orlov {
19790f07bd6bSYevhen Orlov 	switch (iface->type) {
19800f07bd6bSYevhen Orlov 	case PRESTERA_IF_PORT_E:
19810f07bd6bSYevhen Orlov 	case PRESTERA_IF_VID_E:
19820f07bd6bSYevhen Orlov 		msg_if->port = __cpu_to_le32(iface->dev_port.port_num);
19830f07bd6bSYevhen Orlov 		msg_if->dev = __cpu_to_le32(iface->dev_port.hw_dev_num);
19840f07bd6bSYevhen Orlov 		break;
19850f07bd6bSYevhen Orlov 	case PRESTERA_IF_LAG_E:
19860f07bd6bSYevhen Orlov 		msg_if->lag_id = __cpu_to_le16(iface->lag_id);
19870f07bd6bSYevhen Orlov 		break;
19880f07bd6bSYevhen Orlov 	default:
19890f07bd6bSYevhen Orlov 		return -EOPNOTSUPP;
19900f07bd6bSYevhen Orlov 	}
19910f07bd6bSYevhen Orlov 
19920f07bd6bSYevhen Orlov 	msg_if->vr_id = __cpu_to_le16(iface->vr_id);
19930f07bd6bSYevhen Orlov 	msg_if->vid = __cpu_to_le16(iface->vlan_id);
19940f07bd6bSYevhen Orlov 	msg_if->type = iface->type;
19950f07bd6bSYevhen Orlov 	return 0;
19960f07bd6bSYevhen Orlov }
19970f07bd6bSYevhen Orlov 
prestera_hw_rif_create(struct prestera_switch * sw,struct prestera_iface * iif,u8 * mac,u16 * rif_id)19980f07bd6bSYevhen Orlov int prestera_hw_rif_create(struct prestera_switch *sw,
19990f07bd6bSYevhen Orlov 			   struct prestera_iface *iif, u8 *mac, u16 *rif_id)
20000f07bd6bSYevhen Orlov {
20010f07bd6bSYevhen Orlov 	struct prestera_msg_rif_resp resp;
200232d098bbSYevhen Orlov 	struct prestera_msg_rif_req req;
20030f07bd6bSYevhen Orlov 	int err;
20040f07bd6bSYevhen Orlov 
20050f07bd6bSYevhen Orlov 	memcpy(req.mac, mac, ETH_ALEN);
20060f07bd6bSYevhen Orlov 
20070f07bd6bSYevhen Orlov 	err = prestera_iface_to_msg(iif, &req.iif);
20080f07bd6bSYevhen Orlov 	if (err)
20090f07bd6bSYevhen Orlov 		return err;
20100f07bd6bSYevhen Orlov 
20110f07bd6bSYevhen Orlov 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_ROUTER_RIF_CREATE,
20120f07bd6bSYevhen Orlov 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
20130f07bd6bSYevhen Orlov 	if (err)
20140f07bd6bSYevhen Orlov 		return err;
20150f07bd6bSYevhen Orlov 
20160f07bd6bSYevhen Orlov 	*rif_id = __le16_to_cpu(resp.rif_id);
20170f07bd6bSYevhen Orlov 	return err;
20180f07bd6bSYevhen Orlov }
20190f07bd6bSYevhen Orlov 
prestera_hw_rif_delete(struct prestera_switch * sw,u16 rif_id,struct prestera_iface * iif)20200f07bd6bSYevhen Orlov int prestera_hw_rif_delete(struct prestera_switch *sw, u16 rif_id,
20210f07bd6bSYevhen Orlov 			   struct prestera_iface *iif)
20220f07bd6bSYevhen Orlov {
20230f07bd6bSYevhen Orlov 	struct prestera_msg_rif_req req = {
20240f07bd6bSYevhen Orlov 		.rif_id = __cpu_to_le16(rif_id),
20250f07bd6bSYevhen Orlov 	};
20260f07bd6bSYevhen Orlov 	int err;
20270f07bd6bSYevhen Orlov 
20280f07bd6bSYevhen Orlov 	err = prestera_iface_to_msg(iif, &req.iif);
20290f07bd6bSYevhen Orlov 	if (err)
20300f07bd6bSYevhen Orlov 		return err;
20310f07bd6bSYevhen Orlov 
20320f07bd6bSYevhen Orlov 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_RIF_DELETE, &req.cmd,
20330f07bd6bSYevhen Orlov 			    sizeof(req));
20340f07bd6bSYevhen Orlov }
20350f07bd6bSYevhen Orlov 
prestera_hw_vr_create(struct prestera_switch * sw,u16 * vr_id)20366d1b3eb5SYevhen Orlov int prestera_hw_vr_create(struct prestera_switch *sw, u16 *vr_id)
20376d1b3eb5SYevhen Orlov {
20386d1b3eb5SYevhen Orlov 	struct prestera_msg_vr_resp resp;
20396d1b3eb5SYevhen Orlov 	struct prestera_msg_vr_req req;
204032d098bbSYevhen Orlov 	int err;
20416d1b3eb5SYevhen Orlov 
20426d1b3eb5SYevhen Orlov 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_ROUTER_VR_CREATE,
20436d1b3eb5SYevhen Orlov 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
20446d1b3eb5SYevhen Orlov 	if (err)
20456d1b3eb5SYevhen Orlov 		return err;
20466d1b3eb5SYevhen Orlov 
20476d1b3eb5SYevhen Orlov 	*vr_id = __le16_to_cpu(resp.vr_id);
20486d1b3eb5SYevhen Orlov 	return err;
20496d1b3eb5SYevhen Orlov }
20506d1b3eb5SYevhen Orlov 
prestera_hw_vr_delete(struct prestera_switch * sw,u16 vr_id)20516d1b3eb5SYevhen Orlov int prestera_hw_vr_delete(struct prestera_switch *sw, u16 vr_id)
20526d1b3eb5SYevhen Orlov {
20536d1b3eb5SYevhen Orlov 	struct prestera_msg_vr_req req = {
20546d1b3eb5SYevhen Orlov 		.vr_id = __cpu_to_le16(vr_id),
20556d1b3eb5SYevhen Orlov 	};
20566d1b3eb5SYevhen Orlov 
20576d1b3eb5SYevhen Orlov 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_VR_DELETE, &req.cmd,
20586d1b3eb5SYevhen Orlov 			    sizeof(req));
20596d1b3eb5SYevhen Orlov }
20606d1b3eb5SYevhen Orlov 
prestera_hw_lpm_add(struct prestera_switch * sw,u16 vr_id,__be32 dst,u32 dst_len,u32 grp_id)206119787b93SYevhen Orlov int prestera_hw_lpm_add(struct prestera_switch *sw, u16 vr_id,
206219787b93SYevhen Orlov 			__be32 dst, u32 dst_len, u32 grp_id)
206319787b93SYevhen Orlov {
206419787b93SYevhen Orlov 	struct prestera_msg_lpm_req req = {
206519787b93SYevhen Orlov 		.dst_len = __cpu_to_le32(dst_len),
206619787b93SYevhen Orlov 		.vr_id = __cpu_to_le16(vr_id),
206719787b93SYevhen Orlov 		.grp_id = __cpu_to_le32(grp_id),
206819787b93SYevhen Orlov 		.dst.u.ipv4 = dst
206919787b93SYevhen Orlov 	};
207019787b93SYevhen Orlov 
207119787b93SYevhen Orlov 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_LPM_ADD, &req.cmd,
207219787b93SYevhen Orlov 			    sizeof(req));
207319787b93SYevhen Orlov }
207419787b93SYevhen Orlov 
prestera_hw_lpm_del(struct prestera_switch * sw,u16 vr_id,__be32 dst,u32 dst_len)207519787b93SYevhen Orlov int prestera_hw_lpm_del(struct prestera_switch *sw, u16 vr_id,
207619787b93SYevhen Orlov 			__be32 dst, u32 dst_len)
207719787b93SYevhen Orlov {
207819787b93SYevhen Orlov 	struct prestera_msg_lpm_req req = {
207919787b93SYevhen Orlov 		.dst_len = __cpu_to_le32(dst_len),
208019787b93SYevhen Orlov 		.vr_id = __cpu_to_le16(vr_id),
208119787b93SYevhen Orlov 		.dst.u.ipv4 = dst
208219787b93SYevhen Orlov 	};
208319787b93SYevhen Orlov 
208419787b93SYevhen Orlov 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_LPM_DELETE, &req.cmd,
208519787b93SYevhen Orlov 			    sizeof(req));
208619787b93SYevhen Orlov }
208719787b93SYevhen Orlov 
prestera_hw_nh_entries_set(struct prestera_switch * sw,int count,struct prestera_neigh_info * nhs,u32 grp_id)20880a23ae23SYevhen Orlov int prestera_hw_nh_entries_set(struct prestera_switch *sw, int count,
20890a23ae23SYevhen Orlov 			       struct prestera_neigh_info *nhs, u32 grp_id)
20900a23ae23SYevhen Orlov {
20910a23ae23SYevhen Orlov 	struct prestera_msg_nh_req req = { .size = __cpu_to_le32((u32)count),
20920a23ae23SYevhen Orlov 			.grp_id = __cpu_to_le32(grp_id) };
20930a23ae23SYevhen Orlov 	int i, err;
20940a23ae23SYevhen Orlov 
20950a23ae23SYevhen Orlov 	for (i = 0; i < count; i++) {
20960a23ae23SYevhen Orlov 		req.nh[i].is_active = nhs[i].connected;
20970a23ae23SYevhen Orlov 		memcpy(&req.nh[i].mac, nhs[i].ha, ETH_ALEN);
20980a23ae23SYevhen Orlov 		err = prestera_iface_to_msg(&nhs[i].iface, &req.nh[i].oif);
20990a23ae23SYevhen Orlov 		if (err)
21000a23ae23SYevhen Orlov 			return err;
21010a23ae23SYevhen Orlov 	}
21020a23ae23SYevhen Orlov 
21030a23ae23SYevhen Orlov 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_NH_GRP_SET, &req.cmd,
21040a23ae23SYevhen Orlov 			    sizeof(req));
21050a23ae23SYevhen Orlov }
21060a23ae23SYevhen Orlov 
prestera_hw_nhgrp_blk_get(struct prestera_switch * sw,u8 * hw_state,u32 buf_size)21070a23ae23SYevhen Orlov int prestera_hw_nhgrp_blk_get(struct prestera_switch *sw,
21080a23ae23SYevhen Orlov 			      u8 *hw_state, u32 buf_size /* Buffer in bytes */)
21090a23ae23SYevhen Orlov {
21100a23ae23SYevhen Orlov 	static struct prestera_msg_nh_chunk_resp resp;
21110a23ae23SYevhen Orlov 	struct prestera_msg_nh_chunk_req req;
21120a23ae23SYevhen Orlov 	u32 buf_offset;
21130a23ae23SYevhen Orlov 	int err;
21140a23ae23SYevhen Orlov 
21150a23ae23SYevhen Orlov 	memset(&hw_state[0], 0, buf_size);
21160a23ae23SYevhen Orlov 	buf_offset = 0;
21170a23ae23SYevhen Orlov 	while (1) {
21180a23ae23SYevhen Orlov 		if (buf_offset >= buf_size)
21190a23ae23SYevhen Orlov 			break;
21200a23ae23SYevhen Orlov 
21210a23ae23SYevhen Orlov 		memset(&req, 0, sizeof(req));
21220a23ae23SYevhen Orlov 		req.offset = __cpu_to_le32(buf_offset * 8); /* 8 bits in u8 */
21230a23ae23SYevhen Orlov 		err = prestera_cmd_ret(sw,
21240a23ae23SYevhen Orlov 				       PRESTERA_CMD_TYPE_ROUTER_NH_GRP_BLK_GET,
21250a23ae23SYevhen Orlov 				       &req.cmd, sizeof(req), &resp.ret,
21260a23ae23SYevhen Orlov 				       sizeof(resp));
21270a23ae23SYevhen Orlov 		if (err)
21280a23ae23SYevhen Orlov 			return err;
21290a23ae23SYevhen Orlov 
21300a23ae23SYevhen Orlov 		memcpy(&hw_state[buf_offset], &resp.hw_state[0],
21310a23ae23SYevhen Orlov 		       buf_offset + PRESTERA_MSG_CHUNK_SIZE > buf_size ?
21320a23ae23SYevhen Orlov 			buf_size - buf_offset : PRESTERA_MSG_CHUNK_SIZE);
21330a23ae23SYevhen Orlov 		buf_offset += PRESTERA_MSG_CHUNK_SIZE;
21340a23ae23SYevhen Orlov 	}
21350a23ae23SYevhen Orlov 
21360a23ae23SYevhen Orlov 	return 0;
21370a23ae23SYevhen Orlov }
21380a23ae23SYevhen Orlov 
prestera_hw_nh_group_create(struct prestera_switch * sw,u16 nh_count,u32 * grp_id)21390a23ae23SYevhen Orlov int prestera_hw_nh_group_create(struct prestera_switch *sw, u16 nh_count,
21400a23ae23SYevhen Orlov 				u32 *grp_id)
21410a23ae23SYevhen Orlov {
21420a23ae23SYevhen Orlov 	struct prestera_msg_nh_grp_req req = { .size = __cpu_to_le32((u32)nh_count) };
21430a23ae23SYevhen Orlov 	struct prestera_msg_nh_grp_resp resp;
21440a23ae23SYevhen Orlov 	int err;
21450a23ae23SYevhen Orlov 
21460a23ae23SYevhen Orlov 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_ROUTER_NH_GRP_ADD,
21470a23ae23SYevhen Orlov 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
21480a23ae23SYevhen Orlov 	if (err)
21490a23ae23SYevhen Orlov 		return err;
21500a23ae23SYevhen Orlov 
21510a23ae23SYevhen Orlov 	*grp_id = __le32_to_cpu(resp.grp_id);
21520a23ae23SYevhen Orlov 	return err;
21530a23ae23SYevhen Orlov }
21540a23ae23SYevhen Orlov 
prestera_hw_nh_group_delete(struct prestera_switch * sw,u16 nh_count,u32 grp_id)21550a23ae23SYevhen Orlov int prestera_hw_nh_group_delete(struct prestera_switch *sw, u16 nh_count,
21560a23ae23SYevhen Orlov 				u32 grp_id)
21570a23ae23SYevhen Orlov {
21580a23ae23SYevhen Orlov 	struct prestera_msg_nh_grp_req req = {
21590a23ae23SYevhen Orlov 	    .grp_id = __cpu_to_le32(grp_id),
21600a23ae23SYevhen Orlov 	    .size = __cpu_to_le32(nh_count)
21610a23ae23SYevhen Orlov 	};
21620a23ae23SYevhen Orlov 
21630a23ae23SYevhen Orlov 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_NH_GRP_DELETE,
21640a23ae23SYevhen Orlov 			    &req.cmd, sizeof(req));
21650a23ae23SYevhen Orlov }
21660a23ae23SYevhen Orlov 
prestera_hw_rxtx_init(struct prestera_switch * sw,struct prestera_rxtx_params * params)2167501ef306SVadym Kochan int prestera_hw_rxtx_init(struct prestera_switch *sw,
2168501ef306SVadym Kochan 			  struct prestera_rxtx_params *params)
2169501ef306SVadym Kochan {
2170501ef306SVadym Kochan 	struct prestera_msg_rxtx_resp resp;
2171501ef306SVadym Kochan 	struct prestera_msg_rxtx_req req;
2172501ef306SVadym Kochan 	int err;
2173501ef306SVadym Kochan 
2174501ef306SVadym Kochan 	req.use_sdma = params->use_sdma;
2175501ef306SVadym Kochan 
2176501ef306SVadym Kochan 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_RXTX_INIT,
2177501ef306SVadym Kochan 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
2178501ef306SVadym Kochan 	if (err)
2179501ef306SVadym Kochan 		return err;
2180501ef306SVadym Kochan 
2181bb5dbf2cSVolodymyr Mytnyk 	params->map_addr = __le32_to_cpu(resp.map_addr);
2182501ef306SVadym Kochan 
2183501ef306SVadym Kochan 	return 0;
2184501ef306SVadym Kochan }
2185501ef306SVadym Kochan 
prestera_hw_lag_member_add(struct prestera_port * port,u16 lag_id)2186255213caSSerhiy Boiko int prestera_hw_lag_member_add(struct prestera_port *port, u16 lag_id)
2187255213caSSerhiy Boiko {
2188255213caSSerhiy Boiko 	struct prestera_msg_lag_req req = {
2189bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
2190bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
2191bb5dbf2cSVolodymyr Mytnyk 		.lag_id = __cpu_to_le16(lag_id),
2192255213caSSerhiy Boiko 	};
2193255213caSSerhiy Boiko 
2194255213caSSerhiy Boiko 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_LAG_MEMBER_ADD,
2195255213caSSerhiy Boiko 			    &req.cmd, sizeof(req));
2196255213caSSerhiy Boiko }
2197255213caSSerhiy Boiko 
prestera_hw_lag_member_del(struct prestera_port * port,u16 lag_id)2198255213caSSerhiy Boiko int prestera_hw_lag_member_del(struct prestera_port *port, u16 lag_id)
2199255213caSSerhiy Boiko {
2200255213caSSerhiy Boiko 	struct prestera_msg_lag_req req = {
2201bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
2202bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
2203bb5dbf2cSVolodymyr Mytnyk 		.lag_id = __cpu_to_le16(lag_id),
2204255213caSSerhiy Boiko 	};
2205255213caSSerhiy Boiko 
2206255213caSSerhiy Boiko 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_LAG_MEMBER_DELETE,
2207255213caSSerhiy Boiko 			    &req.cmd, sizeof(req));
2208255213caSSerhiy Boiko }
2209255213caSSerhiy Boiko 
prestera_hw_lag_member_enable(struct prestera_port * port,u16 lag_id,bool enable)2210255213caSSerhiy Boiko int prestera_hw_lag_member_enable(struct prestera_port *port, u16 lag_id,
2211255213caSSerhiy Boiko 				  bool enable)
2212255213caSSerhiy Boiko {
2213255213caSSerhiy Boiko 	struct prestera_msg_lag_req req = {
2214bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
2215bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
2216bb5dbf2cSVolodymyr Mytnyk 		.lag_id = __cpu_to_le16(lag_id),
2217255213caSSerhiy Boiko 	};
2218255213caSSerhiy Boiko 	u32 cmd;
2219255213caSSerhiy Boiko 
2220255213caSSerhiy Boiko 	cmd = enable ? PRESTERA_CMD_TYPE_LAG_MEMBER_ENABLE :
2221255213caSSerhiy Boiko 			PRESTERA_CMD_TYPE_LAG_MEMBER_DISABLE;
2222255213caSSerhiy Boiko 
2223255213caSSerhiy Boiko 	return prestera_cmd(port->sw, cmd, &req.cmd, sizeof(req));
2224255213caSSerhiy Boiko }
2225255213caSSerhiy Boiko 
2226a80cf955SOleksandr Mazur int
prestera_hw_cpu_code_counters_get(struct prestera_switch * sw,u8 code,enum prestera_hw_cpu_code_cnt_t counter_type,u64 * packet_count)2227a80cf955SOleksandr Mazur prestera_hw_cpu_code_counters_get(struct prestera_switch *sw, u8 code,
2228a80cf955SOleksandr Mazur 				  enum prestera_hw_cpu_code_cnt_t counter_type,
2229a80cf955SOleksandr Mazur 				  u64 *packet_count)
2230a80cf955SOleksandr Mazur {
2231a80cf955SOleksandr Mazur 	struct prestera_msg_cpu_code_counter_req req = {
2232a80cf955SOleksandr Mazur 		.counter_type = counter_type,
2233a80cf955SOleksandr Mazur 		.code = code,
2234a80cf955SOleksandr Mazur 	};
2235a80cf955SOleksandr Mazur 	struct mvsw_msg_cpu_code_counter_ret resp;
2236a80cf955SOleksandr Mazur 	int err;
2237a80cf955SOleksandr Mazur 
2238a80cf955SOleksandr Mazur 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_CPU_CODE_COUNTERS_GET,
2239a80cf955SOleksandr Mazur 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
2240a80cf955SOleksandr Mazur 	if (err)
2241a80cf955SOleksandr Mazur 		return err;
2242a80cf955SOleksandr Mazur 
2243bb5dbf2cSVolodymyr Mytnyk 	*packet_count = __le64_to_cpu(resp.packet_count);
2244a80cf955SOleksandr Mazur 
2245a80cf955SOleksandr Mazur 	return 0;
2246a80cf955SOleksandr Mazur }
2247a80cf955SOleksandr Mazur 
prestera_hw_event_handler_register(struct prestera_switch * sw,enum prestera_event_type type,prestera_event_cb_t fn,void * arg)2248501ef306SVadym Kochan int prestera_hw_event_handler_register(struct prestera_switch *sw,
2249501ef306SVadym Kochan 				       enum prestera_event_type type,
2250501ef306SVadym Kochan 				       prestera_event_cb_t fn,
2251501ef306SVadym Kochan 				       void *arg)
2252501ef306SVadym Kochan {
2253501ef306SVadym Kochan 	struct prestera_fw_event_handler *eh;
2254501ef306SVadym Kochan 
2255501ef306SVadym Kochan 	eh = __find_event_handler(sw, type);
2256501ef306SVadym Kochan 	if (eh)
2257501ef306SVadym Kochan 		return -EEXIST;
2258501ef306SVadym Kochan 
2259501ef306SVadym Kochan 	eh = kmalloc(sizeof(*eh), GFP_KERNEL);
2260501ef306SVadym Kochan 	if (!eh)
2261501ef306SVadym Kochan 		return -ENOMEM;
2262501ef306SVadym Kochan 
2263501ef306SVadym Kochan 	eh->type = type;
2264501ef306SVadym Kochan 	eh->func = fn;
2265501ef306SVadym Kochan 	eh->arg = arg;
2266501ef306SVadym Kochan 
2267501ef306SVadym Kochan 	INIT_LIST_HEAD(&eh->list);
2268501ef306SVadym Kochan 
2269501ef306SVadym Kochan 	list_add_rcu(&eh->list, &sw->event_handlers);
2270501ef306SVadym Kochan 
2271501ef306SVadym Kochan 	return 0;
2272501ef306SVadym Kochan }
2273501ef306SVadym Kochan 
prestera_hw_event_handler_unregister(struct prestera_switch * sw,enum prestera_event_type type,prestera_event_cb_t fn)2274501ef306SVadym Kochan void prestera_hw_event_handler_unregister(struct prestera_switch *sw,
2275501ef306SVadym Kochan 					  enum prestera_event_type type,
2276501ef306SVadym Kochan 					  prestera_event_cb_t fn)
2277501ef306SVadym Kochan {
2278501ef306SVadym Kochan 	struct prestera_fw_event_handler *eh;
2279501ef306SVadym Kochan 
2280501ef306SVadym Kochan 	eh = __find_event_handler(sw, type);
2281501ef306SVadym Kochan 	if (!eh)
2282501ef306SVadym Kochan 		return;
2283501ef306SVadym Kochan 
2284501ef306SVadym Kochan 	list_del_rcu(&eh->list);
2285501ef306SVadym Kochan 	kfree_rcu(eh, rcu);
2286501ef306SVadym Kochan }
22876e36c7bcSVolodymyr Mytnyk 
prestera_hw_counter_trigger(struct prestera_switch * sw,u32 block_id)22886e36c7bcSVolodymyr Mytnyk int prestera_hw_counter_trigger(struct prestera_switch *sw, u32 block_id)
22896e36c7bcSVolodymyr Mytnyk {
22906e36c7bcSVolodymyr Mytnyk 	struct prestera_msg_counter_req req = {
22916e36c7bcSVolodymyr Mytnyk 		.block_id = __cpu_to_le32(block_id)
22926e36c7bcSVolodymyr Mytnyk 	};
22936e36c7bcSVolodymyr Mytnyk 
22946e36c7bcSVolodymyr Mytnyk 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_COUNTER_TRIGGER,
22956e36c7bcSVolodymyr Mytnyk 			    &req.cmd, sizeof(req));
22966e36c7bcSVolodymyr Mytnyk }
22976e36c7bcSVolodymyr Mytnyk 
prestera_hw_counter_abort(struct prestera_switch * sw)22986e36c7bcSVolodymyr Mytnyk int prestera_hw_counter_abort(struct prestera_switch *sw)
22996e36c7bcSVolodymyr Mytnyk {
23006e36c7bcSVolodymyr Mytnyk 	struct prestera_msg_counter_req req;
23016e36c7bcSVolodymyr Mytnyk 
23026e36c7bcSVolodymyr Mytnyk 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_COUNTER_ABORT,
23036e36c7bcSVolodymyr Mytnyk 			    &req.cmd, sizeof(req));
23046e36c7bcSVolodymyr Mytnyk }
23056e36c7bcSVolodymyr Mytnyk 
prestera_hw_counters_get(struct prestera_switch * sw,u32 idx,u32 * len,bool * done,struct prestera_counter_stats * stats)23066e36c7bcSVolodymyr Mytnyk int prestera_hw_counters_get(struct prestera_switch *sw, u32 idx,
23076e36c7bcSVolodymyr Mytnyk 			     u32 *len, bool *done,
23086e36c7bcSVolodymyr Mytnyk 			     struct prestera_counter_stats *stats)
23096e36c7bcSVolodymyr Mytnyk {
23106e36c7bcSVolodymyr Mytnyk 	struct prestera_msg_counter_resp *resp;
23116e36c7bcSVolodymyr Mytnyk 	struct prestera_msg_counter_req req = {
23126e36c7bcSVolodymyr Mytnyk 		.block_id = __cpu_to_le32(idx),
23136e36c7bcSVolodymyr Mytnyk 		.num_counters = __cpu_to_le32(*len),
23146e36c7bcSVolodymyr Mytnyk 	};
231501081be1SJosé Expósito 	size_t size = struct_size(resp, stats, *len);
23166e36c7bcSVolodymyr Mytnyk 	int err, i;
23176e36c7bcSVolodymyr Mytnyk 
23186e36c7bcSVolodymyr Mytnyk 	resp = kmalloc(size, GFP_KERNEL);
23196e36c7bcSVolodymyr Mytnyk 	if (!resp)
23206e36c7bcSVolodymyr Mytnyk 		return -ENOMEM;
23216e36c7bcSVolodymyr Mytnyk 
23226e36c7bcSVolodymyr Mytnyk 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_COUNTER_GET,
23236e36c7bcSVolodymyr Mytnyk 			       &req.cmd, sizeof(req), &resp->ret, size);
23246e36c7bcSVolodymyr Mytnyk 	if (err)
23256e36c7bcSVolodymyr Mytnyk 		goto free_buff;
23266e36c7bcSVolodymyr Mytnyk 
23276e36c7bcSVolodymyr Mytnyk 	for (i = 0; i < __le32_to_cpu(resp->num_counters); i++) {
23286e36c7bcSVolodymyr Mytnyk 		stats[i].packets += __le64_to_cpu(resp->stats[i].packets);
23296e36c7bcSVolodymyr Mytnyk 		stats[i].bytes += __le64_to_cpu(resp->stats[i].bytes);
23306e36c7bcSVolodymyr Mytnyk 	}
23316e36c7bcSVolodymyr Mytnyk 
23326e36c7bcSVolodymyr Mytnyk 	*len = __le32_to_cpu(resp->num_counters);
23336e36c7bcSVolodymyr Mytnyk 	*done = __le32_to_cpu(resp->done);
23346e36c7bcSVolodymyr Mytnyk 
23356e36c7bcSVolodymyr Mytnyk free_buff:
23366e36c7bcSVolodymyr Mytnyk 	kfree(resp);
23376e36c7bcSVolodymyr Mytnyk 	return err;
23386e36c7bcSVolodymyr Mytnyk }
23396e36c7bcSVolodymyr Mytnyk 
prestera_hw_counter_block_get(struct prestera_switch * sw,u32 client,u32 * block_id,u32 * offset,u32 * num_counters)23406e36c7bcSVolodymyr Mytnyk int prestera_hw_counter_block_get(struct prestera_switch *sw,
23416e36c7bcSVolodymyr Mytnyk 				  u32 client, u32 *block_id, u32 *offset,
23426e36c7bcSVolodymyr Mytnyk 				  u32 *num_counters)
23436e36c7bcSVolodymyr Mytnyk {
23446e36c7bcSVolodymyr Mytnyk 	struct prestera_msg_counter_resp resp;
23456e36c7bcSVolodymyr Mytnyk 	struct prestera_msg_counter_req req = {
23466e36c7bcSVolodymyr Mytnyk 		.client = __cpu_to_le32(client)
23476e36c7bcSVolodymyr Mytnyk 	};
23486e36c7bcSVolodymyr Mytnyk 	int err;
23496e36c7bcSVolodymyr Mytnyk 
23506e36c7bcSVolodymyr Mytnyk 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_COUNTER_BLOCK_GET,
23516e36c7bcSVolodymyr Mytnyk 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
23526e36c7bcSVolodymyr Mytnyk 	if (err)
23536e36c7bcSVolodymyr Mytnyk 		return err;
23546e36c7bcSVolodymyr Mytnyk 
23556e36c7bcSVolodymyr Mytnyk 	*block_id = __le32_to_cpu(resp.block_id);
23566e36c7bcSVolodymyr Mytnyk 	*offset = __le32_to_cpu(resp.offset);
23576e36c7bcSVolodymyr Mytnyk 	*num_counters = __le32_to_cpu(resp.num_counters);
23586e36c7bcSVolodymyr Mytnyk 
23596e36c7bcSVolodymyr Mytnyk 	return 0;
23606e36c7bcSVolodymyr Mytnyk }
23616e36c7bcSVolodymyr Mytnyk 
prestera_hw_counter_block_release(struct prestera_switch * sw,u32 block_id)23626e36c7bcSVolodymyr Mytnyk int prestera_hw_counter_block_release(struct prestera_switch *sw,
23636e36c7bcSVolodymyr Mytnyk 				      u32 block_id)
23646e36c7bcSVolodymyr Mytnyk {
23656e36c7bcSVolodymyr Mytnyk 	struct prestera_msg_counter_req req = {
23666e36c7bcSVolodymyr Mytnyk 		.block_id = __cpu_to_le32(block_id)
23676e36c7bcSVolodymyr Mytnyk 	};
23686e36c7bcSVolodymyr Mytnyk 
23696e36c7bcSVolodymyr Mytnyk 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_COUNTER_BLOCK_RELEASE,
23706e36c7bcSVolodymyr Mytnyk 			    &req.cmd, sizeof(req));
23716e36c7bcSVolodymyr Mytnyk }
23726e36c7bcSVolodymyr Mytnyk 
prestera_hw_counter_clear(struct prestera_switch * sw,u32 block_id,u32 counter_id)23736e36c7bcSVolodymyr Mytnyk int prestera_hw_counter_clear(struct prestera_switch *sw, u32 block_id,
23746e36c7bcSVolodymyr Mytnyk 			      u32 counter_id)
23756e36c7bcSVolodymyr Mytnyk {
23766e36c7bcSVolodymyr Mytnyk 	struct prestera_msg_counter_req req = {
23776e36c7bcSVolodymyr Mytnyk 		.block_id = __cpu_to_le32(block_id),
23786e36c7bcSVolodymyr Mytnyk 		.num_counters = __cpu_to_le32(counter_id)
23796e36c7bcSVolodymyr Mytnyk 	};
23806e36c7bcSVolodymyr Mytnyk 
23816e36c7bcSVolodymyr Mytnyk 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_COUNTER_CLEAR,
23826e36c7bcSVolodymyr Mytnyk 			    &req.cmd, sizeof(req));
23836e36c7bcSVolodymyr Mytnyk }
2384dde2daa0SVolodymyr Mytnyk 
prestera_hw_policer_create(struct prestera_switch * sw,u8 type,u32 * policer_id)2385dde2daa0SVolodymyr Mytnyk int prestera_hw_policer_create(struct prestera_switch *sw, u8 type,
2386dde2daa0SVolodymyr Mytnyk 			       u32 *policer_id)
2387dde2daa0SVolodymyr Mytnyk {
2388dde2daa0SVolodymyr Mytnyk 	struct prestera_msg_policer_resp resp;
2389dde2daa0SVolodymyr Mytnyk 	struct prestera_msg_policer_req req = {
2390dde2daa0SVolodymyr Mytnyk 		.type = type
2391dde2daa0SVolodymyr Mytnyk 	};
2392dde2daa0SVolodymyr Mytnyk 	int err;
2393dde2daa0SVolodymyr Mytnyk 
2394dde2daa0SVolodymyr Mytnyk 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_POLICER_CREATE,
2395dde2daa0SVolodymyr Mytnyk 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
2396dde2daa0SVolodymyr Mytnyk 	if (err)
2397dde2daa0SVolodymyr Mytnyk 		return err;
2398dde2daa0SVolodymyr Mytnyk 
2399dde2daa0SVolodymyr Mytnyk 	*policer_id = __le32_to_cpu(resp.id);
2400dde2daa0SVolodymyr Mytnyk 	return 0;
2401dde2daa0SVolodymyr Mytnyk }
2402dde2daa0SVolodymyr Mytnyk 
prestera_hw_policer_release(struct prestera_switch * sw,u32 policer_id)2403dde2daa0SVolodymyr Mytnyk int prestera_hw_policer_release(struct prestera_switch *sw,
2404dde2daa0SVolodymyr Mytnyk 				u32 policer_id)
2405dde2daa0SVolodymyr Mytnyk {
2406dde2daa0SVolodymyr Mytnyk 	struct prestera_msg_policer_req req = {
2407dde2daa0SVolodymyr Mytnyk 		.id = __cpu_to_le32(policer_id)
2408dde2daa0SVolodymyr Mytnyk 	};
2409dde2daa0SVolodymyr Mytnyk 
2410dde2daa0SVolodymyr Mytnyk 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_POLICER_RELEASE,
2411dde2daa0SVolodymyr Mytnyk 			    &req.cmd, sizeof(req));
2412dde2daa0SVolodymyr Mytnyk }
2413dde2daa0SVolodymyr Mytnyk 
prestera_hw_policer_sr_tcm_set(struct prestera_switch * sw,u32 policer_id,u64 cir,u32 cbs)2414dde2daa0SVolodymyr Mytnyk int prestera_hw_policer_sr_tcm_set(struct prestera_switch *sw,
2415dde2daa0SVolodymyr Mytnyk 				   u32 policer_id, u64 cir, u32 cbs)
2416dde2daa0SVolodymyr Mytnyk {
2417dde2daa0SVolodymyr Mytnyk 	struct prestera_msg_policer_req req = {
2418dde2daa0SVolodymyr Mytnyk 		.mode = PRESTERA_POLICER_MODE_SR_TCM,
2419dde2daa0SVolodymyr Mytnyk 		.id = __cpu_to_le32(policer_id),
2420dde2daa0SVolodymyr Mytnyk 		.sr_tcm = {
2421dde2daa0SVolodymyr Mytnyk 			.cir = __cpu_to_le64(cir),
2422dde2daa0SVolodymyr Mytnyk 			.cbs = __cpu_to_le32(cbs)
2423dde2daa0SVolodymyr Mytnyk 		}
2424dde2daa0SVolodymyr Mytnyk 	};
2425dde2daa0SVolodymyr Mytnyk 
2426dde2daa0SVolodymyr Mytnyk 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_POLICER_SET,
2427dde2daa0SVolodymyr Mytnyk 			    &req.cmd, sizeof(req));
2428dde2daa0SVolodymyr Mytnyk }
2429fec7c9c7SOleksandr Mazur 
prestera_hw_flood_domain_create(struct prestera_flood_domain * domain)2430fec7c9c7SOleksandr Mazur int prestera_hw_flood_domain_create(struct prestera_flood_domain *domain)
2431fec7c9c7SOleksandr Mazur {
2432fec7c9c7SOleksandr Mazur 	struct prestera_msg_flood_domain_create_resp resp;
2433fec7c9c7SOleksandr Mazur 	struct prestera_msg_flood_domain_create_req req;
2434fec7c9c7SOleksandr Mazur 	int err;
2435fec7c9c7SOleksandr Mazur 
2436fec7c9c7SOleksandr Mazur 	err = prestera_cmd_ret(domain->sw,
2437fec7c9c7SOleksandr Mazur 			       PRESTERA_CMD_TYPE_FLOOD_DOMAIN_CREATE, &req.cmd,
2438fec7c9c7SOleksandr Mazur 			       sizeof(req), &resp.ret, sizeof(resp));
2439fec7c9c7SOleksandr Mazur 	if (err)
2440fec7c9c7SOleksandr Mazur 		return err;
2441fec7c9c7SOleksandr Mazur 
2442fec7c9c7SOleksandr Mazur 	domain->idx = __le32_to_cpu(resp.flood_domain_idx);
2443fec7c9c7SOleksandr Mazur 
2444fec7c9c7SOleksandr Mazur 	return 0;
2445fec7c9c7SOleksandr Mazur }
2446fec7c9c7SOleksandr Mazur 
prestera_hw_flood_domain_destroy(struct prestera_flood_domain * domain)2447fec7c9c7SOleksandr Mazur int prestera_hw_flood_domain_destroy(struct prestera_flood_domain *domain)
2448fec7c9c7SOleksandr Mazur {
2449fec7c9c7SOleksandr Mazur 	struct prestera_msg_flood_domain_destroy_req req = {
2450fec7c9c7SOleksandr Mazur 		.flood_domain_idx = __cpu_to_le32(domain->idx),
2451fec7c9c7SOleksandr Mazur 	};
2452fec7c9c7SOleksandr Mazur 
2453fec7c9c7SOleksandr Mazur 	return prestera_cmd(domain->sw, PRESTERA_CMD_TYPE_FLOOD_DOMAIN_DESTROY,
2454fec7c9c7SOleksandr Mazur 			   &req.cmd, sizeof(req));
2455fec7c9c7SOleksandr Mazur }
2456fec7c9c7SOleksandr Mazur 
prestera_hw_flood_domain_ports_set(struct prestera_flood_domain * domain)2457fec7c9c7SOleksandr Mazur int prestera_hw_flood_domain_ports_set(struct prestera_flood_domain *domain)
2458fec7c9c7SOleksandr Mazur {
2459fec7c9c7SOleksandr Mazur 	struct prestera_flood_domain_port *flood_domain_port;
2460fec7c9c7SOleksandr Mazur 	struct prestera_msg_flood_domain_ports_set_req *req;
2461fec7c9c7SOleksandr Mazur 	struct prestera_switch *sw = domain->sw;
2462fec7c9c7SOleksandr Mazur 	struct prestera_port *port;
2463fec7c9c7SOleksandr Mazur 	u32 ports_num = 0;
2464*86348d21SErick Archer 	size_t buf_size;
2465fec7c9c7SOleksandr Mazur 	u16 lag_id;
2466fec7c9c7SOleksandr Mazur 	int err;
2467*86348d21SErick Archer 	int i = 0;
2468fec7c9c7SOleksandr Mazur 
2469fec7c9c7SOleksandr Mazur 	list_for_each_entry(flood_domain_port, &domain->flood_domain_port_list,
2470fec7c9c7SOleksandr Mazur 			    flood_domain_port_node)
2471fec7c9c7SOleksandr Mazur 		ports_num++;
2472fec7c9c7SOleksandr Mazur 
2473fec7c9c7SOleksandr Mazur 	if (!ports_num)
2474fec7c9c7SOleksandr Mazur 		return -EINVAL;
2475fec7c9c7SOleksandr Mazur 
2476*86348d21SErick Archer 	buf_size = struct_size(req, ports, ports_num);
2477*86348d21SErick Archer 	req = kmalloc(buf_size, GFP_KERNEL);
2478*86348d21SErick Archer 	if (!req)
2479fec7c9c7SOleksandr Mazur 		return -ENOMEM;
2480fec7c9c7SOleksandr Mazur 
2481fec7c9c7SOleksandr Mazur 	req->flood_domain_idx = __cpu_to_le32(domain->idx);
2482fec7c9c7SOleksandr Mazur 	req->ports_num = __cpu_to_le32(ports_num);
2483fec7c9c7SOleksandr Mazur 
2484fec7c9c7SOleksandr Mazur 	list_for_each_entry(flood_domain_port, &domain->flood_domain_port_list,
2485fec7c9c7SOleksandr Mazur 			    flood_domain_port_node) {
2486fec7c9c7SOleksandr Mazur 		if (netif_is_lag_master(flood_domain_port->dev)) {
2487fec7c9c7SOleksandr Mazur 			if (prestera_lag_id(sw, flood_domain_port->dev,
2488fec7c9c7SOleksandr Mazur 					    &lag_id)) {
2489*86348d21SErick Archer 				kfree(req);
2490fec7c9c7SOleksandr Mazur 				return -EINVAL;
2491fec7c9c7SOleksandr Mazur 			}
2492fec7c9c7SOleksandr Mazur 
2493*86348d21SErick Archer 			req->ports[i].port_type =
2494fec7c9c7SOleksandr Mazur 				__cpu_to_le16(PRESTERA_HW_FLOOD_DOMAIN_PORT_TYPE_LAG);
2495*86348d21SErick Archer 			req->ports[i].lag_id = __cpu_to_le16(lag_id);
2496fec7c9c7SOleksandr Mazur 		} else {
2497fec7c9c7SOleksandr Mazur 			port = prestera_port_dev_lower_find(flood_domain_port->dev);
2498fec7c9c7SOleksandr Mazur 
2499*86348d21SErick Archer 			req->ports[i].port_type =
2500fec7c9c7SOleksandr Mazur 				__cpu_to_le16(PRESTERA_HW_FDB_ENTRY_TYPE_REG_PORT);
2501*86348d21SErick Archer 			req->ports[i].dev_num = __cpu_to_le32(port->dev_id);
2502*86348d21SErick Archer 			req->ports[i].port_num = __cpu_to_le32(port->hw_id);
2503fec7c9c7SOleksandr Mazur 		}
2504fec7c9c7SOleksandr Mazur 
2505*86348d21SErick Archer 		req->ports[i].vid = __cpu_to_le16(flood_domain_port->vid);
2506*86348d21SErick Archer 		i++;
2507fec7c9c7SOleksandr Mazur 	}
2508fec7c9c7SOleksandr Mazur 
2509fec7c9c7SOleksandr Mazur 	err = prestera_cmd(sw, PRESTERA_CMD_TYPE_FLOOD_DOMAIN_PORTS_SET,
2510fec7c9c7SOleksandr Mazur 			   &req->cmd, buf_size);
2511fec7c9c7SOleksandr Mazur 
2512*86348d21SErick Archer 	kfree(req);
2513fec7c9c7SOleksandr Mazur 
2514fec7c9c7SOleksandr Mazur 	return err;
2515fec7c9c7SOleksandr Mazur }
2516fec7c9c7SOleksandr Mazur 
prestera_hw_flood_domain_ports_reset(struct prestera_flood_domain * domain)2517fec7c9c7SOleksandr Mazur int prestera_hw_flood_domain_ports_reset(struct prestera_flood_domain *domain)
2518fec7c9c7SOleksandr Mazur {
2519fec7c9c7SOleksandr Mazur 	struct prestera_msg_flood_domain_ports_reset_req req = {
2520fec7c9c7SOleksandr Mazur 		.flood_domain_idx = __cpu_to_le32(domain->idx),
2521fec7c9c7SOleksandr Mazur 	};
2522fec7c9c7SOleksandr Mazur 
2523fec7c9c7SOleksandr Mazur 	return prestera_cmd(domain->sw,
2524fec7c9c7SOleksandr Mazur 			   PRESTERA_CMD_TYPE_FLOOD_DOMAIN_PORTS_RESET, &req.cmd,
2525fec7c9c7SOleksandr Mazur 			   sizeof(req));
2526fec7c9c7SOleksandr Mazur }
2527fec7c9c7SOleksandr Mazur 
prestera_hw_mdb_create(struct prestera_mdb_entry * mdb)2528fec7c9c7SOleksandr Mazur int prestera_hw_mdb_create(struct prestera_mdb_entry *mdb)
2529fec7c9c7SOleksandr Mazur {
2530fec7c9c7SOleksandr Mazur 	struct prestera_msg_mdb_create_req req = {
2531fec7c9c7SOleksandr Mazur 		.flood_domain_idx = __cpu_to_le32(mdb->flood_domain->idx),
2532fec7c9c7SOleksandr Mazur 		.vid = __cpu_to_le16(mdb->vid),
2533fec7c9c7SOleksandr Mazur 	};
2534fec7c9c7SOleksandr Mazur 
2535fec7c9c7SOleksandr Mazur 	memcpy(req.mac, mdb->addr, ETH_ALEN);
2536fec7c9c7SOleksandr Mazur 
2537fec7c9c7SOleksandr Mazur 	return prestera_cmd(mdb->sw, PRESTERA_CMD_TYPE_MDB_CREATE, &req.cmd,
2538fec7c9c7SOleksandr Mazur 			    sizeof(req));
2539fec7c9c7SOleksandr Mazur }
2540fec7c9c7SOleksandr Mazur 
prestera_hw_mdb_destroy(struct prestera_mdb_entry * mdb)2541fec7c9c7SOleksandr Mazur int prestera_hw_mdb_destroy(struct prestera_mdb_entry *mdb)
2542fec7c9c7SOleksandr Mazur {
2543fec7c9c7SOleksandr Mazur 	struct prestera_msg_mdb_destroy_req req = {
2544fec7c9c7SOleksandr Mazur 		.flood_domain_idx = __cpu_to_le32(mdb->flood_domain->idx),
2545fec7c9c7SOleksandr Mazur 		.vid = __cpu_to_le16(mdb->vid),
2546fec7c9c7SOleksandr Mazur 	};
2547fec7c9c7SOleksandr Mazur 
2548fec7c9c7SOleksandr Mazur 	memcpy(req.mac, mdb->addr, ETH_ALEN);
2549fec7c9c7SOleksandr Mazur 
2550fec7c9c7SOleksandr Mazur 	return prestera_cmd(mdb->sw, PRESTERA_CMD_TYPE_MDB_DESTROY, &req.cmd,
2551fec7c9c7SOleksandr Mazur 			    sizeof(req));
2552fec7c9c7SOleksandr Mazur }
2553