net: dsa: Move FDB dump implementation inside DSA
>From all switchdev devices only DSA requires special FDB dump. This is due to lack of ability for syncing the hardware learned FDBs with the bridge. Due to this it is removed from switchdev and moved inside DSA. Signed-off-by: Arkadi Sharshevsky <arkadis@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committato da
David S. Miller

parent
dc0cbff3ff
commit
2bedde1abb
@@ -1227,8 +1227,7 @@ static void b53_arl_search_rd(struct b53_device *dev, u8 idx,
|
||||
}
|
||||
|
||||
static int b53_fdb_copy(int port, const struct b53_arl_entry *ent,
|
||||
struct switchdev_obj_port_fdb *fdb,
|
||||
switchdev_obj_dump_cb_t *cb)
|
||||
dsa_fdb_dump_cb_t *cb, void *data)
|
||||
{
|
||||
if (!ent->is_valid)
|
||||
return 0;
|
||||
@@ -1236,16 +1235,11 @@ static int b53_fdb_copy(int port, const struct b53_arl_entry *ent,
|
||||
if (port != ent->port)
|
||||
return 0;
|
||||
|
||||
ether_addr_copy(fdb->addr, ent->mac);
|
||||
fdb->vid = ent->vid;
|
||||
fdb->ndm_state = ent->is_static ? NUD_NOARP : NUD_REACHABLE;
|
||||
|
||||
return cb(&fdb->obj);
|
||||
return cb(ent->mac, ent->vid, ent->is_static, data);
|
||||
}
|
||||
|
||||
int b53_fdb_dump(struct dsa_switch *ds, int port,
|
||||
struct switchdev_obj_port_fdb *fdb,
|
||||
switchdev_obj_dump_cb_t *cb)
|
||||
dsa_fdb_dump_cb_t *cb, void *data)
|
||||
{
|
||||
struct b53_device *priv = ds->priv;
|
||||
struct b53_arl_entry results[2];
|
||||
@@ -1263,13 +1257,13 @@ int b53_fdb_dump(struct dsa_switch *ds, int port,
|
||||
return ret;
|
||||
|
||||
b53_arl_search_rd(priv, 0, &results[0]);
|
||||
ret = b53_fdb_copy(port, &results[0], fdb, cb);
|
||||
ret = b53_fdb_copy(port, &results[0], cb, data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (priv->num_arl_entries > 2) {
|
||||
b53_arl_search_rd(priv, 1, &results[1]);
|
||||
ret = b53_fdb_copy(port, &results[1], fdb, cb);
|
||||
ret = b53_fdb_copy(port, &results[1], cb, data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@@ -398,8 +398,7 @@ int b53_fdb_add(struct dsa_switch *ds, int port,
|
||||
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,
|
||||
struct switchdev_obj_port_fdb *fdb,
|
||||
switchdev_obj_dump_cb_t *cb);
|
||||
dsa_fdb_dump_cb_t *cb, void *data);
|
||||
int b53_mirror_add(struct dsa_switch *ds, int port,
|
||||
struct dsa_mall_mirror_tc_entry *mirror, bool ingress);
|
||||
void b53_mirror_del(struct dsa_switch *ds, int port,
|
||||
|
@@ -805,12 +805,11 @@ static void convert_alu(struct alu_struct *alu, u32 *alu_table)
|
||||
}
|
||||
|
||||
static int ksz_port_fdb_dump(struct dsa_switch *ds, int port,
|
||||
struct switchdev_obj_port_fdb *fdb,
|
||||
switchdev_obj_dump_cb_t *cb)
|
||||
dsa_fdb_dump_cb_t *cb, void *data)
|
||||
{
|
||||
struct ksz_device *dev = ds->priv;
|
||||
int ret = 0;
|
||||
u32 data;
|
||||
u32 ksz_data;
|
||||
u32 alu_table[4];
|
||||
struct alu_struct alu;
|
||||
int timeout;
|
||||
@@ -823,8 +822,8 @@ static int ksz_port_fdb_dump(struct dsa_switch *ds, int port,
|
||||
do {
|
||||
timeout = 1000;
|
||||
do {
|
||||
ksz_read32(dev, REG_SW_ALU_CTRL__4, &data);
|
||||
if ((data & ALU_VALID) || !(data & ALU_START))
|
||||
ksz_read32(dev, REG_SW_ALU_CTRL__4, &ksz_data);
|
||||
if ((ksz_data & ALU_VALID) || !(ksz_data & ALU_START))
|
||||
break;
|
||||
usleep_range(1, 10);
|
||||
} while (timeout-- > 0);
|
||||
@@ -841,18 +840,11 @@ static int ksz_port_fdb_dump(struct dsa_switch *ds, int port,
|
||||
convert_alu(&alu, alu_table);
|
||||
|
||||
if (alu.port_forward & BIT(port)) {
|
||||
fdb->vid = alu.fid;
|
||||
if (alu.is_static)
|
||||
fdb->ndm_state = NUD_NOARP;
|
||||
else
|
||||
fdb->ndm_state = NUD_REACHABLE;
|
||||
ether_addr_copy(fdb->addr, alu.mac);
|
||||
|
||||
ret = cb(&fdb->obj);
|
||||
ret = cb(alu.mac, alu.fid, alu.is_static, data);
|
||||
if (ret)
|
||||
goto exit;
|
||||
}
|
||||
} while (data & ALU_START);
|
||||
} while (ksz_data & ALU_START);
|
||||
|
||||
exit:
|
||||
|
||||
|
@@ -834,8 +834,7 @@ mt7530_port_fdb_del(struct dsa_switch *ds, int port,
|
||||
|
||||
static int
|
||||
mt7530_port_fdb_dump(struct dsa_switch *ds, int port,
|
||||
struct switchdev_obj_port_fdb *fdb,
|
||||
switchdev_obj_dump_cb_t *cb)
|
||||
dsa_fdb_dump_cb_t *cb, void *data)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
struct mt7530_fdb _fdb = { 0 };
|
||||
@@ -853,11 +852,8 @@ mt7530_port_fdb_dump(struct dsa_switch *ds, int port,
|
||||
if (rsp & ATC_SRCH_HIT) {
|
||||
mt7530_fdb_read(priv, &_fdb);
|
||||
if (_fdb.port_mask & BIT(port)) {
|
||||
ether_addr_copy(fdb->addr, _fdb.mac);
|
||||
fdb->vid = _fdb.vid;
|
||||
fdb->ndm_state = _fdb.noarp ?
|
||||
NUD_NOARP : NUD_REACHABLE;
|
||||
ret = cb(&fdb->obj);
|
||||
ret = cb(_fdb.mac, _fdb.vid, _fdb.noarp,
|
||||
data);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
|
@@ -1381,10 +1381,10 @@ static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
|
||||
|
||||
static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
|
||||
u16 fid, u16 vid, int port,
|
||||
struct switchdev_obj *obj,
|
||||
switchdev_obj_dump_cb_t *cb)
|
||||
dsa_fdb_dump_cb_t *cb, void *data)
|
||||
{
|
||||
struct mv88e6xxx_atu_entry addr;
|
||||
bool is_static;
|
||||
int err;
|
||||
|
||||
addr.state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED;
|
||||
@@ -1401,24 +1401,12 @@ static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
|
||||
if (addr.trunk || (addr.portvec & BIT(port)) == 0)
|
||||
continue;
|
||||
|
||||
if (obj->id == SWITCHDEV_OBJ_ID_PORT_FDB) {
|
||||
struct switchdev_obj_port_fdb *fdb;
|
||||
if (!is_unicast_ether_addr(addr.mac))
|
||||
continue;
|
||||
|
||||
if (!is_unicast_ether_addr(addr.mac))
|
||||
continue;
|
||||
|
||||
fdb = SWITCHDEV_OBJ_PORT_FDB(obj);
|
||||
fdb->vid = vid;
|
||||
ether_addr_copy(fdb->addr, addr.mac);
|
||||
if (addr.state == MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC)
|
||||
fdb->ndm_state = NUD_NOARP;
|
||||
else
|
||||
fdb->ndm_state = NUD_REACHABLE;
|
||||
} else {
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
err = cb(obj);
|
||||
is_static = (addr.state ==
|
||||
MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC);
|
||||
err = cb(addr.mac, vid, is_static, data);
|
||||
if (err)
|
||||
return err;
|
||||
} while (!is_broadcast_ether_addr(addr.mac));
|
||||
@@ -1427,8 +1415,7 @@ static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
|
||||
}
|
||||
|
||||
static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
|
||||
struct switchdev_obj *obj,
|
||||
switchdev_obj_dump_cb_t *cb)
|
||||
dsa_fdb_dump_cb_t *cb, void *data)
|
||||
{
|
||||
struct mv88e6xxx_vtu_entry vlan = {
|
||||
.vid = chip->info->max_vid,
|
||||
@@ -1441,7 +1428,7 @@ static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mv88e6xxx_port_db_dump_fid(chip, fid, 0, port, obj, cb);
|
||||
err = mv88e6xxx_port_db_dump_fid(chip, fid, 0, port, cb, data);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -1455,7 +1442,7 @@ static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
|
||||
break;
|
||||
|
||||
err = mv88e6xxx_port_db_dump_fid(chip, vlan.fid, vlan.vid, port,
|
||||
obj, cb);
|
||||
cb, data);
|
||||
if (err)
|
||||
return err;
|
||||
} while (vlan.vid < chip->info->max_vid);
|
||||
@@ -1464,14 +1451,13 @@ static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
|
||||
}
|
||||
|
||||
static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
|
||||
struct switchdev_obj_port_fdb *fdb,
|
||||
switchdev_obj_dump_cb_t *cb)
|
||||
dsa_fdb_dump_cb_t *cb, void *data)
|
||||
{
|
||||
struct mv88e6xxx_chip *chip = ds->priv;
|
||||
int err;
|
||||
|
||||
mutex_lock(&chip->reg_lock);
|
||||
err = mv88e6xxx_port_db_dump(chip, port, &fdb->obj, cb);
|
||||
err = mv88e6xxx_port_db_dump(chip, port, cb, data);
|
||||
mutex_unlock(&chip->reg_lock);
|
||||
|
||||
return err;
|
||||
|
@@ -801,27 +801,20 @@ qca8k_port_fdb_del(struct dsa_switch *ds, int port,
|
||||
|
||||
static int
|
||||
qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
|
||||
struct switchdev_obj_port_fdb *fdb,
|
||||
switchdev_obj_dump_cb_t *cb)
|
||||
dsa_fdb_dump_cb_t *cb, void *data)
|
||||
{
|
||||
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
|
||||
struct qca8k_fdb _fdb = { 0 };
|
||||
int cnt = QCA8K_NUM_FDB_RECORDS;
|
||||
bool is_static;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&priv->reg_mutex);
|
||||
while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) {
|
||||
if (!_fdb.aging)
|
||||
break;
|
||||
|
||||
ether_addr_copy(fdb->addr, _fdb.mac);
|
||||
fdb->vid = _fdb.vid;
|
||||
if (_fdb.aging == QCA8K_ATU_STATUS_STATIC)
|
||||
fdb->ndm_state = NUD_NOARP;
|
||||
else
|
||||
fdb->ndm_state = NUD_REACHABLE;
|
||||
|
||||
ret = cb(&fdb->obj);
|
||||
is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC);
|
||||
ret = cb(_fdb.mac, _fdb.vid, is_static, data);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
Fai riferimento in un nuovo problema
Block a user