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>
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 860b9f8..707c4bb 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -6328,7 +6328,7 @@
static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
{
u32 load_code;
- int i, rc;
+ int i, rc = 0;
#ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic))
return -EPERM;
@@ -6336,6 +6336,77 @@
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
Returns the type of LOAD command:
if it is the first port to be initialized
@@ -6345,10 +6416,13 @@
load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
if (!load_code) {
BNX2X_ERR("MCP response failure, aborting\n");
- return -EBUSY;
+ rc = -EBUSY;
+ goto load_error2;
}
- if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED)
- return -EBUSY; /* other port in diagnostic mode */
+ if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) {
+ rc = -EBUSY; /* other port in diagnostic mode */
+ goto load_error2;
+ }
} else {
int port = BP_PORT(bp);
@@ -6374,66 +6448,11 @@
bp->port.pmf = 0;
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 */
rc = bnx2x_init_hw(bp, load_code);
if (rc) {
BNX2X_ERR("HW init failed, aborting\n");
- goto load_int_disable;
+ goto load_error2;
}
/* Setup NIC internals and enable interrupts */
@@ -6445,7 +6464,7 @@
if (!load_code) {
BNX2X_ERR("MCP response failure, aborting\n");
rc = -EBUSY;
- goto load_rings_free;
+ goto load_error3;
}
}
@@ -6454,7 +6473,7 @@
rc = bnx2x_setup_leading(bp);
if (rc) {
BNX2X_ERR("Setup leading failed!\n");
- goto load_netif_stop;
+ goto load_error3;
}
if (CHIP_IS_E1H(bp))
@@ -6467,7 +6486,7 @@
for_each_nondefault_queue(bp, i) {
rc = bnx2x_setup_multi(bp, i);
if (rc)
- goto load_netif_stop;
+ goto load_error3;
}
if (CHIP_IS_E1(bp))
@@ -6483,18 +6502,18 @@
case LOAD_NORMAL:
/* Tx queue should be only reenabled */
netif_wake_queue(bp->dev);
+ /* Initialize the receive filter. */
bnx2x_set_rx_mode(bp->dev);
break;
case LOAD_OPEN:
netif_start_queue(bp->dev);
+ /* Initialize the receive filter. */
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;
case LOAD_DIAG:
+ /* Initialize the receive filter. */
bnx2x_set_rx_mode(bp->dev);
bp->state = BNX2X_STATE_DIAG;
break;
@@ -6512,20 +6531,23 @@
return 0;
-load_netif_stop:
- bnx2x_napi_disable(bp);
-load_rings_free:
+load_error3:
+ bnx2x_int_disable_sync(bp, 1);
+ 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 */
bnx2x_free_skbs(bp);
for_each_queue(bp, i)
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
-load_int_disable:
- bnx2x_int_disable_sync(bp, 1);
+load_error2:
/* Release IRQs */
bnx2x_free_irq(bp);
-load_error:
+load_error1:
+ bnx2x_napi_disable(bp);
bnx2x_free_mem(bp);
- bp->port.pmf = 0;
/* TBD we really need to reset the chip
if we want to recover from this */