1*4882a593Smuzhiyun // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2*4882a593Smuzhiyun /* Copyright (c) 2019 Mellanox Technologies. All rights reserved */
3*4882a593Smuzhiyun
4*4882a593Smuzhiyun #include <linux/bitops.h>
5*4882a593Smuzhiyun #include <linux/kernel.h>
6*4882a593Smuzhiyun #include <linux/netlink.h>
7*4882a593Smuzhiyun #include <net/devlink.h>
8*4882a593Smuzhiyun #include <uapi/linux/devlink.h>
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include "core.h"
11*4882a593Smuzhiyun #include "reg.h"
12*4882a593Smuzhiyun #include "spectrum.h"
13*4882a593Smuzhiyun #include "spectrum_trap.h"
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun struct mlxsw_sp_trap_policer_item {
16*4882a593Smuzhiyun struct devlink_trap_policer policer;
17*4882a593Smuzhiyun u16 hw_id;
18*4882a593Smuzhiyun };
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun struct mlxsw_sp_trap_group_item {
21*4882a593Smuzhiyun struct devlink_trap_group group;
22*4882a593Smuzhiyun u16 hw_group_id;
23*4882a593Smuzhiyun u8 priority;
24*4882a593Smuzhiyun u8 fixed_policer:1; /* Whether policer binding can change */
25*4882a593Smuzhiyun };
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun #define MLXSW_SP_TRAP_LISTENERS_MAX 3
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun struct mlxsw_sp_trap_item {
30*4882a593Smuzhiyun struct devlink_trap trap;
31*4882a593Smuzhiyun struct mlxsw_listener listeners_arr[MLXSW_SP_TRAP_LISTENERS_MAX];
32*4882a593Smuzhiyun u8 is_source:1;
33*4882a593Smuzhiyun };
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun /* All driver-specific traps must be documented in
36*4882a593Smuzhiyun * Documentation/networking/devlink/mlxsw.rst
37*4882a593Smuzhiyun */
38*4882a593Smuzhiyun enum {
39*4882a593Smuzhiyun DEVLINK_MLXSW_TRAP_ID_BASE = DEVLINK_TRAP_GENERIC_ID_MAX,
40*4882a593Smuzhiyun DEVLINK_MLXSW_TRAP_ID_IRIF_DISABLED,
41*4882a593Smuzhiyun DEVLINK_MLXSW_TRAP_ID_ERIF_DISABLED,
42*4882a593Smuzhiyun };
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun #define DEVLINK_MLXSW_TRAP_NAME_IRIF_DISABLED \
45*4882a593Smuzhiyun "irif_disabled"
46*4882a593Smuzhiyun #define DEVLINK_MLXSW_TRAP_NAME_ERIF_DISABLED \
47*4882a593Smuzhiyun "erif_disabled"
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun #define MLXSW_SP_TRAP_METADATA DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun enum {
52*4882a593Smuzhiyun /* Packet was early dropped. */
53*4882a593Smuzhiyun MLXSW_SP_MIRROR_REASON_INGRESS_WRED = 9,
54*4882a593Smuzhiyun };
55*4882a593Smuzhiyun
mlxsw_sp_rx_listener(struct mlxsw_sp * mlxsw_sp,struct sk_buff * skb,u8 local_port,struct mlxsw_sp_port * mlxsw_sp_port)56*4882a593Smuzhiyun static int mlxsw_sp_rx_listener(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
57*4882a593Smuzhiyun u8 local_port,
58*4882a593Smuzhiyun struct mlxsw_sp_port *mlxsw_sp_port)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun struct mlxsw_sp_port_pcpu_stats *pcpu_stats;
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun if (unlikely(!mlxsw_sp_port)) {
63*4882a593Smuzhiyun dev_warn_ratelimited(mlxsw_sp->bus_info->dev, "Port %d: skb received for non-existent port\n",
64*4882a593Smuzhiyun local_port);
65*4882a593Smuzhiyun kfree_skb(skb);
66*4882a593Smuzhiyun return -EINVAL;
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun skb->dev = mlxsw_sp_port->dev;
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun pcpu_stats = this_cpu_ptr(mlxsw_sp_port->pcpu_stats);
72*4882a593Smuzhiyun u64_stats_update_begin(&pcpu_stats->syncp);
73*4882a593Smuzhiyun pcpu_stats->rx_packets++;
74*4882a593Smuzhiyun pcpu_stats->rx_bytes += skb->len;
75*4882a593Smuzhiyun u64_stats_update_end(&pcpu_stats->syncp);
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun skb->protocol = eth_type_trans(skb, skb->dev);
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun return 0;
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun
mlxsw_sp_rx_drop_listener(struct sk_buff * skb,u8 local_port,void * trap_ctx)82*4882a593Smuzhiyun static void mlxsw_sp_rx_drop_listener(struct sk_buff *skb, u8 local_port,
83*4882a593Smuzhiyun void *trap_ctx)
84*4882a593Smuzhiyun {
85*4882a593Smuzhiyun struct devlink_port *in_devlink_port;
86*4882a593Smuzhiyun struct mlxsw_sp_port *mlxsw_sp_port;
87*4882a593Smuzhiyun struct mlxsw_sp *mlxsw_sp;
88*4882a593Smuzhiyun struct devlink *devlink;
89*4882a593Smuzhiyun int err;
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun mlxsw_sp = devlink_trap_ctx_priv(trap_ctx);
92*4882a593Smuzhiyun mlxsw_sp_port = mlxsw_sp->ports[local_port];
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun err = mlxsw_sp_rx_listener(mlxsw_sp, skb, local_port, mlxsw_sp_port);
95*4882a593Smuzhiyun if (err)
96*4882a593Smuzhiyun return;
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun devlink = priv_to_devlink(mlxsw_sp->core);
99*4882a593Smuzhiyun in_devlink_port = mlxsw_core_port_devlink_port_get(mlxsw_sp->core,
100*4882a593Smuzhiyun local_port);
101*4882a593Smuzhiyun skb_push(skb, ETH_HLEN);
102*4882a593Smuzhiyun devlink_trap_report(devlink, skb, trap_ctx, in_devlink_port, NULL);
103*4882a593Smuzhiyun consume_skb(skb);
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
mlxsw_sp_rx_acl_drop_listener(struct sk_buff * skb,u8 local_port,void * trap_ctx)106*4882a593Smuzhiyun static void mlxsw_sp_rx_acl_drop_listener(struct sk_buff *skb, u8 local_port,
107*4882a593Smuzhiyun void *trap_ctx)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun u32 cookie_index = mlxsw_skb_cb(skb)->cookie_index;
110*4882a593Smuzhiyun const struct flow_action_cookie *fa_cookie;
111*4882a593Smuzhiyun struct devlink_port *in_devlink_port;
112*4882a593Smuzhiyun struct mlxsw_sp_port *mlxsw_sp_port;
113*4882a593Smuzhiyun struct mlxsw_sp *mlxsw_sp;
114*4882a593Smuzhiyun struct devlink *devlink;
115*4882a593Smuzhiyun int err;
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun mlxsw_sp = devlink_trap_ctx_priv(trap_ctx);
118*4882a593Smuzhiyun mlxsw_sp_port = mlxsw_sp->ports[local_port];
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun err = mlxsw_sp_rx_listener(mlxsw_sp, skb, local_port, mlxsw_sp_port);
121*4882a593Smuzhiyun if (err)
122*4882a593Smuzhiyun return;
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun devlink = priv_to_devlink(mlxsw_sp->core);
125*4882a593Smuzhiyun in_devlink_port = mlxsw_core_port_devlink_port_get(mlxsw_sp->core,
126*4882a593Smuzhiyun local_port);
127*4882a593Smuzhiyun skb_push(skb, ETH_HLEN);
128*4882a593Smuzhiyun rcu_read_lock();
129*4882a593Smuzhiyun fa_cookie = mlxsw_sp_acl_act_cookie_lookup(mlxsw_sp, cookie_index);
130*4882a593Smuzhiyun devlink_trap_report(devlink, skb, trap_ctx, in_devlink_port, fa_cookie);
131*4882a593Smuzhiyun rcu_read_unlock();
132*4882a593Smuzhiyun consume_skb(skb);
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun
__mlxsw_sp_rx_no_mark_listener(struct sk_buff * skb,u8 local_port,void * trap_ctx)135*4882a593Smuzhiyun static int __mlxsw_sp_rx_no_mark_listener(struct sk_buff *skb, u8 local_port,
136*4882a593Smuzhiyun void *trap_ctx)
137*4882a593Smuzhiyun {
138*4882a593Smuzhiyun struct devlink_port *in_devlink_port;
139*4882a593Smuzhiyun struct mlxsw_sp_port *mlxsw_sp_port;
140*4882a593Smuzhiyun struct mlxsw_sp *mlxsw_sp;
141*4882a593Smuzhiyun struct devlink *devlink;
142*4882a593Smuzhiyun int err;
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun mlxsw_sp = devlink_trap_ctx_priv(trap_ctx);
145*4882a593Smuzhiyun mlxsw_sp_port = mlxsw_sp->ports[local_port];
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun err = mlxsw_sp_rx_listener(mlxsw_sp, skb, local_port, mlxsw_sp_port);
148*4882a593Smuzhiyun if (err)
149*4882a593Smuzhiyun return err;
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun devlink = priv_to_devlink(mlxsw_sp->core);
152*4882a593Smuzhiyun in_devlink_port = mlxsw_core_port_devlink_port_get(mlxsw_sp->core,
153*4882a593Smuzhiyun local_port);
154*4882a593Smuzhiyun skb_push(skb, ETH_HLEN);
155*4882a593Smuzhiyun devlink_trap_report(devlink, skb, trap_ctx, in_devlink_port, NULL);
156*4882a593Smuzhiyun skb_pull(skb, ETH_HLEN);
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun return 0;
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun
mlxsw_sp_rx_no_mark_listener(struct sk_buff * skb,u8 local_port,void * trap_ctx)161*4882a593Smuzhiyun static void mlxsw_sp_rx_no_mark_listener(struct sk_buff *skb, u8 local_port,
162*4882a593Smuzhiyun void *trap_ctx)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun int err;
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun err = __mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx);
167*4882a593Smuzhiyun if (err)
168*4882a593Smuzhiyun return;
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun netif_receive_skb(skb);
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun
mlxsw_sp_rx_mark_listener(struct sk_buff * skb,u8 local_port,void * trap_ctx)173*4882a593Smuzhiyun static void mlxsw_sp_rx_mark_listener(struct sk_buff *skb, u8 local_port,
174*4882a593Smuzhiyun void *trap_ctx)
175*4882a593Smuzhiyun {
176*4882a593Smuzhiyun skb->offload_fwd_mark = 1;
177*4882a593Smuzhiyun mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx);
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun
mlxsw_sp_rx_l3_mark_listener(struct sk_buff * skb,u8 local_port,void * trap_ctx)180*4882a593Smuzhiyun static void mlxsw_sp_rx_l3_mark_listener(struct sk_buff *skb, u8 local_port,
181*4882a593Smuzhiyun void *trap_ctx)
182*4882a593Smuzhiyun {
183*4882a593Smuzhiyun skb->offload_l3_fwd_mark = 1;
184*4882a593Smuzhiyun skb->offload_fwd_mark = 1;
185*4882a593Smuzhiyun mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx);
186*4882a593Smuzhiyun }
187*4882a593Smuzhiyun
mlxsw_sp_rx_ptp_listener(struct sk_buff * skb,u8 local_port,void * trap_ctx)188*4882a593Smuzhiyun static void mlxsw_sp_rx_ptp_listener(struct sk_buff *skb, u8 local_port,
189*4882a593Smuzhiyun void *trap_ctx)
190*4882a593Smuzhiyun {
191*4882a593Smuzhiyun struct mlxsw_sp *mlxsw_sp = devlink_trap_ctx_priv(trap_ctx);
192*4882a593Smuzhiyun int err;
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun err = __mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx);
195*4882a593Smuzhiyun if (err)
196*4882a593Smuzhiyun return;
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun /* The PTP handler expects skb->data to point to the start of the
199*4882a593Smuzhiyun * Ethernet header.
200*4882a593Smuzhiyun */
201*4882a593Smuzhiyun skb_push(skb, ETH_HLEN);
202*4882a593Smuzhiyun mlxsw_sp_ptp_receive(mlxsw_sp, skb, local_port);
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun
mlxsw_sp_rx_sample_listener(struct sk_buff * skb,u8 local_port,void * trap_ctx)205*4882a593Smuzhiyun static void mlxsw_sp_rx_sample_listener(struct sk_buff *skb, u8 local_port,
206*4882a593Smuzhiyun void *trap_ctx)
207*4882a593Smuzhiyun {
208*4882a593Smuzhiyun struct mlxsw_sp *mlxsw_sp = devlink_trap_ctx_priv(trap_ctx);
209*4882a593Smuzhiyun int err;
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun err = __mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx);
212*4882a593Smuzhiyun if (err)
213*4882a593Smuzhiyun return;
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun /* The sample handler expects skb->data to point to the start of the
216*4882a593Smuzhiyun * Ethernet header.
217*4882a593Smuzhiyun */
218*4882a593Smuzhiyun skb_push(skb, ETH_HLEN);
219*4882a593Smuzhiyun mlxsw_sp_sample_receive(mlxsw_sp, skb, local_port);
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun #define MLXSW_SP_TRAP_DROP(_id, _group_id) \
223*4882a593Smuzhiyun DEVLINK_TRAP_GENERIC(DROP, DROP, _id, \
224*4882a593Smuzhiyun DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
225*4882a593Smuzhiyun MLXSW_SP_TRAP_METADATA)
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun #define MLXSW_SP_TRAP_DROP_EXT(_id, _group_id, _metadata) \
228*4882a593Smuzhiyun DEVLINK_TRAP_GENERIC(DROP, DROP, _id, \
229*4882a593Smuzhiyun DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
230*4882a593Smuzhiyun MLXSW_SP_TRAP_METADATA | (_metadata))
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun #define MLXSW_SP_TRAP_BUFFER_DROP(_id) \
233*4882a593Smuzhiyun DEVLINK_TRAP_GENERIC(DROP, TRAP, _id, \
234*4882a593Smuzhiyun DEVLINK_TRAP_GROUP_GENERIC_ID_BUFFER_DROPS, \
235*4882a593Smuzhiyun MLXSW_SP_TRAP_METADATA)
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun #define MLXSW_SP_TRAP_DRIVER_DROP(_id, _group_id) \
238*4882a593Smuzhiyun DEVLINK_TRAP_DRIVER(DROP, DROP, DEVLINK_MLXSW_TRAP_ID_##_id, \
239*4882a593Smuzhiyun DEVLINK_MLXSW_TRAP_NAME_##_id, \
240*4882a593Smuzhiyun DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
241*4882a593Smuzhiyun MLXSW_SP_TRAP_METADATA)
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun #define MLXSW_SP_TRAP_EXCEPTION(_id, _group_id) \
244*4882a593Smuzhiyun DEVLINK_TRAP_GENERIC(EXCEPTION, TRAP, _id, \
245*4882a593Smuzhiyun DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
246*4882a593Smuzhiyun MLXSW_SP_TRAP_METADATA)
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun #define MLXSW_SP_TRAP_CONTROL(_id, _group_id, _action) \
249*4882a593Smuzhiyun DEVLINK_TRAP_GENERIC(CONTROL, _action, _id, \
250*4882a593Smuzhiyun DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
251*4882a593Smuzhiyun MLXSW_SP_TRAP_METADATA)
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun #define MLXSW_SP_RXL_DISCARD(_id, _group_id) \
254*4882a593Smuzhiyun MLXSW_RXL_DIS(mlxsw_sp_rx_drop_listener, DISCARD_##_id, \
255*4882a593Smuzhiyun TRAP_EXCEPTION_TO_CPU, false, SP_##_group_id, \
256*4882a593Smuzhiyun SET_FW_DEFAULT, SP_##_group_id)
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun #define MLXSW_SP_RXL_ACL_DISCARD(_id, _en_group_id, _dis_group_id) \
259*4882a593Smuzhiyun MLXSW_RXL_DIS(mlxsw_sp_rx_acl_drop_listener, DISCARD_##_id, \
260*4882a593Smuzhiyun TRAP_EXCEPTION_TO_CPU, false, SP_##_en_group_id, \
261*4882a593Smuzhiyun SET_FW_DEFAULT, SP_##_dis_group_id)
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun #define MLXSW_SP_RXL_BUFFER_DISCARD(_mirror_reason) \
264*4882a593Smuzhiyun MLXSW_RXL_MIRROR(mlxsw_sp_rx_drop_listener, 0, SP_BUFFER_DISCARDS, \
265*4882a593Smuzhiyun MLXSW_SP_MIRROR_REASON_##_mirror_reason)
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun #define MLXSW_SP_RXL_EXCEPTION(_id, _group_id, _action) \
268*4882a593Smuzhiyun MLXSW_RXL(mlxsw_sp_rx_mark_listener, _id, \
269*4882a593Smuzhiyun _action, false, SP_##_group_id, SET_FW_DEFAULT)
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun #define MLXSW_SP_RXL_NO_MARK(_id, _group_id, _action, _is_ctrl) \
272*4882a593Smuzhiyun MLXSW_RXL(mlxsw_sp_rx_no_mark_listener, _id, _action, \
273*4882a593Smuzhiyun _is_ctrl, SP_##_group_id, DISCARD)
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun #define MLXSW_SP_RXL_MARK(_id, _group_id, _action, _is_ctrl) \
276*4882a593Smuzhiyun MLXSW_RXL(mlxsw_sp_rx_mark_listener, _id, _action, _is_ctrl, \
277*4882a593Smuzhiyun SP_##_group_id, DISCARD)
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun #define MLXSW_SP_RXL_L3_MARK(_id, _group_id, _action, _is_ctrl) \
280*4882a593Smuzhiyun MLXSW_RXL(mlxsw_sp_rx_l3_mark_listener, _id, _action, _is_ctrl, \
281*4882a593Smuzhiyun SP_##_group_id, DISCARD)
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun #define MLXSW_SP_TRAP_POLICER(_id, _rate, _burst) \
284*4882a593Smuzhiyun DEVLINK_TRAP_POLICER(_id, _rate, _burst, \
285*4882a593Smuzhiyun MLXSW_REG_QPCR_HIGHEST_CIR, \
286*4882a593Smuzhiyun MLXSW_REG_QPCR_LOWEST_CIR, \
287*4882a593Smuzhiyun 1 << MLXSW_REG_QPCR_HIGHEST_CBS, \
288*4882a593Smuzhiyun 1 << MLXSW_REG_QPCR_LOWEST_CBS)
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun /* Ordered by policer identifier */
291*4882a593Smuzhiyun static const struct mlxsw_sp_trap_policer_item
292*4882a593Smuzhiyun mlxsw_sp_trap_policer_items_arr[] = {
293*4882a593Smuzhiyun {
294*4882a593Smuzhiyun .policer = MLXSW_SP_TRAP_POLICER(1, 10 * 1024, 4096),
295*4882a593Smuzhiyun },
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun .policer = MLXSW_SP_TRAP_POLICER(2, 128, 128),
298*4882a593Smuzhiyun },
299*4882a593Smuzhiyun {
300*4882a593Smuzhiyun .policer = MLXSW_SP_TRAP_POLICER(3, 128, 128),
301*4882a593Smuzhiyun },
302*4882a593Smuzhiyun {
303*4882a593Smuzhiyun .policer = MLXSW_SP_TRAP_POLICER(4, 128, 128),
304*4882a593Smuzhiyun },
305*4882a593Smuzhiyun {
306*4882a593Smuzhiyun .policer = MLXSW_SP_TRAP_POLICER(5, 16 * 1024, 8192),
307*4882a593Smuzhiyun },
308*4882a593Smuzhiyun {
309*4882a593Smuzhiyun .policer = MLXSW_SP_TRAP_POLICER(6, 128, 128),
310*4882a593Smuzhiyun },
311*4882a593Smuzhiyun {
312*4882a593Smuzhiyun .policer = MLXSW_SP_TRAP_POLICER(7, 1024, 512),
313*4882a593Smuzhiyun },
314*4882a593Smuzhiyun {
315*4882a593Smuzhiyun .policer = MLXSW_SP_TRAP_POLICER(8, 20 * 1024, 8192),
316*4882a593Smuzhiyun },
317*4882a593Smuzhiyun {
318*4882a593Smuzhiyun .policer = MLXSW_SP_TRAP_POLICER(9, 128, 128),
319*4882a593Smuzhiyun },
320*4882a593Smuzhiyun {
321*4882a593Smuzhiyun .policer = MLXSW_SP_TRAP_POLICER(10, 1024, 512),
322*4882a593Smuzhiyun },
323*4882a593Smuzhiyun {
324*4882a593Smuzhiyun .policer = MLXSW_SP_TRAP_POLICER(11, 256, 128),
325*4882a593Smuzhiyun },
326*4882a593Smuzhiyun {
327*4882a593Smuzhiyun .policer = MLXSW_SP_TRAP_POLICER(12, 128, 128),
328*4882a593Smuzhiyun },
329*4882a593Smuzhiyun {
330*4882a593Smuzhiyun .policer = MLXSW_SP_TRAP_POLICER(13, 128, 128),
331*4882a593Smuzhiyun },
332*4882a593Smuzhiyun {
333*4882a593Smuzhiyun .policer = MLXSW_SP_TRAP_POLICER(14, 1024, 512),
334*4882a593Smuzhiyun },
335*4882a593Smuzhiyun {
336*4882a593Smuzhiyun .policer = MLXSW_SP_TRAP_POLICER(15, 1024, 512),
337*4882a593Smuzhiyun },
338*4882a593Smuzhiyun {
339*4882a593Smuzhiyun .policer = MLXSW_SP_TRAP_POLICER(16, 24 * 1024, 16384),
340*4882a593Smuzhiyun },
341*4882a593Smuzhiyun {
342*4882a593Smuzhiyun .policer = MLXSW_SP_TRAP_POLICER(17, 19 * 1024, 8192),
343*4882a593Smuzhiyun },
344*4882a593Smuzhiyun {
345*4882a593Smuzhiyun .policer = MLXSW_SP_TRAP_POLICER(18, 1024, 512),
346*4882a593Smuzhiyun },
347*4882a593Smuzhiyun {
348*4882a593Smuzhiyun .policer = MLXSW_SP_TRAP_POLICER(19, 1024, 512),
349*4882a593Smuzhiyun },
350*4882a593Smuzhiyun {
351*4882a593Smuzhiyun .policer = MLXSW_SP_TRAP_POLICER(20, 10240, 4096),
352*4882a593Smuzhiyun },
353*4882a593Smuzhiyun };
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun static const struct mlxsw_sp_trap_group_item mlxsw_sp_trap_group_items_arr[] = {
356*4882a593Smuzhiyun {
357*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS, 1),
358*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_L2_DISCARDS,
359*4882a593Smuzhiyun .priority = 0,
360*4882a593Smuzhiyun },
361*4882a593Smuzhiyun {
362*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(L3_DROPS, 1),
363*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_L3_DISCARDS,
364*4882a593Smuzhiyun .priority = 0,
365*4882a593Smuzhiyun },
366*4882a593Smuzhiyun {
367*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(L3_EXCEPTIONS, 1),
368*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_L3_EXCEPTIONS,
369*4882a593Smuzhiyun .priority = 2,
370*4882a593Smuzhiyun },
371*4882a593Smuzhiyun {
372*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(TUNNEL_DROPS, 1),
373*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_TUNNEL_DISCARDS,
374*4882a593Smuzhiyun .priority = 0,
375*4882a593Smuzhiyun },
376*4882a593Smuzhiyun {
377*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(ACL_DROPS, 1),
378*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_ACL_DISCARDS,
379*4882a593Smuzhiyun .priority = 0,
380*4882a593Smuzhiyun },
381*4882a593Smuzhiyun {
382*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(STP, 2),
383*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_STP,
384*4882a593Smuzhiyun .priority = 5,
385*4882a593Smuzhiyun },
386*4882a593Smuzhiyun {
387*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(LACP, 3),
388*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_LACP,
389*4882a593Smuzhiyun .priority = 5,
390*4882a593Smuzhiyun },
391*4882a593Smuzhiyun {
392*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(LLDP, 4),
393*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_LLDP,
394*4882a593Smuzhiyun .priority = 5,
395*4882a593Smuzhiyun },
396*4882a593Smuzhiyun {
397*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(MC_SNOOPING, 5),
398*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_MC_SNOOPING,
399*4882a593Smuzhiyun .priority = 3,
400*4882a593Smuzhiyun },
401*4882a593Smuzhiyun {
402*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(DHCP, 6),
403*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_DHCP,
404*4882a593Smuzhiyun .priority = 2,
405*4882a593Smuzhiyun },
406*4882a593Smuzhiyun {
407*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(NEIGH_DISCOVERY, 7),
408*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_NEIGH_DISCOVERY,
409*4882a593Smuzhiyun .priority = 2,
410*4882a593Smuzhiyun },
411*4882a593Smuzhiyun {
412*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(BFD, 8),
413*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_BFD,
414*4882a593Smuzhiyun .priority = 5,
415*4882a593Smuzhiyun },
416*4882a593Smuzhiyun {
417*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(OSPF, 9),
418*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF,
419*4882a593Smuzhiyun .priority = 5,
420*4882a593Smuzhiyun },
421*4882a593Smuzhiyun {
422*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(BGP, 10),
423*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_BGP,
424*4882a593Smuzhiyun .priority = 4,
425*4882a593Smuzhiyun },
426*4882a593Smuzhiyun {
427*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(VRRP, 11),
428*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_VRRP,
429*4882a593Smuzhiyun .priority = 5,
430*4882a593Smuzhiyun },
431*4882a593Smuzhiyun {
432*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(PIM, 12),
433*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_PIM,
434*4882a593Smuzhiyun .priority = 5,
435*4882a593Smuzhiyun },
436*4882a593Smuzhiyun {
437*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(UC_LB, 13),
438*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_LBERROR,
439*4882a593Smuzhiyun .priority = 0,
440*4882a593Smuzhiyun },
441*4882a593Smuzhiyun {
442*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(LOCAL_DELIVERY, 14),
443*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_IP2ME,
444*4882a593Smuzhiyun .priority = 2,
445*4882a593Smuzhiyun },
446*4882a593Smuzhiyun {
447*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(EXTERNAL_DELIVERY, 19),
448*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_EXTERNAL_ROUTE,
449*4882a593Smuzhiyun .priority = 1,
450*4882a593Smuzhiyun },
451*4882a593Smuzhiyun {
452*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(IPV6, 15),
453*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_IPV6,
454*4882a593Smuzhiyun .priority = 2,
455*4882a593Smuzhiyun },
456*4882a593Smuzhiyun {
457*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(PTP_EVENT, 16),
458*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP0,
459*4882a593Smuzhiyun .priority = 5,
460*4882a593Smuzhiyun },
461*4882a593Smuzhiyun {
462*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(PTP_GENERAL, 17),
463*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP1,
464*4882a593Smuzhiyun .priority = 2,
465*4882a593Smuzhiyun },
466*4882a593Smuzhiyun {
467*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(ACL_SAMPLE, 0),
468*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_PKT_SAMPLE,
469*4882a593Smuzhiyun .priority = 0,
470*4882a593Smuzhiyun },
471*4882a593Smuzhiyun {
472*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(ACL_TRAP, 18),
473*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_FLOW_LOGGING,
474*4882a593Smuzhiyun .priority = 4,
475*4882a593Smuzhiyun },
476*4882a593Smuzhiyun };
477*4882a593Smuzhiyun
478*4882a593Smuzhiyun static const struct mlxsw_sp_trap_item mlxsw_sp_trap_items_arr[] = {
479*4882a593Smuzhiyun {
480*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DROP(SMAC_MC, L2_DROPS),
481*4882a593Smuzhiyun .listeners_arr = {
482*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(ING_PACKET_SMAC_MC, L2_DISCARDS),
483*4882a593Smuzhiyun },
484*4882a593Smuzhiyun },
485*4882a593Smuzhiyun {
486*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DROP(VLAN_TAG_MISMATCH, L2_DROPS),
487*4882a593Smuzhiyun .listeners_arr = {
488*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(ING_SWITCH_VTAG_ALLOW,
489*4882a593Smuzhiyun L2_DISCARDS),
490*4882a593Smuzhiyun },
491*4882a593Smuzhiyun },
492*4882a593Smuzhiyun {
493*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DROP(INGRESS_VLAN_FILTER, L2_DROPS),
494*4882a593Smuzhiyun .listeners_arr = {
495*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(ING_SWITCH_VLAN, L2_DISCARDS),
496*4882a593Smuzhiyun },
497*4882a593Smuzhiyun },
498*4882a593Smuzhiyun {
499*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DROP(INGRESS_STP_FILTER, L2_DROPS),
500*4882a593Smuzhiyun .listeners_arr = {
501*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(ING_SWITCH_STP, L2_DISCARDS),
502*4882a593Smuzhiyun },
503*4882a593Smuzhiyun },
504*4882a593Smuzhiyun {
505*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DROP(EMPTY_TX_LIST, L2_DROPS),
506*4882a593Smuzhiyun .listeners_arr = {
507*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(LOOKUP_SWITCH_UC, L2_DISCARDS),
508*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(LOOKUP_SWITCH_MC_NULL, L2_DISCARDS),
509*4882a593Smuzhiyun },
510*4882a593Smuzhiyun },
511*4882a593Smuzhiyun {
512*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DROP(PORT_LOOPBACK_FILTER, L2_DROPS),
513*4882a593Smuzhiyun .listeners_arr = {
514*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(LOOKUP_SWITCH_LB, L2_DISCARDS),
515*4882a593Smuzhiyun },
516*4882a593Smuzhiyun },
517*4882a593Smuzhiyun {
518*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DROP(BLACKHOLE_ROUTE, L3_DROPS),
519*4882a593Smuzhiyun .listeners_arr = {
520*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(ROUTER2, L3_DISCARDS),
521*4882a593Smuzhiyun },
522*4882a593Smuzhiyun },
523*4882a593Smuzhiyun {
524*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DROP(NON_IP_PACKET, L3_DROPS),
525*4882a593Smuzhiyun .listeners_arr = {
526*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(ING_ROUTER_NON_IP_PACKET,
527*4882a593Smuzhiyun L3_DISCARDS),
528*4882a593Smuzhiyun },
529*4882a593Smuzhiyun },
530*4882a593Smuzhiyun {
531*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DROP(UC_DIP_MC_DMAC, L3_DROPS),
532*4882a593Smuzhiyun .listeners_arr = {
533*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(ING_ROUTER_UC_DIP_MC_DMAC,
534*4882a593Smuzhiyun L3_DISCARDS),
535*4882a593Smuzhiyun },
536*4882a593Smuzhiyun },
537*4882a593Smuzhiyun {
538*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DROP(DIP_LB, L3_DROPS),
539*4882a593Smuzhiyun .listeners_arr = {
540*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(ING_ROUTER_DIP_LB, L3_DISCARDS),
541*4882a593Smuzhiyun },
542*4882a593Smuzhiyun },
543*4882a593Smuzhiyun {
544*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DROP(SIP_MC, L3_DROPS),
545*4882a593Smuzhiyun .listeners_arr = {
546*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(ING_ROUTER_SIP_MC, L3_DISCARDS),
547*4882a593Smuzhiyun },
548*4882a593Smuzhiyun },
549*4882a593Smuzhiyun {
550*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DROP(SIP_LB, L3_DROPS),
551*4882a593Smuzhiyun .listeners_arr = {
552*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(ING_ROUTER_SIP_LB, L3_DISCARDS),
553*4882a593Smuzhiyun },
554*4882a593Smuzhiyun },
555*4882a593Smuzhiyun {
556*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DROP(CORRUPTED_IP_HDR, L3_DROPS),
557*4882a593Smuzhiyun .listeners_arr = {
558*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(ING_ROUTER_CORRUPTED_IP_HDR,
559*4882a593Smuzhiyun L3_DISCARDS),
560*4882a593Smuzhiyun },
561*4882a593Smuzhiyun },
562*4882a593Smuzhiyun {
563*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DROP(IPV4_SIP_BC, L3_DROPS),
564*4882a593Smuzhiyun .listeners_arr = {
565*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(ING_ROUTER_IPV4_SIP_BC,
566*4882a593Smuzhiyun L3_DISCARDS),
567*4882a593Smuzhiyun },
568*4882a593Smuzhiyun },
569*4882a593Smuzhiyun {
570*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DROP(IPV6_MC_DIP_RESERVED_SCOPE,
571*4882a593Smuzhiyun L3_DROPS),
572*4882a593Smuzhiyun .listeners_arr = {
573*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(IPV6_MC_DIP_RESERVED_SCOPE,
574*4882a593Smuzhiyun L3_DISCARDS),
575*4882a593Smuzhiyun },
576*4882a593Smuzhiyun },
577*4882a593Smuzhiyun {
578*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DROP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE,
579*4882a593Smuzhiyun L3_DROPS),
580*4882a593Smuzhiyun .listeners_arr = {
581*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE,
582*4882a593Smuzhiyun L3_DISCARDS),
583*4882a593Smuzhiyun },
584*4882a593Smuzhiyun },
585*4882a593Smuzhiyun {
586*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_EXCEPTION(MTU_ERROR, L3_EXCEPTIONS),
587*4882a593Smuzhiyun .listeners_arr = {
588*4882a593Smuzhiyun MLXSW_SP_RXL_EXCEPTION(MTUERROR, L3_EXCEPTIONS,
589*4882a593Smuzhiyun TRAP_TO_CPU),
590*4882a593Smuzhiyun },
591*4882a593Smuzhiyun },
592*4882a593Smuzhiyun {
593*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_EXCEPTION(TTL_ERROR, L3_EXCEPTIONS),
594*4882a593Smuzhiyun .listeners_arr = {
595*4882a593Smuzhiyun MLXSW_SP_RXL_EXCEPTION(TTLERROR, L3_EXCEPTIONS,
596*4882a593Smuzhiyun TRAP_TO_CPU),
597*4882a593Smuzhiyun },
598*4882a593Smuzhiyun },
599*4882a593Smuzhiyun {
600*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_EXCEPTION(RPF, L3_EXCEPTIONS),
601*4882a593Smuzhiyun .listeners_arr = {
602*4882a593Smuzhiyun MLXSW_SP_RXL_EXCEPTION(RPF, L3_EXCEPTIONS, TRAP_TO_CPU),
603*4882a593Smuzhiyun },
604*4882a593Smuzhiyun },
605*4882a593Smuzhiyun {
606*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_EXCEPTION(REJECT_ROUTE, L3_EXCEPTIONS),
607*4882a593Smuzhiyun .listeners_arr = {
608*4882a593Smuzhiyun MLXSW_SP_RXL_EXCEPTION(RTR_INGRESS1, L3_EXCEPTIONS,
609*4882a593Smuzhiyun TRAP_TO_CPU),
610*4882a593Smuzhiyun },
611*4882a593Smuzhiyun },
612*4882a593Smuzhiyun {
613*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_EXCEPTION(UNRESOLVED_NEIGH,
614*4882a593Smuzhiyun L3_EXCEPTIONS),
615*4882a593Smuzhiyun .listeners_arr = {
616*4882a593Smuzhiyun MLXSW_SP_RXL_EXCEPTION(HOST_MISS_IPV4, L3_EXCEPTIONS,
617*4882a593Smuzhiyun TRAP_TO_CPU),
618*4882a593Smuzhiyun MLXSW_SP_RXL_EXCEPTION(HOST_MISS_IPV6, L3_EXCEPTIONS,
619*4882a593Smuzhiyun TRAP_TO_CPU),
620*4882a593Smuzhiyun MLXSW_SP_RXL_EXCEPTION(DISCARD_ROUTER3, L3_EXCEPTIONS,
621*4882a593Smuzhiyun TRAP_EXCEPTION_TO_CPU),
622*4882a593Smuzhiyun },
623*4882a593Smuzhiyun },
624*4882a593Smuzhiyun {
625*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_EXCEPTION(IPV4_LPM_UNICAST_MISS,
626*4882a593Smuzhiyun L3_EXCEPTIONS),
627*4882a593Smuzhiyun .listeners_arr = {
628*4882a593Smuzhiyun MLXSW_SP_RXL_EXCEPTION(DISCARD_ROUTER_LPM4,
629*4882a593Smuzhiyun L3_EXCEPTIONS,
630*4882a593Smuzhiyun TRAP_EXCEPTION_TO_CPU),
631*4882a593Smuzhiyun },
632*4882a593Smuzhiyun },
633*4882a593Smuzhiyun {
634*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_EXCEPTION(IPV6_LPM_UNICAST_MISS,
635*4882a593Smuzhiyun L3_EXCEPTIONS),
636*4882a593Smuzhiyun .listeners_arr = {
637*4882a593Smuzhiyun MLXSW_SP_RXL_EXCEPTION(DISCARD_ROUTER_LPM6,
638*4882a593Smuzhiyun L3_EXCEPTIONS,
639*4882a593Smuzhiyun TRAP_EXCEPTION_TO_CPU),
640*4882a593Smuzhiyun },
641*4882a593Smuzhiyun },
642*4882a593Smuzhiyun {
643*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DRIVER_DROP(IRIF_DISABLED, L3_DROPS),
644*4882a593Smuzhiyun .listeners_arr = {
645*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(ROUTER_IRIF_EN, L3_DISCARDS),
646*4882a593Smuzhiyun },
647*4882a593Smuzhiyun },
648*4882a593Smuzhiyun {
649*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DRIVER_DROP(ERIF_DISABLED, L3_DROPS),
650*4882a593Smuzhiyun .listeners_arr = {
651*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(ROUTER_ERIF_EN, L3_DISCARDS),
652*4882a593Smuzhiyun },
653*4882a593Smuzhiyun },
654*4882a593Smuzhiyun {
655*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DROP(NON_ROUTABLE, L3_DROPS),
656*4882a593Smuzhiyun .listeners_arr = {
657*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(NON_ROUTABLE, L3_DISCARDS),
658*4882a593Smuzhiyun },
659*4882a593Smuzhiyun },
660*4882a593Smuzhiyun {
661*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_EXCEPTION(DECAP_ERROR, TUNNEL_DROPS),
662*4882a593Smuzhiyun .listeners_arr = {
663*4882a593Smuzhiyun MLXSW_SP_RXL_EXCEPTION(DECAP_ECN0, TUNNEL_DISCARDS,
664*4882a593Smuzhiyun TRAP_EXCEPTION_TO_CPU),
665*4882a593Smuzhiyun MLXSW_SP_RXL_EXCEPTION(IPIP_DECAP_ERROR,
666*4882a593Smuzhiyun TUNNEL_DISCARDS,
667*4882a593Smuzhiyun TRAP_EXCEPTION_TO_CPU),
668*4882a593Smuzhiyun MLXSW_SP_RXL_EXCEPTION(DISCARD_DEC_PKT, TUNNEL_DISCARDS,
669*4882a593Smuzhiyun TRAP_EXCEPTION_TO_CPU),
670*4882a593Smuzhiyun },
671*4882a593Smuzhiyun },
672*4882a593Smuzhiyun {
673*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DROP(OVERLAY_SMAC_MC, TUNNEL_DROPS),
674*4882a593Smuzhiyun .listeners_arr = {
675*4882a593Smuzhiyun MLXSW_SP_RXL_DISCARD(OVERLAY_SMAC_MC, TUNNEL_DISCARDS),
676*4882a593Smuzhiyun },
677*4882a593Smuzhiyun },
678*4882a593Smuzhiyun {
679*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DROP_EXT(INGRESS_FLOW_ACTION_DROP,
680*4882a593Smuzhiyun ACL_DROPS,
681*4882a593Smuzhiyun DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE),
682*4882a593Smuzhiyun .listeners_arr = {
683*4882a593Smuzhiyun MLXSW_SP_RXL_ACL_DISCARD(INGRESS_ACL, ACL_DISCARDS,
684*4882a593Smuzhiyun DUMMY),
685*4882a593Smuzhiyun },
686*4882a593Smuzhiyun },
687*4882a593Smuzhiyun {
688*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_DROP_EXT(EGRESS_FLOW_ACTION_DROP,
689*4882a593Smuzhiyun ACL_DROPS,
690*4882a593Smuzhiyun DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE),
691*4882a593Smuzhiyun .listeners_arr = {
692*4882a593Smuzhiyun MLXSW_SP_RXL_ACL_DISCARD(EGRESS_ACL, ACL_DISCARDS,
693*4882a593Smuzhiyun DUMMY),
694*4882a593Smuzhiyun },
695*4882a593Smuzhiyun },
696*4882a593Smuzhiyun {
697*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(STP, STP, TRAP),
698*4882a593Smuzhiyun .listeners_arr = {
699*4882a593Smuzhiyun MLXSW_SP_RXL_NO_MARK(STP, STP, TRAP_TO_CPU, true),
700*4882a593Smuzhiyun },
701*4882a593Smuzhiyun },
702*4882a593Smuzhiyun {
703*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(LACP, LACP, TRAP),
704*4882a593Smuzhiyun .listeners_arr = {
705*4882a593Smuzhiyun MLXSW_SP_RXL_NO_MARK(LACP, LACP, TRAP_TO_CPU, true),
706*4882a593Smuzhiyun },
707*4882a593Smuzhiyun },
708*4882a593Smuzhiyun {
709*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(LLDP, LLDP, TRAP),
710*4882a593Smuzhiyun .listeners_arr = {
711*4882a593Smuzhiyun MLXSW_RXL(mlxsw_sp_rx_ptp_listener, LLDP, TRAP_TO_CPU,
712*4882a593Smuzhiyun true, SP_LLDP, DISCARD),
713*4882a593Smuzhiyun },
714*4882a593Smuzhiyun },
715*4882a593Smuzhiyun {
716*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IGMP_QUERY, MC_SNOOPING, MIRROR),
717*4882a593Smuzhiyun .listeners_arr = {
718*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(IGMP_QUERY, MC_SNOOPING,
719*4882a593Smuzhiyun MIRROR_TO_CPU, false),
720*4882a593Smuzhiyun },
721*4882a593Smuzhiyun },
722*4882a593Smuzhiyun {
723*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IGMP_V1_REPORT, MC_SNOOPING,
724*4882a593Smuzhiyun TRAP),
725*4882a593Smuzhiyun .listeners_arr = {
726*4882a593Smuzhiyun MLXSW_SP_RXL_NO_MARK(IGMP_V1_REPORT, MC_SNOOPING,
727*4882a593Smuzhiyun TRAP_TO_CPU, false),
728*4882a593Smuzhiyun },
729*4882a593Smuzhiyun },
730*4882a593Smuzhiyun {
731*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IGMP_V2_REPORT, MC_SNOOPING,
732*4882a593Smuzhiyun TRAP),
733*4882a593Smuzhiyun .listeners_arr = {
734*4882a593Smuzhiyun MLXSW_SP_RXL_NO_MARK(IGMP_V2_REPORT, MC_SNOOPING,
735*4882a593Smuzhiyun TRAP_TO_CPU, false),
736*4882a593Smuzhiyun },
737*4882a593Smuzhiyun },
738*4882a593Smuzhiyun {
739*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IGMP_V3_REPORT, MC_SNOOPING,
740*4882a593Smuzhiyun TRAP),
741*4882a593Smuzhiyun .listeners_arr = {
742*4882a593Smuzhiyun MLXSW_SP_RXL_NO_MARK(IGMP_V3_REPORT, MC_SNOOPING,
743*4882a593Smuzhiyun TRAP_TO_CPU, false),
744*4882a593Smuzhiyun },
745*4882a593Smuzhiyun },
746*4882a593Smuzhiyun {
747*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IGMP_V2_LEAVE, MC_SNOOPING,
748*4882a593Smuzhiyun TRAP),
749*4882a593Smuzhiyun .listeners_arr = {
750*4882a593Smuzhiyun MLXSW_SP_RXL_NO_MARK(IGMP_V2_LEAVE, MC_SNOOPING,
751*4882a593Smuzhiyun TRAP_TO_CPU, false),
752*4882a593Smuzhiyun },
753*4882a593Smuzhiyun },
754*4882a593Smuzhiyun {
755*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(MLD_QUERY, MC_SNOOPING, MIRROR),
756*4882a593Smuzhiyun .listeners_arr = {
757*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(IPV6_MLDV12_LISTENER_QUERY,
758*4882a593Smuzhiyun MC_SNOOPING, MIRROR_TO_CPU, false),
759*4882a593Smuzhiyun },
760*4882a593Smuzhiyun },
761*4882a593Smuzhiyun {
762*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(MLD_V1_REPORT, MC_SNOOPING,
763*4882a593Smuzhiyun TRAP),
764*4882a593Smuzhiyun .listeners_arr = {
765*4882a593Smuzhiyun MLXSW_SP_RXL_NO_MARK(IPV6_MLDV1_LISTENER_REPORT,
766*4882a593Smuzhiyun MC_SNOOPING, TRAP_TO_CPU, false),
767*4882a593Smuzhiyun },
768*4882a593Smuzhiyun },
769*4882a593Smuzhiyun {
770*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(MLD_V2_REPORT, MC_SNOOPING,
771*4882a593Smuzhiyun TRAP),
772*4882a593Smuzhiyun .listeners_arr = {
773*4882a593Smuzhiyun MLXSW_SP_RXL_NO_MARK(IPV6_MLDV2_LISTENER_REPORT,
774*4882a593Smuzhiyun MC_SNOOPING, TRAP_TO_CPU, false),
775*4882a593Smuzhiyun },
776*4882a593Smuzhiyun },
777*4882a593Smuzhiyun {
778*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(MLD_V1_DONE, MC_SNOOPING,
779*4882a593Smuzhiyun TRAP),
780*4882a593Smuzhiyun .listeners_arr = {
781*4882a593Smuzhiyun MLXSW_SP_RXL_NO_MARK(IPV6_MLDV1_LISTENER_DONE,
782*4882a593Smuzhiyun MC_SNOOPING, TRAP_TO_CPU, false),
783*4882a593Smuzhiyun },
784*4882a593Smuzhiyun },
785*4882a593Smuzhiyun {
786*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV4_DHCP, DHCP, TRAP),
787*4882a593Smuzhiyun .listeners_arr = {
788*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(IPV4_DHCP, DHCP, TRAP_TO_CPU, false),
789*4882a593Smuzhiyun },
790*4882a593Smuzhiyun },
791*4882a593Smuzhiyun {
792*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV6_DHCP, DHCP, TRAP),
793*4882a593Smuzhiyun .listeners_arr = {
794*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(IPV6_DHCP, DHCP, TRAP_TO_CPU, false),
795*4882a593Smuzhiyun },
796*4882a593Smuzhiyun },
797*4882a593Smuzhiyun {
798*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(ARP_REQUEST, NEIGH_DISCOVERY,
799*4882a593Smuzhiyun MIRROR),
800*4882a593Smuzhiyun .listeners_arr = {
801*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(ARPBC, NEIGH_DISCOVERY, MIRROR_TO_CPU,
802*4882a593Smuzhiyun false),
803*4882a593Smuzhiyun },
804*4882a593Smuzhiyun },
805*4882a593Smuzhiyun {
806*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(ARP_RESPONSE, NEIGH_DISCOVERY,
807*4882a593Smuzhiyun MIRROR),
808*4882a593Smuzhiyun .listeners_arr = {
809*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(ARPUC, NEIGH_DISCOVERY, MIRROR_TO_CPU,
810*4882a593Smuzhiyun false),
811*4882a593Smuzhiyun },
812*4882a593Smuzhiyun },
813*4882a593Smuzhiyun {
814*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(ARP_OVERLAY, NEIGH_DISCOVERY,
815*4882a593Smuzhiyun TRAP),
816*4882a593Smuzhiyun .listeners_arr = {
817*4882a593Smuzhiyun MLXSW_SP_RXL_NO_MARK(NVE_DECAP_ARP, NEIGH_DISCOVERY,
818*4882a593Smuzhiyun TRAP_TO_CPU, false),
819*4882a593Smuzhiyun },
820*4882a593Smuzhiyun },
821*4882a593Smuzhiyun {
822*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV6_NEIGH_SOLICIT,
823*4882a593Smuzhiyun NEIGH_DISCOVERY, TRAP),
824*4882a593Smuzhiyun .listeners_arr = {
825*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(L3_IPV6_NEIGHBOR_SOLICITATION,
826*4882a593Smuzhiyun NEIGH_DISCOVERY, TRAP_TO_CPU, false),
827*4882a593Smuzhiyun },
828*4882a593Smuzhiyun },
829*4882a593Smuzhiyun {
830*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV6_NEIGH_ADVERT,
831*4882a593Smuzhiyun NEIGH_DISCOVERY, TRAP),
832*4882a593Smuzhiyun .listeners_arr = {
833*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(L3_IPV6_NEIGHBOR_ADVERTISEMENT,
834*4882a593Smuzhiyun NEIGH_DISCOVERY, TRAP_TO_CPU, false),
835*4882a593Smuzhiyun },
836*4882a593Smuzhiyun },
837*4882a593Smuzhiyun {
838*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV4_BFD, BFD, TRAP),
839*4882a593Smuzhiyun .listeners_arr = {
840*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(IPV4_BFD, BFD, TRAP_TO_CPU, false),
841*4882a593Smuzhiyun },
842*4882a593Smuzhiyun },
843*4882a593Smuzhiyun {
844*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV6_BFD, BFD, TRAP),
845*4882a593Smuzhiyun .listeners_arr = {
846*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(IPV6_BFD, BFD, TRAP_TO_CPU, false),
847*4882a593Smuzhiyun },
848*4882a593Smuzhiyun },
849*4882a593Smuzhiyun {
850*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV4_OSPF, OSPF, TRAP),
851*4882a593Smuzhiyun .listeners_arr = {
852*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(IPV4_OSPF, OSPF, TRAP_TO_CPU, false),
853*4882a593Smuzhiyun },
854*4882a593Smuzhiyun },
855*4882a593Smuzhiyun {
856*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV6_OSPF, OSPF, TRAP),
857*4882a593Smuzhiyun .listeners_arr = {
858*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(IPV6_OSPF, OSPF, TRAP_TO_CPU, false),
859*4882a593Smuzhiyun },
860*4882a593Smuzhiyun },
861*4882a593Smuzhiyun {
862*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV4_BGP, BGP, TRAP),
863*4882a593Smuzhiyun .listeners_arr = {
864*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(IPV4_BGP, BGP, TRAP_TO_CPU, false),
865*4882a593Smuzhiyun },
866*4882a593Smuzhiyun },
867*4882a593Smuzhiyun {
868*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV6_BGP, BGP, TRAP),
869*4882a593Smuzhiyun .listeners_arr = {
870*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(IPV6_BGP, BGP, TRAP_TO_CPU, false),
871*4882a593Smuzhiyun },
872*4882a593Smuzhiyun },
873*4882a593Smuzhiyun {
874*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV4_VRRP, VRRP, TRAP),
875*4882a593Smuzhiyun .listeners_arr = {
876*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(IPV4_VRRP, VRRP, TRAP_TO_CPU, false),
877*4882a593Smuzhiyun },
878*4882a593Smuzhiyun },
879*4882a593Smuzhiyun {
880*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV6_VRRP, VRRP, TRAP),
881*4882a593Smuzhiyun .listeners_arr = {
882*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(IPV6_VRRP, VRRP, TRAP_TO_CPU, false),
883*4882a593Smuzhiyun },
884*4882a593Smuzhiyun },
885*4882a593Smuzhiyun {
886*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV4_PIM, PIM, TRAP),
887*4882a593Smuzhiyun .listeners_arr = {
888*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(IPV4_PIM, PIM, TRAP_TO_CPU, false),
889*4882a593Smuzhiyun },
890*4882a593Smuzhiyun },
891*4882a593Smuzhiyun {
892*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV6_PIM, PIM, TRAP),
893*4882a593Smuzhiyun .listeners_arr = {
894*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(IPV6_PIM, PIM, TRAP_TO_CPU, false),
895*4882a593Smuzhiyun },
896*4882a593Smuzhiyun },
897*4882a593Smuzhiyun {
898*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(UC_LB, UC_LB, MIRROR),
899*4882a593Smuzhiyun .listeners_arr = {
900*4882a593Smuzhiyun MLXSW_SP_RXL_L3_MARK(LBERROR, LBERROR, MIRROR_TO_CPU,
901*4882a593Smuzhiyun false),
902*4882a593Smuzhiyun },
903*4882a593Smuzhiyun },
904*4882a593Smuzhiyun {
905*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(LOCAL_ROUTE, LOCAL_DELIVERY,
906*4882a593Smuzhiyun TRAP),
907*4882a593Smuzhiyun .listeners_arr = {
908*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(IP2ME, IP2ME, TRAP_TO_CPU, false),
909*4882a593Smuzhiyun },
910*4882a593Smuzhiyun },
911*4882a593Smuzhiyun {
912*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(EXTERNAL_ROUTE, EXTERNAL_DELIVERY,
913*4882a593Smuzhiyun TRAP),
914*4882a593Smuzhiyun .listeners_arr = {
915*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(RTR_INGRESS0, EXTERNAL_ROUTE,
916*4882a593Smuzhiyun TRAP_TO_CPU, false),
917*4882a593Smuzhiyun },
918*4882a593Smuzhiyun },
919*4882a593Smuzhiyun {
920*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV6_UC_DIP_LINK_LOCAL_SCOPE,
921*4882a593Smuzhiyun LOCAL_DELIVERY, TRAP),
922*4882a593Smuzhiyun .listeners_arr = {
923*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(IPV6_LINK_LOCAL_DEST, IP2ME,
924*4882a593Smuzhiyun TRAP_TO_CPU, false),
925*4882a593Smuzhiyun },
926*4882a593Smuzhiyun },
927*4882a593Smuzhiyun {
928*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV4_ROUTER_ALERT, LOCAL_DELIVERY,
929*4882a593Smuzhiyun TRAP),
930*4882a593Smuzhiyun .listeners_arr = {
931*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV4, IP2ME, TRAP_TO_CPU,
932*4882a593Smuzhiyun false),
933*4882a593Smuzhiyun },
934*4882a593Smuzhiyun },
935*4882a593Smuzhiyun {
936*4882a593Smuzhiyun /* IPV6_ROUTER_ALERT is defined in uAPI as 22, but it is not
937*4882a593Smuzhiyun * used in this file, so undefine it.
938*4882a593Smuzhiyun */
939*4882a593Smuzhiyun #undef IPV6_ROUTER_ALERT
940*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV6_ROUTER_ALERT, LOCAL_DELIVERY,
941*4882a593Smuzhiyun TRAP),
942*4882a593Smuzhiyun .listeners_arr = {
943*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV6, IP2ME, TRAP_TO_CPU,
944*4882a593Smuzhiyun false),
945*4882a593Smuzhiyun },
946*4882a593Smuzhiyun },
947*4882a593Smuzhiyun {
948*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV6_DIP_ALL_NODES, IPV6, TRAP),
949*4882a593Smuzhiyun .listeners_arr = {
950*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(IPV6_ALL_NODES_LINK, IPV6,
951*4882a593Smuzhiyun TRAP_TO_CPU, false),
952*4882a593Smuzhiyun },
953*4882a593Smuzhiyun },
954*4882a593Smuzhiyun {
955*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV6_DIP_ALL_ROUTERS, IPV6, TRAP),
956*4882a593Smuzhiyun .listeners_arr = {
957*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(IPV6_ALL_ROUTERS_LINK, IPV6,
958*4882a593Smuzhiyun TRAP_TO_CPU, false),
959*4882a593Smuzhiyun },
960*4882a593Smuzhiyun },
961*4882a593Smuzhiyun {
962*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV6_ROUTER_SOLICIT, IPV6, TRAP),
963*4882a593Smuzhiyun .listeners_arr = {
964*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(L3_IPV6_ROUTER_SOLICITATION, IPV6,
965*4882a593Smuzhiyun TRAP_TO_CPU, false),
966*4882a593Smuzhiyun },
967*4882a593Smuzhiyun },
968*4882a593Smuzhiyun {
969*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV6_ROUTER_ADVERT, IPV6, TRAP),
970*4882a593Smuzhiyun .listeners_arr = {
971*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(L3_IPV6_ROUTER_ADVERTISEMENT, IPV6,
972*4882a593Smuzhiyun TRAP_TO_CPU, false),
973*4882a593Smuzhiyun },
974*4882a593Smuzhiyun },
975*4882a593Smuzhiyun {
976*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(IPV6_REDIRECT, IPV6, TRAP),
977*4882a593Smuzhiyun .listeners_arr = {
978*4882a593Smuzhiyun MLXSW_SP_RXL_MARK(L3_IPV6_REDIRECTION, IPV6,
979*4882a593Smuzhiyun TRAP_TO_CPU, false),
980*4882a593Smuzhiyun },
981*4882a593Smuzhiyun },
982*4882a593Smuzhiyun {
983*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(PTP_EVENT, PTP_EVENT, TRAP),
984*4882a593Smuzhiyun .listeners_arr = {
985*4882a593Smuzhiyun MLXSW_RXL(mlxsw_sp_rx_ptp_listener, PTP0, TRAP_TO_CPU,
986*4882a593Smuzhiyun false, SP_PTP0, DISCARD),
987*4882a593Smuzhiyun },
988*4882a593Smuzhiyun },
989*4882a593Smuzhiyun {
990*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(PTP_GENERAL, PTP_GENERAL, TRAP),
991*4882a593Smuzhiyun .listeners_arr = {
992*4882a593Smuzhiyun MLXSW_SP_RXL_NO_MARK(PTP1, PTP1, TRAP_TO_CPU, false),
993*4882a593Smuzhiyun },
994*4882a593Smuzhiyun },
995*4882a593Smuzhiyun {
996*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(FLOW_ACTION_SAMPLE, ACL_SAMPLE,
997*4882a593Smuzhiyun MIRROR),
998*4882a593Smuzhiyun .listeners_arr = {
999*4882a593Smuzhiyun MLXSW_RXL(mlxsw_sp_rx_sample_listener, PKT_SAMPLE,
1000*4882a593Smuzhiyun MIRROR_TO_CPU, false, SP_PKT_SAMPLE, DISCARD),
1001*4882a593Smuzhiyun },
1002*4882a593Smuzhiyun },
1003*4882a593Smuzhiyun {
1004*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_CONTROL(FLOW_ACTION_TRAP, ACL_TRAP, TRAP),
1005*4882a593Smuzhiyun .listeners_arr = {
1006*4882a593Smuzhiyun MLXSW_SP_RXL_NO_MARK(ACL0, FLOW_LOGGING, TRAP_TO_CPU,
1007*4882a593Smuzhiyun false),
1008*4882a593Smuzhiyun },
1009*4882a593Smuzhiyun },
1010*4882a593Smuzhiyun };
1011*4882a593Smuzhiyun
1012*4882a593Smuzhiyun static struct mlxsw_sp_trap_policer_item *
mlxsw_sp_trap_policer_item_lookup(struct mlxsw_sp * mlxsw_sp,u32 id)1013*4882a593Smuzhiyun mlxsw_sp_trap_policer_item_lookup(struct mlxsw_sp *mlxsw_sp, u32 id)
1014*4882a593Smuzhiyun {
1015*4882a593Smuzhiyun struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1016*4882a593Smuzhiyun int i;
1017*4882a593Smuzhiyun
1018*4882a593Smuzhiyun for (i = 0; i < trap->policers_count; i++) {
1019*4882a593Smuzhiyun if (trap->policer_items_arr[i].policer.id == id)
1020*4882a593Smuzhiyun return &trap->policer_items_arr[i];
1021*4882a593Smuzhiyun }
1022*4882a593Smuzhiyun
1023*4882a593Smuzhiyun return NULL;
1024*4882a593Smuzhiyun }
1025*4882a593Smuzhiyun
1026*4882a593Smuzhiyun static struct mlxsw_sp_trap_group_item *
mlxsw_sp_trap_group_item_lookup(struct mlxsw_sp * mlxsw_sp,u16 id)1027*4882a593Smuzhiyun mlxsw_sp_trap_group_item_lookup(struct mlxsw_sp *mlxsw_sp, u16 id)
1028*4882a593Smuzhiyun {
1029*4882a593Smuzhiyun struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1030*4882a593Smuzhiyun int i;
1031*4882a593Smuzhiyun
1032*4882a593Smuzhiyun for (i = 0; i < trap->groups_count; i++) {
1033*4882a593Smuzhiyun if (trap->group_items_arr[i].group.id == id)
1034*4882a593Smuzhiyun return &trap->group_items_arr[i];
1035*4882a593Smuzhiyun }
1036*4882a593Smuzhiyun
1037*4882a593Smuzhiyun return NULL;
1038*4882a593Smuzhiyun }
1039*4882a593Smuzhiyun
1040*4882a593Smuzhiyun static struct mlxsw_sp_trap_item *
mlxsw_sp_trap_item_lookup(struct mlxsw_sp * mlxsw_sp,u16 id)1041*4882a593Smuzhiyun mlxsw_sp_trap_item_lookup(struct mlxsw_sp *mlxsw_sp, u16 id)
1042*4882a593Smuzhiyun {
1043*4882a593Smuzhiyun struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1044*4882a593Smuzhiyun int i;
1045*4882a593Smuzhiyun
1046*4882a593Smuzhiyun for (i = 0; i < trap->traps_count; i++) {
1047*4882a593Smuzhiyun if (trap->trap_items_arr[i].trap.id == id)
1048*4882a593Smuzhiyun return &trap->trap_items_arr[i];
1049*4882a593Smuzhiyun }
1050*4882a593Smuzhiyun
1051*4882a593Smuzhiyun return NULL;
1052*4882a593Smuzhiyun }
1053*4882a593Smuzhiyun
mlxsw_sp_trap_cpu_policers_set(struct mlxsw_sp * mlxsw_sp)1054*4882a593Smuzhiyun static int mlxsw_sp_trap_cpu_policers_set(struct mlxsw_sp *mlxsw_sp)
1055*4882a593Smuzhiyun {
1056*4882a593Smuzhiyun struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1057*4882a593Smuzhiyun char qpcr_pl[MLXSW_REG_QPCR_LEN];
1058*4882a593Smuzhiyun u16 hw_id;
1059*4882a593Smuzhiyun
1060*4882a593Smuzhiyun /* The purpose of "thin" policer is to drop as many packets
1061*4882a593Smuzhiyun * as possible. The dummy group is using it.
1062*4882a593Smuzhiyun */
1063*4882a593Smuzhiyun hw_id = find_first_zero_bit(trap->policers_usage, trap->max_policers);
1064*4882a593Smuzhiyun if (WARN_ON(hw_id == trap->max_policers))
1065*4882a593Smuzhiyun return -ENOBUFS;
1066*4882a593Smuzhiyun
1067*4882a593Smuzhiyun __set_bit(hw_id, trap->policers_usage);
1068*4882a593Smuzhiyun trap->thin_policer_hw_id = hw_id;
1069*4882a593Smuzhiyun mlxsw_reg_qpcr_pack(qpcr_pl, hw_id, MLXSW_REG_QPCR_IR_UNITS_M,
1070*4882a593Smuzhiyun false, 1, 4);
1071*4882a593Smuzhiyun return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qpcr), qpcr_pl);
1072*4882a593Smuzhiyun }
1073*4882a593Smuzhiyun
mlxsw_sp_trap_dummy_group_init(struct mlxsw_sp * mlxsw_sp)1074*4882a593Smuzhiyun static int mlxsw_sp_trap_dummy_group_init(struct mlxsw_sp *mlxsw_sp)
1075*4882a593Smuzhiyun {
1076*4882a593Smuzhiyun char htgt_pl[MLXSW_REG_HTGT_LEN];
1077*4882a593Smuzhiyun
1078*4882a593Smuzhiyun mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_SP_DUMMY,
1079*4882a593Smuzhiyun mlxsw_sp->trap->thin_policer_hw_id, 0, 1);
1080*4882a593Smuzhiyun return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(htgt), htgt_pl);
1081*4882a593Smuzhiyun }
1082*4882a593Smuzhiyun
mlxsw_sp_trap_policer_items_arr_init(struct mlxsw_sp * mlxsw_sp)1083*4882a593Smuzhiyun static int mlxsw_sp_trap_policer_items_arr_init(struct mlxsw_sp *mlxsw_sp)
1084*4882a593Smuzhiyun {
1085*4882a593Smuzhiyun size_t arr_size = ARRAY_SIZE(mlxsw_sp_trap_policer_items_arr);
1086*4882a593Smuzhiyun size_t elem_size = sizeof(struct mlxsw_sp_trap_policer_item);
1087*4882a593Smuzhiyun struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1088*4882a593Smuzhiyun size_t free_policers = 0;
1089*4882a593Smuzhiyun u32 last_id;
1090*4882a593Smuzhiyun int i;
1091*4882a593Smuzhiyun
1092*4882a593Smuzhiyun for_each_clear_bit(i, trap->policers_usage, trap->max_policers)
1093*4882a593Smuzhiyun free_policers++;
1094*4882a593Smuzhiyun
1095*4882a593Smuzhiyun if (arr_size > free_policers) {
1096*4882a593Smuzhiyun dev_err(mlxsw_sp->bus_info->dev, "Exceeded number of supported packet trap policers\n");
1097*4882a593Smuzhiyun return -ENOBUFS;
1098*4882a593Smuzhiyun }
1099*4882a593Smuzhiyun
1100*4882a593Smuzhiyun trap->policer_items_arr = kcalloc(free_policers, elem_size, GFP_KERNEL);
1101*4882a593Smuzhiyun if (!trap->policer_items_arr)
1102*4882a593Smuzhiyun return -ENOMEM;
1103*4882a593Smuzhiyun
1104*4882a593Smuzhiyun trap->policers_count = free_policers;
1105*4882a593Smuzhiyun
1106*4882a593Smuzhiyun /* Initialize policer items array with pre-defined policers. */
1107*4882a593Smuzhiyun memcpy(trap->policer_items_arr, mlxsw_sp_trap_policer_items_arr,
1108*4882a593Smuzhiyun elem_size * arr_size);
1109*4882a593Smuzhiyun
1110*4882a593Smuzhiyun /* Initialize policer items array with the rest of the available
1111*4882a593Smuzhiyun * policers.
1112*4882a593Smuzhiyun */
1113*4882a593Smuzhiyun last_id = mlxsw_sp_trap_policer_items_arr[arr_size - 1].policer.id;
1114*4882a593Smuzhiyun for (i = arr_size; i < trap->policers_count; i++) {
1115*4882a593Smuzhiyun const struct mlxsw_sp_trap_policer_item *policer_item;
1116*4882a593Smuzhiyun
1117*4882a593Smuzhiyun /* Use parameters set for first policer and override
1118*4882a593Smuzhiyun * relevant ones.
1119*4882a593Smuzhiyun */
1120*4882a593Smuzhiyun policer_item = &mlxsw_sp_trap_policer_items_arr[0];
1121*4882a593Smuzhiyun trap->policer_items_arr[i] = *policer_item;
1122*4882a593Smuzhiyun trap->policer_items_arr[i].policer.id = ++last_id;
1123*4882a593Smuzhiyun trap->policer_items_arr[i].policer.init_rate = 1;
1124*4882a593Smuzhiyun trap->policer_items_arr[i].policer.init_burst = 16;
1125*4882a593Smuzhiyun }
1126*4882a593Smuzhiyun
1127*4882a593Smuzhiyun return 0;
1128*4882a593Smuzhiyun }
1129*4882a593Smuzhiyun
mlxsw_sp_trap_policer_items_arr_fini(struct mlxsw_sp * mlxsw_sp)1130*4882a593Smuzhiyun static void mlxsw_sp_trap_policer_items_arr_fini(struct mlxsw_sp *mlxsw_sp)
1131*4882a593Smuzhiyun {
1132*4882a593Smuzhiyun kfree(mlxsw_sp->trap->policer_items_arr);
1133*4882a593Smuzhiyun }
1134*4882a593Smuzhiyun
mlxsw_sp_trap_policers_init(struct mlxsw_sp * mlxsw_sp)1135*4882a593Smuzhiyun static int mlxsw_sp_trap_policers_init(struct mlxsw_sp *mlxsw_sp)
1136*4882a593Smuzhiyun {
1137*4882a593Smuzhiyun struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
1138*4882a593Smuzhiyun const struct mlxsw_sp_trap_policer_item *policer_item;
1139*4882a593Smuzhiyun struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1140*4882a593Smuzhiyun int err, i;
1141*4882a593Smuzhiyun
1142*4882a593Smuzhiyun err = mlxsw_sp_trap_policer_items_arr_init(mlxsw_sp);
1143*4882a593Smuzhiyun if (err)
1144*4882a593Smuzhiyun return err;
1145*4882a593Smuzhiyun
1146*4882a593Smuzhiyun for (i = 0; i < trap->policers_count; i++) {
1147*4882a593Smuzhiyun policer_item = &trap->policer_items_arr[i];
1148*4882a593Smuzhiyun err = devlink_trap_policers_register(devlink,
1149*4882a593Smuzhiyun &policer_item->policer, 1);
1150*4882a593Smuzhiyun if (err)
1151*4882a593Smuzhiyun goto err_trap_policer_register;
1152*4882a593Smuzhiyun }
1153*4882a593Smuzhiyun
1154*4882a593Smuzhiyun return 0;
1155*4882a593Smuzhiyun
1156*4882a593Smuzhiyun err_trap_policer_register:
1157*4882a593Smuzhiyun for (i--; i >= 0; i--) {
1158*4882a593Smuzhiyun policer_item = &trap->policer_items_arr[i];
1159*4882a593Smuzhiyun devlink_trap_policers_unregister(devlink,
1160*4882a593Smuzhiyun &policer_item->policer, 1);
1161*4882a593Smuzhiyun }
1162*4882a593Smuzhiyun mlxsw_sp_trap_policer_items_arr_fini(mlxsw_sp);
1163*4882a593Smuzhiyun return err;
1164*4882a593Smuzhiyun }
1165*4882a593Smuzhiyun
mlxsw_sp_trap_policers_fini(struct mlxsw_sp * mlxsw_sp)1166*4882a593Smuzhiyun static void mlxsw_sp_trap_policers_fini(struct mlxsw_sp *mlxsw_sp)
1167*4882a593Smuzhiyun {
1168*4882a593Smuzhiyun struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
1169*4882a593Smuzhiyun const struct mlxsw_sp_trap_policer_item *policer_item;
1170*4882a593Smuzhiyun struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1171*4882a593Smuzhiyun int i;
1172*4882a593Smuzhiyun
1173*4882a593Smuzhiyun for (i = trap->policers_count - 1; i >= 0; i--) {
1174*4882a593Smuzhiyun policer_item = &trap->policer_items_arr[i];
1175*4882a593Smuzhiyun devlink_trap_policers_unregister(devlink,
1176*4882a593Smuzhiyun &policer_item->policer, 1);
1177*4882a593Smuzhiyun }
1178*4882a593Smuzhiyun mlxsw_sp_trap_policer_items_arr_fini(mlxsw_sp);
1179*4882a593Smuzhiyun }
1180*4882a593Smuzhiyun
mlxsw_sp_trap_group_items_arr_init(struct mlxsw_sp * mlxsw_sp)1181*4882a593Smuzhiyun static int mlxsw_sp_trap_group_items_arr_init(struct mlxsw_sp *mlxsw_sp)
1182*4882a593Smuzhiyun {
1183*4882a593Smuzhiyun size_t common_groups_count = ARRAY_SIZE(mlxsw_sp_trap_group_items_arr);
1184*4882a593Smuzhiyun const struct mlxsw_sp_trap_group_item *spec_group_items_arr;
1185*4882a593Smuzhiyun size_t elem_size = sizeof(struct mlxsw_sp_trap_group_item);
1186*4882a593Smuzhiyun struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1187*4882a593Smuzhiyun size_t groups_count, spec_groups_count;
1188*4882a593Smuzhiyun int err;
1189*4882a593Smuzhiyun
1190*4882a593Smuzhiyun err = mlxsw_sp->trap_ops->groups_init(mlxsw_sp, &spec_group_items_arr,
1191*4882a593Smuzhiyun &spec_groups_count);
1192*4882a593Smuzhiyun if (err)
1193*4882a593Smuzhiyun return err;
1194*4882a593Smuzhiyun
1195*4882a593Smuzhiyun /* The group items array is created by concatenating the common trap
1196*4882a593Smuzhiyun * group items and the ASIC-specific trap group items.
1197*4882a593Smuzhiyun */
1198*4882a593Smuzhiyun groups_count = common_groups_count + spec_groups_count;
1199*4882a593Smuzhiyun trap->group_items_arr = kcalloc(groups_count, elem_size, GFP_KERNEL);
1200*4882a593Smuzhiyun if (!trap->group_items_arr)
1201*4882a593Smuzhiyun return -ENOMEM;
1202*4882a593Smuzhiyun
1203*4882a593Smuzhiyun memcpy(trap->group_items_arr, mlxsw_sp_trap_group_items_arr,
1204*4882a593Smuzhiyun elem_size * common_groups_count);
1205*4882a593Smuzhiyun memcpy(trap->group_items_arr + common_groups_count,
1206*4882a593Smuzhiyun spec_group_items_arr, elem_size * spec_groups_count);
1207*4882a593Smuzhiyun
1208*4882a593Smuzhiyun trap->groups_count = groups_count;
1209*4882a593Smuzhiyun
1210*4882a593Smuzhiyun return 0;
1211*4882a593Smuzhiyun }
1212*4882a593Smuzhiyun
mlxsw_sp_trap_group_items_arr_fini(struct mlxsw_sp * mlxsw_sp)1213*4882a593Smuzhiyun static void mlxsw_sp_trap_group_items_arr_fini(struct mlxsw_sp *mlxsw_sp)
1214*4882a593Smuzhiyun {
1215*4882a593Smuzhiyun kfree(mlxsw_sp->trap->group_items_arr);
1216*4882a593Smuzhiyun }
1217*4882a593Smuzhiyun
mlxsw_sp_trap_groups_init(struct mlxsw_sp * mlxsw_sp)1218*4882a593Smuzhiyun static int mlxsw_sp_trap_groups_init(struct mlxsw_sp *mlxsw_sp)
1219*4882a593Smuzhiyun {
1220*4882a593Smuzhiyun struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
1221*4882a593Smuzhiyun const struct mlxsw_sp_trap_group_item *group_item;
1222*4882a593Smuzhiyun struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1223*4882a593Smuzhiyun int err, i;
1224*4882a593Smuzhiyun
1225*4882a593Smuzhiyun err = mlxsw_sp_trap_group_items_arr_init(mlxsw_sp);
1226*4882a593Smuzhiyun if (err)
1227*4882a593Smuzhiyun return err;
1228*4882a593Smuzhiyun
1229*4882a593Smuzhiyun for (i = 0; i < trap->groups_count; i++) {
1230*4882a593Smuzhiyun group_item = &trap->group_items_arr[i];
1231*4882a593Smuzhiyun err = devlink_trap_groups_register(devlink, &group_item->group,
1232*4882a593Smuzhiyun 1);
1233*4882a593Smuzhiyun if (err)
1234*4882a593Smuzhiyun goto err_trap_group_register;
1235*4882a593Smuzhiyun }
1236*4882a593Smuzhiyun
1237*4882a593Smuzhiyun return 0;
1238*4882a593Smuzhiyun
1239*4882a593Smuzhiyun err_trap_group_register:
1240*4882a593Smuzhiyun for (i--; i >= 0; i--) {
1241*4882a593Smuzhiyun group_item = &trap->group_items_arr[i];
1242*4882a593Smuzhiyun devlink_trap_groups_unregister(devlink, &group_item->group, 1);
1243*4882a593Smuzhiyun }
1244*4882a593Smuzhiyun mlxsw_sp_trap_group_items_arr_fini(mlxsw_sp);
1245*4882a593Smuzhiyun return err;
1246*4882a593Smuzhiyun }
1247*4882a593Smuzhiyun
mlxsw_sp_trap_groups_fini(struct mlxsw_sp * mlxsw_sp)1248*4882a593Smuzhiyun static void mlxsw_sp_trap_groups_fini(struct mlxsw_sp *mlxsw_sp)
1249*4882a593Smuzhiyun {
1250*4882a593Smuzhiyun struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
1251*4882a593Smuzhiyun struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1252*4882a593Smuzhiyun int i;
1253*4882a593Smuzhiyun
1254*4882a593Smuzhiyun for (i = trap->groups_count - 1; i >= 0; i--) {
1255*4882a593Smuzhiyun const struct mlxsw_sp_trap_group_item *group_item;
1256*4882a593Smuzhiyun
1257*4882a593Smuzhiyun group_item = &trap->group_items_arr[i];
1258*4882a593Smuzhiyun devlink_trap_groups_unregister(devlink, &group_item->group, 1);
1259*4882a593Smuzhiyun }
1260*4882a593Smuzhiyun mlxsw_sp_trap_group_items_arr_fini(mlxsw_sp);
1261*4882a593Smuzhiyun }
1262*4882a593Smuzhiyun
1263*4882a593Smuzhiyun static bool
mlxsw_sp_trap_listener_is_valid(const struct mlxsw_listener * listener)1264*4882a593Smuzhiyun mlxsw_sp_trap_listener_is_valid(const struct mlxsw_listener *listener)
1265*4882a593Smuzhiyun {
1266*4882a593Smuzhiyun return listener->trap_id != 0;
1267*4882a593Smuzhiyun }
1268*4882a593Smuzhiyun
mlxsw_sp_trap_items_arr_init(struct mlxsw_sp * mlxsw_sp)1269*4882a593Smuzhiyun static int mlxsw_sp_trap_items_arr_init(struct mlxsw_sp *mlxsw_sp)
1270*4882a593Smuzhiyun {
1271*4882a593Smuzhiyun size_t common_traps_count = ARRAY_SIZE(mlxsw_sp_trap_items_arr);
1272*4882a593Smuzhiyun const struct mlxsw_sp_trap_item *spec_trap_items_arr;
1273*4882a593Smuzhiyun size_t elem_size = sizeof(struct mlxsw_sp_trap_item);
1274*4882a593Smuzhiyun struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1275*4882a593Smuzhiyun size_t traps_count, spec_traps_count;
1276*4882a593Smuzhiyun int err;
1277*4882a593Smuzhiyun
1278*4882a593Smuzhiyun err = mlxsw_sp->trap_ops->traps_init(mlxsw_sp, &spec_trap_items_arr,
1279*4882a593Smuzhiyun &spec_traps_count);
1280*4882a593Smuzhiyun if (err)
1281*4882a593Smuzhiyun return err;
1282*4882a593Smuzhiyun
1283*4882a593Smuzhiyun /* The trap items array is created by concatenating the common trap
1284*4882a593Smuzhiyun * items and the ASIC-specific trap items.
1285*4882a593Smuzhiyun */
1286*4882a593Smuzhiyun traps_count = common_traps_count + spec_traps_count;
1287*4882a593Smuzhiyun trap->trap_items_arr = kcalloc(traps_count, elem_size, GFP_KERNEL);
1288*4882a593Smuzhiyun if (!trap->trap_items_arr)
1289*4882a593Smuzhiyun return -ENOMEM;
1290*4882a593Smuzhiyun
1291*4882a593Smuzhiyun memcpy(trap->trap_items_arr, mlxsw_sp_trap_items_arr,
1292*4882a593Smuzhiyun elem_size * common_traps_count);
1293*4882a593Smuzhiyun memcpy(trap->trap_items_arr + common_traps_count,
1294*4882a593Smuzhiyun spec_trap_items_arr, elem_size * spec_traps_count);
1295*4882a593Smuzhiyun
1296*4882a593Smuzhiyun trap->traps_count = traps_count;
1297*4882a593Smuzhiyun
1298*4882a593Smuzhiyun return 0;
1299*4882a593Smuzhiyun }
1300*4882a593Smuzhiyun
mlxsw_sp_trap_items_arr_fini(struct mlxsw_sp * mlxsw_sp)1301*4882a593Smuzhiyun static void mlxsw_sp_trap_items_arr_fini(struct mlxsw_sp *mlxsw_sp)
1302*4882a593Smuzhiyun {
1303*4882a593Smuzhiyun kfree(mlxsw_sp->trap->trap_items_arr);
1304*4882a593Smuzhiyun }
1305*4882a593Smuzhiyun
mlxsw_sp_traps_init(struct mlxsw_sp * mlxsw_sp)1306*4882a593Smuzhiyun static int mlxsw_sp_traps_init(struct mlxsw_sp *mlxsw_sp)
1307*4882a593Smuzhiyun {
1308*4882a593Smuzhiyun struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
1309*4882a593Smuzhiyun struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1310*4882a593Smuzhiyun const struct mlxsw_sp_trap_item *trap_item;
1311*4882a593Smuzhiyun int err, i;
1312*4882a593Smuzhiyun
1313*4882a593Smuzhiyun err = mlxsw_sp_trap_items_arr_init(mlxsw_sp);
1314*4882a593Smuzhiyun if (err)
1315*4882a593Smuzhiyun return err;
1316*4882a593Smuzhiyun
1317*4882a593Smuzhiyun for (i = 0; i < trap->traps_count; i++) {
1318*4882a593Smuzhiyun trap_item = &trap->trap_items_arr[i];
1319*4882a593Smuzhiyun err = devlink_traps_register(devlink, &trap_item->trap, 1,
1320*4882a593Smuzhiyun mlxsw_sp);
1321*4882a593Smuzhiyun if (err)
1322*4882a593Smuzhiyun goto err_trap_register;
1323*4882a593Smuzhiyun }
1324*4882a593Smuzhiyun
1325*4882a593Smuzhiyun return 0;
1326*4882a593Smuzhiyun
1327*4882a593Smuzhiyun err_trap_register:
1328*4882a593Smuzhiyun for (i--; i >= 0; i--) {
1329*4882a593Smuzhiyun trap_item = &trap->trap_items_arr[i];
1330*4882a593Smuzhiyun devlink_traps_unregister(devlink, &trap_item->trap, 1);
1331*4882a593Smuzhiyun }
1332*4882a593Smuzhiyun mlxsw_sp_trap_items_arr_fini(mlxsw_sp);
1333*4882a593Smuzhiyun return err;
1334*4882a593Smuzhiyun }
1335*4882a593Smuzhiyun
mlxsw_sp_traps_fini(struct mlxsw_sp * mlxsw_sp)1336*4882a593Smuzhiyun static void mlxsw_sp_traps_fini(struct mlxsw_sp *mlxsw_sp)
1337*4882a593Smuzhiyun {
1338*4882a593Smuzhiyun struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
1339*4882a593Smuzhiyun struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1340*4882a593Smuzhiyun int i;
1341*4882a593Smuzhiyun
1342*4882a593Smuzhiyun for (i = trap->traps_count - 1; i >= 0; i--) {
1343*4882a593Smuzhiyun const struct mlxsw_sp_trap_item *trap_item;
1344*4882a593Smuzhiyun
1345*4882a593Smuzhiyun trap_item = &trap->trap_items_arr[i];
1346*4882a593Smuzhiyun devlink_traps_unregister(devlink, &trap_item->trap, 1);
1347*4882a593Smuzhiyun }
1348*4882a593Smuzhiyun mlxsw_sp_trap_items_arr_fini(mlxsw_sp);
1349*4882a593Smuzhiyun }
1350*4882a593Smuzhiyun
mlxsw_sp_devlink_traps_init(struct mlxsw_sp * mlxsw_sp)1351*4882a593Smuzhiyun int mlxsw_sp_devlink_traps_init(struct mlxsw_sp *mlxsw_sp)
1352*4882a593Smuzhiyun {
1353*4882a593Smuzhiyun int err;
1354*4882a593Smuzhiyun
1355*4882a593Smuzhiyun err = mlxsw_sp_trap_cpu_policers_set(mlxsw_sp);
1356*4882a593Smuzhiyun if (err)
1357*4882a593Smuzhiyun return err;
1358*4882a593Smuzhiyun
1359*4882a593Smuzhiyun err = mlxsw_sp_trap_dummy_group_init(mlxsw_sp);
1360*4882a593Smuzhiyun if (err)
1361*4882a593Smuzhiyun return err;
1362*4882a593Smuzhiyun
1363*4882a593Smuzhiyun err = mlxsw_sp_trap_policers_init(mlxsw_sp);
1364*4882a593Smuzhiyun if (err)
1365*4882a593Smuzhiyun return err;
1366*4882a593Smuzhiyun
1367*4882a593Smuzhiyun err = mlxsw_sp_trap_groups_init(mlxsw_sp);
1368*4882a593Smuzhiyun if (err)
1369*4882a593Smuzhiyun goto err_trap_groups_init;
1370*4882a593Smuzhiyun
1371*4882a593Smuzhiyun err = mlxsw_sp_traps_init(mlxsw_sp);
1372*4882a593Smuzhiyun if (err)
1373*4882a593Smuzhiyun goto err_traps_init;
1374*4882a593Smuzhiyun
1375*4882a593Smuzhiyun return 0;
1376*4882a593Smuzhiyun
1377*4882a593Smuzhiyun err_traps_init:
1378*4882a593Smuzhiyun mlxsw_sp_trap_groups_fini(mlxsw_sp);
1379*4882a593Smuzhiyun err_trap_groups_init:
1380*4882a593Smuzhiyun mlxsw_sp_trap_policers_fini(mlxsw_sp);
1381*4882a593Smuzhiyun return err;
1382*4882a593Smuzhiyun }
1383*4882a593Smuzhiyun
mlxsw_sp_devlink_traps_fini(struct mlxsw_sp * mlxsw_sp)1384*4882a593Smuzhiyun void mlxsw_sp_devlink_traps_fini(struct mlxsw_sp *mlxsw_sp)
1385*4882a593Smuzhiyun {
1386*4882a593Smuzhiyun mlxsw_sp_traps_fini(mlxsw_sp);
1387*4882a593Smuzhiyun mlxsw_sp_trap_groups_fini(mlxsw_sp);
1388*4882a593Smuzhiyun mlxsw_sp_trap_policers_fini(mlxsw_sp);
1389*4882a593Smuzhiyun }
1390*4882a593Smuzhiyun
mlxsw_sp_trap_init(struct mlxsw_core * mlxsw_core,const struct devlink_trap * trap,void * trap_ctx)1391*4882a593Smuzhiyun int mlxsw_sp_trap_init(struct mlxsw_core *mlxsw_core,
1392*4882a593Smuzhiyun const struct devlink_trap *trap, void *trap_ctx)
1393*4882a593Smuzhiyun {
1394*4882a593Smuzhiyun struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
1395*4882a593Smuzhiyun const struct mlxsw_sp_trap_item *trap_item;
1396*4882a593Smuzhiyun int i;
1397*4882a593Smuzhiyun
1398*4882a593Smuzhiyun trap_item = mlxsw_sp_trap_item_lookup(mlxsw_sp, trap->id);
1399*4882a593Smuzhiyun if (WARN_ON(!trap_item))
1400*4882a593Smuzhiyun return -EINVAL;
1401*4882a593Smuzhiyun
1402*4882a593Smuzhiyun for (i = 0; i < MLXSW_SP_TRAP_LISTENERS_MAX; i++) {
1403*4882a593Smuzhiyun const struct mlxsw_listener *listener;
1404*4882a593Smuzhiyun int err;
1405*4882a593Smuzhiyun
1406*4882a593Smuzhiyun listener = &trap_item->listeners_arr[i];
1407*4882a593Smuzhiyun if (!mlxsw_sp_trap_listener_is_valid(listener))
1408*4882a593Smuzhiyun continue;
1409*4882a593Smuzhiyun err = mlxsw_core_trap_register(mlxsw_core, listener, trap_ctx);
1410*4882a593Smuzhiyun if (err)
1411*4882a593Smuzhiyun return err;
1412*4882a593Smuzhiyun }
1413*4882a593Smuzhiyun
1414*4882a593Smuzhiyun return 0;
1415*4882a593Smuzhiyun }
1416*4882a593Smuzhiyun
mlxsw_sp_trap_fini(struct mlxsw_core * mlxsw_core,const struct devlink_trap * trap,void * trap_ctx)1417*4882a593Smuzhiyun void mlxsw_sp_trap_fini(struct mlxsw_core *mlxsw_core,
1418*4882a593Smuzhiyun const struct devlink_trap *trap, void *trap_ctx)
1419*4882a593Smuzhiyun {
1420*4882a593Smuzhiyun struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
1421*4882a593Smuzhiyun const struct mlxsw_sp_trap_item *trap_item;
1422*4882a593Smuzhiyun int i;
1423*4882a593Smuzhiyun
1424*4882a593Smuzhiyun trap_item = mlxsw_sp_trap_item_lookup(mlxsw_sp, trap->id);
1425*4882a593Smuzhiyun if (WARN_ON(!trap_item))
1426*4882a593Smuzhiyun return;
1427*4882a593Smuzhiyun
1428*4882a593Smuzhiyun for (i = MLXSW_SP_TRAP_LISTENERS_MAX - 1; i >= 0; i--) {
1429*4882a593Smuzhiyun const struct mlxsw_listener *listener;
1430*4882a593Smuzhiyun
1431*4882a593Smuzhiyun listener = &trap_item->listeners_arr[i];
1432*4882a593Smuzhiyun if (!mlxsw_sp_trap_listener_is_valid(listener))
1433*4882a593Smuzhiyun continue;
1434*4882a593Smuzhiyun mlxsw_core_trap_unregister(mlxsw_core, listener, trap_ctx);
1435*4882a593Smuzhiyun }
1436*4882a593Smuzhiyun }
1437*4882a593Smuzhiyun
mlxsw_sp_trap_action_set(struct mlxsw_core * mlxsw_core,const struct devlink_trap * trap,enum devlink_trap_action action,struct netlink_ext_ack * extack)1438*4882a593Smuzhiyun int mlxsw_sp_trap_action_set(struct mlxsw_core *mlxsw_core,
1439*4882a593Smuzhiyun const struct devlink_trap *trap,
1440*4882a593Smuzhiyun enum devlink_trap_action action,
1441*4882a593Smuzhiyun struct netlink_ext_ack *extack)
1442*4882a593Smuzhiyun {
1443*4882a593Smuzhiyun struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
1444*4882a593Smuzhiyun const struct mlxsw_sp_trap_item *trap_item;
1445*4882a593Smuzhiyun int i;
1446*4882a593Smuzhiyun
1447*4882a593Smuzhiyun trap_item = mlxsw_sp_trap_item_lookup(mlxsw_sp, trap->id);
1448*4882a593Smuzhiyun if (WARN_ON(!trap_item))
1449*4882a593Smuzhiyun return -EINVAL;
1450*4882a593Smuzhiyun
1451*4882a593Smuzhiyun if (trap_item->is_source) {
1452*4882a593Smuzhiyun NL_SET_ERR_MSG_MOD(extack, "Changing the action of source traps is not supported");
1453*4882a593Smuzhiyun return -EOPNOTSUPP;
1454*4882a593Smuzhiyun }
1455*4882a593Smuzhiyun
1456*4882a593Smuzhiyun for (i = 0; i < MLXSW_SP_TRAP_LISTENERS_MAX; i++) {
1457*4882a593Smuzhiyun const struct mlxsw_listener *listener;
1458*4882a593Smuzhiyun bool enabled;
1459*4882a593Smuzhiyun int err;
1460*4882a593Smuzhiyun
1461*4882a593Smuzhiyun listener = &trap_item->listeners_arr[i];
1462*4882a593Smuzhiyun if (!mlxsw_sp_trap_listener_is_valid(listener))
1463*4882a593Smuzhiyun continue;
1464*4882a593Smuzhiyun
1465*4882a593Smuzhiyun switch (action) {
1466*4882a593Smuzhiyun case DEVLINK_TRAP_ACTION_DROP:
1467*4882a593Smuzhiyun enabled = false;
1468*4882a593Smuzhiyun break;
1469*4882a593Smuzhiyun case DEVLINK_TRAP_ACTION_TRAP:
1470*4882a593Smuzhiyun enabled = true;
1471*4882a593Smuzhiyun break;
1472*4882a593Smuzhiyun default:
1473*4882a593Smuzhiyun return -EINVAL;
1474*4882a593Smuzhiyun }
1475*4882a593Smuzhiyun err = mlxsw_core_trap_state_set(mlxsw_core, listener, enabled);
1476*4882a593Smuzhiyun if (err)
1477*4882a593Smuzhiyun return err;
1478*4882a593Smuzhiyun }
1479*4882a593Smuzhiyun
1480*4882a593Smuzhiyun return 0;
1481*4882a593Smuzhiyun }
1482*4882a593Smuzhiyun
1483*4882a593Smuzhiyun static int
__mlxsw_sp_trap_group_init(struct mlxsw_core * mlxsw_core,const struct devlink_trap_group * group,u32 policer_id,struct netlink_ext_ack * extack)1484*4882a593Smuzhiyun __mlxsw_sp_trap_group_init(struct mlxsw_core *mlxsw_core,
1485*4882a593Smuzhiyun const struct devlink_trap_group *group,
1486*4882a593Smuzhiyun u32 policer_id, struct netlink_ext_ack *extack)
1487*4882a593Smuzhiyun {
1488*4882a593Smuzhiyun struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
1489*4882a593Smuzhiyun u16 hw_policer_id = MLXSW_REG_HTGT_INVALID_POLICER;
1490*4882a593Smuzhiyun const struct mlxsw_sp_trap_group_item *group_item;
1491*4882a593Smuzhiyun char htgt_pl[MLXSW_REG_HTGT_LEN];
1492*4882a593Smuzhiyun
1493*4882a593Smuzhiyun group_item = mlxsw_sp_trap_group_item_lookup(mlxsw_sp, group->id);
1494*4882a593Smuzhiyun if (WARN_ON(!group_item))
1495*4882a593Smuzhiyun return -EINVAL;
1496*4882a593Smuzhiyun
1497*4882a593Smuzhiyun if (group_item->fixed_policer && policer_id != group->init_policer_id) {
1498*4882a593Smuzhiyun NL_SET_ERR_MSG_MOD(extack, "Changing the policer binding of this group is not supported");
1499*4882a593Smuzhiyun return -EOPNOTSUPP;
1500*4882a593Smuzhiyun }
1501*4882a593Smuzhiyun
1502*4882a593Smuzhiyun if (policer_id) {
1503*4882a593Smuzhiyun struct mlxsw_sp_trap_policer_item *policer_item;
1504*4882a593Smuzhiyun
1505*4882a593Smuzhiyun policer_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp,
1506*4882a593Smuzhiyun policer_id);
1507*4882a593Smuzhiyun if (WARN_ON(!policer_item))
1508*4882a593Smuzhiyun return -EINVAL;
1509*4882a593Smuzhiyun hw_policer_id = policer_item->hw_id;
1510*4882a593Smuzhiyun }
1511*4882a593Smuzhiyun
1512*4882a593Smuzhiyun mlxsw_reg_htgt_pack(htgt_pl, group_item->hw_group_id, hw_policer_id,
1513*4882a593Smuzhiyun group_item->priority, group_item->priority);
1514*4882a593Smuzhiyun return mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl);
1515*4882a593Smuzhiyun }
1516*4882a593Smuzhiyun
mlxsw_sp_trap_group_init(struct mlxsw_core * mlxsw_core,const struct devlink_trap_group * group)1517*4882a593Smuzhiyun int mlxsw_sp_trap_group_init(struct mlxsw_core *mlxsw_core,
1518*4882a593Smuzhiyun const struct devlink_trap_group *group)
1519*4882a593Smuzhiyun {
1520*4882a593Smuzhiyun return __mlxsw_sp_trap_group_init(mlxsw_core, group,
1521*4882a593Smuzhiyun group->init_policer_id, NULL);
1522*4882a593Smuzhiyun }
1523*4882a593Smuzhiyun
mlxsw_sp_trap_group_set(struct mlxsw_core * mlxsw_core,const struct devlink_trap_group * group,const struct devlink_trap_policer * policer,struct netlink_ext_ack * extack)1524*4882a593Smuzhiyun int mlxsw_sp_trap_group_set(struct mlxsw_core *mlxsw_core,
1525*4882a593Smuzhiyun const struct devlink_trap_group *group,
1526*4882a593Smuzhiyun const struct devlink_trap_policer *policer,
1527*4882a593Smuzhiyun struct netlink_ext_ack *extack)
1528*4882a593Smuzhiyun {
1529*4882a593Smuzhiyun u32 policer_id = policer ? policer->id : 0;
1530*4882a593Smuzhiyun
1531*4882a593Smuzhiyun return __mlxsw_sp_trap_group_init(mlxsw_core, group, policer_id,
1532*4882a593Smuzhiyun extack);
1533*4882a593Smuzhiyun }
1534*4882a593Smuzhiyun
1535*4882a593Smuzhiyun static int
mlxsw_sp_trap_policer_item_init(struct mlxsw_sp * mlxsw_sp,struct mlxsw_sp_trap_policer_item * policer_item)1536*4882a593Smuzhiyun mlxsw_sp_trap_policer_item_init(struct mlxsw_sp *mlxsw_sp,
1537*4882a593Smuzhiyun struct mlxsw_sp_trap_policer_item *policer_item)
1538*4882a593Smuzhiyun {
1539*4882a593Smuzhiyun struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1540*4882a593Smuzhiyun u16 hw_id;
1541*4882a593Smuzhiyun
1542*4882a593Smuzhiyun /* We should be able to allocate a policer because the number of
1543*4882a593Smuzhiyun * policers we registered with devlink is in according with the number
1544*4882a593Smuzhiyun * of available policers.
1545*4882a593Smuzhiyun */
1546*4882a593Smuzhiyun hw_id = find_first_zero_bit(trap->policers_usage, trap->max_policers);
1547*4882a593Smuzhiyun if (WARN_ON(hw_id == trap->max_policers))
1548*4882a593Smuzhiyun return -ENOBUFS;
1549*4882a593Smuzhiyun
1550*4882a593Smuzhiyun __set_bit(hw_id, trap->policers_usage);
1551*4882a593Smuzhiyun policer_item->hw_id = hw_id;
1552*4882a593Smuzhiyun
1553*4882a593Smuzhiyun return 0;
1554*4882a593Smuzhiyun }
1555*4882a593Smuzhiyun
1556*4882a593Smuzhiyun static void
mlxsw_sp_trap_policer_item_fini(struct mlxsw_sp * mlxsw_sp,struct mlxsw_sp_trap_policer_item * policer_item)1557*4882a593Smuzhiyun mlxsw_sp_trap_policer_item_fini(struct mlxsw_sp *mlxsw_sp,
1558*4882a593Smuzhiyun struct mlxsw_sp_trap_policer_item *policer_item)
1559*4882a593Smuzhiyun {
1560*4882a593Smuzhiyun __clear_bit(policer_item->hw_id, mlxsw_sp->trap->policers_usage);
1561*4882a593Smuzhiyun }
1562*4882a593Smuzhiyun
mlxsw_sp_trap_policer_bs(u64 burst,u8 * p_burst_size,struct netlink_ext_ack * extack)1563*4882a593Smuzhiyun static int mlxsw_sp_trap_policer_bs(u64 burst, u8 *p_burst_size,
1564*4882a593Smuzhiyun struct netlink_ext_ack *extack)
1565*4882a593Smuzhiyun {
1566*4882a593Smuzhiyun int bs = fls64(burst) - 1;
1567*4882a593Smuzhiyun
1568*4882a593Smuzhiyun if (burst != (BIT_ULL(bs))) {
1569*4882a593Smuzhiyun NL_SET_ERR_MSG_MOD(extack, "Policer burst size is not power of two");
1570*4882a593Smuzhiyun return -EINVAL;
1571*4882a593Smuzhiyun }
1572*4882a593Smuzhiyun
1573*4882a593Smuzhiyun *p_burst_size = bs;
1574*4882a593Smuzhiyun
1575*4882a593Smuzhiyun return 0;
1576*4882a593Smuzhiyun }
1577*4882a593Smuzhiyun
__mlxsw_sp_trap_policer_set(struct mlxsw_sp * mlxsw_sp,u16 hw_id,u64 rate,u64 burst,bool clear_counter,struct netlink_ext_ack * extack)1578*4882a593Smuzhiyun static int __mlxsw_sp_trap_policer_set(struct mlxsw_sp *mlxsw_sp, u16 hw_id,
1579*4882a593Smuzhiyun u64 rate, u64 burst, bool clear_counter,
1580*4882a593Smuzhiyun struct netlink_ext_ack *extack)
1581*4882a593Smuzhiyun {
1582*4882a593Smuzhiyun char qpcr_pl[MLXSW_REG_QPCR_LEN];
1583*4882a593Smuzhiyun u8 burst_size;
1584*4882a593Smuzhiyun int err;
1585*4882a593Smuzhiyun
1586*4882a593Smuzhiyun err = mlxsw_sp_trap_policer_bs(burst, &burst_size, extack);
1587*4882a593Smuzhiyun if (err)
1588*4882a593Smuzhiyun return err;
1589*4882a593Smuzhiyun
1590*4882a593Smuzhiyun mlxsw_reg_qpcr_pack(qpcr_pl, hw_id, MLXSW_REG_QPCR_IR_UNITS_M, false,
1591*4882a593Smuzhiyun rate, burst_size);
1592*4882a593Smuzhiyun mlxsw_reg_qpcr_clear_counter_set(qpcr_pl, clear_counter);
1593*4882a593Smuzhiyun return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qpcr), qpcr_pl);
1594*4882a593Smuzhiyun }
1595*4882a593Smuzhiyun
mlxsw_sp_trap_policer_init(struct mlxsw_core * mlxsw_core,const struct devlink_trap_policer * policer)1596*4882a593Smuzhiyun int mlxsw_sp_trap_policer_init(struct mlxsw_core *mlxsw_core,
1597*4882a593Smuzhiyun const struct devlink_trap_policer *policer)
1598*4882a593Smuzhiyun {
1599*4882a593Smuzhiyun struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
1600*4882a593Smuzhiyun struct mlxsw_sp_trap_policer_item *policer_item;
1601*4882a593Smuzhiyun int err;
1602*4882a593Smuzhiyun
1603*4882a593Smuzhiyun policer_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, policer->id);
1604*4882a593Smuzhiyun if (WARN_ON(!policer_item))
1605*4882a593Smuzhiyun return -EINVAL;
1606*4882a593Smuzhiyun
1607*4882a593Smuzhiyun err = mlxsw_sp_trap_policer_item_init(mlxsw_sp, policer_item);
1608*4882a593Smuzhiyun if (err)
1609*4882a593Smuzhiyun return err;
1610*4882a593Smuzhiyun
1611*4882a593Smuzhiyun err = __mlxsw_sp_trap_policer_set(mlxsw_sp, policer_item->hw_id,
1612*4882a593Smuzhiyun policer->init_rate,
1613*4882a593Smuzhiyun policer->init_burst, true, NULL);
1614*4882a593Smuzhiyun if (err)
1615*4882a593Smuzhiyun goto err_trap_policer_set;
1616*4882a593Smuzhiyun
1617*4882a593Smuzhiyun return 0;
1618*4882a593Smuzhiyun
1619*4882a593Smuzhiyun err_trap_policer_set:
1620*4882a593Smuzhiyun mlxsw_sp_trap_policer_item_fini(mlxsw_sp, policer_item);
1621*4882a593Smuzhiyun return err;
1622*4882a593Smuzhiyun }
1623*4882a593Smuzhiyun
mlxsw_sp_trap_policer_fini(struct mlxsw_core * mlxsw_core,const struct devlink_trap_policer * policer)1624*4882a593Smuzhiyun void mlxsw_sp_trap_policer_fini(struct mlxsw_core *mlxsw_core,
1625*4882a593Smuzhiyun const struct devlink_trap_policer *policer)
1626*4882a593Smuzhiyun {
1627*4882a593Smuzhiyun struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
1628*4882a593Smuzhiyun struct mlxsw_sp_trap_policer_item *policer_item;
1629*4882a593Smuzhiyun
1630*4882a593Smuzhiyun policer_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, policer->id);
1631*4882a593Smuzhiyun if (WARN_ON(!policer_item))
1632*4882a593Smuzhiyun return;
1633*4882a593Smuzhiyun
1634*4882a593Smuzhiyun mlxsw_sp_trap_policer_item_fini(mlxsw_sp, policer_item);
1635*4882a593Smuzhiyun }
1636*4882a593Smuzhiyun
mlxsw_sp_trap_policer_set(struct mlxsw_core * mlxsw_core,const struct devlink_trap_policer * policer,u64 rate,u64 burst,struct netlink_ext_ack * extack)1637*4882a593Smuzhiyun int mlxsw_sp_trap_policer_set(struct mlxsw_core *mlxsw_core,
1638*4882a593Smuzhiyun const struct devlink_trap_policer *policer,
1639*4882a593Smuzhiyun u64 rate, u64 burst,
1640*4882a593Smuzhiyun struct netlink_ext_ack *extack)
1641*4882a593Smuzhiyun {
1642*4882a593Smuzhiyun struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
1643*4882a593Smuzhiyun struct mlxsw_sp_trap_policer_item *policer_item;
1644*4882a593Smuzhiyun
1645*4882a593Smuzhiyun policer_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, policer->id);
1646*4882a593Smuzhiyun if (WARN_ON(!policer_item))
1647*4882a593Smuzhiyun return -EINVAL;
1648*4882a593Smuzhiyun
1649*4882a593Smuzhiyun return __mlxsw_sp_trap_policer_set(mlxsw_sp, policer_item->hw_id,
1650*4882a593Smuzhiyun rate, burst, false, extack);
1651*4882a593Smuzhiyun }
1652*4882a593Smuzhiyun
1653*4882a593Smuzhiyun int
mlxsw_sp_trap_policer_counter_get(struct mlxsw_core * mlxsw_core,const struct devlink_trap_policer * policer,u64 * p_drops)1654*4882a593Smuzhiyun mlxsw_sp_trap_policer_counter_get(struct mlxsw_core *mlxsw_core,
1655*4882a593Smuzhiyun const struct devlink_trap_policer *policer,
1656*4882a593Smuzhiyun u64 *p_drops)
1657*4882a593Smuzhiyun {
1658*4882a593Smuzhiyun struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
1659*4882a593Smuzhiyun struct mlxsw_sp_trap_policer_item *policer_item;
1660*4882a593Smuzhiyun char qpcr_pl[MLXSW_REG_QPCR_LEN];
1661*4882a593Smuzhiyun int err;
1662*4882a593Smuzhiyun
1663*4882a593Smuzhiyun policer_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, policer->id);
1664*4882a593Smuzhiyun if (WARN_ON(!policer_item))
1665*4882a593Smuzhiyun return -EINVAL;
1666*4882a593Smuzhiyun
1667*4882a593Smuzhiyun mlxsw_reg_qpcr_pack(qpcr_pl, policer_item->hw_id,
1668*4882a593Smuzhiyun MLXSW_REG_QPCR_IR_UNITS_M, false, 0, 0);
1669*4882a593Smuzhiyun err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(qpcr), qpcr_pl);
1670*4882a593Smuzhiyun if (err)
1671*4882a593Smuzhiyun return err;
1672*4882a593Smuzhiyun
1673*4882a593Smuzhiyun *p_drops = mlxsw_reg_qpcr_violate_count_get(qpcr_pl);
1674*4882a593Smuzhiyun
1675*4882a593Smuzhiyun return 0;
1676*4882a593Smuzhiyun }
1677*4882a593Smuzhiyun
mlxsw_sp_trap_group_policer_hw_id_get(struct mlxsw_sp * mlxsw_sp,u16 id,bool * p_enabled,u16 * p_hw_id)1678*4882a593Smuzhiyun int mlxsw_sp_trap_group_policer_hw_id_get(struct mlxsw_sp *mlxsw_sp, u16 id,
1679*4882a593Smuzhiyun bool *p_enabled, u16 *p_hw_id)
1680*4882a593Smuzhiyun {
1681*4882a593Smuzhiyun struct mlxsw_sp_trap_policer_item *pol_item;
1682*4882a593Smuzhiyun struct mlxsw_sp_trap_group_item *gr_item;
1683*4882a593Smuzhiyun u32 pol_id;
1684*4882a593Smuzhiyun
1685*4882a593Smuzhiyun gr_item = mlxsw_sp_trap_group_item_lookup(mlxsw_sp, id);
1686*4882a593Smuzhiyun if (!gr_item)
1687*4882a593Smuzhiyun return -ENOENT;
1688*4882a593Smuzhiyun
1689*4882a593Smuzhiyun pol_id = gr_item->group.init_policer_id;
1690*4882a593Smuzhiyun if (!pol_id) {
1691*4882a593Smuzhiyun *p_enabled = false;
1692*4882a593Smuzhiyun return 0;
1693*4882a593Smuzhiyun }
1694*4882a593Smuzhiyun
1695*4882a593Smuzhiyun pol_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, pol_id);
1696*4882a593Smuzhiyun if (WARN_ON(!pol_item))
1697*4882a593Smuzhiyun return -ENOENT;
1698*4882a593Smuzhiyun
1699*4882a593Smuzhiyun *p_enabled = true;
1700*4882a593Smuzhiyun *p_hw_id = pol_item->hw_id;
1701*4882a593Smuzhiyun return 0;
1702*4882a593Smuzhiyun }
1703*4882a593Smuzhiyun
1704*4882a593Smuzhiyun static const struct mlxsw_sp_trap_group_item
1705*4882a593Smuzhiyun mlxsw_sp1_trap_group_items_arr[] = {
1706*4882a593Smuzhiyun };
1707*4882a593Smuzhiyun
1708*4882a593Smuzhiyun static const struct mlxsw_sp_trap_item
1709*4882a593Smuzhiyun mlxsw_sp1_trap_items_arr[] = {
1710*4882a593Smuzhiyun };
1711*4882a593Smuzhiyun
1712*4882a593Smuzhiyun static int
mlxsw_sp1_trap_groups_init(struct mlxsw_sp * mlxsw_sp,const struct mlxsw_sp_trap_group_item ** arr,size_t * p_groups_count)1713*4882a593Smuzhiyun mlxsw_sp1_trap_groups_init(struct mlxsw_sp *mlxsw_sp,
1714*4882a593Smuzhiyun const struct mlxsw_sp_trap_group_item **arr,
1715*4882a593Smuzhiyun size_t *p_groups_count)
1716*4882a593Smuzhiyun {
1717*4882a593Smuzhiyun *arr = mlxsw_sp1_trap_group_items_arr;
1718*4882a593Smuzhiyun *p_groups_count = ARRAY_SIZE(mlxsw_sp1_trap_group_items_arr);
1719*4882a593Smuzhiyun
1720*4882a593Smuzhiyun return 0;
1721*4882a593Smuzhiyun }
1722*4882a593Smuzhiyun
mlxsw_sp1_traps_init(struct mlxsw_sp * mlxsw_sp,const struct mlxsw_sp_trap_item ** arr,size_t * p_traps_count)1723*4882a593Smuzhiyun static int mlxsw_sp1_traps_init(struct mlxsw_sp *mlxsw_sp,
1724*4882a593Smuzhiyun const struct mlxsw_sp_trap_item **arr,
1725*4882a593Smuzhiyun size_t *p_traps_count)
1726*4882a593Smuzhiyun {
1727*4882a593Smuzhiyun *arr = mlxsw_sp1_trap_items_arr;
1728*4882a593Smuzhiyun *p_traps_count = ARRAY_SIZE(mlxsw_sp1_trap_items_arr);
1729*4882a593Smuzhiyun
1730*4882a593Smuzhiyun return 0;
1731*4882a593Smuzhiyun }
1732*4882a593Smuzhiyun
1733*4882a593Smuzhiyun const struct mlxsw_sp_trap_ops mlxsw_sp1_trap_ops = {
1734*4882a593Smuzhiyun .groups_init = mlxsw_sp1_trap_groups_init,
1735*4882a593Smuzhiyun .traps_init = mlxsw_sp1_traps_init,
1736*4882a593Smuzhiyun };
1737*4882a593Smuzhiyun
1738*4882a593Smuzhiyun static const struct mlxsw_sp_trap_group_item
1739*4882a593Smuzhiyun mlxsw_sp2_trap_group_items_arr[] = {
1740*4882a593Smuzhiyun {
1741*4882a593Smuzhiyun .group = DEVLINK_TRAP_GROUP_GENERIC(BUFFER_DROPS, 20),
1742*4882a593Smuzhiyun .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_BUFFER_DISCARDS,
1743*4882a593Smuzhiyun .priority = 0,
1744*4882a593Smuzhiyun .fixed_policer = true,
1745*4882a593Smuzhiyun },
1746*4882a593Smuzhiyun };
1747*4882a593Smuzhiyun
1748*4882a593Smuzhiyun static const struct mlxsw_sp_trap_item
1749*4882a593Smuzhiyun mlxsw_sp2_trap_items_arr[] = {
1750*4882a593Smuzhiyun {
1751*4882a593Smuzhiyun .trap = MLXSW_SP_TRAP_BUFFER_DROP(EARLY_DROP),
1752*4882a593Smuzhiyun .listeners_arr = {
1753*4882a593Smuzhiyun MLXSW_SP_RXL_BUFFER_DISCARD(INGRESS_WRED),
1754*4882a593Smuzhiyun },
1755*4882a593Smuzhiyun .is_source = true,
1756*4882a593Smuzhiyun },
1757*4882a593Smuzhiyun };
1758*4882a593Smuzhiyun
1759*4882a593Smuzhiyun static int
mlxsw_sp2_trap_groups_init(struct mlxsw_sp * mlxsw_sp,const struct mlxsw_sp_trap_group_item ** arr,size_t * p_groups_count)1760*4882a593Smuzhiyun mlxsw_sp2_trap_groups_init(struct mlxsw_sp *mlxsw_sp,
1761*4882a593Smuzhiyun const struct mlxsw_sp_trap_group_item **arr,
1762*4882a593Smuzhiyun size_t *p_groups_count)
1763*4882a593Smuzhiyun {
1764*4882a593Smuzhiyun *arr = mlxsw_sp2_trap_group_items_arr;
1765*4882a593Smuzhiyun *p_groups_count = ARRAY_SIZE(mlxsw_sp2_trap_group_items_arr);
1766*4882a593Smuzhiyun
1767*4882a593Smuzhiyun return 0;
1768*4882a593Smuzhiyun }
1769*4882a593Smuzhiyun
mlxsw_sp2_traps_init(struct mlxsw_sp * mlxsw_sp,const struct mlxsw_sp_trap_item ** arr,size_t * p_traps_count)1770*4882a593Smuzhiyun static int mlxsw_sp2_traps_init(struct mlxsw_sp *mlxsw_sp,
1771*4882a593Smuzhiyun const struct mlxsw_sp_trap_item **arr,
1772*4882a593Smuzhiyun size_t *p_traps_count)
1773*4882a593Smuzhiyun {
1774*4882a593Smuzhiyun *arr = mlxsw_sp2_trap_items_arr;
1775*4882a593Smuzhiyun *p_traps_count = ARRAY_SIZE(mlxsw_sp2_trap_items_arr);
1776*4882a593Smuzhiyun
1777*4882a593Smuzhiyun return 0;
1778*4882a593Smuzhiyun }
1779*4882a593Smuzhiyun
1780*4882a593Smuzhiyun const struct mlxsw_sp_trap_ops mlxsw_sp2_trap_ops = {
1781*4882a593Smuzhiyun .groups_init = mlxsw_sp2_trap_groups_init,
1782*4882a593Smuzhiyun .traps_init = mlxsw_sp2_traps_init,
1783*4882a593Smuzhiyun };
1784