Create a kernel option BGE_FAKE_AUTONEG for IBM/Intel blade servers,
authorJoerg Sonnenberger <joerg@dragonflybsd.org>
Mon, 22 Aug 2005 18:29:52 +0000 (18:29 +0000)
committerJoerg Sonnenberger <joerg@dragonflybsd.org>
Mon, 22 Aug 2005 18:29:52 +0000 (18:29 +0000)
which should make the DNLK switch module work.  IBM/Intel blade server
with Intel or AD switch modules should work without the kernel options

Obtained-from: FreeBSD
Submitted-by: Sepherosa Ziehau <sepherosa@gmail.com>
sys/conf/options
sys/dev/netif/bge/Makefile
sys/dev/netif/bge/if_bge.c
sys/dev/netif/bge/if_bgereg.h

index cdfc77b..6a62e58 100644 (file)
@@ -1,5 +1,5 @@
 # $FreeBSD: src/sys/conf/options,v 1.191.2.53 2003/06/04 17:56:58 sam Exp $
-# $DragonFly: src/sys/conf/options,v 1.40 2005/08/15 16:46:17 dillon Exp $
+# $DragonFly: src/sys/conf/options,v 1.41 2005/08/22 18:29:52 joerg Exp $
 #
 #        On the handling of kernel options
 #
@@ -536,6 +536,9 @@ KTR_MSGPORT                 opt_ktr.h
 KTR_ENTRIES                    opt_global.h
 KTR_VERBOSE                    opt_ktr.h
 
+# bge driver
+BGE_FAKE_AUTONEG       opt_bge.h
+
 # ed driver
 ED_NO_MIIBUS           opt_ed.h
 
index 1768731..62c2a8f 100644 (file)
@@ -1,8 +1,10 @@
 # $FreeBSD: src/sys/modules/bge/Makefile,v 1.1.2.2 2001/12/04 20:01:53 brooks Exp $
-# $DragonFly: src/sys/dev/netif/bge/Makefile,v 1.3 2005/05/21 07:28:04 joerg Exp $
+# $DragonFly: src/sys/dev/netif/bge/Makefile,v 1.4 2005/08/22 18:29:52 joerg Exp $
 
 KMOD=  if_bge
-SRCS=  if_bge.c miibus_if.h opt_bdg.h device_if.h bus_if.h pci_if.h
+SRCS=  if_bge.c
+SRCS+= opt_bge.h opt_bdg.h
+SRCS+= miibus_if.h device_if.h bus_if.h pci_if.h
 KMODDEPS = miibus
 
 .include <bsd.kmod.mk>
index 41007e9..ba76e3c 100644 (file)
@@ -31,7 +31,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/bge/if_bge.c,v 1.3.2.29 2003/12/01 21:06:59 ambrisko Exp $
- * $DragonFly: src/sys/dev/netif/bge/if_bge.c,v 1.45 2005/08/19 14:43:30 joerg Exp $
+ * $DragonFly: src/sys/dev/netif/bge/if_bge.c,v 1.46 2005/08/22 18:29:52 joerg Exp $
  *
  */
 
@@ -72,6 +72,8 @@
  * ring.
  */
 
+#include "opt_bge.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/sockio.h>
@@ -1679,6 +1681,7 @@ bge_attach(device_t dev)
                    IFM_ETHER|IFM_1000_SX|IFM_FDX, 0, NULL);
                ifmedia_add(&sc->bge_ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL);
                ifmedia_set(&sc->bge_ifmedia, IFM_ETHER|IFM_AUTO);
+               sc->bge_ifmedia.ifm_media = sc->bge_ifmedia.ifm_cur->ifm_media;
        } else {
                /*
                 * Do transceiver setup.
@@ -1898,6 +1901,19 @@ bge_reset(struct bge_softc *sc)
 
        CSR_WRITE_4(sc, BGE_MAC_MODE, 0);
 
+       /*
+        * The 5704 in TBI mode apparently needs some special
+        * adjustment to insure the SERDES drive level is set
+        * to 1.2V.
+        */
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5704 && sc->bge_tbi) {
+               uint32_t serdescfg;
+
+               serdescfg = CSR_READ_4(sc, BGE_SERDES_CFG);
+               serdescfg = (serdescfg & ~0xFFF) | 0x880;
+               CSR_WRITE_4(sc, BGE_SERDES_CFG, serdescfg);
+       }
+
        /* XXX: Broadcom Linux driver. */
        if (sc->bge_pcie && sc->bge_chipid != BGE_CHIPID_BCM5750_A0) {
                uint32_t v;
@@ -2192,6 +2208,10 @@ bge_tick(void *xsc)
                if (CSR_READ_4(sc, BGE_MAC_STS) &
                    BGE_MACSTAT_TBI_PCS_SYNCHED) {
                        sc->bge_link++;
+                       if (sc->bge_asicrev == BGE_ASICREV_BCM5704) {
+                               BGE_CLRBIT(sc, BGE_MAC_MODE,
+                                          BGE_MACMODE_TBI_SEND_CFGS);
+                       }
                        CSR_WRITE_4(sc, BGE_MAC_STS, 0xFFFFFFFF);
                        if_printf(ifp, "gigabit link up\n");
                        if (!ifq_is_empty(&ifp->if_snd))
@@ -2530,6 +2550,26 @@ bge_ifmedia_upd(struct ifnet *ifp)
                        return(EINVAL);
                switch(IFM_SUBTYPE(ifm->ifm_media)) {
                case IFM_AUTO:
+#ifndef BGE_FAKE_AUTONEG
+                       /*
+                        * The BCM5704 ASIC appears to have a special
+                        * mechanism for programming the autoneg
+                        * advertisement registers in TBI mode.
+                        */
+                       if (sc->bge_asicrev == BGE_ASICREV_BCM5704) {
+                               uint32_t sgdig;
+
+                               CSR_WRITE_4(sc, BGE_TX_TBI_AUTONEG, 0);
+                               sgdig = CSR_READ_4(sc, BGE_SGDIG_CFG);
+                               sgdig |= BGE_SGDIGCFG_AUTO |
+                                        BGE_SGDIGCFG_PAUSE_CAP |
+                                        BGE_SGDIGCFG_ASYM_PAUSE;
+                               CSR_WRITE_4(sc, BGE_SGDIG_CFG,
+                                           sgdig | BGE_SGDIGCFG_SEND);
+                               DELAY(5);
+                               CSR_WRITE_4(sc, BGE_SGDIG_CFG, sgdig);
+                       }
+#endif /* !BEG_FAKE_AUTONEG */
                        break;
                case IFM_1000_SX:
                        if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX) {
index c4e6bca..58418df 100644 (file)
@@ -31,7 +31,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/bge/if_bgereg.h,v 1.1.2.13 2003/12/01 21:06:59 ambrisko Exp $
- * $DragonFly: src/sys/dev/netif/bge/if_bgereg.h,v 1.11 2005/08/19 14:40:03 joerg Exp $
+ * $DragonFly: src/sys/dev/netif/bge/if_bgereg.h,v 1.12 2005/08/22 18:29:52 joerg Exp $
  */
 
 /*
 #define BGE_RX_BD_RULES_CTL15          0x04F8
 #define BGE_RX_BD_RULES_MASKVAL15      0x04FC
 #define BGE_RX_RULES_CFG               0x0500
+#define BGE_SERDES_CFG                 0x0590
+#define BGE_SERDES_STS                 0x0594
+#define BGE_SGDIG_CFG                  0x05B0
+#define BGE_SGDIG_STS                  0x05B4
 #define BGE_RX_STATS                   0x0800
 #define BGE_TX_STATS                   0x0880
 
 #define BGE_RXRULEMASK_VALUE           0x0000FFFF
 #define BGE_RXRULEMASK_MASKVAL         0xFFFF0000
 
+/* SERDES configuration register */
+#define BGE_SERDESCFG_RXR              0x00000007 /* phase interpolator */
+#define BGE_SERDESCFG_RXG              0x00000018 /* rx gain setting */
+#define BGE_SERDESCFG_RXEDGESEL                0x00000040 /* rising/falling egde */
+#define BGE_SERDESCFG_TX_BIAS          0x00000380 /* TXDAC bias setting */
+#define BGE_SERDESCFG_IBMAX            0x00000400 /* bias current +25% */
+#define BGE_SERDESCFG_IBMIN            0x00000800 /* bias current -25% */
+#define BGE_SERDESCFG_TXMODE           0x00001000
+#define BGE_SERDESCFG_TXEDGESEL                0x00002000 /* rising/falling edge */
+#define BGE_SERDESCFG_MODE             0x00004000 /* TXCP/TXCN disabled */
+#define BGE_SERDESCFG_PLLTEST          0x00008000 /* PLL test mode */
+#define BGE_SERDESCFG_CDET             0x00010000 /* comma detect enable */
+#define BGE_SERDESCFG_TBILOOP          0x00020000 /* local loopback */
+#define BGE_SERDESCFG_REMLOOP          0x00040000 /* remote loopback */
+#define BGE_SERDESCFG_INVPHASE         0x00080000 /* Reverse 125Mhz clock */
+#define BGE_SERDESCFG_12REGCTL         0x00300000 /* 1.2v regulator ctl */
+#define BGE_SERDESCFG_REGCTL           0x00C00000 /* regulator ctl (2.5v) */
+
+/* SERDES status register */
+#define BGE_SERDESSTS_RXSTAT           0x0000000F /* receive status bits */
+#define BGE_SERDESSTS_CDET             0x00000010 /* comma code detected */
+
+/* SGDIG config (not documented) */
+#define BGE_SGDIGCFG_PAUSE_CAP         0x00000800
+#define BGE_SGDIGCFG_ASYM_PAUSE                0x00001000
+#define BGE_SGDIGCFG_SEND              0x40000000
+#define BGE_SGDIGCFG_AUTO              0x80000000
+
+/* SGDIG status (not documented) */
+#define BGE_SGDIGSTS_PAUSE_CAP         0x00080000
+#define BGE_SGDIGSTS_ASYM_PAUSE                0x00100000
+#define BGE_SGDIGSTS_DONE              0x00000002
+
 /* MI communication register */
 #define BGE_MICOMM_DATA                        0x0000FFFF
 #define BGE_MICOMM_REG                 0x001F0000