scsi: qla2xxx: Add First Burst support for FC-NVMe devices
authorDarren Trapp <darren.trapp@cavium.com>
Fri, 15 Feb 2019 22:37:13 +0000 (14:37 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 19 Feb 2019 23:58:35 +0000 (18:58 -0500)
Add Support for First Burst for FC-NVMe protocol. This feature requires
First Burst support in the firmware.

Signed-off-by: Darren Trapp <darren.trapp@cavium.com>
Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_nvme.c
drivers/scsi/qla2xxx/qla_nvme.h

index 80acf30fd8a518abf732334093e082b59bc781fd..c256ba7fba84772f87c57f63e5d91387796d11df 100644 (file)
@@ -2367,7 +2367,9 @@ typedef struct fc_port {
 #define NVME_PRLI_SP_INITIATOR  BIT_5
 #define NVME_PRLI_SP_TARGET     BIT_4
 #define NVME_PRLI_SP_DISCOVERY  BIT_3
+#define NVME_PRLI_SP_FIRST_BURST       BIT_0
        uint8_t nvme_flag;
+       uint32_t nvme_first_burst_size;
 #define NVME_FLAG_REGISTERED 4
 #define NVME_FLAG_DELETING 2
 #define NVME_FLAG_RESETTING 1
@@ -3966,6 +3968,7 @@ struct qla_hw_data {
        uint16_t        fw_subminor_version;
        uint16_t        fw_attributes;
        uint16_t        fw_attributes_h;
+#define FW_ATTR_H_NVME_FBURST  BIT_1
 #define FW_ATTR_H_NVME         BIT_10
 #define FW_ATTR_H_NVME_UPDATED  BIT_14
 
@@ -4260,6 +4263,7 @@ typedef struct scsi_qla_host {
                uint32_t        qpairs_req_created:1;
                uint32_t        qpairs_rsp_created:1;
                uint32_t        nvme_enabled:1;
+               uint32_t        nvme_first_burst:1;
        } flags;
 
        atomic_t        loop_state;
index c6c96533eef23f551d7905d248703d11bd261b82..4480a5632c11000a7dbbb6fa51576f2b5882797a 100644 (file)
@@ -1831,6 +1831,12 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
 
                ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset;
                ea->fcport->logout_on_delete = 1;
+               ea->fcport->nvme_prli_service_param = ea->iop[0];
+               if (ea->iop[0] & NVME_PRLI_SP_FIRST_BURST)
+                       ea->fcport->nvme_first_burst_size =
+                           (ea->iop[1] & 0xffff) * 512;
+               else
+                       ea->fcport->nvme_first_burst_size = 0;
                qla24xx_post_gpdb_work(vha, ea->fcport, 0);
                break;
        default:
index 2c27ae1924c575d62972b57e3b7c4aed4fa6ca13..cdac282b5bd3bf3fea95be3bca1166631361278a 100644 (file)
@@ -2419,8 +2419,11 @@ qla24xx_prli_iocb(srb_t *sp, struct logio_entry_24xx *logio)
 
        logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
        logio->control_flags = cpu_to_le16(LCF_COMMAND_PRLI);
-       if (lio->u.logio.flags & SRB_LOGIN_NVME_PRLI)
+       if (lio->u.logio.flags & SRB_LOGIN_NVME_PRLI) {
                logio->control_flags |= LCF_NVME_PRLI;
+               if (sp->vha->flags.nvme_first_burst)
+                       logio->io_parameter[0] = NVME_PRLI_SP_FIRST_BURST;
+       }
 
        logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
        logio->port_id[0] = sp->fcport->d_id.b.al_pa;
index bde9940ea7d1f51a87280d7f0285e6d80a3bec92..b5ae76869d5b9735199b869b57190db4a50da163 100644 (file)
@@ -1715,6 +1715,15 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
 
                vha->hw->exch_starvation = 0;
                data[0] = MBS_COMMAND_COMPLETE;
+
+               if (sp->type == SRB_PRLI_CMD) {
+                       lio->u.logio.iop[0] =
+                           le32_to_cpu(logio->io_parameter[0]);
+                       lio->u.logio.iop[1] =
+                           le32_to_cpu(logio->io_parameter[1]);
+                       goto logio_done;
+               }
+
                if (sp->type != SRB_LOGIN_CMD)
                        goto logio_done;
 
index f4adf6baee690ad5e4d7b670eaab0819dd99b581..6c911f2e4cdbbe09f0ed5e0e188e887a4a642059 100644 (file)
@@ -1112,6 +1112,9 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
                if ((ha->fw_attributes_h &
                    (FW_ATTR_H_NVME | FW_ATTR_H_NVME_UPDATED)) &&
                        ql2xnvmeenable) {
+                       if (ha->fw_attributes_h & FW_ATTR_H_NVME_FBURST)
+                               vha->flags.nvme_first_burst = 1;
+
                        vha->flags.nvme_enabled = 1;
                        ql_log(ql_log_info, vha, 0xd302,
                            "%s: FC-NVMe is Enabled (0x%x)\n",
@@ -6267,8 +6270,6 @@ int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport,
        fcport->d_id.b.rsvd_1 = 0;
 
        if (fcport->fc4f_nvme) {
-               fcport->nvme_prli_service_param =
-                   pd->prli_nvme_svc_param_word_3;
                fcport->port_type = FCT_NVME;
        } else {
                /* If not target must be initiator or unknown type. */
index 39d892bbd2193bf5c5a68a821f67be2796a908d4..d6ba078d8255caf1382db411755051120f5c773c 100644 (file)
@@ -358,17 +358,24 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp)
 
        /* No data transfer how do we check buffer len == 0?? */
        if (fd->io_dir == NVMEFC_FCP_READ) {
-               cmd_pkt->control_flags =
-                   cpu_to_le16(CF_READ_DATA | CF_NVME_ENABLE);
+               cmd_pkt->control_flags = CF_READ_DATA;
                vha->qla_stats.input_bytes += fd->payload_length;
                vha->qla_stats.input_requests++;
        } else if (fd->io_dir == NVMEFC_FCP_WRITE) {
-               cmd_pkt->control_flags =
-                   cpu_to_le16(CF_WRITE_DATA | CF_NVME_ENABLE);
+               cmd_pkt->control_flags = CF_WRITE_DATA;
+               if ((vha->flags.nvme_first_burst) &&
+                   (sp->fcport->nvme_prli_service_param &
+                       NVME_PRLI_SP_FIRST_BURST)) {
+                       if ((fd->payload_length <=
+                           sp->fcport->nvme_first_burst_size) ||
+                               (sp->fcport->nvme_first_burst_size == 0))
+                               cmd_pkt->control_flags |=
+                                   CF_NVME_FIRST_BURST_ENABLE;
+               }
                vha->qla_stats.output_bytes += fd->payload_length;
                vha->qla_stats.output_requests++;
        } else if (fd->io_dir == 0) {
-               cmd_pkt->control_flags = cpu_to_le16(CF_NVME_ENABLE);
+               cmd_pkt->control_flags = 0;
        }
 
        /* Set NPORT-ID */
index 4941d107fb1c31f09211ab491377b9349f90593a..da8dad5ad6939cc81ec2c98616b11ce7106cf3f1 100644 (file)
@@ -57,7 +57,7 @@ struct cmd_nvme {
        uint64_t rsvd;
 
        uint16_t control_flags;         /* Control Flags */
-#define CF_NVME_ENABLE                  BIT_9
+#define CF_NVME_FIRST_BURST_ENABLE     BIT_11
 #define CF_DIF_SEG_DESCR_ENABLE         BIT_3
 #define CF_DATA_SEG_DESCR_ENABLE        BIT_2
 #define CF_READ_DATA                    BIT_1