1b5ce611fSIdo Schimmel // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2b5ce611fSIdo Schimmel /* Copyright (c) 2019 Mellanox Technologies. All rights reserved */
3b5ce611fSIdo Schimmel
44561705bSIdo Schimmel #include <linux/bitops.h>
5b5ce611fSIdo Schimmel #include <linux/kernel.h>
613f2e64bSIdo Schimmel #include <linux/netlink.h>
7b5ce611fSIdo Schimmel #include <net/devlink.h>
8b5ce611fSIdo Schimmel #include <uapi/linux/devlink.h>
9b5ce611fSIdo Schimmel
10b5ce611fSIdo Schimmel #include "core.h"
11b5ce611fSIdo Schimmel #include "reg.h"
12b5ce611fSIdo Schimmel #include "spectrum.h"
1303484e49SIdo Schimmel #include "spectrum_trap.h"
14b5ce611fSIdo Schimmel
1585d4ec59SIdo Schimmel struct mlxsw_sp_trap_policer_item {
16cc678f4dSIdo Schimmel struct devlink_trap_policer policer;
1785d4ec59SIdo Schimmel u16 hw_id;
1885d4ec59SIdo Schimmel };
1985d4ec59SIdo Schimmel
20b14a40dbSIdo Schimmel struct mlxsw_sp_trap_group_item {
21b14a40dbSIdo Schimmel struct devlink_trap_group group;
22b14a40dbSIdo Schimmel u16 hw_group_id;
23b14a40dbSIdo Schimmel u8 priority;
246687e953SIdo Schimmel u8 fixed_policer:1; /* Whether policer binding can change */
25b14a40dbSIdo Schimmel };
26b14a40dbSIdo Schimmel
27200b7ccaSIdo Schimmel #define MLXSW_SP_TRAP_LISTENERS_MAX 3
28200b7ccaSIdo Schimmel
29200b7ccaSIdo Schimmel struct mlxsw_sp_trap_item {
30200b7ccaSIdo Schimmel struct devlink_trap trap;
31200b7ccaSIdo Schimmel struct mlxsw_listener listeners_arr[MLXSW_SP_TRAP_LISTENERS_MAX];
326687e953SIdo Schimmel u8 is_source:1;
33200b7ccaSIdo Schimmel };
34200b7ccaSIdo Schimmel
355b051621SAmit Cohen /* All driver-specific traps must be documented in
365b051621SAmit Cohen * Documentation/networking/devlink/mlxsw.rst
375b051621SAmit Cohen */
385b051621SAmit Cohen enum {
395b051621SAmit Cohen DEVLINK_MLXSW_TRAP_ID_BASE = DEVLINK_TRAP_GENERIC_ID_MAX,
405b051621SAmit Cohen DEVLINK_MLXSW_TRAP_ID_IRIF_DISABLED,
415b051621SAmit Cohen DEVLINK_MLXSW_TRAP_ID_ERIF_DISABLED,
425b051621SAmit Cohen };
435b051621SAmit Cohen
445b051621SAmit Cohen #define DEVLINK_MLXSW_TRAP_NAME_IRIF_DISABLED \
455b051621SAmit Cohen "irif_disabled"
465b051621SAmit Cohen #define DEVLINK_MLXSW_TRAP_NAME_ERIF_DISABLED \
475b051621SAmit Cohen "erif_disabled"
485b051621SAmit Cohen
49b5ce611fSIdo Schimmel #define MLXSW_SP_TRAP_METADATA DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT
50b5ce611fSIdo Schimmel
516687e953SIdo Schimmel enum {
52cf31190aSIdo Schimmel /* Packet was mirrored from ingress. */
53cf31190aSIdo Schimmel MLXSW_SP_MIRROR_REASON_INGRESS = 1,
5445aad0b7SIdo Schimmel /* Packet was mirrored from policy engine. */
5545aad0b7SIdo Schimmel MLXSW_SP_MIRROR_REASON_POLICY_ENGINE = 2,
566687e953SIdo Schimmel /* Packet was early dropped. */
576687e953SIdo Schimmel MLXSW_SP_MIRROR_REASON_INGRESS_WRED = 9,
5854d0e963SIdo Schimmel /* Packet was mirrored from egress. */
5954d0e963SIdo Schimmel MLXSW_SP_MIRROR_REASON_EGRESS = 14,
606687e953SIdo Schimmel };
616687e953SIdo Schimmel
mlxsw_sp_rx_listener(struct mlxsw_sp * mlxsw_sp,struct sk_buff * skb,u16 local_port,struct mlxsw_sp_port * mlxsw_sp_port)62a5118ef1SJiri Pirko static int mlxsw_sp_rx_listener(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
63c934757dSAmit Cohen u16 local_port,
64a5118ef1SJiri Pirko struct mlxsw_sp_port *mlxsw_sp_port)
65a5118ef1SJiri Pirko {
66a5118ef1SJiri Pirko struct mlxsw_sp_port_pcpu_stats *pcpu_stats;
67a5118ef1SJiri Pirko
68a5118ef1SJiri Pirko if (unlikely(!mlxsw_sp_port)) {
69a5118ef1SJiri Pirko dev_warn_ratelimited(mlxsw_sp->bus_info->dev, "Port %d: skb received for non-existent port\n",
70a5118ef1SJiri Pirko local_port);
71a5118ef1SJiri Pirko kfree_skb(skb);
72a5118ef1SJiri Pirko return -EINVAL;
73a5118ef1SJiri Pirko }
74a5118ef1SJiri Pirko
75a5118ef1SJiri Pirko skb->dev = mlxsw_sp_port->dev;
76a5118ef1SJiri Pirko
77a5118ef1SJiri Pirko pcpu_stats = this_cpu_ptr(mlxsw_sp_port->pcpu_stats);
78a5118ef1SJiri Pirko u64_stats_update_begin(&pcpu_stats->syncp);
79a5118ef1SJiri Pirko pcpu_stats->rx_packets++;
80a5118ef1SJiri Pirko pcpu_stats->rx_bytes += skb->len;
81a5118ef1SJiri Pirko u64_stats_update_end(&pcpu_stats->syncp);
82a5118ef1SJiri Pirko
83a5118ef1SJiri Pirko skb->protocol = eth_type_trans(skb, skb->dev);
84a5118ef1SJiri Pirko
85a5118ef1SJiri Pirko return 0;
86a5118ef1SJiri Pirko }
87a5118ef1SJiri Pirko
mlxsw_sp_rx_drop_listener(struct sk_buff * skb,u16 local_port,void * trap_ctx)88c934757dSAmit Cohen static void mlxsw_sp_rx_drop_listener(struct sk_buff *skb, u16 local_port,
89a5118ef1SJiri Pirko void *trap_ctx)
90a5118ef1SJiri Pirko {
91a5118ef1SJiri Pirko struct devlink_port *in_devlink_port;
92a5118ef1SJiri Pirko struct mlxsw_sp_port *mlxsw_sp_port;
93a5118ef1SJiri Pirko struct mlxsw_sp *mlxsw_sp;
94a5118ef1SJiri Pirko struct devlink *devlink;
95a5118ef1SJiri Pirko int err;
96a5118ef1SJiri Pirko
97a5118ef1SJiri Pirko mlxsw_sp = devlink_trap_ctx_priv(trap_ctx);
98a5118ef1SJiri Pirko mlxsw_sp_port = mlxsw_sp->ports[local_port];
99a5118ef1SJiri Pirko
100a5118ef1SJiri Pirko err = mlxsw_sp_rx_listener(mlxsw_sp, skb, local_port, mlxsw_sp_port);
101a5118ef1SJiri Pirko if (err)
102a5118ef1SJiri Pirko return;
103a5118ef1SJiri Pirko
104a5118ef1SJiri Pirko devlink = priv_to_devlink(mlxsw_sp->core);
105a5118ef1SJiri Pirko in_devlink_port = mlxsw_core_port_devlink_port_get(mlxsw_sp->core,
106a5118ef1SJiri Pirko local_port);
107a5118ef1SJiri Pirko skb_push(skb, ETH_HLEN);
1085a2e106cSJiri Pirko devlink_trap_report(devlink, skb, trap_ctx, in_devlink_port, NULL);
109a5118ef1SJiri Pirko consume_skb(skb);
110a5118ef1SJiri Pirko }
111a5118ef1SJiri Pirko
mlxsw_sp_rx_acl_drop_listener(struct sk_buff * skb,u16 local_port,void * trap_ctx)112c934757dSAmit Cohen static void mlxsw_sp_rx_acl_drop_listener(struct sk_buff *skb, u16 local_port,
1136de9fceeSJiri Pirko void *trap_ctx)
1146de9fceeSJiri Pirko {
115d4cabaadSIdo Schimmel u32 cookie_index = mlxsw_skb_cb(skb)->rx_md_info.cookie_index;
1166de9fceeSJiri Pirko const struct flow_action_cookie *fa_cookie;
1176de9fceeSJiri Pirko struct devlink_port *in_devlink_port;
1186de9fceeSJiri Pirko struct mlxsw_sp_port *mlxsw_sp_port;
1196de9fceeSJiri Pirko struct mlxsw_sp *mlxsw_sp;
1206de9fceeSJiri Pirko struct devlink *devlink;
1216de9fceeSJiri Pirko int err;
1226de9fceeSJiri Pirko
1236de9fceeSJiri Pirko mlxsw_sp = devlink_trap_ctx_priv(trap_ctx);
1246de9fceeSJiri Pirko mlxsw_sp_port = mlxsw_sp->ports[local_port];
1256de9fceeSJiri Pirko
1266de9fceeSJiri Pirko err = mlxsw_sp_rx_listener(mlxsw_sp, skb, local_port, mlxsw_sp_port);
1276de9fceeSJiri Pirko if (err)
1286de9fceeSJiri Pirko return;
1296de9fceeSJiri Pirko
1306de9fceeSJiri Pirko devlink = priv_to_devlink(mlxsw_sp->core);
1316de9fceeSJiri Pirko in_devlink_port = mlxsw_core_port_devlink_port_get(mlxsw_sp->core,
1326de9fceeSJiri Pirko local_port);
1336de9fceeSJiri Pirko skb_push(skb, ETH_HLEN);
1346de9fceeSJiri Pirko rcu_read_lock();
1356de9fceeSJiri Pirko fa_cookie = mlxsw_sp_acl_act_cookie_lookup(mlxsw_sp, cookie_index);
1366de9fceeSJiri Pirko devlink_trap_report(devlink, skb, trap_ctx, in_devlink_port, fa_cookie);
1376de9fceeSJiri Pirko rcu_read_unlock();
1386de9fceeSJiri Pirko consume_skb(skb);
1396de9fceeSJiri Pirko }
1406de9fceeSJiri Pirko
__mlxsw_sp_rx_no_mark_listener(struct sk_buff * skb,u16 local_port,void * trap_ctx)141c934757dSAmit Cohen static int __mlxsw_sp_rx_no_mark_listener(struct sk_buff *skb, u16 local_port,
142a5118ef1SJiri Pirko void *trap_ctx)
143a5118ef1SJiri Pirko {
144a5118ef1SJiri Pirko struct devlink_port *in_devlink_port;
145a5118ef1SJiri Pirko struct mlxsw_sp_port *mlxsw_sp_port;
146a5118ef1SJiri Pirko struct mlxsw_sp *mlxsw_sp;
147a5118ef1SJiri Pirko struct devlink *devlink;
148a5118ef1SJiri Pirko int err;
149a5118ef1SJiri Pirko
150a5118ef1SJiri Pirko mlxsw_sp = devlink_trap_ctx_priv(trap_ctx);
151a5118ef1SJiri Pirko mlxsw_sp_port = mlxsw_sp->ports[local_port];
152a5118ef1SJiri Pirko
153a5118ef1SJiri Pirko err = mlxsw_sp_rx_listener(mlxsw_sp, skb, local_port, mlxsw_sp_port);
154a5118ef1SJiri Pirko if (err)
15545b1c873SIdo Schimmel return err;
156a5118ef1SJiri Pirko
157a5118ef1SJiri Pirko devlink = priv_to_devlink(mlxsw_sp->core);
158a5118ef1SJiri Pirko in_devlink_port = mlxsw_core_port_devlink_port_get(mlxsw_sp->core,
159a5118ef1SJiri Pirko local_port);
160a5118ef1SJiri Pirko skb_push(skb, ETH_HLEN);
1615a2e106cSJiri Pirko devlink_trap_report(devlink, skb, trap_ctx, in_devlink_port, NULL);
162a5118ef1SJiri Pirko skb_pull(skb, ETH_HLEN);
16345b1c873SIdo Schimmel
16445b1c873SIdo Schimmel return 0;
16545b1c873SIdo Schimmel }
16645b1c873SIdo Schimmel
mlxsw_sp_rx_no_mark_listener(struct sk_buff * skb,u16 local_port,void * trap_ctx)167c934757dSAmit Cohen static void mlxsw_sp_rx_no_mark_listener(struct sk_buff *skb, u16 local_port,
16845b1c873SIdo Schimmel void *trap_ctx)
16945b1c873SIdo Schimmel {
17045b1c873SIdo Schimmel int err;
17145b1c873SIdo Schimmel
17245b1c873SIdo Schimmel err = __mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx);
17345b1c873SIdo Schimmel if (err)
17445b1c873SIdo Schimmel return;
17545b1c873SIdo Schimmel
176a5118ef1SJiri Pirko netif_receive_skb(skb);
177a5118ef1SJiri Pirko }
178b5ce611fSIdo Schimmel
mlxsw_sp_rx_mark_listener(struct sk_buff * skb,u16 local_port,void * trap_ctx)179c934757dSAmit Cohen static void mlxsw_sp_rx_mark_listener(struct sk_buff *skb, u16 local_port,
18045b1c873SIdo Schimmel void *trap_ctx)
18145b1c873SIdo Schimmel {
18245b1c873SIdo Schimmel skb->offload_fwd_mark = 1;
18345b1c873SIdo Schimmel mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx);
18445b1c873SIdo Schimmel }
18545b1c873SIdo Schimmel
mlxsw_sp_rx_l3_mark_listener(struct sk_buff * skb,u16 local_port,void * trap_ctx)186c934757dSAmit Cohen static void mlxsw_sp_rx_l3_mark_listener(struct sk_buff *skb, u16 local_port,
1878110668eSIdo Schimmel void *trap_ctx)
1888110668eSIdo Schimmel {
1898110668eSIdo Schimmel skb->offload_l3_fwd_mark = 1;
1908110668eSIdo Schimmel skb->offload_fwd_mark = 1;
1918110668eSIdo Schimmel mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx);
1928110668eSIdo Schimmel }
1938110668eSIdo Schimmel
mlxsw_sp_rx_ptp_listener(struct sk_buff * skb,u16 local_port,void * trap_ctx)194c934757dSAmit Cohen static void mlxsw_sp_rx_ptp_listener(struct sk_buff *skb, u16 local_port,
19539c10350SIdo Schimmel void *trap_ctx)
19639c10350SIdo Schimmel {
19739c10350SIdo Schimmel struct mlxsw_sp *mlxsw_sp = devlink_trap_ctx_priv(trap_ctx);
19839c10350SIdo Schimmel int err;
19939c10350SIdo Schimmel
20039c10350SIdo Schimmel err = __mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx);
20139c10350SIdo Schimmel if (err)
20239c10350SIdo Schimmel return;
20339c10350SIdo Schimmel
20439c10350SIdo Schimmel /* The PTP handler expects skb->data to point to the start of the
20539c10350SIdo Schimmel * Ethernet header.
20639c10350SIdo Schimmel */
20739c10350SIdo Schimmel skb_push(skb, ETH_HLEN);
20839c10350SIdo Schimmel mlxsw_sp_ptp_receive(mlxsw_sp, skb, local_port);
20939c10350SIdo Schimmel }
21039c10350SIdo Schimmel
2112073c600SIdo Schimmel static struct mlxsw_sp_port *
mlxsw_sp_sample_tx_port_get(struct mlxsw_sp * mlxsw_sp,const struct mlxsw_rx_md_info * rx_md_info)2122073c600SIdo Schimmel mlxsw_sp_sample_tx_port_get(struct mlxsw_sp *mlxsw_sp,
2132073c600SIdo Schimmel const struct mlxsw_rx_md_info *rx_md_info)
2142073c600SIdo Schimmel {
215c934757dSAmit Cohen u16 local_port;
2162073c600SIdo Schimmel
2172073c600SIdo Schimmel if (!rx_md_info->tx_port_valid)
2182073c600SIdo Schimmel return NULL;
2192073c600SIdo Schimmel
2202073c600SIdo Schimmel if (rx_md_info->tx_port_is_lag)
2212073c600SIdo Schimmel local_port = mlxsw_core_lag_mapping_get(mlxsw_sp->core,
2222073c600SIdo Schimmel rx_md_info->tx_lag_id,
2232073c600SIdo Schimmel rx_md_info->tx_lag_port_index);
2242073c600SIdo Schimmel else
2252073c600SIdo Schimmel local_port = rx_md_info->tx_sys_port;
2262073c600SIdo Schimmel
2272073c600SIdo Schimmel if (local_port >= mlxsw_core_max_ports(mlxsw_sp->core))
2282073c600SIdo Schimmel return NULL;
2292073c600SIdo Schimmel
2302073c600SIdo Schimmel return mlxsw_sp->ports[local_port];
2312073c600SIdo Schimmel }
2322073c600SIdo Schimmel
2332073c600SIdo Schimmel /* The latency units are determined according to MOGCR.mirror_latency_units. It
2342073c600SIdo Schimmel * defaults to 64 nanoseconds.
2352073c600SIdo Schimmel */
2362073c600SIdo Schimmel #define MLXSW_SP_MIRROR_LATENCY_SHIFT 6
2372073c600SIdo Schimmel
mlxsw_sp_psample_md_init(struct mlxsw_sp * mlxsw_sp,struct psample_metadata * md,struct sk_buff * skb,int in_ifindex,bool truncate,u32 trunc_size)2382073c600SIdo Schimmel static void mlxsw_sp_psample_md_init(struct mlxsw_sp *mlxsw_sp,
2392073c600SIdo Schimmel struct psample_metadata *md,
2402073c600SIdo Schimmel struct sk_buff *skb, int in_ifindex,
2412073c600SIdo Schimmel bool truncate, u32 trunc_size)
2422073c600SIdo Schimmel {
2432073c600SIdo Schimmel struct mlxsw_rx_md_info *rx_md_info = &mlxsw_skb_cb(skb)->rx_md_info;
2442073c600SIdo Schimmel struct mlxsw_sp_port *mlxsw_sp_port;
2452073c600SIdo Schimmel
2462073c600SIdo Schimmel md->trunc_size = truncate ? trunc_size : skb->len;
2472073c600SIdo Schimmel md->in_ifindex = in_ifindex;
2482073c600SIdo Schimmel mlxsw_sp_port = mlxsw_sp_sample_tx_port_get(mlxsw_sp, rx_md_info);
2492073c600SIdo Schimmel md->out_ifindex = mlxsw_sp_port && mlxsw_sp_port->dev ?
2502073c600SIdo Schimmel mlxsw_sp_port->dev->ifindex : 0;
2512073c600SIdo Schimmel md->out_tc_valid = rx_md_info->tx_tc_valid;
2522073c600SIdo Schimmel md->out_tc = rx_md_info->tx_tc;
2532073c600SIdo Schimmel md->out_tc_occ_valid = rx_md_info->tx_congestion_valid;
2542073c600SIdo Schimmel md->out_tc_occ = rx_md_info->tx_congestion;
2552073c600SIdo Schimmel md->latency_valid = rx_md_info->latency_valid;
2562073c600SIdo Schimmel md->latency = rx_md_info->latency;
2572073c600SIdo Schimmel md->latency <<= MLXSW_SP_MIRROR_LATENCY_SHIFT;
2582073c600SIdo Schimmel }
2592073c600SIdo Schimmel
mlxsw_sp_rx_sample_listener(struct sk_buff * skb,u16 local_port,void * trap_ctx)260c934757dSAmit Cohen static void mlxsw_sp_rx_sample_listener(struct sk_buff *skb, u16 local_port,
26188e27749SIdo Schimmel void *trap_ctx)
26288e27749SIdo Schimmel {
26388e27749SIdo Schimmel struct mlxsw_sp *mlxsw_sp = devlink_trap_ctx_priv(trap_ctx);
26490f53c53SIdo Schimmel struct mlxsw_sp_sample_trigger trigger;
26590f53c53SIdo Schimmel struct mlxsw_sp_sample_params *params;
26648990befSIdo Schimmel struct mlxsw_sp_port *mlxsw_sp_port;
26748990befSIdo Schimmel struct psample_metadata md = {};
26888e27749SIdo Schimmel int err;
26988e27749SIdo Schimmel
27088e27749SIdo Schimmel err = __mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx);
27188e27749SIdo Schimmel if (err)
27288e27749SIdo Schimmel return;
27388e27749SIdo Schimmel
27448990befSIdo Schimmel mlxsw_sp_port = mlxsw_sp->ports[local_port];
27548990befSIdo Schimmel if (!mlxsw_sp_port)
27648990befSIdo Schimmel goto out;
27748990befSIdo Schimmel
27890f53c53SIdo Schimmel trigger.type = MLXSW_SP_SAMPLE_TRIGGER_TYPE_INGRESS;
27990f53c53SIdo Schimmel trigger.local_port = local_port;
28090f53c53SIdo Schimmel params = mlxsw_sp_sample_trigger_params_lookup(mlxsw_sp, &trigger);
28190f53c53SIdo Schimmel if (!params)
28248990befSIdo Schimmel goto out;
28348990befSIdo Schimmel
28448990befSIdo Schimmel /* The psample module expects skb->data to point to the start of the
28588e27749SIdo Schimmel * Ethernet header.
28688e27749SIdo Schimmel */
28788e27749SIdo Schimmel skb_push(skb, ETH_HLEN);
2882073c600SIdo Schimmel mlxsw_sp_psample_md_init(mlxsw_sp, &md, skb,
28990f53c53SIdo Schimmel mlxsw_sp_port->dev->ifindex, params->truncate,
29090f53c53SIdo Schimmel params->trunc_size);
29190f53c53SIdo Schimmel psample_sample_packet(params->psample_group, skb, params->rate, &md);
29248990befSIdo Schimmel out:
29348990befSIdo Schimmel consume_skb(skb);
29488e27749SIdo Schimmel }
29588e27749SIdo Schimmel
mlxsw_sp_rx_sample_tx_listener(struct sk_buff * skb,u16 local_port,void * trap_ctx)296c934757dSAmit Cohen static void mlxsw_sp_rx_sample_tx_listener(struct sk_buff *skb, u16 local_port,
29754d0e963SIdo Schimmel void *trap_ctx)
29854d0e963SIdo Schimmel {
29954d0e963SIdo Schimmel struct mlxsw_rx_md_info *rx_md_info = &mlxsw_skb_cb(skb)->rx_md_info;
30054d0e963SIdo Schimmel struct mlxsw_sp *mlxsw_sp = devlink_trap_ctx_priv(trap_ctx);
30154d0e963SIdo Schimmel struct mlxsw_sp_port *mlxsw_sp_port, *mlxsw_sp_port_tx;
30254d0e963SIdo Schimmel struct mlxsw_sp_sample_trigger trigger;
30354d0e963SIdo Schimmel struct mlxsw_sp_sample_params *params;
30454d0e963SIdo Schimmel struct psample_metadata md = {};
30554d0e963SIdo Schimmel int err;
30654d0e963SIdo Schimmel
30754d0e963SIdo Schimmel /* Locally generated packets are not reported from the policy engine
30854d0e963SIdo Schimmel * trigger, so do not report them from the egress trigger as well.
30954d0e963SIdo Schimmel */
31054d0e963SIdo Schimmel if (local_port == MLXSW_PORT_CPU_PORT)
31154d0e963SIdo Schimmel goto out;
31254d0e963SIdo Schimmel
31354d0e963SIdo Schimmel err = __mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx);
31454d0e963SIdo Schimmel if (err)
31554d0e963SIdo Schimmel return;
31654d0e963SIdo Schimmel
31754d0e963SIdo Schimmel mlxsw_sp_port = mlxsw_sp->ports[local_port];
31854d0e963SIdo Schimmel if (!mlxsw_sp_port)
31954d0e963SIdo Schimmel goto out;
32054d0e963SIdo Schimmel
32154d0e963SIdo Schimmel /* Packet was sampled from Tx, so we need to retrieve the sample
32254d0e963SIdo Schimmel * parameters based on the Tx port and not the Rx port.
32354d0e963SIdo Schimmel */
32454d0e963SIdo Schimmel mlxsw_sp_port_tx = mlxsw_sp_sample_tx_port_get(mlxsw_sp, rx_md_info);
32554d0e963SIdo Schimmel if (!mlxsw_sp_port_tx)
32654d0e963SIdo Schimmel goto out;
32754d0e963SIdo Schimmel
32854d0e963SIdo Schimmel trigger.type = MLXSW_SP_SAMPLE_TRIGGER_TYPE_EGRESS;
32954d0e963SIdo Schimmel trigger.local_port = mlxsw_sp_port_tx->local_port;
33054d0e963SIdo Schimmel params = mlxsw_sp_sample_trigger_params_lookup(mlxsw_sp, &trigger);
33154d0e963SIdo Schimmel if (!params)
33254d0e963SIdo Schimmel goto out;
33354d0e963SIdo Schimmel
33454d0e963SIdo Schimmel /* The psample module expects skb->data to point to the start of the
33554d0e963SIdo Schimmel * Ethernet header.
33654d0e963SIdo Schimmel */
33754d0e963SIdo Schimmel skb_push(skb, ETH_HLEN);
33854d0e963SIdo Schimmel mlxsw_sp_psample_md_init(mlxsw_sp, &md, skb,
33954d0e963SIdo Schimmel mlxsw_sp_port->dev->ifindex, params->truncate,
34054d0e963SIdo Schimmel params->trunc_size);
34154d0e963SIdo Schimmel psample_sample_packet(params->psample_group, skb, params->rate, &md);
34254d0e963SIdo Schimmel out:
34354d0e963SIdo Schimmel consume_skb(skb);
34454d0e963SIdo Schimmel }
34554d0e963SIdo Schimmel
mlxsw_sp_rx_sample_acl_listener(struct sk_buff * skb,u16 local_port,void * trap_ctx)346c934757dSAmit Cohen static void mlxsw_sp_rx_sample_acl_listener(struct sk_buff *skb, u16 local_port,
34745aad0b7SIdo Schimmel void *trap_ctx)
34845aad0b7SIdo Schimmel {
34945aad0b7SIdo Schimmel struct mlxsw_sp *mlxsw_sp = devlink_trap_ctx_priv(trap_ctx);
35045aad0b7SIdo Schimmel struct mlxsw_sp_sample_trigger trigger = {
35145aad0b7SIdo Schimmel .type = MLXSW_SP_SAMPLE_TRIGGER_TYPE_POLICY_ENGINE,
35245aad0b7SIdo Schimmel };
35345aad0b7SIdo Schimmel struct mlxsw_sp_sample_params *params;
35445aad0b7SIdo Schimmel struct mlxsw_sp_port *mlxsw_sp_port;
35545aad0b7SIdo Schimmel struct psample_metadata md = {};
35645aad0b7SIdo Schimmel int err;
35745aad0b7SIdo Schimmel
35845aad0b7SIdo Schimmel err = __mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx);
35945aad0b7SIdo Schimmel if (err)
36045aad0b7SIdo Schimmel return;
36145aad0b7SIdo Schimmel
36245aad0b7SIdo Schimmel mlxsw_sp_port = mlxsw_sp->ports[local_port];
36345aad0b7SIdo Schimmel if (!mlxsw_sp_port)
36445aad0b7SIdo Schimmel goto out;
36545aad0b7SIdo Schimmel
36645aad0b7SIdo Schimmel params = mlxsw_sp_sample_trigger_params_lookup(mlxsw_sp, &trigger);
36745aad0b7SIdo Schimmel if (!params)
36845aad0b7SIdo Schimmel goto out;
36945aad0b7SIdo Schimmel
37045aad0b7SIdo Schimmel /* The psample module expects skb->data to point to the start of the
37145aad0b7SIdo Schimmel * Ethernet header.
37245aad0b7SIdo Schimmel */
37345aad0b7SIdo Schimmel skb_push(skb, ETH_HLEN);
37445aad0b7SIdo Schimmel mlxsw_sp_psample_md_init(mlxsw_sp, &md, skb,
37545aad0b7SIdo Schimmel mlxsw_sp_port->dev->ifindex, params->truncate,
37645aad0b7SIdo Schimmel params->trunc_size);
37745aad0b7SIdo Schimmel psample_sample_packet(params->psample_group, skb, params->rate, &md);
37845aad0b7SIdo Schimmel out:
37945aad0b7SIdo Schimmel consume_skb(skb);
38045aad0b7SIdo Schimmel }
38145aad0b7SIdo Schimmel
382b5ce611fSIdo Schimmel #define MLXSW_SP_TRAP_DROP(_id, _group_id) \
383b5ce611fSIdo Schimmel DEVLINK_TRAP_GENERIC(DROP, DROP, _id, \
384107f1678SIdo Schimmel DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
385b5ce611fSIdo Schimmel MLXSW_SP_TRAP_METADATA)
386b5ce611fSIdo Schimmel
3876de9fceeSJiri Pirko #define MLXSW_SP_TRAP_DROP_EXT(_id, _group_id, _metadata) \
3886de9fceeSJiri Pirko DEVLINK_TRAP_GENERIC(DROP, DROP, _id, \
389107f1678SIdo Schimmel DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
3906de9fceeSJiri Pirko MLXSW_SP_TRAP_METADATA | (_metadata))
3916de9fceeSJiri Pirko
3926687e953SIdo Schimmel #define MLXSW_SP_TRAP_BUFFER_DROP(_id) \
3936687e953SIdo Schimmel DEVLINK_TRAP_GENERIC(DROP, TRAP, _id, \
3946687e953SIdo Schimmel DEVLINK_TRAP_GROUP_GENERIC_ID_BUFFER_DROPS, \
3956687e953SIdo Schimmel MLXSW_SP_TRAP_METADATA)
3966687e953SIdo Schimmel
3975b051621SAmit Cohen #define MLXSW_SP_TRAP_DRIVER_DROP(_id, _group_id) \
3985b051621SAmit Cohen DEVLINK_TRAP_DRIVER(DROP, DROP, DEVLINK_MLXSW_TRAP_ID_##_id, \
3995b051621SAmit Cohen DEVLINK_MLXSW_TRAP_NAME_##_id, \
400107f1678SIdo Schimmel DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
4015b051621SAmit Cohen MLXSW_SP_TRAP_METADATA)
4025b051621SAmit Cohen
403fd74feebSAmit Cohen #define MLXSW_SP_TRAP_EXCEPTION(_id, _group_id) \
404fd74feebSAmit Cohen DEVLINK_TRAP_GENERIC(EXCEPTION, TRAP, _id, \
405107f1678SIdo Schimmel DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
406fd74feebSAmit Cohen MLXSW_SP_TRAP_METADATA)
407fd74feebSAmit Cohen
40839c10350SIdo Schimmel #define MLXSW_SP_TRAP_CONTROL(_id, _group_id, _action) \
40939c10350SIdo Schimmel DEVLINK_TRAP_GENERIC(CONTROL, _action, _id, \
41039c10350SIdo Schimmel DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
41139c10350SIdo Schimmel MLXSW_SP_TRAP_METADATA)
41239c10350SIdo Schimmel
413b5ce611fSIdo Schimmel #define MLXSW_SP_RXL_DISCARD(_id, _group_id) \
41476d4067fSJiri Pirko MLXSW_RXL_DIS(mlxsw_sp_rx_drop_listener, DISCARD_##_id, \
41576d4067fSJiri Pirko TRAP_EXCEPTION_TO_CPU, false, SP_##_group_id, \
416dbd1ddadSJiri Pirko SET_FW_DEFAULT, SP_##_group_id)
417b5ce611fSIdo Schimmel
41845dbee09SJiri Pirko #define MLXSW_SP_RXL_ACL_DISCARD(_id, _en_group_id, _dis_group_id) \
4196de9fceeSJiri Pirko MLXSW_RXL_DIS(mlxsw_sp_rx_acl_drop_listener, DISCARD_##_id, \
42045dbee09SJiri Pirko TRAP_EXCEPTION_TO_CPU, false, SP_##_en_group_id, \
42145dbee09SJiri Pirko SET_FW_DEFAULT, SP_##_dis_group_id)
42245dbee09SJiri Pirko
4236687e953SIdo Schimmel #define MLXSW_SP_RXL_BUFFER_DISCARD(_mirror_reason) \
4246687e953SIdo Schimmel MLXSW_RXL_MIRROR(mlxsw_sp_rx_drop_listener, 0, SP_BUFFER_DISCARDS, \
4256687e953SIdo Schimmel MLXSW_SP_MIRROR_REASON_##_mirror_reason)
4266687e953SIdo Schimmel
427fd74feebSAmit Cohen #define MLXSW_SP_RXL_EXCEPTION(_id, _group_id, _action) \
42845b1c873SIdo Schimmel MLXSW_RXL(mlxsw_sp_rx_mark_listener, _id, \
4291ef658a3SJiri Pirko _action, false, SP_##_group_id, SET_FW_DEFAULT)
430fd74feebSAmit Cohen
43139c10350SIdo Schimmel #define MLXSW_SP_RXL_NO_MARK(_id, _group_id, _action, _is_ctrl) \
43239c10350SIdo Schimmel MLXSW_RXL(mlxsw_sp_rx_no_mark_listener, _id, _action, \
43339c10350SIdo Schimmel _is_ctrl, SP_##_group_id, DISCARD)
43439c10350SIdo Schimmel
43539c10350SIdo Schimmel #define MLXSW_SP_RXL_MARK(_id, _group_id, _action, _is_ctrl) \
43639c10350SIdo Schimmel MLXSW_RXL(mlxsw_sp_rx_mark_listener, _id, _action, _is_ctrl, \
43739c10350SIdo Schimmel SP_##_group_id, DISCARD)
43839c10350SIdo Schimmel
4398110668eSIdo Schimmel #define MLXSW_SP_RXL_L3_MARK(_id, _group_id, _action, _is_ctrl) \
4408110668eSIdo Schimmel MLXSW_RXL(mlxsw_sp_rx_l3_mark_listener, _id, _action, _is_ctrl, \
4418110668eSIdo Schimmel SP_##_group_id, DISCARD)
4428110668eSIdo Schimmel
4434561705bSIdo Schimmel #define MLXSW_SP_TRAP_POLICER(_id, _rate, _burst) \
4444561705bSIdo Schimmel DEVLINK_TRAP_POLICER(_id, _rate, _burst, \
4454561705bSIdo Schimmel MLXSW_REG_QPCR_HIGHEST_CIR, \
4464561705bSIdo Schimmel MLXSW_REG_QPCR_LOWEST_CIR, \
4474561705bSIdo Schimmel 1 << MLXSW_REG_QPCR_HIGHEST_CBS, \
4484561705bSIdo Schimmel 1 << MLXSW_REG_QPCR_LOWEST_CBS)
4494561705bSIdo Schimmel
4504561705bSIdo Schimmel /* Ordered by policer identifier */
451cc678f4dSIdo Schimmel static const struct mlxsw_sp_trap_policer_item
452cc678f4dSIdo Schimmel mlxsw_sp_trap_policer_items_arr[] = {
453cc678f4dSIdo Schimmel {
4547ee0db9dSIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(1, 10 * 1024, 4096),
455cc678f4dSIdo Schimmel },
45639c10350SIdo Schimmel {
45739c10350SIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(2, 128, 128),
45839c10350SIdo Schimmel },
45939c10350SIdo Schimmel {
46039c10350SIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(3, 128, 128),
46139c10350SIdo Schimmel },
46239c10350SIdo Schimmel {
46339c10350SIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(4, 128, 128),
46439c10350SIdo Schimmel },
46539c10350SIdo Schimmel {
4667ee0db9dSIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(5, 16 * 1024, 8192),
46739c10350SIdo Schimmel },
4688110668eSIdo Schimmel {
4698110668eSIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(6, 128, 128),
4708110668eSIdo Schimmel },
4718110668eSIdo Schimmel {
4727ee0db9dSIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(7, 1024, 512),
4738110668eSIdo Schimmel },
4748110668eSIdo Schimmel {
4757ee0db9dSIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(8, 20 * 1024, 8192),
4768110668eSIdo Schimmel },
4778110668eSIdo Schimmel {
4788110668eSIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(9, 128, 128),
4798110668eSIdo Schimmel },
4808110668eSIdo Schimmel {
4817ee0db9dSIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(10, 1024, 512),
4828110668eSIdo Schimmel },
4838110668eSIdo Schimmel {
4847ee0db9dSIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(11, 256, 128),
4858110668eSIdo Schimmel },
4868110668eSIdo Schimmel {
4878110668eSIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(12, 128, 128),
4888110668eSIdo Schimmel },
4898110668eSIdo Schimmel {
4908110668eSIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(13, 128, 128),
4918110668eSIdo Schimmel },
4928110668eSIdo Schimmel {
4937ee0db9dSIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(14, 1024, 512),
4948110668eSIdo Schimmel },
4958110668eSIdo Schimmel {
4967ee0db9dSIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(15, 1024, 512),
4978110668eSIdo Schimmel },
4988110668eSIdo Schimmel {
4997ee0db9dSIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(16, 24 * 1024, 16384),
5008110668eSIdo Schimmel },
5018110668eSIdo Schimmel {
5027ee0db9dSIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(17, 19 * 1024, 8192),
5038110668eSIdo Schimmel },
50488e27749SIdo Schimmel {
5057ee0db9dSIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(18, 1024, 512),
50688e27749SIdo Schimmel },
507ec4f5b36SIdo Schimmel {
508ec4f5b36SIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(19, 1024, 512),
509ec4f5b36SIdo Schimmel },
5106687e953SIdo Schimmel {
5116687e953SIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(20, 10240, 4096),
5126687e953SIdo Schimmel },
513*d85be0f5SIdo Schimmel {
514*d85be0f5SIdo Schimmel .policer = MLXSW_SP_TRAP_POLICER(21, 128, 128),
515*d85be0f5SIdo Schimmel },
5164561705bSIdo Schimmel };
5174561705bSIdo Schimmel
518b14a40dbSIdo Schimmel static const struct mlxsw_sp_trap_group_item mlxsw_sp_trap_group_items_arr[] = {
519b14a40dbSIdo Schimmel {
520b14a40dbSIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS, 1),
521b14a40dbSIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_L2_DISCARDS,
522b14a40dbSIdo Schimmel .priority = 0,
523b14a40dbSIdo Schimmel },
524b14a40dbSIdo Schimmel {
525b14a40dbSIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(L3_DROPS, 1),
526b14a40dbSIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_L3_DISCARDS,
527b14a40dbSIdo Schimmel .priority = 0,
528b14a40dbSIdo Schimmel },
529b14a40dbSIdo Schimmel {
5301e292f5cSIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(L3_EXCEPTIONS, 1),
5311e292f5cSIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_L3_EXCEPTIONS,
5321e292f5cSIdo Schimmel .priority = 2,
5331e292f5cSIdo Schimmel },
5341e292f5cSIdo Schimmel {
535b14a40dbSIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(TUNNEL_DROPS, 1),
536b14a40dbSIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_TUNNEL_DISCARDS,
537b14a40dbSIdo Schimmel .priority = 0,
538b14a40dbSIdo Schimmel },
539b14a40dbSIdo Schimmel {
540b14a40dbSIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(ACL_DROPS, 1),
541b14a40dbSIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_ACL_DISCARDS,
542b14a40dbSIdo Schimmel .priority = 0,
543b14a40dbSIdo Schimmel },
54439c10350SIdo Schimmel {
54539c10350SIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(STP, 2),
54639c10350SIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_STP,
54739c10350SIdo Schimmel .priority = 5,
54839c10350SIdo Schimmel },
54939c10350SIdo Schimmel {
55039c10350SIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(LACP, 3),
55139c10350SIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_LACP,
55239c10350SIdo Schimmel .priority = 5,
55339c10350SIdo Schimmel },
55439c10350SIdo Schimmel {
55539c10350SIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(LLDP, 4),
55639c10350SIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_LLDP,
55739c10350SIdo Schimmel .priority = 5,
55839c10350SIdo Schimmel },
55939c10350SIdo Schimmel {
56039c10350SIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(MC_SNOOPING, 5),
56139c10350SIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_MC_SNOOPING,
56239c10350SIdo Schimmel .priority = 3,
56339c10350SIdo Schimmel },
5648110668eSIdo Schimmel {
5658110668eSIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(DHCP, 6),
5668110668eSIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_DHCP,
5678110668eSIdo Schimmel .priority = 2,
5688110668eSIdo Schimmel },
5698110668eSIdo Schimmel {
5708110668eSIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(NEIGH_DISCOVERY, 7),
5718110668eSIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_NEIGH_DISCOVERY,
5728110668eSIdo Schimmel .priority = 2,
5738110668eSIdo Schimmel },
5748110668eSIdo Schimmel {
5758110668eSIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(BFD, 8),
5768110668eSIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_BFD,
5778110668eSIdo Schimmel .priority = 5,
5788110668eSIdo Schimmel },
5798110668eSIdo Schimmel {
5808110668eSIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(OSPF, 9),
5818110668eSIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF,
5828110668eSIdo Schimmel .priority = 5,
5838110668eSIdo Schimmel },
5848110668eSIdo Schimmel {
5858110668eSIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(BGP, 10),
5868110668eSIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_BGP,
5878110668eSIdo Schimmel .priority = 4,
5888110668eSIdo Schimmel },
5898110668eSIdo Schimmel {
5908110668eSIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(VRRP, 11),
5918110668eSIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_VRRP,
5928110668eSIdo Schimmel .priority = 5,
5938110668eSIdo Schimmel },
5948110668eSIdo Schimmel {
5958110668eSIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(PIM, 12),
5968110668eSIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_PIM,
5978110668eSIdo Schimmel .priority = 5,
5988110668eSIdo Schimmel },
5998110668eSIdo Schimmel {
6008110668eSIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(UC_LB, 13),
6018110668eSIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_LBERROR,
6028110668eSIdo Schimmel .priority = 0,
6038110668eSIdo Schimmel },
6048110668eSIdo Schimmel {
6058110668eSIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(LOCAL_DELIVERY, 14),
6068110668eSIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_IP2ME,
6078110668eSIdo Schimmel .priority = 2,
6088110668eSIdo Schimmel },
6098110668eSIdo Schimmel {
610ec4f5b36SIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(EXTERNAL_DELIVERY, 19),
611ec4f5b36SIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_EXTERNAL_ROUTE,
612ec4f5b36SIdo Schimmel .priority = 1,
613ec4f5b36SIdo Schimmel },
614ec4f5b36SIdo Schimmel {
6158110668eSIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(IPV6, 15),
6168110668eSIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_IPV6,
6178110668eSIdo Schimmel .priority = 2,
6188110668eSIdo Schimmel },
6198110668eSIdo Schimmel {
6208110668eSIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(PTP_EVENT, 16),
6218110668eSIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP0,
6228110668eSIdo Schimmel .priority = 5,
6238110668eSIdo Schimmel },
6248110668eSIdo Schimmel {
6258110668eSIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(PTP_GENERAL, 17),
6268110668eSIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP1,
6278110668eSIdo Schimmel .priority = 2,
6288110668eSIdo Schimmel },
62988e27749SIdo Schimmel {
63088e27749SIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(ACL_TRAP, 18),
63188e27749SIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_FLOW_LOGGING,
63288e27749SIdo Schimmel .priority = 4,
63388e27749SIdo Schimmel },
634*d85be0f5SIdo Schimmel {
635*d85be0f5SIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(EAPOL, 21),
636*d85be0f5SIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_EAPOL,
637*d85be0f5SIdo Schimmel .priority = 5,
638*d85be0f5SIdo Schimmel },
6398cd999e4SIdo Schimmel };
6408cd999e4SIdo Schimmel
641200b7ccaSIdo Schimmel static const struct mlxsw_sp_trap_item mlxsw_sp_trap_items_arr[] = {
642200b7ccaSIdo Schimmel {
643200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DROP(SMAC_MC, L2_DROPS),
644200b7ccaSIdo Schimmel .listeners_arr = {
645b5ce611fSIdo Schimmel MLXSW_SP_RXL_DISCARD(ING_PACKET_SMAC_MC, L2_DISCARDS),
646200b7ccaSIdo Schimmel },
647200b7ccaSIdo Schimmel },
648200b7ccaSIdo Schimmel {
649200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DROP(VLAN_TAG_MISMATCH, L2_DROPS),
650200b7ccaSIdo Schimmel .listeners_arr = {
651200b7ccaSIdo Schimmel MLXSW_SP_RXL_DISCARD(ING_SWITCH_VTAG_ALLOW,
652200b7ccaSIdo Schimmel L2_DISCARDS),
653200b7ccaSIdo Schimmel },
654200b7ccaSIdo Schimmel },
655200b7ccaSIdo Schimmel {
656200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DROP(INGRESS_VLAN_FILTER, L2_DROPS),
657200b7ccaSIdo Schimmel .listeners_arr = {
658b5ce611fSIdo Schimmel MLXSW_SP_RXL_DISCARD(ING_SWITCH_VLAN, L2_DISCARDS),
659200b7ccaSIdo Schimmel },
660200b7ccaSIdo Schimmel },
661200b7ccaSIdo Schimmel {
662200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DROP(INGRESS_STP_FILTER, L2_DROPS),
663200b7ccaSIdo Schimmel .listeners_arr = {
664b5ce611fSIdo Schimmel MLXSW_SP_RXL_DISCARD(ING_SWITCH_STP, L2_DISCARDS),
665200b7ccaSIdo Schimmel },
666200b7ccaSIdo Schimmel },
667200b7ccaSIdo Schimmel {
668200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DROP(EMPTY_TX_LIST, L2_DROPS),
669200b7ccaSIdo Schimmel .listeners_arr = {
670b5ce611fSIdo Schimmel MLXSW_SP_RXL_DISCARD(LOOKUP_SWITCH_UC, L2_DISCARDS),
671b5ce611fSIdo Schimmel MLXSW_SP_RXL_DISCARD(LOOKUP_SWITCH_MC_NULL, L2_DISCARDS),
672200b7ccaSIdo Schimmel },
673200b7ccaSIdo Schimmel },
674200b7ccaSIdo Schimmel {
675200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DROP(PORT_LOOPBACK_FILTER, L2_DROPS),
676200b7ccaSIdo Schimmel .listeners_arr = {
677b5ce611fSIdo Schimmel MLXSW_SP_RXL_DISCARD(LOOKUP_SWITCH_LB, L2_DISCARDS),
678200b7ccaSIdo Schimmel },
679200b7ccaSIdo Schimmel },
680200b7ccaSIdo Schimmel {
681200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DROP(BLACKHOLE_ROUTE, L3_DROPS),
682200b7ccaSIdo Schimmel .listeners_arr = {
683dbc684f1SAmit Cohen MLXSW_SP_RXL_DISCARD(ROUTER2, L3_DISCARDS),
684200b7ccaSIdo Schimmel },
685200b7ccaSIdo Schimmel },
686200b7ccaSIdo Schimmel {
687200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DROP(NON_IP_PACKET, L3_DROPS),
688200b7ccaSIdo Schimmel .listeners_arr = {
689200b7ccaSIdo Schimmel MLXSW_SP_RXL_DISCARD(ING_ROUTER_NON_IP_PACKET,
690200b7ccaSIdo Schimmel L3_DISCARDS),
691200b7ccaSIdo Schimmel },
692200b7ccaSIdo Schimmel },
693200b7ccaSIdo Schimmel {
694200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DROP(UC_DIP_MC_DMAC, L3_DROPS),
695200b7ccaSIdo Schimmel .listeners_arr = {
696200b7ccaSIdo Schimmel MLXSW_SP_RXL_DISCARD(ING_ROUTER_UC_DIP_MC_DMAC,
697200b7ccaSIdo Schimmel L3_DISCARDS),
698200b7ccaSIdo Schimmel },
699200b7ccaSIdo Schimmel },
700200b7ccaSIdo Schimmel {
701200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DROP(DIP_LB, L3_DROPS),
702200b7ccaSIdo Schimmel .listeners_arr = {
703dbc684f1SAmit Cohen MLXSW_SP_RXL_DISCARD(ING_ROUTER_DIP_LB, L3_DISCARDS),
704200b7ccaSIdo Schimmel },
705200b7ccaSIdo Schimmel },
706200b7ccaSIdo Schimmel {
707200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DROP(SIP_MC, L3_DROPS),
708200b7ccaSIdo Schimmel .listeners_arr = {
709dbc684f1SAmit Cohen MLXSW_SP_RXL_DISCARD(ING_ROUTER_SIP_MC, L3_DISCARDS),
710200b7ccaSIdo Schimmel },
711200b7ccaSIdo Schimmel },
712200b7ccaSIdo Schimmel {
713200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DROP(SIP_LB, L3_DROPS),
714200b7ccaSIdo Schimmel .listeners_arr = {
715dbc684f1SAmit Cohen MLXSW_SP_RXL_DISCARD(ING_ROUTER_SIP_LB, L3_DISCARDS),
716200b7ccaSIdo Schimmel },
717200b7ccaSIdo Schimmel },
718200b7ccaSIdo Schimmel {
719200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DROP(CORRUPTED_IP_HDR, L3_DROPS),
720200b7ccaSIdo Schimmel .listeners_arr = {
721200b7ccaSIdo Schimmel MLXSW_SP_RXL_DISCARD(ING_ROUTER_CORRUPTED_IP_HDR,
722200b7ccaSIdo Schimmel L3_DISCARDS),
723200b7ccaSIdo Schimmel },
724200b7ccaSIdo Schimmel },
725200b7ccaSIdo Schimmel {
726200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DROP(IPV4_SIP_BC, L3_DROPS),
727200b7ccaSIdo Schimmel .listeners_arr = {
728200b7ccaSIdo Schimmel MLXSW_SP_RXL_DISCARD(ING_ROUTER_IPV4_SIP_BC,
729200b7ccaSIdo Schimmel L3_DISCARDS),
730200b7ccaSIdo Schimmel },
731200b7ccaSIdo Schimmel },
732200b7ccaSIdo Schimmel {
733200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DROP(IPV6_MC_DIP_RESERVED_SCOPE,
734200b7ccaSIdo Schimmel L3_DROPS),
735200b7ccaSIdo Schimmel .listeners_arr = {
736200b7ccaSIdo Schimmel MLXSW_SP_RXL_DISCARD(IPV6_MC_DIP_RESERVED_SCOPE,
737200b7ccaSIdo Schimmel L3_DISCARDS),
738200b7ccaSIdo Schimmel },
739200b7ccaSIdo Schimmel },
740200b7ccaSIdo Schimmel {
741200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DROP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE,
742200b7ccaSIdo Schimmel L3_DROPS),
743200b7ccaSIdo Schimmel .listeners_arr = {
744200b7ccaSIdo Schimmel MLXSW_SP_RXL_DISCARD(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE,
745200b7ccaSIdo Schimmel L3_DISCARDS),
746200b7ccaSIdo Schimmel },
747200b7ccaSIdo Schimmel },
748200b7ccaSIdo Schimmel {
7491e292f5cSIdo Schimmel .trap = MLXSW_SP_TRAP_EXCEPTION(MTU_ERROR, L3_EXCEPTIONS),
750200b7ccaSIdo Schimmel .listeners_arr = {
7511e292f5cSIdo Schimmel MLXSW_SP_RXL_EXCEPTION(MTUERROR, L3_EXCEPTIONS,
752200b7ccaSIdo Schimmel TRAP_TO_CPU),
753200b7ccaSIdo Schimmel },
754200b7ccaSIdo Schimmel },
755200b7ccaSIdo Schimmel {
7561e292f5cSIdo Schimmel .trap = MLXSW_SP_TRAP_EXCEPTION(TTL_ERROR, L3_EXCEPTIONS),
757200b7ccaSIdo Schimmel .listeners_arr = {
7581e292f5cSIdo Schimmel MLXSW_SP_RXL_EXCEPTION(TTLERROR, L3_EXCEPTIONS,
759200b7ccaSIdo Schimmel TRAP_TO_CPU),
760200b7ccaSIdo Schimmel },
761200b7ccaSIdo Schimmel },
762200b7ccaSIdo Schimmel {
7631e292f5cSIdo Schimmel .trap = MLXSW_SP_TRAP_EXCEPTION(RPF, L3_EXCEPTIONS),
764200b7ccaSIdo Schimmel .listeners_arr = {
7651e292f5cSIdo Schimmel MLXSW_SP_RXL_EXCEPTION(RPF, L3_EXCEPTIONS, TRAP_TO_CPU),
766200b7ccaSIdo Schimmel },
767200b7ccaSIdo Schimmel },
768200b7ccaSIdo Schimmel {
7691e292f5cSIdo Schimmel .trap = MLXSW_SP_TRAP_EXCEPTION(REJECT_ROUTE, L3_EXCEPTIONS),
770200b7ccaSIdo Schimmel .listeners_arr = {
7711e292f5cSIdo Schimmel MLXSW_SP_RXL_EXCEPTION(RTR_INGRESS1, L3_EXCEPTIONS,
772200b7ccaSIdo Schimmel TRAP_TO_CPU),
773200b7ccaSIdo Schimmel },
774200b7ccaSIdo Schimmel },
775200b7ccaSIdo Schimmel {
7761e292f5cSIdo Schimmel .trap = MLXSW_SP_TRAP_EXCEPTION(UNRESOLVED_NEIGH,
7771e292f5cSIdo Schimmel L3_EXCEPTIONS),
778200b7ccaSIdo Schimmel .listeners_arr = {
7791e292f5cSIdo Schimmel MLXSW_SP_RXL_EXCEPTION(HOST_MISS_IPV4, L3_EXCEPTIONS,
780200b7ccaSIdo Schimmel TRAP_TO_CPU),
7811e292f5cSIdo Schimmel MLXSW_SP_RXL_EXCEPTION(HOST_MISS_IPV6, L3_EXCEPTIONS,
782200b7ccaSIdo Schimmel TRAP_TO_CPU),
78352d45575SIdo Schimmel MLXSW_SP_RXL_EXCEPTION(RTR_EGRESS0, L3_EXCEPTIONS,
784fd74feebSAmit Cohen TRAP_EXCEPTION_TO_CPU),
785200b7ccaSIdo Schimmel },
786200b7ccaSIdo Schimmel },
787200b7ccaSIdo Schimmel {
788200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_EXCEPTION(IPV4_LPM_UNICAST_MISS,
7891e292f5cSIdo Schimmel L3_EXCEPTIONS),
790200b7ccaSIdo Schimmel .listeners_arr = {
7911e292f5cSIdo Schimmel MLXSW_SP_RXL_EXCEPTION(DISCARD_ROUTER_LPM4,
7921e292f5cSIdo Schimmel L3_EXCEPTIONS,
793fd74feebSAmit Cohen TRAP_EXCEPTION_TO_CPU),
794200b7ccaSIdo Schimmel },
795200b7ccaSIdo Schimmel },
796200b7ccaSIdo Schimmel {
797200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_EXCEPTION(IPV6_LPM_UNICAST_MISS,
7981e292f5cSIdo Schimmel L3_EXCEPTIONS),
799200b7ccaSIdo Schimmel .listeners_arr = {
8001e292f5cSIdo Schimmel MLXSW_SP_RXL_EXCEPTION(DISCARD_ROUTER_LPM6,
8011e292f5cSIdo Schimmel L3_EXCEPTIONS,
802fd74feebSAmit Cohen TRAP_EXCEPTION_TO_CPU),
803200b7ccaSIdo Schimmel },
804200b7ccaSIdo Schimmel },
805200b7ccaSIdo Schimmel {
806200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DRIVER_DROP(IRIF_DISABLED, L3_DROPS),
807200b7ccaSIdo Schimmel .listeners_arr = {
8085b051621SAmit Cohen MLXSW_SP_RXL_DISCARD(ROUTER_IRIF_EN, L3_DISCARDS),
809200b7ccaSIdo Schimmel },
810200b7ccaSIdo Schimmel },
811200b7ccaSIdo Schimmel {
812200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DRIVER_DROP(ERIF_DISABLED, L3_DROPS),
813200b7ccaSIdo Schimmel .listeners_arr = {
8145b051621SAmit Cohen MLXSW_SP_RXL_DISCARD(ROUTER_ERIF_EN, L3_DISCARDS),
815200b7ccaSIdo Schimmel },
816200b7ccaSIdo Schimmel },
817200b7ccaSIdo Schimmel {
818200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DROP(NON_ROUTABLE, L3_DROPS),
819200b7ccaSIdo Schimmel .listeners_arr = {
820196442ecSAmit Cohen MLXSW_SP_RXL_DISCARD(NON_ROUTABLE, L3_DISCARDS),
821200b7ccaSIdo Schimmel },
822200b7ccaSIdo Schimmel },
823200b7ccaSIdo Schimmel {
824200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_EXCEPTION(DECAP_ERROR, TUNNEL_DROPS),
825200b7ccaSIdo Schimmel .listeners_arr = {
826d12d8468SIdo Schimmel MLXSW_SP_RXL_EXCEPTION(DECAP_ECN0, TUNNEL_DISCARDS,
827d12d8468SIdo Schimmel TRAP_EXCEPTION_TO_CPU),
828200b7ccaSIdo Schimmel MLXSW_SP_RXL_EXCEPTION(IPIP_DECAP_ERROR,
829200b7ccaSIdo Schimmel TUNNEL_DISCARDS,
830a318bf62SAmit Cohen TRAP_EXCEPTION_TO_CPU),
831a318bf62SAmit Cohen MLXSW_SP_RXL_EXCEPTION(DISCARD_DEC_PKT, TUNNEL_DISCARDS,
832a318bf62SAmit Cohen TRAP_EXCEPTION_TO_CPU),
833200b7ccaSIdo Schimmel },
834200b7ccaSIdo Schimmel },
835200b7ccaSIdo Schimmel {
836200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DROP(OVERLAY_SMAC_MC, TUNNEL_DROPS),
837200b7ccaSIdo Schimmel .listeners_arr = {
8383aed0722SAmit Cohen MLXSW_SP_RXL_DISCARD(OVERLAY_SMAC_MC, TUNNEL_DISCARDS),
839200b7ccaSIdo Schimmel },
840200b7ccaSIdo Schimmel },
841200b7ccaSIdo Schimmel {
842200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DROP_EXT(INGRESS_FLOW_ACTION_DROP,
843200b7ccaSIdo Schimmel ACL_DROPS,
844200b7ccaSIdo Schimmel DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE),
845200b7ccaSIdo Schimmel .listeners_arr = {
846200b7ccaSIdo Schimmel MLXSW_SP_RXL_ACL_DISCARD(INGRESS_ACL, ACL_DISCARDS,
847200b7ccaSIdo Schimmel DUMMY),
848200b7ccaSIdo Schimmel },
849200b7ccaSIdo Schimmel },
850200b7ccaSIdo Schimmel {
851200b7ccaSIdo Schimmel .trap = MLXSW_SP_TRAP_DROP_EXT(EGRESS_FLOW_ACTION_DROP,
852200b7ccaSIdo Schimmel ACL_DROPS,
853200b7ccaSIdo Schimmel DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE),
854200b7ccaSIdo Schimmel .listeners_arr = {
855200b7ccaSIdo Schimmel MLXSW_SP_RXL_ACL_DISCARD(EGRESS_ACL, ACL_DISCARDS,
856200b7ccaSIdo Schimmel DUMMY),
857200b7ccaSIdo Schimmel },
858200b7ccaSIdo Schimmel },
85939c10350SIdo Schimmel {
86039c10350SIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(STP, STP, TRAP),
86139c10350SIdo Schimmel .listeners_arr = {
86239c10350SIdo Schimmel MLXSW_SP_RXL_NO_MARK(STP, STP, TRAP_TO_CPU, true),
86339c10350SIdo Schimmel },
86439c10350SIdo Schimmel },
86539c10350SIdo Schimmel {
86639c10350SIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(LACP, LACP, TRAP),
86739c10350SIdo Schimmel .listeners_arr = {
86839c10350SIdo Schimmel MLXSW_SP_RXL_NO_MARK(LACP, LACP, TRAP_TO_CPU, true),
86939c10350SIdo Schimmel },
87039c10350SIdo Schimmel },
87139c10350SIdo Schimmel {
87239c10350SIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(LLDP, LLDP, TRAP),
87339c10350SIdo Schimmel .listeners_arr = {
87439c10350SIdo Schimmel MLXSW_RXL(mlxsw_sp_rx_ptp_listener, LLDP, TRAP_TO_CPU,
8750106668cSPetr Machata true, SP_LLDP, DISCARD),
87639c10350SIdo Schimmel },
87739c10350SIdo Schimmel },
87839c10350SIdo Schimmel {
87939c10350SIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IGMP_QUERY, MC_SNOOPING, MIRROR),
88039c10350SIdo Schimmel .listeners_arr = {
88139c10350SIdo Schimmel MLXSW_SP_RXL_MARK(IGMP_QUERY, MC_SNOOPING,
88239c10350SIdo Schimmel MIRROR_TO_CPU, false),
88339c10350SIdo Schimmel },
88439c10350SIdo Schimmel },
88539c10350SIdo Schimmel {
88639c10350SIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IGMP_V1_REPORT, MC_SNOOPING,
88739c10350SIdo Schimmel TRAP),
88839c10350SIdo Schimmel .listeners_arr = {
88939c10350SIdo Schimmel MLXSW_SP_RXL_NO_MARK(IGMP_V1_REPORT, MC_SNOOPING,
89039c10350SIdo Schimmel TRAP_TO_CPU, false),
89139c10350SIdo Schimmel },
89239c10350SIdo Schimmel },
89339c10350SIdo Schimmel {
89439c10350SIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IGMP_V2_REPORT, MC_SNOOPING,
89539c10350SIdo Schimmel TRAP),
89639c10350SIdo Schimmel .listeners_arr = {
89739c10350SIdo Schimmel MLXSW_SP_RXL_NO_MARK(IGMP_V2_REPORT, MC_SNOOPING,
89839c10350SIdo Schimmel TRAP_TO_CPU, false),
89939c10350SIdo Schimmel },
90039c10350SIdo Schimmel },
90139c10350SIdo Schimmel {
90239c10350SIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IGMP_V3_REPORT, MC_SNOOPING,
90339c10350SIdo Schimmel TRAP),
90439c10350SIdo Schimmel .listeners_arr = {
90539c10350SIdo Schimmel MLXSW_SP_RXL_NO_MARK(IGMP_V3_REPORT, MC_SNOOPING,
90639c10350SIdo Schimmel TRAP_TO_CPU, false),
90739c10350SIdo Schimmel },
90839c10350SIdo Schimmel },
90939c10350SIdo Schimmel {
91039c10350SIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IGMP_V2_LEAVE, MC_SNOOPING,
91139c10350SIdo Schimmel TRAP),
91239c10350SIdo Schimmel .listeners_arr = {
91339c10350SIdo Schimmel MLXSW_SP_RXL_NO_MARK(IGMP_V2_LEAVE, MC_SNOOPING,
91439c10350SIdo Schimmel TRAP_TO_CPU, false),
91539c10350SIdo Schimmel },
91639c10350SIdo Schimmel },
91739c10350SIdo Schimmel {
91839c10350SIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(MLD_QUERY, MC_SNOOPING, MIRROR),
91939c10350SIdo Schimmel .listeners_arr = {
92039c10350SIdo Schimmel MLXSW_SP_RXL_MARK(IPV6_MLDV12_LISTENER_QUERY,
92139c10350SIdo Schimmel MC_SNOOPING, MIRROR_TO_CPU, false),
92239c10350SIdo Schimmel },
92339c10350SIdo Schimmel },
92439c10350SIdo Schimmel {
92539c10350SIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(MLD_V1_REPORT, MC_SNOOPING,
92639c10350SIdo Schimmel TRAP),
92739c10350SIdo Schimmel .listeners_arr = {
92839c10350SIdo Schimmel MLXSW_SP_RXL_NO_MARK(IPV6_MLDV1_LISTENER_REPORT,
92939c10350SIdo Schimmel MC_SNOOPING, TRAP_TO_CPU, false),
93039c10350SIdo Schimmel },
93139c10350SIdo Schimmel },
93239c10350SIdo Schimmel {
93339c10350SIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(MLD_V2_REPORT, MC_SNOOPING,
93439c10350SIdo Schimmel TRAP),
93539c10350SIdo Schimmel .listeners_arr = {
93639c10350SIdo Schimmel MLXSW_SP_RXL_NO_MARK(IPV6_MLDV2_LISTENER_REPORT,
93739c10350SIdo Schimmel MC_SNOOPING, TRAP_TO_CPU, false),
93839c10350SIdo Schimmel },
93939c10350SIdo Schimmel },
94039c10350SIdo Schimmel {
94139c10350SIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(MLD_V1_DONE, MC_SNOOPING,
94239c10350SIdo Schimmel TRAP),
94339c10350SIdo Schimmel .listeners_arr = {
94439c10350SIdo Schimmel MLXSW_SP_RXL_NO_MARK(IPV6_MLDV1_LISTENER_DONE,
94539c10350SIdo Schimmel MC_SNOOPING, TRAP_TO_CPU, false),
94639c10350SIdo Schimmel },
94739c10350SIdo Schimmel },
9488110668eSIdo Schimmel {
9498110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV4_DHCP, DHCP, TRAP),
9508110668eSIdo Schimmel .listeners_arr = {
9518110668eSIdo Schimmel MLXSW_SP_RXL_MARK(IPV4_DHCP, DHCP, TRAP_TO_CPU, false),
9528110668eSIdo Schimmel },
9538110668eSIdo Schimmel },
9548110668eSIdo Schimmel {
9558110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV6_DHCP, DHCP, TRAP),
9568110668eSIdo Schimmel .listeners_arr = {
9578110668eSIdo Schimmel MLXSW_SP_RXL_MARK(IPV6_DHCP, DHCP, TRAP_TO_CPU, false),
9588110668eSIdo Schimmel },
9598110668eSIdo Schimmel },
9608110668eSIdo Schimmel {
9618110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(ARP_REQUEST, NEIGH_DISCOVERY,
9628110668eSIdo Schimmel MIRROR),
9638110668eSIdo Schimmel .listeners_arr = {
9644b1cc357SAmit Cohen MLXSW_SP_RXL_MARK(ROUTER_ARPBC, NEIGH_DISCOVERY,
9654b1cc357SAmit Cohen TRAP_TO_CPU, false),
9668110668eSIdo Schimmel },
9678110668eSIdo Schimmel },
9688110668eSIdo Schimmel {
9698110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(ARP_RESPONSE, NEIGH_DISCOVERY,
9708110668eSIdo Schimmel MIRROR),
9718110668eSIdo Schimmel .listeners_arr = {
9724b1cc357SAmit Cohen MLXSW_SP_RXL_MARK(ROUTER_ARPUC, NEIGH_DISCOVERY,
9734b1cc357SAmit Cohen TRAP_TO_CPU, false),
9748110668eSIdo Schimmel },
9758110668eSIdo Schimmel },
9768110668eSIdo Schimmel {
9778110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(ARP_OVERLAY, NEIGH_DISCOVERY,
9788110668eSIdo Schimmel TRAP),
9798110668eSIdo Schimmel .listeners_arr = {
9808110668eSIdo Schimmel MLXSW_SP_RXL_NO_MARK(NVE_DECAP_ARP, NEIGH_DISCOVERY,
9818110668eSIdo Schimmel TRAP_TO_CPU, false),
9828110668eSIdo Schimmel },
9838110668eSIdo Schimmel },
9848110668eSIdo Schimmel {
9858110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV6_NEIGH_SOLICIT,
9868110668eSIdo Schimmel NEIGH_DISCOVERY, TRAP),
9878110668eSIdo Schimmel .listeners_arr = {
9888110668eSIdo Schimmel MLXSW_SP_RXL_MARK(L3_IPV6_NEIGHBOR_SOLICITATION,
9898110668eSIdo Schimmel NEIGH_DISCOVERY, TRAP_TO_CPU, false),
9908110668eSIdo Schimmel },
9918110668eSIdo Schimmel },
9928110668eSIdo Schimmel {
9938110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV6_NEIGH_ADVERT,
9948110668eSIdo Schimmel NEIGH_DISCOVERY, TRAP),
9958110668eSIdo Schimmel .listeners_arr = {
9968110668eSIdo Schimmel MLXSW_SP_RXL_MARK(L3_IPV6_NEIGHBOR_ADVERTISEMENT,
9978110668eSIdo Schimmel NEIGH_DISCOVERY, TRAP_TO_CPU, false),
9988110668eSIdo Schimmel },
9998110668eSIdo Schimmel },
10008110668eSIdo Schimmel {
10018110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV4_BFD, BFD, TRAP),
10028110668eSIdo Schimmel .listeners_arr = {
10038110668eSIdo Schimmel MLXSW_SP_RXL_MARK(IPV4_BFD, BFD, TRAP_TO_CPU, false),
10048110668eSIdo Schimmel },
10058110668eSIdo Schimmel },
10068110668eSIdo Schimmel {
10078110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV6_BFD, BFD, TRAP),
10088110668eSIdo Schimmel .listeners_arr = {
10098110668eSIdo Schimmel MLXSW_SP_RXL_MARK(IPV6_BFD, BFD, TRAP_TO_CPU, false),
10108110668eSIdo Schimmel },
10118110668eSIdo Schimmel },
10128110668eSIdo Schimmel {
10138110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV4_OSPF, OSPF, TRAP),
10148110668eSIdo Schimmel .listeners_arr = {
10158110668eSIdo Schimmel MLXSW_SP_RXL_MARK(IPV4_OSPF, OSPF, TRAP_TO_CPU, false),
10168110668eSIdo Schimmel },
10178110668eSIdo Schimmel },
10188110668eSIdo Schimmel {
10198110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV6_OSPF, OSPF, TRAP),
10208110668eSIdo Schimmel .listeners_arr = {
10218110668eSIdo Schimmel MLXSW_SP_RXL_MARK(IPV6_OSPF, OSPF, TRAP_TO_CPU, false),
10228110668eSIdo Schimmel },
10238110668eSIdo Schimmel },
10248110668eSIdo Schimmel {
10258110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV4_BGP, BGP, TRAP),
10268110668eSIdo Schimmel .listeners_arr = {
10278110668eSIdo Schimmel MLXSW_SP_RXL_MARK(IPV4_BGP, BGP, TRAP_TO_CPU, false),
10288110668eSIdo Schimmel },
10298110668eSIdo Schimmel },
10308110668eSIdo Schimmel {
10318110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV6_BGP, BGP, TRAP),
10328110668eSIdo Schimmel .listeners_arr = {
10338110668eSIdo Schimmel MLXSW_SP_RXL_MARK(IPV6_BGP, BGP, TRAP_TO_CPU, false),
10348110668eSIdo Schimmel },
10358110668eSIdo Schimmel },
10368110668eSIdo Schimmel {
10378110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV4_VRRP, VRRP, TRAP),
10388110668eSIdo Schimmel .listeners_arr = {
10398110668eSIdo Schimmel MLXSW_SP_RXL_MARK(IPV4_VRRP, VRRP, TRAP_TO_CPU, false),
10408110668eSIdo Schimmel },
10418110668eSIdo Schimmel },
10428110668eSIdo Schimmel {
10438110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV6_VRRP, VRRP, TRAP),
10448110668eSIdo Schimmel .listeners_arr = {
10458110668eSIdo Schimmel MLXSW_SP_RXL_MARK(IPV6_VRRP, VRRP, TRAP_TO_CPU, false),
10468110668eSIdo Schimmel },
10478110668eSIdo Schimmel },
10488110668eSIdo Schimmel {
10498110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV4_PIM, PIM, TRAP),
10508110668eSIdo Schimmel .listeners_arr = {
10518110668eSIdo Schimmel MLXSW_SP_RXL_MARK(IPV4_PIM, PIM, TRAP_TO_CPU, false),
10528110668eSIdo Schimmel },
10538110668eSIdo Schimmel },
10548110668eSIdo Schimmel {
10558110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV6_PIM, PIM, TRAP),
10568110668eSIdo Schimmel .listeners_arr = {
10578110668eSIdo Schimmel MLXSW_SP_RXL_MARK(IPV6_PIM, PIM, TRAP_TO_CPU, false),
10588110668eSIdo Schimmel },
10598110668eSIdo Schimmel },
10608110668eSIdo Schimmel {
10618110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(UC_LB, UC_LB, MIRROR),
10628110668eSIdo Schimmel .listeners_arr = {
10638110668eSIdo Schimmel MLXSW_SP_RXL_L3_MARK(LBERROR, LBERROR, MIRROR_TO_CPU,
10648110668eSIdo Schimmel false),
10658110668eSIdo Schimmel },
10668110668eSIdo Schimmel },
10678110668eSIdo Schimmel {
10688110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(LOCAL_ROUTE, LOCAL_DELIVERY,
10698110668eSIdo Schimmel TRAP),
10708110668eSIdo Schimmel .listeners_arr = {
10718110668eSIdo Schimmel MLXSW_SP_RXL_MARK(IP2ME, IP2ME, TRAP_TO_CPU, false),
10728110668eSIdo Schimmel },
10738110668eSIdo Schimmel },
10748110668eSIdo Schimmel {
1075ec4f5b36SIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(EXTERNAL_ROUTE, EXTERNAL_DELIVERY,
10768110668eSIdo Schimmel TRAP),
10778110668eSIdo Schimmel .listeners_arr = {
1078ec4f5b36SIdo Schimmel MLXSW_SP_RXL_MARK(RTR_INGRESS0, EXTERNAL_ROUTE,
1079ec4f5b36SIdo Schimmel TRAP_TO_CPU, false),
10808110668eSIdo Schimmel },
10818110668eSIdo Schimmel },
10828110668eSIdo Schimmel {
10838110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV6_UC_DIP_LINK_LOCAL_SCOPE,
10848110668eSIdo Schimmel LOCAL_DELIVERY, TRAP),
10858110668eSIdo Schimmel .listeners_arr = {
10868110668eSIdo Schimmel MLXSW_SP_RXL_MARK(IPV6_LINK_LOCAL_DEST, IP2ME,
10878110668eSIdo Schimmel TRAP_TO_CPU, false),
10888110668eSIdo Schimmel },
10898110668eSIdo Schimmel },
10908110668eSIdo Schimmel {
10918110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV4_ROUTER_ALERT, LOCAL_DELIVERY,
10928110668eSIdo Schimmel TRAP),
10938110668eSIdo Schimmel .listeners_arr = {
10948110668eSIdo Schimmel MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV4, IP2ME, TRAP_TO_CPU,
10958110668eSIdo Schimmel false),
10968110668eSIdo Schimmel },
10978110668eSIdo Schimmel },
10988110668eSIdo Schimmel {
10998110668eSIdo Schimmel /* IPV6_ROUTER_ALERT is defined in uAPI as 22, but it is not
11008110668eSIdo Schimmel * used in this file, so undefine it.
11018110668eSIdo Schimmel */
11028110668eSIdo Schimmel #undef IPV6_ROUTER_ALERT
11038110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV6_ROUTER_ALERT, LOCAL_DELIVERY,
11048110668eSIdo Schimmel TRAP),
11058110668eSIdo Schimmel .listeners_arr = {
11068110668eSIdo Schimmel MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV6, IP2ME, TRAP_TO_CPU,
11078110668eSIdo Schimmel false),
11088110668eSIdo Schimmel },
11098110668eSIdo Schimmel },
11108110668eSIdo Schimmel {
11118110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV6_DIP_ALL_NODES, IPV6, TRAP),
11128110668eSIdo Schimmel .listeners_arr = {
11138110668eSIdo Schimmel MLXSW_SP_RXL_MARK(IPV6_ALL_NODES_LINK, IPV6,
11148110668eSIdo Schimmel TRAP_TO_CPU, false),
11158110668eSIdo Schimmel },
11168110668eSIdo Schimmel },
11178110668eSIdo Schimmel {
11188110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV6_DIP_ALL_ROUTERS, IPV6, TRAP),
11198110668eSIdo Schimmel .listeners_arr = {
11208110668eSIdo Schimmel MLXSW_SP_RXL_MARK(IPV6_ALL_ROUTERS_LINK, IPV6,
11218110668eSIdo Schimmel TRAP_TO_CPU, false),
11228110668eSIdo Schimmel },
11238110668eSIdo Schimmel },
11248110668eSIdo Schimmel {
11258110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV6_ROUTER_SOLICIT, IPV6, TRAP),
11268110668eSIdo Schimmel .listeners_arr = {
11278110668eSIdo Schimmel MLXSW_SP_RXL_MARK(L3_IPV6_ROUTER_SOLICITATION, IPV6,
11288110668eSIdo Schimmel TRAP_TO_CPU, false),
11298110668eSIdo Schimmel },
11308110668eSIdo Schimmel },
11318110668eSIdo Schimmel {
11328110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV6_ROUTER_ADVERT, IPV6, TRAP),
11338110668eSIdo Schimmel .listeners_arr = {
11348110668eSIdo Schimmel MLXSW_SP_RXL_MARK(L3_IPV6_ROUTER_ADVERTISEMENT, IPV6,
11358110668eSIdo Schimmel TRAP_TO_CPU, false),
11368110668eSIdo Schimmel },
11378110668eSIdo Schimmel },
11388110668eSIdo Schimmel {
11398110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(IPV6_REDIRECT, IPV6, TRAP),
11408110668eSIdo Schimmel .listeners_arr = {
11418110668eSIdo Schimmel MLXSW_SP_RXL_MARK(L3_IPV6_REDIRECTION, IPV6,
11428110668eSIdo Schimmel TRAP_TO_CPU, false),
11438110668eSIdo Schimmel },
11448110668eSIdo Schimmel },
11458110668eSIdo Schimmel {
11468110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(PTP_EVENT, PTP_EVENT, TRAP),
11478110668eSIdo Schimmel .listeners_arr = {
11488110668eSIdo Schimmel MLXSW_RXL(mlxsw_sp_rx_ptp_listener, PTP0, TRAP_TO_CPU,
11498110668eSIdo Schimmel false, SP_PTP0, DISCARD),
11508110668eSIdo Schimmel },
11518110668eSIdo Schimmel },
11528110668eSIdo Schimmel {
11538110668eSIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(PTP_GENERAL, PTP_GENERAL, TRAP),
11548110668eSIdo Schimmel .listeners_arr = {
11558110668eSIdo Schimmel MLXSW_SP_RXL_NO_MARK(PTP1, PTP1, TRAP_TO_CPU, false),
11568110668eSIdo Schimmel },
11578110668eSIdo Schimmel },
115888e27749SIdo Schimmel {
115988e27749SIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(FLOW_ACTION_TRAP, ACL_TRAP, TRAP),
116088e27749SIdo Schimmel .listeners_arr = {
116188e27749SIdo Schimmel MLXSW_SP_RXL_NO_MARK(ACL0, FLOW_LOGGING, TRAP_TO_CPU,
116288e27749SIdo Schimmel false),
116388e27749SIdo Schimmel },
116488e27749SIdo Schimmel },
116537b50e55SIdo Schimmel {
116637b50e55SIdo Schimmel .trap = MLXSW_SP_TRAP_DROP(BLACKHOLE_NEXTHOP, L3_DROPS),
116737b50e55SIdo Schimmel .listeners_arr = {
116837b50e55SIdo Schimmel MLXSW_SP_RXL_DISCARD(ROUTER3, L3_DISCARDS),
116937b50e55SIdo Schimmel },
117037b50e55SIdo Schimmel },
1171*d85be0f5SIdo Schimmel {
1172*d85be0f5SIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(EAPOL, EAPOL, TRAP),
1173*d85be0f5SIdo Schimmel .listeners_arr = {
1174*d85be0f5SIdo Schimmel MLXSW_SP_RXL_NO_MARK(EAPOL, EAPOL, TRAP_TO_CPU, true),
1175*d85be0f5SIdo Schimmel },
1176*d85be0f5SIdo Schimmel },
1177*d85be0f5SIdo Schimmel {
1178*d85be0f5SIdo Schimmel .trap = MLXSW_SP_TRAP_DROP(LOCKED_PORT, L2_DROPS),
1179*d85be0f5SIdo Schimmel .listeners_arr = {
1180*d85be0f5SIdo Schimmel MLXSW_RXL_DIS(mlxsw_sp_rx_drop_listener, FDB_MISS,
1181*d85be0f5SIdo Schimmel TRAP_EXCEPTION_TO_CPU, false,
1182*d85be0f5SIdo Schimmel SP_L2_DISCARDS, DISCARD, SP_L2_DISCARDS),
1183*d85be0f5SIdo Schimmel MLXSW_RXL_DIS(mlxsw_sp_rx_drop_listener, FDB_MISMATCH,
1184*d85be0f5SIdo Schimmel TRAP_EXCEPTION_TO_CPU, false,
1185*d85be0f5SIdo Schimmel SP_L2_DISCARDS, DISCARD, SP_L2_DISCARDS),
1186*d85be0f5SIdo Schimmel },
1187*d85be0f5SIdo Schimmel },
1188b5ce611fSIdo Schimmel };
1189b5ce611fSIdo Schimmel
119013f2e64bSIdo Schimmel static struct mlxsw_sp_trap_policer_item *
mlxsw_sp_trap_policer_item_lookup(struct mlxsw_sp * mlxsw_sp,u32 id)119113f2e64bSIdo Schimmel mlxsw_sp_trap_policer_item_lookup(struct mlxsw_sp *mlxsw_sp, u32 id)
119213f2e64bSIdo Schimmel {
119313f2e64bSIdo Schimmel struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1194cc678f4dSIdo Schimmel int i;
119513f2e64bSIdo Schimmel
1196cc678f4dSIdo Schimmel for (i = 0; i < trap->policers_count; i++) {
1197cc678f4dSIdo Schimmel if (trap->policer_items_arr[i].policer.id == id)
1198cc678f4dSIdo Schimmel return &trap->policer_items_arr[i];
119913f2e64bSIdo Schimmel }
120013f2e64bSIdo Schimmel
120113f2e64bSIdo Schimmel return NULL;
120213f2e64bSIdo Schimmel }
120313f2e64bSIdo Schimmel
1204b14a40dbSIdo Schimmel static struct mlxsw_sp_trap_group_item *
mlxsw_sp_trap_group_item_lookup(struct mlxsw_sp * mlxsw_sp,u16 id)1205b14a40dbSIdo Schimmel mlxsw_sp_trap_group_item_lookup(struct mlxsw_sp *mlxsw_sp, u16 id)
1206b14a40dbSIdo Schimmel {
1207b14a40dbSIdo Schimmel struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1208b14a40dbSIdo Schimmel int i;
1209b14a40dbSIdo Schimmel
1210b14a40dbSIdo Schimmel for (i = 0; i < trap->groups_count; i++) {
1211b14a40dbSIdo Schimmel if (trap->group_items_arr[i].group.id == id)
1212b14a40dbSIdo Schimmel return &trap->group_items_arr[i];
1213b14a40dbSIdo Schimmel }
1214b14a40dbSIdo Schimmel
1215b14a40dbSIdo Schimmel return NULL;
1216b14a40dbSIdo Schimmel }
1217b14a40dbSIdo Schimmel
1218200b7ccaSIdo Schimmel static struct mlxsw_sp_trap_item *
mlxsw_sp_trap_item_lookup(struct mlxsw_sp * mlxsw_sp,u16 id)1219200b7ccaSIdo Schimmel mlxsw_sp_trap_item_lookup(struct mlxsw_sp *mlxsw_sp, u16 id)
1220200b7ccaSIdo Schimmel {
1221200b7ccaSIdo Schimmel struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1222200b7ccaSIdo Schimmel int i;
1223200b7ccaSIdo Schimmel
1224200b7ccaSIdo Schimmel for (i = 0; i < trap->traps_count; i++) {
1225200b7ccaSIdo Schimmel if (trap->trap_items_arr[i].trap.id == id)
1226200b7ccaSIdo Schimmel return &trap->trap_items_arr[i];
1227200b7ccaSIdo Schimmel }
1228200b7ccaSIdo Schimmel
1229200b7ccaSIdo Schimmel return NULL;
1230200b7ccaSIdo Schimmel }
1231200b7ccaSIdo Schimmel
mlxsw_sp_trap_cpu_policers_set(struct mlxsw_sp * mlxsw_sp)12323cbc37e6SJiri Pirko static int mlxsw_sp_trap_cpu_policers_set(struct mlxsw_sp *mlxsw_sp)
12333cbc37e6SJiri Pirko {
1234b87bde80SIdo Schimmel struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
12353cbc37e6SJiri Pirko char qpcr_pl[MLXSW_REG_QPCR_LEN];
1236b87bde80SIdo Schimmel u16 hw_id;
1237e6125230SJiri Pirko
1238e6125230SJiri Pirko /* The purpose of "thin" policer is to drop as many packets
1239e6125230SJiri Pirko * as possible. The dummy group is using it.
1240e6125230SJiri Pirko */
1241b87bde80SIdo Schimmel hw_id = find_first_zero_bit(trap->policers_usage, trap->max_policers);
1242b87bde80SIdo Schimmel if (WARN_ON(hw_id == trap->max_policers))
1243b87bde80SIdo Schimmel return -ENOBUFS;
1244b87bde80SIdo Schimmel
1245b87bde80SIdo Schimmel __set_bit(hw_id, trap->policers_usage);
1246b87bde80SIdo Schimmel trap->thin_policer_hw_id = hw_id;
1247b87bde80SIdo Schimmel mlxsw_reg_qpcr_pack(qpcr_pl, hw_id, MLXSW_REG_QPCR_IR_UNITS_M,
1248b87bde80SIdo Schimmel false, 1, 4);
12493cbc37e6SJiri Pirko return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qpcr), qpcr_pl);
12503cbc37e6SJiri Pirko }
12513cbc37e6SJiri Pirko
mlxsw_sp_trap_dummy_group_init(struct mlxsw_sp * mlxsw_sp)1252e6125230SJiri Pirko static int mlxsw_sp_trap_dummy_group_init(struct mlxsw_sp *mlxsw_sp)
1253e6125230SJiri Pirko {
1254e6125230SJiri Pirko char htgt_pl[MLXSW_REG_HTGT_LEN];
1255e6125230SJiri Pirko
1256e6125230SJiri Pirko mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_SP_DUMMY,
1257b87bde80SIdo Schimmel mlxsw_sp->trap->thin_policer_hw_id, 0, 1);
1258e6125230SJiri Pirko return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(htgt), htgt_pl);
1259e6125230SJiri Pirko }
1260e6125230SJiri Pirko
mlxsw_sp_trap_policer_items_arr_init(struct mlxsw_sp * mlxsw_sp)1261cc678f4dSIdo Schimmel static int mlxsw_sp_trap_policer_items_arr_init(struct mlxsw_sp *mlxsw_sp)
12624561705bSIdo Schimmel {
126376ba292cSIdo Schimmel size_t arr_size = ARRAY_SIZE(mlxsw_sp_trap_policer_items_arr);
1264cc678f4dSIdo Schimmel size_t elem_size = sizeof(struct mlxsw_sp_trap_policer_item);
12654561705bSIdo Schimmel struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
126676ba292cSIdo Schimmel size_t free_policers = 0;
1267cc678f4dSIdo Schimmel u32 last_id;
1268cc678f4dSIdo Schimmel int i;
12694561705bSIdo Schimmel
12704561705bSIdo Schimmel for_each_clear_bit(i, trap->policers_usage, trap->max_policers)
12714561705bSIdo Schimmel free_policers++;
12724561705bSIdo Schimmel
1273cc678f4dSIdo Schimmel if (arr_size > free_policers) {
12744561705bSIdo Schimmel dev_err(mlxsw_sp->bus_info->dev, "Exceeded number of supported packet trap policers\n");
12754561705bSIdo Schimmel return -ENOBUFS;
12764561705bSIdo Schimmel }
12774561705bSIdo Schimmel
1278cc678f4dSIdo Schimmel trap->policer_items_arr = kcalloc(free_policers, elem_size, GFP_KERNEL);
1279cc678f4dSIdo Schimmel if (!trap->policer_items_arr)
12804561705bSIdo Schimmel return -ENOMEM;
12814561705bSIdo Schimmel
12824561705bSIdo Schimmel trap->policers_count = free_policers;
12834561705bSIdo Schimmel
1284cc678f4dSIdo Schimmel /* Initialize policer items array with pre-defined policers. */
1285cc678f4dSIdo Schimmel memcpy(trap->policer_items_arr, mlxsw_sp_trap_policer_items_arr,
1286cc678f4dSIdo Schimmel elem_size * arr_size);
12874561705bSIdo Schimmel
1288cc678f4dSIdo Schimmel /* Initialize policer items array with the rest of the available
1289cc678f4dSIdo Schimmel * policers.
1290cc678f4dSIdo Schimmel */
1291cc678f4dSIdo Schimmel last_id = mlxsw_sp_trap_policer_items_arr[arr_size - 1].policer.id;
1292cc678f4dSIdo Schimmel for (i = arr_size; i < trap->policers_count; i++) {
1293cc678f4dSIdo Schimmel const struct mlxsw_sp_trap_policer_item *policer_item;
1294cc678f4dSIdo Schimmel
12954561705bSIdo Schimmel /* Use parameters set for first policer and override
12964561705bSIdo Schimmel * relevant ones.
12974561705bSIdo Schimmel */
1298cc678f4dSIdo Schimmel policer_item = &mlxsw_sp_trap_policer_items_arr[0];
1299cc678f4dSIdo Schimmel trap->policer_items_arr[i] = *policer_item;
1300cc678f4dSIdo Schimmel trap->policer_items_arr[i].policer.id = ++last_id;
1301cc678f4dSIdo Schimmel trap->policer_items_arr[i].policer.init_rate = 1;
1302cc678f4dSIdo Schimmel trap->policer_items_arr[i].policer.init_burst = 16;
13034561705bSIdo Schimmel }
13044561705bSIdo Schimmel
1305cc678f4dSIdo Schimmel return 0;
1306cc678f4dSIdo Schimmel }
130713f2e64bSIdo Schimmel
mlxsw_sp_trap_policer_items_arr_fini(struct mlxsw_sp * mlxsw_sp)1308cc678f4dSIdo Schimmel static void mlxsw_sp_trap_policer_items_arr_fini(struct mlxsw_sp *mlxsw_sp)
1309cc678f4dSIdo Schimmel {
1310cc678f4dSIdo Schimmel kfree(mlxsw_sp->trap->policer_items_arr);
1311cc678f4dSIdo Schimmel }
1312cc678f4dSIdo Schimmel
mlxsw_sp_trap_policers_init(struct mlxsw_sp * mlxsw_sp)1313cc678f4dSIdo Schimmel static int mlxsw_sp_trap_policers_init(struct mlxsw_sp *mlxsw_sp)
1314cc678f4dSIdo Schimmel {
1315cc678f4dSIdo Schimmel struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
1316cc678f4dSIdo Schimmel const struct mlxsw_sp_trap_policer_item *policer_item;
1317cc678f4dSIdo Schimmel struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1318cc678f4dSIdo Schimmel int err, i;
1319cc678f4dSIdo Schimmel
1320cc678f4dSIdo Schimmel err = mlxsw_sp_trap_policer_items_arr_init(mlxsw_sp);
132113f2e64bSIdo Schimmel if (err)
1322cc678f4dSIdo Schimmel return err;
1323cc678f4dSIdo Schimmel
1324cc678f4dSIdo Schimmel for (i = 0; i < trap->policers_count; i++) {
1325cc678f4dSIdo Schimmel policer_item = &trap->policer_items_arr[i];
132672a4c8c9SJiri Pirko err = devl_trap_policers_register(devlink,
1327cc678f4dSIdo Schimmel &policer_item->policer, 1);
1328cc678f4dSIdo Schimmel if (err)
1329cc678f4dSIdo Schimmel goto err_trap_policer_register;
1330cc678f4dSIdo Schimmel }
133113f2e64bSIdo Schimmel
13324561705bSIdo Schimmel return 0;
133313f2e64bSIdo Schimmel
1334cc678f4dSIdo Schimmel err_trap_policer_register:
1335cc678f4dSIdo Schimmel for (i--; i >= 0; i--) {
1336cc678f4dSIdo Schimmel policer_item = &trap->policer_items_arr[i];
133772a4c8c9SJiri Pirko devl_trap_policers_unregister(devlink,
1338cc678f4dSIdo Schimmel &policer_item->policer, 1);
1339cc678f4dSIdo Schimmel }
1340cc678f4dSIdo Schimmel mlxsw_sp_trap_policer_items_arr_fini(mlxsw_sp);
134113f2e64bSIdo Schimmel return err;
13424561705bSIdo Schimmel }
13434561705bSIdo Schimmel
mlxsw_sp_trap_policers_fini(struct mlxsw_sp * mlxsw_sp)13444561705bSIdo Schimmel static void mlxsw_sp_trap_policers_fini(struct mlxsw_sp *mlxsw_sp)
13454561705bSIdo Schimmel {
134613f2e64bSIdo Schimmel struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
1347cc678f4dSIdo Schimmel const struct mlxsw_sp_trap_policer_item *policer_item;
13484561705bSIdo Schimmel struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1349cc678f4dSIdo Schimmel int i;
13504561705bSIdo Schimmel
1351cc678f4dSIdo Schimmel for (i = trap->policers_count - 1; i >= 0; i--) {
1352cc678f4dSIdo Schimmel policer_item = &trap->policer_items_arr[i];
135372a4c8c9SJiri Pirko devl_trap_policers_unregister(devlink,
1354cc678f4dSIdo Schimmel &policer_item->policer, 1);
1355cc678f4dSIdo Schimmel }
1356cc678f4dSIdo Schimmel mlxsw_sp_trap_policer_items_arr_fini(mlxsw_sp);
13574561705bSIdo Schimmel }
13584561705bSIdo Schimmel
mlxsw_sp_trap_group_items_arr_init(struct mlxsw_sp * mlxsw_sp)135936d1fd68SIdo Schimmel static int mlxsw_sp_trap_group_items_arr_init(struct mlxsw_sp *mlxsw_sp)
136036d1fd68SIdo Schimmel {
136136d1fd68SIdo Schimmel size_t common_groups_count = ARRAY_SIZE(mlxsw_sp_trap_group_items_arr);
136236d1fd68SIdo Schimmel const struct mlxsw_sp_trap_group_item *spec_group_items_arr;
136336d1fd68SIdo Schimmel size_t elem_size = sizeof(struct mlxsw_sp_trap_group_item);
136436d1fd68SIdo Schimmel struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
136536d1fd68SIdo Schimmel size_t groups_count, spec_groups_count;
136636d1fd68SIdo Schimmel int err;
136736d1fd68SIdo Schimmel
136836d1fd68SIdo Schimmel err = mlxsw_sp->trap_ops->groups_init(mlxsw_sp, &spec_group_items_arr,
136936d1fd68SIdo Schimmel &spec_groups_count);
137036d1fd68SIdo Schimmel if (err)
137136d1fd68SIdo Schimmel return err;
137236d1fd68SIdo Schimmel
137336d1fd68SIdo Schimmel /* The group items array is created by concatenating the common trap
137436d1fd68SIdo Schimmel * group items and the ASIC-specific trap group items.
137536d1fd68SIdo Schimmel */
137636d1fd68SIdo Schimmel groups_count = common_groups_count + spec_groups_count;
137736d1fd68SIdo Schimmel trap->group_items_arr = kcalloc(groups_count, elem_size, GFP_KERNEL);
137836d1fd68SIdo Schimmel if (!trap->group_items_arr)
137936d1fd68SIdo Schimmel return -ENOMEM;
138036d1fd68SIdo Schimmel
138136d1fd68SIdo Schimmel memcpy(trap->group_items_arr, mlxsw_sp_trap_group_items_arr,
138236d1fd68SIdo Schimmel elem_size * common_groups_count);
138336d1fd68SIdo Schimmel memcpy(trap->group_items_arr + common_groups_count,
138436d1fd68SIdo Schimmel spec_group_items_arr, elem_size * spec_groups_count);
138536d1fd68SIdo Schimmel
138636d1fd68SIdo Schimmel trap->groups_count = groups_count;
138736d1fd68SIdo Schimmel
138836d1fd68SIdo Schimmel return 0;
138936d1fd68SIdo Schimmel }
139036d1fd68SIdo Schimmel
mlxsw_sp_trap_group_items_arr_fini(struct mlxsw_sp * mlxsw_sp)139136d1fd68SIdo Schimmel static void mlxsw_sp_trap_group_items_arr_fini(struct mlxsw_sp *mlxsw_sp)
139236d1fd68SIdo Schimmel {
139336d1fd68SIdo Schimmel kfree(mlxsw_sp->trap->group_items_arr);
139436d1fd68SIdo Schimmel }
139536d1fd68SIdo Schimmel
mlxsw_sp_trap_groups_init(struct mlxsw_sp * mlxsw_sp)1396b14a40dbSIdo Schimmel static int mlxsw_sp_trap_groups_init(struct mlxsw_sp *mlxsw_sp)
1397b14a40dbSIdo Schimmel {
1398b14a40dbSIdo Schimmel struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
1399b14a40dbSIdo Schimmel const struct mlxsw_sp_trap_group_item *group_item;
1400b14a40dbSIdo Schimmel struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1401b14a40dbSIdo Schimmel int err, i;
1402b14a40dbSIdo Schimmel
140336d1fd68SIdo Schimmel err = mlxsw_sp_trap_group_items_arr_init(mlxsw_sp);
140436d1fd68SIdo Schimmel if (err)
140536d1fd68SIdo Schimmel return err;
1406b14a40dbSIdo Schimmel
1407b14a40dbSIdo Schimmel for (i = 0; i < trap->groups_count; i++) {
1408b14a40dbSIdo Schimmel group_item = &trap->group_items_arr[i];
140972a4c8c9SJiri Pirko err = devl_trap_groups_register(devlink, &group_item->group, 1);
1410b14a40dbSIdo Schimmel if (err)
1411b14a40dbSIdo Schimmel goto err_trap_group_register;
1412b14a40dbSIdo Schimmel }
1413b14a40dbSIdo Schimmel
1414b14a40dbSIdo Schimmel return 0;
1415b14a40dbSIdo Schimmel
1416b14a40dbSIdo Schimmel err_trap_group_register:
1417b14a40dbSIdo Schimmel for (i--; i >= 0; i--) {
1418b14a40dbSIdo Schimmel group_item = &trap->group_items_arr[i];
141972a4c8c9SJiri Pirko devl_trap_groups_unregister(devlink, &group_item->group, 1);
1420b14a40dbSIdo Schimmel }
142136d1fd68SIdo Schimmel mlxsw_sp_trap_group_items_arr_fini(mlxsw_sp);
1422b14a40dbSIdo Schimmel return err;
1423b14a40dbSIdo Schimmel }
1424b14a40dbSIdo Schimmel
mlxsw_sp_trap_groups_fini(struct mlxsw_sp * mlxsw_sp)1425b14a40dbSIdo Schimmel static void mlxsw_sp_trap_groups_fini(struct mlxsw_sp *mlxsw_sp)
1426b14a40dbSIdo Schimmel {
1427b14a40dbSIdo Schimmel struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
1428b14a40dbSIdo Schimmel struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1429b14a40dbSIdo Schimmel int i;
1430b14a40dbSIdo Schimmel
1431b14a40dbSIdo Schimmel for (i = trap->groups_count - 1; i >= 0; i--) {
1432b14a40dbSIdo Schimmel const struct mlxsw_sp_trap_group_item *group_item;
1433b14a40dbSIdo Schimmel
1434b14a40dbSIdo Schimmel group_item = &trap->group_items_arr[i];
143572a4c8c9SJiri Pirko devl_trap_groups_unregister(devlink, &group_item->group, 1);
1436b14a40dbSIdo Schimmel }
143736d1fd68SIdo Schimmel mlxsw_sp_trap_group_items_arr_fini(mlxsw_sp);
1438b14a40dbSIdo Schimmel }
1439b14a40dbSIdo Schimmel
1440200b7ccaSIdo Schimmel static bool
mlxsw_sp_trap_listener_is_valid(const struct mlxsw_listener * listener)1441200b7ccaSIdo Schimmel mlxsw_sp_trap_listener_is_valid(const struct mlxsw_listener *listener)
1442200b7ccaSIdo Schimmel {
1443200b7ccaSIdo Schimmel return listener->trap_id != 0;
1444200b7ccaSIdo Schimmel }
1445200b7ccaSIdo Schimmel
mlxsw_sp_trap_items_arr_init(struct mlxsw_sp * mlxsw_sp)1446869c7be9SIdo Schimmel static int mlxsw_sp_trap_items_arr_init(struct mlxsw_sp *mlxsw_sp)
1447869c7be9SIdo Schimmel {
1448869c7be9SIdo Schimmel size_t common_traps_count = ARRAY_SIZE(mlxsw_sp_trap_items_arr);
1449869c7be9SIdo Schimmel const struct mlxsw_sp_trap_item *spec_trap_items_arr;
1450869c7be9SIdo Schimmel size_t elem_size = sizeof(struct mlxsw_sp_trap_item);
1451869c7be9SIdo Schimmel struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1452869c7be9SIdo Schimmel size_t traps_count, spec_traps_count;
1453869c7be9SIdo Schimmel int err;
1454869c7be9SIdo Schimmel
1455869c7be9SIdo Schimmel err = mlxsw_sp->trap_ops->traps_init(mlxsw_sp, &spec_trap_items_arr,
1456869c7be9SIdo Schimmel &spec_traps_count);
1457869c7be9SIdo Schimmel if (err)
1458869c7be9SIdo Schimmel return err;
1459869c7be9SIdo Schimmel
1460869c7be9SIdo Schimmel /* The trap items array is created by concatenating the common trap
1461869c7be9SIdo Schimmel * items and the ASIC-specific trap items.
1462869c7be9SIdo Schimmel */
1463869c7be9SIdo Schimmel traps_count = common_traps_count + spec_traps_count;
1464869c7be9SIdo Schimmel trap->trap_items_arr = kcalloc(traps_count, elem_size, GFP_KERNEL);
1465869c7be9SIdo Schimmel if (!trap->trap_items_arr)
1466869c7be9SIdo Schimmel return -ENOMEM;
1467869c7be9SIdo Schimmel
1468869c7be9SIdo Schimmel memcpy(trap->trap_items_arr, mlxsw_sp_trap_items_arr,
1469869c7be9SIdo Schimmel elem_size * common_traps_count);
1470869c7be9SIdo Schimmel memcpy(trap->trap_items_arr + common_traps_count,
1471869c7be9SIdo Schimmel spec_trap_items_arr, elem_size * spec_traps_count);
1472869c7be9SIdo Schimmel
1473869c7be9SIdo Schimmel trap->traps_count = traps_count;
1474869c7be9SIdo Schimmel
1475869c7be9SIdo Schimmel return 0;
1476869c7be9SIdo Schimmel }
1477869c7be9SIdo Schimmel
mlxsw_sp_trap_items_arr_fini(struct mlxsw_sp * mlxsw_sp)1478869c7be9SIdo Schimmel static void mlxsw_sp_trap_items_arr_fini(struct mlxsw_sp *mlxsw_sp)
1479869c7be9SIdo Schimmel {
1480869c7be9SIdo Schimmel kfree(mlxsw_sp->trap->trap_items_arr);
1481869c7be9SIdo Schimmel }
1482869c7be9SIdo Schimmel
mlxsw_sp_traps_init(struct mlxsw_sp * mlxsw_sp)1483200b7ccaSIdo Schimmel static int mlxsw_sp_traps_init(struct mlxsw_sp *mlxsw_sp)
1484b5ce611fSIdo Schimmel {
1485b5ce611fSIdo Schimmel struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
1486200b7ccaSIdo Schimmel struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1487200b7ccaSIdo Schimmel const struct mlxsw_sp_trap_item *trap_item;
1488200b7ccaSIdo Schimmel int err, i;
1489200b7ccaSIdo Schimmel
1490869c7be9SIdo Schimmel err = mlxsw_sp_trap_items_arr_init(mlxsw_sp);
1491869c7be9SIdo Schimmel if (err)
1492869c7be9SIdo Schimmel return err;
1493200b7ccaSIdo Schimmel
1494200b7ccaSIdo Schimmel for (i = 0; i < trap->traps_count; i++) {
1495200b7ccaSIdo Schimmel trap_item = &trap->trap_items_arr[i];
149672a4c8c9SJiri Pirko err = devl_traps_register(devlink, &trap_item->trap, 1,
1497200b7ccaSIdo Schimmel mlxsw_sp);
1498200b7ccaSIdo Schimmel if (err)
1499200b7ccaSIdo Schimmel goto err_trap_register;
1500200b7ccaSIdo Schimmel }
1501200b7ccaSIdo Schimmel
1502200b7ccaSIdo Schimmel return 0;
1503200b7ccaSIdo Schimmel
1504200b7ccaSIdo Schimmel err_trap_register:
1505200b7ccaSIdo Schimmel for (i--; i >= 0; i--) {
1506200b7ccaSIdo Schimmel trap_item = &trap->trap_items_arr[i];
150772a4c8c9SJiri Pirko devl_traps_unregister(devlink, &trap_item->trap, 1);
1508200b7ccaSIdo Schimmel }
1509869c7be9SIdo Schimmel mlxsw_sp_trap_items_arr_fini(mlxsw_sp);
1510200b7ccaSIdo Schimmel return err;
1511200b7ccaSIdo Schimmel }
1512200b7ccaSIdo Schimmel
mlxsw_sp_traps_fini(struct mlxsw_sp * mlxsw_sp)1513200b7ccaSIdo Schimmel static void mlxsw_sp_traps_fini(struct mlxsw_sp *mlxsw_sp)
1514200b7ccaSIdo Schimmel {
1515200b7ccaSIdo Schimmel struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
1516200b7ccaSIdo Schimmel struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
1517200b7ccaSIdo Schimmel int i;
1518200b7ccaSIdo Schimmel
1519200b7ccaSIdo Schimmel for (i = trap->traps_count - 1; i >= 0; i--) {
1520200b7ccaSIdo Schimmel const struct mlxsw_sp_trap_item *trap_item;
1521200b7ccaSIdo Schimmel
1522200b7ccaSIdo Schimmel trap_item = &trap->trap_items_arr[i];
152372a4c8c9SJiri Pirko devl_traps_unregister(devlink, &trap_item->trap, 1);
1524200b7ccaSIdo Schimmel }
1525869c7be9SIdo Schimmel mlxsw_sp_trap_items_arr_fini(mlxsw_sp);
1526200b7ccaSIdo Schimmel }
1527200b7ccaSIdo Schimmel
mlxsw_sp_devlink_traps_init(struct mlxsw_sp * mlxsw_sp)1528200b7ccaSIdo Schimmel int mlxsw_sp_devlink_traps_init(struct mlxsw_sp *mlxsw_sp)
1529200b7ccaSIdo Schimmel {
15303cbc37e6SJiri Pirko int err;
15313cbc37e6SJiri Pirko
15323cbc37e6SJiri Pirko err = mlxsw_sp_trap_cpu_policers_set(mlxsw_sp);
15333cbc37e6SJiri Pirko if (err)
15343cbc37e6SJiri Pirko return err;
1535b5ce611fSIdo Schimmel
1536e6125230SJiri Pirko err = mlxsw_sp_trap_dummy_group_init(mlxsw_sp);
1537e6125230SJiri Pirko if (err)
1538e6125230SJiri Pirko return err;
1539e6125230SJiri Pirko
15404561705bSIdo Schimmel err = mlxsw_sp_trap_policers_init(mlxsw_sp);
15414561705bSIdo Schimmel if (err)
15424561705bSIdo Schimmel return err;
15434561705bSIdo Schimmel
1544b14a40dbSIdo Schimmel err = mlxsw_sp_trap_groups_init(mlxsw_sp);
15458cd999e4SIdo Schimmel if (err)
1546b14a40dbSIdo Schimmel goto err_trap_groups_init;
15478cd999e4SIdo Schimmel
1548200b7ccaSIdo Schimmel err = mlxsw_sp_traps_init(mlxsw_sp);
15498cd999e4SIdo Schimmel if (err)
1550200b7ccaSIdo Schimmel goto err_traps_init;
15518cd999e4SIdo Schimmel
15528cd999e4SIdo Schimmel return 0;
15538cd999e4SIdo Schimmel
1554200b7ccaSIdo Schimmel err_traps_init:
1555b14a40dbSIdo Schimmel mlxsw_sp_trap_groups_fini(mlxsw_sp);
1556b14a40dbSIdo Schimmel err_trap_groups_init:
15574561705bSIdo Schimmel mlxsw_sp_trap_policers_fini(mlxsw_sp);
15588cd999e4SIdo Schimmel return err;
1559b5ce611fSIdo Schimmel }
1560b5ce611fSIdo Schimmel
mlxsw_sp_devlink_traps_fini(struct mlxsw_sp * mlxsw_sp)1561b5ce611fSIdo Schimmel void mlxsw_sp_devlink_traps_fini(struct mlxsw_sp *mlxsw_sp)
1562b5ce611fSIdo Schimmel {
1563200b7ccaSIdo Schimmel mlxsw_sp_traps_fini(mlxsw_sp);
1564b14a40dbSIdo Schimmel mlxsw_sp_trap_groups_fini(mlxsw_sp);
15654561705bSIdo Schimmel mlxsw_sp_trap_policers_fini(mlxsw_sp);
1566b5ce611fSIdo Schimmel }
1567b5ce611fSIdo Schimmel
mlxsw_sp_trap_init(struct mlxsw_core * mlxsw_core,const struct devlink_trap * trap,void * trap_ctx)1568b5ce611fSIdo Schimmel int mlxsw_sp_trap_init(struct mlxsw_core *mlxsw_core,
1569b5ce611fSIdo Schimmel const struct devlink_trap *trap, void *trap_ctx)
1570b5ce611fSIdo Schimmel {
1571200b7ccaSIdo Schimmel struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
1572200b7ccaSIdo Schimmel const struct mlxsw_sp_trap_item *trap_item;
1573b5ce611fSIdo Schimmel int i;
1574b5ce611fSIdo Schimmel
1575200b7ccaSIdo Schimmel trap_item = mlxsw_sp_trap_item_lookup(mlxsw_sp, trap->id);
1576200b7ccaSIdo Schimmel if (WARN_ON(!trap_item))
1577200b7ccaSIdo Schimmel return -EINVAL;
1578200b7ccaSIdo Schimmel
1579200b7ccaSIdo Schimmel for (i = 0; i < MLXSW_SP_TRAP_LISTENERS_MAX; i++) {
158016adc56cSJiri Pirko const struct mlxsw_listener *listener;
1581b5ce611fSIdo Schimmel int err;
1582b5ce611fSIdo Schimmel
1583200b7ccaSIdo Schimmel listener = &trap_item->listeners_arr[i];
1584200b7ccaSIdo Schimmel if (!mlxsw_sp_trap_listener_is_valid(listener))
1585b5ce611fSIdo Schimmel continue;
1586b5ce611fSIdo Schimmel err = mlxsw_core_trap_register(mlxsw_core, listener, trap_ctx);
1587b5ce611fSIdo Schimmel if (err)
1588b5ce611fSIdo Schimmel return err;
1589b5ce611fSIdo Schimmel }
1590b5ce611fSIdo Schimmel
1591b5ce611fSIdo Schimmel return 0;
1592b5ce611fSIdo Schimmel }
1593b5ce611fSIdo Schimmel
mlxsw_sp_trap_fini(struct mlxsw_core * mlxsw_core,const struct devlink_trap * trap,void * trap_ctx)1594b5ce611fSIdo Schimmel void mlxsw_sp_trap_fini(struct mlxsw_core *mlxsw_core,
1595b5ce611fSIdo Schimmel const struct devlink_trap *trap, void *trap_ctx)
1596b5ce611fSIdo Schimmel {
1597200b7ccaSIdo Schimmel struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
1598200b7ccaSIdo Schimmel const struct mlxsw_sp_trap_item *trap_item;
1599b5ce611fSIdo Schimmel int i;
1600b5ce611fSIdo Schimmel
1601200b7ccaSIdo Schimmel trap_item = mlxsw_sp_trap_item_lookup(mlxsw_sp, trap->id);
1602200b7ccaSIdo Schimmel if (WARN_ON(!trap_item))
1603200b7ccaSIdo Schimmel return;
1604200b7ccaSIdo Schimmel
1605200b7ccaSIdo Schimmel for (i = MLXSW_SP_TRAP_LISTENERS_MAX - 1; i >= 0; i--) {
160616adc56cSJiri Pirko const struct mlxsw_listener *listener;
1607b5ce611fSIdo Schimmel
1608200b7ccaSIdo Schimmel listener = &trap_item->listeners_arr[i];
1609200b7ccaSIdo Schimmel if (!mlxsw_sp_trap_listener_is_valid(listener))
1610b5ce611fSIdo Schimmel continue;
1611b5ce611fSIdo Schimmel mlxsw_core_trap_unregister(mlxsw_core, listener, trap_ctx);
1612b5ce611fSIdo Schimmel }
1613b5ce611fSIdo Schimmel }
1614b5ce611fSIdo Schimmel
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)1615b5ce611fSIdo Schimmel int mlxsw_sp_trap_action_set(struct mlxsw_core *mlxsw_core,
1616b5ce611fSIdo Schimmel const struct devlink_trap *trap,
1617c88e11e0SIdo Schimmel enum devlink_trap_action action,
1618c88e11e0SIdo Schimmel struct netlink_ext_ack *extack)
1619b5ce611fSIdo Schimmel {
1620200b7ccaSIdo Schimmel struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
1621200b7ccaSIdo Schimmel const struct mlxsw_sp_trap_item *trap_item;
1622b5ce611fSIdo Schimmel int i;
1623b5ce611fSIdo Schimmel
1624200b7ccaSIdo Schimmel trap_item = mlxsw_sp_trap_item_lookup(mlxsw_sp, trap->id);
1625200b7ccaSIdo Schimmel if (WARN_ON(!trap_item))
1626200b7ccaSIdo Schimmel return -EINVAL;
1627200b7ccaSIdo Schimmel
16286687e953SIdo Schimmel if (trap_item->is_source) {
16296687e953SIdo Schimmel NL_SET_ERR_MSG_MOD(extack, "Changing the action of source traps is not supported");
16306687e953SIdo Schimmel return -EOPNOTSUPP;
16316687e953SIdo Schimmel }
16326687e953SIdo Schimmel
1633200b7ccaSIdo Schimmel for (i = 0; i < MLXSW_SP_TRAP_LISTENERS_MAX; i++) {
163416adc56cSJiri Pirko const struct mlxsw_listener *listener;
16354a23d45aSJiri Pirko bool enabled;
1636b5ce611fSIdo Schimmel int err;
1637b5ce611fSIdo Schimmel
1638200b7ccaSIdo Schimmel listener = &trap_item->listeners_arr[i];
1639200b7ccaSIdo Schimmel if (!mlxsw_sp_trap_listener_is_valid(listener))
1640b5ce611fSIdo Schimmel continue;
1641200b7ccaSIdo Schimmel
1642b5ce611fSIdo Schimmel switch (action) {
1643b5ce611fSIdo Schimmel case DEVLINK_TRAP_ACTION_DROP:
16444a23d45aSJiri Pirko enabled = false;
1645b5ce611fSIdo Schimmel break;
1646b5ce611fSIdo Schimmel case DEVLINK_TRAP_ACTION_TRAP:
16474a23d45aSJiri Pirko enabled = true;
1648b5ce611fSIdo Schimmel break;
1649b5ce611fSIdo Schimmel default:
1650b5ce611fSIdo Schimmel return -EINVAL;
1651b5ce611fSIdo Schimmel }
16524a23d45aSJiri Pirko err = mlxsw_core_trap_state_set(mlxsw_core, listener, enabled);
1653b5ce611fSIdo Schimmel if (err)
1654b5ce611fSIdo Schimmel return err;
1655b5ce611fSIdo Schimmel }
1656b5ce611fSIdo Schimmel
1657b5ce611fSIdo Schimmel return 0;
1658b5ce611fSIdo Schimmel }
1659b5ce611fSIdo Schimmel
166039defcbbSIdo Schimmel 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)166139defcbbSIdo Schimmel __mlxsw_sp_trap_group_init(struct mlxsw_core *mlxsw_core,
166239defcbbSIdo Schimmel const struct devlink_trap_group *group,
1663c88e11e0SIdo Schimmel u32 policer_id, struct netlink_ext_ack *extack)
1664b5ce611fSIdo Schimmel {
166513f2e64bSIdo Schimmel struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
166613f2e64bSIdo Schimmel u16 hw_policer_id = MLXSW_REG_HTGT_INVALID_POLICER;
1667b14a40dbSIdo Schimmel const struct mlxsw_sp_trap_group_item *group_item;
1668b5ce611fSIdo Schimmel char htgt_pl[MLXSW_REG_HTGT_LEN];
1669b5ce611fSIdo Schimmel
1670b14a40dbSIdo Schimmel group_item = mlxsw_sp_trap_group_item_lookup(mlxsw_sp, group->id);
1671b14a40dbSIdo Schimmel if (WARN_ON(!group_item))
1672b5ce611fSIdo Schimmel return -EINVAL;
1673b5ce611fSIdo Schimmel
16746687e953SIdo Schimmel if (group_item->fixed_policer && policer_id != group->init_policer_id) {
16756687e953SIdo Schimmel NL_SET_ERR_MSG_MOD(extack, "Changing the policer binding of this group is not supported");
16766687e953SIdo Schimmel return -EOPNOTSUPP;
16776687e953SIdo Schimmel }
16786687e953SIdo Schimmel
167939defcbbSIdo Schimmel if (policer_id) {
168013f2e64bSIdo Schimmel struct mlxsw_sp_trap_policer_item *policer_item;
168113f2e64bSIdo Schimmel
168239defcbbSIdo Schimmel policer_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp,
168339defcbbSIdo Schimmel policer_id);
168413f2e64bSIdo Schimmel if (WARN_ON(!policer_item))
168513f2e64bSIdo Schimmel return -EINVAL;
168613f2e64bSIdo Schimmel hw_policer_id = policer_item->hw_id;
168713f2e64bSIdo Schimmel }
168813f2e64bSIdo Schimmel
1689b14a40dbSIdo Schimmel mlxsw_reg_htgt_pack(htgt_pl, group_item->hw_group_id, hw_policer_id,
1690d88f8cc1SIdo Schimmel group_item->priority, group_item->priority);
16913cbc37e6SJiri Pirko return mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl);
1692b5ce611fSIdo Schimmel }
169313f2e64bSIdo Schimmel
mlxsw_sp_trap_group_init(struct mlxsw_core * mlxsw_core,const struct devlink_trap_group * group)169439defcbbSIdo Schimmel int mlxsw_sp_trap_group_init(struct mlxsw_core *mlxsw_core,
169539defcbbSIdo Schimmel const struct devlink_trap_group *group)
169639defcbbSIdo Schimmel {
169739defcbbSIdo Schimmel return __mlxsw_sp_trap_group_init(mlxsw_core, group,
1698c88e11e0SIdo Schimmel group->init_policer_id, NULL);
169939defcbbSIdo Schimmel }
170039defcbbSIdo Schimmel
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)170139defcbbSIdo Schimmel int mlxsw_sp_trap_group_set(struct mlxsw_core *mlxsw_core,
170239defcbbSIdo Schimmel const struct devlink_trap_group *group,
1703c88e11e0SIdo Schimmel const struct devlink_trap_policer *policer,
1704c88e11e0SIdo Schimmel struct netlink_ext_ack *extack)
170539defcbbSIdo Schimmel {
170639defcbbSIdo Schimmel u32 policer_id = policer ? policer->id : 0;
170739defcbbSIdo Schimmel
1708c88e11e0SIdo Schimmel return __mlxsw_sp_trap_group_init(mlxsw_core, group, policer_id,
1709c88e11e0SIdo Schimmel extack);
171039defcbbSIdo Schimmel }
171139defcbbSIdo Schimmel
1712cc678f4dSIdo Schimmel static int
mlxsw_sp_trap_policer_item_init(struct mlxsw_sp * mlxsw_sp,struct mlxsw_sp_trap_policer_item * policer_item)1713cc678f4dSIdo Schimmel mlxsw_sp_trap_policer_item_init(struct mlxsw_sp *mlxsw_sp,
1714cc678f4dSIdo Schimmel struct mlxsw_sp_trap_policer_item *policer_item)
171513f2e64bSIdo Schimmel {
171613f2e64bSIdo Schimmel struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
171713f2e64bSIdo Schimmel u16 hw_id;
171813f2e64bSIdo Schimmel
171913f2e64bSIdo Schimmel /* We should be able to allocate a policer because the number of
172013f2e64bSIdo Schimmel * policers we registered with devlink is in according with the number
172113f2e64bSIdo Schimmel * of available policers.
172213f2e64bSIdo Schimmel */
172313f2e64bSIdo Schimmel hw_id = find_first_zero_bit(trap->policers_usage, trap->max_policers);
172413f2e64bSIdo Schimmel if (WARN_ON(hw_id == trap->max_policers))
1725cc678f4dSIdo Schimmel return -ENOBUFS;
172613f2e64bSIdo Schimmel
172713f2e64bSIdo Schimmel __set_bit(hw_id, trap->policers_usage);
172813f2e64bSIdo Schimmel policer_item->hw_id = hw_id;
172913f2e64bSIdo Schimmel
1730cc678f4dSIdo Schimmel return 0;
173113f2e64bSIdo Schimmel }
173213f2e64bSIdo Schimmel
173313f2e64bSIdo Schimmel static void
mlxsw_sp_trap_policer_item_fini(struct mlxsw_sp * mlxsw_sp,struct mlxsw_sp_trap_policer_item * policer_item)173413f2e64bSIdo Schimmel mlxsw_sp_trap_policer_item_fini(struct mlxsw_sp *mlxsw_sp,
173513f2e64bSIdo Schimmel struct mlxsw_sp_trap_policer_item *policer_item)
173613f2e64bSIdo Schimmel {
173713f2e64bSIdo Schimmel __clear_bit(policer_item->hw_id, mlxsw_sp->trap->policers_usage);
173813f2e64bSIdo Schimmel }
173913f2e64bSIdo Schimmel
mlxsw_sp_trap_policer_bs(u64 burst,u8 * p_burst_size,struct netlink_ext_ack * extack)174013f2e64bSIdo Schimmel static int mlxsw_sp_trap_policer_bs(u64 burst, u8 *p_burst_size,
174113f2e64bSIdo Schimmel struct netlink_ext_ack *extack)
174213f2e64bSIdo Schimmel {
174313f2e64bSIdo Schimmel int bs = fls64(burst) - 1;
174413f2e64bSIdo Schimmel
1745468c2a10SColin Ian King if (burst != (BIT_ULL(bs))) {
174613f2e64bSIdo Schimmel NL_SET_ERR_MSG_MOD(extack, "Policer burst size is not power of two");
174713f2e64bSIdo Schimmel return -EINVAL;
174813f2e64bSIdo Schimmel }
174913f2e64bSIdo Schimmel
175013f2e64bSIdo Schimmel *p_burst_size = bs;
175113f2e64bSIdo Schimmel
175213f2e64bSIdo Schimmel return 0;
175313f2e64bSIdo Schimmel }
175413f2e64bSIdo Schimmel
__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)175513f2e64bSIdo Schimmel static int __mlxsw_sp_trap_policer_set(struct mlxsw_sp *mlxsw_sp, u16 hw_id,
175613f2e64bSIdo Schimmel u64 rate, u64 burst, bool clear_counter,
175713f2e64bSIdo Schimmel struct netlink_ext_ack *extack)
175813f2e64bSIdo Schimmel {
175913f2e64bSIdo Schimmel char qpcr_pl[MLXSW_REG_QPCR_LEN];
176013f2e64bSIdo Schimmel u8 burst_size;
176113f2e64bSIdo Schimmel int err;
176213f2e64bSIdo Schimmel
176313f2e64bSIdo Schimmel err = mlxsw_sp_trap_policer_bs(burst, &burst_size, extack);
176413f2e64bSIdo Schimmel if (err)
176513f2e64bSIdo Schimmel return err;
176613f2e64bSIdo Schimmel
176713f2e64bSIdo Schimmel mlxsw_reg_qpcr_pack(qpcr_pl, hw_id, MLXSW_REG_QPCR_IR_UNITS_M, false,
176813f2e64bSIdo Schimmel rate, burst_size);
176913f2e64bSIdo Schimmel mlxsw_reg_qpcr_clear_counter_set(qpcr_pl, clear_counter);
177013f2e64bSIdo Schimmel return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qpcr), qpcr_pl);
177113f2e64bSIdo Schimmel }
177213f2e64bSIdo Schimmel
mlxsw_sp_trap_policer_init(struct mlxsw_core * mlxsw_core,const struct devlink_trap_policer * policer)177313f2e64bSIdo Schimmel int mlxsw_sp_trap_policer_init(struct mlxsw_core *mlxsw_core,
177413f2e64bSIdo Schimmel const struct devlink_trap_policer *policer)
177513f2e64bSIdo Schimmel {
177613f2e64bSIdo Schimmel struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
177713f2e64bSIdo Schimmel struct mlxsw_sp_trap_policer_item *policer_item;
177813f2e64bSIdo Schimmel int err;
177913f2e64bSIdo Schimmel
1780cc678f4dSIdo Schimmel policer_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, policer->id);
1781cc678f4dSIdo Schimmel if (WARN_ON(!policer_item))
1782cc678f4dSIdo Schimmel return -EINVAL;
1783cc678f4dSIdo Schimmel
1784cc678f4dSIdo Schimmel err = mlxsw_sp_trap_policer_item_init(mlxsw_sp, policer_item);
1785cc678f4dSIdo Schimmel if (err)
1786cc678f4dSIdo Schimmel return err;
178713f2e64bSIdo Schimmel
178813f2e64bSIdo Schimmel err = __mlxsw_sp_trap_policer_set(mlxsw_sp, policer_item->hw_id,
178913f2e64bSIdo Schimmel policer->init_rate,
179013f2e64bSIdo Schimmel policer->init_burst, true, NULL);
179113f2e64bSIdo Schimmel if (err)
179213f2e64bSIdo Schimmel goto err_trap_policer_set;
179313f2e64bSIdo Schimmel
179413f2e64bSIdo Schimmel return 0;
179513f2e64bSIdo Schimmel
179613f2e64bSIdo Schimmel err_trap_policer_set:
179713f2e64bSIdo Schimmel mlxsw_sp_trap_policer_item_fini(mlxsw_sp, policer_item);
179813f2e64bSIdo Schimmel return err;
179913f2e64bSIdo Schimmel }
180013f2e64bSIdo Schimmel
mlxsw_sp_trap_policer_fini(struct mlxsw_core * mlxsw_core,const struct devlink_trap_policer * policer)180113f2e64bSIdo Schimmel void mlxsw_sp_trap_policer_fini(struct mlxsw_core *mlxsw_core,
180213f2e64bSIdo Schimmel const struct devlink_trap_policer *policer)
180313f2e64bSIdo Schimmel {
180413f2e64bSIdo Schimmel struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
180513f2e64bSIdo Schimmel struct mlxsw_sp_trap_policer_item *policer_item;
180613f2e64bSIdo Schimmel
180713f2e64bSIdo Schimmel policer_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, policer->id);
180813f2e64bSIdo Schimmel if (WARN_ON(!policer_item))
180913f2e64bSIdo Schimmel return;
181013f2e64bSIdo Schimmel
181113f2e64bSIdo Schimmel mlxsw_sp_trap_policer_item_fini(mlxsw_sp, policer_item);
181213f2e64bSIdo Schimmel }
181313f2e64bSIdo Schimmel
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)181413f2e64bSIdo Schimmel int mlxsw_sp_trap_policer_set(struct mlxsw_core *mlxsw_core,
181513f2e64bSIdo Schimmel const struct devlink_trap_policer *policer,
181613f2e64bSIdo Schimmel u64 rate, u64 burst,
181713f2e64bSIdo Schimmel struct netlink_ext_ack *extack)
181813f2e64bSIdo Schimmel {
181913f2e64bSIdo Schimmel struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
182013f2e64bSIdo Schimmel struct mlxsw_sp_trap_policer_item *policer_item;
182113f2e64bSIdo Schimmel
182213f2e64bSIdo Schimmel policer_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, policer->id);
182313f2e64bSIdo Schimmel if (WARN_ON(!policer_item))
182413f2e64bSIdo Schimmel return -EINVAL;
182513f2e64bSIdo Schimmel
182613f2e64bSIdo Schimmel return __mlxsw_sp_trap_policer_set(mlxsw_sp, policer_item->hw_id,
182713f2e64bSIdo Schimmel rate, burst, false, extack);
182813f2e64bSIdo Schimmel }
182913f2e64bSIdo Schimmel
183013f2e64bSIdo Schimmel int
mlxsw_sp_trap_policer_counter_get(struct mlxsw_core * mlxsw_core,const struct devlink_trap_policer * policer,u64 * p_drops)183113f2e64bSIdo Schimmel mlxsw_sp_trap_policer_counter_get(struct mlxsw_core *mlxsw_core,
183213f2e64bSIdo Schimmel const struct devlink_trap_policer *policer,
183313f2e64bSIdo Schimmel u64 *p_drops)
183413f2e64bSIdo Schimmel {
183513f2e64bSIdo Schimmel struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
183613f2e64bSIdo Schimmel struct mlxsw_sp_trap_policer_item *policer_item;
183713f2e64bSIdo Schimmel char qpcr_pl[MLXSW_REG_QPCR_LEN];
183813f2e64bSIdo Schimmel int err;
183913f2e64bSIdo Schimmel
184013f2e64bSIdo Schimmel policer_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, policer->id);
184113f2e64bSIdo Schimmel if (WARN_ON(!policer_item))
184213f2e64bSIdo Schimmel return -EINVAL;
184313f2e64bSIdo Schimmel
184413f2e64bSIdo Schimmel mlxsw_reg_qpcr_pack(qpcr_pl, policer_item->hw_id,
184513f2e64bSIdo Schimmel MLXSW_REG_QPCR_IR_UNITS_M, false, 0, 0);
184613f2e64bSIdo Schimmel err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(qpcr), qpcr_pl);
184713f2e64bSIdo Schimmel if (err)
184813f2e64bSIdo Schimmel return err;
184913f2e64bSIdo Schimmel
185013f2e64bSIdo Schimmel *p_drops = mlxsw_reg_qpcr_violate_count_get(qpcr_pl);
185113f2e64bSIdo Schimmel
185213f2e64bSIdo Schimmel return 0;
185313f2e64bSIdo Schimmel }
185436d1fd68SIdo Schimmel
mlxsw_sp_trap_group_policer_hw_id_get(struct mlxsw_sp * mlxsw_sp,u16 id,bool * p_enabled,u16 * p_hw_id)185554a92385SPetr Machata int mlxsw_sp_trap_group_policer_hw_id_get(struct mlxsw_sp *mlxsw_sp, u16 id,
185654a92385SPetr Machata bool *p_enabled, u16 *p_hw_id)
185754a92385SPetr Machata {
185854a92385SPetr Machata struct mlxsw_sp_trap_policer_item *pol_item;
185954a92385SPetr Machata struct mlxsw_sp_trap_group_item *gr_item;
186054a92385SPetr Machata u32 pol_id;
186154a92385SPetr Machata
186254a92385SPetr Machata gr_item = mlxsw_sp_trap_group_item_lookup(mlxsw_sp, id);
186354a92385SPetr Machata if (!gr_item)
186454a92385SPetr Machata return -ENOENT;
186554a92385SPetr Machata
186654a92385SPetr Machata pol_id = gr_item->group.init_policer_id;
186754a92385SPetr Machata if (!pol_id) {
186854a92385SPetr Machata *p_enabled = false;
186954a92385SPetr Machata return 0;
187054a92385SPetr Machata }
187154a92385SPetr Machata
187254a92385SPetr Machata pol_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, pol_id);
187354a92385SPetr Machata if (WARN_ON(!pol_item))
187454a92385SPetr Machata return -ENOENT;
187554a92385SPetr Machata
187654a92385SPetr Machata *p_enabled = true;
187754a92385SPetr Machata *p_hw_id = pol_item->hw_id;
187854a92385SPetr Machata return 0;
187954a92385SPetr Machata }
188054a92385SPetr Machata
188136d1fd68SIdo Schimmel static const struct mlxsw_sp_trap_group_item
188236d1fd68SIdo Schimmel mlxsw_sp1_trap_group_items_arr[] = {
188334a27721SIdo Schimmel {
188434a27721SIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(ACL_SAMPLE, 0),
188534a27721SIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_PKT_SAMPLE,
188634a27721SIdo Schimmel .priority = 0,
188734a27721SIdo Schimmel },
188836d1fd68SIdo Schimmel };
188936d1fd68SIdo Schimmel
1890869c7be9SIdo Schimmel static const struct mlxsw_sp_trap_item
1891869c7be9SIdo Schimmel mlxsw_sp1_trap_items_arr[] = {
189234a27721SIdo Schimmel {
189334a27721SIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(FLOW_ACTION_SAMPLE, ACL_SAMPLE,
189434a27721SIdo Schimmel MIRROR),
189534a27721SIdo Schimmel .listeners_arr = {
189634a27721SIdo Schimmel MLXSW_RXL(mlxsw_sp_rx_sample_listener, PKT_SAMPLE,
189734a27721SIdo Schimmel MIRROR_TO_CPU, false, SP_PKT_SAMPLE, DISCARD),
189834a27721SIdo Schimmel },
189934a27721SIdo Schimmel },
1900869c7be9SIdo Schimmel };
1901869c7be9SIdo Schimmel
190236d1fd68SIdo Schimmel 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)190336d1fd68SIdo Schimmel mlxsw_sp1_trap_groups_init(struct mlxsw_sp *mlxsw_sp,
190436d1fd68SIdo Schimmel const struct mlxsw_sp_trap_group_item **arr,
190536d1fd68SIdo Schimmel size_t *p_groups_count)
190636d1fd68SIdo Schimmel {
190736d1fd68SIdo Schimmel *arr = mlxsw_sp1_trap_group_items_arr;
190836d1fd68SIdo Schimmel *p_groups_count = ARRAY_SIZE(mlxsw_sp1_trap_group_items_arr);
190936d1fd68SIdo Schimmel
191036d1fd68SIdo Schimmel return 0;
191136d1fd68SIdo Schimmel }
191236d1fd68SIdo Schimmel
mlxsw_sp1_traps_init(struct mlxsw_sp * mlxsw_sp,const struct mlxsw_sp_trap_item ** arr,size_t * p_traps_count)1913869c7be9SIdo Schimmel static int mlxsw_sp1_traps_init(struct mlxsw_sp *mlxsw_sp,
1914869c7be9SIdo Schimmel const struct mlxsw_sp_trap_item **arr,
1915869c7be9SIdo Schimmel size_t *p_traps_count)
1916869c7be9SIdo Schimmel {
1917869c7be9SIdo Schimmel *arr = mlxsw_sp1_trap_items_arr;
1918869c7be9SIdo Schimmel *p_traps_count = ARRAY_SIZE(mlxsw_sp1_trap_items_arr);
1919869c7be9SIdo Schimmel
1920869c7be9SIdo Schimmel return 0;
1921869c7be9SIdo Schimmel }
1922869c7be9SIdo Schimmel
192336d1fd68SIdo Schimmel const struct mlxsw_sp_trap_ops mlxsw_sp1_trap_ops = {
192436d1fd68SIdo Schimmel .groups_init = mlxsw_sp1_trap_groups_init,
1925869c7be9SIdo Schimmel .traps_init = mlxsw_sp1_traps_init,
192636d1fd68SIdo Schimmel };
192736d1fd68SIdo Schimmel
192836d1fd68SIdo Schimmel static const struct mlxsw_sp_trap_group_item
192936d1fd68SIdo Schimmel mlxsw_sp2_trap_group_items_arr[] = {
19306687e953SIdo Schimmel {
19316687e953SIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(BUFFER_DROPS, 20),
19326687e953SIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_BUFFER_DISCARDS,
19336687e953SIdo Schimmel .priority = 0,
19346687e953SIdo Schimmel .fixed_policer = true,
19356687e953SIdo Schimmel },
193634a27721SIdo Schimmel {
193734a27721SIdo Schimmel .group = DEVLINK_TRAP_GROUP_GENERIC(ACL_SAMPLE, 0),
193834a27721SIdo Schimmel .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_PKT_SAMPLE,
193934a27721SIdo Schimmel .priority = 0,
1940cf31190aSIdo Schimmel .fixed_policer = true,
194134a27721SIdo Schimmel },
194236d1fd68SIdo Schimmel };
194336d1fd68SIdo Schimmel
1944869c7be9SIdo Schimmel static const struct mlxsw_sp_trap_item
1945869c7be9SIdo Schimmel mlxsw_sp2_trap_items_arr[] = {
19466687e953SIdo Schimmel {
19476687e953SIdo Schimmel .trap = MLXSW_SP_TRAP_BUFFER_DROP(EARLY_DROP),
19486687e953SIdo Schimmel .listeners_arr = {
19496687e953SIdo Schimmel MLXSW_SP_RXL_BUFFER_DISCARD(INGRESS_WRED),
19506687e953SIdo Schimmel },
19516687e953SIdo Schimmel .is_source = true,
19526687e953SIdo Schimmel },
195334a27721SIdo Schimmel {
195434a27721SIdo Schimmel .trap = MLXSW_SP_TRAP_CONTROL(FLOW_ACTION_SAMPLE, ACL_SAMPLE,
195534a27721SIdo Schimmel MIRROR),
195634a27721SIdo Schimmel .listeners_arr = {
1957cf31190aSIdo Schimmel MLXSW_RXL_MIRROR(mlxsw_sp_rx_sample_listener, 1,
1958cf31190aSIdo Schimmel SP_PKT_SAMPLE,
1959cf31190aSIdo Schimmel MLXSW_SP_MIRROR_REASON_INGRESS),
196054d0e963SIdo Schimmel MLXSW_RXL_MIRROR(mlxsw_sp_rx_sample_tx_listener, 1,
196154d0e963SIdo Schimmel SP_PKT_SAMPLE,
196254d0e963SIdo Schimmel MLXSW_SP_MIRROR_REASON_EGRESS),
196345aad0b7SIdo Schimmel MLXSW_RXL_MIRROR(mlxsw_sp_rx_sample_acl_listener, 1,
196445aad0b7SIdo Schimmel SP_PKT_SAMPLE,
196545aad0b7SIdo Schimmel MLXSW_SP_MIRROR_REASON_POLICY_ENGINE),
196634a27721SIdo Schimmel },
196734a27721SIdo Schimmel },
1968869c7be9SIdo Schimmel };
1969869c7be9SIdo Schimmel
197036d1fd68SIdo Schimmel 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)197136d1fd68SIdo Schimmel mlxsw_sp2_trap_groups_init(struct mlxsw_sp *mlxsw_sp,
197236d1fd68SIdo Schimmel const struct mlxsw_sp_trap_group_item **arr,
197336d1fd68SIdo Schimmel size_t *p_groups_count)
197436d1fd68SIdo Schimmel {
197536d1fd68SIdo Schimmel *arr = mlxsw_sp2_trap_group_items_arr;
197636d1fd68SIdo Schimmel *p_groups_count = ARRAY_SIZE(mlxsw_sp2_trap_group_items_arr);
197736d1fd68SIdo Schimmel
197836d1fd68SIdo Schimmel return 0;
197936d1fd68SIdo Schimmel }
198036d1fd68SIdo Schimmel
mlxsw_sp2_traps_init(struct mlxsw_sp * mlxsw_sp,const struct mlxsw_sp_trap_item ** arr,size_t * p_traps_count)1981869c7be9SIdo Schimmel static int mlxsw_sp2_traps_init(struct mlxsw_sp *mlxsw_sp,
1982869c7be9SIdo Schimmel const struct mlxsw_sp_trap_item **arr,
1983869c7be9SIdo Schimmel size_t *p_traps_count)
1984869c7be9SIdo Schimmel {
1985869c7be9SIdo Schimmel *arr = mlxsw_sp2_trap_items_arr;
1986869c7be9SIdo Schimmel *p_traps_count = ARRAY_SIZE(mlxsw_sp2_trap_items_arr);
1987869c7be9SIdo Schimmel
1988869c7be9SIdo Schimmel return 0;
1989869c7be9SIdo Schimmel }
1990869c7be9SIdo Schimmel
199136d1fd68SIdo Schimmel const struct mlxsw_sp_trap_ops mlxsw_sp2_trap_ops = {
199236d1fd68SIdo Schimmel .groups_init = mlxsw_sp2_trap_groups_init,
1993869c7be9SIdo Schimmel .traps_init = mlxsw_sp2_traps_init,
199436d1fd68SIdo Schimmel };
1995