diff options
author | Yuval Mintz <Yuval.Mintz@qlogic.com> | 2014-06-12 07:55:31 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-06-12 10:28:18 -0700 |
commit | b17b0ca1642c23f0cd4e4cf52cdb9970798f3501 (patch) | |
tree | cff93c1ec6ddec06a3c1139a74ea75a031aa0001 /drivers | |
parent | a2755be5b5340eeb0f00a318d23a302fe95c45ba (diff) |
bnx2x: Check for UNDI in uncommon branch
If L2FW utilized by the UNDI driver has the same version number as that
of the regular FW, a driver loading after UNDI and receiving an uncommon
answer from management will mistakenly assume the loaded FW matches its
own requirement and try to exist the flow via FLR.
Signed-off-by: Yuval Mintz <yuval.mintz@qlogic.com>
Signed-off-by: Ariel Elior <ariel.elior@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index cf14218697e..c5061353a47 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -10053,6 +10053,24 @@ static void bnx2x_prev_unload_close_mac(struct bnx2x *bp, #define BCM_5710_UNDI_FW_MF_VERS (0x05) #define BNX2X_PREV_UNDI_MF_PORT(p) (BAR_TSTRORM_INTMEM + 0x150c + ((p) << 4)) #define BNX2X_PREV_UNDI_MF_FUNC(f) (BAR_TSTRORM_INTMEM + 0x184c + ((f) << 4)) + +static bool bnx2x_prev_is_after_undi(struct bnx2x *bp) +{ + /* UNDI marks its presence in DORQ - + * it initializes CID offset for normal bell to 0x7 + */ + if (!(REG_RD(bp, MISC_REG_RESET_REG_1) & + MISC_REGISTERS_RESET_REG_1_RST_DORQ)) + return false; + + if (REG_RD(bp, DORQ_REG_NORM_CID_OFST) == 0x7) { + BNX2X_DEV_INFO("UNDI previously loaded\n"); + return true; + } + + return false; +} + static bool bnx2x_prev_unload_undi_fw_supports_mf(struct bnx2x *bp) { u8 major, minor, version; @@ -10302,6 +10320,10 @@ static int bnx2x_prev_unload_uncommon(struct bnx2x *bp) BNX2X_DEV_INFO("Path is unmarked\n"); + /* Cannot proceed with FLR if UNDI is loaded, since FW does not match */ + if (bnx2x_prev_is_after_undi(bp)) + goto out; + /* If function has FLR capabilities, and existing FW version matches * the one required, then FLR will be sufficient to clean any residue * left by previous driver @@ -10322,6 +10344,7 @@ static int bnx2x_prev_unload_uncommon(struct bnx2x *bp) BNX2X_DEV_INFO("Could not FLR\n"); +out: /* Close the MCP request, return failure*/ rc = bnx2x_prev_mcp_done(bp); if (!rc) @@ -10360,19 +10383,13 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp) /* close LLH filters towards the BRB */ bnx2x_set_rx_filter(&bp->link_params, 0); - /* Check if the UNDI driver was previously loaded - * UNDI driver initializes CID offset for normal bell to 0x7 - */ - if (reset_reg & MISC_REGISTERS_RESET_REG_1_RST_DORQ) { - tmp_reg = REG_RD(bp, DORQ_REG_NORM_CID_OFST); - if (tmp_reg == 0x7) { - BNX2X_DEV_INFO("UNDI previously loaded\n"); - prev_undi = true; - /* clear the UNDI indication */ - REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0); - /* clear possible idle check errors */ - REG_RD(bp, NIG_REG_NIG_INT_STS_CLR_0); - } + /* Check if the UNDI driver was previously loaded */ + if (bnx2x_prev_is_after_undi(bp)) { + prev_undi = true; + /* clear the UNDI indication */ + REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0); + /* clear possible idle check errors */ + REG_RD(bp, NIG_REG_NIG_INT_STS_CLR_0); } if (!CHIP_IS_E1x(bp)) /* block FW from writing to host */ |