Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Insert the completion barrier between register w...
details: https://anonhg.NetBSD.org/src/rev/81d623c1fe76
branches: trunk
changeset: 785291:81d623c1fe76
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Thu Mar 07 08:46:54 2013 +0000
description:
Insert the completion barrier between register write and the
consecutive delay(). It will fix some device timeout problems
we have seen before.
diffstat:
sys/dev/pci/if_bge.c | 68 ++++++++++++++++++++++++++++--------------------
sys/dev/pci/if_bgevar.h | 18 ++++++++++++-
2 files changed, 57 insertions(+), 29 deletions(-)
diffs (277 lines):
diff -r 9d6d7b29c924 -r 81d623c1fe76 sys/dev/pci/if_bge.c
--- a/sys/dev/pci/if_bge.c Thu Mar 07 05:33:13 2013 +0000
+++ b/sys/dev/pci/if_bge.c Thu Mar 07 08:46:54 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bge.c,v 1.210 2013/03/07 04:42:09 msaitoh Exp $ */
+/* $NetBSD: if_bge.c,v 1.211 2013/03/07 08:46:54 msaitoh Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
@@ -79,7 +79,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.210 2013/03/07 04:42:09 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.211 2013/03/07 08:46:54 msaitoh Exp $");
#include "vlan.h"
@@ -243,6 +243,7 @@
static uint32_t bge_readmem_ind(struct bge_softc *, int);
static void bge_writemem_ind(struct bge_softc *, int, int);
static void bge_writembx(struct bge_softc *, int, int);
+static void bge_writembx_flush(struct bge_softc *, int, int);
static void bge_writemem_direct(struct bge_softc *, int, int);
static void bge_writereg_ind(struct bge_softc *, int, int);
static void bge_set_max_readrq(struct bge_softc *);
@@ -825,6 +826,15 @@
CSR_WRITE_4(sc, off, val);
}
+static void
+bge_writembx_flush(struct bge_softc *sc, int off, int val)
+{
+ if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906)
+ off += BGE_LPMBX_IRQ0_HI - BGE_MBX_IRQ0_HI;
+
+ CSR_WRITE_4_FLUSH(sc, off, val);
+}
+
static uint8_t
bge_nvram_getbyte(struct bge_softc *sc, int addr, uint8_t *dest)
{
@@ -869,8 +879,7 @@
CSR_WRITE_4(sc, BGE_NVRAM_ACCESS, access);
/* Unlock. */
- CSR_WRITE_4(sc, BGE_NVRAM_SWARB, BGE_NVRAMSWARB_CLR1);
- CSR_READ_4(sc, BGE_NVRAM_SWARB);
+ CSR_WRITE_4_FLUSH(sc, BGE_NVRAM_SWARB, BGE_NVRAMSWARB_CLR1);
return 0;
}
@@ -987,11 +996,11 @@
autopoll = CSR_READ_4(sc, BGE_MI_MODE);
if (autopoll & BGE_MIMODE_AUTOPOLL) {
BGE_STS_CLRBIT(sc, BGE_STS_AUTOPOLL);
- BGE_CLRBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);
+ BGE_CLRBIT_FLUSH(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);
DELAY(40);
}
- CSR_WRITE_4(sc, BGE_MI_COMM, BGE_MICMD_READ | BGE_MICOMM_BUSY |
+ CSR_WRITE_4_FLUSH(sc, BGE_MI_COMM, BGE_MICMD_READ | BGE_MICOMM_BUSY |
BGE_MIPHY(phy) | BGE_MIREG(reg));
for (i = 0; i < BGE_TIMEOUT; i++) {
@@ -1012,7 +1021,7 @@
done:
if (autopoll & BGE_MIMODE_AUTOPOLL) {
BGE_STS_SETBIT(sc, BGE_STS_AUTOPOLL);
- BGE_SETBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);
+ BGE_SETBIT_FLUSH(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);
DELAY(40);
}
@@ -1042,11 +1051,11 @@
if (autopoll & BGE_MIMODE_AUTOPOLL) {
delay(40);
BGE_STS_CLRBIT(sc, BGE_STS_AUTOPOLL);
- BGE_CLRBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);
+ BGE_CLRBIT_FLUSH(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);
delay(10); /* 40 usec is supposed to be adequate */
}
- CSR_WRITE_4(sc, BGE_MI_COMM, BGE_MICMD_WRITE | BGE_MICOMM_BUSY |
+ CSR_WRITE_4_FLUSH(sc, BGE_MI_COMM, BGE_MICMD_WRITE | BGE_MICOMM_BUSY |
BGE_MIPHY(phy) | BGE_MIREG(reg) | val);
for (i = 0; i < BGE_TIMEOUT; i++) {
@@ -1060,7 +1069,7 @@
if (autopoll & BGE_MIMODE_AUTOPOLL) {
BGE_STS_SETBIT(sc, BGE_STS_AUTOPOLL);
- BGE_SETBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);
+ BGE_SETBIT_FLUSH(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);
delay(40);
}
@@ -1091,9 +1100,10 @@
BGE_SETBIT(sc, BGE_MAC_MODE, BGE_PORTMODE_MII);
if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
- BGE_CLRBIT(sc, BGE_MAC_MODE, BGE_MACMODE_HALF_DUPLEX);
+ BGE_CLRBIT_FLUSH(sc, BGE_MAC_MODE, BGE_MACMODE_HALF_DUPLEX);
else
- BGE_SETBIT(sc, BGE_MAC_MODE, BGE_MACMODE_HALF_DUPLEX);
+ BGE_SETBIT_FLUSH(sc, BGE_MAC_MODE, BGE_MACMODE_HALF_DUPLEX);
+ DELAY(40);
/*
* 802.3x flow control
@@ -1731,7 +1741,7 @@
if (sc->bge_asf_mode) {
bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM_FW, BGE_FW_PAUSE);
- CSR_WRITE_4(sc, BGE_CPU_EVENT,
+ CSR_WRITE_4_FLUSH(sc, BGE_CPU_EVENT,
CSR_READ_4(sc, BGE_CPU_EVENT) | (1 << 14));
for (i = 0; i < 100; i++) {
@@ -1932,8 +1942,7 @@
DELAY(40); /* XXX */
/* Put PHY into ready state */
- BGE_CLRBIT(sc, BGE_MISC_CFG, BGE_MISCCFG_EPHY_IDDQ);
- CSR_READ_4(sc, BGE_MISC_CFG); /* Flush */
+ BGE_CLRBIT_FLUSH(sc, BGE_MISC_CFG, BGE_MISCCFG_EPHY_IDDQ);
DELAY(40);
}
@@ -2297,7 +2306,8 @@
val |= BGE_PORTMODE_MII;
/* Turn on DMA, clear stats */
- CSR_WRITE_4(sc, BGE_MAC_MODE, val);
+ CSR_WRITE_4_FLUSH(sc, BGE_MAC_MODE, val);
+ DELAY(40);
/* Set misc. local control, enable interrupts on attentions */
sc->bge_local_ctrl_reg = BGE_MLC_INTR_ONATTN | BGE_MLC_AUTO_EEPROM;
@@ -2349,7 +2359,7 @@
val |= BGE_RDMAMODE_TSO4_ENABLE;
/* Turn on read DMA state machine */
- CSR_WRITE_4(sc, BGE_RDMA_MODE, val);
+ CSR_WRITE_4_FLUSH(sc, BGE_RDMA_MODE, val);
delay(40);
/* Turn on RX data completion state machine */
@@ -3280,7 +3290,8 @@
* Step 18: wirte mac mode
* XXX Write 0x0c for 5703S and 5704S
*/
- CSR_WRITE_4(sc, BGE_MAC_MODE, 0);
+ CSR_WRITE_4_FLUSH(sc, BGE_MAC_MODE, 0);
+ DELAY(40);
/* Step 21: 5822 B0 errata */
@@ -3626,7 +3637,7 @@
(!(pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_PCISTATE) &
BGE_PCISTATE_INTR_NOT_ACTIVE))) {
/* Ack interrupt and stop others from occuring. */
- bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
+ bge_writembx_flush(sc, BGE_MBX_IRQ0_LO, 1);
BGE_EVCNT_INCR(sc->bge_ev_intr);
@@ -3664,7 +3675,7 @@
bge_handle_events(sc);
/* Re-enable interrupts. */
- bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
+ bge_writembx_flush(sc, BGE_MBX_IRQ0_LO, 0);
if (ifp->if_flags & IFF_RUNNING && !IFQ_IS_EMPTY(&ifp->if_snd))
bge_start(ifp);
@@ -3687,7 +3698,7 @@
BGE_FW_DRV_ALIVE);
bge_writemem_ind(sc, BGE_SOFTWARE_GENNCOMM_FW_LEN, 4);
bge_writemem_ind(sc, BGE_SOFTWARE_GENNCOMM_FW_DATA, 3);
- CSR_WRITE_4(sc, BGE_CPU_EVENT,
+ CSR_WRITE_4_FLUSH(sc, BGE_CPU_EVENT,
CSR_READ_4(sc, BGE_CPU_EVENT) | (1 << 14));
}
}
@@ -4417,11 +4428,11 @@
mode |= BGE_TXMODE_MBUF_LOCKUP_FIX;
/* Turn on transmitter */
- CSR_WRITE_4(sc, BGE_TX_MODE, mode | BGE_TXMODE_ENABLE);
+ CSR_WRITE_4_FLUSH(sc, BGE_TX_MODE, mode | BGE_TXMODE_ENABLE);
DELAY(100);
/* Turn on receiver */
- BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_ENABLE);
+ BGE_SETBIT_FLUSH(sc, BGE_RX_MODE, BGE_RXMODE_ENABLE);
DELAY(10);
CSR_WRITE_4(sc, BGE_MAX_RX_FRAME_LOWAT, 2);
@@ -4434,7 +4445,7 @@
BGE_PCIMISCCTL_CLEAR_INTA);
PCI_CLRBIT(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MISC_CTL,
BGE_PCIMISCCTL_MASK_PCI_INTR);
- bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
+ bge_writembx_flush(sc, BGE_MBX_IRQ0_LO, 0);
if ((error = bge_ifmedia_upd(ifp)) != 0)
goto out;
@@ -4482,10 +4493,11 @@
sgdig |= BGE_SGDIGCFG_AUTO |
BGE_SGDIGCFG_PAUSE_CAP |
BGE_SGDIGCFG_ASYM_PAUSE;
- CSR_WRITE_4(sc, BGE_SGDIG_CFG,
+ CSR_WRITE_4_FLUSH(sc, BGE_SGDIG_CFG,
sgdig | BGE_SGDIGCFG_SEND);
DELAY(5);
- CSR_WRITE_4(sc, BGE_SGDIG_CFG, sgdig);
+ CSR_WRITE_4_FLUSH(sc, BGE_SGDIG_CFG,
+ sgdig);
}
}
break;
@@ -4658,7 +4670,7 @@
{
int i;
- BGE_CLRBIT(sc, reg, bit);
+ BGE_CLRBIT_FLUSH(sc, reg, bit);
for (i = 0; i < 1000; i++) {
if ((CSR_READ_4(sc, reg) & bit) == 0)
@@ -4696,7 +4708,7 @@
/* Disable host interrupts. */
PCI_SETBIT(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MISC_CTL,
BGE_PCIMISCCTL_MASK_PCI_INTR);
- bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
+ bge_writembx_flush(sc, BGE_MBX_IRQ0_LO, 1);
/*
* Disable all of the receiver blocks.
diff -r 9d6d7b29c924 -r 81d623c1fe76 sys/dev/pci/if_bgevar.h
--- a/sys/dev/pci/if_bgevar.h Thu Mar 07 05:33:13 2013 +0000
+++ b/sys/dev/pci/if_bgevar.h Thu Mar 07 08:46:54 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bgevar.h,v 1.10 2013/02/27 13:53:51 msaitoh Exp $ */
+/* $NetBSD: if_bgevar.h,v 1.11 2013/03/07 08:46:54 msaitoh Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
* Copyright (c) 1997, 1998, 1999, 2001
@@ -99,10 +99,26 @@
#define CSR_READ_4(sc, reg) \
bus_space_read_4(sc->bge_btag, sc->bge_bhandle, reg)
+#define CSR_WRITE_4_FLUSH(sc, reg, val) \
+ do { \
+ CSR_WRITE_4(sc, reg, val); \
+ CSR_READ_4(sc, reg); \
+ } while(0)
+
#define BGE_SETBIT(sc, reg, x) \
CSR_WRITE_4(sc, reg, (CSR_READ_4(sc, reg) | (x)))
+#define BGE_SETBIT_FLUSH(sc, reg, x) \
+ do { \
+ BGE_SETBIT(sc, reg, x); \
+ CSR_READ_4(sc, reg); \
+ } while(0)
#define BGE_CLRBIT(sc, reg, x) \
CSR_WRITE_4(sc, reg, (CSR_READ_4(sc, reg) & ~(x)))
+#define BGE_CLRBIT_FLUSH(sc, reg, x) \
+ do { \
+ BGE_CLRBIT(sc, reg, x); \
+ CSR_READ_4(sc, reg); \
+ } while(0)
#define PCI_SETBIT(pc, tag, reg, x) \
pci_conf_write(pc, tag, reg, (pci_conf_read(pc, tag, reg) | (x)))
Home |
Main Index |
Thread Index |
Old Index