ive tested this on: bge0 at pci4 dev 0 function 0 "Broadcom BCM5721" rev 0x21, BCM5750 C1 (0x4201): apic 0 int 16, address 00:18:f3:d1:80:64 brgphy0 at bge0 phy 1: BCM5750 10/100/1000baseT PHY, rev. 0
bge1 at pci5 dev 0 function 0 "Broadcom BCM5720" rev 0x00, BCM5720 A0 (0x5720000), APE firmware NCSI 1.0.85.0: apic 0 int 16, address d4:ae:52:a7:05:38 brgphy1 at bge1 phy 1: BCM5720C 10/100/1000baseT PHY, rev. 0 bge2 at pci5 dev 0 function 1 "Broadcom BCM5720" rev 0x00, BCM5720 A0 (0x5720000), APE firmware NCSI 1.0.85.0: apic 0 int 17, address d4:ae:52:a7:05:39 brgphy2 at bge2 phy 2: BCM5720C 10/100/1000baseT PHY, rev. 0 bge0 at pci3 dev 4 function 0 "Broadcom BCM5714" rev 0xa3, BCM5715 A3 (0x9003): ivec 0x795, address 00:14:4f:a9:34:90 brgphy0 at bge0 phy 1: BCM5714 10/100/1000baseT/SX PHY, rev. 0 bge1 at pci3 dev 4 function 1 "Broadcom BCM5714" rev 0xa3, BCM5715 A3 (0x9003): ivec 0x796, address 00:14:4f:a9:34:91 brgphy1 at bge1 phy 1: BCM5714 10/100/1000baseT/SX PHY, rev. 0 bge2 at pci7 dev 0 function 0 "Broadcom BCM5719" rev 0x01, unknown BCM5719 (0x5719001), APE firmware NCSI 1.0.60.0: ivec 0x795, address 00:10:18:e5:e1:b8 brgphy2 at bge2 phy 1: BCM5719C 10/100/1000baseT PHY, rev. 0 bge3 at pci7 dev 0 function 1 "Broadcom BCM5719" rev 0x01, unknown BCM5719 (0x5719001), APE firmware NCSI 1.0.60.0: ivec 0x796, address 00:10:18:e5:e1:b9 brgphy3 at bge3 phy 2: BCM5719C 10/100/1000baseT PHY, rev. 0 bge4 at pci7 dev 0 function 2 "Broadcom BCM5719" rev 0x01, unknown BCM5719 (0x5719001), APE firmware NCSI 1.0.60.0: ivec 0x795, address 00:10:18:e5:e1:ba brgphy4 at bge4 phy 3: BCM5719C 10/100/1000baseT PHY, rev. 0 bge5 at pci7 dev 0 function 3 "Broadcom BCM5719" rev 0x01, unknown BCM5719 (0x5719001), APE firmware NCSI 1.0.60.0: ivec 0x796, address 00:10:18:e5:e1:bb brgphy5 at bge5 phy 4: BCM5719C 10/100/1000baseT PHY, rev. 0 bge6 at pci13 dev 4 function 0 "Broadcom BCM5714" rev 0xa3, BCM5715 A3 (0x9003): ivec 0x7d6, address 00:14:4f:a9:34:92 working fine on each of them. makes sense to me. ok. On 28/05/2013, at 12:53 AM, Mike Belopuhov <m...@belopuhov.com> wrote: > Hi, > > While trying to fix the link state bug on BCM5719, David Imhoff > has arrived at conclusion that the chip won't generate proper > link state interrupts which renders auto-polling mode useless. > > As it turns out neither Linux nor FreeBSD use auto-polling mode > for anything newer than BCM5705 and recent Broadcom documentation > is not describing this method at all. > > This diff brings us in line with others, but requires heavy > testing on currently supported hardware. > > OK's are welcome as well. > > diff --git sys/dev/pci/if_bge.c sys/dev/pci/if_bge.c > index 1d37192..8007108 100644 > --- sys/dev/pci/if_bge.c > +++ sys/dev/pci/if_bge.c > @@ -1055,10 +1055,22 @@ bge_miibus_statchg(struct device *dev) > (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); > + else if (BGE_STS_BIT(sc, BGE_STS_LINK) && > + (!(mii->mii_media_status & IFM_ACTIVE) || > + IFM_SUBTYPE(mii->mii_media_active) == IFM_NONE)) > + BGE_STS_CLRBIT(sc, BGE_STS_LINK); > + > + if (!BGE_STS_BIT(sc, BGE_STS_LINK)) > + return; > + > /* Set the port mode (MII/GMII) to match the link speed. */ > mac_mode = CSR_READ_4(sc, BGE_MAC_MODE) & > ~(BGE_MACMODE_PORTMODE | BGE_MACMODE_HALF_DUPLEX); > tx_mode = CSR_READ_4(sc, BGE_TX_MODE); > rx_mode = CSR_READ_4(sc, BGE_RX_MODE); > @@ -1773,11 +1785,11 @@ int > bge_blockinit(struct bge_softc *sc) > { > volatile struct bge_rcb *rcb; > vaddr_t rcb_addr; > bge_hostaddr taddr; > - u_int32_t dmactl, val; > + u_int32_t dmactl, mimode, val; > int i, limit; > > /* > * Initialize the memory window pointer register so that > * we can access the first 32K of internal NIC RAM. This will > @@ -2369,13 +2381,23 @@ bge_blockinit(struct bge_softc *sc) > > /* Enable PHY auto polling (for MII/GMII only) */ > if (sc->bge_flags & BGE_PHY_FIBER_TBI) { > CSR_WRITE_4(sc, BGE_MI_STS, BGE_MISTS_LINK); > } else { > - BGE_STS_SETBIT(sc, BGE_STS_AUTOPOLL); > - BGE_SETBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL|10<<16); > - if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700) > + if ((sc->bge_flags & BGE_CPMU_PRESENT) != 0) > + mimode = BGE_MIMODE_500KHZ_CONST; > + else > + mimode = BGE_MIMODE_BASE; > + if (BGE_IS_5700_FAMILY(sc) || > + BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5705) { > + mimode |= BGE_MIMODE_AUTOPOLL; > + BGE_STS_SETBIT(sc, BGE_STS_AUTOPOLL); > + } > + mimode |= BGE_MIMODE_PHYADDR(sc->bge_phy_addr); > + CSR_WRITE_4(sc, BGE_MI_MODE, mimode); > + if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700 && > + sc->bge_chipid != BGE_CHIPID_BCM5700_B2) > CSR_WRITE_4(sc, BGE_MAC_EVT_ENB, > BGE_EVTENB_MI_INTERRUPT); > } > > /* > @@ -2719,13 +2741,10 @@ bge_attach(struct device *parent, struct device > *self, void *aux) > BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5761 || > BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5785 || > BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57780) > sc->bge_flags |= BGE_CPMU_PRESENT; > > - if ((sc->bge_flags & BGE_CPMU_PRESENT) != 0) > - BGE_SETBIT(sc, BGE_MI_MODE, BGE_MIMODE_500KHZ_CONST); > - > /* Try to reset the chip. */ > DPRINTFN(5, ("bge_reset\n")); > bge_sig_pre_reset(sc, BGE_RESET_START); > bge_reset(sc); > > @@ -4489,15 +4508,10 @@ bge_link_upd(struct bge_softc *sc) > BGE_STS_CLRBIT(sc, BGE_STS_LINK); > ifp->if_link_state = LINK_STATE_DOWN; > if_link_state_change(ifp); > ifp->if_baudrate = 0; > } > - /* > - * Discard link events for MII/GMII cards if MI auto-polling disabled. > - * This should not happen since mii callouts are locked now, but > - * we keep this check for debug. > - */ > } else if (BGE_STS_BIT(sc, BGE_STS_AUTOPOLL)) { > /* > * Some broken BCM chips have BGE_STATFLAG_LINKSTATE_CHANGED bit > * in status word always set. Workaround this bug by reading > * PHY link status directly. > @@ -4515,10 +4529,17 @@ bge_link_upd(struct bge_softc *sc) > else if (BGE_STS_BIT(sc, BGE_STS_LINK) && > (!(mii->mii_media_status & IFM_ACTIVE) || > IFM_SUBTYPE(mii->mii_media_active) == IFM_NONE)) > BGE_STS_CLRBIT(sc, BGE_STS_LINK); > } > + } else { > + /* > + * 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| > diff --git sys/dev/pci/if_bgereg.h sys/dev/pci/if_bgereg.h > index a6846bc..852fffa 100644 > --- sys/dev/pci/if_bgereg.h > +++ sys/dev/pci/if_bgereg.h > @@ -961,10 +961,11 @@ > #define BGE_MIMODE_SHORTPREAMBLE 0x00000002 > #define BGE_MIMODE_AUTOPOLL 0x00000010 > #define BGE_MIMODE_CLKCNT 0x001F0000 > #define BGE_MIMODE_500KHZ_CONST 0x00008000 > #define BGE_MIMODE_BASE 0x000C0000 > +#define BGE_MIMODE_PHYADDR(x) ((x & 0x1F) << 5) > > /* > * Send data initiator control registers. > */ > #define BGE_SDI_MODE 0x0C00 >