Commit 742b0cf8 authored by Gaurav Srivastava's avatar Gaurav Srivastava Committed by Martin K. Petersen

scsi: lpfc: vmid: Implement CT commands for appid

Implement CT commands for registering and deregistering the appid for the
application. Also, a small change in decrementing the ndlp ref counter has
been added.

Link: https://lore.kernel.org/r/20210608043556.274139-10-muneendra.kumar@broadcom.comReviewed-by: default avatarHannes Reinecke <hare@suse.de>
Signed-off-by: default avatarGaurav Srivastava <gaurav.srivastava@broadcom.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
Signed-off-by: default avatarMuneendra Kumar <muneendra.kumar@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent dc50715e
......@@ -75,6 +75,9 @@
static char *lpfc_release_version = LPFC_DRIVER_VERSION;
static void
lpfc_cmpl_ct_cmd_vmid(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb);
static void
lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
......@@ -3777,3 +3780,255 @@ lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag)
}
return;
}
static void
lpfc_cmpl_ct_cmd_vmid(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb)
{
struct lpfc_vport *vport = cmdiocb->vport;
struct lpfc_dmabuf *inp = cmdiocb->context1;
struct lpfc_dmabuf *outp = cmdiocb->context2;
struct lpfc_sli_ct_request *ctcmd = inp->virt;
struct lpfc_sli_ct_request *ctrsp = outp->virt;
u16 rsp = ctrsp->CommandResponse.bits.CmdRsp;
struct app_id_object *app;
u32 cmd, hash, bucket;
struct lpfc_vmid *vmp, *cur;
u8 *data = outp->virt;
int i;
cmd = be16_to_cpu(ctcmd->CommandResponse.bits.CmdRsp);
if (cmd == SLI_CTAS_DALLAPP_ID)
lpfc_ct_free_iocb(phba, cmdiocb);
if (lpfc_els_chk_latt(vport) || rspiocb->iocb.ulpStatus) {
if (cmd != SLI_CTAS_DALLAPP_ID)
return;
}
/* Check for a CT LS_RJT response */
if (rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
if (cmd != SLI_CTAS_DALLAPP_ID)
lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY,
"3306 VMID FS_RJT Data: x%x x%x x%x\n",
cmd, ctrsp->ReasonCode,
ctrsp->Explanation);
if ((cmd != SLI_CTAS_DALLAPP_ID) ||
(ctrsp->ReasonCode != SLI_CT_UNABLE_TO_PERFORM_REQ) ||
(ctrsp->Explanation != SLI_CT_APP_ID_NOT_AVAILABLE)) {
/* If DALLAPP_ID failed retry later */
if (cmd == SLI_CTAS_DALLAPP_ID)
vport->load_flag |= FC_DEREGISTER_ALL_APP_ID;
return;
}
}
switch (cmd) {
case SLI_CTAS_RAPP_IDENT:
app = (struct app_id_object *)(RAPP_IDENT_OFFSET + data);
lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY,
"6712 RAPP_IDENT app id %d port id x%x id "
"len %d\n", be32_to_cpu(app->app_id),
be32_to_cpu(app->port_id),
app->obj.entity_id_len);
if (app->obj.entity_id_len == 0 || app->port_id == 0)
return;
hash = lpfc_vmid_hash_fn(app->obj.entity_id,
app->obj.entity_id_len);
vmp = lpfc_get_vmid_from_hashtable(vport, hash,
app->obj.entity_id);
if (vmp) {
write_lock(&vport->vmid_lock);
vmp->un.app_id = be32_to_cpu(app->app_id);
vmp->flag |= LPFC_VMID_REGISTERED;
vmp->flag &= ~LPFC_VMID_REQ_REGISTER;
write_unlock(&vport->vmid_lock);
/* Set IN USE flag */
vport->vmid_flag |= LPFC_VMID_IN_USE;
} else {
lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY,
"6901 No entry found %s hash %d\n",
app->obj.entity_id, hash);
}
break;
case SLI_CTAS_DAPP_IDENT:
app = (struct app_id_object *)(DAPP_IDENT_OFFSET + data);
lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY,
"6713 DAPP_IDENT app id %d port id x%x\n",
be32_to_cpu(app->app_id),
be32_to_cpu(app->port_id));
break;
case SLI_CTAS_DALLAPP_ID:
lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY,
"8856 Deregistered all app ids\n");
read_lock(&vport->vmid_lock);
for (i = 0; i < phba->cfg_max_vmid; i++) {
vmp = &vport->vmid[i];
if (vmp->flag != LPFC_VMID_SLOT_FREE)
memset(vmp, 0, sizeof(struct lpfc_vmid));
}
read_unlock(&vport->vmid_lock);
/* for all elements in the hash table */
if (!hash_empty(vport->hash_table))
hash_for_each(vport->hash_table, bucket, cur, hnode)
hash_del(&cur->hnode);
vport->load_flag |= FC_ALLOW_VMID;
break;
default:
lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY,
"8857 Invalid command code\n");
}
}
/**
* lpfc_vmid_cmd - Build and send a FDMI cmd to the specified NPort
* @vport: pointer to a host virtual N_Port data structure.
* @ndlp: ndlp to send FDMI cmd to (if NULL use FDMI_DID)
* cmdcode: FDMI command to send
* mask: Mask of HBA or PORT Attributes to send
*
* Builds and sends a FDMI command using the CT subsystem.
*/
int
lpfc_vmid_cmd(struct lpfc_vport *vport,
int cmdcode, struct lpfc_vmid *vmid)
{
struct lpfc_hba *phba = vport->phba;
struct lpfc_dmabuf *mp, *bmp;
struct lpfc_sli_ct_request *ctreq;
struct ulp_bde64 *bpl;
u32 size;
u32 rsp_size;
u8 *data;
struct lpfc_vmid_rapp_ident_list *rap;
struct lpfc_vmid_dapp_ident_list *dap;
u8 retry = 0;
struct lpfc_nodelist *ndlp;
void (*cmpl)(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb);
ndlp = lpfc_findnode_did(vport, FDMI_DID);
if (!ndlp || ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)
return 0;
cmpl = lpfc_cmpl_ct_cmd_vmid;
/* fill in BDEs for command */
/* Allocate buffer for command payload */
mp = kmalloc(sizeof(*mp), GFP_KERNEL);
if (!mp)
goto vmid_free_mp_exit;
mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
if (!mp->virt)
goto vmid_free_mp_virt_exit;
/* Allocate buffer for Buffer ptr list */
bmp = kmalloc(sizeof(*bmp), GFP_KERNEL);
if (!bmp)
goto vmid_free_bmp_exit;
bmp->virt = lpfc_mbuf_alloc(phba, 0, &bmp->phys);
if (!bmp->virt)
goto vmid_free_bmp_virt_exit;
INIT_LIST_HEAD(&mp->list);
INIT_LIST_HEAD(&bmp->list);
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
"3275 VMID Request Data: x%x x%x x%x\n",
vport->fc_flag, vport->port_state, cmdcode);
ctreq = (struct lpfc_sli_ct_request *)mp->virt;
data = mp->virt;
/* First populate the CT_IU preamble */
memset(data, 0, LPFC_BPL_SIZE);
ctreq->RevisionId.bits.Revision = SLI_CT_REVISION;
ctreq->RevisionId.bits.InId = 0;
ctreq->FsType = SLI_CT_MANAGEMENT_SERVICE;
ctreq->FsSubType = SLI_CT_APP_SEV_Subtypes;
ctreq->CommandResponse.bits.CmdRsp = cpu_to_be16(cmdcode);
rsp_size = LPFC_BPL_SIZE;
size = 0;
switch (cmdcode) {
case SLI_CTAS_RAPP_IDENT:
lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY,
"1329 RAPP_IDENT for %s\n", vmid->host_vmid);
ctreq->un.PortID = cpu_to_be32(vport->fc_myDID);
rap = (struct lpfc_vmid_rapp_ident_list *)
(DAPP_IDENT_OFFSET + data);
rap->no_of_objects = cpu_to_be32(1);
rap->obj[0].entity_id_len = vmid->vmid_len;
memcpy(rap->obj[0].entity_id, vmid->host_vmid, vmid->vmid_len);
size = RAPP_IDENT_OFFSET +
sizeof(struct lpfc_vmid_rapp_ident_list);
retry = 1;
break;
case SLI_CTAS_GALLAPPIA_ID:
ctreq->un.PortID = cpu_to_be32(vport->fc_myDID);
size = GALLAPPIA_ID_SIZE;
break;
case SLI_CTAS_DAPP_IDENT:
lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY,
"1469 DAPP_IDENT for %s\n", vmid->host_vmid);
ctreq->un.PortID = cpu_to_be32(vport->fc_myDID);
dap = (struct lpfc_vmid_dapp_ident_list *)
(DAPP_IDENT_OFFSET + data);
dap->no_of_objects = cpu_to_be32(1);
dap->obj[0].entity_id_len = vmid->vmid_len;
memcpy(dap->obj[0].entity_id, vmid->host_vmid, vmid->vmid_len);
size = DAPP_IDENT_OFFSET +
sizeof(struct lpfc_vmid_dapp_ident_list);
write_lock(&vport->vmid_lock);
vmid->flag &= ~LPFC_VMID_REGISTERED;
write_unlock(&vport->vmid_lock);
retry = 1;
break;
case SLI_CTAS_DALLAPP_ID:
ctreq->un.PortID = cpu_to_be32(vport->fc_myDID);
size = DALLAPP_ID_SIZE;
break;
default:
lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY,
"7062 VMID cmdcode x%x not supported\n",
cmdcode);
goto vmid_free_all_mem;
}
ctreq->CommandResponse.bits.Size = cpu_to_be16(rsp_size);
bpl = (struct ulp_bde64 *)bmp->virt;
bpl->addrHigh = putPaddrHigh(mp->phys);
bpl->addrLow = putPaddrLow(mp->phys);
bpl->tus.f.bdeFlags = 0;
bpl->tus.f.bdeSize = size;
/* The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count
* to hold ndlp reference for the corresponding callback function.
*/
if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, retry))
return 0;
vmid_free_all_mem:
lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
vmid_free_bmp_virt_exit:
kfree(bmp);
vmid_free_bmp_exit:
lpfc_mbuf_free(phba, mp->virt, mp->phys);
vmid_free_mp_virt_exit:
kfree(mp);
vmid_free_mp_exit:
/* Issue CT request failed */
lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY,
"3276 VMID CT request failed Data: x%x\n", cmdcode);
return -EIO;
}
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