]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.drivers/bnx2x-Handling-load-failures.patch
Add a patch to fix Intel E100 wake-on-lan problems.
[ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / bnx2x-Handling-load-failures.patch
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>
6 Reference: bnc#472500
7
8 Failures on load were not handled correctly - separate the flow to handle
9
10 different failures
11
12 Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
13 Signed-off-by: David S. Miller <davem@davemloft.net>
14 ---
15 drivers/net/bnx2x_main.c | 154 ++++++++++++++++++++++++++--------------------
16 1 files changed, 88 insertions(+), 66 deletions(-)
17
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)
24 {
25 u32 load_code;
26 - int i, rc;
27 + int i, rc = 0;
28 #ifdef BNX2X_STOP_ON_ERROR
29 if (unlikely(bp->panic))
30 return -EPERM;
31 @@ -6339,48 +6339,6 @@ static int bnx2x_nic_load(struct bnx2x *
32
33 bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
34
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
39 - */
40 - if (!BP_NOMCP(bp)) {
41 - load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
42 - if (!load_code) {
43 - BNX2X_ERR("MCP response failure, aborting\n");
44 - return -EBUSY;
45 - }
46 - if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED)
47 - return -EBUSY; /* other port in diagnostic mode */
48 -
49 - } else {
50 - int port = BP_PORT(bp);
51 -
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]);
54 - load_count[0]++;
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;
62 - else
63 - load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION;
64 - }
65 -
66 - if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) ||
67 - (load_code == FW_MSG_CODE_DRV_LOAD_PORT))
68 - bp->port.pmf = 1;
69 - else
70 - bp->port.pmf = 0;
71 - DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf);
72 -
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
76 - */
77 if (use_inta) {
78 bp->num_queues = 1;
79
80 @@ -6395,7 +6353,15 @@ static int bnx2x_nic_load(struct bnx2x *
81 else
82 bp->num_queues = 1;
83
84 - if (bnx2x_enable_msix(bp)) {
85 + DP(NETIF_MSG_IFUP,
86 + "set number of queues to %d\n", bp->num_queues);
87 +
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
91 + */
92 + rc = bnx2x_enable_msix(bp);
93 + if (rc) {
94 /* failed to enable MSI-X */
95 bp->num_queues = 1;
96 if (use_multi)
97 @@ -6403,8 +6369,6 @@ static int bnx2x_nic_load(struct bnx2x *
98 " to enable MSI-X\n");
99 }
100 }
101 - DP(NETIF_MSG_IFUP,
102 - "set number of queues to %d\n", bp->num_queues);
103
104 if (bnx2x_alloc_mem(bp))
105 return -ENOMEM;
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);
109
110 + for_each_queue(bp, i)
111 + netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
112 + bnx2x_poll, 128);
113 +
114 +#ifdef BNX2X_STOP_ON_ERROR
115 + for_each_queue(bp, i) {
116 + struct bnx2x_fastpath *fp = &bp->fp[i];
117 +
118 + fp->poll_no_work = 0;
119 + fp->poll_calls = 0;
120 + fp->poll_max_calls = 0;
121 + fp->poll_complete = 0;
122 + fp->poll_exit = 0;
123 + }
124 +#endif
125 + bnx2x_napi_enable(bp);
126 +
127 if (bp->flags & USING_MSIX_FLAG) {
128 rc = bnx2x_req_msix_irqs(bp);
129 if (rc) {
130 pci_disable_msix(bp->pdev);
131 - goto load_error;
132 + goto load_error1;
133 }
134 + printk(KERN_INFO PFX "%s: using MSI-X\n", bp->dev->name);
135 } else {
136 bnx2x_ack_int(bp);
137 rc = bnx2x_req_irq(bp);
138 if (rc) {
139 - BNX2X_ERR("IRQ request failed, aborting\n");
140 - goto load_error;
141 + BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc);
142 + goto load_error1;
143 }
144 }
145
146 - for_each_queue(bp, i)
147 - netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
148 - bnx2x_poll, 128);
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
153 + */
154 + if (!BP_NOMCP(bp)) {
155 + load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
156 + if (!load_code) {
157 + BNX2X_ERR("MCP response failure, aborting\n");
158 + rc = -EBUSY;
159 + goto load_error2;
160 + }
161 + if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) {
162 + rc = -EBUSY; /* other port in diagnostic mode */
163 + goto load_error2;
164 + }
165 +
166 + } else {
167 + int port = BP_PORT(bp);
168 +
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]);
171 + load_count[0]++;
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;
179 + else
180 + load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION;
181 + }
182 +
183 + if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) ||
184 + (load_code == FW_MSG_CODE_DRV_LOAD_PORT))
185 + bp->port.pmf = 1;
186 + else
187 + bp->port.pmf = 0;
188 + DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf);
189
190 /* Initialize HW */
191 rc = bnx2x_init_hw(bp, load_code);
192 if (rc) {
193 BNX2X_ERR("HW init failed, aborting\n");
194 - goto load_int_disable;
195 + goto load_error2;
196 }
197
198 /* Setup NIC internals and enable interrupts */
199 @@ -6448,7 +6467,7 @@ static int bnx2x_nic_load(struct bnx2x *
200 if (!load_code) {
201 BNX2X_ERR("MCP response failure, aborting\n");
202 rc = -EBUSY;
203 - goto load_rings_free;
204 + goto load_error3;
205 }
206 }
207
208 @@ -6457,7 +6476,7 @@ static int bnx2x_nic_load(struct bnx2x *
209 rc = bnx2x_setup_leading(bp);
210 if (rc) {
211 BNX2X_ERR("Setup leading failed!\n");
212 - goto load_netif_stop;
213 + goto load_error3;
214 }
215
216 if (CHIP_IS_E1H(bp))
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);
220 if (rc)
221 - goto load_netif_stop;
222 + goto load_error3;
223 }
224
225 if (CHIP_IS_E1(bp))
226 @@ -6486,18 +6505,18 @@ static int bnx2x_nic_load(struct bnx2x *
227 case LOAD_NORMAL:
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);
232 break;
233
234 case LOAD_OPEN:
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",
240 - bp->dev->name);
241 break;
242
243 case LOAD_DIAG:
244 + /* Initialize the receive filter. */
245 bnx2x_set_rx_mode(bp->dev);
246 bp->state = BNX2X_STATE_DIAG;
247 break;
248 @@ -6515,20 +6534,23 @@ static int bnx2x_nic_load(struct bnx2x *
249
250 return 0;
251
252 -load_netif_stop:
253 - bnx2x_napi_disable(bp);
254 -load_rings_free:
255 +load_error3:
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);
260 + }
261 + bp->port.pmf = 0;
262 /* Free SKBs, SGEs, TPA pool and driver internals */
263 bnx2x_free_skbs(bp);
264 for_each_queue(bp, i)
265 bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
266 -load_int_disable:
267 - bnx2x_int_disable_sync(bp, 1);
268 +load_error2:
269 /* Release IRQs */
270 bnx2x_free_irq(bp);
271 -load_error:
272 +load_error1:
273 + bnx2x_napi_disable(bp);
274 bnx2x_free_mem(bp);
275 - bp->port.pmf = 0;
276
277 /* TBD we really need to reset the chip
278 if we want to recover from this */