Skip to content

Commit

Permalink
scsi: lpfc: Add MDS driver loopback diagnostics support
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
James Smart authored and Martin K. Petersen committed Aug 20, 2019
1 parent ec76242 commit e62245d
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 11 deletions.
2 changes: 1 addition & 1 deletion drivers/scsi/lpfc/lpfc_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -5912,7 +5912,7 @@ lpfc_sg_seg_cnt_init(struct lpfc_hba *phba, int val)
* 1 = MDS Diagnostics enabled
* Value range is [0,1]. Default value is 0.
*/
LPFC_ATTR_R(enable_mds_diags, 0, 0, 1, "Enable MDS Diagnostics");
LPFC_ATTR_RW(enable_mds_diags, 0, 0, 1, "Enable MDS Diagnostics");

/*
* lpfc_ras_fwlog_buffsize: Firmware logging host buffer size
Expand Down
11 changes: 6 additions & 5 deletions drivers/scsi/lpfc/lpfc_els.c
Original file line number Diff line number Diff line change
Expand Up @@ -1052,17 +1052,18 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
if (lpfc_els_retry(phba, cmdiocb, rspiocb))
goto out;

lpfc_printf_vlog(vport, KERN_WARNING, LOG_ELS,
"0150 FLOGI failure Status:x%x/x%x "
"xri x%x TMO:x%x\n",
irsp->ulpStatus, irsp->un.ulpWord[4],
cmdiocb->sli4_xritag, irsp->ulpTimeout);

/* If this is not a loop open failure, bail out */
if (!(irsp->ulpStatus == IOSTAT_LOCAL_REJECT &&
((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
IOERR_LOOP_OPEN_FAILURE)))
goto flogifail;

lpfc_printf_vlog(vport, KERN_WARNING, LOG_ELS,
"0150 FLOGI failure Status:x%x/x%x xri x%x TMO:x%x\n",
irsp->ulpStatus, irsp->un.ulpWord[4],
cmdiocb->sli4_xritag, irsp->ulpTimeout);

/* FLOGI failed, so there is no fabric */
spin_lock_irq(shost->host_lock);
vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
Expand Down
6 changes: 6 additions & 0 deletions drivers/scsi/lpfc/lpfc_hw4.h
Original file line number Diff line number Diff line change
Expand Up @@ -4314,6 +4314,12 @@ struct wqe_common {
#define wqe_rcvoxid_SHIFT 16
#define wqe_rcvoxid_MASK 0x0000FFFF
#define wqe_rcvoxid_WORD word9
#define wqe_sof_SHIFT 24
#define wqe_sof_MASK 0x000000FF
#define wqe_sof_WORD word9
#define wqe_eof_SHIFT 16
#define wqe_eof_MASK 0x000000FF
#define wqe_eof_WORD word9
uint32_t word10;
#define wqe_ebde_cnt_SHIFT 0
#define wqe_ebde_cnt_MASK 0x0000000f
Expand Down
30 changes: 25 additions & 5 deletions drivers/scsi/lpfc/lpfc_sli.c
Original file line number Diff line number Diff line change
Expand Up @@ -9352,11 +9352,9 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
memset(wqe, 0, sizeof(union lpfc_wqe128));
/* Some of the fields are in the right position already */
memcpy(wqe, &iocbq->iocb, sizeof(union lpfc_wqe));
if (iocbq->iocb.ulpCommand != CMD_SEND_FRAME) {
/* The ct field has moved so reset */
wqe->generic.wqe_com.word7 = 0;
wqe->generic.wqe_com.word10 = 0;
}
/* The ct field has moved so reset */
wqe->generic.wqe_com.word7 = 0;
wqe->generic.wqe_com.word10 = 0;

abort_tag = (uint32_t) iocbq->iotag;
xritag = iocbq->sli4_xritag;
Expand Down Expand Up @@ -9862,6 +9860,15 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,

break;
case CMD_SEND_FRAME:
bf_set(wqe_cmnd, &wqe->generic.wqe_com, CMD_SEND_FRAME);
bf_set(wqe_sof, &wqe->generic.wqe_com, 0x2E); /* SOF byte */
bf_set(wqe_eof, &wqe->generic.wqe_com, 0x41); /* EOF byte */
bf_set(wqe_lenloc, &wqe->generic.wqe_com, 1);
bf_set(wqe_xbl, &wqe->generic.wqe_com, 1);
bf_set(wqe_dbde, &wqe->generic.wqe_com, 1);
bf_set(wqe_xc, &wqe->generic.wqe_com, 1);
bf_set(wqe_cmd_type, &wqe->generic.wqe_com, 0xA);
bf_set(wqe_cqid, &wqe->generic.wqe_com, LPFC_WQE_CQ_ID_DEFAULT);
bf_set(wqe_xri_tag, &wqe->generic.wqe_com, xritag);
bf_set(wqe_reqtag, &wqe->generic.wqe_com, iocbq->iotag);
return 0;
Expand Down Expand Up @@ -16940,6 +16947,8 @@ lpfc_fc_frame_check(struct lpfc_hba *phba, struct fc_frame_header *fc_hdr)
struct fc_vft_header *fc_vft_hdr;
uint32_t *header = (uint32_t *) fc_hdr;

#define FC_RCTL_MDS_DIAGS 0xF4

switch (fc_hdr->fh_r_ctl) {
case FC_RCTL_DD_UNCAT: /* uncategorized information */
case FC_RCTL_DD_SOL_DATA: /* solicited data */
Expand Down Expand Up @@ -17949,6 +17958,17 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba,
fcfi = bf_get(lpfc_rcqe_fcf_id,
&dmabuf->cq_event.cqe.rcqe_cmpl);

if (fc_hdr->fh_r_ctl == 0xF4 && fc_hdr->fh_type == 0xFF) {
vport = phba->pport;
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
"2023 MDS Loopback %d bytes\n",
bf_get(lpfc_rcqe_length,
&dmabuf->cq_event.cqe.rcqe_cmpl));
/* Handle MDS Loopback frames */
lpfc_sli4_handle_mds_loopback(vport, dmabuf);
return;
}

/* d_id this frame is directed to */
did = sli4_did_from_fc_hdr(fc_hdr);

Expand Down

0 comments on commit e62245d

Please sign in to comment.