提交 b17b0ca1 编写于 作者: Y Yuval Mintz 提交者: David S. Miller

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: NYuval Mintz <yuval.mintz@qlogic.com>
Signed-off-by: NAriel Elior <ariel.elior@qlogic.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 a2755be5
...@@ -10053,6 +10053,24 @@ static void bnx2x_prev_unload_close_mac(struct bnx2x *bp, ...@@ -10053,6 +10053,24 @@ static void bnx2x_prev_unload_close_mac(struct bnx2x *bp,
#define BCM_5710_UNDI_FW_MF_VERS (0x05) #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_PORT(p) (BAR_TSTRORM_INTMEM + 0x150c + ((p) << 4))
#define BNX2X_PREV_UNDI_MF_FUNC(f) (BAR_TSTRORM_INTMEM + 0x184c + ((f) << 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) static bool bnx2x_prev_unload_undi_fw_supports_mf(struct bnx2x *bp)
{ {
u8 major, minor, version; u8 major, minor, version;
...@@ -10302,6 +10320,10 @@ static int bnx2x_prev_unload_uncommon(struct bnx2x *bp) ...@@ -10302,6 +10320,10 @@ static int bnx2x_prev_unload_uncommon(struct bnx2x *bp)
BNX2X_DEV_INFO("Path is unmarked\n"); 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 /* If function has FLR capabilities, and existing FW version matches
* the one required, then FLR will be sufficient to clean any residue * the one required, then FLR will be sufficient to clean any residue
* left by previous driver * left by previous driver
...@@ -10322,6 +10344,7 @@ static int bnx2x_prev_unload_uncommon(struct bnx2x *bp) ...@@ -10322,6 +10344,7 @@ static int bnx2x_prev_unload_uncommon(struct bnx2x *bp)
BNX2X_DEV_INFO("Could not FLR\n"); BNX2X_DEV_INFO("Could not FLR\n");
out:
/* Close the MCP request, return failure*/ /* Close the MCP request, return failure*/
rc = bnx2x_prev_mcp_done(bp); rc = bnx2x_prev_mcp_done(bp);
if (!rc) if (!rc)
...@@ -10360,19 +10383,13 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp) ...@@ -10360,19 +10383,13 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp)
/* close LLH filters towards the BRB */ /* close LLH filters towards the BRB */
bnx2x_set_rx_filter(&bp->link_params, 0); bnx2x_set_rx_filter(&bp->link_params, 0);
/* Check if the UNDI driver was previously loaded /* Check if the UNDI driver was previously loaded */
* UNDI driver initializes CID offset for normal bell to 0x7 if (bnx2x_prev_is_after_undi(bp)) {
*/ prev_undi = true;
if (reset_reg & MISC_REGISTERS_RESET_REG_1_RST_DORQ) { /* clear the UNDI indication */
tmp_reg = REG_RD(bp, DORQ_REG_NORM_CID_OFST); REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0);
if (tmp_reg == 0x7) { /* clear possible idle check errors */
BNX2X_DEV_INFO("UNDI previously loaded\n"); REG_RD(bp, NIG_REG_NIG_INT_STS_CLR_0);
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)) if (!CHIP_IS_E1x(bp))
/* block FW from writing to host */ /* block FW from writing to host */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册