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 */

Reply via email to