scsi: lpfc: Add reporting capability for Link Degrade Signaling
Firmware reports link degrade signaling via ACQES. Handlers and new additions to the SET_FEATURES mbox command are implemented so that link degrade parameters for 64GB capable links are reported through EDC ELS frames. Link: https://lore.kernel.org/r/20220911221505.117655-12-jsmart2021@gmail.com Co-developed-by: Justin Tee <justin.tee@broadcom.com> Signed-off-by: Justin Tee <justin.tee@broadcom.com> Signed-off-by: James Smart <jsmart2021@gmail.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
045c58c875
commit
dbb1e2ff87
|
@ -403,6 +403,7 @@ struct lpfc_trunk_link {
|
|||
link1,
|
||||
link2,
|
||||
link3;
|
||||
u32 phy_lnk_speed;
|
||||
};
|
||||
|
||||
/* Format of congestion module parameters */
|
||||
|
@ -1596,6 +1597,11 @@ struct lpfc_hba {
|
|||
|
||||
char os_host_name[MAXHOSTNAMELEN];
|
||||
|
||||
/* LD Signaling */
|
||||
u32 degrade_activate_threshold;
|
||||
u32 degrade_deactivate_threshold;
|
||||
u32 fec_degrade_interval;
|
||||
|
||||
atomic_t dbg_log_idx;
|
||||
atomic_t dbg_log_cnt;
|
||||
atomic_t dbg_log_dmping;
|
||||
|
|
|
@ -78,6 +78,7 @@ int lpfc_init_iocb_list(struct lpfc_hba *phba, int cnt);
|
|||
void lpfc_free_iocb_list(struct lpfc_hba *phba);
|
||||
int lpfc_post_rq_buffer(struct lpfc_hba *phba, struct lpfc_queue *hrq,
|
||||
struct lpfc_queue *drq, int count, int idx);
|
||||
int lpfc_read_lds_params(struct lpfc_hba *phba);
|
||||
uint32_t lpfc_calc_cmf_latency(struct lpfc_hba *phba);
|
||||
void lpfc_cmf_signal_init(struct lpfc_hba *phba);
|
||||
void lpfc_cmf_start(struct lpfc_hba *phba);
|
||||
|
|
|
@ -3988,7 +3988,8 @@ lpfc_cmpl_els_edc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
|||
goto out;
|
||||
|
||||
/* ELS cmd tag <ulpIoTag> completes */
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_ELS | LOG_CGN_MGMT,
|
||||
lpfc_printf_log(phba, KERN_INFO,
|
||||
LOG_ELS | LOG_CGN_MGMT | LOG_LDS_EVENT,
|
||||
"4676 Fabric EDC Rsp: "
|
||||
"0x%02x, 0x%08x\n",
|
||||
edc_rsp->acc_hdr.la_cmd,
|
||||
|
@ -4025,18 +4026,18 @@ lpfc_cmpl_els_edc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
|||
if (bytes_remain < FC_TLV_DESC_SZ_FROM_LENGTH(tlv) ||
|
||||
FC_TLV_DESC_SZ_FROM_LENGTH(tlv) !=
|
||||
sizeof(struct fc_diag_lnkflt_desc)) {
|
||||
lpfc_printf_log(
|
||||
phba, KERN_WARNING, LOG_CGN_MGMT,
|
||||
lpfc_printf_log(phba, KERN_WARNING,
|
||||
LOG_ELS | LOG_CGN_MGMT | LOG_LDS_EVENT,
|
||||
"6462 Truncated Link Fault Diagnostic "
|
||||
"descriptor[%d]: %d vs 0x%zx 0x%zx\n",
|
||||
desc_cnt, bytes_remain,
|
||||
FC_TLV_DESC_SZ_FROM_LENGTH(tlv),
|
||||
sizeof(struct fc_diag_cg_sig_desc));
|
||||
sizeof(struct fc_diag_lnkflt_desc));
|
||||
goto out;
|
||||
}
|
||||
plnkflt = (struct fc_diag_lnkflt_desc *)tlv;
|
||||
lpfc_printf_log(
|
||||
phba, KERN_INFO, LOG_ELS | LOG_CGN_MGMT,
|
||||
lpfc_printf_log(phba, KERN_INFO,
|
||||
LOG_ELS | LOG_LDS_EVENT,
|
||||
"4617 Link Fault Desc Data: 0x%08x 0x%08x "
|
||||
"0x%08x 0x%08x 0x%08x\n",
|
||||
be32_to_cpu(plnkflt->desc_tag),
|
||||
|
@ -4116,8 +4117,26 @@ out:
|
|||
}
|
||||
|
||||
static void
|
||||
lpfc_format_edc_cgn_desc(struct lpfc_hba *phba, struct fc_diag_cg_sig_desc *cgd)
|
||||
lpfc_format_edc_lft_desc(struct lpfc_hba *phba, struct fc_tlv_desc *tlv)
|
||||
{
|
||||
struct fc_diag_lnkflt_desc *lft = (struct fc_diag_lnkflt_desc *)tlv;
|
||||
|
||||
lft->desc_tag = cpu_to_be32(ELS_DTAG_LNK_FAULT_CAP);
|
||||
lft->desc_len = cpu_to_be32(
|
||||
FC_TLV_DESC_LENGTH_FROM_SZ(struct fc_diag_lnkflt_desc));
|
||||
|
||||
lft->degrade_activate_threshold =
|
||||
cpu_to_be32(phba->degrade_activate_threshold);
|
||||
lft->degrade_deactivate_threshold =
|
||||
cpu_to_be32(phba->degrade_deactivate_threshold);
|
||||
lft->fec_degrade_interval = cpu_to_be32(phba->fec_degrade_interval);
|
||||
}
|
||||
|
||||
static void
|
||||
lpfc_format_edc_cgn_desc(struct lpfc_hba *phba, struct fc_tlv_desc *tlv)
|
||||
{
|
||||
struct fc_diag_cg_sig_desc *cgd = (struct fc_diag_cg_sig_desc *)tlv;
|
||||
|
||||
/* We are assuming cgd was zero'ed before calling this routine */
|
||||
|
||||
/* Configure the congestion detection capability */
|
||||
|
@ -4161,6 +4180,23 @@ lpfc_format_edc_cgn_desc(struct lpfc_hba *phba, struct fc_diag_cg_sig_desc *cgd)
|
|||
cpu_to_be16(EDC_CG_SIGFREQ_MSEC);
|
||||
}
|
||||
|
||||
static bool
|
||||
lpfc_link_is_lds_capable(struct lpfc_hba *phba)
|
||||
{
|
||||
if (!(phba->lmt & LMT_64Gb))
|
||||
return false;
|
||||
if (phba->sli_rev != LPFC_SLI_REV4)
|
||||
return false;
|
||||
|
||||
if (phba->sli4_hba.conf_trunk) {
|
||||
if (phba->trunk_link.phy_lnk_speed == LPFC_USER_LINK_SPEED_64G)
|
||||
return true;
|
||||
} else if (phba->fc_linkspeed == LPFC_LINK_SPEED_64GHZ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_issue_els_edc - Exchange Diagnostic Capabilities with the fabric.
|
||||
* @vport: pointer to a host virtual N_Port data structure.
|
||||
|
@ -4188,12 +4224,12 @@ lpfc_issue_els_edc(struct lpfc_vport *vport, uint8_t retry)
|
|||
{
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
struct lpfc_iocbq *elsiocb;
|
||||
struct lpfc_els_edc_req *edc_req;
|
||||
struct fc_diag_cg_sig_desc *cgn_desc;
|
||||
struct fc_els_edc *edc_req;
|
||||
struct fc_tlv_desc *tlv;
|
||||
u16 cmdsize;
|
||||
struct lpfc_nodelist *ndlp;
|
||||
u8 *pcmd = NULL;
|
||||
u32 edc_req_size, cgn_desc_size;
|
||||
u32 cgn_desc_size, lft_desc_size;
|
||||
int rc;
|
||||
|
||||
if (vport->port_type == LPFC_NPIV_PORT)
|
||||
|
@ -4203,13 +4239,17 @@ lpfc_issue_els_edc(struct lpfc_vport *vport, uint8_t retry)
|
|||
if (!ndlp || ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)
|
||||
return -ENODEV;
|
||||
|
||||
/* If HBA doesn't support signals, drop into RDF */
|
||||
if (!phba->cgn_init_reg_signal)
|
||||
cgn_desc_size = (phba->cgn_init_reg_signal) ?
|
||||
sizeof(struct fc_diag_cg_sig_desc) : 0;
|
||||
lft_desc_size = (lpfc_link_is_lds_capable(phba)) ?
|
||||
sizeof(struct fc_diag_lnkflt_desc) : 0;
|
||||
cmdsize = cgn_desc_size + lft_desc_size;
|
||||
|
||||
/* Skip EDC if no applicable descriptors */
|
||||
if (!cmdsize)
|
||||
goto try_rdf;
|
||||
|
||||
edc_req_size = sizeof(struct fc_els_edc);
|
||||
cgn_desc_size = sizeof(struct fc_diag_cg_sig_desc);
|
||||
cmdsize = edc_req_size + cgn_desc_size;
|
||||
cmdsize += sizeof(struct fc_els_edc);
|
||||
elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
|
||||
ndlp->nlp_DID, ELS_CMD_EDC);
|
||||
if (!elsiocb)
|
||||
|
@ -4218,15 +4258,19 @@ lpfc_issue_els_edc(struct lpfc_vport *vport, uint8_t retry)
|
|||
/* Configure the payload for the supported Diagnostics capabilities. */
|
||||
pcmd = (u8 *)elsiocb->cmd_dmabuf->virt;
|
||||
memset(pcmd, 0, cmdsize);
|
||||
edc_req = (struct lpfc_els_edc_req *)pcmd;
|
||||
edc_req->edc.desc_len = cpu_to_be32(cgn_desc_size);
|
||||
edc_req->edc.edc_cmd = ELS_EDC;
|
||||
edc_req = (struct fc_els_edc *)pcmd;
|
||||
edc_req->desc_len = cpu_to_be32(cgn_desc_size + lft_desc_size);
|
||||
edc_req->edc_cmd = ELS_EDC;
|
||||
tlv = edc_req->desc;
|
||||
|
||||
cgn_desc = &edc_req->cgn_desc;
|
||||
if (cgn_desc_size) {
|
||||
lpfc_format_edc_cgn_desc(phba, tlv);
|
||||
phba->cgn_sig_freq = lpfc_fabric_cgn_frequency;
|
||||
tlv = fc_tlv_next_desc(tlv);
|
||||
}
|
||||
|
||||
lpfc_format_edc_cgn_desc(phba, cgn_desc);
|
||||
|
||||
phba->cgn_sig_freq = lpfc_fabric_cgn_frequency;
|
||||
if (lft_desc_size)
|
||||
lpfc_format_edc_lft_desc(phba, tlv);
|
||||
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS | LOG_CGN_MGMT,
|
||||
"4623 Xmit EDC to remote "
|
||||
|
@ -5780,14 +5824,21 @@ lpfc_issue_els_edc_rsp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
|||
struct lpfc_nodelist *ndlp)
|
||||
{
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
struct lpfc_els_edc_rsp *edc_rsp;
|
||||
struct fc_els_edc_resp *edc_rsp;
|
||||
struct fc_tlv_desc *tlv;
|
||||
struct lpfc_iocbq *elsiocb;
|
||||
IOCB_t *icmd, *cmd;
|
||||
union lpfc_wqe128 *wqe;
|
||||
u32 cgn_desc_size, lft_desc_size;
|
||||
u16 cmdsize;
|
||||
uint8_t *pcmd;
|
||||
int cmdsize, rc;
|
||||
int rc;
|
||||
|
||||
cmdsize = sizeof(struct lpfc_els_edc_rsp);
|
||||
cmdsize = sizeof(struct fc_els_edc_resp);
|
||||
cgn_desc_size = sizeof(struct fc_diag_cg_sig_desc);
|
||||
lft_desc_size = (lpfc_link_is_lds_capable(phba)) ?
|
||||
sizeof(struct fc_diag_lnkflt_desc) : 0;
|
||||
cmdsize += cgn_desc_size + lft_desc_size;
|
||||
elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, cmdiocb->retry,
|
||||
ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
|
||||
if (!elsiocb)
|
||||
|
@ -5809,15 +5860,19 @@ lpfc_issue_els_edc_rsp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
|||
pcmd = elsiocb->cmd_dmabuf->virt;
|
||||
memset(pcmd, 0, cmdsize);
|
||||
|
||||
edc_rsp = (struct lpfc_els_edc_rsp *)pcmd;
|
||||
edc_rsp->edc_rsp.acc_hdr.la_cmd = ELS_LS_ACC;
|
||||
edc_rsp->edc_rsp.desc_list_len = cpu_to_be32(
|
||||
FC_TLV_DESC_LENGTH_FROM_SZ(struct lpfc_els_edc_rsp));
|
||||
edc_rsp->edc_rsp.lsri.desc_tag = cpu_to_be32(ELS_DTAG_LS_REQ_INFO);
|
||||
edc_rsp->edc_rsp.lsri.desc_len = cpu_to_be32(
|
||||
edc_rsp = (struct fc_els_edc_resp *)pcmd;
|
||||
edc_rsp->acc_hdr.la_cmd = ELS_LS_ACC;
|
||||
edc_rsp->desc_list_len = cpu_to_be32(sizeof(struct fc_els_lsri_desc) +
|
||||
cgn_desc_size + lft_desc_size);
|
||||
edc_rsp->lsri.desc_tag = cpu_to_be32(ELS_DTAG_LS_REQ_INFO);
|
||||
edc_rsp->lsri.desc_len = cpu_to_be32(
|
||||
FC_TLV_DESC_LENGTH_FROM_SZ(struct fc_els_lsri_desc));
|
||||
edc_rsp->edc_rsp.lsri.rqst_w0.cmd = ELS_EDC;
|
||||
lpfc_format_edc_cgn_desc(phba, &edc_rsp->cgn_desc);
|
||||
edc_rsp->lsri.rqst_w0.cmd = ELS_EDC;
|
||||
tlv = edc_rsp->desc;
|
||||
lpfc_format_edc_cgn_desc(phba, tlv);
|
||||
tlv = fc_tlv_next_desc(tlv);
|
||||
if (lft_desc_size)
|
||||
lpfc_format_edc_lft_desc(phba, tlv);
|
||||
|
||||
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
|
||||
"Issue EDC ACC: did:x%x flg:x%x refcnt %d",
|
||||
|
@ -9082,7 +9137,7 @@ lpfc_els_rcv_edc(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
|||
uint32_t *ptr, dtag;
|
||||
const char *dtag_nm;
|
||||
int desc_cnt = 0, bytes_remain;
|
||||
bool rcv_cap_desc = false;
|
||||
struct fc_diag_lnkflt_desc *plnkflt;
|
||||
|
||||
payload = cmdiocb->cmd_dmabuf->virt;
|
||||
|
||||
|
@ -9090,7 +9145,8 @@ lpfc_els_rcv_edc(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
|||
bytes_remain = be32_to_cpu(edc_req->desc_len);
|
||||
|
||||
ptr = (uint32_t *)payload;
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS | LOG_CGN_MGMT,
|
||||
lpfc_printf_vlog(vport, KERN_INFO,
|
||||
LOG_ELS | LOG_CGN_MGMT | LOG_LDS_EVENT,
|
||||
"3319 Rcv EDC payload len %d: x%x x%x x%x\n",
|
||||
bytes_remain, be32_to_cpu(*ptr),
|
||||
be32_to_cpu(*(ptr + 1)), be32_to_cpu(*(ptr + 2)));
|
||||
|
@ -9109,9 +9165,10 @@ lpfc_els_rcv_edc(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
|||
* cycle through EDC diagnostic descriptors to find the
|
||||
* congestion signaling capability descriptor
|
||||
*/
|
||||
while (bytes_remain && !rcv_cap_desc) {
|
||||
while (bytes_remain) {
|
||||
if (bytes_remain < FC_TLV_DESC_HDR_SZ) {
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_CGN_MGMT,
|
||||
lpfc_printf_log(phba, KERN_WARNING,
|
||||
LOG_ELS | LOG_CGN_MGMT | LOG_LDS_EVENT,
|
||||
"6464 Truncated TLV hdr on "
|
||||
"Diagnostic descriptor[%d]\n",
|
||||
desc_cnt);
|
||||
|
@ -9124,16 +9181,27 @@ lpfc_els_rcv_edc(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
|||
if (bytes_remain < FC_TLV_DESC_SZ_FROM_LENGTH(tlv) ||
|
||||
FC_TLV_DESC_SZ_FROM_LENGTH(tlv) !=
|
||||
sizeof(struct fc_diag_lnkflt_desc)) {
|
||||
lpfc_printf_log(
|
||||
phba, KERN_WARNING, LOG_CGN_MGMT,
|
||||
lpfc_printf_log(phba, KERN_WARNING,
|
||||
LOG_ELS | LOG_CGN_MGMT | LOG_LDS_EVENT,
|
||||
"6465 Truncated Link Fault Diagnostic "
|
||||
"descriptor[%d]: %d vs 0x%zx 0x%zx\n",
|
||||
desc_cnt, bytes_remain,
|
||||
FC_TLV_DESC_SZ_FROM_LENGTH(tlv),
|
||||
sizeof(struct fc_diag_cg_sig_desc));
|
||||
sizeof(struct fc_diag_lnkflt_desc));
|
||||
goto out;
|
||||
}
|
||||
/* No action for Link Fault descriptor for now */
|
||||
plnkflt = (struct fc_diag_lnkflt_desc *)tlv;
|
||||
lpfc_printf_log(phba, KERN_INFO,
|
||||
LOG_ELS | LOG_LDS_EVENT,
|
||||
"4626 Link Fault Desc Data: x%08x len x%x "
|
||||
"da x%x dd x%x interval x%x\n",
|
||||
be32_to_cpu(plnkflt->desc_tag),
|
||||
be32_to_cpu(plnkflt->desc_len),
|
||||
be32_to_cpu(
|
||||
plnkflt->degrade_activate_threshold),
|
||||
be32_to_cpu(
|
||||
plnkflt->degrade_deactivate_threshold),
|
||||
be32_to_cpu(plnkflt->fec_degrade_interval));
|
||||
break;
|
||||
case ELS_DTAG_CG_SIGNAL_CAP:
|
||||
if (bytes_remain < FC_TLV_DESC_SZ_FROM_LENGTH(tlv) ||
|
||||
|
@ -9160,11 +9228,11 @@ lpfc_els_rcv_edc(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
|||
|
||||
lpfc_least_capable_settings(
|
||||
phba, (struct fc_diag_cg_sig_desc *)tlv);
|
||||
rcv_cap_desc = true;
|
||||
break;
|
||||
default:
|
||||
dtag_nm = lpfc_get_tlv_dtag_nm(dtag);
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_CGN_MGMT,
|
||||
lpfc_printf_log(phba, KERN_WARNING,
|
||||
LOG_ELS | LOG_CGN_MGMT | LOG_LDS_EVENT,
|
||||
"6467 unknown Diagnostic "
|
||||
"Descriptor[%d]: tag x%x (%s)\n",
|
||||
desc_cnt, dtag, dtag_nm);
|
||||
|
|
|
@ -1242,6 +1242,8 @@ lpfc_linkdown(struct lpfc_hba *phba)
|
|||
phba->trunk_link.link1.state = 0;
|
||||
phba->trunk_link.link2.state = 0;
|
||||
phba->trunk_link.link3.state = 0;
|
||||
phba->trunk_link.phy_lnk_speed =
|
||||
LPFC_LINK_SPEED_UNKNOWN;
|
||||
phba->sli4_hba.link_state.logical_speed =
|
||||
LPFC_LINK_SPEED_UNKNOWN;
|
||||
}
|
||||
|
@ -3794,6 +3796,9 @@ lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
|||
if (phba->cmf_active_mode != LPFC_CFG_OFF)
|
||||
lpfc_cmf_signal_init(phba);
|
||||
|
||||
if (phba->lmt & LMT_64Gb)
|
||||
lpfc_read_lds_params(phba);
|
||||
|
||||
} else if (attn_type == LPFC_ATT_LINK_DOWN ||
|
||||
attn_type == LPFC_ATT_UNEXP_WWPN) {
|
||||
phba->fc_stat.LinkDown++;
|
||||
|
@ -4393,8 +4398,11 @@ out:
|
|||
rc = lpfc_issue_els_edc(vport, 0);
|
||||
lpfc_printf_log(phba, KERN_INFO,
|
||||
LOG_INIT | LOG_ELS | LOG_DISCOVERY,
|
||||
"4220 EDC issue error x%x, Data: x%x\n",
|
||||
"4220 Issue EDC status x%x Data x%x\n",
|
||||
rc, phba->cgn_init_reg_signal);
|
||||
} else if (phba->lmt & LMT_64Gb) {
|
||||
/* may send link fault capability descriptor */
|
||||
lpfc_issue_els_edc(vport, 0);
|
||||
} else {
|
||||
lpfc_issue_els_rdf(vport, 0);
|
||||
}
|
||||
|
|
|
@ -3484,9 +3484,10 @@ struct lpfc_sli4_parameters {
|
|||
|
||||
#define LPFC_SET_UE_RECOVERY 0x10
|
||||
#define LPFC_SET_MDS_DIAGS 0x12
|
||||
#define LPFC_SET_CGN_SIGNAL 0x1f
|
||||
#define LPFC_SET_DUAL_DUMP 0x1e
|
||||
#define LPFC_SET_CGN_SIGNAL 0x1f
|
||||
#define LPFC_SET_ENABLE_MI 0x21
|
||||
#define LPFC_SET_LD_SIGNAL 0x23
|
||||
#define LPFC_SET_ENABLE_CMF 0x24
|
||||
struct lpfc_mbx_set_feature {
|
||||
struct mbox_header header;
|
||||
|
@ -3517,13 +3518,17 @@ struct lpfc_mbx_set_feature {
|
|||
#define lpfc_mbx_set_feature_cmf_SHIFT 0
|
||||
#define lpfc_mbx_set_feature_cmf_MASK 0x00000001
|
||||
#define lpfc_mbx_set_feature_cmf_WORD word6
|
||||
#define lpfc_mbx_set_feature_lds_qry_SHIFT 0
|
||||
#define lpfc_mbx_set_feature_lds_qry_MASK 0x00000001
|
||||
#define lpfc_mbx_set_feature_lds_qry_WORD word6
|
||||
#define LPFC_QUERY_LDS_OP 1
|
||||
#define lpfc_mbx_set_feature_mi_SHIFT 0
|
||||
#define lpfc_mbx_set_feature_mi_MASK 0x0000ffff
|
||||
#define lpfc_mbx_set_feature_mi_WORD word6
|
||||
#define lpfc_mbx_set_feature_milunq_SHIFT 16
|
||||
#define lpfc_mbx_set_feature_milunq_MASK 0x0000ffff
|
||||
#define lpfc_mbx_set_feature_milunq_WORD word6
|
||||
uint32_t word7;
|
||||
u32 word7;
|
||||
#define lpfc_mbx_set_feature_UERP_SHIFT 0
|
||||
#define lpfc_mbx_set_feature_UERP_MASK 0x0000ffff
|
||||
#define lpfc_mbx_set_feature_UERP_WORD word7
|
||||
|
@ -3537,6 +3542,8 @@ struct lpfc_mbx_set_feature {
|
|||
#define lpfc_mbx_set_feature_CGN_acqe_freq_SHIFT 0
|
||||
#define lpfc_mbx_set_feature_CGN_acqe_freq_MASK 0x000000ff
|
||||
#define lpfc_mbx_set_feature_CGN_acqe_freq_WORD word8
|
||||
u32 word9;
|
||||
u32 word10;
|
||||
};
|
||||
|
||||
|
||||
|
@ -4314,7 +4321,7 @@ struct lpfc_acqe_cgn_signal {
|
|||
struct lpfc_acqe_sli {
|
||||
uint32_t event_data1;
|
||||
uint32_t event_data2;
|
||||
uint32_t reserved;
|
||||
uint32_t event_data3;
|
||||
uint32_t trailer;
|
||||
#define LPFC_SLI_EVENT_TYPE_PORT_ERROR 0x1
|
||||
#define LPFC_SLI_EVENT_TYPE_OVER_TEMP 0x2
|
||||
|
@ -4327,6 +4334,7 @@ struct lpfc_acqe_sli {
|
|||
#define LPFC_SLI_EVENT_TYPE_MISCONF_FAWWN 0xF
|
||||
#define LPFC_SLI_EVENT_TYPE_EEPROM_FAILURE 0x10
|
||||
#define LPFC_SLI_EVENT_TYPE_CGN_SIGNAL 0x11
|
||||
#define LPFC_SLI_EVENT_TYPE_RD_SIGNAL 0x12
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -5050,22 +5058,6 @@ struct lpfc_grp_hdr {
|
|||
{ FPIN_CONGN_SEVERITY_ERROR, "Alarm" }, \
|
||||
}
|
||||
|
||||
/* EDC supports two descriptors. When allocated, it is the
|
||||
* size of this structure plus each supported descriptor.
|
||||
*/
|
||||
struct lpfc_els_edc_req {
|
||||
struct fc_els_edc edc; /* hdr up to descriptors */
|
||||
struct fc_diag_cg_sig_desc cgn_desc; /* 1st descriptor */
|
||||
};
|
||||
|
||||
/* Minimum structure defines for the EDC response.
|
||||
* Balance is in buffer.
|
||||
*/
|
||||
struct lpfc_els_edc_rsp {
|
||||
struct fc_els_edc_resp edc_rsp; /* hdr up to descriptors */
|
||||
struct fc_diag_cg_sig_desc cgn_desc; /* 1st descriptor */
|
||||
};
|
||||
|
||||
/* Used for logging FPIN messages */
|
||||
#define LPFC_FPIN_WWPN_LINE_SZ 128
|
||||
#define LPFC_FPIN_WWPN_LINE_CNT 6
|
||||
|
|
|
@ -6185,6 +6185,7 @@ lpfc_update_trunk_link_status(struct lpfc_hba *phba,
|
|||
{
|
||||
uint8_t port_fault = bf_get(lpfc_acqe_fc_la_trunk_linkmask, acqe_fc);
|
||||
uint8_t err = bf_get(lpfc_acqe_fc_la_trunk_fault, acqe_fc);
|
||||
u8 cnt = 0;
|
||||
|
||||
phba->sli4_hba.link_state.speed =
|
||||
lpfc_sli4_port_speed_parse(phba, LPFC_TRAILER_CODE_FC,
|
||||
|
@ -6203,26 +6204,36 @@ lpfc_update_trunk_link_status(struct lpfc_hba *phba,
|
|||
bf_get(lpfc_acqe_fc_la_trunk_link_status_port0, acqe_fc)
|
||||
? LPFC_LINK_UP : LPFC_LINK_DOWN;
|
||||
phba->trunk_link.link0.fault = port_fault & 0x1 ? err : 0;
|
||||
cnt++;
|
||||
}
|
||||
if (bf_get(lpfc_acqe_fc_la_trunk_config_port1, acqe_fc)) {
|
||||
phba->trunk_link.link1.state =
|
||||
bf_get(lpfc_acqe_fc_la_trunk_link_status_port1, acqe_fc)
|
||||
? LPFC_LINK_UP : LPFC_LINK_DOWN;
|
||||
phba->trunk_link.link1.fault = port_fault & 0x2 ? err : 0;
|
||||
cnt++;
|
||||
}
|
||||
if (bf_get(lpfc_acqe_fc_la_trunk_config_port2, acqe_fc)) {
|
||||
phba->trunk_link.link2.state =
|
||||
bf_get(lpfc_acqe_fc_la_trunk_link_status_port2, acqe_fc)
|
||||
? LPFC_LINK_UP : LPFC_LINK_DOWN;
|
||||
phba->trunk_link.link2.fault = port_fault & 0x4 ? err : 0;
|
||||
cnt++;
|
||||
}
|
||||
if (bf_get(lpfc_acqe_fc_la_trunk_config_port3, acqe_fc)) {
|
||||
phba->trunk_link.link3.state =
|
||||
bf_get(lpfc_acqe_fc_la_trunk_link_status_port3, acqe_fc)
|
||||
? LPFC_LINK_UP : LPFC_LINK_DOWN;
|
||||
phba->trunk_link.link3.fault = port_fault & 0x8 ? err : 0;
|
||||
cnt++;
|
||||
}
|
||||
|
||||
if (cnt)
|
||||
phba->trunk_link.phy_lnk_speed =
|
||||
phba->sli4_hba.link_state.logical_speed / (cnt * 1000);
|
||||
else
|
||||
phba->trunk_link.phy_lnk_speed = LPFC_LINK_SPEED_UNKNOWN;
|
||||
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
|
||||
"2910 Async FC Trunking Event - Speed:%d\n"
|
||||
"\tLogical speed:%d "
|
||||
|
@ -6300,7 +6311,7 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc)
|
|||
if (bf_get(lpfc_acqe_fc_la_att_type, acqe_fc) ==
|
||||
LPFC_FC_LA_TYPE_LINK_DOWN)
|
||||
phba->sli4_hba.link_state.logical_speed = 0;
|
||||
else if (!phba->sli4_hba.conf_trunk)
|
||||
else if (!phba->sli4_hba.conf_trunk)
|
||||
phba->sli4_hba.link_state.logical_speed =
|
||||
bf_get(lpfc_acqe_fc_la_llink_spd, acqe_fc) * 10;
|
||||
|
||||
|
@ -6418,7 +6429,7 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli)
|
|||
"2901 Async SLI event - Type:%d, Event Data: x%08x "
|
||||
"x%08x x%08x x%08x\n", evt_type,
|
||||
acqe_sli->event_data1, acqe_sli->event_data2,
|
||||
acqe_sli->reserved, acqe_sli->trailer);
|
||||
acqe_sli->event_data3, acqe_sli->trailer);
|
||||
|
||||
port_name = phba->Port[0];
|
||||
if (port_name == 0x00)
|
||||
|
@ -6447,7 +6458,7 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli)
|
|||
temp_event_data.event_code = LPFC_NORMAL_TEMP;
|
||||
temp_event_data.data = (uint32_t)acqe_sli->event_data1;
|
||||
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_SLI | LOG_LDS_EVENT,
|
||||
"3191 Normal Temperature:%d Celsius - Port Name %c\n",
|
||||
acqe_sli->event_data1, port_name);
|
||||
|
||||
|
@ -6625,6 +6636,15 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case LPFC_SLI_EVENT_TYPE_RD_SIGNAL:
|
||||
/* May be accompanied by a temperature event */
|
||||
lpfc_printf_log(phba, KERN_INFO,
|
||||
LOG_SLI | LOG_LINK_EVENT | LOG_LDS_EVENT,
|
||||
"2902 Remote Degrade Signaling: x%08x x%08x "
|
||||
"x%08x\n",
|
||||
acqe_sli->event_data1, acqe_sli->event_data2,
|
||||
acqe_sli->event_data3);
|
||||
break;
|
||||
default:
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
|
||||
"3193 Unrecognized SLI event, type: 0x%x",
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define LOG_FCP_ERROR 0x00001000 /* log errors, not underruns */
|
||||
#define LOG_LIBDFC 0x00002000 /* Libdfc events */
|
||||
#define LOG_VPORT 0x00004000 /* NPIV events */
|
||||
#define LOG_SECURITY 0x00008000 /* Security events */
|
||||
#define LOG_LDS_EVENT 0x00008000 /* Link Degrade Signaling events */
|
||||
#define LOG_EVENT 0x00010000 /* CT,TEMP,DUMP, logging */
|
||||
#define LOG_FIP 0x00020000 /* FIP events */
|
||||
#define LOG_FCP_UNDER 0x00040000 /* FCP underruns errors */
|
||||
|
|
|
@ -6830,8 +6830,13 @@ lpfc_set_features(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox,
|
|||
bf_set(lpfc_mbx_set_feature_mi, &mbox->u.mqe.un.set_feature,
|
||||
phba->sli4_hba.pc_sli4_params.mi_ver);
|
||||
break;
|
||||
case LPFC_SET_LD_SIGNAL:
|
||||
mbox->u.mqe.un.set_feature.feature = LPFC_SET_LD_SIGNAL;
|
||||
mbox->u.mqe.un.set_feature.param_len = 16;
|
||||
bf_set(lpfc_mbx_set_feature_lds_qry,
|
||||
&mbox->u.mqe.un.set_feature, LPFC_QUERY_LDS_OP);
|
||||
break;
|
||||
case LPFC_SET_ENABLE_CMF:
|
||||
bf_set(lpfc_mbx_set_feature_dd, &mbox->u.mqe.un.set_feature, 1);
|
||||
mbox->u.mqe.un.set_feature.feature = LPFC_SET_ENABLE_CMF;
|
||||
mbox->u.mqe.un.set_feature.param_len = 4;
|
||||
bf_set(lpfc_mbx_set_feature_cmf,
|
||||
|
@ -7826,6 +7831,62 @@ lpfc_post_rq_buffer(struct lpfc_hba *phba, struct lpfc_queue *hrq,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
lpfc_mbx_cmpl_read_lds_params(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||
{
|
||||
union lpfc_sli4_cfg_shdr *shdr;
|
||||
u32 shdr_status, shdr_add_status;
|
||||
|
||||
shdr = (union lpfc_sli4_cfg_shdr *)
|
||||
&pmb->u.mqe.un.sli4_config.header.cfg_shdr;
|
||||
shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
|
||||
shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
|
||||
if (shdr_status || shdr_add_status || pmb->u.mb.mbxStatus) {
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_LDS_EVENT | LOG_MBOX,
|
||||
"4622 SET_FEATURE (x%x) mbox failed, "
|
||||
"status x%x add_status x%x, mbx status x%x\n",
|
||||
LPFC_SET_LD_SIGNAL, shdr_status,
|
||||
shdr_add_status, pmb->u.mb.mbxStatus);
|
||||
phba->degrade_activate_threshold = 0;
|
||||
phba->degrade_deactivate_threshold = 0;
|
||||
phba->fec_degrade_interval = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
phba->degrade_activate_threshold = pmb->u.mqe.un.set_feature.word7;
|
||||
phba->degrade_deactivate_threshold = pmb->u.mqe.un.set_feature.word8;
|
||||
phba->fec_degrade_interval = pmb->u.mqe.un.set_feature.word10;
|
||||
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_LDS_EVENT,
|
||||
"4624 Success: da x%x dd x%x interval x%x\n",
|
||||
phba->degrade_activate_threshold,
|
||||
phba->degrade_deactivate_threshold,
|
||||
phba->fec_degrade_interval);
|
||||
out:
|
||||
mempool_free(pmb, phba->mbox_mem_pool);
|
||||
}
|
||||
|
||||
int
|
||||
lpfc_read_lds_params(struct lpfc_hba *phba)
|
||||
{
|
||||
LPFC_MBOXQ_t *mboxq;
|
||||
int rc;
|
||||
|
||||
mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
if (!mboxq)
|
||||
return -ENOMEM;
|
||||
|
||||
lpfc_set_features(phba, mboxq, LPFC_SET_LD_SIGNAL);
|
||||
mboxq->vport = phba->pport;
|
||||
mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_lds_params;
|
||||
rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
|
||||
if (rc == MBX_NOT_FINISHED) {
|
||||
mempool_free(mboxq, phba->mbox_mem_pool);
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
lpfc_mbx_cmpl_cgn_set_ftrs(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue