From: Darren Trapp <[email protected]>

Add Support for First Burst for FC-NVMe protocol. This
feature requires First Burst support in the firmware.

Signed-off-by: Darren Trapp <[email protected]>
Signed-off-by: Himanshu Madhani <[email protected]>
---
 drivers/scsi/qla2xxx/qla_def.h  |  4 ++++
 drivers/scsi/qla2xxx/qla_init.c |  6 ++++++
 drivers/scsi/qla2xxx/qla_iocb.c |  5 ++++-
 drivers/scsi/qla2xxx/qla_isr.c  |  9 +++++++++
 drivers/scsi/qla2xxx/qla_mbx.c  |  5 +++--
 drivers/scsi/qla2xxx/qla_nvme.c | 15 ++++++++++++---
 drivers/scsi/qla2xxx/qla_nvme.h |  2 +-
 7 files changed, 39 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 80acf30fd8a5..c256ba7fba84 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -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;
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index cdf57eb643b3..2d9336a87e42 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1829,6 +1829,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:
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 2c27ae1924c5..cdac282b5bd3 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -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;
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index bde9940ea7d1..b5ae76869d5b 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -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;
 
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index f4adf6baee69..6c911f2e4cdb 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -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. */
diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c
index 39d892bbd219..efc23761de1c 100644
--- a/drivers/scsi/qla2xxx/qla_nvme.c
+++ b/drivers/scsi/qla2xxx/qla_nvme.c
@@ -359,16 +359,25 @@ 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);
+                   cpu_to_le16(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);
+                   cpu_to_le16(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 |=
+                                   cpu_to_le16(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 */
diff --git a/drivers/scsi/qla2xxx/qla_nvme.h b/drivers/scsi/qla2xxx/qla_nvme.h
index 4941d107fb1c..da8dad5ad693 100644
--- a/drivers/scsi/qla2xxx/qla_nvme.h
+++ b/drivers/scsi/qla2xxx/qla_nvme.h
@@ -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
-- 
2.12.0

Reply via email to