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.com Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Gaurav Srivastava <gaurav.srivastava@broadcom.com> Signed-off-by: James Smart <jsmart2021@gmail.com> Signed-off-by: Muneendra Kumar <muneendra.kumar@broadcom.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
dc50715e5c
commit
742b0cf87a
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user