aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/lpfc/lpfc_mbox.c
diff options
context:
space:
mode:
authorJames Smart <james.smart@avagotech.com>2015-05-21 13:55:21 -0400
committerJames Bottomley <JBottomley@Odin.com>2015-06-05 22:34:55 -0700
commit86478875eb4d2e7108b914f8a5e53be260816d5c (patch)
tree9f97de6ec770e84e276bfd83d147243ec1428477 /drivers/scsi/lpfc/lpfc_mbox.c
parenta1efe163102fed8a3b5990a67cadb1193e630820 (diff)
lpfc: Add support for RDP ELS command.
Signed-off-by: Dick Kennedy <dick.kennedy@avagotech.com> Signed-off-by: James Smart <james.smart@avagotech.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: James Bottomley <JBottomley@Odin.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_mbox.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c152
1 files changed, 152 insertions, 0 deletions
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 816f596cda60..eb627724417e 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -2255,6 +2255,158 @@ lpfc_sli4_dump_cfg_rg23(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
return 0;
}
+void
+lpfc_mbx_cmpl_rdp_link_stat(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+{
+ MAILBOX_t *mb;
+ int rc = FAILURE;
+ struct lpfc_rdp_context *rdp_context =
+ (struct lpfc_rdp_context *)(mboxq->context2);
+
+ mb = &mboxq->u.mb;
+ if (mb->mbxStatus)
+ goto mbx_failed;
+
+ memcpy(&rdp_context->link_stat, &mb->un.varRdLnk, sizeof(READ_LNK_VAR));
+
+ rc = SUCCESS;
+
+mbx_failed:
+ lpfc_sli4_mbox_cmd_free(phba, mboxq);
+ rdp_context->cmpl(phba, rdp_context, rc);
+}
+
+void
+lpfc_mbx_cmpl_rdp_page_a2(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox)
+{
+ struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) mbox->context1;
+ struct lpfc_rdp_context *rdp_context =
+ (struct lpfc_rdp_context *)(mbox->context2);
+
+ if (bf_get(lpfc_mqe_status, &mbox->u.mqe))
+ goto error;
+
+ lpfc_sli_bemem_bcopy(mp->virt, &rdp_context->page_a2,
+ DMP_SFF_PAGE_A2_SIZE);
+
+ /* We don't need dma buffer for link stat. */
+ lpfc_mbuf_free(phba, mp->virt, mp->phys);
+ kfree(mp);
+
+ memset(mbox, 0, sizeof(*mbox));
+ lpfc_read_lnk_stat(phba, mbox);
+ mbox->vport = rdp_context->ndlp->vport;
+ mbox->mbox_cmpl = lpfc_mbx_cmpl_rdp_link_stat;
+ mbox->context2 = (struct lpfc_rdp_context *) rdp_context;
+ if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) == MBX_NOT_FINISHED)
+ goto error;
+
+ return;
+
+error:
+ lpfc_mbuf_free(phba, mp->virt, mp->phys);
+ kfree(mp);
+ lpfc_sli4_mbox_cmd_free(phba, mbox);
+ rdp_context->cmpl(phba, rdp_context, FAILURE);
+}
+
+void
+lpfc_mbx_cmpl_rdp_page_a0(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox)
+{
+ int rc;
+ struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (mbox->context1);
+ struct lpfc_rdp_context *rdp_context =
+ (struct lpfc_rdp_context *)(mbox->context2);
+
+ if (bf_get(lpfc_mqe_status, &mbox->u.mqe))
+ goto error;
+
+ lpfc_sli_bemem_bcopy(mp->virt, &rdp_context->page_a0,
+ DMP_SFF_PAGE_A0_SIZE);
+
+ memset(mbox, 0, sizeof(*mbox));
+
+ memset(mp->virt, 0, DMP_SFF_PAGE_A2_SIZE);
+ INIT_LIST_HEAD(&mp->list);
+
+ /* save address for completion */
+ mbox->context1 = mp;
+ mbox->vport = rdp_context->ndlp->vport;
+
+ bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_DUMP_MEMORY);
+ bf_set(lpfc_mbx_memory_dump_type3_type,
+ &mbox->u.mqe.un.mem_dump_type3, DMP_LMSD);
+ bf_set(lpfc_mbx_memory_dump_type3_link,
+ &mbox->u.mqe.un.mem_dump_type3, phba->sli4_hba.physical_port);
+ bf_set(lpfc_mbx_memory_dump_type3_page_no,
+ &mbox->u.mqe.un.mem_dump_type3, DMP_PAGE_A2);
+ bf_set(lpfc_mbx_memory_dump_type3_length,
+ &mbox->u.mqe.un.mem_dump_type3, DMP_SFF_PAGE_A2_SIZE);
+ mbox->u.mqe.un.mem_dump_type3.addr_lo = putPaddrLow(mp->phys);
+ mbox->u.mqe.un.mem_dump_type3.addr_hi = putPaddrHigh(mp->phys);
+
+ mbox->mbox_cmpl = lpfc_mbx_cmpl_rdp_page_a2;
+ mbox->context2 = (struct lpfc_rdp_context *) rdp_context;
+ rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
+ if (rc == MBX_NOT_FINISHED)
+ goto error;
+
+ return;
+
+error:
+ lpfc_mbuf_free(phba, mp->virt, mp->phys);
+ kfree(mp);
+ lpfc_sli4_mbox_cmd_free(phba, mbox);
+ rdp_context->cmpl(phba, rdp_context, FAILURE);
+}
+
+
+/*
+ * lpfc_sli4_dump_sfp_pagea0 - Dump sli4 read SFP Diagnostic.
+ * @phba: pointer to the hba structure containing.
+ * @mbox: pointer to lpfc mbox command to initialize.
+ *
+ * This function create a SLI4 dump mailbox command to dump configure
+ * type 3 page 0xA0.
+ */
+int
+lpfc_sli4_dump_page_a0(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
+{
+ struct lpfc_dmabuf *mp = NULL;
+
+ memset(mbox, 0, sizeof(*mbox));
+
+ mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
+ if (mp)
+ mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
+ if (!mp || !mp->virt) {
+ kfree(mp);
+ lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
+ "3569 dump type 3 page 0xA0 allocation failed\n");
+ return 1;
+ }
+
+ memset(mp->virt, 0, LPFC_BPL_SIZE);
+ INIT_LIST_HEAD(&mp->list);
+
+ bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_DUMP_MEMORY);
+ /* save address for completion */
+ mbox->context1 = mp;
+
+ bf_set(lpfc_mbx_memory_dump_type3_type,
+ &mbox->u.mqe.un.mem_dump_type3, DMP_LMSD);
+ bf_set(lpfc_mbx_memory_dump_type3_link,
+ &mbox->u.mqe.un.mem_dump_type3, phba->sli4_hba.physical_port);
+ bf_set(lpfc_mbx_memory_dump_type3_page_no,
+ &mbox->u.mqe.un.mem_dump_type3, DMP_PAGE_A0);
+ bf_set(lpfc_mbx_memory_dump_type3_length,
+ &mbox->u.mqe.un.mem_dump_type3, DMP_SFF_PAGE_A0_SIZE);
+ mbox->u.mqe.un.mem_dump_type3.addr_lo = putPaddrLow(mp->phys);
+ mbox->u.mqe.un.mem_dump_type3.addr_hi = putPaddrHigh(mp->phys);
+
+ return 0;
+}
+
/**
* lpfc_reg_fcfi - Initialize the REG_FCFI mailbox command
* @phba: pointer to the hba structure containing the FCF index and RQ ID.