Skip to content

Commit 998eb80

Browse files
committed
Merge branch 'dsa-port_fdb_dump'
Vivien Didelot says: ==================== net: dsa: implement port_fdb_dump in drivers Not all switch chips provide a Get Next kind of operation to dump FDB entries. It is preferred to let the driver handle the dump operation the way it works best for the chip. Thus, drop port_fdb_getnext and implement the port_fdb_dump operation in DSA, which pushes the switchdev FDB dump callback down to the drivers. mv88e6xxx is the only driver affected and is updated accordingly. v3 -> v4: fix rejects on latest net-next v2 -> v3: opencode switchdev_obj_dump_cb_t to avoid multiple typedef; use ether_addr_copy in fdb_dump v1 -> v2: fix a few "return err" instead of "goto unlock" in mv88e6xxx.c ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents e9829b9 + 1a49a2f commit 998eb80

File tree

6 files changed

+83
-91
lines changed

6 files changed

+83
-91
lines changed

drivers/net/dsa/mv88e6171.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
122122
.port_fdb_prepare = mv88e6xxx_port_fdb_prepare,
123123
.port_fdb_add = mv88e6xxx_port_fdb_add,
124124
.port_fdb_del = mv88e6xxx_port_fdb_del,
125-
.port_fdb_getnext = mv88e6xxx_port_fdb_getnext,
125+
.port_fdb_dump = mv88e6xxx_port_fdb_dump,
126126
};
127127

128128
MODULE_ALIAS("platform:mv88e6171");

drivers/net/dsa/mv88e6352.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
349349
.port_fdb_prepare = mv88e6xxx_port_fdb_prepare,
350350
.port_fdb_add = mv88e6xxx_port_fdb_add,
351351
.port_fdb_del = mv88e6xxx_port_fdb_del,
352-
.port_fdb_getnext = mv88e6xxx_port_fdb_getnext,
352+
.port_fdb_dump = mv88e6xxx_port_fdb_dump,
353353
};
354354

355355
MODULE_ALIAS("platform:mv88e6172");

drivers/net/dsa/mv88e6xxx.c

Lines changed: 71 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,7 +1259,13 @@ static int _mv88e6xxx_vtu_stu_data_write(struct dsa_switch *ds,
12591259
return 0;
12601260
}
12611261

1262-
static int _mv88e6xxx_vtu_getnext(struct dsa_switch *ds, u16 vid,
1262+
static int _mv88e6xxx_vtu_vid_write(struct dsa_switch *ds, u16 vid)
1263+
{
1264+
return _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_VTU_VID,
1265+
vid & GLOBAL_VTU_VID_MASK);
1266+
}
1267+
1268+
static int _mv88e6xxx_vtu_getnext(struct dsa_switch *ds,
12631269
struct mv88e6xxx_vtu_stu_entry *entry)
12641270
{
12651271
struct mv88e6xxx_vtu_stu_entry next = { 0 };
@@ -1269,11 +1275,6 @@ static int _mv88e6xxx_vtu_getnext(struct dsa_switch *ds, u16 vid,
12691275
if (ret < 0)
12701276
return ret;
12711277

1272-
ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_VTU_VID,
1273-
vid & GLOBAL_VTU_VID_MASK);
1274-
if (ret < 0)
1275-
return ret;
1276-
12771278
ret = _mv88e6xxx_vtu_cmd(ds, GLOBAL_VTU_OP_VTU_GET_NEXT);
12781279
if (ret < 0)
12791280
return ret;
@@ -1485,7 +1486,12 @@ int mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, u16 vid,
14851486
int err;
14861487

14871488
mutex_lock(&ps->smi_mutex);
1488-
err = _mv88e6xxx_vtu_getnext(ds, vid - 1, &vlan);
1489+
1490+
err = _mv88e6xxx_vtu_vid_write(ds, vid - 1);
1491+
if (err)
1492+
goto unlock;
1493+
1494+
err = _mv88e6xxx_vtu_getnext(ds, &vlan);
14891495
if (err)
14901496
goto unlock;
14911497

@@ -1514,7 +1520,11 @@ int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid)
15141520

15151521
mutex_lock(&ps->smi_mutex);
15161522

1517-
err = _mv88e6xxx_vtu_getnext(ds, vid - 1, &vlan);
1523+
err = _mv88e6xxx_vtu_vid_write(ds, vid - 1);
1524+
if (err)
1525+
goto unlock;
1526+
1527+
err = _mv88e6xxx_vtu_getnext(ds, &vlan);
15181528
if (err)
15191529
goto unlock;
15201530

@@ -1549,29 +1559,6 @@ int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid)
15491559
return err;
15501560
}
15511561

1552-
static int _mv88e6xxx_port_vtu_getnext(struct dsa_switch *ds, int port, u16 vid,
1553-
struct mv88e6xxx_vtu_stu_entry *entry)
1554-
{
1555-
int err;
1556-
1557-
do {
1558-
if (vid == 4095)
1559-
return -ENOENT;
1560-
1561-
err = _mv88e6xxx_vtu_getnext(ds, vid, entry);
1562-
if (err)
1563-
return err;
1564-
1565-
if (!entry->valid)
1566-
return -ENOENT;
1567-
1568-
vid = entry->vid;
1569-
} while (entry->data[port] != GLOBAL_VTU_DATA_MEMBER_TAG_TAGGED &&
1570-
entry->data[port] != GLOBAL_VTU_DATA_MEMBER_TAG_UNTAGGED);
1571-
1572-
return 0;
1573-
}
1574-
15751562
int mv88e6xxx_vlan_getnext(struct dsa_switch *ds, u16 *vid,
15761563
unsigned long *ports, unsigned long *untagged)
15771564
{
@@ -1584,7 +1571,12 @@ int mv88e6xxx_vlan_getnext(struct dsa_switch *ds, u16 *vid,
15841571
return -ENOENT;
15851572

15861573
mutex_lock(&ps->smi_mutex);
1587-
err = _mv88e6xxx_vtu_getnext(ds, *vid, &next);
1574+
err = _mv88e6xxx_vtu_vid_write(ds, *vid);
1575+
if (err)
1576+
goto unlock;
1577+
1578+
err = _mv88e6xxx_vtu_getnext(ds, &next);
1579+
unlock:
15881580
mutex_unlock(&ps->smi_mutex);
15891581

15901582
if (err)
@@ -1732,7 +1724,6 @@ int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
17321724
}
17331725

17341726
static int _mv88e6xxx_atu_getnext(struct dsa_switch *ds, u16 fid,
1735-
const unsigned char *addr,
17361727
struct mv88e6xxx_atu_entry *entry)
17371728
{
17381729
struct mv88e6xxx_atu_entry next = { 0 };
@@ -1744,10 +1735,6 @@ static int _mv88e6xxx_atu_getnext(struct dsa_switch *ds, u16 fid,
17441735
if (ret < 0)
17451736
return ret;
17461737

1747-
ret = _mv88e6xxx_atu_mac_write(ds, addr);
1748-
if (ret < 0)
1749-
return ret;
1750-
17511738
ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_FID, fid);
17521739
if (ret < 0)
17531740
return ret;
@@ -1785,46 +1772,69 @@ static int _mv88e6xxx_atu_getnext(struct dsa_switch *ds, u16 fid,
17851772
return 0;
17861773
}
17871774

1788-
/* get next entry for port */
1789-
int mv88e6xxx_port_fdb_getnext(struct dsa_switch *ds, int port,
1790-
unsigned char *addr, u16 *vid, bool *is_static)
1775+
int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
1776+
struct switchdev_obj_port_fdb *fdb,
1777+
int (*cb)(struct switchdev_obj *obj))
17911778
{
17921779
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1793-
struct mv88e6xxx_atu_entry next;
1794-
u16 fid = *vid; /* We use one FID per VLAN */
1795-
int ret;
1780+
struct mv88e6xxx_vtu_stu_entry vlan = {
1781+
.vid = GLOBAL_VTU_VID_MASK, /* all ones */
1782+
};
1783+
int err;
17961784

17971785
mutex_lock(&ps->smi_mutex);
17981786

1787+
err = _mv88e6xxx_vtu_vid_write(ds, vlan.vid);
1788+
if (err)
1789+
goto unlock;
1790+
17991791
do {
1800-
if (is_broadcast_ether_addr(addr)) {
1801-
struct mv88e6xxx_vtu_stu_entry vtu;
1792+
struct mv88e6xxx_atu_entry addr = {
1793+
.mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
1794+
};
18021795

1803-
ret = _mv88e6xxx_port_vtu_getnext(ds, port, *vid, &vtu);
1804-
if (ret < 0)
1805-
goto unlock;
1796+
err = _mv88e6xxx_vtu_getnext(ds, &vlan);
1797+
if (err)
1798+
goto unlock;
18061799

1807-
*vid = vtu.vid;
1808-
fid = vtu.fid;
1809-
}
1800+
if (!vlan.valid)
1801+
break;
18101802

1811-
ret = _mv88e6xxx_atu_getnext(ds, fid, addr, &next);
1812-
if (ret < 0)
1803+
err = _mv88e6xxx_atu_mac_write(ds, addr.mac);
1804+
if (err)
18131805
goto unlock;
18141806

1815-
ether_addr_copy(addr, next.mac);
1807+
do {
1808+
err = _mv88e6xxx_atu_getnext(ds, vlan.fid, &addr);
1809+
if (err)
1810+
goto unlock;
18161811

1817-
if (next.state == GLOBAL_ATU_DATA_STATE_UNUSED)
1818-
continue;
1819-
} while (next.trunk || (next.portv_trunkid & BIT(port)) == 0);
1812+
if (addr.state == GLOBAL_ATU_DATA_STATE_UNUSED)
1813+
break;
1814+
1815+
if (!addr.trunk && addr.portv_trunkid & BIT(port)) {
1816+
bool is_static = addr.state ==
1817+
(is_multicast_ether_addr(addr.mac) ?
1818+
GLOBAL_ATU_DATA_STATE_MC_STATIC :
1819+
GLOBAL_ATU_DATA_STATE_UC_STATIC);
1820+
1821+
fdb->vid = vlan.vid;
1822+
ether_addr_copy(fdb->addr, addr.mac);
1823+
fdb->ndm_state = is_static ? NUD_NOARP :
1824+
NUD_REACHABLE;
1825+
1826+
err = cb(&fdb->obj);
1827+
if (err)
1828+
goto unlock;
1829+
}
1830+
} while (!is_broadcast_ether_addr(addr.mac));
1831+
1832+
} while (vlan.vid < GLOBAL_VTU_VID_MASK);
18201833

1821-
*is_static = next.state == (is_multicast_ether_addr(addr) ?
1822-
GLOBAL_ATU_DATA_STATE_MC_STATIC :
1823-
GLOBAL_ATU_DATA_STATE_UC_STATIC);
18241834
unlock:
18251835
mutex_unlock(&ps->smi_mutex);
18261836

1827-
return ret;
1837+
return err;
18281838
}
18291839

18301840
static void mv88e6xxx_bridge_work(struct work_struct *work)

drivers/net/dsa/mv88e6xxx.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -474,8 +474,9 @@ int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
474474
struct switchdev_trans *trans);
475475
int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
476476
const struct switchdev_obj_port_fdb *fdb);
477-
int mv88e6xxx_port_fdb_getnext(struct dsa_switch *ds, int port,
478-
unsigned char *addr, u16 *vid, bool *is_static);
477+
int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
478+
struct switchdev_obj_port_fdb *fdb,
479+
int (*cb)(struct switchdev_obj *obj));
479480
int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg);
480481
int mv88e6xxx_phy_page_write(struct dsa_switch *ds, int port, int page,
481482
int reg, int val);

include/net/dsa.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ static inline u8 dsa_upstream_port(struct dsa_switch *ds)
198198
}
199199

200200
struct switchdev_trans;
201+
struct switchdev_obj;
201202
struct switchdev_obj_port_fdb;
202203

203204
struct dsa_switch_driver {
@@ -327,9 +328,9 @@ struct dsa_switch_driver {
327328
struct switchdev_trans *trans);
328329
int (*port_fdb_del)(struct dsa_switch *ds, int port,
329330
const struct switchdev_obj_port_fdb *fdb);
330-
int (*port_fdb_getnext)(struct dsa_switch *ds, int port,
331-
unsigned char *addr, u16 *vid,
332-
bool *is_static);
331+
int (*port_fdb_dump)(struct dsa_switch *ds, int port,
332+
struct switchdev_obj_port_fdb *fdb,
333+
int (*cb)(struct switchdev_obj *obj));
333334
};
334335

335336
void register_switch_driver(struct dsa_switch_driver *type);

net/dsa/slave.c

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -378,31 +378,11 @@ static int dsa_slave_port_fdb_dump(struct net_device *dev,
378378
{
379379
struct dsa_slave_priv *p = netdev_priv(dev);
380380
struct dsa_switch *ds = p->parent;
381-
unsigned char addr[ETH_ALEN] = { 0 };
382-
u16 vid = 0;
383-
int ret;
384-
385-
if (!ds->drv->port_fdb_getnext)
386-
return -EOPNOTSUPP;
387381

388-
for (;;) {
389-
bool is_static;
390-
391-
ret = ds->drv->port_fdb_getnext(ds, p->port, addr, &vid,
392-
&is_static);
393-
if (ret < 0)
394-
break;
382+
if (ds->drv->port_fdb_dump)
383+
return ds->drv->port_fdb_dump(ds, p->port, fdb, cb);
395384

396-
ether_addr_copy(fdb->addr, addr);
397-
fdb->vid = vid;
398-
fdb->ndm_state = is_static ? NUD_NOARP : NUD_REACHABLE;
399-
400-
ret = cb(&fdb->obj);
401-
if (ret < 0)
402-
break;
403-
}
404-
405-
return ret == -ENOENT ? 0 : ret;
385+
return -EOPNOTSUPP;
406386
}
407387

408388
static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)

0 commit comments

Comments
 (0)