Skip to content

Commit 7c3afd8

Browse files
Yuval Mintzdavem330
authored andcommitted
bnx2x: Revert UNDI flushing mechanism
Commit 91ebb92 ("bnx2x: Add support for Multi-Function UNDI") [which was later supposedly fixed by de68294 ("bnx2x: Fix UNDI driver unload")] introduced a bug in which in some [yet-to-be-determined] scenarios the alternative flushing mechanism which was to guarantee the Rx buffers are empty before resetting them during device probe will fail. If this happens, when device will be loaded once more a fatal attention will occur; Since this most likely happens in boot from SAN scenarios, the machine will fail to load. Notice this may occur not only in the 'Multi-Function' scenario but in the regular scenario as well, i.e., this introduced a regression in the driver's ability to perform boot from SAN. The patch reverts the mechanism and applies the old scheme to multi-function devices as well as to single-function devices. Signed-off-by: Yuval Mintz <[email protected]> Signed-off-by: Ariel Elior <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9a6d33c commit 7c3afd8

File tree

1 file changed

+17
-75
lines changed

1 file changed

+17
-75
lines changed

drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c

Lines changed: 17 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -10052,15 +10052,15 @@ static void bnx2x_prev_unload_close_mac(struct bnx2x *bp,
1005210052
}
1005310053

1005410054
#define BNX2X_PREV_UNDI_PROD_ADDR(p) (BAR_TSTRORM_INTMEM + 0x1508 + ((p) << 4))
10055+
#define BNX2X_PREV_UNDI_PROD_ADDR_H(f) (BAR_TSTRORM_INTMEM + \
10056+
0x1848 + ((f) << 4))
1005510057
#define BNX2X_PREV_UNDI_RCQ(val) ((val) & 0xffff)
1005610058
#define BNX2X_PREV_UNDI_BD(val) ((val) >> 16 & 0xffff)
1005710059
#define BNX2X_PREV_UNDI_PROD(rcq, bd) ((bd) << 16 | (rcq))
1005810060

1005910061
#define BCM_5710_UNDI_FW_MF_MAJOR (0x07)
1006010062
#define BCM_5710_UNDI_FW_MF_MINOR (0x08)
1006110063
#define BCM_5710_UNDI_FW_MF_VERS (0x05)
10062-
#define BNX2X_PREV_UNDI_MF_PORT(p) (BAR_TSTRORM_INTMEM + 0x150c + ((p) << 4))
10063-
#define BNX2X_PREV_UNDI_MF_FUNC(f) (BAR_TSTRORM_INTMEM + 0x184c + ((f) << 4))
1006410064

1006510065
static bool bnx2x_prev_is_after_undi(struct bnx2x *bp)
1006610066
{
@@ -10079,72 +10079,25 @@ static bool bnx2x_prev_is_after_undi(struct bnx2x *bp)
1007910079
return false;
1008010080
}
1008110081

10082-
static bool bnx2x_prev_unload_undi_fw_supports_mf(struct bnx2x *bp)
10083-
{
10084-
u8 major, minor, version;
10085-
u32 fw;
10086-
10087-
/* Must check that FW is loaded */
10088-
if (!(REG_RD(bp, MISC_REG_RESET_REG_1) &
10089-
MISC_REGISTERS_RESET_REG_1_RST_XSEM)) {
10090-
BNX2X_DEV_INFO("XSEM is reset - UNDI MF FW is not loaded\n");
10091-
return false;
10092-
}
10093-
10094-
/* Read Currently loaded FW version */
10095-
fw = REG_RD(bp, XSEM_REG_PRAM);
10096-
major = fw & 0xff;
10097-
minor = (fw >> 0x8) & 0xff;
10098-
version = (fw >> 0x10) & 0xff;
10099-
BNX2X_DEV_INFO("Loaded FW: 0x%08x: Major 0x%02x Minor 0x%02x Version 0x%02x\n",
10100-
fw, major, minor, version);
10101-
10102-
if (major > BCM_5710_UNDI_FW_MF_MAJOR)
10103-
return true;
10104-
10105-
if ((major == BCM_5710_UNDI_FW_MF_MAJOR) &&
10106-
(minor > BCM_5710_UNDI_FW_MF_MINOR))
10107-
return true;
10108-
10109-
if ((major == BCM_5710_UNDI_FW_MF_MAJOR) &&
10110-
(minor == BCM_5710_UNDI_FW_MF_MINOR) &&
10111-
(version >= BCM_5710_UNDI_FW_MF_VERS))
10112-
return true;
10113-
10114-
return false;
10115-
}
10116-
10117-
static void bnx2x_prev_unload_undi_mf(struct bnx2x *bp)
10118-
{
10119-
int i;
10120-
10121-
/* Due to legacy (FW) code, the first function on each engine has a
10122-
* different offset macro from the rest of the functions.
10123-
* Setting this for all 8 functions is harmless regardless of whether
10124-
* this is actually a multi-function device.
10125-
*/
10126-
for (i = 0; i < 2; i++)
10127-
REG_WR(bp, BNX2X_PREV_UNDI_MF_PORT(i), 1);
10128-
10129-
for (i = 2; i < 8; i++)
10130-
REG_WR(bp, BNX2X_PREV_UNDI_MF_FUNC(i - 2), 1);
10131-
10132-
BNX2X_DEV_INFO("UNDI FW (MF) set to discard\n");
10133-
}
10134-
10135-
static void bnx2x_prev_unload_undi_inc(struct bnx2x *bp, u8 port, u8 inc)
10082+
static void bnx2x_prev_unload_undi_inc(struct bnx2x *bp, u8 inc)
1013610083
{
1013710084
u16 rcq, bd;
10138-
u32 tmp_reg = REG_RD(bp, BNX2X_PREV_UNDI_PROD_ADDR(port));
10085+
u32 addr, tmp_reg;
1013910086

10087+
if (BP_FUNC(bp) < 2)
10088+
addr = BNX2X_PREV_UNDI_PROD_ADDR(BP_PORT(bp));
10089+
else
10090+
addr = BNX2X_PREV_UNDI_PROD_ADDR_H(BP_FUNC(bp) - 2);
10091+
10092+
tmp_reg = REG_RD(bp, addr);
1014010093
rcq = BNX2X_PREV_UNDI_RCQ(tmp_reg) + inc;
1014110094
bd = BNX2X_PREV_UNDI_BD(tmp_reg) + inc;
1014210095

1014310096
tmp_reg = BNX2X_PREV_UNDI_PROD(rcq, bd);
10144-
REG_WR(bp, BNX2X_PREV_UNDI_PROD_ADDR(port), tmp_reg);
10097+
REG_WR(bp, addr, tmp_reg);
1014510098

10146-
BNX2X_DEV_INFO("UNDI producer [%d] rings bd -> 0x%04x, rcq -> 0x%04x\n",
10147-
port, bd, rcq);
10099+
BNX2X_DEV_INFO("UNDI producer [%d/%d][%08x] rings bd -> 0x%04x, rcq -> 0x%04x\n",
10100+
BP_PORT(bp), BP_FUNC(bp), addr, bd, rcq);
1014810101
}
1014910102

1015010103
static int bnx2x_prev_mcp_done(struct bnx2x *bp)
@@ -10383,7 +10336,6 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp)
1038310336
/* Reset should be performed after BRB is emptied */
1038410337
if (reset_reg & MISC_REGISTERS_RESET_REG_1_RST_BRB1) {
1038510338
u32 timer_count = 1000;
10386-
bool need_write = true;
1038710339

1038810340
/* Close the MAC Rx to prevent BRB from filling up */
1038910341
bnx2x_prev_unload_close_mac(bp, &mac_vals);
@@ -10420,20 +10372,10 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp)
1042010372
else
1042110373
timer_count--;
1042210374

10423-
/* New UNDI FW supports MF and contains better
10424-
* cleaning methods - might be redundant but harmless.
10425-
*/
10426-
if (bnx2x_prev_unload_undi_fw_supports_mf(bp)) {
10427-
if (need_write) {
10428-
bnx2x_prev_unload_undi_mf(bp);
10429-
need_write = false;
10430-
}
10431-
} else if (prev_undi) {
10432-
/* If UNDI resides in memory,
10433-
* manually increment it
10434-
*/
10435-
bnx2x_prev_unload_undi_inc(bp, BP_PORT(bp), 1);
10436-
}
10375+
/* If UNDI resides in memory, manually increment it */
10376+
if (prev_undi)
10377+
bnx2x_prev_unload_undi_inc(bp, 1);
10378+
1043710379
udelay(10);
1043810380
}
1043910381

0 commit comments

Comments
 (0)