Skip to content

Commit

Permalink
net: dsa: Move FDB dump implementation inside DSA
Browse files Browse the repository at this point in the history
>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 <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Arkadi Sharshevsky authored and davem330 committed Aug 7, 2017
1 parent dc0cbff commit 2bedde1
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 204 deletions.
16 changes: 5 additions & 11 deletions drivers/net/dsa/b53/b53_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1227,25 +1227,19 @@ 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;

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];
Expand All @@ -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;

Expand Down
3 changes: 1 addition & 2 deletions drivers/net/dsa/b53/b53_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
20 changes: 6 additions & 14 deletions drivers/net/dsa/microchip/ksz_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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:

Expand Down
10 changes: 3 additions & 7 deletions drivers/net/dsa/mt7530.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand All @@ -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;
}
Expand Down
38 changes: 12 additions & 26 deletions drivers/net/dsa/mv88e6xxx/chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

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;
}
if (!is_unicast_ether_addr(addr.mac))
continue;

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));
Expand All @@ -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,
Expand All @@ -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;

Expand All @@ -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);
Expand All @@ -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;
Expand Down
15 changes: 4 additions & 11 deletions drivers/net/dsa/qca8k.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
5 changes: 3 additions & 2 deletions include/net/dsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ static inline u8 dsa_upstream_port(struct dsa_switch *ds)
return ds->rtable[dst->cpu_dp->ds->index];
}

typedef int dsa_fdb_dump_cb_t(const unsigned char *addr, u16 vid,
bool is_static, void *data);
struct dsa_switch_ops {
/*
* Legacy probing.
Expand Down Expand Up @@ -386,8 +388,7 @@ struct dsa_switch_ops {
int (*port_fdb_del)(struct dsa_switch *ds, int port,
const unsigned char *addr, u16 vid);
int (*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);

/*
* Multicast database
Expand Down
12 changes: 0 additions & 12 deletions include/net/switchdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,6 @@ int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
struct net_device *dev, const unsigned char *addr,
u16 vid);
int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
struct net_device *dev,
struct net_device *filter_dev, int *idx);
void switchdev_port_fwd_mark_set(struct net_device *dev,
struct net_device *group_dev,
bool joining);
Expand Down Expand Up @@ -309,15 +306,6 @@ static inline int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
return -EOPNOTSUPP;
}

static inline int switchdev_port_fdb_dump(struct sk_buff *skb,
struct netlink_callback *cb,
struct net_device *dev,
struct net_device *filter_dev,
int *idx)
{
return *idx;
}

static inline bool switchdev_port_same_parent_id(struct net_device *a,
struct net_device *b)
{
Expand Down
2 changes: 0 additions & 2 deletions net/dsa/dsa_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,6 @@ int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr,
u16 vid);
int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr,
u16 vid);
int dsa_port_fdb_dump(struct dsa_port *dp, struct switchdev_obj_port_fdb *fdb,
switchdev_obj_dump_cb_t *cb);
int dsa_port_mdb_add(struct dsa_port *dp,
const struct switchdev_obj_port_mdb *mdb,
struct switchdev_trans *trans);
Expand Down
11 changes: 0 additions & 11 deletions net/dsa/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,17 +173,6 @@ int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr,
return dsa_port_notify(dp, DSA_NOTIFIER_FDB_DEL, &info);
}

int dsa_port_fdb_dump(struct dsa_port *dp, struct switchdev_obj_port_fdb *fdb,
switchdev_obj_dump_cb_t *cb)
{
struct dsa_switch *ds = dp->ds;

if (ds->ops->port_fdb_dump)
return ds->ops->port_fdb_dump(ds, dp->index, fdb, cb);

return -EOPNOTSUPP;
}

int dsa_port_mdb_add(struct dsa_port *dp,
const struct switchdev_obj_port_mdb *mdb,
struct switchdev_trans *trans)
Expand Down
Loading

0 comments on commit 2bedde1

Please sign in to comment.