Subject: Re: Dell Optiplex 745
To: Phil Nelson <phil@cs.wwu.edu>
From: Mark Davies <mark@mcs.vuw.ac.nz>
List: current-users
Date: 08/04/2007 09:36:15
--Boundary-00=_Q/5sGaRGV+LalH4
Content-Type: text/plain;
  charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

On Friday 03 August 2007, Phil Nelson wrote:
>   I've recently had a bunch of 745s appear on which I want NetBSD
> to work.  The Broadcom BCM5754 network was recognized but not
> configured.   I added the extra lines to sys/dev/if_bge.c to
> recognize that card as supported by the bge driver.   I didn't add
> anything to the quirks area so I'm not sure I got the generic
> quirks set up properly.
>
>   In any case, I get the following at configure time.
>
> bge0 at pci2 dev 0 function 0: Broadcom BCM5754 10/100/1000
> Ethernet bge0: interrupting at ioapic0 pin 16 (irq 11)
> bge0: firmware handshake timed out, val = 4b657654
> bge0: unknown ASIC (0xb002), Ethernet address 00:1a:a0:4d:f5:2e
	[...]
> So it appears to be doing something.  I'd really like to get this
> working if someone can help me get the proper clue, I should be
> able to do some debugging.

After poking at our 745's off and on all year (see occasional previous 
threads on current-users and tech-net) I finally got the BCM5754 
working yesterday, thanks to a recent fix to the OpenBSD version of 
the driver.

Patches are attached below.  Will commit over the weekend unless 
someone finds a problem.

> p.s.  This machine needed to have the on-board audio turned off so
> the boot wouldn't hang between the cd0 and the boot device lines
> below.  Then turned on, the audio appears as azalia0.  I didn't
> break to the debugger yet, but that is on my list to do at some
> point. Also this was running GENERIC.MP with all of the pci audio
> except azalia commented out.

Yes disabling azalia _or_ disabling ehci gets a system that doesn't 
hang so its presumably some interaction between the two - I suspect 
its more likely to be ehci thats at fault.  Would be nice to get that 
sorted.

cheers
mark

--Boundary-00=_Q/5sGaRGV+LalH4
Content-Type: text/x-diff;
  charset="iso-8859-1";
  name="patches"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="patches"

Index: dev/pci/if_bgereg.h
===================================================================
RCS file: /src/cvs/netbsd/src/sys/dev/pci/if_bgereg.h,v
retrieving revision 1.42
diff -u -r1.42 if_bgereg.h
--- dev/pci/if_bgereg.h	18 May 2007 22:30:24 -0000	1.42
+++ dev/pci/if_bgereg.h	27 Jul 2007 01:24:54 -0000
@@ -275,6 +275,8 @@
 #define BGE_CHIPID_BCM5715_A0		0x90000000
 #define BGE_CHIPID_BCM5715_A1		0x90010000
 #define BGE_CHIPID_BCM5715_A3		0x90030000
+#define BGE_CHIPID_BCM5787_A0		0xb0000000
+#define BGE_CHIPID_BCM5787_A1		0xb0010000
 #define BGE_CHIPID_BCM5787_A2		0xb0020000
 #define BGE_CHIPID_BCM5906_A1		0xc0010000
 
Index: dev/pci/if_bge.c
===================================================================
RCS file: /src/cvs/netbsd/src/sys/dev/pci/if_bge.c,v
retrieving revision 1.132
diff -u -r1.132 if_bge.c
--- dev/pci/if_bge.c	9 Jul 2007 21:00:53 -0000	1.132
+++ dev/pci/if_bge.c	2 Aug 2007 11:28:14 -0000
@@ -277,6 +277,8 @@
 #define BGE_IS_5750_OR_BEYOND(sc)  \
 	(BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750 || \
 	 BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5752 || \
+	 BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755 || \
+	 BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5787 || \
 	 BGE_IS_5714_FAMILY(sc) )
 
 #define BGE_IS_5705_OR_BEYOND(sc)  \
@@ -1587,11 +1589,24 @@
 	}
 
 	/*
-	 * Set the BD ring replentish thresholds. The recommended
+	 * Set the BD ring replenish thresholds. The recommended
 	 * values are 1/8th the number of descriptors allocated to
 	 * each ring.
 	 */
-	CSR_WRITE_4(sc, BGE_RBDI_STD_REPL_THRESH, BGE_STD_RX_RING_CNT/8);
+	i = BGE_STD_RX_RING_CNT / 8;
+
+	/*
+ 	 * Use a value of 8 for the following chips to workaround HW errata.
+	 * Some of these chips have been added based on empirical
+	 * evidence (they don't work unless this is done).
+	 */
+	if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750 ||
+	    BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5752 ||
+	    BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755 ||
+	    BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5787)
+		i = 8;
+
+	CSR_WRITE_4(sc, BGE_RBDI_STD_REPL_THRESH, i);
 	CSR_WRITE_4(sc, BGE_RBDI_JUMBO_REPL_THRESH, BGE_JUMBO_RX_RING_CNT/8);
 
 	/*
@@ -1772,8 +1787,17 @@
 	}
 
 	/* Turn on write DMA state machine */
-	CSR_WRITE_4(sc, BGE_WDMA_MODE,
-	    BGE_WDMAMODE_ENABLE|BGE_WDMAMODE_ALL_ATTNS);
+	{
+		uint32_t bge_wdma_mode =
+			BGE_WDMAMODE_ENABLE|BGE_WDMAMODE_ALL_ATTNS;
+
+		if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755 ||
+		    BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5787)
+		  /* Enable host coalescing bug fix; see Linux tg3.c */
+		  bge_wdma_mode |= (1 << 29);
+
+		CSR_WRITE_4(sc, BGE_WDMA_MODE, bge_wdma_mode);
+        }
 
 	/* Turn on read DMA state machine */
 	{
@@ -1990,6 +2014,18 @@
 	  BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
 	  "BCM5752 A2" },
 
+	{ BGE_CHIPID_BCM5787_A0,
+	  BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
+	  "BCM5754/5787 A0" },
+
+	{ BGE_CHIPID_BCM5787_A1,
+	  BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
+	  "BCM5754/5787 A1" },
+
+	{ BGE_CHIPID_BCM5787_A2,
+	  BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
+	  "BCM5754/5787 A2" },
+
 	{ 0, 0, NULL }
 };
 
@@ -2034,11 +2070,18 @@
 	  BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
 	  "unknown BCM5752 family" },
 
+	{ BGE_ASICREV_BCM5755,
+	  BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
+	  "unknown BCM5755" },
 
 	{ BGE_ASICREV_BCM5780,
 	  BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
 	  "unknown BCM5780" },
 
+	{ BGE_ASICREV_BCM5787,
+	  BGE_QUIRK_ONLY_PHY_1|BGE_QUIRK_5705_CORE,
+	  "unknown BCM5787" },
+
 	{ 0,
 	  0,
 	  NULL }
@@ -2209,6 +2252,26 @@
 	  "Broadcom BCM5753M Gigabit Ethernet",
 	  },
 
+	{ PCI_VENDOR_BROADCOM,
+	  PCI_PRODUCT_BROADCOM_BCM5754,
+	  "Broadcom BCM5754 Gigabit Ethernet",
+	},
+
+	{ PCI_VENDOR_BROADCOM,
+	  PCI_PRODUCT_BROADCOM_BCM5754M,
+	  "Broadcom BCM5754M Gigabit Ethernet",
+	},
+
+	{ PCI_VENDOR_BROADCOM,
+	  PCI_PRODUCT_BROADCOM_BCM5755,
+	  "Broadcom BCM5755 Gigabit Ethernet",
+	},
+
+	{ PCI_VENDOR_BROADCOM,
+	  PCI_PRODUCT_BROADCOM_BCM5755M,
+	  "Broadcom BCM5755M Gigabit Ethernet",
+	},
+
    	{ PCI_VENDOR_BROADCOM,
 	  PCI_PRODUCT_BROADCOM_BCM5780,
 	  "Broadcom BCM5780 Gigabit Ethernet",
@@ -2222,7 +2285,17 @@
    	{ PCI_VENDOR_BROADCOM,
 	  PCI_PRODUCT_BROADCOM_BCM5782,
 	  "Broadcom BCM5782 Gigabit Ethernet",
-	  },
+	},
+
+	{ PCI_VENDOR_BROADCOM,
+	  PCI_PRODUCT_BROADCOM_BCM5787,
+	  "Broadcom BCM5787 Gigabit Ethernet",
+	},
+
+	{ PCI_VENDOR_BROADCOM,
+	  PCI_PRODUCT_BROADCOM_BCM5787M,
+	  "Broadcom BCM5787M Gigabit Ethernet",
+	},
 
    	{ PCI_VENDOR_BROADCOM,
 	  PCI_PRODUCT_BROADCOM_BCM5788,
@@ -2755,6 +2828,11 @@
 			val |= (1<<29);
 		}
 	}
+	/*
+	 * Write the magic number to the firmware mailbox at 0xb50
+	 * so that the driver can synchronize with the firmware.
+	 */
+	bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
 
 	/* Issue global reset */
 	bge_writereg_ind(sc, BGE_MISC_CFG, val);
@@ -2803,12 +2881,6 @@
 	}
 
 	/*
-	 * Prevent PXE restart: write a magic number to the
-	 * general communications memory at 0xB50.
-	 */
-	bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
-
-	/*
 	 * Poll the value location we just wrote until
 	 * we see the 1's complement of the magic number.
 	 * This indicates that the firmware initialization
Index: dev/mii/miidevs
===================================================================
RCS file: /src/cvs/netbsd/src/sys/dev/mii/miidevs,v
retrieving revision 1.70
diff -u -r1.70 miidevs
--- dev/mii/miidevs	17 Feb 2007 23:24:32 -0000	1.70
+++ dev/mii/miidevs	19 Apr 2007 10:55:20 -0000
@@ -55,6 +55,7 @@
 oui ALTIMA			0x0010a9	Altima Communications
 oui AMD				0x00001a	Advanced Micro Devices
 oui BROADCOM			0x001018	Broadcom Corporation
+oui BROADCOM2			0x000af7	Broadcom Corporation
 oui CICADA			0x0003F1	Cicada Semiconductor
 oui DAVICOM			0x00606e	Davicom Semiconductor
 oui ENABLESEMI			0x0010dd	Enable Semiconductor
@@ -141,6 +142,7 @@
 model BROADCOM BCM5750		0x0018 BCM5750 1000BASE-T media interface
 model BROADCOM BCM5714		0x0034 BCM5714 1000BASE-T media interface
 model BROADCOM BCM5780		0x0035 BCM5780 1000BASE-T media interface
+model BROADCOM2 BCM5754		0x000e BCM5754 1000BASE-T media interface
  
 /* Cicada Semiconductor PHYs (now owned by Vitesse?) */
 model CICADA CS8201		0x0001 Cicada CS8201 10/100/1000TX PHY
Index: dev/mii/brgphy.c
===================================================================
RCS file: /src/cvs/netbsd/src/sys/dev/mii/brgphy.c,v
retrieving revision 1.33
diff -u -r1.33 brgphy.c
--- dev/mii/brgphy.c	13 Mar 2007 06:41:52 -0000	1.33
+++ dev/mii/brgphy.c	19 Apr 2007 10:55:20 -0000
@@ -109,6 +109,7 @@
 static void	brgphy_5704_reset(struct mii_softc *);
 static void	brgphy_5705_reset(struct mii_softc *);
 static void	brgphy_5750_reset(struct mii_softc *);
+static void	brgphy_5755_reset(struct mii_softc *);
 
 static const struct mii_phy_funcs brgphy_funcs = {
 	brgphy_service, brgphy_status, mii_phy_reset,
@@ -138,6 +139,10 @@
 	brgphy_service, brgphy_status, brgphy_5750_reset,
 };
 
+const struct mii_phy_funcs brgphy_5755_funcs = {
+	brgphy_service, brgphy_status, brgphy_5755_reset,
+};
+
 
 static const struct mii_phydesc brgphys[] = {
 	{ MII_OUI_BROADCOM,		MII_MODEL_BROADCOM_BCM5400,
@@ -176,6 +181,9 @@
 	{ MII_OUI_BROADCOM,		MII_MODEL_BROADCOM_BCM5780,
 	  MII_STR_BROADCOM_BCM5780 },
 
+	{ MII_OUI_BROADCOM2,		MII_MODEL_BROADCOM2_BCM5754,
+	  MII_STR_BROADCOM2_BCM5754 },
+
 	{ 0,				0,
 	  NULL },
 };
@@ -185,6 +193,7 @@
 static void bcm5703_load_dspcode(struct mii_softc *);
 static void bcm5704_load_dspcode(struct mii_softc *);
 static void bcm5750_load_dspcode(struct mii_softc *);
+static void bcm5755_load_dspcode(struct mii_softc *);
 
 static int
 brgphymatch(struct device *parent, struct cfdata *match,
@@ -264,6 +273,10 @@
 		sc->mii_funcs = &brgphy_5750_funcs;
 		break;
 
+	case MII_MODEL_BROADCOM2_BCM5754:
+		sc->mii_funcs = &brgphy_5755_funcs;
+		break;
+
 	default:
 		sc->mii_funcs = &brgphy_funcs;
 		break;
@@ -570,6 +583,13 @@
 	bcm5750_load_dspcode(sc);
 }
 
+static void
+brgphy_5755_reset(struct mii_softc *sc)
+{
+	mii_phy_reset(sc);
+	bcm5755_load_dspcode(sc);
+}
+
 /* Turn off tap power management on 5401. */
 static void
 bcm5401_load_dspcode(struct mii_softc *sc)
@@ -673,3 +693,23 @@
 	for (i = 0; dspcode[i].reg != 0; i++)
 		PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val);
 }
+
+static void
+bcm5755_load_dspcode(struct mii_softc *sc)
+{
+	static const struct {
+		int		reg;
+		uint16_t	val;
+	} dspcode[] = {
+		{ BRGPHY_MII_AUXCTL,		0x0c00 },
+		{ BRGPHY_MII_DSP_ADDR_REG,	0x000a },
+		{ BRGPHY_MII_DSP_RW_PORT,	0x010b },
+
+		{ BRGPHY_MII_AUXCTL,		0x0400 },
+		{ 0,				0 },
+	};
+	int i;
+
+	for (i = 0; dspcode[i].reg != 0; i++)
+		PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val);
+}

--Boundary-00=_Q/5sGaRGV+LalH4--