1 From 2dfe0e1fecb582b4aae7f2490904864c05472f3a Mon Sep 17 00:00:00 2001
2 From: Eilon Greenstein <eilong@broadcom.com>
3 Date: Thu, 22 Jan 2009 03:37:44 +0000
4 Subject: bnx2x: Handling load failures
5 Acked-by: Karsten Keil <kkeil@novell.com>
8 Failures on load were not handled correctly - separate the flow to handle
12 Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
13 Signed-off-by: David S. Miller <davem@davemloft.net>
15 drivers/net/bnx2x_main.c | 154 ++++++++++++++++++++++++++--------------------
16 1 files changed, 88 insertions(+), 66 deletions(-)
18 Index: linux-2.6.27-bnx2x_2/drivers/net/bnx2x_main.c
19 ===================================================================
20 --- linux-2.6.27-bnx2x_2.orig/drivers/net/bnx2x_main.c
21 +++ linux-2.6.27-bnx2x_2/drivers/net/bnx2x_main.c
22 @@ -6331,7 +6331,7 @@ static void bnx2x_set_rx_mode(struct net
23 static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
28 #ifdef BNX2X_STOP_ON_ERROR
29 if (unlikely(bp->panic))
31 @@ -6339,48 +6339,6 @@ static int bnx2x_nic_load(struct bnx2x *
33 bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
35 - /* Send LOAD_REQUEST command to MCP
36 - Returns the type of LOAD command:
37 - if it is the first port to be initialized
38 - common blocks should be initialized, otherwise - not
40 - if (!BP_NOMCP(bp)) {
41 - load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
43 - BNX2X_ERR("MCP response failure, aborting\n");
46 - if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED)
47 - return -EBUSY; /* other port in diagnostic mode */
50 - int port = BP_PORT(bp);
52 - DP(NETIF_MSG_IFUP, "NO MCP load counts before us %d, %d, %d\n",
53 - load_count[0], load_count[1], load_count[2]);
55 - load_count[1 + port]++;
56 - DP(NETIF_MSG_IFUP, "NO MCP new load counts %d, %d, %d\n",
57 - load_count[0], load_count[1], load_count[2]);
58 - if (load_count[0] == 1)
59 - load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
60 - else if (load_count[1 + port] == 1)
61 - load_code = FW_MSG_CODE_DRV_LOAD_PORT;
63 - load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION;
66 - if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) ||
67 - (load_code == FW_MSG_CODE_DRV_LOAD_PORT))
71 - DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf);
73 - /* if we can't use MSI-X we only need one fp,
74 - * so try to enable MSI-X with the requested number of fp's
75 - * and fallback to inta with one fp
80 @@ -6395,7 +6353,15 @@ static int bnx2x_nic_load(struct bnx2x *
84 - if (bnx2x_enable_msix(bp)) {
86 + "set number of queues to %d\n", bp->num_queues);
88 + /* if we can't use MSI-X we only need one fp,
89 + * so try to enable MSI-X with the requested number of fp's
90 + * and fallback to MSI or legacy INTx with one fp
92 + rc = bnx2x_enable_msix(bp);
94 /* failed to enable MSI-X */
97 @@ -6403,8 +6369,6 @@ static int bnx2x_nic_load(struct bnx2x *
98 " to enable MSI-X\n");
102 - "set number of queues to %d\n", bp->num_queues);
104 if (bnx2x_alloc_mem(bp))
106 @@ -6413,30 +6377,85 @@ static int bnx2x_nic_load(struct bnx2x *
107 bnx2x_fp(bp, i, disable_tpa) =
108 ((bp->flags & TPA_ENABLE_FLAG) == 0);
110 + for_each_queue(bp, i)
111 + netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
114 +#ifdef BNX2X_STOP_ON_ERROR
115 + for_each_queue(bp, i) {
116 + struct bnx2x_fastpath *fp = &bp->fp[i];
118 + fp->poll_no_work = 0;
119 + fp->poll_calls = 0;
120 + fp->poll_max_calls = 0;
121 + fp->poll_complete = 0;
125 + bnx2x_napi_enable(bp);
127 if (bp->flags & USING_MSIX_FLAG) {
128 rc = bnx2x_req_msix_irqs(bp);
130 pci_disable_msix(bp->pdev);
134 + printk(KERN_INFO PFX "%s: using MSI-X\n", bp->dev->name);
137 rc = bnx2x_req_irq(bp);
139 - BNX2X_ERR("IRQ request failed, aborting\n");
141 + BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc);
146 - for_each_queue(bp, i)
147 - netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
149 + /* Send LOAD_REQUEST command to MCP
150 + Returns the type of LOAD command:
151 + if it is the first port to be initialized
152 + common blocks should be initialized, otherwise - not
154 + if (!BP_NOMCP(bp)) {
155 + load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
157 + BNX2X_ERR("MCP response failure, aborting\n");
161 + if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) {
162 + rc = -EBUSY; /* other port in diagnostic mode */
167 + int port = BP_PORT(bp);
169 + DP(NETIF_MSG_IFUP, "NO MCP load counts before us %d, %d, %d\n",
170 + load_count[0], load_count[1], load_count[2]);
172 + load_count[1 + port]++;
173 + DP(NETIF_MSG_IFUP, "NO MCP new load counts %d, %d, %d\n",
174 + load_count[0], load_count[1], load_count[2]);
175 + if (load_count[0] == 1)
176 + load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
177 + else if (load_count[1 + port] == 1)
178 + load_code = FW_MSG_CODE_DRV_LOAD_PORT;
180 + load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION;
183 + if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) ||
184 + (load_code == FW_MSG_CODE_DRV_LOAD_PORT))
188 + DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf);
191 rc = bnx2x_init_hw(bp, load_code);
193 BNX2X_ERR("HW init failed, aborting\n");
194 - goto load_int_disable;
198 /* Setup NIC internals and enable interrupts */
199 @@ -6448,7 +6467,7 @@ static int bnx2x_nic_load(struct bnx2x *
201 BNX2X_ERR("MCP response failure, aborting\n");
203 - goto load_rings_free;
208 @@ -6457,7 +6476,7 @@ static int bnx2x_nic_load(struct bnx2x *
209 rc = bnx2x_setup_leading(bp);
211 BNX2X_ERR("Setup leading failed!\n");
212 - goto load_netif_stop;
217 @@ -6470,7 +6489,7 @@ static int bnx2x_nic_load(struct bnx2x *
218 for_each_nondefault_queue(bp, i) {
219 rc = bnx2x_setup_multi(bp, i);
221 - goto load_netif_stop;
226 @@ -6486,18 +6505,18 @@ static int bnx2x_nic_load(struct bnx2x *
228 /* Tx queue should be only reenabled */
229 netif_wake_queue(bp->dev);
230 + /* Initialize the receive filter. */
231 bnx2x_set_rx_mode(bp->dev);
235 netif_start_queue(bp->dev);
236 + /* Initialize the receive filter. */
237 bnx2x_set_rx_mode(bp->dev);
238 - if (bp->flags & USING_MSIX_FLAG)
239 - printk(KERN_INFO PFX "%s: using MSI-X\n",
244 + /* Initialize the receive filter. */
245 bnx2x_set_rx_mode(bp->dev);
246 bp->state = BNX2X_STATE_DIAG;
248 @@ -6515,20 +6534,23 @@ static int bnx2x_nic_load(struct bnx2x *
253 - bnx2x_napi_disable(bp);
256 + bnx2x_int_disable_sync(bp, 1);
257 + if (!BP_NOMCP(bp)) {
258 + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP);
259 + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
262 /* Free SKBs, SGEs, TPA pool and driver internals */
264 for_each_queue(bp, i)
265 bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
267 - bnx2x_int_disable_sync(bp, 1);
273 + bnx2x_napi_disable(bp);
277 /* TBD we really need to reset the chip
278 if we want to recover from this */