aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <jsmart2021@gmail.com>2018-02-22 11:18:50 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2018-02-22 20:39:29 -0500
commit4e565cf04138fca6ffeb884044febf922b2306d0 (patch)
treef3a195ce30d8447824e800ee437b539535c5d6fb
parent63452e144662a90b77fcdb27bd33c8b43655b850 (diff)
scsi: lpfc: Work around NVME cmd iu SGL type
The hardware offload for NVME commands was created when the FC-NVME standard was setting SGL Descriptor Type to SGL Data Block Descriptor (0h) and SGL Descriptor Sub Type to Address (0h). A late change in NVMe-over-Fabrics obsoleted these values, creating a transport SGL descriptor type with new values to go into these fields. For initial hardware support, in order to be compliant to the spec, use host-supplied cmd IU buffers instead of the adapter generated values. Later hardware will correct this. Add a module parameter to override this offload disablement if looking for lowest latency. This is reasonable as nothing in FC-NVME uses the SQE SGL values. Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: James Smart <james.smart@broadcom.com> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/lpfc/lpfc.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c14
-rw-r--r--drivers/scsi/lpfc/lpfc_hw4.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_nvme.c51
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c15
6 files changed, 69 insertions, 17 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 9136a59b1c5b..6c0d351c0d0d 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -782,6 +782,7 @@ struct lpfc_hba {
782 uint32_t cfg_fcp_io_channel; 782 uint32_t cfg_fcp_io_channel;
783 uint32_t cfg_suppress_rsp; 783 uint32_t cfg_suppress_rsp;
784 uint32_t cfg_nvme_oas; 784 uint32_t cfg_nvme_oas;
785 uint32_t cfg_nvme_embed_cmd;
785 uint32_t cfg_nvme_io_channel; 786 uint32_t cfg_nvme_io_channel;
786 uint32_t cfg_nvmet_mrq; 787 uint32_t cfg_nvmet_mrq;
787 uint32_t cfg_enable_nvmet; 788 uint32_t cfg_enable_nvmet;
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 14f6efcf8f0b..46f6d97d21d6 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -5042,6 +5042,18 @@ LPFC_ATTR_RW(nvme_oas, 0, 0, 1,
5042 "Use OAS bit on NVME IOs"); 5042 "Use OAS bit on NVME IOs");
5043 5043
5044/* 5044/*
5045 * lpfc_nvme_embed_cmd: Use the oas bit when sending NVME/NVMET IOs
5046 *
5047 * 0 = Put NVME Command in SGL
5048 * 1 = Embed NVME Command in WQE (unless G7)
5049 * 2 = Embed NVME Command in WQE (force)
5050 *
5051 * Value range is [0,2]. Default value is 1.
5052 */
5053LPFC_ATTR_RW(nvme_embed_cmd, 1, 0, 2,
5054 "Embed NVME Command in WQE");
5055
5056/*
5045 * lpfc_fcp_io_channel: Set the number of FCP IO channels the driver 5057 * lpfc_fcp_io_channel: Set the number of FCP IO channels the driver
5046 * will advertise it supports to the SCSI layer. This also will map to 5058 * will advertise it supports to the SCSI layer. This also will map to
5047 * the number of WQs the driver will create. 5059 * the number of WQs the driver will create.
@@ -5282,6 +5294,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
5282 &dev_attr_lpfc_task_mgmt_tmo, 5294 &dev_attr_lpfc_task_mgmt_tmo,
5283 &dev_attr_lpfc_use_msi, 5295 &dev_attr_lpfc_use_msi,
5284 &dev_attr_lpfc_nvme_oas, 5296 &dev_attr_lpfc_nvme_oas,
5297 &dev_attr_lpfc_nvme_embed_cmd,
5285 &dev_attr_lpfc_auto_imax, 5298 &dev_attr_lpfc_auto_imax,
5286 &dev_attr_lpfc_fcp_imax, 5299 &dev_attr_lpfc_fcp_imax,
5287 &dev_attr_lpfc_fcp_cpu_map, 5300 &dev_attr_lpfc_fcp_cpu_map,
@@ -6306,6 +6319,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
6306 lpfc_enable_SmartSAN_init(phba, lpfc_enable_SmartSAN); 6319 lpfc_enable_SmartSAN_init(phba, lpfc_enable_SmartSAN);
6307 lpfc_use_msi_init(phba, lpfc_use_msi); 6320 lpfc_use_msi_init(phba, lpfc_use_msi);
6308 lpfc_nvme_oas_init(phba, lpfc_nvme_oas); 6321 lpfc_nvme_oas_init(phba, lpfc_nvme_oas);
6322 lpfc_nvme_embed_cmd_init(phba, lpfc_nvme_embed_cmd);
6309 lpfc_auto_imax_init(phba, lpfc_auto_imax); 6323 lpfc_auto_imax_init(phba, lpfc_auto_imax);
6310 lpfc_fcp_imax_init(phba, lpfc_fcp_imax); 6324 lpfc_fcp_imax_init(phba, lpfc_fcp_imax);
6311 lpfc_fcp_cpu_map_init(phba, lpfc_fcp_cpu_map); 6325 lpfc_fcp_cpu_map_init(phba, lpfc_fcp_cpu_map);
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index ed5e870c58c3..37c547b4bc78 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -2678,6 +2678,7 @@ struct lpfc_mbx_read_rev {
2678#define lpfc_mbx_rd_rev_vpd_MASK 0x00000001 2678#define lpfc_mbx_rd_rev_vpd_MASK 0x00000001
2679#define lpfc_mbx_rd_rev_vpd_WORD word1 2679#define lpfc_mbx_rd_rev_vpd_WORD word1
2680 uint32_t first_hw_rev; 2680 uint32_t first_hw_rev;
2681#define LPFC_G7_ASIC_1 0xd
2681 uint32_t second_hw_rev; 2682 uint32_t second_hw_rev;
2682 uint32_t word4_rsvd; 2683 uint32_t word4_rsvd;
2683 uint32_t third_hw_rev; 2684 uint32_t third_hw_rev;
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index ecb42cae71f2..50bc6c6efa87 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -10653,11 +10653,11 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
10653 phba->fcp_embed_io = 0; 10653 phba->fcp_embed_io = 0;
10654 10654
10655 lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_NVME, 10655 lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_NVME,
10656 "6422 XIB %d: FCP %d %d NVME %d %d %d\n", 10656 "6422 XIB %d: FCP %d %d NVME %d %d %d %d\n",
10657 bf_get(cfg_xib, mbx_sli4_parameters), 10657 bf_get(cfg_xib, mbx_sli4_parameters),
10658 phba->fcp_embed_pbde, phba->fcp_embed_io, 10658 phba->fcp_embed_pbde, phba->fcp_embed_io,
10659 phba->nvme_support, phba->nvme_embed_pbde, 10659 phba->nvme_support, phba->nvme_embed_pbde,
10660 phba->cfg_suppress_rsp); 10660 phba->cfg_nvme_embed_cmd, phba->cfg_suppress_rsp);
10661 10661
10662 if ((bf_get(cfg_cqpsize, mbx_sli4_parameters) & LPFC_CQ_16K_PAGE_SZ) && 10662 if ((bf_get(cfg_cqpsize, mbx_sli4_parameters) & LPFC_CQ_16K_PAGE_SZ) &&
10663 (bf_get(cfg_wqpsize, mbx_sli4_parameters) & LPFC_WQ_16K_PAGE_SZ) && 10663 (bf_get(cfg_wqpsize, mbx_sli4_parameters) & LPFC_WQ_16K_PAGE_SZ) &&
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index c75958daf799..6ea6cc372647 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -617,11 +617,21 @@ lpfc_nvme_adj_fcp_sgls(struct lpfc_vport *vport,
617 struct lpfc_nvme_buf *lpfc_ncmd, 617 struct lpfc_nvme_buf *lpfc_ncmd,
618 struct nvmefc_fcp_req *nCmd) 618 struct nvmefc_fcp_req *nCmd)
619{ 619{
620 struct lpfc_hba *phba = vport->phba;
620 struct sli4_sge *sgl; 621 struct sli4_sge *sgl;
621 union lpfc_wqe128 *wqe; 622 union lpfc_wqe128 *wqe;
622 uint32_t *wptr, *dptr; 623 uint32_t *wptr, *dptr;
623 624
624 /* 625 /*
626 * Get a local pointer to the built-in wqe and correct
627 * the cmd size to match NVME's 96 bytes and fix
628 * the dma address.
629 */
630
631 /* 128 byte wqe support here */
632 wqe = (union lpfc_wqe128 *)&lpfc_ncmd->cur_iocbq.wqe;
633
634 /*
625 * Adjust the FCP_CMD and FCP_RSP DMA data and sge_len to 635 * Adjust the FCP_CMD and FCP_RSP DMA data and sge_len to
626 * match NVME. NVME sends 96 bytes. Also, use the 636 * match NVME. NVME sends 96 bytes. Also, use the
627 * nvme commands command and response dma addresses 637 * nvme commands command and response dma addresses
@@ -630,6 +640,25 @@ lpfc_nvme_adj_fcp_sgls(struct lpfc_vport *vport,
630 */ 640 */
631 sgl = lpfc_ncmd->nvme_sgl; 641 sgl = lpfc_ncmd->nvme_sgl;
632 sgl->sge_len = cpu_to_le32(nCmd->cmdlen); 642 sgl->sge_len = cpu_to_le32(nCmd->cmdlen);
643 if (phba->cfg_nvme_embed_cmd) {
644 sgl->addr_hi = 0;
645 sgl->addr_lo = 0;
646
647 /* Word 0-2 - NVME CMND IU (embedded payload) */
648 wqe->generic.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_IMMED;
649 wqe->generic.bde.tus.f.bdeSize = 56;
650 wqe->generic.bde.addrHigh = 0;
651 wqe->generic.bde.addrLow = 64; /* Word 16 */
652 } else {
653 sgl->addr_hi = cpu_to_le32(putPaddrHigh(nCmd->cmddma));
654 sgl->addr_lo = cpu_to_le32(putPaddrLow(nCmd->cmddma));
655
656 /* Word 0-2 - NVME CMND IU Inline BDE */
657 wqe->generic.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64;
658 wqe->generic.bde.tus.f.bdeSize = nCmd->cmdlen;
659 wqe->generic.bde.addrHigh = sgl->addr_hi;
660 wqe->generic.bde.addrLow = sgl->addr_lo;
661 }
633 662
634 sgl++; 663 sgl++;
635 664
@@ -644,27 +673,19 @@ lpfc_nvme_adj_fcp_sgls(struct lpfc_vport *vport,
644 sgl->word2 = cpu_to_le32(sgl->word2); 673 sgl->word2 = cpu_to_le32(sgl->word2);
645 sgl->sge_len = cpu_to_le32(nCmd->rsplen); 674 sgl->sge_len = cpu_to_le32(nCmd->rsplen);
646 675
647 /*
648 * Get a local pointer to the built-in wqe and correct
649 * the cmd size to match NVME's 96 bytes and fix
650 * the dma address.
651 */
652
653 /* 128 byte wqe support here */
654 wqe = (union lpfc_wqe128 *)&lpfc_ncmd->cur_iocbq.wqe;
655
656 /* Word 0-2 - NVME CMND IU (embedded payload) */
657 wqe->generic.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_IMMED;
658 wqe->generic.bde.tus.f.bdeSize = 56;
659 wqe->generic.bde.addrHigh = 0;
660 wqe->generic.bde.addrLow = 64; /* Word 16 */
661
662 /* Word 3 */ 676 /* Word 3 */
663 bf_set(payload_offset_len, &wqe->fcp_icmd, 677 bf_set(payload_offset_len, &wqe->fcp_icmd,
664 (nCmd->rsplen + nCmd->cmdlen)); 678 (nCmd->rsplen + nCmd->cmdlen));
665 679
666 /* Word 10 */ 680 /* Word 10 */
667 bf_set(wqe_nvme, &wqe->fcp_icmd.wqe_com, 1); 681 bf_set(wqe_nvme, &wqe->fcp_icmd.wqe_com, 1);
682
683 if (!phba->cfg_nvme_embed_cmd) {
684 bf_set(wqe_dbde, &wqe->generic.wqe_com, 1);
685 bf_set(wqe_wqes, &wqe->fcp_icmd.wqe_com, 0);
686 return;
687 }
688 bf_set(wqe_dbde, &wqe->generic.wqe_com, 0);
668 bf_set(wqe_wqes, &wqe->fcp_icmd.wqe_com, 1); 689 bf_set(wqe_wqes, &wqe->fcp_icmd.wqe_com, 1);
669 690
670 /* 691 /*
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 416ba8f8e295..4ce3ca6f4b79 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -6880,6 +6880,18 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
6880 /* Save information as VPD data */ 6880 /* Save information as VPD data */
6881 phba->vpd.rev.biuRev = mqe->un.read_rev.first_hw_rev; 6881 phba->vpd.rev.biuRev = mqe->un.read_rev.first_hw_rev;
6882 phba->vpd.rev.smRev = mqe->un.read_rev.second_hw_rev; 6882 phba->vpd.rev.smRev = mqe->un.read_rev.second_hw_rev;
6883
6884 /*
6885 * This is because first G7 ASIC doesn't support the standard
6886 * 0x5a NVME cmd descriptor type/subtype
6887 */
6888 if ((bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
6889 LPFC_SLI_INTF_IF_TYPE_6) &&
6890 (phba->vpd.rev.biuRev == LPFC_G7_ASIC_1) &&
6891 (phba->vpd.rev.smRev == 0) &&
6892 (phba->cfg_nvme_embed_cmd == 1))
6893 phba->cfg_nvme_embed_cmd = 0;
6894
6883 phba->vpd.rev.endecRev = mqe->un.read_rev.third_hw_rev; 6895 phba->vpd.rev.endecRev = mqe->un.read_rev.third_hw_rev;
6884 phba->vpd.rev.fcphHigh = bf_get(lpfc_mbx_rd_rev_fcph_high, 6896 phba->vpd.rev.fcphHigh = bf_get(lpfc_mbx_rd_rev_fcph_high,
6885 &mqe->un.read_rev); 6897 &mqe->un.read_rev);
@@ -9096,6 +9108,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
9096 wqe128->generic.bde.addrLow = 88; /* Word 22 */ 9108 wqe128->generic.bde.addrLow = 88; /* Word 22 */
9097 9109
9098 bf_set(wqe_wqes, &wqe128->fcp_iwrite.wqe_com, 1); 9110 bf_set(wqe_wqes, &wqe128->fcp_iwrite.wqe_com, 1);
9111 bf_set(wqe_dbde, &wqe128->fcp_iwrite.wqe_com, 0);
9099 9112
9100 /* Word 22-29 FCP CMND Payload */ 9113 /* Word 22-29 FCP CMND Payload */
9101 ptr = &wqe128->words[22]; 9114 ptr = &wqe128->words[22];
@@ -9161,6 +9174,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
9161 wqe128->generic.bde.addrLow = 88; /* Word 22 */ 9174 wqe128->generic.bde.addrLow = 88; /* Word 22 */
9162 9175
9163 bf_set(wqe_wqes, &wqe128->fcp_iread.wqe_com, 1); 9176 bf_set(wqe_wqes, &wqe128->fcp_iread.wqe_com, 1);
9177 bf_set(wqe_dbde, &wqe128->fcp_iread.wqe_com, 0);
9164 9178
9165 /* Word 22-29 FCP CMND Payload */ 9179 /* Word 22-29 FCP CMND Payload */
9166 ptr = &wqe128->words[22]; 9180 ptr = &wqe128->words[22];
@@ -9219,6 +9233,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
9219 wqe128->generic.bde.addrLow = 88; /* Word 22 */ 9233 wqe128->generic.bde.addrLow = 88; /* Word 22 */
9220 9234
9221 bf_set(wqe_wqes, &wqe128->fcp_icmd.wqe_com, 1); 9235 bf_set(wqe_wqes, &wqe128->fcp_icmd.wqe_com, 1);
9236 bf_set(wqe_dbde, &wqe128->fcp_icmd.wqe_com, 0);
9222 9237
9223 /* Word 22-29 FCP CMND Payload */ 9238 /* Word 22-29 FCP CMND Payload */
9224 ptr = &wqe128->words[22]; 9239 ptr = &wqe128->words[22];