I've got test report for the BCM5723/BCM5784. It would be great if someone with a 5703 or 5704 could try this.
On Thu, Jun 13, 2013 at 18:09 +0200, Mike Belopuhov wrote: > Hi, > > David Imhoff has found that flow control got broken in bge > after some recent changes but also that simple "ifconfig bge0" > call done by any user can change current flow control settings. > We've tested it on a bunch of recent cards (5719, 5720), one > old-ish card (5715) but would like others to make sure their > bge's are running fine with this. Changes must be visible > under substantial load from multiple clients. > > An elaborate explanation from David: > > ---------8<--------- > > If auto polling is disabled bge_link_upd() @l4546 does a call to > mii_pollstat() followed by a explicit call to bge_miibus_statchg(). > However bge_miibus_statchg() is also called implicitly from > mii_pollstat() -> brgphy_service(,, MII_POLLSTAT) -> mii_phy_update(). > > bge_miibus_statchg() @l1056 obtains the flow control state from > mii->mii_media_active and afterwards removes the flow control information > from mii->mii_media_active. So the second time bge_miibus_statchg() is > called the flow control flags in mii->mii_media_active are always zero. > And thus flow control on the card is disabled > > Clearing the flow control flags from mii->mii_media_active has one other > disadvantage. That is that the next call to mii_pollstat(), for example > by running 'ifconfig bge0', will trigger bge_miibus_statchg() to be > executed, because mii->mii_media_active and the newly obtained status > don't match. > > This last rogue call to bge_miibus_statchg() has a nasty side effect. > Which is that the flow control flags in mii->mii_media_active will > be equal to bge_flow_flags. Thus the flow contol flags will not be > cleared from mii->mii_media_active. At the bottom of the function > flow control is only enabled if the global options _equal_ full > duplex, however the IFM_FLOW flag is also part of the global options. > Thus a simple call to 'ifconfig bge0' can effectively disable > flow control. > > ---------8<--------- > > OK's are welcome as well. > > diff --git sys/dev/pci/if_bge.c sys/dev/pci/if_bge.c > index 3d396cc..7001b6f 100644 > --- sys/dev/pci/if_bge.c > +++ sys/dev/pci/if_bge.c > @@ -1050,14 +1050,12 @@ bge_miibus_statchg(struct device *dev) > > /* > * Get flow control negotiation result. > */ > if (IFM_SUBTYPE(mii->mii_media.ifm_cur->ifm_media) == IFM_AUTO && > - (mii->mii_media_active & IFM_ETH_FMASK) != sc->bge_flowflags) { > + (mii->mii_media_active & IFM_ETH_FMASK) != sc->bge_flowflags) > sc->bge_flowflags = mii->mii_media_active & IFM_ETH_FMASK; > - mii->mii_media_active &= ~IFM_ETH_FMASK; > - } > > if (!BGE_STS_BIT(sc, BGE_STS_LINK) && > mii->mii_media_status & IFM_ACTIVE && > IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) > BGE_STS_SETBIT(sc, BGE_STS_LINK); > @@ -1082,11 +1080,11 @@ bge_miibus_statchg(struct device *dev) > mac_mode |= BGE_PORTMODE_MII; > > /* Set MAC flow control behavior to match link flow control settings. */ > tx_mode &= ~BGE_TXMODE_FLOWCTL_ENABLE; > rx_mode &= ~BGE_RXMODE_FLOWCTL_ENABLE; > - if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) { > + if (mii->mii_media_active & IFM_FDX) { > if (sc->bge_flowflags & IFM_ETH_TXPAUSE) > tx_mode |= BGE_TXMODE_FLOWCTL_ENABLE; > if (sc->bge_flowflags & IFM_ETH_RXPAUSE) > rx_mode |= BGE_RXMODE_FLOWCTL_ENABLE; > } else > @@ -4542,11 +4540,10 @@ bge_link_upd(struct bge_softc *sc) > /* > * For controllers that call mii_tick, we have to poll > * link status. > */ > mii_pollstat(mii); > - bge_miibus_statchg(&sc->bge_dev); > } > > /* Clear the attention */ > CSR_WRITE_4(sc, BGE_MAC_STS, BGE_MACSTAT_SYNC_CHANGED| > BGE_MACSTAT_CFG_CHANGED|BGE_MACSTAT_MI_COMPLETE|