]> git.ipfire.org Git - ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.drivers/bnx2x-Handling-load-failures.patch
Reenabled linux-xen, added patches for Xen Kernel Version 2.6.27.31,
[ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / bnx2x-Handling-load-failures.patch
diff --git a/src/patches/suse-2.6.27.31/patches.drivers/bnx2x-Handling-load-failures.patch b/src/patches/suse-2.6.27.31/patches.drivers/bnx2x-Handling-load-failures.patch
new file mode 100644 (file)
index 0000000..233766b
--- /dev/null
@@ -0,0 +1,278 @@
+From 2dfe0e1fecb582b4aae7f2490904864c05472f3a Mon Sep 17 00:00:00 2001
+From: Eilon Greenstein <eilong@broadcom.com>
+Date: Thu, 22 Jan 2009 03:37:44 +0000
+Subject: bnx2x: Handling load failures
+Acked-by: Karsten Keil <kkeil@novell.com>
+Reference: bnc#472500
+
+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>
+---
+ drivers/net/bnx2x_main.c |  154 ++++++++++++++++++++++++++--------------------
+ 1 files changed, 88 insertions(+), 66 deletions(-)
+
+Index: linux-2.6.27-bnx2x_2/drivers/net/bnx2x_main.c
+===================================================================
+--- linux-2.6.27-bnx2x_2.orig/drivers/net/bnx2x_main.c
++++ linux-2.6.27-bnx2x_2/drivers/net/bnx2x_main.c
+@@ -6331,7 +6331,7 @@ static void bnx2x_set_rx_mode(struct net
+ 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;
+@@ -6339,48 +6339,6 @@ static int bnx2x_nic_load(struct bnx2x *
+       bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
+-      /* Send LOAD_REQUEST command to MCP
+-         Returns the type of LOAD command:
+-         if it is the first port to be initialized
+-         common blocks should be initialized, otherwise - not
+-      */
+-      if (!BP_NOMCP(bp)) {
+-              load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
+-              if (!load_code) {
+-                      BNX2X_ERR("MCP response failure, aborting\n");
+-                      return -EBUSY;
+-              }
+-              if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED)
+-                      return -EBUSY; /* other port in diagnostic mode */
+-
+-      } else {
+-              int port = BP_PORT(bp);
+-
+-              DP(NETIF_MSG_IFUP, "NO MCP load counts before us %d, %d, %d\n",
+-                 load_count[0], load_count[1], load_count[2]);
+-              load_count[0]++;
+-              load_count[1 + port]++;
+-              DP(NETIF_MSG_IFUP, "NO MCP new load counts       %d, %d, %d\n",
+-                 load_count[0], load_count[1], load_count[2]);
+-              if (load_count[0] == 1)
+-                      load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
+-              else if (load_count[1 + port] == 1)
+-                      load_code = FW_MSG_CODE_DRV_LOAD_PORT;
+-              else
+-                      load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION;
+-      }
+-
+-      if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) ||
+-          (load_code == FW_MSG_CODE_DRV_LOAD_PORT))
+-              bp->port.pmf = 1;
+-      else
+-              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;
+@@ -6395,7 +6353,15 @@ static int bnx2x_nic_load(struct bnx2x *
+               else
+                       bp->num_queues = 1;
+-              if (bnx2x_enable_msix(bp)) {
++              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)
+@@ -6403,8 +6369,6 @@ static int bnx2x_nic_load(struct bnx2x *
+                                         " 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;
+@@ -6413,30 +6377,85 @@ static int bnx2x_nic_load(struct bnx2x *
+               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_error;
++                      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, aborting\n");
+-                      goto load_error;
++                      BNX2X_ERR("IRQ request failed  rc %d, aborting\n", rc);
++                      goto load_error1;
+               }
+       }
+-      for_each_queue(bp, i)
+-              netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
+-                             bnx2x_poll, 128);
++      /* Send LOAD_REQUEST command to MCP
++         Returns the type of LOAD command:
++         if it is the first port to be initialized
++         common blocks should be initialized, otherwise - not
++      */
++      if (!BP_NOMCP(bp)) {
++              load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
++              if (!load_code) {
++                      BNX2X_ERR("MCP response failure, aborting\n");
++                      rc = -EBUSY;
++                      goto load_error2;
++              }
++              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);
++
++              DP(NETIF_MSG_IFUP, "NO MCP load counts before us %d, %d, %d\n",
++                 load_count[0], load_count[1], load_count[2]);
++              load_count[0]++;
++              load_count[1 + port]++;
++              DP(NETIF_MSG_IFUP, "NO MCP new load counts       %d, %d, %d\n",
++                 load_count[0], load_count[1], load_count[2]);
++              if (load_count[0] == 1)
++                      load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
++              else if (load_count[1 + port] == 1)
++                      load_code = FW_MSG_CODE_DRV_LOAD_PORT;
++              else
++                      load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION;
++      }
++
++      if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) ||
++          (load_code == FW_MSG_CODE_DRV_LOAD_PORT))
++              bp->port.pmf = 1;
++      else
++              bp->port.pmf = 0;
++      DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf);
+       /* 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 */
+@@ -6448,7 +6467,7 @@ static int bnx2x_nic_load(struct bnx2x *
+               if (!load_code) {
+                       BNX2X_ERR("MCP response failure, aborting\n");
+                       rc = -EBUSY;
+-                      goto load_rings_free;
++                      goto load_error3;
+               }
+       }
+@@ -6457,7 +6476,7 @@ static int bnx2x_nic_load(struct bnx2x *
+       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))
+@@ -6470,7 +6489,7 @@ static int bnx2x_nic_load(struct bnx2x *
+               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))
+@@ -6486,18 +6505,18 @@ static int bnx2x_nic_load(struct bnx2x *
+       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;
+@@ -6515,20 +6534,23 @@ static int bnx2x_nic_load(struct bnx2x *
+       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 */