xref: /openbmc/linux/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
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