Skip to content

Commit 83dabd1

Browse files
viviendavem330
authored andcommitted
net: dsa: mv88e6xxx: make switchdev DB ops generic
The MDB support for the mv88e6xxx driver will be very similar to the FDB support, since it consists of loading/purging/dumping address to/from the Address Translation Unit (ATU). Prepare the support for MDB by making the FDB code accessing the ATU generic. The FDB operations now provide access to the unicast addresses while the MDB operations will provide access to the multicast addresses. Signed-off-by: Vivien Didelot <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 8df3025 commit 83dabd1

File tree

1 file changed

+57
-43
lines changed
  • drivers/net/dsa/mv88e6xxx

1 file changed

+57
-43
lines changed

drivers/net/dsa/mv88e6xxx/chip.c

Lines changed: 57 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2093,9 +2093,9 @@ static int _mv88e6xxx_atu_load(struct mv88e6xxx_chip *chip,
20932093
return _mv88e6xxx_atu_cmd(chip, entry->fid, GLOBAL_ATU_OP_LOAD_DB);
20942094
}
20952095

2096-
static int _mv88e6xxx_port_fdb_load(struct mv88e6xxx_chip *chip, int port,
2097-
const unsigned char *addr, u16 vid,
2098-
u8 state)
2096+
static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
2097+
const unsigned char *addr, u16 vid,
2098+
u8 state)
20992099
{
21002100
struct mv88e6xxx_atu_entry entry = { 0 };
21012101
struct mv88e6xxx_vtu_stu_entry vlan;
@@ -2134,30 +2134,27 @@ static void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
21342134
const struct switchdev_obj_port_fdb *fdb,
21352135
struct switchdev_trans *trans)
21362136
{
2137-
int state = is_multicast_ether_addr(fdb->addr) ?
2138-
GLOBAL_ATU_DATA_STATE_MC_STATIC :
2139-
GLOBAL_ATU_DATA_STATE_UC_STATIC;
21402137
struct mv88e6xxx_chip *chip = ds_to_priv(ds);
21412138

21422139
mutex_lock(&chip->reg_lock);
2143-
if (_mv88e6xxx_port_fdb_load(chip, port, fdb->addr, fdb->vid, state))
2144-
netdev_err(ds->ports[port].netdev,
2145-
"failed to load MAC address\n");
2140+
if (mv88e6xxx_port_db_load_purge(chip, port, fdb->addr, fdb->vid,
2141+
GLOBAL_ATU_DATA_STATE_UC_STATIC))
2142+
netdev_err(ds->ports[port].netdev, "failed to load unicast MAC address\n");
21462143
mutex_unlock(&chip->reg_lock);
21472144
}
21482145

21492146
static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
21502147
const struct switchdev_obj_port_fdb *fdb)
21512148
{
21522149
struct mv88e6xxx_chip *chip = ds_to_priv(ds);
2153-
int ret;
2150+
int err;
21542151

21552152
mutex_lock(&chip->reg_lock);
2156-
ret = _mv88e6xxx_port_fdb_load(chip, port, fdb->addr, fdb->vid,
2157-
GLOBAL_ATU_DATA_STATE_UNUSED);
2153+
err = mv88e6xxx_port_db_load_purge(chip, port, fdb->addr, fdb->vid,
2154+
GLOBAL_ATU_DATA_STATE_UNUSED);
21582155
mutex_unlock(&chip->reg_lock);
21592156

2160-
return ret;
2157+
return err;
21612158
}
21622159

21632160
static int _mv88e6xxx_atu_getnext(struct mv88e6xxx_chip *chip, u16 fid,
@@ -2205,10 +2202,10 @@ static int _mv88e6xxx_atu_getnext(struct mv88e6xxx_chip *chip, u16 fid,
22052202
return 0;
22062203
}
22072204

2208-
static int _mv88e6xxx_port_fdb_dump_one(struct mv88e6xxx_chip *chip,
2209-
u16 fid, u16 vid, int port,
2210-
struct switchdev_obj_port_fdb *fdb,
2211-
int (*cb)(struct switchdev_obj *obj))
2205+
static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
2206+
u16 fid, u16 vid, int port,
2207+
struct switchdev_obj *obj,
2208+
int (*cb)(struct switchdev_obj *obj))
22122209
{
22132210
struct mv88e6xxx_atu_entry addr = {
22142211
.mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
@@ -2222,72 +2219,89 @@ static int _mv88e6xxx_port_fdb_dump_one(struct mv88e6xxx_chip *chip,
22222219
do {
22232220
err = _mv88e6xxx_atu_getnext(chip, fid, &addr);
22242221
if (err)
2225-
break;
2222+
return err;
22262223

22272224
if (addr.state == GLOBAL_ATU_DATA_STATE_UNUSED)
22282225
break;
22292226

2230-
if (!addr.trunk && addr.portv_trunkid & BIT(port)) {
2231-
bool is_static = addr.state ==
2232-
(is_multicast_ether_addr(addr.mac) ?
2233-
GLOBAL_ATU_DATA_STATE_MC_STATIC :
2234-
GLOBAL_ATU_DATA_STATE_UC_STATIC);
2227+
if (addr.trunk || (addr.portv_trunkid & BIT(port)) == 0)
2228+
continue;
2229+
2230+
if (obj->id == SWITCHDEV_OBJ_ID_PORT_FDB) {
2231+
struct switchdev_obj_port_fdb *fdb;
22352232

2233+
if (!is_unicast_ether_addr(addr.mac))
2234+
continue;
2235+
2236+
fdb = SWITCHDEV_OBJ_PORT_FDB(obj);
22362237
fdb->vid = vid;
22372238
ether_addr_copy(fdb->addr, addr.mac);
2238-
fdb->ndm_state = is_static ? NUD_NOARP : NUD_REACHABLE;
2239-
2240-
err = cb(&fdb->obj);
2241-
if (err)
2242-
break;
2239+
if (addr.state == GLOBAL_ATU_DATA_STATE_UC_STATIC)
2240+
fdb->ndm_state = NUD_NOARP;
2241+
else
2242+
fdb->ndm_state = NUD_REACHABLE;
2243+
} else {
2244+
return -EOPNOTSUPP;
22432245
}
2246+
2247+
err = cb(obj);
2248+
if (err)
2249+
return err;
22442250
} while (!is_broadcast_ether_addr(addr.mac));
22452251

22462252
return err;
22472253
}
22482254

2249-
static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
2250-
struct switchdev_obj_port_fdb *fdb,
2251-
int (*cb)(struct switchdev_obj *obj))
2255+
static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
2256+
struct switchdev_obj *obj,
2257+
int (*cb)(struct switchdev_obj *obj))
22522258
{
2253-
struct mv88e6xxx_chip *chip = ds_to_priv(ds);
22542259
struct mv88e6xxx_vtu_stu_entry vlan = {
22552260
.vid = GLOBAL_VTU_VID_MASK, /* all ones */
22562261
};
22572262
u16 fid;
22582263
int err;
22592264

2260-
mutex_lock(&chip->reg_lock);
2261-
22622265
/* Dump port's default Filtering Information Database (VLAN ID 0) */
22632266
err = _mv88e6xxx_port_fid_get(chip, port, &fid);
22642267
if (err)
2265-
goto unlock;
2268+
return err;
22662269

2267-
err = _mv88e6xxx_port_fdb_dump_one(chip, fid, 0, port, fdb, cb);
2270+
err = mv88e6xxx_port_db_dump_fid(chip, fid, 0, port, obj, cb);
22682271
if (err)
2269-
goto unlock;
2272+
return err;
22702273

22712274
/* Dump VLANs' Filtering Information Databases */
22722275
err = _mv88e6xxx_vtu_vid_write(chip, vlan.vid);
22732276
if (err)
2274-
goto unlock;
2277+
return err;
22752278

22762279
do {
22772280
err = _mv88e6xxx_vtu_getnext(chip, &vlan);
22782281
if (err)
2279-
break;
2282+
return err;
22802283

22812284
if (!vlan.valid)
22822285
break;
22832286

2284-
err = _mv88e6xxx_port_fdb_dump_one(chip, vlan.fid, vlan.vid,
2285-
port, fdb, cb);
2287+
err = mv88e6xxx_port_db_dump_fid(chip, vlan.fid, vlan.vid, port,
2288+
obj, cb);
22862289
if (err)
2287-
break;
2290+
return err;
22882291
} while (vlan.vid < GLOBAL_VTU_VID_MASK);
22892292

2290-
unlock:
2293+
return err;
2294+
}
2295+
2296+
static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
2297+
struct switchdev_obj_port_fdb *fdb,
2298+
int (*cb)(struct switchdev_obj *obj))
2299+
{
2300+
struct mv88e6xxx_chip *chip = ds_to_priv(ds);
2301+
int err;
2302+
2303+
mutex_lock(&chip->reg_lock);
2304+
err = mv88e6xxx_port_db_dump(chip, port, &fdb->obj, cb);
22912305
mutex_unlock(&chip->reg_lock);
22922306

22932307
return err;

0 commit comments

Comments
 (0)