net: dsa: mv88e6xxx: protect FID registers access
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>
Thu, 31 Mar 2016 20:53:42 +0000 (16:53 -0400)
committerDavid S. Miller <davem@davemloft.net>
Tue, 5 Apr 2016 01:31:35 +0000 (21:31 -0400)
Only switch families with 4096 address databases have dedicated FID
registers for ATU and VTU operations.

Factorize the access to the GLOBAL_ATU_FID register and introduce a
mv88e6xxx_has_fid_reg() helper function to protect the access to
GLOBAL_ATU_FID and GLOBAL_VTU_FID.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/mv88e6xxx.c

index 29b2444..ebb9ae9 100644 (file)
@@ -482,6 +482,16 @@ static bool mv88e6xxx_6352_family(struct dsa_switch *ds)
        return false;
 }
 
+static bool mv88e6xxx_has_fid_reg(struct dsa_switch *ds)
+{
+       /* Does the device have dedicated FID registers for ATU and VTU ops? */
+       if (mv88e6xxx_6097_family(ds) || mv88e6xxx_6165_family(ds) ||
+           mv88e6xxx_6351_family(ds) || mv88e6xxx_6352_family(ds))
+               return true;
+
+       return false;
+}
+
 static bool mv88e6xxx_has_stu(struct dsa_switch *ds)
 {
        /* Does the device have STU and dedicated SID registers for VTU ops? */
@@ -961,10 +971,16 @@ out:
        return ret;
 }
 
-static int _mv88e6xxx_atu_cmd(struct dsa_switch *ds, u16 cmd)
+static int _mv88e6xxx_atu_cmd(struct dsa_switch *ds, u16 fid, u16 cmd)
 {
        int ret;
 
+       if (mv88e6xxx_has_fid_reg(ds)) {
+               ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_FID, fid);
+               if (ret < 0)
+                       return ret;
+       }
+
        ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_OP, cmd);
        if (ret < 0)
                return ret;
@@ -1011,11 +1027,6 @@ static int _mv88e6xxx_atu_flush_move(struct dsa_switch *ds,
                return err;
 
        if (entry->fid) {
-               err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_FID,
-                                          entry->fid);
-               if (err)
-                       return err;
-
                op = static_too ? GLOBAL_ATU_OP_FLUSH_MOVE_ALL_DB :
                        GLOBAL_ATU_OP_FLUSH_MOVE_NON_STATIC_DB;
        } else {
@@ -1023,7 +1034,7 @@ static int _mv88e6xxx_atu_flush_move(struct dsa_switch *ds,
                        GLOBAL_ATU_OP_FLUSH_MOVE_NON_STATIC;
        }
 
-       return _mv88e6xxx_atu_cmd(ds, op);
+       return _mv88e6xxx_atu_cmd(ds, entry->fid, op);
 }
 
 static int _mv88e6xxx_atu_flush(struct dsa_switch *ds, u16 fid, bool static_too)
@@ -1331,8 +1342,7 @@ static int _mv88e6xxx_vtu_getnext(struct dsa_switch *ds,
                if (ret < 0)
                        return ret;
 
-               if (mv88e6xxx_6097_family(ds) || mv88e6xxx_6165_family(ds) ||
-                   mv88e6xxx_6351_family(ds) || mv88e6xxx_6352_family(ds)) {
+               if (mv88e6xxx_has_fid_reg(ds)) {
                        ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL,
                                                  GLOBAL_VTU_FID);
                        if (ret < 0)
@@ -1429,7 +1439,9 @@ static int _mv88e6xxx_vtu_loadpurge(struct dsa_switch *ds,
                ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_VTU_SID, reg);
                if (ret < 0)
                        return ret;
+       }
 
+       if (mv88e6xxx_has_fid_reg(ds)) {
                reg = entry->fid & GLOBAL_VTU_FID_MASK;
                ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_VTU_FID, reg);
                if (ret < 0)
@@ -1976,11 +1988,7 @@ static int _mv88e6xxx_atu_load(struct dsa_switch *ds,
        if (ret < 0)
                return ret;
 
-       ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_FID, entry->fid);
-       if (ret < 0)
-               return ret;
-
-       return _mv88e6xxx_atu_cmd(ds, GLOBAL_ATU_OP_LOAD_DB);
+       return _mv88e6xxx_atu_cmd(ds, entry->fid, GLOBAL_ATU_OP_LOAD_DB);
 }
 
 static int _mv88e6xxx_port_fdb_load(struct dsa_switch *ds, int port,
@@ -2063,11 +2071,7 @@ static int _mv88e6xxx_atu_getnext(struct dsa_switch *ds, u16 fid,
        if (ret < 0)
                return ret;
 
-       ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_FID, fid);
-       if (ret < 0)
-               return ret;
-
-       ret = _mv88e6xxx_atu_cmd(ds, GLOBAL_ATU_OP_GET_NEXT_DB);
+       ret = _mv88e6xxx_atu_cmd(ds, fid, GLOBAL_ATU_OP_GET_NEXT_DB);
        if (ret < 0)
                return ret;