summaryrefslogtreecommitdiffstats
path: root/sys/dev/bge
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2009-11-22 21:45:55 +0000
committeryongari <yongari@FreeBSD.org>2009-11-22 21:45:55 +0000
commit54b7126de1577a96cef586b714e7f560e8f65aad (patch)
tree1c7fddcc07a034788adcfcb01fe4ac6b828709f2 /sys/dev/bge
parentd820542a0dde3dfeeb0734ca02caab63313ab47d (diff)
downloadFreeBSD-src-54b7126de1577a96cef586b714e7f560e8f65aad.zip
FreeBSD-src-54b7126de1577a96cef586b714e7f560e8f65aad.tar.gz
Reduce status block size DMAed by controller. bge(4) uses single
Tx/Rx/Rx return ring such that large part of status block was not used at all. All bge(4) controllers except BCM5700 AX/BX has a feature to control the size of status block. So use minimum status block size allowed in controller. This reduces number of DMAed status block size to 32 bytes from 80 bytes.
Diffstat (limited to 'sys/dev/bge')
-rw-r--r--sys/dev/bge/if_bge.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index 66c8f57..be6c52d 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -1757,8 +1757,15 @@ bge_blockinit(struct bge_softc *sc)
sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx = 0;
sc->bge_ldata.bge_status_block->bge_idx[0].bge_tx_cons_idx = 0;
+ /* Set up status block size. */
+ if (sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
+ sc->bge_chipid != BGE_CHIPID_BCM5700_C0)
+ val = BGE_STATBLKSZ_FULL;
+ else
+ val = BGE_STATBLKSZ_32BYTE;
+
/* Turn on host coalescing state machine */
- CSR_WRITE_4(sc, BGE_HCC_MODE, BGE_HCCMODE_ENABLE);
+ CSR_WRITE_4(sc, BGE_HCC_MODE, val | BGE_HCCMODE_ENABLE);
/* Turn on RX BD completion state machine and enable attentions */
CSR_WRITE_4(sc, BGE_RBDC_MODE,
@@ -2113,7 +2120,7 @@ bge_dma_alloc(device_t dev)
struct bge_dmamap_arg ctx;
struct bge_softc *sc;
bus_addr_t lowaddr;
- bus_size_t txsegsz, txmaxsegsz;
+ bus_size_t sbsz, txsegsz, txmaxsegsz;
int i, error;
sc = device_get_softc(dev);
@@ -2365,14 +2372,25 @@ bge_dma_alloc(device_t dev)
sc->bge_ldata.bge_tx_ring_paddr = ctx.bge_busaddr;
- /* Create tag for status block. */
+ /*
+ * Create tag for status block.
+ * Because we only use single Tx/Rx/Rx return ring, use
+ * minimum status block size except BCM5700 AX/BX which
+ * seems to want to see full status block size regardless
+ * of configured number of ring.
+ */
+ if (sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
+ sc->bge_chipid != BGE_CHIPID_BCM5700_C0)
+ sbsz = BGE_STATUS_BLK_SZ;
+ else
+ sbsz = 32;
error = bus_dma_tag_create(sc->bge_cdata.bge_parent_tag,
PAGE_SIZE, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL,
- NULL, BGE_STATUS_BLK_SZ, 1, BGE_STATUS_BLK_SZ, 0,
- NULL, NULL, &sc->bge_cdata.bge_status_tag);
+ NULL, sbsz, 1, sbsz, 0, NULL, NULL, &sc->bge_cdata.bge_status_tag);
if (error) {
- device_printf(sc->bge_dev, "could not allocate dma tag\n");
+ device_printf(sc->bge_dev,
+ "could not allocate status dma tag\n");
return (ENOMEM);
}
@@ -2383,7 +2401,7 @@ bge_dma_alloc(device_t dev)
if (error)
return (ENOMEM);
- bzero((char *)sc->bge_ldata.bge_status_block, BGE_STATUS_BLK_SZ);
+ bzero((char *)sc->bge_ldata.bge_status_block, sbsz);
/* Load the address of the status block. */
ctx.sc = sc;
@@ -2391,7 +2409,7 @@ bge_dma_alloc(device_t dev)
error = bus_dmamap_load(sc->bge_cdata.bge_status_tag,
sc->bge_cdata.bge_status_map, sc->bge_ldata.bge_status_block,
- BGE_STATUS_BLK_SZ, bge_dma_map_addr, &ctx, BUS_DMA_NOWAIT);
+ sbsz, bge_dma_map_addr, &ctx, BUS_DMA_NOWAIT);
if (error)
return (ENOMEM);
OpenPOWER on IntegriCloud