Skip to content

Commit

Permalink
net: dsa: felix: move the updating of PGID_CPU to the ocelot lib
Browse files Browse the repository at this point in the history
PGID_CPU must be updated every time a port is configured or unconfigured
as a tag_8021q CPU port. The ocelot switch lib already has a hook for
that operation, so move the updating of PGID_CPU to those hooks.

These bits are pretty specific to DSA, so normally I would keep them out
of the common switch lib, but when tag_8021q is in use, this has
implications upon the forwarding mask determined by
ocelot_apply_bridge_fwd_mask() and called extensively by the switch lib.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Vladimir Oltean authored and David S. Miller committed May 23, 2022
1 parent 129b753 commit 61be79b
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 7 deletions.
7 changes: 0 additions & 7 deletions drivers/net/dsa/ocelot/felix.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,9 +253,6 @@ static void felix_8021q_cpu_port_init(struct ocelot *ocelot, int port)

ocelot_port_set_dsa_8021q_cpu(ocelot, port);

/* Overwrite PGID_CPU with the non-tagging port */
ocelot_write_rix(ocelot, BIT(port), ANA_PGID_PGID, PGID_CPU);

ocelot_apply_bridge_fwd_mask(ocelot, true);

mutex_unlock(&ocelot->fwd_domain_lock);
Expand All @@ -267,10 +264,6 @@ static void felix_8021q_cpu_port_deinit(struct ocelot *ocelot, int port)

ocelot_port_unset_dsa_8021q_cpu(ocelot, port);

/* Restore PGID_CPU */
ocelot_write_rix(ocelot, BIT(ocelot->num_phys_ports), ANA_PGID_PGID,
PGID_CPU);

ocelot_apply_bridge_fwd_mask(ocelot, true);

mutex_unlock(&ocelot->fwd_domain_lock);
Expand Down
31 changes: 31 additions & 0 deletions drivers/net/ethernet/mscc/ocelot.c
Original file line number Diff line number Diff line change
Expand Up @@ -2165,6 +2165,33 @@ void ocelot_apply_bridge_fwd_mask(struct ocelot *ocelot, bool joining)
}
EXPORT_SYMBOL(ocelot_apply_bridge_fwd_mask);

/* Update PGID_CPU which is the destination port mask used for whitelisting
* unicast addresses filtered towards the host. In the normal and NPI modes,
* this points to the analyzer entry for the CPU port module, while in DSA
* tag_8021q mode, it is a bit mask of all active CPU ports.
* PGID_SRC will take care of forwarding a packet from one user port to
* no more than a single CPU port.
*/
static void ocelot_update_pgid_cpu(struct ocelot *ocelot)
{
int pgid_cpu = 0;
int port;

for (port = 0; port < ocelot->num_phys_ports; port++) {
struct ocelot_port *ocelot_port = ocelot->ports[port];

if (!ocelot_port || !ocelot_port->is_dsa_8021q_cpu)
continue;

pgid_cpu |= BIT(port);
}

if (!pgid_cpu)
pgid_cpu = BIT(ocelot->num_phys_ports);

ocelot_write_rix(ocelot, pgid_cpu, ANA_PGID_PGID, PGID_CPU);
}

void ocelot_port_set_dsa_8021q_cpu(struct ocelot *ocelot, int port)
{
u16 vid;
Expand All @@ -2173,6 +2200,8 @@ void ocelot_port_set_dsa_8021q_cpu(struct ocelot *ocelot, int port)

for (vid = OCELOT_RSV_VLAN_RANGE_START; vid < VLAN_N_VID; vid++)
ocelot_vlan_member_add(ocelot, port, vid, true);

ocelot_update_pgid_cpu(ocelot);
}
EXPORT_SYMBOL_GPL(ocelot_port_set_dsa_8021q_cpu);

Expand All @@ -2184,6 +2213,8 @@ void ocelot_port_unset_dsa_8021q_cpu(struct ocelot *ocelot, int port)

for (vid = OCELOT_RSV_VLAN_RANGE_START; vid < VLAN_N_VID; vid++)
ocelot_vlan_member_del(ocelot, port, vid);

ocelot_update_pgid_cpu(ocelot);
}
EXPORT_SYMBOL_GPL(ocelot_port_unset_dsa_8021q_cpu);

Expand Down

0 comments on commit 61be79b

Please sign in to comment.