aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorArkadi Sharshevsky <arkadis@mellanox.com>2017-08-06 09:15:49 -0400
committerDavid S. Miller <davem@davemloft.net>2017-08-07 17:48:48 -0400
commit2bedde1abbef5eec211308f0293dd7681b0513ec (patch)
treeace07f76bb5f82da40815297675d6e8a9a9a3c02 /drivers/net
parentdc0cbff3ff9fe331160c2be2b3f47564e247137d (diff)
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>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/dsa/b53/b53_common.c16
-rw-r--r--drivers/net/dsa/b53/b53_priv.h3
-rw-r--r--drivers/net/dsa/microchip/ksz_common.c20
-rw-r--r--drivers/net/dsa/mt7530.c10
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.c38
-rw-r--r--drivers/net/dsa/qca8k.c15
6 files changed, 31 insertions, 71 deletions
diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 0176d8087344..274f3679f33d 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -1227,8 +1227,7 @@ static void b53_arl_search_rd(struct b53_device *dev, u8 idx,
1227} 1227}
1228 1228
1229static int b53_fdb_copy(int port, const struct b53_arl_entry *ent, 1229static int b53_fdb_copy(int port, const struct b53_arl_entry *ent,
1230 struct switchdev_obj_port_fdb *fdb, 1230 dsa_fdb_dump_cb_t *cb, void *data)
1231 switchdev_obj_dump_cb_t *cb)
1232{ 1231{
1233 if (!ent->is_valid) 1232 if (!ent->is_valid)
1234 return 0; 1233 return 0;
@@ -1236,16 +1235,11 @@ static int b53_fdb_copy(int port, const struct b53_arl_entry *ent,
1236 if (port != ent->port) 1235 if (port != ent->port)
1237 return 0; 1236 return 0;
1238 1237
1239 ether_addr_copy(fdb->addr, ent->mac); 1238 return cb(ent->mac, ent->vid, ent->is_static, data);
1240 fdb->vid = ent->vid;
1241 fdb->ndm_state = ent->is_static ? NUD_NOARP : NUD_REACHABLE;
1242
1243 return cb(&fdb->obj);
1244} 1239}
1245 1240
1246int b53_fdb_dump(struct dsa_switch *ds, int port, 1241int b53_fdb_dump(struct dsa_switch *ds, int port,
1247 struct switchdev_obj_port_fdb *fdb, 1242 dsa_fdb_dump_cb_t *cb, void *data)
1248 switchdev_obj_dump_cb_t *cb)
1249{ 1243{
1250 struct b53_device *priv = ds->priv; 1244 struct b53_device *priv = ds->priv;
1251 struct b53_arl_entry results[2]; 1245 struct b53_arl_entry results[2];
@@ -1263,13 +1257,13 @@ int b53_fdb_dump(struct dsa_switch *ds, int port,
1263 return ret; 1257 return ret;
1264 1258
1265 b53_arl_search_rd(priv, 0, &results[0]); 1259 b53_arl_search_rd(priv, 0, &results[0]);
1266 ret = b53_fdb_copy(port, &results[0], fdb, cb); 1260 ret = b53_fdb_copy(port, &results[0], cb, data);
1267 if (ret) 1261 if (ret)
1268 return ret; 1262 return ret;
1269 1263
1270 if (priv->num_arl_entries > 2) { 1264 if (priv->num_arl_entries > 2) {
1271 b53_arl_search_rd(priv, 1, &results[1]); 1265 b53_arl_search_rd(priv, 1, &results[1]);
1272 ret = b53_fdb_copy(port, &results[1], fdb, cb); 1266 ret = b53_fdb_copy(port, &results[1], cb, data);
1273 if (ret) 1267 if (ret)
1274 return ret; 1268 return ret;
1275 1269
diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h
index af5d6c166bff..01bd8cbe9a3f 100644
--- a/drivers/net/dsa/b53/b53_priv.h
+++ b/drivers/net/dsa/b53/b53_priv.h
@@ -398,8 +398,7 @@ int b53_fdb_add(struct dsa_switch *ds, int port,
398int b53_fdb_del(struct dsa_switch *ds, int port, 398int b53_fdb_del(struct dsa_switch *ds, int port,
399 const unsigned char *addr, u16 vid); 399 const unsigned char *addr, u16 vid);
400int b53_fdb_dump(struct dsa_switch *ds, int port, 400int b53_fdb_dump(struct dsa_switch *ds, int port,
401 struct switchdev_obj_port_fdb *fdb, 401 dsa_fdb_dump_cb_t *cb, void *data);
402 switchdev_obj_dump_cb_t *cb);
403int b53_mirror_add(struct dsa_switch *ds, int port, 402int b53_mirror_add(struct dsa_switch *ds, int port,
404 struct dsa_mall_mirror_tc_entry *mirror, bool ingress); 403 struct dsa_mall_mirror_tc_entry *mirror, bool ingress);
405void b53_mirror_del(struct dsa_switch *ds, int port, 404void b53_mirror_del(struct dsa_switch *ds, int port,
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 4de9d90a4bb3..56cd6d365352 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -805,12 +805,11 @@ static void convert_alu(struct alu_struct *alu, u32 *alu_table)
805} 805}
806 806
807static int ksz_port_fdb_dump(struct dsa_switch *ds, int port, 807static int ksz_port_fdb_dump(struct dsa_switch *ds, int port,
808 struct switchdev_obj_port_fdb *fdb, 808 dsa_fdb_dump_cb_t *cb, void *data)
809 switchdev_obj_dump_cb_t *cb)
810{ 809{
811 struct ksz_device *dev = ds->priv; 810 struct ksz_device *dev = ds->priv;
812 int ret = 0; 811 int ret = 0;
813 u32 data; 812 u32 ksz_data;
814 u32 alu_table[4]; 813 u32 alu_table[4];
815 struct alu_struct alu; 814 struct alu_struct alu;
816 int timeout; 815 int timeout;
@@ -823,8 +822,8 @@ static int ksz_port_fdb_dump(struct dsa_switch *ds, int port,
823 do { 822 do {
824 timeout = 1000; 823 timeout = 1000;
825 do { 824 do {
826 ksz_read32(dev, REG_SW_ALU_CTRL__4, &data); 825 ksz_read32(dev, REG_SW_ALU_CTRL__4, &ksz_data);
827 if ((data & ALU_VALID) || !(data & ALU_START)) 826 if ((ksz_data & ALU_VALID) || !(ksz_data & ALU_START))
828 break; 827 break;
829 usleep_range(1, 10); 828 usleep_range(1, 10);
830 } while (timeout-- > 0); 829 } while (timeout-- > 0);
@@ -841,18 +840,11 @@ static int ksz_port_fdb_dump(struct dsa_switch *ds, int port,
841 convert_alu(&alu, alu_table); 840 convert_alu(&alu, alu_table);
842 841
843 if (alu.port_forward & BIT(port)) { 842 if (alu.port_forward & BIT(port)) {
844 fdb->vid = alu.fid; 843 ret = cb(alu.mac, alu.fid, alu.is_static, data);
845 if (alu.is_static)
846 fdb->ndm_state = NUD_NOARP;
847 else
848 fdb->ndm_state = NUD_REACHABLE;
849 ether_addr_copy(fdb->addr, alu.mac);
850
851 ret = cb(&fdb->obj);
852 if (ret) 844 if (ret)
853 goto exit; 845 goto exit;
854 } 846 }
855 } while (data & ALU_START); 847 } while (ksz_data & ALU_START);
856 848
857exit: 849exit:
858 850
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index f92aae8947e6..12700710f26d 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -834,8 +834,7 @@ mt7530_port_fdb_del(struct dsa_switch *ds, int port,
834 834
835static int 835static int
836mt7530_port_fdb_dump(struct dsa_switch *ds, int port, 836mt7530_port_fdb_dump(struct dsa_switch *ds, int port,
837 struct switchdev_obj_port_fdb *fdb, 837 dsa_fdb_dump_cb_t *cb, void *data)
838 switchdev_obj_dump_cb_t *cb)
839{ 838{
840 struct mt7530_priv *priv = ds->priv; 839 struct mt7530_priv *priv = ds->priv;
841 struct mt7530_fdb _fdb = { 0 }; 840 struct mt7530_fdb _fdb = { 0 };
@@ -853,11 +852,8 @@ mt7530_port_fdb_dump(struct dsa_switch *ds, int port,
853 if (rsp & ATC_SRCH_HIT) { 852 if (rsp & ATC_SRCH_HIT) {
854 mt7530_fdb_read(priv, &_fdb); 853 mt7530_fdb_read(priv, &_fdb);
855 if (_fdb.port_mask & BIT(port)) { 854 if (_fdb.port_mask & BIT(port)) {
856 ether_addr_copy(fdb->addr, _fdb.mac); 855 ret = cb(_fdb.mac, _fdb.vid, _fdb.noarp,
857 fdb->vid = _fdb.vid; 856 data);
858 fdb->ndm_state = _fdb.noarp ?
859 NUD_NOARP : NUD_REACHABLE;
860 ret = cb(&fdb->obj);
861 if (ret < 0) 857 if (ret < 0)
862 break; 858 break;
863 } 859 }
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 1f5c202b974d..918d8f0fe091 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1381,10 +1381,10 @@ static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
1381 1381
1382static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip, 1382static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
1383 u16 fid, u16 vid, int port, 1383 u16 fid, u16 vid, int port,
1384 struct switchdev_obj *obj, 1384 dsa_fdb_dump_cb_t *cb, void *data)
1385 switchdev_obj_dump_cb_t *cb)
1386{ 1385{
1387 struct mv88e6xxx_atu_entry addr; 1386 struct mv88e6xxx_atu_entry addr;
1387 bool is_static;
1388 int err; 1388 int err;
1389 1389
1390 addr.state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED; 1390 addr.state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED;
@@ -1401,24 +1401,12 @@ static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
1401 if (addr.trunk || (addr.portvec & BIT(port)) == 0) 1401 if (addr.trunk || (addr.portvec & BIT(port)) == 0)
1402 continue; 1402 continue;
1403 1403
1404 if (obj->id == SWITCHDEV_OBJ_ID_PORT_FDB) { 1404 if (!is_unicast_ether_addr(addr.mac))
1405 struct switchdev_obj_port_fdb *fdb; 1405 continue;
1406
1407 if (!is_unicast_ether_addr(addr.mac))
1408 continue;
1409
1410 fdb = SWITCHDEV_OBJ_PORT_FDB(obj);
1411 fdb->vid = vid;
1412 ether_addr_copy(fdb->addr, addr.mac);
1413 if (addr.state == MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC)
1414 fdb->ndm_state = NUD_NOARP;
1415 else
1416 fdb->ndm_state = NUD_REACHABLE;
1417 } else {
1418 return -EOPNOTSUPP;
1419 }
1420 1406
1421 err = cb(obj); 1407 is_static = (addr.state ==
1408 MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC);
1409 err = cb(addr.mac, vid, is_static, data);
1422 if (err) 1410 if (err)
1423 return err; 1411 return err;
1424 } while (!is_broadcast_ether_addr(addr.mac)); 1412 } while (!is_broadcast_ether_addr(addr.mac));
@@ -1427,8 +1415,7 @@ static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
1427} 1415}
1428 1416
1429static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port, 1417static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
1430 struct switchdev_obj *obj, 1418 dsa_fdb_dump_cb_t *cb, void *data)
1431 switchdev_obj_dump_cb_t *cb)
1432{ 1419{
1433 struct mv88e6xxx_vtu_entry vlan = { 1420 struct mv88e6xxx_vtu_entry vlan = {
1434 .vid = chip->info->max_vid, 1421 .vid = chip->info->max_vid,
@@ -1441,7 +1428,7 @@ static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
1441 if (err) 1428 if (err)
1442 return err; 1429 return err;
1443 1430
1444 err = mv88e6xxx_port_db_dump_fid(chip, fid, 0, port, obj, cb); 1431 err = mv88e6xxx_port_db_dump_fid(chip, fid, 0, port, cb, data);
1445 if (err) 1432 if (err)
1446 return err; 1433 return err;
1447 1434
@@ -1455,7 +1442,7 @@ static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
1455 break; 1442 break;
1456 1443
1457 err = mv88e6xxx_port_db_dump_fid(chip, vlan.fid, vlan.vid, port, 1444 err = mv88e6xxx_port_db_dump_fid(chip, vlan.fid, vlan.vid, port,
1458 obj, cb); 1445 cb, data);
1459 if (err) 1446 if (err)
1460 return err; 1447 return err;
1461 } while (vlan.vid < chip->info->max_vid); 1448 } while (vlan.vid < chip->info->max_vid);
@@ -1464,14 +1451,13 @@ static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
1464} 1451}
1465 1452
1466static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port, 1453static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
1467 struct switchdev_obj_port_fdb *fdb, 1454 dsa_fdb_dump_cb_t *cb, void *data)
1468 switchdev_obj_dump_cb_t *cb)
1469{ 1455{
1470 struct mv88e6xxx_chip *chip = ds->priv; 1456 struct mv88e6xxx_chip *chip = ds->priv;
1471 int err; 1457 int err;
1472 1458
1473 mutex_lock(&chip->reg_lock); 1459 mutex_lock(&chip->reg_lock);
1474 err = mv88e6xxx_port_db_dump(chip, port, &fdb->obj, cb); 1460 err = mv88e6xxx_port_db_dump(chip, port, cb, data);
1475 mutex_unlock(&chip->reg_lock); 1461 mutex_unlock(&chip->reg_lock);
1476 1462
1477 return err; 1463 return err;
diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index f8ef823349bc..17977f06cb98 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -801,27 +801,20 @@ qca8k_port_fdb_del(struct dsa_switch *ds, int port,
801 801
802static int 802static int
803qca8k_port_fdb_dump(struct dsa_switch *ds, int port, 803qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
804 struct switchdev_obj_port_fdb *fdb, 804 dsa_fdb_dump_cb_t *cb, void *data)
805 switchdev_obj_dump_cb_t *cb)
806{ 805{
807 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; 806 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
808 struct qca8k_fdb _fdb = { 0 }; 807 struct qca8k_fdb _fdb = { 0 };
809 int cnt = QCA8K_NUM_FDB_RECORDS; 808 int cnt = QCA8K_NUM_FDB_RECORDS;
809 bool is_static;
810 int ret = 0; 810 int ret = 0;
811 811
812 mutex_lock(&priv->reg_mutex); 812 mutex_lock(&priv->reg_mutex);
813 while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) { 813 while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) {
814 if (!_fdb.aging) 814 if (!_fdb.aging)
815 break; 815 break;
816 816 is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC);
817 ether_addr_copy(fdb->addr, _fdb.mac); 817 ret = cb(_fdb.mac, _fdb.vid, is_static, data);
818 fdb->vid = _fdb.vid;
819 if (_fdb.aging == QCA8K_ATU_STATUS_STATIC)
820 fdb->ndm_state = NUD_NOARP;
821 else
822 fdb->ndm_state = NUD_REACHABLE;
823
824 ret = cb(&fdb->obj);
825 if (ret) 818 if (ret)
826 break; 819 break;
827 } 820 }