summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <jsmart2021@gmail.com>2019-08-14 19:57:08 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2019-08-19 22:41:12 -0400
commite62245d923caebc02582b12ce861c3d780b4106f (patch)
tree0141bcf65ed5887c1b1ca04cce4db41670a0d76b
parentec76242f3be73e5cbb950a7ac99d4fba7e226e2e (diff)
scsi: lpfc: Add MDS driver loopback diagnostics support
Added code to support driver loopback with MDS Diagnostics. This style of diagnostics passes frames from the fabric to the driver who then echo them back out the link. SEND_FRAME WQEs are used to transmit the frames. Added the SOF and EOF field location definitions for use by SEND_FRAME. Also ensure that enable_mds_diags is a RW parameter. Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: James Smart <jsmart2021@gmail.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c11
-rw-r--r--drivers/scsi/lpfc/lpfc_hw4.h6
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c30
4 files changed, 38 insertions, 11 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 0a8caa12a30d..bd7a72f6cdbe 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -5912,7 +5912,7 @@ lpfc_sg_seg_cnt_init(struct lpfc_hba *phba, int val)
5912 * 1 = MDS Diagnostics enabled 5912 * 1 = MDS Diagnostics enabled
5913 * Value range is [0,1]. Default value is 0. 5913 * Value range is [0,1]. Default value is 0.
5914 */ 5914 */
5915LPFC_ATTR_R(enable_mds_diags, 0, 0, 1, "Enable MDS Diagnostics"); 5915LPFC_ATTR_RW(enable_mds_diags, 0, 0, 1, "Enable MDS Diagnostics");
5916 5916
5917/* 5917/*
5918 * lpfc_ras_fwlog_buffsize: Firmware logging host buffer size 5918 * lpfc_ras_fwlog_buffsize: Firmware logging host buffer size
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index aaad1c74bb98..30bbfa3f6086 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -1052,17 +1052,18 @@ stop_rr_fcf_flogi:
1052 if (lpfc_els_retry(phba, cmdiocb, rspiocb)) 1052 if (lpfc_els_retry(phba, cmdiocb, rspiocb))
1053 goto out; 1053 goto out;
1054 1054
1055 lpfc_printf_vlog(vport, KERN_WARNING, LOG_ELS,
1056 "0150 FLOGI failure Status:x%x/x%x "
1057 "xri x%x TMO:x%x\n",
1058 irsp->ulpStatus, irsp->un.ulpWord[4],
1059 cmdiocb->sli4_xritag, irsp->ulpTimeout);
1060
1055 /* If this is not a loop open failure, bail out */ 1061 /* If this is not a loop open failure, bail out */
1056 if (!(irsp->ulpStatus == IOSTAT_LOCAL_REJECT && 1062 if (!(irsp->ulpStatus == IOSTAT_LOCAL_REJECT &&
1057 ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) == 1063 ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
1058 IOERR_LOOP_OPEN_FAILURE))) 1064 IOERR_LOOP_OPEN_FAILURE)))
1059 goto flogifail; 1065 goto flogifail;
1060 1066
1061 lpfc_printf_vlog(vport, KERN_WARNING, LOG_ELS,
1062 "0150 FLOGI failure Status:x%x/x%x xri x%x TMO:x%x\n",
1063 irsp->ulpStatus, irsp->un.ulpWord[4],
1064 cmdiocb->sli4_xritag, irsp->ulpTimeout);
1065
1066 /* FLOGI failed, so there is no fabric */ 1067 /* FLOGI failed, so there is no fabric */
1067 spin_lock_irq(shost->host_lock); 1068 spin_lock_irq(shost->host_lock);
1068 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); 1069 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 77f9a55a3f54..d89480b9eade 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -4314,6 +4314,12 @@ struct wqe_common {
4314#define wqe_rcvoxid_SHIFT 16 4314#define wqe_rcvoxid_SHIFT 16
4315#define wqe_rcvoxid_MASK 0x0000FFFF 4315#define wqe_rcvoxid_MASK 0x0000FFFF
4316#define wqe_rcvoxid_WORD word9 4316#define wqe_rcvoxid_WORD word9
4317#define wqe_sof_SHIFT 24
4318#define wqe_sof_MASK 0x000000FF
4319#define wqe_sof_WORD word9
4320#define wqe_eof_SHIFT 16
4321#define wqe_eof_MASK 0x000000FF
4322#define wqe_eof_WORD word9
4317 uint32_t word10; 4323 uint32_t word10;
4318#define wqe_ebde_cnt_SHIFT 0 4324#define wqe_ebde_cnt_SHIFT 0
4319#define wqe_ebde_cnt_MASK 0x0000000f 4325#define wqe_ebde_cnt_MASK 0x0000000f
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 03404dbd6ddf..940dd82a265b 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -9352,11 +9352,9 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
9352 memset(wqe, 0, sizeof(union lpfc_wqe128)); 9352 memset(wqe, 0, sizeof(union lpfc_wqe128));
9353 /* Some of the fields are in the right position already */ 9353 /* Some of the fields are in the right position already */
9354 memcpy(wqe, &iocbq->iocb, sizeof(union lpfc_wqe)); 9354 memcpy(wqe, &iocbq->iocb, sizeof(union lpfc_wqe));
9355 if (iocbq->iocb.ulpCommand != CMD_SEND_FRAME) { 9355 /* The ct field has moved so reset */
9356 /* The ct field has moved so reset */ 9356 wqe->generic.wqe_com.word7 = 0;
9357 wqe->generic.wqe_com.word7 = 0; 9357 wqe->generic.wqe_com.word10 = 0;
9358 wqe->generic.wqe_com.word10 = 0;
9359 }
9360 9358
9361 abort_tag = (uint32_t) iocbq->iotag; 9359 abort_tag = (uint32_t) iocbq->iotag;
9362 xritag = iocbq->sli4_xritag; 9360 xritag = iocbq->sli4_xritag;
@@ -9862,6 +9860,15 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
9862 9860
9863 break; 9861 break;
9864 case CMD_SEND_FRAME: 9862 case CMD_SEND_FRAME:
9863 bf_set(wqe_cmnd, &wqe->generic.wqe_com, CMD_SEND_FRAME);
9864 bf_set(wqe_sof, &wqe->generic.wqe_com, 0x2E); /* SOF byte */
9865 bf_set(wqe_eof, &wqe->generic.wqe_com, 0x41); /* EOF byte */
9866 bf_set(wqe_lenloc, &wqe->generic.wqe_com, 1);
9867 bf_set(wqe_xbl, &wqe->generic.wqe_com, 1);
9868 bf_set(wqe_dbde, &wqe->generic.wqe_com, 1);
9869 bf_set(wqe_xc, &wqe->generic.wqe_com, 1);
9870 bf_set(wqe_cmd_type, &wqe->generic.wqe_com, 0xA);
9871 bf_set(wqe_cqid, &wqe->generic.wqe_com, LPFC_WQE_CQ_ID_DEFAULT);
9865 bf_set(wqe_xri_tag, &wqe->generic.wqe_com, xritag); 9872 bf_set(wqe_xri_tag, &wqe->generic.wqe_com, xritag);
9866 bf_set(wqe_reqtag, &wqe->generic.wqe_com, iocbq->iotag); 9873 bf_set(wqe_reqtag, &wqe->generic.wqe_com, iocbq->iotag);
9867 return 0; 9874 return 0;
@@ -16940,6 +16947,8 @@ lpfc_fc_frame_check(struct lpfc_hba *phba, struct fc_frame_header *fc_hdr)
16940 struct fc_vft_header *fc_vft_hdr; 16947 struct fc_vft_header *fc_vft_hdr;
16941 uint32_t *header = (uint32_t *) fc_hdr; 16948 uint32_t *header = (uint32_t *) fc_hdr;
16942 16949
16950#define FC_RCTL_MDS_DIAGS 0xF4
16951
16943 switch (fc_hdr->fh_r_ctl) { 16952 switch (fc_hdr->fh_r_ctl) {
16944 case FC_RCTL_DD_UNCAT: /* uncategorized information */ 16953 case FC_RCTL_DD_UNCAT: /* uncategorized information */
16945 case FC_RCTL_DD_SOL_DATA: /* solicited data */ 16954 case FC_RCTL_DD_SOL_DATA: /* solicited data */
@@ -17949,6 +17958,17 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba,
17949 fcfi = bf_get(lpfc_rcqe_fcf_id, 17958 fcfi = bf_get(lpfc_rcqe_fcf_id,
17950 &dmabuf->cq_event.cqe.rcqe_cmpl); 17959 &dmabuf->cq_event.cqe.rcqe_cmpl);
17951 17960
17961 if (fc_hdr->fh_r_ctl == 0xF4 && fc_hdr->fh_type == 0xFF) {
17962 vport = phba->pport;
17963 lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
17964 "2023 MDS Loopback %d bytes\n",
17965 bf_get(lpfc_rcqe_length,
17966 &dmabuf->cq_event.cqe.rcqe_cmpl));
17967 /* Handle MDS Loopback frames */
17968 lpfc_sli4_handle_mds_loopback(vport, dmabuf);
17969 return;
17970 }
17971
17952 /* d_id this frame is directed to */ 17972 /* d_id this frame is directed to */
17953 did = sli4_did_from_fc_hdr(fc_hdr); 17973 did = sli4_did_from_fc_hdr(fc_hdr);
17954 17974