On 2013-05-24 23:37, Mike Belopuhov wrote:
<...>
I also noticed if_bge.c line 2293:
BGE_SETBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL|10<<16);
Does any one have a clue why the (10<<16) is there? it changes the
MI clock. But why? and why OR 0xA with the default 0xC, instead of
0x2? FreeBSD and Linux use the default of 0xC for the MI Clock.

I think it's a remnant of the original code and it should be
BGE_MIMODE_BASE (as in "the other frequency").

But since BGE_MIMODE_BASE is the default value after reset and
OR'ing the value wouldn't be correct, I suggest to just remove
the '|(10<<16)'.


I'm not OR'ing it in, I'm overwriting the value.

Sorry, i meant in the old code.

<...>
This also changes the "Use Short Preamble" flag and "PHY Address"
which are not 0 by default.


I've followed FreeBSD here. If you inspect the Linux driver you'll
find the same:

http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/broadcom/tg3.c#n16149
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/broadcom/tg3.c#n1479

I guess we need to think about it a bit more.
Tests will help though.

Ok, I tested this with a Broadcom BCM5721. Auto-polling doesn't work
anymore when the "PHY Address" is set to 0. So I added setting of the
correct phy address in the patch below. Clearing "Use Short Preamble"
doesn't seem to matter, and is also the default for older chips.

Apart from that I think the patch is ok.

Kind regards,

David

Index: sys/dev/pci/if_bge.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_bge.c,v
retrieving revision 1.328
diff -u -p -r1.328 if_bge.c
--- sys/dev/pci/if_bge.c        22 May 2013 16:02:31 -0000      1.328
+++ sys/dev/pci/if_bge.c        27 May 2013 13:01:24 -0000
@@ -1057,6 +1057,18 @@ bge_miibus_statchg(struct device *dev)
                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);
@@ -1775,7 +1787,7 @@ 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;

        /*
@@ -2371,9 +2383,19 @@ bge_blockinit(struct bge_softc *sc)
        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;
+               mimode |= ((sc->bge_phy_addr & 0x1f) << 5);
+               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);
+               }
+               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);
        }
@@ -2721,9 +2743,6 @@ bge_attach(struct device *parent, struct
            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);
@@ -4491,11 +4510,6 @@ bge_link_upd(struct bge_softc *sc)
                        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
@@ -4517,6 +4531,13 @@ bge_link_upd(struct bge_softc *sc)
                            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 */

Reply via email to