#define LPFC_ENABLE_FCP 1
#define LPFC_ENABLE_NVME 2
#define LPFC_ENABLE_BOTH 3
+ uint32_t nvme_embed_pbde;
+ uint32_t fcp_embed_pbde;
uint32_t io_channel_irqs; /* number of irqs for io channels */
struct nvmet_fc_target_port *targetport;
lpfc_vpd_t vpd; /* vital product data */
#define wqe_irsp_SHIFT 4
#define wqe_irsp_MASK 0x00000001
#define wqe_irsp_WORD word11
+#define wqe_pbde_SHIFT 5
+#define wqe_pbde_MASK 0x00000001
+#define wqe_pbde_WORD word11
#define wqe_sup_SHIFT 6
#define wqe_sup_MASK 0x00000001
#define wqe_sup_WORD word11
phba->cfg_enable_fc4_type = LPFC_ENABLE_FCP;
}
+ /* Only embed PBDE for if_type 6 */
+ if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
+ LPFC_SLI_INTF_IF_TYPE_6) {
+ phba->fcp_embed_pbde = 1;
+ phba->nvme_embed_pbde = 1;
+ }
+
+ /* PBDE support requires xib be set */
+ if (!bf_get(cfg_xib, mbx_sli4_parameters)) {
+ phba->fcp_embed_pbde = 0;
+ phba->nvme_embed_pbde = 0;
+ }
+
/*
* To support Suppress Response feature we must satisfy 3 conditions.
* lpfc_suppress_rsp module parameter must be set (default).
else
phba->fcp_embed_io = 0;
+ lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_NVME,
+ "6422 XIB %d: FCP %d %d NVME %d %d %d\n",
+ bf_get(cfg_xib, mbx_sli4_parameters),
+ phba->fcp_embed_pbde, phba->fcp_embed_io,
+ phba->nvme_support, phba->nvme_embed_pbde,
+ phba->cfg_suppress_rsp);
+
if ((bf_get(cfg_cqpsize, mbx_sli4_parameters) & LPFC_CQ_16K_PAGE_SZ) &&
(bf_get(cfg_wqpsize, mbx_sli4_parameters) & LPFC_WQ_16K_PAGE_SZ) &&
(sli4_params->wqsize & LPFC_WQ_SZ128_SUPPORT))
struct sli4_sge *sgl = lpfc_ncmd->nvme_sgl;
struct scatterlist *data_sg;
struct sli4_sge *first_data_sgl;
+ struct ulp_bde64 *bde;
dma_addr_t physaddr;
uint32_t num_bde = 0;
uint32_t dma_len;
data_sg = sg_next(data_sg);
sgl++;
}
+ if (phba->nvme_embed_pbde) {
+ /* Use PBDE support for first SGL only, offset == 0 */
+ /* Words 13-15 */
+ bde = (struct ulp_bde64 *)
+ &wqe->words[13];
+ bde->addrLow = first_data_sgl->addr_lo;
+ bde->addrHigh = first_data_sgl->addr_hi;
+ bde->tus.f.bdeSize =
+ le32_to_cpu(first_data_sgl->sge_len);
+ bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
+ bde->tus.w = cpu_to_le32(bde->tus.w);
+ bf_set(wqe_pbde, &wqe->generic.wqe_com, 1);
+ } else
+ bf_set(wqe_pbde, &wqe->generic.wqe_com, 0);
+
} else {
+ bf_set(wqe_pbde, &wqe->generic.wqe_com, 0);
+
/* For this clause to be valid, the payload_length
* and sg_cnt must zero.
*/
struct lpfc_iocbq *nvmewqe;
struct scatterlist *sgel;
union lpfc_wqe128 *wqe;
+ struct ulp_bde64 *bde;
uint32_t *txrdy;
dma_addr_t physaddr;
int i, cnt;
+ int do_pbde;
int xc = 1;
if (!lpfc_is_link_up(phba)) {
/* Word 7 */
bf_set(wqe_pu, &wqe->fcp_tsend.wqe_com, 1);
bf_set(wqe_cmnd, &wqe->fcp_tsend.wqe_com, CMD_FCP_TSEND64_WQE);
+ do_pbde = 0;
/* Word 8 */
wqe->fcp_tsend.wqe_com.abort_tag = nvmewqe->iotag;
bf_set(wqe_ar, &wqe->fcp_treceive.wqe_com, 0);
bf_set(wqe_cmnd, &wqe->fcp_treceive.wqe_com,
CMD_FCP_TRECEIVE64_WQE);
+ if (phba->nvme_embed_pbde)
+ do_pbde = 1;
+ else
+ do_pbde = 0;
/* Word 8 */
wqe->fcp_treceive.wqe_com.abort_tag = nvmewqe->iotag;
bf_set(wqe_pu, &wqe->fcp_trsp.wqe_com, 0);
bf_set(wqe_ag, &wqe->fcp_trsp.wqe_com, 1);
bf_set(wqe_cmnd, &wqe->fcp_trsp.wqe_com, CMD_FCP_TRSP64_WQE);
+ do_pbde = 0;
/* Word 8 */
wqe->fcp_trsp.wqe_com.abort_tag = nvmewqe->iotag;
bf_set(lpfc_sli4_sge_last, sgl, 1);
sgl->word2 = cpu_to_le32(sgl->word2);
sgl->sge_len = cpu_to_le32(cnt);
+ if (do_pbde && i == 0) {
+ bde = (struct ulp_bde64 *)&wqe->words[13];
+ memset(bde, 0, sizeof(struct ulp_bde64));
+ /* Words 13-15 (PBDE)*/
+ bde->addrLow = sgl->addr_lo;
+ bde->addrHigh = sgl->addr_hi;
+ bde->tus.f.bdeSize =
+ le32_to_cpu(sgl->sge_len);
+ bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
+ bde->tus.w = cpu_to_le32(bde->tus.w);
+ }
sgl++;
ctxp->offset += cnt;
}
+
+ if (do_pbde)
+ bf_set(wqe_pbde, &wqe->generic.wqe_com, 1);
+ else
+ bf_set(wqe_pbde, &wqe->generic.wqe_com, 0);
ctxp->state = LPFC_NVMET_STE_DATA;
ctxp->entry_cnt++;
return nvmewqe;
dma_offset += dma_len;
sgl++;
}
- /* setup the performance hint (first data BDE) if enabled */
- if (phba->sli3_options & LPFC_SLI4_PERFH_ENABLED) {
+ /*
+ * Setup the first Payload BDE. For FCoE we just key off
+ * Performance Hints, for FC we utilize fcp_embed_pbde.
+ */
+ if ((phba->sli3_options & LPFC_SLI4_PERFH_ENABLED) ||
+ phba->fcp_embed_pbde) {
bde = (struct ulp_bde64 *)
&(iocb_cmd->unsli3.sli3Words[5]);
bde->addrLow = first_data_sgl->addr_lo;
"0378 No support for fcpi mode.\n");
ftr_rsp++;
}
- if (bf_get(lpfc_mbx_rq_ftr_rsp_perfh, &mqe->un.req_ftrs))
- phba->sli3_options |= LPFC_SLI4_PERFH_ENABLED;
- else
- phba->sli3_options &= ~LPFC_SLI4_PERFH_ENABLED;
+
+ /* Performance Hints are ONLY for FCoE */
+ if (phba->hba_flag & HBA_FCOE_MODE) {
+ if (bf_get(lpfc_mbx_rq_ftr_rsp_perfh, &mqe->un.req_ftrs))
+ phba->sli3_options |= LPFC_SLI4_PERFH_ENABLED;
+ else
+ phba->sli3_options &= ~LPFC_SLI4_PERFH_ENABLED;
+ }
+
/*
* If the port cannot support the host's requested features
* then turn off the global config parameters to disable the
}
/* Note, word 10 is already initialized to 0 */
+ /* Don't set PBDE for Perf hints, just fcp_embed_pbde */
+ if (phba->fcp_embed_pbde)
+ bf_set(wqe_pbde, &wqe->fcp_iwrite.wqe_com, 1);
+ else
+ bf_set(wqe_pbde, &wqe->fcp_iwrite.wqe_com, 0);
+
if (phba->fcp_embed_io) {
struct lpfc_scsi_buf *lpfc_cmd;
struct sli4_sge *sgl;
}
/* Note, word 10 is already initialized to 0 */
+ /* Don't set PBDE for Perf hints, just fcp_embed_pbde */
+ if (phba->fcp_embed_pbde)
+ bf_set(wqe_pbde, &wqe->fcp_iread.wqe_com, 1);
+ else
+ bf_set(wqe_pbde, &wqe->fcp_iread.wqe_com, 0);
+
if (phba->fcp_embed_io) {
struct lpfc_scsi_buf *lpfc_cmd;
struct sli4_sge *sgl;