Module Name: src
Committed By: msaitoh
Date: Thu Mar 21 12:33:11 UTC 2013
Modified Files:
src/sys/dev/pci: if_bge.c if_bgereg.h if_bgevar.h
Log Message:
- Sync with FreeBSD and OpenBSD. Almost the same as OpenBSD rev. 1.325:
- Sync the ring setup code closer to FreeBSD's driver
- Do not touch the jumbo replenish threshold register on chips that do not
have jumbo support
- Add/sync some of the comments
- Use macro.
- Remove unused code.
To generate a diff of this commit:
cvs rdiff -u -r1.221 -r1.222 src/sys/dev/pci/if_bge.c
cvs rdiff -u -r1.66 -r1.67 src/sys/dev/pci/if_bgereg.h
cvs rdiff -u -r1.12 -r1.13 src/sys/dev/pci/if_bgevar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/pci/if_bge.c
diff -u src/sys/dev/pci/if_bge.c:1.221 src/sys/dev/pci/if_bge.c:1.222
--- src/sys/dev/pci/if_bge.c:1.221 Tue Mar 19 16:49:11 2013
+++ src/sys/dev/pci/if_bge.c Thu Mar 21 12:33:11 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bge.c,v 1.221 2013/03/19 16:49:11 msaitoh Exp $ */
+/* $NetBSD: if_bge.c,v 1.222 2013/03/21 12:33:11 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.221 2013/03/19 16:49:11 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.222 2013/03/21 12:33:11 msaitoh Exp $");
#include "vlan.h"
@@ -2478,10 +2478,10 @@ bge_blockinit(struct bge_softc *sc)
{
volatile struct bge_rcb *rcb;
bus_size_t rcb_addr;
- int i;
struct ifnet *ifp = &sc->ethercom.ec_if;
bge_hostaddr taddr;
uint32_t dmactl, val;
+ int i, limit;
/*
* Initialize the memory window pointer register so that
@@ -2508,12 +2508,6 @@ bge_blockinit(struct bge_softc *sc)
}
/* Step 35: Configure mbuf pool watermarks */
-#ifdef ORIG_WPAUL_VALUES
- CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 24);
- CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 24);
- CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 48);
-#else
-
/* new broadcom docs strongly recommend these: */
if (BGE_IS_5717_PLUS(sc)) {
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);
@@ -2534,7 +2528,6 @@ bge_blockinit(struct bge_softc *sc)
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x20);
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60);
}
-#endif
/* Step 36: Configure DMA resource watermarks */
CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_LOWAT, 5);
@@ -2586,28 +2579,83 @@ bge_blockinit(struct bge_softc *sc)
return ENXIO;
}
+ /*
+ * Summary of rings supported by the controller:
+ *
+ * Standard Receive Producer Ring
+ * - This ring is used to feed receive buffers for "standard"
+ * sized frames (typically 1536 bytes) to the controller.
+ *
+ * Jumbo Receive Producer Ring
+ * - This ring is used to feed receive buffers for jumbo sized
+ * frames (i.e. anything bigger than the "standard" frames)
+ * to the controller.
+ *
+ * Mini Receive Producer Ring
+ * - This ring is used to feed receive buffers for "mini"
+ * sized frames to the controller.
+ * - This feature required external memory for the controller
+ * but was never used in a production system. Should always
+ * be disabled.
+ *
+ * Receive Return Ring
+ * - After the controller has placed an incoming frame into a
+ * receive buffer that buffer is moved into a receive return
+ * ring. The driver is then responsible to passing the
+ * buffer up to the stack. Many versions of the controller
+ * support multiple RR rings.
+ *
+ * Send Ring
+ * - This ring is used for outgoing frames. Many versions of
+ * the controller support multiple send rings.
+ */
+
/* Step 41: Initialize the standard RX ring control block */
rcb = &sc->bge_rdata->bge_info.bge_std_rx_rcb;
BGE_HOSTADDR(rcb->bge_hostaddr, BGE_RING_DMA_ADDR(sc, bge_rx_std_ring));
- if (BGE_IS_5717_PLUS(sc))
+ if (BGE_IS_5717_PLUS(sc)) {
+ /*
+ * Bits 31-16: Programmable ring size (2048, 1024, 512, .., 32)
+ * Bits 15-2 : Maximum RX frame size
+ * Bit 1 : 1 = Ring Disabled, 0 = Ring ENabled
+ * Bit 0 : Reserved
+ */
rcb->bge_maxlen_flags =
BGE_RCB_MAXLEN_FLAGS(512, BGE_MAX_FRAMELEN << 2);
- else if (BGE_IS_5705_PLUS(sc))
+ } else if (BGE_IS_5705_PLUS(sc)) {
+ /*
+ * Bits 31-16: Programmable ring size (512, 256, 128, 64, 32)
+ * Bits 15-2 : Reserved (should be 0)
+ * Bit 1 : 1 = Ring Disabled, 0 = Ring Enabled
+ * Bit 0 : Reserved
+ */
rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(512, 0);
- else
+ } else {
+ /*
+ * Ring size is always XXX entries
+ * Bits 31-16: Maximum RX frame size
+ * Bits 15-2 : Reserved (should be 0)
+ * Bit 1 : 1 = Ring Disabled, 0 = Ring Enabled
+ * Bit 0 : Reserved
+ */
rcb->bge_maxlen_flags =
BGE_RCB_MAXLEN_FLAGS(BGE_MAX_FRAMELEN, 0);
+ }
if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 ||
BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719 ||
BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5720)
rcb->bge_nicaddr = BGE_STD_RX_RINGS_5717;
else
rcb->bge_nicaddr = BGE_STD_RX_RINGS;
+ /* Write the standard receive producer ring control block. */
CSR_WRITE_4(sc, BGE_RX_STD_RCB_HADDR_HI, rcb->bge_hostaddr.bge_addr_hi);
CSR_WRITE_4(sc, BGE_RX_STD_RCB_HADDR_LO, rcb->bge_hostaddr.bge_addr_lo);
CSR_WRITE_4(sc, BGE_RX_STD_RCB_MAXLEN_FLAGS, rcb->bge_maxlen_flags);
CSR_WRITE_4(sc, BGE_RX_STD_RCB_NICADDR, rcb->bge_nicaddr);
+ /* Reset the standard receive producer ring producer index. */
+ bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, 0);
+
/*
* Step 42: Initialize the jumbo RX ring control block
* We set the 'ring disabled' bit in the flags
@@ -2619,9 +2667,8 @@ bge_blockinit(struct bge_softc *sc)
rcb = &sc->bge_rdata->bge_info.bge_jumbo_rx_rcb;
BGE_HOSTADDR(rcb->bge_hostaddr,
BGE_RING_DMA_ADDR(sc, bge_rx_jumbo_ring));
- rcb->bge_maxlen_flags =
- BGE_RCB_MAXLEN_FLAGS(BGE_MAX_FRAMELEN,
- BGE_RCB_FLAG_RING_DISABLED);
+ rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(0,
+ BGE_RCB_FLAG_USE_EXT_RX_BD | BGE_RCB_FLAG_RING_DISABLED);
if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 ||
BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719 ||
BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5720)
@@ -2632,6 +2679,7 @@ bge_blockinit(struct bge_softc *sc)
rcb->bge_hostaddr.bge_addr_hi);
CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_HADDR_LO,
rcb->bge_hostaddr.bge_addr_lo);
+ /* Program the jumbo receive producer ring RCB parameters. */
CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_MAXLEN_FLAGS,
rcb->bge_maxlen_flags);
CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_NICADDR, rcb->bge_nicaddr);
@@ -2643,8 +2691,8 @@ bge_blockinit(struct bge_softc *sc)
if (BGE_IS_5700_FAMILY(sc)) {
/* Set up dummy disabled mini ring RCB */
rcb = &sc->bge_rdata->bge_info.bge_mini_rx_rcb;
- rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(0,
- BGE_RCB_FLAG_RING_DISABLED);
+ rcb->bge_maxlen_flags =
+ BGE_RCB_MAXLEN_FLAGS(0, BGE_RCB_FLAG_RING_DISABLED);
CSR_WRITE_4(sc, BGE_RX_MINI_RCB_MAXLEN_FLAGS,
rcb->bge_maxlen_flags);
/* Reset the mini receive producer ring producer index. */
@@ -2665,22 +2713,21 @@ bge_blockinit(struct bge_softc *sc)
(CSR_READ_4(sc, BGE_ISO_PKT_TX) & ~3) | 2);
}
/*
+ * The BD ring replenish thresholds control how often the
+ * hardware fetches new BD's from the producer rings in host
+ * memory. Setting the value too low on a busy system can
+ * starve the hardware and recue the throughpout.
+ *
* Set the BD ring replenish thresholds. The recommended
* values are 1/8th the number of descriptors allocated to
- * each ring.
+ * each ring, but since we try to avoid filling the entire
+ * ring we set these to the minimal value of 8. This needs to
+ * be done on several of the supported chip revisions anyway,
+ * to work around HW bugs.
*/
- i = BGE_STD_RX_RING_CNT / 8;
-
- /*
- * Use a value of 8 for the following chips to workaround HW errata.
- * Some of these chips have been added based on empirical
- * evidence (they don't work unless this is done).
- */
- if (BGE_IS_5705_PLUS(sc))
- i = 8;
-
- CSR_WRITE_4(sc, BGE_RBDI_STD_REPL_THRESH, i);
- CSR_WRITE_4(sc, BGE_RBDI_JUMBO_REPL_THRESH, BGE_JUMBO_RX_RING_CNT / 8);
+ CSR_WRITE_4(sc, BGE_RBDI_STD_REPL_THRESH, 8);
+ if (BGE_IS_JUMBO_CAPABLE(sc))
+ CSR_WRITE_4(sc, BGE_RBDI_JUMBO_REPL_THRESH, 8);
if (BGE_IS_5717_PLUS(sc)) {
CSR_WRITE_4(sc, BGE_STD_REPL_LWM, 4);
@@ -2688,19 +2735,24 @@ bge_blockinit(struct bge_softc *sc)
}
/*
- * Disable all unused send rings by setting the 'ring disabled'
- * bit in the flags field of all the TX send ring control blocks.
- * These are located in NIC memory.
+ * Disable all send rings by setting the 'ring disabled' bit
+ * in the flags field of all the TX send ring control blocks,
+ * located in NIC memory.
*/
+ if (BGE_IS_5700_FAMILY(sc)) {
+ /* 5700 to 5704 had 16 send rings. */
+ limit = BGE_TX_RINGS_EXTSSRAM_MAX;
+ } else
+ limit = 1;
rcb_addr = BGE_MEMWIN_START + BGE_SEND_RING_RCB;
- for (i = 0; i < BGE_TX_RINGS_EXTSSRAM_MAX; i++) {
+ for (i = 0; i < limit; i++) {
RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,
BGE_RCB_MAXLEN_FLAGS(0, BGE_RCB_FLAG_RING_DISABLED));
RCB_WRITE_4(sc, rcb_addr, bge_nicaddr, 0);
rcb_addr += sizeof(struct bge_rcb);
}
- /* Configure TX RCB 0 (we use only the first ring) */
+ /* Configure send ring RCB 0 (we use only the first ring) */
rcb_addr = BGE_MEMWIN_START + BGE_SEND_RING_RCB;
BGE_HOSTADDR(taddr, BGE_RING_DMA_ADDR(sc, bge_tx_ring));
RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_hi, taddr.bge_addr_hi);
@@ -2712,13 +2764,29 @@ bge_blockinit(struct bge_softc *sc)
else
RCB_WRITE_4(sc, rcb_addr, bge_nicaddr,
BGE_NIC_TXRING_ADDR(0, BGE_TX_RING_CNT));
- if (BGE_IS_5700_FAMILY(sc))
- RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,
- BGE_RCB_MAXLEN_FLAGS(BGE_TX_RING_CNT, 0));
+ RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,
+ BGE_RCB_MAXLEN_FLAGS(BGE_TX_RING_CNT, 0));
- /* Disable all unused RX return rings */
+ /*
+ * Disable all receive return rings by setting the
+ * 'ring diabled' bit in the flags field of all the receive
+ * return ring control blocks, located in NIC memory.
+ */
+ if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 ||
+ BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5719 ||
+ BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5720) {
+ /* Should be 17, use 16 until we get an SRAM map. */
+ limit = 16;
+ } else if (BGE_IS_5700_FAMILY(sc))
+ limit = BGE_RX_RINGS_MAX;
+ else if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755 ||
+ BGE_IS_57765_PLUS(sc))
+ limit = 4;
+ else
+ limit = 1;
+ /* Disable all receive return rings */
rcb_addr = BGE_MEMWIN_START + BGE_RX_RETURN_RING_RCB;
- for (i = 0; i < BGE_RX_RINGS_MAX; i++) {
+ for (i = 0; i < limit; i++) {
RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_hi, 0);
RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_lo, 0);
RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,
@@ -2731,10 +2799,9 @@ bge_blockinit(struct bge_softc *sc)
}
/*
- * Set up RX return ring 0
- * Note that the NIC address for RX return rings is 0x00000000.
- * The return rings live entirely within the host, so the
- * nicaddr field in the RCB isn't used.
+ * Set up receive return ring 0. Note that the NIC address
+ * for RX return rings is 0x0. The return rings live entirely
+ * within the host, so the nicaddr field in the RCB isn't used.
*/
rcb_addr = BGE_MEMWIN_START + BGE_RX_RETURN_RING_RCB;
BGE_HOSTADDR(taddr, BGE_RING_DMA_ADDR(sc, bge_rx_return_ring));
@@ -2864,24 +2931,7 @@ bge_blockinit(struct bge_softc *sc)
DELAY(40);
/* Set misc. local control, enable interrupts on attentions */
- sc->bge_local_ctrl_reg = BGE_MLC_INTR_ONATTN | BGE_MLC_AUTO_EEPROM;
-
-#ifdef notdef
- /* Assert GPIO pins for PHY reset */
- BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_MISCIO_OUT0|
- BGE_MLC_MISCIO_OUT1|BGE_MLC_MISCIO_OUT2);
- BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_MISCIO_OUTEN0|
- BGE_MLC_MISCIO_OUTEN1|BGE_MLC_MISCIO_OUTEN2);
-#endif
-
-#if defined(not_quite_yet)
- /* Linux driver enables enable gpio pin #1 on 5700s */
- if (sc->bge_chipid == BGE_CHIPID_BCM5700) {
- sc->bge_local_ctrl_reg |=
- (BGE_MLC_MISCIO_OUT1|BGE_MLC_MISCIO_OUTEN1);
- }
-#endif
- CSR_WRITE_4(sc, BGE_MISC_LOCAL_CTL, sc->bge_local_ctrl_reg);
+ CSR_WRITE_4(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_INTR_ONATTN);
/* Turn on DMA completion state machine */
if (!(BGE_IS_5705_PLUS(sc)))
@@ -2999,7 +3049,8 @@ bge_blockinit(struct bge_softc *sc)
/* Turn on send data initiator state machine */
if (sc->bge_flags & BGE_TSO) {
/* XXX: magic value from Linux driver */
- CSR_WRITE_4(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE | 0x08);
+ CSR_WRITE_4(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE |
+ BGE_SDIMODE_HW_LSO_PRE_DMA);
} else
CSR_WRITE_4(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE);
@@ -3578,13 +3629,8 @@ bge_attach(device_t parent, device_t sel
sc->bge_stat_ticks = BGE_TICKS_PER_SEC;
sc->bge_rx_coal_ticks = 150;
sc->bge_rx_max_coal_bds = 64;
-#ifdef ORIG_WPAUL_VALUES
- sc->bge_tx_coal_ticks = 150;
- sc->bge_tx_max_coal_bds = 128;
-#else
sc->bge_tx_coal_ticks = 300;
sc->bge_tx_max_coal_bds = 400;
-#endif
if (BGE_IS_5705_PLUS(sc)) {
sc->bge_tx_coal_ticks = (12 * 5);
sc->bge_tx_max_coal_bds = (12 * 5);
@@ -3844,7 +3890,7 @@ bge_reset(struct bge_softc *sc)
* during global reset.
*/
CSR_WRITE_4(sc, BGE_MISC_CFG, 1 << 29);
- reset |= (1<<29);
+ reset |= (1 << 29);
}
}
@@ -3865,10 +3911,6 @@ bge_reset(struct bge_softc *sc)
(sc->bge_flags & BGE_CPMU_PRESENT) == 0)
reset |= BGE_MISCCFG_GPHY_PD_OVERRIDE;
- /* XXX 5721, 5751 and 5752 */
- if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750)
- reset |= BGE_MISCCFG_GRC_RESET_DISABLE;
-
/* Issue global reset */
write_op(sc, BGE_MISC_CFG, reset);
Index: src/sys/dev/pci/if_bgereg.h
diff -u src/sys/dev/pci/if_bgereg.h:1.66 src/sys/dev/pci/if_bgereg.h:1.67
--- src/sys/dev/pci/if_bgereg.h:1.66 Tue Mar 19 04:10:13 2013
+++ src/sys/dev/pci/if_bgereg.h Thu Mar 21 12:33:11 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bgereg.h,v 1.66 2013/03/19 04:10:13 msaitoh Exp $ */
+/* $NetBSD: if_bgereg.h,v 1.67 2013/03/21 12:33:11 msaitoh Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
* Copyright (c) 1997, 1998, 1999, 2001
@@ -890,6 +890,7 @@
#define BGE_SDIMODE_RESET 0x00000001
#define BGE_SDIMODE_ENABLE 0x00000002
#define BGE_SDIMODE_STATS_OFLOW_ATTN 0x00000004
+#define BGE_SDIMODE_HW_LSO_PRE_DMA 0x00000008
/* Send Data Initiator stats register */
#define BGE_SDISTAT_STATS_OFLOW_ATTN 0x00000004
Index: src/sys/dev/pci/if_bgevar.h
diff -u src/sys/dev/pci/if_bgevar.h:1.12 src/sys/dev/pci/if_bgevar.h:1.13
--- src/sys/dev/pci/if_bgevar.h:1.12 Sun Mar 17 04:06:39 2013
+++ src/sys/dev/pci/if_bgevar.h Thu Mar 21 12:33:10 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bgevar.h,v 1.12 2013/03/17 04:06:39 msaitoh Exp $ */
+/* $NetBSD: if_bgevar.h,v 1.13 2013/03/21 12:33:10 msaitoh Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
* Copyright (c) 1997, 1998, 1999, 2001
@@ -284,7 +284,6 @@ struct bge_softc {
int bge_phy_ape_lock;
int bge_phy_addr;
uint32_t bge_chipid;
- uint32_t bge_local_ctrl_reg;
uint8_t bge_asf_mode;
uint8_t bge_asf_count;
struct bge_ring_data *bge_rdata; /* rings */