diff options
author | James Smart <james.smart@emulex.com> | 2010-12-15 17:57:46 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-12-21 13:37:23 -0500 |
commit | 2fcee4bf874a8ae72ada68b62728d1fdeb30e3d4 (patch) | |
tree | 8664c529ffcc3e6967e55116b375ff078a455b8b /drivers/scsi/lpfc | |
parent | 70f3c073362ef7b5e55c92b83eb2dd9a7fb4e9bf (diff) |
[SCSI] lpfc 8.3.20: Implement new SLI4 init procedures based on if_type
Implement new SLI4 init procedures based on if_type:
- Add structure changes for new SLIPORT registers and BAR changes.
- Update register names to be consistent with inteface spec terms.
- Added union to encapsulate Hardward error registers.
- Rework lpfc_sli4_post_status_check() around SLI-4's SLI_INTF type
- Removed the lpfc_sli4_fw_cfg_check routine
- Segmented driver logic to include evaluation of the if_type to
engage different behaviors.
Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw4.h | 108 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 660 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 77 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli4.h | 50 |
4 files changed, 569 insertions, 326 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 3821ecbf5a8f..94c1aa1136de 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h | |||
@@ -460,42 +460,41 @@ struct lpfc_register { | |||
460 | uint32_t word0; | 460 | uint32_t word0; |
461 | }; | 461 | }; |
462 | 462 | ||
463 | /* The SLI4 INTF register offset is common to all if_type values. */ | ||
464 | #define LPFC_SLI_INTF 0x0058 | ||
465 | |||
466 | /* The following BAR0 Registers apply to SLI4 if_type 0 UCNAs. */ | 463 | /* The following BAR0 Registers apply to SLI4 if_type 0 UCNAs. */ |
467 | #define LPFC_UERR_STATUS_HI 0x00A4 | 464 | #define LPFC_UERR_STATUS_HI 0x00A4 |
468 | #define LPFC_UERR_STATUS_LO 0x00A0 | 465 | #define LPFC_UERR_STATUS_LO 0x00A0 |
469 | #define LPFC_UE_MASK_HI 0x00AC | 466 | #define LPFC_UE_MASK_HI 0x00AC |
470 | #define LPFC_UE_MASK_LO 0x00A8 | 467 | #define LPFC_UE_MASK_LO 0x00A8 |
471 | 468 | ||
472 | #define LPFC_HST_STATE 0x00AC | 469 | /* The following BAR0 register sets are defined for if_type 0 and 2 UCNAs. */ |
473 | #define lpfc_hst_state_perr_SHIFT 31 | 470 | #define LPFC_SLI_INTF 0x0058 |
474 | #define lpfc_hst_state_perr_MASK 0x1 | 471 | |
475 | #define lpfc_hst_state_perr_WORD word0 | 472 | #define LPFC_SLIPORT_IF2_SMPHR 0x0400 |
476 | #define lpfc_hst_state_sfi_SHIFT 30 | 473 | #define lpfc_port_smphr_perr_SHIFT 31 |
477 | #define lpfc_hst_state_sfi_MASK 0x1 | 474 | #define lpfc_port_smphr_perr_MASK 0x1 |
478 | #define lpfc_hst_state_sfi_WORD word0 | 475 | #define lpfc_port_smphr_perr_WORD word0 |
479 | #define lpfc_hst_state_nip_SHIFT 29 | 476 | #define lpfc_port_smphr_sfi_SHIFT 30 |
480 | #define lpfc_hst_state_nip_MASK 0x1 | 477 | #define lpfc_port_smphr_sfi_MASK 0x1 |
481 | #define lpfc_hst_state_nip_WORD word0 | 478 | #define lpfc_port_smphr_sfi_WORD word0 |
482 | #define lpfc_hst_state_ipc_SHIFT 28 | 479 | #define lpfc_port_smphr_nip_SHIFT 29 |
483 | #define lpfc_hst_state_ipc_MASK 0x1 | 480 | #define lpfc_port_smphr_nip_MASK 0x1 |
484 | #define lpfc_hst_state_ipc_WORD word0 | 481 | #define lpfc_port_smphr_nip_WORD word0 |
485 | #define lpfc_hst_state_xrom_SHIFT 27 | 482 | #define lpfc_port_smphr_ipc_SHIFT 28 |
486 | #define lpfc_hst_state_xrom_MASK 0x1 | 483 | #define lpfc_port_smphr_ipc_MASK 0x1 |
487 | #define lpfc_hst_state_xrom_WORD word0 | 484 | #define lpfc_port_smphr_ipc_WORD word0 |
488 | #define lpfc_hst_state_dl_SHIFT 26 | 485 | #define lpfc_port_smphr_scr1_SHIFT 27 |
489 | #define lpfc_hst_state_dl_MASK 0x1 | 486 | #define lpfc_port_smphr_scr1_MASK 0x1 |
490 | #define lpfc_hst_state_dl_WORD word0 | 487 | #define lpfc_port_smphr_scr1_WORD word0 |
491 | #define lpfc_hst_state_port_status_SHIFT 0 | 488 | #define lpfc_port_smphr_scr2_SHIFT 26 |
492 | #define lpfc_hst_state_port_status_MASK 0xFFFF | 489 | #define lpfc_port_smphr_scr2_MASK 0x1 |
493 | #define lpfc_hst_state_port_status_WORD word0 | 490 | #define lpfc_port_smphr_scr2_WORD word0 |
491 | #define lpfc_port_smphr_host_scratch_SHIFT 16 | ||
492 | #define lpfc_port_smphr_host_scratch_MASK 0xFF | ||
493 | #define lpfc_port_smphr_host_scratch_WORD word0 | ||
494 | #define lpfc_port_smphr_port_status_SHIFT 0 | ||
495 | #define lpfc_port_smphr_port_status_MASK 0xFFFF | ||
496 | #define lpfc_port_smphr_port_status_WORD word0 | ||
494 | 497 | ||
495 | /* | ||
496 | * The following Port Status Values apply to SLI4, if_type 0 and 2 | ||
497 | * UCNAs. | ||
498 | */ | ||
499 | #define LPFC_POST_STAGE_POWER_ON_RESET 0x0000 | 498 | #define LPFC_POST_STAGE_POWER_ON_RESET 0x0000 |
500 | #define LPFC_POST_STAGE_AWAITING_HOST_RDY 0x0001 | 499 | #define LPFC_POST_STAGE_AWAITING_HOST_RDY 0x0001 |
501 | #define LPFC_POST_STAGE_HOST_RDY 0x0002 | 500 | #define LPFC_POST_STAGE_HOST_RDY 0x0002 |
@@ -527,36 +526,8 @@ struct lpfc_register { | |||
527 | #define LPFC_POST_STAGE_RC_DONE 0x0B07 | 526 | #define LPFC_POST_STAGE_RC_DONE 0x0B07 |
528 | #define LPFC_POST_STAGE_REBOOT_SYSTEM 0x0B08 | 527 | #define LPFC_POST_STAGE_REBOOT_SYSTEM 0x0B08 |
529 | #define LPFC_POST_STAGE_MAC_ADDRESS 0x0C00 | 528 | #define LPFC_POST_STAGE_MAC_ADDRESS 0x0C00 |
530 | #define LPFC_POST_STAGE_ARMFW_READY 0xC000 | 529 | #define LPFC_POST_STAGE_PORT_READY 0xC000 |
531 | #define LPFC_POST_STAGE_ARMFW_UE 0xF000 | 530 | #define LPFC_POST_STAGE_PORT_UE 0xF000 |
532 | |||
533 | |||
534 | /* The following BAR0 register sets are defined for if_type 2 UCNAs. */ | ||
535 | #define LPFC_SLIPORT_SEMAPHORE 0x0400 | ||
536 | #define lpfc_sliport_smphr_perr_SHIFT 31 | ||
537 | #define lpfc_sliport_smphr_perr_MASK 0x1 | ||
538 | #define lpfc_sliport_smphr_perr_WORD word0 | ||
539 | #define lpfc_sliport_smphr_sfi_SHIFT 30 | ||
540 | #define lpfc_sliport_smphr_sfi_MASK 0x1 | ||
541 | #define lpfc_sliport_smphr_sfi_WORD word0 | ||
542 | #define lpfc_sliport_smphr_nip_SHIFT 29 | ||
543 | #define lpfc_sliport_smphr_nip_MASK 0x1 | ||
544 | #define lpfc_sliport_smphr_nip_WORD word0 | ||
545 | #define lpfc_sliport_smphr_ipc_SHIFT 28 | ||
546 | #define lpfc_sliport_smphr_ipc_MASK 0x1 | ||
547 | #define lpfc_sliport_smphr_ipc_WORD word0 | ||
548 | #define lpfc_sliport_smphr_scr1_SHIFT 27 | ||
549 | #define lpfc_sliport_smphr_scr1_MASK 0x1 | ||
550 | #define lpfc_sliport_smphr_scr1_WORD word0 | ||
551 | #define lpfc_sliport_smphr_scr2_SHIFT 26 | ||
552 | #define lpfc_sliport_smphr_scr2_MASK 0x1 | ||
553 | #define lpfc_sliport_smphr_scr2_WORD word0 | ||
554 | #define lpfc_sliport_smphr_host_scratch_SHIFT 16 | ||
555 | #define lpfc_sliport_smphr_host_scratch_MASK 0xFF | ||
556 | #define lpfc_sliport_smphr_host_scratch_WORD word0 | ||
557 | #define lpfc_sliport_smphr_port_status_SHIFT 0 | ||
558 | #define lpfc_sliport_smphr_port_status_MASK 0xFFFF | ||
559 | #define lpfc_sliport_smphr_port_status_WORD word0 | ||
560 | 531 | ||
561 | #define LPFC_SLIPORT_STATUS 0x0404 | 532 | #define LPFC_SLIPORT_STATUS 0x0404 |
562 | #define lpfc_sliport_status_err_SHIFT 31 | 533 | #define lpfc_sliport_status_err_SHIFT 31 |
@@ -574,8 +545,9 @@ struct lpfc_register { | |||
574 | #define lpfc_sliport_status_rdy_SHIFT 23 | 545 | #define lpfc_sliport_status_rdy_SHIFT 23 |
575 | #define lpfc_sliport_status_rdy_MASK 0x1 | 546 | #define lpfc_sliport_status_rdy_MASK 0x1 |
576 | #define lpfc_sliport_status_rdy_WORD word0 | 547 | #define lpfc_sliport_status_rdy_WORD word0 |
548 | #define MAX_IF_TYPE_2_RESETS 1000 | ||
577 | 549 | ||
578 | #define LPFC_SLIPORT_CONTROL 0x0408 | 550 | #define LPFC_SLIPORT_CNTRL 0x0408 |
579 | #define lpfc_sliport_ctrl_end_SHIFT 30 | 551 | #define lpfc_sliport_ctrl_end_SHIFT 30 |
580 | #define lpfc_sliport_ctrl_end_MASK 0x1 | 552 | #define lpfc_sliport_ctrl_end_MASK 0x1 |
581 | #define lpfc_sliport_ctrl_end_WORD word0 | 553 | #define lpfc_sliport_ctrl_end_WORD word0 |
@@ -584,11 +556,16 @@ struct lpfc_register { | |||
584 | #define lpfc_sliport_ctrl_ip_SHIFT 27 | 556 | #define lpfc_sliport_ctrl_ip_SHIFT 27 |
585 | #define lpfc_sliport_ctrl_ip_MASK 0x1 | 557 | #define lpfc_sliport_ctrl_ip_MASK 0x1 |
586 | #define lpfc_sliport_ctrl_ip_WORD word0 | 558 | #define lpfc_sliport_ctrl_ip_WORD word0 |
559 | #define LPFC_SLIPORT_INIT_PORT 1 | ||
587 | 560 | ||
588 | #define LPFC_SLIPORT_ERROR_1 0x040C | 561 | #define LPFC_SLIPORT_ERR_1 0x040C |
589 | #define LPFC_SLIPORT_ERROR_2 0x0410 | 562 | #define LPFC_SLIPORT_ERR_2 0x0410 |
563 | |||
564 | /* The following Registers apply to SLI4 if_type 0 UCNAs. They typically | ||
565 | * reside in BAR 2. | ||
566 | */ | ||
567 | #define LPFC_SLIPORT_IF0_SMPHR 0x00AC | ||
590 | 568 | ||
591 | /* BAR1 Registers */ | ||
592 | #define LPFC_IMR_MASK_ALL 0xFFFFFFFF | 569 | #define LPFC_IMR_MASK_ALL 0xFFFFFFFF |
593 | #define LPFC_ISCR_CLEAR_ALL 0xFFFFFFFF | 570 | #define LPFC_ISCR_CLEAR_ALL 0xFFFFFFFF |
594 | 571 | ||
@@ -647,7 +624,7 @@ struct lpfc_register { | |||
647 | * The Doorbell registers defined here exist in different BAR | 624 | * The Doorbell registers defined here exist in different BAR |
648 | * register sets depending on the UCNA Port's reported if_type | 625 | * register sets depending on the UCNA Port's reported if_type |
649 | * value. For UCNA ports running SLI4 and if_type 0, they reside in | 626 | * value. For UCNA ports running SLI4 and if_type 0, they reside in |
650 | * BAR2. For UCNA ports running SLI4 and if_type 2, they reside in | 627 | * BAR4. For UCNA ports running SLI4 and if_type 2, they reside in |
651 | * BAR0. The offsets are the same so the driver must account for | 628 | * BAR0. The offsets are the same so the driver must account for |
652 | * any base address difference. | 629 | * any base address difference. |
653 | */ | 630 | */ |
@@ -2378,7 +2355,7 @@ struct wqe_common { | |||
2378 | #define wqe_rcvoxid_WORD word9 | 2355 | #define wqe_rcvoxid_WORD word9 |
2379 | uint32_t word10; | 2356 | uint32_t word10; |
2380 | #define wqe_ebde_cnt_SHIFT 0 | 2357 | #define wqe_ebde_cnt_SHIFT 0 |
2381 | #define wqe_ebde_cnt_MASK 0x00000007 | 2358 | #define wqe_ebde_cnt_MASK 0x0000000f |
2382 | #define wqe_ebde_cnt_WORD word10 | 2359 | #define wqe_ebde_cnt_WORD word10 |
2383 | #define wqe_lenloc_SHIFT 7 | 2360 | #define wqe_lenloc_SHIFT 7 |
2384 | #define wqe_lenloc_MASK 0x00000003 | 2361 | #define wqe_lenloc_MASK 0x00000003 |
@@ -2570,7 +2547,6 @@ struct xmit_seq64_wqe { | |||
2570 | uint32_t relative_offset; | 2547 | uint32_t relative_offset; |
2571 | struct wqe_rctl_dfctl wge_ctl; | 2548 | struct wqe_rctl_dfctl wge_ctl; |
2572 | struct wqe_common wqe_com; /* words 6-11 */ | 2549 | struct wqe_common wqe_com; /* words 6-11 */ |
2573 | /* Note: word10 different REVISIT */ | ||
2574 | uint32_t xmit_len; | 2550 | uint32_t xmit_len; |
2575 | uint32_t rsvd_12_15[3]; | 2551 | uint32_t rsvd_12_15[3]; |
2576 | }; | 2552 | }; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 311671d3216f..462242dcdd0a 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -1406,6 +1406,8 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba) | |||
1406 | struct lpfc_vport *vport = phba->pport; | 1406 | struct lpfc_vport *vport = phba->pport; |
1407 | uint32_t event_data; | 1407 | uint32_t event_data; |
1408 | struct Scsi_Host *shost; | 1408 | struct Scsi_Host *shost; |
1409 | uint32_t if_type; | ||
1410 | struct lpfc_register portstat_reg; | ||
1409 | 1411 | ||
1410 | /* If the pci channel is offline, ignore possible errors, since | 1412 | /* If the pci channel is offline, ignore possible errors, since |
1411 | * we cannot communicate with the pci card anyway. | 1413 | * we cannot communicate with the pci card anyway. |
@@ -1422,17 +1424,49 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba) | |||
1422 | /* For now, the actual action for SLI4 device handling is not | 1424 | /* For now, the actual action for SLI4 device handling is not |
1423 | * specified yet, just treated it as adaptor hardware failure | 1425 | * specified yet, just treated it as adaptor hardware failure |
1424 | */ | 1426 | */ |
1425 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
1426 | "0143 SLI4 Adapter Hardware Error Data: x%x x%x\n", | ||
1427 | phba->work_status[0], phba->work_status[1]); | ||
1428 | |||
1429 | event_data = FC_REG_DUMP_EVENT; | 1427 | event_data = FC_REG_DUMP_EVENT; |
1430 | shost = lpfc_shost_from_vport(vport); | 1428 | shost = lpfc_shost_from_vport(vport); |
1431 | fc_host_post_vendor_event(shost, fc_get_event_number(), | 1429 | fc_host_post_vendor_event(shost, fc_get_event_number(), |
1432 | sizeof(event_data), (char *) &event_data, | 1430 | sizeof(event_data), (char *) &event_data, |
1433 | SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); | 1431 | SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); |
1434 | 1432 | ||
1435 | lpfc_sli4_offline_eratt(phba); | 1433 | if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf); |
1434 | switch (if_type) { | ||
1435 | case LPFC_SLI_INTF_IF_TYPE_0: | ||
1436 | lpfc_sli4_offline_eratt(phba); | ||
1437 | break; | ||
1438 | case LPFC_SLI_INTF_IF_TYPE_2: | ||
1439 | portstat_reg.word0 = | ||
1440 | readl(phba->sli4_hba.u.if_type2.STATUSregaddr); | ||
1441 | |||
1442 | if (bf_get(lpfc_sliport_status_oti, &portstat_reg)) { | ||
1443 | /* TODO: Register for Overtemp async events. */ | ||
1444 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
1445 | "2889 Port Overtemperature event, " | ||
1446 | "taking port\n"); | ||
1447 | spin_lock_irq(&phba->hbalock); | ||
1448 | phba->over_temp_state = HBA_OVER_TEMP; | ||
1449 | spin_unlock_irq(&phba->hbalock); | ||
1450 | lpfc_sli4_offline_eratt(phba); | ||
1451 | return; | ||
1452 | } | ||
1453 | if (bf_get(lpfc_sliport_status_rn, &portstat_reg)) { | ||
1454 | /* | ||
1455 | * TODO: Attempt port recovery via a port reset. | ||
1456 | * When fully implemented, the driver should | ||
1457 | * attempt to recover the port here and return. | ||
1458 | * For now, log an error and take the port offline. | ||
1459 | */ | ||
1460 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
1461 | "2887 Port Error: Attempting " | ||
1462 | "Port Recovery\n"); | ||
1463 | } | ||
1464 | lpfc_sli4_offline_eratt(phba); | ||
1465 | break; | ||
1466 | case LPFC_SLI_INTF_IF_TYPE_1: | ||
1467 | default: | ||
1468 | break; | ||
1469 | } | ||
1436 | } | 1470 | } |
1437 | 1471 | ||
1438 | /** | 1472 | /** |
@@ -2983,63 +3017,6 @@ lpfc_sli4_fcf_redisc_wait_tmo(unsigned long ptr) | |||
2983 | } | 3017 | } |
2984 | 3018 | ||
2985 | /** | 3019 | /** |
2986 | * lpfc_sli4_fw_cfg_check - Read the firmware config and verify FCoE support | ||
2987 | * @phba: pointer to lpfc hba data structure. | ||
2988 | * | ||
2989 | * This function uses the QUERY_FW_CFG mailbox command to determine if the | ||
2990 | * firmware loaded supports FCoE. A return of zero indicates that the mailbox | ||
2991 | * was successful and the firmware supports FCoE. Any other return indicates | ||
2992 | * a error. It is assumed that this function will be called before interrupts | ||
2993 | * are enabled. | ||
2994 | **/ | ||
2995 | static int | ||
2996 | lpfc_sli4_fw_cfg_check(struct lpfc_hba *phba) | ||
2997 | { | ||
2998 | int rc = 0; | ||
2999 | LPFC_MBOXQ_t *mboxq; | ||
3000 | struct lpfc_mbx_query_fw_cfg *query_fw_cfg; | ||
3001 | uint32_t length; | ||
3002 | uint32_t shdr_status, shdr_add_status; | ||
3003 | |||
3004 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
3005 | if (!mboxq) { | ||
3006 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
3007 | "2621 Failed to allocate mbox for " | ||
3008 | "query firmware config cmd\n"); | ||
3009 | return -ENOMEM; | ||
3010 | } | ||
3011 | query_fw_cfg = &mboxq->u.mqe.un.query_fw_cfg; | ||
3012 | length = (sizeof(struct lpfc_mbx_query_fw_cfg) - | ||
3013 | sizeof(struct lpfc_sli4_cfg_mhdr)); | ||
3014 | lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON, | ||
3015 | LPFC_MBOX_OPCODE_QUERY_FW_CFG, | ||
3016 | length, LPFC_SLI4_MBX_EMBED); | ||
3017 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | ||
3018 | /* The IOCTL status is embedded in the mailbox subheader. */ | ||
3019 | shdr_status = bf_get(lpfc_mbox_hdr_status, | ||
3020 | &query_fw_cfg->header.cfg_shdr.response); | ||
3021 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, | ||
3022 | &query_fw_cfg->header.cfg_shdr.response); | ||
3023 | if (shdr_status || shdr_add_status || rc != MBX_SUCCESS) { | ||
3024 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
3025 | "2622 Query Firmware Config failed " | ||
3026 | "mbx status x%x, status x%x add_status x%x\n", | ||
3027 | rc, shdr_status, shdr_add_status); | ||
3028 | return -EINVAL; | ||
3029 | } | ||
3030 | if (!bf_get(lpfc_function_mode_fcoe_i, query_fw_cfg)) { | ||
3031 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
3032 | "2623 FCoE Function not supported by firmware. " | ||
3033 | "Function mode = %08x\n", | ||
3034 | query_fw_cfg->function_mode); | ||
3035 | return -EINVAL; | ||
3036 | } | ||
3037 | if (rc != MBX_TIMEOUT) | ||
3038 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
3039 | return 0; | ||
3040 | } | ||
3041 | |||
3042 | /** | ||
3043 | * lpfc_sli4_parse_latt_fault - Parse sli4 link-attention link fault code | 3020 | * lpfc_sli4_parse_latt_fault - Parse sli4 link-attention link fault code |
3044 | * @phba: pointer to lpfc hba data structure. | 3021 | * @phba: pointer to lpfc hba data structure. |
3045 | * @acqe_link: pointer to the async link completion queue entry. | 3022 | * @acqe_link: pointer to the async link completion queue entry. |
@@ -4268,6 +4245,14 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
4268 | if (rc) | 4245 | if (rc) |
4269 | return -ENOMEM; | 4246 | return -ENOMEM; |
4270 | 4247 | ||
4248 | /* IF Type 2 ports get initialized now. */ | ||
4249 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == | ||
4250 | LPFC_SLI_INTF_IF_TYPE_2) { | ||
4251 | rc = lpfc_pci_function_reset(phba); | ||
4252 | if (unlikely(rc)) | ||
4253 | return -ENODEV; | ||
4254 | } | ||
4255 | |||
4271 | /* Create the bootstrap mailbox command */ | 4256 | /* Create the bootstrap mailbox command */ |
4272 | rc = lpfc_create_bootstrap_mbox(phba); | 4257 | rc = lpfc_create_bootstrap_mbox(phba); |
4273 | if (unlikely(rc)) | 4258 | if (unlikely(rc)) |
@@ -4278,19 +4263,18 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
4278 | if (unlikely(rc)) | 4263 | if (unlikely(rc)) |
4279 | goto out_free_bsmbx; | 4264 | goto out_free_bsmbx; |
4280 | 4265 | ||
4281 | rc = lpfc_sli4_fw_cfg_check(phba); | ||
4282 | if (unlikely(rc)) | ||
4283 | goto out_free_bsmbx; | ||
4284 | |||
4285 | /* Set up the hba's configuration parameters. */ | 4266 | /* Set up the hba's configuration parameters. */ |
4286 | rc = lpfc_sli4_read_config(phba); | 4267 | rc = lpfc_sli4_read_config(phba); |
4287 | if (unlikely(rc)) | 4268 | if (unlikely(rc)) |
4288 | goto out_free_bsmbx; | 4269 | goto out_free_bsmbx; |
4289 | 4270 | ||
4290 | /* Perform a function reset */ | 4271 | /* IF Type 0 ports get initialized now. */ |
4291 | rc = lpfc_pci_function_reset(phba); | 4272 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == |
4292 | if (unlikely(rc)) | 4273 | LPFC_SLI_INTF_IF_TYPE_0) { |
4293 | goto out_free_bsmbx; | 4274 | rc = lpfc_pci_function_reset(phba); |
4275 | if (unlikely(rc)) | ||
4276 | goto out_free_bsmbx; | ||
4277 | } | ||
4294 | 4278 | ||
4295 | mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, | 4279 | mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, |
4296 | GFP_KERNEL); | 4280 | GFP_KERNEL); |
@@ -5388,49 +5372,51 @@ lpfc_sli_pci_mem_unset(struct lpfc_hba *phba) | |||
5388 | int | 5372 | int |
5389 | lpfc_sli4_post_status_check(struct lpfc_hba *phba) | 5373 | lpfc_sli4_post_status_check(struct lpfc_hba *phba) |
5390 | { | 5374 | { |
5391 | struct lpfc_register sta_reg, uerrlo_reg, uerrhi_reg; | 5375 | struct lpfc_register portsmphr_reg, uerrlo_reg, uerrhi_reg; |
5392 | int i, port_error = -ENODEV; | 5376 | struct lpfc_register reg_data; |
5377 | int i, port_error = 0; | ||
5378 | uint32_t if_type; | ||
5393 | 5379 | ||
5394 | if (!phba->sli4_hba.STAregaddr) | 5380 | if (!phba->sli4_hba.PSMPHRregaddr) |
5395 | return -ENODEV; | 5381 | return -ENODEV; |
5396 | 5382 | ||
5397 | /* Wait up to 30 seconds for the SLI Port POST done and ready */ | 5383 | /* Wait up to 30 seconds for the SLI Port POST done and ready */ |
5398 | for (i = 0; i < 3000; i++) { | 5384 | for (i = 0; i < 3000; i++) { |
5399 | sta_reg.word0 = readl(phba->sli4_hba.STAregaddr); | 5385 | portsmphr_reg.word0 = readl(phba->sli4_hba.PSMPHRregaddr); |
5400 | /* Encounter fatal POST error, break out */ | 5386 | if (bf_get(lpfc_port_smphr_perr, &portsmphr_reg)) { |
5401 | if (bf_get(lpfc_hst_state_perr, &sta_reg)) { | 5387 | /* Port has a fatal POST error, break out */ |
5402 | port_error = -ENODEV; | 5388 | port_error = -ENODEV; |
5403 | break; | 5389 | break; |
5404 | } | 5390 | } |
5405 | if (LPFC_POST_STAGE_ARMFW_READY == | 5391 | if (LPFC_POST_STAGE_PORT_READY == |
5406 | bf_get(lpfc_hst_state_port_status, &sta_reg)) { | 5392 | bf_get(lpfc_port_smphr_port_status, &portsmphr_reg)) |
5407 | port_error = 0; | ||
5408 | break; | 5393 | break; |
5409 | } | ||
5410 | msleep(10); | 5394 | msleep(10); |
5411 | } | 5395 | } |
5412 | 5396 | ||
5413 | if (port_error) | 5397 | /* |
5398 | * If there was a port error during POST, then don't proceed with | ||
5399 | * other register reads as the data may not be valid. Just exit. | ||
5400 | */ | ||
5401 | if (port_error) { | ||
5414 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 5402 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
5415 | "1408 Failure HBA POST Status: sta_reg=0x%x, " | 5403 | "1408 Port Failed POST - portsmphr=0x%x, " |
5416 | "perr=x%x, sfi=x%x, nip=x%x, ipc=x%x, xrom=x%x, " | 5404 | "perr=x%x, sfi=x%x, nip=x%x, ipc=x%x, scr1=x%x, " |
5417 | "dl=x%x, pstatus=x%x\n", sta_reg.word0, | 5405 | "scr2=x%x, hscratch=x%x, pstatus=x%x\n", |
5418 | bf_get(lpfc_hst_state_perr, &sta_reg), | 5406 | portsmphr_reg.word0, |
5419 | bf_get(lpfc_hst_state_sfi, &sta_reg), | 5407 | bf_get(lpfc_port_smphr_perr, &portsmphr_reg), |
5420 | bf_get(lpfc_hst_state_nip, &sta_reg), | 5408 | bf_get(lpfc_port_smphr_sfi, &portsmphr_reg), |
5421 | bf_get(lpfc_hst_state_ipc, &sta_reg), | 5409 | bf_get(lpfc_port_smphr_nip, &portsmphr_reg), |
5422 | bf_get(lpfc_hst_state_xrom, &sta_reg), | 5410 | bf_get(lpfc_port_smphr_ipc, &portsmphr_reg), |
5423 | bf_get(lpfc_hst_state_dl, &sta_reg), | 5411 | bf_get(lpfc_port_smphr_scr1, &portsmphr_reg), |
5424 | bf_get(lpfc_hst_state_port_status, &sta_reg)); | 5412 | bf_get(lpfc_port_smphr_scr2, &portsmphr_reg), |
5425 | 5413 | bf_get(lpfc_port_smphr_host_scratch, &portsmphr_reg), | |
5426 | /* Log device information */ | 5414 | bf_get(lpfc_port_smphr_port_status, &portsmphr_reg)); |
5427 | phba->sli4_hba.sli_intf.word0 = readl(phba->sli4_hba.SLIINTFregaddr); | 5415 | } else { |
5428 | if (bf_get(lpfc_sli_intf_valid, | ||
5429 | &phba->sli4_hba.sli_intf) == LPFC_SLI_INTF_VALID) { | ||
5430 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | 5416 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, |
5431 | "2534 Device Info: ChipType=0x%x, SliRev=0x%x, " | 5417 | "2534 Device Info: SLIFamily=0x%x, " |
5432 | "IFType=0x%x, SLIHint_1=0x%x, SLIHint_2=0x%x, " | 5418 | "SLIRev=0x%x, IFType=0x%x, SLIHint_1=0x%x, " |
5433 | "FT=0x%x\n", | 5419 | "SLIHint_2=0x%x, FT=0x%x\n", |
5434 | bf_get(lpfc_sli_intf_sli_family, | 5420 | bf_get(lpfc_sli_intf_sli_family, |
5435 | &phba->sli4_hba.sli_intf), | 5421 | &phba->sli4_hba.sli_intf), |
5436 | bf_get(lpfc_sli_intf_slirev, | 5422 | bf_get(lpfc_sli_intf_slirev, |
@@ -5443,48 +5429,126 @@ lpfc_sli4_post_status_check(struct lpfc_hba *phba) | |||
5443 | &phba->sli4_hba.sli_intf), | 5429 | &phba->sli4_hba.sli_intf), |
5444 | bf_get(lpfc_sli_intf_func_type, | 5430 | bf_get(lpfc_sli_intf_func_type, |
5445 | &phba->sli4_hba.sli_intf)); | 5431 | &phba->sli4_hba.sli_intf)); |
5432 | /* | ||
5433 | * Check for other Port errors during the initialization | ||
5434 | * process. Fail the load if the port did not come up | ||
5435 | * correctly. | ||
5436 | */ | ||
5437 | if_type = bf_get(lpfc_sli_intf_if_type, | ||
5438 | &phba->sli4_hba.sli_intf); | ||
5439 | switch (if_type) { | ||
5440 | case LPFC_SLI_INTF_IF_TYPE_0: | ||
5441 | phba->sli4_hba.ue_mask_lo = | ||
5442 | readl(phba->sli4_hba.u.if_type0.UEMASKLOregaddr); | ||
5443 | phba->sli4_hba.ue_mask_hi = | ||
5444 | readl(phba->sli4_hba.u.if_type0.UEMASKHIregaddr); | ||
5445 | uerrlo_reg.word0 = | ||
5446 | readl(phba->sli4_hba.u.if_type0.UERRLOregaddr); | ||
5447 | uerrhi_reg.word0 = | ||
5448 | readl(phba->sli4_hba.u.if_type0.UERRHIregaddr); | ||
5449 | if ((~phba->sli4_hba.ue_mask_lo & uerrlo_reg.word0) || | ||
5450 | (~phba->sli4_hba.ue_mask_hi & uerrhi_reg.word0)) { | ||
5451 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
5452 | "1422 Unrecoverable Error " | ||
5453 | "Detected during POST " | ||
5454 | "uerr_lo_reg=0x%x, " | ||
5455 | "uerr_hi_reg=0x%x, " | ||
5456 | "ue_mask_lo_reg=0x%x, " | ||
5457 | "ue_mask_hi_reg=0x%x\n", | ||
5458 | uerrlo_reg.word0, | ||
5459 | uerrhi_reg.word0, | ||
5460 | phba->sli4_hba.ue_mask_lo, | ||
5461 | phba->sli4_hba.ue_mask_hi); | ||
5462 | port_error = -ENODEV; | ||
5463 | } | ||
5464 | break; | ||
5465 | case LPFC_SLI_INTF_IF_TYPE_2: | ||
5466 | /* Final checks. The port status should be clean. */ | ||
5467 | reg_data.word0 = | ||
5468 | readl(phba->sli4_hba.u.if_type2.STATUSregaddr); | ||
5469 | if (bf_get(lpfc_sliport_status_err, ®_data)) { | ||
5470 | phba->work_status[0] = | ||
5471 | readl(phba->sli4_hba.u.if_type2. | ||
5472 | ERR1regaddr); | ||
5473 | phba->work_status[1] = | ||
5474 | readl(phba->sli4_hba.u.if_type2. | ||
5475 | ERR2regaddr); | ||
5476 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
5477 | "2888 Port Error Detected " | ||
5478 | "during POST: " | ||
5479 | "port status reg 0x%x, " | ||
5480 | "port_smphr reg 0x%x, " | ||
5481 | "error 1=0x%x, error 2=0x%x\n", | ||
5482 | reg_data.word0, | ||
5483 | portsmphr_reg.word0, | ||
5484 | phba->work_status[0], | ||
5485 | phba->work_status[1]); | ||
5486 | port_error = -ENODEV; | ||
5487 | } | ||
5488 | break; | ||
5489 | case LPFC_SLI_INTF_IF_TYPE_1: | ||
5490 | default: | ||
5491 | break; | ||
5492 | } | ||
5446 | } | 5493 | } |
5447 | |||
5448 | phba->sli4_hba.ue_mask_lo = readl(phba->sli4_hba.UEMASKLOregaddr); | ||
5449 | phba->sli4_hba.ue_mask_hi = readl(phba->sli4_hba.UEMASKHIregaddr); | ||
5450 | /* With uncoverable error, log the error message and return error */ | ||
5451 | uerrlo_reg.word0 = readl(phba->sli4_hba.UERRLOregaddr); | ||
5452 | uerrhi_reg.word0 = readl(phba->sli4_hba.UERRHIregaddr); | ||
5453 | if ((~phba->sli4_hba.ue_mask_lo & uerrlo_reg.word0) || | ||
5454 | (~phba->sli4_hba.ue_mask_hi & uerrhi_reg.word0)) { | ||
5455 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
5456 | "1422 HBA Unrecoverable error: " | ||
5457 | "uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, " | ||
5458 | "ue_mask_lo_reg=0x%x, ue_mask_hi_reg=0x%x\n", | ||
5459 | uerrlo_reg.word0, uerrhi_reg.word0, | ||
5460 | phba->sli4_hba.ue_mask_lo, | ||
5461 | phba->sli4_hba.ue_mask_hi); | ||
5462 | return -ENODEV; | ||
5463 | } | ||
5464 | |||
5465 | return port_error; | 5494 | return port_error; |
5466 | } | 5495 | } |
5467 | 5496 | ||
5468 | /** | 5497 | /** |
5469 | * lpfc_sli4_bar0_register_memmap - Set up SLI4 BAR0 register memory map. | 5498 | * lpfc_sli4_bar0_register_memmap - Set up SLI4 BAR0 register memory map. |
5470 | * @phba: pointer to lpfc hba data structure. | 5499 | * @phba: pointer to lpfc hba data structure. |
5500 | * @if_type: The SLI4 interface type getting configured. | ||
5471 | * | 5501 | * |
5472 | * This routine is invoked to set up SLI4 BAR0 PCI config space register | 5502 | * This routine is invoked to set up SLI4 BAR0 PCI config space register |
5473 | * memory map. | 5503 | * memory map. |
5474 | **/ | 5504 | **/ |
5475 | static void | 5505 | static void |
5476 | lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba) | 5506 | lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba, uint32_t if_type) |
5477 | { | 5507 | { |
5478 | phba->sli4_hba.UERRLOregaddr = phba->sli4_hba.conf_regs_memmap_p + | 5508 | switch (if_type) { |
5479 | LPFC_UERR_STATUS_LO; | 5509 | case LPFC_SLI_INTF_IF_TYPE_0: |
5480 | phba->sli4_hba.UERRHIregaddr = phba->sli4_hba.conf_regs_memmap_p + | 5510 | phba->sli4_hba.u.if_type0.UERRLOregaddr = |
5481 | LPFC_UERR_STATUS_HI; | 5511 | phba->sli4_hba.conf_regs_memmap_p + LPFC_UERR_STATUS_LO; |
5482 | phba->sli4_hba.UEMASKLOregaddr = phba->sli4_hba.conf_regs_memmap_p + | 5512 | phba->sli4_hba.u.if_type0.UERRHIregaddr = |
5483 | LPFC_UE_MASK_LO; | 5513 | phba->sli4_hba.conf_regs_memmap_p + LPFC_UERR_STATUS_HI; |
5484 | phba->sli4_hba.UEMASKHIregaddr = phba->sli4_hba.conf_regs_memmap_p + | 5514 | phba->sli4_hba.u.if_type0.UEMASKLOregaddr = |
5485 | LPFC_UE_MASK_HI; | 5515 | phba->sli4_hba.conf_regs_memmap_p + LPFC_UE_MASK_LO; |
5486 | phba->sli4_hba.SLIINTFregaddr = phba->sli4_hba.conf_regs_memmap_p + | 5516 | phba->sli4_hba.u.if_type0.UEMASKHIregaddr = |
5487 | LPFC_SLI_INTF; | 5517 | phba->sli4_hba.conf_regs_memmap_p + LPFC_UE_MASK_HI; |
5518 | phba->sli4_hba.SLIINTFregaddr = | ||
5519 | phba->sli4_hba.conf_regs_memmap_p + LPFC_SLI_INTF; | ||
5520 | break; | ||
5521 | case LPFC_SLI_INTF_IF_TYPE_2: | ||
5522 | phba->sli4_hba.u.if_type2.ERR1regaddr = | ||
5523 | phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_ERR_1; | ||
5524 | phba->sli4_hba.u.if_type2.ERR2regaddr = | ||
5525 | phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_ERR_2; | ||
5526 | phba->sli4_hba.u.if_type2.CTRLregaddr = | ||
5527 | phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_CNTRL; | ||
5528 | phba->sli4_hba.u.if_type2.STATUSregaddr = | ||
5529 | phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_STATUS; | ||
5530 | phba->sli4_hba.SLIINTFregaddr = | ||
5531 | phba->sli4_hba.conf_regs_memmap_p + LPFC_SLI_INTF; | ||
5532 | phba->sli4_hba.PSMPHRregaddr = | ||
5533 | phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_IF2_SMPHR; | ||
5534 | phba->sli4_hba.RQDBregaddr = | ||
5535 | phba->sli4_hba.conf_regs_memmap_p + LPFC_RQ_DOORBELL; | ||
5536 | phba->sli4_hba.WQDBregaddr = | ||
5537 | phba->sli4_hba.conf_regs_memmap_p + LPFC_WQ_DOORBELL; | ||
5538 | phba->sli4_hba.EQCQDBregaddr = | ||
5539 | phba->sli4_hba.conf_regs_memmap_p + LPFC_EQCQ_DOORBELL; | ||
5540 | phba->sli4_hba.MQDBregaddr = | ||
5541 | phba->sli4_hba.conf_regs_memmap_p + LPFC_MQ_DOORBELL; | ||
5542 | phba->sli4_hba.BMBXregaddr = | ||
5543 | phba->sli4_hba.conf_regs_memmap_p + LPFC_BMBX; | ||
5544 | break; | ||
5545 | case LPFC_SLI_INTF_IF_TYPE_1: | ||
5546 | default: | ||
5547 | dev_printk(KERN_ERR, &phba->pcidev->dev, | ||
5548 | "FATAL - unsupported SLI4 interface type - %d\n", | ||
5549 | if_type); | ||
5550 | break; | ||
5551 | } | ||
5488 | } | 5552 | } |
5489 | 5553 | ||
5490 | /** | 5554 | /** |
@@ -5497,16 +5561,14 @@ lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba) | |||
5497 | static void | 5561 | static void |
5498 | lpfc_sli4_bar1_register_memmap(struct lpfc_hba *phba) | 5562 | lpfc_sli4_bar1_register_memmap(struct lpfc_hba *phba) |
5499 | { | 5563 | { |
5500 | 5564 | phba->sli4_hba.PSMPHRregaddr = phba->sli4_hba.ctrl_regs_memmap_p + | |
5501 | phba->sli4_hba.STAregaddr = phba->sli4_hba.ctrl_regs_memmap_p + | 5565 | LPFC_SLIPORT_IF0_SMPHR; |
5502 | LPFC_HST_STATE; | ||
5503 | phba->sli4_hba.ISRregaddr = phba->sli4_hba.ctrl_regs_memmap_p + | 5566 | phba->sli4_hba.ISRregaddr = phba->sli4_hba.ctrl_regs_memmap_p + |
5504 | LPFC_HST_ISR0; | 5567 | LPFC_HST_ISR0; |
5505 | phba->sli4_hba.IMRregaddr = phba->sli4_hba.ctrl_regs_memmap_p + | 5568 | phba->sli4_hba.IMRregaddr = phba->sli4_hba.ctrl_regs_memmap_p + |
5506 | LPFC_HST_IMR0; | 5569 | LPFC_HST_IMR0; |
5507 | phba->sli4_hba.ISCRregaddr = phba->sli4_hba.ctrl_regs_memmap_p + | 5570 | phba->sli4_hba.ISCRregaddr = phba->sli4_hba.ctrl_regs_memmap_p + |
5508 | LPFC_HST_ISCR0; | 5571 | LPFC_HST_ISCR0; |
5509 | return; | ||
5510 | } | 5572 | } |
5511 | 5573 | ||
5512 | /** | 5574 | /** |
@@ -5746,11 +5808,12 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) | |||
5746 | } | 5808 | } |
5747 | 5809 | ||
5748 | /** | 5810 | /** |
5749 | * lpfc_dev_endian_order_setup - Notify the port of the host's endian order. | 5811 | * lpfc_setup_endian_order - Write endian order to an SLI4 if_type 0 port. |
5750 | * @phba: pointer to lpfc hba data structure. | 5812 | * @phba: pointer to lpfc hba data structure. |
5751 | * | 5813 | * |
5752 | * This routine is invoked to setup the host-side endian order to the | 5814 | * This routine is invoked to setup the port-side endian order when |
5753 | * HBA consistent with the SLI-4 interface spec. | 5815 | * the port if_type is 0. This routine has no function for other |
5816 | * if_types. | ||
5754 | * | 5817 | * |
5755 | * Return codes | 5818 | * Return codes |
5756 | * 0 - successful | 5819 | * 0 - successful |
@@ -5761,34 +5824,44 @@ static int | |||
5761 | lpfc_setup_endian_order(struct lpfc_hba *phba) | 5824 | lpfc_setup_endian_order(struct lpfc_hba *phba) |
5762 | { | 5825 | { |
5763 | LPFC_MBOXQ_t *mboxq; | 5826 | LPFC_MBOXQ_t *mboxq; |
5764 | uint32_t rc = 0; | 5827 | uint32_t if_type, rc = 0; |
5765 | uint32_t endian_mb_data[2] = {HOST_ENDIAN_LOW_WORD0, | 5828 | uint32_t endian_mb_data[2] = {HOST_ENDIAN_LOW_WORD0, |
5766 | HOST_ENDIAN_HIGH_WORD1}; | 5829 | HOST_ENDIAN_HIGH_WORD1}; |
5767 | 5830 | ||
5768 | mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 5831 | if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf); |
5769 | if (!mboxq) { | 5832 | switch (if_type) { |
5770 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 5833 | case LPFC_SLI_INTF_IF_TYPE_0: |
5771 | "0492 Unable to allocate memory for issuing " | 5834 | mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, |
5772 | "SLI_CONFIG_SPECIAL mailbox command\n"); | 5835 | GFP_KERNEL); |
5773 | return -ENOMEM; | 5836 | if (!mboxq) { |
5774 | } | 5837 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
5838 | "0492 Unable to allocate memory for " | ||
5839 | "issuing SLI_CONFIG_SPECIAL mailbox " | ||
5840 | "command\n"); | ||
5841 | return -ENOMEM; | ||
5842 | } | ||
5775 | 5843 | ||
5776 | /* | 5844 | /* |
5777 | * The SLI4_CONFIG_SPECIAL mailbox command requires the first two | 5845 | * The SLI4_CONFIG_SPECIAL mailbox command requires the first |
5778 | * words to contain special data values and no other data. | 5846 | * two words to contain special data values and no other data. |
5779 | */ | 5847 | */ |
5780 | memset(mboxq, 0, sizeof(LPFC_MBOXQ_t)); | 5848 | memset(mboxq, 0, sizeof(LPFC_MBOXQ_t)); |
5781 | memcpy(&mboxq->u.mqe, &endian_mb_data, sizeof(endian_mb_data)); | 5849 | memcpy(&mboxq->u.mqe, &endian_mb_data, sizeof(endian_mb_data)); |
5782 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | 5850 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); |
5783 | if (rc != MBX_SUCCESS) { | 5851 | if (rc != MBX_SUCCESS) { |
5784 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 5852 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
5785 | "0493 SLI_CONFIG_SPECIAL mailbox failed with " | 5853 | "0493 SLI_CONFIG_SPECIAL mailbox " |
5786 | "status x%x\n", | 5854 | "failed with status x%x\n", |
5787 | rc); | 5855 | rc); |
5788 | rc = -EIO; | 5856 | rc = -EIO; |
5857 | } | ||
5858 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
5859 | break; | ||
5860 | case LPFC_SLI_INTF_IF_TYPE_2: | ||
5861 | case LPFC_SLI_INTF_IF_TYPE_1: | ||
5862 | default: | ||
5863 | break; | ||
5789 | } | 5864 | } |
5790 | |||
5791 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
5792 | return rc; | 5865 | return rc; |
5793 | } | 5866 | } |
5794 | 5867 | ||
@@ -6620,36 +6693,124 @@ int | |||
6620 | lpfc_pci_function_reset(struct lpfc_hba *phba) | 6693 | lpfc_pci_function_reset(struct lpfc_hba *phba) |
6621 | { | 6694 | { |
6622 | LPFC_MBOXQ_t *mboxq; | 6695 | LPFC_MBOXQ_t *mboxq; |
6623 | uint32_t rc = 0; | 6696 | uint32_t rc = 0, if_type; |
6624 | uint32_t shdr_status, shdr_add_status; | 6697 | uint32_t shdr_status, shdr_add_status; |
6698 | uint32_t rdy_chk, num_resets = 0, reset_again = 0; | ||
6625 | union lpfc_sli4_cfg_shdr *shdr; | 6699 | union lpfc_sli4_cfg_shdr *shdr; |
6700 | struct lpfc_register reg_data; | ||
6626 | 6701 | ||
6627 | mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 6702 | if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf); |
6628 | if (!mboxq) { | 6703 | switch (if_type) { |
6629 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 6704 | case LPFC_SLI_INTF_IF_TYPE_0: |
6630 | "0494 Unable to allocate memory for issuing " | 6705 | mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, |
6631 | "SLI_FUNCTION_RESET mailbox command\n"); | 6706 | GFP_KERNEL); |
6632 | return -ENOMEM; | 6707 | if (!mboxq) { |
6633 | } | 6708 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
6709 | "0494 Unable to allocate memory for " | ||
6710 | "issuing SLI_FUNCTION_RESET mailbox " | ||
6711 | "command\n"); | ||
6712 | return -ENOMEM; | ||
6713 | } | ||
6634 | 6714 | ||
6635 | /* Set up PCI function reset SLI4_CONFIG mailbox-ioctl command */ | 6715 | /* Setup PCI function reset mailbox-ioctl command */ |
6636 | lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON, | 6716 | lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON, |
6637 | LPFC_MBOX_OPCODE_FUNCTION_RESET, 0, | 6717 | LPFC_MBOX_OPCODE_FUNCTION_RESET, 0, |
6638 | LPFC_SLI4_MBX_EMBED); | 6718 | LPFC_SLI4_MBX_EMBED); |
6639 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | 6719 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); |
6640 | shdr = (union lpfc_sli4_cfg_shdr *) | 6720 | shdr = (union lpfc_sli4_cfg_shdr *) |
6641 | &mboxq->u.mqe.un.sli4_config.header.cfg_shdr; | 6721 | &mboxq->u.mqe.un.sli4_config.header.cfg_shdr; |
6642 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | 6722 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); |
6643 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); | 6723 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, |
6644 | if (rc != MBX_TIMEOUT) | 6724 | &shdr->response); |
6645 | mempool_free(mboxq, phba->mbox_mem_pool); | 6725 | if (rc != MBX_TIMEOUT) |
6646 | if (shdr_status || shdr_add_status || rc) { | 6726 | mempool_free(mboxq, phba->mbox_mem_pool); |
6647 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 6727 | if (shdr_status || shdr_add_status || rc) { |
6648 | "0495 SLI_FUNCTION_RESET mailbox failed with " | 6728 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
6649 | "status x%x add_status x%x, mbx status x%x\n", | 6729 | "0495 SLI_FUNCTION_RESET mailbox " |
6650 | shdr_status, shdr_add_status, rc); | 6730 | "failed with status x%x add_status x%x," |
6651 | rc = -ENXIO; | 6731 | " mbx status x%x\n", |
6732 | shdr_status, shdr_add_status, rc); | ||
6733 | rc = -ENXIO; | ||
6734 | } | ||
6735 | break; | ||
6736 | case LPFC_SLI_INTF_IF_TYPE_2: | ||
6737 | for (num_resets = 0; | ||
6738 | num_resets < MAX_IF_TYPE_2_RESETS; | ||
6739 | num_resets++) { | ||
6740 | reg_data.word0 = 0; | ||
6741 | bf_set(lpfc_sliport_ctrl_end, ®_data, | ||
6742 | LPFC_SLIPORT_LITTLE_ENDIAN); | ||
6743 | bf_set(lpfc_sliport_ctrl_ip, ®_data, | ||
6744 | LPFC_SLIPORT_INIT_PORT); | ||
6745 | writel(reg_data.word0, phba->sli4_hba.u.if_type2. | ||
6746 | CTRLregaddr); | ||
6747 | |||
6748 | /* | ||
6749 | * Poll the Port Status Register and wait for RDY for | ||
6750 | * up to 10 seconds. If the port doesn't respond, treat | ||
6751 | * it as an error. If the port responds with RN, start | ||
6752 | * the loop again. | ||
6753 | */ | ||
6754 | for (rdy_chk = 0; rdy_chk < 1000; rdy_chk++) { | ||
6755 | reg_data.word0 = | ||
6756 | readl(phba->sli4_hba.u.if_type2. | ||
6757 | STATUSregaddr); | ||
6758 | if (bf_get(lpfc_sliport_status_rdy, ®_data)) | ||
6759 | break; | ||
6760 | if (bf_get(lpfc_sliport_status_rn, ®_data)) { | ||
6761 | reset_again++; | ||
6762 | break; | ||
6763 | } | ||
6764 | msleep(10); | ||
6765 | } | ||
6766 | |||
6767 | /* | ||
6768 | * If the port responds to the init request with | ||
6769 | * reset needed, delay for a bit and restart the loop. | ||
6770 | */ | ||
6771 | if (reset_again) { | ||
6772 | msleep(10); | ||
6773 | reset_again = 0; | ||
6774 | continue; | ||
6775 | } | ||
6776 | |||
6777 | /* Detect any port errors. */ | ||
6778 | reg_data.word0 = readl(phba->sli4_hba.u.if_type2. | ||
6779 | STATUSregaddr); | ||
6780 | if ((bf_get(lpfc_sliport_status_err, ®_data)) || | ||
6781 | (rdy_chk >= 1000)) { | ||
6782 | phba->work_status[0] = readl( | ||
6783 | phba->sli4_hba.u.if_type2.ERR1regaddr); | ||
6784 | phba->work_status[1] = readl( | ||
6785 | phba->sli4_hba.u.if_type2.ERR2regaddr); | ||
6786 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
6787 | "2890 Port Error Detected " | ||
6788 | "during Port Reset: " | ||
6789 | "port status reg 0x%x, " | ||
6790 | "error 1=0x%x, error 2=0x%x\n", | ||
6791 | reg_data.word0, | ||
6792 | phba->work_status[0], | ||
6793 | phba->work_status[1]); | ||
6794 | rc = -ENODEV; | ||
6795 | } | ||
6796 | |||
6797 | /* | ||
6798 | * Terminate the outer loop provided the Port indicated | ||
6799 | * ready within 10 seconds. | ||
6800 | */ | ||
6801 | if (rdy_chk < 1000) | ||
6802 | break; | ||
6803 | } | ||
6804 | break; | ||
6805 | case LPFC_SLI_INTF_IF_TYPE_1: | ||
6806 | default: | ||
6807 | break; | ||
6652 | } | 6808 | } |
6809 | |||
6810 | /* Catch the not-ready port failure after a port reset. */ | ||
6811 | if (num_resets >= MAX_IF_TYPE_2_RESETS) | ||
6812 | rc = -ENODEV; | ||
6813 | |||
6653 | return rc; | 6814 | return rc; |
6654 | } | 6815 | } |
6655 | 6816 | ||
@@ -6740,6 +6901,7 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba) | |||
6740 | struct pci_dev *pdev; | 6901 | struct pci_dev *pdev; |
6741 | unsigned long bar0map_len, bar1map_len, bar2map_len; | 6902 | unsigned long bar0map_len, bar1map_len, bar2map_len; |
6742 | int error = -ENODEV; | 6903 | int error = -ENODEV; |
6904 | uint32_t if_type; | ||
6743 | 6905 | ||
6744 | /* Obtain PCI device reference */ | 6906 | /* Obtain PCI device reference */ |
6745 | if (!phba->pcidev) | 6907 | if (!phba->pcidev) |
@@ -6756,61 +6918,105 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba) | |||
6756 | } | 6918 | } |
6757 | } | 6919 | } |
6758 | 6920 | ||
6759 | /* Get the bus address of SLI4 device Bar0, Bar1, and Bar2 and the | 6921 | /* |
6760 | * number of bytes required by each mapping. They are actually | 6922 | * The BARs and register set definitions and offset locations are |
6761 | * mapping to the PCI BAR regions 0 or 1, 2, and 4 by the SLI4 device. | 6923 | * dependent on the if_type. |
6924 | */ | ||
6925 | if (pci_read_config_dword(pdev, LPFC_SLI_INTF, | ||
6926 | &phba->sli4_hba.sli_intf.word0)) { | ||
6927 | return error; | ||
6928 | } | ||
6929 | |||
6930 | /* There is no SLI3 failback for SLI4 devices. */ | ||
6931 | if (bf_get(lpfc_sli_intf_valid, &phba->sli4_hba.sli_intf) != | ||
6932 | LPFC_SLI_INTF_VALID) { | ||
6933 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
6934 | "2894 SLI_INTF reg contents invalid " | ||
6935 | "sli_intf reg 0x%x\n", | ||
6936 | phba->sli4_hba.sli_intf.word0); | ||
6937 | return error; | ||
6938 | } | ||
6939 | |||
6940 | if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf); | ||
6941 | /* | ||
6942 | * Get the bus address of SLI4 device Bar regions and the | ||
6943 | * number of bytes required by each mapping. The mapping of the | ||
6944 | * particular PCI BARs regions is dependent on the type of | ||
6945 | * SLI4 device. | ||
6762 | */ | 6946 | */ |
6763 | if (pci_resource_start(pdev, 0)) { | 6947 | if (pci_resource_start(pdev, 0)) { |
6764 | phba->pci_bar0_map = pci_resource_start(pdev, 0); | 6948 | phba->pci_bar0_map = pci_resource_start(pdev, 0); |
6765 | bar0map_len = pci_resource_len(pdev, 0); | 6949 | bar0map_len = pci_resource_len(pdev, 0); |
6950 | |||
6951 | /* | ||
6952 | * Map SLI4 PCI Config Space Register base to a kernel virtual | ||
6953 | * addr | ||
6954 | */ | ||
6955 | phba->sli4_hba.conf_regs_memmap_p = | ||
6956 | ioremap(phba->pci_bar0_map, bar0map_len); | ||
6957 | if (!phba->sli4_hba.conf_regs_memmap_p) { | ||
6958 | dev_printk(KERN_ERR, &pdev->dev, | ||
6959 | "ioremap failed for SLI4 PCI config " | ||
6960 | "registers.\n"); | ||
6961 | goto out; | ||
6962 | } | ||
6963 | /* Set up BAR0 PCI config space register memory map */ | ||
6964 | lpfc_sli4_bar0_register_memmap(phba, if_type); | ||
6766 | } else { | 6965 | } else { |
6767 | phba->pci_bar0_map = pci_resource_start(pdev, 1); | 6966 | phba->pci_bar0_map = pci_resource_start(pdev, 1); |
6768 | bar0map_len = pci_resource_len(pdev, 1); | 6967 | bar0map_len = pci_resource_len(pdev, 1); |
6769 | } | 6968 | if (if_type == LPFC_SLI_INTF_IF_TYPE_2) { |
6770 | phba->pci_bar1_map = pci_resource_start(pdev, 2); | 6969 | dev_printk(KERN_ERR, &pdev->dev, |
6771 | bar1map_len = pci_resource_len(pdev, 2); | 6970 | "FATAL - No BAR0 mapping for SLI4, if_type 2\n"); |
6772 | 6971 | goto out; | |
6773 | phba->pci_bar2_map = pci_resource_start(pdev, 4); | 6972 | } |
6774 | bar2map_len = pci_resource_len(pdev, 4); | 6973 | phba->sli4_hba.conf_regs_memmap_p = |
6775 | |||
6776 | /* Map SLI4 PCI Config Space Register base to a kernel virtual addr */ | ||
6777 | phba->sli4_hba.conf_regs_memmap_p = | ||
6778 | ioremap(phba->pci_bar0_map, bar0map_len); | 6974 | ioremap(phba->pci_bar0_map, bar0map_len); |
6779 | if (!phba->sli4_hba.conf_regs_memmap_p) { | 6975 | if (!phba->sli4_hba.conf_regs_memmap_p) { |
6780 | dev_printk(KERN_ERR, &pdev->dev, | 6976 | dev_printk(KERN_ERR, &pdev->dev, |
6781 | "ioremap failed for SLI4 PCI config registers.\n"); | 6977 | "ioremap failed for SLI4 PCI config " |
6782 | goto out; | 6978 | "registers.\n"); |
6979 | goto out; | ||
6980 | } | ||
6981 | lpfc_sli4_bar0_register_memmap(phba, if_type); | ||
6783 | } | 6982 | } |
6784 | 6983 | ||
6785 | /* Map SLI4 HBA Control Register base to a kernel virtual address. */ | 6984 | if (pci_resource_start(pdev, 2)) { |
6786 | phba->sli4_hba.ctrl_regs_memmap_p = | 6985 | /* |
6986 | * Map SLI4 if type 0 HBA Control Register base to a kernel | ||
6987 | * virtual address and setup the registers. | ||
6988 | */ | ||
6989 | phba->pci_bar1_map = pci_resource_start(pdev, 2); | ||
6990 | bar1map_len = pci_resource_len(pdev, 2); | ||
6991 | phba->sli4_hba.ctrl_regs_memmap_p = | ||
6787 | ioremap(phba->pci_bar1_map, bar1map_len); | 6992 | ioremap(phba->pci_bar1_map, bar1map_len); |
6788 | if (!phba->sli4_hba.ctrl_regs_memmap_p) { | 6993 | if (!phba->sli4_hba.ctrl_regs_memmap_p) { |
6789 | dev_printk(KERN_ERR, &pdev->dev, | 6994 | dev_printk(KERN_ERR, &pdev->dev, |
6790 | "ioremap failed for SLI4 HBA control registers.\n"); | 6995 | "ioremap failed for SLI4 HBA control registers.\n"); |
6791 | goto out_iounmap_conf; | 6996 | goto out_iounmap_conf; |
6997 | } | ||
6998 | lpfc_sli4_bar1_register_memmap(phba); | ||
6792 | } | 6999 | } |
6793 | 7000 | ||
6794 | /* Map SLI4 HBA Doorbell Register base to a kernel virtual address. */ | 7001 | if (pci_resource_start(pdev, 4)) { |
6795 | phba->sli4_hba.drbl_regs_memmap_p = | 7002 | /* |
7003 | * Map SLI4 if type 0 HBA Doorbell Register base to a kernel | ||
7004 | * virtual address and setup the registers. | ||
7005 | */ | ||
7006 | phba->pci_bar2_map = pci_resource_start(pdev, 4); | ||
7007 | bar2map_len = pci_resource_len(pdev, 4); | ||
7008 | phba->sli4_hba.drbl_regs_memmap_p = | ||
6796 | ioremap(phba->pci_bar2_map, bar2map_len); | 7009 | ioremap(phba->pci_bar2_map, bar2map_len); |
6797 | if (!phba->sli4_hba.drbl_regs_memmap_p) { | 7010 | if (!phba->sli4_hba.drbl_regs_memmap_p) { |
6798 | dev_printk(KERN_ERR, &pdev->dev, | 7011 | dev_printk(KERN_ERR, &pdev->dev, |
6799 | "ioremap failed for SLI4 HBA doorbell registers.\n"); | 7012 | "ioremap failed for SLI4 HBA doorbell registers.\n"); |
6800 | goto out_iounmap_ctrl; | 7013 | goto out_iounmap_ctrl; |
7014 | } | ||
7015 | error = lpfc_sli4_bar2_register_memmap(phba, LPFC_VF0); | ||
7016 | if (error) | ||
7017 | goto out_iounmap_all; | ||
6801 | } | 7018 | } |
6802 | 7019 | ||
6803 | /* Set up BAR0 PCI config space register memory map */ | ||
6804 | lpfc_sli4_bar0_register_memmap(phba); | ||
6805 | |||
6806 | /* Set up BAR1 register memory map */ | ||
6807 | lpfc_sli4_bar1_register_memmap(phba); | ||
6808 | |||
6809 | /* Set up BAR2 register memory map */ | ||
6810 | error = lpfc_sli4_bar2_register_memmap(phba, LPFC_VF0); | ||
6811 | if (error) | ||
6812 | goto out_iounmap_all; | ||
6813 | |||
6814 | return 0; | 7020 | return 0; |
6815 | 7021 | ||
6816 | out_iounmap_all: | 7022 | out_iounmap_all: |
@@ -8424,7 +8630,11 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
8424 | "0451 Configure interrupt mode (%d) " | 8630 | "0451 Configure interrupt mode (%d) " |
8425 | "failed active interrupt test.\n", | 8631 | "failed active interrupt test.\n", |
8426 | intr_mode); | 8632 | intr_mode); |
8427 | /* Unset the preivous SLI-4 HBA setup */ | 8633 | /* Unset the previous SLI-4 HBA setup. */ |
8634 | /* | ||
8635 | * TODO: Is this operation compatible with IF TYPE 2 | ||
8636 | * devices? All port state is deleted and cleared. | ||
8637 | */ | ||
8428 | lpfc_sli4_unset_hba(phba); | 8638 | lpfc_sli4_unset_hba(phba); |
8429 | /* Try next level of interrupt mode */ | 8639 | /* Try next level of interrupt mode */ |
8430 | cfg_mode = --intr_mode; | 8640 | cfg_mode = --intr_mode; |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 8df959ea9669..d6f3b83f3219 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -4690,6 +4690,10 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
4690 | struct lpfc_vport *vport = phba->pport; | 4690 | struct lpfc_vport *vport = phba->pport; |
4691 | struct lpfc_dmabuf *mp; | 4691 | struct lpfc_dmabuf *mp; |
4692 | 4692 | ||
4693 | /* | ||
4694 | * TODO: Why does this routine execute these task in a different | ||
4695 | * order from probe? | ||
4696 | */ | ||
4693 | /* Perform a PCI function reset to start from clean */ | 4697 | /* Perform a PCI function reset to start from clean */ |
4694 | rc = lpfc_pci_function_reset(phba); | 4698 | rc = lpfc_pci_function_reset(phba); |
4695 | if (unlikely(rc)) | 4699 | if (unlikely(rc)) |
@@ -8439,29 +8443,66 @@ static int | |||
8439 | lpfc_sli4_eratt_read(struct lpfc_hba *phba) | 8443 | lpfc_sli4_eratt_read(struct lpfc_hba *phba) |
8440 | { | 8444 | { |
8441 | uint32_t uerr_sta_hi, uerr_sta_lo; | 8445 | uint32_t uerr_sta_hi, uerr_sta_lo; |
8446 | uint32_t if_type, portsmphr; | ||
8447 | struct lpfc_register portstat_reg; | ||
8442 | 8448 | ||
8443 | /* For now, use the SLI4 device internal unrecoverable error | 8449 | /* |
8450 | * For now, use the SLI4 device internal unrecoverable error | ||
8444 | * registers for error attention. This can be changed later. | 8451 | * registers for error attention. This can be changed later. |
8445 | */ | 8452 | */ |
8446 | uerr_sta_lo = readl(phba->sli4_hba.UERRLOregaddr); | 8453 | if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf); |
8447 | uerr_sta_hi = readl(phba->sli4_hba.UERRHIregaddr); | 8454 | switch (if_type) { |
8448 | if ((~phba->sli4_hba.ue_mask_lo & uerr_sta_lo) || | 8455 | case LPFC_SLI_INTF_IF_TYPE_0: |
8449 | (~phba->sli4_hba.ue_mask_hi & uerr_sta_hi)) { | 8456 | uerr_sta_lo = readl(phba->sli4_hba.u.if_type0.UERRLOregaddr); |
8457 | uerr_sta_hi = readl(phba->sli4_hba.u.if_type0.UERRHIregaddr); | ||
8458 | if ((~phba->sli4_hba.ue_mask_lo & uerr_sta_lo) || | ||
8459 | (~phba->sli4_hba.ue_mask_hi & uerr_sta_hi)) { | ||
8460 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
8461 | "1423 HBA Unrecoverable error: " | ||
8462 | "uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, " | ||
8463 | "ue_mask_lo_reg=0x%x, " | ||
8464 | "ue_mask_hi_reg=0x%x\n", | ||
8465 | uerr_sta_lo, uerr_sta_hi, | ||
8466 | phba->sli4_hba.ue_mask_lo, | ||
8467 | phba->sli4_hba.ue_mask_hi); | ||
8468 | phba->work_status[0] = uerr_sta_lo; | ||
8469 | phba->work_status[1] = uerr_sta_hi; | ||
8470 | phba->work_ha |= HA_ERATT; | ||
8471 | phba->hba_flag |= HBA_ERATT_HANDLED; | ||
8472 | return 1; | ||
8473 | } | ||
8474 | break; | ||
8475 | case LPFC_SLI_INTF_IF_TYPE_2: | ||
8476 | portstat_reg.word0 = | ||
8477 | readl(phba->sli4_hba.u.if_type2.STATUSregaddr); | ||
8478 | portsmphr = readl(phba->sli4_hba.PSMPHRregaddr); | ||
8479 | if (bf_get(lpfc_sliport_status_err, &portstat_reg)) { | ||
8480 | phba->work_status[0] = | ||
8481 | readl(phba->sli4_hba.u.if_type2.ERR1regaddr); | ||
8482 | phba->work_status[1] = | ||
8483 | readl(phba->sli4_hba.u.if_type2.ERR2regaddr); | ||
8484 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
8485 | "2885 Port Error Detected: " | ||
8486 | "port status reg 0x%x, " | ||
8487 | "port smphr reg 0x%x, " | ||
8488 | "error 1=0x%x, error 2=0x%x\n", | ||
8489 | portstat_reg.word0, | ||
8490 | portsmphr, | ||
8491 | phba->work_status[0], | ||
8492 | phba->work_status[1]); | ||
8493 | phba->work_ha |= HA_ERATT; | ||
8494 | phba->hba_flag |= HBA_ERATT_HANDLED; | ||
8495 | return 1; | ||
8496 | } | ||
8497 | break; | ||
8498 | case LPFC_SLI_INTF_IF_TYPE_1: | ||
8499 | default: | ||
8450 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 8500 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
8451 | "1423 HBA Unrecoverable error: " | 8501 | "2886 HBA Error Attention on unsupported " |
8452 | "uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, " | 8502 | "if type %d.", if_type); |
8453 | "ue_mask_lo_reg=0x%x, ue_mask_hi_reg=0x%x\n", | ||
8454 | uerr_sta_lo, uerr_sta_hi, | ||
8455 | phba->sli4_hba.ue_mask_lo, | ||
8456 | phba->sli4_hba.ue_mask_hi); | ||
8457 | phba->work_status[0] = uerr_sta_lo; | ||
8458 | phba->work_status[1] = uerr_sta_hi; | ||
8459 | /* Set the driver HA work bitmap */ | ||
8460 | phba->work_ha |= HA_ERATT; | ||
8461 | /* Indicate polling handles this ERATT */ | ||
8462 | phba->hba_flag |= HBA_ERATT_HANDLED; | ||
8463 | return 1; | 8503 | return 1; |
8464 | } | 8504 | } |
8505 | |||
8465 | return 0; | 8506 | return 0; |
8466 | } | 8507 | } |
8467 | 8508 | ||
@@ -8516,7 +8557,7 @@ lpfc_sli_check_eratt(struct lpfc_hba *phba) | |||
8516 | ha_copy = lpfc_sli_eratt_read(phba); | 8557 | ha_copy = lpfc_sli_eratt_read(phba); |
8517 | break; | 8558 | break; |
8518 | case LPFC_SLI_REV4: | 8559 | case LPFC_SLI_REV4: |
8519 | /* Read devcie Uncoverable Error (UERR) registers */ | 8560 | /* Read device Uncoverable Error (UERR) registers */ |
8520 | ha_copy = lpfc_sli4_eratt_read(phba); | 8561 | ha_copy = lpfc_sli4_eratt_read(phba); |
8521 | break; | 8562 | break; |
8522 | default: | 8563 | default: |
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index f96eae51d07c..eb0fedfbf370 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h | |||
@@ -369,23 +369,39 @@ struct lpfc_sli4_hba { | |||
369 | PCI BAR1, control registers */ | 369 | PCI BAR1, control registers */ |
370 | void __iomem *drbl_regs_memmap_p; /* Kernel memory mapped address for | 370 | void __iomem *drbl_regs_memmap_p; /* Kernel memory mapped address for |
371 | PCI BAR2, doorbell registers */ | 371 | PCI BAR2, doorbell registers */ |
372 | /* BAR0 PCI config space register memory map */ | 372 | union { |
373 | void __iomem *UERRLOregaddr; /* Address to UERR_STATUS_LO register */ | 373 | struct { |
374 | void __iomem *UERRHIregaddr; /* Address to UERR_STATUS_HI register */ | 374 | /* IF Type 0, BAR 0 PCI cfg space reg mem map */ |
375 | void __iomem *UEMASKLOregaddr; /* Address to UE_MASK_LO register */ | 375 | void __iomem *UERRLOregaddr; |
376 | void __iomem *UEMASKHIregaddr; /* Address to UE_MASK_HI register */ | 376 | void __iomem *UERRHIregaddr; |
377 | void __iomem *SLIINTFregaddr; /* Address to SLI_INTF register */ | 377 | void __iomem *UEMASKLOregaddr; |
378 | /* BAR1 FCoE function CSR register memory map */ | 378 | void __iomem *UEMASKHIregaddr; |
379 | void __iomem *STAregaddr; /* Address to HST_STATE register */ | 379 | } if_type0; |
380 | void __iomem *ISRregaddr; /* Address to HST_ISR register */ | 380 | struct { |
381 | void __iomem *IMRregaddr; /* Address to HST_IMR register */ | 381 | /* IF Type 2, BAR 0 PCI cfg space reg mem map. */ |
382 | void __iomem *ISCRregaddr; /* Address to HST_ISCR register */ | 382 | void __iomem *STATUSregaddr; |
383 | /* BAR2 VF-0 doorbell register memory map */ | 383 | void __iomem *CTRLregaddr; |
384 | void __iomem *RQDBregaddr; /* Address to RQ_DOORBELL register */ | 384 | void __iomem *ERR1regaddr; |
385 | void __iomem *WQDBregaddr; /* Address to WQ_DOORBELL register */ | 385 | void __iomem *ERR2regaddr; |
386 | void __iomem *EQCQDBregaddr; /* Address to EQCQ_DOORBELL register */ | 386 | } if_type2; |
387 | void __iomem *MQDBregaddr; /* Address to MQ_DOORBELL register */ | 387 | } u; |
388 | void __iomem *BMBXregaddr; /* Address to BootStrap MBX register */ | 388 | |
389 | /* IF type 0, BAR1 and if type 2, Bar 0 CSR register memory map */ | ||
390 | void __iomem *PSMPHRregaddr; | ||
391 | |||
392 | /* Well-known SLI INTF register memory map. */ | ||
393 | void __iomem *SLIINTFregaddr; | ||
394 | |||
395 | /* IF type 0, BAR 1 function CSR register memory map */ | ||
396 | void __iomem *ISRregaddr; /* HST_ISR register */ | ||
397 | void __iomem *IMRregaddr; /* HST_IMR register */ | ||
398 | void __iomem *ISCRregaddr; /* HST_ISCR register */ | ||
399 | /* IF type 0, BAR 0 and if type 2, BAR 0 doorbell register memory map */ | ||
400 | void __iomem *RQDBregaddr; /* RQ_DOORBELL register */ | ||
401 | void __iomem *WQDBregaddr; /* WQ_DOORBELL register */ | ||
402 | void __iomem *EQCQDBregaddr; /* EQCQ_DOORBELL register */ | ||
403 | void __iomem *MQDBregaddr; /* MQ_DOORBELL register */ | ||
404 | void __iomem *BMBXregaddr; /* BootStrap MBX register */ | ||
389 | 405 | ||
390 | uint32_t ue_mask_lo; | 406 | uint32_t ue_mask_lo; |
391 | uint32_t ue_mask_hi; | 407 | uint32_t ue_mask_hi; |