mlxsw: spectrum_trap: Register layer 2 control traps
authorIdo Schimmel <idosch@mellanox.com>
Fri, 29 May 2020 18:36:46 +0000 (21:36 +0300)
committerDavid S. Miller <davem@davemloft.net>
Mon, 1 Jun 2020 18:49:23 +0000 (11:49 -0700)
In a similar fashion to other traps, register layer 2 control traps with
devlink.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/mellanox/mlxsw/spectrum.h
drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c

index c598ae9ed1061f8e6775fe017d858cc6006e3de0..74925826a2cb17898f86c360fcdfdaab4da5479a 100644 (file)
@@ -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:
index 147a5634244ba596e502d242afe2a8380dbaae83..9d4dfb22cb7ac31d0421dfc1530f0da51878c0e1 100644 (file)
@@ -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,
index 206751963a4f0a13e6916b613f008647d68ac59b..32b77d5a917d91b0c7c457cf0203996d65f7187a 100644 (file)
@@ -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 *