Commit 01649561 authored by James Smart's avatar James Smart Committed by Martin K. Petersen

scsi: lpfc: NVME Initiator: bind to nvme_fc api

NVME Initiator: Tie in to NVME Fabrics nvme_fc LLDD initiator api

Adds the routines to:
- register and deregister the FC port as a nvme-fc initiator localport
- register and deregister remote FC ports as a nvme-fc remoteport
- binding of nvme queues to adapter WQs
- send/perform NVME LS's
- send/perform NVME FCP initiator io operations
Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <james.smart@broadcom.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent a0f2d3ef
...@@ -28,6 +28,7 @@ endif ...@@ -28,6 +28,7 @@ endif
obj-$(CONFIG_SCSI_LPFC) := lpfc.o obj-$(CONFIG_SCSI_LPFC) := lpfc.o
lpfc-objs := lpfc_mem.o lpfc_sli.o lpfc_ct.o lpfc_els.o lpfc_hbadisc.o \ lpfc-objs := lpfc_mem.o lpfc_sli.o lpfc_ct.o lpfc_els.o \
lpfc_init.o lpfc_mbox.o lpfc_nportdisc.o lpfc_scsi.o lpfc_attr.o \ lpfc_hbadisc.o lpfc_init.o lpfc_mbox.o lpfc_nportdisc.o \
lpfc_vport.o lpfc_debugfs.o lpfc_bsg.o lpfc_scsi.o lpfc_attr.o lpfc_vport.o lpfc_debugfs.o lpfc_bsg.o \
lpfc_nvme.o
...@@ -123,6 +123,11 @@ struct perf_prof { ...@@ -123,6 +123,11 @@ struct perf_prof {
uint16_t wqidx[40]; uint16_t wqidx[40];
}; };
/*
* Provide for FC4 TYPE x28 - NVME. The
* bit mask for FCP and NVME is 0x8 identically
* because they are 32 bit positions distance.
*/
#define LPFC_FC4_TYPE_BITMASK 0x00000100 #define LPFC_FC4_TYPE_BITMASK 0x00000100
/* Provide DMA memory definitions the driver uses per port instance. */ /* Provide DMA memory definitions the driver uses per port instance. */
......
...@@ -518,4 +518,14 @@ int lpfc_sli4_dump_page_a0(struct lpfc_hba *phba, struct lpfcMboxq *mbox); ...@@ -518,4 +518,14 @@ int lpfc_sli4_dump_page_a0(struct lpfc_hba *phba, struct lpfcMboxq *mbox);
void lpfc_mbx_cmpl_rdp_page_a0(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb); void lpfc_mbx_cmpl_rdp_page_a0(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb);
/* NVME interfaces. */ /* NVME interfaces. */
void lpfc_nvme_unregister_port(struct lpfc_vport *vport,
struct lpfc_nodelist *ndlp);
int lpfc_nvme_register_port(struct lpfc_vport *vport,
struct lpfc_nodelist *ndlp);
int lpfc_nvme_create_localport(struct lpfc_vport *vport);
void lpfc_nvme_destroy_localport(struct lpfc_vport *vport);
void lpfc_nvme_update_localport(struct lpfc_vport *vport);
void lpfc_nvme_mod_param_dep(struct lpfc_hba *phba); void lpfc_nvme_mod_param_dep(struct lpfc_hba *phba);
void lpfc_nvme_abort_fcreq_cmpl(struct lpfc_hba *phba,
struct lpfc_iocbq *cmdiocb,
struct lpfc_wcqe_complete *abts_cmpl);
...@@ -1412,7 +1412,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, ...@@ -1412,7 +1412,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
if (((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) || if (((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
(phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) && (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) &&
(context == FC_TYPE_NVME)) { (context == FC_TYPE_NVME)) {
/* todo: init: revise localport nvme attributes */ lpfc_nvme_update_localport(vport);
CtReq->un.rff.type_code = context; CtReq->un.rff.type_code = context;
} else if (((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) || } else if (((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
......
...@@ -2618,7 +2618,9 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -2618,7 +2618,9 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
!(vport->fc_flag & FC_PT2PT_PLOGI)) { !(vport->fc_flag & FC_PT2PT_PLOGI)) {
phba->pport->fc_myDID = 0; phba->pport->fc_myDID = 0;
/* todo: init: revise localport nvme attributes */ if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
(phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME))
lpfc_nvme_update_localport(phba->pport);
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (mbox) { if (mbox) {
......
...@@ -909,7 +909,9 @@ lpfc_linkdown(struct lpfc_hba *phba) ...@@ -909,7 +909,9 @@ lpfc_linkdown(struct lpfc_hba *phba)
vports[i]->fc_myDID = 0; vports[i]->fc_myDID = 0;
/* todo: init: revise localport nvme attributes */ if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
(phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME))
lpfc_nvme_update_localport(vports[i]);
} }
} }
lpfc_destroy_vport_work_array(phba, vports); lpfc_destroy_vport_work_array(phba, vports);
...@@ -3580,7 +3582,9 @@ lpfc_mbx_cmpl_reg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) ...@@ -3580,7 +3582,9 @@ lpfc_mbx_cmpl_reg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
vport->fc_myDID = 0; vport->fc_myDID = 0;
/* todo: init: revise localport nvme attributes */ if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
(phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME))
lpfc_nvme_update_localport(vport);
goto out; goto out;
} }
...@@ -3950,7 +3954,8 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) ...@@ -3950,7 +3954,8 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) || if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
(phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME))
lpfc_ns_cmd(vport, SLI_CTNS_RFF_ID, 0, FC_TYPE_NVME); lpfc_ns_cmd(vport, SLI_CTNS_RFF_ID, 0,
FC_TYPE_NVME);
/* Issue SCR just before NameServer GID_FT Query */ /* Issue SCR just before NameServer GID_FT Query */
lpfc_issue_els_scr(vport, SCR_DID, 0); lpfc_issue_els_scr(vport, SCR_DID, 0);
...@@ -4144,7 +4149,7 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ...@@ -4144,7 +4149,7 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
((ndlp->nlp_fc4_type & NLP_FC4_NVME) || ((ndlp->nlp_fc4_type & NLP_FC4_NVME) ||
(ndlp->nlp_DID == Fabric_DID))) { (ndlp->nlp_DID == Fabric_DID))) {
vport->phba->nport_event_cnt++; vport->phba->nport_event_cnt++;
/* todo: init: unregister rport from nvme */ lpfc_nvme_unregister_port(vport, ndlp);
} }
} }
...@@ -4169,7 +4174,7 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ...@@ -4169,7 +4174,7 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
* the register. * the register.
*/ */
vport->phba->nport_event_cnt++; vport->phba->nport_event_cnt++;
/* todo: init: register rport with nvme */ lpfc_nvme_register_port(vport, ndlp);
} }
} }
} }
......
...@@ -3128,7 +3128,6 @@ static void ...@@ -3128,7 +3128,6 @@ static void
lpfc_scsi_free(struct lpfc_hba *phba) lpfc_scsi_free(struct lpfc_hba *phba)
{ {
struct lpfc_scsi_buf *sb, *sb_next; struct lpfc_scsi_buf *sb, *sb_next;
struct lpfc_iocbq *io, *io_next;
if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP)) if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP))
return; return;
...@@ -3158,14 +3157,6 @@ lpfc_scsi_free(struct lpfc_hba *phba) ...@@ -3158,14 +3157,6 @@ lpfc_scsi_free(struct lpfc_hba *phba)
phba->total_scsi_bufs--; phba->total_scsi_bufs--;
} }
spin_unlock(&phba->scsi_buf_list_get_lock); spin_unlock(&phba->scsi_buf_list_get_lock);
/* Release all the lpfc_iocbq entries maintained by this host. */
list_for_each_entry_safe(io, io_next, &phba->lpfc_iocb_list, list) {
list_del(&io->list);
kfree(io);
phba->total_iocbq_bufs--;
}
spin_unlock_irq(&phba->hbalock); spin_unlock_irq(&phba->hbalock);
} }
/** /**
...@@ -3180,7 +3171,6 @@ static void ...@@ -3180,7 +3171,6 @@ static void
lpfc_nvme_free(struct lpfc_hba *phba) lpfc_nvme_free(struct lpfc_hba *phba)
{ {
struct lpfc_nvme_buf *lpfc_ncmd, *lpfc_ncmd_next; struct lpfc_nvme_buf *lpfc_ncmd, *lpfc_ncmd_next;
struct lpfc_iocbq *io, *io_next;
if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME)) if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME))
return; return;
...@@ -3209,14 +3199,6 @@ lpfc_nvme_free(struct lpfc_hba *phba) ...@@ -3209,14 +3199,6 @@ lpfc_nvme_free(struct lpfc_hba *phba)
phba->total_nvme_bufs--; phba->total_nvme_bufs--;
} }
spin_unlock(&phba->nvme_buf_list_get_lock); spin_unlock(&phba->nvme_buf_list_get_lock);
/* Release all the lpfc_iocbq entries maintained by this host. */
list_for_each_entry_safe(io, io_next, &phba->lpfc_iocb_list, list) {
list_del(&io->list);
kfree(io);
phba->total_iocbq_bufs--;
}
spin_unlock_irq(&phba->hbalock); spin_unlock_irq(&phba->hbalock);
} }
/** /**
...@@ -10685,7 +10667,23 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) ...@@ -10685,7 +10667,23 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
/* Perform post initialization setup */ /* Perform post initialization setup */
lpfc_post_init_setup(phba); lpfc_post_init_setup(phba);
/* todo: init: register port with nvme */ /* NVME support in FW earlier in the driver load corrects the
* FC4 type making a check for nvme_support unnecessary.
*/
if ((phba->nvmet_support == 0) &&
(phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME)) {
/* Create NVME binding with nvme_fc_transport. This
* ensures the vport is initialized.
*/
error = lpfc_nvme_create_localport(vport);
if (error) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"6004 NVME registration failed, "
"error x%x\n",
error);
goto out_disable_intr;
}
}
/* check for firmware upgrade or downgrade */ /* check for firmware upgrade or downgrade */
if (phba->cfg_request_firmware_upgrade) if (phba->cfg_request_firmware_upgrade)
...@@ -10761,8 +10759,8 @@ lpfc_pci_remove_one_s4(struct pci_dev *pdev) ...@@ -10761,8 +10759,8 @@ lpfc_pci_remove_one_s4(struct pci_dev *pdev)
/* Perform ndlp cleanup on the physical port. The nvme localport /* Perform ndlp cleanup on the physical port. The nvme localport
* is destroyed after to ensure all rports are io-disabled. * is destroyed after to ensure all rports are io-disabled.
*/ */
lpfc_nvme_destroy_localport(vport);
lpfc_cleanup(vport); lpfc_cleanup(vport);
/* todo: init: unregister port with nvme */
/* /*
* Bring down the SLI Layer. This step disables all interrupts, * Bring down the SLI Layer. This step disables all interrupts,
...@@ -10781,6 +10779,7 @@ lpfc_pci_remove_one_s4(struct pci_dev *pdev) ...@@ -10781,6 +10779,7 @@ lpfc_pci_remove_one_s4(struct pci_dev *pdev)
*/ */
lpfc_scsi_free(phba); lpfc_scsi_free(phba);
lpfc_nvme_free(phba); lpfc_nvme_free(phba);
lpfc_free_iocb_list(phba);
lpfc_sli4_driver_resource_unset(phba); lpfc_sli4_driver_resource_unset(phba);
......
...@@ -1655,9 +1655,7 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport, ...@@ -1655,9 +1655,7 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport,
(phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) { (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) {
ndlp->nlp_fc4_type |= NLP_FC4_NVME; ndlp->nlp_fc4_type |= NLP_FC4_NVME;
/* We need to update the localport also */ /* We need to update the localport also */
/* todo: init: revise localport nvme lpfc_nvme_update_localport(vport);
* attributes
*/
} }
} else if (ndlp->nlp_fc4_type == 0) { } else if (ndlp->nlp_fc4_type == 0) {
......
This diff is collapsed.
...@@ -29,6 +29,12 @@ ...@@ -29,6 +29,12 @@
#define LPFC_NVME_ERSP_LEN 0x20 #define LPFC_NVME_ERSP_LEN 0x20
struct lpfc_nvme_qhandle {
uint32_t index; /* WQ index to use */
uint32_t qidx; /* queue index passed to create */
uint32_t cpu_id; /* current cpu id at time of create */
};
/* Declare nvme-based local and remote port definitions. */ /* Declare nvme-based local and remote port definitions. */
struct lpfc_nvme_lport { struct lpfc_nvme_lport {
struct lpfc_vport *vport; struct lpfc_vport *vport;
......
...@@ -6795,6 +6795,22 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) ...@@ -6795,6 +6795,22 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
} }
} }
if ((phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) &&
(phba->nvmet_support == 0)) {
/* register the allocated nvme sgl pool to the port */
rc = lpfc_repost_nvme_sgl_list(phba);
if (unlikely(rc)) {
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
"6116 Error %d during nvme sgl post "
"operation\n", rc);
/* Some NVME buffers were moved to abort nvme list */
/* A pci function reset will repost them */
rc = -ENODEV;
goto out_destroy_queue;
}
}
/* Post the rpi header region to the device. */ /* Post the rpi header region to the device. */
rc = lpfc_sli4_post_all_rpi_hdrs(phba); rc = lpfc_sli4_post_all_rpi_hdrs(phba);
if (unlikely(rc)) { if (unlikely(rc)) {
...@@ -10492,10 +10508,7 @@ lpfc_sli4_abort_nvme_io(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, ...@@ -10492,10 +10508,7 @@ lpfc_sli4_abort_nvme_io(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
/* ABTS WQE must go to the same WQ as the WQE to be aborted */ /* ABTS WQE must go to the same WQ as the WQE to be aborted */
abtsiocbp->iocb_flag |= LPFC_IO_NVME; abtsiocbp->iocb_flag |= LPFC_IO_NVME;
abtsiocbp->vport = vport; abtsiocbp->vport = vport;
/* todo: assign wqe_cmpl to lpfc_nvme_abort_fcreq_cmpl abtsiocbp->wqe_cmpl = lpfc_nvme_abort_fcreq_cmpl;
* subsequent patch will add routine. For now, just skip assignment
* as won't ever be called.
*/
retval = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, abtsiocbp); retval = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, abtsiocbp);
if (retval == IOCB_ERROR) { if (retval == IOCB_ERROR) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME, lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME,
......
...@@ -753,6 +753,7 @@ int lpfc_sli4_queue_setup(struct lpfc_hba *); ...@@ -753,6 +753,7 @@ int lpfc_sli4_queue_setup(struct lpfc_hba *);
void lpfc_sli4_queue_unset(struct lpfc_hba *); void lpfc_sli4_queue_unset(struct lpfc_hba *);
int lpfc_sli4_post_sgl(struct lpfc_hba *, dma_addr_t, dma_addr_t, uint16_t); int lpfc_sli4_post_sgl(struct lpfc_hba *, dma_addr_t, dma_addr_t, uint16_t);
int lpfc_sli4_repost_scsi_sgl_list(struct lpfc_hba *); int lpfc_sli4_repost_scsi_sgl_list(struct lpfc_hba *);
int lpfc_repost_nvme_sgl_list(struct lpfc_hba *phba);
uint16_t lpfc_sli4_next_xritag(struct lpfc_hba *); uint16_t lpfc_sli4_next_xritag(struct lpfc_hba *);
void lpfc_sli4_free_xri(struct lpfc_hba *, int); void lpfc_sli4_free_xri(struct lpfc_hba *, int);
int lpfc_sli4_post_async_mbox(struct lpfc_hba *); int lpfc_sli4_post_async_mbox(struct lpfc_hba *);
......
...@@ -403,7 +403,21 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) ...@@ -403,7 +403,21 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
vport->fdmi_port_mask = phba->pport->fdmi_port_mask; vport->fdmi_port_mask = phba->pport->fdmi_port_mask;
} }
/* todo: init: register port with nvme */ if ((phba->nvmet_support == 0) &&
((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
(phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME))) {
/* Create NVME binding with nvme_fc_transport. This
* ensures the vport is initialized.
*/
rc = lpfc_nvme_create_localport(vport);
if (rc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"6003 %s status x%x\n",
"NVME registration failed, ",
rc);
goto error_out;
}
}
/* /*
* In SLI4, the vpi must be activated before it can be used * In SLI4, the vpi must be activated before it can be used
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment