Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 May 2006 17:34:48 GMT
From:      Ted Mittelstaedt <tedm@ipinc.net>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   kern/96806: Correction of kernel panic with Broadcom chip BCM5714C and other updates (fix included)
Message-ID:  <200605041734.k44HYmEg002338@ipinc-hp-test.ipinc.net>
Resent-Message-ID: <200605050040.k450eJ5g005168@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         96806
>Category:       kern
>Synopsis:       Correction of kernel panic with Broadcom chip BCM5714C and other updates (fix included)
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri May 05 00:40:19 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Ted Mittelstaedt
>Release:        FreeBSD 6.1-RC1 i386
>Organization:
Internet Partners, Inc.
>Environment:
System: FreeBSD ipinc-hp-test.ipinc.net 6.1-RC1 FreeBSD 6.1-RC1 #0: Thu May 4 16:13:49 UTC 2006 root@:/usr/src/sys/i386/compile/GENERIC i386


	
>Description:
	

Some versions of the HP DL320 G4 ship with a Broadcom ethernet chip BCM5414C, this chip needs special
exceptions in the bge driver or the system will panic.  During the investigation to fix this
while examining the Broadcom-written Linux driver source available from their website, I
found that an old update to the bge driver, CVS revision 1.38 with the notation:

"Change the short hand representation of the various ASIC revisions"

had bitwise manipulation shifts in it that I have been unable to find out how exactly
they produced the same magic numbers that were previously in the FreeBSD code that
they replaced.  I've tried many incantations BY HAND to work these shifts and gotten
nothing whatsoever that seems to agree.

Broadcom has expanded the list of magic numbers for
various bugs in subsequent chipsets they have released and these are all in the Broadcom
Linux driver, along with exceptions for the BCM5714, the BCM5780 and the BCM5705 that
are not in the FreeBSD driver.

I have removed the BGE_PCIDMARWCTL_RD_WAT_SHIFT and BGE_PCIDMARWCTL_WR_WAT_SHIFT variables
and put back in the list of magic numbers from the Linux driver, this should also
make it easier to maintain in the future should Broadcom release yet more buggy
chipsets.

I refuse to speculate further on how exactly the driver worked with this error. :-)

I have also added a number of PCI chip ID's that were in the Broadcom Linux driver
that were not in the FreeBSD driver.  I have also corrected the BCM5714 ASIC chip
ID it was previously set at 0x05 but the Broadcom-written driver has this set to
0x09, the result of the wrong chipset ID was the one previous exception in the FreeBSD
code for the BCM5714 dealing with the ring buffer size wasn't even activated.

The result of these changes is that the Ethernet port #2 on the HP Proliant DL320 G4
now works without panicing the system.  The Ethernet port #1 on the DL320 G4 still does
not work, this I mentioned in PR kern/94307.  I will investigate that further at
some future time and hopefully produce a patch for it.  (fortunately most servers
don't need 2 NICs)

>How-To-Repeat:
	
>Fix:

	

----------------------------------cut here patch to if_bge.c-------------------------------------
*** if_bge.c.dist	Sat Mar  4 09:34:48 2006
--- if_bge.c	Thu May  4 16:56:36 2006
***************
*** 152,167 ****
--- 152,179 ----
  		"Broadcom BCM5704C Dual Gigabit Ethernet" },
  	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5704S,
  		"Broadcom BCM5704S Dual Gigabit Ethernet" },
+ 	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5704S_2,
+ 		"Broadcom BCM5704S v2 Dual Gigabit Ethernet" },
  	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5705,
  		"Broadcom BCM5705 Gigabit Ethernet" },
  	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5705K,
  		"Broadcom BCM5705K Gigabit Ethernet" },
+ 	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5705F,
+ 		"Broadcom BCM5705F Gigabit Ethernet" },
  	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5705M,
  		"Broadcom BCM5705M Gigabit Ethernet" },
  	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5705M_ALT,
  		"Broadcom BCM5705M Gigabit Ethernet" },
  	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5714C,
  		"Broadcom BCM5714C Gigabit Ethernet" },
+ 	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5714S,
+ 		"Broadcom BCM5714S Gigabit Ethernet" },
+ 	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5715,
+ 		"Broadcom BCM5715 Gigabit Ethernet" },
+ 	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5715S,
+ 		"Broadcom BCM5715S Gigabit Ethernet" },
+ 	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5720,
+ 		"Broadcom BCM5720 Gigabit Ethernet" },
  	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5721,
  		"Broadcom BCM5721 Gigabit Ethernet" },
  	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5750,
***************
*** 170,179 ****
--- 182,203 ----
  		"Broadcom BCM5750M Gigabit Ethernet" },
  	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5751,
  		"Broadcom BCM5751 Gigabit Ethernet" },
+ 	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5751F,
+ 		"Broadcom BCM5751F Gigabit Ethernet" },
  	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5751M,
  		"Broadcom BCM5751M Gigabit Ethernet" },
  	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5752,
  		"Broadcom BCM5752 Gigabit Ethernet" },
+ 	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5753F,
+ 		"Broadcom BCM5753F Gigabit Ethernet" },
+ 	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5753M,
+ 		"Broadcom BCM5753M Gigabit Ethernet" },
+ 	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5780,
+ 		"Broadcom BCM5780 Gigabit Ethernet" },
+ 	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5780S,
+ 		"Broadcom BCM5780S Gigabit Ethernet" },
+ 	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5781,
+ 		"Broadcom BCM5781 Gigabit Ethernet" },
  	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5782,
  		"Broadcom BCM5782 Gigabit Ethernet" },
  	{ BCOM_VENDORID, BCOM_DEVICEID_BCM5788,
***************
*** 1048,1077 ****
  	/* Set up the PCI DMA control register. */
  	if (sc->bge_pcie) {
  		dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD |
! 		    (0xf << BGE_PCIDMARWCTL_RD_WAT_SHIFT) |
! 		    (0x2 << BGE_PCIDMARWCTL_WR_WAT_SHIFT);
  	} else if (pci_read_config(sc->bge_dev, BGE_PCI_PCISTATE, 4) &
  	    BGE_PCISTATE_PCI_BUSMODE) {
  		/* Conventional PCI bus */
! 		dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD |
! 		    (0x7 << BGE_PCIDMARWCTL_RD_WAT_SHIFT) |
! 		    (0x7 << BGE_PCIDMARWCTL_WR_WAT_SHIFT) |
! 		    (0x0F);
  	} else {
  		/* PCI-X bus */
  		/*
  		 * The 5704 uses a different encoding of read/write
  		 * watermarks.
  		 */
! 		if (sc->bge_asicrev == BGE_ASICREV_BCM5704)
  			dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD |
! 			    (0x7 << BGE_PCIDMARWCTL_RD_WAT_SHIFT) |
! 			    (0x3 << BGE_PCIDMARWCTL_WR_WAT_SHIFT);
! 		else
  			dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD |
! 			    (0x3 << BGE_PCIDMARWCTL_RD_WAT_SHIFT) |
! 			    (0x3 << BGE_PCIDMARWCTL_WR_WAT_SHIFT) |
! 			    (0x0F);
  
  		/*
  		 * 5703 and 5704 need ONEDMA_AT_ONCE as a workaround
--- 1072,1106 ----
  	/* Set up the PCI DMA control register. */
  	if (sc->bge_pcie) {
  		dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD |
! 		    (0x180000);
  	} else if (pci_read_config(sc->bge_dev, BGE_PCI_PCISTATE, 4) &
  	    BGE_PCISTATE_PCI_BUSMODE) {
  		/* Conventional PCI bus */
! 			if (sc->bge_asicrev == BGE_ASICREV_BCM5705 ||
! 					BGE_ASICREV_BCM5750) {
!                           dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD |
!                                 (0x3F0000); }
!          else 
! 			  dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD |
! 				(0x3F000F);
  	} else {
  		/* PCI-X bus */
  		/*
  		 * The 5704 uses a different encoding of read/write
  		 * watermarks.
  		 */
! 		if (sc->bge_asicrev == BGE_ASICREV_BCM5704 || BGE_ASICREV_BCM5703)
! 			dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD |
! 			    (0x9F0000);
! 		else if (sc->bge_asicrev == BGE_ASICREV_BCM5780)
! 			dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD |
! 			    (0x144000);
! 		else if (sc->bge_asicrev == BGE_ASICREV_BCM5780)
  			dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD |
! 			    (0x148000);
! 		else 
  			dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD |
! 			    (0x1B000F);
  
  		/*
  		 * 5703 and 5704 need ONEDMA_AT_ONCE as a workaround
-----------------------------------cut here-------------------------------------------------


----------------------------------cut here patch to if_bgereg.h-----------------------------
*** if_bgereg.h.dist	Sun Feb  5 18:07:15 2006
--- if_bgereg.h	Thu May  4 17:18:06 2006
***************
*** 224,232 ****
  
  #define BGE_CHIPID_TIGON_I		0x40000000
  #define BGE_CHIPID_TIGON_II		0x60000000
  #define BGE_CHIPID_BCM5700_B0		0x71000000
! #define BGE_CHIPID_BCM5700_B1		0x71020000
! #define BGE_CHIPID_BCM5700_B2		0x71030000
  #define BGE_CHIPID_BCM5700_ALTIMA	0x71040000
  #define BGE_CHIPID_BCM5700_C0		0x72000000
  #define BGE_CHIPID_BCM5701_A0		0x00000000	/* grrrr */
--- 224,234 ----
  
  #define BGE_CHIPID_TIGON_I		0x40000000
  #define BGE_CHIPID_TIGON_II		0x60000000
+ #define BGE_CHIPID_BCM5700_A0		0x70000000
+ #define BGE_CHIPID_BCM5700_A1		0x70010000
  #define BGE_CHIPID_BCM5700_B0		0x71000000
! #define BGE_CHIPID_BCM5700_B1		0x71010000
! #define BGE_CHIPID_BCM5700_B3		0x71020000
  #define BGE_CHIPID_BCM5700_ALTIMA	0x71040000
  #define BGE_CHIPID_BCM5700_C0		0x72000000
  #define BGE_CHIPID_BCM5701_A0		0x00000000	/* grrrr */
***************
*** 236,251 ****
  #define BGE_CHIPID_BCM5703_A0		0x10000000
  #define BGE_CHIPID_BCM5703_A1		0x10010000
  #define BGE_CHIPID_BCM5703_A2		0x10020000
  #define BGE_CHIPID_BCM5704_A0		0x20000000
  #define BGE_CHIPID_BCM5704_A1		0x20010000
  #define BGE_CHIPID_BCM5704_A2		0x20020000
  #define BGE_CHIPID_BCM5705_A0		0x30000000
  #define BGE_CHIPID_BCM5705_A1		0x30010000
  #define BGE_CHIPID_BCM5705_A2		0x30020000
  #define BGE_CHIPID_BCM5705_A3		0x30030000
  #define BGE_CHIPID_BCM5750_A0		0x40000000
  #define BGE_CHIPID_BCM5750_A1		0x40010000
! #define BGE_CHIPID_BCM5714_A0		0x50000000
  
  /* shorthand one */
  #define BGE_ASICREV(x)			((x) >> 28)
--- 238,258 ----
  #define BGE_CHIPID_BCM5703_A0		0x10000000
  #define BGE_CHIPID_BCM5703_A1		0x10010000
  #define BGE_CHIPID_BCM5703_A2		0x10020000
+ #define BGE_CHIPID_BCM5703_A3		0x10030000
  #define BGE_CHIPID_BCM5704_A0		0x20000000
  #define BGE_CHIPID_BCM5704_A1		0x20010000
  #define BGE_CHIPID_BCM5704_A2		0x20020000
+ #define BGE_CHIPID_BCM5704_A3		0x20030000
  #define BGE_CHIPID_BCM5705_A0		0x30000000
  #define BGE_CHIPID_BCM5705_A1		0x30010000
  #define BGE_CHIPID_BCM5705_A2		0x30020000
  #define BGE_CHIPID_BCM5705_A3		0x30030000
  #define BGE_CHIPID_BCM5750_A0		0x40000000
  #define BGE_CHIPID_BCM5750_A1		0x40010000
! #define BGE_CHIPID_BCM5750_A3		0x40030000
! #define BGE_CHIPID_BCM5752_A0_HW	0x50000000
! #define BGE_CHIPID_BCM5752_A0		0x60000000
! #define BGE_CHIPID_BCM5752_A1		0x60010000
  
  /* shorthand one */
  #define BGE_ASICREV(x)			((x) >> 28)
***************
*** 255,262 ****
  #define BGE_ASICREV_BCM5704		0x02
  #define BGE_ASICREV_BCM5705		0x03
  #define BGE_ASICREV_BCM5750		0x04
- #define BGE_ASICREV_BCM5714		0x05
  #define BGE_ASICREV_BCM5752		0x06
  
  /* chip revisions */
  #define BGE_CHIPREV(x)			((x) >> 24)
--- 262,270 ----
  #define BGE_ASICREV_BCM5704		0x02
  #define BGE_ASICREV_BCM5705		0x03
  #define BGE_ASICREV_BCM5750		0x04
  #define BGE_ASICREV_BCM5752		0x06
+ #define BGE_ASICREV_BCM5780		0x08
+ #define BGE_ASICREV_BCM5714		0x09
  
  /* chip revisions */
  #define BGE_CHIPREV(x)			((x) >> 24)
***************
*** 264,269 ****
--- 272,282 ----
  #define BGE_CHIPREV_5700_BX		0x71
  #define BGE_CHIPREV_5700_CX		0x72
  #define BGE_CHIPREV_5701_AX		0x00
+ #define BGE_CHIPREV_5703_AX		0x10
+ #define BGE_CHIPREV_5704_AX		0x20
+ #define BGE_CHIPREV_5704_BX		0x21
+ #define BGE_CHIPREV_5750_AX		0x40
+ #define BGE_CHIPREV_5750_BX		0x41
  
  /* PCI DMA Read/Write Control register */
  #define BGE_PCIDMARWCTL_MINDMA		0x000000FF
***************
*** 271,279 ****
  #define BGE_PCIDMARWCTL_WRADDR_BNDRY	0x00003800
  #define BGE_PCIDMARWCTL_ONEDMA_ATONCE	0x00004000
  #define BGE_PCIDMARWCTL_RD_WAT		0x00070000
- # define BGE_PCIDMARWCTL_RD_WAT_SHIFT	16
  #define BGE_PCIDMARWCTL_WR_WAT		0x00380000
- # define BGE_PCIDMARWCTL_WR_WAT_SHIFT	19
  #define BGE_PCIDMARWCTL_USE_MRM		0x00400000
  #define BGE_PCIDMARWCTL_ASRT_ALL_BE	0x00800000
  #define BGE_PCIDMARWCTL_DFLT_PCI_RD_CMD	0x0F000000
--- 284,290 ----
***************
*** 1945,1961 ****
--- 1956,1984 ----
  #define BCOM_DEVICEID_BCM5703X		0x16C7
  #define BCOM_DEVICEID_BCM5704C		0x1648
  #define BCOM_DEVICEID_BCM5704S		0x16A8
+ #define BCOM_DEVICEID_BCM5704S_2	0x1649
  #define BCOM_DEVICEID_BCM5705		0x1653
+ #define BCOM_DEVICEID_BCM5705F		0x166E
  #define BCOM_DEVICEID_BCM5705K		0x1654
+ #define BCOM_DEVICEID_BCM5720		0x1658
  #define BCOM_DEVICEID_BCM5721		0x1659
  #define BCOM_DEVICEID_BCM5705M		0x165D
  #define BCOM_DEVICEID_BCM5705M_ALT	0x165E
  #define BCOM_DEVICEID_BCM5714C		0x1668
+ #define BCOM_DEVICEID_BCM5714S		0x1669
+ #define BCOM_DEVICEID_BCM5715		0x1678
+ #define BCOM_DEVICEID_BCM5715S		0x1679
  #define BCOM_DEVICEID_BCM5750		0x1676
  #define BCOM_DEVICEID_BCM5750M		0x167C
  #define BCOM_DEVICEID_BCM5751		0x1677
+ #define BCOM_DEVICEID_BCM5751F		0x167E
  #define BCOM_DEVICEID_BCM5751M		0x167D
  #define BCOM_DEVICEID_BCM5752		0x1600
+ #define BCOM_DEVICEID_BCM5753F		0x16FE
+ #define BCOM_DEVICEID_BCM5753M		0x16FD
+ #define BCOM_DEVICEID_BCM5780		0x166A
+ #define BCOM_DEVICEID_BCM5780S		0x166B
+ #define BCOM_DEVICEID_BCM5781		0x16DD
  #define BCOM_DEVICEID_BCM5782		0x1696
  #define BCOM_DEVICEID_BCM5788		0x169C
  #define BCOM_DEVICEID_BCM5789		0x169D
-----------------------------------------------------------cut here-----------------------------------------

Ted
>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200605041734.k44HYmEg002338>