Subject: kern/26807: BCM5701 does not work with AMD760MPX chipset
To: None <gnats-bugs@gnats.NetBSD.org>
From: HITOSHI Osada <QFH02545@nifty.com>
List: netbsd-bugs
Date: 08/30/2004 22:13:21
>Number: 26807
>Category: kern
>Synopsis: BCM5701 does not work with AMD760MPX chipset
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Aug 30 13:19:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator: HITOSHI Osada
>Release: NetBSD 2.0G (20040824)
>Organization:
>Environment:
System: NetBSD that 2.0G NetBSD 2.0G (TIGERMPX2) #10: Mon Aug 30 17:55:49 JST 2004 that@that:/sys/arch/i386/compile/TIGERMPX2 i386
Architecture: i386
Machine: i386
>Description:
The Broadcom 5701 does not work with AMD760MPX(AMD 762+AMD768)
chipset when using 64bit slot.(corrupt packets)
Using 32bit slot works very well.
>How-To-Repeat:
Put BCM5701 NIC into AMD760MPX 64bit slot.
>Fix:
*** if_bge.c 6 Jun 2004 11:09:39 -0000
--- if_bge.c 30 Aug 2004 08:54:08 -0000
***************
*** 246,251 ****
--- 246,255 ----
void bge_dump_status(struct bge_softc *);
void bge_dump_rxbd(struct bge_rx_bd *);
+ static int bge_amd762_match(struct pci_attach_args *);
+ static void bge_amd762_fix(struct bge_softc *);
+
+
#define BGE_DEBUG
#ifdef BGE_DEBUG
#define DPRINTF(x) if (bgedebug) printf x
***************
*** 276,281 ****
--- 280,286 ----
#define BGE_QUIRK_PCIX_DMA_ALIGN_BUG 0x00000040
#define BGE_QUIRK_5705_CORE 0x00000080
#define BGE_QUIRK_FEWER_MBUFS 0x00000100
+ #define BGE_QUIRK_FLUSH_POSTED_WRITE 0x00000200
/* following bugs are common to bcm5700 rev B, all flavours */
#define BGE_QUIRK_5700_COMMON \
***************
*** 1002,1007 ****
--- 1007,1015 ----
sc->bge_std = i - 1;
CSR_WRITE_4(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
+ if (sc->bge_quirks & BGE_QUIRK_FLUSH_POSTED_WRITE) /* fix for AMD762 */
+ (void)CSR_READ_4(sc, BGE_MBX_RX_STD_PROD_LO);
+
sc->bge_flags |= BGE_RXRING_VALID;
***************
*** 1054,1059 ****
--- 1062,1069 ----
CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_MAXLEN_FLAGS, rcb->bge_maxlen_flags);
CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
+ if (sc->bge_quirks & BGE_QUIRK_FLUSH_POSTED_WRITE) /* fix for AMD762 */
+ (void)CSR_READ_4(sc, BGE_MBX_RX_JUMBO_PROD_LO);
return(0);
}
***************
*** 1129,1138 ****
CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, 0);
if (sc->bge_quirks & BGE_QUIRK_PRODUCER_BUG) /* 5700 b2 errata */
CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, 0);
CSR_WRITE_4(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
if (sc->bge_quirks & BGE_QUIRK_PRODUCER_BUG) /* 5700 b2 errata */
! CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, 0);
SLIST_INIT(&sc->txdma_list);
for (i = 0; i < BGE_RSLOTS; i++) {
--- 1139,1152 ----
CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, 0);
if (sc->bge_quirks & BGE_QUIRK_PRODUCER_BUG) /* 5700 b2 errata */
CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, 0);
+ if (sc->bge_quirks & BGE_QUIRK_FLUSH_POSTED_WRITE) /* fix for AMD762 */
+ (void)CSR_READ_4(sc, BGE_MBX_TX_HOST_PROD0_LO);
CSR_WRITE_4(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
if (sc->bge_quirks & BGE_QUIRK_PRODUCER_BUG) /* 5700 b2 errata */
! CSR_WRITE_4(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
! if (sc->bge_quirks & BGE_QUIRK_FLUSH_POSTED_WRITE) /* fix for AMD762 */
! (void)CSR_READ_4(sc, BGE_MBX_TX_NIC_PROD0_LO);
SLIST_INIT(&sc->txdma_list);
for (i = 0; i < BGE_RSLOTS; i++) {
***************
*** 1333,1345 ****
BGE_MODECTL_TX_NO_PHDR_CSUM|BGE_MODECTL_RX_NO_PHDR_CSUM);
/* Get cache line size. */
! cachesize = pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_CACHESZ);
/*
* Avoid violating PCI spec on certain chip revs.
*/
! if (pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_CMD) &
! PCIM_CMD_MWIEN) {
switch(cachesize) {
case 1:
PCI_SETBIT(pa->pa_pc, pa->pa_tag, BGE_PCI_DMA_RW_CTL,
--- 1347,1358 ----
BGE_MODECTL_TX_NO_PHDR_CSUM|BGE_MODECTL_RX_NO_PHDR_CSUM);
/* Get cache line size. */
! cachesize = pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_CACHESZ) & 0xff;
/*
* Avoid violating PCI spec on certain chip revs.
*/
! if (pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_CMD) & PCIM_CMD_MWIEN) {
switch(cachesize) {
case 1:
PCI_SETBIT(pa->pa_pc, pa->pa_tag, BGE_PCI_DMA_RW_CTL,
***************
*** 1383,1395 ****
}
}
/*
* Disable memory write invalidate. Apparently it is not supported
* properly by these devices.
*/
PCI_CLRBIT(pa->pa_pc, pa->pa_tag, BGE_PCI_CMD, PCIM_CMD_MWIEN);
-
#ifdef __brokenalpha__
/*
* Must insure that we do not cross an 8K (bytes) boundary
--- 1396,1417 ----
}
}
+ if ((BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700) ||
+ (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5701)) {
+ /* XXX
+ * At my TigerMPX, 64bit-slot requires this fix, but 32bit does not.
+ */
+ if (sc->bge_quirks & BGE_QUIRK_FLUSH_POSTED_WRITE)
+ pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_DMA_RW_CTL,
+ (dma_rw_ctl | BGE_PCI_WRITE_BNDRY_16BYTES));
+ }
+
/*
* Disable memory write invalidate. Apparently it is not supported
* properly by these devices.
*/
PCI_CLRBIT(pa->pa_pc, pa->pa_tag, BGE_PCI_CMD, PCIM_CMD_MWIEN);
#ifdef __brokenalpha__
/*
* Must insure that we do not cross an 8K (bytes) boundary
***************
*** 2179,2184 ****
--- 2201,2236 ----
return (0);
}
+ /* find AMD762 chipset. */
+ static int
+ bge_amd762_match(struct pci_attach_args *pa)
+ {
+ if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_SC762_NB)
+ return (1);
+ return 0;
+ }
+
+ /* fix for AMD762 chipset. */
+ static void
+ bge_amd762_fix(struct bge_softc *sc)
+ {
+ struct pci_attach_args amd762_pa;
+ u_int32_t val;
+
+ if (pci_find_device(&amd762_pa, bge_amd762_match) == 0)
+ return;
+
+ sc->bge_quirks |= BGE_QUIRK_FLUSH_POSTED_WRITE;
+
+ val = pci_conf_read(amd762_pa.pa_pc, amd762_pa.pa_tag, 0x4c);
+ if ((val & 0x02) == 0) {
+ printf("%s: Setting AMD762 Northbridge to enable PCI ordering compliance\n",
+ sc->bge_dev.dv_xname);
+ pci_conf_write(amd762_pa.pa_pc, amd762_pa.pa_tag, 0x4c, (val | 0x02));
+ }
+ }
+
+
void
bge_attach(parent, self, aux)
struct device *parent, *self;
***************
*** 2212,2217 ****
--- 2264,2272 ----
aprint_naive(": Ethernet controller\n");
aprint_normal(": %s\n", bp->bp_name);
+ /* Fix for AMD762 */
+ bge_amd762_fix(sc);
+
/*
* Map control/status registers.
*/
***************
*** 2493,2499 ****
if ((pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_PCISTATE) &
(BGE_PCISTATE_PCI_BUSMODE | BGE_PCISTATE_PCI_BUSSPEED)) ==
BGE_PCISTATE_PCI_BUSSPEED)
! sc->bge_rx_alignment_bug = 1;
}
/*
--- 2548,2554 ----
if ((pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_PCISTATE) &
(BGE_PCISTATE_PCI_BUSMODE | BGE_PCISTATE_PCI_BUSSPEED)) ==
BGE_PCISTATE_PCI_BUSSPEED)
! sc->bge_rx_alignment_bug = 1;
}
/*
***************
*** 2801,2810 ****
}
CSR_WRITE_4(sc, BGE_MBX_RX_CONS0_LO, sc->bge_rx_saved_considx);
! if (stdcnt)
CSR_WRITE_4(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
! if (jumbocnt)
CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
}
void
--- 2856,2874 ----
}
CSR_WRITE_4(sc, BGE_MBX_RX_CONS0_LO, sc->bge_rx_saved_considx);
! if (sc->bge_quirks & BGE_QUIRK_FLUSH_POSTED_WRITE) /* fix for AMD762 */
! (void)CSR_READ_4(sc, BGE_MBX_RX_CONS0_LO);
!
! if (stdcnt) {
CSR_WRITE_4(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
! if (sc->bge_quirks & BGE_QUIRK_FLUSH_POSTED_WRITE) /* fix for AMD762 */
! (void)CSR_READ_4(sc, BGE_MBX_RX_STD_PROD_LO);
! }
! if (jumbocnt) {
CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
+ if (sc->bge_quirks & BGE_QUIRK_FLUSH_POSTED_WRITE) /* fix for AMD762 */
+ (void)CSR_READ_4(sc, BGE_MBX_RX_JUMBO_PROD_LO);
+ }
}
void
***************
*** 2895,2900 ****
--- 2959,2966 ----
#endif
/* Ack interrupt and stop others from occuring. */
CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1);
+ if (sc->bge_quirks & BGE_QUIRK_FLUSH_POSTED_WRITE) /* fix for AMD762 */
+ (void)CSR_READ_4(sc, BGE_MBX_IRQ0_LO);
BGE_EVCNT_INCR(sc->bge_ev_intr);
***************
*** 2965,2970 ****
--- 3031,3038 ----
/* Re-enable interrupts. */
CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0);
+ if (sc->bge_quirks & BGE_QUIRK_FLUSH_POSTED_WRITE) /* fix for AMD762 */
+ (void)CSR_READ_4(sc, BGE_MBX_IRQ0_LO);
if (ifp->if_flags & IFF_RUNNING && !IFQ_IS_EMPTY(&ifp->if_snd))
bge_start(ifp);
***************
*** 3450,3455 ****
--- 3518,3525 ----
CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
if (sc->bge_quirks & BGE_QUIRK_PRODUCER_BUG) /* 5700 b2 errata */
CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
+ if (sc->bge_quirks & BGE_QUIRK_FLUSH_POSTED_WRITE) /* fix for AMD762 */
+ (void)CSR_READ_4(sc, BGE_MBX_TX_HOST_PROD0_LO);
/*
* Set a timeout in case the chip goes out to lunch.
***************
*** 3535,3540 ****
--- 3605,3612 ----
BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_CLEAR_INTA);
BGE_CLRBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0);
+ if (sc->bge_quirks & BGE_QUIRK_FLUSH_POSTED_WRITE) /* fix for AMD762 */
+ (void)CSR_READ_4(sc, BGE_MBX_IRQ0_LO);
bge_ifmedia_upd(ifp);
***************
*** 3800,3805 ****
--- 3872,3879 ----
/* Disable host interrupts. */
BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1);
+ if (sc->bge_quirks & BGE_QUIRK_FLUSH_POSTED_WRITE) /* fix for AMD762 */
+ (void)CSR_READ_4(sc, BGE_MBX_IRQ0_LO);
/*
* Tell firmware we're shutting down.
>Release-Note:
>Audit-Trail:
>Unformatted: