#include <linux/if_bridge.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/refcount.h>
#include <linux/rtnetlink.h>
#include <linux/workqueue.h>
#include <net/arp.h>
#include <net/gre.h>
#include <net/lag.h>
#include <net/ndisc.h>
#include <net/ip6_tunnel.h>
#include "spectrum.h"
#include "spectrum_ipip.h"
#include "spectrum_span.h"
#include "spectrum_switchdev.h"
struct mlxsw_sp_span { … };
struct mlxsw_sp_span_analyzed_port { … };
struct mlxsw_sp_span_trigger_entry { … };
enum mlxsw_sp_span_trigger_type { … };
struct mlxsw_sp_span_trigger_ops { … };
static void mlxsw_sp_span_respin_work(struct work_struct *work);
static u64 mlxsw_sp_span_occ_get(void *priv)
{ … }
int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp)
{ … }
void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp)
{ … }
static bool mlxsw_sp1_span_cpu_can_handle(const struct net_device *dev)
{ … }
static int mlxsw_sp1_span_entry_cpu_parms(struct mlxsw_sp *mlxsw_sp,
const struct net_device *to_dev,
struct mlxsw_sp_span_parms *sparmsp)
{ … }
static int
mlxsw_sp1_span_entry_cpu_configure(struct mlxsw_sp_span_entry *span_entry,
struct mlxsw_sp_span_parms sparms)
{ … }
static void
mlxsw_sp1_span_entry_cpu_deconfigure(struct mlxsw_sp_span_entry *span_entry)
{ … }
static const
struct mlxsw_sp_span_entry_ops mlxsw_sp1_span_entry_ops_cpu = …;
static int
mlxsw_sp_span_entry_phys_parms(struct mlxsw_sp *mlxsw_sp,
const struct net_device *to_dev,
struct mlxsw_sp_span_parms *sparmsp)
{ … }
static int
mlxsw_sp_span_entry_phys_configure(struct mlxsw_sp_span_entry *span_entry,
struct mlxsw_sp_span_parms sparms)
{ … }
static void
mlxsw_sp_span_entry_deconfigure_common(struct mlxsw_sp_span_entry *span_entry,
enum mlxsw_reg_mpat_span_type span_type)
{ … }
static void
mlxsw_sp_span_entry_phys_deconfigure(struct mlxsw_sp_span_entry *span_entry)
{ … }
static const
struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_phys = …;
static int mlxsw_sp_span_dmac(struct neigh_table *tbl,
const void *pkey,
struct net_device *dev,
unsigned char dmac[ETH_ALEN])
{ … }
static int
mlxsw_sp_span_entry_unoffloadable(struct mlxsw_sp_span_parms *sparmsp)
{ … }
static struct net_device *
mlxsw_sp_span_entry_bridge_8021q(const struct net_device *br_dev,
unsigned char *dmac,
u16 *p_vid)
{ … }
static struct net_device *
mlxsw_sp_span_entry_bridge_8021d(const struct net_device *br_dev,
unsigned char *dmac)
{ … }
static struct net_device *
mlxsw_sp_span_entry_bridge(const struct net_device *br_dev,
unsigned char dmac[ETH_ALEN],
u16 *p_vid)
{ … }
static struct net_device *
mlxsw_sp_span_entry_vlan(const struct net_device *vlan_dev,
u16 *p_vid)
{ … }
static struct net_device *
mlxsw_sp_span_entry_lag(struct net_device *lag_dev)
{ … }
static __maybe_unused int
mlxsw_sp_span_entry_tunnel_parms_common(struct net_device *edev,
union mlxsw_sp_l3addr saddr,
union mlxsw_sp_l3addr daddr,
union mlxsw_sp_l3addr gw,
__u8 ttl,
struct neigh_table *tbl,
struct mlxsw_sp_span_parms *sparmsp)
{ … }
#if IS_ENABLED(CONFIG_NET_IPGRE)
static struct net_device *
mlxsw_sp_span_gretap4_route(const struct net_device *to_dev,
__be32 *saddrp, __be32 *daddrp)
{ … }
static int
mlxsw_sp_span_entry_gretap4_parms(struct mlxsw_sp *mlxsw_sp,
const struct net_device *to_dev,
struct mlxsw_sp_span_parms *sparmsp)
{ … }
static int
mlxsw_sp_span_entry_gretap4_configure(struct mlxsw_sp_span_entry *span_entry,
struct mlxsw_sp_span_parms sparms)
{ … }
static void
mlxsw_sp_span_entry_gretap4_deconfigure(struct mlxsw_sp_span_entry *span_entry)
{ … }
static const struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_gretap4 = …;
#endif
#if IS_ENABLED(CONFIG_IPV6_GRE)
static struct net_device *
mlxsw_sp_span_gretap6_route(const struct net_device *to_dev,
struct in6_addr *saddrp,
struct in6_addr *daddrp)
{ … }
static int
mlxsw_sp_span_entry_gretap6_parms(struct mlxsw_sp *mlxsw_sp,
const struct net_device *to_dev,
struct mlxsw_sp_span_parms *sparmsp)
{ … }
static int
mlxsw_sp_span_entry_gretap6_configure(struct mlxsw_sp_span_entry *span_entry,
struct mlxsw_sp_span_parms sparms)
{ … }
static void
mlxsw_sp_span_entry_gretap6_deconfigure(struct mlxsw_sp_span_entry *span_entry)
{ … }
static const
struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_gretap6 = …;
#endif
static bool
mlxsw_sp_span_vlan_can_handle(const struct net_device *dev)
{ … }
static int
mlxsw_sp_span_entry_vlan_parms(struct mlxsw_sp *mlxsw_sp,
const struct net_device *to_dev,
struct mlxsw_sp_span_parms *sparmsp)
{ … }
static int
mlxsw_sp_span_entry_vlan_configure(struct mlxsw_sp_span_entry *span_entry,
struct mlxsw_sp_span_parms sparms)
{ … }
static void
mlxsw_sp_span_entry_vlan_deconfigure(struct mlxsw_sp_span_entry *span_entry)
{ … }
static const
struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_vlan = …;
static const
struct mlxsw_sp_span_entry_ops *mlxsw_sp1_span_entry_ops_arr[] = …;
static bool mlxsw_sp2_span_cpu_can_handle(const struct net_device *dev)
{ … }
static int mlxsw_sp2_span_entry_cpu_parms(struct mlxsw_sp *mlxsw_sp,
const struct net_device *to_dev,
struct mlxsw_sp_span_parms *sparmsp)
{ … }
static int
mlxsw_sp2_span_entry_cpu_configure(struct mlxsw_sp_span_entry *span_entry,
struct mlxsw_sp_span_parms sparms)
{ … }
static void
mlxsw_sp2_span_entry_cpu_deconfigure(struct mlxsw_sp_span_entry *span_entry)
{ … }
static const
struct mlxsw_sp_span_entry_ops mlxsw_sp2_span_entry_ops_cpu = …;
static const
struct mlxsw_sp_span_entry_ops *mlxsw_sp2_span_entry_ops_arr[] = …;
static int
mlxsw_sp_span_entry_nop_parms(struct mlxsw_sp *mlxsw_sp,
const struct net_device *to_dev,
struct mlxsw_sp_span_parms *sparmsp)
{ … }
static int
mlxsw_sp_span_entry_nop_configure(struct mlxsw_sp_span_entry *span_entry,
struct mlxsw_sp_span_parms sparms)
{ … }
static void
mlxsw_sp_span_entry_nop_deconfigure(struct mlxsw_sp_span_entry *span_entry)
{ … }
static const struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_nop = …;
static void
mlxsw_sp_span_entry_configure(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_span_entry *span_entry,
struct mlxsw_sp_span_parms sparms)
{ … }
static void
mlxsw_sp_span_entry_deconfigure(struct mlxsw_sp_span_entry *span_entry)
{ … }
static int mlxsw_sp_span_policer_id_base_set(struct mlxsw_sp_span *span,
u16 policer_id)
{ … }
static void mlxsw_sp_span_policer_id_base_unset(struct mlxsw_sp_span *span)
{ … }
static struct mlxsw_sp_span_entry *
mlxsw_sp_span_entry_create(struct mlxsw_sp *mlxsw_sp,
const struct net_device *to_dev,
const struct mlxsw_sp_span_entry_ops *ops,
struct mlxsw_sp_span_parms sparms)
{ … }
static void mlxsw_sp_span_entry_destroy(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_span_entry *span_entry)
{ … }
struct mlxsw_sp_span_entry *
mlxsw_sp_span_entry_find_by_port(struct mlxsw_sp *mlxsw_sp,
const struct net_device *to_dev)
{ … }
void mlxsw_sp_span_entry_invalidate(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_span_entry *span_entry)
{ … }
static struct mlxsw_sp_span_entry *
mlxsw_sp_span_entry_find_by_id(struct mlxsw_sp *mlxsw_sp, int span_id)
{ … }
static struct mlxsw_sp_span_entry *
mlxsw_sp_span_entry_find_by_parms(struct mlxsw_sp *mlxsw_sp,
const struct net_device *to_dev,
const struct mlxsw_sp_span_parms *sparms)
{ … }
static struct mlxsw_sp_span_entry *
mlxsw_sp_span_entry_get(struct mlxsw_sp *mlxsw_sp,
const struct net_device *to_dev,
const struct mlxsw_sp_span_entry_ops *ops,
struct mlxsw_sp_span_parms sparms)
{ … }
static int mlxsw_sp_span_entry_put(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_span_entry *span_entry)
{ … }
static int mlxsw_sp_span_port_buffer_update(struct mlxsw_sp_port *mlxsw_sp_port, bool enable)
{ … }
static int
mlxsw_sp_span_port_buffer_enable(struct mlxsw_sp_port *mlxsw_sp_port)
{ … }
static void mlxsw_sp_span_port_buffer_disable(struct mlxsw_sp_port *mlxsw_sp_port)
{ … }
static struct mlxsw_sp_span_analyzed_port *
mlxsw_sp_span_analyzed_port_find(struct mlxsw_sp_span *span, u16 local_port,
bool ingress)
{ … }
static const struct mlxsw_sp_span_entry_ops *
mlxsw_sp_span_entry_ops(struct mlxsw_sp *mlxsw_sp,
const struct net_device *to_dev)
{ … }
static void mlxsw_sp_span_respin_work(struct work_struct *work)
{ … }
void mlxsw_sp_span_respin(struct mlxsw_sp *mlxsw_sp)
{ … }
int mlxsw_sp_span_agent_get(struct mlxsw_sp *mlxsw_sp, int *p_span_id,
const struct mlxsw_sp_span_agent_parms *parms)
{ … }
void mlxsw_sp_span_agent_put(struct mlxsw_sp *mlxsw_sp, int span_id)
{ … }
static struct mlxsw_sp_span_analyzed_port *
mlxsw_sp_span_analyzed_port_create(struct mlxsw_sp_span *span,
struct mlxsw_sp_port *mlxsw_sp_port,
bool ingress)
{ … }
static void
mlxsw_sp_span_analyzed_port_destroy(struct mlxsw_sp_port *mlxsw_sp_port,
struct mlxsw_sp_span_analyzed_port *
analyzed_port)
{ … }
int mlxsw_sp_span_analyzed_port_get(struct mlxsw_sp_port *mlxsw_sp_port,
bool ingress)
{ … }
void mlxsw_sp_span_analyzed_port_put(struct mlxsw_sp_port *mlxsw_sp_port,
bool ingress)
{ … }
static int
__mlxsw_sp_span_trigger_port_bind(struct mlxsw_sp_span *span,
struct mlxsw_sp_span_trigger_entry *
trigger_entry, bool enable)
{ … }
static int
mlxsw_sp_span_trigger_port_bind(struct mlxsw_sp_span_trigger_entry *
trigger_entry)
{ … }
static void
mlxsw_sp_span_trigger_port_unbind(struct mlxsw_sp_span_trigger_entry *
trigger_entry)
{ … }
static bool
mlxsw_sp_span_trigger_port_matches(struct mlxsw_sp_span_trigger_entry *
trigger_entry,
enum mlxsw_sp_span_trigger trigger,
struct mlxsw_sp_port *mlxsw_sp_port)
{ … }
static int
mlxsw_sp_span_trigger_port_enable(struct mlxsw_sp_span_trigger_entry *
trigger_entry,
struct mlxsw_sp_port *mlxsw_sp_port, u8 tc)
{ … }
static void
mlxsw_sp_span_trigger_port_disable(struct mlxsw_sp_span_trigger_entry *
trigger_entry,
struct mlxsw_sp_port *mlxsw_sp_port, u8 tc)
{ … }
static const struct mlxsw_sp_span_trigger_ops
mlxsw_sp_span_trigger_port_ops = …;
static int
mlxsw_sp1_span_trigger_global_bind(struct mlxsw_sp_span_trigger_entry *
trigger_entry)
{ … }
static void
mlxsw_sp1_span_trigger_global_unbind(struct mlxsw_sp_span_trigger_entry *
trigger_entry)
{ … }
static bool
mlxsw_sp1_span_trigger_global_matches(struct mlxsw_sp_span_trigger_entry *
trigger_entry,
enum mlxsw_sp_span_trigger trigger,
struct mlxsw_sp_port *mlxsw_sp_port)
{ … }
static int
mlxsw_sp1_span_trigger_global_enable(struct mlxsw_sp_span_trigger_entry *
trigger_entry,
struct mlxsw_sp_port *mlxsw_sp_port,
u8 tc)
{ … }
static void
mlxsw_sp1_span_trigger_global_disable(struct mlxsw_sp_span_trigger_entry *
trigger_entry,
struct mlxsw_sp_port *mlxsw_sp_port,
u8 tc)
{ … }
static const struct mlxsw_sp_span_trigger_ops
mlxsw_sp1_span_trigger_global_ops = …;
static const struct mlxsw_sp_span_trigger_ops *
mlxsw_sp1_span_trigger_ops_arr[] = …;
static int
mlxsw_sp2_span_trigger_global_bind(struct mlxsw_sp_span_trigger_entry *
trigger_entry)
{ … }
static void
mlxsw_sp2_span_trigger_global_unbind(struct mlxsw_sp_span_trigger_entry *
trigger_entry)
{ … }
static bool
mlxsw_sp2_span_trigger_global_matches(struct mlxsw_sp_span_trigger_entry *
trigger_entry,
enum mlxsw_sp_span_trigger trigger,
struct mlxsw_sp_port *mlxsw_sp_port)
{ … }
static int
__mlxsw_sp2_span_trigger_global_enable(struct mlxsw_sp_span_trigger_entry *
trigger_entry,
struct mlxsw_sp_port *mlxsw_sp_port,
u8 tc, bool enable)
{ … }
static int
mlxsw_sp2_span_trigger_global_enable(struct mlxsw_sp_span_trigger_entry *
trigger_entry,
struct mlxsw_sp_port *mlxsw_sp_port,
u8 tc)
{ … }
static void
mlxsw_sp2_span_trigger_global_disable(struct mlxsw_sp_span_trigger_entry *
trigger_entry,
struct mlxsw_sp_port *mlxsw_sp_port,
u8 tc)
{ … }
static const struct mlxsw_sp_span_trigger_ops
mlxsw_sp2_span_trigger_global_ops = …;
static const struct mlxsw_sp_span_trigger_ops *
mlxsw_sp2_span_trigger_ops_arr[] = …;
static void
mlxsw_sp_span_trigger_ops_set(struct mlxsw_sp_span_trigger_entry *trigger_entry)
{ … }
static struct mlxsw_sp_span_trigger_entry *
mlxsw_sp_span_trigger_entry_create(struct mlxsw_sp_span *span,
enum mlxsw_sp_span_trigger trigger,
struct mlxsw_sp_port *mlxsw_sp_port,
const struct mlxsw_sp_span_trigger_parms
*parms)
{ … }
static void
mlxsw_sp_span_trigger_entry_destroy(struct mlxsw_sp_span *span,
struct mlxsw_sp_span_trigger_entry *
trigger_entry)
{ … }
static struct mlxsw_sp_span_trigger_entry *
mlxsw_sp_span_trigger_entry_find(struct mlxsw_sp_span *span,
enum mlxsw_sp_span_trigger trigger,
struct mlxsw_sp_port *mlxsw_sp_port)
{ … }
int mlxsw_sp_span_agent_bind(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_span_trigger trigger,
struct mlxsw_sp_port *mlxsw_sp_port,
const struct mlxsw_sp_span_trigger_parms *parms)
{ … }
void mlxsw_sp_span_agent_unbind(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_span_trigger trigger,
struct mlxsw_sp_port *mlxsw_sp_port,
const struct mlxsw_sp_span_trigger_parms *parms)
{ … }
int mlxsw_sp_span_trigger_enable(struct mlxsw_sp_port *mlxsw_sp_port,
enum mlxsw_sp_span_trigger trigger, u8 tc)
{ … }
void mlxsw_sp_span_trigger_disable(struct mlxsw_sp_port *mlxsw_sp_port,
enum mlxsw_sp_span_trigger trigger, u8 tc)
{ … }
bool mlxsw_sp_span_trigger_is_ingress(enum mlxsw_sp_span_trigger trigger)
{ … }
static int mlxsw_sp1_span_init(struct mlxsw_sp *mlxsw_sp)
{ … }
static int mlxsw_sp1_span_policer_id_base_set(struct mlxsw_sp *mlxsw_sp,
u16 policer_id_base)
{ … }
const struct mlxsw_sp_span_ops mlxsw_sp1_span_ops = …;
static int mlxsw_sp2_span_init(struct mlxsw_sp *mlxsw_sp)
{ … }
#define MLXSW_SP2_SPAN_EG_MIRROR_BUFFER_FACTOR …
#define MLXSW_SP3_SPAN_EG_MIRROR_BUFFER_FACTOR …
static int mlxsw_sp2_span_policer_id_base_set(struct mlxsw_sp *mlxsw_sp,
u16 policer_id_base)
{ … }
const struct mlxsw_sp_span_ops mlxsw_sp2_span_ops = …;
const struct mlxsw_sp_span_ops mlxsw_sp3_span_ops = …;