@@ -9854,6 +9854,64 @@ static void bnx2x_prev_unload_close_mac(struct bnx2x *bp,
9854
9854
#define BNX2X_PREV_UNDI_BD (val ) ((val) >> 16 & 0xffff)
9855
9855
#define BNX2X_PREV_UNDI_PROD (rcq , bd ) ((bd) << 16 | (rcq))
9856
9856
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
+
9857
9915
static void bnx2x_prev_unload_undi_inc (struct bnx2x * bp , u8 port , u8 inc )
9858
9916
{
9859
9917
u16 rcq , bd ;
@@ -10054,7 +10112,7 @@ static int bnx2x_prev_unload_uncommon(struct bnx2x *bp)
10054
10112
* the one required, then FLR will be sufficient to clean any residue
10055
10113
* left by previous driver
10056
10114
*/
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 );
10058
10116
10059
10117
if (!rc ) {
10060
10118
/* fw version is good */
@@ -10142,10 +10200,17 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp)
10142
10200
else
10143
10201
timer_count -- ;
10144
10202
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
+ */
10147
10212
bnx2x_prev_unload_undi_inc (bp , BP_PORT (bp ), 1 );
10148
-
10213
+ }
10149
10214
udelay (10 );
10150
10215
}
10151
10216
@@ -10265,8 +10330,8 @@ static int bnx2x_prev_unload(struct bnx2x *bp)
10265
10330
} while (-- time_counter );
10266
10331
10267
10332
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 ;
10270
10335
}
10271
10336
10272
10337
/* Mark function if its port was used to boot from SAN */
@@ -11636,7 +11701,11 @@ static int bnx2x_init_bp(struct bnx2x *bp)
11636
11701
DRV_MSG_SEQ_NUMBER_MASK ;
11637
11702
BNX2X_DEV_INFO ("fw_seq 0x%08x\n" , bp -> fw_seq );
11638
11703
11639
- bnx2x_prev_unload (bp );
11704
+ rc = bnx2x_prev_unload (bp );
11705
+ if (rc ) {
11706
+ bnx2x_free_mem_bp (bp );
11707
+ return rc ;
11708
+ }
11640
11709
}
11641
11710
11642
11711
if (CHIP_REV_IS_FPGA (bp ))
0 commit comments