OSDN Git Service

net: dsa: sja1105: rely on DSA core tracking of port learning state
authorVladimir Oltean <vladimir.oltean@nxp.com>
Sun, 8 Aug 2021 14:35:26 +0000 (17:35 +0300)
committerDavid S. Miller <davem@davemloft.net>
Sun, 8 Aug 2021 19:56:51 +0000 (20:56 +0100)
Now that DSA keeps track of the port learning state, it becomes
superfluous to keep an additional variable with this information in the
sja1105 driver. Remove it.

The DSA core's learning state is present in struct dsa_port *dp.
To avoid the antipattern where we iterate through a DSA switch's
ports and then call dsa_to_port to obtain the "dp" reference (which is
bad because dsa_to_port iterates through the DSA switch tree once
again), just iterate through the dst->ports and operate on those
directly.

The sja1105 had an extra use of priv->learn_ena on non-user ports. DSA
does not touch the learning state of those ports - drivers are free to
do what they wish on them. Mark that information with a comment in
struct dsa_port and let sja1105 set dp->learning for cascade ports.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/sja1105/sja1105.h
drivers/net/dsa/sja1105/sja1105_main.c
include/net/dsa.h

index 9cd7dbd..2e899c9 100644 (file)
@@ -233,7 +233,6 @@ struct sja1105_private {
        phy_interface_t phy_mode[SJA1105_MAX_NUM_PORTS];
        bool fixed_link[SJA1105_MAX_NUM_PORTS];
        bool vlan_aware;
-       unsigned long learn_ena;
        unsigned long ucast_egress_floods;
        unsigned long bcast_egress_floods;
        const struct sja1105_info *info;
index 241fd25..87e279b 100644 (file)
@@ -176,7 +176,7 @@ static int sja1105_init_mac_settings(struct sja1105_private *priv)
        struct sja1105_mac_config_entry *mac;
        struct dsa_switch *ds = priv->ds;
        struct sja1105_table *table;
-       int i;
+       struct dsa_port *dp;
 
        table = &priv->static_config.tables[BLK_IDX_MAC_CONFIG];
 
@@ -195,8 +195,11 @@ static int sja1105_init_mac_settings(struct sja1105_private *priv)
 
        mac = table->entries;
 
-       for (i = 0; i < ds->num_ports; i++) {
-               mac[i] = default_mac;
+       list_for_each_entry(dp, &ds->dst->ports, list) {
+               if (dp->ds != ds)
+                       continue;
+
+               mac[dp->index] = default_mac;
 
                /* Let sja1105_bridge_stp_state_set() keep address learning
                 * enabled for the DSA ports. CPU ports use software-assisted
@@ -205,8 +208,8 @@ static int sja1105_init_mac_settings(struct sja1105_private *priv)
                 * CPU ports in a cross-chip topology if multiple CPU ports
                 * exist.
                 */
-               if (dsa_is_dsa_port(ds, i))
-                       priv->learn_ena |= BIT(i);
+               if (dsa_port_is_dsa(dp))
+                       dp->learning = true;
        }
 
        return 0;
@@ -1899,6 +1902,7 @@ static int sja1105_bridge_member(struct dsa_switch *ds, int port,
 static void sja1105_bridge_stp_state_set(struct dsa_switch *ds, int port,
                                         u8 state)
 {
+       struct dsa_port *dp = dsa_to_port(ds, port);
        struct sja1105_private *priv = ds->priv;
        struct sja1105_mac_config_entry *mac;
 
@@ -1924,12 +1928,12 @@ static void sja1105_bridge_stp_state_set(struct dsa_switch *ds, int port,
        case BR_STATE_LEARNING:
                mac[port].ingress   = true;
                mac[port].egress    = false;
-               mac[port].dyn_learn = !!(priv->learn_ena & BIT(port));
+               mac[port].dyn_learn = dp->learning;
                break;
        case BR_STATE_FORWARDING:
                mac[port].ingress   = true;
                mac[port].egress    = true;
-               mac[port].dyn_learn = !!(priv->learn_ena & BIT(port));
+               mac[port].dyn_learn = dp->learning;
                break;
        default:
                dev_err(ds->dev, "invalid STP state: %d\n", state);
@@ -2891,23 +2895,13 @@ static int sja1105_port_set_learning(struct sja1105_private *priv, int port,
                                     bool enabled)
 {
        struct sja1105_mac_config_entry *mac;
-       int rc;
 
        mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
 
        mac[port].dyn_learn = enabled;
 
-       rc = sja1105_dynamic_config_write(priv, BLK_IDX_MAC_CONFIG, port,
-                                         &mac[port], true);
-       if (rc)
-               return rc;
-
-       if (enabled)
-               priv->learn_ena |= BIT(port);
-       else
-               priv->learn_ena &= ~BIT(port);
-
-       return 0;
+       return sja1105_dynamic_config_write(priv, BLK_IDX_MAC_CONFIG, port,
+                                           &mac[port], true);
 }
 
 static int sja1105_port_ucast_bcast_flood(struct sja1105_private *priv, int to,
index 995e9d3..0c2cba4 100644 (file)
@@ -254,6 +254,7 @@ struct dsa_port {
        struct device_node      *dn;
        unsigned int            ageing_time;
        bool                    vlan_filtering;
+       /* Managed by DSA on user ports and by drivers on CPU and DSA ports */
        bool                    learning;
        u8                      stp_state;
        struct net_device       *bridge_dev;