aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/qlge/qlge.h6
-rw-r--r--drivers/net/qlge/qlge_dbg.c523
-rw-r--r--drivers/net/qlge/qlge_main.c20
-rw-r--r--drivers/net/qlge/qlge_mpi.c73
4 files changed, 622 insertions, 0 deletions
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index a265325abb15..bbdd388aa9b7 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -2211,6 +2211,7 @@ extern int ql_write_cfg(struct ql_adapter *qdev, void *ptr, int size, u32 bit,
2211void ql_queue_fw_error(struct ql_adapter *qdev); 2211void ql_queue_fw_error(struct ql_adapter *qdev);
2212void ql_mpi_work(struct work_struct *work); 2212void ql_mpi_work(struct work_struct *work);
2213void ql_mpi_reset_work(struct work_struct *work); 2213void ql_mpi_reset_work(struct work_struct *work);
2214void ql_mpi_core_to_log(struct work_struct *work);
2214int ql_wait_reg_rdy(struct ql_adapter *qdev, u32 reg, u32 bit, u32 ebit); 2215int ql_wait_reg_rdy(struct ql_adapter *qdev, u32 reg, u32 bit, u32 ebit);
2215void ql_queue_asic_error(struct ql_adapter *qdev); 2216void ql_queue_asic_error(struct ql_adapter *qdev);
2216u32 ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr); 2217u32 ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr);
@@ -2221,6 +2222,11 @@ void ql_mpi_port_cfg_work(struct work_struct *work);
2221int ql_mb_get_fw_state(struct ql_adapter *qdev); 2222int ql_mb_get_fw_state(struct ql_adapter *qdev);
2222int ql_cam_route_initialize(struct ql_adapter *qdev); 2223int ql_cam_route_initialize(struct ql_adapter *qdev);
2223int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data); 2224int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data);
2225int ql_write_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 data);
2226int ql_unpause_mpi_risc(struct ql_adapter *qdev);
2227int ql_pause_mpi_risc(struct ql_adapter *qdev);
2228int ql_core_dump(struct ql_adapter *qdev,
2229 struct ql_mpi_coredump *mpi_coredump);
2224int ql_mb_about_fw(struct ql_adapter *qdev); 2230int ql_mb_about_fw(struct ql_adapter *qdev);
2225int ql_wol(struct ql_adapter *qdev); 2231int ql_wol(struct ql_adapter *qdev);
2226int ql_mb_wol_set_magic(struct ql_adapter *qdev, u32 enable_wol); 2232int ql_mb_wol_set_magic(struct ql_adapter *qdev, u32 enable_wol);
diff --git a/drivers/net/qlge/qlge_dbg.c b/drivers/net/qlge/qlge_dbg.c
index 9f58c4710761..1d026141b78d 100644
--- a/drivers/net/qlge/qlge_dbg.c
+++ b/drivers/net/qlge/qlge_dbg.c
@@ -91,6 +91,179 @@ err:
91 return status; 91 return status;
92} 92}
93 93
94/* Read the MPI Processor shadow registers */
95static int ql_get_mpi_shadow_regs(struct ql_adapter *qdev, u32 * buf)
96{
97 u32 i;
98 int status;
99
100 for (i = 0; i < MPI_CORE_SH_REGS_CNT; i++, buf++) {
101 status = ql_write_mpi_reg(qdev, RISC_124,
102 (SHADOW_OFFSET | i << SHADOW_REG_SHIFT));
103 if (status)
104 goto end;
105 status = ql_read_mpi_reg(qdev, RISC_127, buf);
106 if (status)
107 goto end;
108 }
109end:
110 return status;
111}
112
113/* Read the MPI Processor core registers */
114static int ql_get_mpi_regs(struct ql_adapter *qdev, u32 * buf,
115 u32 offset, u32 count)
116{
117 int i, status = 0;
118 for (i = 0; i < count; i++, buf++) {
119 status = ql_read_mpi_reg(qdev, offset + i, buf);
120 if (status)
121 return status;
122 }
123 return status;
124}
125
126
127/* Read out the routing index registers */
128static int ql_get_routing_index_registers(struct ql_adapter *qdev, u32 *buf)
129{
130 int status;
131 u32 type, index, index_max;
132 u32 result_index;
133 u32 result_data;
134 u32 val;
135
136 status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
137 if (status)
138 return status;
139
140 for (type = 0; type < 4; type++) {
141 if (type < 2)
142 index_max = 8;
143 else
144 index_max = 16;
145 for (index = 0; index < index_max; index++) {
146 val = RT_IDX_RS
147 | (type << RT_IDX_TYPE_SHIFT)
148 | (index << RT_IDX_IDX_SHIFT);
149 ql_write32(qdev, RT_IDX, val);
150 result_index = 0;
151 while ((result_index & RT_IDX_MR) == 0)
152 result_index = ql_read32(qdev, RT_IDX);
153 result_data = ql_read32(qdev, RT_DATA);
154 *buf = type;
155 buf++;
156 *buf = index;
157 buf++;
158 *buf = result_index;
159 buf++;
160 *buf = result_data;
161 buf++;
162 }
163 }
164 ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
165 return status;
166}
167
168/* Read out the MAC protocol registers */
169static void ql_get_mac_protocol_registers(struct ql_adapter *qdev, u32 *buf)
170{
171 u32 result_index, result_data;
172 u32 type;
173 u32 index;
174 u32 offset;
175 u32 val;
176 u32 initial_val = MAC_ADDR_RS;
177 u32 max_index;
178 u32 max_offset;
179
180 for (type = 0; type < MAC_ADDR_TYPE_COUNT; type++) {
181 switch (type) {
182
183 case 0: /* CAM */
184 initial_val |= MAC_ADDR_ADR;
185 max_index = MAC_ADDR_MAX_CAM_ENTRIES;
186 max_offset = MAC_ADDR_MAX_CAM_WCOUNT;
187 break;
188 case 1: /* Multicast MAC Address */
189 max_index = MAC_ADDR_MAX_CAM_WCOUNT;
190 max_offset = MAC_ADDR_MAX_CAM_WCOUNT;
191 break;
192 case 2: /* VLAN filter mask */
193 case 3: /* MC filter mask */
194 max_index = MAC_ADDR_MAX_CAM_WCOUNT;
195 max_offset = MAC_ADDR_MAX_CAM_WCOUNT;
196 break;
197 case 4: /* FC MAC addresses */
198 max_index = MAC_ADDR_MAX_FC_MAC_ENTRIES;
199 max_offset = MAC_ADDR_MAX_FC_MAC_WCOUNT;
200 break;
201 case 5: /* Mgmt MAC addresses */
202 max_index = MAC_ADDR_MAX_MGMT_MAC_ENTRIES;
203 max_offset = MAC_ADDR_MAX_MGMT_MAC_WCOUNT;
204 break;
205 case 6: /* Mgmt VLAN addresses */
206 max_index = MAC_ADDR_MAX_MGMT_VLAN_ENTRIES;
207 max_offset = MAC_ADDR_MAX_MGMT_VLAN_WCOUNT;
208 break;
209 case 7: /* Mgmt IPv4 address */
210 max_index = MAC_ADDR_MAX_MGMT_V4_ENTRIES;
211 max_offset = MAC_ADDR_MAX_MGMT_V4_WCOUNT;
212 break;
213 case 8: /* Mgmt IPv6 address */
214 max_index = MAC_ADDR_MAX_MGMT_V6_ENTRIES;
215 max_offset = MAC_ADDR_MAX_MGMT_V6_WCOUNT;
216 break;
217 case 9: /* Mgmt TCP/UDP Dest port */
218 max_index = MAC_ADDR_MAX_MGMT_TU_DP_ENTRIES;
219 max_offset = MAC_ADDR_MAX_MGMT_TU_DP_WCOUNT;
220 break;
221 default:
222 printk(KERN_ERR"Bad type!!! 0x%08x\n", type);
223 max_index = 0;
224 max_offset = 0;
225 break;
226 }
227 for (index = 0; index < max_index; index++) {
228 for (offset = 0; offset < max_offset; offset++) {
229 val = initial_val
230 | (type << MAC_ADDR_TYPE_SHIFT)
231 | (index << MAC_ADDR_IDX_SHIFT)
232 | (offset);
233 ql_write32(qdev, MAC_ADDR_IDX, val);
234 result_index = 0;
235 while ((result_index & MAC_ADDR_MR) == 0) {
236 result_index = ql_read32(qdev,
237 MAC_ADDR_IDX);
238 }
239 result_data = ql_read32(qdev, MAC_ADDR_DATA);
240 *buf = result_index;
241 buf++;
242 *buf = result_data;
243 buf++;
244 }
245 }
246 }
247}
248
249static void ql_get_sem_registers(struct ql_adapter *qdev, u32 *buf)
250{
251 u32 func_num, reg, reg_val;
252 int status;
253
254 for (func_num = 0; func_num < MAX_SEMAPHORE_FUNCTIONS ; func_num++) {
255 reg = MPI_NIC_REG_BLOCK
256 | (func_num << MPI_NIC_FUNCTION_SHIFT)
257 | (SEM / 4);
258 status = ql_read_mpi_reg(qdev, reg, &reg_val);
259 *buf = reg_val;
260 /* if the read failed then dead fill the element. */
261 if (!status)
262 *buf = 0xdeadbeef;
263 buf++;
264 }
265}
266
94/* Create a coredump segment header */ 267/* Create a coredump segment header */
95static void ql_build_coredump_seg_header( 268static void ql_build_coredump_seg_header(
96 struct mpi_coredump_segment_header *seg_hdr, 269 struct mpi_coredump_segment_header *seg_hdr,
@@ -103,6 +276,329 @@ static void ql_build_coredump_seg_header(
103 memcpy(seg_hdr->description, desc, (sizeof(seg_hdr->description)) - 1); 276 memcpy(seg_hdr->description, desc, (sizeof(seg_hdr->description)) - 1);
104} 277}
105 278
279/*
280 * This function should be called when a coredump / probedump
281 * is to be extracted from the HBA. It is assumed there is a
282 * qdev structure that contains the base address of the register
283 * space for this function as well as a coredump structure that
284 * will contain the dump.
285 */
286int ql_core_dump(struct ql_adapter *qdev, struct ql_mpi_coredump *mpi_coredump)
287{
288 int status;
289 int i;
290
291 if (!mpi_coredump) {
292 QPRINTK(qdev, DRV, ERR,
293 "No memory available.\n");
294 return -ENOMEM;
295 }
296
297 /* Try to get the spinlock, but dont worry if
298 * it isn't available. If the firmware died it
299 * might be holding the sem.
300 */
301 ql_sem_spinlock(qdev, SEM_PROC_REG_MASK);
302
303 status = ql_pause_mpi_risc(qdev);
304 if (status) {
305 QPRINTK(qdev, DRV, ERR,
306 "Failed RISC pause. Status = 0x%.08x\n", status);
307 goto err;
308 }
309
310 /* Insert the global header */
311 memset(&(mpi_coredump->mpi_global_header), 0,
312 sizeof(struct mpi_coredump_global_header));
313 mpi_coredump->mpi_global_header.cookie = MPI_COREDUMP_COOKIE;
314 mpi_coredump->mpi_global_header.headerSize =
315 sizeof(struct mpi_coredump_global_header);
316 mpi_coredump->mpi_global_header.imageSize =
317 sizeof(struct ql_mpi_coredump);
318 memcpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump",
319 sizeof(mpi_coredump->mpi_global_header.idString));
320
321 /* Get generic NIC reg dump */
322 ql_build_coredump_seg_header(&mpi_coredump->nic_regs_seg_hdr,
323 NIC1_CONTROL_SEG_NUM,
324 sizeof(struct mpi_coredump_segment_header) +
325 sizeof(mpi_coredump->nic_regs), "NIC1 Registers");
326
327 if (qdev->func & 1) {
328 /* Odd means our function is NIC 2 */
329 for (i = 0; i < NIC_REGS_DUMP_WORD_COUNT; i++)
330 mpi_coredump->nic2_regs[i] =
331 ql_read32(qdev, i * sizeof(u32));
332 } else {
333 /* Even means our function is NIC 1 */
334 for (i = 0; i < NIC_REGS_DUMP_WORD_COUNT; i++)
335 mpi_coredump->nic_regs[i] =
336 ql_read32(qdev, i * sizeof(u32));
337 }
338
339 ql_build_coredump_seg_header(&mpi_coredump->core_regs_seg_hdr,
340 CORE_SEG_NUM,
341 sizeof(mpi_coredump->core_regs_seg_hdr) +
342 sizeof(mpi_coredump->mpi_core_regs) +
343 sizeof(mpi_coredump->mpi_core_sh_regs),
344 "Core Registers");
345
346 /* Get the MPI Core Registers */
347 status = ql_get_mpi_regs(qdev, &mpi_coredump->mpi_core_regs[0],
348 MPI_CORE_REGS_ADDR, MPI_CORE_REGS_CNT);
349 if (status)
350 goto err;
351 /* Get the 16 MPI shadow registers */
352 status = ql_get_mpi_shadow_regs(qdev,
353 &mpi_coredump->mpi_core_sh_regs[0]);
354 if (status)
355 goto err;
356
357 /* Get the Test Logic Registers */
358 ql_build_coredump_seg_header(&mpi_coredump->test_logic_regs_seg_hdr,
359 TEST_LOGIC_SEG_NUM,
360 sizeof(struct mpi_coredump_segment_header)
361 + sizeof(mpi_coredump->test_logic_regs),
362 "Test Logic Regs");
363 status = ql_get_mpi_regs(qdev, &mpi_coredump->test_logic_regs[0],
364 TEST_REGS_ADDR, TEST_REGS_CNT);
365 if (status)
366 goto err;
367
368 /* Get the RMII Registers */
369 ql_build_coredump_seg_header(&mpi_coredump->rmii_regs_seg_hdr,
370 RMII_SEG_NUM,
371 sizeof(struct mpi_coredump_segment_header)
372 + sizeof(mpi_coredump->rmii_regs),
373 "RMII Registers");
374 status = ql_get_mpi_regs(qdev, &mpi_coredump->rmii_regs[0],
375 RMII_REGS_ADDR, RMII_REGS_CNT);
376 if (status)
377 goto err;
378
379 /* Get the FCMAC1 Registers */
380 ql_build_coredump_seg_header(&mpi_coredump->fcmac1_regs_seg_hdr,
381 FCMAC1_SEG_NUM,
382 sizeof(struct mpi_coredump_segment_header)
383 + sizeof(mpi_coredump->fcmac1_regs),
384 "FCMAC1 Registers");
385 status = ql_get_mpi_regs(qdev, &mpi_coredump->fcmac1_regs[0],
386 FCMAC1_REGS_ADDR, FCMAC_REGS_CNT);
387 if (status)
388 goto err;
389
390 /* Get the FCMAC2 Registers */
391
392 ql_build_coredump_seg_header(&mpi_coredump->fcmac2_regs_seg_hdr,
393 FCMAC2_SEG_NUM,
394 sizeof(struct mpi_coredump_segment_header)
395 + sizeof(mpi_coredump->fcmac2_regs),
396 "FCMAC2 Registers");
397
398 status = ql_get_mpi_regs(qdev, &mpi_coredump->fcmac2_regs[0],
399 FCMAC2_REGS_ADDR, FCMAC_REGS_CNT);
400 if (status)
401 goto err;
402
403 /* Get the FC1 MBX Registers */
404 ql_build_coredump_seg_header(&mpi_coredump->fc1_mbx_regs_seg_hdr,
405 FC1_MBOX_SEG_NUM,
406 sizeof(struct mpi_coredump_segment_header)
407 + sizeof(mpi_coredump->fc1_mbx_regs),
408 "FC1 MBox Regs");
409 status = ql_get_mpi_regs(qdev, &mpi_coredump->fc1_mbx_regs[0],
410 FC1_MBX_REGS_ADDR, FC_MBX_REGS_CNT);
411 if (status)
412 goto err;
413
414 /* Get the IDE Registers */
415 ql_build_coredump_seg_header(&mpi_coredump->ide_regs_seg_hdr,
416 IDE_SEG_NUM,
417 sizeof(struct mpi_coredump_segment_header)
418 + sizeof(mpi_coredump->ide_regs),
419 "IDE Registers");
420 status = ql_get_mpi_regs(qdev, &mpi_coredump->ide_regs[0],
421 IDE_REGS_ADDR, IDE_REGS_CNT);
422 if (status)
423 goto err;
424
425 /* Get the NIC1 MBX Registers */
426 ql_build_coredump_seg_header(&mpi_coredump->nic1_mbx_regs_seg_hdr,
427 NIC1_MBOX_SEG_NUM,
428 sizeof(struct mpi_coredump_segment_header)
429 + sizeof(mpi_coredump->nic1_mbx_regs),
430 "NIC1 MBox Regs");
431 status = ql_get_mpi_regs(qdev, &mpi_coredump->nic1_mbx_regs[0],
432 NIC1_MBX_REGS_ADDR, NIC_MBX_REGS_CNT);
433 if (status)
434 goto err;
435
436 /* Get the SMBus Registers */
437 ql_build_coredump_seg_header(&mpi_coredump->smbus_regs_seg_hdr,
438 SMBUS_SEG_NUM,
439 sizeof(struct mpi_coredump_segment_header)
440 + sizeof(mpi_coredump->smbus_regs),
441 "SMBus Registers");
442 status = ql_get_mpi_regs(qdev, &mpi_coredump->smbus_regs[0],
443 SMBUS_REGS_ADDR, SMBUS_REGS_CNT);
444 if (status)
445 goto err;
446
447 /* Get the FC2 MBX Registers */
448 ql_build_coredump_seg_header(&mpi_coredump->fc2_mbx_regs_seg_hdr,
449 FC2_MBOX_SEG_NUM,
450 sizeof(struct mpi_coredump_segment_header)
451 + sizeof(mpi_coredump->fc2_mbx_regs),
452 "FC2 MBox Regs");
453 status = ql_get_mpi_regs(qdev, &mpi_coredump->fc2_mbx_regs[0],
454 FC2_MBX_REGS_ADDR, FC_MBX_REGS_CNT);
455 if (status)
456 goto err;
457
458 /* Get the NIC2 MBX Registers */
459 ql_build_coredump_seg_header(&mpi_coredump->nic2_mbx_regs_seg_hdr,
460 NIC2_MBOX_SEG_NUM,
461 sizeof(struct mpi_coredump_segment_header)
462 + sizeof(mpi_coredump->nic2_mbx_regs),
463 "NIC2 MBox Regs");
464 status = ql_get_mpi_regs(qdev, &mpi_coredump->nic2_mbx_regs[0],
465 NIC2_MBX_REGS_ADDR, NIC_MBX_REGS_CNT);
466 if (status)
467 goto err;
468
469 /* Get the I2C Registers */
470 ql_build_coredump_seg_header(&mpi_coredump->i2c_regs_seg_hdr,
471 I2C_SEG_NUM,
472 sizeof(struct mpi_coredump_segment_header)
473 + sizeof(mpi_coredump->i2c_regs),
474 "I2C Registers");
475 status = ql_get_mpi_regs(qdev, &mpi_coredump->i2c_regs[0],
476 I2C_REGS_ADDR, I2C_REGS_CNT);
477 if (status)
478 goto err;
479
480 /* Get the MEMC Registers */
481 ql_build_coredump_seg_header(&mpi_coredump->memc_regs_seg_hdr,
482 MEMC_SEG_NUM,
483 sizeof(struct mpi_coredump_segment_header)
484 + sizeof(mpi_coredump->memc_regs),
485 "MEMC Registers");
486 status = ql_get_mpi_regs(qdev, &mpi_coredump->memc_regs[0],
487 MEMC_REGS_ADDR, MEMC_REGS_CNT);
488 if (status)
489 goto err;
490
491 /* Get the PBus Registers */
492 ql_build_coredump_seg_header(&mpi_coredump->pbus_regs_seg_hdr,
493 PBUS_SEG_NUM,
494 sizeof(struct mpi_coredump_segment_header)
495 + sizeof(mpi_coredump->pbus_regs),
496 "PBUS Registers");
497 status = ql_get_mpi_regs(qdev, &mpi_coredump->pbus_regs[0],
498 PBUS_REGS_ADDR, PBUS_REGS_CNT);
499 if (status)
500 goto err;
501
502 /* Get the MDE Registers */
503 ql_build_coredump_seg_header(&mpi_coredump->mde_regs_seg_hdr,
504 MDE_SEG_NUM,
505 sizeof(struct mpi_coredump_segment_header)
506 + sizeof(mpi_coredump->mde_regs),
507 "MDE Registers");
508 status = ql_get_mpi_regs(qdev, &mpi_coredump->mde_regs[0],
509 MDE_REGS_ADDR, MDE_REGS_CNT);
510 if (status)
511 goto err;
512
513 ql_build_coredump_seg_header(&mpi_coredump->misc_nic_seg_hdr,
514 MISC_NIC_INFO_SEG_NUM,
515 sizeof(struct mpi_coredump_segment_header)
516 + sizeof(mpi_coredump->misc_nic_info),
517 "MISC NIC INFO");
518 mpi_coredump->misc_nic_info.rx_ring_count = qdev->rx_ring_count;
519 mpi_coredump->misc_nic_info.tx_ring_count = qdev->tx_ring_count;
520 mpi_coredump->misc_nic_info.intr_count = qdev->intr_count;
521 mpi_coredump->misc_nic_info.function = qdev->func;
522
523 /* Segment 31 */
524 /* Get indexed register values. */
525 ql_build_coredump_seg_header(&mpi_coredump->intr_states_seg_hdr,
526 INTR_STATES_SEG_NUM,
527 sizeof(struct mpi_coredump_segment_header)
528 + sizeof(mpi_coredump->intr_states),
529 "INTR States");
530 ql_get_intr_states(qdev, &mpi_coredump->intr_states[0]);
531
532 ql_build_coredump_seg_header(&mpi_coredump->cam_entries_seg_hdr,
533 CAM_ENTRIES_SEG_NUM,
534 sizeof(struct mpi_coredump_segment_header)
535 + sizeof(mpi_coredump->cam_entries),
536 "CAM Entries");
537 status = ql_get_cam_entries(qdev, &mpi_coredump->cam_entries[0]);
538 if (status)
539 goto err;
540
541 ql_build_coredump_seg_header(&mpi_coredump->nic_routing_words_seg_hdr,
542 ROUTING_WORDS_SEG_NUM,
543 sizeof(struct mpi_coredump_segment_header)
544 + sizeof(mpi_coredump->nic_routing_words),
545 "Routing Words");
546 status = ql_get_routing_entries(qdev,
547 &mpi_coredump->nic_routing_words[0]);
548 if (status)
549 goto err;
550
551 /* Segment 34 (Rev C. step 23) */
552 ql_build_coredump_seg_header(&mpi_coredump->ets_seg_hdr,
553 ETS_SEG_NUM,
554 sizeof(struct mpi_coredump_segment_header)
555 + sizeof(mpi_coredump->ets),
556 "ETS Registers");
557 status = ql_get_ets_regs(qdev, &mpi_coredump->ets[0]);
558 if (status)
559 goto err;
560
561 ql_build_coredump_seg_header(&mpi_coredump->routing_reg_seg_hdr,
562 ROUTING_INDEX_SEG_NUM,
563 sizeof(struct mpi_coredump_segment_header)
564 + sizeof(mpi_coredump->routing_regs),
565 "Routing Regs");
566 status = ql_get_routing_index_registers(qdev,
567 &mpi_coredump->routing_regs[0]);
568 if (status)
569 goto err;
570
571 ql_build_coredump_seg_header(&mpi_coredump->mac_prot_reg_seg_hdr,
572 MAC_PROTOCOL_SEG_NUM,
573 sizeof(struct mpi_coredump_segment_header)
574 + sizeof(mpi_coredump->mac_prot_regs),
575 "MAC Prot Regs");
576 ql_get_mac_protocol_registers(qdev, &mpi_coredump->mac_prot_regs[0]);
577
578 /* Get the semaphore registers for all 5 functions */
579 ql_build_coredump_seg_header(&mpi_coredump->sem_regs_seg_hdr,
580 SEM_REGS_SEG_NUM,
581 sizeof(struct mpi_coredump_segment_header) +
582 sizeof(mpi_coredump->sem_regs), "Sem Registers");
583
584 ql_get_sem_registers(qdev, &mpi_coredump->sem_regs[0]);
585
586 /* Prevent the mpi restarting while we dump the memory.*/
587 ql_write_mpi_reg(qdev, MPI_TEST_FUNC_RST_STS, MPI_TEST_FUNC_RST_FRC);
588
589 /* clear the pause */
590 status = ql_unpause_mpi_risc(qdev);
591 if (status) {
592 QPRINTK(qdev, DRV, ERR,
593 "Failed RISC unpause. Status = 0x%.08x\n", status);
594 goto err;
595 }
596err:
597 ql_sem_unlock(qdev, SEM_PROC_REG_MASK); /* does flush too */
598 return status;
599
600}
601
106void ql_gen_reg_dump(struct ql_adapter *qdev, 602void ql_gen_reg_dump(struct ql_adapter *qdev,
107 struct ql_reg_dump *mpi_coredump) 603 struct ql_reg_dump *mpi_coredump)
108{ 604{
@@ -180,6 +676,33 @@ void ql_gen_reg_dump(struct ql_adapter *qdev,
180 return; 676 return;
181} 677}
182 678
679/* Coredump to messages log file using separate worker thread */
680void ql_mpi_core_to_log(struct work_struct *work)
681{
682 struct ql_adapter *qdev =
683 container_of(work, struct ql_adapter, mpi_core_to_log.work);
684 u32 *tmp, count;
685 int i;
686
687 count = sizeof(struct ql_mpi_coredump) / sizeof(u32);
688 tmp = (u32 *)qdev->mpi_coredump;
689 QPRINTK(qdev, DRV, DEBUG, "Core is dumping to log file!\n");
690
691 for (i = 0; i < count; i += 8) {
692 printk(KERN_ERR "%.08x: %.08x %.08x %.08x %.08x %.08x "
693 "%.08x %.08x %.08x \n", i,
694 tmp[i + 0],
695 tmp[i + 1],
696 tmp[i + 2],
697 tmp[i + 3],
698 tmp[i + 4],
699 tmp[i + 5],
700 tmp[i + 6],
701 tmp[i + 7]);
702 msleep(5);
703 }
704}
705
183#ifdef QL_REG_DUMP 706#ifdef QL_REG_DUMP
184static void ql_dump_intr_states(struct ql_adapter *qdev) 707static void ql_dump_intr_states(struct ql_adapter *qdev)
185{ 708{
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 167a3dab2f18..e58892304e19 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -73,6 +73,13 @@ static int qlge_irq_type = MSIX_IRQ;
73module_param(qlge_irq_type, int, MSIX_IRQ); 73module_param(qlge_irq_type, int, MSIX_IRQ);
74MODULE_PARM_DESC(qlge_irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy."); 74MODULE_PARM_DESC(qlge_irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy.");
75 75
76static int qlge_mpi_coredump;
77module_param(qlge_mpi_coredump, int, 0);
78MODULE_PARM_DESC(qlge_mpi_coredump,
79 "Option to enable MPI firmware dump. "
80 "Default is OFF - Do Not allocate memory. "
81 "Do not perform firmware coredump.");
82
76static DEFINE_PCI_DEVICE_TABLE(qlge_pci_tbl) = { 83static DEFINE_PCI_DEVICE_TABLE(qlge_pci_tbl) = {
77 {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID_8012)}, 84 {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID_8012)},
78 {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID_8000)}, 85 {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID_8000)},
@@ -3842,6 +3849,7 @@ static int ql_adapter_down(struct ql_adapter *qdev)
3842 cancel_delayed_work_sync(&qdev->mpi_reset_work); 3849 cancel_delayed_work_sync(&qdev->mpi_reset_work);
3843 cancel_delayed_work_sync(&qdev->mpi_work); 3850 cancel_delayed_work_sync(&qdev->mpi_work);
3844 cancel_delayed_work_sync(&qdev->mpi_idc_work); 3851 cancel_delayed_work_sync(&qdev->mpi_idc_work);
3852 cancel_delayed_work_sync(&qdev->mpi_core_to_log);
3845 cancel_delayed_work_sync(&qdev->mpi_port_cfg_work); 3853 cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
3846 3854
3847 for (i = 0; i < qdev->rss_ring_count; i++) 3855 for (i = 0; i < qdev->rss_ring_count; i++)
@@ -4398,6 +4406,7 @@ static void ql_release_all(struct pci_dev *pdev)
4398 iounmap(qdev->reg_base); 4406 iounmap(qdev->reg_base);
4399 if (qdev->doorbell_area) 4407 if (qdev->doorbell_area)
4400 iounmap(qdev->doorbell_area); 4408 iounmap(qdev->doorbell_area);
4409 vfree(qdev->mpi_coredump);
4401 pci_release_regions(pdev); 4410 pci_release_regions(pdev);
4402 pci_set_drvdata(pdev, NULL); 4411 pci_set_drvdata(pdev, NULL);
4403} 4412}
@@ -4479,6 +4488,15 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
4479 spin_lock_init(&qdev->hw_lock); 4488 spin_lock_init(&qdev->hw_lock);
4480 spin_lock_init(&qdev->stats_lock); 4489 spin_lock_init(&qdev->stats_lock);
4481 4490
4491 if (qlge_mpi_coredump) {
4492 qdev->mpi_coredump =
4493 vmalloc(sizeof(struct ql_mpi_coredump));
4494 if (qdev->mpi_coredump == NULL) {
4495 dev_err(&pdev->dev, "Coredump alloc failed.\n");
4496 err = -ENOMEM;
4497 goto err_out;
4498 }
4499 }
4482 /* make sure the EEPROM is good */ 4500 /* make sure the EEPROM is good */
4483 err = qdev->nic_ops->get_flash(qdev); 4501 err = qdev->nic_ops->get_flash(qdev);
4484 if (err) { 4502 if (err) {
@@ -4508,6 +4526,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
4508 INIT_DELAYED_WORK(&qdev->mpi_work, ql_mpi_work); 4526 INIT_DELAYED_WORK(&qdev->mpi_work, ql_mpi_work);
4509 INIT_DELAYED_WORK(&qdev->mpi_port_cfg_work, ql_mpi_port_cfg_work); 4527 INIT_DELAYED_WORK(&qdev->mpi_port_cfg_work, ql_mpi_port_cfg_work);
4510 INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work); 4528 INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work);
4529 INIT_DELAYED_WORK(&qdev->mpi_core_to_log, ql_mpi_core_to_log);
4511 init_completion(&qdev->ide_completion); 4530 init_completion(&qdev->ide_completion);
4512 4531
4513 if (!cards_found) { 4532 if (!cards_found) {
@@ -4630,6 +4649,7 @@ static void ql_eeh_close(struct net_device *ndev)
4630 cancel_delayed_work_sync(&qdev->mpi_reset_work); 4649 cancel_delayed_work_sync(&qdev->mpi_reset_work);
4631 cancel_delayed_work_sync(&qdev->mpi_work); 4650 cancel_delayed_work_sync(&qdev->mpi_work);
4632 cancel_delayed_work_sync(&qdev->mpi_idc_work); 4651 cancel_delayed_work_sync(&qdev->mpi_idc_work);
4652 cancel_delayed_work_sync(&qdev->mpi_core_to_log);
4633 cancel_delayed_work_sync(&qdev->mpi_port_cfg_work); 4653 cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
4634 4654
4635 for (i = 0; i < qdev->rss_ring_count; i++) 4655 for (i = 0; i < qdev->rss_ring_count; i++)
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index e2b2286102d4..242b1ea955e4 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -1,5 +1,35 @@
1#include "qlge.h" 1#include "qlge.h"
2 2
3int ql_unpause_mpi_risc(struct ql_adapter *qdev)
4{
5 u32 tmp;
6
7 /* Un-pause the RISC */
8 tmp = ql_read32(qdev, CSR);
9 if (!(tmp & CSR_RP))
10 return -EIO;
11
12 ql_write32(qdev, CSR, CSR_CMD_CLR_PAUSE);
13 return 0;
14}
15
16int ql_pause_mpi_risc(struct ql_adapter *qdev)
17{
18 u32 tmp;
19 int count = UDELAY_COUNT;
20
21 /* Pause the RISC */
22 ql_write32(qdev, CSR, CSR_CMD_SET_PAUSE);
23 do {
24 tmp = ql_read32(qdev, CSR);
25 if (tmp & CSR_RP)
26 break;
27 mdelay(UDELAY_DELAY);
28 count--;
29 } while (count);
30 return (count == 0) ? -ETIMEDOUT : 0;
31}
32
3int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data) 33int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
4{ 34{
5 int status; 35 int status;
@@ -45,6 +75,35 @@ int ql_soft_reset_mpi_risc(struct ql_adapter *qdev)
45 return status; 75 return status;
46} 76}
47 77
78/* Determine if we are in charge of the firwmare. If
79 * we are the lower of the 2 NIC pcie functions, or if
80 * we are the higher function and the lower function
81 * is not enabled.
82 */
83int ql_own_firmware(struct ql_adapter *qdev)
84{
85 u32 temp;
86
87 /* If we are the lower of the 2 NIC functions
88 * on the chip the we are responsible for
89 * core dump and firmware reset after an error.
90 */
91 if (qdev->func < qdev->alt_func)
92 return 1;
93
94 /* If we are the higher of the 2 NIC functions
95 * on the chip and the lower function is not
96 * enabled, then we are responsible for
97 * core dump and firmware reset after an error.
98 */
99 temp = ql_read32(qdev, STS);
100 if (!(temp & (1 << (8 + qdev->alt_func))))
101 return 1;
102
103 return 0;
104
105}
106
48static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp) 107static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
49{ 108{
50 int i, status; 109 int i, status;
@@ -1143,5 +1202,19 @@ void ql_mpi_reset_work(struct work_struct *work)
1143 cancel_delayed_work_sync(&qdev->mpi_work); 1202 cancel_delayed_work_sync(&qdev->mpi_work);
1144 cancel_delayed_work_sync(&qdev->mpi_port_cfg_work); 1203 cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
1145 cancel_delayed_work_sync(&qdev->mpi_idc_work); 1204 cancel_delayed_work_sync(&qdev->mpi_idc_work);
1205 /* If we're not the dominant NIC function,
1206 * then there is nothing to do.
1207 */
1208 if (!ql_own_firmware(qdev)) {
1209 QPRINTK(qdev, DRV, ERR, "Don't own firmware!\n");
1210 return;
1211 }
1212
1213 if (!ql_core_dump(qdev, qdev->mpi_coredump)) {
1214 QPRINTK(qdev, DRV, ERR, "Core is dumped!\n");
1215 qdev->core_is_dumped = 1;
1216 queue_delayed_work(qdev->workqueue,
1217 &qdev->mpi_core_to_log, 5 * HZ);
1218 }
1146 ql_soft_reset_mpi_risc(qdev); 1219 ql_soft_reset_mpi_risc(qdev);
1147} 1220}