Skip to content

Commit

Permalink
bnx2x: fix unload previous driver flow when flr-capable
Browse files Browse the repository at this point in the history
The existing previous driver unload flow is flawed, causing the probe of
functions reaching the 'uncommon fork' in flr-capable devices to fail.

This patch resolves this, as well as fixing the flow for hypervisors which
disable flr capabilities from functions as they pass them as PDA to VMs,
as we cannot base the flow on the pci configuration space.

Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: Ariel Elior <ariele@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Yuval Mintz authored and David S. Miller committed Aug 9, 2012
1 parent 66d1b92 commit 8eee694
Showing 1 changed file with 28 additions and 27 deletions.
55 changes: 28 additions & 27 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -9384,32 +9384,24 @@ static int __devinit bnx2x_prev_mark_path(struct bnx2x *bp)
return rc;
}

static bool __devinit bnx2x_can_flr(struct bnx2x *bp)
{
int pos;
u32 cap;
struct pci_dev *dev = bp->pdev;

pos = pci_pcie_cap(dev);
if (!pos)
return false;

pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP, &cap);
if (!(cap & PCI_EXP_DEVCAP_FLR))
return false;

return true;
}

static int __devinit bnx2x_do_flr(struct bnx2x *bp)
{
int i, pos;
u16 status;
struct pci_dev *dev = bp->pdev;

/* probe the capability first */
if (bnx2x_can_flr(bp))
return -ENOTTY;

if (CHIP_IS_E1x(bp)) {
BNX2X_DEV_INFO("FLR not supported in E1/E1H\n");
return -EINVAL;
}

/* only bootcode REQ_BC_VER_4_INITIATE_FLR and onwards support flr */
if (bp->common.bc_ver < REQ_BC_VER_4_INITIATE_FLR) {
BNX2X_ERR("FLR not supported by BC_VER: 0x%x\n",
bp->common.bc_ver);
return -EINVAL;
}

pos = pci_pcie_cap(dev);
if (!pos)
Expand All @@ -9429,12 +9421,8 @@ static int __devinit bnx2x_do_flr(struct bnx2x *bp)
"transaction is not cleared; proceeding with reset anyway\n");

clear:
if (bp->common.bc_ver < REQ_BC_VER_4_INITIATE_FLR) {
BNX2X_ERR("FLR not supported by BC_VER: 0x%x\n",
bp->common.bc_ver);
return -EINVAL;
}

BNX2X_DEV_INFO("Initiating FLR\n");
bnx2x_fw_command(bp, DRV_MSG_CODE_INITIATE_FLR, 0);

return 0;
Expand All @@ -9454,8 +9442,21 @@ static int __devinit bnx2x_prev_unload_uncommon(struct bnx2x *bp)
* the one required, then FLR will be sufficient to clean any residue
* left by previous driver
*/
if (bnx2x_test_firmware_version(bp, false) && bnx2x_can_flr(bp))
return bnx2x_do_flr(bp);
rc = bnx2x_test_firmware_version(bp, false);

if (!rc) {
/* fw version is good */
BNX2X_DEV_INFO("FW version matches our own. Attempting FLR\n");
rc = bnx2x_do_flr(bp);
}

if (!rc) {
/* FLR was performed */
BNX2X_DEV_INFO("FLR successful\n");
return 0;
}

BNX2X_DEV_INFO("Could not FLR\n");

/* Close the MCP request, return failure*/
rc = bnx2x_prev_mcp_done(bp);
Expand Down

0 comments on commit 8eee694

Please sign in to comment.