Commit 452427b0 authored by Yuval Mintz's avatar Yuval Mintz Committed by David S. Miller

bnx2x: previous driver unload revised

The flow in which the bnx2x driver starts after a previous driver
has been terminated in an 'unclean' manner has several bugs and
FW risks, which makes it possible for the driver to fail after
boot-from-SAN or kdump.
This patch contains a revised flow which performs a safer
initialization, solving the possible crash scenarios.
Notice this patch contains lines with over 80 characters, as it
keeps print-strings in a single line.
Signed-off-by: default avatarYuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: default avatarEilon Greenstein <eilong@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a2daf263
...@@ -1173,6 +1173,13 @@ enum { ...@@ -1173,6 +1173,13 @@ enum {
}; };
struct bnx2x_prev_path_list {
u8 bus;
u8 slot;
u8 path;
struct list_head list;
};
struct bnx2x { struct bnx2x {
/* Fields used in the tx and intr/napi performance paths /* Fields used in the tx and intr/napi performance paths
* are grouped together in the beginning of the structure * are grouped together in the beginning of the structure
......
...@@ -1721,6 +1721,29 @@ static void bnx2x_squeeze_objects(struct bnx2x *bp) ...@@ -1721,6 +1721,29 @@ static void bnx2x_squeeze_objects(struct bnx2x *bp)
} while (0) } while (0)
#endif #endif
bool bnx2x_test_firmware_version(struct bnx2x *bp, bool is_err)
{
/* build FW version dword */
u32 my_fw = (BCM_5710_FW_MAJOR_VERSION) +
(BCM_5710_FW_MINOR_VERSION << 8) +
(BCM_5710_FW_REVISION_VERSION << 16) +
(BCM_5710_FW_ENGINEERING_VERSION << 24);
/* read loaded FW from chip */
u32 loaded_fw = REG_RD(bp, XSEM_REG_PRAM);
DP(NETIF_MSG_IFUP, "loaded fw %x, my fw %x\n", loaded_fw, my_fw);
if (loaded_fw != my_fw) {
if (is_err)
BNX2X_ERR("bnx2x with FW %x was already loaded, which mismatches my %x FW. aborting\n",
loaded_fw, my_fw);
return false;
}
return true;
}
/* must be called with rtnl_lock */ /* must be called with rtnl_lock */
int bnx2x_nic_load(struct bnx2x *bp, int load_mode) int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
{ {
...@@ -1815,23 +1838,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) ...@@ -1815,23 +1838,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
} }
if (load_code != FW_MSG_CODE_DRV_LOAD_COMMON_CHIP && if (load_code != FW_MSG_CODE_DRV_LOAD_COMMON_CHIP &&
load_code != FW_MSG_CODE_DRV_LOAD_COMMON) { load_code != FW_MSG_CODE_DRV_LOAD_COMMON) {
/* build FW version dword */
u32 my_fw = (BCM_5710_FW_MAJOR_VERSION) +
(BCM_5710_FW_MINOR_VERSION << 8) +
(BCM_5710_FW_REVISION_VERSION << 16) +
(BCM_5710_FW_ENGINEERING_VERSION << 24);
/* read loaded FW from chip */
u32 loaded_fw = REG_RD(bp, XSEM_REG_PRAM);
DP(BNX2X_MSG_SP, "loaded fw %x, my fw %x",
loaded_fw, my_fw);
/* abort nic load if version mismatch */ /* abort nic load if version mismatch */
if (my_fw != loaded_fw) { if (!bnx2x_test_firmware_version(bp, true)) {
BNX2X_ERR("bnx2x with FW %x already loaded, "
"which mismatches my %x FW. aborting",
loaded_fw, my_fw);
rc = -EBUSY; rc = -EBUSY;
LOAD_ERROR_EXIT(bp, load_error2); LOAD_ERROR_EXIT(bp, load_error2);
} }
......
...@@ -431,6 +431,9 @@ void bnx2x_panic_dump(struct bnx2x *bp); ...@@ -431,6 +431,9 @@ void bnx2x_panic_dump(struct bnx2x *bp);
void bnx2x_fw_dump_lvl(struct bnx2x *bp, const char *lvl); void bnx2x_fw_dump_lvl(struct bnx2x *bp, const char *lvl);
/* validate currect fw is loaded */
bool bnx2x_test_firmware_version(struct bnx2x *bp, bool is_err);
/* dev_close main block */ /* dev_close main block */
int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode); int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode);
......
...@@ -1251,6 +1251,9 @@ struct drv_func_mb { ...@@ -1251,6 +1251,9 @@ struct drv_func_mb {
#define DRV_MSG_CODE_LINK_STATUS_CHANGED 0x01000000 #define DRV_MSG_CODE_LINK_STATUS_CHANGED 0x01000000
#define DRV_MSG_CODE_INITIATE_FLR 0x02000000
#define REQ_BC_VER_4_INITIATE_FLR 0x00070213
#define BIOS_MSG_CODE_LIC_CHALLENGE 0xff010000 #define BIOS_MSG_CODE_LIC_CHALLENGE 0xff010000
#define BIOS_MSG_CODE_LIC_RESPONSE 0xff020000 #define BIOS_MSG_CODE_LIC_RESPONSE 0xff020000
#define BIOS_MSG_CODE_VIRT_MAC_PRIM 0xff030000 #define BIOS_MSG_CODE_VIRT_MAC_PRIM 0xff030000
......
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#define ETH_MAX_PACKET_SIZE 1500 #define ETH_MAX_PACKET_SIZE 1500
#define ETH_MAX_JUMBO_PACKET_SIZE 9600 #define ETH_MAX_JUMBO_PACKET_SIZE 9600
#define MDIO_ACCESS_TIMEOUT 1000 #define MDIO_ACCESS_TIMEOUT 1000
#define BMAC_CONTROL_RX_ENABLE 2
#define WC_LANE_MAX 4 #define WC_LANE_MAX 4
#define I2C_SWITCH_WIDTH 2 #define I2C_SWITCH_WIDTH 2
#define I2C_BSC0 0 #define I2C_BSC0 0
......
...@@ -89,6 +89,8 @@ ...@@ -89,6 +89,8 @@
#define PFC_BRB_FULL_LB_XON_THRESHOLD 250 #define PFC_BRB_FULL_LB_XON_THRESHOLD 250
#define MAXVAL(a, b) (((a) > (b)) ? (a) : (b)) #define MAXVAL(a, b) (((a) > (b)) ? (a) : (b))
#define BMAC_CONTROL_RX_ENABLE 2
/***********************************************************/ /***********************************************************/
/* Structs */ /* Structs */
/***********************************************************/ /***********************************************************/
......
...@@ -987,6 +987,7 @@ ...@@ -987,6 +987,7 @@
* clear; 1 = set. Data valid only in addresses 0-4. all the rest are zero. */ * clear; 1 = set. Data valid only in addresses 0-4. all the rest are zero. */
#define IGU_REG_WRITE_DONE_PENDING 0x130480 #define IGU_REG_WRITE_DONE_PENDING 0x130480
#define MCP_A_REG_MCPR_SCRATCH 0x3a0000 #define MCP_A_REG_MCPR_SCRATCH 0x3a0000
#define MCP_REG_MCPR_ACCESS_LOCK 0x8009c
#define MCP_REG_MCPR_CPU_PROGRAM_COUNTER 0x8501c #define MCP_REG_MCPR_CPU_PROGRAM_COUNTER 0x8501c
#define MCP_REG_MCPR_GP_INPUTS 0x800c0 #define MCP_REG_MCPR_GP_INPUTS 0x800c0
#define MCP_REG_MCPR_GP_OENABLE 0x800c8 #define MCP_REG_MCPR_GP_OENABLE 0x800c8
...@@ -1686,6 +1687,7 @@ ...@@ -1686,6 +1687,7 @@
[10] rst_dbg; [11] rst_misc_core; [12] rst_dbue (UART); [13] [10] rst_dbg; [11] rst_misc_core; [12] rst_dbue (UART); [13]
Pci_resetmdio_n; [14] rst_emac0_hard_core; [15] rst_emac1_hard_core; 16] Pci_resetmdio_n; [14] rst_emac0_hard_core; [15] rst_emac1_hard_core; 16]
rst_pxp_rq_rd_wr; 31:17] reserved */ rst_pxp_rq_rd_wr; 31:17] reserved */
#define MISC_REG_RESET_REG_1 0xa580
#define MISC_REG_RESET_REG_2 0xa590 #define MISC_REG_RESET_REG_2 0xa590
/* [RW 20] 20 bit GRC address where the scratch-pad of the MCP that is /* [RW 20] 20 bit GRC address where the scratch-pad of the MCP that is
shared with the driver resides */ shared with the driver resides */
...@@ -5606,6 +5608,7 @@ ...@@ -5606,6 +5608,7 @@
/* [RC 32] Parity register #0 read clear */ /* [RC 32] Parity register #0 read clear */
#define XSEM_REG_XSEM_PRTY_STS_CLR_0 0x280128 #define XSEM_REG_XSEM_PRTY_STS_CLR_0 0x280128
#define XSEM_REG_XSEM_PRTY_STS_CLR_1 0x280138 #define XSEM_REG_XSEM_PRTY_STS_CLR_1 0x280138
#define MCPR_ACCESS_LOCK_LOCK (1L<<31)
#define MCPR_NVM_ACCESS_ENABLE_EN (1L<<0) #define MCPR_NVM_ACCESS_ENABLE_EN (1L<<0)
#define MCPR_NVM_ACCESS_ENABLE_WR_EN (1L<<1) #define MCPR_NVM_ACCESS_ENABLE_WR_EN (1L<<1)
#define MCPR_NVM_ADDR_NVM_ADDR_VALUE (0xffffffL<<0) #define MCPR_NVM_ADDR_NVM_ADDR_VALUE (0xffffffL<<0)
...@@ -5732,6 +5735,7 @@ ...@@ -5732,6 +5735,7 @@
#define MISC_REGISTERS_GPIO_PORT_SHIFT 4 #define MISC_REGISTERS_GPIO_PORT_SHIFT 4
#define MISC_REGISTERS_GPIO_SET_POS 8 #define MISC_REGISTERS_GPIO_SET_POS 8
#define MISC_REGISTERS_RESET_REG_1_CLEAR 0x588 #define MISC_REGISTERS_RESET_REG_1_CLEAR 0x588
#define MISC_REGISTERS_RESET_REG_1_RST_BRB1 (0x1<<0)
#define MISC_REGISTERS_RESET_REG_1_RST_DORQ (0x1<<19) #define MISC_REGISTERS_RESET_REG_1_RST_DORQ (0x1<<19)
#define MISC_REGISTERS_RESET_REG_1_RST_HC (0x1<<29) #define MISC_REGISTERS_RESET_REG_1_RST_HC (0x1<<29)
#define MISC_REGISTERS_RESET_REG_1_RST_NIG (0x1<<7) #define MISC_REGISTERS_RESET_REG_1_RST_NIG (0x1<<7)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment