diff options
Diffstat (limited to 'sys/dev/bce')
-rw-r--r-- | sys/dev/bce/if_bce.c | 161 | ||||
-rw-r--r-- | sys/dev/bce/if_bcereg.h | 13 |
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. */ |