162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 262306a36Sopenharmony_ci/* Copyright (c) 2019 Mellanox Technologies. All rights reserved */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include <linux/bitops.h> 562306a36Sopenharmony_ci#include <linux/kernel.h> 662306a36Sopenharmony_ci#include <linux/netlink.h> 762306a36Sopenharmony_ci#include <net/devlink.h> 862306a36Sopenharmony_ci#include <uapi/linux/devlink.h> 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include "core.h" 1162306a36Sopenharmony_ci#include "reg.h" 1262306a36Sopenharmony_ci#include "spectrum.h" 1362306a36Sopenharmony_ci#include "spectrum_trap.h" 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_cistruct mlxsw_sp_trap_policer_item { 1662306a36Sopenharmony_ci struct devlink_trap_policer policer; 1762306a36Sopenharmony_ci u16 hw_id; 1862306a36Sopenharmony_ci}; 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistruct mlxsw_sp_trap_group_item { 2162306a36Sopenharmony_ci struct devlink_trap_group group; 2262306a36Sopenharmony_ci u16 hw_group_id; 2362306a36Sopenharmony_ci u8 priority; 2462306a36Sopenharmony_ci u8 fixed_policer:1; /* Whether policer binding can change */ 2562306a36Sopenharmony_ci}; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#define MLXSW_SP_TRAP_LISTENERS_MAX 3 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_cistruct mlxsw_sp_trap_item { 3062306a36Sopenharmony_ci struct devlink_trap trap; 3162306a36Sopenharmony_ci struct mlxsw_listener listeners_arr[MLXSW_SP_TRAP_LISTENERS_MAX]; 3262306a36Sopenharmony_ci u8 is_source:1; 3362306a36Sopenharmony_ci}; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci/* All driver-specific traps must be documented in 3662306a36Sopenharmony_ci * Documentation/networking/devlink/mlxsw.rst 3762306a36Sopenharmony_ci */ 3862306a36Sopenharmony_cienum { 3962306a36Sopenharmony_ci DEVLINK_MLXSW_TRAP_ID_BASE = DEVLINK_TRAP_GENERIC_ID_MAX, 4062306a36Sopenharmony_ci DEVLINK_MLXSW_TRAP_ID_IRIF_DISABLED, 4162306a36Sopenharmony_ci DEVLINK_MLXSW_TRAP_ID_ERIF_DISABLED, 4262306a36Sopenharmony_ci}; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci#define DEVLINK_MLXSW_TRAP_NAME_IRIF_DISABLED \ 4562306a36Sopenharmony_ci "irif_disabled" 4662306a36Sopenharmony_ci#define DEVLINK_MLXSW_TRAP_NAME_ERIF_DISABLED \ 4762306a36Sopenharmony_ci "erif_disabled" 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci#define MLXSW_SP_TRAP_METADATA DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cienum { 5262306a36Sopenharmony_ci /* Packet was mirrored from ingress. */ 5362306a36Sopenharmony_ci MLXSW_SP_MIRROR_REASON_INGRESS = 1, 5462306a36Sopenharmony_ci /* Packet was mirrored from policy engine. */ 5562306a36Sopenharmony_ci MLXSW_SP_MIRROR_REASON_POLICY_ENGINE = 2, 5662306a36Sopenharmony_ci /* Packet was early dropped. */ 5762306a36Sopenharmony_ci MLXSW_SP_MIRROR_REASON_INGRESS_WRED = 9, 5862306a36Sopenharmony_ci /* Packet was mirrored from egress. */ 5962306a36Sopenharmony_ci MLXSW_SP_MIRROR_REASON_EGRESS = 14, 6062306a36Sopenharmony_ci}; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_cistatic int mlxsw_sp_rx_listener(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb, 6362306a36Sopenharmony_ci u16 local_port, 6462306a36Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port) 6562306a36Sopenharmony_ci{ 6662306a36Sopenharmony_ci struct mlxsw_sp_port_pcpu_stats *pcpu_stats; 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci if (unlikely(!mlxsw_sp_port)) { 6962306a36Sopenharmony_ci dev_warn_ratelimited(mlxsw_sp->bus_info->dev, "Port %d: skb received for non-existent port\n", 7062306a36Sopenharmony_ci local_port); 7162306a36Sopenharmony_ci kfree_skb(skb); 7262306a36Sopenharmony_ci return -EINVAL; 7362306a36Sopenharmony_ci } 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci skb->dev = mlxsw_sp_port->dev; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci pcpu_stats = this_cpu_ptr(mlxsw_sp_port->pcpu_stats); 7862306a36Sopenharmony_ci u64_stats_update_begin(&pcpu_stats->syncp); 7962306a36Sopenharmony_ci pcpu_stats->rx_packets++; 8062306a36Sopenharmony_ci pcpu_stats->rx_bytes += skb->len; 8162306a36Sopenharmony_ci u64_stats_update_end(&pcpu_stats->syncp); 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci skb->protocol = eth_type_trans(skb, skb->dev); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci return 0; 8662306a36Sopenharmony_ci} 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_cistatic void mlxsw_sp_rx_drop_listener(struct sk_buff *skb, u16 local_port, 8962306a36Sopenharmony_ci void *trap_ctx) 9062306a36Sopenharmony_ci{ 9162306a36Sopenharmony_ci struct devlink_port *in_devlink_port; 9262306a36Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port; 9362306a36Sopenharmony_ci struct mlxsw_sp *mlxsw_sp; 9462306a36Sopenharmony_ci struct devlink *devlink; 9562306a36Sopenharmony_ci int err; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci mlxsw_sp = devlink_trap_ctx_priv(trap_ctx); 9862306a36Sopenharmony_ci mlxsw_sp_port = mlxsw_sp->ports[local_port]; 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci err = mlxsw_sp_rx_listener(mlxsw_sp, skb, local_port, mlxsw_sp_port); 10162306a36Sopenharmony_ci if (err) 10262306a36Sopenharmony_ci return; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci devlink = priv_to_devlink(mlxsw_sp->core); 10562306a36Sopenharmony_ci in_devlink_port = mlxsw_core_port_devlink_port_get(mlxsw_sp->core, 10662306a36Sopenharmony_ci local_port); 10762306a36Sopenharmony_ci skb_push(skb, ETH_HLEN); 10862306a36Sopenharmony_ci devlink_trap_report(devlink, skb, trap_ctx, in_devlink_port, NULL); 10962306a36Sopenharmony_ci consume_skb(skb); 11062306a36Sopenharmony_ci} 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_cistatic void mlxsw_sp_rx_acl_drop_listener(struct sk_buff *skb, u16 local_port, 11362306a36Sopenharmony_ci void *trap_ctx) 11462306a36Sopenharmony_ci{ 11562306a36Sopenharmony_ci u32 cookie_index = mlxsw_skb_cb(skb)->rx_md_info.cookie_index; 11662306a36Sopenharmony_ci const struct flow_action_cookie *fa_cookie; 11762306a36Sopenharmony_ci struct devlink_port *in_devlink_port; 11862306a36Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port; 11962306a36Sopenharmony_ci struct mlxsw_sp *mlxsw_sp; 12062306a36Sopenharmony_ci struct devlink *devlink; 12162306a36Sopenharmony_ci int err; 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci mlxsw_sp = devlink_trap_ctx_priv(trap_ctx); 12462306a36Sopenharmony_ci mlxsw_sp_port = mlxsw_sp->ports[local_port]; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci err = mlxsw_sp_rx_listener(mlxsw_sp, skb, local_port, mlxsw_sp_port); 12762306a36Sopenharmony_ci if (err) 12862306a36Sopenharmony_ci return; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci devlink = priv_to_devlink(mlxsw_sp->core); 13162306a36Sopenharmony_ci in_devlink_port = mlxsw_core_port_devlink_port_get(mlxsw_sp->core, 13262306a36Sopenharmony_ci local_port); 13362306a36Sopenharmony_ci skb_push(skb, ETH_HLEN); 13462306a36Sopenharmony_ci rcu_read_lock(); 13562306a36Sopenharmony_ci fa_cookie = mlxsw_sp_acl_act_cookie_lookup(mlxsw_sp, cookie_index); 13662306a36Sopenharmony_ci devlink_trap_report(devlink, skb, trap_ctx, in_devlink_port, fa_cookie); 13762306a36Sopenharmony_ci rcu_read_unlock(); 13862306a36Sopenharmony_ci consume_skb(skb); 13962306a36Sopenharmony_ci} 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cistatic int __mlxsw_sp_rx_no_mark_listener(struct sk_buff *skb, u16 local_port, 14262306a36Sopenharmony_ci void *trap_ctx) 14362306a36Sopenharmony_ci{ 14462306a36Sopenharmony_ci struct devlink_port *in_devlink_port; 14562306a36Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port; 14662306a36Sopenharmony_ci struct mlxsw_sp *mlxsw_sp; 14762306a36Sopenharmony_ci struct devlink *devlink; 14862306a36Sopenharmony_ci int err; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci mlxsw_sp = devlink_trap_ctx_priv(trap_ctx); 15162306a36Sopenharmony_ci mlxsw_sp_port = mlxsw_sp->ports[local_port]; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci err = mlxsw_sp_rx_listener(mlxsw_sp, skb, local_port, mlxsw_sp_port); 15462306a36Sopenharmony_ci if (err) 15562306a36Sopenharmony_ci return err; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci devlink = priv_to_devlink(mlxsw_sp->core); 15862306a36Sopenharmony_ci in_devlink_port = mlxsw_core_port_devlink_port_get(mlxsw_sp->core, 15962306a36Sopenharmony_ci local_port); 16062306a36Sopenharmony_ci skb_push(skb, ETH_HLEN); 16162306a36Sopenharmony_ci devlink_trap_report(devlink, skb, trap_ctx, in_devlink_port, NULL); 16262306a36Sopenharmony_ci skb_pull(skb, ETH_HLEN); 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci return 0; 16562306a36Sopenharmony_ci} 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_cistatic void mlxsw_sp_rx_no_mark_listener(struct sk_buff *skb, u16 local_port, 16862306a36Sopenharmony_ci void *trap_ctx) 16962306a36Sopenharmony_ci{ 17062306a36Sopenharmony_ci int err; 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci err = __mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx); 17362306a36Sopenharmony_ci if (err) 17462306a36Sopenharmony_ci return; 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci netif_receive_skb(skb); 17762306a36Sopenharmony_ci} 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_cistatic void mlxsw_sp_rx_mark_listener(struct sk_buff *skb, u16 local_port, 18062306a36Sopenharmony_ci void *trap_ctx) 18162306a36Sopenharmony_ci{ 18262306a36Sopenharmony_ci skb->offload_fwd_mark = 1; 18362306a36Sopenharmony_ci mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx); 18462306a36Sopenharmony_ci} 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_cistatic void mlxsw_sp_rx_l3_mark_listener(struct sk_buff *skb, u16 local_port, 18762306a36Sopenharmony_ci void *trap_ctx) 18862306a36Sopenharmony_ci{ 18962306a36Sopenharmony_ci skb->offload_l3_fwd_mark = 1; 19062306a36Sopenharmony_ci skb->offload_fwd_mark = 1; 19162306a36Sopenharmony_ci mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx); 19262306a36Sopenharmony_ci} 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_cistatic void mlxsw_sp_rx_ptp_listener(struct sk_buff *skb, u16 local_port, 19562306a36Sopenharmony_ci void *trap_ctx) 19662306a36Sopenharmony_ci{ 19762306a36Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = devlink_trap_ctx_priv(trap_ctx); 19862306a36Sopenharmony_ci int err; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci err = __mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx); 20162306a36Sopenharmony_ci if (err) 20262306a36Sopenharmony_ci return; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci /* The PTP handler expects skb->data to point to the start of the 20562306a36Sopenharmony_ci * Ethernet header. 20662306a36Sopenharmony_ci */ 20762306a36Sopenharmony_ci skb_push(skb, ETH_HLEN); 20862306a36Sopenharmony_ci mlxsw_sp_ptp_receive(mlxsw_sp, skb, local_port); 20962306a36Sopenharmony_ci} 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_cistatic struct mlxsw_sp_port * 21262306a36Sopenharmony_cimlxsw_sp_sample_tx_port_get(struct mlxsw_sp *mlxsw_sp, 21362306a36Sopenharmony_ci const struct mlxsw_rx_md_info *rx_md_info) 21462306a36Sopenharmony_ci{ 21562306a36Sopenharmony_ci u16 local_port; 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci if (!rx_md_info->tx_port_valid) 21862306a36Sopenharmony_ci return NULL; 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci if (rx_md_info->tx_port_is_lag) 22162306a36Sopenharmony_ci local_port = mlxsw_core_lag_mapping_get(mlxsw_sp->core, 22262306a36Sopenharmony_ci rx_md_info->tx_lag_id, 22362306a36Sopenharmony_ci rx_md_info->tx_lag_port_index); 22462306a36Sopenharmony_ci else 22562306a36Sopenharmony_ci local_port = rx_md_info->tx_sys_port; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci if (local_port >= mlxsw_core_max_ports(mlxsw_sp->core)) 22862306a36Sopenharmony_ci return NULL; 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci return mlxsw_sp->ports[local_port]; 23162306a36Sopenharmony_ci} 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci/* The latency units are determined according to MOGCR.mirror_latency_units. It 23462306a36Sopenharmony_ci * defaults to 64 nanoseconds. 23562306a36Sopenharmony_ci */ 23662306a36Sopenharmony_ci#define MLXSW_SP_MIRROR_LATENCY_SHIFT 6 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_cistatic void mlxsw_sp_psample_md_init(struct mlxsw_sp *mlxsw_sp, 23962306a36Sopenharmony_ci struct psample_metadata *md, 24062306a36Sopenharmony_ci struct sk_buff *skb, int in_ifindex, 24162306a36Sopenharmony_ci bool truncate, u32 trunc_size) 24262306a36Sopenharmony_ci{ 24362306a36Sopenharmony_ci struct mlxsw_rx_md_info *rx_md_info = &mlxsw_skb_cb(skb)->rx_md_info; 24462306a36Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci md->trunc_size = truncate ? trunc_size : skb->len; 24762306a36Sopenharmony_ci md->in_ifindex = in_ifindex; 24862306a36Sopenharmony_ci mlxsw_sp_port = mlxsw_sp_sample_tx_port_get(mlxsw_sp, rx_md_info); 24962306a36Sopenharmony_ci md->out_ifindex = mlxsw_sp_port && mlxsw_sp_port->dev ? 25062306a36Sopenharmony_ci mlxsw_sp_port->dev->ifindex : 0; 25162306a36Sopenharmony_ci md->out_tc_valid = rx_md_info->tx_tc_valid; 25262306a36Sopenharmony_ci md->out_tc = rx_md_info->tx_tc; 25362306a36Sopenharmony_ci md->out_tc_occ_valid = rx_md_info->tx_congestion_valid; 25462306a36Sopenharmony_ci md->out_tc_occ = rx_md_info->tx_congestion; 25562306a36Sopenharmony_ci md->latency_valid = rx_md_info->latency_valid; 25662306a36Sopenharmony_ci md->latency = rx_md_info->latency; 25762306a36Sopenharmony_ci md->latency <<= MLXSW_SP_MIRROR_LATENCY_SHIFT; 25862306a36Sopenharmony_ci} 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_cistatic void mlxsw_sp_rx_sample_listener(struct sk_buff *skb, u16 local_port, 26162306a36Sopenharmony_ci void *trap_ctx) 26262306a36Sopenharmony_ci{ 26362306a36Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = devlink_trap_ctx_priv(trap_ctx); 26462306a36Sopenharmony_ci struct mlxsw_sp_sample_trigger trigger; 26562306a36Sopenharmony_ci struct mlxsw_sp_sample_params *params; 26662306a36Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port; 26762306a36Sopenharmony_ci struct psample_metadata md = {}; 26862306a36Sopenharmony_ci int err; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci err = __mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx); 27162306a36Sopenharmony_ci if (err) 27262306a36Sopenharmony_ci return; 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci mlxsw_sp_port = mlxsw_sp->ports[local_port]; 27562306a36Sopenharmony_ci if (!mlxsw_sp_port) 27662306a36Sopenharmony_ci goto out; 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci trigger.type = MLXSW_SP_SAMPLE_TRIGGER_TYPE_INGRESS; 27962306a36Sopenharmony_ci trigger.local_port = local_port; 28062306a36Sopenharmony_ci params = mlxsw_sp_sample_trigger_params_lookup(mlxsw_sp, &trigger); 28162306a36Sopenharmony_ci if (!params) 28262306a36Sopenharmony_ci goto out; 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci /* The psample module expects skb->data to point to the start of the 28562306a36Sopenharmony_ci * Ethernet header. 28662306a36Sopenharmony_ci */ 28762306a36Sopenharmony_ci skb_push(skb, ETH_HLEN); 28862306a36Sopenharmony_ci mlxsw_sp_psample_md_init(mlxsw_sp, &md, skb, 28962306a36Sopenharmony_ci mlxsw_sp_port->dev->ifindex, params->truncate, 29062306a36Sopenharmony_ci params->trunc_size); 29162306a36Sopenharmony_ci psample_sample_packet(params->psample_group, skb, params->rate, &md); 29262306a36Sopenharmony_ciout: 29362306a36Sopenharmony_ci consume_skb(skb); 29462306a36Sopenharmony_ci} 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_cistatic void mlxsw_sp_rx_sample_tx_listener(struct sk_buff *skb, u16 local_port, 29762306a36Sopenharmony_ci void *trap_ctx) 29862306a36Sopenharmony_ci{ 29962306a36Sopenharmony_ci struct mlxsw_rx_md_info *rx_md_info = &mlxsw_skb_cb(skb)->rx_md_info; 30062306a36Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = devlink_trap_ctx_priv(trap_ctx); 30162306a36Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port, *mlxsw_sp_port_tx; 30262306a36Sopenharmony_ci struct mlxsw_sp_sample_trigger trigger; 30362306a36Sopenharmony_ci struct mlxsw_sp_sample_params *params; 30462306a36Sopenharmony_ci struct psample_metadata md = {}; 30562306a36Sopenharmony_ci int err; 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci /* Locally generated packets are not reported from the policy engine 30862306a36Sopenharmony_ci * trigger, so do not report them from the egress trigger as well. 30962306a36Sopenharmony_ci */ 31062306a36Sopenharmony_ci if (local_port == MLXSW_PORT_CPU_PORT) 31162306a36Sopenharmony_ci goto out; 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci err = __mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx); 31462306a36Sopenharmony_ci if (err) 31562306a36Sopenharmony_ci return; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci mlxsw_sp_port = mlxsw_sp->ports[local_port]; 31862306a36Sopenharmony_ci if (!mlxsw_sp_port) 31962306a36Sopenharmony_ci goto out; 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci /* Packet was sampled from Tx, so we need to retrieve the sample 32262306a36Sopenharmony_ci * parameters based on the Tx port and not the Rx port. 32362306a36Sopenharmony_ci */ 32462306a36Sopenharmony_ci mlxsw_sp_port_tx = mlxsw_sp_sample_tx_port_get(mlxsw_sp, rx_md_info); 32562306a36Sopenharmony_ci if (!mlxsw_sp_port_tx) 32662306a36Sopenharmony_ci goto out; 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci trigger.type = MLXSW_SP_SAMPLE_TRIGGER_TYPE_EGRESS; 32962306a36Sopenharmony_ci trigger.local_port = mlxsw_sp_port_tx->local_port; 33062306a36Sopenharmony_ci params = mlxsw_sp_sample_trigger_params_lookup(mlxsw_sp, &trigger); 33162306a36Sopenharmony_ci if (!params) 33262306a36Sopenharmony_ci goto out; 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci /* The psample module expects skb->data to point to the start of the 33562306a36Sopenharmony_ci * Ethernet header. 33662306a36Sopenharmony_ci */ 33762306a36Sopenharmony_ci skb_push(skb, ETH_HLEN); 33862306a36Sopenharmony_ci mlxsw_sp_psample_md_init(mlxsw_sp, &md, skb, 33962306a36Sopenharmony_ci mlxsw_sp_port->dev->ifindex, params->truncate, 34062306a36Sopenharmony_ci params->trunc_size); 34162306a36Sopenharmony_ci psample_sample_packet(params->psample_group, skb, params->rate, &md); 34262306a36Sopenharmony_ciout: 34362306a36Sopenharmony_ci consume_skb(skb); 34462306a36Sopenharmony_ci} 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_cistatic void mlxsw_sp_rx_sample_acl_listener(struct sk_buff *skb, u16 local_port, 34762306a36Sopenharmony_ci void *trap_ctx) 34862306a36Sopenharmony_ci{ 34962306a36Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = devlink_trap_ctx_priv(trap_ctx); 35062306a36Sopenharmony_ci struct mlxsw_sp_sample_trigger trigger = { 35162306a36Sopenharmony_ci .type = MLXSW_SP_SAMPLE_TRIGGER_TYPE_POLICY_ENGINE, 35262306a36Sopenharmony_ci }; 35362306a36Sopenharmony_ci struct mlxsw_sp_sample_params *params; 35462306a36Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port; 35562306a36Sopenharmony_ci struct psample_metadata md = {}; 35662306a36Sopenharmony_ci int err; 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci err = __mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx); 35962306a36Sopenharmony_ci if (err) 36062306a36Sopenharmony_ci return; 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci mlxsw_sp_port = mlxsw_sp->ports[local_port]; 36362306a36Sopenharmony_ci if (!mlxsw_sp_port) 36462306a36Sopenharmony_ci goto out; 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci params = mlxsw_sp_sample_trigger_params_lookup(mlxsw_sp, &trigger); 36762306a36Sopenharmony_ci if (!params) 36862306a36Sopenharmony_ci goto out; 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci /* The psample module expects skb->data to point to the start of the 37162306a36Sopenharmony_ci * Ethernet header. 37262306a36Sopenharmony_ci */ 37362306a36Sopenharmony_ci skb_push(skb, ETH_HLEN); 37462306a36Sopenharmony_ci mlxsw_sp_psample_md_init(mlxsw_sp, &md, skb, 37562306a36Sopenharmony_ci mlxsw_sp_port->dev->ifindex, params->truncate, 37662306a36Sopenharmony_ci params->trunc_size); 37762306a36Sopenharmony_ci psample_sample_packet(params->psample_group, skb, params->rate, &md); 37862306a36Sopenharmony_ciout: 37962306a36Sopenharmony_ci consume_skb(skb); 38062306a36Sopenharmony_ci} 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci#define MLXSW_SP_TRAP_DROP(_id, _group_id) \ 38362306a36Sopenharmony_ci DEVLINK_TRAP_GENERIC(DROP, DROP, _id, \ 38462306a36Sopenharmony_ci DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \ 38562306a36Sopenharmony_ci MLXSW_SP_TRAP_METADATA) 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci#define MLXSW_SP_TRAP_DROP_EXT(_id, _group_id, _metadata) \ 38862306a36Sopenharmony_ci DEVLINK_TRAP_GENERIC(DROP, DROP, _id, \ 38962306a36Sopenharmony_ci DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \ 39062306a36Sopenharmony_ci MLXSW_SP_TRAP_METADATA | (_metadata)) 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci#define MLXSW_SP_TRAP_BUFFER_DROP(_id) \ 39362306a36Sopenharmony_ci DEVLINK_TRAP_GENERIC(DROP, TRAP, _id, \ 39462306a36Sopenharmony_ci DEVLINK_TRAP_GROUP_GENERIC_ID_BUFFER_DROPS, \ 39562306a36Sopenharmony_ci MLXSW_SP_TRAP_METADATA) 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_ci#define MLXSW_SP_TRAP_DRIVER_DROP(_id, _group_id) \ 39862306a36Sopenharmony_ci DEVLINK_TRAP_DRIVER(DROP, DROP, DEVLINK_MLXSW_TRAP_ID_##_id, \ 39962306a36Sopenharmony_ci DEVLINK_MLXSW_TRAP_NAME_##_id, \ 40062306a36Sopenharmony_ci DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \ 40162306a36Sopenharmony_ci MLXSW_SP_TRAP_METADATA) 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci#define MLXSW_SP_TRAP_EXCEPTION(_id, _group_id) \ 40462306a36Sopenharmony_ci DEVLINK_TRAP_GENERIC(EXCEPTION, TRAP, _id, \ 40562306a36Sopenharmony_ci DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \ 40662306a36Sopenharmony_ci MLXSW_SP_TRAP_METADATA) 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_ci#define MLXSW_SP_TRAP_CONTROL(_id, _group_id, _action) \ 40962306a36Sopenharmony_ci DEVLINK_TRAP_GENERIC(CONTROL, _action, _id, \ 41062306a36Sopenharmony_ci DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \ 41162306a36Sopenharmony_ci MLXSW_SP_TRAP_METADATA) 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci#define MLXSW_SP_RXL_DISCARD(_id, _group_id) \ 41462306a36Sopenharmony_ci MLXSW_RXL_DIS(mlxsw_sp_rx_drop_listener, DISCARD_##_id, \ 41562306a36Sopenharmony_ci TRAP_EXCEPTION_TO_CPU, false, SP_##_group_id, \ 41662306a36Sopenharmony_ci SET_FW_DEFAULT, SP_##_group_id) 41762306a36Sopenharmony_ci 41862306a36Sopenharmony_ci#define MLXSW_SP_RXL_ACL_DISCARD(_id, _en_group_id, _dis_group_id) \ 41962306a36Sopenharmony_ci MLXSW_RXL_DIS(mlxsw_sp_rx_acl_drop_listener, DISCARD_##_id, \ 42062306a36Sopenharmony_ci TRAP_EXCEPTION_TO_CPU, false, SP_##_en_group_id, \ 42162306a36Sopenharmony_ci SET_FW_DEFAULT, SP_##_dis_group_id) 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_ci#define MLXSW_SP_RXL_BUFFER_DISCARD(_mirror_reason) \ 42462306a36Sopenharmony_ci MLXSW_RXL_MIRROR(mlxsw_sp_rx_drop_listener, 0, SP_BUFFER_DISCARDS, \ 42562306a36Sopenharmony_ci MLXSW_SP_MIRROR_REASON_##_mirror_reason) 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_ci#define MLXSW_SP_RXL_EXCEPTION(_id, _group_id, _action) \ 42862306a36Sopenharmony_ci MLXSW_RXL(mlxsw_sp_rx_mark_listener, _id, \ 42962306a36Sopenharmony_ci _action, false, SP_##_group_id, SET_FW_DEFAULT) 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci#define MLXSW_SP_RXL_NO_MARK(_id, _group_id, _action, _is_ctrl) \ 43262306a36Sopenharmony_ci MLXSW_RXL(mlxsw_sp_rx_no_mark_listener, _id, _action, \ 43362306a36Sopenharmony_ci _is_ctrl, SP_##_group_id, DISCARD) 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ci#define MLXSW_SP_RXL_MARK(_id, _group_id, _action, _is_ctrl) \ 43662306a36Sopenharmony_ci MLXSW_RXL(mlxsw_sp_rx_mark_listener, _id, _action, _is_ctrl, \ 43762306a36Sopenharmony_ci SP_##_group_id, DISCARD) 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci#define MLXSW_SP_RXL_L3_MARK(_id, _group_id, _action, _is_ctrl) \ 44062306a36Sopenharmony_ci MLXSW_RXL(mlxsw_sp_rx_l3_mark_listener, _id, _action, _is_ctrl, \ 44162306a36Sopenharmony_ci SP_##_group_id, DISCARD) 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci#define MLXSW_SP_TRAP_POLICER(_id, _rate, _burst) \ 44462306a36Sopenharmony_ci DEVLINK_TRAP_POLICER(_id, _rate, _burst, \ 44562306a36Sopenharmony_ci MLXSW_REG_QPCR_HIGHEST_CIR, \ 44662306a36Sopenharmony_ci MLXSW_REG_QPCR_LOWEST_CIR, \ 44762306a36Sopenharmony_ci 1 << MLXSW_REG_QPCR_HIGHEST_CBS, \ 44862306a36Sopenharmony_ci 1 << MLXSW_REG_QPCR_LOWEST_CBS) 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci/* Ordered by policer identifier */ 45162306a36Sopenharmony_cistatic const struct mlxsw_sp_trap_policer_item 45262306a36Sopenharmony_cimlxsw_sp_trap_policer_items_arr[] = { 45362306a36Sopenharmony_ci { 45462306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(1, 10 * 1024, 4096), 45562306a36Sopenharmony_ci }, 45662306a36Sopenharmony_ci { 45762306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(2, 128, 128), 45862306a36Sopenharmony_ci }, 45962306a36Sopenharmony_ci { 46062306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(3, 128, 128), 46162306a36Sopenharmony_ci }, 46262306a36Sopenharmony_ci { 46362306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(4, 128, 128), 46462306a36Sopenharmony_ci }, 46562306a36Sopenharmony_ci { 46662306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(5, 16 * 1024, 8192), 46762306a36Sopenharmony_ci }, 46862306a36Sopenharmony_ci { 46962306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(6, 128, 128), 47062306a36Sopenharmony_ci }, 47162306a36Sopenharmony_ci { 47262306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(7, 1024, 512), 47362306a36Sopenharmony_ci }, 47462306a36Sopenharmony_ci { 47562306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(8, 20 * 1024, 8192), 47662306a36Sopenharmony_ci }, 47762306a36Sopenharmony_ci { 47862306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(9, 128, 128), 47962306a36Sopenharmony_ci }, 48062306a36Sopenharmony_ci { 48162306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(10, 1024, 512), 48262306a36Sopenharmony_ci }, 48362306a36Sopenharmony_ci { 48462306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(11, 256, 128), 48562306a36Sopenharmony_ci }, 48662306a36Sopenharmony_ci { 48762306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(12, 128, 128), 48862306a36Sopenharmony_ci }, 48962306a36Sopenharmony_ci { 49062306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(13, 128, 128), 49162306a36Sopenharmony_ci }, 49262306a36Sopenharmony_ci { 49362306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(14, 1024, 512), 49462306a36Sopenharmony_ci }, 49562306a36Sopenharmony_ci { 49662306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(15, 1024, 512), 49762306a36Sopenharmony_ci }, 49862306a36Sopenharmony_ci { 49962306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(16, 24 * 1024, 16384), 50062306a36Sopenharmony_ci }, 50162306a36Sopenharmony_ci { 50262306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(17, 19 * 1024, 8192), 50362306a36Sopenharmony_ci }, 50462306a36Sopenharmony_ci { 50562306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(18, 1024, 512), 50662306a36Sopenharmony_ci }, 50762306a36Sopenharmony_ci { 50862306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(19, 1024, 512), 50962306a36Sopenharmony_ci }, 51062306a36Sopenharmony_ci { 51162306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(20, 10240, 4096), 51262306a36Sopenharmony_ci }, 51362306a36Sopenharmony_ci { 51462306a36Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(21, 128, 128), 51562306a36Sopenharmony_ci }, 51662306a36Sopenharmony_ci}; 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_cistatic const struct mlxsw_sp_trap_group_item mlxsw_sp_trap_group_items_arr[] = { 51962306a36Sopenharmony_ci { 52062306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS, 1), 52162306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_L2_DISCARDS, 52262306a36Sopenharmony_ci .priority = 0, 52362306a36Sopenharmony_ci }, 52462306a36Sopenharmony_ci { 52562306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(L3_DROPS, 1), 52662306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_L3_DISCARDS, 52762306a36Sopenharmony_ci .priority = 0, 52862306a36Sopenharmony_ci }, 52962306a36Sopenharmony_ci { 53062306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(L3_EXCEPTIONS, 1), 53162306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_L3_EXCEPTIONS, 53262306a36Sopenharmony_ci .priority = 2, 53362306a36Sopenharmony_ci }, 53462306a36Sopenharmony_ci { 53562306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(TUNNEL_DROPS, 1), 53662306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_TUNNEL_DISCARDS, 53762306a36Sopenharmony_ci .priority = 0, 53862306a36Sopenharmony_ci }, 53962306a36Sopenharmony_ci { 54062306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(ACL_DROPS, 1), 54162306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_ACL_DISCARDS, 54262306a36Sopenharmony_ci .priority = 0, 54362306a36Sopenharmony_ci }, 54462306a36Sopenharmony_ci { 54562306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(STP, 2), 54662306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_STP, 54762306a36Sopenharmony_ci .priority = 5, 54862306a36Sopenharmony_ci }, 54962306a36Sopenharmony_ci { 55062306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(LACP, 3), 55162306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_LACP, 55262306a36Sopenharmony_ci .priority = 5, 55362306a36Sopenharmony_ci }, 55462306a36Sopenharmony_ci { 55562306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(LLDP, 4), 55662306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_LLDP, 55762306a36Sopenharmony_ci .priority = 5, 55862306a36Sopenharmony_ci }, 55962306a36Sopenharmony_ci { 56062306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(MC_SNOOPING, 5), 56162306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_MC_SNOOPING, 56262306a36Sopenharmony_ci .priority = 3, 56362306a36Sopenharmony_ci }, 56462306a36Sopenharmony_ci { 56562306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(DHCP, 6), 56662306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_DHCP, 56762306a36Sopenharmony_ci .priority = 2, 56862306a36Sopenharmony_ci }, 56962306a36Sopenharmony_ci { 57062306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(NEIGH_DISCOVERY, 7), 57162306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_NEIGH_DISCOVERY, 57262306a36Sopenharmony_ci .priority = 2, 57362306a36Sopenharmony_ci }, 57462306a36Sopenharmony_ci { 57562306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(BFD, 8), 57662306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_BFD, 57762306a36Sopenharmony_ci .priority = 5, 57862306a36Sopenharmony_ci }, 57962306a36Sopenharmony_ci { 58062306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(OSPF, 9), 58162306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF, 58262306a36Sopenharmony_ci .priority = 5, 58362306a36Sopenharmony_ci }, 58462306a36Sopenharmony_ci { 58562306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(BGP, 10), 58662306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_BGP, 58762306a36Sopenharmony_ci .priority = 4, 58862306a36Sopenharmony_ci }, 58962306a36Sopenharmony_ci { 59062306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(VRRP, 11), 59162306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_VRRP, 59262306a36Sopenharmony_ci .priority = 5, 59362306a36Sopenharmony_ci }, 59462306a36Sopenharmony_ci { 59562306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(PIM, 12), 59662306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_PIM, 59762306a36Sopenharmony_ci .priority = 5, 59862306a36Sopenharmony_ci }, 59962306a36Sopenharmony_ci { 60062306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(UC_LB, 13), 60162306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_LBERROR, 60262306a36Sopenharmony_ci .priority = 0, 60362306a36Sopenharmony_ci }, 60462306a36Sopenharmony_ci { 60562306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(LOCAL_DELIVERY, 14), 60662306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_IP2ME, 60762306a36Sopenharmony_ci .priority = 2, 60862306a36Sopenharmony_ci }, 60962306a36Sopenharmony_ci { 61062306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(EXTERNAL_DELIVERY, 19), 61162306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_EXTERNAL_ROUTE, 61262306a36Sopenharmony_ci .priority = 1, 61362306a36Sopenharmony_ci }, 61462306a36Sopenharmony_ci { 61562306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(IPV6, 15), 61662306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_IPV6, 61762306a36Sopenharmony_ci .priority = 2, 61862306a36Sopenharmony_ci }, 61962306a36Sopenharmony_ci { 62062306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(PTP_EVENT, 16), 62162306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP0, 62262306a36Sopenharmony_ci .priority = 5, 62362306a36Sopenharmony_ci }, 62462306a36Sopenharmony_ci { 62562306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(PTP_GENERAL, 17), 62662306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP1, 62762306a36Sopenharmony_ci .priority = 2, 62862306a36Sopenharmony_ci }, 62962306a36Sopenharmony_ci { 63062306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(ACL_TRAP, 18), 63162306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_FLOW_LOGGING, 63262306a36Sopenharmony_ci .priority = 4, 63362306a36Sopenharmony_ci }, 63462306a36Sopenharmony_ci { 63562306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(EAPOL, 21), 63662306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_EAPOL, 63762306a36Sopenharmony_ci .priority = 5, 63862306a36Sopenharmony_ci }, 63962306a36Sopenharmony_ci}; 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_cistatic const struct mlxsw_sp_trap_item mlxsw_sp_trap_items_arr[] = { 64262306a36Sopenharmony_ci { 64362306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(SMAC_MC, L2_DROPS), 64462306a36Sopenharmony_ci .listeners_arr = { 64562306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_PACKET_SMAC_MC, L2_DISCARDS), 64662306a36Sopenharmony_ci }, 64762306a36Sopenharmony_ci }, 64862306a36Sopenharmony_ci { 64962306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(VLAN_TAG_MISMATCH, L2_DROPS), 65062306a36Sopenharmony_ci .listeners_arr = { 65162306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_SWITCH_VTAG_ALLOW, 65262306a36Sopenharmony_ci L2_DISCARDS), 65362306a36Sopenharmony_ci }, 65462306a36Sopenharmony_ci }, 65562306a36Sopenharmony_ci { 65662306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(INGRESS_VLAN_FILTER, L2_DROPS), 65762306a36Sopenharmony_ci .listeners_arr = { 65862306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_SWITCH_VLAN, L2_DISCARDS), 65962306a36Sopenharmony_ci }, 66062306a36Sopenharmony_ci }, 66162306a36Sopenharmony_ci { 66262306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(INGRESS_STP_FILTER, L2_DROPS), 66362306a36Sopenharmony_ci .listeners_arr = { 66462306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_SWITCH_STP, L2_DISCARDS), 66562306a36Sopenharmony_ci }, 66662306a36Sopenharmony_ci }, 66762306a36Sopenharmony_ci { 66862306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(EMPTY_TX_LIST, L2_DROPS), 66962306a36Sopenharmony_ci .listeners_arr = { 67062306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(LOOKUP_SWITCH_UC, L2_DISCARDS), 67162306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(LOOKUP_SWITCH_MC_NULL, L2_DISCARDS), 67262306a36Sopenharmony_ci }, 67362306a36Sopenharmony_ci }, 67462306a36Sopenharmony_ci { 67562306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(PORT_LOOPBACK_FILTER, L2_DROPS), 67662306a36Sopenharmony_ci .listeners_arr = { 67762306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(LOOKUP_SWITCH_LB, L2_DISCARDS), 67862306a36Sopenharmony_ci }, 67962306a36Sopenharmony_ci }, 68062306a36Sopenharmony_ci { 68162306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(BLACKHOLE_ROUTE, L3_DROPS), 68262306a36Sopenharmony_ci .listeners_arr = { 68362306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ROUTER2, L3_DISCARDS), 68462306a36Sopenharmony_ci }, 68562306a36Sopenharmony_ci }, 68662306a36Sopenharmony_ci { 68762306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(NON_IP_PACKET, L3_DROPS), 68862306a36Sopenharmony_ci .listeners_arr = { 68962306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_ROUTER_NON_IP_PACKET, 69062306a36Sopenharmony_ci L3_DISCARDS), 69162306a36Sopenharmony_ci }, 69262306a36Sopenharmony_ci }, 69362306a36Sopenharmony_ci { 69462306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(UC_DIP_MC_DMAC, L3_DROPS), 69562306a36Sopenharmony_ci .listeners_arr = { 69662306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_ROUTER_UC_DIP_MC_DMAC, 69762306a36Sopenharmony_ci L3_DISCARDS), 69862306a36Sopenharmony_ci }, 69962306a36Sopenharmony_ci }, 70062306a36Sopenharmony_ci { 70162306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(DIP_LB, L3_DROPS), 70262306a36Sopenharmony_ci .listeners_arr = { 70362306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_ROUTER_DIP_LB, L3_DISCARDS), 70462306a36Sopenharmony_ci }, 70562306a36Sopenharmony_ci }, 70662306a36Sopenharmony_ci { 70762306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(SIP_MC, L3_DROPS), 70862306a36Sopenharmony_ci .listeners_arr = { 70962306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_ROUTER_SIP_MC, L3_DISCARDS), 71062306a36Sopenharmony_ci }, 71162306a36Sopenharmony_ci }, 71262306a36Sopenharmony_ci { 71362306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(SIP_LB, L3_DROPS), 71462306a36Sopenharmony_ci .listeners_arr = { 71562306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_ROUTER_SIP_LB, L3_DISCARDS), 71662306a36Sopenharmony_ci }, 71762306a36Sopenharmony_ci }, 71862306a36Sopenharmony_ci { 71962306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(CORRUPTED_IP_HDR, L3_DROPS), 72062306a36Sopenharmony_ci .listeners_arr = { 72162306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_ROUTER_CORRUPTED_IP_HDR, 72262306a36Sopenharmony_ci L3_DISCARDS), 72362306a36Sopenharmony_ci }, 72462306a36Sopenharmony_ci }, 72562306a36Sopenharmony_ci { 72662306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(IPV4_SIP_BC, L3_DROPS), 72762306a36Sopenharmony_ci .listeners_arr = { 72862306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_ROUTER_IPV4_SIP_BC, 72962306a36Sopenharmony_ci L3_DISCARDS), 73062306a36Sopenharmony_ci }, 73162306a36Sopenharmony_ci }, 73262306a36Sopenharmony_ci { 73362306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(IPV6_MC_DIP_RESERVED_SCOPE, 73462306a36Sopenharmony_ci L3_DROPS), 73562306a36Sopenharmony_ci .listeners_arr = { 73662306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(IPV6_MC_DIP_RESERVED_SCOPE, 73762306a36Sopenharmony_ci L3_DISCARDS), 73862306a36Sopenharmony_ci }, 73962306a36Sopenharmony_ci }, 74062306a36Sopenharmony_ci { 74162306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, 74262306a36Sopenharmony_ci L3_DROPS), 74362306a36Sopenharmony_ci .listeners_arr = { 74462306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, 74562306a36Sopenharmony_ci L3_DISCARDS), 74662306a36Sopenharmony_ci }, 74762306a36Sopenharmony_ci }, 74862306a36Sopenharmony_ci { 74962306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_EXCEPTION(MTU_ERROR, L3_EXCEPTIONS), 75062306a36Sopenharmony_ci .listeners_arr = { 75162306a36Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(MTUERROR, L3_EXCEPTIONS, 75262306a36Sopenharmony_ci TRAP_TO_CPU), 75362306a36Sopenharmony_ci }, 75462306a36Sopenharmony_ci }, 75562306a36Sopenharmony_ci { 75662306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_EXCEPTION(TTL_ERROR, L3_EXCEPTIONS), 75762306a36Sopenharmony_ci .listeners_arr = { 75862306a36Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(TTLERROR, L3_EXCEPTIONS, 75962306a36Sopenharmony_ci TRAP_TO_CPU), 76062306a36Sopenharmony_ci }, 76162306a36Sopenharmony_ci }, 76262306a36Sopenharmony_ci { 76362306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_EXCEPTION(RPF, L3_EXCEPTIONS), 76462306a36Sopenharmony_ci .listeners_arr = { 76562306a36Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(RPF, L3_EXCEPTIONS, TRAP_TO_CPU), 76662306a36Sopenharmony_ci }, 76762306a36Sopenharmony_ci }, 76862306a36Sopenharmony_ci { 76962306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_EXCEPTION(REJECT_ROUTE, L3_EXCEPTIONS), 77062306a36Sopenharmony_ci .listeners_arr = { 77162306a36Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(RTR_INGRESS1, L3_EXCEPTIONS, 77262306a36Sopenharmony_ci TRAP_TO_CPU), 77362306a36Sopenharmony_ci }, 77462306a36Sopenharmony_ci }, 77562306a36Sopenharmony_ci { 77662306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_EXCEPTION(UNRESOLVED_NEIGH, 77762306a36Sopenharmony_ci L3_EXCEPTIONS), 77862306a36Sopenharmony_ci .listeners_arr = { 77962306a36Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(HOST_MISS_IPV4, L3_EXCEPTIONS, 78062306a36Sopenharmony_ci TRAP_TO_CPU), 78162306a36Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(HOST_MISS_IPV6, L3_EXCEPTIONS, 78262306a36Sopenharmony_ci TRAP_TO_CPU), 78362306a36Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(RTR_EGRESS0, L3_EXCEPTIONS, 78462306a36Sopenharmony_ci TRAP_EXCEPTION_TO_CPU), 78562306a36Sopenharmony_ci }, 78662306a36Sopenharmony_ci }, 78762306a36Sopenharmony_ci { 78862306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_EXCEPTION(IPV4_LPM_UNICAST_MISS, 78962306a36Sopenharmony_ci L3_EXCEPTIONS), 79062306a36Sopenharmony_ci .listeners_arr = { 79162306a36Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(DISCARD_ROUTER_LPM4, 79262306a36Sopenharmony_ci L3_EXCEPTIONS, 79362306a36Sopenharmony_ci TRAP_EXCEPTION_TO_CPU), 79462306a36Sopenharmony_ci }, 79562306a36Sopenharmony_ci }, 79662306a36Sopenharmony_ci { 79762306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_EXCEPTION(IPV6_LPM_UNICAST_MISS, 79862306a36Sopenharmony_ci L3_EXCEPTIONS), 79962306a36Sopenharmony_ci .listeners_arr = { 80062306a36Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(DISCARD_ROUTER_LPM6, 80162306a36Sopenharmony_ci L3_EXCEPTIONS, 80262306a36Sopenharmony_ci TRAP_EXCEPTION_TO_CPU), 80362306a36Sopenharmony_ci }, 80462306a36Sopenharmony_ci }, 80562306a36Sopenharmony_ci { 80662306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DRIVER_DROP(IRIF_DISABLED, L3_DROPS), 80762306a36Sopenharmony_ci .listeners_arr = { 80862306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ROUTER_IRIF_EN, L3_DISCARDS), 80962306a36Sopenharmony_ci }, 81062306a36Sopenharmony_ci }, 81162306a36Sopenharmony_ci { 81262306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DRIVER_DROP(ERIF_DISABLED, L3_DROPS), 81362306a36Sopenharmony_ci .listeners_arr = { 81462306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ROUTER_ERIF_EN, L3_DISCARDS), 81562306a36Sopenharmony_ci }, 81662306a36Sopenharmony_ci }, 81762306a36Sopenharmony_ci { 81862306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(NON_ROUTABLE, L3_DROPS), 81962306a36Sopenharmony_ci .listeners_arr = { 82062306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(NON_ROUTABLE, L3_DISCARDS), 82162306a36Sopenharmony_ci }, 82262306a36Sopenharmony_ci }, 82362306a36Sopenharmony_ci { 82462306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_EXCEPTION(DECAP_ERROR, TUNNEL_DROPS), 82562306a36Sopenharmony_ci .listeners_arr = { 82662306a36Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(DECAP_ECN0, TUNNEL_DISCARDS, 82762306a36Sopenharmony_ci TRAP_EXCEPTION_TO_CPU), 82862306a36Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(IPIP_DECAP_ERROR, 82962306a36Sopenharmony_ci TUNNEL_DISCARDS, 83062306a36Sopenharmony_ci TRAP_EXCEPTION_TO_CPU), 83162306a36Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(DISCARD_DEC_PKT, TUNNEL_DISCARDS, 83262306a36Sopenharmony_ci TRAP_EXCEPTION_TO_CPU), 83362306a36Sopenharmony_ci }, 83462306a36Sopenharmony_ci }, 83562306a36Sopenharmony_ci { 83662306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(OVERLAY_SMAC_MC, TUNNEL_DROPS), 83762306a36Sopenharmony_ci .listeners_arr = { 83862306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(OVERLAY_SMAC_MC, TUNNEL_DISCARDS), 83962306a36Sopenharmony_ci }, 84062306a36Sopenharmony_ci }, 84162306a36Sopenharmony_ci { 84262306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP_EXT(INGRESS_FLOW_ACTION_DROP, 84362306a36Sopenharmony_ci ACL_DROPS, 84462306a36Sopenharmony_ci DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE), 84562306a36Sopenharmony_ci .listeners_arr = { 84662306a36Sopenharmony_ci MLXSW_SP_RXL_ACL_DISCARD(INGRESS_ACL, ACL_DISCARDS, 84762306a36Sopenharmony_ci DUMMY), 84862306a36Sopenharmony_ci }, 84962306a36Sopenharmony_ci }, 85062306a36Sopenharmony_ci { 85162306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP_EXT(EGRESS_FLOW_ACTION_DROP, 85262306a36Sopenharmony_ci ACL_DROPS, 85362306a36Sopenharmony_ci DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE), 85462306a36Sopenharmony_ci .listeners_arr = { 85562306a36Sopenharmony_ci MLXSW_SP_RXL_ACL_DISCARD(EGRESS_ACL, ACL_DISCARDS, 85662306a36Sopenharmony_ci DUMMY), 85762306a36Sopenharmony_ci }, 85862306a36Sopenharmony_ci }, 85962306a36Sopenharmony_ci { 86062306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(STP, STP, TRAP), 86162306a36Sopenharmony_ci .listeners_arr = { 86262306a36Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(STP, STP, TRAP_TO_CPU, true), 86362306a36Sopenharmony_ci }, 86462306a36Sopenharmony_ci }, 86562306a36Sopenharmony_ci { 86662306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(LACP, LACP, TRAP), 86762306a36Sopenharmony_ci .listeners_arr = { 86862306a36Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(LACP, LACP, TRAP_TO_CPU, true), 86962306a36Sopenharmony_ci }, 87062306a36Sopenharmony_ci }, 87162306a36Sopenharmony_ci { 87262306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(LLDP, LLDP, TRAP), 87362306a36Sopenharmony_ci .listeners_arr = { 87462306a36Sopenharmony_ci MLXSW_RXL(mlxsw_sp_rx_ptp_listener, LLDP, TRAP_TO_CPU, 87562306a36Sopenharmony_ci true, SP_LLDP, DISCARD), 87662306a36Sopenharmony_ci }, 87762306a36Sopenharmony_ci }, 87862306a36Sopenharmony_ci { 87962306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IGMP_QUERY, MC_SNOOPING, MIRROR), 88062306a36Sopenharmony_ci .listeners_arr = { 88162306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(IGMP_QUERY, MC_SNOOPING, 88262306a36Sopenharmony_ci MIRROR_TO_CPU, false), 88362306a36Sopenharmony_ci }, 88462306a36Sopenharmony_ci }, 88562306a36Sopenharmony_ci { 88662306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IGMP_V1_REPORT, MC_SNOOPING, 88762306a36Sopenharmony_ci TRAP), 88862306a36Sopenharmony_ci .listeners_arr = { 88962306a36Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(IGMP_V1_REPORT, MC_SNOOPING, 89062306a36Sopenharmony_ci TRAP_TO_CPU, false), 89162306a36Sopenharmony_ci }, 89262306a36Sopenharmony_ci }, 89362306a36Sopenharmony_ci { 89462306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IGMP_V2_REPORT, MC_SNOOPING, 89562306a36Sopenharmony_ci TRAP), 89662306a36Sopenharmony_ci .listeners_arr = { 89762306a36Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(IGMP_V2_REPORT, MC_SNOOPING, 89862306a36Sopenharmony_ci TRAP_TO_CPU, false), 89962306a36Sopenharmony_ci }, 90062306a36Sopenharmony_ci }, 90162306a36Sopenharmony_ci { 90262306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IGMP_V3_REPORT, MC_SNOOPING, 90362306a36Sopenharmony_ci TRAP), 90462306a36Sopenharmony_ci .listeners_arr = { 90562306a36Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(IGMP_V3_REPORT, MC_SNOOPING, 90662306a36Sopenharmony_ci TRAP_TO_CPU, false), 90762306a36Sopenharmony_ci }, 90862306a36Sopenharmony_ci }, 90962306a36Sopenharmony_ci { 91062306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IGMP_V2_LEAVE, MC_SNOOPING, 91162306a36Sopenharmony_ci TRAP), 91262306a36Sopenharmony_ci .listeners_arr = { 91362306a36Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(IGMP_V2_LEAVE, MC_SNOOPING, 91462306a36Sopenharmony_ci TRAP_TO_CPU, false), 91562306a36Sopenharmony_ci }, 91662306a36Sopenharmony_ci }, 91762306a36Sopenharmony_ci { 91862306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(MLD_QUERY, MC_SNOOPING, MIRROR), 91962306a36Sopenharmony_ci .listeners_arr = { 92062306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV6_MLDV12_LISTENER_QUERY, 92162306a36Sopenharmony_ci MC_SNOOPING, MIRROR_TO_CPU, false), 92262306a36Sopenharmony_ci }, 92362306a36Sopenharmony_ci }, 92462306a36Sopenharmony_ci { 92562306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(MLD_V1_REPORT, MC_SNOOPING, 92662306a36Sopenharmony_ci TRAP), 92762306a36Sopenharmony_ci .listeners_arr = { 92862306a36Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(IPV6_MLDV1_LISTENER_REPORT, 92962306a36Sopenharmony_ci MC_SNOOPING, TRAP_TO_CPU, false), 93062306a36Sopenharmony_ci }, 93162306a36Sopenharmony_ci }, 93262306a36Sopenharmony_ci { 93362306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(MLD_V2_REPORT, MC_SNOOPING, 93462306a36Sopenharmony_ci TRAP), 93562306a36Sopenharmony_ci .listeners_arr = { 93662306a36Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(IPV6_MLDV2_LISTENER_REPORT, 93762306a36Sopenharmony_ci MC_SNOOPING, TRAP_TO_CPU, false), 93862306a36Sopenharmony_ci }, 93962306a36Sopenharmony_ci }, 94062306a36Sopenharmony_ci { 94162306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(MLD_V1_DONE, MC_SNOOPING, 94262306a36Sopenharmony_ci TRAP), 94362306a36Sopenharmony_ci .listeners_arr = { 94462306a36Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(IPV6_MLDV1_LISTENER_DONE, 94562306a36Sopenharmony_ci MC_SNOOPING, TRAP_TO_CPU, false), 94662306a36Sopenharmony_ci }, 94762306a36Sopenharmony_ci }, 94862306a36Sopenharmony_ci { 94962306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV4_DHCP, DHCP, TRAP), 95062306a36Sopenharmony_ci .listeners_arr = { 95162306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV4_DHCP, DHCP, TRAP_TO_CPU, false), 95262306a36Sopenharmony_ci }, 95362306a36Sopenharmony_ci }, 95462306a36Sopenharmony_ci { 95562306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_DHCP, DHCP, TRAP), 95662306a36Sopenharmony_ci .listeners_arr = { 95762306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV6_DHCP, DHCP, TRAP_TO_CPU, false), 95862306a36Sopenharmony_ci }, 95962306a36Sopenharmony_ci }, 96062306a36Sopenharmony_ci { 96162306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(ARP_REQUEST, NEIGH_DISCOVERY, 96262306a36Sopenharmony_ci MIRROR), 96362306a36Sopenharmony_ci .listeners_arr = { 96462306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(ROUTER_ARPBC, NEIGH_DISCOVERY, 96562306a36Sopenharmony_ci TRAP_TO_CPU, false), 96662306a36Sopenharmony_ci }, 96762306a36Sopenharmony_ci }, 96862306a36Sopenharmony_ci { 96962306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(ARP_RESPONSE, NEIGH_DISCOVERY, 97062306a36Sopenharmony_ci MIRROR), 97162306a36Sopenharmony_ci .listeners_arr = { 97262306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(ROUTER_ARPUC, NEIGH_DISCOVERY, 97362306a36Sopenharmony_ci TRAP_TO_CPU, false), 97462306a36Sopenharmony_ci }, 97562306a36Sopenharmony_ci }, 97662306a36Sopenharmony_ci { 97762306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(ARP_OVERLAY, NEIGH_DISCOVERY, 97862306a36Sopenharmony_ci TRAP), 97962306a36Sopenharmony_ci .listeners_arr = { 98062306a36Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(NVE_DECAP_ARP, NEIGH_DISCOVERY, 98162306a36Sopenharmony_ci TRAP_TO_CPU, false), 98262306a36Sopenharmony_ci }, 98362306a36Sopenharmony_ci }, 98462306a36Sopenharmony_ci { 98562306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_NEIGH_SOLICIT, 98662306a36Sopenharmony_ci NEIGH_DISCOVERY, TRAP), 98762306a36Sopenharmony_ci .listeners_arr = { 98862306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(L3_IPV6_NEIGHBOR_SOLICITATION, 98962306a36Sopenharmony_ci NEIGH_DISCOVERY, TRAP_TO_CPU, false), 99062306a36Sopenharmony_ci }, 99162306a36Sopenharmony_ci }, 99262306a36Sopenharmony_ci { 99362306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_NEIGH_ADVERT, 99462306a36Sopenharmony_ci NEIGH_DISCOVERY, TRAP), 99562306a36Sopenharmony_ci .listeners_arr = { 99662306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(L3_IPV6_NEIGHBOR_ADVERTISEMENT, 99762306a36Sopenharmony_ci NEIGH_DISCOVERY, TRAP_TO_CPU, false), 99862306a36Sopenharmony_ci }, 99962306a36Sopenharmony_ci }, 100062306a36Sopenharmony_ci { 100162306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV4_BFD, BFD, TRAP), 100262306a36Sopenharmony_ci .listeners_arr = { 100362306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV4_BFD, BFD, TRAP_TO_CPU, false), 100462306a36Sopenharmony_ci }, 100562306a36Sopenharmony_ci }, 100662306a36Sopenharmony_ci { 100762306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_BFD, BFD, TRAP), 100862306a36Sopenharmony_ci .listeners_arr = { 100962306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV6_BFD, BFD, TRAP_TO_CPU, false), 101062306a36Sopenharmony_ci }, 101162306a36Sopenharmony_ci }, 101262306a36Sopenharmony_ci { 101362306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV4_OSPF, OSPF, TRAP), 101462306a36Sopenharmony_ci .listeners_arr = { 101562306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV4_OSPF, OSPF, TRAP_TO_CPU, false), 101662306a36Sopenharmony_ci }, 101762306a36Sopenharmony_ci }, 101862306a36Sopenharmony_ci { 101962306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_OSPF, OSPF, TRAP), 102062306a36Sopenharmony_ci .listeners_arr = { 102162306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV6_OSPF, OSPF, TRAP_TO_CPU, false), 102262306a36Sopenharmony_ci }, 102362306a36Sopenharmony_ci }, 102462306a36Sopenharmony_ci { 102562306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV4_BGP, BGP, TRAP), 102662306a36Sopenharmony_ci .listeners_arr = { 102762306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV4_BGP, BGP, TRAP_TO_CPU, false), 102862306a36Sopenharmony_ci }, 102962306a36Sopenharmony_ci }, 103062306a36Sopenharmony_ci { 103162306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_BGP, BGP, TRAP), 103262306a36Sopenharmony_ci .listeners_arr = { 103362306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV6_BGP, BGP, TRAP_TO_CPU, false), 103462306a36Sopenharmony_ci }, 103562306a36Sopenharmony_ci }, 103662306a36Sopenharmony_ci { 103762306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV4_VRRP, VRRP, TRAP), 103862306a36Sopenharmony_ci .listeners_arr = { 103962306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV4_VRRP, VRRP, TRAP_TO_CPU, false), 104062306a36Sopenharmony_ci }, 104162306a36Sopenharmony_ci }, 104262306a36Sopenharmony_ci { 104362306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_VRRP, VRRP, TRAP), 104462306a36Sopenharmony_ci .listeners_arr = { 104562306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV6_VRRP, VRRP, TRAP_TO_CPU, false), 104662306a36Sopenharmony_ci }, 104762306a36Sopenharmony_ci }, 104862306a36Sopenharmony_ci { 104962306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV4_PIM, PIM, TRAP), 105062306a36Sopenharmony_ci .listeners_arr = { 105162306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV4_PIM, PIM, TRAP_TO_CPU, false), 105262306a36Sopenharmony_ci }, 105362306a36Sopenharmony_ci }, 105462306a36Sopenharmony_ci { 105562306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_PIM, PIM, TRAP), 105662306a36Sopenharmony_ci .listeners_arr = { 105762306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV6_PIM, PIM, TRAP_TO_CPU, false), 105862306a36Sopenharmony_ci }, 105962306a36Sopenharmony_ci }, 106062306a36Sopenharmony_ci { 106162306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(UC_LB, UC_LB, MIRROR), 106262306a36Sopenharmony_ci .listeners_arr = { 106362306a36Sopenharmony_ci MLXSW_SP_RXL_L3_MARK(LBERROR, LBERROR, MIRROR_TO_CPU, 106462306a36Sopenharmony_ci false), 106562306a36Sopenharmony_ci }, 106662306a36Sopenharmony_ci }, 106762306a36Sopenharmony_ci { 106862306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(LOCAL_ROUTE, LOCAL_DELIVERY, 106962306a36Sopenharmony_ci TRAP), 107062306a36Sopenharmony_ci .listeners_arr = { 107162306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(IP2ME, IP2ME, TRAP_TO_CPU, false), 107262306a36Sopenharmony_ci }, 107362306a36Sopenharmony_ci }, 107462306a36Sopenharmony_ci { 107562306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(EXTERNAL_ROUTE, EXTERNAL_DELIVERY, 107662306a36Sopenharmony_ci TRAP), 107762306a36Sopenharmony_ci .listeners_arr = { 107862306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(RTR_INGRESS0, EXTERNAL_ROUTE, 107962306a36Sopenharmony_ci TRAP_TO_CPU, false), 108062306a36Sopenharmony_ci }, 108162306a36Sopenharmony_ci }, 108262306a36Sopenharmony_ci { 108362306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_UC_DIP_LINK_LOCAL_SCOPE, 108462306a36Sopenharmony_ci LOCAL_DELIVERY, TRAP), 108562306a36Sopenharmony_ci .listeners_arr = { 108662306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV6_LINK_LOCAL_DEST, IP2ME, 108762306a36Sopenharmony_ci TRAP_TO_CPU, false), 108862306a36Sopenharmony_ci }, 108962306a36Sopenharmony_ci }, 109062306a36Sopenharmony_ci { 109162306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV4_ROUTER_ALERT, LOCAL_DELIVERY, 109262306a36Sopenharmony_ci TRAP), 109362306a36Sopenharmony_ci .listeners_arr = { 109462306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV4, IP2ME, TRAP_TO_CPU, 109562306a36Sopenharmony_ci false), 109662306a36Sopenharmony_ci }, 109762306a36Sopenharmony_ci }, 109862306a36Sopenharmony_ci { 109962306a36Sopenharmony_ci /* IPV6_ROUTER_ALERT is defined in uAPI as 22, but it is not 110062306a36Sopenharmony_ci * used in this file, so undefine it. 110162306a36Sopenharmony_ci */ 110262306a36Sopenharmony_ci #undef IPV6_ROUTER_ALERT 110362306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_ROUTER_ALERT, LOCAL_DELIVERY, 110462306a36Sopenharmony_ci TRAP), 110562306a36Sopenharmony_ci .listeners_arr = { 110662306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV6, IP2ME, TRAP_TO_CPU, 110762306a36Sopenharmony_ci false), 110862306a36Sopenharmony_ci }, 110962306a36Sopenharmony_ci }, 111062306a36Sopenharmony_ci { 111162306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_DIP_ALL_NODES, IPV6, TRAP), 111262306a36Sopenharmony_ci .listeners_arr = { 111362306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV6_ALL_NODES_LINK, IPV6, 111462306a36Sopenharmony_ci TRAP_TO_CPU, false), 111562306a36Sopenharmony_ci }, 111662306a36Sopenharmony_ci }, 111762306a36Sopenharmony_ci { 111862306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_DIP_ALL_ROUTERS, IPV6, TRAP), 111962306a36Sopenharmony_ci .listeners_arr = { 112062306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV6_ALL_ROUTERS_LINK, IPV6, 112162306a36Sopenharmony_ci TRAP_TO_CPU, false), 112262306a36Sopenharmony_ci }, 112362306a36Sopenharmony_ci }, 112462306a36Sopenharmony_ci { 112562306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_ROUTER_SOLICIT, IPV6, TRAP), 112662306a36Sopenharmony_ci .listeners_arr = { 112762306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(L3_IPV6_ROUTER_SOLICITATION, IPV6, 112862306a36Sopenharmony_ci TRAP_TO_CPU, false), 112962306a36Sopenharmony_ci }, 113062306a36Sopenharmony_ci }, 113162306a36Sopenharmony_ci { 113262306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_ROUTER_ADVERT, IPV6, TRAP), 113362306a36Sopenharmony_ci .listeners_arr = { 113462306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(L3_IPV6_ROUTER_ADVERTISEMENT, IPV6, 113562306a36Sopenharmony_ci TRAP_TO_CPU, false), 113662306a36Sopenharmony_ci }, 113762306a36Sopenharmony_ci }, 113862306a36Sopenharmony_ci { 113962306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_REDIRECT, IPV6, TRAP), 114062306a36Sopenharmony_ci .listeners_arr = { 114162306a36Sopenharmony_ci MLXSW_SP_RXL_MARK(L3_IPV6_REDIRECTION, IPV6, 114262306a36Sopenharmony_ci TRAP_TO_CPU, false), 114362306a36Sopenharmony_ci }, 114462306a36Sopenharmony_ci }, 114562306a36Sopenharmony_ci { 114662306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(PTP_EVENT, PTP_EVENT, TRAP), 114762306a36Sopenharmony_ci .listeners_arr = { 114862306a36Sopenharmony_ci MLXSW_RXL(mlxsw_sp_rx_ptp_listener, PTP0, TRAP_TO_CPU, 114962306a36Sopenharmony_ci false, SP_PTP0, DISCARD), 115062306a36Sopenharmony_ci }, 115162306a36Sopenharmony_ci }, 115262306a36Sopenharmony_ci { 115362306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(PTP_GENERAL, PTP_GENERAL, TRAP), 115462306a36Sopenharmony_ci .listeners_arr = { 115562306a36Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(PTP1, PTP1, TRAP_TO_CPU, false), 115662306a36Sopenharmony_ci }, 115762306a36Sopenharmony_ci }, 115862306a36Sopenharmony_ci { 115962306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(FLOW_ACTION_TRAP, ACL_TRAP, TRAP), 116062306a36Sopenharmony_ci .listeners_arr = { 116162306a36Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(ACL0, FLOW_LOGGING, TRAP_TO_CPU, 116262306a36Sopenharmony_ci false), 116362306a36Sopenharmony_ci }, 116462306a36Sopenharmony_ci }, 116562306a36Sopenharmony_ci { 116662306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(BLACKHOLE_NEXTHOP, L3_DROPS), 116762306a36Sopenharmony_ci .listeners_arr = { 116862306a36Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ROUTER3, L3_DISCARDS), 116962306a36Sopenharmony_ci }, 117062306a36Sopenharmony_ci }, 117162306a36Sopenharmony_ci { 117262306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(EAPOL, EAPOL, TRAP), 117362306a36Sopenharmony_ci .listeners_arr = { 117462306a36Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(EAPOL, EAPOL, TRAP_TO_CPU, true), 117562306a36Sopenharmony_ci }, 117662306a36Sopenharmony_ci }, 117762306a36Sopenharmony_ci { 117862306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(LOCKED_PORT, L2_DROPS), 117962306a36Sopenharmony_ci .listeners_arr = { 118062306a36Sopenharmony_ci MLXSW_RXL_DIS(mlxsw_sp_rx_drop_listener, FDB_MISS, 118162306a36Sopenharmony_ci TRAP_EXCEPTION_TO_CPU, false, 118262306a36Sopenharmony_ci SP_L2_DISCARDS, DISCARD, SP_L2_DISCARDS), 118362306a36Sopenharmony_ci MLXSW_RXL_DIS(mlxsw_sp_rx_drop_listener, FDB_MISMATCH, 118462306a36Sopenharmony_ci TRAP_EXCEPTION_TO_CPU, false, 118562306a36Sopenharmony_ci SP_L2_DISCARDS, DISCARD, SP_L2_DISCARDS), 118662306a36Sopenharmony_ci }, 118762306a36Sopenharmony_ci }, 118862306a36Sopenharmony_ci}; 118962306a36Sopenharmony_ci 119062306a36Sopenharmony_cistatic struct mlxsw_sp_trap_policer_item * 119162306a36Sopenharmony_cimlxsw_sp_trap_policer_item_lookup(struct mlxsw_sp *mlxsw_sp, u32 id) 119262306a36Sopenharmony_ci{ 119362306a36Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 119462306a36Sopenharmony_ci int i; 119562306a36Sopenharmony_ci 119662306a36Sopenharmony_ci for (i = 0; i < trap->policers_count; i++) { 119762306a36Sopenharmony_ci if (trap->policer_items_arr[i].policer.id == id) 119862306a36Sopenharmony_ci return &trap->policer_items_arr[i]; 119962306a36Sopenharmony_ci } 120062306a36Sopenharmony_ci 120162306a36Sopenharmony_ci return NULL; 120262306a36Sopenharmony_ci} 120362306a36Sopenharmony_ci 120462306a36Sopenharmony_cistatic struct mlxsw_sp_trap_group_item * 120562306a36Sopenharmony_cimlxsw_sp_trap_group_item_lookup(struct mlxsw_sp *mlxsw_sp, u16 id) 120662306a36Sopenharmony_ci{ 120762306a36Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 120862306a36Sopenharmony_ci int i; 120962306a36Sopenharmony_ci 121062306a36Sopenharmony_ci for (i = 0; i < trap->groups_count; i++) { 121162306a36Sopenharmony_ci if (trap->group_items_arr[i].group.id == id) 121262306a36Sopenharmony_ci return &trap->group_items_arr[i]; 121362306a36Sopenharmony_ci } 121462306a36Sopenharmony_ci 121562306a36Sopenharmony_ci return NULL; 121662306a36Sopenharmony_ci} 121762306a36Sopenharmony_ci 121862306a36Sopenharmony_cistatic struct mlxsw_sp_trap_item * 121962306a36Sopenharmony_cimlxsw_sp_trap_item_lookup(struct mlxsw_sp *mlxsw_sp, u16 id) 122062306a36Sopenharmony_ci{ 122162306a36Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 122262306a36Sopenharmony_ci int i; 122362306a36Sopenharmony_ci 122462306a36Sopenharmony_ci for (i = 0; i < trap->traps_count; i++) { 122562306a36Sopenharmony_ci if (trap->trap_items_arr[i].trap.id == id) 122662306a36Sopenharmony_ci return &trap->trap_items_arr[i]; 122762306a36Sopenharmony_ci } 122862306a36Sopenharmony_ci 122962306a36Sopenharmony_ci return NULL; 123062306a36Sopenharmony_ci} 123162306a36Sopenharmony_ci 123262306a36Sopenharmony_cistatic int mlxsw_sp_trap_cpu_policers_set(struct mlxsw_sp *mlxsw_sp) 123362306a36Sopenharmony_ci{ 123462306a36Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 123562306a36Sopenharmony_ci char qpcr_pl[MLXSW_REG_QPCR_LEN]; 123662306a36Sopenharmony_ci u16 hw_id; 123762306a36Sopenharmony_ci 123862306a36Sopenharmony_ci /* The purpose of "thin" policer is to drop as many packets 123962306a36Sopenharmony_ci * as possible. The dummy group is using it. 124062306a36Sopenharmony_ci */ 124162306a36Sopenharmony_ci hw_id = find_first_zero_bit(trap->policers_usage, trap->max_policers); 124262306a36Sopenharmony_ci if (WARN_ON(hw_id == trap->max_policers)) 124362306a36Sopenharmony_ci return -ENOBUFS; 124462306a36Sopenharmony_ci 124562306a36Sopenharmony_ci __set_bit(hw_id, trap->policers_usage); 124662306a36Sopenharmony_ci trap->thin_policer_hw_id = hw_id; 124762306a36Sopenharmony_ci mlxsw_reg_qpcr_pack(qpcr_pl, hw_id, MLXSW_REG_QPCR_IR_UNITS_M, 124862306a36Sopenharmony_ci false, 1, 4); 124962306a36Sopenharmony_ci return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qpcr), qpcr_pl); 125062306a36Sopenharmony_ci} 125162306a36Sopenharmony_ci 125262306a36Sopenharmony_cistatic int mlxsw_sp_trap_dummy_group_init(struct mlxsw_sp *mlxsw_sp) 125362306a36Sopenharmony_ci{ 125462306a36Sopenharmony_ci char htgt_pl[MLXSW_REG_HTGT_LEN]; 125562306a36Sopenharmony_ci 125662306a36Sopenharmony_ci mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_SP_DUMMY, 125762306a36Sopenharmony_ci mlxsw_sp->trap->thin_policer_hw_id, 0, 1); 125862306a36Sopenharmony_ci return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(htgt), htgt_pl); 125962306a36Sopenharmony_ci} 126062306a36Sopenharmony_ci 126162306a36Sopenharmony_cistatic int mlxsw_sp_trap_policer_items_arr_init(struct mlxsw_sp *mlxsw_sp) 126262306a36Sopenharmony_ci{ 126362306a36Sopenharmony_ci size_t arr_size = ARRAY_SIZE(mlxsw_sp_trap_policer_items_arr); 126462306a36Sopenharmony_ci size_t elem_size = sizeof(struct mlxsw_sp_trap_policer_item); 126562306a36Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 126662306a36Sopenharmony_ci size_t free_policers = 0; 126762306a36Sopenharmony_ci u32 last_id; 126862306a36Sopenharmony_ci int i; 126962306a36Sopenharmony_ci 127062306a36Sopenharmony_ci for_each_clear_bit(i, trap->policers_usage, trap->max_policers) 127162306a36Sopenharmony_ci free_policers++; 127262306a36Sopenharmony_ci 127362306a36Sopenharmony_ci if (arr_size > free_policers) { 127462306a36Sopenharmony_ci dev_err(mlxsw_sp->bus_info->dev, "Exceeded number of supported packet trap policers\n"); 127562306a36Sopenharmony_ci return -ENOBUFS; 127662306a36Sopenharmony_ci } 127762306a36Sopenharmony_ci 127862306a36Sopenharmony_ci trap->policer_items_arr = kcalloc(free_policers, elem_size, GFP_KERNEL); 127962306a36Sopenharmony_ci if (!trap->policer_items_arr) 128062306a36Sopenharmony_ci return -ENOMEM; 128162306a36Sopenharmony_ci 128262306a36Sopenharmony_ci trap->policers_count = free_policers; 128362306a36Sopenharmony_ci 128462306a36Sopenharmony_ci /* Initialize policer items array with pre-defined policers. */ 128562306a36Sopenharmony_ci memcpy(trap->policer_items_arr, mlxsw_sp_trap_policer_items_arr, 128662306a36Sopenharmony_ci elem_size * arr_size); 128762306a36Sopenharmony_ci 128862306a36Sopenharmony_ci /* Initialize policer items array with the rest of the available 128962306a36Sopenharmony_ci * policers. 129062306a36Sopenharmony_ci */ 129162306a36Sopenharmony_ci last_id = mlxsw_sp_trap_policer_items_arr[arr_size - 1].policer.id; 129262306a36Sopenharmony_ci for (i = arr_size; i < trap->policers_count; i++) { 129362306a36Sopenharmony_ci const struct mlxsw_sp_trap_policer_item *policer_item; 129462306a36Sopenharmony_ci 129562306a36Sopenharmony_ci /* Use parameters set for first policer and override 129662306a36Sopenharmony_ci * relevant ones. 129762306a36Sopenharmony_ci */ 129862306a36Sopenharmony_ci policer_item = &mlxsw_sp_trap_policer_items_arr[0]; 129962306a36Sopenharmony_ci trap->policer_items_arr[i] = *policer_item; 130062306a36Sopenharmony_ci trap->policer_items_arr[i].policer.id = ++last_id; 130162306a36Sopenharmony_ci trap->policer_items_arr[i].policer.init_rate = 1; 130262306a36Sopenharmony_ci trap->policer_items_arr[i].policer.init_burst = 16; 130362306a36Sopenharmony_ci } 130462306a36Sopenharmony_ci 130562306a36Sopenharmony_ci return 0; 130662306a36Sopenharmony_ci} 130762306a36Sopenharmony_ci 130862306a36Sopenharmony_cistatic void mlxsw_sp_trap_policer_items_arr_fini(struct mlxsw_sp *mlxsw_sp) 130962306a36Sopenharmony_ci{ 131062306a36Sopenharmony_ci kfree(mlxsw_sp->trap->policer_items_arr); 131162306a36Sopenharmony_ci} 131262306a36Sopenharmony_ci 131362306a36Sopenharmony_cistatic int mlxsw_sp_trap_policers_init(struct mlxsw_sp *mlxsw_sp) 131462306a36Sopenharmony_ci{ 131562306a36Sopenharmony_ci struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); 131662306a36Sopenharmony_ci const struct mlxsw_sp_trap_policer_item *policer_item; 131762306a36Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 131862306a36Sopenharmony_ci int err, i; 131962306a36Sopenharmony_ci 132062306a36Sopenharmony_ci err = mlxsw_sp_trap_policer_items_arr_init(mlxsw_sp); 132162306a36Sopenharmony_ci if (err) 132262306a36Sopenharmony_ci return err; 132362306a36Sopenharmony_ci 132462306a36Sopenharmony_ci for (i = 0; i < trap->policers_count; i++) { 132562306a36Sopenharmony_ci policer_item = &trap->policer_items_arr[i]; 132662306a36Sopenharmony_ci err = devl_trap_policers_register(devlink, 132762306a36Sopenharmony_ci &policer_item->policer, 1); 132862306a36Sopenharmony_ci if (err) 132962306a36Sopenharmony_ci goto err_trap_policer_register; 133062306a36Sopenharmony_ci } 133162306a36Sopenharmony_ci 133262306a36Sopenharmony_ci return 0; 133362306a36Sopenharmony_ci 133462306a36Sopenharmony_cierr_trap_policer_register: 133562306a36Sopenharmony_ci for (i--; i >= 0; i--) { 133662306a36Sopenharmony_ci policer_item = &trap->policer_items_arr[i]; 133762306a36Sopenharmony_ci devl_trap_policers_unregister(devlink, 133862306a36Sopenharmony_ci &policer_item->policer, 1); 133962306a36Sopenharmony_ci } 134062306a36Sopenharmony_ci mlxsw_sp_trap_policer_items_arr_fini(mlxsw_sp); 134162306a36Sopenharmony_ci return err; 134262306a36Sopenharmony_ci} 134362306a36Sopenharmony_ci 134462306a36Sopenharmony_cistatic void mlxsw_sp_trap_policers_fini(struct mlxsw_sp *mlxsw_sp) 134562306a36Sopenharmony_ci{ 134662306a36Sopenharmony_ci struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); 134762306a36Sopenharmony_ci const struct mlxsw_sp_trap_policer_item *policer_item; 134862306a36Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 134962306a36Sopenharmony_ci int i; 135062306a36Sopenharmony_ci 135162306a36Sopenharmony_ci for (i = trap->policers_count - 1; i >= 0; i--) { 135262306a36Sopenharmony_ci policer_item = &trap->policer_items_arr[i]; 135362306a36Sopenharmony_ci devl_trap_policers_unregister(devlink, 135462306a36Sopenharmony_ci &policer_item->policer, 1); 135562306a36Sopenharmony_ci } 135662306a36Sopenharmony_ci mlxsw_sp_trap_policer_items_arr_fini(mlxsw_sp); 135762306a36Sopenharmony_ci} 135862306a36Sopenharmony_ci 135962306a36Sopenharmony_cistatic int mlxsw_sp_trap_group_items_arr_init(struct mlxsw_sp *mlxsw_sp) 136062306a36Sopenharmony_ci{ 136162306a36Sopenharmony_ci size_t common_groups_count = ARRAY_SIZE(mlxsw_sp_trap_group_items_arr); 136262306a36Sopenharmony_ci const struct mlxsw_sp_trap_group_item *spec_group_items_arr; 136362306a36Sopenharmony_ci size_t elem_size = sizeof(struct mlxsw_sp_trap_group_item); 136462306a36Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 136562306a36Sopenharmony_ci size_t groups_count, spec_groups_count; 136662306a36Sopenharmony_ci int err; 136762306a36Sopenharmony_ci 136862306a36Sopenharmony_ci err = mlxsw_sp->trap_ops->groups_init(mlxsw_sp, &spec_group_items_arr, 136962306a36Sopenharmony_ci &spec_groups_count); 137062306a36Sopenharmony_ci if (err) 137162306a36Sopenharmony_ci return err; 137262306a36Sopenharmony_ci 137362306a36Sopenharmony_ci /* The group items array is created by concatenating the common trap 137462306a36Sopenharmony_ci * group items and the ASIC-specific trap group items. 137562306a36Sopenharmony_ci */ 137662306a36Sopenharmony_ci groups_count = common_groups_count + spec_groups_count; 137762306a36Sopenharmony_ci trap->group_items_arr = kcalloc(groups_count, elem_size, GFP_KERNEL); 137862306a36Sopenharmony_ci if (!trap->group_items_arr) 137962306a36Sopenharmony_ci return -ENOMEM; 138062306a36Sopenharmony_ci 138162306a36Sopenharmony_ci memcpy(trap->group_items_arr, mlxsw_sp_trap_group_items_arr, 138262306a36Sopenharmony_ci elem_size * common_groups_count); 138362306a36Sopenharmony_ci memcpy(trap->group_items_arr + common_groups_count, 138462306a36Sopenharmony_ci spec_group_items_arr, elem_size * spec_groups_count); 138562306a36Sopenharmony_ci 138662306a36Sopenharmony_ci trap->groups_count = groups_count; 138762306a36Sopenharmony_ci 138862306a36Sopenharmony_ci return 0; 138962306a36Sopenharmony_ci} 139062306a36Sopenharmony_ci 139162306a36Sopenharmony_cistatic void mlxsw_sp_trap_group_items_arr_fini(struct mlxsw_sp *mlxsw_sp) 139262306a36Sopenharmony_ci{ 139362306a36Sopenharmony_ci kfree(mlxsw_sp->trap->group_items_arr); 139462306a36Sopenharmony_ci} 139562306a36Sopenharmony_ci 139662306a36Sopenharmony_cistatic int mlxsw_sp_trap_groups_init(struct mlxsw_sp *mlxsw_sp) 139762306a36Sopenharmony_ci{ 139862306a36Sopenharmony_ci struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); 139962306a36Sopenharmony_ci const struct mlxsw_sp_trap_group_item *group_item; 140062306a36Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 140162306a36Sopenharmony_ci int err, i; 140262306a36Sopenharmony_ci 140362306a36Sopenharmony_ci err = mlxsw_sp_trap_group_items_arr_init(mlxsw_sp); 140462306a36Sopenharmony_ci if (err) 140562306a36Sopenharmony_ci return err; 140662306a36Sopenharmony_ci 140762306a36Sopenharmony_ci for (i = 0; i < trap->groups_count; i++) { 140862306a36Sopenharmony_ci group_item = &trap->group_items_arr[i]; 140962306a36Sopenharmony_ci err = devl_trap_groups_register(devlink, &group_item->group, 1); 141062306a36Sopenharmony_ci if (err) 141162306a36Sopenharmony_ci goto err_trap_group_register; 141262306a36Sopenharmony_ci } 141362306a36Sopenharmony_ci 141462306a36Sopenharmony_ci return 0; 141562306a36Sopenharmony_ci 141662306a36Sopenharmony_cierr_trap_group_register: 141762306a36Sopenharmony_ci for (i--; i >= 0; i--) { 141862306a36Sopenharmony_ci group_item = &trap->group_items_arr[i]; 141962306a36Sopenharmony_ci devl_trap_groups_unregister(devlink, &group_item->group, 1); 142062306a36Sopenharmony_ci } 142162306a36Sopenharmony_ci mlxsw_sp_trap_group_items_arr_fini(mlxsw_sp); 142262306a36Sopenharmony_ci return err; 142362306a36Sopenharmony_ci} 142462306a36Sopenharmony_ci 142562306a36Sopenharmony_cistatic void mlxsw_sp_trap_groups_fini(struct mlxsw_sp *mlxsw_sp) 142662306a36Sopenharmony_ci{ 142762306a36Sopenharmony_ci struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); 142862306a36Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 142962306a36Sopenharmony_ci int i; 143062306a36Sopenharmony_ci 143162306a36Sopenharmony_ci for (i = trap->groups_count - 1; i >= 0; i--) { 143262306a36Sopenharmony_ci const struct mlxsw_sp_trap_group_item *group_item; 143362306a36Sopenharmony_ci 143462306a36Sopenharmony_ci group_item = &trap->group_items_arr[i]; 143562306a36Sopenharmony_ci devl_trap_groups_unregister(devlink, &group_item->group, 1); 143662306a36Sopenharmony_ci } 143762306a36Sopenharmony_ci mlxsw_sp_trap_group_items_arr_fini(mlxsw_sp); 143862306a36Sopenharmony_ci} 143962306a36Sopenharmony_ci 144062306a36Sopenharmony_cistatic bool 144162306a36Sopenharmony_cimlxsw_sp_trap_listener_is_valid(const struct mlxsw_listener *listener) 144262306a36Sopenharmony_ci{ 144362306a36Sopenharmony_ci return listener->trap_id != 0; 144462306a36Sopenharmony_ci} 144562306a36Sopenharmony_ci 144662306a36Sopenharmony_cistatic int mlxsw_sp_trap_items_arr_init(struct mlxsw_sp *mlxsw_sp) 144762306a36Sopenharmony_ci{ 144862306a36Sopenharmony_ci size_t common_traps_count = ARRAY_SIZE(mlxsw_sp_trap_items_arr); 144962306a36Sopenharmony_ci const struct mlxsw_sp_trap_item *spec_trap_items_arr; 145062306a36Sopenharmony_ci size_t elem_size = sizeof(struct mlxsw_sp_trap_item); 145162306a36Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 145262306a36Sopenharmony_ci size_t traps_count, spec_traps_count; 145362306a36Sopenharmony_ci int err; 145462306a36Sopenharmony_ci 145562306a36Sopenharmony_ci err = mlxsw_sp->trap_ops->traps_init(mlxsw_sp, &spec_trap_items_arr, 145662306a36Sopenharmony_ci &spec_traps_count); 145762306a36Sopenharmony_ci if (err) 145862306a36Sopenharmony_ci return err; 145962306a36Sopenharmony_ci 146062306a36Sopenharmony_ci /* The trap items array is created by concatenating the common trap 146162306a36Sopenharmony_ci * items and the ASIC-specific trap items. 146262306a36Sopenharmony_ci */ 146362306a36Sopenharmony_ci traps_count = common_traps_count + spec_traps_count; 146462306a36Sopenharmony_ci trap->trap_items_arr = kcalloc(traps_count, elem_size, GFP_KERNEL); 146562306a36Sopenharmony_ci if (!trap->trap_items_arr) 146662306a36Sopenharmony_ci return -ENOMEM; 146762306a36Sopenharmony_ci 146862306a36Sopenharmony_ci memcpy(trap->trap_items_arr, mlxsw_sp_trap_items_arr, 146962306a36Sopenharmony_ci elem_size * common_traps_count); 147062306a36Sopenharmony_ci memcpy(trap->trap_items_arr + common_traps_count, 147162306a36Sopenharmony_ci spec_trap_items_arr, elem_size * spec_traps_count); 147262306a36Sopenharmony_ci 147362306a36Sopenharmony_ci trap->traps_count = traps_count; 147462306a36Sopenharmony_ci 147562306a36Sopenharmony_ci return 0; 147662306a36Sopenharmony_ci} 147762306a36Sopenharmony_ci 147862306a36Sopenharmony_cistatic void mlxsw_sp_trap_items_arr_fini(struct mlxsw_sp *mlxsw_sp) 147962306a36Sopenharmony_ci{ 148062306a36Sopenharmony_ci kfree(mlxsw_sp->trap->trap_items_arr); 148162306a36Sopenharmony_ci} 148262306a36Sopenharmony_ci 148362306a36Sopenharmony_cistatic int mlxsw_sp_traps_init(struct mlxsw_sp *mlxsw_sp) 148462306a36Sopenharmony_ci{ 148562306a36Sopenharmony_ci struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); 148662306a36Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 148762306a36Sopenharmony_ci const struct mlxsw_sp_trap_item *trap_item; 148862306a36Sopenharmony_ci int err, i; 148962306a36Sopenharmony_ci 149062306a36Sopenharmony_ci err = mlxsw_sp_trap_items_arr_init(mlxsw_sp); 149162306a36Sopenharmony_ci if (err) 149262306a36Sopenharmony_ci return err; 149362306a36Sopenharmony_ci 149462306a36Sopenharmony_ci for (i = 0; i < trap->traps_count; i++) { 149562306a36Sopenharmony_ci trap_item = &trap->trap_items_arr[i]; 149662306a36Sopenharmony_ci err = devl_traps_register(devlink, &trap_item->trap, 1, 149762306a36Sopenharmony_ci mlxsw_sp); 149862306a36Sopenharmony_ci if (err) 149962306a36Sopenharmony_ci goto err_trap_register; 150062306a36Sopenharmony_ci } 150162306a36Sopenharmony_ci 150262306a36Sopenharmony_ci return 0; 150362306a36Sopenharmony_ci 150462306a36Sopenharmony_cierr_trap_register: 150562306a36Sopenharmony_ci for (i--; i >= 0; i--) { 150662306a36Sopenharmony_ci trap_item = &trap->trap_items_arr[i]; 150762306a36Sopenharmony_ci devl_traps_unregister(devlink, &trap_item->trap, 1); 150862306a36Sopenharmony_ci } 150962306a36Sopenharmony_ci mlxsw_sp_trap_items_arr_fini(mlxsw_sp); 151062306a36Sopenharmony_ci return err; 151162306a36Sopenharmony_ci} 151262306a36Sopenharmony_ci 151362306a36Sopenharmony_cistatic void mlxsw_sp_traps_fini(struct mlxsw_sp *mlxsw_sp) 151462306a36Sopenharmony_ci{ 151562306a36Sopenharmony_ci struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); 151662306a36Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 151762306a36Sopenharmony_ci int i; 151862306a36Sopenharmony_ci 151962306a36Sopenharmony_ci for (i = trap->traps_count - 1; i >= 0; i--) { 152062306a36Sopenharmony_ci const struct mlxsw_sp_trap_item *trap_item; 152162306a36Sopenharmony_ci 152262306a36Sopenharmony_ci trap_item = &trap->trap_items_arr[i]; 152362306a36Sopenharmony_ci devl_traps_unregister(devlink, &trap_item->trap, 1); 152462306a36Sopenharmony_ci } 152562306a36Sopenharmony_ci mlxsw_sp_trap_items_arr_fini(mlxsw_sp); 152662306a36Sopenharmony_ci} 152762306a36Sopenharmony_ci 152862306a36Sopenharmony_ciint mlxsw_sp_devlink_traps_init(struct mlxsw_sp *mlxsw_sp) 152962306a36Sopenharmony_ci{ 153062306a36Sopenharmony_ci int err; 153162306a36Sopenharmony_ci 153262306a36Sopenharmony_ci err = mlxsw_sp_trap_cpu_policers_set(mlxsw_sp); 153362306a36Sopenharmony_ci if (err) 153462306a36Sopenharmony_ci return err; 153562306a36Sopenharmony_ci 153662306a36Sopenharmony_ci err = mlxsw_sp_trap_dummy_group_init(mlxsw_sp); 153762306a36Sopenharmony_ci if (err) 153862306a36Sopenharmony_ci return err; 153962306a36Sopenharmony_ci 154062306a36Sopenharmony_ci err = mlxsw_sp_trap_policers_init(mlxsw_sp); 154162306a36Sopenharmony_ci if (err) 154262306a36Sopenharmony_ci return err; 154362306a36Sopenharmony_ci 154462306a36Sopenharmony_ci err = mlxsw_sp_trap_groups_init(mlxsw_sp); 154562306a36Sopenharmony_ci if (err) 154662306a36Sopenharmony_ci goto err_trap_groups_init; 154762306a36Sopenharmony_ci 154862306a36Sopenharmony_ci err = mlxsw_sp_traps_init(mlxsw_sp); 154962306a36Sopenharmony_ci if (err) 155062306a36Sopenharmony_ci goto err_traps_init; 155162306a36Sopenharmony_ci 155262306a36Sopenharmony_ci return 0; 155362306a36Sopenharmony_ci 155462306a36Sopenharmony_cierr_traps_init: 155562306a36Sopenharmony_ci mlxsw_sp_trap_groups_fini(mlxsw_sp); 155662306a36Sopenharmony_cierr_trap_groups_init: 155762306a36Sopenharmony_ci mlxsw_sp_trap_policers_fini(mlxsw_sp); 155862306a36Sopenharmony_ci return err; 155962306a36Sopenharmony_ci} 156062306a36Sopenharmony_ci 156162306a36Sopenharmony_civoid mlxsw_sp_devlink_traps_fini(struct mlxsw_sp *mlxsw_sp) 156262306a36Sopenharmony_ci{ 156362306a36Sopenharmony_ci mlxsw_sp_traps_fini(mlxsw_sp); 156462306a36Sopenharmony_ci mlxsw_sp_trap_groups_fini(mlxsw_sp); 156562306a36Sopenharmony_ci mlxsw_sp_trap_policers_fini(mlxsw_sp); 156662306a36Sopenharmony_ci} 156762306a36Sopenharmony_ci 156862306a36Sopenharmony_ciint mlxsw_sp_trap_init(struct mlxsw_core *mlxsw_core, 156962306a36Sopenharmony_ci const struct devlink_trap *trap, void *trap_ctx) 157062306a36Sopenharmony_ci{ 157162306a36Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 157262306a36Sopenharmony_ci const struct mlxsw_sp_trap_item *trap_item; 157362306a36Sopenharmony_ci int i; 157462306a36Sopenharmony_ci 157562306a36Sopenharmony_ci trap_item = mlxsw_sp_trap_item_lookup(mlxsw_sp, trap->id); 157662306a36Sopenharmony_ci if (WARN_ON(!trap_item)) 157762306a36Sopenharmony_ci return -EINVAL; 157862306a36Sopenharmony_ci 157962306a36Sopenharmony_ci for (i = 0; i < MLXSW_SP_TRAP_LISTENERS_MAX; i++) { 158062306a36Sopenharmony_ci const struct mlxsw_listener *listener; 158162306a36Sopenharmony_ci int err; 158262306a36Sopenharmony_ci 158362306a36Sopenharmony_ci listener = &trap_item->listeners_arr[i]; 158462306a36Sopenharmony_ci if (!mlxsw_sp_trap_listener_is_valid(listener)) 158562306a36Sopenharmony_ci continue; 158662306a36Sopenharmony_ci err = mlxsw_core_trap_register(mlxsw_core, listener, trap_ctx); 158762306a36Sopenharmony_ci if (err) 158862306a36Sopenharmony_ci return err; 158962306a36Sopenharmony_ci } 159062306a36Sopenharmony_ci 159162306a36Sopenharmony_ci return 0; 159262306a36Sopenharmony_ci} 159362306a36Sopenharmony_ci 159462306a36Sopenharmony_civoid mlxsw_sp_trap_fini(struct mlxsw_core *mlxsw_core, 159562306a36Sopenharmony_ci const struct devlink_trap *trap, void *trap_ctx) 159662306a36Sopenharmony_ci{ 159762306a36Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 159862306a36Sopenharmony_ci const struct mlxsw_sp_trap_item *trap_item; 159962306a36Sopenharmony_ci int i; 160062306a36Sopenharmony_ci 160162306a36Sopenharmony_ci trap_item = mlxsw_sp_trap_item_lookup(mlxsw_sp, trap->id); 160262306a36Sopenharmony_ci if (WARN_ON(!trap_item)) 160362306a36Sopenharmony_ci return; 160462306a36Sopenharmony_ci 160562306a36Sopenharmony_ci for (i = MLXSW_SP_TRAP_LISTENERS_MAX - 1; i >= 0; i--) { 160662306a36Sopenharmony_ci const struct mlxsw_listener *listener; 160762306a36Sopenharmony_ci 160862306a36Sopenharmony_ci listener = &trap_item->listeners_arr[i]; 160962306a36Sopenharmony_ci if (!mlxsw_sp_trap_listener_is_valid(listener)) 161062306a36Sopenharmony_ci continue; 161162306a36Sopenharmony_ci mlxsw_core_trap_unregister(mlxsw_core, listener, trap_ctx); 161262306a36Sopenharmony_ci } 161362306a36Sopenharmony_ci} 161462306a36Sopenharmony_ci 161562306a36Sopenharmony_ciint mlxsw_sp_trap_action_set(struct mlxsw_core *mlxsw_core, 161662306a36Sopenharmony_ci const struct devlink_trap *trap, 161762306a36Sopenharmony_ci enum devlink_trap_action action, 161862306a36Sopenharmony_ci struct netlink_ext_ack *extack) 161962306a36Sopenharmony_ci{ 162062306a36Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 162162306a36Sopenharmony_ci const struct mlxsw_sp_trap_item *trap_item; 162262306a36Sopenharmony_ci int i; 162362306a36Sopenharmony_ci 162462306a36Sopenharmony_ci trap_item = mlxsw_sp_trap_item_lookup(mlxsw_sp, trap->id); 162562306a36Sopenharmony_ci if (WARN_ON(!trap_item)) 162662306a36Sopenharmony_ci return -EINVAL; 162762306a36Sopenharmony_ci 162862306a36Sopenharmony_ci if (trap_item->is_source) { 162962306a36Sopenharmony_ci NL_SET_ERR_MSG_MOD(extack, "Changing the action of source traps is not supported"); 163062306a36Sopenharmony_ci return -EOPNOTSUPP; 163162306a36Sopenharmony_ci } 163262306a36Sopenharmony_ci 163362306a36Sopenharmony_ci for (i = 0; i < MLXSW_SP_TRAP_LISTENERS_MAX; i++) { 163462306a36Sopenharmony_ci const struct mlxsw_listener *listener; 163562306a36Sopenharmony_ci bool enabled; 163662306a36Sopenharmony_ci int err; 163762306a36Sopenharmony_ci 163862306a36Sopenharmony_ci listener = &trap_item->listeners_arr[i]; 163962306a36Sopenharmony_ci if (!mlxsw_sp_trap_listener_is_valid(listener)) 164062306a36Sopenharmony_ci continue; 164162306a36Sopenharmony_ci 164262306a36Sopenharmony_ci switch (action) { 164362306a36Sopenharmony_ci case DEVLINK_TRAP_ACTION_DROP: 164462306a36Sopenharmony_ci enabled = false; 164562306a36Sopenharmony_ci break; 164662306a36Sopenharmony_ci case DEVLINK_TRAP_ACTION_TRAP: 164762306a36Sopenharmony_ci enabled = true; 164862306a36Sopenharmony_ci break; 164962306a36Sopenharmony_ci default: 165062306a36Sopenharmony_ci return -EINVAL; 165162306a36Sopenharmony_ci } 165262306a36Sopenharmony_ci err = mlxsw_core_trap_state_set(mlxsw_core, listener, enabled); 165362306a36Sopenharmony_ci if (err) 165462306a36Sopenharmony_ci return err; 165562306a36Sopenharmony_ci } 165662306a36Sopenharmony_ci 165762306a36Sopenharmony_ci return 0; 165862306a36Sopenharmony_ci} 165962306a36Sopenharmony_ci 166062306a36Sopenharmony_cistatic int 166162306a36Sopenharmony_ci__mlxsw_sp_trap_group_init(struct mlxsw_core *mlxsw_core, 166262306a36Sopenharmony_ci const struct devlink_trap_group *group, 166362306a36Sopenharmony_ci u32 policer_id, struct netlink_ext_ack *extack) 166462306a36Sopenharmony_ci{ 166562306a36Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 166662306a36Sopenharmony_ci u16 hw_policer_id = MLXSW_REG_HTGT_INVALID_POLICER; 166762306a36Sopenharmony_ci const struct mlxsw_sp_trap_group_item *group_item; 166862306a36Sopenharmony_ci char htgt_pl[MLXSW_REG_HTGT_LEN]; 166962306a36Sopenharmony_ci 167062306a36Sopenharmony_ci group_item = mlxsw_sp_trap_group_item_lookup(mlxsw_sp, group->id); 167162306a36Sopenharmony_ci if (WARN_ON(!group_item)) 167262306a36Sopenharmony_ci return -EINVAL; 167362306a36Sopenharmony_ci 167462306a36Sopenharmony_ci if (group_item->fixed_policer && policer_id != group->init_policer_id) { 167562306a36Sopenharmony_ci NL_SET_ERR_MSG_MOD(extack, "Changing the policer binding of this group is not supported"); 167662306a36Sopenharmony_ci return -EOPNOTSUPP; 167762306a36Sopenharmony_ci } 167862306a36Sopenharmony_ci 167962306a36Sopenharmony_ci if (policer_id) { 168062306a36Sopenharmony_ci struct mlxsw_sp_trap_policer_item *policer_item; 168162306a36Sopenharmony_ci 168262306a36Sopenharmony_ci policer_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, 168362306a36Sopenharmony_ci policer_id); 168462306a36Sopenharmony_ci if (WARN_ON(!policer_item)) 168562306a36Sopenharmony_ci return -EINVAL; 168662306a36Sopenharmony_ci hw_policer_id = policer_item->hw_id; 168762306a36Sopenharmony_ci } 168862306a36Sopenharmony_ci 168962306a36Sopenharmony_ci mlxsw_reg_htgt_pack(htgt_pl, group_item->hw_group_id, hw_policer_id, 169062306a36Sopenharmony_ci group_item->priority, group_item->priority); 169162306a36Sopenharmony_ci return mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl); 169262306a36Sopenharmony_ci} 169362306a36Sopenharmony_ci 169462306a36Sopenharmony_ciint mlxsw_sp_trap_group_init(struct mlxsw_core *mlxsw_core, 169562306a36Sopenharmony_ci const struct devlink_trap_group *group) 169662306a36Sopenharmony_ci{ 169762306a36Sopenharmony_ci return __mlxsw_sp_trap_group_init(mlxsw_core, group, 169862306a36Sopenharmony_ci group->init_policer_id, NULL); 169962306a36Sopenharmony_ci} 170062306a36Sopenharmony_ci 170162306a36Sopenharmony_ciint mlxsw_sp_trap_group_set(struct mlxsw_core *mlxsw_core, 170262306a36Sopenharmony_ci const struct devlink_trap_group *group, 170362306a36Sopenharmony_ci const struct devlink_trap_policer *policer, 170462306a36Sopenharmony_ci struct netlink_ext_ack *extack) 170562306a36Sopenharmony_ci{ 170662306a36Sopenharmony_ci u32 policer_id = policer ? policer->id : 0; 170762306a36Sopenharmony_ci 170862306a36Sopenharmony_ci return __mlxsw_sp_trap_group_init(mlxsw_core, group, policer_id, 170962306a36Sopenharmony_ci extack); 171062306a36Sopenharmony_ci} 171162306a36Sopenharmony_ci 171262306a36Sopenharmony_cistatic int 171362306a36Sopenharmony_cimlxsw_sp_trap_policer_item_init(struct mlxsw_sp *mlxsw_sp, 171462306a36Sopenharmony_ci struct mlxsw_sp_trap_policer_item *policer_item) 171562306a36Sopenharmony_ci{ 171662306a36Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 171762306a36Sopenharmony_ci u16 hw_id; 171862306a36Sopenharmony_ci 171962306a36Sopenharmony_ci /* We should be able to allocate a policer because the number of 172062306a36Sopenharmony_ci * policers we registered with devlink is in according with the number 172162306a36Sopenharmony_ci * of available policers. 172262306a36Sopenharmony_ci */ 172362306a36Sopenharmony_ci hw_id = find_first_zero_bit(trap->policers_usage, trap->max_policers); 172462306a36Sopenharmony_ci if (WARN_ON(hw_id == trap->max_policers)) 172562306a36Sopenharmony_ci return -ENOBUFS; 172662306a36Sopenharmony_ci 172762306a36Sopenharmony_ci __set_bit(hw_id, trap->policers_usage); 172862306a36Sopenharmony_ci policer_item->hw_id = hw_id; 172962306a36Sopenharmony_ci 173062306a36Sopenharmony_ci return 0; 173162306a36Sopenharmony_ci} 173262306a36Sopenharmony_ci 173362306a36Sopenharmony_cistatic void 173462306a36Sopenharmony_cimlxsw_sp_trap_policer_item_fini(struct mlxsw_sp *mlxsw_sp, 173562306a36Sopenharmony_ci struct mlxsw_sp_trap_policer_item *policer_item) 173662306a36Sopenharmony_ci{ 173762306a36Sopenharmony_ci __clear_bit(policer_item->hw_id, mlxsw_sp->trap->policers_usage); 173862306a36Sopenharmony_ci} 173962306a36Sopenharmony_ci 174062306a36Sopenharmony_cistatic int mlxsw_sp_trap_policer_bs(u64 burst, u8 *p_burst_size, 174162306a36Sopenharmony_ci struct netlink_ext_ack *extack) 174262306a36Sopenharmony_ci{ 174362306a36Sopenharmony_ci int bs = fls64(burst) - 1; 174462306a36Sopenharmony_ci 174562306a36Sopenharmony_ci if (burst != (BIT_ULL(bs))) { 174662306a36Sopenharmony_ci NL_SET_ERR_MSG_MOD(extack, "Policer burst size is not power of two"); 174762306a36Sopenharmony_ci return -EINVAL; 174862306a36Sopenharmony_ci } 174962306a36Sopenharmony_ci 175062306a36Sopenharmony_ci *p_burst_size = bs; 175162306a36Sopenharmony_ci 175262306a36Sopenharmony_ci return 0; 175362306a36Sopenharmony_ci} 175462306a36Sopenharmony_ci 175562306a36Sopenharmony_cistatic int __mlxsw_sp_trap_policer_set(struct mlxsw_sp *mlxsw_sp, u16 hw_id, 175662306a36Sopenharmony_ci u64 rate, u64 burst, bool clear_counter, 175762306a36Sopenharmony_ci struct netlink_ext_ack *extack) 175862306a36Sopenharmony_ci{ 175962306a36Sopenharmony_ci char qpcr_pl[MLXSW_REG_QPCR_LEN]; 176062306a36Sopenharmony_ci u8 burst_size; 176162306a36Sopenharmony_ci int err; 176262306a36Sopenharmony_ci 176362306a36Sopenharmony_ci err = mlxsw_sp_trap_policer_bs(burst, &burst_size, extack); 176462306a36Sopenharmony_ci if (err) 176562306a36Sopenharmony_ci return err; 176662306a36Sopenharmony_ci 176762306a36Sopenharmony_ci mlxsw_reg_qpcr_pack(qpcr_pl, hw_id, MLXSW_REG_QPCR_IR_UNITS_M, false, 176862306a36Sopenharmony_ci rate, burst_size); 176962306a36Sopenharmony_ci mlxsw_reg_qpcr_clear_counter_set(qpcr_pl, clear_counter); 177062306a36Sopenharmony_ci return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qpcr), qpcr_pl); 177162306a36Sopenharmony_ci} 177262306a36Sopenharmony_ci 177362306a36Sopenharmony_ciint mlxsw_sp_trap_policer_init(struct mlxsw_core *mlxsw_core, 177462306a36Sopenharmony_ci const struct devlink_trap_policer *policer) 177562306a36Sopenharmony_ci{ 177662306a36Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 177762306a36Sopenharmony_ci struct mlxsw_sp_trap_policer_item *policer_item; 177862306a36Sopenharmony_ci int err; 177962306a36Sopenharmony_ci 178062306a36Sopenharmony_ci policer_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, policer->id); 178162306a36Sopenharmony_ci if (WARN_ON(!policer_item)) 178262306a36Sopenharmony_ci return -EINVAL; 178362306a36Sopenharmony_ci 178462306a36Sopenharmony_ci err = mlxsw_sp_trap_policer_item_init(mlxsw_sp, policer_item); 178562306a36Sopenharmony_ci if (err) 178662306a36Sopenharmony_ci return err; 178762306a36Sopenharmony_ci 178862306a36Sopenharmony_ci err = __mlxsw_sp_trap_policer_set(mlxsw_sp, policer_item->hw_id, 178962306a36Sopenharmony_ci policer->init_rate, 179062306a36Sopenharmony_ci policer->init_burst, true, NULL); 179162306a36Sopenharmony_ci if (err) 179262306a36Sopenharmony_ci goto err_trap_policer_set; 179362306a36Sopenharmony_ci 179462306a36Sopenharmony_ci return 0; 179562306a36Sopenharmony_ci 179662306a36Sopenharmony_cierr_trap_policer_set: 179762306a36Sopenharmony_ci mlxsw_sp_trap_policer_item_fini(mlxsw_sp, policer_item); 179862306a36Sopenharmony_ci return err; 179962306a36Sopenharmony_ci} 180062306a36Sopenharmony_ci 180162306a36Sopenharmony_civoid mlxsw_sp_trap_policer_fini(struct mlxsw_core *mlxsw_core, 180262306a36Sopenharmony_ci const struct devlink_trap_policer *policer) 180362306a36Sopenharmony_ci{ 180462306a36Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 180562306a36Sopenharmony_ci struct mlxsw_sp_trap_policer_item *policer_item; 180662306a36Sopenharmony_ci 180762306a36Sopenharmony_ci policer_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, policer->id); 180862306a36Sopenharmony_ci if (WARN_ON(!policer_item)) 180962306a36Sopenharmony_ci return; 181062306a36Sopenharmony_ci 181162306a36Sopenharmony_ci mlxsw_sp_trap_policer_item_fini(mlxsw_sp, policer_item); 181262306a36Sopenharmony_ci} 181362306a36Sopenharmony_ci 181462306a36Sopenharmony_ciint mlxsw_sp_trap_policer_set(struct mlxsw_core *mlxsw_core, 181562306a36Sopenharmony_ci const struct devlink_trap_policer *policer, 181662306a36Sopenharmony_ci u64 rate, u64 burst, 181762306a36Sopenharmony_ci struct netlink_ext_ack *extack) 181862306a36Sopenharmony_ci{ 181962306a36Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 182062306a36Sopenharmony_ci struct mlxsw_sp_trap_policer_item *policer_item; 182162306a36Sopenharmony_ci 182262306a36Sopenharmony_ci policer_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, policer->id); 182362306a36Sopenharmony_ci if (WARN_ON(!policer_item)) 182462306a36Sopenharmony_ci return -EINVAL; 182562306a36Sopenharmony_ci 182662306a36Sopenharmony_ci return __mlxsw_sp_trap_policer_set(mlxsw_sp, policer_item->hw_id, 182762306a36Sopenharmony_ci rate, burst, false, extack); 182862306a36Sopenharmony_ci} 182962306a36Sopenharmony_ci 183062306a36Sopenharmony_ciint 183162306a36Sopenharmony_cimlxsw_sp_trap_policer_counter_get(struct mlxsw_core *mlxsw_core, 183262306a36Sopenharmony_ci const struct devlink_trap_policer *policer, 183362306a36Sopenharmony_ci u64 *p_drops) 183462306a36Sopenharmony_ci{ 183562306a36Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 183662306a36Sopenharmony_ci struct mlxsw_sp_trap_policer_item *policer_item; 183762306a36Sopenharmony_ci char qpcr_pl[MLXSW_REG_QPCR_LEN]; 183862306a36Sopenharmony_ci int err; 183962306a36Sopenharmony_ci 184062306a36Sopenharmony_ci policer_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, policer->id); 184162306a36Sopenharmony_ci if (WARN_ON(!policer_item)) 184262306a36Sopenharmony_ci return -EINVAL; 184362306a36Sopenharmony_ci 184462306a36Sopenharmony_ci mlxsw_reg_qpcr_pack(qpcr_pl, policer_item->hw_id, 184562306a36Sopenharmony_ci MLXSW_REG_QPCR_IR_UNITS_M, false, 0, 0); 184662306a36Sopenharmony_ci err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(qpcr), qpcr_pl); 184762306a36Sopenharmony_ci if (err) 184862306a36Sopenharmony_ci return err; 184962306a36Sopenharmony_ci 185062306a36Sopenharmony_ci *p_drops = mlxsw_reg_qpcr_violate_count_get(qpcr_pl); 185162306a36Sopenharmony_ci 185262306a36Sopenharmony_ci return 0; 185362306a36Sopenharmony_ci} 185462306a36Sopenharmony_ci 185562306a36Sopenharmony_ciint mlxsw_sp_trap_group_policer_hw_id_get(struct mlxsw_sp *mlxsw_sp, u16 id, 185662306a36Sopenharmony_ci bool *p_enabled, u16 *p_hw_id) 185762306a36Sopenharmony_ci{ 185862306a36Sopenharmony_ci struct mlxsw_sp_trap_policer_item *pol_item; 185962306a36Sopenharmony_ci struct mlxsw_sp_trap_group_item *gr_item; 186062306a36Sopenharmony_ci u32 pol_id; 186162306a36Sopenharmony_ci 186262306a36Sopenharmony_ci gr_item = mlxsw_sp_trap_group_item_lookup(mlxsw_sp, id); 186362306a36Sopenharmony_ci if (!gr_item) 186462306a36Sopenharmony_ci return -ENOENT; 186562306a36Sopenharmony_ci 186662306a36Sopenharmony_ci pol_id = gr_item->group.init_policer_id; 186762306a36Sopenharmony_ci if (!pol_id) { 186862306a36Sopenharmony_ci *p_enabled = false; 186962306a36Sopenharmony_ci return 0; 187062306a36Sopenharmony_ci } 187162306a36Sopenharmony_ci 187262306a36Sopenharmony_ci pol_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, pol_id); 187362306a36Sopenharmony_ci if (WARN_ON(!pol_item)) 187462306a36Sopenharmony_ci return -ENOENT; 187562306a36Sopenharmony_ci 187662306a36Sopenharmony_ci *p_enabled = true; 187762306a36Sopenharmony_ci *p_hw_id = pol_item->hw_id; 187862306a36Sopenharmony_ci return 0; 187962306a36Sopenharmony_ci} 188062306a36Sopenharmony_ci 188162306a36Sopenharmony_cistatic const struct mlxsw_sp_trap_group_item 188262306a36Sopenharmony_cimlxsw_sp1_trap_group_items_arr[] = { 188362306a36Sopenharmony_ci { 188462306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(ACL_SAMPLE, 0), 188562306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_PKT_SAMPLE, 188662306a36Sopenharmony_ci .priority = 0, 188762306a36Sopenharmony_ci }, 188862306a36Sopenharmony_ci}; 188962306a36Sopenharmony_ci 189062306a36Sopenharmony_cistatic const struct mlxsw_sp_trap_item 189162306a36Sopenharmony_cimlxsw_sp1_trap_items_arr[] = { 189262306a36Sopenharmony_ci { 189362306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(FLOW_ACTION_SAMPLE, ACL_SAMPLE, 189462306a36Sopenharmony_ci MIRROR), 189562306a36Sopenharmony_ci .listeners_arr = { 189662306a36Sopenharmony_ci MLXSW_RXL(mlxsw_sp_rx_sample_listener, PKT_SAMPLE, 189762306a36Sopenharmony_ci MIRROR_TO_CPU, false, SP_PKT_SAMPLE, DISCARD), 189862306a36Sopenharmony_ci }, 189962306a36Sopenharmony_ci }, 190062306a36Sopenharmony_ci}; 190162306a36Sopenharmony_ci 190262306a36Sopenharmony_cistatic int 190362306a36Sopenharmony_cimlxsw_sp1_trap_groups_init(struct mlxsw_sp *mlxsw_sp, 190462306a36Sopenharmony_ci const struct mlxsw_sp_trap_group_item **arr, 190562306a36Sopenharmony_ci size_t *p_groups_count) 190662306a36Sopenharmony_ci{ 190762306a36Sopenharmony_ci *arr = mlxsw_sp1_trap_group_items_arr; 190862306a36Sopenharmony_ci *p_groups_count = ARRAY_SIZE(mlxsw_sp1_trap_group_items_arr); 190962306a36Sopenharmony_ci 191062306a36Sopenharmony_ci return 0; 191162306a36Sopenharmony_ci} 191262306a36Sopenharmony_ci 191362306a36Sopenharmony_cistatic int mlxsw_sp1_traps_init(struct mlxsw_sp *mlxsw_sp, 191462306a36Sopenharmony_ci const struct mlxsw_sp_trap_item **arr, 191562306a36Sopenharmony_ci size_t *p_traps_count) 191662306a36Sopenharmony_ci{ 191762306a36Sopenharmony_ci *arr = mlxsw_sp1_trap_items_arr; 191862306a36Sopenharmony_ci *p_traps_count = ARRAY_SIZE(mlxsw_sp1_trap_items_arr); 191962306a36Sopenharmony_ci 192062306a36Sopenharmony_ci return 0; 192162306a36Sopenharmony_ci} 192262306a36Sopenharmony_ci 192362306a36Sopenharmony_ciconst struct mlxsw_sp_trap_ops mlxsw_sp1_trap_ops = { 192462306a36Sopenharmony_ci .groups_init = mlxsw_sp1_trap_groups_init, 192562306a36Sopenharmony_ci .traps_init = mlxsw_sp1_traps_init, 192662306a36Sopenharmony_ci}; 192762306a36Sopenharmony_ci 192862306a36Sopenharmony_cistatic const struct mlxsw_sp_trap_group_item 192962306a36Sopenharmony_cimlxsw_sp2_trap_group_items_arr[] = { 193062306a36Sopenharmony_ci { 193162306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(BUFFER_DROPS, 20), 193262306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_BUFFER_DISCARDS, 193362306a36Sopenharmony_ci .priority = 0, 193462306a36Sopenharmony_ci .fixed_policer = true, 193562306a36Sopenharmony_ci }, 193662306a36Sopenharmony_ci { 193762306a36Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(ACL_SAMPLE, 0), 193862306a36Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_PKT_SAMPLE, 193962306a36Sopenharmony_ci .priority = 0, 194062306a36Sopenharmony_ci .fixed_policer = true, 194162306a36Sopenharmony_ci }, 194262306a36Sopenharmony_ci}; 194362306a36Sopenharmony_ci 194462306a36Sopenharmony_cistatic const struct mlxsw_sp_trap_item 194562306a36Sopenharmony_cimlxsw_sp2_trap_items_arr[] = { 194662306a36Sopenharmony_ci { 194762306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_BUFFER_DROP(EARLY_DROP), 194862306a36Sopenharmony_ci .listeners_arr = { 194962306a36Sopenharmony_ci MLXSW_SP_RXL_BUFFER_DISCARD(INGRESS_WRED), 195062306a36Sopenharmony_ci }, 195162306a36Sopenharmony_ci .is_source = true, 195262306a36Sopenharmony_ci }, 195362306a36Sopenharmony_ci { 195462306a36Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(FLOW_ACTION_SAMPLE, ACL_SAMPLE, 195562306a36Sopenharmony_ci MIRROR), 195662306a36Sopenharmony_ci .listeners_arr = { 195762306a36Sopenharmony_ci MLXSW_RXL_MIRROR(mlxsw_sp_rx_sample_listener, 1, 195862306a36Sopenharmony_ci SP_PKT_SAMPLE, 195962306a36Sopenharmony_ci MLXSW_SP_MIRROR_REASON_INGRESS), 196062306a36Sopenharmony_ci MLXSW_RXL_MIRROR(mlxsw_sp_rx_sample_tx_listener, 1, 196162306a36Sopenharmony_ci SP_PKT_SAMPLE, 196262306a36Sopenharmony_ci MLXSW_SP_MIRROR_REASON_EGRESS), 196362306a36Sopenharmony_ci MLXSW_RXL_MIRROR(mlxsw_sp_rx_sample_acl_listener, 1, 196462306a36Sopenharmony_ci SP_PKT_SAMPLE, 196562306a36Sopenharmony_ci MLXSW_SP_MIRROR_REASON_POLICY_ENGINE), 196662306a36Sopenharmony_ci }, 196762306a36Sopenharmony_ci }, 196862306a36Sopenharmony_ci}; 196962306a36Sopenharmony_ci 197062306a36Sopenharmony_cistatic int 197162306a36Sopenharmony_cimlxsw_sp2_trap_groups_init(struct mlxsw_sp *mlxsw_sp, 197262306a36Sopenharmony_ci const struct mlxsw_sp_trap_group_item **arr, 197362306a36Sopenharmony_ci size_t *p_groups_count) 197462306a36Sopenharmony_ci{ 197562306a36Sopenharmony_ci *arr = mlxsw_sp2_trap_group_items_arr; 197662306a36Sopenharmony_ci *p_groups_count = ARRAY_SIZE(mlxsw_sp2_trap_group_items_arr); 197762306a36Sopenharmony_ci 197862306a36Sopenharmony_ci return 0; 197962306a36Sopenharmony_ci} 198062306a36Sopenharmony_ci 198162306a36Sopenharmony_cistatic int mlxsw_sp2_traps_init(struct mlxsw_sp *mlxsw_sp, 198262306a36Sopenharmony_ci const struct mlxsw_sp_trap_item **arr, 198362306a36Sopenharmony_ci size_t *p_traps_count) 198462306a36Sopenharmony_ci{ 198562306a36Sopenharmony_ci *arr = mlxsw_sp2_trap_items_arr; 198662306a36Sopenharmony_ci *p_traps_count = ARRAY_SIZE(mlxsw_sp2_trap_items_arr); 198762306a36Sopenharmony_ci 198862306a36Sopenharmony_ci return 0; 198962306a36Sopenharmony_ci} 199062306a36Sopenharmony_ci 199162306a36Sopenharmony_ciconst struct mlxsw_sp_trap_ops mlxsw_sp2_trap_ops = { 199262306a36Sopenharmony_ci .groups_init = mlxsw_sp2_trap_groups_init, 199362306a36Sopenharmony_ci .traps_init = mlxsw_sp2_traps_init, 199462306a36Sopenharmony_ci}; 1995