Commit 424e7834 authored by Manish Chopra's avatar Manish Chopra Committed by Jakub Kicinski

bnx2x: fix built-in kernel driver load failure

Commit b7a49f73 ("bnx2x: Utilize firmware 7.13.21.0")
added request_firmware() logic in probe() which caused
load failure when firmware file is not present in initrd (below),
as access to firmware file is not feasible during probe.

  Direct firmware load for bnx2x/bnx2x-e2-7.13.15.0.fw failed with error -2
  Direct firmware load for bnx2x/bnx2x-e2-7.13.21.0.fw failed with error -2

This patch fixes this issue by -

1. Removing request_firmware() logic from the probe()
   such that .ndo_open() handle it as it used to handle
   it earlier

2. Given request_firmware() is removed from probe(), so
   driver has to relax FW version comparisons a bit against
   the already loaded FW version (by some other PFs of same
   adapter) to allow different compatible/close enough FWs with which
   multiple PFs may run with (in different environments), as the
   given PF who is in probe flow has no idea now with which firmware
   file version it is going to initialize the device in ndo_open()

Link: https://lore.kernel.org/all/46f2d9d9-ae7f-b332-ddeb-b59802be2bab@molgen.mpg.de/Reported-by: default avatarPaul Menzel <pmenzel@molgen.mpg.de>
Tested-by: default avatarPaul Menzel <pmenzel@molgen.mpg.de>
Fixes: b7a49f73 ("bnx2x: Utilize firmware 7.13.21.0")
Signed-off-by: default avatarManish Chopra <manishc@marvell.com>
Signed-off-by: default avatarAriel Elior <aelior@marvell.com>
Link: https://lore.kernel.org/r/20220316214613.6884-1-manishc@marvell.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent f1858c27
...@@ -2533,6 +2533,4 @@ void bnx2x_register_phc(struct bnx2x *bp); ...@@ -2533,6 +2533,4 @@ void bnx2x_register_phc(struct bnx2x *bp);
* Meant for implicit re-load flows. * Meant for implicit re-load flows.
*/ */
int bnx2x_vlan_reconfigure_vid(struct bnx2x *bp); int bnx2x_vlan_reconfigure_vid(struct bnx2x *bp);
int bnx2x_init_firmware(struct bnx2x *bp);
void bnx2x_release_firmware(struct bnx2x *bp);
#endif /* bnx2x.h */ #endif /* bnx2x.h */
...@@ -2364,24 +2364,30 @@ int bnx2x_compare_fw_ver(struct bnx2x *bp, u32 load_code, bool print_err) ...@@ -2364,24 +2364,30 @@ int bnx2x_compare_fw_ver(struct bnx2x *bp, u32 load_code, bool print_err)
/* is another pf loaded on this engine? */ /* is another pf loaded on this engine? */
if (load_code != FW_MSG_CODE_DRV_LOAD_COMMON_CHIP && if (load_code != FW_MSG_CODE_DRV_LOAD_COMMON_CHIP &&
load_code != FW_MSG_CODE_DRV_LOAD_COMMON) { load_code != FW_MSG_CODE_DRV_LOAD_COMMON) {
/* build my FW version dword */ u8 loaded_fw_major, loaded_fw_minor, loaded_fw_rev, loaded_fw_eng;
u32 my_fw = (bp->fw_major) + (bp->fw_minor << 8) + u32 loaded_fw;
(bp->fw_rev << 16) + (bp->fw_eng << 24);
/* read loaded FW from chip */ /* read loaded FW from chip */
u32 loaded_fw = REG_RD(bp, XSEM_REG_PRAM); loaded_fw = REG_RD(bp, XSEM_REG_PRAM);
DP(BNX2X_MSG_SP, "loaded fw %x, my fw %x\n", loaded_fw_major = loaded_fw & 0xff;
loaded_fw, my_fw); loaded_fw_minor = (loaded_fw >> 8) & 0xff;
loaded_fw_rev = (loaded_fw >> 16) & 0xff;
loaded_fw_eng = (loaded_fw >> 24) & 0xff;
DP(BNX2X_MSG_SP, "loaded fw 0x%x major 0x%x minor 0x%x rev 0x%x eng 0x%x\n",
loaded_fw, loaded_fw_major, loaded_fw_minor, loaded_fw_rev, loaded_fw_eng);
/* abort nic load if version mismatch */ /* abort nic load if version mismatch */
if (my_fw != loaded_fw) { if (loaded_fw_major != BCM_5710_FW_MAJOR_VERSION ||
loaded_fw_minor != BCM_5710_FW_MINOR_VERSION ||
loaded_fw_eng != BCM_5710_FW_ENGINEERING_VERSION ||
loaded_fw_rev < BCM_5710_FW_REVISION_VERSION_V15) {
if (print_err) if (print_err)
BNX2X_ERR("bnx2x with FW %x was already loaded which mismatches my %x FW. Aborting\n", BNX2X_ERR("loaded FW incompatible. Aborting\n");
loaded_fw, my_fw);
else else
BNX2X_DEV_INFO("bnx2x with FW %x was already loaded which mismatches my %x FW, possibly due to MF UNDI\n", BNX2X_DEV_INFO("loaded FW incompatible, possibly due to MF UNDI\n");
loaded_fw, my_fw);
return -EBUSY; return -EBUSY;
} }
} }
......
...@@ -12319,15 +12319,6 @@ static int bnx2x_init_bp(struct bnx2x *bp) ...@@ -12319,15 +12319,6 @@ static int bnx2x_init_bp(struct bnx2x *bp)
bnx2x_read_fwinfo(bp); bnx2x_read_fwinfo(bp);
if (IS_PF(bp)) {
rc = bnx2x_init_firmware(bp);
if (rc) {
bnx2x_free_mem_bp(bp);
return rc;
}
}
func = BP_FUNC(bp); func = BP_FUNC(bp);
/* need to reset chip if undi was active */ /* need to reset chip if undi was active */
...@@ -12340,7 +12331,6 @@ static int bnx2x_init_bp(struct bnx2x *bp) ...@@ -12340,7 +12331,6 @@ static int bnx2x_init_bp(struct bnx2x *bp)
rc = bnx2x_prev_unload(bp); rc = bnx2x_prev_unload(bp);
if (rc) { if (rc) {
bnx2x_release_firmware(bp);
bnx2x_free_mem_bp(bp); bnx2x_free_mem_bp(bp);
return rc; return rc;
} }
...@@ -13409,7 +13399,7 @@ do { \ ...@@ -13409,7 +13399,7 @@ do { \
(u8 *)bp->arr, len); \ (u8 *)bp->arr, len); \
} while (0) } while (0)
int bnx2x_init_firmware(struct bnx2x *bp) static int bnx2x_init_firmware(struct bnx2x *bp)
{ {
const char *fw_file_name, *fw_file_name_v15; const char *fw_file_name, *fw_file_name_v15;
struct bnx2x_fw_file_hdr *fw_hdr; struct bnx2x_fw_file_hdr *fw_hdr;
...@@ -13509,7 +13499,7 @@ int bnx2x_init_firmware(struct bnx2x *bp) ...@@ -13509,7 +13499,7 @@ int bnx2x_init_firmware(struct bnx2x *bp)
return rc; return rc;
} }
void bnx2x_release_firmware(struct bnx2x *bp) static void bnx2x_release_firmware(struct bnx2x *bp)
{ {
kfree(bp->init_ops_offsets); kfree(bp->init_ops_offsets);
kfree(bp->init_ops); kfree(bp->init_ops);
...@@ -14026,7 +14016,6 @@ static int bnx2x_init_one(struct pci_dev *pdev, ...@@ -14026,7 +14016,6 @@ static int bnx2x_init_one(struct pci_dev *pdev,
return 0; return 0;
init_one_freemem: init_one_freemem:
bnx2x_release_firmware(bp);
bnx2x_free_mem_bp(bp); bnx2x_free_mem_bp(bp);
init_one_exit: init_one_exit:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment