aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c101
1 files changed, 85 insertions, 16 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 70edf21ae1b9..351d08ace24a 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -2947,8 +2947,8 @@ void lpfc_poll_eratt(unsigned long ptr)
else
cnt = (sli_intr - phba->sli.slistat.sli_prev_intr);
- /* 64-bit integer division not supporte on 32-bit x86 - use do_div */
- do_div(cnt, LPFC_ERATT_POLL_INTERVAL);
+ /* 64-bit integer division not supported on 32-bit x86 - use do_div */
+ do_div(cnt, phba->eratt_poll_interval);
phba->sli.slistat.sli_ips = cnt;
phba->sli.slistat.sli_prev_intr = sli_intr;
@@ -2963,7 +2963,7 @@ void lpfc_poll_eratt(unsigned long ptr)
/* Restart the timer for next eratt poll */
mod_timer(&phba->eratt_poll,
jiffies +
- msecs_to_jiffies(1000 * LPFC_ERATT_POLL_INTERVAL));
+ msecs_to_jiffies(1000 * phba->eratt_poll_interval));
return;
}
@@ -4665,13 +4665,13 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba)
int mode = 3, i;
int longs;
- switch (lpfc_sli_mode) {
+ switch (phba->cfg_sli_mode) {
case 2:
if (phba->cfg_enable_npiv) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_VPORT,
- "1824 NPIV enabled: Override lpfc_sli_mode "
+ "1824 NPIV enabled: Override sli_mode "
"parameter (%d) to auto (0).\n",
- lpfc_sli_mode);
+ phba->cfg_sli_mode);
break;
}
mode = 2;
@@ -4681,8 +4681,8 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba)
break;
default:
lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_VPORT,
- "1819 Unrecognized lpfc_sli_mode "
- "parameter: %d.\n", lpfc_sli_mode);
+ "1819 Unrecognized sli_mode parameter: %d.\n",
+ phba->cfg_sli_mode);
break;
}
@@ -4690,12 +4690,14 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba)
rc = lpfc_sli_config_port(phba, mode);
- if (rc && lpfc_sli_mode == 3)
+ if (rc && phba->cfg_sli_mode == 3)
lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_VPORT,
"1820 Unable to select SLI-3. "
"Not supported by adapter.\n");
if (rc && mode != 2)
rc = lpfc_sli_config_port(phba, 2);
+ else if (rc && mode == 2)
+ rc = lpfc_sli_config_port(phba, 3);
if (rc)
goto lpfc_sli_hba_setup_error;
@@ -5690,6 +5692,38 @@ lpfc_sli4_dealloc_extent(struct lpfc_hba *phba, uint16_t type)
return rc;
}
+void
+lpfc_set_features(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox,
+ uint32_t feature)
+{
+ uint32_t len;
+
+ len = sizeof(struct lpfc_mbx_set_feature) -
+ sizeof(struct lpfc_sli4_cfg_mhdr);
+ lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON,
+ LPFC_MBOX_OPCODE_SET_FEATURES, len,
+ LPFC_SLI4_MBX_EMBED);
+
+ switch (feature) {
+ case LPFC_SET_UE_RECOVERY:
+ bf_set(lpfc_mbx_set_feature_UER,
+ &mbox->u.mqe.un.set_feature, 1);
+ mbox->u.mqe.un.set_feature.feature = LPFC_SET_UE_RECOVERY;
+ mbox->u.mqe.un.set_feature.param_len = 8;
+ break;
+ case LPFC_SET_MDS_DIAGS:
+ bf_set(lpfc_mbx_set_feature_mds,
+ &mbox->u.mqe.un.set_feature, 1);
+ bf_set(lpfc_mbx_set_feature_mds_deep_loopbk,
+ &mbox->u.mqe.un.set_feature, 0);
+ mbox->u.mqe.un.set_feature.feature = LPFC_SET_MDS_DIAGS;
+ mbox->u.mqe.un.set_feature.param_len = 8;
+ break;
+ }
+
+ return;
+}
+
/**
* lpfc_sli4_alloc_resource_identifiers - Allocate all SLI4 resource extents.
* @phba: Pointer to HBA context object.
@@ -6414,6 +6448,30 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
phba->pport->cfg_lun_queue_depth = rc;
}
+ if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
+ LPFC_SLI_INTF_IF_TYPE_0) {
+ lpfc_set_features(phba, mboxq, LPFC_SET_UE_RECOVERY);
+ rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
+ if (rc == MBX_SUCCESS) {
+ phba->hba_flag |= HBA_RECOVERABLE_UE;
+ /* Set 1Sec interval to detect UE */
+ phba->eratt_poll_interval = 1;
+ phba->sli4_hba.ue_to_sr = bf_get(
+ lpfc_mbx_set_feature_UESR,
+ &mboxq->u.mqe.un.set_feature);
+ phba->sli4_hba.ue_to_rp = bf_get(
+ lpfc_mbx_set_feature_UERP,
+ &mboxq->u.mqe.un.set_feature);
+ }
+ }
+
+ if (phba->cfg_enable_mds_diags && phba->mds_diags_support) {
+ /* Enable MDS Diagnostics only if the SLI Port supports it */
+ lpfc_set_features(phba, mboxq, LPFC_SET_MDS_DIAGS);
+ rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
+ if (rc != MBX_SUCCESS)
+ phba->mds_diags_support = 0;
+ }
/*
* Discover the port's supported feature set and match it against the
@@ -6612,7 +6670,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
/* Start error attention (ERATT) polling timer */
mod_timer(&phba->eratt_poll,
- jiffies + msecs_to_jiffies(1000 * LPFC_ERATT_POLL_INTERVAL));
+ jiffies + msecs_to_jiffies(1000 * phba->eratt_poll_interval));
/* Enable PCIe device Advanced Error Reporting (AER) if configured */
if (phba->cfg_aer_support == 1 && !(phba->hba_flag & HBA_AER_ENABLED)) {
@@ -8383,8 +8441,11 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 1);
if (iocbq->iocb_flag & LPFC_IO_OAS) {
bf_set(wqe_oas, &wqe->fcp_iwrite.wqe_com, 1);
- if (phba->cfg_XLanePriority) {
- bf_set(wqe_ccpe, &wqe->fcp_iwrite.wqe_com, 1);
+ bf_set(wqe_ccpe, &wqe->fcp_iwrite.wqe_com, 1);
+ if (iocbq->priority) {
+ bf_set(wqe_ccp, &wqe->fcp_iwrite.wqe_com,
+ (iocbq->priority << 1));
+ } else {
bf_set(wqe_ccp, &wqe->fcp_iwrite.wqe_com,
(phba->cfg_XLanePriority << 1));
}
@@ -8439,8 +8500,11 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
bf_set(wqe_dbde, &wqe->fcp_iread.wqe_com, 1);
if (iocbq->iocb_flag & LPFC_IO_OAS) {
bf_set(wqe_oas, &wqe->fcp_iread.wqe_com, 1);
- if (phba->cfg_XLanePriority) {
- bf_set(wqe_ccpe, &wqe->fcp_iread.wqe_com, 1);
+ bf_set(wqe_ccpe, &wqe->fcp_iread.wqe_com, 1);
+ if (iocbq->priority) {
+ bf_set(wqe_ccp, &wqe->fcp_iread.wqe_com,
+ (iocbq->priority << 1));
+ } else {
bf_set(wqe_ccp, &wqe->fcp_iread.wqe_com,
(phba->cfg_XLanePriority << 1));
}
@@ -8494,8 +8558,11 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
iocbq->iocb.ulpFCP2Rcvy);
if (iocbq->iocb_flag & LPFC_IO_OAS) {
bf_set(wqe_oas, &wqe->fcp_icmd.wqe_com, 1);
- if (phba->cfg_XLanePriority) {
- bf_set(wqe_ccpe, &wqe->fcp_icmd.wqe_com, 1);
+ bf_set(wqe_ccpe, &wqe->fcp_icmd.wqe_com, 1);
+ if (iocbq->priority) {
+ bf_set(wqe_ccp, &wqe->fcp_icmd.wqe_com,
+ (iocbq->priority << 1));
+ } else {
bf_set(wqe_ccp, &wqe->fcp_icmd.wqe_com,
(phba->cfg_XLanePriority << 1));
}
@@ -10136,6 +10203,7 @@ lpfc_sli_sum_iocb(struct lpfc_vport *vport, uint16_t tgt_id, uint64_t lun_id,
struct lpfc_iocbq *iocbq;
int sum, i;
+ spin_lock_irq(&phba->hbalock);
for (i = 1, sum = 0; i <= phba->sli.last_iotag; i++) {
iocbq = phba->sli.iocbq_lookup[i];
@@ -10143,6 +10211,7 @@ lpfc_sli_sum_iocb(struct lpfc_vport *vport, uint16_t tgt_id, uint64_t lun_id,
ctx_cmd) == 0)
sum++;
}
+ spin_unlock_irq(&phba->hbalock);
return sum;
}