net: dsa: bcm_sf2: Allow looping back CFP rules
authorFlorian Fainelli <f.fainelli@gmail.com>
Wed, 6 Feb 2019 20:46:00 +0000 (12:46 -0800)
committerDavid S. Miller <davem@davemloft.net>
Sat, 9 Feb 2019 06:11:07 +0000 (22:11 -0800)
When the source and destination port of a CFP rule match, we must set
the loopback bit enable to allow that, otherwise the frame is discarded.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/bcm_sf2_cfp.c

index 8747d18297fa369041552044381e230ffa8bc7d9..0b9ca4bdf47ea844b9a7e12e6b22686712e0ac6b 100644 (file)
@@ -213,6 +213,7 @@ static inline unsigned int bcm_sf2_cfp_rule_size(struct bcm_sf2_priv *priv)
 
 static int bcm_sf2_cfp_act_pol_set(struct bcm_sf2_priv *priv,
                                   unsigned int rule_index,
+                                  int src_port,
                                   unsigned int port_num,
                                   unsigned int queue_num,
                                   bool fwd_map_change)
@@ -230,6 +231,10 @@ static int bcm_sf2_cfp_act_pol_set(struct bcm_sf2_priv *priv,
        else
                reg = 0;
 
+       /* Enable looping back to the original port */
+       if (src_port == port_num)
+               reg |= LOOP_BK_EN;
+
        core_writel(priv, reg, CORE_ACT_POL_DATA0);
 
        /* Set classification ID that needs to be put in Broadcom tag */
@@ -443,7 +448,7 @@ static int bcm_sf2_cfp_ipv4_rule_set(struct bcm_sf2_priv *priv, int port,
        }
 
        /* Insert into Action and policer RAMs now */
-       ret = bcm_sf2_cfp_act_pol_set(priv, rule_index, port_num,
+       ret = bcm_sf2_cfp_act_pol_set(priv, rule_index, port, port_num,
                                      queue_num, true);
        if (ret)
                goto out_err_flow_rule;
@@ -733,7 +738,7 @@ static int bcm_sf2_cfp_ipv6_rule_set(struct bcm_sf2_priv *priv, int port,
        }
 
        /* Insert into Action and policer RAMs now */
-       ret = bcm_sf2_cfp_act_pol_set(priv, rule_index[0], port_num,
+       ret = bcm_sf2_cfp_act_pol_set(priv, rule_index[0], port, port_num,
                                      queue_num, false);
        if (ret)
                goto out_err_flow_rule;
@@ -795,7 +800,7 @@ static int bcm_sf2_cfp_ipv6_rule_set(struct bcm_sf2_priv *priv, int port,
        /* Insert into Action and policer RAMs now, set chain ID to
         * the one we are chained to
         */
-       ret = bcm_sf2_cfp_act_pol_set(priv, rule_index[1], port_num,
+       ret = bcm_sf2_cfp_act_pol_set(priv, rule_index[1], port, port_num,
                                      queue_num, true);
        if (ret)
                goto out_err_flow_rule;