diff options
-rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 4 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 10 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 7 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw4.h | 14 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 28 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 65 |
6 files changed, 103 insertions, 25 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 64d6e3399a68..69da16d63a01 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -695,7 +695,8 @@ struct lpfc_hba { | |||
695 | uint8_t wwnn[8]; | 695 | uint8_t wwnn[8]; |
696 | uint8_t wwpn[8]; | 696 | uint8_t wwpn[8]; |
697 | uint32_t RandomData[7]; | 697 | uint32_t RandomData[7]; |
698 | uint32_t fcp_embed_io; | 698 | uint8_t fcp_embed_io; |
699 | uint8_t mds_diags_support; | ||
699 | 700 | ||
700 | /* HBA Config Parameters */ | 701 | /* HBA Config Parameters */ |
701 | uint32_t cfg_ack0; | 702 | uint32_t cfg_ack0; |
@@ -760,6 +761,7 @@ struct lpfc_hba { | |||
760 | #define LPFC_FDMI_NO_SUPPORT 0 /* FDMI not supported */ | 761 | #define LPFC_FDMI_NO_SUPPORT 0 /* FDMI not supported */ |
761 | #define LPFC_FDMI_SUPPORT 1 /* FDMI supported? */ | 762 | #define LPFC_FDMI_SUPPORT 1 /* FDMI supported? */ |
762 | uint32_t cfg_enable_SmartSAN; | 763 | uint32_t cfg_enable_SmartSAN; |
764 | uint32_t cfg_enable_mds_diags; | ||
763 | lpfc_vpd_t vpd; /* vital product data */ | 765 | lpfc_vpd_t vpd; /* vital product data */ |
764 | 766 | ||
765 | struct pci_dev *pcidev; | 767 | struct pci_dev *pcidev; |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index cfec2eca4dd3..cde7da6af2ea 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -4780,6 +4780,14 @@ LPFC_ATTR_R(prot_sg_seg_cnt, LPFC_DEFAULT_SG_SEG_CNT, | |||
4780 | LPFC_DEFAULT_SG_SEG_CNT, LPFC_MAX_SG_SEG_CNT, | 4780 | LPFC_DEFAULT_SG_SEG_CNT, LPFC_MAX_SG_SEG_CNT, |
4781 | "Max Protection Scatter Gather Segment Count"); | 4781 | "Max Protection Scatter Gather Segment Count"); |
4782 | 4782 | ||
4783 | /* | ||
4784 | * lpfc_enable_mds_diags: Enable MDS Diagnostics | ||
4785 | * 0 = MDS Diagnostics disabled (default) | ||
4786 | * 1 = MDS Diagnostics enabled | ||
4787 | * Value range is [0,1]. Default value is 0. | ||
4788 | */ | ||
4789 | LPFC_ATTR_R(enable_mds_diags, 0, 0, 1, "Enable MDS Diagnostics"); | ||
4790 | |||
4783 | struct device_attribute *lpfc_hba_attrs[] = { | 4791 | struct device_attribute *lpfc_hba_attrs[] = { |
4784 | &dev_attr_bg_info, | 4792 | &dev_attr_bg_info, |
4785 | &dev_attr_bg_guard_err, | 4793 | &dev_attr_bg_guard_err, |
@@ -4876,6 +4884,7 @@ struct device_attribute *lpfc_hba_attrs[] = { | |||
4876 | &dev_attr_lpfc_sriov_hw_max_virtfn, | 4884 | &dev_attr_lpfc_sriov_hw_max_virtfn, |
4877 | &dev_attr_protocol, | 4885 | &dev_attr_protocol, |
4878 | &dev_attr_lpfc_xlane_supported, | 4886 | &dev_attr_lpfc_xlane_supported, |
4887 | &dev_attr_lpfc_enable_mds_diags, | ||
4879 | NULL, | 4888 | NULL, |
4880 | }; | 4889 | }; |
4881 | 4890 | ||
@@ -5867,6 +5876,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) | |||
5867 | lpfc_suppress_link_up_init(phba, lpfc_suppress_link_up); | 5876 | lpfc_suppress_link_up_init(phba, lpfc_suppress_link_up); |
5868 | lpfc_iocb_cnt_init(phba, lpfc_iocb_cnt); | 5877 | lpfc_iocb_cnt_init(phba, lpfc_iocb_cnt); |
5869 | phba->cfg_enable_dss = 1; | 5878 | phba->cfg_enable_dss = 1; |
5879 | lpfc_enable_mds_diags_init(phba, lpfc_enable_mds_diags); | ||
5870 | return; | 5880 | return; |
5871 | } | 5881 | } |
5872 | 5882 | ||
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 861270edd84a..5afbf4d06d53 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -3299,6 +3299,12 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
3299 | FC_VPORT_FABRIC_REJ_WWN); | 3299 | FC_VPORT_FABRIC_REJ_WWN); |
3300 | } | 3300 | } |
3301 | break; | 3301 | break; |
3302 | case LSRJT_VENDOR_UNIQUE: | ||
3303 | if ((stat.un.b.vendorUnique == 0x45) && | ||
3304 | (cmd == ELS_CMD_FLOGI)) { | ||
3305 | goto out_retry; | ||
3306 | } | ||
3307 | break; | ||
3302 | } | 3308 | } |
3303 | break; | 3309 | break; |
3304 | 3310 | ||
@@ -3344,6 +3350,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
3344 | if ((vport->load_flag & FC_UNLOADING) != 0) | 3350 | if ((vport->load_flag & FC_UNLOADING) != 0) |
3345 | retry = 0; | 3351 | retry = 0; |
3346 | 3352 | ||
3353 | out_retry: | ||
3347 | if (retry) { | 3354 | if (retry) { |
3348 | if ((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_FDISC)) { | 3355 | if ((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_FDISC)) { |
3349 | /* Stop retrying PLOGI and FDISC if in FCF discovery */ | 3356 | /* Stop retrying PLOGI and FDISC if in FCF discovery */ |
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 8738b3dc87f1..ee8022737591 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h | |||
@@ -2888,9 +2888,13 @@ struct lpfc_sli4_parameters { | |||
2888 | #define cfg_ext_embed_cb_SHIFT 0 | 2888 | #define cfg_ext_embed_cb_SHIFT 0 |
2889 | #define cfg_ext_embed_cb_MASK 0x00000001 | 2889 | #define cfg_ext_embed_cb_MASK 0x00000001 |
2890 | #define cfg_ext_embed_cb_WORD word19 | 2890 | #define cfg_ext_embed_cb_WORD word19 |
2891 | #define cfg_mds_diags_SHIFT 1 | ||
2892 | #define cfg_mds_diags_MASK 0x00000001 | ||
2893 | #define cfg_mds_diags_WORD word19 | ||
2891 | }; | 2894 | }; |
2892 | 2895 | ||
2893 | #define LPFC_SET_UE_RECOVERY 0x10 | 2896 | #define LPFC_SET_UE_RECOVERY 0x10 |
2897 | #define LPFC_SET_MDS_DIAGS 0x11 | ||
2894 | struct lpfc_mbx_set_feature { | 2898 | struct lpfc_mbx_set_feature { |
2895 | struct mbox_header header; | 2899 | struct mbox_header header; |
2896 | uint32_t feature; | 2900 | uint32_t feature; |
@@ -2899,6 +2903,12 @@ struct lpfc_mbx_set_feature { | |||
2899 | #define lpfc_mbx_set_feature_UER_SHIFT 0 | 2903 | #define lpfc_mbx_set_feature_UER_SHIFT 0 |
2900 | #define lpfc_mbx_set_feature_UER_MASK 0x00000001 | 2904 | #define lpfc_mbx_set_feature_UER_MASK 0x00000001 |
2901 | #define lpfc_mbx_set_feature_UER_WORD word6 | 2905 | #define lpfc_mbx_set_feature_UER_WORD word6 |
2906 | #define lpfc_mbx_set_feature_mds_SHIFT 0 | ||
2907 | #define lpfc_mbx_set_feature_mds_MASK 0x00000001 | ||
2908 | #define lpfc_mbx_set_feature_mds_WORD word6 | ||
2909 | #define lpfc_mbx_set_feature_mds_deep_loopbk_SHIFT 1 | ||
2910 | #define lpfc_mbx_set_feature_mds_deep_loopbk_MASK 0x00000001 | ||
2911 | #define lpfc_mbx_set_feature_mds_deep_loopbk_WORD word6 | ||
2902 | uint32_t word7; | 2912 | uint32_t word7; |
2903 | #define lpfc_mbx_set_feature_UERP_SHIFT 0 | 2913 | #define lpfc_mbx_set_feature_UERP_SHIFT 0 |
2904 | #define lpfc_mbx_set_feature_UERP_MASK 0x0000ffff | 2914 | #define lpfc_mbx_set_feature_UERP_MASK 0x0000ffff |
@@ -3464,6 +3474,8 @@ struct lpfc_acqe_fc_la { | |||
3464 | #define LPFC_FC_LA_TYPE_LINK_UP 0x1 | 3474 | #define LPFC_FC_LA_TYPE_LINK_UP 0x1 |
3465 | #define LPFC_FC_LA_TYPE_LINK_DOWN 0x2 | 3475 | #define LPFC_FC_LA_TYPE_LINK_DOWN 0x2 |
3466 | #define LPFC_FC_LA_TYPE_NO_HARD_ALPA 0x3 | 3476 | #define LPFC_FC_LA_TYPE_NO_HARD_ALPA 0x3 |
3477 | #define LPFC_FC_LA_TYPE_MDS_LINK_DOWN 0x4 | ||
3478 | #define LPFC_FC_LA_TYPE_MDS_LOOPBACK 0x5 | ||
3467 | #define lpfc_acqe_fc_la_port_type_SHIFT 6 | 3479 | #define lpfc_acqe_fc_la_port_type_SHIFT 6 |
3468 | #define lpfc_acqe_fc_la_port_type_MASK 0x00000003 | 3480 | #define lpfc_acqe_fc_la_port_type_MASK 0x00000003 |
3469 | #define lpfc_acqe_fc_la_port_type_WORD word0 | 3481 | #define lpfc_acqe_fc_la_port_type_WORD word0 |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index f11e33ee4132..bb514d2262cf 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -4040,6 +4040,8 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc) | |||
4040 | { | 4040 | { |
4041 | struct lpfc_dmabuf *mp; | 4041 | struct lpfc_dmabuf *mp; |
4042 | LPFC_MBOXQ_t *pmb; | 4042 | LPFC_MBOXQ_t *pmb; |
4043 | MAILBOX_t *mb; | ||
4044 | struct lpfc_mbx_read_top *la; | ||
4043 | int rc; | 4045 | int rc; |
4044 | 4046 | ||
4045 | if (bf_get(lpfc_trailer_type, acqe_fc) != | 4047 | if (bf_get(lpfc_trailer_type, acqe_fc) != |
@@ -4110,6 +4112,24 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc) | |||
4110 | pmb->mbox_cmpl = lpfc_mbx_cmpl_read_topology; | 4112 | pmb->mbox_cmpl = lpfc_mbx_cmpl_read_topology; |
4111 | pmb->vport = phba->pport; | 4113 | pmb->vport = phba->pport; |
4112 | 4114 | ||
4115 | if (phba->sli4_hba.link_state.status != LPFC_FC_LA_TYPE_LINK_UP) { | ||
4116 | /* Parse and translate status field */ | ||
4117 | mb = &pmb->u.mb; | ||
4118 | mb->mbxStatus = lpfc_sli4_parse_latt_fault(phba, | ||
4119 | (void *)acqe_fc); | ||
4120 | |||
4121 | /* Parse and translate link attention fields */ | ||
4122 | la = (struct lpfc_mbx_read_top *)&pmb->u.mb.un.varReadTop; | ||
4123 | la->eventTag = acqe_fc->event_tag; | ||
4124 | bf_set(lpfc_mbx_read_top_att_type, la, | ||
4125 | LPFC_FC_LA_TYPE_LINK_DOWN); | ||
4126 | |||
4127 | /* Invoke the mailbox command callback function */ | ||
4128 | lpfc_mbx_cmpl_read_topology(phba, pmb); | ||
4129 | |||
4130 | return; | ||
4131 | } | ||
4132 | |||
4113 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | 4133 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); |
4114 | if (rc == MBX_NOT_FINISHED) | 4134 | if (rc == MBX_NOT_FINISHED) |
4115 | goto out_free_dmabuf; | 4135 | goto out_free_dmabuf; |
@@ -9585,6 +9605,14 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
9585 | phba->fcp_embed_io = 1; | 9605 | phba->fcp_embed_io = 1; |
9586 | else | 9606 | else |
9587 | phba->fcp_embed_io = 0; | 9607 | phba->fcp_embed_io = 0; |
9608 | |||
9609 | /* | ||
9610 | * Check if the SLI port supports MDS Diagnostics | ||
9611 | */ | ||
9612 | if (bf_get(cfg_mds_diags, mbx_sli4_parameters)) | ||
9613 | phba->mds_diags_support = 1; | ||
9614 | else | ||
9615 | phba->mds_diags_support = 0; | ||
9588 | return 0; | 9616 | return 0; |
9589 | } | 9617 | } |
9590 | 9618 | ||
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index b3a781d38fa8..6eef9720e5c9 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -5691,37 +5691,35 @@ lpfc_sli4_dealloc_extent(struct lpfc_hba *phba, uint16_t type) | |||
5691 | } | 5691 | } |
5692 | 5692 | ||
5693 | void | 5693 | void |
5694 | lpfc_set_features(struct lpfc_hba *phba) | 5694 | lpfc_set_features(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox, |
5695 | uint32_t feature) | ||
5695 | { | 5696 | { |
5696 | LPFC_MBOXQ_t *mbox = NULL; | ||
5697 | uint32_t len; | 5697 | uint32_t len; |
5698 | int rc; | ||
5699 | 5698 | ||
5700 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
5701 | if (!mbox) | ||
5702 | return; | ||
5703 | len = sizeof(struct lpfc_mbx_set_feature) - | 5699 | len = sizeof(struct lpfc_mbx_set_feature) - |
5704 | sizeof(struct lpfc_sli4_cfg_mhdr); | 5700 | sizeof(struct lpfc_sli4_cfg_mhdr); |
5705 | lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON, | 5701 | lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON, |
5706 | LPFC_MBOX_OPCODE_SET_FEATURES, len, | 5702 | LPFC_MBOX_OPCODE_SET_FEATURES, len, |
5707 | LPFC_SLI4_MBX_EMBED); | 5703 | LPFC_SLI4_MBX_EMBED); |
5708 | bf_set(lpfc_mbx_set_feature_UER, | ||
5709 | &mbox->u.mqe.un.set_feature, 1); | ||
5710 | mbox->u.mqe.un.set_feature.feature = LPFC_SET_UE_RECOVERY; | ||
5711 | mbox->u.mqe.un.set_feature.param_len = 8; | ||
5712 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); | ||
5713 | 5704 | ||
5714 | if (rc != MBX_SUCCESS) { | 5705 | switch (feature) { |
5715 | mempool_free(mbox, phba->mbox_mem_pool); | 5706 | case LPFC_SET_UE_RECOVERY: |
5716 | return; | 5707 | bf_set(lpfc_mbx_set_feature_UER, |
5708 | &mbox->u.mqe.un.set_feature, 1); | ||
5709 | mbox->u.mqe.un.set_feature.feature = LPFC_SET_UE_RECOVERY; | ||
5710 | mbox->u.mqe.un.set_feature.param_len = 8; | ||
5711 | break; | ||
5712 | case LPFC_SET_MDS_DIAGS: | ||
5713 | bf_set(lpfc_mbx_set_feature_mds, | ||
5714 | &mbox->u.mqe.un.set_feature, 1); | ||
5715 | bf_set(lpfc_mbx_set_feature_mds_deep_loopbk, | ||
5716 | &mbox->u.mqe.un.set_feature, 0); | ||
5717 | mbox->u.mqe.un.set_feature.feature = LPFC_SET_MDS_DIAGS; | ||
5718 | mbox->u.mqe.un.set_feature.param_len = 8; | ||
5719 | break; | ||
5717 | } | 5720 | } |
5718 | phba->hba_flag |= HBA_RECOVERABLE_UE; | 5721 | |
5719 | phba->eratt_poll_interval = 1; /* Set 1Sec interval to detect UE */ | 5722 | return; |
5720 | phba->sli4_hba.ue_to_sr = bf_get(lpfc_mbx_set_feature_UESR, | ||
5721 | &mbox->u.mqe.un.set_feature); | ||
5722 | phba->sli4_hba.ue_to_rp = bf_get(lpfc_mbx_set_feature_UERP, | ||
5723 | &mbox->u.mqe.un.set_feature); | ||
5724 | mempool_free(mbox, phba->mbox_mem_pool); | ||
5725 | } | 5723 | } |
5726 | 5724 | ||
5727 | /** | 5725 | /** |
@@ -6449,8 +6447,29 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
6449 | } | 6447 | } |
6450 | 6448 | ||
6451 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == | 6449 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == |
6452 | LPFC_SLI_INTF_IF_TYPE_0) | 6450 | LPFC_SLI_INTF_IF_TYPE_0) { |
6453 | lpfc_set_features(phba); | 6451 | lpfc_set_features(phba, mboxq, LPFC_SET_UE_RECOVERY); |
6452 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | ||
6453 | if (rc == MBX_SUCCESS) { | ||
6454 | phba->hba_flag |= HBA_RECOVERABLE_UE; | ||
6455 | /* Set 1Sec interval to detect UE */ | ||
6456 | phba->eratt_poll_interval = 1; | ||
6457 | phba->sli4_hba.ue_to_sr = bf_get( | ||
6458 | lpfc_mbx_set_feature_UESR, | ||
6459 | &mboxq->u.mqe.un.set_feature); | ||
6460 | phba->sli4_hba.ue_to_rp = bf_get( | ||
6461 | lpfc_mbx_set_feature_UERP, | ||
6462 | &mboxq->u.mqe.un.set_feature); | ||
6463 | } | ||
6464 | } | ||
6465 | |||
6466 | if (phba->cfg_enable_mds_diags && phba->mds_diags_support) { | ||
6467 | /* Enable MDS Diagnostics only if the SLI Port supports it */ | ||
6468 | lpfc_set_features(phba, mboxq, LPFC_SET_MDS_DIAGS); | ||
6469 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | ||
6470 | if (rc != MBX_SUCCESS) | ||
6471 | phba->mds_diags_support = 0; | ||
6472 | } | ||
6454 | 6473 | ||
6455 | /* | 6474 | /* |
6456 | * Discover the port's supported feature set and match it against the | 6475 | * Discover the port's supported feature set and match it against the |