From: Gaurav Srivastava <gaurav.srivastava@xxxxxxxxxxxx> This patch does the following - 1.adds supporting datastructures for mailbox command which helps in determining if the firmware supports appid or not. 2.This patch allocates the resource for vmid and checks if the firmware supports the feature or not. 3.The patch cleans up the vmid resources and stops the timer. Reviewed-by: Hannes Reinecke <hare@xxxxxxx> Signed-off-by: Gaurav Srivastava <gaurav.srivastava@xxxxxxxxxxxx> Signed-off-by: James Smart <jsmart2021@xxxxxxxxx> --- v11: No change v10: No change v9: Modified code for use of hashtable v8: Added new function declaration, return error code and memory allocation API changes v7: No change v6: Added Forward declarations and functions to static v5: Merged patches 8 and 11 of v4 to this patch Changed Return code to non-numeric/Symbol v4: No change v3: No change v2: Ported the patch on top of 5.10/scsi-queue --- drivers/scsi/lpfc/lpfc_hw4.h | 12 +++++++ drivers/scsi/lpfc/lpfc_init.c | 64 +++++++++++++++++++++++++++++++++++ drivers/scsi/lpfc/lpfc_mbox.c | 6 ++++ drivers/scsi/lpfc/lpfc_scsi.c | 29 ++++++++++++++++ drivers/scsi/lpfc/lpfc_sli.c | 9 +++++ 5 files changed, 120 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index f77e71e6dbbd..eb8c735a243b 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -273,6 +273,9 @@ struct lpfc_sli4_flags { #define lpfc_vfi_rsrc_rdy_MASK 0x00000001 #define lpfc_vfi_rsrc_rdy_WORD word0 #define LPFC_VFI_RSRC_RDY 1 +#define lpfc_ftr_ashdr_SHIFT 4 +#define lpfc_ftr_ashdr_MASK 0x00000001 +#define lpfc_ftr_ashdr_WORD word0 }; struct sli4_bls_rsp { @@ -2944,6 +2947,9 @@ struct lpfc_mbx_request_features { #define lpfc_mbx_rq_ftr_rq_mrqp_SHIFT 16 #define lpfc_mbx_rq_ftr_rq_mrqp_MASK 0x00000001 #define lpfc_mbx_rq_ftr_rq_mrqp_WORD word2 +#define lpfc_mbx_rq_ftr_rq_ashdr_SHIFT 17 +#define lpfc_mbx_rq_ftr_rq_ashdr_MASK 0x00000001 +#define lpfc_mbx_rq_ftr_rq_ashdr_WORD word2 uint32_t word3; #define lpfc_mbx_rq_ftr_rsp_iaab_SHIFT 0 #define lpfc_mbx_rq_ftr_rsp_iaab_MASK 0x00000001 @@ -2975,6 +2981,9 @@ struct lpfc_mbx_request_features { #define lpfc_mbx_rq_ftr_rsp_mrqp_SHIFT 16 #define lpfc_mbx_rq_ftr_rsp_mrqp_MASK 0x00000001 #define lpfc_mbx_rq_ftr_rsp_mrqp_WORD word3 +#define lpfc_mbx_rq_ftr_rsp_ashdr_SHIFT 17 +#define lpfc_mbx_rq_ftr_rsp_ashdr_MASK 0x00000001 +#define lpfc_mbx_rq_ftr_rsp_ashdr_WORD word3 }; struct lpfc_mbx_memory_dump_type3 { @@ -4219,6 +4228,9 @@ struct wqe_common { #define wqe_xchg_WORD word10 #define LPFC_SCSI_XCHG 0x0 #define LPFC_NVME_XCHG 0x1 +#define wqe_appid_SHIFT 5 +#define wqe_appid_MASK 0x00000001 +#define wqe_appid_WORD word10 #define wqe_oas_SHIFT 6 #define wqe_oas_MASK 0x00000001 #define wqe_oas_WORD word10 diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index f81dfa3cb0a1..d6434e4ffa20 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -98,6 +98,7 @@ static struct scsi_transport_template *lpfc_transport_template = NULL; static struct scsi_transport_template *lpfc_vport_transport_template = NULL; static DEFINE_IDR(lpfc_hba_index); #define LPFC_NVMET_BUF_POST 254 +static int lpfc_vmid_res_alloc(struct lpfc_hba *phba, struct lpfc_vport *vport); /** * lpfc_config_port_prep - Perform lpfc initialization prior to config port @@ -2888,6 +2889,10 @@ lpfc_cleanup(struct lpfc_vport *vport) if (phba->link_state > LPFC_LINK_DOWN) lpfc_port_link_failure(vport); + /* cleanup vmid resources */ + if (lpfc_is_vmid_enabled(phba)) + lpfc_vmid_vport_cleanup(vport); + list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { if (vport->port_type != LPFC_PHYSICAL_PORT && ndlp->nlp_DID == Fabric_DID) { @@ -4307,6 +4312,57 @@ lpfc_get_wwpn(struct lpfc_hba *phba) return rol64(wwn, 32); } +/** + * lpfc_vmid_res_alloc - Allocates resources for VMID + * @phba: pointer to lpfc hba data structure. + * @vport: pointer to vport data structure + * + * This routine allocated the resources needed for the vmid. + * + * Return codes + * 0 on Succeess + * Non-0 on Failure + */ +static int +lpfc_vmid_res_alloc(struct lpfc_hba *phba, struct lpfc_vport *vport) +{ + /* vmid feature is supported only on SLI4 */ + if (phba->sli_rev == LPFC_SLI_REV3) { + phba->cfg_vmid_app_header = 0; + phba->cfg_vmid_priority_tagging = 0; + } + + /* if enabled, then allocated the resources */ + if (lpfc_is_vmid_enabled(phba)) { + vport->vmid = + kcalloc(phba->cfg_max_vmid, sizeof(struct lpfc_vmid), + GFP_KERNEL); + if (!vport->vmid) + return -ENOMEM; + + rwlock_init(&vport->vmid_lock); + + /* setting the VMID parameters for the vport */ + vport->vmid_priority_tagging = phba->cfg_vmid_priority_tagging; + vport->vmid_inactivity_timeout = + phba->cfg_vmid_inactivity_timeout; + vport->max_vmid = phba->cfg_max_vmid; + vport->cur_vmid_cnt = 0; + + vport->vmid_priority_range = bitmap_zalloc + (LPFC_VMID_MAX_PRIORITY_RANGE, GFP_KERNEL); + + if (!vport->vmid_priority_range) { + kfree(vport->vmid); + return -ENOMEM; + } + + /* Initialize the hashtable */ + hash_init(vport->hash_table); + } + return 0; +} + /** * lpfc_create_port - Create an FC port * @phba: pointer to lpfc hba data structure. @@ -4459,6 +4515,12 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) vport->port_type, shost->sg_tablesize, phba->cfg_scsi_seg_cnt, phba->cfg_sg_seg_cnt); + /* allocate the resources for vmid */ + rc = lpfc_vmid_res_alloc(phba, vport); + + if (rc) + goto out; + /* Initialize all internally managed lists. */ INIT_LIST_HEAD(&vport->fc_nodes); INIT_LIST_HEAD(&vport->rcv_buffer_list); @@ -4483,6 +4545,8 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) return vport; out_put_shost: + kfree(vport->vmid); + bitmap_free(vport->vmid_priority_range); scsi_host_put(shost); out: return NULL; diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index eab991739e37..698243ca8f09 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c @@ -2101,6 +2101,12 @@ lpfc_request_features(struct lpfc_hba *phba, struct lpfcMboxq *mboxq) bf_set(lpfc_mbx_rq_ftr_rq_iaab, &mboxq->u.mqe.un.req_ftrs, 0); bf_set(lpfc_mbx_rq_ftr_rq_iaar, &mboxq->u.mqe.un.req_ftrs, 0); } + + /* Enable Application Services Header for apphedr VMID */ + if (phba->cfg_vmid_app_header) { + bf_set(lpfc_mbx_rq_ftr_rq_ashdr, &mboxq->u.mqe.un.req_ftrs, 1); + bf_set(lpfc_ftr_ashdr, &phba->sli4_hba.sli4_flags, 1); + } return; } diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index b8bb012abb33..37188a6c5c27 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -5417,6 +5417,35 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) return 0; } +/* + * lpfc_vmid_vport_cleanup - cleans up the resources associated with a vports + * @vport: The virtual port for which this call is being executed. + */ +void lpfc_vmid_vport_cleanup(struct lpfc_vport *vport) +{ + u32 bucket; + struct lpfc_vmid *cur; + + /* delete the timer */ + if (vport->port_type == LPFC_PHYSICAL_PORT) + del_timer_sync(&vport->phba->inactive_vmid_poll); + + /* free the resources */ + kfree(vport->qfpa_res); + kfree(vport->vmid_priority.vmid_range); + kfree(vport->vmid); + + /* 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); + + /* reset variables */ + vport->qfpa_res = NULL; + vport->vmid_priority.vmid_range = NULL; + vport->vmid = NULL; + vport->cur_vmid_cnt = 0; +} /** * lpfc_abort_handler - scsi_host_template eh_abort_handler entry point diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 1ad1beb2a8a8..c7d0acd6c8ef 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -7699,6 +7699,15 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) goto out_free_mbox; } + /* Disable vmid if app header is not supported */ + if (phba->cfg_vmid_app_header && !(bf_get(lpfc_mbx_rq_ftr_rsp_ashdr, + &mqe->un.req_ftrs))) { + bf_set(lpfc_ftr_ashdr, &phba->sli4_hba.sli4_flags, 0); + phba->cfg_vmid_app_header = 0; + lpfc_printf_log(phba, KERN_DEBUG, LOG_SLI, + "1242 vmid feature not supported\n"); + } + /* * The port must support FCP initiator mode as this is the * only mode running in the host. -- 2.26.2