Message ID | 20201208120802.1268708-11-vladimir.oltean@nxp.com (mailing list archive) |
---|---|
State | RFC |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | LAG offload for Ocelot DSA switches | expand |
Context | Check | Description |
---|---|---|
netdev/cover_letter | success | Link |
netdev/fixes_present | success | Link |
netdev/patch_count | fail | Series longer than 15 patches |
netdev/tree_selection | success | Clearly marked for net-next |
netdev/subject_prefix | success | Link |
netdev/source_inline | success | Was 0 now: 0 |
netdev/verify_signedoff | success | Link |
netdev/module_param | success | Was 0 now: 0 |
netdev/build_32bit | fail | Errors and warnings before: 4 this patch: 4 |
netdev/kdoc | success | Errors and warnings before: 0 this patch: 0 |
netdev/verify_fixes | success | Link |
netdev/checkpatch | warning | WARNING: line length of 82 exceeds 80 columns |
netdev/build_allmodconfig_warn | fail | Errors and warnings before: 4 this patch: 4 |
netdev/header_inline | success | Link |
netdev/stable | success | Stable not CCed |
On 08/12/2020 14:07:56+0200, Vladimir Oltean wrote: > 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. > > Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com> > --- > drivers/net/ethernet/mscc/ocelot.c | 68 +++++++++++++++++------------- > 1 file changed, 38 insertions(+), 30 deletions(-) > > diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c > index c3c6682e6e79..ee0fcee8e09a 100644 > --- a/drivers/net/ethernet/mscc/ocelot.c > +++ b/drivers/net/ethernet/mscc/ocelot.c > @@ -899,11 +899,45 @@ static u32 ocelot_get_bond_mask(struct ocelot *ocelot, struct net_device *bond) > return bond_mask; > } > > +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. If the source port is in a bond, then > + * all the other ports from that bond need to be removed from this > + * source port's forwarding mask. > + */ > + 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) > { > struct ocelot_port *ocelot_port = ocelot->ports[port]; > u32 port_cfg; > - int p; > > if (!(BIT(port) & ocelot->bridge_mask)) > return; > @@ -927,35 +961,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. If the source port is in a bond, then > - * all the other ports from that bond need to be removed from this > - * source port's forwarding mask. > - */ > - 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); > - 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(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); > > @@ -1315,6 +1321,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; > @@ -1350,6 +1357,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); > -- > 2.25.1 >
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c index c3c6682e6e79..ee0fcee8e09a 100644 --- a/drivers/net/ethernet/mscc/ocelot.c +++ b/drivers/net/ethernet/mscc/ocelot.c @@ -899,11 +899,45 @@ static u32 ocelot_get_bond_mask(struct ocelot *ocelot, struct net_device *bond) return bond_mask; } +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. If the source port is in a bond, then + * all the other ports from that bond need to be removed from this + * source port's forwarding mask. + */ + 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) { struct ocelot_port *ocelot_port = ocelot->ports[port]; u32 port_cfg; - int p; if (!(BIT(port) & ocelot->bridge_mask)) return; @@ -927,35 +961,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. If the source port is in a bond, then - * all the other ports from that bond need to be removed from this - * source port's forwarding mask. - */ - 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); - 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(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); @@ -1315,6 +1321,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; @@ -1350,6 +1357,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);
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. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> --- drivers/net/ethernet/mscc/ocelot.c | 68 +++++++++++++++++------------- 1 file changed, 38 insertions(+), 30 deletions(-)