return b53_arl_rw_op(dev, 0);
 }
 
-int b53_fdb_prepare(struct dsa_switch *ds, int port,
-                   const unsigned char *addr, u16 vid)
+int b53_fdb_add(struct dsa_switch *ds, int port,
+               const unsigned char *addr, u16 vid)
 {
        struct b53_device *priv = ds->priv;
 
        if (is5325(priv) || is5365(priv))
                return -EOPNOTSUPP;
 
-       return 0;
-}
-EXPORT_SYMBOL(b53_fdb_prepare);
-
-void b53_fdb_add(struct dsa_switch *ds, int port,
-                const unsigned char *addr, u16 vid)
-{
-       struct b53_device *priv = ds->priv;
-
-       if (b53_arl_op(priv, 0, port, addr, vid, true))
-               pr_err("%s: failed to add MAC address\n", __func__);
+       return b53_arl_op(priv, 0, port, addr, vid, true);
 }
 EXPORT_SYMBOL(b53_fdb_add);
 
        .port_vlan_add          = b53_vlan_add,
        .port_vlan_del          = b53_vlan_del,
        .port_vlan_dump         = b53_vlan_dump,
-       .port_fdb_prepare       = b53_fdb_prepare,
        .port_fdb_dump          = b53_fdb_dump,
        .port_fdb_add           = b53_fdb_add,
        .port_fdb_del           = b53_fdb_del,
 
 int b53_vlan_dump(struct dsa_switch *ds, int port,
                  struct switchdev_obj_port_vlan *vlan,
                  switchdev_obj_dump_cb_t *cb);
-int b53_fdb_prepare(struct dsa_switch *ds, int port,
-                   const unsigned char *addr, u16 vid);
-void b53_fdb_add(struct dsa_switch *ds, int port,
-                const unsigned char *addr, u16 vid);
+int b53_fdb_add(struct dsa_switch *ds, int port,
+               const unsigned char *addr, u16 vid);
 int b53_fdb_del(struct dsa_switch *ds, int port,
                const unsigned char *addr, u16 vid);
 int b53_fdb_dump(struct dsa_switch *ds, int port,
 
        .port_vlan_add          = b53_vlan_add,
        .port_vlan_del          = b53_vlan_del,
        .port_vlan_dump         = b53_vlan_dump,
-       .port_fdb_prepare       = b53_fdb_prepare,
        .port_fdb_dump          = b53_fdb_dump,
        .port_fdb_add           = b53_fdb_add,
        .port_fdb_del           = b53_fdb_del,
 
        return err;
 }
 
-static int ksz_port_fdb_prepare(struct dsa_switch *ds, int port,
-                               const unsigned char *addr, u16 vid)
-{
-       /* nothing needed */
-
-       return 0;
-}
-
 struct alu_struct {
        /* entry 1 */
        u8      is_static:1;
        u8      mac[ETH_ALEN];
 };
 
-static void ksz_port_fdb_add(struct dsa_switch *ds, int port,
-                            const unsigned char *addr, u16 vid)
+static int ksz_port_fdb_add(struct dsa_switch *ds, int port,
+                           const unsigned char *addr, u16 vid)
 {
        struct ksz_device *dev = ds->priv;
        u32 alu_table[4];
        u32 data;
+       int ret = 0;
 
        mutex_lock(&dev->alu_mutex);
 
        ksz_write32(dev, REG_SW_ALU_CTRL__4, ALU_READ | ALU_START);
 
        /* wait to be finished */
-       if (wait_alu_ready(dev, ALU_START, 1000) < 0) {
+       ret = wait_alu_ready(dev, ALU_START, 1000);
+       if (ret < 0) {
                dev_dbg(dev->dev, "Failed to read ALU\n");
                goto exit;
        }
        ksz_write32(dev, REG_SW_ALU_CTRL__4, ALU_WRITE | ALU_START);
 
        /* wait to be finished */
-       if (wait_alu_ready(dev, ALU_START, 1000) < 0)
-               dev_dbg(dev->dev, "Failed to read ALU\n");
+       ret = wait_alu_ready(dev, ALU_START, 1000);
+       if (ret < 0)
+               dev_dbg(dev->dev, "Failed to write ALU\n");
 
 exit:
        mutex_unlock(&dev->alu_mutex);
+
+       return ret;
 }
 
 static int ksz_port_fdb_del(struct dsa_switch *ds, int port,
        .port_vlan_add          = ksz_port_vlan_add,
        .port_vlan_del          = ksz_port_vlan_del,
        .port_vlan_dump         = ksz_port_vlan_dump,
-       .port_fdb_prepare       = ksz_port_fdb_prepare,
        .port_fdb_dump          = ksz_port_fdb_dump,
        .port_fdb_add           = ksz_port_fdb_add,
        .port_fdb_del           = ksz_port_fdb_del,
 
 }
 
 static int
-mt7530_port_fdb_prepare(struct dsa_switch *ds, int port,
-                       const unsigned char *addr, u16 vid)
-{
-       struct mt7530_priv *priv = ds->priv;
-       int ret;
-
-       /* Because auto-learned entrie shares the same FDB table.
-        * an entry is reserved with no port_mask to make sure fdb_add
-        * is called while the entry is still available.
-        */
-       mutex_lock(&priv->reg_mutex);
-       mt7530_fdb_write(priv, vid, 0, addr, -1, STATIC_ENT);
-       ret = mt7530_fdb_cmd(priv, MT7530_FDB_WRITE, 0);
-       mutex_unlock(&priv->reg_mutex);
-
-       return ret;
-}
-
-static void
 mt7530_port_fdb_add(struct dsa_switch *ds, int port,
                    const unsigned char *addr, u16 vid)
 {
        struct mt7530_priv *priv = ds->priv;
+       int ret;
        u8 port_mask = BIT(port);
 
        mutex_lock(&priv->reg_mutex);
        mt7530_fdb_write(priv, vid, port_mask, addr, -1, STATIC_ENT);
-       mt7530_fdb_cmd(priv, MT7530_FDB_WRITE, 0);
+       ret = mt7530_fdb_cmd(priv, MT7530_FDB_WRITE, 0);
        mutex_unlock(&priv->reg_mutex);
+
+       return ret;
 }
 
 static int
        .port_stp_state_set     = mt7530_stp_state_set,
        .port_bridge_join       = mt7530_port_bridge_join,
        .port_bridge_leave      = mt7530_port_bridge_leave,
-       .port_fdb_prepare       = mt7530_port_fdb_prepare,
        .port_fdb_add           = mt7530_port_fdb_add,
        .port_fdb_del           = mt7530_port_fdb_del,
        .port_fdb_dump          = mt7530_port_fdb_dump,
 
        return mv88e6xxx_g1_atu_loadpurge(chip, vlan.fid, &entry);
 }
 
-static int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
-                                     const unsigned char *addr, u16 vid)
-{
-       /* We don't need any dynamic resource from the kernel (yet),
-        * so skip the prepare phase.
-        */
-       return 0;
-}
-
-static void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
-                                  const unsigned char *addr, u16 vid)
+static int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
+                                 const unsigned char *addr, u16 vid)
 {
        struct mv88e6xxx_chip *chip = ds->priv;
+       int err;
 
        mutex_lock(&chip->reg_lock);
-       if (mv88e6xxx_port_db_load_purge(chip, port, addr, vid,
-                                        MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC))
-               dev_err(ds->dev, "p%d: failed to load unicast MAC address\n",
-                       port);
+       err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid,
+                                          MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC);
        mutex_unlock(&chip->reg_lock);
+
+       return err;
 }
 
 static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
        .port_vlan_add          = mv88e6xxx_port_vlan_add,
        .port_vlan_del          = mv88e6xxx_port_vlan_del,
        .port_vlan_dump         = mv88e6xxx_port_vlan_dump,
-       .port_fdb_prepare       = mv88e6xxx_port_fdb_prepare,
        .port_fdb_add           = mv88e6xxx_port_fdb_add,
        .port_fdb_del           = mv88e6xxx_port_fdb_del,
        .port_fdb_dump          = mv88e6xxx_port_fdb_dump,
 
 }
 
 static int
-qca8k_port_fdb_prepare(struct dsa_switch *ds, int port,
-                      const unsigned char *addr, u16 vid)
-{
-       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-
-       /* The FDB table for static and auto learned entries is the same. We
-        * need to reserve an entry with no port_mask set to make sure that
-        * when port_fdb_add is called an entry is still available. Otherwise
-        * the last free entry might have been used up by auto learning
-        */
-       return qca8k_port_fdb_insert(priv, addr, 0, vid);
-}
-
-static void
 qca8k_port_fdb_add(struct dsa_switch *ds, int port,
                   const unsigned char *addr, u16 vid)
 {
        struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
        u16 port_mask = BIT(port);
 
-       /* Update the FDB entry adding the port_mask */
-       qca8k_port_fdb_insert(priv, addr, port_mask, vid);
+       return qca8k_port_fdb_insert(priv, addr, port_mask, vid);
 }
 
 static int
        .port_stp_state_set     = qca8k_port_stp_state_set,
        .port_bridge_join       = qca8k_port_bridge_join,
        .port_bridge_leave      = qca8k_port_bridge_leave,
-       .port_fdb_prepare       = qca8k_port_fdb_prepare,
        .port_fdb_add           = qca8k_port_fdb_add,
        .port_fdb_del           = qca8k_port_fdb_del,
        .port_fdb_dump          = qca8k_port_fdb_dump,
 
        /*
         * Forwarding database
         */
-       int     (*port_fdb_prepare)(struct dsa_switch *ds, int port,
-                                   const unsigned char *addr, u16 vid);
-       void    (*port_fdb_add)(struct dsa_switch *ds, int port,
+       int     (*port_fdb_add)(struct dsa_switch *ds, int port,
                                const unsigned char *addr, u16 vid);
        int     (*port_fdb_del)(struct dsa_switch *ds, int port,
                                const unsigned char *addr, u16 vid);
 
 /* DSA_NOTIFIER_FDB_* */
 struct dsa_notifier_fdb_info {
        const struct switchdev_obj_port_fdb *fdb;
-       struct switchdev_trans *trans;
        int sw_index;
        int port;
 };
 int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock,
                         struct switchdev_trans *trans);
 int dsa_port_fdb_add(struct dsa_port *dp,
-                    const struct switchdev_obj_port_fdb *fdb,
-                    struct switchdev_trans *trans);
+                    const struct switchdev_obj_port_fdb *fdb);
 int dsa_port_fdb_del(struct dsa_port *dp,
                     const struct switchdev_obj_port_fdb *fdb);
 int dsa_port_fdb_dump(struct dsa_port *dp, struct switchdev_obj_port_fdb *fdb,
 
 }
 
 int dsa_port_fdb_add(struct dsa_port *dp,
-                    const struct switchdev_obj_port_fdb *fdb,
-                    struct switchdev_trans *trans)
+                    const struct switchdev_obj_port_fdb *fdb)
 {
        struct dsa_notifier_fdb_info info = {
                .sw_index = dp->ds->index,
                .port = dp->index,
-               .trans = trans,
                .fdb = fdb,
        };
 
 
 
        switch (obj->id) {
        case SWITCHDEV_OBJ_ID_PORT_FDB:
-               err = dsa_port_fdb_add(dp, SWITCHDEV_OBJ_PORT_FDB(obj), trans);
+               if (switchdev_trans_ph_prepare(trans))
+                       return 0;
+               err = dsa_port_fdb_add(dp, SWITCHDEV_OBJ_PORT_FDB(obj));
                break;
        case SWITCHDEV_OBJ_ID_PORT_MDB:
                err = dsa_port_mdb_add(dp, SWITCHDEV_OBJ_PORT_MDB(obj), trans);
 
                              struct dsa_notifier_fdb_info *info)
 {
        const struct switchdev_obj_port_fdb *fdb = info->fdb;
-       struct switchdev_trans *trans = info->trans;
 
        /* Do not care yet about other switch chips of the fabric */
        if (ds->index != info->sw_index)
                return 0;
 
-       if (switchdev_trans_ph_prepare(trans)) {
-               if (!ds->ops->port_fdb_prepare || !ds->ops->port_fdb_add)
-                       return -EOPNOTSUPP;
-
-               return ds->ops->port_fdb_prepare(ds, info->port, fdb->addr,
-                                                fdb->vid);
-       }
-
-       ds->ops->port_fdb_add(ds, info->port, fdb->addr, fdb->vid);
+       if (!ds->ops->port_fdb_add)
+               return -EOPNOTSUPP;
 
-       return 0;
+       return ds->ops->port_fdb_add(ds, info->port, fdb->addr, fdb->vid);
 }
 
 static int dsa_switch_fdb_del(struct dsa_switch *ds,