134dd1710SVadym Kochan // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
234dd1710SVadym Kochan /* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved */
334dd1710SVadym Kochan 
434dd1710SVadym Kochan #include <net/devlink.h>
534dd1710SVadym Kochan 
634dd1710SVadym Kochan #include "prestera_devlink.h"
7a80cf955SOleksandr Mazur #include "prestera_hw.h"
834dd1710SVadym Kochan 
90a9003f4SOleksandr Mazur /* All driver-specific traps must be documented in
100a9003f4SOleksandr Mazur  * Documentation/networking/devlink/prestera.rst
110a9003f4SOleksandr Mazur  */
120a9003f4SOleksandr Mazur enum {
130a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_BASE = DEVLINK_TRAP_GENERIC_ID_MAX,
140a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_ARP_BC,
150a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_IS_IS,
160a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_OSPF,
170a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_IP_BC_MAC,
180a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_ROUTER_MC,
190a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_VRRP,
200a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_DHCP,
210a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_MAC_TO_ME,
220a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_IPV4_OPTIONS,
230a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_IP_DEFAULT_ROUTE,
240a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_IP_TO_ME,
250a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_IPV4_ICMP_REDIRECT,
260a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_0,
270a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_1,
280a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_2,
290a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_3,
300a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_4,
310a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_5,
320a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_6,
330a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_7,
340a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_BGP,
350a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_SSH,
360a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_TELNET,
370a9003f4SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_ICMP,
38a80cf955SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_MET_RED,
39a80cf955SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_IP_SIP_IS_ZERO,
40a80cf955SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_IP_UC_DIP_DA_MISMATCH,
41a80cf955SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_ILLEGAL_IPV4_HDR,
42a80cf955SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_ILLEGAL_IP_ADDR,
43a80cf955SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_INVALID_SA,
44a80cf955SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_LOCAL_PORT,
45a80cf955SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_PORT_NO_VLAN,
46a80cf955SOleksandr Mazur 	DEVLINK_PRESTERA_TRAP_ID_RXDMA_DROP,
470a9003f4SOleksandr Mazur };
480a9003f4SOleksandr Mazur 
490a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_ARP_BC \
500a9003f4SOleksandr Mazur 	"arp_bc"
510a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_IS_IS \
520a9003f4SOleksandr Mazur 	"is_is"
530a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_OSPF \
540a9003f4SOleksandr Mazur 	"ospf"
550a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_IP_BC_MAC \
560a9003f4SOleksandr Mazur 	"ip_bc_mac"
570a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_ROUTER_MC \
580a9003f4SOleksandr Mazur 	"router_mc"
590a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_VRRP \
600a9003f4SOleksandr Mazur 	"vrrp"
610a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_DHCP \
620a9003f4SOleksandr Mazur 	"dhcp"
630a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_MAC_TO_ME \
640a9003f4SOleksandr Mazur 	"mac_to_me"
650a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_IPV4_OPTIONS \
660a9003f4SOleksandr Mazur 	"ipv4_options"
670a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_IP_DEFAULT_ROUTE \
680a9003f4SOleksandr Mazur 	"ip_default_route"
690a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_IP_TO_ME \
700a9003f4SOleksandr Mazur 	"ip_to_me"
710a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_IPV4_ICMP_REDIRECT \
720a9003f4SOleksandr Mazur 	"ipv4_icmp_redirect"
730a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_0 \
740a9003f4SOleksandr Mazur 	"acl_code_0"
750a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_1 \
760a9003f4SOleksandr Mazur 	"acl_code_1"
770a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_2 \
780a9003f4SOleksandr Mazur 	"acl_code_2"
790a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_3 \
800a9003f4SOleksandr Mazur 	"acl_code_3"
810a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_4 \
820a9003f4SOleksandr Mazur 	"acl_code_4"
830a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_5 \
840a9003f4SOleksandr Mazur 	"acl_code_5"
850a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_6 \
860a9003f4SOleksandr Mazur 	"acl_code_6"
870a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_7 \
880a9003f4SOleksandr Mazur 	"acl_code_7"
890a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_BGP \
900a9003f4SOleksandr Mazur 	"bgp"
910a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_SSH \
920a9003f4SOleksandr Mazur 	"ssh"
930a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_TELNET \
940a9003f4SOleksandr Mazur 	"telnet"
950a9003f4SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_ICMP \
960a9003f4SOleksandr Mazur 	"icmp"
97a80cf955SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_RXDMA_DROP \
98a80cf955SOleksandr Mazur 	"rxdma_drop"
99a80cf955SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_PORT_NO_VLAN \
100a80cf955SOleksandr Mazur 	"port_no_vlan"
101a80cf955SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_LOCAL_PORT \
102a80cf955SOleksandr Mazur 	"local_port"
103a80cf955SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_INVALID_SA \
104a80cf955SOleksandr Mazur 	"invalid_sa"
105a80cf955SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_ILLEGAL_IP_ADDR \
106a80cf955SOleksandr Mazur 	"illegal_ip_addr"
107a80cf955SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_ILLEGAL_IPV4_HDR \
108a80cf955SOleksandr Mazur 	"illegal_ipv4_hdr"
109a80cf955SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_IP_UC_DIP_DA_MISMATCH \
110a80cf955SOleksandr Mazur 	"ip_uc_dip_da_mismatch"
111a80cf955SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_IP_SIP_IS_ZERO \
112a80cf955SOleksandr Mazur 	"ip_sip_is_zero"
113a80cf955SOleksandr Mazur #define DEVLINK_PRESTERA_TRAP_NAME_MET_RED \
114a80cf955SOleksandr Mazur 	"met_red"
1150a9003f4SOleksandr Mazur 
1160a9003f4SOleksandr Mazur struct prestera_trap {
1170a9003f4SOleksandr Mazur 	struct devlink_trap trap;
1180a9003f4SOleksandr Mazur 	u8 cpu_code;
1190a9003f4SOleksandr Mazur };
1200a9003f4SOleksandr Mazur 
1210a9003f4SOleksandr Mazur struct prestera_trap_item {
1220a9003f4SOleksandr Mazur 	enum devlink_trap_action action;
1230a9003f4SOleksandr Mazur 	void *trap_ctx;
1240a9003f4SOleksandr Mazur };
1250a9003f4SOleksandr Mazur 
1260a9003f4SOleksandr Mazur struct prestera_trap_data {
1270a9003f4SOleksandr Mazur 	struct prestera_switch *sw;
1280a9003f4SOleksandr Mazur 	struct prestera_trap_item *trap_items_arr;
1290a9003f4SOleksandr Mazur 	u32 traps_count;
1300a9003f4SOleksandr Mazur };
1310a9003f4SOleksandr Mazur 
1320a9003f4SOleksandr Mazur #define PRESTERA_TRAP_METADATA DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT
1330a9003f4SOleksandr Mazur 
1340a9003f4SOleksandr Mazur #define PRESTERA_TRAP_CONTROL(_id, _group_id, _action)			      \
1350a9003f4SOleksandr Mazur 	DEVLINK_TRAP_GENERIC(CONTROL, _action, _id,			      \
1360a9003f4SOleksandr Mazur 			     DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,	      \
1370a9003f4SOleksandr Mazur 			     PRESTERA_TRAP_METADATA)
1380a9003f4SOleksandr Mazur 
1390a9003f4SOleksandr Mazur #define PRESTERA_TRAP_DRIVER_CONTROL(_id, _group_id)			      \
1400a9003f4SOleksandr Mazur 	DEVLINK_TRAP_DRIVER(CONTROL, TRAP, DEVLINK_PRESTERA_TRAP_ID_##_id,    \
1410a9003f4SOleksandr Mazur 			    DEVLINK_PRESTERA_TRAP_NAME_##_id,		      \
1420a9003f4SOleksandr Mazur 			    DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,	      \
1430a9003f4SOleksandr Mazur 			    PRESTERA_TRAP_METADATA)
1440a9003f4SOleksandr Mazur 
1450a9003f4SOleksandr Mazur #define PRESTERA_TRAP_EXCEPTION(_id, _group_id)				      \
1460a9003f4SOleksandr Mazur 	DEVLINK_TRAP_GENERIC(EXCEPTION, TRAP, _id,			      \
1470a9003f4SOleksandr Mazur 			     DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,	      \
1480a9003f4SOleksandr Mazur 			     PRESTERA_TRAP_METADATA)
1490a9003f4SOleksandr Mazur 
1500a9003f4SOleksandr Mazur #define PRESTERA_TRAP_DRIVER_EXCEPTION(_id, _group_id)			      \
1510a9003f4SOleksandr Mazur 	DEVLINK_TRAP_DRIVER(EXCEPTION, TRAP, DEVLINK_PRESTERA_TRAP_ID_##_id,  \
1520a9003f4SOleksandr Mazur 			    DEVLINK_PRESTERA_TRAP_NAME_##_id,		      \
1530a9003f4SOleksandr Mazur 			    DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,	      \
1540a9003f4SOleksandr Mazur 			    PRESTERA_TRAP_METADATA)
1550a9003f4SOleksandr Mazur 
156a80cf955SOleksandr Mazur #define PRESTERA_TRAP_DRIVER_DROP(_id, _group_id)			      \
157a80cf955SOleksandr Mazur 	DEVLINK_TRAP_DRIVER(DROP, DROP, DEVLINK_PRESTERA_TRAP_ID_##_id,	      \
158a80cf955SOleksandr Mazur 			    DEVLINK_PRESTERA_TRAP_NAME_##_id,		      \
159a80cf955SOleksandr Mazur 			    DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,	      \
160a80cf955SOleksandr Mazur 			    PRESTERA_TRAP_METADATA)
161a80cf955SOleksandr Mazur 
1620a9003f4SOleksandr Mazur static const struct devlink_trap_group prestera_trap_groups_arr[] = {
1630a9003f4SOleksandr Mazur 	/* No policer is associated with following groups (policerid == 0)*/
1640a9003f4SOleksandr Mazur 	DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS, 0),
1650a9003f4SOleksandr Mazur 	DEVLINK_TRAP_GROUP_GENERIC(L3_DROPS, 0),
1660a9003f4SOleksandr Mazur 	DEVLINK_TRAP_GROUP_GENERIC(L3_EXCEPTIONS, 0),
1670a9003f4SOleksandr Mazur 	DEVLINK_TRAP_GROUP_GENERIC(NEIGH_DISCOVERY, 0),
1680a9003f4SOleksandr Mazur 	DEVLINK_TRAP_GROUP_GENERIC(ACL_TRAP, 0),
1690a9003f4SOleksandr Mazur 	DEVLINK_TRAP_GROUP_GENERIC(ACL_DROPS, 0),
1700a9003f4SOleksandr Mazur 	DEVLINK_TRAP_GROUP_GENERIC(ACL_SAMPLE, 0),
1710a9003f4SOleksandr Mazur 	DEVLINK_TRAP_GROUP_GENERIC(OSPF, 0),
1720a9003f4SOleksandr Mazur 	DEVLINK_TRAP_GROUP_GENERIC(STP, 0),
1730a9003f4SOleksandr Mazur 	DEVLINK_TRAP_GROUP_GENERIC(LACP, 0),
1740a9003f4SOleksandr Mazur 	DEVLINK_TRAP_GROUP_GENERIC(LLDP, 0),
1750a9003f4SOleksandr Mazur 	DEVLINK_TRAP_GROUP_GENERIC(VRRP, 0),
1760a9003f4SOleksandr Mazur 	DEVLINK_TRAP_GROUP_GENERIC(DHCP, 0),
1770a9003f4SOleksandr Mazur 	DEVLINK_TRAP_GROUP_GENERIC(BGP, 0),
1780a9003f4SOleksandr Mazur 	DEVLINK_TRAP_GROUP_GENERIC(LOCAL_DELIVERY, 0),
179a80cf955SOleksandr Mazur 	DEVLINK_TRAP_GROUP_GENERIC(BUFFER_DROPS, 0),
1800a9003f4SOleksandr Mazur };
1810a9003f4SOleksandr Mazur 
1820a9003f4SOleksandr Mazur /* Initialize trap list, as well as associate CPU code with them. */
1830a9003f4SOleksandr Mazur static struct prestera_trap prestera_trap_items_arr[] = {
1840a9003f4SOleksandr Mazur 	{
1850a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(ARP_BC, NEIGH_DISCOVERY),
1860a9003f4SOleksandr Mazur 		.cpu_code = 5,
1870a9003f4SOleksandr Mazur 	},
1880a9003f4SOleksandr Mazur 	{
1890a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(IS_IS, LOCAL_DELIVERY),
1900a9003f4SOleksandr Mazur 		.cpu_code = 13,
1910a9003f4SOleksandr Mazur 	},
1920a9003f4SOleksandr Mazur 	{
1930a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(OSPF, OSPF),
1940a9003f4SOleksandr Mazur 		.cpu_code = 16,
1950a9003f4SOleksandr Mazur 	},
1960a9003f4SOleksandr Mazur 	{
1970a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(IP_BC_MAC, LOCAL_DELIVERY),
1980a9003f4SOleksandr Mazur 		.cpu_code = 19,
1990a9003f4SOleksandr Mazur 	},
2000a9003f4SOleksandr Mazur 	{
2010a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_CONTROL(STP, STP, TRAP),
2020a9003f4SOleksandr Mazur 		.cpu_code = 26,
2030a9003f4SOleksandr Mazur 	},
2040a9003f4SOleksandr Mazur 	{
2050a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_CONTROL(LACP, LACP, TRAP),
2060a9003f4SOleksandr Mazur 		.cpu_code = 27,
2070a9003f4SOleksandr Mazur 	},
2080a9003f4SOleksandr Mazur 	{
2090a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_CONTROL(LLDP, LLDP, TRAP),
2100a9003f4SOleksandr Mazur 		.cpu_code = 28,
2110a9003f4SOleksandr Mazur 	},
2120a9003f4SOleksandr Mazur 	{
2130a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(ROUTER_MC, LOCAL_DELIVERY),
2140a9003f4SOleksandr Mazur 		.cpu_code = 29,
2150a9003f4SOleksandr Mazur 	},
2160a9003f4SOleksandr Mazur 	{
2170a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(VRRP, VRRP),
2180a9003f4SOleksandr Mazur 		.cpu_code = 30,
2190a9003f4SOleksandr Mazur 	},
2200a9003f4SOleksandr Mazur 	{
2210a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(DHCP, DHCP),
2220a9003f4SOleksandr Mazur 		.cpu_code = 33,
2230a9003f4SOleksandr Mazur 	},
2240a9003f4SOleksandr Mazur 	{
2250a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_EXCEPTION(MTU_ERROR, L3_EXCEPTIONS),
2260a9003f4SOleksandr Mazur 		.cpu_code = 63,
2270a9003f4SOleksandr Mazur 	},
2280a9003f4SOleksandr Mazur 	{
2290a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(MAC_TO_ME, LOCAL_DELIVERY),
2300a9003f4SOleksandr Mazur 		.cpu_code = 65,
2310a9003f4SOleksandr Mazur 	},
2320a9003f4SOleksandr Mazur 	{
2330a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_EXCEPTION(TTL_ERROR, L3_EXCEPTIONS),
2340a9003f4SOleksandr Mazur 		.cpu_code = 133,
2350a9003f4SOleksandr Mazur 	},
2360a9003f4SOleksandr Mazur 	{
2370a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_EXCEPTION(IPV4_OPTIONS,
2380a9003f4SOleksandr Mazur 						       L3_EXCEPTIONS),
2390a9003f4SOleksandr Mazur 		.cpu_code = 141,
2400a9003f4SOleksandr Mazur 	},
2410a9003f4SOleksandr Mazur 	{
2420a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(IP_DEFAULT_ROUTE,
2430a9003f4SOleksandr Mazur 						     LOCAL_DELIVERY),
2440a9003f4SOleksandr Mazur 		.cpu_code = 160,
2450a9003f4SOleksandr Mazur 	},
2460a9003f4SOleksandr Mazur 	{
2470a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_CONTROL(LOCAL_ROUTE, LOCAL_DELIVERY,
2480a9003f4SOleksandr Mazur 					      TRAP),
2490a9003f4SOleksandr Mazur 		.cpu_code = 161,
2500a9003f4SOleksandr Mazur 	},
2510a9003f4SOleksandr Mazur 	{
2520a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_EXCEPTION(IPV4_ICMP_REDIRECT,
2530a9003f4SOleksandr Mazur 						       L3_EXCEPTIONS),
2540a9003f4SOleksandr Mazur 		.cpu_code = 180,
2550a9003f4SOleksandr Mazur 	},
2560a9003f4SOleksandr Mazur 	{
2570a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_CONTROL(ARP_RESPONSE, NEIGH_DISCOVERY,
2580a9003f4SOleksandr Mazur 					      TRAP),
2590a9003f4SOleksandr Mazur 		.cpu_code = 188,
2600a9003f4SOleksandr Mazur 	},
2610a9003f4SOleksandr Mazur 	{
2620a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_0, ACL_TRAP),
2630a9003f4SOleksandr Mazur 		.cpu_code = 192,
2640a9003f4SOleksandr Mazur 	},
2650a9003f4SOleksandr Mazur 	{
2660a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_1, ACL_TRAP),
2670a9003f4SOleksandr Mazur 		.cpu_code = 193,
2680a9003f4SOleksandr Mazur 	},
2690a9003f4SOleksandr Mazur 	{
2700a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_2, ACL_TRAP),
2710a9003f4SOleksandr Mazur 		.cpu_code = 194,
2720a9003f4SOleksandr Mazur 	},
2730a9003f4SOleksandr Mazur 	{
2740a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_3, ACL_TRAP),
2750a9003f4SOleksandr Mazur 		.cpu_code = 195,
2760a9003f4SOleksandr Mazur 	},
2770a9003f4SOleksandr Mazur 	{
2780a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_4, ACL_TRAP),
2790a9003f4SOleksandr Mazur 		.cpu_code = 196,
2800a9003f4SOleksandr Mazur 	},
2810a9003f4SOleksandr Mazur 	{
2820a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_5, ACL_TRAP),
2830a9003f4SOleksandr Mazur 		.cpu_code = 197,
2840a9003f4SOleksandr Mazur 	},
2850a9003f4SOleksandr Mazur 	{
2860a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_6, ACL_TRAP),
2870a9003f4SOleksandr Mazur 		.cpu_code = 198,
2880a9003f4SOleksandr Mazur 	},
2890a9003f4SOleksandr Mazur 	{
2900a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_7, ACL_TRAP),
2910a9003f4SOleksandr Mazur 		.cpu_code = 199,
2920a9003f4SOleksandr Mazur 	},
2930a9003f4SOleksandr Mazur 	{
2940a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(BGP, BGP),
2950a9003f4SOleksandr Mazur 		.cpu_code = 206,
2960a9003f4SOleksandr Mazur 	},
2970a9003f4SOleksandr Mazur 	{
2980a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(SSH, LOCAL_DELIVERY),
2990a9003f4SOleksandr Mazur 		.cpu_code = 207,
3000a9003f4SOleksandr Mazur 	},
3010a9003f4SOleksandr Mazur 	{
3020a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(TELNET, LOCAL_DELIVERY),
3030a9003f4SOleksandr Mazur 		.cpu_code = 208,
3040a9003f4SOleksandr Mazur 	},
3050a9003f4SOleksandr Mazur 	{
3060a9003f4SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_CONTROL(ICMP, LOCAL_DELIVERY),
3070a9003f4SOleksandr Mazur 		.cpu_code = 209,
3080a9003f4SOleksandr Mazur 	},
309a80cf955SOleksandr Mazur 	{
310a80cf955SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_DROP(RXDMA_DROP, BUFFER_DROPS),
311a80cf955SOleksandr Mazur 		.cpu_code = 37,
312a80cf955SOleksandr Mazur 	},
313a80cf955SOleksandr Mazur 	{
314a80cf955SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_DROP(PORT_NO_VLAN, L2_DROPS),
315a80cf955SOleksandr Mazur 		.cpu_code = 39,
316a80cf955SOleksandr Mazur 	},
317a80cf955SOleksandr Mazur 	{
318a80cf955SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_DROP(LOCAL_PORT, L2_DROPS),
319a80cf955SOleksandr Mazur 		.cpu_code = 56,
320a80cf955SOleksandr Mazur 	},
321a80cf955SOleksandr Mazur 	{
322a80cf955SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_DROP(INVALID_SA, L2_DROPS),
323a80cf955SOleksandr Mazur 		.cpu_code = 60,
324a80cf955SOleksandr Mazur 	},
325a80cf955SOleksandr Mazur 	{
326a80cf955SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_DROP(ILLEGAL_IP_ADDR, L3_DROPS),
327a80cf955SOleksandr Mazur 		.cpu_code = 136,
328a80cf955SOleksandr Mazur 	},
329a80cf955SOleksandr Mazur 	{
330a80cf955SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_DROP(ILLEGAL_IPV4_HDR, L3_DROPS),
331a80cf955SOleksandr Mazur 		.cpu_code = 137,
332a80cf955SOleksandr Mazur 	},
333a80cf955SOleksandr Mazur 	{
334a80cf955SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_DROP(IP_UC_DIP_DA_MISMATCH,
335a80cf955SOleksandr Mazur 						  L3_DROPS),
336a80cf955SOleksandr Mazur 		.cpu_code = 138,
337a80cf955SOleksandr Mazur 	},
338a80cf955SOleksandr Mazur 	{
339a80cf955SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_DROP(IP_SIP_IS_ZERO, L3_DROPS),
340a80cf955SOleksandr Mazur 		.cpu_code = 145,
341a80cf955SOleksandr Mazur 	},
342a80cf955SOleksandr Mazur 	{
343a80cf955SOleksandr Mazur 		.trap = PRESTERA_TRAP_DRIVER_DROP(MET_RED, BUFFER_DROPS),
344a80cf955SOleksandr Mazur 		.cpu_code = 185,
345a80cf955SOleksandr Mazur 	},
3460a9003f4SOleksandr Mazur };
3470a9003f4SOleksandr Mazur 
348a80cf955SOleksandr Mazur static int prestera_drop_counter_get(struct devlink *devlink,
349a80cf955SOleksandr Mazur 				     const struct devlink_trap *trap,
350a80cf955SOleksandr Mazur 				     u64 *p_drops);
351a80cf955SOleksandr Mazur 
prestera_dl_info_get(struct devlink * dl,struct devlink_info_req * req,struct netlink_ext_ack * extack)35234dd1710SVadym Kochan static int prestera_dl_info_get(struct devlink *dl,
35334dd1710SVadym Kochan 				struct devlink_info_req *req,
35434dd1710SVadym Kochan 				struct netlink_ext_ack *extack)
35534dd1710SVadym Kochan {
35634dd1710SVadym Kochan 	struct prestera_switch *sw = devlink_priv(dl);
35734dd1710SVadym Kochan 	char buf[16];
35834dd1710SVadym Kochan 
35934dd1710SVadym Kochan 	snprintf(buf, sizeof(buf), "%d.%d.%d",
36034dd1710SVadym Kochan 		 sw->dev->fw_rev.maj,
36134dd1710SVadym Kochan 		 sw->dev->fw_rev.min,
36234dd1710SVadym Kochan 		 sw->dev->fw_rev.sub);
36334dd1710SVadym Kochan 
36434dd1710SVadym Kochan 	return devlink_info_version_running_put(req,
36534dd1710SVadym Kochan 					       DEVLINK_INFO_VERSION_GENERIC_FW,
36634dd1710SVadym Kochan 					       buf);
36734dd1710SVadym Kochan }
36834dd1710SVadym Kochan 
3690a9003f4SOleksandr Mazur static int prestera_trap_init(struct devlink *devlink,
3700a9003f4SOleksandr Mazur 			      const struct devlink_trap *trap, void *trap_ctx);
3710a9003f4SOleksandr Mazur 
3720a9003f4SOleksandr Mazur static int prestera_trap_action_set(struct devlink *devlink,
3730a9003f4SOleksandr Mazur 				    const struct devlink_trap *trap,
3740a9003f4SOleksandr Mazur 				    enum devlink_trap_action action,
3750a9003f4SOleksandr Mazur 				    struct netlink_ext_ack *extack);
3760a9003f4SOleksandr Mazur 
37734dd1710SVadym Kochan static const struct devlink_ops prestera_dl_ops = {
37834dd1710SVadym Kochan 	.info_get = prestera_dl_info_get,
3790a9003f4SOleksandr Mazur 	.trap_init = prestera_trap_init,
3800a9003f4SOleksandr Mazur 	.trap_action_set = prestera_trap_action_set,
381a80cf955SOleksandr Mazur 	.trap_drop_counter_get = prestera_drop_counter_get,
38234dd1710SVadym Kochan };
38334dd1710SVadym Kochan 
prestera_devlink_alloc(struct prestera_device * dev)384919d13a7SLeon Romanovsky struct prestera_switch *prestera_devlink_alloc(struct prestera_device *dev)
38534dd1710SVadym Kochan {
38634dd1710SVadym Kochan 	struct devlink *dl;
38734dd1710SVadym Kochan 
388919d13a7SLeon Romanovsky 	dl = devlink_alloc(&prestera_dl_ops, sizeof(struct prestera_switch),
389919d13a7SLeon Romanovsky 			   dev->dev);
39034dd1710SVadym Kochan 
39134dd1710SVadym Kochan 	return devlink_priv(dl);
39234dd1710SVadym Kochan }
39334dd1710SVadym Kochan 
prestera_devlink_free(struct prestera_switch * sw)39434dd1710SVadym Kochan void prestera_devlink_free(struct prestera_switch *sw)
39534dd1710SVadym Kochan {
39634dd1710SVadym Kochan 	struct devlink *dl = priv_to_devlink(sw);
39734dd1710SVadym Kochan 
39834dd1710SVadym Kochan 	devlink_free(dl);
39934dd1710SVadym Kochan }
40034dd1710SVadym Kochan 
prestera_devlink_register(struct prestera_switch * sw)401*4beb0c24SLeon Romanovsky void prestera_devlink_register(struct prestera_switch *sw)
40234dd1710SVadym Kochan {
40334dd1710SVadym Kochan 	struct devlink *dl = priv_to_devlink(sw);
40434dd1710SVadym Kochan 
405db4278c5SLeon Romanovsky 	devlink_register(dl);
4060a9003f4SOleksandr Mazur }
4070a9003f4SOleksandr Mazur 
prestera_devlink_unregister(struct prestera_switch * sw)40834dd1710SVadym Kochan void prestera_devlink_unregister(struct prestera_switch *sw)
40934dd1710SVadym Kochan {
41034dd1710SVadym Kochan 	struct devlink *dl = priv_to_devlink(sw);
41134dd1710SVadym Kochan 
41234dd1710SVadym Kochan 	devlink_unregister(dl);
41334dd1710SVadym Kochan }
41434dd1710SVadym Kochan 
prestera_devlink_port_register(struct prestera_port * port)41534dd1710SVadym Kochan int prestera_devlink_port_register(struct prestera_port *port)
41634dd1710SVadym Kochan {
41734dd1710SVadym Kochan 	struct prestera_switch *sw = port->sw;
41834dd1710SVadym Kochan 	struct devlink *dl = priv_to_devlink(sw);
41934dd1710SVadym Kochan 	struct devlink_port_attrs attrs = {};
42034dd1710SVadym Kochan 	int err;
42134dd1710SVadym Kochan 
42234dd1710SVadym Kochan 	attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
42334dd1710SVadym Kochan 	attrs.phys.port_number = port->fp_id;
42434dd1710SVadym Kochan 	attrs.switch_id.id_len = sizeof(sw->id);
42534dd1710SVadym Kochan 	memcpy(attrs.switch_id.id, &sw->id, attrs.switch_id.id_len);
42634dd1710SVadym Kochan 
42734dd1710SVadym Kochan 	devlink_port_attrs_set(&port->dl_port, &attrs);
42834dd1710SVadym Kochan 
42934dd1710SVadym Kochan 	err = devlink_port_register(dl, &port->dl_port, port->fp_id);
43034dd1710SVadym Kochan 	if (err) {
43134dd1710SVadym Kochan 		dev_err(prestera_dev(sw), "devlink_port_register failed: %d\n", err);
43234dd1710SVadym Kochan 		return err;
43334dd1710SVadym Kochan 	}
43434dd1710SVadym Kochan 
43534dd1710SVadym Kochan 	return 0;
43634dd1710SVadym Kochan }
43734dd1710SVadym Kochan 
prestera_devlink_port_unregister(struct prestera_port * port)43834dd1710SVadym Kochan void prestera_devlink_port_unregister(struct prestera_port *port)
43934dd1710SVadym Kochan {
44034dd1710SVadym Kochan 	devlink_port_unregister(&port->dl_port);
44134dd1710SVadym Kochan }
44234dd1710SVadym Kochan 
prestera_devlink_traps_register(struct prestera_switch * sw)443*4beb0c24SLeon Romanovsky int prestera_devlink_traps_register(struct prestera_switch *sw)
4440a9003f4SOleksandr Mazur {
4450a9003f4SOleksandr Mazur 	const u32 groups_count = ARRAY_SIZE(prestera_trap_groups_arr);
4460a9003f4SOleksandr Mazur 	const u32 traps_count = ARRAY_SIZE(prestera_trap_items_arr);
4470a9003f4SOleksandr Mazur 	struct devlink *devlink = priv_to_devlink(sw);
4480a9003f4SOleksandr Mazur 	struct prestera_trap_data *trap_data;
4490a9003f4SOleksandr Mazur 	struct prestera_trap *prestera_trap;
4500a9003f4SOleksandr Mazur 	int err, i;
4510a9003f4SOleksandr Mazur 
4520a9003f4SOleksandr Mazur 	trap_data = kzalloc(sizeof(*trap_data), GFP_KERNEL);
4530a9003f4SOleksandr Mazur 	if (!trap_data)
4540a9003f4SOleksandr Mazur 		return -ENOMEM;
4550a9003f4SOleksandr Mazur 
4560a9003f4SOleksandr Mazur 	trap_data->trap_items_arr = kcalloc(traps_count,
4570a9003f4SOleksandr Mazur 					    sizeof(struct prestera_trap_item),
4580a9003f4SOleksandr Mazur 					    GFP_KERNEL);
4590a9003f4SOleksandr Mazur 	if (!trap_data->trap_items_arr) {
4600a9003f4SOleksandr Mazur 		err = -ENOMEM;
4610a9003f4SOleksandr Mazur 		goto err_trap_items_alloc;
4620a9003f4SOleksandr Mazur 	}
4630a9003f4SOleksandr Mazur 
4640a9003f4SOleksandr Mazur 	trap_data->sw = sw;
4650a9003f4SOleksandr Mazur 	trap_data->traps_count = traps_count;
4660a9003f4SOleksandr Mazur 	sw->trap_data = trap_data;
4670a9003f4SOleksandr Mazur 
4680a9003f4SOleksandr Mazur 	err = devlink_trap_groups_register(devlink, prestera_trap_groups_arr,
4690a9003f4SOleksandr Mazur 					   groups_count);
4700a9003f4SOleksandr Mazur 	if (err)
4710a9003f4SOleksandr Mazur 		goto err_groups_register;
4720a9003f4SOleksandr Mazur 
4730a9003f4SOleksandr Mazur 	for (i = 0; i < traps_count; i++) {
4740a9003f4SOleksandr Mazur 		prestera_trap = &prestera_trap_items_arr[i];
4750a9003f4SOleksandr Mazur 		err = devlink_traps_register(devlink, &prestera_trap->trap, 1,
4760a9003f4SOleksandr Mazur 					     sw);
4770a9003f4SOleksandr Mazur 		if (err)
4780a9003f4SOleksandr Mazur 			goto err_trap_register;
4790a9003f4SOleksandr Mazur 	}
4800a9003f4SOleksandr Mazur 
4810a9003f4SOleksandr Mazur 	return 0;
4820a9003f4SOleksandr Mazur 
4830a9003f4SOleksandr Mazur err_trap_register:
4840a9003f4SOleksandr Mazur 	for (i--; i >= 0; i--) {
4850a9003f4SOleksandr Mazur 		prestera_trap = &prestera_trap_items_arr[i];
4860a9003f4SOleksandr Mazur 		devlink_traps_unregister(devlink, &prestera_trap->trap, 1);
4870a9003f4SOleksandr Mazur 	}
48813a9c4acSLeon Romanovsky 	devlink_trap_groups_unregister(devlink, prestera_trap_groups_arr,
48913a9c4acSLeon Romanovsky 				       groups_count);
4900a9003f4SOleksandr Mazur err_groups_register:
4910a9003f4SOleksandr Mazur 	kfree(trap_data->trap_items_arr);
4920a9003f4SOleksandr Mazur err_trap_items_alloc:
4930a9003f4SOleksandr Mazur 	kfree(trap_data);
4940a9003f4SOleksandr Mazur 	return err;
4950a9003f4SOleksandr Mazur }
4960a9003f4SOleksandr Mazur 
4970a9003f4SOleksandr Mazur static struct prestera_trap_item *
prestera_get_trap_item_by_cpu_code(struct prestera_switch * sw,u8 cpu_code)4980a9003f4SOleksandr Mazur prestera_get_trap_item_by_cpu_code(struct prestera_switch *sw, u8 cpu_code)
4990a9003f4SOleksandr Mazur {
5000a9003f4SOleksandr Mazur 	struct prestera_trap_data *trap_data = sw->trap_data;
5010a9003f4SOleksandr Mazur 	struct prestera_trap *prestera_trap;
5020a9003f4SOleksandr Mazur 	int i;
5030a9003f4SOleksandr Mazur 
5040a9003f4SOleksandr Mazur 	for (i = 0; i < trap_data->traps_count; i++) {
5050a9003f4SOleksandr Mazur 		prestera_trap = &prestera_trap_items_arr[i];
5060a9003f4SOleksandr Mazur 		if (cpu_code == prestera_trap->cpu_code)
5070a9003f4SOleksandr Mazur 			return &trap_data->trap_items_arr[i];
5080a9003f4SOleksandr Mazur 	}
5090a9003f4SOleksandr Mazur 
5100a9003f4SOleksandr Mazur 	return NULL;
5110a9003f4SOleksandr Mazur }
5120a9003f4SOleksandr Mazur 
prestera_devlink_trap_report(struct prestera_port * port,struct sk_buff * skb,u8 cpu_code)5130a9003f4SOleksandr Mazur void prestera_devlink_trap_report(struct prestera_port *port,
5140a9003f4SOleksandr Mazur 				  struct sk_buff *skb, u8 cpu_code)
5150a9003f4SOleksandr Mazur {
5160a9003f4SOleksandr Mazur 	struct prestera_trap_item *trap_item;
5170a9003f4SOleksandr Mazur 	struct devlink *devlink;
5180a9003f4SOleksandr Mazur 
5190a9003f4SOleksandr Mazur 	devlink = port->dl_port.devlink;
5200a9003f4SOleksandr Mazur 
5210a9003f4SOleksandr Mazur 	trap_item = prestera_get_trap_item_by_cpu_code(port->sw, cpu_code);
5220a9003f4SOleksandr Mazur 	if (unlikely(!trap_item))
5230a9003f4SOleksandr Mazur 		return;
5240a9003f4SOleksandr Mazur 
5250a9003f4SOleksandr Mazur 	devlink_trap_report(devlink, skb, trap_item->trap_ctx,
5260a9003f4SOleksandr Mazur 			    &port->dl_port, NULL);
5270a9003f4SOleksandr Mazur }
5280a9003f4SOleksandr Mazur 
5290a9003f4SOleksandr Mazur static struct prestera_trap_item *
prestera_devlink_trap_item_lookup(struct prestera_switch * sw,u16 trap_id)5300a9003f4SOleksandr Mazur prestera_devlink_trap_item_lookup(struct prestera_switch *sw, u16 trap_id)
5310a9003f4SOleksandr Mazur {
5320a9003f4SOleksandr Mazur 	struct prestera_trap_data *trap_data = sw->trap_data;
5330a9003f4SOleksandr Mazur 	int i;
5340a9003f4SOleksandr Mazur 
5350a9003f4SOleksandr Mazur 	for (i = 0; i < ARRAY_SIZE(prestera_trap_items_arr); i++) {
5360a9003f4SOleksandr Mazur 		if (prestera_trap_items_arr[i].trap.id == trap_id)
5370a9003f4SOleksandr Mazur 			return &trap_data->trap_items_arr[i];
5380a9003f4SOleksandr Mazur 	}
5390a9003f4SOleksandr Mazur 
5400a9003f4SOleksandr Mazur 	return NULL;
5410a9003f4SOleksandr Mazur }
5420a9003f4SOleksandr Mazur 
prestera_trap_init(struct devlink * devlink,const struct devlink_trap * trap,void * trap_ctx)5430a9003f4SOleksandr Mazur static int prestera_trap_init(struct devlink *devlink,
5440a9003f4SOleksandr Mazur 			      const struct devlink_trap *trap, void *trap_ctx)
5450a9003f4SOleksandr Mazur {
5460a9003f4SOleksandr Mazur 	struct prestera_switch *sw = devlink_priv(devlink);
5470a9003f4SOleksandr Mazur 	struct prestera_trap_item *trap_item;
5480a9003f4SOleksandr Mazur 
5490a9003f4SOleksandr Mazur 	trap_item = prestera_devlink_trap_item_lookup(sw, trap->id);
5500a9003f4SOleksandr Mazur 	if (WARN_ON(!trap_item))
5510a9003f4SOleksandr Mazur 		return -EINVAL;
5520a9003f4SOleksandr Mazur 
5530a9003f4SOleksandr Mazur 	trap_item->trap_ctx = trap_ctx;
5540a9003f4SOleksandr Mazur 	trap_item->action = trap->init_action;
5550a9003f4SOleksandr Mazur 
5560a9003f4SOleksandr Mazur 	return 0;
5570a9003f4SOleksandr Mazur }
5580a9003f4SOleksandr Mazur 
prestera_trap_action_set(struct devlink * devlink,const struct devlink_trap * trap,enum devlink_trap_action action,struct netlink_ext_ack * extack)5590a9003f4SOleksandr Mazur static int prestera_trap_action_set(struct devlink *devlink,
5600a9003f4SOleksandr Mazur 				    const struct devlink_trap *trap,
5610a9003f4SOleksandr Mazur 				    enum devlink_trap_action action,
5620a9003f4SOleksandr Mazur 				    struct netlink_ext_ack *extack)
5630a9003f4SOleksandr Mazur {
5640a9003f4SOleksandr Mazur 	/* Currently, driver does not support trap action altering */
5650a9003f4SOleksandr Mazur 	return -EOPNOTSUPP;
5660a9003f4SOleksandr Mazur }
5670a9003f4SOleksandr Mazur 
prestera_drop_counter_get(struct devlink * devlink,const struct devlink_trap * trap,u64 * p_drops)568a80cf955SOleksandr Mazur static int prestera_drop_counter_get(struct devlink *devlink,
569a80cf955SOleksandr Mazur 				     const struct devlink_trap *trap,
570a80cf955SOleksandr Mazur 				     u64 *p_drops)
571a80cf955SOleksandr Mazur {
572a80cf955SOleksandr Mazur 	struct prestera_switch *sw = devlink_priv(devlink);
573a80cf955SOleksandr Mazur 	enum prestera_hw_cpu_code_cnt_t cpu_code_type =
574a80cf955SOleksandr Mazur 		PRESTERA_HW_CPU_CODE_CNT_TYPE_DROP;
575a80cf955SOleksandr Mazur 	struct prestera_trap *prestera_trap =
576a80cf955SOleksandr Mazur 		container_of(trap, struct prestera_trap, trap);
577a80cf955SOleksandr Mazur 
578a80cf955SOleksandr Mazur 	return prestera_hw_cpu_code_counters_get(sw, prestera_trap->cpu_code,
579a80cf955SOleksandr Mazur 						 cpu_code_type, p_drops);
580a80cf955SOleksandr Mazur }
581a80cf955SOleksandr Mazur 
prestera_devlink_traps_unregister(struct prestera_switch * sw)582*4beb0c24SLeon Romanovsky void prestera_devlink_traps_unregister(struct prestera_switch *sw)
5830a9003f4SOleksandr Mazur {
584*4beb0c24SLeon Romanovsky 	struct prestera_trap_data *trap_data = sw->trap_data;
5850a9003f4SOleksandr Mazur 	struct devlink *dl = priv_to_devlink(sw);
5860a9003f4SOleksandr Mazur 	const struct devlink_trap *trap;
5870a9003f4SOleksandr Mazur 	int i;
5880a9003f4SOleksandr Mazur 
5890a9003f4SOleksandr Mazur 	for (i = 0; i < ARRAY_SIZE(prestera_trap_items_arr); ++i) {
5900a9003f4SOleksandr Mazur 		trap = &prestera_trap_items_arr[i].trap;
5910a9003f4SOleksandr Mazur 		devlink_traps_unregister(dl, trap, 1);
5920a9003f4SOleksandr Mazur 	}
5930a9003f4SOleksandr Mazur 
5940a9003f4SOleksandr Mazur 	devlink_trap_groups_unregister(dl, prestera_trap_groups_arr,
5950a9003f4SOleksandr Mazur 				       ARRAY_SIZE(prestera_trap_groups_arr));
596*4beb0c24SLeon Romanovsky 	kfree(trap_data->trap_items_arr);
597*4beb0c24SLeon Romanovsky 	kfree(trap_data);
5980a9003f4SOleksandr Mazur }
599