xref: /openbmc/linux/drivers/net/ethernet/marvell/prestera/prestera_hw.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
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"
13*0a23ae23SYevhen 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 
19*0a23ae23SYevhen Orlov #define PRESTERA_MSG_CHUNK_SIZE 1024
20*0a23ae23SYevhen 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,
63*0a23ae23SYevhen Orlov 	PRESTERA_CMD_TYPE_ROUTER_NH_GRP_SET = 0x622,
64*0a23ae23SYevhen Orlov 	PRESTERA_CMD_TYPE_ROUTER_NH_GRP_BLK_GET = 0x645,
65*0a23ae23SYevhen Orlov 	PRESTERA_CMD_TYPE_ROUTER_NH_GRP_ADD = 0x623,
66*0a23ae23SYevhen 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_add_req {
42347327e19SVolodymyr Mytnyk 	struct prestera_msg_cmd cmd;
42447327e19SVolodymyr Mytnyk 	__le32 key[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX];
42547327e19SVolodymyr Mytnyk 	__le32 keymask[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX];
42647327e19SVolodymyr Mytnyk 	__le32 vtcam_id;
42747327e19SVolodymyr Mytnyk 	__le32 prio;
42847327e19SVolodymyr Mytnyk 	__le32 n_act;
42947327e19SVolodymyr Mytnyk };
43047327e19SVolodymyr Mytnyk 
43147327e19SVolodymyr Mytnyk struct prestera_msg_vtcam_rule_del_req {
43247327e19SVolodymyr Mytnyk 	struct prestera_msg_cmd cmd;
43347327e19SVolodymyr Mytnyk 	__le32 vtcam_id;
43447327e19SVolodymyr Mytnyk 	__le32 id;
43547327e19SVolodymyr Mytnyk };
43647327e19SVolodymyr Mytnyk 
43747327e19SVolodymyr Mytnyk struct prestera_msg_vtcam_bind_req {
43847327e19SVolodymyr Mytnyk 	struct prestera_msg_cmd cmd;
4398b474a9fSSerhiy Boiko 	union {
4408b474a9fSSerhiy Boiko 		struct {
44147327e19SVolodymyr Mytnyk 			__le32 hw_id;
44247327e19SVolodymyr Mytnyk 			__le32 dev_id;
44347327e19SVolodymyr Mytnyk 		} port;
44447327e19SVolodymyr Mytnyk 		__le32 index;
44547327e19SVolodymyr Mytnyk 	};
44647327e19SVolodymyr Mytnyk 	__le32 vtcam_id;
44747327e19SVolodymyr Mytnyk 	__le16 pcl_id;
44847327e19SVolodymyr Mytnyk 	__le16 type;
4498b474a9fSSerhiy Boiko };
4508b474a9fSSerhiy Boiko 
45147327e19SVolodymyr Mytnyk struct prestera_msg_vtcam_resp {
45247327e19SVolodymyr Mytnyk 	struct prestera_msg_ret ret;
45347327e19SVolodymyr Mytnyk 	__le32 vtcam_id;
45447327e19SVolodymyr Mytnyk 	__le32 rule_id;
45547327e19SVolodymyr Mytnyk };
45647327e19SVolodymyr Mytnyk 
45747327e19SVolodymyr Mytnyk struct prestera_msg_acl_action {
458bb5dbf2cSVolodymyr Mytnyk 	__le32 id;
4596e36c7bcSVolodymyr Mytnyk 	__le32 __reserved;
4606e36c7bcSVolodymyr Mytnyk 	union {
4616e36c7bcSVolodymyr Mytnyk 		struct {
462fa5d824cSVolodymyr Mytnyk 			__le32 index;
463fa5d824cSVolodymyr Mytnyk 		} jump;
464fa5d824cSVolodymyr Mytnyk 		struct {
4656e36c7bcSVolodymyr Mytnyk 			__le32 id;
466dde2daa0SVolodymyr Mytnyk 		} police;
467dde2daa0SVolodymyr Mytnyk 		struct {
468dde2daa0SVolodymyr Mytnyk 			__le32 id;
4696e36c7bcSVolodymyr Mytnyk 		} count;
4706e36c7bcSVolodymyr Mytnyk 		__le32 reserved[6];
4716e36c7bcSVolodymyr Mytnyk 	};
4726e36c7bcSVolodymyr Mytnyk };
4736e36c7bcSVolodymyr Mytnyk 
4746e36c7bcSVolodymyr Mytnyk struct prestera_msg_counter_req {
4756e36c7bcSVolodymyr Mytnyk 	struct prestera_msg_cmd cmd;
4766e36c7bcSVolodymyr Mytnyk 	__le32 client;
4776e36c7bcSVolodymyr Mytnyk 	__le32 block_id;
4786e36c7bcSVolodymyr Mytnyk 	__le32 num_counters;
4796e36c7bcSVolodymyr Mytnyk };
4806e36c7bcSVolodymyr Mytnyk 
4816e36c7bcSVolodymyr Mytnyk struct prestera_msg_counter_stats {
4826e36c7bcSVolodymyr Mytnyk 	__le64 packets;
4836e36c7bcSVolodymyr Mytnyk 	__le64 bytes;
4846e36c7bcSVolodymyr Mytnyk };
4856e36c7bcSVolodymyr Mytnyk 
4866e36c7bcSVolodymyr Mytnyk struct prestera_msg_counter_resp {
4876e36c7bcSVolodymyr Mytnyk 	struct prestera_msg_ret ret;
4886e36c7bcSVolodymyr Mytnyk 	__le32 block_id;
4896e36c7bcSVolodymyr Mytnyk 	__le32 offset;
4906e36c7bcSVolodymyr Mytnyk 	__le32 num_counters;
4916e36c7bcSVolodymyr Mytnyk 	__le32 done;
49201081be1SJosé Expósito 	struct prestera_msg_counter_stats stats[];
4938b474a9fSSerhiy Boiko };
4948b474a9fSSerhiy Boiko 
49513defa27SSerhiy Boiko struct prestera_msg_span_req {
49613defa27SSerhiy Boiko 	struct prestera_msg_cmd cmd;
497bb5dbf2cSVolodymyr Mytnyk 	__le32 port;
498bb5dbf2cSVolodymyr Mytnyk 	__le32 dev;
49913defa27SSerhiy Boiko 	u8 id;
500236f57feSGeert Uytterhoeven 	u8 pad[3];
501bb5dbf2cSVolodymyr Mytnyk };
50213defa27SSerhiy Boiko 
50313defa27SSerhiy Boiko struct prestera_msg_span_resp {
50413defa27SSerhiy Boiko 	struct prestera_msg_ret ret;
50513defa27SSerhiy Boiko 	u8 id;
506236f57feSGeert Uytterhoeven 	u8 pad[3];
507bb5dbf2cSVolodymyr Mytnyk };
50813defa27SSerhiy Boiko 
509e1189d9aSVadym Kochan struct prestera_msg_stp_req {
510e1189d9aSVadym Kochan 	struct prestera_msg_cmd cmd;
511bb5dbf2cSVolodymyr Mytnyk 	__le32 port;
512bb5dbf2cSVolodymyr Mytnyk 	__le32 dev;
513bb5dbf2cSVolodymyr Mytnyk 	__le16 vid;
514e1189d9aSVadym Kochan 	u8 state;
515e1464db5SVolodymyr Mytnyk 	u8 __pad;
516e1189d9aSVadym Kochan };
517e1189d9aSVadym Kochan 
518501ef306SVadym Kochan struct prestera_msg_rxtx_req {
519501ef306SVadym Kochan 	struct prestera_msg_cmd cmd;
520501ef306SVadym Kochan 	u8 use_sdma;
521236f57feSGeert Uytterhoeven 	u8 pad[3];
522501ef306SVadym Kochan };
523501ef306SVadym Kochan 
524501ef306SVadym Kochan struct prestera_msg_rxtx_resp {
525501ef306SVadym Kochan 	struct prestera_msg_ret ret;
526bb5dbf2cSVolodymyr Mytnyk 	__le32 map_addr;
527501ef306SVadym Kochan };
528501ef306SVadym Kochan 
5290f07bd6bSYevhen Orlov struct prestera_msg_iface {
5300f07bd6bSYevhen Orlov 	union {
5310f07bd6bSYevhen Orlov 		struct {
5320f07bd6bSYevhen Orlov 			__le32 dev;
5330f07bd6bSYevhen Orlov 			__le32 port;
5340f07bd6bSYevhen Orlov 		};
5350f07bd6bSYevhen Orlov 		__le16 lag_id;
5360f07bd6bSYevhen Orlov 	};
5370f07bd6bSYevhen Orlov 	__le16 vr_id;
5380f07bd6bSYevhen Orlov 	__le16 vid;
5390f07bd6bSYevhen Orlov 	u8 type;
5400f07bd6bSYevhen Orlov 	u8 __pad[3];
5410f07bd6bSYevhen Orlov };
5420f07bd6bSYevhen Orlov 
54319787b93SYevhen Orlov struct prestera_msg_ip_addr {
54419787b93SYevhen Orlov 	union {
54519787b93SYevhen Orlov 		__be32 ipv4;
54619787b93SYevhen Orlov 		__be32 ipv6[4];
54719787b93SYevhen Orlov 	} u;
54819787b93SYevhen Orlov 	u8 v; /* e.g. PRESTERA_IPV4 */
54919787b93SYevhen Orlov 	u8 __pad[3];
55019787b93SYevhen Orlov };
55119787b93SYevhen Orlov 
552*0a23ae23SYevhen Orlov struct prestera_msg_nh {
553*0a23ae23SYevhen Orlov 	struct prestera_msg_iface oif;
554*0a23ae23SYevhen Orlov 	__le32 hw_id;
555*0a23ae23SYevhen Orlov 	u8 mac[ETH_ALEN];
556*0a23ae23SYevhen Orlov 	u8 is_active;
557*0a23ae23SYevhen Orlov 	u8 pad;
558*0a23ae23SYevhen Orlov };
559*0a23ae23SYevhen Orlov 
5600f07bd6bSYevhen Orlov struct prestera_msg_rif_req {
5610f07bd6bSYevhen Orlov 	struct prestera_msg_cmd cmd;
5620f07bd6bSYevhen Orlov 	struct prestera_msg_iface iif;
5630f07bd6bSYevhen Orlov 	__le32 mtu;
5640f07bd6bSYevhen Orlov 	__le16 rif_id;
5650f07bd6bSYevhen Orlov 	__le16 __reserved;
5660f07bd6bSYevhen Orlov 	u8 mac[ETH_ALEN];
5670f07bd6bSYevhen Orlov 	u8 __pad[2];
5680f07bd6bSYevhen Orlov };
5690f07bd6bSYevhen Orlov 
5700f07bd6bSYevhen Orlov struct prestera_msg_rif_resp {
5710f07bd6bSYevhen Orlov 	struct prestera_msg_ret ret;
5720f07bd6bSYevhen Orlov 	__le16 rif_id;
5730f07bd6bSYevhen Orlov 	u8 __pad[2];
5740f07bd6bSYevhen Orlov };
5750f07bd6bSYevhen Orlov 
57619787b93SYevhen Orlov struct prestera_msg_lpm_req {
57719787b93SYevhen Orlov 	struct prestera_msg_cmd cmd;
57819787b93SYevhen Orlov 	struct prestera_msg_ip_addr dst;
57919787b93SYevhen Orlov 	__le32 grp_id;
58019787b93SYevhen Orlov 	__le32 dst_len;
58119787b93SYevhen Orlov 	__le16 vr_id;
58219787b93SYevhen Orlov 	u8 __pad[2];
58319787b93SYevhen Orlov };
58419787b93SYevhen Orlov 
585*0a23ae23SYevhen Orlov struct prestera_msg_nh_req {
586*0a23ae23SYevhen Orlov 	struct prestera_msg_cmd cmd;
587*0a23ae23SYevhen Orlov 	struct prestera_msg_nh nh[PRESTERA_NHGR_SIZE_MAX];
588*0a23ae23SYevhen Orlov 	__le32 size;
589*0a23ae23SYevhen Orlov 	__le32 grp_id;
590*0a23ae23SYevhen Orlov };
591*0a23ae23SYevhen Orlov 
592*0a23ae23SYevhen Orlov struct prestera_msg_nh_chunk_req {
593*0a23ae23SYevhen Orlov 	struct prestera_msg_cmd cmd;
594*0a23ae23SYevhen Orlov 	__le32 offset;
595*0a23ae23SYevhen Orlov };
596*0a23ae23SYevhen Orlov 
597*0a23ae23SYevhen Orlov struct prestera_msg_nh_chunk_resp {
598*0a23ae23SYevhen Orlov 	struct prestera_msg_ret ret;
599*0a23ae23SYevhen Orlov 	u8 hw_state[PRESTERA_MSG_CHUNK_SIZE];
600*0a23ae23SYevhen Orlov };
601*0a23ae23SYevhen Orlov 
602*0a23ae23SYevhen Orlov struct prestera_msg_nh_grp_req {
603*0a23ae23SYevhen Orlov 	struct prestera_msg_cmd cmd;
604*0a23ae23SYevhen Orlov 	__le32 grp_id;
605*0a23ae23SYevhen Orlov 	__le32 size;
606*0a23ae23SYevhen Orlov };
607*0a23ae23SYevhen Orlov 
608*0a23ae23SYevhen Orlov struct prestera_msg_nh_grp_resp {
609*0a23ae23SYevhen Orlov 	struct prestera_msg_ret ret;
610*0a23ae23SYevhen Orlov 	__le32 grp_id;
611*0a23ae23SYevhen Orlov };
612*0a23ae23SYevhen Orlov 
6136d1b3eb5SYevhen Orlov struct prestera_msg_vr_req {
6146d1b3eb5SYevhen Orlov 	struct prestera_msg_cmd cmd;
6156d1b3eb5SYevhen Orlov 	__le16 vr_id;
6166d1b3eb5SYevhen Orlov 	u8 __pad[2];
6176d1b3eb5SYevhen Orlov };
6186d1b3eb5SYevhen Orlov 
6196d1b3eb5SYevhen Orlov struct prestera_msg_vr_resp {
6206d1b3eb5SYevhen Orlov 	struct prestera_msg_ret ret;
6216d1b3eb5SYevhen Orlov 	__le16 vr_id;
6226d1b3eb5SYevhen Orlov 	u8 __pad[2];
6236d1b3eb5SYevhen Orlov };
6246d1b3eb5SYevhen Orlov 
625255213caSSerhiy Boiko struct prestera_msg_lag_req {
626255213caSSerhiy Boiko 	struct prestera_msg_cmd cmd;
627bb5dbf2cSVolodymyr Mytnyk 	__le32 port;
628bb5dbf2cSVolodymyr Mytnyk 	__le32 dev;
629bb5dbf2cSVolodymyr Mytnyk 	__le16 lag_id;
630236f57feSGeert Uytterhoeven 	u8 pad[2];
631255213caSSerhiy Boiko };
632255213caSSerhiy Boiko 
633a80cf955SOleksandr Mazur struct prestera_msg_cpu_code_counter_req {
634a80cf955SOleksandr Mazur 	struct prestera_msg_cmd cmd;
635a80cf955SOleksandr Mazur 	u8 counter_type;
636a80cf955SOleksandr Mazur 	u8 code;
637236f57feSGeert Uytterhoeven 	u8 pad[2];
638a80cf955SOleksandr Mazur };
639a80cf955SOleksandr Mazur 
640a80cf955SOleksandr Mazur struct mvsw_msg_cpu_code_counter_ret {
641a80cf955SOleksandr Mazur 	struct prestera_msg_ret ret;
642bb5dbf2cSVolodymyr Mytnyk 	__le64 packet_count;
643a80cf955SOleksandr Mazur };
644a80cf955SOleksandr Mazur 
645dde2daa0SVolodymyr Mytnyk struct prestera_msg_policer_req {
646dde2daa0SVolodymyr Mytnyk 	struct prestera_msg_cmd cmd;
647dde2daa0SVolodymyr Mytnyk 	__le32 id;
648dde2daa0SVolodymyr Mytnyk 	union {
649dde2daa0SVolodymyr Mytnyk 		struct {
650dde2daa0SVolodymyr Mytnyk 			__le64 cir;
651dde2daa0SVolodymyr Mytnyk 			__le32 cbs;
652dde2daa0SVolodymyr Mytnyk 		} __packed sr_tcm; /* make sure always 12 bytes size */
653dde2daa0SVolodymyr Mytnyk 		__le32 reserved[6];
654dde2daa0SVolodymyr Mytnyk 	};
655dde2daa0SVolodymyr Mytnyk 	u8 mode;
656dde2daa0SVolodymyr Mytnyk 	u8 type;
657dde2daa0SVolodymyr Mytnyk 	u8 pad[2];
658dde2daa0SVolodymyr Mytnyk };
659dde2daa0SVolodymyr Mytnyk 
660dde2daa0SVolodymyr Mytnyk struct prestera_msg_policer_resp {
661dde2daa0SVolodymyr Mytnyk 	struct prestera_msg_ret ret;
662dde2daa0SVolodymyr Mytnyk 	__le32 id;
663dde2daa0SVolodymyr Mytnyk };
664dde2daa0SVolodymyr Mytnyk 
665501ef306SVadym Kochan struct prestera_msg_event {
666bb5dbf2cSVolodymyr Mytnyk 	__le16 type;
667bb5dbf2cSVolodymyr Mytnyk 	__le16 id;
668501ef306SVadym Kochan };
669501ef306SVadym Kochan 
670501ef306SVadym Kochan struct prestera_msg_event_port {
671501ef306SVadym Kochan 	struct prestera_msg_event id;
672bb5dbf2cSVolodymyr Mytnyk 	__le32 port_id;
673bb5dbf2cSVolodymyr Mytnyk 	struct prestera_msg_event_port_param param;
674501ef306SVadym Kochan };
675501ef306SVadym Kochan 
676e1189d9aSVadym Kochan union prestera_msg_event_fdb_param {
677e1189d9aSVadym Kochan 	u8 mac[ETH_ALEN];
678e1189d9aSVadym Kochan };
679e1189d9aSVadym Kochan 
680e1189d9aSVadym Kochan struct prestera_msg_event_fdb {
681e1189d9aSVadym Kochan 	struct prestera_msg_event id;
682e1464db5SVolodymyr Mytnyk 	__le32 vid;
683255213caSSerhiy Boiko 	union {
684bb5dbf2cSVolodymyr Mytnyk 		__le32 port_id;
685bb5dbf2cSVolodymyr Mytnyk 		__le16 lag_id;
686255213caSSerhiy Boiko 	} dest;
687e1189d9aSVadym Kochan 	union prestera_msg_event_fdb_param param;
688e1464db5SVolodymyr Mytnyk 	u8 dest_type;
689e1464db5SVolodymyr Mytnyk };
690bb5dbf2cSVolodymyr Mytnyk 
691fec7c9c7SOleksandr Mazur struct prestera_msg_flood_domain_create_req {
692fec7c9c7SOleksandr Mazur 	struct prestera_msg_cmd cmd;
693fec7c9c7SOleksandr Mazur };
694fec7c9c7SOleksandr Mazur 
695fec7c9c7SOleksandr Mazur struct prestera_msg_flood_domain_create_resp {
696fec7c9c7SOleksandr Mazur 	struct prestera_msg_ret ret;
697fec7c9c7SOleksandr Mazur 	__le32 flood_domain_idx;
698fec7c9c7SOleksandr Mazur };
699fec7c9c7SOleksandr Mazur 
700fec7c9c7SOleksandr Mazur struct prestera_msg_flood_domain_destroy_req {
701fec7c9c7SOleksandr Mazur 	struct prestera_msg_cmd cmd;
702fec7c9c7SOleksandr Mazur 	__le32 flood_domain_idx;
703fec7c9c7SOleksandr Mazur };
704fec7c9c7SOleksandr Mazur 
705fec7c9c7SOleksandr Mazur struct prestera_msg_flood_domain_ports_set_req {
706fec7c9c7SOleksandr Mazur 	struct prestera_msg_cmd cmd;
707fec7c9c7SOleksandr Mazur 	__le32 flood_domain_idx;
708fec7c9c7SOleksandr Mazur 	__le32 ports_num;
709fec7c9c7SOleksandr Mazur };
710fec7c9c7SOleksandr Mazur 
711fec7c9c7SOleksandr Mazur struct prestera_msg_flood_domain_ports_reset_req {
712fec7c9c7SOleksandr Mazur 	struct prestera_msg_cmd cmd;
713fec7c9c7SOleksandr Mazur 	__le32 flood_domain_idx;
714fec7c9c7SOleksandr Mazur };
715fec7c9c7SOleksandr Mazur 
716fec7c9c7SOleksandr Mazur struct prestera_msg_flood_domain_port {
717fec7c9c7SOleksandr Mazur 	union {
718fec7c9c7SOleksandr Mazur 		struct {
719fec7c9c7SOleksandr Mazur 			__le32 port_num;
720fec7c9c7SOleksandr Mazur 			__le32 dev_num;
721fec7c9c7SOleksandr Mazur 		};
722fec7c9c7SOleksandr Mazur 		__le16 lag_id;
723fec7c9c7SOleksandr Mazur 	};
724fec7c9c7SOleksandr Mazur 	__le16 vid;
725fec7c9c7SOleksandr Mazur 	__le16 port_type;
726fec7c9c7SOleksandr Mazur };
727fec7c9c7SOleksandr Mazur 
728fec7c9c7SOleksandr Mazur struct prestera_msg_mdb_create_req {
729fec7c9c7SOleksandr Mazur 	struct prestera_msg_cmd cmd;
730fec7c9c7SOleksandr Mazur 	__le32 flood_domain_idx;
731fec7c9c7SOleksandr Mazur 	__le16 vid;
732fec7c9c7SOleksandr Mazur 	u8 mac[ETH_ALEN];
733fec7c9c7SOleksandr Mazur };
734fec7c9c7SOleksandr Mazur 
735fec7c9c7SOleksandr Mazur struct prestera_msg_mdb_destroy_req {
736fec7c9c7SOleksandr Mazur 	struct prestera_msg_cmd cmd;
737fec7c9c7SOleksandr Mazur 	__le32 flood_domain_idx;
738fec7c9c7SOleksandr Mazur 	__le16 vid;
739fec7c9c7SOleksandr Mazur 	u8 mac[ETH_ALEN];
740fec7c9c7SOleksandr Mazur };
741fec7c9c7SOleksandr Mazur 
prestera_hw_build_tests(void)742e1464db5SVolodymyr Mytnyk static void prestera_hw_build_tests(void)
743bb5dbf2cSVolodymyr Mytnyk {
744bb5dbf2cSVolodymyr Mytnyk 	/* check requests */
745bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_common_req) != 4);
746bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_switch_attr_req) != 16);
747e1464db5SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_port_attr_req) != 144);
748bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_port_info_req) != 8);
749bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_vlan_req) != 16);
750bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_fdb_req) != 28);
751bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_bridge_req) != 16);
752bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_span_req) != 16);
753bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_stp_req) != 16);
754bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_rxtx_req) != 8);
755bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_lag_req) != 16);
756bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_cpu_code_counter_req) != 8);
75747327e19SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_create_req) != 84);
75847327e19SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_destroy_req) != 8);
75947327e19SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_rule_add_req) != 168);
76047327e19SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_rule_del_req) != 12);
76147327e19SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_bind_req) != 20);
76247327e19SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_acl_action) != 32);
7636e36c7bcSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_counter_req) != 16);
7646e36c7bcSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_counter_stats) != 16);
7650f07bd6bSYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_rif_req) != 36);
7666d1b3eb5SYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_vr_req) != 8);
76719787b93SYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_lpm_req) != 36);
768dde2daa0SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_policer_req) != 36);
769fec7c9c7SOleksandr Mazur 	BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_create_req) != 4);
770fec7c9c7SOleksandr Mazur 	BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_destroy_req) != 8);
771fec7c9c7SOleksandr Mazur 	BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_ports_set_req) != 12);
772fec7c9c7SOleksandr Mazur 	BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_ports_reset_req) != 8);
773fec7c9c7SOleksandr Mazur 	BUILD_BUG_ON(sizeof(struct prestera_msg_mdb_create_req) != 16);
774fec7c9c7SOleksandr Mazur 	BUILD_BUG_ON(sizeof(struct prestera_msg_mdb_destroy_req) != 16);
775*0a23ae23SYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_nh_req) != 124);
776*0a23ae23SYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_nh_chunk_req) != 8);
777*0a23ae23SYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_nh_grp_req) != 12);
778bb5dbf2cSVolodymyr Mytnyk 
7790f07bd6bSYevhen Orlov 	/*  structure that are part of req/resp fw messages */
7800f07bd6bSYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_iface) != 16);
78119787b93SYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_ip_addr) != 20);
782fec7c9c7SOleksandr Mazur 	BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_port) != 12);
783*0a23ae23SYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_nh) != 28);
7840f07bd6bSYevhen Orlov 
785bb5dbf2cSVolodymyr Mytnyk 	/* check responses */
786bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_common_resp) != 8);
787bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_switch_init_resp) != 24);
788e1464db5SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_port_attr_resp) != 136);
789bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_port_stats_resp) != 248);
790bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_port_info_resp) != 20);
791bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_bridge_resp) != 12);
792bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_span_resp) != 12);
793bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_rxtx_resp) != 12);
79447327e19SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_vtcam_resp) != 16);
7956e36c7bcSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_counter_resp) != 24);
7960f07bd6bSYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_rif_resp) != 12);
7976d1b3eb5SYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_vr_resp) != 12);
798dde2daa0SVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_policer_resp) != 12);
799917edfb9SMaksym Glubokiy 	BUILD_BUG_ON(sizeof(struct prestera_msg_flood_domain_create_resp) != 12);
800*0a23ae23SYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_nh_chunk_resp) != 1032);
801*0a23ae23SYevhen Orlov 	BUILD_BUG_ON(sizeof(struct prestera_msg_nh_grp_resp) != 12);
802bb5dbf2cSVolodymyr Mytnyk 
803bb5dbf2cSVolodymyr Mytnyk 	/* check events */
804bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_event_port) != 20);
805bb5dbf2cSVolodymyr Mytnyk 	BUILD_BUG_ON(sizeof(struct prestera_msg_event_fdb) != 20);
806bb5dbf2cSVolodymyr Mytnyk }
807bb5dbf2cSVolodymyr Mytnyk 
808bb5dbf2cSVolodymyr Mytnyk static u8 prestera_hw_mdix_to_eth(u8 mode);
809bb5dbf2cSVolodymyr Mytnyk static void prestera_hw_remote_fc_to_eth(u8 fc, bool *pause, bool *asym_pause);
810e1189d9aSVadym 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)811501ef306SVadym Kochan static int __prestera_cmd_ret(struct prestera_switch *sw,
812501ef306SVadym Kochan 			      enum prestera_cmd_type_t type,
813501ef306SVadym Kochan 			      struct prestera_msg_cmd *cmd, size_t clen,
814501ef306SVadym Kochan 			      struct prestera_msg_ret *ret, size_t rlen,
815501ef306SVadym Kochan 			      int waitms)
816501ef306SVadym Kochan {
817501ef306SVadym Kochan 	struct prestera_device *dev = sw->dev;
818501ef306SVadym Kochan 	int err;
819501ef306SVadym Kochan 
820bb5dbf2cSVolodymyr Mytnyk 	cmd->type = __cpu_to_le32(type);
821501ef306SVadym Kochan 
822bb5dbf2cSVolodymyr Mytnyk 	err = dev->send_req(dev, 0, cmd, clen, ret, rlen, waitms);
823501ef306SVadym Kochan 	if (err)
824501ef306SVadym Kochan 		return err;
825501ef306SVadym Kochan 
826e1464db5SVolodymyr Mytnyk 	if (ret->cmd.type != __cpu_to_le32(PRESTERA_CMD_TYPE_ACK))
827501ef306SVadym Kochan 		return -EBADE;
828e1464db5SVolodymyr Mytnyk 	if (ret->status != __cpu_to_le32(PRESTERA_CMD_ACK_OK))
829501ef306SVadym Kochan 		return -EINVAL;
830501ef306SVadym Kochan 
831501ef306SVadym Kochan 	return 0;
832501ef306SVadym Kochan }
833501ef306SVadym 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)834501ef306SVadym Kochan static int prestera_cmd_ret(struct prestera_switch *sw,
835501ef306SVadym Kochan 			    enum prestera_cmd_type_t type,
836501ef306SVadym Kochan 			    struct prestera_msg_cmd *cmd, size_t clen,
837501ef306SVadym Kochan 			    struct prestera_msg_ret *ret, size_t rlen)
838501ef306SVadym Kochan {
839501ef306SVadym Kochan 	return __prestera_cmd_ret(sw, type, cmd, clen, ret, rlen, 0);
840501ef306SVadym Kochan }
841501ef306SVadym 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)842501ef306SVadym Kochan static int prestera_cmd_ret_wait(struct prestera_switch *sw,
843501ef306SVadym Kochan 				 enum prestera_cmd_type_t type,
844501ef306SVadym Kochan 				 struct prestera_msg_cmd *cmd, size_t clen,
845501ef306SVadym Kochan 				 struct prestera_msg_ret *ret, size_t rlen,
846501ef306SVadym Kochan 				 int waitms)
847501ef306SVadym Kochan {
848501ef306SVadym Kochan 	return __prestera_cmd_ret(sw, type, cmd, clen, ret, rlen, waitms);
849501ef306SVadym Kochan }
850501ef306SVadym Kochan 
prestera_cmd(struct prestera_switch * sw,enum prestera_cmd_type_t type,struct prestera_msg_cmd * cmd,size_t clen)851501ef306SVadym Kochan static int prestera_cmd(struct prestera_switch *sw,
852501ef306SVadym Kochan 			enum prestera_cmd_type_t type,
853501ef306SVadym Kochan 			struct prestera_msg_cmd *cmd, size_t clen)
854501ef306SVadym Kochan {
855501ef306SVadym Kochan 	struct prestera_msg_common_resp resp;
856501ef306SVadym Kochan 
857501ef306SVadym Kochan 	return prestera_cmd_ret(sw, type, cmd, clen, &resp.ret, sizeof(resp));
858501ef306SVadym Kochan }
859501ef306SVadym Kochan 
prestera_fw_parse_port_evt(void * msg,struct prestera_event * evt)860501ef306SVadym Kochan static int prestera_fw_parse_port_evt(void *msg, struct prestera_event *evt)
861501ef306SVadym Kochan {
862bb5dbf2cSVolodymyr Mytnyk 	struct prestera_msg_event_port *hw_evt;
863501ef306SVadym Kochan 
864bb5dbf2cSVolodymyr Mytnyk 	hw_evt = (struct prestera_msg_event_port *)msg;
865bb5dbf2cSVolodymyr Mytnyk 
866bb5dbf2cSVolodymyr Mytnyk 	evt->port_evt.port_id = __le32_to_cpu(hw_evt->port_id);
867bb5dbf2cSVolodymyr Mytnyk 
868bb5dbf2cSVolodymyr Mytnyk 	if (evt->id == PRESTERA_PORT_EVENT_MAC_STATE_CHANGED) {
869bb5dbf2cSVolodymyr Mytnyk 		evt->port_evt.data.mac.oper = hw_evt->param.mac.oper;
870bb5dbf2cSVolodymyr Mytnyk 		evt->port_evt.data.mac.mode =
871bb5dbf2cSVolodymyr Mytnyk 			__le32_to_cpu(hw_evt->param.mac.mode);
872bb5dbf2cSVolodymyr Mytnyk 		evt->port_evt.data.mac.speed =
873bb5dbf2cSVolodymyr Mytnyk 			__le32_to_cpu(hw_evt->param.mac.speed);
874bb5dbf2cSVolodymyr Mytnyk 		evt->port_evt.data.mac.duplex = hw_evt->param.mac.duplex;
875bb5dbf2cSVolodymyr Mytnyk 		evt->port_evt.data.mac.fc = hw_evt->param.mac.fc;
876bb5dbf2cSVolodymyr Mytnyk 		evt->port_evt.data.mac.fec = hw_evt->param.mac.fec;
877bb5dbf2cSVolodymyr Mytnyk 	} else {
878501ef306SVadym Kochan 		return -EINVAL;
879bb5dbf2cSVolodymyr Mytnyk 	}
880501ef306SVadym Kochan 
881501ef306SVadym Kochan 	return 0;
882501ef306SVadym Kochan }
883501ef306SVadym Kochan 
prestera_fw_parse_fdb_evt(void * msg,struct prestera_event * evt)884e1189d9aSVadym Kochan static int prestera_fw_parse_fdb_evt(void *msg, struct prestera_event *evt)
885e1189d9aSVadym Kochan {
886e1189d9aSVadym Kochan 	struct prestera_msg_event_fdb *hw_evt = msg;
887e1189d9aSVadym Kochan 
888255213caSSerhiy Boiko 	switch (hw_evt->dest_type) {
889255213caSSerhiy Boiko 	case PRESTERA_HW_FDB_ENTRY_TYPE_REG_PORT:
890255213caSSerhiy Boiko 		evt->fdb_evt.type = PRESTERA_FDB_ENTRY_TYPE_REG_PORT;
891bb5dbf2cSVolodymyr Mytnyk 		evt->fdb_evt.dest.port_id = __le32_to_cpu(hw_evt->dest.port_id);
892255213caSSerhiy Boiko 		break;
893255213caSSerhiy Boiko 	case PRESTERA_HW_FDB_ENTRY_TYPE_LAG:
894255213caSSerhiy Boiko 		evt->fdb_evt.type = PRESTERA_FDB_ENTRY_TYPE_LAG;
895bb5dbf2cSVolodymyr Mytnyk 		evt->fdb_evt.dest.lag_id = __le16_to_cpu(hw_evt->dest.lag_id);
896255213caSSerhiy Boiko 		break;
897255213caSSerhiy Boiko 	default:
898255213caSSerhiy Boiko 		return -EINVAL;
899255213caSSerhiy Boiko 	}
900255213caSSerhiy Boiko 
901bb5dbf2cSVolodymyr Mytnyk 	evt->fdb_evt.vid = __le32_to_cpu(hw_evt->vid);
902e1189d9aSVadym Kochan 
903e1189d9aSVadym Kochan 	ether_addr_copy(evt->fdb_evt.data.mac, hw_evt->param.mac);
904e1189d9aSVadym Kochan 
905e1189d9aSVadym Kochan 	return 0;
906e1189d9aSVadym Kochan }
907e1189d9aSVadym Kochan 
908501ef306SVadym Kochan static struct prestera_fw_evt_parser {
909501ef306SVadym Kochan 	int (*func)(void *msg, struct prestera_event *evt);
910501ef306SVadym Kochan } fw_event_parsers[PRESTERA_EVENT_TYPE_MAX] = {
911501ef306SVadym Kochan 	[PRESTERA_EVENT_TYPE_PORT] = { .func = prestera_fw_parse_port_evt },
912e1189d9aSVadym Kochan 	[PRESTERA_EVENT_TYPE_FDB] = { .func = prestera_fw_parse_fdb_evt },
913501ef306SVadym Kochan };
914501ef306SVadym Kochan 
915501ef306SVadym Kochan static struct prestera_fw_event_handler *
__find_event_handler(const struct prestera_switch * sw,enum prestera_event_type type)916501ef306SVadym Kochan __find_event_handler(const struct prestera_switch *sw,
917501ef306SVadym Kochan 		     enum prestera_event_type type)
918501ef306SVadym Kochan {
919501ef306SVadym Kochan 	struct prestera_fw_event_handler *eh;
920501ef306SVadym Kochan 
921501ef306SVadym Kochan 	list_for_each_entry_rcu(eh, &sw->event_handlers, list) {
922501ef306SVadym Kochan 		if (eh->type == type)
923501ef306SVadym Kochan 			return eh;
924501ef306SVadym Kochan 	}
925501ef306SVadym Kochan 
926501ef306SVadym Kochan 	return NULL;
927501ef306SVadym Kochan }
928501ef306SVadym Kochan 
prestera_find_event_handler(const struct prestera_switch * sw,enum prestera_event_type type,struct prestera_fw_event_handler * eh)929501ef306SVadym Kochan static int prestera_find_event_handler(const struct prestera_switch *sw,
930501ef306SVadym Kochan 				       enum prestera_event_type type,
931501ef306SVadym Kochan 				       struct prestera_fw_event_handler *eh)
932501ef306SVadym Kochan {
933501ef306SVadym Kochan 	struct prestera_fw_event_handler *tmp;
934501ef306SVadym Kochan 	int err = 0;
935501ef306SVadym Kochan 
936501ef306SVadym Kochan 	rcu_read_lock();
937501ef306SVadym Kochan 	tmp = __find_event_handler(sw, type);
938501ef306SVadym Kochan 	if (tmp)
939501ef306SVadym Kochan 		*eh = *tmp;
940501ef306SVadym Kochan 	else
941501ef306SVadym Kochan 		err = -ENOENT;
942501ef306SVadym Kochan 	rcu_read_unlock();
943501ef306SVadym Kochan 
944501ef306SVadym Kochan 	return err;
945501ef306SVadym Kochan }
946501ef306SVadym Kochan 
prestera_evt_recv(struct prestera_device * dev,void * buf,size_t size)947501ef306SVadym Kochan static int prestera_evt_recv(struct prestera_device *dev, void *buf, size_t size)
948501ef306SVadym Kochan {
949501ef306SVadym Kochan 	struct prestera_switch *sw = dev->priv;
950501ef306SVadym Kochan 	struct prestera_msg_event *msg = buf;
951501ef306SVadym Kochan 	struct prestera_fw_event_handler eh;
952501ef306SVadym Kochan 	struct prestera_event evt;
953bb5dbf2cSVolodymyr Mytnyk 	u16 msg_type;
954501ef306SVadym Kochan 	int err;
955501ef306SVadym Kochan 
956bb5dbf2cSVolodymyr Mytnyk 	msg_type = __le16_to_cpu(msg->type);
957bb5dbf2cSVolodymyr Mytnyk 	if (msg_type >= PRESTERA_EVENT_TYPE_MAX)
958501ef306SVadym Kochan 		return -EINVAL;
959bb5dbf2cSVolodymyr Mytnyk 	if (!fw_event_parsers[msg_type].func)
960501ef306SVadym Kochan 		return -ENOENT;
961501ef306SVadym Kochan 
962bb5dbf2cSVolodymyr Mytnyk 	err = prestera_find_event_handler(sw, msg_type, &eh);
963501ef306SVadym Kochan 	if (err)
964501ef306SVadym Kochan 		return err;
965501ef306SVadym Kochan 
966bb5dbf2cSVolodymyr Mytnyk 	evt.id = __le16_to_cpu(msg->id);
967501ef306SVadym Kochan 
968bb5dbf2cSVolodymyr Mytnyk 	err = fw_event_parsers[msg_type].func(buf, &evt);
969501ef306SVadym Kochan 	if (err)
970501ef306SVadym Kochan 		return err;
971501ef306SVadym Kochan 
972501ef306SVadym Kochan 	eh.func(sw, &evt, eh.arg);
973501ef306SVadym Kochan 
974501ef306SVadym Kochan 	return 0;
975501ef306SVadym Kochan }
976501ef306SVadym Kochan 
prestera_pkt_recv(struct prestera_device * dev)977501ef306SVadym Kochan static void prestera_pkt_recv(struct prestera_device *dev)
978501ef306SVadym Kochan {
979501ef306SVadym Kochan 	struct prestera_switch *sw = dev->priv;
980501ef306SVadym Kochan 	struct prestera_fw_event_handler eh;
981501ef306SVadym Kochan 	struct prestera_event ev;
982501ef306SVadym Kochan 	int err;
983501ef306SVadym Kochan 
984501ef306SVadym Kochan 	ev.id = PRESTERA_RXTX_EVENT_RCV_PKT;
985501ef306SVadym Kochan 
986501ef306SVadym Kochan 	err = prestera_find_event_handler(sw, PRESTERA_EVENT_TYPE_RXTX, &eh);
987501ef306SVadym Kochan 	if (err)
988501ef306SVadym Kochan 		return;
989501ef306SVadym Kochan 
990501ef306SVadym Kochan 	eh.func(sw, &ev, eh.arg);
991501ef306SVadym Kochan }
992501ef306SVadym Kochan 
prestera_hw_mdix_to_eth(u8 mode)993bb5dbf2cSVolodymyr Mytnyk static u8 prestera_hw_mdix_to_eth(u8 mode)
994bb5dbf2cSVolodymyr Mytnyk {
995bb5dbf2cSVolodymyr Mytnyk 	switch (mode) {
996bb5dbf2cSVolodymyr Mytnyk 	case PRESTERA_PORT_TP_MDI:
997bb5dbf2cSVolodymyr Mytnyk 		return ETH_TP_MDI;
998bb5dbf2cSVolodymyr Mytnyk 	case PRESTERA_PORT_TP_MDIX:
999bb5dbf2cSVolodymyr Mytnyk 		return ETH_TP_MDI_X;
1000bb5dbf2cSVolodymyr Mytnyk 	case PRESTERA_PORT_TP_AUTO:
1001bb5dbf2cSVolodymyr Mytnyk 		return ETH_TP_MDI_AUTO;
1002bb5dbf2cSVolodymyr Mytnyk 	default:
1003bb5dbf2cSVolodymyr Mytnyk 		return ETH_TP_MDI_INVALID;
1004bb5dbf2cSVolodymyr Mytnyk 	}
1005bb5dbf2cSVolodymyr Mytnyk }
1006bb5dbf2cSVolodymyr Mytnyk 
prestera_hw_mdix_from_eth(u8 mode)1007bb5dbf2cSVolodymyr Mytnyk static u8 prestera_hw_mdix_from_eth(u8 mode)
1008bb5dbf2cSVolodymyr Mytnyk {
1009bb5dbf2cSVolodymyr Mytnyk 	switch (mode) {
1010bb5dbf2cSVolodymyr Mytnyk 	case ETH_TP_MDI:
1011bb5dbf2cSVolodymyr Mytnyk 		return PRESTERA_PORT_TP_MDI;
1012bb5dbf2cSVolodymyr Mytnyk 	case ETH_TP_MDI_X:
1013bb5dbf2cSVolodymyr Mytnyk 		return PRESTERA_PORT_TP_MDIX;
1014bb5dbf2cSVolodymyr Mytnyk 	case ETH_TP_MDI_AUTO:
1015bb5dbf2cSVolodymyr Mytnyk 		return PRESTERA_PORT_TP_AUTO;
1016bb5dbf2cSVolodymyr Mytnyk 	default:
1017bb5dbf2cSVolodymyr Mytnyk 		return PRESTERA_PORT_TP_NA;
1018bb5dbf2cSVolodymyr Mytnyk 	}
1019bb5dbf2cSVolodymyr Mytnyk }
1020bb5dbf2cSVolodymyr Mytnyk 
prestera_hw_port_info_get(const struct prestera_port * port,u32 * dev_id,u32 * hw_id,u16 * fp_id)1021501ef306SVadym Kochan int prestera_hw_port_info_get(const struct prestera_port *port,
1022501ef306SVadym Kochan 			      u32 *dev_id, u32 *hw_id, u16 *fp_id)
1023501ef306SVadym Kochan {
1024501ef306SVadym Kochan 	struct prestera_msg_port_info_req req = {
1025bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->id),
1026501ef306SVadym Kochan 	};
1027501ef306SVadym Kochan 	struct prestera_msg_port_info_resp resp;
1028501ef306SVadym Kochan 	int err;
1029501ef306SVadym Kochan 
1030501ef306SVadym Kochan 	err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_INFO_GET,
1031501ef306SVadym Kochan 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
1032501ef306SVadym Kochan 	if (err)
1033501ef306SVadym Kochan 		return err;
1034501ef306SVadym Kochan 
1035bb5dbf2cSVolodymyr Mytnyk 	*dev_id = __le32_to_cpu(resp.dev_id);
1036bb5dbf2cSVolodymyr Mytnyk 	*hw_id = __le32_to_cpu(resp.hw_id);
1037bb5dbf2cSVolodymyr Mytnyk 	*fp_id = __le16_to_cpu(resp.fp_id);
1038501ef306SVadym Kochan 
1039501ef306SVadym Kochan 	return 0;
1040501ef306SVadym Kochan }
1041501ef306SVadym Kochan 
prestera_hw_switch_mac_set(struct prestera_switch * sw,const char * mac)1042501ef306SVadym Kochan int prestera_hw_switch_mac_set(struct prestera_switch *sw, const char *mac)
1043501ef306SVadym Kochan {
1044501ef306SVadym Kochan 	struct prestera_msg_switch_attr_req req = {
1045bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_SWITCH_ATTR_MAC),
1046501ef306SVadym Kochan 	};
1047501ef306SVadym Kochan 
1048501ef306SVadym Kochan 	ether_addr_copy(req.param.mac, mac);
1049501ef306SVadym Kochan 
1050501ef306SVadym Kochan 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_SWITCH_ATTR_SET,
1051501ef306SVadym Kochan 			    &req.cmd, sizeof(req));
1052501ef306SVadym Kochan }
1053501ef306SVadym Kochan 
prestera_hw_switch_init(struct prestera_switch * sw)1054501ef306SVadym Kochan int prestera_hw_switch_init(struct prestera_switch *sw)
1055501ef306SVadym Kochan {
1056501ef306SVadym Kochan 	struct prestera_msg_switch_init_resp resp;
1057501ef306SVadym Kochan 	struct prestera_msg_common_req req;
1058501ef306SVadym Kochan 	int err;
1059501ef306SVadym Kochan 
1060501ef306SVadym Kochan 	INIT_LIST_HEAD(&sw->event_handlers);
1061501ef306SVadym Kochan 
1062bb5dbf2cSVolodymyr Mytnyk 	prestera_hw_build_tests();
1063bb5dbf2cSVolodymyr Mytnyk 
1064501ef306SVadym Kochan 	err = prestera_cmd_ret_wait(sw, PRESTERA_CMD_TYPE_SWITCH_INIT,
1065501ef306SVadym Kochan 				    &req.cmd, sizeof(req),
1066501ef306SVadym Kochan 				    &resp.ret, sizeof(resp),
1067501ef306SVadym Kochan 				    PRESTERA_SWITCH_INIT_TIMEOUT_MS);
1068501ef306SVadym Kochan 	if (err)
1069501ef306SVadym Kochan 		return err;
1070501ef306SVadym Kochan 
1071501ef306SVadym Kochan 	sw->dev->recv_msg = prestera_evt_recv;
1072501ef306SVadym Kochan 	sw->dev->recv_pkt = prestera_pkt_recv;
1073bb5dbf2cSVolodymyr Mytnyk 	sw->port_count = __le32_to_cpu(resp.port_count);
1074501ef306SVadym Kochan 	sw->mtu_min = PRESTERA_MIN_MTU;
1075bb5dbf2cSVolodymyr Mytnyk 	sw->mtu_max = __le32_to_cpu(resp.mtu_max);
1076501ef306SVadym Kochan 	sw->id = resp.switch_id;
1077255213caSSerhiy Boiko 	sw->lag_member_max = resp.lag_member_max;
1078255213caSSerhiy Boiko 	sw->lag_max = resp.lag_max;
1079*0a23ae23SYevhen Orlov 	sw->size_tbl_router_nexthop =
1080*0a23ae23SYevhen Orlov 		__le32_to_cpu(resp.size_tbl_router_nexthop);
1081501ef306SVadym Kochan 
1082501ef306SVadym Kochan 	return 0;
1083501ef306SVadym Kochan }
1084501ef306SVadym Kochan 
prestera_hw_switch_fini(struct prestera_switch * sw)1085501ef306SVadym Kochan void prestera_hw_switch_fini(struct prestera_switch *sw)
1086501ef306SVadym Kochan {
1087501ef306SVadym Kochan 	WARN_ON(!list_empty(&sw->event_handlers));
1088501ef306SVadym Kochan }
1089501ef306SVadym Kochan 
prestera_hw_switch_ageing_set(struct prestera_switch * sw,u32 ageing_ms)1090e1189d9aSVadym Kochan int prestera_hw_switch_ageing_set(struct prestera_switch *sw, u32 ageing_ms)
1091e1189d9aSVadym Kochan {
1092e1189d9aSVadym Kochan 	struct prestera_msg_switch_attr_req req = {
1093bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_SWITCH_ATTR_AGEING),
1094e1189d9aSVadym Kochan 		.param = {
1095bb5dbf2cSVolodymyr Mytnyk 			.ageing_timeout_ms = __cpu_to_le32(ageing_ms),
1096e1189d9aSVadym Kochan 		},
1097e1189d9aSVadym Kochan 	};
1098e1189d9aSVadym Kochan 
1099e1189d9aSVadym Kochan 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_SWITCH_ATTR_SET,
1100e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1101e1189d9aSVadym Kochan }
1102e1189d9aSVadym Kochan 
prestera_hw_port_mac_mode_get(const struct prestera_port * port,u32 * mode,u32 * speed,u8 * duplex,u8 * fec)1103bb5dbf2cSVolodymyr Mytnyk int prestera_hw_port_mac_mode_get(const struct prestera_port *port,
1104bb5dbf2cSVolodymyr Mytnyk 				  u32 *mode, u32 *speed, u8 *duplex, u8 *fec)
1105bb5dbf2cSVolodymyr Mytnyk {
1106bb5dbf2cSVolodymyr Mytnyk 	struct prestera_msg_port_attr_resp resp;
1107bb5dbf2cSVolodymyr Mytnyk 	struct prestera_msg_port_attr_req req = {
1108bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_MAC_MODE),
1109bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1110bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id)
1111bb5dbf2cSVolodymyr Mytnyk 	};
1112bb5dbf2cSVolodymyr Mytnyk 	int err;
1113bb5dbf2cSVolodymyr Mytnyk 
1114bb5dbf2cSVolodymyr Mytnyk 	err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET,
1115bb5dbf2cSVolodymyr Mytnyk 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
1116bb5dbf2cSVolodymyr Mytnyk 	if (err)
1117bb5dbf2cSVolodymyr Mytnyk 		return err;
1118bb5dbf2cSVolodymyr Mytnyk 
1119bb5dbf2cSVolodymyr Mytnyk 	if (mode)
1120bb5dbf2cSVolodymyr Mytnyk 		*mode = __le32_to_cpu(resp.param.link_evt.mac.mode);
1121bb5dbf2cSVolodymyr Mytnyk 
1122bb5dbf2cSVolodymyr Mytnyk 	if (speed)
1123bb5dbf2cSVolodymyr Mytnyk 		*speed = __le32_to_cpu(resp.param.link_evt.mac.speed);
1124bb5dbf2cSVolodymyr Mytnyk 
1125bb5dbf2cSVolodymyr Mytnyk 	if (duplex)
1126bb5dbf2cSVolodymyr Mytnyk 		*duplex = resp.param.link_evt.mac.duplex;
1127bb5dbf2cSVolodymyr Mytnyk 
1128bb5dbf2cSVolodymyr Mytnyk 	if (fec)
1129bb5dbf2cSVolodymyr Mytnyk 		*fec = resp.param.link_evt.mac.fec;
1130bb5dbf2cSVolodymyr Mytnyk 
1131bb5dbf2cSVolodymyr Mytnyk 	return err;
1132bb5dbf2cSVolodymyr Mytnyk }
1133bb5dbf2cSVolodymyr Mytnyk 
prestera_hw_port_mac_mode_set(const struct prestera_port * port,bool admin,u32 mode,u8 inband,u32 speed,u8 duplex,u8 fec)1134bb5dbf2cSVolodymyr Mytnyk int prestera_hw_port_mac_mode_set(const struct prestera_port *port,
1135bb5dbf2cSVolodymyr Mytnyk 				  bool admin, u32 mode, u8 inband,
1136bb5dbf2cSVolodymyr Mytnyk 				  u32 speed, u8 duplex, u8 fec)
1137501ef306SVadym Kochan {
1138501ef306SVadym Kochan 	struct prestera_msg_port_attr_req req = {
1139bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_MAC_MODE),
1140bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1141bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1142501ef306SVadym Kochan 		.param = {
1143bb5dbf2cSVolodymyr Mytnyk 			.link = {
1144bb5dbf2cSVolodymyr Mytnyk 				.mac = {
1145bb5dbf2cSVolodymyr Mytnyk 					.admin = admin,
1146bb5dbf2cSVolodymyr Mytnyk 					.reg_mode.mode = __cpu_to_le32(mode),
1147bb5dbf2cSVolodymyr Mytnyk 					.reg_mode.inband = inband,
1148bb5dbf2cSVolodymyr Mytnyk 					.reg_mode.speed = __cpu_to_le32(speed),
1149bb5dbf2cSVolodymyr Mytnyk 					.reg_mode.duplex = duplex,
1150bb5dbf2cSVolodymyr Mytnyk 					.reg_mode.fec = fec
1151bb5dbf2cSVolodymyr Mytnyk 				}
1152bb5dbf2cSVolodymyr Mytnyk 			}
1153501ef306SVadym Kochan 		}
1154501ef306SVadym Kochan 	};
1155501ef306SVadym Kochan 
1156501ef306SVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET,
1157501ef306SVadym Kochan 			    &req.cmd, sizeof(req));
1158501ef306SVadym Kochan }
1159501ef306SVadym Kochan 
prestera_hw_port_phy_mode_get(const struct prestera_port * port,u8 * mdix,u64 * lmode_bmap,bool * fc_pause,bool * fc_asym)1160bb5dbf2cSVolodymyr Mytnyk int prestera_hw_port_phy_mode_get(const struct prestera_port *port,
1161bb5dbf2cSVolodymyr Mytnyk 				  u8 *mdix, u64 *lmode_bmap,
1162bb5dbf2cSVolodymyr Mytnyk 				  bool *fc_pause, bool *fc_asym)
1163bb5dbf2cSVolodymyr Mytnyk {
1164bb5dbf2cSVolodymyr Mytnyk 	struct prestera_msg_port_attr_resp resp;
1165bb5dbf2cSVolodymyr Mytnyk 	struct prestera_msg_port_attr_req req = {
1166bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_PHY_MODE),
1167bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1168bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id)
1169bb5dbf2cSVolodymyr Mytnyk 	};
1170bb5dbf2cSVolodymyr Mytnyk 	int err;
1171bb5dbf2cSVolodymyr Mytnyk 
1172bb5dbf2cSVolodymyr Mytnyk 	err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET,
1173bb5dbf2cSVolodymyr Mytnyk 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
1174bb5dbf2cSVolodymyr Mytnyk 	if (err)
1175bb5dbf2cSVolodymyr Mytnyk 		return err;
1176bb5dbf2cSVolodymyr Mytnyk 
1177bb5dbf2cSVolodymyr Mytnyk 	if (mdix)
1178bb5dbf2cSVolodymyr Mytnyk 		*mdix = prestera_hw_mdix_to_eth(resp.param.link_evt.phy.mdix);
1179bb5dbf2cSVolodymyr Mytnyk 
1180bb5dbf2cSVolodymyr Mytnyk 	if (lmode_bmap)
1181bb5dbf2cSVolodymyr Mytnyk 		*lmode_bmap = __le64_to_cpu(resp.param.link_evt.phy.lmode_bmap);
1182bb5dbf2cSVolodymyr Mytnyk 
1183bb5dbf2cSVolodymyr Mytnyk 	if (fc_pause && fc_asym)
1184bb5dbf2cSVolodymyr Mytnyk 		prestera_hw_remote_fc_to_eth(resp.param.link_evt.phy.fc,
1185bb5dbf2cSVolodymyr Mytnyk 					     fc_pause, fc_asym);
1186bb5dbf2cSVolodymyr Mytnyk 
1187bb5dbf2cSVolodymyr Mytnyk 	return err;
1188bb5dbf2cSVolodymyr Mytnyk }
1189bb5dbf2cSVolodymyr Mytnyk 
prestera_hw_port_phy_mode_set(const struct prestera_port * port,bool admin,bool adv,u32 mode,u64 modes,u8 mdix)1190bb5dbf2cSVolodymyr Mytnyk int prestera_hw_port_phy_mode_set(const struct prestera_port *port,
1191bb5dbf2cSVolodymyr Mytnyk 				  bool admin, bool adv, u32 mode, u64 modes,
1192bb5dbf2cSVolodymyr Mytnyk 				  u8 mdix)
1193bb5dbf2cSVolodymyr Mytnyk {
1194bb5dbf2cSVolodymyr Mytnyk 	struct prestera_msg_port_attr_req req = {
1195bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_PHY_MODE),
1196bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1197bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1198bb5dbf2cSVolodymyr Mytnyk 		.param = {
1199bb5dbf2cSVolodymyr Mytnyk 			.link = {
1200bb5dbf2cSVolodymyr Mytnyk 				.phy = {
1201bb5dbf2cSVolodymyr Mytnyk 					.admin = admin,
1202bb5dbf2cSVolodymyr Mytnyk 					.adv_enable = adv ? 1 : 0,
1203bb5dbf2cSVolodymyr Mytnyk 					.mode = __cpu_to_le32(mode),
1204bb5dbf2cSVolodymyr Mytnyk 					.modes = __cpu_to_le64(modes),
1205bb5dbf2cSVolodymyr Mytnyk 				}
1206bb5dbf2cSVolodymyr Mytnyk 			}
1207bb5dbf2cSVolodymyr Mytnyk 		}
1208bb5dbf2cSVolodymyr Mytnyk 	};
1209bb5dbf2cSVolodymyr Mytnyk 
1210bb5dbf2cSVolodymyr Mytnyk 	req.param.link.phy.mdix = prestera_hw_mdix_from_eth(mdix);
1211bb5dbf2cSVolodymyr Mytnyk 
1212bb5dbf2cSVolodymyr Mytnyk 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET,
1213bb5dbf2cSVolodymyr Mytnyk 			    &req.cmd, sizeof(req));
1214bb5dbf2cSVolodymyr Mytnyk }
1215bb5dbf2cSVolodymyr Mytnyk 
prestera_hw_port_mtu_set(const struct prestera_port * port,u32 mtu)1216501ef306SVadym Kochan int prestera_hw_port_mtu_set(const struct prestera_port *port, u32 mtu)
1217501ef306SVadym Kochan {
1218501ef306SVadym Kochan 	struct prestera_msg_port_attr_req req = {
1219bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_MTU),
1220bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1221bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1222501ef306SVadym Kochan 		.param = {
1223bb5dbf2cSVolodymyr Mytnyk 			.mtu = __cpu_to_le32(mtu),
1224501ef306SVadym Kochan 		}
1225501ef306SVadym Kochan 	};
1226501ef306SVadym Kochan 
1227501ef306SVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET,
1228501ef306SVadym Kochan 			    &req.cmd, sizeof(req));
1229501ef306SVadym Kochan }
1230501ef306SVadym Kochan 
prestera_hw_port_mac_set(const struct prestera_port * port,const char * mac)1231501ef306SVadym Kochan int prestera_hw_port_mac_set(const struct prestera_port *port, const char *mac)
1232501ef306SVadym Kochan {
1233501ef306SVadym Kochan 	struct prestera_msg_port_attr_req req = {
1234bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_MAC),
1235bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1236bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1237501ef306SVadym Kochan 	};
1238501ef306SVadym Kochan 
1239501ef306SVadym Kochan 	ether_addr_copy(req.param.mac, mac);
1240501ef306SVadym Kochan 
1241501ef306SVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET,
1242501ef306SVadym Kochan 			    &req.cmd, sizeof(req));
1243501ef306SVadym Kochan }
1244501ef306SVadym Kochan 
prestera_hw_port_accept_frm_type(struct prestera_port * port,enum prestera_accept_frm_type type)1245e1189d9aSVadym Kochan int prestera_hw_port_accept_frm_type(struct prestera_port *port,
1246e1189d9aSVadym Kochan 				     enum prestera_accept_frm_type type)
1247e1189d9aSVadym Kochan {
1248e1189d9aSVadym Kochan 	struct prestera_msg_port_attr_req req = {
1249bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_ACCEPT_FRAME_TYPE),
1250bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1251bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1252e1189d9aSVadym Kochan 		.param = {
1253e1189d9aSVadym Kochan 			.accept_frm_type = type,
1254e1189d9aSVadym Kochan 		}
1255e1189d9aSVadym Kochan 	};
1256e1189d9aSVadym Kochan 
1257e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET,
1258e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1259e1189d9aSVadym Kochan }
1260e1189d9aSVadym Kochan 
prestera_hw_port_cap_get(const struct prestera_port * port,struct prestera_port_caps * caps)1261501ef306SVadym Kochan int prestera_hw_port_cap_get(const struct prestera_port *port,
1262501ef306SVadym Kochan 			     struct prestera_port_caps *caps)
1263501ef306SVadym Kochan {
1264501ef306SVadym Kochan 	struct prestera_msg_port_attr_req req = {
1265bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_CAPABILITY),
1266bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1267bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1268501ef306SVadym Kochan 	};
1269501ef306SVadym Kochan 	struct prestera_msg_port_attr_resp resp;
1270501ef306SVadym Kochan 	int err;
1271501ef306SVadym Kochan 
1272501ef306SVadym Kochan 	err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET,
1273501ef306SVadym Kochan 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
1274501ef306SVadym Kochan 	if (err)
1275501ef306SVadym Kochan 		return err;
1276501ef306SVadym Kochan 
1277bb5dbf2cSVolodymyr Mytnyk 	caps->supp_link_modes = __le64_to_cpu(resp.param.cap.link_mode);
1278501ef306SVadym Kochan 	caps->transceiver = resp.param.cap.transceiver;
1279501ef306SVadym Kochan 	caps->supp_fec = resp.param.cap.fec;
1280501ef306SVadym Kochan 	caps->type = resp.param.cap.type;
1281501ef306SVadym Kochan 
1282501ef306SVadym Kochan 	return err;
1283501ef306SVadym Kochan }
1284501ef306SVadym Kochan 
prestera_hw_remote_fc_to_eth(u8 fc,bool * pause,bool * asym_pause)1285bb5dbf2cSVolodymyr Mytnyk static void prestera_hw_remote_fc_to_eth(u8 fc, bool *pause, bool *asym_pause)
1286a97d3c69SVadym Kochan {
1287bb5dbf2cSVolodymyr Mytnyk 	switch (fc) {
1288a97d3c69SVadym Kochan 	case PRESTERA_FC_SYMMETRIC:
1289a97d3c69SVadym Kochan 		*pause = true;
1290a97d3c69SVadym Kochan 		*asym_pause = false;
1291a97d3c69SVadym Kochan 		break;
1292a97d3c69SVadym Kochan 	case PRESTERA_FC_ASYMMETRIC:
1293a97d3c69SVadym Kochan 		*pause = false;
1294a97d3c69SVadym Kochan 		*asym_pause = true;
1295a97d3c69SVadym Kochan 		break;
1296a97d3c69SVadym Kochan 	case PRESTERA_FC_SYMM_ASYMM:
1297a97d3c69SVadym Kochan 		*pause = true;
1298a97d3c69SVadym Kochan 		*asym_pause = true;
1299a97d3c69SVadym Kochan 		break;
1300a97d3c69SVadym Kochan 	default:
1301a97d3c69SVadym Kochan 		*pause = false;
1302a97d3c69SVadym Kochan 		*asym_pause = false;
1303a97d3c69SVadym Kochan 	}
1304a97d3c69SVadym Kochan }
1305a97d3c69SVadym Kochan 
prestera_hw_vtcam_create(struct prestera_switch * sw,u8 lookup,const u32 * keymask,u32 * vtcam_id,enum prestera_hw_vtcam_direction_t dir)130647327e19SVolodymyr Mytnyk int prestera_hw_vtcam_create(struct prestera_switch *sw,
130747327e19SVolodymyr Mytnyk 			     u8 lookup, const u32 *keymask, u32 *vtcam_id,
130847327e19SVolodymyr Mytnyk 			     enum prestera_hw_vtcam_direction_t dir)
13098b474a9fSSerhiy Boiko {
13108b474a9fSSerhiy Boiko 	int err;
131147327e19SVolodymyr Mytnyk 	struct prestera_msg_vtcam_resp resp;
131247327e19SVolodymyr Mytnyk 	struct prestera_msg_vtcam_create_req req = {
131347327e19SVolodymyr Mytnyk 		.lookup = lookup,
131447327e19SVolodymyr Mytnyk 		.direction = dir,
131547327e19SVolodymyr Mytnyk 	};
13168b474a9fSSerhiy Boiko 
131747327e19SVolodymyr Mytnyk 	if (keymask)
131847327e19SVolodymyr Mytnyk 		memcpy(req.keymask, keymask, sizeof(req.keymask));
131947327e19SVolodymyr Mytnyk 	else
132047327e19SVolodymyr Mytnyk 		memset(req.keymask, 0, sizeof(req.keymask));
132147327e19SVolodymyr Mytnyk 
132247327e19SVolodymyr Mytnyk 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_VTCAM_CREATE,
13238b474a9fSSerhiy Boiko 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
13248b474a9fSSerhiy Boiko 	if (err)
13258b474a9fSSerhiy Boiko 		return err;
13268b474a9fSSerhiy Boiko 
132747327e19SVolodymyr Mytnyk 	*vtcam_id = __le32_to_cpu(resp.vtcam_id);
13288b474a9fSSerhiy Boiko 	return 0;
13298b474a9fSSerhiy Boiko }
13308b474a9fSSerhiy Boiko 
prestera_hw_vtcam_destroy(struct prestera_switch * sw,u32 vtcam_id)133147327e19SVolodymyr Mytnyk int prestera_hw_vtcam_destroy(struct prestera_switch *sw, u32 vtcam_id)
13328b474a9fSSerhiy Boiko {
133347327e19SVolodymyr Mytnyk 	struct prestera_msg_vtcam_destroy_req req = {
133447327e19SVolodymyr Mytnyk 		.vtcam_id = __cpu_to_le32(vtcam_id),
13358b474a9fSSerhiy Boiko 	};
13368b474a9fSSerhiy Boiko 
133747327e19SVolodymyr Mytnyk 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_VTCAM_DESTROY,
13388b474a9fSSerhiy Boiko 			    &req.cmd, sizeof(req));
13398b474a9fSSerhiy Boiko }
13408b474a9fSSerhiy Boiko 
134147327e19SVolodymyr Mytnyk static int
prestera_acl_rule_add_put_action(struct prestera_msg_acl_action * action,struct prestera_acl_hw_action_info * info)134247327e19SVolodymyr Mytnyk prestera_acl_rule_add_put_action(struct prestera_msg_acl_action *action,
134347327e19SVolodymyr Mytnyk 				 struct prestera_acl_hw_action_info *info)
13448b474a9fSSerhiy Boiko {
134547327e19SVolodymyr Mytnyk 	action->id = __cpu_to_le32(info->id);
13468b474a9fSSerhiy Boiko 
134747327e19SVolodymyr Mytnyk 	switch (info->id) {
13488b474a9fSSerhiy Boiko 	case PRESTERA_ACL_RULE_ACTION_ACCEPT:
13498b474a9fSSerhiy Boiko 	case PRESTERA_ACL_RULE_ACTION_DROP:
13508b474a9fSSerhiy Boiko 	case PRESTERA_ACL_RULE_ACTION_TRAP:
13518b474a9fSSerhiy Boiko 		/* just rule action id, no specific data */
13528b474a9fSSerhiy Boiko 		break;
1353fa5d824cSVolodymyr Mytnyk 	case PRESTERA_ACL_RULE_ACTION_JUMP:
1354fa5d824cSVolodymyr Mytnyk 		action->jump.index = __cpu_to_le32(info->jump.index);
1355fa5d824cSVolodymyr Mytnyk 		break;
1356dde2daa0SVolodymyr Mytnyk 	case PRESTERA_ACL_RULE_ACTION_POLICE:
1357dde2daa0SVolodymyr Mytnyk 		action->police.id = __cpu_to_le32(info->police.id);
1358dde2daa0SVolodymyr Mytnyk 		break;
13596e36c7bcSVolodymyr Mytnyk 	case PRESTERA_ACL_RULE_ACTION_COUNT:
13606e36c7bcSVolodymyr Mytnyk 		action->count.id = __cpu_to_le32(info->count.id);
13616e36c7bcSVolodymyr Mytnyk 		break;
13628b474a9fSSerhiy Boiko 	default:
13638b474a9fSSerhiy Boiko 		return -EINVAL;
13648b474a9fSSerhiy Boiko 	}
13658b474a9fSSerhiy Boiko 
13668b474a9fSSerhiy Boiko 	return 0;
13678b474a9fSSerhiy Boiko }
13688b474a9fSSerhiy 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)136947327e19SVolodymyr Mytnyk int prestera_hw_vtcam_rule_add(struct prestera_switch *sw,
137047327e19SVolodymyr Mytnyk 			       u32 vtcam_id, u32 prio, void *key, void *keymask,
137147327e19SVolodymyr Mytnyk 			       struct prestera_acl_hw_action_info *act,
137247327e19SVolodymyr Mytnyk 			       u8 n_act, u32 *rule_id)
13738b474a9fSSerhiy Boiko {
137447327e19SVolodymyr Mytnyk 	struct prestera_msg_acl_action *actions_msg;
137547327e19SVolodymyr Mytnyk 	struct prestera_msg_vtcam_rule_add_req *req;
137647327e19SVolodymyr Mytnyk 	struct prestera_msg_vtcam_resp resp;
13778b474a9fSSerhiy Boiko 	void *buff;
13788b474a9fSSerhiy Boiko 	u32 size;
13798b474a9fSSerhiy Boiko 	int err;
138047327e19SVolodymyr Mytnyk 	u8 i;
13818b474a9fSSerhiy Boiko 
138247327e19SVolodymyr Mytnyk 	size = sizeof(*req) + sizeof(*actions_msg) * n_act;
13838b474a9fSSerhiy Boiko 
13848b474a9fSSerhiy Boiko 	buff = kzalloc(size, GFP_KERNEL);
13858b474a9fSSerhiy Boiko 	if (!buff)
13868b474a9fSSerhiy Boiko 		return -ENOMEM;
13878b474a9fSSerhiy Boiko 
13888b474a9fSSerhiy Boiko 	req = buff;
138947327e19SVolodymyr Mytnyk 	req->n_act = __cpu_to_le32(n_act);
139047327e19SVolodymyr Mytnyk 	actions_msg = buff + sizeof(*req);
13918b474a9fSSerhiy Boiko 
13928b474a9fSSerhiy Boiko 	/* put acl matches into the message */
139347327e19SVolodymyr Mytnyk 	memcpy(req->key, key, sizeof(req->key));
139447327e19SVolodymyr Mytnyk 	memcpy(req->keymask, keymask, sizeof(req->keymask));
139547327e19SVolodymyr Mytnyk 
139647327e19SVolodymyr Mytnyk 	/* put acl actions into the message */
139747327e19SVolodymyr Mytnyk 	for (i = 0; i < n_act; i++) {
139847327e19SVolodymyr Mytnyk 		err = prestera_acl_rule_add_put_action(&actions_msg[i],
139947327e19SVolodymyr Mytnyk 						       &act[i]);
14008b474a9fSSerhiy Boiko 		if (err)
14018b474a9fSSerhiy Boiko 			goto free_buff;
140247327e19SVolodymyr Mytnyk 	}
14038b474a9fSSerhiy Boiko 
140447327e19SVolodymyr Mytnyk 	req->vtcam_id = __cpu_to_le32(vtcam_id);
140547327e19SVolodymyr Mytnyk 	req->prio = __cpu_to_le32(prio);
14068b474a9fSSerhiy Boiko 
140747327e19SVolodymyr Mytnyk 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_VTCAM_RULE_ADD,
14088b474a9fSSerhiy Boiko 			       &req->cmd, size, &resp.ret, sizeof(resp));
14098b474a9fSSerhiy Boiko 	if (err)
14108b474a9fSSerhiy Boiko 		goto free_buff;
14118b474a9fSSerhiy Boiko 
141247327e19SVolodymyr Mytnyk 	*rule_id = __le32_to_cpu(resp.rule_id);
14138b474a9fSSerhiy Boiko free_buff:
14148b474a9fSSerhiy Boiko 	kfree(buff);
14158b474a9fSSerhiy Boiko 	return err;
14168b474a9fSSerhiy Boiko }
14178b474a9fSSerhiy Boiko 
prestera_hw_vtcam_rule_del(struct prestera_switch * sw,u32 vtcam_id,u32 rule_id)141847327e19SVolodymyr Mytnyk int prestera_hw_vtcam_rule_del(struct prestera_switch *sw,
141947327e19SVolodymyr Mytnyk 			       u32 vtcam_id, u32 rule_id)
14208b474a9fSSerhiy Boiko {
142147327e19SVolodymyr Mytnyk 	struct prestera_msg_vtcam_rule_del_req req = {
142247327e19SVolodymyr Mytnyk 		.vtcam_id = __cpu_to_le32(vtcam_id),
1423bb5dbf2cSVolodymyr Mytnyk 		.id = __cpu_to_le32(rule_id)
14248b474a9fSSerhiy Boiko 	};
14258b474a9fSSerhiy Boiko 
142647327e19SVolodymyr Mytnyk 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_VTCAM_RULE_DELETE,
14278b474a9fSSerhiy Boiko 			    &req.cmd, sizeof(req));
14288b474a9fSSerhiy Boiko }
14298b474a9fSSerhiy Boiko 
prestera_hw_vtcam_iface_bind(struct prestera_switch * sw,struct prestera_acl_iface * iface,u32 vtcam_id,u16 pcl_id)143047327e19SVolodymyr Mytnyk int prestera_hw_vtcam_iface_bind(struct prestera_switch *sw,
143147327e19SVolodymyr Mytnyk 				 struct prestera_acl_iface *iface,
143247327e19SVolodymyr Mytnyk 				 u32 vtcam_id, u16 pcl_id)
14338b474a9fSSerhiy Boiko {
143447327e19SVolodymyr Mytnyk 	struct prestera_msg_vtcam_bind_req req = {
143547327e19SVolodymyr Mytnyk 		.vtcam_id = __cpu_to_le32(vtcam_id),
143647327e19SVolodymyr Mytnyk 		.type = __cpu_to_le16(iface->type),
143747327e19SVolodymyr Mytnyk 		.pcl_id = __cpu_to_le16(pcl_id)
14388b474a9fSSerhiy Boiko 	};
14398b474a9fSSerhiy Boiko 
144047327e19SVolodymyr Mytnyk 	if (iface->type == PRESTERA_ACL_IFACE_TYPE_PORT) {
144147327e19SVolodymyr Mytnyk 		req.port.dev_id = __cpu_to_le32(iface->port->dev_id);
144247327e19SVolodymyr Mytnyk 		req.port.hw_id = __cpu_to_le32(iface->port->hw_id);
144347327e19SVolodymyr Mytnyk 	} else {
144447327e19SVolodymyr Mytnyk 		req.index = __cpu_to_le32(iface->index);
14458b474a9fSSerhiy Boiko 	}
14468b474a9fSSerhiy Boiko 
144747327e19SVolodymyr Mytnyk 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_VTCAM_IFACE_BIND,
14488b474a9fSSerhiy Boiko 			    &req.cmd, sizeof(req));
14498b474a9fSSerhiy Boiko }
14508b474a9fSSerhiy Boiko 
prestera_hw_vtcam_iface_unbind(struct prestera_switch * sw,struct prestera_acl_iface * iface,u32 vtcam_id)145147327e19SVolodymyr Mytnyk int prestera_hw_vtcam_iface_unbind(struct prestera_switch *sw,
145247327e19SVolodymyr Mytnyk 				   struct prestera_acl_iface *iface,
145347327e19SVolodymyr Mytnyk 				   u32 vtcam_id)
14548b474a9fSSerhiy Boiko {
145547327e19SVolodymyr Mytnyk 	struct prestera_msg_vtcam_bind_req req = {
145647327e19SVolodymyr Mytnyk 		.vtcam_id = __cpu_to_le32(vtcam_id),
145747327e19SVolodymyr Mytnyk 		.type = __cpu_to_le16(iface->type)
14588b474a9fSSerhiy Boiko 	};
14598b474a9fSSerhiy Boiko 
146047327e19SVolodymyr Mytnyk 	if (iface->type == PRESTERA_ACL_IFACE_TYPE_PORT) {
146147327e19SVolodymyr Mytnyk 		req.port.dev_id = __cpu_to_le32(iface->port->dev_id);
146247327e19SVolodymyr Mytnyk 		req.port.hw_id = __cpu_to_le32(iface->port->hw_id);
146347327e19SVolodymyr Mytnyk 	} else {
146447327e19SVolodymyr Mytnyk 		req.index = __cpu_to_le32(iface->index);
146547327e19SVolodymyr Mytnyk 	}
146647327e19SVolodymyr Mytnyk 
146747327e19SVolodymyr Mytnyk 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_VTCAM_IFACE_UNBIND,
14688b474a9fSSerhiy Boiko 			    &req.cmd, sizeof(req));
14698b474a9fSSerhiy Boiko }
14708b474a9fSSerhiy Boiko 
prestera_hw_span_get(const struct prestera_port * port,u8 * span_id)147113defa27SSerhiy Boiko int prestera_hw_span_get(const struct prestera_port *port, u8 *span_id)
147213defa27SSerhiy Boiko {
147313defa27SSerhiy Boiko 	struct prestera_msg_span_resp resp;
147413defa27SSerhiy Boiko 	struct prestera_msg_span_req req = {
1475bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1476bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
147713defa27SSerhiy Boiko 	};
147813defa27SSerhiy Boiko 	int err;
147913defa27SSerhiy Boiko 
148013defa27SSerhiy Boiko 	err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_SPAN_GET,
148113defa27SSerhiy Boiko 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
148213defa27SSerhiy Boiko 	if (err)
148313defa27SSerhiy Boiko 		return err;
148413defa27SSerhiy Boiko 
148513defa27SSerhiy Boiko 	*span_id = resp.id;
148613defa27SSerhiy Boiko 
148713defa27SSerhiy Boiko 	return 0;
148813defa27SSerhiy Boiko }
148913defa27SSerhiy Boiko 
prestera_hw_span_bind(const struct prestera_port * port,u8 span_id,bool ingress)14908c448c2bSSerhiy Boiko int prestera_hw_span_bind(const struct prestera_port *port, u8 span_id,
14918c448c2bSSerhiy Boiko 			  bool ingress)
149213defa27SSerhiy Boiko {
149313defa27SSerhiy Boiko 	struct prestera_msg_span_req req = {
1494bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1495bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
149613defa27SSerhiy Boiko 		.id = span_id,
149713defa27SSerhiy Boiko 	};
14988c448c2bSSerhiy Boiko 	enum prestera_cmd_type_t cmd_type;
149913defa27SSerhiy Boiko 
15008c448c2bSSerhiy Boiko 	if (ingress)
15018c448c2bSSerhiy Boiko 		cmd_type = PRESTERA_CMD_TYPE_SPAN_INGRESS_BIND;
15028c448c2bSSerhiy Boiko 	else
15038c448c2bSSerhiy Boiko 		cmd_type = PRESTERA_CMD_TYPE_SPAN_EGRESS_BIND;
15048c448c2bSSerhiy Boiko 
15058c448c2bSSerhiy Boiko 	return prestera_cmd(port->sw, cmd_type, &req.cmd, sizeof(req));
15068c448c2bSSerhiy Boiko 
150713defa27SSerhiy Boiko }
150813defa27SSerhiy Boiko 
prestera_hw_span_unbind(const struct prestera_port * port,bool ingress)15098c448c2bSSerhiy Boiko int prestera_hw_span_unbind(const struct prestera_port *port, bool ingress)
151013defa27SSerhiy Boiko {
151113defa27SSerhiy Boiko 	struct prestera_msg_span_req req = {
1512bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1513bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
151413defa27SSerhiy Boiko 	};
15158c448c2bSSerhiy Boiko 	enum prestera_cmd_type_t cmd_type;
151613defa27SSerhiy Boiko 
15178c448c2bSSerhiy Boiko 	if (ingress)
15188c448c2bSSerhiy Boiko 		cmd_type = PRESTERA_CMD_TYPE_SPAN_INGRESS_UNBIND;
15198c448c2bSSerhiy Boiko 	else
15208c448c2bSSerhiy Boiko 		cmd_type = PRESTERA_CMD_TYPE_SPAN_EGRESS_UNBIND;
15218c448c2bSSerhiy Boiko 
15228c448c2bSSerhiy Boiko 	return prestera_cmd(port->sw, cmd_type, &req.cmd, sizeof(req));
152313defa27SSerhiy Boiko }
152413defa27SSerhiy Boiko 
prestera_hw_span_release(struct prestera_switch * sw,u8 span_id)152513defa27SSerhiy Boiko int prestera_hw_span_release(struct prestera_switch *sw, u8 span_id)
152613defa27SSerhiy Boiko {
152713defa27SSerhiy Boiko 	struct prestera_msg_span_req req = {
152813defa27SSerhiy Boiko 		.id = span_id
152913defa27SSerhiy Boiko 	};
153013defa27SSerhiy Boiko 
153113defa27SSerhiy Boiko 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_SPAN_RELEASE,
153213defa27SSerhiy Boiko 			    &req.cmd, sizeof(req));
153313defa27SSerhiy Boiko }
153413defa27SSerhiy Boiko 
prestera_hw_port_type_get(const struct prestera_port * port,u8 * type)1535a97d3c69SVadym Kochan int prestera_hw_port_type_get(const struct prestera_port *port, u8 *type)
1536a97d3c69SVadym Kochan {
1537a97d3c69SVadym Kochan 	struct prestera_msg_port_attr_req req = {
1538bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_TYPE),
1539bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1540bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1541a97d3c69SVadym Kochan 	};
1542a97d3c69SVadym Kochan 	struct prestera_msg_port_attr_resp resp;
1543a97d3c69SVadym Kochan 	int err;
1544a97d3c69SVadym Kochan 
1545a97d3c69SVadym Kochan 	err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET,
1546a97d3c69SVadym Kochan 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
1547a97d3c69SVadym Kochan 	if (err)
1548a97d3c69SVadym Kochan 		return err;
1549a97d3c69SVadym Kochan 
1550a97d3c69SVadym Kochan 	*type = resp.param.type;
1551a97d3c69SVadym Kochan 
1552a97d3c69SVadym Kochan 	return 0;
1553a97d3c69SVadym Kochan }
1554a97d3c69SVadym Kochan 
prestera_hw_port_speed_get(const struct prestera_port * port,u32 * speed)1555a97d3c69SVadym Kochan int prestera_hw_port_speed_get(const struct prestera_port *port, u32 *speed)
1556a97d3c69SVadym Kochan {
1557a97d3c69SVadym Kochan 	struct prestera_msg_port_attr_req req = {
1558bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_SPEED),
1559bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1560bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1561a97d3c69SVadym Kochan 	};
1562a97d3c69SVadym Kochan 	struct prestera_msg_port_attr_resp resp;
1563a97d3c69SVadym Kochan 	int err;
1564a97d3c69SVadym Kochan 
1565a97d3c69SVadym Kochan 	err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET,
1566a97d3c69SVadym Kochan 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
1567a97d3c69SVadym Kochan 	if (err)
1568a97d3c69SVadym Kochan 		return err;
1569a97d3c69SVadym Kochan 
1570bb5dbf2cSVolodymyr Mytnyk 	*speed = __le32_to_cpu(resp.param.speed);
1571a97d3c69SVadym Kochan 
1572a97d3c69SVadym Kochan 	return 0;
1573a97d3c69SVadym Kochan }
1574a97d3c69SVadym Kochan 
prestera_hw_port_autoneg_restart(struct prestera_port * port)1575a97d3c69SVadym Kochan int prestera_hw_port_autoneg_restart(struct prestera_port *port)
1576a97d3c69SVadym Kochan {
1577a97d3c69SVadym Kochan 	struct prestera_msg_port_attr_req req = {
1578a46a5036SVolodymyr Mytnyk 		.attr =
1579a46a5036SVolodymyr Mytnyk 		    __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_PHY_AUTONEG_RESTART),
1580bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1581bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1582a97d3c69SVadym Kochan 	};
1583a97d3c69SVadym Kochan 
1584a97d3c69SVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET,
1585a97d3c69SVadym Kochan 			    &req.cmd, sizeof(req));
1586a97d3c69SVadym Kochan }
1587a97d3c69SVadym Kochan 
prestera_hw_port_stats_get(const struct prestera_port * port,struct prestera_port_stats * st)1588501ef306SVadym Kochan int prestera_hw_port_stats_get(const struct prestera_port *port,
1589501ef306SVadym Kochan 			       struct prestera_port_stats *st)
1590501ef306SVadym Kochan {
1591501ef306SVadym Kochan 	struct prestera_msg_port_attr_req req = {
1592bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_STATS),
1593bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1594bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1595501ef306SVadym Kochan 	};
1596501ef306SVadym Kochan 	struct prestera_msg_port_stats_resp resp;
1597bb5dbf2cSVolodymyr Mytnyk 	__le64 *hw = resp.stats;
1598501ef306SVadym Kochan 	int err;
1599501ef306SVadym Kochan 
1600501ef306SVadym Kochan 	err = prestera_cmd_ret(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_GET,
1601501ef306SVadym Kochan 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
1602501ef306SVadym Kochan 	if (err)
1603501ef306SVadym Kochan 		return err;
1604501ef306SVadym Kochan 
1605bb5dbf2cSVolodymyr Mytnyk 	st->good_octets_received =
1606bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_GOOD_OCTETS_RCV_CNT]);
1607bb5dbf2cSVolodymyr Mytnyk 	st->bad_octets_received =
1608bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_BAD_OCTETS_RCV_CNT]);
1609bb5dbf2cSVolodymyr Mytnyk 	st->mac_trans_error =
1610bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_MAC_TRANSMIT_ERR_CNT]);
1611bb5dbf2cSVolodymyr Mytnyk 	st->broadcast_frames_received =
1612bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_BRDC_PKTS_RCV_CNT]);
1613bb5dbf2cSVolodymyr Mytnyk 	st->multicast_frames_received =
1614bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_MC_PKTS_RCV_CNT]);
1615bb5dbf2cSVolodymyr Mytnyk 	st->frames_64_octets = __le64_to_cpu(hw[PRESTERA_PORT_PKTS_64L_CNT]);
1616bb5dbf2cSVolodymyr Mytnyk 	st->frames_65_to_127_octets =
1617bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_PKTS_65TO127L_CNT]);
1618bb5dbf2cSVolodymyr Mytnyk 	st->frames_128_to_255_octets =
1619bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_PKTS_128TO255L_CNT]);
1620bb5dbf2cSVolodymyr Mytnyk 	st->frames_256_to_511_octets =
1621bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_PKTS_256TO511L_CNT]);
1622bb5dbf2cSVolodymyr Mytnyk 	st->frames_512_to_1023_octets =
1623bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_PKTS_512TO1023L_CNT]);
1624bb5dbf2cSVolodymyr Mytnyk 	st->frames_1024_to_max_octets =
1625bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_PKTS_1024TOMAXL_CNT]);
1626bb5dbf2cSVolodymyr Mytnyk 	st->excessive_collision =
1627bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_EXCESSIVE_COLLISIONS_CNT]);
1628bb5dbf2cSVolodymyr Mytnyk 	st->multicast_frames_sent =
1629bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_MC_PKTS_SENT_CNT]);
1630bb5dbf2cSVolodymyr Mytnyk 	st->broadcast_frames_sent =
1631bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_BRDC_PKTS_SENT_CNT]);
1632bb5dbf2cSVolodymyr Mytnyk 	st->fc_sent = __le64_to_cpu(hw[PRESTERA_PORT_FC_SENT_CNT]);
1633bb5dbf2cSVolodymyr Mytnyk 	st->fc_received = __le64_to_cpu(hw[PRESTERA_PORT_GOOD_FC_RCV_CNT]);
1634bb5dbf2cSVolodymyr Mytnyk 	st->buffer_overrun = __le64_to_cpu(hw[PRESTERA_PORT_DROP_EVENTS_CNT]);
1635bb5dbf2cSVolodymyr Mytnyk 	st->undersize = __le64_to_cpu(hw[PRESTERA_PORT_UNDERSIZE_PKTS_CNT]);
1636bb5dbf2cSVolodymyr Mytnyk 	st->fragments = __le64_to_cpu(hw[PRESTERA_PORT_FRAGMENTS_PKTS_CNT]);
1637bb5dbf2cSVolodymyr Mytnyk 	st->oversize = __le64_to_cpu(hw[PRESTERA_PORT_OVERSIZE_PKTS_CNT]);
1638bb5dbf2cSVolodymyr Mytnyk 	st->jabber = __le64_to_cpu(hw[PRESTERA_PORT_JABBER_PKTS_CNT]);
1639bb5dbf2cSVolodymyr Mytnyk 	st->rx_error_frame_received =
1640bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_MAC_RCV_ERROR_CNT]);
1641bb5dbf2cSVolodymyr Mytnyk 	st->bad_crc = __le64_to_cpu(hw[PRESTERA_PORT_BAD_CRC_CNT]);
1642bb5dbf2cSVolodymyr Mytnyk 	st->collisions = __le64_to_cpu(hw[PRESTERA_PORT_COLLISIONS_CNT]);
1643bb5dbf2cSVolodymyr Mytnyk 	st->late_collision =
1644bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_LATE_COLLISIONS_CNT]);
1645bb5dbf2cSVolodymyr Mytnyk 	st->unicast_frames_received =
1646bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_GOOD_UC_PKTS_RCV_CNT]);
1647bb5dbf2cSVolodymyr Mytnyk 	st->unicast_frames_sent =
1648bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_GOOD_UC_PKTS_SENT_CNT]);
1649bb5dbf2cSVolodymyr Mytnyk 	st->sent_multiple =
1650bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_MULTIPLE_PKTS_SENT_CNT]);
1651bb5dbf2cSVolodymyr Mytnyk 	st->sent_deferred =
1652bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_DEFERRED_PKTS_SENT_CNT]);
1653bb5dbf2cSVolodymyr Mytnyk 	st->good_octets_sent =
1654bb5dbf2cSVolodymyr Mytnyk 		__le64_to_cpu(hw[PRESTERA_PORT_GOOD_OCTETS_SENT_CNT]);
1655501ef306SVadym Kochan 
1656501ef306SVadym Kochan 	return 0;
1657501ef306SVadym Kochan }
1658501ef306SVadym Kochan 
prestera_hw_port_learning_set(struct prestera_port * port,bool enable)1659e1189d9aSVadym Kochan int prestera_hw_port_learning_set(struct prestera_port *port, bool enable)
1660e1189d9aSVadym Kochan {
1661e1189d9aSVadym Kochan 	struct prestera_msg_port_attr_req req = {
1662bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_LEARNING),
1663bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1664bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1665e1189d9aSVadym Kochan 		.param = {
1666e1189d9aSVadym Kochan 			.learning = enable,
1667e1189d9aSVadym Kochan 		}
1668e1189d9aSVadym Kochan 	};
1669e1189d9aSVadym Kochan 
1670e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET,
1671e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1672e1189d9aSVadym Kochan }
1673e1189d9aSVadym Kochan 
prestera_hw_port_uc_flood_set(const struct prestera_port * port,bool flood)1674116f5af7SOleksandr Mazur int prestera_hw_port_uc_flood_set(const struct prestera_port *port, bool flood)
1675c00e8a69SVadym Kochan {
1676c00e8a69SVadym Kochan 	struct prestera_msg_port_attr_req req = {
1677bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_FLOOD),
1678bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1679bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1680c00e8a69SVadym Kochan 		.param = {
1681c00e8a69SVadym Kochan 			.flood_ext = {
1682c00e8a69SVadym Kochan 				.type = PRESTERA_PORT_FLOOD_TYPE_UC,
1683c00e8a69SVadym Kochan 				.enable = flood,
1684c00e8a69SVadym Kochan 			}
1685c00e8a69SVadym Kochan 		}
1686c00e8a69SVadym Kochan 	};
1687c00e8a69SVadym Kochan 
1688c00e8a69SVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET,
1689c00e8a69SVadym Kochan 			    &req.cmd, sizeof(req));
1690c00e8a69SVadym Kochan }
1691c00e8a69SVadym Kochan 
prestera_hw_port_mc_flood_set(const struct prestera_port * port,bool flood)1692116f5af7SOleksandr Mazur int prestera_hw_port_mc_flood_set(const struct prestera_port *port, bool flood)
1693c00e8a69SVadym Kochan {
1694c00e8a69SVadym Kochan 	struct prestera_msg_port_attr_req req = {
1695bb5dbf2cSVolodymyr Mytnyk 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_FLOOD),
1696bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1697bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1698c00e8a69SVadym Kochan 		.param = {
1699c00e8a69SVadym Kochan 			.flood_ext = {
1700c00e8a69SVadym Kochan 				.type = PRESTERA_PORT_FLOOD_TYPE_MC,
1701c00e8a69SVadym Kochan 				.enable = flood,
1702c00e8a69SVadym Kochan 			}
1703c00e8a69SVadym Kochan 		}
1704c00e8a69SVadym Kochan 	};
1705c00e8a69SVadym Kochan 
1706c00e8a69SVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET,
1707c00e8a69SVadym Kochan 			    &req.cmd, sizeof(req));
1708c00e8a69SVadym Kochan }
1709c00e8a69SVadym Kochan 
prestera_hw_port_br_locked_set(const struct prestera_port * port,bool br_locked)171073ef239cSOleksandr Mazur int prestera_hw_port_br_locked_set(const struct prestera_port *port,
171173ef239cSOleksandr Mazur 				   bool br_locked)
171273ef239cSOleksandr Mazur {
171373ef239cSOleksandr Mazur 	struct prestera_msg_port_attr_req req = {
171473ef239cSOleksandr Mazur 		.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_LOCKED),
171573ef239cSOleksandr Mazur 		.port = __cpu_to_le32(port->hw_id),
171673ef239cSOleksandr Mazur 		.dev = __cpu_to_le32(port->dev_id),
171773ef239cSOleksandr Mazur 		.param = {
171873ef239cSOleksandr Mazur 			.br_locked = br_locked,
171973ef239cSOleksandr Mazur 		}
172073ef239cSOleksandr Mazur 	};
172173ef239cSOleksandr Mazur 
172273ef239cSOleksandr Mazur 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_PORT_ATTR_SET,
172373ef239cSOleksandr Mazur 			    &req.cmd, sizeof(req));
172473ef239cSOleksandr Mazur }
172573ef239cSOleksandr Mazur 
prestera_hw_vlan_create(struct prestera_switch * sw,u16 vid)1726e1189d9aSVadym Kochan int prestera_hw_vlan_create(struct prestera_switch *sw, u16 vid)
1727e1189d9aSVadym Kochan {
1728e1189d9aSVadym Kochan 	struct prestera_msg_vlan_req req = {
1729bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1730e1189d9aSVadym Kochan 	};
1731e1189d9aSVadym Kochan 
1732e1189d9aSVadym Kochan 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_VLAN_CREATE,
1733e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1734e1189d9aSVadym Kochan }
1735e1189d9aSVadym Kochan 
prestera_hw_vlan_delete(struct prestera_switch * sw,u16 vid)1736e1189d9aSVadym Kochan int prestera_hw_vlan_delete(struct prestera_switch *sw, u16 vid)
1737e1189d9aSVadym Kochan {
1738e1189d9aSVadym Kochan 	struct prestera_msg_vlan_req req = {
1739bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1740e1189d9aSVadym Kochan 	};
1741e1189d9aSVadym Kochan 
1742e1189d9aSVadym Kochan 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_VLAN_DELETE,
1743e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1744e1189d9aSVadym Kochan }
1745e1189d9aSVadym Kochan 
prestera_hw_vlan_port_set(struct prestera_port * port,u16 vid,bool is_member,bool untagged)1746e1189d9aSVadym Kochan int prestera_hw_vlan_port_set(struct prestera_port *port, u16 vid,
1747e1189d9aSVadym Kochan 			      bool is_member, bool untagged)
1748e1189d9aSVadym Kochan {
1749e1189d9aSVadym Kochan 	struct prestera_msg_vlan_req req = {
1750bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1751bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1752bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1753e1189d9aSVadym Kochan 		.is_member = is_member,
1754e1189d9aSVadym Kochan 		.is_tagged = !untagged,
1755e1189d9aSVadym Kochan 	};
1756e1189d9aSVadym Kochan 
1757e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_VLAN_PORT_SET,
1758e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1759e1189d9aSVadym Kochan }
1760e1189d9aSVadym Kochan 
prestera_hw_vlan_port_vid_set(struct prestera_port * port,u16 vid)1761e1189d9aSVadym Kochan int prestera_hw_vlan_port_vid_set(struct prestera_port *port, u16 vid)
1762e1189d9aSVadym Kochan {
1763e1189d9aSVadym Kochan 	struct prestera_msg_vlan_req req = {
1764bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1765bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1766bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1767e1189d9aSVadym Kochan 	};
1768e1189d9aSVadym Kochan 
1769e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_VLAN_PVID_SET,
1770e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1771e1189d9aSVadym Kochan }
1772e1189d9aSVadym Kochan 
prestera_hw_vlan_port_stp_set(struct prestera_port * port,u16 vid,u8 state)1773e1189d9aSVadym Kochan int prestera_hw_vlan_port_stp_set(struct prestera_port *port, u16 vid, u8 state)
1774e1189d9aSVadym Kochan {
1775e1189d9aSVadym Kochan 	struct prestera_msg_stp_req req = {
1776bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1777bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1778bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1779e1189d9aSVadym Kochan 		.state = state,
1780e1189d9aSVadym Kochan 	};
1781e1189d9aSVadym Kochan 
1782e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_STP_PORT_SET,
1783e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1784e1189d9aSVadym Kochan }
1785e1189d9aSVadym Kochan 
prestera_hw_fdb_add(struct prestera_port * port,const unsigned char * mac,u16 vid,bool dynamic)1786e1189d9aSVadym Kochan int prestera_hw_fdb_add(struct prestera_port *port, const unsigned char *mac,
1787e1189d9aSVadym Kochan 			u16 vid, bool dynamic)
1788e1189d9aSVadym Kochan {
1789e1189d9aSVadym Kochan 	struct prestera_msg_fdb_req req = {
1790255213caSSerhiy Boiko 		.dest = {
1791bb5dbf2cSVolodymyr Mytnyk 			.dev = __cpu_to_le32(port->dev_id),
1792bb5dbf2cSVolodymyr Mytnyk 			.port = __cpu_to_le32(port->hw_id),
1793255213caSSerhiy Boiko 		},
1794bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1795e1189d9aSVadym Kochan 		.dynamic = dynamic,
1796e1189d9aSVadym Kochan 	};
1797e1189d9aSVadym Kochan 
1798e1189d9aSVadym Kochan 	ether_addr_copy(req.mac, mac);
1799e1189d9aSVadym Kochan 
1800e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_FDB_ADD,
1801e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1802e1189d9aSVadym Kochan }
1803e1189d9aSVadym Kochan 
prestera_hw_fdb_del(struct prestera_port * port,const unsigned char * mac,u16 vid)1804e1189d9aSVadym Kochan int prestera_hw_fdb_del(struct prestera_port *port, const unsigned char *mac,
1805e1189d9aSVadym Kochan 			u16 vid)
1806e1189d9aSVadym Kochan {
1807e1189d9aSVadym Kochan 	struct prestera_msg_fdb_req req = {
1808255213caSSerhiy Boiko 		.dest = {
1809bb5dbf2cSVolodymyr Mytnyk 			.dev = __cpu_to_le32(port->dev_id),
1810bb5dbf2cSVolodymyr Mytnyk 			.port = __cpu_to_le32(port->hw_id),
1811255213caSSerhiy Boiko 		},
1812bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1813e1189d9aSVadym Kochan 	};
1814e1189d9aSVadym Kochan 
1815e1189d9aSVadym Kochan 	ether_addr_copy(req.mac, mac);
1816e1189d9aSVadym Kochan 
1817e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_FDB_DELETE,
1818e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1819e1189d9aSVadym Kochan }
1820e1189d9aSVadym Kochan 
prestera_hw_lag_fdb_add(struct prestera_switch * sw,u16 lag_id,const unsigned char * mac,u16 vid,bool dynamic)1821255213caSSerhiy Boiko int prestera_hw_lag_fdb_add(struct prestera_switch *sw, u16 lag_id,
1822255213caSSerhiy Boiko 			    const unsigned char *mac, u16 vid, bool dynamic)
1823255213caSSerhiy Boiko {
1824255213caSSerhiy Boiko 	struct prestera_msg_fdb_req req = {
1825255213caSSerhiy Boiko 		.dest_type = PRESTERA_HW_FDB_ENTRY_TYPE_LAG,
1826255213caSSerhiy Boiko 		.dest = {
1827bb5dbf2cSVolodymyr Mytnyk 			.lag_id = __cpu_to_le16(lag_id),
1828255213caSSerhiy Boiko 		},
1829bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1830255213caSSerhiy Boiko 		.dynamic = dynamic,
1831255213caSSerhiy Boiko 	};
1832255213caSSerhiy Boiko 
1833255213caSSerhiy Boiko 	ether_addr_copy(req.mac, mac);
1834255213caSSerhiy Boiko 
1835255213caSSerhiy Boiko 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_FDB_ADD,
1836255213caSSerhiy Boiko 			    &req.cmd, sizeof(req));
1837255213caSSerhiy Boiko }
1838255213caSSerhiy Boiko 
prestera_hw_lag_fdb_del(struct prestera_switch * sw,u16 lag_id,const unsigned char * mac,u16 vid)1839255213caSSerhiy Boiko int prestera_hw_lag_fdb_del(struct prestera_switch *sw, u16 lag_id,
1840255213caSSerhiy Boiko 			    const unsigned char *mac, u16 vid)
1841255213caSSerhiy Boiko {
1842255213caSSerhiy Boiko 	struct prestera_msg_fdb_req req = {
1843255213caSSerhiy Boiko 		.dest_type = PRESTERA_HW_FDB_ENTRY_TYPE_LAG,
1844255213caSSerhiy Boiko 		.dest = {
1845bb5dbf2cSVolodymyr Mytnyk 			.lag_id = __cpu_to_le16(lag_id),
1846255213caSSerhiy Boiko 		},
1847bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1848255213caSSerhiy Boiko 	};
1849255213caSSerhiy Boiko 
1850255213caSSerhiy Boiko 	ether_addr_copy(req.mac, mac);
1851255213caSSerhiy Boiko 
1852255213caSSerhiy Boiko 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_FDB_DELETE,
1853255213caSSerhiy Boiko 			    &req.cmd, sizeof(req));
1854255213caSSerhiy Boiko }
1855255213caSSerhiy Boiko 
prestera_hw_fdb_flush_port(struct prestera_port * port,u32 mode)1856e1189d9aSVadym Kochan int prestera_hw_fdb_flush_port(struct prestera_port *port, u32 mode)
1857e1189d9aSVadym Kochan {
1858e1189d9aSVadym Kochan 	struct prestera_msg_fdb_req req = {
1859255213caSSerhiy Boiko 		.dest = {
1860bb5dbf2cSVolodymyr Mytnyk 			.dev = __cpu_to_le32(port->dev_id),
1861bb5dbf2cSVolodymyr Mytnyk 			.port = __cpu_to_le32(port->hw_id),
1862255213caSSerhiy Boiko 		},
1863bb5dbf2cSVolodymyr Mytnyk 		.flush_mode = __cpu_to_le32(mode),
1864e1189d9aSVadym Kochan 	};
1865e1189d9aSVadym Kochan 
1866e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_FDB_FLUSH_PORT,
1867e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1868e1189d9aSVadym Kochan }
1869e1189d9aSVadym Kochan 
prestera_hw_fdb_flush_vlan(struct prestera_switch * sw,u16 vid,u32 mode)1870e1189d9aSVadym Kochan int prestera_hw_fdb_flush_vlan(struct prestera_switch *sw, u16 vid, u32 mode)
1871e1189d9aSVadym Kochan {
1872e1189d9aSVadym Kochan 	struct prestera_msg_fdb_req req = {
1873bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1874bb5dbf2cSVolodymyr Mytnyk 		.flush_mode = __cpu_to_le32(mode),
1875e1189d9aSVadym Kochan 	};
1876e1189d9aSVadym Kochan 
1877e1189d9aSVadym Kochan 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_FDB_FLUSH_VLAN,
1878e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1879e1189d9aSVadym Kochan }
1880e1189d9aSVadym Kochan 
prestera_hw_fdb_flush_port_vlan(struct prestera_port * port,u16 vid,u32 mode)1881e1189d9aSVadym Kochan int prestera_hw_fdb_flush_port_vlan(struct prestera_port *port, u16 vid,
1882e1189d9aSVadym Kochan 				    u32 mode)
1883e1189d9aSVadym Kochan {
1884e1189d9aSVadym Kochan 	struct prestera_msg_fdb_req req = {
1885255213caSSerhiy Boiko 		.dest = {
1886bb5dbf2cSVolodymyr Mytnyk 			.dev = __cpu_to_le32(port->dev_id),
1887bb5dbf2cSVolodymyr Mytnyk 			.port = __cpu_to_le32(port->hw_id),
1888255213caSSerhiy Boiko 		},
1889bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1890bb5dbf2cSVolodymyr Mytnyk 		.flush_mode = __cpu_to_le32(mode),
1891e1189d9aSVadym Kochan 	};
1892e1189d9aSVadym Kochan 
1893e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_FDB_FLUSH_PORT_VLAN,
1894e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1895e1189d9aSVadym Kochan }
1896e1189d9aSVadym Kochan 
prestera_hw_fdb_flush_lag(struct prestera_switch * sw,u16 lag_id,u32 mode)1897255213caSSerhiy Boiko int prestera_hw_fdb_flush_lag(struct prestera_switch *sw, u16 lag_id,
1898255213caSSerhiy Boiko 			      u32 mode)
1899255213caSSerhiy Boiko {
1900255213caSSerhiy Boiko 	struct prestera_msg_fdb_req req = {
1901255213caSSerhiy Boiko 		.dest_type = PRESTERA_HW_FDB_ENTRY_TYPE_LAG,
1902255213caSSerhiy Boiko 		.dest = {
1903bb5dbf2cSVolodymyr Mytnyk 			.lag_id = __cpu_to_le16(lag_id),
1904255213caSSerhiy Boiko 		},
1905bb5dbf2cSVolodymyr Mytnyk 		.flush_mode = __cpu_to_le32(mode),
1906255213caSSerhiy Boiko 	};
1907255213caSSerhiy Boiko 
1908255213caSSerhiy Boiko 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_FDB_FLUSH_PORT,
1909255213caSSerhiy Boiko 			    &req.cmd, sizeof(req));
1910255213caSSerhiy Boiko }
1911255213caSSerhiy Boiko 
prestera_hw_fdb_flush_lag_vlan(struct prestera_switch * sw,u16 lag_id,u16 vid,u32 mode)1912255213caSSerhiy Boiko int prestera_hw_fdb_flush_lag_vlan(struct prestera_switch *sw,
1913255213caSSerhiy Boiko 				   u16 lag_id, u16 vid, u32 mode)
1914255213caSSerhiy Boiko {
1915255213caSSerhiy Boiko 	struct prestera_msg_fdb_req req = {
1916255213caSSerhiy Boiko 		.dest_type = PRESTERA_HW_FDB_ENTRY_TYPE_LAG,
1917255213caSSerhiy Boiko 		.dest = {
1918bb5dbf2cSVolodymyr Mytnyk 			.lag_id = __cpu_to_le16(lag_id),
1919255213caSSerhiy Boiko 		},
1920bb5dbf2cSVolodymyr Mytnyk 		.vid = __cpu_to_le16(vid),
1921bb5dbf2cSVolodymyr Mytnyk 		.flush_mode = __cpu_to_le32(mode),
1922255213caSSerhiy Boiko 	};
1923255213caSSerhiy Boiko 
1924255213caSSerhiy Boiko 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_FDB_FLUSH_PORT_VLAN,
1925255213caSSerhiy Boiko 			    &req.cmd, sizeof(req));
1926255213caSSerhiy Boiko }
1927255213caSSerhiy Boiko 
prestera_hw_bridge_create(struct prestera_switch * sw,u16 * bridge_id)1928e1189d9aSVadym Kochan int prestera_hw_bridge_create(struct prestera_switch *sw, u16 *bridge_id)
1929e1189d9aSVadym Kochan {
1930e1189d9aSVadym Kochan 	struct prestera_msg_bridge_resp resp;
1931e1189d9aSVadym Kochan 	struct prestera_msg_bridge_req req;
1932e1189d9aSVadym Kochan 	int err;
1933e1189d9aSVadym Kochan 
1934e1189d9aSVadym Kochan 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_BRIDGE_CREATE,
1935e1189d9aSVadym Kochan 			       &req.cmd, sizeof(req),
1936e1189d9aSVadym Kochan 			       &resp.ret, sizeof(resp));
1937e1189d9aSVadym Kochan 	if (err)
1938e1189d9aSVadym Kochan 		return err;
1939e1189d9aSVadym Kochan 
1940bb5dbf2cSVolodymyr Mytnyk 	*bridge_id = __le16_to_cpu(resp.bridge);
1941e1189d9aSVadym Kochan 
1942e1189d9aSVadym Kochan 	return 0;
1943e1189d9aSVadym Kochan }
1944e1189d9aSVadym Kochan 
prestera_hw_bridge_delete(struct prestera_switch * sw,u16 bridge_id)1945e1189d9aSVadym Kochan int prestera_hw_bridge_delete(struct prestera_switch *sw, u16 bridge_id)
1946e1189d9aSVadym Kochan {
1947e1189d9aSVadym Kochan 	struct prestera_msg_bridge_req req = {
1948bb5dbf2cSVolodymyr Mytnyk 		.bridge = __cpu_to_le16(bridge_id),
1949e1189d9aSVadym Kochan 	};
1950e1189d9aSVadym Kochan 
1951e1189d9aSVadym Kochan 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_BRIDGE_DELETE,
1952e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1953e1189d9aSVadym Kochan }
1954e1189d9aSVadym Kochan 
prestera_hw_bridge_port_add(struct prestera_port * port,u16 bridge_id)1955e1189d9aSVadym Kochan int prestera_hw_bridge_port_add(struct prestera_port *port, u16 bridge_id)
1956e1189d9aSVadym Kochan {
1957e1189d9aSVadym Kochan 	struct prestera_msg_bridge_req req = {
1958bb5dbf2cSVolodymyr Mytnyk 		.bridge = __cpu_to_le16(bridge_id),
1959bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1960bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1961e1189d9aSVadym Kochan 	};
1962e1189d9aSVadym Kochan 
1963e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_BRIDGE_PORT_ADD,
1964e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1965e1189d9aSVadym Kochan }
1966e1189d9aSVadym Kochan 
prestera_hw_bridge_port_delete(struct prestera_port * port,u16 bridge_id)1967e1189d9aSVadym Kochan int prestera_hw_bridge_port_delete(struct prestera_port *port, u16 bridge_id)
1968e1189d9aSVadym Kochan {
1969e1189d9aSVadym Kochan 	struct prestera_msg_bridge_req req = {
1970bb5dbf2cSVolodymyr Mytnyk 		.bridge = __cpu_to_le16(bridge_id),
1971bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
1972bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
1973e1189d9aSVadym Kochan 	};
1974e1189d9aSVadym Kochan 
1975e1189d9aSVadym Kochan 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_BRIDGE_PORT_DELETE,
1976e1189d9aSVadym Kochan 			    &req.cmd, sizeof(req));
1977e1189d9aSVadym Kochan }
1978e1189d9aSVadym Kochan 
prestera_iface_to_msg(struct prestera_iface * iface,struct prestera_msg_iface * msg_if)19790f07bd6bSYevhen Orlov static int prestera_iface_to_msg(struct prestera_iface *iface,
19800f07bd6bSYevhen Orlov 				 struct prestera_msg_iface *msg_if)
19810f07bd6bSYevhen Orlov {
19820f07bd6bSYevhen Orlov 	switch (iface->type) {
19830f07bd6bSYevhen Orlov 	case PRESTERA_IF_PORT_E:
19840f07bd6bSYevhen Orlov 	case PRESTERA_IF_VID_E:
19850f07bd6bSYevhen Orlov 		msg_if->port = __cpu_to_le32(iface->dev_port.port_num);
19860f07bd6bSYevhen Orlov 		msg_if->dev = __cpu_to_le32(iface->dev_port.hw_dev_num);
19870f07bd6bSYevhen Orlov 		break;
19880f07bd6bSYevhen Orlov 	case PRESTERA_IF_LAG_E:
19890f07bd6bSYevhen Orlov 		msg_if->lag_id = __cpu_to_le16(iface->lag_id);
19900f07bd6bSYevhen Orlov 		break;
19910f07bd6bSYevhen Orlov 	default:
19920f07bd6bSYevhen Orlov 		return -EOPNOTSUPP;
19930f07bd6bSYevhen Orlov 	}
19940f07bd6bSYevhen Orlov 
19950f07bd6bSYevhen Orlov 	msg_if->vr_id = __cpu_to_le16(iface->vr_id);
19960f07bd6bSYevhen Orlov 	msg_if->vid = __cpu_to_le16(iface->vlan_id);
19970f07bd6bSYevhen Orlov 	msg_if->type = iface->type;
19980f07bd6bSYevhen Orlov 	return 0;
19990f07bd6bSYevhen Orlov }
20000f07bd6bSYevhen Orlov 
prestera_hw_rif_create(struct prestera_switch * sw,struct prestera_iface * iif,u8 * mac,u16 * rif_id)20010f07bd6bSYevhen Orlov int prestera_hw_rif_create(struct prestera_switch *sw,
20020f07bd6bSYevhen Orlov 			   struct prestera_iface *iif, u8 *mac, u16 *rif_id)
20030f07bd6bSYevhen Orlov {
20040f07bd6bSYevhen Orlov 	struct prestera_msg_rif_resp resp;
200532d098bbSYevhen Orlov 	struct prestera_msg_rif_req req;
20060f07bd6bSYevhen Orlov 	int err;
20070f07bd6bSYevhen Orlov 
20080f07bd6bSYevhen Orlov 	memcpy(req.mac, mac, ETH_ALEN);
20090f07bd6bSYevhen Orlov 
20100f07bd6bSYevhen Orlov 	err = prestera_iface_to_msg(iif, &req.iif);
20110f07bd6bSYevhen Orlov 	if (err)
20120f07bd6bSYevhen Orlov 		return err;
20130f07bd6bSYevhen Orlov 
20140f07bd6bSYevhen Orlov 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_ROUTER_RIF_CREATE,
20150f07bd6bSYevhen Orlov 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
20160f07bd6bSYevhen Orlov 	if (err)
20170f07bd6bSYevhen Orlov 		return err;
20180f07bd6bSYevhen Orlov 
20190f07bd6bSYevhen Orlov 	*rif_id = __le16_to_cpu(resp.rif_id);
20200f07bd6bSYevhen Orlov 	return err;
20210f07bd6bSYevhen Orlov }
20220f07bd6bSYevhen Orlov 
prestera_hw_rif_delete(struct prestera_switch * sw,u16 rif_id,struct prestera_iface * iif)20230f07bd6bSYevhen Orlov int prestera_hw_rif_delete(struct prestera_switch *sw, u16 rif_id,
20240f07bd6bSYevhen Orlov 			   struct prestera_iface *iif)
20250f07bd6bSYevhen Orlov {
20260f07bd6bSYevhen Orlov 	struct prestera_msg_rif_req req = {
20270f07bd6bSYevhen Orlov 		.rif_id = __cpu_to_le16(rif_id),
20280f07bd6bSYevhen Orlov 	};
20290f07bd6bSYevhen Orlov 	int err;
20300f07bd6bSYevhen Orlov 
20310f07bd6bSYevhen Orlov 	err = prestera_iface_to_msg(iif, &req.iif);
20320f07bd6bSYevhen Orlov 	if (err)
20330f07bd6bSYevhen Orlov 		return err;
20340f07bd6bSYevhen Orlov 
20350f07bd6bSYevhen Orlov 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_RIF_DELETE, &req.cmd,
20360f07bd6bSYevhen Orlov 			    sizeof(req));
20370f07bd6bSYevhen Orlov }
20380f07bd6bSYevhen Orlov 
prestera_hw_vr_create(struct prestera_switch * sw,u16 * vr_id)20396d1b3eb5SYevhen Orlov int prestera_hw_vr_create(struct prestera_switch *sw, u16 *vr_id)
20406d1b3eb5SYevhen Orlov {
20416d1b3eb5SYevhen Orlov 	struct prestera_msg_vr_resp resp;
20426d1b3eb5SYevhen Orlov 	struct prestera_msg_vr_req req;
204332d098bbSYevhen Orlov 	int err;
20446d1b3eb5SYevhen Orlov 
20456d1b3eb5SYevhen Orlov 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_ROUTER_VR_CREATE,
20466d1b3eb5SYevhen Orlov 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
20476d1b3eb5SYevhen Orlov 	if (err)
20486d1b3eb5SYevhen Orlov 		return err;
20496d1b3eb5SYevhen Orlov 
20506d1b3eb5SYevhen Orlov 	*vr_id = __le16_to_cpu(resp.vr_id);
20516d1b3eb5SYevhen Orlov 	return err;
20526d1b3eb5SYevhen Orlov }
20536d1b3eb5SYevhen Orlov 
prestera_hw_vr_delete(struct prestera_switch * sw,u16 vr_id)20546d1b3eb5SYevhen Orlov int prestera_hw_vr_delete(struct prestera_switch *sw, u16 vr_id)
20556d1b3eb5SYevhen Orlov {
20566d1b3eb5SYevhen Orlov 	struct prestera_msg_vr_req req = {
20576d1b3eb5SYevhen Orlov 		.vr_id = __cpu_to_le16(vr_id),
20586d1b3eb5SYevhen Orlov 	};
20596d1b3eb5SYevhen Orlov 
20606d1b3eb5SYevhen Orlov 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_VR_DELETE, &req.cmd,
20616d1b3eb5SYevhen Orlov 			    sizeof(req));
20626d1b3eb5SYevhen Orlov }
20636d1b3eb5SYevhen Orlov 
prestera_hw_lpm_add(struct prestera_switch * sw,u16 vr_id,__be32 dst,u32 dst_len,u32 grp_id)206419787b93SYevhen Orlov int prestera_hw_lpm_add(struct prestera_switch *sw, u16 vr_id,
206519787b93SYevhen Orlov 			__be32 dst, u32 dst_len, u32 grp_id)
206619787b93SYevhen Orlov {
206719787b93SYevhen Orlov 	struct prestera_msg_lpm_req req = {
206819787b93SYevhen Orlov 		.dst_len = __cpu_to_le32(dst_len),
206919787b93SYevhen Orlov 		.vr_id = __cpu_to_le16(vr_id),
207019787b93SYevhen Orlov 		.grp_id = __cpu_to_le32(grp_id),
207119787b93SYevhen Orlov 		.dst.u.ipv4 = dst
207219787b93SYevhen Orlov 	};
207319787b93SYevhen Orlov 
207419787b93SYevhen Orlov 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_LPM_ADD, &req.cmd,
207519787b93SYevhen Orlov 			    sizeof(req));
207619787b93SYevhen Orlov }
207719787b93SYevhen Orlov 
prestera_hw_lpm_del(struct prestera_switch * sw,u16 vr_id,__be32 dst,u32 dst_len)207819787b93SYevhen Orlov int prestera_hw_lpm_del(struct prestera_switch *sw, u16 vr_id,
207919787b93SYevhen Orlov 			__be32 dst, u32 dst_len)
208019787b93SYevhen Orlov {
208119787b93SYevhen Orlov 	struct prestera_msg_lpm_req req = {
208219787b93SYevhen Orlov 		.dst_len = __cpu_to_le32(dst_len),
208319787b93SYevhen Orlov 		.vr_id = __cpu_to_le16(vr_id),
208419787b93SYevhen Orlov 		.dst.u.ipv4 = dst
208519787b93SYevhen Orlov 	};
208619787b93SYevhen Orlov 
208719787b93SYevhen Orlov 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_LPM_DELETE, &req.cmd,
208819787b93SYevhen Orlov 			    sizeof(req));
208919787b93SYevhen Orlov }
209019787b93SYevhen Orlov 
prestera_hw_nh_entries_set(struct prestera_switch * sw,int count,struct prestera_neigh_info * nhs,u32 grp_id)2091*0a23ae23SYevhen Orlov int prestera_hw_nh_entries_set(struct prestera_switch *sw, int count,
2092*0a23ae23SYevhen Orlov 			       struct prestera_neigh_info *nhs, u32 grp_id)
2093*0a23ae23SYevhen Orlov {
2094*0a23ae23SYevhen Orlov 	struct prestera_msg_nh_req req = { .size = __cpu_to_le32((u32)count),
2095*0a23ae23SYevhen Orlov 			.grp_id = __cpu_to_le32(grp_id) };
2096*0a23ae23SYevhen Orlov 	int i, err;
2097*0a23ae23SYevhen Orlov 
2098*0a23ae23SYevhen Orlov 	for (i = 0; i < count; i++) {
2099*0a23ae23SYevhen Orlov 		req.nh[i].is_active = nhs[i].connected;
2100*0a23ae23SYevhen Orlov 		memcpy(&req.nh[i].mac, nhs[i].ha, ETH_ALEN);
2101*0a23ae23SYevhen Orlov 		err = prestera_iface_to_msg(&nhs[i].iface, &req.nh[i].oif);
2102*0a23ae23SYevhen Orlov 		if (err)
2103*0a23ae23SYevhen Orlov 			return err;
2104*0a23ae23SYevhen Orlov 	}
2105*0a23ae23SYevhen Orlov 
2106*0a23ae23SYevhen Orlov 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_NH_GRP_SET, &req.cmd,
2107*0a23ae23SYevhen Orlov 			    sizeof(req));
2108*0a23ae23SYevhen Orlov }
2109*0a23ae23SYevhen Orlov 
prestera_hw_nhgrp_blk_get(struct prestera_switch * sw,u8 * hw_state,u32 buf_size)2110*0a23ae23SYevhen Orlov int prestera_hw_nhgrp_blk_get(struct prestera_switch *sw,
2111*0a23ae23SYevhen Orlov 			      u8 *hw_state, u32 buf_size /* Buffer in bytes */)
2112*0a23ae23SYevhen Orlov {
2113*0a23ae23SYevhen Orlov 	static struct prestera_msg_nh_chunk_resp resp;
2114*0a23ae23SYevhen Orlov 	struct prestera_msg_nh_chunk_req req;
2115*0a23ae23SYevhen Orlov 	u32 buf_offset;
2116*0a23ae23SYevhen Orlov 	int err;
2117*0a23ae23SYevhen Orlov 
2118*0a23ae23SYevhen Orlov 	memset(&hw_state[0], 0, buf_size);
2119*0a23ae23SYevhen Orlov 	buf_offset = 0;
2120*0a23ae23SYevhen Orlov 	while (1) {
2121*0a23ae23SYevhen Orlov 		if (buf_offset >= buf_size)
2122*0a23ae23SYevhen Orlov 			break;
2123*0a23ae23SYevhen Orlov 
2124*0a23ae23SYevhen Orlov 		memset(&req, 0, sizeof(req));
2125*0a23ae23SYevhen Orlov 		req.offset = __cpu_to_le32(buf_offset * 8); /* 8 bits in u8 */
2126*0a23ae23SYevhen Orlov 		err = prestera_cmd_ret(sw,
2127*0a23ae23SYevhen Orlov 				       PRESTERA_CMD_TYPE_ROUTER_NH_GRP_BLK_GET,
2128*0a23ae23SYevhen Orlov 				       &req.cmd, sizeof(req), &resp.ret,
2129*0a23ae23SYevhen Orlov 				       sizeof(resp));
2130*0a23ae23SYevhen Orlov 		if (err)
2131*0a23ae23SYevhen Orlov 			return err;
2132*0a23ae23SYevhen Orlov 
2133*0a23ae23SYevhen Orlov 		memcpy(&hw_state[buf_offset], &resp.hw_state[0],
2134*0a23ae23SYevhen Orlov 		       buf_offset + PRESTERA_MSG_CHUNK_SIZE > buf_size ?
2135*0a23ae23SYevhen Orlov 			buf_size - buf_offset : PRESTERA_MSG_CHUNK_SIZE);
2136*0a23ae23SYevhen Orlov 		buf_offset += PRESTERA_MSG_CHUNK_SIZE;
2137*0a23ae23SYevhen Orlov 	}
2138*0a23ae23SYevhen Orlov 
2139*0a23ae23SYevhen Orlov 	return 0;
2140*0a23ae23SYevhen Orlov }
2141*0a23ae23SYevhen Orlov 
prestera_hw_nh_group_create(struct prestera_switch * sw,u16 nh_count,u32 * grp_id)2142*0a23ae23SYevhen Orlov int prestera_hw_nh_group_create(struct prestera_switch *sw, u16 nh_count,
2143*0a23ae23SYevhen Orlov 				u32 *grp_id)
2144*0a23ae23SYevhen Orlov {
2145*0a23ae23SYevhen Orlov 	struct prestera_msg_nh_grp_req req = { .size = __cpu_to_le32((u32)nh_count) };
2146*0a23ae23SYevhen Orlov 	struct prestera_msg_nh_grp_resp resp;
2147*0a23ae23SYevhen Orlov 	int err;
2148*0a23ae23SYevhen Orlov 
2149*0a23ae23SYevhen Orlov 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_ROUTER_NH_GRP_ADD,
2150*0a23ae23SYevhen Orlov 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
2151*0a23ae23SYevhen Orlov 	if (err)
2152*0a23ae23SYevhen Orlov 		return err;
2153*0a23ae23SYevhen Orlov 
2154*0a23ae23SYevhen Orlov 	*grp_id = __le32_to_cpu(resp.grp_id);
2155*0a23ae23SYevhen Orlov 	return err;
2156*0a23ae23SYevhen Orlov }
2157*0a23ae23SYevhen Orlov 
prestera_hw_nh_group_delete(struct prestera_switch * sw,u16 nh_count,u32 grp_id)2158*0a23ae23SYevhen Orlov int prestera_hw_nh_group_delete(struct prestera_switch *sw, u16 nh_count,
2159*0a23ae23SYevhen Orlov 				u32 grp_id)
2160*0a23ae23SYevhen Orlov {
2161*0a23ae23SYevhen Orlov 	struct prestera_msg_nh_grp_req req = {
2162*0a23ae23SYevhen Orlov 	    .grp_id = __cpu_to_le32(grp_id),
2163*0a23ae23SYevhen Orlov 	    .size = __cpu_to_le32(nh_count)
2164*0a23ae23SYevhen Orlov 	};
2165*0a23ae23SYevhen Orlov 
2166*0a23ae23SYevhen Orlov 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_NH_GRP_DELETE,
2167*0a23ae23SYevhen Orlov 			    &req.cmd, sizeof(req));
2168*0a23ae23SYevhen Orlov }
2169*0a23ae23SYevhen Orlov 
prestera_hw_rxtx_init(struct prestera_switch * sw,struct prestera_rxtx_params * params)2170501ef306SVadym Kochan int prestera_hw_rxtx_init(struct prestera_switch *sw,
2171501ef306SVadym Kochan 			  struct prestera_rxtx_params *params)
2172501ef306SVadym Kochan {
2173501ef306SVadym Kochan 	struct prestera_msg_rxtx_resp resp;
2174501ef306SVadym Kochan 	struct prestera_msg_rxtx_req req;
2175501ef306SVadym Kochan 	int err;
2176501ef306SVadym Kochan 
2177501ef306SVadym Kochan 	req.use_sdma = params->use_sdma;
2178501ef306SVadym Kochan 
2179501ef306SVadym Kochan 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_RXTX_INIT,
2180501ef306SVadym Kochan 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
2181501ef306SVadym Kochan 	if (err)
2182501ef306SVadym Kochan 		return err;
2183501ef306SVadym Kochan 
2184bb5dbf2cSVolodymyr Mytnyk 	params->map_addr = __le32_to_cpu(resp.map_addr);
2185501ef306SVadym Kochan 
2186501ef306SVadym Kochan 	return 0;
2187501ef306SVadym Kochan }
2188501ef306SVadym Kochan 
prestera_hw_lag_member_add(struct prestera_port * port,u16 lag_id)2189255213caSSerhiy Boiko int prestera_hw_lag_member_add(struct prestera_port *port, u16 lag_id)
2190255213caSSerhiy Boiko {
2191255213caSSerhiy Boiko 	struct prestera_msg_lag_req req = {
2192bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
2193bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
2194bb5dbf2cSVolodymyr Mytnyk 		.lag_id = __cpu_to_le16(lag_id),
2195255213caSSerhiy Boiko 	};
2196255213caSSerhiy Boiko 
2197255213caSSerhiy Boiko 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_LAG_MEMBER_ADD,
2198255213caSSerhiy Boiko 			    &req.cmd, sizeof(req));
2199255213caSSerhiy Boiko }
2200255213caSSerhiy Boiko 
prestera_hw_lag_member_del(struct prestera_port * port,u16 lag_id)2201255213caSSerhiy Boiko int prestera_hw_lag_member_del(struct prestera_port *port, u16 lag_id)
2202255213caSSerhiy Boiko {
2203255213caSSerhiy Boiko 	struct prestera_msg_lag_req req = {
2204bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
2205bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
2206bb5dbf2cSVolodymyr Mytnyk 		.lag_id = __cpu_to_le16(lag_id),
2207255213caSSerhiy Boiko 	};
2208255213caSSerhiy Boiko 
2209255213caSSerhiy Boiko 	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_LAG_MEMBER_DELETE,
2210255213caSSerhiy Boiko 			    &req.cmd, sizeof(req));
2211255213caSSerhiy Boiko }
2212255213caSSerhiy Boiko 
prestera_hw_lag_member_enable(struct prestera_port * port,u16 lag_id,bool enable)2213255213caSSerhiy Boiko int prestera_hw_lag_member_enable(struct prestera_port *port, u16 lag_id,
2214255213caSSerhiy Boiko 				  bool enable)
2215255213caSSerhiy Boiko {
2216255213caSSerhiy Boiko 	struct prestera_msg_lag_req req = {
2217bb5dbf2cSVolodymyr Mytnyk 		.port = __cpu_to_le32(port->hw_id),
2218bb5dbf2cSVolodymyr Mytnyk 		.dev = __cpu_to_le32(port->dev_id),
2219bb5dbf2cSVolodymyr Mytnyk 		.lag_id = __cpu_to_le16(lag_id),
2220255213caSSerhiy Boiko 	};
2221255213caSSerhiy Boiko 	u32 cmd;
2222255213caSSerhiy Boiko 
2223255213caSSerhiy Boiko 	cmd = enable ? PRESTERA_CMD_TYPE_LAG_MEMBER_ENABLE :
2224255213caSSerhiy Boiko 			PRESTERA_CMD_TYPE_LAG_MEMBER_DISABLE;
2225255213caSSerhiy Boiko 
2226255213caSSerhiy Boiko 	return prestera_cmd(port->sw, cmd, &req.cmd, sizeof(req));
2227255213caSSerhiy Boiko }
2228255213caSSerhiy Boiko 
2229a80cf955SOleksandr 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)2230a80cf955SOleksandr Mazur prestera_hw_cpu_code_counters_get(struct prestera_switch *sw, u8 code,
2231a80cf955SOleksandr Mazur 				  enum prestera_hw_cpu_code_cnt_t counter_type,
2232a80cf955SOleksandr Mazur 				  u64 *packet_count)
2233a80cf955SOleksandr Mazur {
2234a80cf955SOleksandr Mazur 	struct prestera_msg_cpu_code_counter_req req = {
2235a80cf955SOleksandr Mazur 		.counter_type = counter_type,
2236a80cf955SOleksandr Mazur 		.code = code,
2237a80cf955SOleksandr Mazur 	};
2238a80cf955SOleksandr Mazur 	struct mvsw_msg_cpu_code_counter_ret resp;
2239a80cf955SOleksandr Mazur 	int err;
2240a80cf955SOleksandr Mazur 
2241a80cf955SOleksandr Mazur 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_CPU_CODE_COUNTERS_GET,
2242a80cf955SOleksandr Mazur 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
2243a80cf955SOleksandr Mazur 	if (err)
2244a80cf955SOleksandr Mazur 		return err;
2245a80cf955SOleksandr Mazur 
2246bb5dbf2cSVolodymyr Mytnyk 	*packet_count = __le64_to_cpu(resp.packet_count);
2247a80cf955SOleksandr Mazur 
2248a80cf955SOleksandr Mazur 	return 0;
2249a80cf955SOleksandr Mazur }
2250a80cf955SOleksandr Mazur 
prestera_hw_event_handler_register(struct prestera_switch * sw,enum prestera_event_type type,prestera_event_cb_t fn,void * arg)2251501ef306SVadym Kochan int prestera_hw_event_handler_register(struct prestera_switch *sw,
2252501ef306SVadym Kochan 				       enum prestera_event_type type,
2253501ef306SVadym Kochan 				       prestera_event_cb_t fn,
2254501ef306SVadym Kochan 				       void *arg)
2255501ef306SVadym Kochan {
2256501ef306SVadym Kochan 	struct prestera_fw_event_handler *eh;
2257501ef306SVadym Kochan 
2258501ef306SVadym Kochan 	eh = __find_event_handler(sw, type);
2259501ef306SVadym Kochan 	if (eh)
2260501ef306SVadym Kochan 		return -EEXIST;
2261501ef306SVadym Kochan 
2262501ef306SVadym Kochan 	eh = kmalloc(sizeof(*eh), GFP_KERNEL);
2263501ef306SVadym Kochan 	if (!eh)
2264501ef306SVadym Kochan 		return -ENOMEM;
2265501ef306SVadym Kochan 
2266501ef306SVadym Kochan 	eh->type = type;
2267501ef306SVadym Kochan 	eh->func = fn;
2268501ef306SVadym Kochan 	eh->arg = arg;
2269501ef306SVadym Kochan 
2270501ef306SVadym Kochan 	INIT_LIST_HEAD(&eh->list);
2271501ef306SVadym Kochan 
2272501ef306SVadym Kochan 	list_add_rcu(&eh->list, &sw->event_handlers);
2273501ef306SVadym Kochan 
2274501ef306SVadym Kochan 	return 0;
2275501ef306SVadym Kochan }
2276501ef306SVadym Kochan 
prestera_hw_event_handler_unregister(struct prestera_switch * sw,enum prestera_event_type type,prestera_event_cb_t fn)2277501ef306SVadym Kochan void prestera_hw_event_handler_unregister(struct prestera_switch *sw,
2278501ef306SVadym Kochan 					  enum prestera_event_type type,
2279501ef306SVadym Kochan 					  prestera_event_cb_t fn)
2280501ef306SVadym Kochan {
2281501ef306SVadym Kochan 	struct prestera_fw_event_handler *eh;
2282501ef306SVadym Kochan 
2283501ef306SVadym Kochan 	eh = __find_event_handler(sw, type);
2284501ef306SVadym Kochan 	if (!eh)
2285501ef306SVadym Kochan 		return;
2286501ef306SVadym Kochan 
2287501ef306SVadym Kochan 	list_del_rcu(&eh->list);
2288501ef306SVadym Kochan 	kfree_rcu(eh, rcu);
2289501ef306SVadym Kochan }
22906e36c7bcSVolodymyr Mytnyk 
prestera_hw_counter_trigger(struct prestera_switch * sw,u32 block_id)22916e36c7bcSVolodymyr Mytnyk int prestera_hw_counter_trigger(struct prestera_switch *sw, u32 block_id)
22926e36c7bcSVolodymyr Mytnyk {
22936e36c7bcSVolodymyr Mytnyk 	struct prestera_msg_counter_req req = {
22946e36c7bcSVolodymyr Mytnyk 		.block_id = __cpu_to_le32(block_id)
22956e36c7bcSVolodymyr Mytnyk 	};
22966e36c7bcSVolodymyr Mytnyk 
22976e36c7bcSVolodymyr Mytnyk 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_COUNTER_TRIGGER,
22986e36c7bcSVolodymyr Mytnyk 			    &req.cmd, sizeof(req));
22996e36c7bcSVolodymyr Mytnyk }
23006e36c7bcSVolodymyr Mytnyk 
prestera_hw_counter_abort(struct prestera_switch * sw)23016e36c7bcSVolodymyr Mytnyk int prestera_hw_counter_abort(struct prestera_switch *sw)
23026e36c7bcSVolodymyr Mytnyk {
23036e36c7bcSVolodymyr Mytnyk 	struct prestera_msg_counter_req req;
23046e36c7bcSVolodymyr Mytnyk 
23056e36c7bcSVolodymyr Mytnyk 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_COUNTER_ABORT,
23066e36c7bcSVolodymyr Mytnyk 			    &req.cmd, sizeof(req));
23076e36c7bcSVolodymyr Mytnyk }
23086e36c7bcSVolodymyr Mytnyk 
prestera_hw_counters_get(struct prestera_switch * sw,u32 idx,u32 * len,bool * done,struct prestera_counter_stats * stats)23096e36c7bcSVolodymyr Mytnyk int prestera_hw_counters_get(struct prestera_switch *sw, u32 idx,
23106e36c7bcSVolodymyr Mytnyk 			     u32 *len, bool *done,
23116e36c7bcSVolodymyr Mytnyk 			     struct prestera_counter_stats *stats)
23126e36c7bcSVolodymyr Mytnyk {
23136e36c7bcSVolodymyr Mytnyk 	struct prestera_msg_counter_resp *resp;
23146e36c7bcSVolodymyr Mytnyk 	struct prestera_msg_counter_req req = {
23156e36c7bcSVolodymyr Mytnyk 		.block_id = __cpu_to_le32(idx),
23166e36c7bcSVolodymyr Mytnyk 		.num_counters = __cpu_to_le32(*len),
23176e36c7bcSVolodymyr Mytnyk 	};
231801081be1SJosé Expósito 	size_t size = struct_size(resp, stats, *len);
23196e36c7bcSVolodymyr Mytnyk 	int err, i;
23206e36c7bcSVolodymyr Mytnyk 
23216e36c7bcSVolodymyr Mytnyk 	resp = kmalloc(size, GFP_KERNEL);
23226e36c7bcSVolodymyr Mytnyk 	if (!resp)
23236e36c7bcSVolodymyr Mytnyk 		return -ENOMEM;
23246e36c7bcSVolodymyr Mytnyk 
23256e36c7bcSVolodymyr Mytnyk 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_COUNTER_GET,
23266e36c7bcSVolodymyr Mytnyk 			       &req.cmd, sizeof(req), &resp->ret, size);
23276e36c7bcSVolodymyr Mytnyk 	if (err)
23286e36c7bcSVolodymyr Mytnyk 		goto free_buff;
23296e36c7bcSVolodymyr Mytnyk 
23306e36c7bcSVolodymyr Mytnyk 	for (i = 0; i < __le32_to_cpu(resp->num_counters); i++) {
23316e36c7bcSVolodymyr Mytnyk 		stats[i].packets += __le64_to_cpu(resp->stats[i].packets);
23326e36c7bcSVolodymyr Mytnyk 		stats[i].bytes += __le64_to_cpu(resp->stats[i].bytes);
23336e36c7bcSVolodymyr Mytnyk 	}
23346e36c7bcSVolodymyr Mytnyk 
23356e36c7bcSVolodymyr Mytnyk 	*len = __le32_to_cpu(resp->num_counters);
23366e36c7bcSVolodymyr Mytnyk 	*done = __le32_to_cpu(resp->done);
23376e36c7bcSVolodymyr Mytnyk 
23386e36c7bcSVolodymyr Mytnyk free_buff:
23396e36c7bcSVolodymyr Mytnyk 	kfree(resp);
23406e36c7bcSVolodymyr Mytnyk 	return err;
23416e36c7bcSVolodymyr Mytnyk }
23426e36c7bcSVolodymyr Mytnyk 
prestera_hw_counter_block_get(struct prestera_switch * sw,u32 client,u32 * block_id,u32 * offset,u32 * num_counters)23436e36c7bcSVolodymyr Mytnyk int prestera_hw_counter_block_get(struct prestera_switch *sw,
23446e36c7bcSVolodymyr Mytnyk 				  u32 client, u32 *block_id, u32 *offset,
23456e36c7bcSVolodymyr Mytnyk 				  u32 *num_counters)
23466e36c7bcSVolodymyr Mytnyk {
23476e36c7bcSVolodymyr Mytnyk 	struct prestera_msg_counter_resp resp;
23486e36c7bcSVolodymyr Mytnyk 	struct prestera_msg_counter_req req = {
23496e36c7bcSVolodymyr Mytnyk 		.client = __cpu_to_le32(client)
23506e36c7bcSVolodymyr Mytnyk 	};
23516e36c7bcSVolodymyr Mytnyk 	int err;
23526e36c7bcSVolodymyr Mytnyk 
23536e36c7bcSVolodymyr Mytnyk 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_COUNTER_BLOCK_GET,
23546e36c7bcSVolodymyr Mytnyk 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
23556e36c7bcSVolodymyr Mytnyk 	if (err)
23566e36c7bcSVolodymyr Mytnyk 		return err;
23576e36c7bcSVolodymyr Mytnyk 
23586e36c7bcSVolodymyr Mytnyk 	*block_id = __le32_to_cpu(resp.block_id);
23596e36c7bcSVolodymyr Mytnyk 	*offset = __le32_to_cpu(resp.offset);
23606e36c7bcSVolodymyr Mytnyk 	*num_counters = __le32_to_cpu(resp.num_counters);
23616e36c7bcSVolodymyr Mytnyk 
23626e36c7bcSVolodymyr Mytnyk 	return 0;
23636e36c7bcSVolodymyr Mytnyk }
23646e36c7bcSVolodymyr Mytnyk 
prestera_hw_counter_block_release(struct prestera_switch * sw,u32 block_id)23656e36c7bcSVolodymyr Mytnyk int prestera_hw_counter_block_release(struct prestera_switch *sw,
23666e36c7bcSVolodymyr Mytnyk 				      u32 block_id)
23676e36c7bcSVolodymyr Mytnyk {
23686e36c7bcSVolodymyr Mytnyk 	struct prestera_msg_counter_req req = {
23696e36c7bcSVolodymyr Mytnyk 		.block_id = __cpu_to_le32(block_id)
23706e36c7bcSVolodymyr Mytnyk 	};
23716e36c7bcSVolodymyr Mytnyk 
23726e36c7bcSVolodymyr Mytnyk 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_COUNTER_BLOCK_RELEASE,
23736e36c7bcSVolodymyr Mytnyk 			    &req.cmd, sizeof(req));
23746e36c7bcSVolodymyr Mytnyk }
23756e36c7bcSVolodymyr Mytnyk 
prestera_hw_counter_clear(struct prestera_switch * sw,u32 block_id,u32 counter_id)23766e36c7bcSVolodymyr Mytnyk int prestera_hw_counter_clear(struct prestera_switch *sw, u32 block_id,
23776e36c7bcSVolodymyr Mytnyk 			      u32 counter_id)
23786e36c7bcSVolodymyr Mytnyk {
23796e36c7bcSVolodymyr Mytnyk 	struct prestera_msg_counter_req req = {
23806e36c7bcSVolodymyr Mytnyk 		.block_id = __cpu_to_le32(block_id),
23816e36c7bcSVolodymyr Mytnyk 		.num_counters = __cpu_to_le32(counter_id)
23826e36c7bcSVolodymyr Mytnyk 	};
23836e36c7bcSVolodymyr Mytnyk 
23846e36c7bcSVolodymyr Mytnyk 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_COUNTER_CLEAR,
23856e36c7bcSVolodymyr Mytnyk 			    &req.cmd, sizeof(req));
23866e36c7bcSVolodymyr Mytnyk }
2387dde2daa0SVolodymyr Mytnyk 
prestera_hw_policer_create(struct prestera_switch * sw,u8 type,u32 * policer_id)2388dde2daa0SVolodymyr Mytnyk int prestera_hw_policer_create(struct prestera_switch *sw, u8 type,
2389dde2daa0SVolodymyr Mytnyk 			       u32 *policer_id)
2390dde2daa0SVolodymyr Mytnyk {
2391dde2daa0SVolodymyr Mytnyk 	struct prestera_msg_policer_resp resp;
2392dde2daa0SVolodymyr Mytnyk 	struct prestera_msg_policer_req req = {
2393dde2daa0SVolodymyr Mytnyk 		.type = type
2394dde2daa0SVolodymyr Mytnyk 	};
2395dde2daa0SVolodymyr Mytnyk 	int err;
2396dde2daa0SVolodymyr Mytnyk 
2397dde2daa0SVolodymyr Mytnyk 	err = prestera_cmd_ret(sw, PRESTERA_CMD_TYPE_POLICER_CREATE,
2398dde2daa0SVolodymyr Mytnyk 			       &req.cmd, sizeof(req), &resp.ret, sizeof(resp));
2399dde2daa0SVolodymyr Mytnyk 	if (err)
2400dde2daa0SVolodymyr Mytnyk 		return err;
2401dde2daa0SVolodymyr Mytnyk 
2402dde2daa0SVolodymyr Mytnyk 	*policer_id = __le32_to_cpu(resp.id);
2403dde2daa0SVolodymyr Mytnyk 	return 0;
2404dde2daa0SVolodymyr Mytnyk }
2405dde2daa0SVolodymyr Mytnyk 
prestera_hw_policer_release(struct prestera_switch * sw,u32 policer_id)2406dde2daa0SVolodymyr Mytnyk int prestera_hw_policer_release(struct prestera_switch *sw,
2407dde2daa0SVolodymyr Mytnyk 				u32 policer_id)
2408dde2daa0SVolodymyr Mytnyk {
2409dde2daa0SVolodymyr Mytnyk 	struct prestera_msg_policer_req req = {
2410dde2daa0SVolodymyr Mytnyk 		.id = __cpu_to_le32(policer_id)
2411dde2daa0SVolodymyr Mytnyk 	};
2412dde2daa0SVolodymyr Mytnyk 
2413dde2daa0SVolodymyr Mytnyk 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_POLICER_RELEASE,
2414dde2daa0SVolodymyr Mytnyk 			    &req.cmd, sizeof(req));
2415dde2daa0SVolodymyr Mytnyk }
2416dde2daa0SVolodymyr Mytnyk 
prestera_hw_policer_sr_tcm_set(struct prestera_switch * sw,u32 policer_id,u64 cir,u32 cbs)2417dde2daa0SVolodymyr Mytnyk int prestera_hw_policer_sr_tcm_set(struct prestera_switch *sw,
2418dde2daa0SVolodymyr Mytnyk 				   u32 policer_id, u64 cir, u32 cbs)
2419dde2daa0SVolodymyr Mytnyk {
2420dde2daa0SVolodymyr Mytnyk 	struct prestera_msg_policer_req req = {
2421dde2daa0SVolodymyr Mytnyk 		.mode = PRESTERA_POLICER_MODE_SR_TCM,
2422dde2daa0SVolodymyr Mytnyk 		.id = __cpu_to_le32(policer_id),
2423dde2daa0SVolodymyr Mytnyk 		.sr_tcm = {
2424dde2daa0SVolodymyr Mytnyk 			.cir = __cpu_to_le64(cir),
2425dde2daa0SVolodymyr Mytnyk 			.cbs = __cpu_to_le32(cbs)
2426dde2daa0SVolodymyr Mytnyk 		}
2427dde2daa0SVolodymyr Mytnyk 	};
2428dde2daa0SVolodymyr Mytnyk 
2429dde2daa0SVolodymyr Mytnyk 	return prestera_cmd(sw, PRESTERA_CMD_TYPE_POLICER_SET,
2430dde2daa0SVolodymyr Mytnyk 			    &req.cmd, sizeof(req));
2431dde2daa0SVolodymyr Mytnyk }
2432fec7c9c7SOleksandr Mazur 
prestera_hw_flood_domain_create(struct prestera_flood_domain * domain)2433fec7c9c7SOleksandr Mazur int prestera_hw_flood_domain_create(struct prestera_flood_domain *domain)
2434fec7c9c7SOleksandr Mazur {
2435fec7c9c7SOleksandr Mazur 	struct prestera_msg_flood_domain_create_resp resp;
2436fec7c9c7SOleksandr Mazur 	struct prestera_msg_flood_domain_create_req req;
2437fec7c9c7SOleksandr Mazur 	int err;
2438fec7c9c7SOleksandr Mazur 
2439fec7c9c7SOleksandr Mazur 	err = prestera_cmd_ret(domain->sw,
2440fec7c9c7SOleksandr Mazur 			       PRESTERA_CMD_TYPE_FLOOD_DOMAIN_CREATE, &req.cmd,
2441fec7c9c7SOleksandr Mazur 			       sizeof(req), &resp.ret, sizeof(resp));
2442fec7c9c7SOleksandr Mazur 	if (err)
2443fec7c9c7SOleksandr Mazur 		return err;
2444fec7c9c7SOleksandr Mazur 
2445fec7c9c7SOleksandr Mazur 	domain->idx = __le32_to_cpu(resp.flood_domain_idx);
2446fec7c9c7SOleksandr Mazur 
2447fec7c9c7SOleksandr Mazur 	return 0;
2448fec7c9c7SOleksandr Mazur }
2449fec7c9c7SOleksandr Mazur 
prestera_hw_flood_domain_destroy(struct prestera_flood_domain * domain)2450fec7c9c7SOleksandr Mazur int prestera_hw_flood_domain_destroy(struct prestera_flood_domain *domain)
2451fec7c9c7SOleksandr Mazur {
2452fec7c9c7SOleksandr Mazur 	struct prestera_msg_flood_domain_destroy_req req = {
2453fec7c9c7SOleksandr Mazur 		.flood_domain_idx = __cpu_to_le32(domain->idx),
2454fec7c9c7SOleksandr Mazur 	};
2455fec7c9c7SOleksandr Mazur 
2456fec7c9c7SOleksandr Mazur 	return prestera_cmd(domain->sw, PRESTERA_CMD_TYPE_FLOOD_DOMAIN_DESTROY,
2457fec7c9c7SOleksandr Mazur 			   &req.cmd, sizeof(req));
2458fec7c9c7SOleksandr Mazur }
2459fec7c9c7SOleksandr Mazur 
prestera_hw_flood_domain_ports_set(struct prestera_flood_domain * domain)2460fec7c9c7SOleksandr Mazur int prestera_hw_flood_domain_ports_set(struct prestera_flood_domain *domain)
2461fec7c9c7SOleksandr Mazur {
2462fec7c9c7SOleksandr Mazur 	struct prestera_flood_domain_port *flood_domain_port;
2463fec7c9c7SOleksandr Mazur 	struct prestera_msg_flood_domain_ports_set_req *req;
2464fec7c9c7SOleksandr Mazur 	struct prestera_msg_flood_domain_port *ports;
2465fec7c9c7SOleksandr Mazur 	struct prestera_switch *sw = domain->sw;
2466fec7c9c7SOleksandr Mazur 	struct prestera_port *port;
2467fec7c9c7SOleksandr Mazur 	u32 ports_num = 0;
2468fec7c9c7SOleksandr Mazur 	int buf_size;
2469fec7c9c7SOleksandr Mazur 	void *buff;
2470fec7c9c7SOleksandr Mazur 	u16 lag_id;
2471fec7c9c7SOleksandr Mazur 	int err;
2472fec7c9c7SOleksandr Mazur 
2473fec7c9c7SOleksandr Mazur 	list_for_each_entry(flood_domain_port, &domain->flood_domain_port_list,
2474fec7c9c7SOleksandr Mazur 			    flood_domain_port_node)
2475fec7c9c7SOleksandr Mazur 		ports_num++;
2476fec7c9c7SOleksandr Mazur 
2477fec7c9c7SOleksandr Mazur 	if (!ports_num)
2478fec7c9c7SOleksandr Mazur 		return -EINVAL;
2479fec7c9c7SOleksandr Mazur 
2480fec7c9c7SOleksandr Mazur 	buf_size = sizeof(*req) + sizeof(*ports) * ports_num;
2481fec7c9c7SOleksandr Mazur 
2482fec7c9c7SOleksandr Mazur 	buff = kmalloc(buf_size, GFP_KERNEL);
2483fec7c9c7SOleksandr Mazur 	if (!buff)
2484fec7c9c7SOleksandr Mazur 		return -ENOMEM;
2485fec7c9c7SOleksandr Mazur 
2486fec7c9c7SOleksandr Mazur 	req = buff;
2487fec7c9c7SOleksandr Mazur 	ports = buff + sizeof(*req);
2488fec7c9c7SOleksandr Mazur 
2489fec7c9c7SOleksandr Mazur 	req->flood_domain_idx = __cpu_to_le32(domain->idx);
2490fec7c9c7SOleksandr Mazur 	req->ports_num = __cpu_to_le32(ports_num);
2491fec7c9c7SOleksandr Mazur 
2492fec7c9c7SOleksandr Mazur 	list_for_each_entry(flood_domain_port, &domain->flood_domain_port_list,
2493fec7c9c7SOleksandr Mazur 			    flood_domain_port_node) {
2494fec7c9c7SOleksandr Mazur 		if (netif_is_lag_master(flood_domain_port->dev)) {
2495fec7c9c7SOleksandr Mazur 			if (prestera_lag_id(sw, flood_domain_port->dev,
2496fec7c9c7SOleksandr Mazur 					    &lag_id)) {
2497fec7c9c7SOleksandr Mazur 				kfree(buff);
2498fec7c9c7SOleksandr Mazur 				return -EINVAL;
2499fec7c9c7SOleksandr Mazur 			}
2500fec7c9c7SOleksandr Mazur 
2501fec7c9c7SOleksandr Mazur 			ports->port_type =
2502fec7c9c7SOleksandr Mazur 				__cpu_to_le16(PRESTERA_HW_FLOOD_DOMAIN_PORT_TYPE_LAG);
2503fec7c9c7SOleksandr Mazur 			ports->lag_id = __cpu_to_le16(lag_id);
2504fec7c9c7SOleksandr Mazur 		} else {
2505fec7c9c7SOleksandr Mazur 			port = prestera_port_dev_lower_find(flood_domain_port->dev);
2506fec7c9c7SOleksandr Mazur 
2507fec7c9c7SOleksandr Mazur 			ports->port_type =
2508fec7c9c7SOleksandr Mazur 				__cpu_to_le16(PRESTERA_HW_FDB_ENTRY_TYPE_REG_PORT);
2509fec7c9c7SOleksandr Mazur 			ports->dev_num = __cpu_to_le32(port->dev_id);
2510fec7c9c7SOleksandr Mazur 			ports->port_num = __cpu_to_le32(port->hw_id);
2511fec7c9c7SOleksandr Mazur 		}
2512fec7c9c7SOleksandr Mazur 
2513fec7c9c7SOleksandr Mazur 		ports->vid = __cpu_to_le16(flood_domain_port->vid);
2514fec7c9c7SOleksandr Mazur 
2515fec7c9c7SOleksandr Mazur 		ports++;
2516fec7c9c7SOleksandr Mazur 	}
2517fec7c9c7SOleksandr Mazur 
2518fec7c9c7SOleksandr Mazur 	err = prestera_cmd(sw, PRESTERA_CMD_TYPE_FLOOD_DOMAIN_PORTS_SET,
2519fec7c9c7SOleksandr Mazur 			   &req->cmd, buf_size);
2520fec7c9c7SOleksandr Mazur 
2521fec7c9c7SOleksandr Mazur 	kfree(buff);
2522fec7c9c7SOleksandr Mazur 
2523fec7c9c7SOleksandr Mazur 	return err;
2524fec7c9c7SOleksandr Mazur }
2525fec7c9c7SOleksandr Mazur 
prestera_hw_flood_domain_ports_reset(struct prestera_flood_domain * domain)2526fec7c9c7SOleksandr Mazur int prestera_hw_flood_domain_ports_reset(struct prestera_flood_domain *domain)
2527fec7c9c7SOleksandr Mazur {
2528fec7c9c7SOleksandr Mazur 	struct prestera_msg_flood_domain_ports_reset_req req = {
2529fec7c9c7SOleksandr Mazur 		.flood_domain_idx = __cpu_to_le32(domain->idx),
2530fec7c9c7SOleksandr Mazur 	};
2531fec7c9c7SOleksandr Mazur 
2532fec7c9c7SOleksandr Mazur 	return prestera_cmd(domain->sw,
2533fec7c9c7SOleksandr Mazur 			   PRESTERA_CMD_TYPE_FLOOD_DOMAIN_PORTS_RESET, &req.cmd,
2534fec7c9c7SOleksandr Mazur 			   sizeof(req));
2535fec7c9c7SOleksandr Mazur }
2536fec7c9c7SOleksandr Mazur 
prestera_hw_mdb_create(struct prestera_mdb_entry * mdb)2537fec7c9c7SOleksandr Mazur int prestera_hw_mdb_create(struct prestera_mdb_entry *mdb)
2538fec7c9c7SOleksandr Mazur {
2539fec7c9c7SOleksandr Mazur 	struct prestera_msg_mdb_create_req req = {
2540fec7c9c7SOleksandr Mazur 		.flood_domain_idx = __cpu_to_le32(mdb->flood_domain->idx),
2541fec7c9c7SOleksandr Mazur 		.vid = __cpu_to_le16(mdb->vid),
2542fec7c9c7SOleksandr Mazur 	};
2543fec7c9c7SOleksandr Mazur 
2544fec7c9c7SOleksandr Mazur 	memcpy(req.mac, mdb->addr, ETH_ALEN);
2545fec7c9c7SOleksandr Mazur 
2546fec7c9c7SOleksandr Mazur 	return prestera_cmd(mdb->sw, PRESTERA_CMD_TYPE_MDB_CREATE, &req.cmd,
2547fec7c9c7SOleksandr Mazur 			    sizeof(req));
2548fec7c9c7SOleksandr Mazur }
2549fec7c9c7SOleksandr Mazur 
prestera_hw_mdb_destroy(struct prestera_mdb_entry * mdb)2550fec7c9c7SOleksandr Mazur int prestera_hw_mdb_destroy(struct prestera_mdb_entry *mdb)
2551fec7c9c7SOleksandr Mazur {
2552fec7c9c7SOleksandr Mazur 	struct prestera_msg_mdb_destroy_req req = {
2553fec7c9c7SOleksandr Mazur 		.flood_domain_idx = __cpu_to_le32(mdb->flood_domain->idx),
2554fec7c9c7SOleksandr Mazur 		.vid = __cpu_to_le16(mdb->vid),
2555fec7c9c7SOleksandr Mazur 	};
2556fec7c9c7SOleksandr Mazur 
2557fec7c9c7SOleksandr Mazur 	memcpy(req.mac, mdb->addr, ETH_ALEN);
2558fec7c9c7SOleksandr Mazur 
2559fec7c9c7SOleksandr Mazur 	return prestera_cmd(mdb->sw, PRESTERA_CMD_TYPE_MDB_DESTROY, &req.cmd,
2560fec7c9c7SOleksandr Mazur 			    sizeof(req));
2561fec7c9c7SOleksandr Mazur }
2562