Skip to content

Commit 91ebb92

Browse files
Yuval Mintzdavem330
authored andcommitted
bnx2x: Add support for Multi-Function UNDI
This adds the ability for bnx2x to load after UNDI is used in the preboot environment on a multi-function interface which is not the first interface of a given device. Notice a side-effect is that the order by which the functions are probed and thus interfaces appear might change, as this patch utilizes the EPROBE_DEFER return value (and mechanism). Signed-off-by: Yuval Mintz <[email protected]> Signed-off-by: Ariel Elior <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 539c89c commit 91ebb92

File tree

4 files changed

+87
-12
lines changed

4 files changed

+87
-12
lines changed

drivers/net/ethernet/broadcom/bnx2x/bnx2x.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2436,7 +2436,8 @@ void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func, u8 idu_sb_id,
24362436

24372437
#define GOOD_ME_REG(me_reg) (((me_reg) & ME_REG_VF_VALID) && \
24382438
(!((me_reg) & ME_REG_VF_ERR)))
2439-
int bnx2x_nic_load_analyze_req(struct bnx2x *bp, u32 load_code);
2439+
int bnx2x_compare_fw_ver(struct bnx2x *bp, u32 load_code, bool print_err);
2440+
24402441
/* Congestion management fairness mode */
24412442
#define CMNG_FNS_NONE 0
24422443
#define CMNG_FNS_MINMAX 1

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2265,7 +2265,7 @@ static int bnx2x_nic_load_request(struct bnx2x *bp, u32 *load_code)
22652265
* virtualized environments a pf from another VM may have already
22662266
* initialized the device including loading FW
22672267
*/
2268-
int bnx2x_nic_load_analyze_req(struct bnx2x *bp, u32 load_code)
2268+
int bnx2x_compare_fw_ver(struct bnx2x *bp, u32 load_code, bool print_err)
22692269
{
22702270
/* is another pf loaded on this engine? */
22712271
if (load_code != FW_MSG_CODE_DRV_LOAD_COMMON_CHIP &&
@@ -2284,8 +2284,12 @@ int bnx2x_nic_load_analyze_req(struct bnx2x *bp, u32 load_code)
22842284

22852285
/* abort nic load if version mismatch */
22862286
if (my_fw != loaded_fw) {
2287-
BNX2X_ERR("bnx2x with FW %x was already loaded which mismatches my %x FW. Aborting\n",
2288-
loaded_fw, my_fw);
2287+
if (print_err)
2288+
BNX2X_ERR("bnx2x with FW %x was already loaded which mismatches my %x FW. Aborting\n",
2289+
loaded_fw, my_fw);
2290+
else
2291+
BNX2X_DEV_INFO("bnx2x with FW %x was already loaded which mismatches my %x FW, possibly due to MF UNDI\n",
2292+
loaded_fw, my_fw);
22892293
return -EBUSY;
22902294
}
22912295
}
@@ -2600,7 +2604,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
26002604
LOAD_ERROR_EXIT(bp, load_error1);
26012605

26022606
/* what did mcp say? */
2603-
rc = bnx2x_nic_load_analyze_req(bp, load_code);
2607+
rc = bnx2x_compare_fw_ver(bp, load_code, true);
26042608
if (rc) {
26052609
bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0);
26062610
LOAD_ERROR_EXIT(bp, load_error2);

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

Lines changed: 76 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9854,6 +9854,64 @@ static void bnx2x_prev_unload_close_mac(struct bnx2x *bp,
98549854
#define BNX2X_PREV_UNDI_BD(val) ((val) >> 16 & 0xffff)
98559855
#define BNX2X_PREV_UNDI_PROD(rcq, bd) ((bd) << 16 | (rcq))
98569856

9857+
#define BCM_5710_UNDI_FW_MF_MAJOR (0x07)
9858+
#define BCM_5710_UNDI_FW_MF_MINOR (0x08)
9859+
#define BCM_5710_UNDI_FW_MF_VERS (0x05)
9860+
#define BNX2X_PREV_UNDI_MF_PORT(p) (0x1a150c + ((p) << 4))
9861+
#define BNX2X_PREV_UNDI_MF_FUNC(f) (0x1a184c + ((f) << 4))
9862+
static bool bnx2x_prev_unload_undi_fw_supports_mf(struct bnx2x *bp)
9863+
{
9864+
u8 major, minor, version;
9865+
u32 fw;
9866+
9867+
/* Must check that FW is loaded */
9868+
if (!(REG_RD(bp, MISC_REG_RESET_REG_1) &
9869+
MISC_REGISTERS_RESET_REG_1_RST_XSEM)) {
9870+
BNX2X_DEV_INFO("XSEM is reset - UNDI MF FW is not loaded\n");
9871+
return false;
9872+
}
9873+
9874+
/* Read Currently loaded FW version */
9875+
fw = REG_RD(bp, XSEM_REG_PRAM);
9876+
major = fw & 0xff;
9877+
minor = (fw >> 0x8) & 0xff;
9878+
version = (fw >> 0x10) & 0xff;
9879+
BNX2X_DEV_INFO("Loaded FW: 0x%08x: Major 0x%02x Minor 0x%02x Version 0x%02x\n",
9880+
fw, major, minor, version);
9881+
9882+
if (major > BCM_5710_UNDI_FW_MF_MAJOR)
9883+
return true;
9884+
9885+
if ((major == BCM_5710_UNDI_FW_MF_MAJOR) &&
9886+
(minor > BCM_5710_UNDI_FW_MF_MINOR))
9887+
return true;
9888+
9889+
if ((major == BCM_5710_UNDI_FW_MF_MAJOR) &&
9890+
(minor == BCM_5710_UNDI_FW_MF_MINOR) &&
9891+
(version >= BCM_5710_UNDI_FW_MF_VERS))
9892+
return true;
9893+
9894+
return false;
9895+
}
9896+
9897+
static void bnx2x_prev_unload_undi_mf(struct bnx2x *bp)
9898+
{
9899+
int i;
9900+
9901+
/* Due to legacy (FW) code, the first function on each engine has a
9902+
* different offset macro from the rest of the functions.
9903+
* Setting this for all 8 functions is harmless regardless of whether
9904+
* this is actually a multi-function device.
9905+
*/
9906+
for (i = 0; i < 2; i++)
9907+
REG_WR(bp, BNX2X_PREV_UNDI_MF_PORT(i), 1);
9908+
9909+
for (i = 2; i < 8; i++)
9910+
REG_WR(bp, BNX2X_PREV_UNDI_MF_FUNC(i - 2), 1);
9911+
9912+
BNX2X_DEV_INFO("UNDI FW (MF) set to discard\n");
9913+
}
9914+
98579915
static void bnx2x_prev_unload_undi_inc(struct bnx2x *bp, u8 port, u8 inc)
98589916
{
98599917
u16 rcq, bd;
@@ -10054,7 +10112,7 @@ static int bnx2x_prev_unload_uncommon(struct bnx2x *bp)
1005410112
* the one required, then FLR will be sufficient to clean any residue
1005510113
* left by previous driver
1005610114
*/
10057-
rc = bnx2x_nic_load_analyze_req(bp, FW_MSG_CODE_DRV_LOAD_FUNCTION);
10115+
rc = bnx2x_compare_fw_ver(bp, FW_MSG_CODE_DRV_LOAD_FUNCTION, false);
1005810116

1005910117
if (!rc) {
1006010118
/* fw version is good */
@@ -10142,10 +10200,17 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp)
1014210200
else
1014310201
timer_count--;
1014410202

10145-
/* If UNDI resides in memory, manually increment it */
10146-
if (prev_undi)
10203+
/* New UNDI FW supports MF and contains better
10204+
* cleaning methods - might be redundant but harmless.
10205+
*/
10206+
if (bnx2x_prev_unload_undi_fw_supports_mf(bp)) {
10207+
bnx2x_prev_unload_undi_mf(bp);
10208+
} else if (prev_undi) {
10209+
/* If UNDI resides in memory,
10210+
* manually increment it
10211+
*/
1014710212
bnx2x_prev_unload_undi_inc(bp, BP_PORT(bp), 1);
10148-
10213+
}
1014910214
udelay(10);
1015010215
}
1015110216

@@ -10265,8 +10330,8 @@ static int bnx2x_prev_unload(struct bnx2x *bp)
1026510330
} while (--time_counter);
1026610331

1026710332
if (!time_counter || rc) {
10268-
BNX2X_ERR("Failed unloading previous driver, aborting\n");
10269-
rc = -EBUSY;
10333+
BNX2X_DEV_INFO("Unloading previous driver did not occur, Possibly due to MF UNDI\n");
10334+
rc = -EPROBE_DEFER;
1027010335
}
1027110336

1027210337
/* Mark function if its port was used to boot from SAN */
@@ -11636,7 +11701,11 @@ static int bnx2x_init_bp(struct bnx2x *bp)
1163611701
DRV_MSG_SEQ_NUMBER_MASK;
1163711702
BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq);
1163811703

11639-
bnx2x_prev_unload(bp);
11704+
rc = bnx2x_prev_unload(bp);
11705+
if (rc) {
11706+
bnx2x_free_mem_bp(bp);
11707+
return rc;
11708+
}
1164011709
}
1164111710

1164211711
if (CHIP_REV_IS_FPGA(bp))

drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5932,6 +5932,7 @@
59325932
#define MISC_REGISTERS_RESET_REG_1_RST_NIG (0x1<<7)
59335933
#define MISC_REGISTERS_RESET_REG_1_RST_PXP (0x1<<26)
59345934
#define MISC_REGISTERS_RESET_REG_1_RST_PXPV (0x1<<27)
5935+
#define MISC_REGISTERS_RESET_REG_1_RST_XSEM (0x1<<22)
59355936
#define MISC_REGISTERS_RESET_REG_1_SET 0x584
59365937
#define MISC_REGISTERS_RESET_REG_2_CLEAR 0x598
59375938
#define MISC_REGISTERS_RESET_REG_2_MSTAT0 (0x1<<24)

0 commit comments

Comments
 (0)