Commit 39c10350 authored by Ido Schimmel's avatar Ido Schimmel Committed by David S. Miller
Browse files

mlxsw: spectrum_trap: Register layer 2 control traps



In a similar fashion to other traps, register layer 2 control traps with
devlink.

Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Reviewed-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 45b1c873
Loading
Loading
Loading
Loading
+6 −31
Original line number Diff line number Diff line
@@ -4022,6 +4022,12 @@ static void mlxsw_sp_rx_listener_ptp(struct sk_buff *skb, u8 local_port,
	mlxsw_sp->ptp_ops->receive(mlxsw_sp, skb, local_port);
}

void mlxsw_sp_ptp_receive(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
			  u8 local_port)
{
	mlxsw_sp->ptp_ops->receive(mlxsw_sp, skb, local_port);
}

#define MLXSW_SP_RXL_NO_MARK(_trap_id, _action, _trap_group, _is_ctrl)	\
	MLXSW_RXL(mlxsw_sp_rx_listener_no_mark_func, _trap_id, _action,	\
		  _is_ctrl, SP_##_trap_group, DISCARD)
@@ -4041,26 +4047,9 @@ static const struct mlxsw_listener mlxsw_sp_listener[] = {
	/* Events */
	MLXSW_SP_EVENTL(mlxsw_sp_pude_event_func, PUDE),
	/* L2 traps */
	MLXSW_SP_RXL_NO_MARK(STP, TRAP_TO_CPU, STP, true),
	MLXSW_SP_RXL_NO_MARK(LACP, TRAP_TO_CPU, LACP, true),
	MLXSW_RXL(mlxsw_sp_rx_listener_ptp, LLDP, TRAP_TO_CPU,
		  false, SP_LLDP, DISCARD),
	MLXSW_SP_RXL_MARK(IGMP_QUERY, MIRROR_TO_CPU, MC_SNOOPING, false),
	MLXSW_SP_RXL_NO_MARK(IGMP_V1_REPORT, TRAP_TO_CPU, MC_SNOOPING, false),
	MLXSW_SP_RXL_NO_MARK(IGMP_V2_REPORT, TRAP_TO_CPU, MC_SNOOPING, false),
	MLXSW_SP_RXL_NO_MARK(IGMP_V2_LEAVE, TRAP_TO_CPU, MC_SNOOPING, false),
	MLXSW_SP_RXL_NO_MARK(IGMP_V3_REPORT, TRAP_TO_CPU, MC_SNOOPING, false),
	MLXSW_SP_RXL_MARK(ARPBC, MIRROR_TO_CPU, NEIGH_DISCOVERY, false),
	MLXSW_SP_RXL_MARK(ARPUC, MIRROR_TO_CPU, NEIGH_DISCOVERY, false),
	MLXSW_SP_RXL_NO_MARK(FID_MISS, TRAP_TO_CPU, FID_MISS, false),
	MLXSW_SP_RXL_MARK(IPV6_MLDV12_LISTENER_QUERY, MIRROR_TO_CPU,
			  MC_SNOOPING, false),
	MLXSW_SP_RXL_NO_MARK(IPV6_MLDV1_LISTENER_REPORT, TRAP_TO_CPU,
			     MC_SNOOPING, false),
	MLXSW_SP_RXL_NO_MARK(IPV6_MLDV1_LISTENER_DONE, TRAP_TO_CPU, MC_SNOOPING,
			     false),
	MLXSW_SP_RXL_NO_MARK(IPV6_MLDV2_LISTENER_REPORT, TRAP_TO_CPU,
			     MC_SNOOPING, false),
	/* L3 traps */
	MLXSW_SP_RXL_L3_MARK(LBERROR, MIRROR_TO_CPU, LBERROR, false),
	MLXSW_SP_RXL_MARK(IP2ME, TRAP_TO_CPU, IP2ME, false),
@@ -4149,9 +4138,6 @@ static int mlxsw_sp_cpu_policers_set(struct mlxsw_core *mlxsw_core)
	for (i = 0; i < max_cpu_policers; i++) {
		is_bytes = false;
		switch (i) {
		case MLXSW_REG_HTGT_TRAP_GROUP_SP_STP:
		case MLXSW_REG_HTGT_TRAP_GROUP_SP_LACP:
		case MLXSW_REG_HTGT_TRAP_GROUP_SP_LLDP:
		case MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF:
		case MLXSW_REG_HTGT_TRAP_GROUP_SP_PIM:
		case MLXSW_REG_HTGT_TRAP_GROUP_SP_LBERROR:
@@ -4159,10 +4145,6 @@ static int mlxsw_sp_cpu_policers_set(struct mlxsw_core *mlxsw_core)
			rate = 128;
			burst_size = 7;
			break;
		case MLXSW_REG_HTGT_TRAP_GROUP_SP_MC_SNOOPING:
			rate = 16 * 1024;
			burst_size = 10;
			break;
		case MLXSW_REG_HTGT_TRAP_GROUP_SP_BGP:
		case MLXSW_REG_HTGT_TRAP_GROUP_SP_NEIGH_DISCOVERY:
		case MLXSW_REG_HTGT_TRAP_GROUP_SP_ROUTER_EXP:
@@ -4225,9 +4207,6 @@ static int mlxsw_sp_trap_groups_set(struct mlxsw_core *mlxsw_core)
	for (i = 0; i < max_trap_groups; i++) {
		policer_id = i;
		switch (i) {
		case MLXSW_REG_HTGT_TRAP_GROUP_SP_STP:
		case MLXSW_REG_HTGT_TRAP_GROUP_SP_LACP:
		case MLXSW_REG_HTGT_TRAP_GROUP_SP_LLDP:
		case MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF:
		case MLXSW_REG_HTGT_TRAP_GROUP_SP_PIM:
		case MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP0:
@@ -4241,10 +4220,6 @@ static int mlxsw_sp_trap_groups_set(struct mlxsw_core *mlxsw_core)
			priority = 4;
			tc = 4;
			break;
		case MLXSW_REG_HTGT_TRAP_GROUP_SP_MC_SNOOPING:
			priority = 3;
			tc = 3;
			break;
		case MLXSW_REG_HTGT_TRAP_GROUP_SP_NEIGH_DISCOVERY:
		case MLXSW_REG_HTGT_TRAP_GROUP_SP_IP2ME:
		case MLXSW_REG_HTGT_TRAP_GROUP_SP_IPV6:
+2 −0
Original line number Diff line number Diff line
@@ -451,6 +451,8 @@ extern struct notifier_block mlxsw_sp_switchdev_notifier;
/* spectrum.c */
void mlxsw_sp_rx_listener_no_mark_func(struct sk_buff *skb,
				       u8 local_port, void *priv);
void mlxsw_sp_ptp_receive(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
			  u8 local_port);
int mlxsw_sp_port_speed_get(struct mlxsw_sp_port *mlxsw_sp_port, u32 *speed);
int mlxsw_sp_port_ets_set(struct mlxsw_sp_port *mlxsw_sp_port,
			  enum mlxsw_reg_qeec_hr hr, u8 index, u8 next_index,
+151 −0
Original line number Diff line number Diff line
@@ -170,6 +170,23 @@ static void mlxsw_sp_rx_mark_listener(struct sk_buff *skb, u8 local_port,
	mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx);
}

static void mlxsw_sp_rx_ptp_listener(struct sk_buff *skb, u8 local_port,
				     void *trap_ctx)
{
	struct mlxsw_sp *mlxsw_sp = devlink_trap_ctx_priv(trap_ctx);
	int err;

	err = __mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx);
	if (err)
		return;

	/* The PTP handler expects skb->data to point to the start of the
	 * Ethernet header.
	 */
	skb_push(skb, ETH_HLEN);
	mlxsw_sp_ptp_receive(mlxsw_sp, skb, local_port);
}

#define MLXSW_SP_TRAP_DROP(_id, _group_id)				      \
	DEVLINK_TRAP_GENERIC(DROP, DROP, _id,				      \
			     DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,	      \
@@ -191,6 +208,11 @@ static void mlxsw_sp_rx_mark_listener(struct sk_buff *skb, u8 local_port,
			     DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,	      \
			     MLXSW_SP_TRAP_METADATA)

#define MLXSW_SP_TRAP_CONTROL(_id, _group_id, _action)			      \
	DEVLINK_TRAP_GENERIC(CONTROL, _action, _id,			      \
			     DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,	      \
			     MLXSW_SP_TRAP_METADATA)

#define MLXSW_SP_RXL_DISCARD(_id, _group_id)				      \
	MLXSW_RXL_DIS(mlxsw_sp_rx_drop_listener, DISCARD_##_id,		      \
		      TRAP_EXCEPTION_TO_CPU, false, SP_##_group_id,	      \
@@ -205,6 +227,14 @@ static void mlxsw_sp_rx_mark_listener(struct sk_buff *skb, u8 local_port,
	MLXSW_RXL(mlxsw_sp_rx_mark_listener, _id,			      \
		   _action, false, SP_##_group_id, SET_FW_DEFAULT)

#define MLXSW_SP_RXL_NO_MARK(_id, _group_id, _action, _is_ctrl)		      \
	MLXSW_RXL(mlxsw_sp_rx_no_mark_listener, _id, _action,		      \
		  _is_ctrl, SP_##_group_id, DISCARD)

#define MLXSW_SP_RXL_MARK(_id, _group_id, _action, _is_ctrl)		      \
	MLXSW_RXL(mlxsw_sp_rx_mark_listener, _id, _action, _is_ctrl,	      \
		  SP_##_group_id, DISCARD)

#define MLXSW_SP_TRAP_POLICER(_id, _rate, _burst)			      \
	DEVLINK_TRAP_POLICER(_id, _rate, _burst,			      \
			     MLXSW_REG_QPCR_HIGHEST_CIR,		      \
@@ -218,6 +248,18 @@ mlxsw_sp_trap_policer_items_arr[] = {
	{
		.policer = MLXSW_SP_TRAP_POLICER(1, 10 * 1024, 128),
	},
	{
		.policer = MLXSW_SP_TRAP_POLICER(2, 128, 128),
	},
	{
		.policer = MLXSW_SP_TRAP_POLICER(3, 128, 128),
	},
	{
		.policer = MLXSW_SP_TRAP_POLICER(4, 128, 128),
	},
	{
		.policer = MLXSW_SP_TRAP_POLICER(5, 16 * 1024, 128),
	},
};

static const struct mlxsw_sp_trap_group_item mlxsw_sp_trap_group_items_arr[] = {
@@ -246,6 +288,26 @@ static const struct mlxsw_sp_trap_group_item mlxsw_sp_trap_group_items_arr[] = {
		.hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_ACL_DISCARDS,
		.priority = 0,
	},
	{
		.group = DEVLINK_TRAP_GROUP_GENERIC(STP, 2),
		.hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_STP,
		.priority = 5,
	},
	{
		.group = DEVLINK_TRAP_GROUP_GENERIC(LACP, 3),
		.hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_LACP,
		.priority = 5,
	},
	{
		.group = DEVLINK_TRAP_GROUP_GENERIC(LLDP, 4),
		.hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_LLDP,
		.priority = 5,
	},
	{
		.group = DEVLINK_TRAP_GROUP_GENERIC(MC_SNOOPING, 5),
		.hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_MC_SNOOPING,
		.priority = 3,
	},
};

static const struct mlxsw_sp_trap_item mlxsw_sp_trap_items_arr[] = {
@@ -466,6 +528,95 @@ static const struct mlxsw_sp_trap_item mlxsw_sp_trap_items_arr[] = {
						 DUMMY),
		},
	},
	{
		.trap = MLXSW_SP_TRAP_CONTROL(STP, STP, TRAP),
		.listeners_arr = {
			MLXSW_SP_RXL_NO_MARK(STP, STP, TRAP_TO_CPU, true),
		},
	},
	{
		.trap = MLXSW_SP_TRAP_CONTROL(LACP, LACP, TRAP),
		.listeners_arr = {
			MLXSW_SP_RXL_NO_MARK(LACP, LACP, TRAP_TO_CPU, true),
		},
	},
	{
		.trap = MLXSW_SP_TRAP_CONTROL(LLDP, LLDP, TRAP),
		.listeners_arr = {
			MLXSW_RXL(mlxsw_sp_rx_ptp_listener, LLDP, TRAP_TO_CPU,
				  false, SP_LLDP, DISCARD),
		},
	},
	{
		.trap = MLXSW_SP_TRAP_CONTROL(IGMP_QUERY, MC_SNOOPING, MIRROR),
		.listeners_arr = {
			MLXSW_SP_RXL_MARK(IGMP_QUERY, MC_SNOOPING,
					  MIRROR_TO_CPU, false),
		},
	},
	{
		.trap = MLXSW_SP_TRAP_CONTROL(IGMP_V1_REPORT, MC_SNOOPING,
					      TRAP),
		.listeners_arr = {
			MLXSW_SP_RXL_NO_MARK(IGMP_V1_REPORT, MC_SNOOPING,
					     TRAP_TO_CPU, false),
		},
	},
	{
		.trap = MLXSW_SP_TRAP_CONTROL(IGMP_V2_REPORT, MC_SNOOPING,
					      TRAP),
		.listeners_arr = {
			MLXSW_SP_RXL_NO_MARK(IGMP_V2_REPORT, MC_SNOOPING,
					     TRAP_TO_CPU, false),
		},
	},
	{
		.trap = MLXSW_SP_TRAP_CONTROL(IGMP_V3_REPORT, MC_SNOOPING,
					      TRAP),
		.listeners_arr = {
			MLXSW_SP_RXL_NO_MARK(IGMP_V3_REPORT, MC_SNOOPING,
					     TRAP_TO_CPU, false),
		},
	},
	{
		.trap = MLXSW_SP_TRAP_CONTROL(IGMP_V2_LEAVE, MC_SNOOPING,
					      TRAP),
		.listeners_arr = {
			MLXSW_SP_RXL_NO_MARK(IGMP_V2_LEAVE, MC_SNOOPING,
					     TRAP_TO_CPU, false),
		},
	},
	{
		.trap = MLXSW_SP_TRAP_CONTROL(MLD_QUERY, MC_SNOOPING, MIRROR),
		.listeners_arr = {
			MLXSW_SP_RXL_MARK(IPV6_MLDV12_LISTENER_QUERY,
					  MC_SNOOPING, MIRROR_TO_CPU, false),
		},
	},
	{
		.trap = MLXSW_SP_TRAP_CONTROL(MLD_V1_REPORT, MC_SNOOPING,
					      TRAP),
		.listeners_arr = {
			MLXSW_SP_RXL_NO_MARK(IPV6_MLDV1_LISTENER_REPORT,
					     MC_SNOOPING, TRAP_TO_CPU, false),
		},
	},
	{
		.trap = MLXSW_SP_TRAP_CONTROL(MLD_V2_REPORT, MC_SNOOPING,
					      TRAP),
		.listeners_arr = {
			MLXSW_SP_RXL_NO_MARK(IPV6_MLDV2_LISTENER_REPORT,
					     MC_SNOOPING, TRAP_TO_CPU, false),
		},
	},
	{
		.trap = MLXSW_SP_TRAP_CONTROL(MLD_V1_DONE, MC_SNOOPING,
					      TRAP),
		.listeners_arr = {
			MLXSW_SP_RXL_NO_MARK(IPV6_MLDV1_LISTENER_DONE,
					     MC_SNOOPING, TRAP_TO_CPU, false),
		},
	},
};

static struct mlxsw_sp_trap_policer_item *