summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2013-05-31 14:27:22 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2013-05-31 14:27:22 +0000
commitd3280d765b2f1f040fbaed0bd17cb27a848f8b8e (patch)
tree1333e4b605c2b39a05fcc80cab9168503bc9a346
parent3098b3bfa538fca84e27f2c73885ffcd8732ab9d (diff)
New logic to accommodate the E5/C600 and 5719/5720 changes in PCI-E
maximum payload size handling from FreeBSD. Fixes RX path on 5719 found in newer machines such as HP DL3[68]0 G8 and Dell R320. Tested by dlg@ on 5714, 5719 (Sun V445) and 5720, 5721 (Dell R420); David Imhoff on 5719, 5720, 5721 (various Dell servers); Rob Sessnik on 5719 (HP DL360p G8); mikeb@ on 5719 (HP DL380p G8). ok dlg
-rw-r--r--sys/dev/pci/if_bge.c44
-rw-r--r--sys/dev/pci/if_bgereg.h14
2 files changed, 34 insertions, 24 deletions
diff --git a/sys/dev/pci/if_bge.c b/sys/dev/pci/if_bge.c
index e0b8dadc7a0..2fecaab1c8f 100644
--- a/sys/dev/pci/if_bge.c
+++ b/sys/dev/pci/if_bge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bge.c,v 1.329 2013/05/29 17:04:46 mikeb Exp $ */
+/* $OpenBSD: if_bge.c,v 1.330 2013/05/31 14:27:20 mikeb Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
@@ -1651,8 +1651,10 @@ bge_chipinit(struct bge_softc *sc)
BGE_PCIDMARWCTL_WR_CMD_SHIFT(7);
if (sc->bge_flags & BGE_PCIE) {
- /* Read watermark not used, 128 bytes for write. */
- dma_rw_ctl |= BGE_PCIDMARWCTL_WR_WAT_SHIFT(3);
+ if (sc->bge_mps >= 256)
+ dma_rw_ctl |= BGE_PCIDMARWCTL_WR_WAT_SHIFT(7);
+ else
+ dma_rw_ctl |= BGE_PCIDMARWCTL_WR_WAT_SHIFT(3);
} else if (sc->bge_flags & BGE_PCIX) {
/* PCI-X bus */
if (BGE_IS_5714_FAMILY(sc)) {
@@ -2461,7 +2463,7 @@ bge_attach(struct device *parent, struct device *self, void *aux)
const char *intrstr = NULL;
bus_size_t size, apesize;
bus_dma_segment_t seg;
- int rseg, gotenaddr = 0, aspm_off;
+ int rseg, gotenaddr = 0;
u_int32_t hwcfg = 0;
u_int32_t mac_addr = 0;
u_int32_t misccfg;
@@ -2557,13 +2559,22 @@ bge_attach(struct device *parent, struct device *self, void *aux)
* PCI Express or PCI-X controller check.
*/
if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIEXPRESS,
- &aspm_off, NULL) != 0) {
+ &sc->bge_expcap, NULL) != 0) {
+ /* Extract supported maximum payload size. */
+ reg = pci_conf_read(pa->pa_pc, pa->pa_tag, sc->bge_expcap +
+ PCI_PCIE_DCAP);
+ sc->bge_mps = 128 << (reg & 0x7);
+ if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719 ||
+ BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5720)
+ sc->bge_expmrq = 0x4000; /* (fls(2048) - 8) << 12 */
+ else
+ sc->bge_expmrq = 0x5000; /* (fls(4096) - 8) << 12 */
/* Disable PCIe Active State Power Management (ASPM). */
reg = pci_conf_read(pa->pa_pc, pa->pa_tag,
- aspm_off + PCI_PCIE_LCSR);
+ sc->bge_expcap + PCI_PCIE_LCSR);
reg &= ~(PCI_PCIE_LCSR_ASPM_L0S | PCI_PCIE_LCSR_ASPM_L1);
pci_conf_write(pa->pa_pc, pa->pa_tag,
- aspm_off + PCI_PCIE_LCSR, reg);
+ sc->bge_expcap + PCI_PCIE_LCSR, reg);
sc->bge_flags |= BGE_PCIE;
} else {
if ((pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_PCISTATE) &
@@ -3042,7 +3053,7 @@ void
bge_reset(struct bge_softc *sc)
{
struct pci_attach_args *pa = &sc->bge_pa;
- pcireg_t cachesize, command;
+ pcireg_t cachesize, command, devctl;
u_int32_t reset, mac_mode, mac_mode_mask, val;
void (*write_op)(struct bge_softc *, int, int);
int i;
@@ -3142,12 +3153,17 @@ bge_reset(struct bge_softc *sc)
pci_conf_write(pa->pa_pc, pa->pa_tag, 0xc4, v | (1<<15));
}
- /*
- * Set PCI Express max payload size to 128 bytes
- * and clear error status.
- */
- pci_conf_write(pa->pa_pc, pa->pa_tag,
- BGE_PCI_CONF_DEV_CTRL, 0xf5000);
+ devctl = pci_conf_read(pa->pa_pc, pa->pa_tag, sc->bge_expcap +
+ PCI_PCIE_DCSR);
+ /* Clear enable no snoop and disable relaxed ordering. */
+ devctl &= ~(0x10 | 0x800);
+ /* Set PCI Express max payload size. */
+ devctl &= ~0x7000;
+ devctl |= sc->bge_expmrq;
+ /* Clear error status. */
+ devctl |= 0xf0000;
+ pci_conf_write(pa->pa_pc, pa->pa_tag, sc->bge_expcap +
+ PCI_PCIE_DCSR, devctl);
}
/* Reset some of the PCI state that got zapped by reset */
diff --git a/sys/dev/pci/if_bgereg.h b/sys/dev/pci/if_bgereg.h
index e7ae628fabb..3685f14385f 100644
--- a/sys/dev/pci/if_bgereg.h
+++ b/sys/dev/pci/if_bgereg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bgereg.h,v 1.114 2013/05/29 17:04:46 mikeb Exp $ */
+/* $OpenBSD: if_bgereg.h,v 1.115 2013/05/31 14:27:21 mikeb Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
@@ -216,15 +216,6 @@
#define BGE_PCI_GEN2_PRODID_ASICREV 0xF4
#define BGE_PCI_GEN15_PRODID_ASICREV 0xFC
-/* XXX:
- * Used in PCI-Express code for 575x chips.
- * Should be replaced with checking for a PCI config-space
- * capability for PCI-Express, and PCI-Express standard
- * offsets into that capability block.
- */
-#define BGE_PCI_CONF_DEV_CTRL 0xD8
-#define BGE_PCI_CONF_DEV_STUS 0xDA
-
/* PCI Misc. Host control register */
#define BGE_PCIMISCCTL_CLEAR_INTA 0x00000001
#define BGE_PCIMISCCTL_MASK_PCI_INTR 0x00000002
@@ -2816,6 +2807,9 @@ struct bge_softc {
struct pci_attach_args bge_pa;
struct mii_data bge_mii;
struct ifmedia bge_ifmedia; /* media info */
+ u_int32_t bge_expcap;
+ u_int32_t bge_mps;
+ u_int32_t bge_expmrq;
u_int32_t bge_flags;
#define BGE_TXRING_VALID 0x00000001
#define BGE_RXRING_VALID 0x00000002