scsi: lpfc: vmid: Add support for VMID in mailbox command
authorGaurav Srivastava <gaurav.srivastava@broadcom.com>
Tue, 8 Jun 2021 04:35:49 +0000 (10:05 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 10 Jun 2021 14:01:32 +0000 (10:01 -0400)
Add supporting datastructures for mailbox command which helps in
determining if the firmware supports appid. Allocate resources for VMID at
initialization time and clean them up on removal.

Link: https://lore.kernel.org/r/20210608043556.274139-7-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>
drivers/scsi/lpfc/lpfc_hw4.h
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_mbox.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/lpfc/lpfc_sli.c

index f77e71e..eb8c735 100644 (file)
@@ -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
index f81dfa3..f309048 100644 (file)
@@ -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);
 
+       /* Clean up 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) {
@@ -4308,6 +4313,55 @@ lpfc_get_wwpn(struct lpfc_hba *phba)
 }
 
 /**
+ * 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 Success
+ *     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 (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);
+
+               /* Set 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;
+               }
+
+               hash_init(vport->hash_table);
+       }
+       return 0;
+}
+
+/**
  * lpfc_create_port - Create an FC port
  * @phba: pointer to lpfc hba data structure.
  * @instance: a unique integer ID to this FC port.
@@ -4459,6 +4513,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 +4543,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;
index eab9917..84bc373 100644 (file)
@@ -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 appheader 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;
 }
 
index 503919b..2b9d3fe 100644 (file)
@@ -5399,6 +5399,31 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd)
        return 0;
 }
 
+/*
+ * lpfc_vmid_vport_cleanup - cleans up the resources associated with a vport
+ * @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;
+
+       if (vport->port_type == LPFC_PHYSICAL_PORT)
+               del_timer_sync(&vport->phba->inactive_vmid_poll);
+
+       kfree(vport->qfpa_res);
+       kfree(vport->vmid_priority.vmid_range);
+       kfree(vport->vmid);
+
+       if (!hash_empty(vport->hash_table))
+               hash_for_each(vport->hash_table, bucket, cur, hnode)
+                       hash_del(&cur->hnode);
+
+       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
index 1ad1beb..64fc5af 100644 (file)
@@ -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.