18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 28c2ecf20Sopenharmony_ci/* Copyright (c) 2019 Mellanox Technologies. All rights reserved */ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include <linux/bitops.h> 58c2ecf20Sopenharmony_ci#include <linux/kernel.h> 68c2ecf20Sopenharmony_ci#include <linux/netlink.h> 78c2ecf20Sopenharmony_ci#include <net/devlink.h> 88c2ecf20Sopenharmony_ci#include <uapi/linux/devlink.h> 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include "core.h" 118c2ecf20Sopenharmony_ci#include "reg.h" 128c2ecf20Sopenharmony_ci#include "spectrum.h" 138c2ecf20Sopenharmony_ci#include "spectrum_trap.h" 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_cistruct mlxsw_sp_trap_policer_item { 168c2ecf20Sopenharmony_ci struct devlink_trap_policer policer; 178c2ecf20Sopenharmony_ci u16 hw_id; 188c2ecf20Sopenharmony_ci}; 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_cistruct mlxsw_sp_trap_group_item { 218c2ecf20Sopenharmony_ci struct devlink_trap_group group; 228c2ecf20Sopenharmony_ci u16 hw_group_id; 238c2ecf20Sopenharmony_ci u8 priority; 248c2ecf20Sopenharmony_ci u8 fixed_policer:1; /* Whether policer binding can change */ 258c2ecf20Sopenharmony_ci}; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#define MLXSW_SP_TRAP_LISTENERS_MAX 3 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_cistruct mlxsw_sp_trap_item { 308c2ecf20Sopenharmony_ci struct devlink_trap trap; 318c2ecf20Sopenharmony_ci struct mlxsw_listener listeners_arr[MLXSW_SP_TRAP_LISTENERS_MAX]; 328c2ecf20Sopenharmony_ci u8 is_source:1; 338c2ecf20Sopenharmony_ci}; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci/* All driver-specific traps must be documented in 368c2ecf20Sopenharmony_ci * Documentation/networking/devlink/mlxsw.rst 378c2ecf20Sopenharmony_ci */ 388c2ecf20Sopenharmony_cienum { 398c2ecf20Sopenharmony_ci DEVLINK_MLXSW_TRAP_ID_BASE = DEVLINK_TRAP_GENERIC_ID_MAX, 408c2ecf20Sopenharmony_ci DEVLINK_MLXSW_TRAP_ID_IRIF_DISABLED, 418c2ecf20Sopenharmony_ci DEVLINK_MLXSW_TRAP_ID_ERIF_DISABLED, 428c2ecf20Sopenharmony_ci}; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci#define DEVLINK_MLXSW_TRAP_NAME_IRIF_DISABLED \ 458c2ecf20Sopenharmony_ci "irif_disabled" 468c2ecf20Sopenharmony_ci#define DEVLINK_MLXSW_TRAP_NAME_ERIF_DISABLED \ 478c2ecf20Sopenharmony_ci "erif_disabled" 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci#define MLXSW_SP_TRAP_METADATA DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cienum { 528c2ecf20Sopenharmony_ci /* Packet was early dropped. */ 538c2ecf20Sopenharmony_ci MLXSW_SP_MIRROR_REASON_INGRESS_WRED = 9, 548c2ecf20Sopenharmony_ci}; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistatic int mlxsw_sp_rx_listener(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb, 578c2ecf20Sopenharmony_ci u8 local_port, 588c2ecf20Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port) 598c2ecf20Sopenharmony_ci{ 608c2ecf20Sopenharmony_ci struct mlxsw_sp_port_pcpu_stats *pcpu_stats; 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci if (unlikely(!mlxsw_sp_port)) { 638c2ecf20Sopenharmony_ci dev_warn_ratelimited(mlxsw_sp->bus_info->dev, "Port %d: skb received for non-existent port\n", 648c2ecf20Sopenharmony_ci local_port); 658c2ecf20Sopenharmony_ci kfree_skb(skb); 668c2ecf20Sopenharmony_ci return -EINVAL; 678c2ecf20Sopenharmony_ci } 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci skb->dev = mlxsw_sp_port->dev; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci pcpu_stats = this_cpu_ptr(mlxsw_sp_port->pcpu_stats); 728c2ecf20Sopenharmony_ci u64_stats_update_begin(&pcpu_stats->syncp); 738c2ecf20Sopenharmony_ci pcpu_stats->rx_packets++; 748c2ecf20Sopenharmony_ci pcpu_stats->rx_bytes += skb->len; 758c2ecf20Sopenharmony_ci u64_stats_update_end(&pcpu_stats->syncp); 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci skb->protocol = eth_type_trans(skb, skb->dev); 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci return 0; 808c2ecf20Sopenharmony_ci} 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_cistatic void mlxsw_sp_rx_drop_listener(struct sk_buff *skb, u8 local_port, 838c2ecf20Sopenharmony_ci void *trap_ctx) 848c2ecf20Sopenharmony_ci{ 858c2ecf20Sopenharmony_ci struct devlink_port *in_devlink_port; 868c2ecf20Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port; 878c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp; 888c2ecf20Sopenharmony_ci struct devlink *devlink; 898c2ecf20Sopenharmony_ci int err; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci mlxsw_sp = devlink_trap_ctx_priv(trap_ctx); 928c2ecf20Sopenharmony_ci mlxsw_sp_port = mlxsw_sp->ports[local_port]; 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci err = mlxsw_sp_rx_listener(mlxsw_sp, skb, local_port, mlxsw_sp_port); 958c2ecf20Sopenharmony_ci if (err) 968c2ecf20Sopenharmony_ci return; 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci devlink = priv_to_devlink(mlxsw_sp->core); 998c2ecf20Sopenharmony_ci in_devlink_port = mlxsw_core_port_devlink_port_get(mlxsw_sp->core, 1008c2ecf20Sopenharmony_ci local_port); 1018c2ecf20Sopenharmony_ci skb_push(skb, ETH_HLEN); 1028c2ecf20Sopenharmony_ci devlink_trap_report(devlink, skb, trap_ctx, in_devlink_port, NULL); 1038c2ecf20Sopenharmony_ci consume_skb(skb); 1048c2ecf20Sopenharmony_ci} 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_cistatic void mlxsw_sp_rx_acl_drop_listener(struct sk_buff *skb, u8 local_port, 1078c2ecf20Sopenharmony_ci void *trap_ctx) 1088c2ecf20Sopenharmony_ci{ 1098c2ecf20Sopenharmony_ci u32 cookie_index = mlxsw_skb_cb(skb)->cookie_index; 1108c2ecf20Sopenharmony_ci const struct flow_action_cookie *fa_cookie; 1118c2ecf20Sopenharmony_ci struct devlink_port *in_devlink_port; 1128c2ecf20Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port; 1138c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp; 1148c2ecf20Sopenharmony_ci struct devlink *devlink; 1158c2ecf20Sopenharmony_ci int err; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci mlxsw_sp = devlink_trap_ctx_priv(trap_ctx); 1188c2ecf20Sopenharmony_ci mlxsw_sp_port = mlxsw_sp->ports[local_port]; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci err = mlxsw_sp_rx_listener(mlxsw_sp, skb, local_port, mlxsw_sp_port); 1218c2ecf20Sopenharmony_ci if (err) 1228c2ecf20Sopenharmony_ci return; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci devlink = priv_to_devlink(mlxsw_sp->core); 1258c2ecf20Sopenharmony_ci in_devlink_port = mlxsw_core_port_devlink_port_get(mlxsw_sp->core, 1268c2ecf20Sopenharmony_ci local_port); 1278c2ecf20Sopenharmony_ci skb_push(skb, ETH_HLEN); 1288c2ecf20Sopenharmony_ci rcu_read_lock(); 1298c2ecf20Sopenharmony_ci fa_cookie = mlxsw_sp_acl_act_cookie_lookup(mlxsw_sp, cookie_index); 1308c2ecf20Sopenharmony_ci devlink_trap_report(devlink, skb, trap_ctx, in_devlink_port, fa_cookie); 1318c2ecf20Sopenharmony_ci rcu_read_unlock(); 1328c2ecf20Sopenharmony_ci consume_skb(skb); 1338c2ecf20Sopenharmony_ci} 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_cistatic int __mlxsw_sp_rx_no_mark_listener(struct sk_buff *skb, u8 local_port, 1368c2ecf20Sopenharmony_ci void *trap_ctx) 1378c2ecf20Sopenharmony_ci{ 1388c2ecf20Sopenharmony_ci struct devlink_port *in_devlink_port; 1398c2ecf20Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port; 1408c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp; 1418c2ecf20Sopenharmony_ci struct devlink *devlink; 1428c2ecf20Sopenharmony_ci int err; 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci mlxsw_sp = devlink_trap_ctx_priv(trap_ctx); 1458c2ecf20Sopenharmony_ci mlxsw_sp_port = mlxsw_sp->ports[local_port]; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci err = mlxsw_sp_rx_listener(mlxsw_sp, skb, local_port, mlxsw_sp_port); 1488c2ecf20Sopenharmony_ci if (err) 1498c2ecf20Sopenharmony_ci return err; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci devlink = priv_to_devlink(mlxsw_sp->core); 1528c2ecf20Sopenharmony_ci in_devlink_port = mlxsw_core_port_devlink_port_get(mlxsw_sp->core, 1538c2ecf20Sopenharmony_ci local_port); 1548c2ecf20Sopenharmony_ci skb_push(skb, ETH_HLEN); 1558c2ecf20Sopenharmony_ci devlink_trap_report(devlink, skb, trap_ctx, in_devlink_port, NULL); 1568c2ecf20Sopenharmony_ci skb_pull(skb, ETH_HLEN); 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci return 0; 1598c2ecf20Sopenharmony_ci} 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_cistatic void mlxsw_sp_rx_no_mark_listener(struct sk_buff *skb, u8 local_port, 1628c2ecf20Sopenharmony_ci void *trap_ctx) 1638c2ecf20Sopenharmony_ci{ 1648c2ecf20Sopenharmony_ci int err; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci err = __mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx); 1678c2ecf20Sopenharmony_ci if (err) 1688c2ecf20Sopenharmony_ci return; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci netif_receive_skb(skb); 1718c2ecf20Sopenharmony_ci} 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_cistatic void mlxsw_sp_rx_mark_listener(struct sk_buff *skb, u8 local_port, 1748c2ecf20Sopenharmony_ci void *trap_ctx) 1758c2ecf20Sopenharmony_ci{ 1768c2ecf20Sopenharmony_ci skb->offload_fwd_mark = 1; 1778c2ecf20Sopenharmony_ci mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx); 1788c2ecf20Sopenharmony_ci} 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_cistatic void mlxsw_sp_rx_l3_mark_listener(struct sk_buff *skb, u8 local_port, 1818c2ecf20Sopenharmony_ci void *trap_ctx) 1828c2ecf20Sopenharmony_ci{ 1838c2ecf20Sopenharmony_ci skb->offload_l3_fwd_mark = 1; 1848c2ecf20Sopenharmony_ci skb->offload_fwd_mark = 1; 1858c2ecf20Sopenharmony_ci mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx); 1868c2ecf20Sopenharmony_ci} 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_cistatic void mlxsw_sp_rx_ptp_listener(struct sk_buff *skb, u8 local_port, 1898c2ecf20Sopenharmony_ci void *trap_ctx) 1908c2ecf20Sopenharmony_ci{ 1918c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = devlink_trap_ctx_priv(trap_ctx); 1928c2ecf20Sopenharmony_ci int err; 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci err = __mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx); 1958c2ecf20Sopenharmony_ci if (err) 1968c2ecf20Sopenharmony_ci return; 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci /* The PTP handler expects skb->data to point to the start of the 1998c2ecf20Sopenharmony_ci * Ethernet header. 2008c2ecf20Sopenharmony_ci */ 2018c2ecf20Sopenharmony_ci skb_push(skb, ETH_HLEN); 2028c2ecf20Sopenharmony_ci mlxsw_sp_ptp_receive(mlxsw_sp, skb, local_port); 2038c2ecf20Sopenharmony_ci} 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_cistatic void mlxsw_sp_rx_sample_listener(struct sk_buff *skb, u8 local_port, 2068c2ecf20Sopenharmony_ci void *trap_ctx) 2078c2ecf20Sopenharmony_ci{ 2088c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = devlink_trap_ctx_priv(trap_ctx); 2098c2ecf20Sopenharmony_ci int err; 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci err = __mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx); 2128c2ecf20Sopenharmony_ci if (err) 2138c2ecf20Sopenharmony_ci return; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci /* The sample handler expects skb->data to point to the start of the 2168c2ecf20Sopenharmony_ci * Ethernet header. 2178c2ecf20Sopenharmony_ci */ 2188c2ecf20Sopenharmony_ci skb_push(skb, ETH_HLEN); 2198c2ecf20Sopenharmony_ci mlxsw_sp_sample_receive(mlxsw_sp, skb, local_port); 2208c2ecf20Sopenharmony_ci} 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci#define MLXSW_SP_TRAP_DROP(_id, _group_id) \ 2238c2ecf20Sopenharmony_ci DEVLINK_TRAP_GENERIC(DROP, DROP, _id, \ 2248c2ecf20Sopenharmony_ci DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \ 2258c2ecf20Sopenharmony_ci MLXSW_SP_TRAP_METADATA) 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci#define MLXSW_SP_TRAP_DROP_EXT(_id, _group_id, _metadata) \ 2288c2ecf20Sopenharmony_ci DEVLINK_TRAP_GENERIC(DROP, DROP, _id, \ 2298c2ecf20Sopenharmony_ci DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \ 2308c2ecf20Sopenharmony_ci MLXSW_SP_TRAP_METADATA | (_metadata)) 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci#define MLXSW_SP_TRAP_BUFFER_DROP(_id) \ 2338c2ecf20Sopenharmony_ci DEVLINK_TRAP_GENERIC(DROP, TRAP, _id, \ 2348c2ecf20Sopenharmony_ci DEVLINK_TRAP_GROUP_GENERIC_ID_BUFFER_DROPS, \ 2358c2ecf20Sopenharmony_ci MLXSW_SP_TRAP_METADATA) 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci#define MLXSW_SP_TRAP_DRIVER_DROP(_id, _group_id) \ 2388c2ecf20Sopenharmony_ci DEVLINK_TRAP_DRIVER(DROP, DROP, DEVLINK_MLXSW_TRAP_ID_##_id, \ 2398c2ecf20Sopenharmony_ci DEVLINK_MLXSW_TRAP_NAME_##_id, \ 2408c2ecf20Sopenharmony_ci DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \ 2418c2ecf20Sopenharmony_ci MLXSW_SP_TRAP_METADATA) 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci#define MLXSW_SP_TRAP_EXCEPTION(_id, _group_id) \ 2448c2ecf20Sopenharmony_ci DEVLINK_TRAP_GENERIC(EXCEPTION, TRAP, _id, \ 2458c2ecf20Sopenharmony_ci DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \ 2468c2ecf20Sopenharmony_ci MLXSW_SP_TRAP_METADATA) 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci#define MLXSW_SP_TRAP_CONTROL(_id, _group_id, _action) \ 2498c2ecf20Sopenharmony_ci DEVLINK_TRAP_GENERIC(CONTROL, _action, _id, \ 2508c2ecf20Sopenharmony_ci DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \ 2518c2ecf20Sopenharmony_ci MLXSW_SP_TRAP_METADATA) 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci#define MLXSW_SP_RXL_DISCARD(_id, _group_id) \ 2548c2ecf20Sopenharmony_ci MLXSW_RXL_DIS(mlxsw_sp_rx_drop_listener, DISCARD_##_id, \ 2558c2ecf20Sopenharmony_ci TRAP_EXCEPTION_TO_CPU, false, SP_##_group_id, \ 2568c2ecf20Sopenharmony_ci SET_FW_DEFAULT, SP_##_group_id) 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci#define MLXSW_SP_RXL_ACL_DISCARD(_id, _en_group_id, _dis_group_id) \ 2598c2ecf20Sopenharmony_ci MLXSW_RXL_DIS(mlxsw_sp_rx_acl_drop_listener, DISCARD_##_id, \ 2608c2ecf20Sopenharmony_ci TRAP_EXCEPTION_TO_CPU, false, SP_##_en_group_id, \ 2618c2ecf20Sopenharmony_ci SET_FW_DEFAULT, SP_##_dis_group_id) 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci#define MLXSW_SP_RXL_BUFFER_DISCARD(_mirror_reason) \ 2648c2ecf20Sopenharmony_ci MLXSW_RXL_MIRROR(mlxsw_sp_rx_drop_listener, 0, SP_BUFFER_DISCARDS, \ 2658c2ecf20Sopenharmony_ci MLXSW_SP_MIRROR_REASON_##_mirror_reason) 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci#define MLXSW_SP_RXL_EXCEPTION(_id, _group_id, _action) \ 2688c2ecf20Sopenharmony_ci MLXSW_RXL(mlxsw_sp_rx_mark_listener, _id, \ 2698c2ecf20Sopenharmony_ci _action, false, SP_##_group_id, SET_FW_DEFAULT) 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci#define MLXSW_SP_RXL_NO_MARK(_id, _group_id, _action, _is_ctrl) \ 2728c2ecf20Sopenharmony_ci MLXSW_RXL(mlxsw_sp_rx_no_mark_listener, _id, _action, \ 2738c2ecf20Sopenharmony_ci _is_ctrl, SP_##_group_id, DISCARD) 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci#define MLXSW_SP_RXL_MARK(_id, _group_id, _action, _is_ctrl) \ 2768c2ecf20Sopenharmony_ci MLXSW_RXL(mlxsw_sp_rx_mark_listener, _id, _action, _is_ctrl, \ 2778c2ecf20Sopenharmony_ci SP_##_group_id, DISCARD) 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci#define MLXSW_SP_RXL_L3_MARK(_id, _group_id, _action, _is_ctrl) \ 2808c2ecf20Sopenharmony_ci MLXSW_RXL(mlxsw_sp_rx_l3_mark_listener, _id, _action, _is_ctrl, \ 2818c2ecf20Sopenharmony_ci SP_##_group_id, DISCARD) 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci#define MLXSW_SP_TRAP_POLICER(_id, _rate, _burst) \ 2848c2ecf20Sopenharmony_ci DEVLINK_TRAP_POLICER(_id, _rate, _burst, \ 2858c2ecf20Sopenharmony_ci MLXSW_REG_QPCR_HIGHEST_CIR, \ 2868c2ecf20Sopenharmony_ci MLXSW_REG_QPCR_LOWEST_CIR, \ 2878c2ecf20Sopenharmony_ci 1 << MLXSW_REG_QPCR_HIGHEST_CBS, \ 2888c2ecf20Sopenharmony_ci 1 << MLXSW_REG_QPCR_LOWEST_CBS) 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci/* Ordered by policer identifier */ 2918c2ecf20Sopenharmony_cistatic const struct mlxsw_sp_trap_policer_item 2928c2ecf20Sopenharmony_cimlxsw_sp_trap_policer_items_arr[] = { 2938c2ecf20Sopenharmony_ci { 2948c2ecf20Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(1, 10 * 1024, 4096), 2958c2ecf20Sopenharmony_ci }, 2968c2ecf20Sopenharmony_ci { 2978c2ecf20Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(2, 128, 128), 2988c2ecf20Sopenharmony_ci }, 2998c2ecf20Sopenharmony_ci { 3008c2ecf20Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(3, 128, 128), 3018c2ecf20Sopenharmony_ci }, 3028c2ecf20Sopenharmony_ci { 3038c2ecf20Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(4, 128, 128), 3048c2ecf20Sopenharmony_ci }, 3058c2ecf20Sopenharmony_ci { 3068c2ecf20Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(5, 16 * 1024, 8192), 3078c2ecf20Sopenharmony_ci }, 3088c2ecf20Sopenharmony_ci { 3098c2ecf20Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(6, 128, 128), 3108c2ecf20Sopenharmony_ci }, 3118c2ecf20Sopenharmony_ci { 3128c2ecf20Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(7, 1024, 512), 3138c2ecf20Sopenharmony_ci }, 3148c2ecf20Sopenharmony_ci { 3158c2ecf20Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(8, 20 * 1024, 8192), 3168c2ecf20Sopenharmony_ci }, 3178c2ecf20Sopenharmony_ci { 3188c2ecf20Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(9, 128, 128), 3198c2ecf20Sopenharmony_ci }, 3208c2ecf20Sopenharmony_ci { 3218c2ecf20Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(10, 1024, 512), 3228c2ecf20Sopenharmony_ci }, 3238c2ecf20Sopenharmony_ci { 3248c2ecf20Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(11, 256, 128), 3258c2ecf20Sopenharmony_ci }, 3268c2ecf20Sopenharmony_ci { 3278c2ecf20Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(12, 128, 128), 3288c2ecf20Sopenharmony_ci }, 3298c2ecf20Sopenharmony_ci { 3308c2ecf20Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(13, 128, 128), 3318c2ecf20Sopenharmony_ci }, 3328c2ecf20Sopenharmony_ci { 3338c2ecf20Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(14, 1024, 512), 3348c2ecf20Sopenharmony_ci }, 3358c2ecf20Sopenharmony_ci { 3368c2ecf20Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(15, 1024, 512), 3378c2ecf20Sopenharmony_ci }, 3388c2ecf20Sopenharmony_ci { 3398c2ecf20Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(16, 24 * 1024, 16384), 3408c2ecf20Sopenharmony_ci }, 3418c2ecf20Sopenharmony_ci { 3428c2ecf20Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(17, 19 * 1024, 8192), 3438c2ecf20Sopenharmony_ci }, 3448c2ecf20Sopenharmony_ci { 3458c2ecf20Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(18, 1024, 512), 3468c2ecf20Sopenharmony_ci }, 3478c2ecf20Sopenharmony_ci { 3488c2ecf20Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(19, 1024, 512), 3498c2ecf20Sopenharmony_ci }, 3508c2ecf20Sopenharmony_ci { 3518c2ecf20Sopenharmony_ci .policer = MLXSW_SP_TRAP_POLICER(20, 10240, 4096), 3528c2ecf20Sopenharmony_ci }, 3538c2ecf20Sopenharmony_ci}; 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_cistatic const struct mlxsw_sp_trap_group_item mlxsw_sp_trap_group_items_arr[] = { 3568c2ecf20Sopenharmony_ci { 3578c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS, 1), 3588c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_L2_DISCARDS, 3598c2ecf20Sopenharmony_ci .priority = 0, 3608c2ecf20Sopenharmony_ci }, 3618c2ecf20Sopenharmony_ci { 3628c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(L3_DROPS, 1), 3638c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_L3_DISCARDS, 3648c2ecf20Sopenharmony_ci .priority = 0, 3658c2ecf20Sopenharmony_ci }, 3668c2ecf20Sopenharmony_ci { 3678c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(L3_EXCEPTIONS, 1), 3688c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_L3_EXCEPTIONS, 3698c2ecf20Sopenharmony_ci .priority = 2, 3708c2ecf20Sopenharmony_ci }, 3718c2ecf20Sopenharmony_ci { 3728c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(TUNNEL_DROPS, 1), 3738c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_TUNNEL_DISCARDS, 3748c2ecf20Sopenharmony_ci .priority = 0, 3758c2ecf20Sopenharmony_ci }, 3768c2ecf20Sopenharmony_ci { 3778c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(ACL_DROPS, 1), 3788c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_ACL_DISCARDS, 3798c2ecf20Sopenharmony_ci .priority = 0, 3808c2ecf20Sopenharmony_ci }, 3818c2ecf20Sopenharmony_ci { 3828c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(STP, 2), 3838c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_STP, 3848c2ecf20Sopenharmony_ci .priority = 5, 3858c2ecf20Sopenharmony_ci }, 3868c2ecf20Sopenharmony_ci { 3878c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(LACP, 3), 3888c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_LACP, 3898c2ecf20Sopenharmony_ci .priority = 5, 3908c2ecf20Sopenharmony_ci }, 3918c2ecf20Sopenharmony_ci { 3928c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(LLDP, 4), 3938c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_LLDP, 3948c2ecf20Sopenharmony_ci .priority = 5, 3958c2ecf20Sopenharmony_ci }, 3968c2ecf20Sopenharmony_ci { 3978c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(MC_SNOOPING, 5), 3988c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_MC_SNOOPING, 3998c2ecf20Sopenharmony_ci .priority = 3, 4008c2ecf20Sopenharmony_ci }, 4018c2ecf20Sopenharmony_ci { 4028c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(DHCP, 6), 4038c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_DHCP, 4048c2ecf20Sopenharmony_ci .priority = 2, 4058c2ecf20Sopenharmony_ci }, 4068c2ecf20Sopenharmony_ci { 4078c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(NEIGH_DISCOVERY, 7), 4088c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_NEIGH_DISCOVERY, 4098c2ecf20Sopenharmony_ci .priority = 2, 4108c2ecf20Sopenharmony_ci }, 4118c2ecf20Sopenharmony_ci { 4128c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(BFD, 8), 4138c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_BFD, 4148c2ecf20Sopenharmony_ci .priority = 5, 4158c2ecf20Sopenharmony_ci }, 4168c2ecf20Sopenharmony_ci { 4178c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(OSPF, 9), 4188c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF, 4198c2ecf20Sopenharmony_ci .priority = 5, 4208c2ecf20Sopenharmony_ci }, 4218c2ecf20Sopenharmony_ci { 4228c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(BGP, 10), 4238c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_BGP, 4248c2ecf20Sopenharmony_ci .priority = 4, 4258c2ecf20Sopenharmony_ci }, 4268c2ecf20Sopenharmony_ci { 4278c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(VRRP, 11), 4288c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_VRRP, 4298c2ecf20Sopenharmony_ci .priority = 5, 4308c2ecf20Sopenharmony_ci }, 4318c2ecf20Sopenharmony_ci { 4328c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(PIM, 12), 4338c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_PIM, 4348c2ecf20Sopenharmony_ci .priority = 5, 4358c2ecf20Sopenharmony_ci }, 4368c2ecf20Sopenharmony_ci { 4378c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(UC_LB, 13), 4388c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_LBERROR, 4398c2ecf20Sopenharmony_ci .priority = 0, 4408c2ecf20Sopenharmony_ci }, 4418c2ecf20Sopenharmony_ci { 4428c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(LOCAL_DELIVERY, 14), 4438c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_IP2ME, 4448c2ecf20Sopenharmony_ci .priority = 2, 4458c2ecf20Sopenharmony_ci }, 4468c2ecf20Sopenharmony_ci { 4478c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(EXTERNAL_DELIVERY, 19), 4488c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_EXTERNAL_ROUTE, 4498c2ecf20Sopenharmony_ci .priority = 1, 4508c2ecf20Sopenharmony_ci }, 4518c2ecf20Sopenharmony_ci { 4528c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(IPV6, 15), 4538c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_IPV6, 4548c2ecf20Sopenharmony_ci .priority = 2, 4558c2ecf20Sopenharmony_ci }, 4568c2ecf20Sopenharmony_ci { 4578c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(PTP_EVENT, 16), 4588c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP0, 4598c2ecf20Sopenharmony_ci .priority = 5, 4608c2ecf20Sopenharmony_ci }, 4618c2ecf20Sopenharmony_ci { 4628c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(PTP_GENERAL, 17), 4638c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP1, 4648c2ecf20Sopenharmony_ci .priority = 2, 4658c2ecf20Sopenharmony_ci }, 4668c2ecf20Sopenharmony_ci { 4678c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(ACL_SAMPLE, 0), 4688c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_PKT_SAMPLE, 4698c2ecf20Sopenharmony_ci .priority = 0, 4708c2ecf20Sopenharmony_ci }, 4718c2ecf20Sopenharmony_ci { 4728c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(ACL_TRAP, 18), 4738c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_FLOW_LOGGING, 4748c2ecf20Sopenharmony_ci .priority = 4, 4758c2ecf20Sopenharmony_ci }, 4768c2ecf20Sopenharmony_ci}; 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_cistatic const struct mlxsw_sp_trap_item mlxsw_sp_trap_items_arr[] = { 4798c2ecf20Sopenharmony_ci { 4808c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(SMAC_MC, L2_DROPS), 4818c2ecf20Sopenharmony_ci .listeners_arr = { 4828c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_PACKET_SMAC_MC, L2_DISCARDS), 4838c2ecf20Sopenharmony_ci }, 4848c2ecf20Sopenharmony_ci }, 4858c2ecf20Sopenharmony_ci { 4868c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(VLAN_TAG_MISMATCH, L2_DROPS), 4878c2ecf20Sopenharmony_ci .listeners_arr = { 4888c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_SWITCH_VTAG_ALLOW, 4898c2ecf20Sopenharmony_ci L2_DISCARDS), 4908c2ecf20Sopenharmony_ci }, 4918c2ecf20Sopenharmony_ci }, 4928c2ecf20Sopenharmony_ci { 4938c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(INGRESS_VLAN_FILTER, L2_DROPS), 4948c2ecf20Sopenharmony_ci .listeners_arr = { 4958c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_SWITCH_VLAN, L2_DISCARDS), 4968c2ecf20Sopenharmony_ci }, 4978c2ecf20Sopenharmony_ci }, 4988c2ecf20Sopenharmony_ci { 4998c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(INGRESS_STP_FILTER, L2_DROPS), 5008c2ecf20Sopenharmony_ci .listeners_arr = { 5018c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_SWITCH_STP, L2_DISCARDS), 5028c2ecf20Sopenharmony_ci }, 5038c2ecf20Sopenharmony_ci }, 5048c2ecf20Sopenharmony_ci { 5058c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(EMPTY_TX_LIST, L2_DROPS), 5068c2ecf20Sopenharmony_ci .listeners_arr = { 5078c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(LOOKUP_SWITCH_UC, L2_DISCARDS), 5088c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(LOOKUP_SWITCH_MC_NULL, L2_DISCARDS), 5098c2ecf20Sopenharmony_ci }, 5108c2ecf20Sopenharmony_ci }, 5118c2ecf20Sopenharmony_ci { 5128c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(PORT_LOOPBACK_FILTER, L2_DROPS), 5138c2ecf20Sopenharmony_ci .listeners_arr = { 5148c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(LOOKUP_SWITCH_LB, L2_DISCARDS), 5158c2ecf20Sopenharmony_ci }, 5168c2ecf20Sopenharmony_ci }, 5178c2ecf20Sopenharmony_ci { 5188c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(BLACKHOLE_ROUTE, L3_DROPS), 5198c2ecf20Sopenharmony_ci .listeners_arr = { 5208c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ROUTER2, L3_DISCARDS), 5218c2ecf20Sopenharmony_ci }, 5228c2ecf20Sopenharmony_ci }, 5238c2ecf20Sopenharmony_ci { 5248c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(NON_IP_PACKET, L3_DROPS), 5258c2ecf20Sopenharmony_ci .listeners_arr = { 5268c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_ROUTER_NON_IP_PACKET, 5278c2ecf20Sopenharmony_ci L3_DISCARDS), 5288c2ecf20Sopenharmony_ci }, 5298c2ecf20Sopenharmony_ci }, 5308c2ecf20Sopenharmony_ci { 5318c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(UC_DIP_MC_DMAC, L3_DROPS), 5328c2ecf20Sopenharmony_ci .listeners_arr = { 5338c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_ROUTER_UC_DIP_MC_DMAC, 5348c2ecf20Sopenharmony_ci L3_DISCARDS), 5358c2ecf20Sopenharmony_ci }, 5368c2ecf20Sopenharmony_ci }, 5378c2ecf20Sopenharmony_ci { 5388c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(DIP_LB, L3_DROPS), 5398c2ecf20Sopenharmony_ci .listeners_arr = { 5408c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_ROUTER_DIP_LB, L3_DISCARDS), 5418c2ecf20Sopenharmony_ci }, 5428c2ecf20Sopenharmony_ci }, 5438c2ecf20Sopenharmony_ci { 5448c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(SIP_MC, L3_DROPS), 5458c2ecf20Sopenharmony_ci .listeners_arr = { 5468c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_ROUTER_SIP_MC, L3_DISCARDS), 5478c2ecf20Sopenharmony_ci }, 5488c2ecf20Sopenharmony_ci }, 5498c2ecf20Sopenharmony_ci { 5508c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(SIP_LB, L3_DROPS), 5518c2ecf20Sopenharmony_ci .listeners_arr = { 5528c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_ROUTER_SIP_LB, L3_DISCARDS), 5538c2ecf20Sopenharmony_ci }, 5548c2ecf20Sopenharmony_ci }, 5558c2ecf20Sopenharmony_ci { 5568c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(CORRUPTED_IP_HDR, L3_DROPS), 5578c2ecf20Sopenharmony_ci .listeners_arr = { 5588c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_ROUTER_CORRUPTED_IP_HDR, 5598c2ecf20Sopenharmony_ci L3_DISCARDS), 5608c2ecf20Sopenharmony_ci }, 5618c2ecf20Sopenharmony_ci }, 5628c2ecf20Sopenharmony_ci { 5638c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(IPV4_SIP_BC, L3_DROPS), 5648c2ecf20Sopenharmony_ci .listeners_arr = { 5658c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ING_ROUTER_IPV4_SIP_BC, 5668c2ecf20Sopenharmony_ci L3_DISCARDS), 5678c2ecf20Sopenharmony_ci }, 5688c2ecf20Sopenharmony_ci }, 5698c2ecf20Sopenharmony_ci { 5708c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(IPV6_MC_DIP_RESERVED_SCOPE, 5718c2ecf20Sopenharmony_ci L3_DROPS), 5728c2ecf20Sopenharmony_ci .listeners_arr = { 5738c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(IPV6_MC_DIP_RESERVED_SCOPE, 5748c2ecf20Sopenharmony_ci L3_DISCARDS), 5758c2ecf20Sopenharmony_ci }, 5768c2ecf20Sopenharmony_ci }, 5778c2ecf20Sopenharmony_ci { 5788c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, 5798c2ecf20Sopenharmony_ci L3_DROPS), 5808c2ecf20Sopenharmony_ci .listeners_arr = { 5818c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, 5828c2ecf20Sopenharmony_ci L3_DISCARDS), 5838c2ecf20Sopenharmony_ci }, 5848c2ecf20Sopenharmony_ci }, 5858c2ecf20Sopenharmony_ci { 5868c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_EXCEPTION(MTU_ERROR, L3_EXCEPTIONS), 5878c2ecf20Sopenharmony_ci .listeners_arr = { 5888c2ecf20Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(MTUERROR, L3_EXCEPTIONS, 5898c2ecf20Sopenharmony_ci TRAP_TO_CPU), 5908c2ecf20Sopenharmony_ci }, 5918c2ecf20Sopenharmony_ci }, 5928c2ecf20Sopenharmony_ci { 5938c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_EXCEPTION(TTL_ERROR, L3_EXCEPTIONS), 5948c2ecf20Sopenharmony_ci .listeners_arr = { 5958c2ecf20Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(TTLERROR, L3_EXCEPTIONS, 5968c2ecf20Sopenharmony_ci TRAP_TO_CPU), 5978c2ecf20Sopenharmony_ci }, 5988c2ecf20Sopenharmony_ci }, 5998c2ecf20Sopenharmony_ci { 6008c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_EXCEPTION(RPF, L3_EXCEPTIONS), 6018c2ecf20Sopenharmony_ci .listeners_arr = { 6028c2ecf20Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(RPF, L3_EXCEPTIONS, TRAP_TO_CPU), 6038c2ecf20Sopenharmony_ci }, 6048c2ecf20Sopenharmony_ci }, 6058c2ecf20Sopenharmony_ci { 6068c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_EXCEPTION(REJECT_ROUTE, L3_EXCEPTIONS), 6078c2ecf20Sopenharmony_ci .listeners_arr = { 6088c2ecf20Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(RTR_INGRESS1, L3_EXCEPTIONS, 6098c2ecf20Sopenharmony_ci TRAP_TO_CPU), 6108c2ecf20Sopenharmony_ci }, 6118c2ecf20Sopenharmony_ci }, 6128c2ecf20Sopenharmony_ci { 6138c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_EXCEPTION(UNRESOLVED_NEIGH, 6148c2ecf20Sopenharmony_ci L3_EXCEPTIONS), 6158c2ecf20Sopenharmony_ci .listeners_arr = { 6168c2ecf20Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(HOST_MISS_IPV4, L3_EXCEPTIONS, 6178c2ecf20Sopenharmony_ci TRAP_TO_CPU), 6188c2ecf20Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(HOST_MISS_IPV6, L3_EXCEPTIONS, 6198c2ecf20Sopenharmony_ci TRAP_TO_CPU), 6208c2ecf20Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(DISCARD_ROUTER3, L3_EXCEPTIONS, 6218c2ecf20Sopenharmony_ci TRAP_EXCEPTION_TO_CPU), 6228c2ecf20Sopenharmony_ci }, 6238c2ecf20Sopenharmony_ci }, 6248c2ecf20Sopenharmony_ci { 6258c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_EXCEPTION(IPV4_LPM_UNICAST_MISS, 6268c2ecf20Sopenharmony_ci L3_EXCEPTIONS), 6278c2ecf20Sopenharmony_ci .listeners_arr = { 6288c2ecf20Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(DISCARD_ROUTER_LPM4, 6298c2ecf20Sopenharmony_ci L3_EXCEPTIONS, 6308c2ecf20Sopenharmony_ci TRAP_EXCEPTION_TO_CPU), 6318c2ecf20Sopenharmony_ci }, 6328c2ecf20Sopenharmony_ci }, 6338c2ecf20Sopenharmony_ci { 6348c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_EXCEPTION(IPV6_LPM_UNICAST_MISS, 6358c2ecf20Sopenharmony_ci L3_EXCEPTIONS), 6368c2ecf20Sopenharmony_ci .listeners_arr = { 6378c2ecf20Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(DISCARD_ROUTER_LPM6, 6388c2ecf20Sopenharmony_ci L3_EXCEPTIONS, 6398c2ecf20Sopenharmony_ci TRAP_EXCEPTION_TO_CPU), 6408c2ecf20Sopenharmony_ci }, 6418c2ecf20Sopenharmony_ci }, 6428c2ecf20Sopenharmony_ci { 6438c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DRIVER_DROP(IRIF_DISABLED, L3_DROPS), 6448c2ecf20Sopenharmony_ci .listeners_arr = { 6458c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ROUTER_IRIF_EN, L3_DISCARDS), 6468c2ecf20Sopenharmony_ci }, 6478c2ecf20Sopenharmony_ci }, 6488c2ecf20Sopenharmony_ci { 6498c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DRIVER_DROP(ERIF_DISABLED, L3_DROPS), 6508c2ecf20Sopenharmony_ci .listeners_arr = { 6518c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(ROUTER_ERIF_EN, L3_DISCARDS), 6528c2ecf20Sopenharmony_ci }, 6538c2ecf20Sopenharmony_ci }, 6548c2ecf20Sopenharmony_ci { 6558c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(NON_ROUTABLE, L3_DROPS), 6568c2ecf20Sopenharmony_ci .listeners_arr = { 6578c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(NON_ROUTABLE, L3_DISCARDS), 6588c2ecf20Sopenharmony_ci }, 6598c2ecf20Sopenharmony_ci }, 6608c2ecf20Sopenharmony_ci { 6618c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_EXCEPTION(DECAP_ERROR, TUNNEL_DROPS), 6628c2ecf20Sopenharmony_ci .listeners_arr = { 6638c2ecf20Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(DECAP_ECN0, TUNNEL_DISCARDS, 6648c2ecf20Sopenharmony_ci TRAP_EXCEPTION_TO_CPU), 6658c2ecf20Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(IPIP_DECAP_ERROR, 6668c2ecf20Sopenharmony_ci TUNNEL_DISCARDS, 6678c2ecf20Sopenharmony_ci TRAP_EXCEPTION_TO_CPU), 6688c2ecf20Sopenharmony_ci MLXSW_SP_RXL_EXCEPTION(DISCARD_DEC_PKT, TUNNEL_DISCARDS, 6698c2ecf20Sopenharmony_ci TRAP_EXCEPTION_TO_CPU), 6708c2ecf20Sopenharmony_ci }, 6718c2ecf20Sopenharmony_ci }, 6728c2ecf20Sopenharmony_ci { 6738c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP(OVERLAY_SMAC_MC, TUNNEL_DROPS), 6748c2ecf20Sopenharmony_ci .listeners_arr = { 6758c2ecf20Sopenharmony_ci MLXSW_SP_RXL_DISCARD(OVERLAY_SMAC_MC, TUNNEL_DISCARDS), 6768c2ecf20Sopenharmony_ci }, 6778c2ecf20Sopenharmony_ci }, 6788c2ecf20Sopenharmony_ci { 6798c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP_EXT(INGRESS_FLOW_ACTION_DROP, 6808c2ecf20Sopenharmony_ci ACL_DROPS, 6818c2ecf20Sopenharmony_ci DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE), 6828c2ecf20Sopenharmony_ci .listeners_arr = { 6838c2ecf20Sopenharmony_ci MLXSW_SP_RXL_ACL_DISCARD(INGRESS_ACL, ACL_DISCARDS, 6848c2ecf20Sopenharmony_ci DUMMY), 6858c2ecf20Sopenharmony_ci }, 6868c2ecf20Sopenharmony_ci }, 6878c2ecf20Sopenharmony_ci { 6888c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_DROP_EXT(EGRESS_FLOW_ACTION_DROP, 6898c2ecf20Sopenharmony_ci ACL_DROPS, 6908c2ecf20Sopenharmony_ci DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE), 6918c2ecf20Sopenharmony_ci .listeners_arr = { 6928c2ecf20Sopenharmony_ci MLXSW_SP_RXL_ACL_DISCARD(EGRESS_ACL, ACL_DISCARDS, 6938c2ecf20Sopenharmony_ci DUMMY), 6948c2ecf20Sopenharmony_ci }, 6958c2ecf20Sopenharmony_ci }, 6968c2ecf20Sopenharmony_ci { 6978c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(STP, STP, TRAP), 6988c2ecf20Sopenharmony_ci .listeners_arr = { 6998c2ecf20Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(STP, STP, TRAP_TO_CPU, true), 7008c2ecf20Sopenharmony_ci }, 7018c2ecf20Sopenharmony_ci }, 7028c2ecf20Sopenharmony_ci { 7038c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(LACP, LACP, TRAP), 7048c2ecf20Sopenharmony_ci .listeners_arr = { 7058c2ecf20Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(LACP, LACP, TRAP_TO_CPU, true), 7068c2ecf20Sopenharmony_ci }, 7078c2ecf20Sopenharmony_ci }, 7088c2ecf20Sopenharmony_ci { 7098c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(LLDP, LLDP, TRAP), 7108c2ecf20Sopenharmony_ci .listeners_arr = { 7118c2ecf20Sopenharmony_ci MLXSW_RXL(mlxsw_sp_rx_ptp_listener, LLDP, TRAP_TO_CPU, 7128c2ecf20Sopenharmony_ci true, SP_LLDP, DISCARD), 7138c2ecf20Sopenharmony_ci }, 7148c2ecf20Sopenharmony_ci }, 7158c2ecf20Sopenharmony_ci { 7168c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IGMP_QUERY, MC_SNOOPING, MIRROR), 7178c2ecf20Sopenharmony_ci .listeners_arr = { 7188c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(IGMP_QUERY, MC_SNOOPING, 7198c2ecf20Sopenharmony_ci MIRROR_TO_CPU, false), 7208c2ecf20Sopenharmony_ci }, 7218c2ecf20Sopenharmony_ci }, 7228c2ecf20Sopenharmony_ci { 7238c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IGMP_V1_REPORT, MC_SNOOPING, 7248c2ecf20Sopenharmony_ci TRAP), 7258c2ecf20Sopenharmony_ci .listeners_arr = { 7268c2ecf20Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(IGMP_V1_REPORT, MC_SNOOPING, 7278c2ecf20Sopenharmony_ci TRAP_TO_CPU, false), 7288c2ecf20Sopenharmony_ci }, 7298c2ecf20Sopenharmony_ci }, 7308c2ecf20Sopenharmony_ci { 7318c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IGMP_V2_REPORT, MC_SNOOPING, 7328c2ecf20Sopenharmony_ci TRAP), 7338c2ecf20Sopenharmony_ci .listeners_arr = { 7348c2ecf20Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(IGMP_V2_REPORT, MC_SNOOPING, 7358c2ecf20Sopenharmony_ci TRAP_TO_CPU, false), 7368c2ecf20Sopenharmony_ci }, 7378c2ecf20Sopenharmony_ci }, 7388c2ecf20Sopenharmony_ci { 7398c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IGMP_V3_REPORT, MC_SNOOPING, 7408c2ecf20Sopenharmony_ci TRAP), 7418c2ecf20Sopenharmony_ci .listeners_arr = { 7428c2ecf20Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(IGMP_V3_REPORT, MC_SNOOPING, 7438c2ecf20Sopenharmony_ci TRAP_TO_CPU, false), 7448c2ecf20Sopenharmony_ci }, 7458c2ecf20Sopenharmony_ci }, 7468c2ecf20Sopenharmony_ci { 7478c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IGMP_V2_LEAVE, MC_SNOOPING, 7488c2ecf20Sopenharmony_ci TRAP), 7498c2ecf20Sopenharmony_ci .listeners_arr = { 7508c2ecf20Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(IGMP_V2_LEAVE, MC_SNOOPING, 7518c2ecf20Sopenharmony_ci TRAP_TO_CPU, false), 7528c2ecf20Sopenharmony_ci }, 7538c2ecf20Sopenharmony_ci }, 7548c2ecf20Sopenharmony_ci { 7558c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(MLD_QUERY, MC_SNOOPING, MIRROR), 7568c2ecf20Sopenharmony_ci .listeners_arr = { 7578c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV6_MLDV12_LISTENER_QUERY, 7588c2ecf20Sopenharmony_ci MC_SNOOPING, MIRROR_TO_CPU, false), 7598c2ecf20Sopenharmony_ci }, 7608c2ecf20Sopenharmony_ci }, 7618c2ecf20Sopenharmony_ci { 7628c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(MLD_V1_REPORT, MC_SNOOPING, 7638c2ecf20Sopenharmony_ci TRAP), 7648c2ecf20Sopenharmony_ci .listeners_arr = { 7658c2ecf20Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(IPV6_MLDV1_LISTENER_REPORT, 7668c2ecf20Sopenharmony_ci MC_SNOOPING, TRAP_TO_CPU, false), 7678c2ecf20Sopenharmony_ci }, 7688c2ecf20Sopenharmony_ci }, 7698c2ecf20Sopenharmony_ci { 7708c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(MLD_V2_REPORT, MC_SNOOPING, 7718c2ecf20Sopenharmony_ci TRAP), 7728c2ecf20Sopenharmony_ci .listeners_arr = { 7738c2ecf20Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(IPV6_MLDV2_LISTENER_REPORT, 7748c2ecf20Sopenharmony_ci MC_SNOOPING, TRAP_TO_CPU, false), 7758c2ecf20Sopenharmony_ci }, 7768c2ecf20Sopenharmony_ci }, 7778c2ecf20Sopenharmony_ci { 7788c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(MLD_V1_DONE, MC_SNOOPING, 7798c2ecf20Sopenharmony_ci TRAP), 7808c2ecf20Sopenharmony_ci .listeners_arr = { 7818c2ecf20Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(IPV6_MLDV1_LISTENER_DONE, 7828c2ecf20Sopenharmony_ci MC_SNOOPING, TRAP_TO_CPU, false), 7838c2ecf20Sopenharmony_ci }, 7848c2ecf20Sopenharmony_ci }, 7858c2ecf20Sopenharmony_ci { 7868c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV4_DHCP, DHCP, TRAP), 7878c2ecf20Sopenharmony_ci .listeners_arr = { 7888c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV4_DHCP, DHCP, TRAP_TO_CPU, false), 7898c2ecf20Sopenharmony_ci }, 7908c2ecf20Sopenharmony_ci }, 7918c2ecf20Sopenharmony_ci { 7928c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_DHCP, DHCP, TRAP), 7938c2ecf20Sopenharmony_ci .listeners_arr = { 7948c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV6_DHCP, DHCP, TRAP_TO_CPU, false), 7958c2ecf20Sopenharmony_ci }, 7968c2ecf20Sopenharmony_ci }, 7978c2ecf20Sopenharmony_ci { 7988c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(ARP_REQUEST, NEIGH_DISCOVERY, 7998c2ecf20Sopenharmony_ci MIRROR), 8008c2ecf20Sopenharmony_ci .listeners_arr = { 8018c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(ARPBC, NEIGH_DISCOVERY, MIRROR_TO_CPU, 8028c2ecf20Sopenharmony_ci false), 8038c2ecf20Sopenharmony_ci }, 8048c2ecf20Sopenharmony_ci }, 8058c2ecf20Sopenharmony_ci { 8068c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(ARP_RESPONSE, NEIGH_DISCOVERY, 8078c2ecf20Sopenharmony_ci MIRROR), 8088c2ecf20Sopenharmony_ci .listeners_arr = { 8098c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(ARPUC, NEIGH_DISCOVERY, MIRROR_TO_CPU, 8108c2ecf20Sopenharmony_ci false), 8118c2ecf20Sopenharmony_ci }, 8128c2ecf20Sopenharmony_ci }, 8138c2ecf20Sopenharmony_ci { 8148c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(ARP_OVERLAY, NEIGH_DISCOVERY, 8158c2ecf20Sopenharmony_ci TRAP), 8168c2ecf20Sopenharmony_ci .listeners_arr = { 8178c2ecf20Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(NVE_DECAP_ARP, NEIGH_DISCOVERY, 8188c2ecf20Sopenharmony_ci TRAP_TO_CPU, false), 8198c2ecf20Sopenharmony_ci }, 8208c2ecf20Sopenharmony_ci }, 8218c2ecf20Sopenharmony_ci { 8228c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_NEIGH_SOLICIT, 8238c2ecf20Sopenharmony_ci NEIGH_DISCOVERY, TRAP), 8248c2ecf20Sopenharmony_ci .listeners_arr = { 8258c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(L3_IPV6_NEIGHBOR_SOLICITATION, 8268c2ecf20Sopenharmony_ci NEIGH_DISCOVERY, TRAP_TO_CPU, false), 8278c2ecf20Sopenharmony_ci }, 8288c2ecf20Sopenharmony_ci }, 8298c2ecf20Sopenharmony_ci { 8308c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_NEIGH_ADVERT, 8318c2ecf20Sopenharmony_ci NEIGH_DISCOVERY, TRAP), 8328c2ecf20Sopenharmony_ci .listeners_arr = { 8338c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(L3_IPV6_NEIGHBOR_ADVERTISEMENT, 8348c2ecf20Sopenharmony_ci NEIGH_DISCOVERY, TRAP_TO_CPU, false), 8358c2ecf20Sopenharmony_ci }, 8368c2ecf20Sopenharmony_ci }, 8378c2ecf20Sopenharmony_ci { 8388c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV4_BFD, BFD, TRAP), 8398c2ecf20Sopenharmony_ci .listeners_arr = { 8408c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV4_BFD, BFD, TRAP_TO_CPU, false), 8418c2ecf20Sopenharmony_ci }, 8428c2ecf20Sopenharmony_ci }, 8438c2ecf20Sopenharmony_ci { 8448c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_BFD, BFD, TRAP), 8458c2ecf20Sopenharmony_ci .listeners_arr = { 8468c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV6_BFD, BFD, TRAP_TO_CPU, false), 8478c2ecf20Sopenharmony_ci }, 8488c2ecf20Sopenharmony_ci }, 8498c2ecf20Sopenharmony_ci { 8508c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV4_OSPF, OSPF, TRAP), 8518c2ecf20Sopenharmony_ci .listeners_arr = { 8528c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV4_OSPF, OSPF, TRAP_TO_CPU, false), 8538c2ecf20Sopenharmony_ci }, 8548c2ecf20Sopenharmony_ci }, 8558c2ecf20Sopenharmony_ci { 8568c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_OSPF, OSPF, TRAP), 8578c2ecf20Sopenharmony_ci .listeners_arr = { 8588c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV6_OSPF, OSPF, TRAP_TO_CPU, false), 8598c2ecf20Sopenharmony_ci }, 8608c2ecf20Sopenharmony_ci }, 8618c2ecf20Sopenharmony_ci { 8628c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV4_BGP, BGP, TRAP), 8638c2ecf20Sopenharmony_ci .listeners_arr = { 8648c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV4_BGP, BGP, TRAP_TO_CPU, false), 8658c2ecf20Sopenharmony_ci }, 8668c2ecf20Sopenharmony_ci }, 8678c2ecf20Sopenharmony_ci { 8688c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_BGP, BGP, TRAP), 8698c2ecf20Sopenharmony_ci .listeners_arr = { 8708c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV6_BGP, BGP, TRAP_TO_CPU, false), 8718c2ecf20Sopenharmony_ci }, 8728c2ecf20Sopenharmony_ci }, 8738c2ecf20Sopenharmony_ci { 8748c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV4_VRRP, VRRP, TRAP), 8758c2ecf20Sopenharmony_ci .listeners_arr = { 8768c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV4_VRRP, VRRP, TRAP_TO_CPU, false), 8778c2ecf20Sopenharmony_ci }, 8788c2ecf20Sopenharmony_ci }, 8798c2ecf20Sopenharmony_ci { 8808c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_VRRP, VRRP, TRAP), 8818c2ecf20Sopenharmony_ci .listeners_arr = { 8828c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV6_VRRP, VRRP, TRAP_TO_CPU, false), 8838c2ecf20Sopenharmony_ci }, 8848c2ecf20Sopenharmony_ci }, 8858c2ecf20Sopenharmony_ci { 8868c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV4_PIM, PIM, TRAP), 8878c2ecf20Sopenharmony_ci .listeners_arr = { 8888c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV4_PIM, PIM, TRAP_TO_CPU, false), 8898c2ecf20Sopenharmony_ci }, 8908c2ecf20Sopenharmony_ci }, 8918c2ecf20Sopenharmony_ci { 8928c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_PIM, PIM, TRAP), 8938c2ecf20Sopenharmony_ci .listeners_arr = { 8948c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV6_PIM, PIM, TRAP_TO_CPU, false), 8958c2ecf20Sopenharmony_ci }, 8968c2ecf20Sopenharmony_ci }, 8978c2ecf20Sopenharmony_ci { 8988c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(UC_LB, UC_LB, MIRROR), 8998c2ecf20Sopenharmony_ci .listeners_arr = { 9008c2ecf20Sopenharmony_ci MLXSW_SP_RXL_L3_MARK(LBERROR, LBERROR, MIRROR_TO_CPU, 9018c2ecf20Sopenharmony_ci false), 9028c2ecf20Sopenharmony_ci }, 9038c2ecf20Sopenharmony_ci }, 9048c2ecf20Sopenharmony_ci { 9058c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(LOCAL_ROUTE, LOCAL_DELIVERY, 9068c2ecf20Sopenharmony_ci TRAP), 9078c2ecf20Sopenharmony_ci .listeners_arr = { 9088c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(IP2ME, IP2ME, TRAP_TO_CPU, false), 9098c2ecf20Sopenharmony_ci }, 9108c2ecf20Sopenharmony_ci }, 9118c2ecf20Sopenharmony_ci { 9128c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(EXTERNAL_ROUTE, EXTERNAL_DELIVERY, 9138c2ecf20Sopenharmony_ci TRAP), 9148c2ecf20Sopenharmony_ci .listeners_arr = { 9158c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(RTR_INGRESS0, EXTERNAL_ROUTE, 9168c2ecf20Sopenharmony_ci TRAP_TO_CPU, false), 9178c2ecf20Sopenharmony_ci }, 9188c2ecf20Sopenharmony_ci }, 9198c2ecf20Sopenharmony_ci { 9208c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_UC_DIP_LINK_LOCAL_SCOPE, 9218c2ecf20Sopenharmony_ci LOCAL_DELIVERY, TRAP), 9228c2ecf20Sopenharmony_ci .listeners_arr = { 9238c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV6_LINK_LOCAL_DEST, IP2ME, 9248c2ecf20Sopenharmony_ci TRAP_TO_CPU, false), 9258c2ecf20Sopenharmony_ci }, 9268c2ecf20Sopenharmony_ci }, 9278c2ecf20Sopenharmony_ci { 9288c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV4_ROUTER_ALERT, LOCAL_DELIVERY, 9298c2ecf20Sopenharmony_ci TRAP), 9308c2ecf20Sopenharmony_ci .listeners_arr = { 9318c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV4, IP2ME, TRAP_TO_CPU, 9328c2ecf20Sopenharmony_ci false), 9338c2ecf20Sopenharmony_ci }, 9348c2ecf20Sopenharmony_ci }, 9358c2ecf20Sopenharmony_ci { 9368c2ecf20Sopenharmony_ci /* IPV6_ROUTER_ALERT is defined in uAPI as 22, but it is not 9378c2ecf20Sopenharmony_ci * used in this file, so undefine it. 9388c2ecf20Sopenharmony_ci */ 9398c2ecf20Sopenharmony_ci #undef IPV6_ROUTER_ALERT 9408c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_ROUTER_ALERT, LOCAL_DELIVERY, 9418c2ecf20Sopenharmony_ci TRAP), 9428c2ecf20Sopenharmony_ci .listeners_arr = { 9438c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV6, IP2ME, TRAP_TO_CPU, 9448c2ecf20Sopenharmony_ci false), 9458c2ecf20Sopenharmony_ci }, 9468c2ecf20Sopenharmony_ci }, 9478c2ecf20Sopenharmony_ci { 9488c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_DIP_ALL_NODES, IPV6, TRAP), 9498c2ecf20Sopenharmony_ci .listeners_arr = { 9508c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV6_ALL_NODES_LINK, IPV6, 9518c2ecf20Sopenharmony_ci TRAP_TO_CPU, false), 9528c2ecf20Sopenharmony_ci }, 9538c2ecf20Sopenharmony_ci }, 9548c2ecf20Sopenharmony_ci { 9558c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_DIP_ALL_ROUTERS, IPV6, TRAP), 9568c2ecf20Sopenharmony_ci .listeners_arr = { 9578c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(IPV6_ALL_ROUTERS_LINK, IPV6, 9588c2ecf20Sopenharmony_ci TRAP_TO_CPU, false), 9598c2ecf20Sopenharmony_ci }, 9608c2ecf20Sopenharmony_ci }, 9618c2ecf20Sopenharmony_ci { 9628c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_ROUTER_SOLICIT, IPV6, TRAP), 9638c2ecf20Sopenharmony_ci .listeners_arr = { 9648c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(L3_IPV6_ROUTER_SOLICITATION, IPV6, 9658c2ecf20Sopenharmony_ci TRAP_TO_CPU, false), 9668c2ecf20Sopenharmony_ci }, 9678c2ecf20Sopenharmony_ci }, 9688c2ecf20Sopenharmony_ci { 9698c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_ROUTER_ADVERT, IPV6, TRAP), 9708c2ecf20Sopenharmony_ci .listeners_arr = { 9718c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(L3_IPV6_ROUTER_ADVERTISEMENT, IPV6, 9728c2ecf20Sopenharmony_ci TRAP_TO_CPU, false), 9738c2ecf20Sopenharmony_ci }, 9748c2ecf20Sopenharmony_ci }, 9758c2ecf20Sopenharmony_ci { 9768c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(IPV6_REDIRECT, IPV6, TRAP), 9778c2ecf20Sopenharmony_ci .listeners_arr = { 9788c2ecf20Sopenharmony_ci MLXSW_SP_RXL_MARK(L3_IPV6_REDIRECTION, IPV6, 9798c2ecf20Sopenharmony_ci TRAP_TO_CPU, false), 9808c2ecf20Sopenharmony_ci }, 9818c2ecf20Sopenharmony_ci }, 9828c2ecf20Sopenharmony_ci { 9838c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(PTP_EVENT, PTP_EVENT, TRAP), 9848c2ecf20Sopenharmony_ci .listeners_arr = { 9858c2ecf20Sopenharmony_ci MLXSW_RXL(mlxsw_sp_rx_ptp_listener, PTP0, TRAP_TO_CPU, 9868c2ecf20Sopenharmony_ci false, SP_PTP0, DISCARD), 9878c2ecf20Sopenharmony_ci }, 9888c2ecf20Sopenharmony_ci }, 9898c2ecf20Sopenharmony_ci { 9908c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(PTP_GENERAL, PTP_GENERAL, TRAP), 9918c2ecf20Sopenharmony_ci .listeners_arr = { 9928c2ecf20Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(PTP1, PTP1, TRAP_TO_CPU, false), 9938c2ecf20Sopenharmony_ci }, 9948c2ecf20Sopenharmony_ci }, 9958c2ecf20Sopenharmony_ci { 9968c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(FLOW_ACTION_SAMPLE, ACL_SAMPLE, 9978c2ecf20Sopenharmony_ci MIRROR), 9988c2ecf20Sopenharmony_ci .listeners_arr = { 9998c2ecf20Sopenharmony_ci MLXSW_RXL(mlxsw_sp_rx_sample_listener, PKT_SAMPLE, 10008c2ecf20Sopenharmony_ci MIRROR_TO_CPU, false, SP_PKT_SAMPLE, DISCARD), 10018c2ecf20Sopenharmony_ci }, 10028c2ecf20Sopenharmony_ci }, 10038c2ecf20Sopenharmony_ci { 10048c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_CONTROL(FLOW_ACTION_TRAP, ACL_TRAP, TRAP), 10058c2ecf20Sopenharmony_ci .listeners_arr = { 10068c2ecf20Sopenharmony_ci MLXSW_SP_RXL_NO_MARK(ACL0, FLOW_LOGGING, TRAP_TO_CPU, 10078c2ecf20Sopenharmony_ci false), 10088c2ecf20Sopenharmony_ci }, 10098c2ecf20Sopenharmony_ci }, 10108c2ecf20Sopenharmony_ci}; 10118c2ecf20Sopenharmony_ci 10128c2ecf20Sopenharmony_cistatic struct mlxsw_sp_trap_policer_item * 10138c2ecf20Sopenharmony_cimlxsw_sp_trap_policer_item_lookup(struct mlxsw_sp *mlxsw_sp, u32 id) 10148c2ecf20Sopenharmony_ci{ 10158c2ecf20Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 10168c2ecf20Sopenharmony_ci int i; 10178c2ecf20Sopenharmony_ci 10188c2ecf20Sopenharmony_ci for (i = 0; i < trap->policers_count; i++) { 10198c2ecf20Sopenharmony_ci if (trap->policer_items_arr[i].policer.id == id) 10208c2ecf20Sopenharmony_ci return &trap->policer_items_arr[i]; 10218c2ecf20Sopenharmony_ci } 10228c2ecf20Sopenharmony_ci 10238c2ecf20Sopenharmony_ci return NULL; 10248c2ecf20Sopenharmony_ci} 10258c2ecf20Sopenharmony_ci 10268c2ecf20Sopenharmony_cistatic struct mlxsw_sp_trap_group_item * 10278c2ecf20Sopenharmony_cimlxsw_sp_trap_group_item_lookup(struct mlxsw_sp *mlxsw_sp, u16 id) 10288c2ecf20Sopenharmony_ci{ 10298c2ecf20Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 10308c2ecf20Sopenharmony_ci int i; 10318c2ecf20Sopenharmony_ci 10328c2ecf20Sopenharmony_ci for (i = 0; i < trap->groups_count; i++) { 10338c2ecf20Sopenharmony_ci if (trap->group_items_arr[i].group.id == id) 10348c2ecf20Sopenharmony_ci return &trap->group_items_arr[i]; 10358c2ecf20Sopenharmony_ci } 10368c2ecf20Sopenharmony_ci 10378c2ecf20Sopenharmony_ci return NULL; 10388c2ecf20Sopenharmony_ci} 10398c2ecf20Sopenharmony_ci 10408c2ecf20Sopenharmony_cistatic struct mlxsw_sp_trap_item * 10418c2ecf20Sopenharmony_cimlxsw_sp_trap_item_lookup(struct mlxsw_sp *mlxsw_sp, u16 id) 10428c2ecf20Sopenharmony_ci{ 10438c2ecf20Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 10448c2ecf20Sopenharmony_ci int i; 10458c2ecf20Sopenharmony_ci 10468c2ecf20Sopenharmony_ci for (i = 0; i < trap->traps_count; i++) { 10478c2ecf20Sopenharmony_ci if (trap->trap_items_arr[i].trap.id == id) 10488c2ecf20Sopenharmony_ci return &trap->trap_items_arr[i]; 10498c2ecf20Sopenharmony_ci } 10508c2ecf20Sopenharmony_ci 10518c2ecf20Sopenharmony_ci return NULL; 10528c2ecf20Sopenharmony_ci} 10538c2ecf20Sopenharmony_ci 10548c2ecf20Sopenharmony_cistatic int mlxsw_sp_trap_cpu_policers_set(struct mlxsw_sp *mlxsw_sp) 10558c2ecf20Sopenharmony_ci{ 10568c2ecf20Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 10578c2ecf20Sopenharmony_ci char qpcr_pl[MLXSW_REG_QPCR_LEN]; 10588c2ecf20Sopenharmony_ci u16 hw_id; 10598c2ecf20Sopenharmony_ci 10608c2ecf20Sopenharmony_ci /* The purpose of "thin" policer is to drop as many packets 10618c2ecf20Sopenharmony_ci * as possible. The dummy group is using it. 10628c2ecf20Sopenharmony_ci */ 10638c2ecf20Sopenharmony_ci hw_id = find_first_zero_bit(trap->policers_usage, trap->max_policers); 10648c2ecf20Sopenharmony_ci if (WARN_ON(hw_id == trap->max_policers)) 10658c2ecf20Sopenharmony_ci return -ENOBUFS; 10668c2ecf20Sopenharmony_ci 10678c2ecf20Sopenharmony_ci __set_bit(hw_id, trap->policers_usage); 10688c2ecf20Sopenharmony_ci trap->thin_policer_hw_id = hw_id; 10698c2ecf20Sopenharmony_ci mlxsw_reg_qpcr_pack(qpcr_pl, hw_id, MLXSW_REG_QPCR_IR_UNITS_M, 10708c2ecf20Sopenharmony_ci false, 1, 4); 10718c2ecf20Sopenharmony_ci return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qpcr), qpcr_pl); 10728c2ecf20Sopenharmony_ci} 10738c2ecf20Sopenharmony_ci 10748c2ecf20Sopenharmony_cistatic int mlxsw_sp_trap_dummy_group_init(struct mlxsw_sp *mlxsw_sp) 10758c2ecf20Sopenharmony_ci{ 10768c2ecf20Sopenharmony_ci char htgt_pl[MLXSW_REG_HTGT_LEN]; 10778c2ecf20Sopenharmony_ci 10788c2ecf20Sopenharmony_ci mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_SP_DUMMY, 10798c2ecf20Sopenharmony_ci mlxsw_sp->trap->thin_policer_hw_id, 0, 1); 10808c2ecf20Sopenharmony_ci return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(htgt), htgt_pl); 10818c2ecf20Sopenharmony_ci} 10828c2ecf20Sopenharmony_ci 10838c2ecf20Sopenharmony_cistatic int mlxsw_sp_trap_policer_items_arr_init(struct mlxsw_sp *mlxsw_sp) 10848c2ecf20Sopenharmony_ci{ 10858c2ecf20Sopenharmony_ci size_t arr_size = ARRAY_SIZE(mlxsw_sp_trap_policer_items_arr); 10868c2ecf20Sopenharmony_ci size_t elem_size = sizeof(struct mlxsw_sp_trap_policer_item); 10878c2ecf20Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 10888c2ecf20Sopenharmony_ci size_t free_policers = 0; 10898c2ecf20Sopenharmony_ci u32 last_id; 10908c2ecf20Sopenharmony_ci int i; 10918c2ecf20Sopenharmony_ci 10928c2ecf20Sopenharmony_ci for_each_clear_bit(i, trap->policers_usage, trap->max_policers) 10938c2ecf20Sopenharmony_ci free_policers++; 10948c2ecf20Sopenharmony_ci 10958c2ecf20Sopenharmony_ci if (arr_size > free_policers) { 10968c2ecf20Sopenharmony_ci dev_err(mlxsw_sp->bus_info->dev, "Exceeded number of supported packet trap policers\n"); 10978c2ecf20Sopenharmony_ci return -ENOBUFS; 10988c2ecf20Sopenharmony_ci } 10998c2ecf20Sopenharmony_ci 11008c2ecf20Sopenharmony_ci trap->policer_items_arr = kcalloc(free_policers, elem_size, GFP_KERNEL); 11018c2ecf20Sopenharmony_ci if (!trap->policer_items_arr) 11028c2ecf20Sopenharmony_ci return -ENOMEM; 11038c2ecf20Sopenharmony_ci 11048c2ecf20Sopenharmony_ci trap->policers_count = free_policers; 11058c2ecf20Sopenharmony_ci 11068c2ecf20Sopenharmony_ci /* Initialize policer items array with pre-defined policers. */ 11078c2ecf20Sopenharmony_ci memcpy(trap->policer_items_arr, mlxsw_sp_trap_policer_items_arr, 11088c2ecf20Sopenharmony_ci elem_size * arr_size); 11098c2ecf20Sopenharmony_ci 11108c2ecf20Sopenharmony_ci /* Initialize policer items array with the rest of the available 11118c2ecf20Sopenharmony_ci * policers. 11128c2ecf20Sopenharmony_ci */ 11138c2ecf20Sopenharmony_ci last_id = mlxsw_sp_trap_policer_items_arr[arr_size - 1].policer.id; 11148c2ecf20Sopenharmony_ci for (i = arr_size; i < trap->policers_count; i++) { 11158c2ecf20Sopenharmony_ci const struct mlxsw_sp_trap_policer_item *policer_item; 11168c2ecf20Sopenharmony_ci 11178c2ecf20Sopenharmony_ci /* Use parameters set for first policer and override 11188c2ecf20Sopenharmony_ci * relevant ones. 11198c2ecf20Sopenharmony_ci */ 11208c2ecf20Sopenharmony_ci policer_item = &mlxsw_sp_trap_policer_items_arr[0]; 11218c2ecf20Sopenharmony_ci trap->policer_items_arr[i] = *policer_item; 11228c2ecf20Sopenharmony_ci trap->policer_items_arr[i].policer.id = ++last_id; 11238c2ecf20Sopenharmony_ci trap->policer_items_arr[i].policer.init_rate = 1; 11248c2ecf20Sopenharmony_ci trap->policer_items_arr[i].policer.init_burst = 16; 11258c2ecf20Sopenharmony_ci } 11268c2ecf20Sopenharmony_ci 11278c2ecf20Sopenharmony_ci return 0; 11288c2ecf20Sopenharmony_ci} 11298c2ecf20Sopenharmony_ci 11308c2ecf20Sopenharmony_cistatic void mlxsw_sp_trap_policer_items_arr_fini(struct mlxsw_sp *mlxsw_sp) 11318c2ecf20Sopenharmony_ci{ 11328c2ecf20Sopenharmony_ci kfree(mlxsw_sp->trap->policer_items_arr); 11338c2ecf20Sopenharmony_ci} 11348c2ecf20Sopenharmony_ci 11358c2ecf20Sopenharmony_cistatic int mlxsw_sp_trap_policers_init(struct mlxsw_sp *mlxsw_sp) 11368c2ecf20Sopenharmony_ci{ 11378c2ecf20Sopenharmony_ci struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); 11388c2ecf20Sopenharmony_ci const struct mlxsw_sp_trap_policer_item *policer_item; 11398c2ecf20Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 11408c2ecf20Sopenharmony_ci int err, i; 11418c2ecf20Sopenharmony_ci 11428c2ecf20Sopenharmony_ci err = mlxsw_sp_trap_policer_items_arr_init(mlxsw_sp); 11438c2ecf20Sopenharmony_ci if (err) 11448c2ecf20Sopenharmony_ci return err; 11458c2ecf20Sopenharmony_ci 11468c2ecf20Sopenharmony_ci for (i = 0; i < trap->policers_count; i++) { 11478c2ecf20Sopenharmony_ci policer_item = &trap->policer_items_arr[i]; 11488c2ecf20Sopenharmony_ci err = devlink_trap_policers_register(devlink, 11498c2ecf20Sopenharmony_ci &policer_item->policer, 1); 11508c2ecf20Sopenharmony_ci if (err) 11518c2ecf20Sopenharmony_ci goto err_trap_policer_register; 11528c2ecf20Sopenharmony_ci } 11538c2ecf20Sopenharmony_ci 11548c2ecf20Sopenharmony_ci return 0; 11558c2ecf20Sopenharmony_ci 11568c2ecf20Sopenharmony_cierr_trap_policer_register: 11578c2ecf20Sopenharmony_ci for (i--; i >= 0; i--) { 11588c2ecf20Sopenharmony_ci policer_item = &trap->policer_items_arr[i]; 11598c2ecf20Sopenharmony_ci devlink_trap_policers_unregister(devlink, 11608c2ecf20Sopenharmony_ci &policer_item->policer, 1); 11618c2ecf20Sopenharmony_ci } 11628c2ecf20Sopenharmony_ci mlxsw_sp_trap_policer_items_arr_fini(mlxsw_sp); 11638c2ecf20Sopenharmony_ci return err; 11648c2ecf20Sopenharmony_ci} 11658c2ecf20Sopenharmony_ci 11668c2ecf20Sopenharmony_cistatic void mlxsw_sp_trap_policers_fini(struct mlxsw_sp *mlxsw_sp) 11678c2ecf20Sopenharmony_ci{ 11688c2ecf20Sopenharmony_ci struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); 11698c2ecf20Sopenharmony_ci const struct mlxsw_sp_trap_policer_item *policer_item; 11708c2ecf20Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 11718c2ecf20Sopenharmony_ci int i; 11728c2ecf20Sopenharmony_ci 11738c2ecf20Sopenharmony_ci for (i = trap->policers_count - 1; i >= 0; i--) { 11748c2ecf20Sopenharmony_ci policer_item = &trap->policer_items_arr[i]; 11758c2ecf20Sopenharmony_ci devlink_trap_policers_unregister(devlink, 11768c2ecf20Sopenharmony_ci &policer_item->policer, 1); 11778c2ecf20Sopenharmony_ci } 11788c2ecf20Sopenharmony_ci mlxsw_sp_trap_policer_items_arr_fini(mlxsw_sp); 11798c2ecf20Sopenharmony_ci} 11808c2ecf20Sopenharmony_ci 11818c2ecf20Sopenharmony_cistatic int mlxsw_sp_trap_group_items_arr_init(struct mlxsw_sp *mlxsw_sp) 11828c2ecf20Sopenharmony_ci{ 11838c2ecf20Sopenharmony_ci size_t common_groups_count = ARRAY_SIZE(mlxsw_sp_trap_group_items_arr); 11848c2ecf20Sopenharmony_ci const struct mlxsw_sp_trap_group_item *spec_group_items_arr; 11858c2ecf20Sopenharmony_ci size_t elem_size = sizeof(struct mlxsw_sp_trap_group_item); 11868c2ecf20Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 11878c2ecf20Sopenharmony_ci size_t groups_count, spec_groups_count; 11888c2ecf20Sopenharmony_ci int err; 11898c2ecf20Sopenharmony_ci 11908c2ecf20Sopenharmony_ci err = mlxsw_sp->trap_ops->groups_init(mlxsw_sp, &spec_group_items_arr, 11918c2ecf20Sopenharmony_ci &spec_groups_count); 11928c2ecf20Sopenharmony_ci if (err) 11938c2ecf20Sopenharmony_ci return err; 11948c2ecf20Sopenharmony_ci 11958c2ecf20Sopenharmony_ci /* The group items array is created by concatenating the common trap 11968c2ecf20Sopenharmony_ci * group items and the ASIC-specific trap group items. 11978c2ecf20Sopenharmony_ci */ 11988c2ecf20Sopenharmony_ci groups_count = common_groups_count + spec_groups_count; 11998c2ecf20Sopenharmony_ci trap->group_items_arr = kcalloc(groups_count, elem_size, GFP_KERNEL); 12008c2ecf20Sopenharmony_ci if (!trap->group_items_arr) 12018c2ecf20Sopenharmony_ci return -ENOMEM; 12028c2ecf20Sopenharmony_ci 12038c2ecf20Sopenharmony_ci memcpy(trap->group_items_arr, mlxsw_sp_trap_group_items_arr, 12048c2ecf20Sopenharmony_ci elem_size * common_groups_count); 12058c2ecf20Sopenharmony_ci memcpy(trap->group_items_arr + common_groups_count, 12068c2ecf20Sopenharmony_ci spec_group_items_arr, elem_size * spec_groups_count); 12078c2ecf20Sopenharmony_ci 12088c2ecf20Sopenharmony_ci trap->groups_count = groups_count; 12098c2ecf20Sopenharmony_ci 12108c2ecf20Sopenharmony_ci return 0; 12118c2ecf20Sopenharmony_ci} 12128c2ecf20Sopenharmony_ci 12138c2ecf20Sopenharmony_cistatic void mlxsw_sp_trap_group_items_arr_fini(struct mlxsw_sp *mlxsw_sp) 12148c2ecf20Sopenharmony_ci{ 12158c2ecf20Sopenharmony_ci kfree(mlxsw_sp->trap->group_items_arr); 12168c2ecf20Sopenharmony_ci} 12178c2ecf20Sopenharmony_ci 12188c2ecf20Sopenharmony_cistatic int mlxsw_sp_trap_groups_init(struct mlxsw_sp *mlxsw_sp) 12198c2ecf20Sopenharmony_ci{ 12208c2ecf20Sopenharmony_ci struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); 12218c2ecf20Sopenharmony_ci const struct mlxsw_sp_trap_group_item *group_item; 12228c2ecf20Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 12238c2ecf20Sopenharmony_ci int err, i; 12248c2ecf20Sopenharmony_ci 12258c2ecf20Sopenharmony_ci err = mlxsw_sp_trap_group_items_arr_init(mlxsw_sp); 12268c2ecf20Sopenharmony_ci if (err) 12278c2ecf20Sopenharmony_ci return err; 12288c2ecf20Sopenharmony_ci 12298c2ecf20Sopenharmony_ci for (i = 0; i < trap->groups_count; i++) { 12308c2ecf20Sopenharmony_ci group_item = &trap->group_items_arr[i]; 12318c2ecf20Sopenharmony_ci err = devlink_trap_groups_register(devlink, &group_item->group, 12328c2ecf20Sopenharmony_ci 1); 12338c2ecf20Sopenharmony_ci if (err) 12348c2ecf20Sopenharmony_ci goto err_trap_group_register; 12358c2ecf20Sopenharmony_ci } 12368c2ecf20Sopenharmony_ci 12378c2ecf20Sopenharmony_ci return 0; 12388c2ecf20Sopenharmony_ci 12398c2ecf20Sopenharmony_cierr_trap_group_register: 12408c2ecf20Sopenharmony_ci for (i--; i >= 0; i--) { 12418c2ecf20Sopenharmony_ci group_item = &trap->group_items_arr[i]; 12428c2ecf20Sopenharmony_ci devlink_trap_groups_unregister(devlink, &group_item->group, 1); 12438c2ecf20Sopenharmony_ci } 12448c2ecf20Sopenharmony_ci mlxsw_sp_trap_group_items_arr_fini(mlxsw_sp); 12458c2ecf20Sopenharmony_ci return err; 12468c2ecf20Sopenharmony_ci} 12478c2ecf20Sopenharmony_ci 12488c2ecf20Sopenharmony_cistatic void mlxsw_sp_trap_groups_fini(struct mlxsw_sp *mlxsw_sp) 12498c2ecf20Sopenharmony_ci{ 12508c2ecf20Sopenharmony_ci struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); 12518c2ecf20Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 12528c2ecf20Sopenharmony_ci int i; 12538c2ecf20Sopenharmony_ci 12548c2ecf20Sopenharmony_ci for (i = trap->groups_count - 1; i >= 0; i--) { 12558c2ecf20Sopenharmony_ci const struct mlxsw_sp_trap_group_item *group_item; 12568c2ecf20Sopenharmony_ci 12578c2ecf20Sopenharmony_ci group_item = &trap->group_items_arr[i]; 12588c2ecf20Sopenharmony_ci devlink_trap_groups_unregister(devlink, &group_item->group, 1); 12598c2ecf20Sopenharmony_ci } 12608c2ecf20Sopenharmony_ci mlxsw_sp_trap_group_items_arr_fini(mlxsw_sp); 12618c2ecf20Sopenharmony_ci} 12628c2ecf20Sopenharmony_ci 12638c2ecf20Sopenharmony_cistatic bool 12648c2ecf20Sopenharmony_cimlxsw_sp_trap_listener_is_valid(const struct mlxsw_listener *listener) 12658c2ecf20Sopenharmony_ci{ 12668c2ecf20Sopenharmony_ci return listener->trap_id != 0; 12678c2ecf20Sopenharmony_ci} 12688c2ecf20Sopenharmony_ci 12698c2ecf20Sopenharmony_cistatic int mlxsw_sp_trap_items_arr_init(struct mlxsw_sp *mlxsw_sp) 12708c2ecf20Sopenharmony_ci{ 12718c2ecf20Sopenharmony_ci size_t common_traps_count = ARRAY_SIZE(mlxsw_sp_trap_items_arr); 12728c2ecf20Sopenharmony_ci const struct mlxsw_sp_trap_item *spec_trap_items_arr; 12738c2ecf20Sopenharmony_ci size_t elem_size = sizeof(struct mlxsw_sp_trap_item); 12748c2ecf20Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 12758c2ecf20Sopenharmony_ci size_t traps_count, spec_traps_count; 12768c2ecf20Sopenharmony_ci int err; 12778c2ecf20Sopenharmony_ci 12788c2ecf20Sopenharmony_ci err = mlxsw_sp->trap_ops->traps_init(mlxsw_sp, &spec_trap_items_arr, 12798c2ecf20Sopenharmony_ci &spec_traps_count); 12808c2ecf20Sopenharmony_ci if (err) 12818c2ecf20Sopenharmony_ci return err; 12828c2ecf20Sopenharmony_ci 12838c2ecf20Sopenharmony_ci /* The trap items array is created by concatenating the common trap 12848c2ecf20Sopenharmony_ci * items and the ASIC-specific trap items. 12858c2ecf20Sopenharmony_ci */ 12868c2ecf20Sopenharmony_ci traps_count = common_traps_count + spec_traps_count; 12878c2ecf20Sopenharmony_ci trap->trap_items_arr = kcalloc(traps_count, elem_size, GFP_KERNEL); 12888c2ecf20Sopenharmony_ci if (!trap->trap_items_arr) 12898c2ecf20Sopenharmony_ci return -ENOMEM; 12908c2ecf20Sopenharmony_ci 12918c2ecf20Sopenharmony_ci memcpy(trap->trap_items_arr, mlxsw_sp_trap_items_arr, 12928c2ecf20Sopenharmony_ci elem_size * common_traps_count); 12938c2ecf20Sopenharmony_ci memcpy(trap->trap_items_arr + common_traps_count, 12948c2ecf20Sopenharmony_ci spec_trap_items_arr, elem_size * spec_traps_count); 12958c2ecf20Sopenharmony_ci 12968c2ecf20Sopenharmony_ci trap->traps_count = traps_count; 12978c2ecf20Sopenharmony_ci 12988c2ecf20Sopenharmony_ci return 0; 12998c2ecf20Sopenharmony_ci} 13008c2ecf20Sopenharmony_ci 13018c2ecf20Sopenharmony_cistatic void mlxsw_sp_trap_items_arr_fini(struct mlxsw_sp *mlxsw_sp) 13028c2ecf20Sopenharmony_ci{ 13038c2ecf20Sopenharmony_ci kfree(mlxsw_sp->trap->trap_items_arr); 13048c2ecf20Sopenharmony_ci} 13058c2ecf20Sopenharmony_ci 13068c2ecf20Sopenharmony_cistatic int mlxsw_sp_traps_init(struct mlxsw_sp *mlxsw_sp) 13078c2ecf20Sopenharmony_ci{ 13088c2ecf20Sopenharmony_ci struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); 13098c2ecf20Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 13108c2ecf20Sopenharmony_ci const struct mlxsw_sp_trap_item *trap_item; 13118c2ecf20Sopenharmony_ci int err, i; 13128c2ecf20Sopenharmony_ci 13138c2ecf20Sopenharmony_ci err = mlxsw_sp_trap_items_arr_init(mlxsw_sp); 13148c2ecf20Sopenharmony_ci if (err) 13158c2ecf20Sopenharmony_ci return err; 13168c2ecf20Sopenharmony_ci 13178c2ecf20Sopenharmony_ci for (i = 0; i < trap->traps_count; i++) { 13188c2ecf20Sopenharmony_ci trap_item = &trap->trap_items_arr[i]; 13198c2ecf20Sopenharmony_ci err = devlink_traps_register(devlink, &trap_item->trap, 1, 13208c2ecf20Sopenharmony_ci mlxsw_sp); 13218c2ecf20Sopenharmony_ci if (err) 13228c2ecf20Sopenharmony_ci goto err_trap_register; 13238c2ecf20Sopenharmony_ci } 13248c2ecf20Sopenharmony_ci 13258c2ecf20Sopenharmony_ci return 0; 13268c2ecf20Sopenharmony_ci 13278c2ecf20Sopenharmony_cierr_trap_register: 13288c2ecf20Sopenharmony_ci for (i--; i >= 0; i--) { 13298c2ecf20Sopenharmony_ci trap_item = &trap->trap_items_arr[i]; 13308c2ecf20Sopenharmony_ci devlink_traps_unregister(devlink, &trap_item->trap, 1); 13318c2ecf20Sopenharmony_ci } 13328c2ecf20Sopenharmony_ci mlxsw_sp_trap_items_arr_fini(mlxsw_sp); 13338c2ecf20Sopenharmony_ci return err; 13348c2ecf20Sopenharmony_ci} 13358c2ecf20Sopenharmony_ci 13368c2ecf20Sopenharmony_cistatic void mlxsw_sp_traps_fini(struct mlxsw_sp *mlxsw_sp) 13378c2ecf20Sopenharmony_ci{ 13388c2ecf20Sopenharmony_ci struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); 13398c2ecf20Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 13408c2ecf20Sopenharmony_ci int i; 13418c2ecf20Sopenharmony_ci 13428c2ecf20Sopenharmony_ci for (i = trap->traps_count - 1; i >= 0; i--) { 13438c2ecf20Sopenharmony_ci const struct mlxsw_sp_trap_item *trap_item; 13448c2ecf20Sopenharmony_ci 13458c2ecf20Sopenharmony_ci trap_item = &trap->trap_items_arr[i]; 13468c2ecf20Sopenharmony_ci devlink_traps_unregister(devlink, &trap_item->trap, 1); 13478c2ecf20Sopenharmony_ci } 13488c2ecf20Sopenharmony_ci mlxsw_sp_trap_items_arr_fini(mlxsw_sp); 13498c2ecf20Sopenharmony_ci} 13508c2ecf20Sopenharmony_ci 13518c2ecf20Sopenharmony_ciint mlxsw_sp_devlink_traps_init(struct mlxsw_sp *mlxsw_sp) 13528c2ecf20Sopenharmony_ci{ 13538c2ecf20Sopenharmony_ci int err; 13548c2ecf20Sopenharmony_ci 13558c2ecf20Sopenharmony_ci err = mlxsw_sp_trap_cpu_policers_set(mlxsw_sp); 13568c2ecf20Sopenharmony_ci if (err) 13578c2ecf20Sopenharmony_ci return err; 13588c2ecf20Sopenharmony_ci 13598c2ecf20Sopenharmony_ci err = mlxsw_sp_trap_dummy_group_init(mlxsw_sp); 13608c2ecf20Sopenharmony_ci if (err) 13618c2ecf20Sopenharmony_ci return err; 13628c2ecf20Sopenharmony_ci 13638c2ecf20Sopenharmony_ci err = mlxsw_sp_trap_policers_init(mlxsw_sp); 13648c2ecf20Sopenharmony_ci if (err) 13658c2ecf20Sopenharmony_ci return err; 13668c2ecf20Sopenharmony_ci 13678c2ecf20Sopenharmony_ci err = mlxsw_sp_trap_groups_init(mlxsw_sp); 13688c2ecf20Sopenharmony_ci if (err) 13698c2ecf20Sopenharmony_ci goto err_trap_groups_init; 13708c2ecf20Sopenharmony_ci 13718c2ecf20Sopenharmony_ci err = mlxsw_sp_traps_init(mlxsw_sp); 13728c2ecf20Sopenharmony_ci if (err) 13738c2ecf20Sopenharmony_ci goto err_traps_init; 13748c2ecf20Sopenharmony_ci 13758c2ecf20Sopenharmony_ci return 0; 13768c2ecf20Sopenharmony_ci 13778c2ecf20Sopenharmony_cierr_traps_init: 13788c2ecf20Sopenharmony_ci mlxsw_sp_trap_groups_fini(mlxsw_sp); 13798c2ecf20Sopenharmony_cierr_trap_groups_init: 13808c2ecf20Sopenharmony_ci mlxsw_sp_trap_policers_fini(mlxsw_sp); 13818c2ecf20Sopenharmony_ci return err; 13828c2ecf20Sopenharmony_ci} 13838c2ecf20Sopenharmony_ci 13848c2ecf20Sopenharmony_civoid mlxsw_sp_devlink_traps_fini(struct mlxsw_sp *mlxsw_sp) 13858c2ecf20Sopenharmony_ci{ 13868c2ecf20Sopenharmony_ci mlxsw_sp_traps_fini(mlxsw_sp); 13878c2ecf20Sopenharmony_ci mlxsw_sp_trap_groups_fini(mlxsw_sp); 13888c2ecf20Sopenharmony_ci mlxsw_sp_trap_policers_fini(mlxsw_sp); 13898c2ecf20Sopenharmony_ci} 13908c2ecf20Sopenharmony_ci 13918c2ecf20Sopenharmony_ciint mlxsw_sp_trap_init(struct mlxsw_core *mlxsw_core, 13928c2ecf20Sopenharmony_ci const struct devlink_trap *trap, void *trap_ctx) 13938c2ecf20Sopenharmony_ci{ 13948c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 13958c2ecf20Sopenharmony_ci const struct mlxsw_sp_trap_item *trap_item; 13968c2ecf20Sopenharmony_ci int i; 13978c2ecf20Sopenharmony_ci 13988c2ecf20Sopenharmony_ci trap_item = mlxsw_sp_trap_item_lookup(mlxsw_sp, trap->id); 13998c2ecf20Sopenharmony_ci if (WARN_ON(!trap_item)) 14008c2ecf20Sopenharmony_ci return -EINVAL; 14018c2ecf20Sopenharmony_ci 14028c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP_TRAP_LISTENERS_MAX; i++) { 14038c2ecf20Sopenharmony_ci const struct mlxsw_listener *listener; 14048c2ecf20Sopenharmony_ci int err; 14058c2ecf20Sopenharmony_ci 14068c2ecf20Sopenharmony_ci listener = &trap_item->listeners_arr[i]; 14078c2ecf20Sopenharmony_ci if (!mlxsw_sp_trap_listener_is_valid(listener)) 14088c2ecf20Sopenharmony_ci continue; 14098c2ecf20Sopenharmony_ci err = mlxsw_core_trap_register(mlxsw_core, listener, trap_ctx); 14108c2ecf20Sopenharmony_ci if (err) 14118c2ecf20Sopenharmony_ci return err; 14128c2ecf20Sopenharmony_ci } 14138c2ecf20Sopenharmony_ci 14148c2ecf20Sopenharmony_ci return 0; 14158c2ecf20Sopenharmony_ci} 14168c2ecf20Sopenharmony_ci 14178c2ecf20Sopenharmony_civoid mlxsw_sp_trap_fini(struct mlxsw_core *mlxsw_core, 14188c2ecf20Sopenharmony_ci const struct devlink_trap *trap, void *trap_ctx) 14198c2ecf20Sopenharmony_ci{ 14208c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 14218c2ecf20Sopenharmony_ci const struct mlxsw_sp_trap_item *trap_item; 14228c2ecf20Sopenharmony_ci int i; 14238c2ecf20Sopenharmony_ci 14248c2ecf20Sopenharmony_ci trap_item = mlxsw_sp_trap_item_lookup(mlxsw_sp, trap->id); 14258c2ecf20Sopenharmony_ci if (WARN_ON(!trap_item)) 14268c2ecf20Sopenharmony_ci return; 14278c2ecf20Sopenharmony_ci 14288c2ecf20Sopenharmony_ci for (i = MLXSW_SP_TRAP_LISTENERS_MAX - 1; i >= 0; i--) { 14298c2ecf20Sopenharmony_ci const struct mlxsw_listener *listener; 14308c2ecf20Sopenharmony_ci 14318c2ecf20Sopenharmony_ci listener = &trap_item->listeners_arr[i]; 14328c2ecf20Sopenharmony_ci if (!mlxsw_sp_trap_listener_is_valid(listener)) 14338c2ecf20Sopenharmony_ci continue; 14348c2ecf20Sopenharmony_ci mlxsw_core_trap_unregister(mlxsw_core, listener, trap_ctx); 14358c2ecf20Sopenharmony_ci } 14368c2ecf20Sopenharmony_ci} 14378c2ecf20Sopenharmony_ci 14388c2ecf20Sopenharmony_ciint mlxsw_sp_trap_action_set(struct mlxsw_core *mlxsw_core, 14398c2ecf20Sopenharmony_ci const struct devlink_trap *trap, 14408c2ecf20Sopenharmony_ci enum devlink_trap_action action, 14418c2ecf20Sopenharmony_ci struct netlink_ext_ack *extack) 14428c2ecf20Sopenharmony_ci{ 14438c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 14448c2ecf20Sopenharmony_ci const struct mlxsw_sp_trap_item *trap_item; 14458c2ecf20Sopenharmony_ci int i; 14468c2ecf20Sopenharmony_ci 14478c2ecf20Sopenharmony_ci trap_item = mlxsw_sp_trap_item_lookup(mlxsw_sp, trap->id); 14488c2ecf20Sopenharmony_ci if (WARN_ON(!trap_item)) 14498c2ecf20Sopenharmony_ci return -EINVAL; 14508c2ecf20Sopenharmony_ci 14518c2ecf20Sopenharmony_ci if (trap_item->is_source) { 14528c2ecf20Sopenharmony_ci NL_SET_ERR_MSG_MOD(extack, "Changing the action of source traps is not supported"); 14538c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 14548c2ecf20Sopenharmony_ci } 14558c2ecf20Sopenharmony_ci 14568c2ecf20Sopenharmony_ci for (i = 0; i < MLXSW_SP_TRAP_LISTENERS_MAX; i++) { 14578c2ecf20Sopenharmony_ci const struct mlxsw_listener *listener; 14588c2ecf20Sopenharmony_ci bool enabled; 14598c2ecf20Sopenharmony_ci int err; 14608c2ecf20Sopenharmony_ci 14618c2ecf20Sopenharmony_ci listener = &trap_item->listeners_arr[i]; 14628c2ecf20Sopenharmony_ci if (!mlxsw_sp_trap_listener_is_valid(listener)) 14638c2ecf20Sopenharmony_ci continue; 14648c2ecf20Sopenharmony_ci 14658c2ecf20Sopenharmony_ci switch (action) { 14668c2ecf20Sopenharmony_ci case DEVLINK_TRAP_ACTION_DROP: 14678c2ecf20Sopenharmony_ci enabled = false; 14688c2ecf20Sopenharmony_ci break; 14698c2ecf20Sopenharmony_ci case DEVLINK_TRAP_ACTION_TRAP: 14708c2ecf20Sopenharmony_ci enabled = true; 14718c2ecf20Sopenharmony_ci break; 14728c2ecf20Sopenharmony_ci default: 14738c2ecf20Sopenharmony_ci return -EINVAL; 14748c2ecf20Sopenharmony_ci } 14758c2ecf20Sopenharmony_ci err = mlxsw_core_trap_state_set(mlxsw_core, listener, enabled); 14768c2ecf20Sopenharmony_ci if (err) 14778c2ecf20Sopenharmony_ci return err; 14788c2ecf20Sopenharmony_ci } 14798c2ecf20Sopenharmony_ci 14808c2ecf20Sopenharmony_ci return 0; 14818c2ecf20Sopenharmony_ci} 14828c2ecf20Sopenharmony_ci 14838c2ecf20Sopenharmony_cistatic int 14848c2ecf20Sopenharmony_ci__mlxsw_sp_trap_group_init(struct mlxsw_core *mlxsw_core, 14858c2ecf20Sopenharmony_ci const struct devlink_trap_group *group, 14868c2ecf20Sopenharmony_ci u32 policer_id, struct netlink_ext_ack *extack) 14878c2ecf20Sopenharmony_ci{ 14888c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 14898c2ecf20Sopenharmony_ci u16 hw_policer_id = MLXSW_REG_HTGT_INVALID_POLICER; 14908c2ecf20Sopenharmony_ci const struct mlxsw_sp_trap_group_item *group_item; 14918c2ecf20Sopenharmony_ci char htgt_pl[MLXSW_REG_HTGT_LEN]; 14928c2ecf20Sopenharmony_ci 14938c2ecf20Sopenharmony_ci group_item = mlxsw_sp_trap_group_item_lookup(mlxsw_sp, group->id); 14948c2ecf20Sopenharmony_ci if (WARN_ON(!group_item)) 14958c2ecf20Sopenharmony_ci return -EINVAL; 14968c2ecf20Sopenharmony_ci 14978c2ecf20Sopenharmony_ci if (group_item->fixed_policer && policer_id != group->init_policer_id) { 14988c2ecf20Sopenharmony_ci NL_SET_ERR_MSG_MOD(extack, "Changing the policer binding of this group is not supported"); 14998c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 15008c2ecf20Sopenharmony_ci } 15018c2ecf20Sopenharmony_ci 15028c2ecf20Sopenharmony_ci if (policer_id) { 15038c2ecf20Sopenharmony_ci struct mlxsw_sp_trap_policer_item *policer_item; 15048c2ecf20Sopenharmony_ci 15058c2ecf20Sopenharmony_ci policer_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, 15068c2ecf20Sopenharmony_ci policer_id); 15078c2ecf20Sopenharmony_ci if (WARN_ON(!policer_item)) 15088c2ecf20Sopenharmony_ci return -EINVAL; 15098c2ecf20Sopenharmony_ci hw_policer_id = policer_item->hw_id; 15108c2ecf20Sopenharmony_ci } 15118c2ecf20Sopenharmony_ci 15128c2ecf20Sopenharmony_ci mlxsw_reg_htgt_pack(htgt_pl, group_item->hw_group_id, hw_policer_id, 15138c2ecf20Sopenharmony_ci group_item->priority, group_item->priority); 15148c2ecf20Sopenharmony_ci return mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl); 15158c2ecf20Sopenharmony_ci} 15168c2ecf20Sopenharmony_ci 15178c2ecf20Sopenharmony_ciint mlxsw_sp_trap_group_init(struct mlxsw_core *mlxsw_core, 15188c2ecf20Sopenharmony_ci const struct devlink_trap_group *group) 15198c2ecf20Sopenharmony_ci{ 15208c2ecf20Sopenharmony_ci return __mlxsw_sp_trap_group_init(mlxsw_core, group, 15218c2ecf20Sopenharmony_ci group->init_policer_id, NULL); 15228c2ecf20Sopenharmony_ci} 15238c2ecf20Sopenharmony_ci 15248c2ecf20Sopenharmony_ciint mlxsw_sp_trap_group_set(struct mlxsw_core *mlxsw_core, 15258c2ecf20Sopenharmony_ci const struct devlink_trap_group *group, 15268c2ecf20Sopenharmony_ci const struct devlink_trap_policer *policer, 15278c2ecf20Sopenharmony_ci struct netlink_ext_ack *extack) 15288c2ecf20Sopenharmony_ci{ 15298c2ecf20Sopenharmony_ci u32 policer_id = policer ? policer->id : 0; 15308c2ecf20Sopenharmony_ci 15318c2ecf20Sopenharmony_ci return __mlxsw_sp_trap_group_init(mlxsw_core, group, policer_id, 15328c2ecf20Sopenharmony_ci extack); 15338c2ecf20Sopenharmony_ci} 15348c2ecf20Sopenharmony_ci 15358c2ecf20Sopenharmony_cistatic int 15368c2ecf20Sopenharmony_cimlxsw_sp_trap_policer_item_init(struct mlxsw_sp *mlxsw_sp, 15378c2ecf20Sopenharmony_ci struct mlxsw_sp_trap_policer_item *policer_item) 15388c2ecf20Sopenharmony_ci{ 15398c2ecf20Sopenharmony_ci struct mlxsw_sp_trap *trap = mlxsw_sp->trap; 15408c2ecf20Sopenharmony_ci u16 hw_id; 15418c2ecf20Sopenharmony_ci 15428c2ecf20Sopenharmony_ci /* We should be able to allocate a policer because the number of 15438c2ecf20Sopenharmony_ci * policers we registered with devlink is in according with the number 15448c2ecf20Sopenharmony_ci * of available policers. 15458c2ecf20Sopenharmony_ci */ 15468c2ecf20Sopenharmony_ci hw_id = find_first_zero_bit(trap->policers_usage, trap->max_policers); 15478c2ecf20Sopenharmony_ci if (WARN_ON(hw_id == trap->max_policers)) 15488c2ecf20Sopenharmony_ci return -ENOBUFS; 15498c2ecf20Sopenharmony_ci 15508c2ecf20Sopenharmony_ci __set_bit(hw_id, trap->policers_usage); 15518c2ecf20Sopenharmony_ci policer_item->hw_id = hw_id; 15528c2ecf20Sopenharmony_ci 15538c2ecf20Sopenharmony_ci return 0; 15548c2ecf20Sopenharmony_ci} 15558c2ecf20Sopenharmony_ci 15568c2ecf20Sopenharmony_cistatic void 15578c2ecf20Sopenharmony_cimlxsw_sp_trap_policer_item_fini(struct mlxsw_sp *mlxsw_sp, 15588c2ecf20Sopenharmony_ci struct mlxsw_sp_trap_policer_item *policer_item) 15598c2ecf20Sopenharmony_ci{ 15608c2ecf20Sopenharmony_ci __clear_bit(policer_item->hw_id, mlxsw_sp->trap->policers_usage); 15618c2ecf20Sopenharmony_ci} 15628c2ecf20Sopenharmony_ci 15638c2ecf20Sopenharmony_cistatic int mlxsw_sp_trap_policer_bs(u64 burst, u8 *p_burst_size, 15648c2ecf20Sopenharmony_ci struct netlink_ext_ack *extack) 15658c2ecf20Sopenharmony_ci{ 15668c2ecf20Sopenharmony_ci int bs = fls64(burst) - 1; 15678c2ecf20Sopenharmony_ci 15688c2ecf20Sopenharmony_ci if (burst != (BIT_ULL(bs))) { 15698c2ecf20Sopenharmony_ci NL_SET_ERR_MSG_MOD(extack, "Policer burst size is not power of two"); 15708c2ecf20Sopenharmony_ci return -EINVAL; 15718c2ecf20Sopenharmony_ci } 15728c2ecf20Sopenharmony_ci 15738c2ecf20Sopenharmony_ci *p_burst_size = bs; 15748c2ecf20Sopenharmony_ci 15758c2ecf20Sopenharmony_ci return 0; 15768c2ecf20Sopenharmony_ci} 15778c2ecf20Sopenharmony_ci 15788c2ecf20Sopenharmony_cistatic int __mlxsw_sp_trap_policer_set(struct mlxsw_sp *mlxsw_sp, u16 hw_id, 15798c2ecf20Sopenharmony_ci u64 rate, u64 burst, bool clear_counter, 15808c2ecf20Sopenharmony_ci struct netlink_ext_ack *extack) 15818c2ecf20Sopenharmony_ci{ 15828c2ecf20Sopenharmony_ci char qpcr_pl[MLXSW_REG_QPCR_LEN]; 15838c2ecf20Sopenharmony_ci u8 burst_size; 15848c2ecf20Sopenharmony_ci int err; 15858c2ecf20Sopenharmony_ci 15868c2ecf20Sopenharmony_ci err = mlxsw_sp_trap_policer_bs(burst, &burst_size, extack); 15878c2ecf20Sopenharmony_ci if (err) 15888c2ecf20Sopenharmony_ci return err; 15898c2ecf20Sopenharmony_ci 15908c2ecf20Sopenharmony_ci mlxsw_reg_qpcr_pack(qpcr_pl, hw_id, MLXSW_REG_QPCR_IR_UNITS_M, false, 15918c2ecf20Sopenharmony_ci rate, burst_size); 15928c2ecf20Sopenharmony_ci mlxsw_reg_qpcr_clear_counter_set(qpcr_pl, clear_counter); 15938c2ecf20Sopenharmony_ci return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qpcr), qpcr_pl); 15948c2ecf20Sopenharmony_ci} 15958c2ecf20Sopenharmony_ci 15968c2ecf20Sopenharmony_ciint mlxsw_sp_trap_policer_init(struct mlxsw_core *mlxsw_core, 15978c2ecf20Sopenharmony_ci const struct devlink_trap_policer *policer) 15988c2ecf20Sopenharmony_ci{ 15998c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 16008c2ecf20Sopenharmony_ci struct mlxsw_sp_trap_policer_item *policer_item; 16018c2ecf20Sopenharmony_ci int err; 16028c2ecf20Sopenharmony_ci 16038c2ecf20Sopenharmony_ci policer_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, policer->id); 16048c2ecf20Sopenharmony_ci if (WARN_ON(!policer_item)) 16058c2ecf20Sopenharmony_ci return -EINVAL; 16068c2ecf20Sopenharmony_ci 16078c2ecf20Sopenharmony_ci err = mlxsw_sp_trap_policer_item_init(mlxsw_sp, policer_item); 16088c2ecf20Sopenharmony_ci if (err) 16098c2ecf20Sopenharmony_ci return err; 16108c2ecf20Sopenharmony_ci 16118c2ecf20Sopenharmony_ci err = __mlxsw_sp_trap_policer_set(mlxsw_sp, policer_item->hw_id, 16128c2ecf20Sopenharmony_ci policer->init_rate, 16138c2ecf20Sopenharmony_ci policer->init_burst, true, NULL); 16148c2ecf20Sopenharmony_ci if (err) 16158c2ecf20Sopenharmony_ci goto err_trap_policer_set; 16168c2ecf20Sopenharmony_ci 16178c2ecf20Sopenharmony_ci return 0; 16188c2ecf20Sopenharmony_ci 16198c2ecf20Sopenharmony_cierr_trap_policer_set: 16208c2ecf20Sopenharmony_ci mlxsw_sp_trap_policer_item_fini(mlxsw_sp, policer_item); 16218c2ecf20Sopenharmony_ci return err; 16228c2ecf20Sopenharmony_ci} 16238c2ecf20Sopenharmony_ci 16248c2ecf20Sopenharmony_civoid mlxsw_sp_trap_policer_fini(struct mlxsw_core *mlxsw_core, 16258c2ecf20Sopenharmony_ci const struct devlink_trap_policer *policer) 16268c2ecf20Sopenharmony_ci{ 16278c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 16288c2ecf20Sopenharmony_ci struct mlxsw_sp_trap_policer_item *policer_item; 16298c2ecf20Sopenharmony_ci 16308c2ecf20Sopenharmony_ci policer_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, policer->id); 16318c2ecf20Sopenharmony_ci if (WARN_ON(!policer_item)) 16328c2ecf20Sopenharmony_ci return; 16338c2ecf20Sopenharmony_ci 16348c2ecf20Sopenharmony_ci mlxsw_sp_trap_policer_item_fini(mlxsw_sp, policer_item); 16358c2ecf20Sopenharmony_ci} 16368c2ecf20Sopenharmony_ci 16378c2ecf20Sopenharmony_ciint mlxsw_sp_trap_policer_set(struct mlxsw_core *mlxsw_core, 16388c2ecf20Sopenharmony_ci const struct devlink_trap_policer *policer, 16398c2ecf20Sopenharmony_ci u64 rate, u64 burst, 16408c2ecf20Sopenharmony_ci struct netlink_ext_ack *extack) 16418c2ecf20Sopenharmony_ci{ 16428c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 16438c2ecf20Sopenharmony_ci struct mlxsw_sp_trap_policer_item *policer_item; 16448c2ecf20Sopenharmony_ci 16458c2ecf20Sopenharmony_ci policer_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, policer->id); 16468c2ecf20Sopenharmony_ci if (WARN_ON(!policer_item)) 16478c2ecf20Sopenharmony_ci return -EINVAL; 16488c2ecf20Sopenharmony_ci 16498c2ecf20Sopenharmony_ci return __mlxsw_sp_trap_policer_set(mlxsw_sp, policer_item->hw_id, 16508c2ecf20Sopenharmony_ci rate, burst, false, extack); 16518c2ecf20Sopenharmony_ci} 16528c2ecf20Sopenharmony_ci 16538c2ecf20Sopenharmony_ciint 16548c2ecf20Sopenharmony_cimlxsw_sp_trap_policer_counter_get(struct mlxsw_core *mlxsw_core, 16558c2ecf20Sopenharmony_ci const struct devlink_trap_policer *policer, 16568c2ecf20Sopenharmony_ci u64 *p_drops) 16578c2ecf20Sopenharmony_ci{ 16588c2ecf20Sopenharmony_ci struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 16598c2ecf20Sopenharmony_ci struct mlxsw_sp_trap_policer_item *policer_item; 16608c2ecf20Sopenharmony_ci char qpcr_pl[MLXSW_REG_QPCR_LEN]; 16618c2ecf20Sopenharmony_ci int err; 16628c2ecf20Sopenharmony_ci 16638c2ecf20Sopenharmony_ci policer_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, policer->id); 16648c2ecf20Sopenharmony_ci if (WARN_ON(!policer_item)) 16658c2ecf20Sopenharmony_ci return -EINVAL; 16668c2ecf20Sopenharmony_ci 16678c2ecf20Sopenharmony_ci mlxsw_reg_qpcr_pack(qpcr_pl, policer_item->hw_id, 16688c2ecf20Sopenharmony_ci MLXSW_REG_QPCR_IR_UNITS_M, false, 0, 0); 16698c2ecf20Sopenharmony_ci err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(qpcr), qpcr_pl); 16708c2ecf20Sopenharmony_ci if (err) 16718c2ecf20Sopenharmony_ci return err; 16728c2ecf20Sopenharmony_ci 16738c2ecf20Sopenharmony_ci *p_drops = mlxsw_reg_qpcr_violate_count_get(qpcr_pl); 16748c2ecf20Sopenharmony_ci 16758c2ecf20Sopenharmony_ci return 0; 16768c2ecf20Sopenharmony_ci} 16778c2ecf20Sopenharmony_ci 16788c2ecf20Sopenharmony_ciint mlxsw_sp_trap_group_policer_hw_id_get(struct mlxsw_sp *mlxsw_sp, u16 id, 16798c2ecf20Sopenharmony_ci bool *p_enabled, u16 *p_hw_id) 16808c2ecf20Sopenharmony_ci{ 16818c2ecf20Sopenharmony_ci struct mlxsw_sp_trap_policer_item *pol_item; 16828c2ecf20Sopenharmony_ci struct mlxsw_sp_trap_group_item *gr_item; 16838c2ecf20Sopenharmony_ci u32 pol_id; 16848c2ecf20Sopenharmony_ci 16858c2ecf20Sopenharmony_ci gr_item = mlxsw_sp_trap_group_item_lookup(mlxsw_sp, id); 16868c2ecf20Sopenharmony_ci if (!gr_item) 16878c2ecf20Sopenharmony_ci return -ENOENT; 16888c2ecf20Sopenharmony_ci 16898c2ecf20Sopenharmony_ci pol_id = gr_item->group.init_policer_id; 16908c2ecf20Sopenharmony_ci if (!pol_id) { 16918c2ecf20Sopenharmony_ci *p_enabled = false; 16928c2ecf20Sopenharmony_ci return 0; 16938c2ecf20Sopenharmony_ci } 16948c2ecf20Sopenharmony_ci 16958c2ecf20Sopenharmony_ci pol_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, pol_id); 16968c2ecf20Sopenharmony_ci if (WARN_ON(!pol_item)) 16978c2ecf20Sopenharmony_ci return -ENOENT; 16988c2ecf20Sopenharmony_ci 16998c2ecf20Sopenharmony_ci *p_enabled = true; 17008c2ecf20Sopenharmony_ci *p_hw_id = pol_item->hw_id; 17018c2ecf20Sopenharmony_ci return 0; 17028c2ecf20Sopenharmony_ci} 17038c2ecf20Sopenharmony_ci 17048c2ecf20Sopenharmony_cistatic const struct mlxsw_sp_trap_group_item 17058c2ecf20Sopenharmony_cimlxsw_sp1_trap_group_items_arr[] = { 17068c2ecf20Sopenharmony_ci}; 17078c2ecf20Sopenharmony_ci 17088c2ecf20Sopenharmony_cistatic const struct mlxsw_sp_trap_item 17098c2ecf20Sopenharmony_cimlxsw_sp1_trap_items_arr[] = { 17108c2ecf20Sopenharmony_ci}; 17118c2ecf20Sopenharmony_ci 17128c2ecf20Sopenharmony_cistatic int 17138c2ecf20Sopenharmony_cimlxsw_sp1_trap_groups_init(struct mlxsw_sp *mlxsw_sp, 17148c2ecf20Sopenharmony_ci const struct mlxsw_sp_trap_group_item **arr, 17158c2ecf20Sopenharmony_ci size_t *p_groups_count) 17168c2ecf20Sopenharmony_ci{ 17178c2ecf20Sopenharmony_ci *arr = mlxsw_sp1_trap_group_items_arr; 17188c2ecf20Sopenharmony_ci *p_groups_count = ARRAY_SIZE(mlxsw_sp1_trap_group_items_arr); 17198c2ecf20Sopenharmony_ci 17208c2ecf20Sopenharmony_ci return 0; 17218c2ecf20Sopenharmony_ci} 17228c2ecf20Sopenharmony_ci 17238c2ecf20Sopenharmony_cistatic int mlxsw_sp1_traps_init(struct mlxsw_sp *mlxsw_sp, 17248c2ecf20Sopenharmony_ci const struct mlxsw_sp_trap_item **arr, 17258c2ecf20Sopenharmony_ci size_t *p_traps_count) 17268c2ecf20Sopenharmony_ci{ 17278c2ecf20Sopenharmony_ci *arr = mlxsw_sp1_trap_items_arr; 17288c2ecf20Sopenharmony_ci *p_traps_count = ARRAY_SIZE(mlxsw_sp1_trap_items_arr); 17298c2ecf20Sopenharmony_ci 17308c2ecf20Sopenharmony_ci return 0; 17318c2ecf20Sopenharmony_ci} 17328c2ecf20Sopenharmony_ci 17338c2ecf20Sopenharmony_ciconst struct mlxsw_sp_trap_ops mlxsw_sp1_trap_ops = { 17348c2ecf20Sopenharmony_ci .groups_init = mlxsw_sp1_trap_groups_init, 17358c2ecf20Sopenharmony_ci .traps_init = mlxsw_sp1_traps_init, 17368c2ecf20Sopenharmony_ci}; 17378c2ecf20Sopenharmony_ci 17388c2ecf20Sopenharmony_cistatic const struct mlxsw_sp_trap_group_item 17398c2ecf20Sopenharmony_cimlxsw_sp2_trap_group_items_arr[] = { 17408c2ecf20Sopenharmony_ci { 17418c2ecf20Sopenharmony_ci .group = DEVLINK_TRAP_GROUP_GENERIC(BUFFER_DROPS, 20), 17428c2ecf20Sopenharmony_ci .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_BUFFER_DISCARDS, 17438c2ecf20Sopenharmony_ci .priority = 0, 17448c2ecf20Sopenharmony_ci .fixed_policer = true, 17458c2ecf20Sopenharmony_ci }, 17468c2ecf20Sopenharmony_ci}; 17478c2ecf20Sopenharmony_ci 17488c2ecf20Sopenharmony_cistatic const struct mlxsw_sp_trap_item 17498c2ecf20Sopenharmony_cimlxsw_sp2_trap_items_arr[] = { 17508c2ecf20Sopenharmony_ci { 17518c2ecf20Sopenharmony_ci .trap = MLXSW_SP_TRAP_BUFFER_DROP(EARLY_DROP), 17528c2ecf20Sopenharmony_ci .listeners_arr = { 17538c2ecf20Sopenharmony_ci MLXSW_SP_RXL_BUFFER_DISCARD(INGRESS_WRED), 17548c2ecf20Sopenharmony_ci }, 17558c2ecf20Sopenharmony_ci .is_source = true, 17568c2ecf20Sopenharmony_ci }, 17578c2ecf20Sopenharmony_ci}; 17588c2ecf20Sopenharmony_ci 17598c2ecf20Sopenharmony_cistatic int 17608c2ecf20Sopenharmony_cimlxsw_sp2_trap_groups_init(struct mlxsw_sp *mlxsw_sp, 17618c2ecf20Sopenharmony_ci const struct mlxsw_sp_trap_group_item **arr, 17628c2ecf20Sopenharmony_ci size_t *p_groups_count) 17638c2ecf20Sopenharmony_ci{ 17648c2ecf20Sopenharmony_ci *arr = mlxsw_sp2_trap_group_items_arr; 17658c2ecf20Sopenharmony_ci *p_groups_count = ARRAY_SIZE(mlxsw_sp2_trap_group_items_arr); 17668c2ecf20Sopenharmony_ci 17678c2ecf20Sopenharmony_ci return 0; 17688c2ecf20Sopenharmony_ci} 17698c2ecf20Sopenharmony_ci 17708c2ecf20Sopenharmony_cistatic int mlxsw_sp2_traps_init(struct mlxsw_sp *mlxsw_sp, 17718c2ecf20Sopenharmony_ci const struct mlxsw_sp_trap_item **arr, 17728c2ecf20Sopenharmony_ci size_t *p_traps_count) 17738c2ecf20Sopenharmony_ci{ 17748c2ecf20Sopenharmony_ci *arr = mlxsw_sp2_trap_items_arr; 17758c2ecf20Sopenharmony_ci *p_traps_count = ARRAY_SIZE(mlxsw_sp2_trap_items_arr); 17768c2ecf20Sopenharmony_ci 17778c2ecf20Sopenharmony_ci return 0; 17788c2ecf20Sopenharmony_ci} 17798c2ecf20Sopenharmony_ci 17808c2ecf20Sopenharmony_ciconst struct mlxsw_sp_trap_ops mlxsw_sp2_trap_ops = { 17818c2ecf20Sopenharmony_ci .groups_init = mlxsw_sp2_trap_groups_init, 17828c2ecf20Sopenharmony_ci .traps_init = mlxsw_sp2_traps_init, 17838c2ecf20Sopenharmony_ci}; 1784