Skip to content

Commit

Permalink
net: mscc: ocelot: reapply bridge forwarding mask on bonding join/leave
Browse files Browse the repository at this point in the history
Applying the bridge forwarding mask currently is done only on the STP
state changes for any port. But it depends on both STP state changes,
and bonding interface state changes. Export the bit that recalculates
the forwarding mask so that it could be reused, and call it when a port
starts and stops offloading a bonding interface.

Now that the logic is split into a separate function, we can rename "p"
into "port", since the "port" variable was already taken in
ocelot_bridge_stp_state_set. Also, we can rename "i" into "lag", to make
it more clear what is it that we're iterating through.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Vladimir Oltean authored and Jakub Kicinski committed Jan 30, 2021
1 parent 50c6cc5 commit 9b52125
Showing 1 changed file with 36 additions and 27 deletions.
63 changes: 36 additions & 27 deletions drivers/net/ethernet/mscc/ocelot.c
Original file line number Diff line number Diff line change
Expand Up @@ -889,10 +889,42 @@ int ocelot_get_ts_info(struct ocelot *ocelot, int port,
}
EXPORT_SYMBOL(ocelot_get_ts_info);

static void ocelot_apply_bridge_fwd_mask(struct ocelot *ocelot)
{
int port;

/* Apply FWD mask. The loop is needed to add/remove the current port as
* a source for the other ports.
*/
for (port = 0; port < ocelot->num_phys_ports; port++) {
if (ocelot->bridge_fwd_mask & BIT(port)) {
unsigned long mask = ocelot->bridge_fwd_mask & ~BIT(port);
int lag;

for (lag = 0; lag < ocelot->num_phys_ports; lag++) {
unsigned long bond_mask = ocelot->lags[lag];

if (!bond_mask)
continue;

if (bond_mask & BIT(port)) {
mask &= ~bond_mask;
break;
}
}

ocelot_write_rix(ocelot, mask,
ANA_PGID_PGID, PGID_SRC + port);
} else {
ocelot_write_rix(ocelot, 0,
ANA_PGID_PGID, PGID_SRC + port);
}
}
}

void ocelot_bridge_stp_state_set(struct ocelot *ocelot, int port, u8 state)
{
u32 port_cfg;
int p, i;

if (!(BIT(port) & ocelot->bridge_mask))
return;
Expand All @@ -915,32 +947,7 @@ void ocelot_bridge_stp_state_set(struct ocelot *ocelot, int port, u8 state)

ocelot_write_gix(ocelot, port_cfg, ANA_PORT_PORT_CFG, port);

/* Apply FWD mask. The loop is needed to add/remove the current port as
* a source for the other ports.
*/
for (p = 0; p < ocelot->num_phys_ports; p++) {
if (ocelot->bridge_fwd_mask & BIT(p)) {
unsigned long mask = ocelot->bridge_fwd_mask & ~BIT(p);

for (i = 0; i < ocelot->num_phys_ports; i++) {
unsigned long bond_mask = ocelot->lags[i];

if (!bond_mask)
continue;

if (bond_mask & BIT(p)) {
mask &= ~bond_mask;
break;
}
}

ocelot_write_rix(ocelot, mask,
ANA_PGID_PGID, PGID_SRC + p);
} else {
ocelot_write_rix(ocelot, 0,
ANA_PGID_PGID, PGID_SRC + p);
}
}
ocelot_apply_bridge_fwd_mask(ocelot);
}
EXPORT_SYMBOL(ocelot_bridge_stp_state_set);

Expand Down Expand Up @@ -1297,6 +1304,7 @@ int ocelot_port_lag_join(struct ocelot *ocelot, int port,
}

ocelot_setup_lag(ocelot, lag);
ocelot_apply_bridge_fwd_mask(ocelot);
ocelot_set_aggr_pgids(ocelot);

return 0;
Expand Down Expand Up @@ -1330,6 +1338,7 @@ void ocelot_port_lag_leave(struct ocelot *ocelot, int port,
ocelot_write_gix(ocelot, port_cfg | ANA_PORT_PORT_CFG_PORTID_VAL(port),
ANA_PORT_PORT_CFG, port);

ocelot_apply_bridge_fwd_mask(ocelot);
ocelot_set_aggr_pgids(ocelot);
}
EXPORT_SYMBOL(ocelot_port_lag_leave);
Expand Down

0 comments on commit 9b52125

Please sign in to comment.