svn commit: r202717 - head/sys/dev/bce

David Christensen davidch at FreeBSD.org
Wed Jan 20 20:33:11 UTC 2010


Author: davidch
Date: Wed Jan 20 20:33:10 2010
New Revision: 202717
URL: http://svn.freebsd.org/changeset/base/202717

Log:
  - Added a workaround for NC-SI management firmware that would allow
    frames to be accepted while the driver is resetting the hardware.
    This failure is generally observed when broadcast frames are received
    during driver load and will generate "Unable to write CTX memory"
    errors.
  - Small changes to driver flags display.

Modified:
  head/sys/dev/bce/if_bce.c
  head/sys/dev/bce/if_bcereg.h

Modified: head/sys/dev/bce/if_bce.c
==============================================================================
--- head/sys/dev/bce/if_bce.c	Wed Jan 20 19:20:31 2010	(r202716)
+++ head/sys/dev/bce/if_bce.c	Wed Jan 20 20:33:10 2010	(r202717)
@@ -371,6 +371,9 @@ static void bce_release_resources	(struc
 static int  bce_fw_sync				(struct bce_softc *, u32);
 static void bce_load_rv2p_fw		(struct bce_softc *, u32 *, u32, u32);
 static void bce_load_cpu_fw			(struct bce_softc *, struct cpu_reg *, struct fw_info *);
+static void bce_start_cpu           (struct bce_softc *, struct cpu_reg *);
+static void bce_halt_cpu            (struct bce_softc *, struct cpu_reg *);
+static void bce_start_rxp_cpu       (struct bce_softc *);
 static void bce_init_rxp_cpu		(struct bce_softc *);
 static void bce_init_txp_cpu 		(struct bce_softc *);
 static void bce_init_tpat_cpu		(struct bce_softc *);
@@ -603,9 +606,10 @@ bce_print_adapter_info(struct bce_softc 
 	printf("B/C (%s); Flags (", sc->bce_bc_ver);
 
 #ifdef BCE_JUMBO_HDRSPLIT
-	printf("SPLT ");
+	printf("SPLT");
     i++;
 #endif
+
     if (sc->bce_flags & BCE_USING_MSI_FLAG) {
         if (i > 0) printf("|");
 		printf("MSI"); i++;
@@ -613,7 +617,7 @@ bce_print_adapter_info(struct bce_softc 
 
     if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
         if (i > 0) printf("|");
-		printf("MSI-X "); i++;
+		printf("MSI-X"); i++;
     }
 
     if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) {
@@ -2976,6 +2980,7 @@ bce_dma_map_addr(void *arg, bus_dma_segm
 /* |PG Buffers       |   none   |   none   |   none   |   none   |          */
 /* |TX Buffers       |   none   |   none   |   none   |   none   |          */
 /* |Chain Pages(1)   |   4KiB   |   4KiB   |   4KiB   |   4KiB   |          */
+/* |Context Memory   |          |          |          |          |          */
 /* +-----------------+----------+----------+----------+----------+          */
 /*                                                                          */
 /* (1) Must align with CPU page size (BCM_PAGE_SZIE).                       */
@@ -3665,15 +3670,10 @@ bce_load_cpu_fw(struct bce_softc *sc, st
 	struct fw_info *fw)
 {
 	u32 offset;
-	u32 val;
 
 	DBENTER(BCE_VERBOSE_RESET);
 
-	/* Halt the CPU. */
-	val = REG_RD_IND(sc, cpu_reg->mode);
-	val |= cpu_reg->mode_value_halt;
-	REG_WR_IND(sc, cpu_reg->mode, val);
-	REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
+    bce_halt_cpu(sc, cpu_reg);
 
 	/* Load the Text area. */
 	offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
@@ -3726,9 +3726,28 @@ bce_load_cpu_fw(struct bce_softc *sc, st
 		}
 	}
 
-	/* Clear the pre-fetch instruction. */
-	REG_WR_IND(sc, cpu_reg->inst, 0);
-	REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
+    /* Clear the pre-fetch instruction and set the FW start address. */
+    REG_WR_IND(sc, cpu_reg->inst, 0);
+    REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
+
+	DBEXIT(BCE_VERBOSE_RESET);
+}
+
+
+/****************************************************************************/
+/* Starts the RISC processor.                                               */
+/*                                                                          */
+/* Assumes the CPU starting address has already been set.                   */
+/*                                                                          */
+/* Returns:                                                                 */
+/*   Nothing.                                                               */
+/****************************************************************************/
+static void
+bce_start_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg)
+{
+	u32 val;
+
+	DBENTER(BCE_VERBOSE_RESET);
 
 	/* Start the CPU. */
 	val = REG_RD_IND(sc, cpu_reg->mode);
@@ -3741,6 +3760,62 @@ bce_load_cpu_fw(struct bce_softc *sc, st
 
 
 /****************************************************************************/
+/* Halts the RISC processor.                                                */
+/*                                                                          */
+/* Returns:                                                                 */
+/*   Nothing.                                                               */
+/****************************************************************************/
+static void
+bce_halt_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg)
+{
+	u32 val;
+
+	DBENTER(BCE_VERBOSE_RESET);
+
+    /* Halt the CPU. */
+    val = REG_RD_IND(sc, cpu_reg->mode);
+    val |= cpu_reg->mode_value_halt;
+    REG_WR_IND(sc, cpu_reg->mode, val);
+    REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
+
+	DBEXIT(BCE_VERBOSE_RESET);
+}
+
+
+/****************************************************************************/
+/* Initialize the RX CPU.                                                   */
+/*                                                                          */
+/* Returns:                                                                 */
+/*   Nothing.                                                               */
+/****************************************************************************/
+static void
+bce_start_rxp_cpu(struct bce_softc *sc)
+{
+	struct cpu_reg cpu_reg;
+
+	DBENTER(BCE_VERBOSE_RESET);
+
+	cpu_reg.mode = BCE_RXP_CPU_MODE;
+	cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
+	cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
+	cpu_reg.state = BCE_RXP_CPU_STATE;
+	cpu_reg.state_value_clear = 0xffffff;
+	cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
+	cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
+	cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
+	cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
+	cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
+	cpu_reg.spad_base = BCE_RXP_SCRATCH;
+	cpu_reg.mips_view_base = 0x8000000;
+
+	DBPRINT(sc, BCE_INFO_RESET, "Starting RX firmware.\n");
+	bce_start_cpu(sc, &cpu_reg);
+
+	DBEXIT(BCE_VERBOSE_RESET);
+}
+
+
+/****************************************************************************/
 /* Initialize the RX CPU.                                                   */
 /*                                                                          */
 /* Returns:                                                                 */
@@ -3833,6 +3908,8 @@ bce_init_rxp_cpu(struct bce_softc *sc)
 	DBPRINT(sc, BCE_INFO_RESET, "Loading RX firmware.\n");
 	bce_load_cpu_fw(sc, &cpu_reg, &fw);
 
+    /* Delay RXP start until initialization is complete. */
+
 	DBEXIT(BCE_VERBOSE_RESET);
 }
 
@@ -3929,6 +4006,7 @@ bce_init_txp_cpu(struct bce_softc *sc)
 
 	DBPRINT(sc, BCE_INFO_RESET, "Loading TX firmware.\n");
 	bce_load_cpu_fw(sc, &cpu_reg, &fw);
+    bce_start_cpu(sc, &cpu_reg);
 
 	DBEXIT(BCE_VERBOSE_RESET);
 }
@@ -4026,6 +4104,7 @@ bce_init_tpat_cpu(struct bce_softc *sc)
 
 	DBPRINT(sc, BCE_INFO_RESET, "Loading TPAT firmware.\n");
 	bce_load_cpu_fw(sc, &cpu_reg, &fw);
+    bce_start_cpu(sc, &cpu_reg);
 
 	DBEXIT(BCE_VERBOSE_RESET);
 }
@@ -4123,6 +4202,7 @@ bce_init_cp_cpu(struct bce_softc *sc)
 
 	DBPRINT(sc, BCE_INFO_RESET, "Loading CP firmware.\n");
 	bce_load_cpu_fw(sc, &cpu_reg, &fw);
+    bce_start_cpu(sc, &cpu_reg);
 
 	DBEXIT(BCE_VERBOSE_RESET);
 }
@@ -4220,6 +4300,7 @@ bce_init_com_cpu(struct bce_softc *sc)
 
 	DBPRINT(sc, BCE_INFO_RESET, "Loading COM firmware.\n");
 	bce_load_cpu_fw(sc, &cpu_reg, &fw);
+    bce_start_cpu(sc, &cpu_reg);
 
 	DBEXIT(BCE_VERBOSE_RESET);
 }
@@ -4665,6 +4746,12 @@ bce_chipinit(struct bce_softc *sc)
 	/* Initialize the on-boards CPUs */
 	bce_init_cpus(sc);
 
+    /* Enable management frames (NC-SI) to flow to the MCP. */
+    if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
+        val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) | BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
+        REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
+    }
+
 	/* Prepare NVRAM for access. */
 	if (bce_init_nvram(sc)) {
 		rc = ENODEV;
@@ -4845,6 +4932,15 @@ bce_blockinit(struct bce_softc *sc)
 	/* Enable link state change interrupt generation. */
 	REG_WR(sc, BCE_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
 
+    /* Enable the RXP. */
+    bce_start_rxp_cpu(sc);
+
+    /* Disable management frames (NC-SI) from flowing to the MCP. */
+    if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
+        val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) & ~BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
+        REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
+    }
+
 	/* Enable all remaining blocks in the MAC. */
 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)	||
 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
@@ -5851,22 +5947,29 @@ bce_rx_intr(struct bce_softc *sc)
 		DBRUN(sc->debug_rx_mbuf_alloc--);
 		sc->free_rx_bd++;
 
-		/*
-		 * Frames received on the NetXteme II are prepended	with an
-		 * l2_fhdr structure which provides status information about
-		 * the received frame (including VLAN tags and checksum info).
-		 * The frames are also automatically adjusted to align the IP
-		 * header (i.e. two null bytes are inserted before the Ethernet
-		 * header).  As a result the data DMA'd by the controller into
-		 * the mbuf is as follows:
-		 * 
-		 * +---------+-----+---------------------+-----+
-		 * | l2_fhdr | pad | packet data         | FCS |
-		 * +---------+-----+---------------------+-----+
-		 * 
-		 * The l2_fhdr needs to be checked and skipped and the FCS needs
-		 * to be stripped before sending the packet up the stack.
-		 */
+        if(m0 == NULL) {
+            DBPRINT(sc, BCE_EXTREME_RECV, "%s(): Oops! Empty mbuf pointer "
+                "found in sc->rx_mbuf_ptr[0x%04X]!\n",
+                __FUNCTION__, sw_rx_cons_idx);
+            goto bce_rx_int_next_rx;
+        }
+
+        /*
+         * Frames received on the NetXteme II are prepended	with an
+         * l2_fhdr structure which provides status information about
+         * the received frame (including VLAN tags and checksum info).
+         * The frames are also automatically adjusted to align the IP
+         * header (i.e. two null bytes are inserted before the Ethernet
+         * header).  As a result the data DMA'd by the controller into
+         * the mbuf is as follows:
+         * 
+         * +---------+-----+---------------------+-----+
+         * | l2_fhdr | pad | packet data         | FCS |
+         * +---------+-----+---------------------+-----+
+         * 
+         * The l2_fhdr needs to be checked and skipped and the FCS needs
+         * to be stripped before sending the packet up the stack.
+         */
 		l2fhdr  = mtod(m0, struct l2_fhdr *);
 
 		/* Get the packet data + FCS length and the status. */
@@ -6387,6 +6490,7 @@ bce_init_locked(struct bce_softc *sc)
 
 	bce_ifmedia_upd_locked(ifp);
 
+	/* Let the OS know the driver is up and running. */
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 
@@ -10038,9 +10142,9 @@ bce_dump_bc_state(struct bce_softc *sc)
 	BCE_PRINTF("0x%08X - (0x%06X) state\n",
 		val, BCE_BC_STATE);
 
-	val = bce_shmem_rd(sc, BCE_BC_CONDITION);
+	val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
 	BCE_PRINTF("0x%08X - (0x%06X) condition\n",
-		val, BCE_BC_CONDITION);
+		val, BCE_BC_STATE_CONDITION);
 
 	val = bce_shmem_rd(sc, BCE_BC_STATE_DEBUG_CMD);
 	BCE_PRINTF("0x%08X - (0x%06X) debug_cmd\n",

Modified: head/sys/dev/bce/if_bcereg.h
==============================================================================
--- head/sys/dev/bce/if_bcereg.h	Wed Jan 20 19:20:31 2010	(r202716)
+++ head/sys/dev/bce/if_bcereg.h	Wed Jan 20 20:33:10 2010	(r202717)
@@ -3715,6 +3715,10 @@ struct l2_fhdr {
 #define BCE_RPM_CONFIG_SORT_VECT_VAL			 (0xfL<<4)
 #define BCE_RPM_CONFIG_IGNORE_VLAN			 (1L<<31)
 
+#define BCE_RPM_MGMT_PKT_CTRL					0x0000180c
+#define BCE_RPM_MGMT_PKT_CTRL_MGMT_DISCARD_EN	 (1L<<30)
+#define BCE_RPM_MGMT_PKT_CTRL_MGMT_EN   		 (1L<<31)
+
 #define BCE_RPM_VLAN_MATCH0				0x00001810
 #define BCE_RPM_VLAN_MATCH0_RPM_VLAN_MTCH0_VALUE	 (0xfffL<<0)
 


More information about the svn-src-all mailing list