|
@@ -610,7 +610,8 @@ lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi)
|
|
|
mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm);
|
|
|
mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys);
|
|
|
mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys);
|
|
|
- mb->un.varRdSparm.vpi = vpi + phba->vpi_base;
|
|
|
+ if (phba->sli_rev >= LPFC_SLI_REV3)
|
|
|
+ mb->un.varRdSparm.vpi = phba->vpi_ids[vpi];
|
|
|
|
|
|
/* save address for completion */
|
|
|
pmb->context1 = mp;
|
|
@@ -643,9 +644,10 @@ lpfc_unreg_did(struct lpfc_hba * phba, uint16_t vpi, uint32_t did,
|
|
|
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
|
|
|
|
|
|
mb->un.varUnregDID.did = did;
|
|
|
- if (vpi != 0xffff)
|
|
|
- vpi += phba->vpi_base;
|
|
|
mb->un.varUnregDID.vpi = vpi;
|
|
|
+ if ((vpi != 0xffff) &&
|
|
|
+ (phba->sli_rev == LPFC_SLI_REV4))
|
|
|
+ mb->un.varUnregDID.vpi = phba->vpi_ids[vpi];
|
|
|
|
|
|
mb->mbxCommand = MBX_UNREG_D_ID;
|
|
|
mb->mbxOwner = OWN_HOST;
|
|
@@ -738,12 +740,10 @@ lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
|
|
|
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
|
|
|
|
|
|
mb->un.varRegLogin.rpi = 0;
|
|
|
- if (phba->sli_rev == LPFC_SLI_REV4) {
|
|
|
- mb->un.varRegLogin.rpi = rpi;
|
|
|
- if (mb->un.varRegLogin.rpi == LPFC_RPI_ALLOC_ERROR)
|
|
|
- return 1;
|
|
|
- }
|
|
|
- mb->un.varRegLogin.vpi = vpi + phba->vpi_base;
|
|
|
+ if (phba->sli_rev == LPFC_SLI_REV4)
|
|
|
+ mb->un.varRegLogin.rpi = phba->sli4_hba.rpi_ids[rpi];
|
|
|
+ if (phba->sli_rev >= LPFC_SLI_REV3)
|
|
|
+ mb->un.varRegLogin.vpi = phba->vpi_ids[vpi];
|
|
|
mb->un.varRegLogin.did = did;
|
|
|
mb->mbxOwner = OWN_HOST;
|
|
|
/* Get a buffer to hold NPorts Service Parameters */
|
|
@@ -757,7 +757,7 @@ lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
|
|
|
lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
|
|
|
"0302 REG_LOGIN: no buffers, VPI:%d DID:x%x, "
|
|
|
"rpi x%x\n", vpi, did, rpi);
|
|
|
- return (1);
|
|
|
+ return 1;
|
|
|
}
|
|
|
INIT_LIST_HEAD(&mp->list);
|
|
|
sparam = mp->virt;
|
|
@@ -773,7 +773,7 @@ lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
|
|
|
mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys);
|
|
|
mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys);
|
|
|
|
|
|
- return (0);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -789,6 +789,9 @@ lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
|
|
|
*
|
|
|
* This routine prepares the mailbox command for unregistering remote port
|
|
|
* login.
|
|
|
+ *
|
|
|
+ * For SLI4 ports, the rpi passed to this function must be the physical
|
|
|
+ * rpi value, not the logical index.
|
|
|
**/
|
|
|
void
|
|
|
lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi,
|
|
@@ -799,9 +802,10 @@ lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi,
|
|
|
mb = &pmb->u.mb;
|
|
|
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
|
|
|
|
|
|
- mb->un.varUnregLogin.rpi = (uint16_t) rpi;
|
|
|
+ mb->un.varUnregLogin.rpi = rpi;
|
|
|
mb->un.varUnregLogin.rsvd1 = 0;
|
|
|
- mb->un.varUnregLogin.vpi = vpi + phba->vpi_base;
|
|
|
+ if (phba->sli_rev >= LPFC_SLI_REV3)
|
|
|
+ mb->un.varUnregLogin.vpi = phba->vpi_ids[vpi];
|
|
|
|
|
|
mb->mbxCommand = MBX_UNREG_LOGIN;
|
|
|
mb->mbxOwner = OWN_HOST;
|
|
@@ -825,9 +829,16 @@ lpfc_sli4_unreg_all_rpis(struct lpfc_vport *vport)
|
|
|
|
|
|
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
|
|
if (mbox) {
|
|
|
- lpfc_unreg_login(phba, vport->vpi,
|
|
|
- vport->vpi + phba->vpi_base, mbox);
|
|
|
- mbox->u.mb.un.varUnregLogin.rsvd1 = 0x4000 ;
|
|
|
+ /*
|
|
|
+ * For SLI4 functions, the rpi field is overloaded for
|
|
|
+ * the vport context unreg all. This routine passes
|
|
|
+ * 0 for the rpi field in lpfc_unreg_login for compatibility
|
|
|
+ * with SLI3 and then overrides the rpi field with the
|
|
|
+ * expected value for SLI4.
|
|
|
+ */
|
|
|
+ lpfc_unreg_login(phba, vport->vpi, phba->vpi_ids[vport->vpi],
|
|
|
+ mbox);
|
|
|
+ mbox->u.mb.un.varUnregLogin.rsvd1 = 0x4000;
|
|
|
mbox->vport = vport;
|
|
|
mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
|
|
mbox->context1 = NULL;
|
|
@@ -865,9 +876,13 @@ lpfc_reg_vpi(struct lpfc_vport *vport, LPFC_MBOXQ_t *pmb)
|
|
|
if ((phba->sli_rev == LPFC_SLI_REV4) &&
|
|
|
!(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI))
|
|
|
mb->un.varRegVpi.upd = 1;
|
|
|
- mb->un.varRegVpi.vpi = vport->vpi + vport->phba->vpi_base;
|
|
|
+
|
|
|
+ mb->un.varRegVpi.vpi = phba->vpi_ids[vport->vpi];
|
|
|
mb->un.varRegVpi.sid = vport->fc_myDID;
|
|
|
- mb->un.varRegVpi.vfi = vport->vfi + vport->phba->vfi_base;
|
|
|
+ if (phba->sli_rev == LPFC_SLI_REV4)
|
|
|
+ mb->un.varRegVpi.vfi = phba->sli4_hba.vfi_ids[vport->vfi];
|
|
|
+ else
|
|
|
+ mb->un.varRegVpi.vfi = vport->vfi + vport->phba->vfi_base;
|
|
|
memcpy(mb->un.varRegVpi.wwn, &vport->fc_portname,
|
|
|
sizeof(struct lpfc_name));
|
|
|
mb->un.varRegVpi.wwn[0] = cpu_to_le32(mb->un.varRegVpi.wwn[0]);
|
|
@@ -901,10 +916,10 @@ lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb)
|
|
|
MAILBOX_t *mb = &pmb->u.mb;
|
|
|
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
|
|
|
|
|
|
- if (phba->sli_rev < LPFC_SLI_REV4)
|
|
|
- mb->un.varUnregVpi.vpi = vpi + phba->vpi_base;
|
|
|
- else
|
|
|
- mb->un.varUnregVpi.sli4_vpi = vpi + phba->vpi_base;
|
|
|
+ if (phba->sli_rev == LPFC_SLI_REV3)
|
|
|
+ mb->un.varUnregVpi.vpi = phba->vpi_ids[vpi];
|
|
|
+ else if (phba->sli_rev >= LPFC_SLI_REV4)
|
|
|
+ mb->un.varUnregVpi.sli4_vpi = phba->vpi_ids[vpi];
|
|
|
|
|
|
mb->mbxCommand = MBX_UNREG_VPI;
|
|
|
mb->mbxOwner = OWN_HOST;
|
|
@@ -1735,12 +1750,12 @@ lpfc_sli4_config(struct lpfc_hba *phba, struct lpfcMboxq *mbox,
|
|
|
return length;
|
|
|
}
|
|
|
|
|
|
- /* Setup for the none-embedded mbox command */
|
|
|
+ /* Setup for the non-embedded mbox command */
|
|
|
pcount = (SLI4_PAGE_ALIGN(length))/SLI4_PAGE_SIZE;
|
|
|
pcount = (pcount > LPFC_SLI4_MBX_SGE_MAX_PAGES) ?
|
|
|
LPFC_SLI4_MBX_SGE_MAX_PAGES : pcount;
|
|
|
/* Allocate record for keeping SGE virtual addresses */
|
|
|
- mbox->sge_array = kmalloc(sizeof(struct lpfc_mbx_nembed_sge_virt),
|
|
|
+ mbox->sge_array = kzalloc(sizeof(struct lpfc_mbx_nembed_sge_virt),
|
|
|
GFP_KERNEL);
|
|
|
if (!mbox->sge_array) {
|
|
|
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
|
|
@@ -1790,11 +1805,86 @@ lpfc_sli4_config(struct lpfc_hba *phba, struct lpfcMboxq *mbox,
|
|
|
/* The sub-header is in DMA memory, which needs endian converstion */
|
|
|
if (cfg_shdr)
|
|
|
lpfc_sli_pcimem_bcopy(cfg_shdr, cfg_shdr,
|
|
|
- sizeof(union lpfc_sli4_cfg_shdr));
|
|
|
-
|
|
|
+ sizeof(union lpfc_sli4_cfg_shdr));
|
|
|
return alloc_len;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_sli4_mbox_rsrc_extent - Initialize the opcode resource extent.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ * @mbox: pointer to an allocated lpfc mbox resource.
|
|
|
+ * @exts_count: the number of extents, if required, to allocate.
|
|
|
+ * @rsrc_type: the resource extent type.
|
|
|
+ * @emb: true if LPFC_SLI4_MBX_EMBED. false if LPFC_SLI4_MBX_NEMBED.
|
|
|
+ *
|
|
|
+ * This routine completes the subcommand header for SLI4 resource extent
|
|
|
+ * mailbox commands. It is called after lpfc_sli4_config. The caller must
|
|
|
+ * pass an allocated mailbox and the attributes required to initialize the
|
|
|
+ * mailbox correctly.
|
|
|
+ *
|
|
|
+ * Return: the actual length of the mbox command allocated.
|
|
|
+ **/
|
|
|
+int
|
|
|
+lpfc_sli4_mbox_rsrc_extent(struct lpfc_hba *phba, struct lpfcMboxq *mbox,
|
|
|
+ uint16_t exts_count, uint16_t rsrc_type, bool emb)
|
|
|
+{
|
|
|
+ uint8_t opcode = 0;
|
|
|
+ struct lpfc_mbx_nembed_rsrc_extent *n_rsrc_extnt = NULL;
|
|
|
+ void *virtaddr = NULL;
|
|
|
+
|
|
|
+ /* Set up SLI4 ioctl command header fields */
|
|
|
+ if (emb == LPFC_SLI4_MBX_NEMBED) {
|
|
|
+ /* Get the first SGE entry from the non-embedded DMA memory */
|
|
|
+ virtaddr = mbox->sge_array->addr[0];
|
|
|
+ if (virtaddr == NULL)
|
|
|
+ return 1;
|
|
|
+ n_rsrc_extnt = (struct lpfc_mbx_nembed_rsrc_extent *) virtaddr;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The resource type is common to all extent Opcodes and resides in the
|
|
|
+ * same position.
|
|
|
+ */
|
|
|
+ if (emb == LPFC_SLI4_MBX_EMBED)
|
|
|
+ bf_set(lpfc_mbx_alloc_rsrc_extents_type,
|
|
|
+ &mbox->u.mqe.un.alloc_rsrc_extents.u.req,
|
|
|
+ rsrc_type);
|
|
|
+ else {
|
|
|
+ /* This is DMA data. Byteswap is required. */
|
|
|
+ bf_set(lpfc_mbx_alloc_rsrc_extents_type,
|
|
|
+ n_rsrc_extnt, rsrc_type);
|
|
|
+ lpfc_sli_pcimem_bcopy(&n_rsrc_extnt->word4,
|
|
|
+ &n_rsrc_extnt->word4,
|
|
|
+ sizeof(uint32_t));
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Complete the initialization for the particular Opcode. */
|
|
|
+ opcode = lpfc_sli4_mbox_opcode_get(phba, mbox);
|
|
|
+ switch (opcode) {
|
|
|
+ case LPFC_MBOX_OPCODE_ALLOC_RSRC_EXTENT:
|
|
|
+ if (emb == LPFC_SLI4_MBX_EMBED)
|
|
|
+ bf_set(lpfc_mbx_alloc_rsrc_extents_cnt,
|
|
|
+ &mbox->u.mqe.un.alloc_rsrc_extents.u.req,
|
|
|
+ exts_count);
|
|
|
+ else
|
|
|
+ bf_set(lpfc_mbx_alloc_rsrc_extents_cnt,
|
|
|
+ n_rsrc_extnt, exts_count);
|
|
|
+ break;
|
|
|
+ case LPFC_MBOX_OPCODE_GET_ALLOC_RSRC_EXTENT:
|
|
|
+ case LPFC_MBOX_OPCODE_GET_RSRC_EXTENT_INFO:
|
|
|
+ case LPFC_MBOX_OPCODE_DEALLOC_RSRC_EXTENT:
|
|
|
+ /* Initialization is complete.*/
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
|
|
|
+ "2929 Resource Extent Opcode x%x is "
|
|
|
+ "unsupported\n", opcode);
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* lpfc_sli4_mbox_opcode_get - Get the opcode from a sli4 mailbox command
|
|
|
* @phba: pointer to lpfc hba data structure.
|
|
@@ -1939,9 +2029,12 @@ lpfc_init_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport)
|
|
|
bf_set(lpfc_init_vfi_vr, init_vfi, 1);
|
|
|
bf_set(lpfc_init_vfi_vt, init_vfi, 1);
|
|
|
bf_set(lpfc_init_vfi_vp, init_vfi, 1);
|
|
|
- bf_set(lpfc_init_vfi_vfi, init_vfi, vport->vfi + vport->phba->vfi_base);
|
|
|
- bf_set(lpfc_init_vpi_vpi, init_vfi, vport->vpi + vport->phba->vpi_base);
|
|
|
- bf_set(lpfc_init_vfi_fcfi, init_vfi, vport->phba->fcf.fcfi);
|
|
|
+ bf_set(lpfc_init_vfi_vfi, init_vfi,
|
|
|
+ vport->phba->sli4_hba.vfi_ids[vport->vfi]);
|
|
|
+ bf_set(lpfc_init_vpi_vpi, init_vfi,
|
|
|
+ vport->phba->vpi_ids[vport->vpi]);
|
|
|
+ bf_set(lpfc_init_vfi_fcfi, init_vfi,
|
|
|
+ vport->phba->fcf.fcfi);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1964,9 +2057,10 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport, dma_addr_t phys)
|
|
|
reg_vfi = &mbox->u.mqe.un.reg_vfi;
|
|
|
bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_REG_VFI);
|
|
|
bf_set(lpfc_reg_vfi_vp, reg_vfi, 1);
|
|
|
- bf_set(lpfc_reg_vfi_vfi, reg_vfi, vport->vfi + vport->phba->vfi_base);
|
|
|
+ bf_set(lpfc_reg_vfi_vfi, reg_vfi,
|
|
|
+ vport->phba->sli4_hba.vfi_ids[vport->vfi]);
|
|
|
bf_set(lpfc_reg_vfi_fcfi, reg_vfi, vport->phba->fcf.fcfi);
|
|
|
- bf_set(lpfc_reg_vfi_vpi, reg_vfi, vport->vpi + vport->phba->vpi_base);
|
|
|
+ bf_set(lpfc_reg_vfi_vpi, reg_vfi, vport->phba->vpi_ids[vport->vpi]);
|
|
|
memcpy(reg_vfi->wwn, &vport->fc_portname, sizeof(struct lpfc_name));
|
|
|
reg_vfi->wwn[0] = cpu_to_le32(reg_vfi->wwn[0]);
|
|
|
reg_vfi->wwn[1] = cpu_to_le32(reg_vfi->wwn[1]);
|
|
@@ -1997,9 +2091,9 @@ lpfc_init_vpi(struct lpfc_hba *phba, struct lpfcMboxq *mbox, uint16_t vpi)
|
|
|
memset(mbox, 0, sizeof(*mbox));
|
|
|
bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_INIT_VPI);
|
|
|
bf_set(lpfc_init_vpi_vpi, &mbox->u.mqe.un.init_vpi,
|
|
|
- vpi + phba->vpi_base);
|
|
|
+ phba->vpi_ids[vpi]);
|
|
|
bf_set(lpfc_init_vpi_vfi, &mbox->u.mqe.un.init_vpi,
|
|
|
- phba->pport->vfi + phba->vfi_base);
|
|
|
+ phba->sli4_hba.vfi_ids[phba->pport->vfi]);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -2019,7 +2113,7 @@ lpfc_unreg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport)
|
|
|
memset(mbox, 0, sizeof(*mbox));
|
|
|
bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_UNREG_VFI);
|
|
|
bf_set(lpfc_unreg_vfi_vfi, &mbox->u.mqe.un.unreg_vfi,
|
|
|
- vport->vfi + vport->phba->vfi_base);
|
|
|
+ vport->phba->sli4_hba.vfi_ids[vport->vfi]);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -2131,12 +2225,14 @@ lpfc_unreg_fcfi(struct lpfcMboxq *mbox, uint16_t fcfi)
|
|
|
void
|
|
|
lpfc_resume_rpi(struct lpfcMboxq *mbox, struct lpfc_nodelist *ndlp)
|
|
|
{
|
|
|
+ struct lpfc_hba *phba = ndlp->phba;
|
|
|
struct lpfc_mbx_resume_rpi *resume_rpi;
|
|
|
|
|
|
memset(mbox, 0, sizeof(*mbox));
|
|
|
resume_rpi = &mbox->u.mqe.un.resume_rpi;
|
|
|
bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_RESUME_RPI);
|
|
|
- bf_set(lpfc_resume_rpi_index, resume_rpi, ndlp->nlp_rpi);
|
|
|
+ bf_set(lpfc_resume_rpi_index, resume_rpi,
|
|
|
+ phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]);
|
|
|
bf_set(lpfc_resume_rpi_ii, resume_rpi, RESUME_INDEX_RPI);
|
|
|
resume_rpi->event_tag = ndlp->phba->fc_eventTag;
|
|
|
}
|