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,