summaryrefslogtreecommitdiffstats
path: root/sys/dev/bge/if_bge.c
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2012-10-10 01:24:02 +0000
committeryongari <yongari@FreeBSD.org>2012-10-10 01:24:02 +0000
commitf01bf63b42d8f87ece024108648b829499865eb1 (patch)
treee5835ff672f7e8419ff0fc515e7f740a210f6ee4 /sys/dev/bge/if_bge.c
parent23175e013f29eb5d54b96fba48352515dc1252aa (diff)
downloadFreeBSD-src-f01bf63b42d8f87ece024108648b829499865eb1.zip
FreeBSD-src-f01bf63b42d8f87ece024108648b829499865eb1.tar.gz
If the maximum payload size is 256 bytes or more, set the DMA write
water mark to 256 bytes. Otherwise controller will encounter DMA write under run errors and would result in RX DMA hang. If the maximum payload size is 128 bytes, the water mark is set to 128 bytes as usual. While here, set maximum read request size to 2048 for BCM5719/BCM5720. For other PCIe devices, use 4096. And reprogram the maximum read request size whenever device reset is performed.
Diffstat (limited to 'sys/dev/bge/if_bge.c')
-rw-r--r--sys/dev/bge/if_bge.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index cc30b14..44ff518 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -1466,8 +1466,10 @@ bge_chipinit(struct bge_softc *sc)
dma_rw_ctl = BGE_PCIDMARWCTL_RD_CMD_SHIFT(6) |
BGE_PCIDMARWCTL_WR_CMD_SHIFT(7);
if (sc->bge_flags & BGE_FLAG_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_FLAG_PCIX) {
if (BGE_IS_5714_FAMILY(sc)) {
/* 256 bytes for read and write. */
@@ -3161,11 +3163,16 @@ bge_attach(device_t dev)
*/
sc->bge_flags |= BGE_FLAG_PCIE;
sc->bge_expcap = reg;
+ /* Extract supported maximum payload size. */
+ sc->bge_mps = pci_read_config(dev, sc->bge_expcap +
+ PCIER_DEVICE_CAP, 2);
+ sc->bge_mps = 128 << (sc->bge_mps & PCIEM_CAP_MAX_PAYLOAD);
if (sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
sc->bge_asicrev == BGE_ASICREV_BCM5720)
- pci_set_max_read_req(dev, 2048);
- else if (pci_get_max_read_req(dev) != 4096)
- pci_set_max_read_req(dev, 4096);
+ sc->bge_expmrq = 2048;
+ else
+ sc->bge_expmrq = 4096;
+ pci_set_max_read_req(dev, sc->bge_expmrq);
} else {
/*
* Check if the device is in PCI-X Mode.
@@ -3642,6 +3649,7 @@ bge_reset(struct bge_softc *sc)
PCIEM_CTL_NOSNOOP_ENABLE);
pci_write_config(dev, sc->bge_expcap + PCIER_DEVICE_CTL,
devctl, 2);
+ pci_set_max_read_req(dev, sc->bge_expmrq);
/* Clear error status. */
pci_write_config(dev, sc->bge_expcap + PCIER_DEVICE_STA,
PCIEM_STA_CORRECTABLE_ERROR |
OpenPOWER on IntegriCloud