diff options
| author | James Smart <jsmart2021@gmail.com> | 2018-02-22 11:18:50 -0500 |
|---|---|---|
| committer | Martin K. Petersen <martin.petersen@oracle.com> | 2018-02-22 20:39:29 -0500 |
| commit | 4e565cf04138fca6ffeb884044febf922b2306d0 (patch) | |
| tree | f3a195ce30d8447824e800ee437b539535c5d6fb | |
| parent | 63452e144662a90b77fcdb27bd33c8b43655b850 (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.h | 1 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 14 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_hw4.h | 1 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 4 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_nvme.c | 51 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 15 |
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 | */ | ||
| 5053 | LPFC_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]; |
