summaryrefslogtreecommitdiffstats
path: root/sys/dev/bce
diff options
context:
space:
mode:
authordavidch <davidch@FreeBSD.org>2009-06-23 22:19:27 +0000
committerdavidch <davidch@FreeBSD.org>2009-06-23 22:19:27 +0000
commitdaf61e7b90caa82bf71529387b20f823971b0e43 (patch)
tree446170869614daf2671d1562c46ed4c9f8f5710f /sys/dev/bce
parent92b4ecdc77d13ff9a166408b07bb4c90b00bb3f2 (diff)
downloadFreeBSD-src-daf61e7b90caa82bf71529387b20f823971b0e43.zip
FreeBSD-src-daf61e7b90caa82bf71529387b20f823971b0e43.tar.gz
- Added code to read bootcode firwmare version.
- Created dedicated shared memory access routines. MFC after: One week
Diffstat (limited to 'sys/dev/bce')
-rw-r--r--sys/dev/bce/if_bce.c161
-rw-r--r--sys/dev/bce/if_bcereg.h13
2 files changed, 131 insertions, 43 deletions
diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c
index 43aec4b..c65451d 100644
--- a/sys/dev/bce/if_bce.c
+++ b/sys/dev/bce/if_bce.c
@@ -329,6 +329,8 @@ static void bce_breakpoint (struct bce_softc *);
/****************************************************************************/
static u32 bce_reg_rd_ind (struct bce_softc *, u32);
static void bce_reg_wr_ind (struct bce_softc *, u32, u32);
+static void bce_shmem_wr (struct bce_softc *, u32, u32);
+static u32 bce_shmem_rd (struct bce_softc *, u32);
static void bce_ctx_wr (struct bce_softc *, u32, u32, u32);
static int bce_miibus_read_reg (device_t, int, int);
static int bce_miibus_write_reg (device_t, int, int, int);
@@ -574,6 +576,8 @@ bce_probe(device_t dev)
static void
bce_print_adapter_info(struct bce_softc *sc)
{
+ int i = 0;
+
DBENTER(BCE_VERBOSE_LOAD);
BCE_PRINTF("ASIC (0x%08X); ", sc->bce_chipid);
@@ -596,19 +600,33 @@ bce_print_adapter_info(struct bce_softc *sc)
}
/* Firmware version and device features. */
- printf("B/C (0x%08X); Flags( ", sc->bce_bc_ver);
+ printf("B/C (%s); Flags (", sc->bce_bc_ver);
+
#ifdef ZERO_COPY_SOCKETS
printf("SPLT ");
+ i++;
#endif
- if (sc->bce_flags & BCE_MFW_ENABLE_FLAG)
- printf("MFW ");
- if (sc->bce_flags & BCE_USING_MSI_FLAG)
- printf("MSI ");
- if (sc->bce_flags & BCE_USING_MSIX_FLAG)
- printf("MSI-X ");
- if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)
- printf("2.5G ");
- printf(")\n");
+ if (sc->bce_flags & BCE_USING_MSI_FLAG) {
+ if (i > 0) printf("|");
+ printf("MSI"); i++;
+ }
+
+ if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
+ if (i > 0) printf("|");
+ printf("MSI-X "); i++;
+ }
+
+ if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) {
+ if (i > 0) printf("|");
+ printf("2.5G"); i++;
+ }
+
+ if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
+ if (i > 0) printf("|");
+ printf("MFW); MFW (%s)\n", sc->bce_mfw_ver);
+ } else {
+ printf(")\n");
+ }
DBEXIT(BCE_VERBOSE_LOAD);
}
@@ -847,13 +865,50 @@ bce_attach(device_t dev)
__FUNCTION__, sc->bce_shmem_base);
/* Fetch the bootcode revision. */
- sc->bce_bc_ver = REG_RD_IND(sc, sc->bce_shmem_base +
- BCE_DEV_INFO_BC_REV);
-
- /* Check if any management firmware is running. */
- val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_PORT_FEATURE);
- if (val & (BCE_PORT_FEATURE_ASF_ENABLED | BCE_PORT_FEATURE_IMD_ENABLED))
- sc->bce_flags |= BCE_MFW_ENABLE_FLAG;
+ val = bce_shmem_rd(sc, BCE_DEV_INFO_BC_REV);
+ for (int i = 0, j = 0; i < 3; i++) {
+ u8 num;
+
+ num = (u8) (val >> (24 - (i * 8)));
+ for (int k = 100, skip0 = 1; k >= 1; num %= k, k /= 10) {
+ if (num >= k || !skip0 || k == 1) {
+ sc->bce_bc_ver[j++] = (num / k) + '0';
+ skip0 = 0;
+ }
+ }
+ if (i != 2)
+ sc->bce_bc_ver[j++] = '.';
+ }
+
+ /* Check if any management firwmare is running. */
+ val = bce_shmem_rd(sc, BCE_PORT_FEATURE);
+ if (val & BCE_PORT_FEATURE_ASF_ENABLED) {
+ sc->bce_flags |= BCE_MFW_ENABLE_FLAG;
+
+ /* Allow time for firmware to enter the running state. */
+ for (int i = 0; i < 30; i++) {
+ val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
+ if (val & BCE_CONDITION_MFW_RUN_MASK)
+ break;
+ DELAY(10000);
+ }
+ }
+
+ /* Check the current bootcode state. */
+ val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
+ val &= BCE_CONDITION_MFW_RUN_MASK;
+ if (val != BCE_CONDITION_MFW_RUN_UNKNOWN &&
+ val != BCE_CONDITION_MFW_RUN_NONE) {
+ u32 addr = bce_shmem_rd(sc, BCE_MFW_VER_PTR);
+ int i = 0;
+
+ for (int j = 0; j < 3; j++) {
+ val = bce_reg_rd_ind(sc, addr + j * 4);
+ val = bswap32(val);
+ memcpy(&sc->bce_mfw_ver[i], &val, 4);
+ i += 4;
+ }
+ }
/* Get PCI bus information (speed and type). */
val = REG_RD(sc, BCE_PCICFG_MISC_STATUS);
@@ -967,10 +1022,8 @@ bce_attach(device_t dev)
bce_get_media(sc);
/* Store data needed by PHY driver for backplane applications */
- sc->bce_shared_hw_cfg = REG_RD_IND(sc, sc->bce_shmem_base +
- BCE_SHARED_HW_CFG_CONFIG);
- sc->bce_port_hw_cfg = REG_RD_IND(sc, sc->bce_shmem_base +
- BCE_PORT_HW_CFG_CONFIG);
+ sc->bce_shared_hw_cfg = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
+ sc->bce_port_hw_cfg = bce_shmem_rd(sc, BCE_PORT_HW_CFG_CONFIG);
/* Allocate DMA memory resources. */
if (bce_dma_alloc(dev)) {
@@ -1293,6 +1346,36 @@ bce_reg_wr_ind(struct bce_softc *sc, u32 offset, u32 val)
}
+/****************************************************************************/
+/* Shared memory write. */
+/* */
+/* Writes NetXtreme II shared memory region. */
+/* */
+/* Returns: */
+/* Nothing. */
+/****************************************************************************/
+static void
+bce_shmem_wr(struct bce_softc *sc, u32 offset, u32 val)
+{
+ bce_reg_wr_ind(sc, sc->bce_shmem_base + offset, val);
+}
+
+
+/****************************************************************************/
+/* Shared memory read. */
+/* */
+/* Reads NetXtreme II shared memory region. */
+/* */
+/* Returns: */
+/* The 32 bit value read. */
+/****************************************************************************/
+static u32
+bce_shmem_rd(struct bce_softc *sc, u32 offset)
+{
+ return (bce_reg_rd_ind(sc, sc->bce_shmem_base + offset));
+}
+
+
#ifdef BCE_DEBUG
/****************************************************************************/
/* Context memory read. */
@@ -2094,7 +2177,7 @@ bce_init_nvram(struct bce_softc *sc)
bce_init_nvram_get_flash_size:
/* Write the flash config data to the shared memory interface. */
- val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_SHARED_HW_CFG_CONFIG2);
+ val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG2);
val &= BCE_SHARED_HW_CFG2_NVM_SIZE_MASK;
if (val)
sc->bce_flash_size = val;
@@ -2583,8 +2666,7 @@ bce_get_media(struct bce_softc *sc)
sc->bce_flags |= BCE_NO_WOL_FLAG;
if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
sc->bce_phy_addr = 2;
- val = REG_RD_IND(sc, sc->bce_shmem_base +
- BCE_SHARED_HW_CFG_CONFIG);
+ val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
if (val & BCE_SHARED_HW_CFG_PHY_2_5G) {
sc->bce_phy_flags |= BCE_PHY_2_5G_CAPABLE_FLAG;
DBPRINT(sc, BCE_INFO_LOAD, "Found 2.5Gb capable adapter\n");
@@ -3487,12 +3569,12 @@ bce_fw_sync(struct bce_softc *sc, u32 msg_data)
msg_data);
/* Send the message to the bootcode driver mailbox. */
- REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_MB, msg_data);
+ bce_shmem_wr(sc, BCE_DRV_MB, msg_data);
/* Wait for the bootcode to acknowledge the message. */
for (i = 0; i < FW_ACK_TIME_OUT_MS; i++) {
/* Check for a response in the bootcode firmware mailbox. */
- val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_FW_MB);
+ val = bce_shmem_rd(sc, BCE_FW_MB);
if ((val & BCE_FW_MSG_ACK) == (msg_data & BCE_DRV_MSG_SEQ))
break;
DELAY(1000);
@@ -3509,7 +3591,7 @@ bce_fw_sync(struct bce_softc *sc, u32 msg_data)
msg_data &= ~BCE_DRV_MSG_CODE;
msg_data |= BCE_DRV_MSG_CODE_FW_TIMEOUT;
- REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_MB, msg_data);
+ bce_shmem_wr(sc, BCE_DRV_MB, msg_data);
sc->bce_fw_timed_out = 1;
rc = EBUSY;
@@ -4309,10 +4391,8 @@ bce_get_mac_addr(struct bce_softc *sc)
* shared memory for speed.
*/
- mac_hi = REG_RD_IND(sc, sc->bce_shmem_base +
- BCE_PORT_HW_CFG_MAC_UPPER);
- mac_lo = REG_RD_IND(sc, sc->bce_shmem_base +
- BCE_PORT_HW_CFG_MAC_LOWER);
+ mac_hi = bce_shmem_rd(sc, BCE_PORT_HW_CFG_MAC_UPPER);
+ mac_lo = bce_shmem_rd(sc, BCE_PORT_HW_CFG_MAC_LOWER);
if ((mac_lo == 0) && (mac_hi == 0)) {
BCE_PRINTF("%s(%d): Invalid Ethernet address!\n",
@@ -4467,8 +4547,7 @@ bce_reset(struct bce_softc *sc, u32 reset_code)
goto bce_reset_exit;
/* Set a firmware reminder that this is a soft reset. */
- REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_RESET_SIGNATURE,
- BCE_DRV_RESET_SIGNATURE_MAGIC);
+ bce_shmem_wr(sc, BCE_DRV_RESET_SIGNATURE, BCE_DRV_RESET_SIGNATURE_MAGIC);
/* Dummy read to force the chip to complete all current transactions. */
val = REG_RD(sc, BCE_MISC_ID);
@@ -4735,7 +4814,7 @@ bce_blockinit(struct bce_softc *sc)
REG_WR(sc, BCE_HC_COMMAND, BCE_HC_COMMAND_CLR_STAT_NOW);
/* Verify that bootcode is running. */
- reg = REG_RD_IND(sc, sc->bce_shmem_base + BCE_DEV_INFO_SIGNATURE);
+ reg = bce_shmem_rd(sc, BCE_DEV_INFO_SIGNATURE);
DBRUNIF(DB_RANDOMTRUE(bootcode_running_failure_sim_control),
BCE_PRINTF("%s(%d): Simulating bootcode failure.\n",
@@ -7470,7 +7549,7 @@ bce_pulse(void *xsc)
/* Tell the firmware that the driver is still running. */
msg = (u32) ++sc->bce_fw_drv_pulse_wr_seq;
- REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_PULSE_MB, msg);
+ bce_shmem_wr(sc, BCE_DRV_PULSE_MB, msg);
/* Schedule the next pulse. */
callout_reset(&sc->bce_pulse_callout, hz, bce_pulse, sc);
@@ -9824,7 +9903,7 @@ bce_dump_hw_state(struct bce_softc *sc)
" Hardware State "
"----------------------------\n");
- BCE_PRINTF("0x%08X - bootcode version\n", sc->bce_bc_ver);
+ BCE_PRINTF("%s - bootcode version\n", sc->bce_bc_ver);
val = REG_RD(sc, BCE_MISC_ENABLE_STATUS_BITS);
BCE_PRINTF("0x%08X - (0x%06X) misc_enable_status_bits\n",
@@ -9949,21 +10028,21 @@ bce_dump_bc_state(struct bce_softc *sc)
" Bootcode State "
"----------------------------\n");
- BCE_PRINTF("0x%08X - bootcode version\n", sc->bce_bc_ver);
+ BCE_PRINTF("%s - bootcode version\n", sc->bce_bc_ver);
- val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_BC_RESET_TYPE);
+ val = bce_shmem_rd(sc, BCE_BC_RESET_TYPE);
BCE_PRINTF("0x%08X - (0x%06X) reset_type\n",
val, BCE_BC_RESET_TYPE);
- val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_BC_STATE);
+ val = bce_shmem_rd(sc, BCE_BC_STATE);
BCE_PRINTF("0x%08X - (0x%06X) state\n",
val, BCE_BC_STATE);
- val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_BC_CONDITION);
+ val = bce_shmem_rd(sc, BCE_BC_CONDITION);
BCE_PRINTF("0x%08X - (0x%06X) condition\n",
val, BCE_BC_CONDITION);
- val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_BC_STATE_DEBUG_CMD);
+ val = bce_shmem_rd(sc, BCE_BC_STATE_DEBUG_CMD);
BCE_PRINTF("0x%08X - (0x%06X) debug_cmd\n",
val, BCE_BC_STATE_DEBUG_CMD);
diff --git a/sys/dev/bce/if_bcereg.h b/sys/dev/bce/if_bcereg.h
index 32456fd..cd75f0c 100644
--- a/sys/dev/bce/if_bcereg.h
+++ b/sys/dev/bce/if_bcereg.h
@@ -999,6 +999,8 @@ struct flash_spec {
#define BCE_PORT_FEATURE_MBA_VLAN_TAG_MASK 0xffff
#define BCE_PORT_FEATURE_MBA_VLAN_ENABLE 0x10000
+#define BCE_MFW_VER_PTR 0x00000014c
+
#define BCE_BC_STATE_RESET_TYPE 0x000001c0
#define BCE_BC_STATE_RESET_TYPE_SIG 0x00005254
#define BCE_BC_STATE_RESET_TYPE_SIG_MASK 0x0000ffff
@@ -1054,7 +1056,13 @@ struct flash_spec {
#define BCE_BC_STATE_ERR_NO_RXP (BCE_BC_STATE_SIGN | 0x0600)
#define BCE_BC_STATE_ERR_TOO_MANY_RBUF (BCE_BC_STATE_SIGN | 0x0700)
-#define BCE_BC_CONDITION 0x000001c8
+#define BCE_BC_STATE_CONDITION 0x000001c8
+#define BCE_CONDITION_MFW_RUN_UNKNOWN 0x00000000
+#define BCE_CONDITION_MFW_RUN_IPMI 0x00002000
+#define BCE_CONDITION_MFW_RUN_UMP 0x00004000
+#define BCE_CONDITION_MFW_RUN_NCSI 0x00006000
+#define BCE_CONDITION_MFW_RUN_NONE 0x0000e000
+#define BCE_CONDITION_MFW_RUN_MASK 0x0000e000
#define BCE_BC_STATE_DEBUG_CMD 0x1dc
#define BCE_BC_STATE_BC_DBG_CMD_SIGNATURE 0x42440000
@@ -6457,7 +6465,8 @@ struct bce_softc
char * bce_name; /* Name string */
/* Tracks the version of bootcode firmware. */
- u32 bce_bc_ver;
+ char bce_bc_ver[32];
+ char bce_mfw_ver[32];
/* Tracks the state of the firmware. 0 = Running while any */
/* other value indicates that the firmware is not responding. */
OpenPOWER on IntegriCloud