162306a36Sopenharmony_ci/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ 262306a36Sopenharmony_ci/* Copyright (c) 2018 Mellanox Technologies. All rights reserved */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#ifndef _MLXSW_SPECTRUM_SPAN_H 562306a36Sopenharmony_ci#define _MLXSW_SPECTRUM_SPAN_H 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <linux/types.h> 862306a36Sopenharmony_ci#include <linux/if_ether.h> 962306a36Sopenharmony_ci#include <linux/refcount.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include "spectrum_router.h" 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_cistruct mlxsw_sp; 1462306a36Sopenharmony_cistruct mlxsw_sp_port; 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci/* SPAN session identifiers that correspond to MLXSW_TRAP_ID_MIRROR_SESSION<i> 1762306a36Sopenharmony_ci * trap identifiers. The session identifier is an attribute of the SPAN agent, 1862306a36Sopenharmony_ci * which determines the trap identifier of packets that are mirrored to the 1962306a36Sopenharmony_ci * CPU. Packets that are trapped to the CPU for the same logical reason (e.g., 2062306a36Sopenharmony_ci * buffer drops) should use the same session identifier. 2162306a36Sopenharmony_ci */ 2262306a36Sopenharmony_cienum mlxsw_sp_span_session_id { 2362306a36Sopenharmony_ci MLXSW_SP_SPAN_SESSION_ID_BUFFER, 2462306a36Sopenharmony_ci MLXSW_SP_SPAN_SESSION_ID_SAMPLING, 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci __MLXSW_SP_SPAN_SESSION_ID_MAX = 8, 2762306a36Sopenharmony_ci}; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_cistruct mlxsw_sp_span_parms { 3062306a36Sopenharmony_ci struct mlxsw_sp_port *dest_port; /* NULL for unoffloaded SPAN. */ 3162306a36Sopenharmony_ci unsigned int ttl; 3262306a36Sopenharmony_ci unsigned char dmac[ETH_ALEN]; 3362306a36Sopenharmony_ci unsigned char smac[ETH_ALEN]; 3462306a36Sopenharmony_ci union mlxsw_sp_l3addr daddr; 3562306a36Sopenharmony_ci union mlxsw_sp_l3addr saddr; 3662306a36Sopenharmony_ci u16 vid; 3762306a36Sopenharmony_ci u16 policer_id; 3862306a36Sopenharmony_ci bool policer_enable; 3962306a36Sopenharmony_ci enum mlxsw_sp_span_session_id session_id; 4062306a36Sopenharmony_ci}; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_cienum mlxsw_sp_span_trigger { 4362306a36Sopenharmony_ci MLXSW_SP_SPAN_TRIGGER_INGRESS, 4462306a36Sopenharmony_ci MLXSW_SP_SPAN_TRIGGER_EGRESS, 4562306a36Sopenharmony_ci MLXSW_SP_SPAN_TRIGGER_TAIL_DROP, 4662306a36Sopenharmony_ci MLXSW_SP_SPAN_TRIGGER_EARLY_DROP, 4762306a36Sopenharmony_ci MLXSW_SP_SPAN_TRIGGER_ECN, 4862306a36Sopenharmony_ci}; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_cistruct mlxsw_sp_span_trigger_parms { 5162306a36Sopenharmony_ci int span_id; 5262306a36Sopenharmony_ci u32 probability_rate; 5362306a36Sopenharmony_ci}; 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_cistruct mlxsw_sp_span_agent_parms { 5662306a36Sopenharmony_ci const struct net_device *to_dev; 5762306a36Sopenharmony_ci u16 policer_id; 5862306a36Sopenharmony_ci bool policer_enable; 5962306a36Sopenharmony_ci enum mlxsw_sp_span_session_id session_id; 6062306a36Sopenharmony_ci}; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_cistruct mlxsw_sp_span_entry_ops; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cistruct mlxsw_sp_span_ops { 6562306a36Sopenharmony_ci int (*init)(struct mlxsw_sp *mlxsw_sp); 6662306a36Sopenharmony_ci int (*policer_id_base_set)(struct mlxsw_sp *mlxsw_sp, 6762306a36Sopenharmony_ci u16 policer_id_base); 6862306a36Sopenharmony_ci}; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_cistruct mlxsw_sp_span_entry { 7162306a36Sopenharmony_ci const struct net_device *to_dev; 7262306a36Sopenharmony_ci const struct mlxsw_sp_span_entry_ops *ops; 7362306a36Sopenharmony_ci struct mlxsw_sp_span_parms parms; 7462306a36Sopenharmony_ci refcount_t ref_count; 7562306a36Sopenharmony_ci int id; 7662306a36Sopenharmony_ci}; 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_cistruct mlxsw_sp_span_entry_ops { 7962306a36Sopenharmony_ci bool is_static; 8062306a36Sopenharmony_ci bool (*can_handle)(const struct net_device *to_dev); 8162306a36Sopenharmony_ci int (*parms_set)(struct mlxsw_sp *mlxsw_sp, 8262306a36Sopenharmony_ci const struct net_device *to_dev, 8362306a36Sopenharmony_ci struct mlxsw_sp_span_parms *sparmsp); 8462306a36Sopenharmony_ci int (*configure)(struct mlxsw_sp_span_entry *span_entry, 8562306a36Sopenharmony_ci struct mlxsw_sp_span_parms sparms); 8662306a36Sopenharmony_ci void (*deconfigure)(struct mlxsw_sp_span_entry *span_entry); 8762306a36Sopenharmony_ci}; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ciint mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp); 9062306a36Sopenharmony_civoid mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp); 9162306a36Sopenharmony_civoid mlxsw_sp_span_respin(struct mlxsw_sp *mlxsw_sp); 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_cistruct mlxsw_sp_span_entry * 9462306a36Sopenharmony_cimlxsw_sp_span_entry_find_by_port(struct mlxsw_sp *mlxsw_sp, 9562306a36Sopenharmony_ci const struct net_device *to_dev); 9662306a36Sopenharmony_civoid mlxsw_sp_span_entry_invalidate(struct mlxsw_sp *mlxsw_sp, 9762306a36Sopenharmony_ci struct mlxsw_sp_span_entry *span_entry); 9862306a36Sopenharmony_ciint mlxsw_sp_span_agent_get(struct mlxsw_sp *mlxsw_sp, int *p_span_id, 9962306a36Sopenharmony_ci const struct mlxsw_sp_span_agent_parms *parms); 10062306a36Sopenharmony_civoid mlxsw_sp_span_agent_put(struct mlxsw_sp *mlxsw_sp, int span_id); 10162306a36Sopenharmony_ciint mlxsw_sp_span_analyzed_port_get(struct mlxsw_sp_port *mlxsw_sp_port, 10262306a36Sopenharmony_ci bool ingress); 10362306a36Sopenharmony_civoid mlxsw_sp_span_analyzed_port_put(struct mlxsw_sp_port *mlxsw_sp_port, 10462306a36Sopenharmony_ci bool ingress); 10562306a36Sopenharmony_ciint mlxsw_sp_span_agent_bind(struct mlxsw_sp *mlxsw_sp, 10662306a36Sopenharmony_ci enum mlxsw_sp_span_trigger trigger, 10762306a36Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port, 10862306a36Sopenharmony_ci const struct mlxsw_sp_span_trigger_parms *parms); 10962306a36Sopenharmony_civoid 11062306a36Sopenharmony_cimlxsw_sp_span_agent_unbind(struct mlxsw_sp *mlxsw_sp, 11162306a36Sopenharmony_ci enum mlxsw_sp_span_trigger trigger, 11262306a36Sopenharmony_ci struct mlxsw_sp_port *mlxsw_sp_port, 11362306a36Sopenharmony_ci const struct mlxsw_sp_span_trigger_parms *parms); 11462306a36Sopenharmony_ciint mlxsw_sp_span_trigger_enable(struct mlxsw_sp_port *mlxsw_sp_port, 11562306a36Sopenharmony_ci enum mlxsw_sp_span_trigger trigger, u8 tc); 11662306a36Sopenharmony_civoid mlxsw_sp_span_trigger_disable(struct mlxsw_sp_port *mlxsw_sp_port, 11762306a36Sopenharmony_ci enum mlxsw_sp_span_trigger trigger, u8 tc); 11862306a36Sopenharmony_cibool mlxsw_sp_span_trigger_is_ingress(enum mlxsw_sp_span_trigger trigger); 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ciextern const struct mlxsw_sp_span_ops mlxsw_sp1_span_ops; 12162306a36Sopenharmony_ciextern const struct mlxsw_sp_span_ops mlxsw_sp2_span_ops; 12262306a36Sopenharmony_ciextern const struct mlxsw_sp_span_ops mlxsw_sp3_span_ops; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci#endif 125