1/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
2/* Copyright (c) 2018 Mellanox Technologies. All rights reserved */
3
4#ifndef _MLXSW_SPECTRUM_SPAN_H
5#define _MLXSW_SPECTRUM_SPAN_H
6
7#include <linux/types.h>
8#include <linux/if_ether.h>
9#include <linux/refcount.h>
10
11#include "spectrum_router.h"
12
13struct mlxsw_sp;
14struct mlxsw_sp_port;
15
16struct mlxsw_sp_span_parms {
17	struct mlxsw_sp_port *dest_port; /* NULL for unoffloaded SPAN. */
18	unsigned int ttl;
19	unsigned char dmac[ETH_ALEN];
20	unsigned char smac[ETH_ALEN];
21	union mlxsw_sp_l3addr daddr;
22	union mlxsw_sp_l3addr saddr;
23	u16 vid;
24	u16 policer_id;
25	bool policer_enable;
26};
27
28enum mlxsw_sp_span_trigger {
29	MLXSW_SP_SPAN_TRIGGER_INGRESS,
30	MLXSW_SP_SPAN_TRIGGER_EGRESS,
31	MLXSW_SP_SPAN_TRIGGER_TAIL_DROP,
32	MLXSW_SP_SPAN_TRIGGER_EARLY_DROP,
33	MLXSW_SP_SPAN_TRIGGER_ECN,
34};
35
36struct mlxsw_sp_span_trigger_parms {
37	int span_id;
38};
39
40struct mlxsw_sp_span_agent_parms {
41	const struct net_device *to_dev;
42	u16 policer_id;
43	bool policer_enable;
44};
45
46struct mlxsw_sp_span_entry_ops;
47
48struct mlxsw_sp_span_ops {
49	int (*init)(struct mlxsw_sp *mlxsw_sp);
50	int (*policer_id_base_set)(struct mlxsw_sp *mlxsw_sp,
51				   u16 policer_id_base);
52};
53
54struct mlxsw_sp_span_entry {
55	const struct net_device *to_dev;
56	const struct mlxsw_sp_span_entry_ops *ops;
57	struct mlxsw_sp_span_parms parms;
58	refcount_t ref_count;
59	int id;
60};
61
62struct mlxsw_sp_span_entry_ops {
63	bool is_static;
64	bool (*can_handle)(const struct net_device *to_dev);
65	int (*parms_set)(struct mlxsw_sp *mlxsw_sp,
66			 const struct net_device *to_dev,
67			 struct mlxsw_sp_span_parms *sparmsp);
68	int (*configure)(struct mlxsw_sp_span_entry *span_entry,
69			 struct mlxsw_sp_span_parms sparms);
70	void (*deconfigure)(struct mlxsw_sp_span_entry *span_entry);
71};
72
73int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp);
74void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp);
75void mlxsw_sp_span_respin(struct mlxsw_sp *mlxsw_sp);
76
77struct mlxsw_sp_span_entry *
78mlxsw_sp_span_entry_find_by_port(struct mlxsw_sp *mlxsw_sp,
79				 const struct net_device *to_dev);
80
81void mlxsw_sp_span_entry_invalidate(struct mlxsw_sp *mlxsw_sp,
82				    struct mlxsw_sp_span_entry *span_entry);
83
84int mlxsw_sp_span_port_mtu_update(struct mlxsw_sp_port *port, u16 mtu);
85void mlxsw_sp_span_speed_update_work(struct work_struct *work);
86
87int mlxsw_sp_span_agent_get(struct mlxsw_sp *mlxsw_sp, int *p_span_id,
88			    const struct mlxsw_sp_span_agent_parms *parms);
89void mlxsw_sp_span_agent_put(struct mlxsw_sp *mlxsw_sp, int span_id);
90int mlxsw_sp_span_analyzed_port_get(struct mlxsw_sp_port *mlxsw_sp_port,
91				    bool ingress);
92void mlxsw_sp_span_analyzed_port_put(struct mlxsw_sp_port *mlxsw_sp_port,
93				     bool ingress);
94int mlxsw_sp_span_agent_bind(struct mlxsw_sp *mlxsw_sp,
95			     enum mlxsw_sp_span_trigger trigger,
96			     struct mlxsw_sp_port *mlxsw_sp_port,
97			     const struct mlxsw_sp_span_trigger_parms *parms);
98void
99mlxsw_sp_span_agent_unbind(struct mlxsw_sp *mlxsw_sp,
100			   enum mlxsw_sp_span_trigger trigger,
101			   struct mlxsw_sp_port *mlxsw_sp_port,
102			   const struct mlxsw_sp_span_trigger_parms *parms);
103int mlxsw_sp_span_trigger_enable(struct mlxsw_sp_port *mlxsw_sp_port,
104				 enum mlxsw_sp_span_trigger trigger, u8 tc);
105void mlxsw_sp_span_trigger_disable(struct mlxsw_sp_port *mlxsw_sp_port,
106				   enum mlxsw_sp_span_trigger trigger, u8 tc);
107
108extern const struct mlxsw_sp_span_ops mlxsw_sp1_span_ops;
109extern const struct mlxsw_sp_span_ops mlxsw_sp2_span_ops;
110extern const struct mlxsw_sp_span_ops mlxsw_sp3_span_ops;
111
112#endif
113