bnx2x: Handling load failures
Failures on load were not handled correctly - separate the flow to handle different failures Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
e94d8af3da
commit
2dfe0e1fec
|
@ -6328,7 +6328,7 @@ static void bnx2x_set_rx_mode(struct net_device *dev);
|
||||||
static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
|
static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
|
||||||
{
|
{
|
||||||
u32 load_code;
|
u32 load_code;
|
||||||
int i, rc;
|
int i, rc = 0;
|
||||||
#ifdef BNX2X_STOP_ON_ERROR
|
#ifdef BNX2X_STOP_ON_ERROR
|
||||||
if (unlikely(bp->panic))
|
if (unlikely(bp->panic))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
@ -6336,6 +6336,77 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
|
||||||
|
|
||||||
bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
|
bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
|
||||||
|
|
||||||
|
if (use_inta) {
|
||||||
|
bp->num_queues = 1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if ((use_multi > 1) && (use_multi <= BP_MAX_QUEUES(bp)))
|
||||||
|
/* user requested number */
|
||||||
|
bp->num_queues = use_multi;
|
||||||
|
|
||||||
|
else if (use_multi)
|
||||||
|
bp->num_queues = min_t(u32, num_online_cpus(),
|
||||||
|
BP_MAX_QUEUES(bp));
|
||||||
|
else
|
||||||
|
bp->num_queues = 1;
|
||||||
|
|
||||||
|
DP(NETIF_MSG_IFUP,
|
||||||
|
"set number of queues to %d\n", bp->num_queues);
|
||||||
|
|
||||||
|
/* if we can't use MSI-X we only need one fp,
|
||||||
|
* so try to enable MSI-X with the requested number of fp's
|
||||||
|
* and fallback to MSI or legacy INTx with one fp
|
||||||
|
*/
|
||||||
|
rc = bnx2x_enable_msix(bp);
|
||||||
|
if (rc) {
|
||||||
|
/* failed to enable MSI-X */
|
||||||
|
bp->num_queues = 1;
|
||||||
|
if (use_multi)
|
||||||
|
BNX2X_ERR("Multi requested but failed"
|
||||||
|
" to enable MSI-X\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bnx2x_alloc_mem(bp))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
for_each_queue(bp, i)
|
||||||
|
bnx2x_fp(bp, i, disable_tpa) =
|
||||||
|
((bp->flags & TPA_ENABLE_FLAG) == 0);
|
||||||
|
|
||||||
|
for_each_queue(bp, i)
|
||||||
|
netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
|
||||||
|
bnx2x_poll, 128);
|
||||||
|
|
||||||
|
#ifdef BNX2X_STOP_ON_ERROR
|
||||||
|
for_each_queue(bp, i) {
|
||||||
|
struct bnx2x_fastpath *fp = &bp->fp[i];
|
||||||
|
|
||||||
|
fp->poll_no_work = 0;
|
||||||
|
fp->poll_calls = 0;
|
||||||
|
fp->poll_max_calls = 0;
|
||||||
|
fp->poll_complete = 0;
|
||||||
|
fp->poll_exit = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
bnx2x_napi_enable(bp);
|
||||||
|
|
||||||
|
if (bp->flags & USING_MSIX_FLAG) {
|
||||||
|
rc = bnx2x_req_msix_irqs(bp);
|
||||||
|
if (rc) {
|
||||||
|
pci_disable_msix(bp->pdev);
|
||||||
|
goto load_error1;
|
||||||
|
}
|
||||||
|
printk(KERN_INFO PFX "%s: using MSI-X\n", bp->dev->name);
|
||||||
|
} else {
|
||||||
|
bnx2x_ack_int(bp);
|
||||||
|
rc = bnx2x_req_irq(bp);
|
||||||
|
if (rc) {
|
||||||
|
BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc);
|
||||||
|
goto load_error1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Send LOAD_REQUEST command to MCP
|
/* Send LOAD_REQUEST command to MCP
|
||||||
Returns the type of LOAD command:
|
Returns the type of LOAD command:
|
||||||
if it is the first port to be initialized
|
if it is the first port to be initialized
|
||||||
|
@ -6345,10 +6416,13 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
|
||||||
load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
|
load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
|
||||||
if (!load_code) {
|
if (!load_code) {
|
||||||
BNX2X_ERR("MCP response failure, aborting\n");
|
BNX2X_ERR("MCP response failure, aborting\n");
|
||||||
return -EBUSY;
|
rc = -EBUSY;
|
||||||
|
goto load_error2;
|
||||||
|
}
|
||||||
|
if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) {
|
||||||
|
rc = -EBUSY; /* other port in diagnostic mode */
|
||||||
|
goto load_error2;
|
||||||
}
|
}
|
||||||
if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED)
|
|
||||||
return -EBUSY; /* other port in diagnostic mode */
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
int port = BP_PORT(bp);
|
int port = BP_PORT(bp);
|
||||||
|
@ -6374,66 +6448,11 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
|
||||||
bp->port.pmf = 0;
|
bp->port.pmf = 0;
|
||||||
DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf);
|
DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf);
|
||||||
|
|
||||||
/* if we can't use MSI-X we only need one fp,
|
|
||||||
* so try to enable MSI-X with the requested number of fp's
|
|
||||||
* and fallback to inta with one fp
|
|
||||||
*/
|
|
||||||
if (use_inta) {
|
|
||||||
bp->num_queues = 1;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if ((use_multi > 1) && (use_multi <= BP_MAX_QUEUES(bp)))
|
|
||||||
/* user requested number */
|
|
||||||
bp->num_queues = use_multi;
|
|
||||||
|
|
||||||
else if (use_multi)
|
|
||||||
bp->num_queues = min_t(u32, num_online_cpus(),
|
|
||||||
BP_MAX_QUEUES(bp));
|
|
||||||
else
|
|
||||||
bp->num_queues = 1;
|
|
||||||
|
|
||||||
if (bnx2x_enable_msix(bp)) {
|
|
||||||
/* failed to enable MSI-X */
|
|
||||||
bp->num_queues = 1;
|
|
||||||
if (use_multi)
|
|
||||||
BNX2X_ERR("Multi requested but failed"
|
|
||||||
" to enable MSI-X\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DP(NETIF_MSG_IFUP,
|
|
||||||
"set number of queues to %d\n", bp->num_queues);
|
|
||||||
|
|
||||||
if (bnx2x_alloc_mem(bp))
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
for_each_queue(bp, i)
|
|
||||||
bnx2x_fp(bp, i, disable_tpa) =
|
|
||||||
((bp->flags & TPA_ENABLE_FLAG) == 0);
|
|
||||||
|
|
||||||
if (bp->flags & USING_MSIX_FLAG) {
|
|
||||||
rc = bnx2x_req_msix_irqs(bp);
|
|
||||||
if (rc) {
|
|
||||||
pci_disable_msix(bp->pdev);
|
|
||||||
goto load_error;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bnx2x_ack_int(bp);
|
|
||||||
rc = bnx2x_req_irq(bp);
|
|
||||||
if (rc) {
|
|
||||||
BNX2X_ERR("IRQ request failed, aborting\n");
|
|
||||||
goto load_error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for_each_queue(bp, i)
|
|
||||||
netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
|
|
||||||
bnx2x_poll, 128);
|
|
||||||
|
|
||||||
/* Initialize HW */
|
/* Initialize HW */
|
||||||
rc = bnx2x_init_hw(bp, load_code);
|
rc = bnx2x_init_hw(bp, load_code);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
BNX2X_ERR("HW init failed, aborting\n");
|
BNX2X_ERR("HW init failed, aborting\n");
|
||||||
goto load_int_disable;
|
goto load_error2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup NIC internals and enable interrupts */
|
/* Setup NIC internals and enable interrupts */
|
||||||
|
@ -6445,7 +6464,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
|
||||||
if (!load_code) {
|
if (!load_code) {
|
||||||
BNX2X_ERR("MCP response failure, aborting\n");
|
BNX2X_ERR("MCP response failure, aborting\n");
|
||||||
rc = -EBUSY;
|
rc = -EBUSY;
|
||||||
goto load_rings_free;
|
goto load_error3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6454,7 +6473,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
|
||||||
rc = bnx2x_setup_leading(bp);
|
rc = bnx2x_setup_leading(bp);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
BNX2X_ERR("Setup leading failed!\n");
|
BNX2X_ERR("Setup leading failed!\n");
|
||||||
goto load_netif_stop;
|
goto load_error3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CHIP_IS_E1H(bp))
|
if (CHIP_IS_E1H(bp))
|
||||||
|
@ -6467,7 +6486,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
|
||||||
for_each_nondefault_queue(bp, i) {
|
for_each_nondefault_queue(bp, i) {
|
||||||
rc = bnx2x_setup_multi(bp, i);
|
rc = bnx2x_setup_multi(bp, i);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto load_netif_stop;
|
goto load_error3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CHIP_IS_E1(bp))
|
if (CHIP_IS_E1(bp))
|
||||||
|
@ -6483,18 +6502,18 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
|
||||||
case LOAD_NORMAL:
|
case LOAD_NORMAL:
|
||||||
/* Tx queue should be only reenabled */
|
/* Tx queue should be only reenabled */
|
||||||
netif_wake_queue(bp->dev);
|
netif_wake_queue(bp->dev);
|
||||||
|
/* Initialize the receive filter. */
|
||||||
bnx2x_set_rx_mode(bp->dev);
|
bnx2x_set_rx_mode(bp->dev);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LOAD_OPEN:
|
case LOAD_OPEN:
|
||||||
netif_start_queue(bp->dev);
|
netif_start_queue(bp->dev);
|
||||||
|
/* Initialize the receive filter. */
|
||||||
bnx2x_set_rx_mode(bp->dev);
|
bnx2x_set_rx_mode(bp->dev);
|
||||||
if (bp->flags & USING_MSIX_FLAG)
|
|
||||||
printk(KERN_INFO PFX "%s: using MSI-X\n",
|
|
||||||
bp->dev->name);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LOAD_DIAG:
|
case LOAD_DIAG:
|
||||||
|
/* Initialize the receive filter. */
|
||||||
bnx2x_set_rx_mode(bp->dev);
|
bnx2x_set_rx_mode(bp->dev);
|
||||||
bp->state = BNX2X_STATE_DIAG;
|
bp->state = BNX2X_STATE_DIAG;
|
||||||
break;
|
break;
|
||||||
|
@ -6512,20 +6531,23 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
load_netif_stop:
|
load_error3:
|
||||||
bnx2x_napi_disable(bp);
|
bnx2x_int_disable_sync(bp, 1);
|
||||||
load_rings_free:
|
if (!BP_NOMCP(bp)) {
|
||||||
|
bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP);
|
||||||
|
bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
|
||||||
|
}
|
||||||
|
bp->port.pmf = 0;
|
||||||
/* Free SKBs, SGEs, TPA pool and driver internals */
|
/* Free SKBs, SGEs, TPA pool and driver internals */
|
||||||
bnx2x_free_skbs(bp);
|
bnx2x_free_skbs(bp);
|
||||||
for_each_queue(bp, i)
|
for_each_queue(bp, i)
|
||||||
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
|
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
|
||||||
load_int_disable:
|
load_error2:
|
||||||
bnx2x_int_disable_sync(bp, 1);
|
|
||||||
/* Release IRQs */
|
/* Release IRQs */
|
||||||
bnx2x_free_irq(bp);
|
bnx2x_free_irq(bp);
|
||||||
load_error:
|
load_error1:
|
||||||
|
bnx2x_napi_disable(bp);
|
||||||
bnx2x_free_mem(bp);
|
bnx2x_free_mem(bp);
|
||||||
bp->port.pmf = 0;
|
|
||||||
|
|
||||||
/* TBD we really need to reset the chip
|
/* TBD we really need to reset the chip
|
||||||
if we want to recover from this */
|
if we want to recover from this */
|
||||||
|
|
Loading…
Reference in New Issue