19948a064SJiri Pirko /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ 29948a064SJiri Pirko /* Copyright (c) 2018 Mellanox Technologies. All rights reserved */ 3a629ef21SPetr Machata 4a629ef21SPetr Machata #ifndef _MLXSW_SPECTRUM_SPAN_H 5a629ef21SPetr Machata #define _MLXSW_SPECTRUM_SPAN_H 6a629ef21SPetr Machata 7a629ef21SPetr Machata #include <linux/types.h> 827cf76feSPetr Machata #include <linux/if_ether.h> 94c00dafcSIdo Schimmel #include <linux/refcount.h> 1027cf76feSPetr Machata 1127cf76feSPetr Machata #include "spectrum_router.h" 12a629ef21SPetr Machata 13a629ef21SPetr Machata struct mlxsw_sp; 14a629ef21SPetr Machata struct mlxsw_sp_port; 15a629ef21SPetr Machata 165c7659ebSIdo Schimmel /* SPAN session identifiers that correspond to MLXSW_TRAP_ID_MIRROR_SESSION<i> 175c7659ebSIdo Schimmel * trap identifiers. The session identifier is an attribute of the SPAN agent, 185c7659ebSIdo Schimmel * which determines the trap identifier of packets that are mirrored to the 195c7659ebSIdo Schimmel * CPU. Packets that are trapped to the CPU for the same logical reason (e.g., 205c7659ebSIdo Schimmel * buffer drops) should use the same session identifier. 215c7659ebSIdo Schimmel */ 225c7659ebSIdo Schimmel enum mlxsw_sp_span_session_id { 235c7659ebSIdo Schimmel MLXSW_SP_SPAN_SESSION_ID_BUFFER, 24cf31190aSIdo Schimmel MLXSW_SP_SPAN_SESSION_ID_SAMPLING, 255c7659ebSIdo Schimmel 265c7659ebSIdo Schimmel __MLXSW_SP_SPAN_SESSION_ID_MAX = 8, 275c7659ebSIdo Schimmel }; 285c7659ebSIdo Schimmel 29169b5d95SPetr Machata struct mlxsw_sp_span_parms { 30169b5d95SPetr Machata struct mlxsw_sp_port *dest_port; /* NULL for unoffloaded SPAN. */ 3127cf76feSPetr Machata unsigned int ttl; 3227cf76feSPetr Machata unsigned char dmac[ETH_ALEN]; 3327cf76feSPetr Machata unsigned char smac[ETH_ALEN]; 3427cf76feSPetr Machata union mlxsw_sp_l3addr daddr; 3527cf76feSPetr Machata union mlxsw_sp_l3addr saddr; 36946a11e7SPetr Machata u16 vid; 374039504eSIdo Schimmel u16 policer_id; 384039504eSIdo Schimmel bool policer_enable; 395c7659ebSIdo Schimmel enum mlxsw_sp_span_session_id session_id; 40169b5d95SPetr Machata }; 41169b5d95SPetr Machata 42c056618cSIdo Schimmel enum mlxsw_sp_span_trigger { 43c056618cSIdo Schimmel MLXSW_SP_SPAN_TRIGGER_INGRESS, 44c056618cSIdo Schimmel MLXSW_SP_SPAN_TRIGGER_EGRESS, 45ab8c06b7SIdo Schimmel MLXSW_SP_SPAN_TRIGGER_TAIL_DROP, 46ab8c06b7SIdo Schimmel MLXSW_SP_SPAN_TRIGGER_EARLY_DROP, 47ab8c06b7SIdo Schimmel MLXSW_SP_SPAN_TRIGGER_ECN, 48c056618cSIdo Schimmel }; 49c056618cSIdo Schimmel 50c056618cSIdo Schimmel struct mlxsw_sp_span_trigger_parms { 51c056618cSIdo Schimmel int span_id; 522dcbd920SIdo Schimmel u32 probability_rate; 53c056618cSIdo Schimmel }; 54c056618cSIdo Schimmel 55a120ecc3SIdo Schimmel struct mlxsw_sp_span_agent_parms { 56a120ecc3SIdo Schimmel const struct net_device *to_dev; 574039504eSIdo Schimmel u16 policer_id; 584039504eSIdo Schimmel bool policer_enable; 595c7659ebSIdo Schimmel enum mlxsw_sp_span_session_id session_id; 60a120ecc3SIdo Schimmel }; 61a120ecc3SIdo Schimmel 62169b5d95SPetr Machata struct mlxsw_sp_span_entry_ops; 63169b5d95SPetr Machata 644bafb85aSIdo Schimmel struct mlxsw_sp_span_ops { 6508a3641fSIdo Schimmel int (*init)(struct mlxsw_sp *mlxsw_sp); 664039504eSIdo Schimmel int (*policer_id_base_set)(struct mlxsw_sp *mlxsw_sp, 674039504eSIdo Schimmel u16 policer_id_base); 684bafb85aSIdo Schimmel }; 694bafb85aSIdo Schimmel 70a629ef21SPetr Machata struct mlxsw_sp_span_entry { 71079c9f39SPetr Machata const struct net_device *to_dev; 72169b5d95SPetr Machata const struct mlxsw_sp_span_entry_ops *ops; 73169b5d95SPetr Machata struct mlxsw_sp_span_parms parms; 744c00dafcSIdo Schimmel refcount_t ref_count; 75a629ef21SPetr Machata int id; 76a629ef21SPetr Machata }; 77a629ef21SPetr Machata 78169b5d95SPetr Machata struct mlxsw_sp_span_entry_ops { 79b6f6881aSIdo Schimmel bool is_static; 80169b5d95SPetr Machata bool (*can_handle)(const struct net_device *to_dev); 81f4a626e2SIdo Schimmel int (*parms_set)(struct mlxsw_sp *mlxsw_sp, 82f4a626e2SIdo Schimmel const struct net_device *to_dev, 83169b5d95SPetr Machata struct mlxsw_sp_span_parms *sparmsp); 84169b5d95SPetr Machata int (*configure)(struct mlxsw_sp_span_entry *span_entry, 85169b5d95SPetr Machata struct mlxsw_sp_span_parms sparms); 86169b5d95SPetr Machata void (*deconfigure)(struct mlxsw_sp_span_entry *span_entry); 87169b5d95SPetr Machata }; 88169b5d95SPetr Machata 89a629ef21SPetr Machata int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp); 90a629ef21SPetr Machata void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp); 91803335acSPetr Machata void mlxsw_sp_span_respin(struct mlxsw_sp *mlxsw_sp); 92a629ef21SPetr Machata 93a629ef21SPetr Machata struct mlxsw_sp_span_entry * 94079c9f39SPetr Machata mlxsw_sp_span_entry_find_by_port(struct mlxsw_sp *mlxsw_sp, 95079c9f39SPetr Machata const struct net_device *to_dev); 96079c9f39SPetr Machata void mlxsw_sp_span_entry_invalidate(struct mlxsw_sp *mlxsw_sp, 97079c9f39SPetr Machata struct mlxsw_sp_span_entry *span_entry); 98a120ecc3SIdo Schimmel int mlxsw_sp_span_agent_get(struct mlxsw_sp *mlxsw_sp, int *p_span_id, 99a120ecc3SIdo Schimmel const struct mlxsw_sp_span_agent_parms *parms); 10046601034SIdo Schimmel void mlxsw_sp_span_agent_put(struct mlxsw_sp *mlxsw_sp, int span_id); 101ed04458dSIdo Schimmel int mlxsw_sp_span_analyzed_port_get(struct mlxsw_sp_port *mlxsw_sp_port, 102ed04458dSIdo Schimmel bool ingress); 103ed04458dSIdo Schimmel void mlxsw_sp_span_analyzed_port_put(struct mlxsw_sp_port *mlxsw_sp_port, 104ed04458dSIdo Schimmel bool ingress); 105c056618cSIdo Schimmel int mlxsw_sp_span_agent_bind(struct mlxsw_sp *mlxsw_sp, 106c056618cSIdo Schimmel enum mlxsw_sp_span_trigger trigger, 107c056618cSIdo Schimmel struct mlxsw_sp_port *mlxsw_sp_port, 108c056618cSIdo Schimmel const struct mlxsw_sp_span_trigger_parms *parms); 109c056618cSIdo Schimmel void 110c056618cSIdo Schimmel mlxsw_sp_span_agent_unbind(struct mlxsw_sp *mlxsw_sp, 111c056618cSIdo Schimmel enum mlxsw_sp_span_trigger trigger, 112c056618cSIdo Schimmel struct mlxsw_sp_port *mlxsw_sp_port, 113c056618cSIdo Schimmel const struct mlxsw_sp_span_trigger_parms *parms); 1142bafb216SIdo Schimmel int mlxsw_sp_span_trigger_enable(struct mlxsw_sp_port *mlxsw_sp_port, 1152bafb216SIdo Schimmel enum mlxsw_sp_span_trigger trigger, u8 tc); 1162bafb216SIdo Schimmel void mlxsw_sp_span_trigger_disable(struct mlxsw_sp_port *mlxsw_sp_port, 1172bafb216SIdo Schimmel enum mlxsw_sp_span_trigger trigger, u8 tc); 118*0908e42aSPetr Machata bool mlxsw_sp_span_trigger_is_ingress(enum mlxsw_sp_span_trigger trigger); 11946601034SIdo Schimmel 1204bafb85aSIdo Schimmel extern const struct mlxsw_sp_span_ops mlxsw_sp1_span_ops; 1214bafb85aSIdo Schimmel extern const struct mlxsw_sp_span_ops mlxsw_sp2_span_ops; 1224bafb85aSIdo Schimmel extern const struct mlxsw_sp_span_ops mlxsw_sp3_span_ops; 1234bafb85aSIdo Schimmel 124a629ef21SPetr Machata #endif 125