diff options
author | Santosh Vernekar <santosh.vernekar@qlogic.com> | 2012-08-22 14:21:03 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-09-24 04:10:47 -0400 |
commit | 7d613ac6acec8c29e7aa3f80e28e8e982977a151 (patch) | |
tree | eec782c42537c4658850ffb8982973f122e388a2 /drivers/scsi/qla2xxx/qla_isr.c | |
parent | 40129a4c6edc1753b9a537877b6a2eac9fc6c659 (diff) |
[SCSI] qla2xxx: IDC implementation for ISP83xx.
Signed-off-by: Santosh Vernekar <santosh.vernekar@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_isr.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 176 |
1 files changed, 173 insertions, 3 deletions
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 31ef8e25a61..1222e937a5f 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -332,6 +332,166 @@ qla2x00_get_link_speed_str(struct qla_hw_data *ha) | |||
332 | return link_speed; | 332 | return link_speed; |
333 | } | 333 | } |
334 | 334 | ||
335 | void | ||
336 | qla83xx_handle_8200_aen(scsi_qla_host_t *vha, uint16_t *mb) | ||
337 | { | ||
338 | struct qla_hw_data *ha = vha->hw; | ||
339 | |||
340 | /* | ||
341 | * 8200 AEN Interpretation: | ||
342 | * mb[0] = AEN code | ||
343 | * mb[1] = AEN Reason code | ||
344 | * mb[2] = LSW of Peg-Halt Status-1 Register | ||
345 | * mb[6] = MSW of Peg-Halt Status-1 Register | ||
346 | * mb[3] = LSW of Peg-Halt Status-2 register | ||
347 | * mb[7] = MSW of Peg-Halt Status-2 register | ||
348 | * mb[4] = IDC Device-State Register value | ||
349 | * mb[5] = IDC Driver-Presence Register value | ||
350 | */ | ||
351 | ql_dbg(ql_dbg_async, vha, 0x506b, "AEN Code: mb[0] = 0x%x AEN reason: " | ||
352 | "mb[1] = 0x%x PH-status1: mb[2] = 0x%x PH-status1: mb[6] = 0x%x.\n", | ||
353 | mb[0], mb[1], mb[2], mb[6]); | ||
354 | ql_dbg(ql_dbg_async, vha, 0x506c, "PH-status2: mb[3] = 0x%x " | ||
355 | "PH-status2: mb[7] = 0x%x Device-State: mb[4] = 0x%x " | ||
356 | "Drv-Presence: mb[5] = 0x%x.\n", mb[3], mb[7], mb[4], mb[5]); | ||
357 | |||
358 | if (mb[1] & (IDC_PEG_HALT_STATUS_CHANGE | IDC_NIC_FW_REPORTED_FAILURE | | ||
359 | IDC_HEARTBEAT_FAILURE)) { | ||
360 | ha->flags.nic_core_hung = 1; | ||
361 | ql_log(ql_log_warn, vha, 0x5060, | ||
362 | "83XX: F/W Error Reported: Check if reset required.\n"); | ||
363 | |||
364 | if (mb[1] & IDC_PEG_HALT_STATUS_CHANGE) { | ||
365 | uint32_t protocol_engine_id, fw_err_code, err_level; | ||
366 | |||
367 | /* | ||
368 | * IDC_PEG_HALT_STATUS_CHANGE interpretation: | ||
369 | * - PEG-Halt Status-1 Register: | ||
370 | * (LSW = mb[2], MSW = mb[6]) | ||
371 | * Bits 0-7 = protocol-engine ID | ||
372 | * Bits 8-28 = f/w error code | ||
373 | * Bits 29-31 = Error-level | ||
374 | * Error-level 0x1 = Non-Fatal error | ||
375 | * Error-level 0x2 = Recoverable Fatal error | ||
376 | * Error-level 0x4 = UnRecoverable Fatal error | ||
377 | * - PEG-Halt Status-2 Register: | ||
378 | * (LSW = mb[3], MSW = mb[7]) | ||
379 | */ | ||
380 | protocol_engine_id = (mb[2] & 0xff); | ||
381 | fw_err_code = (((mb[2] & 0xff00) >> 8) | | ||
382 | ((mb[6] & 0x1fff) << 8)); | ||
383 | err_level = ((mb[6] & 0xe000) >> 13); | ||
384 | ql_log(ql_log_warn, vha, 0x5061, "PegHalt Status-1 " | ||
385 | "Register: protocol_engine_id=0x%x " | ||
386 | "fw_err_code=0x%x err_level=0x%x.\n", | ||
387 | protocol_engine_id, fw_err_code, err_level); | ||
388 | ql_log(ql_log_warn, vha, 0x5062, "PegHalt Status-2 " | ||
389 | "Register: 0x%x%x.\n", mb[7], mb[3]); | ||
390 | if (err_level == ERR_LEVEL_NON_FATAL) { | ||
391 | ql_log(ql_log_warn, vha, 0x5063, | ||
392 | "Not a fatal error, f/w has recovered " | ||
393 | "iteself.\n"); | ||
394 | } else if (err_level == ERR_LEVEL_RECOVERABLE_FATAL) { | ||
395 | ql_log(ql_log_fatal, vha, 0x5064, | ||
396 | "Recoverable Fatal error: Chip reset " | ||
397 | "required.\n"); | ||
398 | qla83xx_schedule_work(vha, | ||
399 | QLA83XX_NIC_CORE_RESET); | ||
400 | } else if (err_level == ERR_LEVEL_UNRECOVERABLE_FATAL) { | ||
401 | ql_log(ql_log_fatal, vha, 0x5065, | ||
402 | "Unrecoverable Fatal error: Set FAILED " | ||
403 | "state, reboot required.\n"); | ||
404 | qla83xx_schedule_work(vha, | ||
405 | QLA83XX_NIC_CORE_UNRECOVERABLE); | ||
406 | } | ||
407 | } | ||
408 | |||
409 | if (mb[1] & IDC_NIC_FW_REPORTED_FAILURE) { | ||
410 | uint16_t peg_fw_state, nw_interface_link_up; | ||
411 | uint16_t nw_interface_signal_detect, sfp_status; | ||
412 | uint16_t htbt_counter, htbt_monitor_enable; | ||
413 | uint16_t sfp_additonal_info, sfp_multirate; | ||
414 | uint16_t sfp_tx_fault, link_speed, dcbx_status; | ||
415 | |||
416 | /* | ||
417 | * IDC_NIC_FW_REPORTED_FAILURE interpretation: | ||
418 | * - PEG-to-FC Status Register: | ||
419 | * (LSW = mb[2], MSW = mb[6]) | ||
420 | * Bits 0-7 = Peg-Firmware state | ||
421 | * Bit 8 = N/W Interface Link-up | ||
422 | * Bit 9 = N/W Interface signal detected | ||
423 | * Bits 10-11 = SFP Status | ||
424 | * SFP Status 0x0 = SFP+ transceiver not expected | ||
425 | * SFP Status 0x1 = SFP+ transceiver not present | ||
426 | * SFP Status 0x2 = SFP+ transceiver invalid | ||
427 | * SFP Status 0x3 = SFP+ transceiver present and | ||
428 | * valid | ||
429 | * Bits 12-14 = Heartbeat Counter | ||
430 | * Bit 15 = Heartbeat Monitor Enable | ||
431 | * Bits 16-17 = SFP Additional Info | ||
432 | * SFP info 0x0 = Unregocnized transceiver for | ||
433 | * Ethernet | ||
434 | * SFP info 0x1 = SFP+ brand validation failed | ||
435 | * SFP info 0x2 = SFP+ speed validation failed | ||
436 | * SFP info 0x3 = SFP+ access error | ||
437 | * Bit 18 = SFP Multirate | ||
438 | * Bit 19 = SFP Tx Fault | ||
439 | * Bits 20-22 = Link Speed | ||
440 | * Bits 23-27 = Reserved | ||
441 | * Bits 28-30 = DCBX Status | ||
442 | * DCBX Status 0x0 = DCBX Disabled | ||
443 | * DCBX Status 0x1 = DCBX Enabled | ||
444 | * DCBX Status 0x2 = DCBX Exchange error | ||
445 | * Bit 31 = Reserved | ||
446 | */ | ||
447 | peg_fw_state = (mb[2] & 0x00ff); | ||
448 | nw_interface_link_up = ((mb[2] & 0x0100) >> 8); | ||
449 | nw_interface_signal_detect = ((mb[2] & 0x0200) >> 9); | ||
450 | sfp_status = ((mb[2] & 0x0c00) >> 10); | ||
451 | htbt_counter = ((mb[2] & 0x7000) >> 12); | ||
452 | htbt_monitor_enable = ((mb[2] & 0x8000) >> 15); | ||
453 | sfp_additonal_info = (mb[6] & 0x0003); | ||
454 | sfp_multirate = ((mb[6] & 0x0004) >> 2); | ||
455 | sfp_tx_fault = ((mb[6] & 0x0008) >> 3); | ||
456 | link_speed = ((mb[6] & 0x0070) >> 4); | ||
457 | dcbx_status = ((mb[6] & 0x7000) >> 12); | ||
458 | |||
459 | ql_log(ql_log_warn, vha, 0x5066, | ||
460 | "Peg-to-Fc Status Register:\n" | ||
461 | "peg_fw_state=0x%x, nw_interface_link_up=0x%x, " | ||
462 | "nw_interface_signal_detect=0x%x" | ||
463 | "\nsfp_statis=0x%x.\n ", peg_fw_state, | ||
464 | nw_interface_link_up, nw_interface_signal_detect, | ||
465 | sfp_status); | ||
466 | ql_log(ql_log_warn, vha, 0x5067, | ||
467 | "htbt_counter=0x%x, htbt_monitor_enable=0x%x, " | ||
468 | "sfp_additonal_info=0x%x, sfp_multirate=0x%x.\n ", | ||
469 | htbt_counter, htbt_monitor_enable, | ||
470 | sfp_additonal_info, sfp_multirate); | ||
471 | ql_log(ql_log_warn, vha, 0x5068, | ||
472 | "sfp_tx_fault=0x%x, link_state=0x%x, " | ||
473 | "dcbx_status=0x%x.\n", sfp_tx_fault, link_speed, | ||
474 | dcbx_status); | ||
475 | |||
476 | qla83xx_schedule_work(vha, QLA83XX_NIC_CORE_RESET); | ||
477 | } | ||
478 | |||
479 | if (mb[1] & IDC_HEARTBEAT_FAILURE) { | ||
480 | ql_log(ql_log_warn, vha, 0x5069, | ||
481 | "Heartbeat Failure encountered, chip reset " | ||
482 | "required.\n"); | ||
483 | |||
484 | qla83xx_schedule_work(vha, QLA83XX_NIC_CORE_RESET); | ||
485 | } | ||
486 | } | ||
487 | |||
488 | if (mb[1] & IDC_DEVICE_STATE_CHANGE) { | ||
489 | ql_log(ql_log_info, vha, 0x506a, | ||
490 | "IDC Device-State changed = 0x%x.\n", mb[4]); | ||
491 | qla83xx_schedule_work(vha, MBA_IDC_AEN); | ||
492 | } | ||
493 | } | ||
494 | |||
335 | /** | 495 | /** |
336 | * qla2x00_async_event() - Process aynchronous events. | 496 | * qla2x00_async_event() - Process aynchronous events. |
337 | * @ha: SCSI driver HA context | 497 | * @ha: SCSI driver HA context |
@@ -825,8 +985,18 @@ skip_rio: | |||
825 | case MBA_IDC_COMPLETE: | 985 | case MBA_IDC_COMPLETE: |
826 | case MBA_IDC_NOTIFY: | 986 | case MBA_IDC_NOTIFY: |
827 | case MBA_IDC_TIME_EXT: | 987 | case MBA_IDC_TIME_EXT: |
828 | qla81xx_idc_event(vha, mb[0], mb[1]); | 988 | if (IS_QLA81XX(vha->hw)) |
989 | qla81xx_idc_event(vha, mb[0], mb[1]); | ||
990 | break; | ||
991 | |||
992 | case MBA_IDC_AEN: | ||
993 | mb[4] = RD_REG_WORD(®24->mailbox4); | ||
994 | mb[5] = RD_REG_WORD(®24->mailbox5); | ||
995 | mb[6] = RD_REG_WORD(®24->mailbox6); | ||
996 | mb[7] = RD_REG_WORD(®24->mailbox7); | ||
997 | qla83xx_handle_8200_aen(vha, mb); | ||
829 | break; | 998 | break; |
999 | |||
830 | default: | 1000 | default: |
831 | ql_dbg(ql_dbg_async, vha, 0x5057, | 1001 | ql_dbg(ql_dbg_async, vha, 0x5057, |
832 | "Unknown AEN:%04x %04x %04x %04x\n", | 1002 | "Unknown AEN:%04x %04x %04x %04x\n", |
@@ -2301,7 +2471,7 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
2301 | unsigned long iter; | 2471 | unsigned long iter; |
2302 | uint32_t stat; | 2472 | uint32_t stat; |
2303 | uint32_t hccr; | 2473 | uint32_t hccr; |
2304 | uint16_t mb[4]; | 2474 | uint16_t mb[8]; |
2305 | struct rsp_que *rsp; | 2475 | struct rsp_que *rsp; |
2306 | unsigned long flags; | 2476 | unsigned long flags; |
2307 | 2477 | ||
@@ -2457,7 +2627,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
2457 | int status; | 2627 | int status; |
2458 | uint32_t stat; | 2628 | uint32_t stat; |
2459 | uint32_t hccr; | 2629 | uint32_t hccr; |
2460 | uint16_t mb[4]; | 2630 | uint16_t mb[8]; |
2461 | unsigned long flags; | 2631 | unsigned long flags; |
2462 | 2632 | ||
2463 | rsp = (struct rsp_que *) dev_id; | 2633 | rsp = (struct rsp_que *) dev_id; |