Merge branch 'mhi-net-immutable' of https://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / net / dsa / microchip / ksz9477.c
index 42e647b..00e38c8 100644 (file)
@@ -493,14 +493,10 @@ static void ksz9477_flush_dyn_mac_table(struct ksz_device *dev, int port)
 }
 
 static int ksz9477_port_vlan_filtering(struct dsa_switch *ds, int port,
-                                      bool flag,
-                                      struct switchdev_trans *trans)
+                                      bool flag)
 {
        struct ksz_device *dev = ds->priv;
 
-       if (switchdev_trans_ph_prepare(trans))
-               return 0;
-
        if (flag) {
                ksz_port_cfg(dev, port, REG_PORT_LUE_CTRL,
                             PORT_VLAN_LOOKUP_VID_0, true);
@@ -514,38 +510,40 @@ static int ksz9477_port_vlan_filtering(struct dsa_switch *ds, int port,
        return 0;
 }
 
-static void ksz9477_port_vlan_add(struct dsa_switch *ds, int port,
-                                 const struct switchdev_obj_port_vlan *vlan)
+static int ksz9477_port_vlan_add(struct dsa_switch *ds, int port,
+                                const struct switchdev_obj_port_vlan *vlan)
 {
        struct ksz_device *dev = ds->priv;
        u32 vlan_table[3];
-       u16 vid;
        bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
+       int err;
 
-       for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) {
-               if (ksz9477_get_vlan_table(dev, vid, vlan_table)) {
-                       dev_dbg(dev->dev, "Failed to get vlan table\n");
-                       return;
-               }
-
-               vlan_table[0] = VLAN_VALID | (vid & VLAN_FID_M);
-               if (untagged)
-                       vlan_table[1] |= BIT(port);
-               else
-                       vlan_table[1] &= ~BIT(port);
-               vlan_table[1] &= ~(BIT(dev->cpu_port));
+       err = ksz9477_get_vlan_table(dev, vlan->vid, vlan_table);
+       if (err) {
+               dev_dbg(dev->dev, "Failed to get vlan table\n");
+               return err;
+       }
 
-               vlan_table[2] |= BIT(port) | BIT(dev->cpu_port);
+       vlan_table[0] = VLAN_VALID | (vlan->vid & VLAN_FID_M);
+       if (untagged)
+               vlan_table[1] |= BIT(port);
+       else
+               vlan_table[1] &= ~BIT(port);
+       vlan_table[1] &= ~(BIT(dev->cpu_port));
 
-               if (ksz9477_set_vlan_table(dev, vid, vlan_table)) {
-                       dev_dbg(dev->dev, "Failed to set vlan table\n");
-                       return;
-               }
+       vlan_table[2] |= BIT(port) | BIT(dev->cpu_port);
 
-               /* change PVID */
-               if (vlan->flags & BRIDGE_VLAN_INFO_PVID)
-                       ksz_pwrite16(dev, port, REG_PORT_DEFAULT_VID, vid);
+       err = ksz9477_set_vlan_table(dev, vlan->vid, vlan_table);
+       if (err) {
+               dev_dbg(dev->dev, "Failed to set vlan table\n");
+               return err;
        }
+
+       /* change PVID */
+       if (vlan->flags & BRIDGE_VLAN_INFO_PVID)
+               ksz_pwrite16(dev, port, REG_PORT_DEFAULT_VID, vlan->vid);
+
+       return 0;
 }
 
 static int ksz9477_port_vlan_del(struct dsa_switch *ds, int port,
@@ -554,30 +552,27 @@ static int ksz9477_port_vlan_del(struct dsa_switch *ds, int port,
        struct ksz_device *dev = ds->priv;
        bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
        u32 vlan_table[3];
-       u16 vid;
        u16 pvid;
 
        ksz_pread16(dev, port, REG_PORT_DEFAULT_VID, &pvid);
        pvid = pvid & 0xFFF;
 
-       for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) {
-               if (ksz9477_get_vlan_table(dev, vid, vlan_table)) {
-                       dev_dbg(dev->dev, "Failed to get vlan table\n");
-                       return -ETIMEDOUT;
-               }
+       if (ksz9477_get_vlan_table(dev, vlan->vid, vlan_table)) {
+               dev_dbg(dev->dev, "Failed to get vlan table\n");
+               return -ETIMEDOUT;
+       }
 
-               vlan_table[2] &= ~BIT(port);
+       vlan_table[2] &= ~BIT(port);
 
-               if (pvid == vid)
-                       pvid = 1;
+       if (pvid == vlan->vid)
+               pvid = 1;
 
-               if (untagged)
-                       vlan_table[1] &= ~BIT(port);
+       if (untagged)
+               vlan_table[1] &= ~BIT(port);
 
-               if (ksz9477_set_vlan_table(dev, vid, vlan_table)) {
-                       dev_dbg(dev->dev, "Failed to set vlan table\n");
-                       return -ETIMEDOUT;
-               }
+       if (ksz9477_set_vlan_table(dev, vlan->vid, vlan_table)) {
+               dev_dbg(dev->dev, "Failed to set vlan table\n");
+               return -ETIMEDOUT;
        }
 
        ksz_pwrite16(dev, port, REG_PORT_DEFAULT_VID, pvid);
@@ -784,14 +779,15 @@ exit:
        return ret;
 }
 
-static void ksz9477_port_mdb_add(struct dsa_switch *ds, int port,
-                                const struct switchdev_obj_port_mdb *mdb)
+static int ksz9477_port_mdb_add(struct dsa_switch *ds, int port,
+                               const struct switchdev_obj_port_mdb *mdb)
 {
        struct ksz_device *dev = ds->priv;
        u32 static_table[4];
        u32 data;
        int index;
        u32 mac_hi, mac_lo;
+       int err = 0;
 
        mac_hi = ((mdb->addr[0] << 8) | mdb->addr[1]);
        mac_lo = ((mdb->addr[2] << 24) | (mdb->addr[3] << 16));
@@ -806,7 +802,8 @@ static void ksz9477_port_mdb_add(struct dsa_switch *ds, int port,
                ksz_write32(dev, REG_SW_ALU_STAT_CTRL__4, data);
 
                /* wait to be finished */
-               if (ksz9477_wait_alu_sta_ready(dev)) {
+               err = ksz9477_wait_alu_sta_ready(dev);
+               if (err) {
                        dev_dbg(dev->dev, "Failed to read ALU STATIC\n");
                        goto exit;
                }
@@ -829,8 +826,10 @@ static void ksz9477_port_mdb_add(struct dsa_switch *ds, int port,
        }
 
        /* no available entry */
-       if (index == dev->num_statics)
+       if (index == dev->num_statics) {
+               err = -ENOSPC;
                goto exit;
+       }
 
        /* add entry */
        static_table[0] = ALU_V_STATIC_VALID;
@@ -852,6 +851,7 @@ static void ksz9477_port_mdb_add(struct dsa_switch *ds, int port,
 
 exit:
        mutex_unlock(&dev->alu_mutex);
+       return err;
 }
 
 static int ksz9477_port_mdb_del(struct dsa_switch *ds, int port,
@@ -1381,6 +1381,8 @@ static int ksz9477_setup(struct dsa_switch *ds)
 
        ksz_init_mib_timer(dev);
 
+       ds->configure_vlan_while_not_filtering = false;
+
        return 0;
 }
 
@@ -1399,13 +1401,11 @@ static const struct dsa_switch_ops ksz9477_switch_ops = {
        .port_stp_state_set     = ksz9477_port_stp_state_set,
        .port_fast_age          = ksz_port_fast_age,
        .port_vlan_filtering    = ksz9477_port_vlan_filtering,
-       .port_vlan_prepare      = ksz_port_vlan_prepare,
        .port_vlan_add          = ksz9477_port_vlan_add,
        .port_vlan_del          = ksz9477_port_vlan_del,
        .port_fdb_dump          = ksz9477_port_fdb_dump,
        .port_fdb_add           = ksz9477_port_fdb_add,
        .port_fdb_del           = ksz9477_port_fdb_del,
-       .port_mdb_prepare       = ksz_port_mdb_prepare,
        .port_mdb_add           = ksz9477_port_mdb_add,
        .port_mdb_del           = ksz9477_port_mdb_del,
        .port_mirror_add        = ksz9477_port_mirror_add,