Commit bb8d53fd authored by Vladimir Oltean's avatar Vladimir Oltean Committed by Jakub Kicinski

net: mscc: ocelot: make entry_type a member of struct ocelot_multicast

This saves a re-classification of the MDB address on deletion.
Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 728e69ae
...@@ -962,7 +962,7 @@ static enum macaccess_entry_type ocelot_classify_mdb(const unsigned char *addr) ...@@ -962,7 +962,7 @@ static enum macaccess_entry_type ocelot_classify_mdb(const unsigned char *addr)
} }
static int ocelot_mdb_get_pgid(struct ocelot *ocelot, static int ocelot_mdb_get_pgid(struct ocelot *ocelot,
enum macaccess_entry_type entry_type) const struct ocelot_multicast *mc)
{ {
int pgid; int pgid;
...@@ -971,8 +971,8 @@ static int ocelot_mdb_get_pgid(struct ocelot *ocelot, ...@@ -971,8 +971,8 @@ static int ocelot_mdb_get_pgid(struct ocelot *ocelot,
* destination mask table (PGID), the destination set is programmed as * destination mask table (PGID), the destination set is programmed as
* part of the entry MAC address.", and the DEST_IDX is set to 0. * part of the entry MAC address.", and the DEST_IDX is set to 0.
*/ */
if (entry_type == ENTRYTYPE_MACv4 || if (mc->entry_type == ENTRYTYPE_MACv4 ||
entry_type == ENTRYTYPE_MACv6) mc->entry_type == ENTRYTYPE_MACv6)
return 0; return 0;
for_each_nonreserved_multicast_dest_pgid(ocelot, pgid) { for_each_nonreserved_multicast_dest_pgid(ocelot, pgid) {
...@@ -994,16 +994,15 @@ static int ocelot_mdb_get_pgid(struct ocelot *ocelot, ...@@ -994,16 +994,15 @@ static int ocelot_mdb_get_pgid(struct ocelot *ocelot,
} }
static void ocelot_encode_ports_to_mdb(unsigned char *addr, static void ocelot_encode_ports_to_mdb(unsigned char *addr,
struct ocelot_multicast *mc, struct ocelot_multicast *mc)
enum macaccess_entry_type entry_type)
{ {
ether_addr_copy(addr, mc->addr); ether_addr_copy(addr, mc->addr);
if (entry_type == ENTRYTYPE_MACv4) { if (mc->entry_type == ENTRYTYPE_MACv4) {
addr[0] = 0; addr[0] = 0;
addr[1] = mc->ports >> 8; addr[1] = mc->ports >> 8;
addr[2] = mc->ports & 0xff; addr[2] = mc->ports & 0xff;
} else if (entry_type == ENTRYTYPE_MACv6) { } else if (mc->entry_type == ENTRYTYPE_MACv6) {
addr[0] = mc->ports >> 8; addr[0] = mc->ports >> 8;
addr[1] = mc->ports & 0xff; addr[1] = mc->ports & 0xff;
} }
...@@ -1013,7 +1012,6 @@ int ocelot_port_mdb_add(struct ocelot *ocelot, int port, ...@@ -1013,7 +1012,6 @@ int ocelot_port_mdb_add(struct ocelot *ocelot, int port,
const struct switchdev_obj_port_mdb *mdb) const struct switchdev_obj_port_mdb *mdb)
{ {
struct ocelot_port *ocelot_port = ocelot->ports[port]; struct ocelot_port *ocelot_port = ocelot->ports[port];
enum macaccess_entry_type entry_type;
unsigned char addr[ETH_ALEN]; unsigned char addr[ETH_ALEN];
struct ocelot_multicast *mc; struct ocelot_multicast *mc;
u16 vid = mdb->vid; u16 vid = mdb->vid;
...@@ -1024,12 +1022,20 @@ int ocelot_port_mdb_add(struct ocelot *ocelot, int port, ...@@ -1024,12 +1022,20 @@ int ocelot_port_mdb_add(struct ocelot *ocelot, int port,
if (!vid) if (!vid)
vid = ocelot_port->pvid; vid = ocelot_port->pvid;
entry_type = ocelot_classify_mdb(mdb->addr);
mc = ocelot_multicast_get(ocelot, mdb->addr, vid); mc = ocelot_multicast_get(ocelot, mdb->addr, vid);
if (!mc) { if (!mc) {
/* New entry */ /* New entry */
int pgid = ocelot_mdb_get_pgid(ocelot, entry_type); int pgid;
mc = devm_kzalloc(ocelot->dev, sizeof(*mc), GFP_KERNEL);
if (!mc)
return -ENOMEM;
mc->entry_type = ocelot_classify_mdb(mdb->addr);
ether_addr_copy(mc->addr, mdb->addr);
mc->vid = vid;
pgid = ocelot_mdb_get_pgid(ocelot, mc);
if (pgid < 0) { if (pgid < 0) {
dev_err(ocelot->dev, dev_err(ocelot->dev,
...@@ -1038,24 +1044,19 @@ int ocelot_port_mdb_add(struct ocelot *ocelot, int port, ...@@ -1038,24 +1044,19 @@ int ocelot_port_mdb_add(struct ocelot *ocelot, int port,
return -ENOSPC; return -ENOSPC;
} }
mc = devm_kzalloc(ocelot->dev, sizeof(*mc), GFP_KERNEL);
if (!mc)
return -ENOMEM;
ether_addr_copy(mc->addr, mdb->addr);
mc->vid = vid;
mc->pgid = pgid; mc->pgid = pgid;
list_add_tail(&mc->list, &ocelot->multicast); list_add_tail(&mc->list, &ocelot->multicast);
} else { } else {
ocelot_encode_ports_to_mdb(addr, mc, entry_type); ocelot_encode_ports_to_mdb(addr, mc);
ocelot_mact_forget(ocelot, addr, vid); ocelot_mact_forget(ocelot, addr, vid);
} }
mc->ports |= BIT(port); mc->ports |= BIT(port);
ocelot_encode_ports_to_mdb(addr, mc, entry_type); ocelot_encode_ports_to_mdb(addr, mc);
return ocelot_mact_learn(ocelot, mc->pgid, addr, vid, entry_type); return ocelot_mact_learn(ocelot, mc->pgid, addr, vid,
mc->entry_type);
} }
EXPORT_SYMBOL(ocelot_port_mdb_add); EXPORT_SYMBOL(ocelot_port_mdb_add);
...@@ -1063,7 +1064,6 @@ int ocelot_port_mdb_del(struct ocelot *ocelot, int port, ...@@ -1063,7 +1064,6 @@ int ocelot_port_mdb_del(struct ocelot *ocelot, int port,
const struct switchdev_obj_port_mdb *mdb) const struct switchdev_obj_port_mdb *mdb)
{ {
struct ocelot_port *ocelot_port = ocelot->ports[port]; struct ocelot_port *ocelot_port = ocelot->ports[port];
enum macaccess_entry_type entry_type;
unsigned char addr[ETH_ALEN]; unsigned char addr[ETH_ALEN];
struct ocelot_multicast *mc; struct ocelot_multicast *mc;
u16 vid = mdb->vid; u16 vid = mdb->vid;
...@@ -1078,9 +1078,7 @@ int ocelot_port_mdb_del(struct ocelot *ocelot, int port, ...@@ -1078,9 +1078,7 @@ int ocelot_port_mdb_del(struct ocelot *ocelot, int port,
if (!mc) if (!mc)
return -ENOENT; return -ENOENT;
entry_type = ocelot_classify_mdb(mdb->addr); ocelot_encode_ports_to_mdb(addr, mc);
ocelot_encode_ports_to_mdb(addr, mc, entry_type);
ocelot_mact_forget(ocelot, addr, vid); ocelot_mact_forget(ocelot, addr, vid);
mc->ports &= ~BIT(port); mc->ports &= ~BIT(port);
...@@ -1090,9 +1088,10 @@ int ocelot_port_mdb_del(struct ocelot *ocelot, int port, ...@@ -1090,9 +1088,10 @@ int ocelot_port_mdb_del(struct ocelot *ocelot, int port,
return 0; return 0;
} }
ocelot_encode_ports_to_mdb(addr, mc, entry_type); ocelot_encode_ports_to_mdb(addr, mc);
return ocelot_mact_learn(ocelot, mc->pgid, addr, vid, entry_type); return ocelot_mact_learn(ocelot, mc->pgid, addr, vid,
mc->entry_type);
} }
EXPORT_SYMBOL(ocelot_port_mdb_del); EXPORT_SYMBOL(ocelot_port_mdb_del);
......
...@@ -41,14 +41,6 @@ struct frame_info { ...@@ -41,14 +41,6 @@ struct frame_info {
u32 timestamp; /* rew_val */ u32 timestamp; /* rew_val */
}; };
struct ocelot_multicast {
struct list_head list;
unsigned char addr[ETH_ALEN];
u16 vid;
u16 ports;
int pgid;
};
struct ocelot_port_tc { struct ocelot_port_tc {
bool block_shared; bool block_shared;
unsigned long offload_cnt; unsigned long offload_cnt;
...@@ -87,6 +79,15 @@ enum macaccess_entry_type { ...@@ -87,6 +79,15 @@ enum macaccess_entry_type {
ENTRYTYPE_MACv6, ENTRYTYPE_MACv6,
}; };
struct ocelot_multicast {
struct list_head list;
enum macaccess_entry_type entry_type;
unsigned char addr[ETH_ALEN];
u16 vid;
u16 ports;
int pgid;
};
int ocelot_port_fdb_do_dump(const unsigned char *addr, u16 vid, int ocelot_port_fdb_do_dump(const unsigned char *addr, u16 vid,
bool is_static, void *data); bool is_static, void *data);
int ocelot_mact_learn(struct ocelot *ocelot, int port, int ocelot_mact_learn(struct ocelot *ocelot, int port,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment