[PATCH 17/19] lpfc: Fix nonrecovery of NVME controller after cable swap.

2018-01-24 Thread James Smart
In a test that is doing large numbers of cable swaps on the target,
the nvme controllers wouldn't reconnect.

During the cable swaps, the targets n_port_id would change. This
information was passed to the nvme-fc transport, in the new remoteport
registration. However, the nvme-fc transport didn't update the n_port_id
value in the remoteport struct when it reused an existing structure.
Later, when a new association was attempted on the remoteport, the
driver's NVME LS routine would use the stale n_port_id from the remoteport
struct to address the LS. As the device is no longer at that address,
the LS would go into never never land.

Separately, the nvme-fc transport will be corrected to update the
n_port_id value on a re-registration.

However, for now, there's no reason to use the transports values.
The private pointer points to the drivers node structure and the
node structure is up to date. Therefore, revise the LS routine to
use the drivers data structures for the LS. Augmented the debug
message for better debugging in the future.

Also removed a duplicate if check that seems to have slipped in.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_nvme.c | 24 +---
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 92643ffa79c3..fc6d85f0bfcf 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -241,10 +241,11 @@ lpfc_nvme_cmpl_gen_req(struct lpfc_hba *phba, struct 
lpfc_iocbq *cmdwqe,
ndlp = (struct lpfc_nodelist *)cmdwqe->context1;
lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
 "6047 nvme cmpl Enter "
-"Data %p DID %x Xri: %x status %x cmd:%p lsreg:%p "
-"bmp:%p ndlp:%p\n",
+"Data %p DID %x Xri: %x status %x reason x%x cmd:%p "
+"lsreg:%p bmp:%p ndlp:%p\n",
 pnvme_lsreq, ndlp ? ndlp->nlp_DID : 0,
 cmdwqe->sli4_xritag, status,
+(wcqe->parameter & 0x),
 cmdwqe, pnvme_lsreq, cmdwqe->context3, ndlp);
 
lpfc_nvmeio_data(phba, "NVME LS  CMPL: xri x%x stat x%x parm x%x\n",
@@ -419,6 +420,7 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport,
 {
int ret = 0;
struct lpfc_nvme_lport *lport;
+   struct lpfc_nvme_rport *rport;
struct lpfc_vport *vport;
struct lpfc_nodelist *ndlp;
struct ulp_bde64 *bpl;
@@ -437,19 +439,18 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport,
 */
 
lport = (struct lpfc_nvme_lport *)pnvme_lport->private;
+   rport = (struct lpfc_nvme_rport *)pnvme_rport->private;
vport = lport->vport;
 
if (vport->load_flag & FC_UNLOADING)
return -ENODEV;
 
-   if (vport->load_flag & FC_UNLOADING)
-   return -ENODEV;
-
-   ndlp = lpfc_findnode_did(vport, pnvme_rport->port_id);
+   /* Need the ndlp.  It is stored in the driver's rport. */
+   ndlp = rport->ndlp;
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE | LOG_NVME_IOERR,
-"6051 DID x%06x not an active rport.\n",
-pnvme_rport->port_id);
+"6051 Remoteport %p, rport has invalid ndlp. "
+"Failing LS Req\n", pnvme_rport);
return -ENODEV;
}
 
@@ -500,8 +501,9 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport,
 
/* Expand print to include key fields. */
lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
-"6149 ENTER.  lport %p, rport %p lsreq%p rqstlen:%d "
-"rsplen:%d %pad %pad\n",
+"6149 Issue LS Req to DID 0x%06x lport %p, rport %p "
+"lsreq%p rqstlen:%d rsplen:%d %pad %pad\n",
+ndlp->nlp_DID,
 pnvme_lport, pnvme_rport,
 pnvme_lsreq, pnvme_lsreq->rqstlen,
 pnvme_lsreq->rsplen, &pnvme_lsreq->rqstdma,
@@ -517,7 +519,7 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport,
ndlp, 2, 30, 0);
if (ret != WQE_SUCCESS) {
atomic_inc(&lport->xmt_ls_err);
-   lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
+   lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_DISC,
 "6052 EXIT. issue ls wqe failed lport %p, "
 "rport %p lsreq%p Status %x DID %x\n",
 pnvme_lport, pnvme_rport, pnvme_lsreq,
-- 
2.13.1



[PATCH v2 12/19] lpfc: Indicate CONF support in NVMe PRLI

2018-01-26 Thread James Smart
Revise the NVME PRLI to indicate CONF support.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_els.c   | 3 ++-
 drivers/scsi/lpfc/lpfc_hw4.h   | 6 +++---
 drivers/scsi/lpfc/lpfc_nportdisc.c | 3 ---
 3 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 234c7c015982..404e1af5e2ab 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -2293,10 +2293,11 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct 
lpfc_nodelist *ndlp,
if (phba->nvmet_support) {
bf_set(prli_tgt, npr_nvme, 1);
bf_set(prli_disc, npr_nvme, 1);
-
} else {
bf_set(prli_init, npr_nvme, 1);
+   bf_set(prli_conf, npr_nvme, 1);
}
+
npr_nvme->word1 = cpu_to_be32(npr_nvme->word1);
npr_nvme->word4 = cpu_to_be32(npr_nvme->word4);
elsiocb->iocb_flag |= LPFC_PRLI_NVME_REQ;
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index ef469129fb71..7c3afc3d3121 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -4346,9 +4346,9 @@ struct lpfc_nvme_prli {
 #define prli_init_SHIFT 5
 #define prli_init_MASK  0x0001
 #define prli_init_WORD  word4
-#define prli_recov_SHIFT8
-#define prli_recov_MASK 0x0001
-#define prli_recov_WORD word4
+#define prli_conf_SHIFT 7
+#define prli_conf_MASK  0x0001
+#define prli_conf_WORD  word4
uint32_t word5;
 #define prli_fb_sz_SHIFT0
 #define prli_fb_sz_MASK 0x
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c 
b/drivers/scsi/lpfc/lpfc_nportdisc.c
index d841aa42f607..bbf1e1342b09 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -2011,9 +2011,6 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, 
struct lpfc_nodelist *ndlp,
}
}
 
-   if (bf_get_be32(prli_recov, nvpr))
-   ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
-
lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
 "6029 NVME PRLI Cmpl w1 x%08x "
 "w4 x%08x w5 x%08x flag x%x, "
-- 
2.13.1



[PATCH v2 05/19] lpfc: Add WQ Full Logic for NVME Target

2018-01-26 Thread James Smart
I/O conditions on the nvme target may have the driver submitting
to a full hardware wq. The hardware wq is a shared resource among
all nvme controllers. When the driver hit a full wq, it failed the
io posting back to the nvme-fc transport, which then escalated it
into errors.

Correct by maintaining a sideband queue within the driver that is
added to when the WQ full condition is hit, and drained from as soon
as new WQ space opens up.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_crtn.h  |   1 +
 drivers/scsi/lpfc/lpfc_nvmet.c | 116 +
 drivers/scsi/lpfc/lpfc_nvmet.h |   1 +
 drivers/scsi/lpfc/lpfc_sli.c   |   3 ++
 drivers/scsi/lpfc/lpfc_sli4.h  |   5 +-
 5 files changed, 125 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 559f9aa0ed08..3ecf50df93f4 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -254,6 +254,7 @@ void lpfc_nvmet_ctxbuf_post(struct lpfc_hba *phba,
struct lpfc_nvmet_ctxbuf *ctxp);
 int lpfc_nvmet_rcv_unsol_abort(struct lpfc_vport *vport,
   struct fc_frame_header *fc_hdr);
+void lpfc_nvmet_wqfull_process(struct lpfc_hba *phba, struct lpfc_queue *wq);
 void lpfc_sli_flush_nvme_rings(struct lpfc_hba *phba);
 void lpfc_nvme_wait_for_io_drain(struct lpfc_hba *phba);
 void lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *, struct fcf_record *,
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
index 7927ac46d345..9c2acf90212c 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.c
+++ b/drivers/scsi/lpfc/lpfc_nvmet.c
@@ -71,6 +71,8 @@ static int lpfc_nvmet_unsol_fcp_issue_abort(struct lpfc_hba *,
 static int lpfc_nvmet_unsol_ls_issue_abort(struct lpfc_hba *,
   struct lpfc_nvmet_rcv_ctx *,
   uint32_t, uint16_t);
+static void lpfc_nvmet_wqfull_flush(struct lpfc_hba *, struct lpfc_queue *,
+   struct lpfc_nvmet_rcv_ctx *);
 
 void
 lpfc_nvmet_defer_release(struct lpfc_hba *phba, struct lpfc_nvmet_rcv_ctx 
*ctxp)
@@ -741,7 +743,10 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport,
struct lpfc_nvmet_rcv_ctx *ctxp =
container_of(rsp, struct lpfc_nvmet_rcv_ctx, ctx.fcp_req);
struct lpfc_hba *phba = ctxp->phba;
+   struct lpfc_queue *wq;
struct lpfc_iocbq *nvmewqeq;
+   struct lpfc_sli_ring *pring;
+   unsigned long iflags;
int rc;
 
if (phba->pport->load_flag & FC_UNLOADING) {
@@ -820,6 +825,21 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport,
return 0;
}
 
+   if (rc == -EBUSY) {
+   /*
+* WQ was full, so queue nvmewqeq to be sent after
+* WQE release CQE
+*/
+   ctxp->flag |= LPFC_NVMET_DEFER_WQFULL;
+   wq = phba->sli4_hba.nvme_wq[rsp->hwqid];
+   pring = wq->pring;
+   spin_lock_irqsave(&pring->ring_lock, iflags);
+   list_add_tail(&nvmewqeq->list, &wq->wqfull_list);
+   wq->q_flag |= HBA_NVMET_WQFULL;
+   spin_unlock_irqrestore(&pring->ring_lock, iflags);
+   return 0;
+   }
+
/* Give back resources */
atomic_inc(&lpfc_nvmep->xmt_fcp_drop);
lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR,
@@ -851,6 +871,7 @@ lpfc_nvmet_xmt_fcp_abort(struct nvmet_fc_target_port 
*tgtport,
struct lpfc_nvmet_rcv_ctx *ctxp =
container_of(req, struct lpfc_nvmet_rcv_ctx, ctx.fcp_req);
struct lpfc_hba *phba = ctxp->phba;
+   struct lpfc_queue *wq;
unsigned long flags;
 
if (phba->pport->load_flag & FC_UNLOADING)
@@ -880,6 +901,14 @@ lpfc_nvmet_xmt_fcp_abort(struct nvmet_fc_target_port 
*tgtport,
}
ctxp->flag |= LPFC_NVMET_ABORT_OP;
 
+   if (ctxp->flag & LPFC_NVMET_DEFER_WQFULL) {
+   lpfc_nvmet_unsol_fcp_issue_abort(phba, ctxp, ctxp->sid,
+ctxp->oxid);
+   wq = phba->sli4_hba.nvme_wq[ctxp->wqeq->hba_wqidx];
+   lpfc_nvmet_wqfull_flush(phba, wq, ctxp);
+   return;
+   }
+
/* An state of LPFC_NVMET_STE_RCV means we have just received
 * the NVME command and have not started processing it.
 * (by issuing any IO WQEs on this exchange yet)
@@ -1435,16 +1464,103 @@ lpfc_nvmet_rcv_unsol_abort(struct lpfc_vport *vport,
return 0;
 }
 
+static void
+lpfc_nvmet_wqfull_flush(struct lpfc_hba *phba, struct lpfc_queue *wq,
+   struct lpfc_nvmet_rcv_ctx *ctxp)
+{
+   struct lpfc_sli_ring *pring;
+   struct lpfc_iocbq *nvmewqeq;
+   struct lpfc_iocbq

[PATCH v2 04/19] lpfc: correct debug counters for abort

2018-01-26 Thread James Smart
Existing code was using the wrong field for the completion status
when comparing whether to increment abort statistics

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_nvmet.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
index 8dbf5c9d51aa..7927ac46d345 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.c
+++ b/drivers/scsi/lpfc/lpfc_nvmet.c
@@ -130,7 +130,7 @@ lpfc_nvmet_xmt_ls_rsp_cmp(struct lpfc_hba *phba, struct 
lpfc_iocbq *cmdwqe,
if (tgtp) {
if (status) {
atomic_inc(&tgtp->xmt_ls_rsp_error);
-   if (status == IOERR_ABORT_REQUESTED)
+   if (result == IOERR_ABORT_REQUESTED)
atomic_inc(&tgtp->xmt_ls_rsp_aborted);
if (bf_get(lpfc_wcqe_c_xb, wcqe))
atomic_inc(&tgtp->xmt_ls_rsp_xb_set);
@@ -541,7 +541,7 @@ lpfc_nvmet_xmt_fcp_op_cmp(struct lpfc_hba *phba, struct 
lpfc_iocbq *cmdwqe,
rsp->transferred_length = 0;
if (tgtp) {
atomic_inc(&tgtp->xmt_fcp_rsp_error);
-   if (status == IOERR_ABORT_REQUESTED)
+   if (result == IOERR_ABORT_REQUESTED)
atomic_inc(&tgtp->xmt_fcp_rsp_aborted);
}
 
-- 
2.13.1



[PATCH v2 02/19] lpfc: Increase CQ and WQ sizes for SCSI

2018-01-26 Thread James Smart
Increased CQ and WQ sizes for SCSI FCP, matching those used
for NVMe development.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc.h  |  1 +
 drivers/scsi/lpfc/lpfc_hw4.h  |  3 +++
 drivers/scsi/lpfc/lpfc_init.c | 30 ++
 drivers/scsi/lpfc/lpfc_sli.c  |  3 ++-
 drivers/scsi/lpfc/lpfc_sli4.h |  5 +
 5 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 61fb46da05d4..d042f9118e3b 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -760,6 +760,7 @@ struct lpfc_hba {
uint8_t  mds_diags_support;
uint32_t initial_imax;
uint8_t  bbcredit_support;
+   uint8_t  enab_exp_wqcq_pages;
 
/* HBA Config Parameters */
uint32_t cfg_ack0;
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 73c2f6971d2b..ef469129fb71 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -3212,6 +3212,9 @@ struct lpfc_sli4_parameters {
 #define cfg_cqv_SHIFT  14
 #define cfg_cqv_MASK   0x0003
 #define cfg_cqv_WORD   word4
+#define cfg_cqpsize_SHIFT  16
+#define cfg_cqpsize_MASK   0x00ff
+#define cfg_cqpsize_WORD   word4
uint32_t word5;
uint32_t word6;
 #define cfg_mqv_SHIFT  14
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index f539c554588c..5b96bf0d3331 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -8011,9 +8011,10 @@ static int
 lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx)
 {
struct lpfc_queue *qdesc;
+   uint32_t wqesize;
 
/* Create Fast Path FCP CQs */
-   if (phba->fcp_embed_io)
+   if (phba->enab_exp_wqcq_pages)
/* Increase the CQ size when WQEs contain an embedded cdb */
qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE,
  phba->sli4_hba.cq_esize,
@@ -8031,15 +8032,18 @@ lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx)
phba->sli4_hba.fcp_cq[wqidx] = qdesc;
 
/* Create Fast Path FCP WQs */
-   if (phba->fcp_embed_io)
/* Increase the WQ size when WQEs contain an embedded cdb */
+   if (phba->enab_exp_wqcq_pages) {
+   wqesize = (phba->fcp_embed_io) ?
+   LPFC_WQE128_SIZE : phba->sli4_hba.wq_esize;
qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE,
- LPFC_WQE128_SIZE,
+ wqesize,
  LPFC_WQE_EXP_COUNT);
-   else
+   } else {
qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
  phba->sli4_hba.wq_esize,
  phba->sli4_hba.wq_ecount);
+   }
if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0503 Failed allocate fast-path FCP WQ (%d)\n",
@@ -10485,6 +10489,12 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, 
LPFC_MBOXQ_t *mboxq)
else
phba->fcp_embed_io = 0;
 
+   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))
+   phba->enab_exp_wqcq_pages = 1;
+   else
+   phba->enab_exp_wqcq_pages = 0;
/*
 * Check if the SLI port supports MDS Diagnostics
 */
@@ -12227,6 +12237,7 @@ int
 lpfc_fof_queue_create(struct lpfc_hba *phba)
 {
struct lpfc_queue *qdesc;
+   uint32_t wqesize;
 
/* Create FOF EQ */
qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
@@ -12240,7 +12251,7 @@ lpfc_fof_queue_create(struct lpfc_hba *phba)
if (phba->cfg_fof) {
 
/* Create OAS CQ */
-   if (phba->fcp_embed_io)
+   if (phba->enab_exp_wqcq_pages)
qdesc = lpfc_sli4_queue_alloc(phba,
  LPFC_EXPANDED_PAGE_SIZE,
  phba->sli4_hba.cq_esize,
@@ -12256,16 +12267,19 @@ lpfc_fof_queue_create(struct lpfc_hba *phba)
phba->sli4_hba.oas_cq = qdesc;
 
/* Create OAS WQ */
-   if (phba->fcp_embed_io)
+   if (phba->enab_exp_wqcq_pages) {
+   wqesize = (phba->fcp_embed_io) ?
+ 

[PATCH v2 03/19] lpfc: move placement of target destroy on driver detach

2018-01-26 Thread James Smart
Ensure nvme localports/targetports are torn down before
dismantling the adapter sli interface on driver detachment.
This aids leaving interfaces live while nvme may be making
callbacks to abort it.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_init.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 5b96bf0d3331..851d4e889042 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -11503,13 +11503,6 @@ lpfc_pci_remove_one_s4(struct pci_dev *pdev)
/* Remove FC host and then SCSI host with the physical port */
fc_remove_host(shost);
scsi_remove_host(shost);
-   /*
-* Bring down the SLI Layer. This step disables all interrupts,
-* clears the rings, discards all mailbox commands, and resets
-* the HBA FCoE function.
-*/
-   lpfc_debugfs_terminate(vport);
-   lpfc_sli4_hba_unset(phba);
 
/* Perform ndlp cleanup on the physical port.  The nvme and nvmet
 * localports are destroyed after to cleanup all transport memory.
@@ -11518,6 +11511,13 @@ lpfc_pci_remove_one_s4(struct pci_dev *pdev)
lpfc_nvmet_destroy_targetport(phba);
lpfc_nvme_destroy_localport(vport);
 
+   /*
+* Bring down the SLI Layer. This step disables all interrupts,
+* clears the rings, discards all mailbox commands, and resets
+* the HBA FCoE function.
+*/
+   lpfc_debugfs_terminate(vport);
+   lpfc_sli4_hba_unset(phba);
 
lpfc_stop_hba_timers(phba);
spin_lock_irq(&phba->hbalock);
-- 
2.13.1



[PATCH v2 01/19] lpfc: Fix frequency of Release WQE CQEs

2018-01-26 Thread James Smart
The driver controls when the hardware sends completions that
communicate consumption of elements from the WQ. This is done by
setting a WQEC bit on a WQE.

The current driver sets it on every Nth WQE posting. However, the
driver isn't clearing the bit if the WQE is reused. Thus, if the
queue depth isn't evenly divisible by N, with enough time, it can
be set on every element, creating a lot of overhead and risking
CQ full conditions.

Correct by clearing the bit when not setting it on an Nth element.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_sli.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 5f5528a12308..149f21f53b13 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -129,6 +129,8 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe)
/* set consumption flag every once in a while */
if (!((q->host_index + 1) % q->entry_repost))
bf_set(wqe_wqec, &wqe->generic.wqe_com, 1);
+   else
+   bf_set(wqe_wqec, &wqe->generic.wqe_com, 0);
if (q->phba->sli3_options & LPFC_SLI4_PHWQ_ENABLED)
bf_set(wqe_wqid, &wqe->generic.wqe_com, q->queue_id);
lpfc_sli_pcimem_bcopy(wqe, temp_wqe, q->entry_size);
-- 
2.13.1



[PATCH v2 08/19] lpfc: Fix RQ empty firmware trap

2018-01-26 Thread James Smart
When nvme target deferred receive logic waits for exchange
resources, the corresponding receive buffer is not replenished
with the hardware. This can result in a lack of asynchronous
receive buffer resources in the hardware, resulting in a
"2885 Port Status Event: ... error 1=0x52004a01 ..." message.

Correct by replenishing the buffer whenenver the deferred
logic kicks in.  Update corresponding debug messages and
statistics as well.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_attr.c  |  6 ++
 drivers/scsi/lpfc/lpfc_mem.c   |  8 ++--
 drivers/scsi/lpfc/lpfc_nvmet.c | 31 +--
 drivers/scsi/lpfc/lpfc_nvmet.h |  7 +--
 drivers/scsi/lpfc/lpfc_sli.c   | 12 
 5 files changed, 50 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index d188fb565a32..91df2b4e9fce 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -259,6 +259,12 @@ lpfc_nvme_info_show(struct device *dev, struct 
device_attribute *attr,
atomic_read(&tgtp->xmt_abort_rsp),
atomic_read(&tgtp->xmt_abort_rsp_error));
 
+   len += snprintf(buf + len, PAGE_SIZE - len,
+   "DELAY: ctx %08x  fod %08x wqfull %08x\n",
+   atomic_read(&tgtp->defer_ctx),
+   atomic_read(&tgtp->defer_fod),
+   atomic_read(&tgtp->defer_wqfull));
+
/* Calculate outstanding IOs */
tot = atomic_read(&tgtp->rcv_fcp_cmd_drop);
tot += atomic_read(&tgtp->xmt_fcp_release);
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
index 56faeb049b4a..60078e61da5e 100644
--- a/drivers/scsi/lpfc/lpfc_mem.c
+++ b/drivers/scsi/lpfc/lpfc_mem.c
@@ -755,10 +755,14 @@ lpfc_rq_buf_free(struct lpfc_hba *phba, struct 
lpfc_dmabuf *mp)
if (rc < 0) {
(rqbp->rqb_free_buffer)(phba, rqb_entry);
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-   "6409 Cannot post to RQ %d: %x %x\n",
+   "6409 Cannot post to HRQ %d: %x %x %x "
+   "DRQ %x %x\n",
rqb_entry->hrq->queue_id,
rqb_entry->hrq->host_index,
-   rqb_entry->hrq->hba_index);
+   rqb_entry->hrq->hba_index,
+   rqb_entry->hrq->entry_count,
+   rqb_entry->drq->host_index,
+   rqb_entry->drq->hba_index);
} else {
list_add_tail(&rqb_entry->hbuf.list, &rqbp->rqb_buffer_list);
rqbp->buffer_count++;
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
index 9c2acf90212c..0539585d32d4 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.c
+++ b/drivers/scsi/lpfc/lpfc_nvmet.c
@@ -270,8 +270,6 @@ lpfc_nvmet_ctxbuf_post(struct lpfc_hba *phba, struct 
lpfc_nvmet_ctxbuf *ctx_buf)
 "NVMET RCV BUSY: xri x%x sz %d "
 "from %06x\n",
 oxid, size, sid);
-   /* defer repost rcv buffer till .defer_rcv callback */
-   ctxp->flag &= ~LPFC_NVMET_DEFER_RCV_REPOST;
atomic_inc(&tgtp->rcv_fcp_cmd_out);
return;
}
@@ -837,6 +835,7 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport,
list_add_tail(&nvmewqeq->list, &wq->wqfull_list);
wq->q_flag |= HBA_NVMET_WQFULL;
spin_unlock_irqrestore(&pring->ring_lock, iflags);
+   atomic_inc(&lpfc_nvmep->defer_wqfull);
return 0;
}
 
@@ -975,11 +974,9 @@ lpfc_nvmet_defer_rcv(struct nvmet_fc_target_port *tgtport,
 
tgtp = phba->targetport->private;
atomic_inc(&tgtp->rcv_fcp_cmd_defer);
-   if (ctxp->flag & LPFC_NVMET_DEFER_RCV_REPOST)
-   lpfc_rq_buf_free(phba, &nvmebuf->hbuf); /* repost */
-   else
-   nvmebuf->hrq->rqbp->rqb_free_buffer(phba, nvmebuf);
-   ctxp->flag &= ~LPFC_NVMET_DEFER_RCV_REPOST;
+
+   /* Free the nvmebuf since a new buffer already replaced it */
+   nvmebuf->hrq->rqbp->rqb_free_buffer(phba, nvmebuf);
 }
 
 static struct nvmet_fc_target_template lpfc_tgttemplate = {
@@ -1309,6 +1306,9 @@ lpfc_nvmet_create_targetport(struct lpfc_hba *phba)
atomic_set(&

[PATCH v2 11/19] lpfc: Fix issue_lip if link is disabled

2018-01-26 Thread James Smart
The driver ignored checks on whether the link should be
kept administratively down after a link bounce. Correct the
checks.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_attr.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index d8064e3ea0ba..b79dad7b8278 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -911,7 +911,12 @@ lpfc_issue_lip(struct Scsi_Host *shost)
LPFC_MBOXQ_t *pmboxq;
int mbxstatus = MBXERR_ERROR;
 
+   /*
+* If the link is offline, disabled or BLOCK_MGMT_IO
+* it doesn't make any sense to allow issue_lip
+*/
if ((vport->fc_flag & FC_OFFLINE_MODE) ||
+   (phba->hba_flag & LINK_DISABLED) ||
(phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO))
return -EPERM;
 
-- 
2.13.1



[PATCH v2 00/19] lpfc updates for 11.4.0.7

2018-01-26 Thread James Smart
This patch set provides a number of fixes for the driver.

The patches were cut against the Martin's 4.16/scsi-queue tree.
There are no outside dependencies and are expected to be pulled
via Martins tree.


v2:
  respin patch 14 "lpfc: Validate adapter support for SRIU option"
for snippet that was missing

James Smart (19):
  lpfc: Fix frequency of Release WQE CQEs
  lpfc: Increase CQ and WQ sizes for SCSI
  lpfc: move placement of target destroy on driver detach
  lpfc: correct debug counters for abort
  lpfc: Add WQ Full Logic for NVME Target
  lpfc: Fix PRLI handling when topology type changes
  lpfc: Fix IO failure during hba reset testing with nvme io.
  lpfc: Fix RQ empty firmware trap
  lpfc: Allow set of maximum outstanding SCSI cmd limit for a target
parameter
  lpfc: Fix soft lockup in lpfc worker thread during LIP testing
  lpfc: Fix issue_lip if link is disabled
  lpfc: Indicate CONF support in NVMe PRLI
  lpfc: Fix SCSI io host reset causing kernel crash
  lpfc: Validate adapter support for SRIU option
  lpfc: Fix header inclusion in lpfc_nvmet
  lpfc: Treat SCSI Write operation Underruns as an error
  lpfc: Fix nonrecovery of NVME controller after cable swap.
  lpfc: update driver version to 11.4.0.7
  lpfc: Update 11.4.0.7 modified files for 2018 Copyright

 drivers/scsi/lpfc/lpfc.h   |   3 +-
 drivers/scsi/lpfc/lpfc_attr.c  |  17 +++-
 drivers/scsi/lpfc/lpfc_crtn.h  |   3 +-
 drivers/scsi/lpfc/lpfc_els.c   |   5 +-
 drivers/scsi/lpfc/lpfc_hbadisc.c   |   7 +-
 drivers/scsi/lpfc/lpfc_hw4.h   |  14 +++-
 drivers/scsi/lpfc/lpfc_init.c  |  63 +++
 drivers/scsi/lpfc/lpfc_mbox.c  |   6 +-
 drivers/scsi/lpfc/lpfc_mem.c   |  10 ++-
 drivers/scsi/lpfc/lpfc_nportdisc.c |   7 +-
 drivers/scsi/lpfc/lpfc_nvme.c  |  29 ---
 drivers/scsi/lpfc/lpfc_nvmet.c | 162 +
 drivers/scsi/lpfc/lpfc_nvmet.h |  10 ++-
 drivers/scsi/lpfc/lpfc_scsi.c  |  49 +++
 drivers/scsi/lpfc/lpfc_sli.c   |  36 -
 drivers/scsi/lpfc/lpfc_sli4.h  |  12 ++-
 drivers/scsi/lpfc/lpfc_version.h   |   4 +-
 17 files changed, 334 insertions(+), 103 deletions(-)

-- 
2.13.1



[PATCH v2 06/19] lpfc: Fix PRLI handling when topology type changes

2018-01-26 Thread James Smart
The lpfc driver does not discover a target when the topology
changes from switched-fabric to direct-connect. The target
rejects the PRLI from the initiator in direct-connect as the
driver is using the old S_ID from the switched topology.

The driver was inappropriately clearing the VP bit to register the
VPI, which is what is associated with the S_ID.

Fix by leaving the VP bit set (it was set earlier) and as the VFI
is being re-registered, set the UPDT bit.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_mbox.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 81fb92967b11..c32d4a323db2 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -2170,10 +2170,8 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport 
*vport, dma_addr_t phys)
/* Only FC supports upd bit */
if ((phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC) &&
(vport->fc_flag & FC_VFI_REGISTERED) &&
-   (!phba->fc_topology_changed)) {
-   bf_set(lpfc_reg_vfi_vp, reg_vfi, 0);
+   (!phba->fc_topology_changed))
bf_set(lpfc_reg_vfi_upd, reg_vfi, 1);
-   }
 
bf_set(lpfc_reg_vfi_bbcr, reg_vfi, 0);
bf_set(lpfc_reg_vfi_bbscn, reg_vfi, 0);
-- 
2.13.1



[PATCH v2 17/19] lpfc: Fix nonrecovery of NVME controller after cable swap.

2018-01-26 Thread James Smart
In a test that is doing large numbers of cable swaps on the target,
the nvme controllers wouldn't reconnect.

During the cable swaps, the targets n_port_id would change. This
information was passed to the nvme-fc transport, in the new remoteport
registration. However, the nvme-fc transport didn't update the n_port_id
value in the remoteport struct when it reused an existing structure.
Later, when a new association was attempted on the remoteport, the
driver's NVME LS routine would use the stale n_port_id from the remoteport
struct to address the LS. As the device is no longer at that address,
the LS would go into never never land.

Separately, the nvme-fc transport will be corrected to update the
n_port_id value on a re-registration.

However, for now, there's no reason to use the transports values.
The private pointer points to the drivers node structure and the
node structure is up to date. Therefore, revise the LS routine to
use the drivers data structures for the LS. Augmented the debug
message for better debugging in the future.

Also removed a duplicate if check that seems to have slipped in.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_nvme.c | 24 +---
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 92643ffa79c3..fc6d85f0bfcf 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -241,10 +241,11 @@ lpfc_nvme_cmpl_gen_req(struct lpfc_hba *phba, struct 
lpfc_iocbq *cmdwqe,
ndlp = (struct lpfc_nodelist *)cmdwqe->context1;
lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
 "6047 nvme cmpl Enter "
-"Data %p DID %x Xri: %x status %x cmd:%p lsreg:%p "
-"bmp:%p ndlp:%p\n",
+"Data %p DID %x Xri: %x status %x reason x%x cmd:%p "
+"lsreg:%p bmp:%p ndlp:%p\n",
 pnvme_lsreq, ndlp ? ndlp->nlp_DID : 0,
 cmdwqe->sli4_xritag, status,
+(wcqe->parameter & 0x),
 cmdwqe, pnvme_lsreq, cmdwqe->context3, ndlp);
 
lpfc_nvmeio_data(phba, "NVME LS  CMPL: xri x%x stat x%x parm x%x\n",
@@ -419,6 +420,7 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport,
 {
int ret = 0;
struct lpfc_nvme_lport *lport;
+   struct lpfc_nvme_rport *rport;
struct lpfc_vport *vport;
struct lpfc_nodelist *ndlp;
struct ulp_bde64 *bpl;
@@ -437,19 +439,18 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport,
 */
 
lport = (struct lpfc_nvme_lport *)pnvme_lport->private;
+   rport = (struct lpfc_nvme_rport *)pnvme_rport->private;
vport = lport->vport;
 
if (vport->load_flag & FC_UNLOADING)
return -ENODEV;
 
-   if (vport->load_flag & FC_UNLOADING)
-   return -ENODEV;
-
-   ndlp = lpfc_findnode_did(vport, pnvme_rport->port_id);
+   /* Need the ndlp.  It is stored in the driver's rport. */
+   ndlp = rport->ndlp;
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE | LOG_NVME_IOERR,
-"6051 DID x%06x not an active rport.\n",
-pnvme_rport->port_id);
+"6051 Remoteport %p, rport has invalid ndlp. "
+"Failing LS Req\n", pnvme_rport);
return -ENODEV;
}
 
@@ -500,8 +501,9 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport,
 
/* Expand print to include key fields. */
lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
-"6149 ENTER.  lport %p, rport %p lsreq%p rqstlen:%d "
-"rsplen:%d %pad %pad\n",
+"6149 Issue LS Req to DID 0x%06x lport %p, rport %p "
+"lsreq%p rqstlen:%d rsplen:%d %pad %pad\n",
+ndlp->nlp_DID,
 pnvme_lport, pnvme_rport,
 pnvme_lsreq, pnvme_lsreq->rqstlen,
 pnvme_lsreq->rsplen, &pnvme_lsreq->rqstdma,
@@ -517,7 +519,7 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport,
ndlp, 2, 30, 0);
if (ret != WQE_SUCCESS) {
atomic_inc(&lport->xmt_ls_err);
-   lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
+   lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_DISC,
 "6052 EXIT. issue ls wqe failed lport %p, "
 "rport %p lsreq%p Status %x DID %x\n",
 pnvme_lport, pnvme_rport, pnvme_lsreq,
-- 
2.13.1



[PATCH v2 07/19] lpfc: Fix IO failure during hba reset testing with nvme io.

2018-01-26 Thread James Smart
A stress test repeatedly resetting the adapter while performing
io would eventually report I/O failures and missing nvme namespaces.

The driver was setting the nvmefc_fcp_req->private pointer to NULL
during the IO completion routine before upcalling done().
If the transport was also running an abort for that IO, the driver
would fail the abort with message 6140. Failing the abort is not
allowed by the nvme-fc transport, as it mandates that the io must be
returned back to the transport. As that does not happen, the transport
controller delete has an outstanding reference and can't complete
teardown.

Remove the NULL'ing of the private pointer in the nvmefc request.
The driver simply overwrites this value on each IO start.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_nvme.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 81e3a4f10c3c..92643ffa79c3 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -804,7 +804,6 @@ lpfc_nvme_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct 
lpfc_iocbq *pwqeIn,
struct nvme_fc_cmd_iu *cp;
struct lpfc_nvme_rport *rport;
struct lpfc_nodelist *ndlp;
-   struct lpfc_nvme_fcpreq_priv *freqpriv;
struct lpfc_nvme_lport *lport;
unsigned long flags;
uint32_t code, status;
@@ -980,8 +979,6 @@ lpfc_nvme_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct 
lpfc_iocbq *pwqeIn,
phba->cpucheck_cmpl_io[lpfc_ncmd->cpu]++;
}
 #endif
-   freqpriv = nCmd->private;
-   freqpriv->nvme_buf = NULL;
 
/* NVME targets need completion held off until the abort exchange
 * completes unless the NVME Rport is getting unregistered.
-- 
2.13.1



[PATCH v2 19/19] lpfc: Update 11.4.0.7 modified files for 2018 Copyright

2018-01-26 Thread James Smart
Updated Copyright in files updated 11.4.0.7

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc.h   | 2 +-
 drivers/scsi/lpfc/lpfc_attr.c  | 2 +-
 drivers/scsi/lpfc/lpfc_crtn.h  | 2 +-
 drivers/scsi/lpfc/lpfc_els.c   | 2 +-
 drivers/scsi/lpfc/lpfc_hbadisc.c   | 2 +-
 drivers/scsi/lpfc/lpfc_hw4.h   | 2 +-
 drivers/scsi/lpfc/lpfc_init.c  | 2 +-
 drivers/scsi/lpfc/lpfc_mbox.c  | 2 +-
 drivers/scsi/lpfc/lpfc_mem.c   | 2 +-
 drivers/scsi/lpfc/lpfc_nportdisc.c | 4 ++--
 drivers/scsi/lpfc/lpfc_nvme.c  | 2 +-
 drivers/scsi/lpfc/lpfc_nvmet.c | 2 +-
 drivers/scsi/lpfc/lpfc_nvmet.h | 2 +-
 drivers/scsi/lpfc/lpfc_scsi.c  | 2 +-
 drivers/scsi/lpfc/lpfc_sli.c   | 3 +--
 drivers/scsi/lpfc/lpfc_sli4.h  | 2 +-
 drivers/scsi/lpfc/lpfc_version.h   | 2 +-
 17 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index d042f9118e3b..9698b9635058 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index b79dad7b8278..70bd25666243 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 3ecf50df93f4..14a86b5b51e4 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 404e1af5e2ab..ba896554a14f 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 9265906d956e..f5bbac3cadbb 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 52fe28ae50fa..8685d26e6929 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -1,7 +1,7 @@
 /***
  * This file is part of the

[PATCH v2 14/19] lpfc: Validate adapter support for SRIU option

2018-01-26 Thread James Smart
When using the special option to suppress the response iu, ensure
the adapter fully supports the feature by checking feature flags
from the adapter and validating the support when formatting the
WQE.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 

---
v2:
  Add missing snippet that changes check logic before enabling
  suppression in lpfc_nvmet_prep_fcp_wqe()

 drivers/scsi/lpfc/lpfc_hw4.h   |  3 +++
 drivers/scsi/lpfc/lpfc_init.c  | 13 -
 drivers/scsi/lpfc/lpfc_nvmet.c |  7 ---
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 7c3afc3d3121..52fe28ae50fa 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -3293,6 +3293,9 @@ struct lpfc_sli4_parameters {
 #define cfg_eqdr_SHIFT 8
 #define cfg_eqdr_MASK  0x0001
 #define cfg_eqdr_WORD  word19
+#define cfg_nosr_SHIFT 9
+#define cfg_nosr_MASK  0x0001
+#define cfg_nosr_WORD  word19
 #define LPFC_NODELAY_MAX_IO32
 };
 
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 7fc2db968379..895b1da784ee 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -10473,8 +10473,19 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, 
LPFC_MBOXQ_t *mboxq)
phba->cfg_enable_fc4_type = LPFC_ENABLE_FCP;
}
 
-   if (bf_get(cfg_xib, mbx_sli4_parameters) && phba->cfg_suppress_rsp)
+   /*
+* To support Suppress Response feature we must satisfy 3 conditions.
+* lpfc_suppress_rsp module parameter must be set (default).
+* In SLI4-Parameters Descriptor:
+* Extended Inline Buffers (XIB) must be supported.
+* Suppress Response IU Not Supported (SRIUNS) must NOT be supported
+* (double negative).
+*/
+   if (phba->cfg_suppress_rsp && bf_get(cfg_xib, mbx_sli4_parameters) &&
+   !(bf_get(cfg_nosr, mbx_sli4_parameters)))
phba->sli.sli_flag |= LPFC_SLI_SUPPRESS_RSP;
+   else
+   phba->cfg_suppress_rsp = 0;
 
if (bf_get(cfg_eqdr, mbx_sli4_parameters))
phba->sli.sli_flag |= LPFC_SLI_USE_EQDR;
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
index 0539585d32d4..6dd8535918f6 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.c
+++ b/drivers/scsi/lpfc/lpfc_nvmet.c
@@ -2290,9 +2290,10 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
if (rsp->op == NVMET_FCOP_READDATA_RSP) {
atomic_inc(&tgtp->xmt_fcp_read_rsp);
bf_set(wqe_ar, &wqe->fcp_tsend.wqe_com, 1);
-   if ((ndlp->nlp_flag & NLP_SUPPRESS_RSP) &&
-   (rsp->rsplen == 12)) {
-   bf_set(wqe_sup, &wqe->fcp_tsend.wqe_com, 1);
+   if (rsp->rsplen == LPFC_NVMET_SUCCESS_LEN) {
+   if (ndlp->nlp_flag & NLP_SUPPRESS_RSP)
+   bf_set(wqe_sup,
+  &wqe->fcp_tsend.wqe_com, 1);
bf_set(wqe_wqes, &wqe->fcp_tsend.wqe_com, 0);
bf_set(wqe_irsp, &wqe->fcp_tsend.wqe_com, 0);
bf_set(wqe_irsplen, &wqe->fcp_tsend.wqe_com, 0);
-- 
2.13.1



[PATCH v2 15/19] lpfc: Fix header inclusion in lpfc_nvmet

2018-01-26 Thread James Smart
The driver was inappropriately pulling in the nvme host's
nvme.h header. What it really needed was the standard
 header.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_nvmet.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
index 6dd8535918f6..823b6df0aec7 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.c
+++ b/drivers/scsi/lpfc/lpfc_nvmet.c
@@ -36,7 +36,7 @@
 #include 
 #include 
 
-#include <../drivers/nvme/host/nvme.h>
+#include 
 #include 
 #include 
 
-- 
2.13.1



[PATCH v2 10/19] lpfc: Fix soft lockup in lpfc worker thread during LIP testing

2018-01-26 Thread James Smart
During link bounce testing in a point-to-point topology, the
host may enter a soft lockup on the lpfc_worker thread:
Call Trace:
 lpfc_work_done+0x1f3/0x1390 [lpfc]
 lpfc_do_work+0x16f/0x180 [lpfc]
 kthread+0xc7/0xe0
 ret_from_fork+0x3f/0x70

The driver was simultaneously setting a combination of flags
that caused lpfc_do_work()to effectively spin between slow path
work and new event data, causing the lockup.

Ensure in the typical wq completions, that new event data flags
are set if the slow path flag is running. The slow path will
eventually reschedule the wq handling.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_hbadisc.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index b159a5c4e388..9265906d956e 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -696,8 +696,9 @@ lpfc_work_done(struct lpfc_hba *phba)
  phba->hba_flag & HBA_SP_QUEUE_EVT)) {
if (pring->flag & LPFC_STOP_IOCB_EVENT) {
pring->flag |= LPFC_DEFERRED_RING_EVENT;
-   /* Set the lpfc data pending flag */
-   set_bit(LPFC_DATA_READY, &phba->data_flags);
+   /* Preserve legacy behavior. */
+   if (!(phba->hba_flag & HBA_SP_QUEUE_EVT))
+   set_bit(LPFC_DATA_READY, &phba->data_flags);
} else {
if (phba->link_state >= LPFC_LINK_UP ||
phba->link_flag & LS_MDS_LOOPBACK) {
-- 
2.13.1



[PATCH v2 16/19] lpfc: Treat SCSI Write operation Underruns as an error

2018-01-26 Thread James Smart
Currently, write underruns (mismatch of amount transferred vs scsi
status and its residual) detected by the adapter are not being
flagged as an error. Its expected the target controls the data
transfer and would appropriately set the RSP values.  Only read
underruns are treated as errors.

Revise the SCSI error handling to treat write underruns as an
error as well.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_scsi.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index dcc86936e6fc..10c2dc0cf1fa 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -3772,20 +3772,18 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct 
lpfc_scsi_buf *lpfc_cmd,
scsi_set_resid(cmnd, be32_to_cpu(fcprsp->rspResId));
 
lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP_UNDER,
-"9025 FCP Read Underrun, expected %d, "
+"9025 FCP Underrun, expected %d, "
 "residual %d Data: x%x x%x x%x\n",
 fcpDl,
 scsi_get_resid(cmnd), fcpi_parm, cmnd->cmnd[0],
 cmnd->underflow);
 
/*
-* If there is an under run check if under run reported by
+* If there is an under run, check if under run reported by
 * storage array is same as the under run reported by HBA.
 * If this is not same, there is a dropped frame.
 */
-   if ((cmnd->sc_data_direction == DMA_FROM_DEVICE) &&
-   fcpi_parm &&
-   (scsi_get_resid(cmnd) != fcpi_parm)) {
+   if (fcpi_parm && (scsi_get_resid(cmnd) != fcpi_parm)) {
lpfc_printf_vlog(vport, KERN_WARNING,
 LOG_FCP | LOG_FCP_ERROR,
 "9026 FCP Read Check Error "
-- 
2.13.1



[PATCH v2 09/19] lpfc: Allow set of maximum outstanding SCSI cmd limit for a target parameter

2018-01-26 Thread James Smart
Make the attribute writeable.
Remove the ramp up to logic as its unnecessary, simply set depth.
Add debug message if depth changed, possibly reducing limit, yet
our outstanding count has yet to catch up with it.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_attr.c |  4 ++--
 drivers/scsi/lpfc/lpfc_scsi.c | 39 ---
 2 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 91df2b4e9fce..d8064e3ea0ba 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -3471,8 +3471,8 @@ LPFC_VPORT_ATTR_R(lun_queue_depth, 30, 1, 512,
 # tgt_queue_depth:  This parameter is used to limit the number of outstanding
 # commands per target port. Value range is [10,65535]. Default value is 65535.
 */
-LPFC_VPORT_ATTR_R(tgt_queue_depth, 65535, 10, 65535,
- "Max number of FCP commands we can queue to a specific target 
port");
+LPFC_VPORT_ATTR_RW(tgt_queue_depth, 65535, 10, 65535,
+  "Max number of FCP commands we can queue to a specific 
target port");
 
 /*
 # hba_queue_depth:  This parameter is used to limit the number of outstanding
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index c0cdaef4db24..dcc86936e6fc 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -3926,7 +3926,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct 
lpfc_iocbq *pIocbIn,
struct lpfc_rport_data *rdata = lpfc_cmd->rdata;
struct lpfc_nodelist *pnode = rdata->pnode;
struct scsi_cmnd *cmd;
-   int depth;
unsigned long flags;
struct lpfc_fast_path_event *fast_path_evt;
struct Scsi_Host *shost;
@@ -4132,16 +4131,11 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct 
lpfc_iocbq *pIocbIn,
}
spin_unlock_irqrestore(shost->host_lock, flags);
} else if (pnode && NLP_CHK_NODE_ACT(pnode)) {
-   if ((pnode->cmd_qdepth < vport->cfg_tgt_queue_depth) &&
-  time_after(jiffies, pnode->last_change_time +
+   if ((pnode->cmd_qdepth != vport->cfg_tgt_queue_depth) &&
+   time_after(jiffies, pnode->last_change_time +
  msecs_to_jiffies(LPFC_TGTQ_INTERVAL))) {
spin_lock_irqsave(shost->host_lock, flags);
-   depth = pnode->cmd_qdepth * LPFC_TGTQ_RAMPUP_PCENT
-   / 100;
-   depth = depth ? depth : 1;
-   pnode->cmd_qdepth += depth;
-   if (pnode->cmd_qdepth > vport->cfg_tgt_queue_depth)
-   pnode->cmd_qdepth = vport->cfg_tgt_queue_depth;
+   pnode->cmd_qdepth = vport->cfg_tgt_queue_depth;
pnode->last_change_time = jiffies;
spin_unlock_irqrestore(shost->host_lock, flags);
}
@@ -4564,9 +4558,32 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct 
scsi_cmnd *cmnd)
 */
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
goto out_tgt_busy;
-   if (atomic_read(&ndlp->cmd_pending) >= ndlp->cmd_qdepth)
+   if (atomic_read(&ndlp->cmd_pending) >= ndlp->cmd_qdepth) {
+   lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP_ERROR,
+"3377 Target Queue Full, scsi Id:%d Qdepth:%d"
+" Pending command:%d"
+" 
WWNN:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, "
+" 
WWPN:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
+ndlp->nlp_sid, ndlp->cmd_qdepth,
+atomic_read(&ndlp->cmd_pending),
+ndlp->nlp_nodename.u.wwn[0],
+ndlp->nlp_nodename.u.wwn[1],
+ndlp->nlp_nodename.u.wwn[2],
+ndlp->nlp_nodename.u.wwn[3],
+ndlp->nlp_nodename.u.wwn[4],
+ndlp->nlp_nodename.u.wwn[5],
+ndlp->nlp_nodename.u.wwn[6],
+ndlp->nlp_nodename.u.wwn[7],
+ndlp->nlp_portname.u.wwn[0],
+ndlp->nlp_portname.u.wwn[1],
+ndlp->nlp_portname.u.wwn[2],
+ndlp->nlp_portname.u.wwn[3],
+ndlp->nlp_portname.u.wwn[4],
+ndlp->nlp_portname.u.wwn[5],
+  

[PATCH v2 18/19] lpfc: update driver version to 11.4.0.7

2018-01-26 Thread James Smart
Update the driver version to 11.4.0.7

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_version.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index c232bf0e8998..6f4092cb903e 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -20,7 +20,7 @@
  * included with this package. *
  ***/
 
-#define LPFC_DRIVER_VERSION "11.4.0.6"
+#define LPFC_DRIVER_VERSION "11.4.0.7"
 #define LPFC_DRIVER_NAME   "lpfc"
 
 /* Used for SLI 2/3 */
-- 
2.13.1



[PATCH v2 13/19] lpfc: Fix SCSI io host reset causing kernel crash

2018-01-26 Thread James Smart
During SCSI error handling escalation to host reset, the SCSI io
routines were moved off the txcmplq, but the individual io's
ON_CMPLQ flag wasn't cleared.  Thus, a background thread saw the
io and attempted to access it as if on the txcmplq.

Clear the flag upon removal.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_init.c |  4 
 drivers/scsi/lpfc/lpfc_sli.c  | 13 -
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 851d4e889042..7fc2db968379 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -958,6 +958,7 @@ lpfc_hba_clean_txcmplq(struct lpfc_hba *phba)
struct lpfc_sli_ring *pring;
LIST_HEAD(completions);
int i;
+   struct lpfc_iocbq *piocb, *next_iocb;
 
if (phba->sli_rev != LPFC_SLI_REV4) {
for (i = 0; i < psli->num_rings; i++) {
@@ -983,6 +984,9 @@ lpfc_hba_clean_txcmplq(struct lpfc_hba *phba)
if (!pring)
continue;
spin_lock_irq(&pring->ring_lock);
+   list_for_each_entry_safe(piocb, next_iocb,
+&pring->txcmplq, list)
+   piocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
list_splice_init(&pring->txcmplq, &completions);
pring->txcmplq_cnt = 0;
spin_unlock_irq(&pring->ring_lock);
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 8b2919a553d6..d597e15a1974 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -3778,6 +3778,7 @@ lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba)
struct lpfc_sli *psli = &phba->sli;
struct lpfc_sli_ring  *pring;
uint32_t i;
+   struct lpfc_iocbq *piocb, *next_iocb;
 
spin_lock_irq(&phba->hbalock);
/* Indicate the I/O queues are flushed */
@@ -3792,6 +3793,9 @@ lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba)
spin_lock_irq(&pring->ring_lock);
/* Retrieve everything on txq */
list_splice_init(&pring->txq, &txq);
+   list_for_each_entry_safe(piocb, next_iocb,
+&pring->txcmplq, list)
+   piocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
/* Retrieve everything on the txcmplq */
list_splice_init(&pring->txcmplq, &txcmplq);
pring->txq_cnt = 0;
@@ -3813,6 +3817,9 @@ lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba)
spin_lock_irq(&phba->hbalock);
/* Retrieve everything on txq */
list_splice_init(&pring->txq, &txq);
+   list_for_each_entry_safe(piocb, next_iocb,
+&pring->txcmplq, list)
+   piocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
/* Retrieve everything on the txcmplq */
list_splice_init(&pring->txcmplq, &txcmplq);
pring->txq_cnt = 0;
@@ -3844,6 +3851,7 @@ lpfc_sli_flush_nvme_rings(struct lpfc_hba *phba)
LIST_HEAD(txcmplq);
struct lpfc_sli_ring  *pring;
uint32_t i;
+   struct lpfc_iocbq *piocb, *next_iocb;
 
if (phba->sli_rev < LPFC_SLI_REV4)
return;
@@ -3860,8 +3868,11 @@ lpfc_sli_flush_nvme_rings(struct lpfc_hba *phba)
for (i = 0; i < phba->cfg_nvme_io_channel; i++) {
pring = phba->sli4_hba.nvme_wq[i]->pring;
 
-   /* Retrieve everything on the txcmplq */
spin_lock_irq(&pring->ring_lock);
+   list_for_each_entry_safe(piocb, next_iocb,
+&pring->txcmplq, list)
+   piocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
+   /* Retrieve everything on the txcmplq */
list_splice_init(&pring->txcmplq, &txcmplq);
pring->txcmplq_cnt = 0;
spin_unlock_irq(&pring->ring_lock);
-- 
2.13.1



[PATCH 02/13] lpfc: Rework sli4 doorbell infrastructure

2018-01-26 Thread James Smart
Up until now, all SLI-4 devices had the same doorbells at the same
bar locations. With newer hardware, there are now independent EQ and
CQ doorbells and the bar locations differ.

Prepare the code for new hardwre by separating the eq/cq doorbell into
separate components. The components can be set based on if_type.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_debugfs.c | 20 ++--
 drivers/scsi/lpfc/lpfc_debugfs.h | 11 ++-
 drivers/scsi/lpfc/lpfc_init.c|  9 ++---
 drivers/scsi/lpfc/lpfc_sli.c |  8 
 drivers/scsi/lpfc/lpfc_sli4.h|  3 ++-
 5 files changed, 32 insertions(+), 19 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 17ea3bb04266..308303d501cf 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -3944,10 +3944,15 @@ lpfc_idiag_drbacc_read_reg(struct lpfc_hba *phba, char 
*pbuffer,
return 0;
 
switch (drbregid) {
-   case LPFC_DRB_EQCQ:
-   len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
-   "EQCQ-DRB-REG: 0x%08x\n",
-   readl(phba->sli4_hba.EQCQDBregaddr));
+   case LPFC_DRB_EQ:
+   len += snprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE-len,
+   "EQ-DRB-REG: 0x%08x\n",
+   readl(phba->sli4_hba.EQDBregaddr));
+   break;
+   case LPFC_DRB_CQ:
+   len += snprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE - len,
+   "CQ-DRB-REG: 0x%08x\n",
+   readl(phba->sli4_hba.CQDBregaddr));
break;
case LPFC_DRB_MQ:
len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
@@ -4086,8 +4091,11 @@ lpfc_idiag_drbacc_write(struct file *file, const char 
__user *buf,
idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
switch (drb_reg_id) {
-   case LPFC_DRB_EQCQ:
-   drb_reg = phba->sli4_hba.EQCQDBregaddr;
+   case LPFC_DRB_EQ:
+   drb_reg = phba->sli4_hba.EQDBregaddr;
+   break;
+   case LPFC_DRB_CQ:
+   drb_reg = phba->sli4_hba.CQDBregaddr;
break;
case LPFC_DRB_MQ:
drb_reg = phba->sli4_hba.MQDBregaddr;
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
index c4edd87bfc65..12fbf498a7ce 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.h
+++ b/drivers/scsi/lpfc/lpfc_debugfs.h
@@ -126,12 +126,13 @@
 #define LPFC_DRB_ACC_WR_CMD_ARG 2
 #define LPFC_DRB_ACC_BUF_SIZE 256
 
-#define LPFC_DRB_EQCQ 1
-#define LPFC_DRB_MQ   2
-#define LPFC_DRB_WQ   3
-#define LPFC_DRB_RQ   4
+#define LPFC_DRB_EQ   1
+#define LPFC_DRB_CQ   2
+#define LPFC_DRB_MQ   3
+#define LPFC_DRB_WQ   4
+#define LPFC_DRB_RQ   5
 
-#define LPFC_DRB_MAX  4
+#define LPFC_DRB_MAX  5
 
 #define IDIAG_DRBACC_REGID_INDX 0
 #define IDIAG_DRBACC_VALUE_INDX 1
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index fc26c4b58d6b..9a6ece7f7748 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -7430,8 +7430,9 @@ lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba, 
uint32_t if_type)
phba->sli4_hba.WQDBregaddr =
phba->sli4_hba.conf_regs_memmap_p +
LPFC_ULP0_WQ_DOORBELL;
-   phba->sli4_hba.EQCQDBregaddr =
+   phba->sli4_hba.CQDBregaddr =
phba->sli4_hba.conf_regs_memmap_p + LPFC_EQCQ_DOORBELL;
+   phba->sli4_hba.EQDBregaddr = phba->sli4_hba.CQDBregaddr;
phba->sli4_hba.MQDBregaddr =
phba->sli4_hba.conf_regs_memmap_p + LPFC_MQ_DOORBELL;
phba->sli4_hba.BMBXregaddr =
@@ -7488,8 +7489,10 @@ lpfc_sli4_bar2_register_memmap(struct lpfc_hba *phba, 
uint32_t vf)
phba->sli4_hba.WQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
vf * LPFC_VFR_PAGE_SIZE +
LPFC_ULP0_WQ_DOORBELL);
-   phba->sli4_hba.EQCQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
-   vf * LPFC_VFR_PAGE_SIZE + LPFC_EQCQ_DOORBELL);
+   phba->sli4_hba.CQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
+   vf * LPFC_VFR_PAGE_SIZE +
+   LPFC_EQCQ_DOORBELL);
+   phba->sli4_hba.EQDBregaddr = phba->sli4_hba.CQDBregaddr;
phba->sli4_hba.MQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
vf * LPFC_VFR_PAGE_S

[PATCH 04/13] lpfc: Add push-to-adapter support to sli4

2018-01-26 Thread James Smart
New if_type=6 adapters support and additional BAR that provides
apertures to allow direct WQE to adapter push support - termed
Direct Packet Push (DPP). WQ creation differs slightly to ask for
a WQ to be DPP-ized. When submitting a WQE to a DPP WQ, it is
submitted to the host memory for the WQ normally, but is also
written by the host cpu directly to a BAR aperture.  Write buffer
coalescing in hardware is (hopefully) turned on, enabling single
pci write operation support. The doorbell is thing rung to indicate
the WQE is available and was pushed to the aperture.

This patch:
- Updates the WQ Create commands for the DPP options
- Adds the bar mapping for if_type=6 DPP bar
- Adds the WQE pushing to the DDP aperture received from WQ create
- Adds a new module parameter to disable DPP operation if desired.
  Default is enabled.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc.h  |   3 +-
 drivers/scsi/lpfc/lpfc_attr.c |  10 ++
 drivers/scsi/lpfc/lpfc_hw4.h  |  31 ++
 drivers/scsi/lpfc/lpfc_init.c |  18 
 drivers/scsi/lpfc/lpfc_sli.c  | 234 +++---
 drivers/scsi/lpfc/lpfc_sli4.h |  16 ++-
 6 files changed, 225 insertions(+), 87 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 9698b9635058..86ffb9756e65 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -840,7 +840,8 @@ struct lpfc_hba {
uint32_t cfg_enable_SmartSAN;
uint32_t cfg_enable_mds_diags;
uint32_t cfg_enable_fc4_type;
-   uint32_t cfg_enable_bbcr;   /*Enable BB Credit Recovery*/
+   uint32_t cfg_enable_bbcr;   /* Enable BB Credit Recovery */
+   uint32_t cfg_enable_dpp;/* Enable Direct Packet Push */
uint32_t cfg_xri_split;
 #define LPFC_ENABLE_FCP  1
 #define LPFC_ENABLE_NVME 2
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 70bd25666243..705c42e724c2 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -5204,6 +5204,14 @@ LPFC_ATTR_R(enable_mds_diags, 0, 0, 1, "Enable MDS 
Diagnostics");
  */
 LPFC_BBCR_ATTR_RW(enable_bbcr, 1, 0, 1, "Enable BBC Recovery");
 
+/*
+ * lpfc_enable_dpp: Enable DPP on G7
+ *   0  = DPP on G7 disabled
+ *   1  = DPP on G7 enabled (default)
+ * Value range is [0,1]. Default value is 1.
+ */
+LPFC_ATTR_RW(enable_dpp, 1, 0, 1, "Enable Direct Packet Push");
+
 struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_nvme_info,
&dev_attr_bg_info,
@@ -5312,6 +5320,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_lpfc_xlane_supported,
&dev_attr_lpfc_enable_mds_diags,
&dev_attr_lpfc_enable_bbcr,
+   &dev_attr_lpfc_enable_dpp,
NULL,
 };
 
@@ -6324,6 +6333,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
lpfc_fcp_io_channel_init(phba, lpfc_fcp_io_channel);
lpfc_nvme_io_channel_init(phba, lpfc_nvme_io_channel);
lpfc_enable_bbcr_init(phba, lpfc_enable_bbcr);
+   lpfc_enable_dpp_init(phba, lpfc_enable_dpp);
 
if (phba->sli_rev != LPFC_SLI_REV4) {
/* NVME only supported on SLI4 */
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 93fd9fd10a0f..60ccff6fa8b0 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -1372,6 +1372,15 @@ struct lpfc_mbx_wq_create {
 #define lpfc_mbx_wq_create_page_size_MASK  0x00FF
 #define lpfc_mbx_wq_create_page_size_WORD  word1
 #define LPFC_WQ_PAGE_SIZE_4096 0x1
+#define lpfc_mbx_wq_create_dpp_req_SHIFT   15
+#define lpfc_mbx_wq_create_dpp_req_MASK0x0001
+#define lpfc_mbx_wq_create_dpp_req_WORDword1
+#define lpfc_mbx_wq_create_doe_SHIFT   14
+#define lpfc_mbx_wq_create_doe_MASK0x0001
+#define lpfc_mbx_wq_create_doe_WORDword1
+#define lpfc_mbx_wq_create_toe_SHIFT   13
+#define lpfc_mbx_wq_create_toe_MASK0x0001
+#define lpfc_mbx_wq_create_toe_WORDword1
 #define lpfc_mbx_wq_create_wqe_size_SHIFT  8
 #define lpfc_mbx_wq_create_wqe_size_MASK   0x000F
 #define lpfc_mbx_wq_create_wqe_size_WORD   word1
@@ -1400,6 +1409,28 @@ struct lpfc_mbx_wq_create {
 #define lpfc_mbx_wq_create_db_format_MASK  0x
 #define lpfc_mbx_wq_create_db_format_WORD  word2
} response;
+   struct {
+   uint32_t word0;
+#define lpfc_mbx_wq_create_dpp_rsp_SHIFT   31
+#define lpfc_mbx_wq_create_dpp_rsp_MASK0x0001
+#define lpfc_mbx_wq_create_dpp_rsp_WORDword0
+#define lpfc_mbx_wq_create_v1_q_id_SHIFT   0
+#define lpfc_mbx_wq_create_v1_q_id_MASK0x
+#define lpfc_mbx_wq_create_v1_q_id_WORDword0
+   uint32_t word1;
+#define lpfc_mbx_wq_create_v1_bar_s

[PATCH 05/13] lpfc: Add PCI Ids for if_type=6 hardware

2018-01-26 Thread James Smart
Add PCI ids for the new G7 adapter

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_hw.h  | 1 +
 drivers/scsi/lpfc/lpfc_ids.h | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index bdc1f184f67a..d07d2fcbea34 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -1580,6 +1580,7 @@ struct lpfc_fdmi_reg_portattr {
 #define PCI_DEVICE_ID_LANCER_FCOE   0xe260
 #define PCI_DEVICE_ID_LANCER_FCOE_VF 0xe268
 #define PCI_DEVICE_ID_LANCER_G6_FC  0xe300
+#define PCI_DEVICE_ID_LANCER_G7_FC  0xf400
 #define PCI_DEVICE_ID_SAT_SMB   0xf011
 #define PCI_DEVICE_ID_SAT_MID   0xf015
 #define PCI_DEVICE_ID_RFLY  0xf095
diff --git a/drivers/scsi/lpfc/lpfc_ids.h b/drivers/scsi/lpfc/lpfc_ids.h
index 0ba3733eb36d..329c8d28869c 100644
--- a/drivers/scsi/lpfc/lpfc_ids.h
+++ b/drivers/scsi/lpfc/lpfc_ids.h
@@ -116,6 +116,8 @@ const struct pci_device_id lpfc_id_table[] = {
PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_G6_FC,
PCI_ANY_ID, PCI_ANY_ID, },
+   {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_G7_FC,
+   PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK,
PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK_VF,
-- 
2.13.1



[PATCH 03/13] lpfc: Add SLI-4 if_type=6 support to the code base

2018-01-26 Thread James Smart
New hardware supports a SLI-4 interface, but with a new if_type
variant of 6.

If_type=6 has a different PCI BAR map, separate EQ/CQ doorbells,
and some changes in doorbell formats.

Add the changes for the if_type into headers, adapter initialization
and control flows. Add new eq and cq handlers.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_bsg.c  |   4 +-
 drivers/scsi/lpfc/lpfc_hw4.h  |  54 ++-
 drivers/scsi/lpfc/lpfc_init.c | 120 +++---
 drivers/scsi/lpfc/lpfc_sli.c  | 120 --
 drivers/scsi/lpfc/lpfc_sli4.h |   3 ++
 5 files changed, 275 insertions(+), 26 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index d89816222b23..8b33b652226b 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -3867,7 +3867,7 @@ lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, 
struct bsg_job *job,
"ext_buf_cnt:%d\n", ext_buf_cnt);
} else {
/* sanity check on interface type for support */
-   if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+   if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
LPFC_SLI_INTF_IF_TYPE_2) {
rc = -ENODEV;
goto job_error;
@@ -4053,7 +4053,7 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, 
struct bsg_job *job,
"ext_buf_cnt:%d\n", ext_buf_cnt);
} else {
/* sanity check on interface type for support */
-   if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+   if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
LPFC_SLI_INTF_IF_TYPE_2)
return -ENODEV;
/* nemb_tp == nemb_hbd */
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 8685d26e6929..93fd9fd10a0f 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -84,6 +84,7 @@ struct lpfc_sli_intf {
 #define LPFC_SLI_INTF_IF_TYPE_00
 #define LPFC_SLI_INTF_IF_TYPE_11
 #define LPFC_SLI_INTF_IF_TYPE_22
+#define LPFC_SLI_INTF_IF_TYPE_66
 #define lpfc_sli_intf_sli_family_SHIFT 8
 #define lpfc_sli_intf_sli_family_MASK  0x000F
 #define lpfc_sli_intf_sli_family_WORD  word0
@@ -731,11 +732,13 @@ struct lpfc_register {
  * register sets depending on the UCNA Port's reported if_type
  * value.  For UCNA ports running SLI4 and if_type 0, they reside in
  * BAR4.  For UCNA ports running SLI4 and if_type 2, they reside in
- * BAR0.  The offsets are the same so the driver must account for
- * any base address difference.
+ * BAR0.  For FC ports running SLI4 and if_type 6, they reside in
+ * BAR2. The offsets and base address are different,  so the driver
+ * has to compute the register addresses accordingly
  */
 #define LPFC_ULP0_RQ_DOORBELL  0x00A0
 #define LPFC_ULP1_RQ_DOORBELL  0x00C0
+#define LPFC_IF6_RQ_DOORBELL   0x0080
 #define lpfc_rq_db_list_fm_num_posted_SHIFT24
 #define lpfc_rq_db_list_fm_num_posted_MASK 0x00FF
 #define lpfc_rq_db_list_fm_num_posted_WORD word0
@@ -770,6 +773,20 @@ struct lpfc_register {
 #define lpfc_wq_db_ring_fm_id_MASK  0x
 #define lpfc_wq_db_ring_fm_id_WORD  word0
 
+#define LPFC_IF6_WQ_DOORBELL   0x0040
+#define lpfc_if6_wq_db_list_fm_num_posted_SHIFT24
+#define lpfc_if6_wq_db_list_fm_num_posted_MASK 0x00FF
+#define lpfc_if6_wq_db_list_fm_num_posted_WORD word0
+#define lpfc_if6_wq_db_list_fm_dpp_SHIFT   23
+#define lpfc_if6_wq_db_list_fm_dpp_MASK0x0001
+#define lpfc_if6_wq_db_list_fm_dpp_WORDword0
+#define lpfc_if6_wq_db_list_fm_dpp_id_SHIFT16
+#define lpfc_if6_wq_db_list_fm_dpp_id_MASK 0x001F
+#define lpfc_if6_wq_db_list_fm_dpp_id_WORD word0
+#define lpfc_if6_wq_db_list_fm_id_SHIFT0
+#define lpfc_if6_wq_db_list_fm_id_MASK 0x
+#define lpfc_if6_wq_db_list_fm_id_WORD word0
+
 #define LPFC_EQCQ_DOORBELL 0x0120
 #define lpfc_eqcq_doorbell_se_SHIFT31
 #define lpfc_eqcq_doorbell_se_MASK 0x0001
@@ -805,6 +822,38 @@ struct lpfc_register {
 #define LPFC_CQID_HI_FIELD_SHIFT   10
 #define LPFC_EQID_HI_FIELD_SHIFT   9
 
+#define LPFC_IF6_CQ_DOORBELL   0x00C0
+#define lpfc_if6_cq_doorbell_se_SHIFT  31
+#define lpfc_if6_cq_doorbell_se_MASK   0x0001
+#define lpfc_if6_cq_doorbell_se_WORD   word0
+#define LPFC_IF6_CQ_SOLICIT_ENABLE_OFF 0
+#define LPFC_IF6_CQ_SOLICIT_ENABLE_ON  1
+#define lpfc_if6_cq_doorbell_arm_SHIFT 29
+#de

[PATCH 00/13] lpfc new hardware patches for 12.0.0.0

2018-01-26 Thread James Smart
This patch set adds support for Broadcom's new G7 product that
supports G4G FC.

The patches were cut against the Martin's 4.16/scsi-queue tree.

The patches are dependent (layered on top of) the lpfc 11.4.0.7
patchset that was recently posted. See:
  https://www.spinics.net/lists/linux-scsi/msg116956.html


James Smart (13):
  lpfc: Rework lpfc to allow different sli4 cq and eq handlers
  lpfc: Rework sli4 doorbell infrastructure
  lpfc: Add SLI-4 if_type=6 support to the code base
  lpfc: Add push-to-adapter support to sli4
  lpfc: Add PCI Ids for if_type=6 hardware
  lpfc: Add 64G link speed support
  lpfc: Add if_type=6 support for cycling valid bits
  lpfc: Enable fw download on if_type=6 devices
  lpfc: Add embedded data pointers for enhanced performance
  lpfc: Fix nvme embedded io length on new hardware
  lpfc: Work around NVME cmd iu SGL type
  lpfc: update driver version to 12.0.0.0
  lpfc: Update 12.0.0.0 modified files for 2018 Copyright

 drivers/scsi/lpfc/lpfc.h |  20 +-
 drivers/scsi/lpfc/lpfc_attr.c|  85 +--
 drivers/scsi/lpfc/lpfc_bsg.c |   6 +-
 drivers/scsi/lpfc/lpfc_ct.c  |   7 +-
 drivers/scsi/lpfc/lpfc_debugfs.c |  22 +-
 drivers/scsi/lpfc/lpfc_debugfs.h |  13 +-
 drivers/scsi/lpfc/lpfc_els.c |   5 +
 drivers/scsi/lpfc/lpfc_hbadisc.c |   1 +
 drivers/scsi/lpfc/lpfc_hw.h  |  15 +-
 drivers/scsi/lpfc/lpfc_hw4.h | 115 -
 drivers/scsi/lpfc/lpfc_ids.h |   4 +-
 drivers/scsi/lpfc/lpfc_init.c| 245 +++---
 drivers/scsi/lpfc/lpfc_mbox.c|   4 +
 drivers/scsi/lpfc/lpfc_nvme.c|  69 +++--
 drivers/scsi/lpfc/lpfc_nvmet.c   |  24 ++
 drivers/scsi/lpfc/lpfc_scsi.c|   8 +-
 drivers/scsi/lpfc/lpfc_sli.c | 535 +--
 drivers/scsi/lpfc/lpfc_sli4.h|  30 ++-
 drivers/scsi/lpfc/lpfc_version.h |   2 +-
 19 files changed, 960 insertions(+), 250 deletions(-)

-- 
2.13.1



[PATCH 07/13] lpfc: Add if_type=6 support for cycling valid bits

2018-01-26 Thread James Smart
Traditional SLI4 required the driver to clear Valid bits on
EQEs and CQEs after consuming them.

The new if_type=6 hardware will cycle the value for what is
valid on each queue itteration. The driver no longer has to
touch the valid bits. This also means all the cpu cache
dirtying and perhaps flush/refill's done by the hardware
in accessng the EQ/CQ elements is eliminated.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_hw4.h  | 18 --
 drivers/scsi/lpfc/lpfc_init.c | 11 +++
 drivers/scsi/lpfc/lpfc_sli.c  | 77 +++
 drivers/scsi/lpfc/lpfc_sli4.h |  3 ++
 4 files changed, 92 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 0c33510fe75c..dba724e1f5ee 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -1040,6 +1040,9 @@ struct eq_context {
 #define lpfc_eq_context_valid_SHIFT29
 #define lpfc_eq_context_valid_MASK 0x0001
 #define lpfc_eq_context_valid_WORD word0
+#define lpfc_eq_context_autovalid_SHIFT 28
+#define lpfc_eq_context_autovalid_MASK  0x0001
+#define lpfc_eq_context_autovalid_WORD  word0
uint32_t word1;
 #define lpfc_eq_context_count_SHIFT26
 #define lpfc_eq_context_count_MASK 0x0003
@@ -1173,6 +1176,9 @@ struct cq_context {
 #define LPFC_CQ_CNT_5120x1
 #define LPFC_CQ_CNT_1024   0x2
 #define LPFC_CQ_CNT_WORD7  0x3
+#define lpfc_cq_context_autovalid_SHIFT 15
+#define lpfc_cq_context_autovalid_MASK  0x0001
+#define lpfc_cq_context_autovalid_WORD  word0
uint32_t word1;
 #define lpfc_cq_eq_id_SHIFT22  /* Version 0 Only */
 #define lpfc_cq_eq_id_MASK 0x00FF
@@ -1231,9 +1237,9 @@ struct lpfc_mbx_cq_create_set {
 #define lpfc_mbx_cq_create_set_cqe_size_SHIFT  25
 #define lpfc_mbx_cq_create_set_cqe_size_MASK   0x0003
 #define lpfc_mbx_cq_create_set_cqe_size_WORD   word1
-#define lpfc_mbx_cq_create_set_auto_SHIFT  15
-#define lpfc_mbx_cq_create_set_auto_MASK   0x001
-#define lpfc_mbx_cq_create_set_auto_WORD   word1
+#define lpfc_mbx_cq_create_set_autovalid_SHIFT 15
+#define lpfc_mbx_cq_create_set_autovalid_MASK  0x001
+#define lpfc_mbx_cq_create_set_autovalid_WORD  word1
 #define lpfc_mbx_cq_create_set_nodelay_SHIFT   14
 #define lpfc_mbx_cq_create_set_nodelay_MASK0x0001
 #define lpfc_mbx_cq_create_set_nodelay_WORDword1
@@ -3288,6 +3294,9 @@ struct lpfc_sli4_parameters {
 #define cfg_sli_hint_2_MASK0x001f
 #define cfg_sli_hint_2_WORDword1
uint32_t word2;
+#define cfg_eqav_SHIFT 31
+#define cfg_eqav_MASK  0x0001
+#define cfg_eqav_WORD  word2
uint32_t word3;
uint32_t word4;
 #define cfg_cqv_SHIFT  14
@@ -3296,6 +3305,9 @@ struct lpfc_sli4_parameters {
 #define cfg_cqpsize_SHIFT  16
 #define cfg_cqpsize_MASK   0x00ff
 #define cfg_cqpsize_WORD   word4
+#define cfg_cqav_SHIFT 31
+#define cfg_cqav_MASK  0x0001
+#define cfg_cqav_WORD  word4
uint32_t word5;
uint32_t word6;
 #define cfg_mqv_SHIFT  14
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index c38d57353edf..ad51bfcd929b 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -8060,6 +8060,7 @@ lpfc_alloc_nvme_wq_cq(struct lpfc_hba *phba, int wqidx)
wqidx);
return 1;
}
+   qdesc->qe_valid = 1;
phba->sli4_hba.nvme_cq[wqidx] = qdesc;
 
qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE,
@@ -8097,6 +8098,7 @@ lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx)
"0499 Failed allocate fast-path FCP CQ (%d)\n", wqidx);
return 1;
}
+   qdesc->qe_valid = 1;
phba->sli4_hba.fcp_cq[wqidx] = qdesc;
 
/* Create Fast Path FCP WQs */
@@ -8290,6 +8292,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
"0497 Failed allocate EQ (%d)\n", idx);
goto out_error;
}
+   qdesc->qe_valid = 1;
phba->sli4_hba.hba_eq[idx] = qdesc;
}
 
@@ -8315,6 +8318,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
"CQ Set (%d)\n", idx);
goto out_error;
}
+   qdesc->qe_valid = 1;
phba->sli4_hba.nvmet_cqset[idx] = qdesc;
}
}
@@ -8332,6 +8336,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)

[PATCH 06/13] lpfc: Add 64G link speed support

2018-01-26 Thread James Smart
The G7 adapter supports 64G link speeds. Add support to the driver.

In addition, a small cleanup to replace the odd bitmap logic with
a switch case.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc.h | 14 +++--
 drivers/scsi/lpfc/lpfc_attr.c| 61 
 drivers/scsi/lpfc/lpfc_ct.c  |  5 
 drivers/scsi/lpfc/lpfc_els.c |  5 
 drivers/scsi/lpfc/lpfc_hbadisc.c |  1 +
 drivers/scsi/lpfc/lpfc_hw.h  | 12 
 drivers/scsi/lpfc/lpfc_hw4.h |  3 ++
 drivers/scsi/lpfc/lpfc_init.c| 17 +--
 drivers/scsi/lpfc/lpfc_mbox.c|  4 +++
 9 files changed, 92 insertions(+), 30 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 86ffb9756e65..7aad4a717f13 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -544,16 +544,10 @@ struct unsol_rcv_ct_ctx {
 #define LPFC_USER_LINK_SPEED_10G   10  /* 10 Gigabaud */
 #define LPFC_USER_LINK_SPEED_16G   16  /* 16 Gigabaud */
 #define LPFC_USER_LINK_SPEED_32G   32  /* 32 Gigabaud */
-#define LPFC_USER_LINK_SPEED_MAX   LPFC_USER_LINK_SPEED_32G
-#define LPFC_USER_LINK_SPEED_BITMAP  ((1ULL << LPFC_USER_LINK_SPEED_32G) | \
-(1 << LPFC_USER_LINK_SPEED_16G) | \
-(1 << LPFC_USER_LINK_SPEED_10G) | \
-(1 << LPFC_USER_LINK_SPEED_8G) | \
-(1 << LPFC_USER_LINK_SPEED_4G) | \
-(1 << LPFC_USER_LINK_SPEED_2G) | \
-(1 << LPFC_USER_LINK_SPEED_1G) | \
-(1 << LPFC_USER_LINK_SPEED_AUTO))
-#define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16, 32"
+#define LPFC_USER_LINK_SPEED_64G   64  /* 64 Gigabaud */
+#define LPFC_USER_LINK_SPEED_MAX   LPFC_USER_LINK_SPEED_64G
+
+#define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16, 32, 64"
 
 enum nemb_type {
nemb_mse = 1,
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 705c42e724c2..ec080de4e7a7 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -4126,23 +4126,32 @@ lpfc_link_speed_store(struct device *dev, struct 
device_attribute *attr,
((val == LPFC_USER_LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) ||
((val == LPFC_USER_LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)) ||
((val == LPFC_USER_LINK_SPEED_16G) && !(phba->lmt & LMT_16Gb)) ||
-   ((val == LPFC_USER_LINK_SPEED_32G) && !(phba->lmt & LMT_32Gb))) {
+   ((val == LPFC_USER_LINK_SPEED_32G) && !(phba->lmt & LMT_32Gb)) ||
+   ((val == LPFC_USER_LINK_SPEED_64G) && !(phba->lmt & LMT_64Gb))) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"2879 lpfc_link_speed attribute cannot be set "
"to %d. Speed is not supported by this port.\n",
val);
return -EINVAL;
}
-   if (val == LPFC_USER_LINK_SPEED_16G &&
-phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
+   if (val >= LPFC_USER_LINK_SPEED_16G &&
+   phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3112 lpfc_link_speed attribute cannot be set "
"to %d. Speed is not supported in loop mode.\n",
val);
return -EINVAL;
}
-   if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) &&
-   (LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) {
+
+   switch (val) {
+   case LPFC_USER_LINK_SPEED_AUTO:
+   case LPFC_USER_LINK_SPEED_1G:
+   case LPFC_USER_LINK_SPEED_2G:
+   case LPFC_USER_LINK_SPEED_4G:
+   case LPFC_USER_LINK_SPEED_8G:
+   case LPFC_USER_LINK_SPEED_16G:
+   case LPFC_USER_LINK_SPEED_32G:
+   case LPFC_USER_LINK_SPEED_64G:
prev_val = phba->cfg_link_speed;
phba->cfg_link_speed = val;
if (nolip)
@@ -4152,13 +4161,17 @@ lpfc_link_speed_store(struct device *dev, struct 
device_attribute *attr,
if (err) {
phba->cfg_link_speed = prev_val;
return -EINVAL;
-   } else
-   return strlen(buf);
+   }
+   return strlen(buf);
+   default:
+   break;
}
+
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-   "0469 lpfc_link_speed attribute cannot be set to %d, "
-

[PATCH 01/13] lpfc: Rework lpfc to allow different sli4 cq and eq handlers

2018-01-26 Thread James Smart
Up until now, an SLI-4 device had no variance in the way it handled
its EQs and CQs. With newer hardware, there are now differences in
doorbells and some differences in how entries are valid.

Prepare the code for new hardwre by creating a sli4-based callout
table that can be set based on if_type.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_init.c |  7 +
 drivers/scsi/lpfc/lpfc_sli.c  | 63 ++-
 drivers/scsi/lpfc/lpfc_sli4.h |  5 
 3 files changed, 44 insertions(+), 31 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 04a77c308836..fc26c4b58d6b 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -9540,6 +9540,13 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba)
}
}
 
+   /* Set up the EQ/CQ register handeling functions now */
+   if (if_type <= LPFC_SLI_INTF_IF_TYPE_2) {
+   phba->sli4_hba.sli4_eq_clr_intr = lpfc_sli4_eq_clr_intr;
+   phba->sli4_hba.sli4_eq_release = lpfc_sli4_eq_release;
+   phba->sli4_hba.sli4_cq_release = lpfc_sli4_cq_release;
+   }
+
return 0;
 
 out_iounmap_all:
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index e97d080e9f65..f91caae6489a 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -299,7 +299,7 @@ lpfc_sli4_eq_get(struct lpfc_queue *q)
  * @q: The Event Queue to disable interrupts
  *
  **/
-static inline void
+inline void
 lpfc_sli4_eq_clr_intr(struct lpfc_queue *q)
 {
struct lpfc_register doorbell;
@@ -5302,41 +5302,42 @@ static void
 lpfc_sli4_arm_cqeq_intr(struct lpfc_hba *phba)
 {
int qidx;
+   struct lpfc_sli4_hba *sli4_hba = &phba->sli4_hba;
 
-   lpfc_sli4_cq_release(phba->sli4_hba.mbx_cq, LPFC_QUEUE_REARM);
-   lpfc_sli4_cq_release(phba->sli4_hba.els_cq, LPFC_QUEUE_REARM);
-   if (phba->sli4_hba.nvmels_cq)
-   lpfc_sli4_cq_release(phba->sli4_hba.nvmels_cq,
+   sli4_hba->sli4_cq_release(sli4_hba->mbx_cq, LPFC_QUEUE_REARM);
+   sli4_hba->sli4_cq_release(sli4_hba->els_cq, LPFC_QUEUE_REARM);
+   if (sli4_hba->nvmels_cq)
+   sli4_hba->sli4_cq_release(sli4_hba->nvmels_cq,
LPFC_QUEUE_REARM);
 
-   if (phba->sli4_hba.fcp_cq)
+   if (sli4_hba->fcp_cq)
for (qidx = 0; qidx < phba->cfg_fcp_io_channel; qidx++)
-   lpfc_sli4_cq_release(phba->sli4_hba.fcp_cq[qidx],
+   sli4_hba->sli4_cq_release(sli4_hba->fcp_cq[qidx],
LPFC_QUEUE_REARM);
 
-   if (phba->sli4_hba.nvme_cq)
+   if (sli4_hba->nvme_cq)
for (qidx = 0; qidx < phba->cfg_nvme_io_channel; qidx++)
-   lpfc_sli4_cq_release(phba->sli4_hba.nvme_cq[qidx],
+   sli4_hba->sli4_cq_release(sli4_hba->nvme_cq[qidx],
LPFC_QUEUE_REARM);
 
if (phba->cfg_fof)
-   lpfc_sli4_cq_release(phba->sli4_hba.oas_cq, LPFC_QUEUE_REARM);
+   sli4_hba->sli4_cq_release(sli4_hba->oas_cq, LPFC_QUEUE_REARM);
 
-   if (phba->sli4_hba.hba_eq)
+   if (sli4_hba->hba_eq)
for (qidx = 0; qidx < phba->io_channel_irqs; qidx++)
-   lpfc_sli4_eq_release(phba->sli4_hba.hba_eq[qidx],
-   LPFC_QUEUE_REARM);
+   sli4_hba->sli4_eq_release(sli4_hba->hba_eq[qidx],
+   LPFC_QUEUE_REARM);
 
if (phba->nvmet_support) {
for (qidx = 0; qidx < phba->cfg_nvmet_mrq; qidx++) {
-   lpfc_sli4_cq_release(
-   phba->sli4_hba.nvmet_cqset[qidx],
+   sli4_hba->sli4_cq_release(
+   sli4_hba->nvmet_cqset[qidx],
LPFC_QUEUE_REARM);
}
}
 
if (phba->cfg_fof)
-   lpfc_sli4_eq_release(phba->sli4_hba.fof_eq, LPFC_QUEUE_REARM);
+   sli4_hba->sli4_eq_release(sli4_hba->fof_eq, LPFC_QUEUE_REARM);
 }
 
 /**
@@ -7270,7 +7271,7 @@ lpfc_sli4_mbox_completions_pending(struct lpfc_hba *phba)
 bool
 lpfc_sli4_process_missed_mbox_completions(struct lpfc_hba *phba)
 {
-
+   struct lpfc_sli4_hba *sli4_hba = &phba->sli4_hba;
uint32_t eqidx;
struct lpfc_queue *fpeq = NULL;
struct lpfc_eqe *eqe;
@@ -7281,11 +7282,11 @@ lpfc_sli4_process_missed_mbox_completions(struct 
lpfc_hba *phba)
 
/* Find the eq associated with the mcq */
 
-   if (phba->sli4_hba.hba_eq)
+   if (sli4_hba->hba_eq)

[PATCH 09/13] lpfc: Add embedded data pointers for enhanced performance

2018-01-26 Thread James Smart
The current driver isn't taking advantage of a performance hint whereby
the initial data buffer descriptor can be placed in the WQE as well as
the SGL.

Add the logic to detect support for the feature and to use it when
supported.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc.h   |  2 ++
 drivers/scsi/lpfc/lpfc_hw4.h   |  3 +++
 drivers/scsi/lpfc/lpfc_init.c  | 21 +
 drivers/scsi/lpfc/lpfc_nvme.c  | 18 ++
 drivers/scsi/lpfc/lpfc_nvmet.c | 24 
 drivers/scsi/lpfc/lpfc_scsi.c  |  8 ++--
 drivers/scsi/lpfc/lpfc_sli.c   | 25 +
 7 files changed, 95 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 7aad4a717f13..9136a59b1c5b 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -840,6 +840,8 @@ struct lpfc_hba {
 #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 */
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index be8227dfa086..ed5e870c58c3 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -4226,6 +4226,9 @@ struct wqe_common {
 #define wqe_irsp_SHIFT4
 #define wqe_irsp_MASK 0x0001
 #define wqe_irsp_WORD word11
+#define wqe_pbde_SHIFT5
+#define wqe_pbde_MASK 0x0001
+#define wqe_pbde_WORD word11
 #define wqe_sup_SHIFT 6
 #define wqe_sup_MASK  0x0001
 #define wqe_sup_WORD  word11
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 0e05f802bfaa..b04fd30e9de0 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -10605,6 +10605,19 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, 
LPFC_MBOXQ_t *mboxq)
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).
@@ -10636,6 +10649,14 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, 
LPFC_MBOXQ_t *mboxq)
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))
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 527e63c1f1ac..63e2d64da68f 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -1167,6 +1167,7 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport,
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;
@@ -1234,7 +1235,24 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport,
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);

[PATCH 11/13] lpfc: Work around NVME cmd iu SGL type

2018-01-26 Thread James Smart
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 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc.h  |  1 +
 drivers/scsi/lpfc/lpfc_attr.c | 14 
 drivers/scsi/lpfc/lpfc_hw4.h  |  1 +
 drivers/scsi/lpfc/lpfc_init.c |  4 ++--
 drivers/scsi/lpfc/lpfc_nvme.c | 51 ++-
 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 {
uint32_t cfg_fcp_io_channel;
uint32_t cfg_suppress_rsp;
uint32_t cfg_nvme_oas;
+   uint32_t cfg_nvme_embed_cmd;
uint32_t cfg_nvme_io_channel;
uint32_t cfg_nvmet_mrq;
uint32_t cfg_enable_nvmet;
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index ec080de4e7a7..86d241642d03 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -5059,6 +5059,18 @@ LPFC_ATTR_RW(nvme_oas, 0, 0, 1,
 "Use OAS bit on NVME IOs");
 
 /*
+ * lpfc_nvme_embed_cmd: Use the oas bit when sending NVME/NVMET IOs
+ *
+ *  0  = Put NVME Command in SGL
+ *  1  = Embed NVME Command in WQE (unless G7)
+ *  2 =  Embed NVME Command in WQE (force)
+ *
+ * Value range is [0,2]. Default value is 1.
+ */
+LPFC_ATTR_RW(nvme_embed_cmd, 1, 0, 2,
+"Embed NVME Command in WQE");
+
+/*
  * lpfc_fcp_io_channel: Set the number of FCP IO channels the driver
  * will advertise it supports to the SCSI layer. This also will map to
  * the number of WQs the driver will create.
@@ -5299,6 +5311,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_lpfc_task_mgmt_tmo,
&dev_attr_lpfc_use_msi,
&dev_attr_lpfc_nvme_oas,
+   &dev_attr_lpfc_nvme_embed_cmd,
&dev_attr_lpfc_auto_imax,
&dev_attr_lpfc_fcp_imax,
&dev_attr_lpfc_fcp_cpu_map,
@@ -6323,6 +6336,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
lpfc_enable_SmartSAN_init(phba, lpfc_enable_SmartSAN);
lpfc_use_msi_init(phba, lpfc_use_msi);
lpfc_nvme_oas_init(phba, lpfc_nvme_oas);
+   lpfc_nvme_embed_cmd_init(phba, lpfc_nvme_embed_cmd);
lpfc_auto_imax_init(phba, lpfc_auto_imax);
lpfc_fcp_imax_init(phba, lpfc_fcp_imax);
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 {
 #define lpfc_mbx_rd_rev_vpd_MASK   0x0001
 #define lpfc_mbx_rd_rev_vpd_WORD   word1
uint32_t first_hw_rev;
+#define LPFC_G7_ASIC_1 0xd
uint32_t second_hw_rev;
uint32_t word4_rsvd;
uint32_t third_hw_rev;
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index b04fd30e9de0..d7659dff9df4 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -10651,11 +10651,11 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, 
LPFC_MBOXQ_t *mboxq)
 
lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_NVME,
"6422 XIB %d: FCP %d %d "
-   "NVME %d %d %d\n",
+   "NVME %d %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);
+   phba->cfg_nvme_embed_cmd, 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) &&
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index d3eaa6d59179..c094683b14b5 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,
  

[PATCH 08/13] lpfc: Enable fw download on if_type=6 devices

2018-01-26 Thread James Smart
Current code is very explicit in what it allows to be downloaded.
The driver checking prevented G7 firmware download. The driver
checking is unnecessary as the device will validate what it receives.

Revise the firmware download interface checking.
Added a little debug support in case there is still a failure.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_hw4.h  |  5 +
 drivers/scsi/lpfc/lpfc_init.c | 44 ++-
 drivers/scsi/lpfc/lpfc_sli.c  |  1 +
 3 files changed, 33 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index dba724e1f5ee..be8227dfa086 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -2241,6 +2241,7 @@ struct lpfc_mbx_redisc_fcf_tbl {
  * command.
  */
 #define ADD_STATUS_OPERATION_ALREADY_ACTIVE0x67
+#define ADD_STATUS_FW_NOT_SUPPORTED0xEB
 
 struct lpfc_mbx_sli4_config {
struct mbox_header header;
@@ -4603,10 +4604,6 @@ union lpfc_wqe128 {
struct gen_req64_wqe gen_req;
 };
 
-#define LPFC_GROUP_OJECT_MAGIC_G5  0xfeaa0001
-#define LPFC_GROUP_OJECT_MAGIC_G6  0xfeaa0003
-#define LPFC_FILE_TYPE_GROUP   0xf7
-#define LPFC_FILE_ID_GROUP 0xa2
 struct lpfc_grp_hdr {
uint32_t size;
uint32_t magic_number;
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index ad51bfcd929b..0e05f802bfaa 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -11294,6 +11294,27 @@ lpfc_sli4_get_iocb_cnt(struct lpfc_hba *phba)
 }
 
 
+static void
+lpfc_log_write_firmware_error(struct lpfc_hba *phba, uint32_t offset,
+   uint32_t magic_number, uint32_t ftype, uint32_t fid, uint32_t fsize,
+   const struct firmware *fw)
+{
+   if (offset == ADD_STATUS_FW_NOT_SUPPORTED)
+   lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+   "3030 This firmware version is not supported on "
+   "this HBA model. Device:%x Magic:%x Type:%x "
+   "ID:%x Size %d %zd\n",
+   phba->pcidev->device, magic_number, ftype, fid,
+   fsize, fw->size);
+   else
+   lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+   "3022 FW Download failed. Device:%x Magic:%x Type:%x "
+   "ID:%x Size %d %zd\n",
+   phba->pcidev->device, magic_number, ftype, fid,
+   fsize, fw->size);
+}
+
+
 /**
  * lpfc_write_firmware - attempt to write a firmware image to the port
  * @fw: pointer to firmware image returned from request_firmware.
@@ -11321,20 +11342,10 @@ lpfc_write_firmware(const struct firmware *fw, void 
*context)
 
magic_number = be32_to_cpu(image->magic_number);
ftype = bf_get_be32(lpfc_grp_hdr_file_type, image);
-   fid = bf_get_be32(lpfc_grp_hdr_id, image),
+   fid = bf_get_be32(lpfc_grp_hdr_id, image);
fsize = be32_to_cpu(image->size);
 
INIT_LIST_HEAD(&dma_buffer_list);
-   if ((magic_number != LPFC_GROUP_OJECT_MAGIC_G5 &&
-magic_number != LPFC_GROUP_OJECT_MAGIC_G6) ||
-   ftype != LPFC_FILE_TYPE_GROUP || fsize != fw->size) {
-   lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-   "3022 Invalid FW image found. "
-   "Magic:%x Type:%x ID:%x Size %d %zd\n",
-   magic_number, ftype, fid, fsize, fw->size);
-   rc = -EINVAL;
-   goto release_out;
-   }
lpfc_decode_firmware_rev(phba, fwrev, 1);
if (strncmp(fwrev, image->revision, strnlen(image->revision, 16))) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -11375,11 +11386,18 @@ lpfc_write_firmware(const struct firmware *fw, void 
*context)
}
rc = lpfc_wr_object(phba, &dma_buffer_list,
(fw->size - offset), &offset);
-   if (rc)
+   if (rc) {
+   lpfc_log_write_firmware_error(phba, offset,
+   magic_number, ftype, fid, fsize, fw);
goto release_out;
+   }
}
rc = offset;
-   }
+   } else
+   lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+   "3029 Skipped Firmware update, Current "
+   "Version:%s New Version:%s\n",
+   fwrev, image->revision);
 
 release_out:
list_for_each_entry_safe(dmabuf, next, &dma_buffer_list, list) {
diff --git a/dr

[PATCH 10/13] lpfc: Fix nvme embedded io length on new hardware

2018-01-26 Thread James Smart
Newer hardware more strictly enforces buffer lenghts, causing an
mis-set value to be identified. Older hardware won't catch it.
The difference is benign on old hardware.

Set the right embedded buffer length for nvme ios.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_nvme.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 63e2d64da68f..d3eaa6d59179 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -655,7 +655,7 @@ lpfc_nvme_adj_fcp_sgls(struct lpfc_vport *vport,
 
/* Word 0-2 - NVME CMND IU (embedded payload) */
wqe->generic.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_IMMED;
-   wqe->generic.bde.tus.f.bdeSize = 60;
+   wqe->generic.bde.tus.f.bdeSize = 56;
wqe->generic.bde.addrHigh = 0;
wqe->generic.bde.addrLow =  64;  /* Word 16 */
 
-- 
2.13.1



[PATCH 12/13] lpfc: update driver version to 12.0.0.0

2018-01-26 Thread James Smart
Update the driver version to 12.0.0.0

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_version.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index 3b04ecb17a38..830dc36ab028 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -20,7 +20,7 @@
  * included with this package. *
  ***/
 
-#define LPFC_DRIVER_VERSION "11.4.0.7"
+#define LPFC_DRIVER_VERSION "12.0.0.0"
 #define LPFC_DRIVER_NAME   "lpfc"
 
 /* Used for SLI 2/3 */
-- 
2.13.1



[PATCH 13/13] lpfc: Update 12.0.0.0 modified files for 2018 Copyright

2018-01-26 Thread James Smart
Updated Copyright in files updated 12.0.0.0

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_bsg.c | 2 +-
 drivers/scsi/lpfc/lpfc_ct.c  | 2 +-
 drivers/scsi/lpfc/lpfc_debugfs.c | 2 +-
 drivers/scsi/lpfc/lpfc_debugfs.h | 2 +-
 drivers/scsi/lpfc/lpfc_hw.h  | 2 +-
 drivers/scsi/lpfc/lpfc_ids.h | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index 8b33b652226b..0f174ca80f67 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2009-2015 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 03a7e13a049d..ebe8ac1b88e7 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 308303d501cf..fb0dc2aeed91 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2007-2015 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
index 12fbf498a7ce..f32eaeb2225a 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.h
+++ b/drivers/scsi/lpfc/lpfc_debugfs.h
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2007-2011 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index b91b429fe2df..2ebcf707bb3c 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_ids.h b/drivers/scsi/lpfc/lpfc_ids.h
index 329c8d28869c..07ee34017d88 100644
--- a/drivers/scsi/lpfc/lpfc_ids.h
+++ b/drivers/scsi/lpfc/lpfc_ids.h
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
-- 
2.13.1



Re: [PATCH 06/13] lpfc: Add 64G link speed support

2018-01-29 Thread James Smart

On 1/29/2018 3:45 AM, Steffen Maier wrote:

@@ -2966,6 +2975,9 @@ struct lpfc_mbx_read_top {

  #define LPFC_LINK_SPEED_10GHZ    0x40
  #define LPFC_LINK_SPEED_16GHZ    0x80
  #define LPFC_LINK_SPEED_32GHZ    0x90
+#define LPFC_LINK_SPEED_64GHZ    0xA0
+#define LPFC_LINK_SPEED_128GHZ    0xB0
+#define LPFC_LINK_SPEED_2568GHZ    0xC0

  ^
typo? 2568 => 256

The new 128 and 256 definitions do not seem to be used in this patch set?



Yep. And not used yet.  I'll fix in a repost.  For the repost, I'll wait 
until the other patches have a review.


-- james



[PATCH v3 00/19] lpfc updates for 11.4.0.7

2018-01-30 Thread James Smart
This patch set provides a number of fixes for the driver.

The patches were cut against the Martin's 4.16/scsi-queue tree.
There are no outside dependencies and are expected to be pulled
via Martins tree.


v2:
  respin patch 14 "lpfc: Validate adapter support for SRIU option"
for snippet that was missing

v3:
  Responded to review comments from Hannes
  Updated Copyright string used in load banner


James Smart (19):
  lpfc: Fix frequency of Release WQE CQEs
  lpfc: Increase CQ and WQ sizes for SCSI
  lpfc: move placement of target destroy on driver detach
  lpfc: correct debug counters for abort
  lpfc: Add WQ Full Logic for NVME Target
  lpfc: Fix PRLI handling when topology type changes
  lpfc: Fix IO failure during hba reset testing with nvme io.
  lpfc: Fix RQ empty firmware trap
  lpfc: Allow set of maximum outstanding SCSI cmd limit for a target
parameter
  lpfc: Fix soft lockup in lpfc worker thread during LIP testing
  lpfc: Fix issue_lip if link is disabled
  lpfc: Indicate CONF support in NVMe PRLI
  lpfc: Fix SCSI io host reset causing kernel crash
  lpfc: Validate adapter support for SRIU option
  lpfc: Fix header inclusion in lpfc_nvmet
  lpfc: Treat SCSI Write operation Underruns as an error
  lpfc: Fix nonrecovery of NVME controller after cable swap.
  lpfc: update driver version to 11.4.0.7
  lpfc: Update 11.4.0.7 modified files for 2018 Copyright

 drivers/scsi/lpfc/lpfc.h   |   3 +-
 drivers/scsi/lpfc/lpfc_attr.c  |  17 +++-
 drivers/scsi/lpfc/lpfc_crtn.h  |   3 +-
 drivers/scsi/lpfc/lpfc_els.c   |   5 +-
 drivers/scsi/lpfc/lpfc_hbadisc.c   |   7 +-
 drivers/scsi/lpfc/lpfc_hw4.h   |  14 +++-
 drivers/scsi/lpfc/lpfc_init.c  |  69 +++-
 drivers/scsi/lpfc/lpfc_mbox.c  |   6 +-
 drivers/scsi/lpfc/lpfc_mem.c   |  10 ++-
 drivers/scsi/lpfc/lpfc_nportdisc.c |   7 +-
 drivers/scsi/lpfc/lpfc_nvme.c  |  30 +++
 drivers/scsi/lpfc/lpfc_nvmet.c | 162 +
 drivers/scsi/lpfc/lpfc_nvmet.h |  10 ++-
 drivers/scsi/lpfc/lpfc_scsi.c  |  49 +++
 drivers/scsi/lpfc/lpfc_sli.c   |  36 -
 drivers/scsi/lpfc/lpfc_sli4.h  |  12 ++-
 drivers/scsi/lpfc/lpfc_version.h   |   8 +-
 17 files changed, 341 insertions(+), 107 deletions(-)

-- 
2.13.1



[PATCH v3 02/19] lpfc: Increase CQ and WQ sizes for SCSI

2018-01-30 Thread James Smart
Increased CQ and WQ sizes for SCSI FCP, matching those used
for NVMe development.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 

---
v3:
  lpfc_init.c:
Corrected indentation of comments after patching
Removed unnecessary braces
Revised comment on checking embedded cdb support
---
 drivers/scsi/lpfc/lpfc.h  |  1 +
 drivers/scsi/lpfc/lpfc_hw4.h  |  3 +++
 drivers/scsi/lpfc/lpfc_init.c | 36 +---
 drivers/scsi/lpfc/lpfc_sli.c  |  3 ++-
 drivers/scsi/lpfc/lpfc_sli4.h |  5 +
 5 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 61fb46da05d4..d042f9118e3b 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -760,6 +760,7 @@ struct lpfc_hba {
uint8_t  mds_diags_support;
uint32_t initial_imax;
uint8_t  bbcredit_support;
+   uint8_t  enab_exp_wqcq_pages;
 
/* HBA Config Parameters */
uint32_t cfg_ack0;
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 73c2f6971d2b..ef469129fb71 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -3212,6 +3212,9 @@ struct lpfc_sli4_parameters {
 #define cfg_cqv_SHIFT  14
 #define cfg_cqv_MASK   0x0003
 #define cfg_cqv_WORD   word4
+#define cfg_cqpsize_SHIFT  16
+#define cfg_cqpsize_MASK   0x00ff
+#define cfg_cqpsize_WORD   word4
uint32_t word5;
uint32_t word6;
 #define cfg_mqv_SHIFT  14
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index f539c554588c..40ffa042 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -8011,9 +8011,10 @@ static int
 lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx)
 {
struct lpfc_queue *qdesc;
+   uint32_t wqesize;
 
/* Create Fast Path FCP CQs */
-   if (phba->fcp_embed_io)
+   if (phba->enab_exp_wqcq_pages)
/* Increase the CQ size when WQEs contain an embedded cdb */
qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE,
  phba->sli4_hba.cq_esize,
@@ -8031,15 +8032,18 @@ lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx)
phba->sli4_hba.fcp_cq[wqidx] = qdesc;
 
/* Create Fast Path FCP WQs */
-   if (phba->fcp_embed_io)
+   if (phba->enab_exp_wqcq_pages) {
/* Increase the WQ size when WQEs contain an embedded cdb */
+   wqesize = (phba->fcp_embed_io) ?
+   LPFC_WQE128_SIZE : phba->sli4_hba.wq_esize;
qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE,
- LPFC_WQE128_SIZE,
+ wqesize,
  LPFC_WQE_EXP_COUNT);
-   else
+   } else
qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
  phba->sli4_hba.wq_esize,
  phba->sli4_hba.wq_ecount);
+
if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0503 Failed allocate fast-path FCP WQ (%d)\n",
@@ -10476,15 +10480,21 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, 
LPFC_MBOXQ_t *mboxq)
sli4_params->sge_supp_len = LPFC_MAX_SGE_SIZE;
 
/*
-* Issue IOs with CDB embedded in WQE to minimized the number
-* of DMAs the firmware has to do. Setting this to 1 also forces
-* the driver to use 128 bytes WQEs for FCP IOs.
+* Check whether the adapter supports an embedded copy of the
+* FCP CMD IU within the WQE for FCP_Ixxx commands. In order
+* to use this option, 128-byte WQEs must be used.
 */
if (bf_get(cfg_ext_embed_cb, mbx_sli4_parameters))
phba->fcp_embed_io = 1;
else
phba->fcp_embed_io = 0;
 
+   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))
+   phba->enab_exp_wqcq_pages = 1;
+   else
+   phba->enab_exp_wqcq_pages = 0;
/*
 * Check if the SLI port supports MDS Diagnostics
 */
@@ -12227,6 +12237,7 @@ int
 lpfc_fof_queue_create(struct lpfc_hba *phba)
 {
struct lpfc_queue *qdesc;
+   uint32_t wqesize;
 
/* Create FOF EQ */
qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
@@ -12240,7 +12251,7 @@ lpfc_fof_queue_create(struct lpfc_hba *phba)
if (phba-&g

[PATCH v3 04/19] lpfc: correct debug counters for abort

2018-01-30 Thread James Smart
Existing code was using the wrong field for the completion status
when comparing whether to increment abort statistics

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/lpfc/lpfc_nvmet.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
index 8dbf5c9d51aa..7927ac46d345 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.c
+++ b/drivers/scsi/lpfc/lpfc_nvmet.c
@@ -130,7 +130,7 @@ lpfc_nvmet_xmt_ls_rsp_cmp(struct lpfc_hba *phba, struct 
lpfc_iocbq *cmdwqe,
if (tgtp) {
if (status) {
atomic_inc(&tgtp->xmt_ls_rsp_error);
-   if (status == IOERR_ABORT_REQUESTED)
+   if (result == IOERR_ABORT_REQUESTED)
atomic_inc(&tgtp->xmt_ls_rsp_aborted);
if (bf_get(lpfc_wcqe_c_xb, wcqe))
atomic_inc(&tgtp->xmt_ls_rsp_xb_set);
@@ -541,7 +541,7 @@ lpfc_nvmet_xmt_fcp_op_cmp(struct lpfc_hba *phba, struct 
lpfc_iocbq *cmdwqe,
rsp->transferred_length = 0;
if (tgtp) {
atomic_inc(&tgtp->xmt_fcp_rsp_error);
-   if (status == IOERR_ABORT_REQUESTED)
+   if (result == IOERR_ABORT_REQUESTED)
atomic_inc(&tgtp->xmt_fcp_rsp_aborted);
}
 
-- 
2.13.1



[PATCH v3 01/19] lpfc: Fix frequency of Release WQE CQEs

2018-01-30 Thread James Smart
The driver controls when the hardware sends completions that
communicate consumption of elements from the WQ. This is done by
setting a WQEC bit on a WQE.

The current driver sets it on every Nth WQE posting. However, the
driver isn't clearing the bit if the WQE is reused. Thus, if the
queue depth isn't evenly divisible by N, with enough time, it can
be set on every element, creating a lot of overhead and risking
CQ full conditions.

Correct by clearing the bit when not setting it on an Nth element.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/lpfc/lpfc_sli.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 5f5528a12308..149f21f53b13 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -129,6 +129,8 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe)
/* set consumption flag every once in a while */
if (!((q->host_index + 1) % q->entry_repost))
bf_set(wqe_wqec, &wqe->generic.wqe_com, 1);
+   else
+   bf_set(wqe_wqec, &wqe->generic.wqe_com, 0);
if (q->phba->sli3_options & LPFC_SLI4_PHWQ_ENABLED)
bf_set(wqe_wqid, &wqe->generic.wqe_com, q->queue_id);
lpfc_sli_pcimem_bcopy(wqe, temp_wqe, q->entry_size);
-- 
2.13.1



[PATCH v3 03/19] lpfc: move placement of target destroy on driver detach

2018-01-30 Thread James Smart
Ensure nvme localports/targetports are torn down before
dismantling the adapter sli interface on driver detachment.
This aids leaving interfaces live while nvme may be making
callbacks to abort it.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/lpfc/lpfc_init.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 40ffa042..bff5c95cf5df 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -11503,13 +11503,6 @@ lpfc_pci_remove_one_s4(struct pci_dev *pdev)
/* Remove FC host and then SCSI host with the physical port */
fc_remove_host(shost);
scsi_remove_host(shost);
-   /*
-* Bring down the SLI Layer. This step disables all interrupts,
-* clears the rings, discards all mailbox commands, and resets
-* the HBA FCoE function.
-*/
-   lpfc_debugfs_terminate(vport);
-   lpfc_sli4_hba_unset(phba);
 
/* Perform ndlp cleanup on the physical port.  The nvme and nvmet
 * localports are destroyed after to cleanup all transport memory.
@@ -11518,6 +11511,13 @@ lpfc_pci_remove_one_s4(struct pci_dev *pdev)
lpfc_nvmet_destroy_targetport(phba);
lpfc_nvme_destroy_localport(vport);
 
+   /*
+* Bring down the SLI Layer. This step disables all interrupts,
+* clears the rings, discards all mailbox commands, and resets
+* the HBA FCoE function.
+*/
+   lpfc_debugfs_terminate(vport);
+   lpfc_sli4_hba_unset(phba);
 
lpfc_stop_hba_timers(phba);
spin_lock_irq(&phba->hbalock);
-- 
2.13.1



[PATCH v3 12/19] lpfc: Indicate CONF support in NVMe PRLI

2018-01-30 Thread James Smart
Revise the NVME PRLI to indicate CONF support.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/lpfc/lpfc_els.c   | 3 ++-
 drivers/scsi/lpfc/lpfc_hw4.h   | 6 +++---
 drivers/scsi/lpfc/lpfc_nportdisc.c | 3 ---
 3 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 234c7c015982..404e1af5e2ab 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -2293,10 +2293,11 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct 
lpfc_nodelist *ndlp,
if (phba->nvmet_support) {
bf_set(prli_tgt, npr_nvme, 1);
bf_set(prli_disc, npr_nvme, 1);
-
} else {
bf_set(prli_init, npr_nvme, 1);
+   bf_set(prli_conf, npr_nvme, 1);
}
+
npr_nvme->word1 = cpu_to_be32(npr_nvme->word1);
npr_nvme->word4 = cpu_to_be32(npr_nvme->word4);
elsiocb->iocb_flag |= LPFC_PRLI_NVME_REQ;
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index ef469129fb71..7c3afc3d3121 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -4346,9 +4346,9 @@ struct lpfc_nvme_prli {
 #define prli_init_SHIFT 5
 #define prli_init_MASK  0x0001
 #define prli_init_WORD  word4
-#define prli_recov_SHIFT8
-#define prli_recov_MASK 0x0001
-#define prli_recov_WORD word4
+#define prli_conf_SHIFT 7
+#define prli_conf_MASK  0x0001
+#define prli_conf_WORD  word4
uint32_t word5;
 #define prli_fb_sz_SHIFT0
 #define prli_fb_sz_MASK 0x
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c 
b/drivers/scsi/lpfc/lpfc_nportdisc.c
index d841aa42f607..bbf1e1342b09 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -2011,9 +2011,6 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, 
struct lpfc_nodelist *ndlp,
}
}
 
-   if (bf_get_be32(prli_recov, nvpr))
-   ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
-
lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
 "6029 NVME PRLI Cmpl w1 x%08x "
 "w4 x%08x w5 x%08x flag x%x, "
-- 
2.13.1



[PATCH v3 15/19] lpfc: Fix header inclusion in lpfc_nvmet

2018-01-30 Thread James Smart
The driver was inappropriately pulling in the nvme host's
nvme.h header. What it really needed was the standard
 header.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/lpfc/lpfc_nvmet.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
index 6dd8535918f6..823b6df0aec7 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.c
+++ b/drivers/scsi/lpfc/lpfc_nvmet.c
@@ -36,7 +36,7 @@
 #include 
 #include 
 
-#include <../drivers/nvme/host/nvme.h>
+#include 
 #include 
 #include 
 
-- 
2.13.1



[PATCH v3 08/19] lpfc: Fix RQ empty firmware trap

2018-01-30 Thread James Smart
When nvme target deferred receive logic waits for exchange
resources, the corresponding receive buffer is not replenished
with the hardware. This can result in a lack of asynchronous
receive buffer resources in the hardware, resulting in a
"2885 Port Status Event: ... error 1=0x52004a01 ..." message.

Correct by replenishing the buffer whenenver the deferred
logic kicks in.  Update corresponding debug messages and
statistics as well.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/lpfc/lpfc_attr.c  |  6 ++
 drivers/scsi/lpfc/lpfc_mem.c   |  8 ++--
 drivers/scsi/lpfc/lpfc_nvmet.c | 31 +--
 drivers/scsi/lpfc/lpfc_nvmet.h |  7 +--
 drivers/scsi/lpfc/lpfc_sli.c   | 12 
 5 files changed, 50 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index d188fb565a32..91df2b4e9fce 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -259,6 +259,12 @@ lpfc_nvme_info_show(struct device *dev, struct 
device_attribute *attr,
atomic_read(&tgtp->xmt_abort_rsp),
atomic_read(&tgtp->xmt_abort_rsp_error));
 
+   len += snprintf(buf + len, PAGE_SIZE - len,
+   "DELAY: ctx %08x  fod %08x wqfull %08x\n",
+   atomic_read(&tgtp->defer_ctx),
+   atomic_read(&tgtp->defer_fod),
+   atomic_read(&tgtp->defer_wqfull));
+
/* Calculate outstanding IOs */
tot = atomic_read(&tgtp->rcv_fcp_cmd_drop);
tot += atomic_read(&tgtp->xmt_fcp_release);
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
index 56faeb049b4a..60078e61da5e 100644
--- a/drivers/scsi/lpfc/lpfc_mem.c
+++ b/drivers/scsi/lpfc/lpfc_mem.c
@@ -755,10 +755,14 @@ lpfc_rq_buf_free(struct lpfc_hba *phba, struct 
lpfc_dmabuf *mp)
if (rc < 0) {
(rqbp->rqb_free_buffer)(phba, rqb_entry);
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-   "6409 Cannot post to RQ %d: %x %x\n",
+   "6409 Cannot post to HRQ %d: %x %x %x "
+   "DRQ %x %x\n",
rqb_entry->hrq->queue_id,
rqb_entry->hrq->host_index,
-   rqb_entry->hrq->hba_index);
+   rqb_entry->hrq->hba_index,
+   rqb_entry->hrq->entry_count,
+   rqb_entry->drq->host_index,
+   rqb_entry->drq->hba_index);
} else {
list_add_tail(&rqb_entry->hbuf.list, &rqbp->rqb_buffer_list);
rqbp->buffer_count++;
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
index 9c2acf90212c..0539585d32d4 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.c
+++ b/drivers/scsi/lpfc/lpfc_nvmet.c
@@ -270,8 +270,6 @@ lpfc_nvmet_ctxbuf_post(struct lpfc_hba *phba, struct 
lpfc_nvmet_ctxbuf *ctx_buf)
 "NVMET RCV BUSY: xri x%x sz %d "
 "from %06x\n",
 oxid, size, sid);
-   /* defer repost rcv buffer till .defer_rcv callback */
-   ctxp->flag &= ~LPFC_NVMET_DEFER_RCV_REPOST;
atomic_inc(&tgtp->rcv_fcp_cmd_out);
return;
}
@@ -837,6 +835,7 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport,
list_add_tail(&nvmewqeq->list, &wq->wqfull_list);
wq->q_flag |= HBA_NVMET_WQFULL;
spin_unlock_irqrestore(&pring->ring_lock, iflags);
+   atomic_inc(&lpfc_nvmep->defer_wqfull);
return 0;
}
 
@@ -975,11 +974,9 @@ lpfc_nvmet_defer_rcv(struct nvmet_fc_target_port *tgtport,
 
tgtp = phba->targetport->private;
atomic_inc(&tgtp->rcv_fcp_cmd_defer);
-   if (ctxp->flag & LPFC_NVMET_DEFER_RCV_REPOST)
-   lpfc_rq_buf_free(phba, &nvmebuf->hbuf); /* repost */
-   else
-   nvmebuf->hrq->rqbp->rqb_free_buffer(phba, nvmebuf);
-   ctxp->flag &= ~LPFC_NVMET_DEFER_RCV_REPOST;
+
+   /* Free the nvmebuf since a new buffer already replaced it */
+   nvmebuf->hrq->rqbp->rqb_free_buffer(phba, nvmebuf);
 }
 
 static struct nvmet_fc_target_template lpfc_tgttemplate = {
@@ -1309,6 +1306,9 @@ lpfc_nvmet_create_targetport(struct lpfc_hba *phba)
  

[PATCH v3 17/19] lpfc: Fix nonrecovery of NVME controller after cable swap.

2018-01-30 Thread James Smart
In a test that is doing large numbers of cable swaps on the target,
the nvme controllers wouldn't reconnect.

During the cable swaps, the targets n_port_id would change. This
information was passed to the nvme-fc transport, in the new remoteport
registration. However, the nvme-fc transport didn't update the n_port_id
value in the remoteport struct when it reused an existing structure.
Later, when a new association was attempted on the remoteport, the
driver's NVME LS routine would use the stale n_port_id from the remoteport
struct to address the LS. As the device is no longer at that address,
the LS would go into never never land.

Separately, the nvme-fc transport will be corrected to update the
n_port_id value on a re-registration.

However, for now, there's no reason to use the transports values.
The private pointer points to the drivers node structure and the
node structure is up to date. Therefore, revise the LS routine to
use the drivers data structures for the LS. Augmented the debug
message for better debugging in the future.

Also removed a duplicate if check that seems to have slipped in.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/lpfc/lpfc_nvme.c | 24 +---
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index c6e5b9972585..6327f858c4c8 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -241,10 +241,11 @@ lpfc_nvme_cmpl_gen_req(struct lpfc_hba *phba, struct 
lpfc_iocbq *cmdwqe,
ndlp = (struct lpfc_nodelist *)cmdwqe->context1;
lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
 "6047 nvme cmpl Enter "
-"Data %p DID %x Xri: %x status %x cmd:%p lsreg:%p "
-"bmp:%p ndlp:%p\n",
+"Data %p DID %x Xri: %x status %x reason x%x cmd:%p "
+"lsreg:%p bmp:%p ndlp:%p\n",
 pnvme_lsreq, ndlp ? ndlp->nlp_DID : 0,
 cmdwqe->sli4_xritag, status,
+(wcqe->parameter & 0x),
 cmdwqe, pnvme_lsreq, cmdwqe->context3, ndlp);
 
lpfc_nvmeio_data(phba, "NVME LS  CMPL: xri x%x stat x%x parm x%x\n",
@@ -419,6 +420,7 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport,
 {
int ret = 0;
struct lpfc_nvme_lport *lport;
+   struct lpfc_nvme_rport *rport;
struct lpfc_vport *vport;
struct lpfc_nodelist *ndlp;
struct ulp_bde64 *bpl;
@@ -437,19 +439,18 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport,
 */
 
lport = (struct lpfc_nvme_lport *)pnvme_lport->private;
+   rport = (struct lpfc_nvme_rport *)pnvme_rport->private;
vport = lport->vport;
 
if (vport->load_flag & FC_UNLOADING)
return -ENODEV;
 
-   if (vport->load_flag & FC_UNLOADING)
-   return -ENODEV;
-
-   ndlp = lpfc_findnode_did(vport, pnvme_rport->port_id);
+   /* Need the ndlp.  It is stored in the driver's rport. */
+   ndlp = rport->ndlp;
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE | LOG_NVME_IOERR,
-"6051 DID x%06x not an active rport.\n",
-pnvme_rport->port_id);
+"6051 Remoteport %p, rport has invalid ndlp. "
+"Failing LS Req\n", pnvme_rport);
return -ENODEV;
}
 
@@ -500,8 +501,9 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport,
 
/* Expand print to include key fields. */
lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
-"6149 ENTER.  lport %p, rport %p lsreq%p rqstlen:%d "
-"rsplen:%d %pad %pad\n",
+"6149 Issue LS Req to DID 0x%06x lport %p, rport %p "
+"lsreq%p rqstlen:%d rsplen:%d %pad %pad\n",
+ndlp->nlp_DID,
 pnvme_lport, pnvme_rport,
 pnvme_lsreq, pnvme_lsreq->rqstlen,
 pnvme_lsreq->rsplen, &pnvme_lsreq->rqstdma,
@@ -517,7 +519,7 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport,
ndlp, 2, 30, 0);
if (ret != WQE_SUCCESS) {
atomic_inc(&lport->xmt_ls_err);
-   lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
+   lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_DISC,
 "6052 EXIT. issue ls wqe failed lport %p, "
 "rport %p lsreq%p Status %x DID %x\n",
 pnvme_lport, pnvme_rport, pnvme_lsreq,
-- 
2.13.1



[PATCH v3 07/19] lpfc: Fix IO failure during hba reset testing with nvme io.

2018-01-30 Thread James Smart
A stress test repeatedly resetting the adapter while performing
io would eventually report I/O failures and missing nvme namespaces.

The driver was setting the nvmefc_fcp_req->private pointer to NULL
during the IO completion routine before upcalling done().
If the transport was also running an abort for that IO, the driver
would fail the abort with message 6140. Failing the abort is not
allowed by the nvme-fc transport, as it mandates that the io must be
returned back to the transport. As that does not happen, the transport
controller delete has an outstanding reference and can't complete
teardown.

The NULL-ing of the private pointer should be done only when the io
is considered complete. It's complete when the adapter returns the
exchange with the "exchange busy" flag clear.

Move the NULL'ing of the structure to the done case. This leaves the
io contexts set while it is busy and until the subsequent XRI_ABORTED
completion which returns the exchange is received.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 

---
v3:
  Address review comment that preferred to continue to NULL if the
  io did complete in order to protect stale conditions. After review,
  we agreed, thus the above change.
---
 drivers/scsi/lpfc/lpfc_nvme.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 81e3a4f10c3c..c6e5b9972585 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -980,14 +980,14 @@ lpfc_nvme_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct 
lpfc_iocbq *pwqeIn,
phba->cpucheck_cmpl_io[lpfc_ncmd->cpu]++;
}
 #endif
-   freqpriv = nCmd->private;
-   freqpriv->nvme_buf = NULL;
 
/* NVME targets need completion held off until the abort exchange
 * completes unless the NVME Rport is getting unregistered.
 */
 
if (!(lpfc_ncmd->flags & LPFC_SBUF_XBUSY)) {
+   freqpriv = nCmd->private;
+   freqpriv->nvme_buf = NULL;
nCmd->done(nCmd);
lpfc_ncmd->nvmeCmd = NULL;
}
-- 
2.13.1



[PATCH v3 14/19] lpfc: Validate adapter support for SRIU option

2018-01-30 Thread James Smart
When using the special option to suppress the response iu, ensure
the adapter fully supports the feature by checking feature flags
from the adapter and validating the support when formatting the
WQE.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Hannes Reinecke 

---
v2:
  Add missing snippet that changes check logic before enabling
  suppression in lpfc_nvmet_prep_fcp_wqe()
---
 drivers/scsi/lpfc/lpfc_hw4.h   |  3 +++
 drivers/scsi/lpfc/lpfc_init.c  | 13 -
 drivers/scsi/lpfc/lpfc_nvmet.c |  7 ---
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 7c3afc3d3121..52fe28ae50fa 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -3293,6 +3293,9 @@ struct lpfc_sli4_parameters {
 #define cfg_eqdr_SHIFT 8
 #define cfg_eqdr_MASK  0x0001
 #define cfg_eqdr_WORD  word19
+#define cfg_nosr_SHIFT 9
+#define cfg_nosr_MASK  0x0001
+#define cfg_nosr_WORD  word19
 #define LPFC_NODELAY_MAX_IO32
 };
 
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index aa7872a7b493..f2d2faef8710 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -10473,8 +10473,19 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, 
LPFC_MBOXQ_t *mboxq)
phba->cfg_enable_fc4_type = LPFC_ENABLE_FCP;
}
 
-   if (bf_get(cfg_xib, mbx_sli4_parameters) && phba->cfg_suppress_rsp)
+   /*
+* To support Suppress Response feature we must satisfy 3 conditions.
+* lpfc_suppress_rsp module parameter must be set (default).
+* In SLI4-Parameters Descriptor:
+* Extended Inline Buffers (XIB) must be supported.
+* Suppress Response IU Not Supported (SRIUNS) must NOT be supported
+* (double negative).
+*/
+   if (phba->cfg_suppress_rsp && bf_get(cfg_xib, mbx_sli4_parameters) &&
+   !(bf_get(cfg_nosr, mbx_sli4_parameters)))
phba->sli.sli_flag |= LPFC_SLI_SUPPRESS_RSP;
+   else
+   phba->cfg_suppress_rsp = 0;
 
if (bf_get(cfg_eqdr, mbx_sli4_parameters))
phba->sli.sli_flag |= LPFC_SLI_USE_EQDR;
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
index 0539585d32d4..6dd8535918f6 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.c
+++ b/drivers/scsi/lpfc/lpfc_nvmet.c
@@ -2290,9 +2290,10 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
if (rsp->op == NVMET_FCOP_READDATA_RSP) {
atomic_inc(&tgtp->xmt_fcp_read_rsp);
bf_set(wqe_ar, &wqe->fcp_tsend.wqe_com, 1);
-   if ((ndlp->nlp_flag & NLP_SUPPRESS_RSP) &&
-   (rsp->rsplen == 12)) {
-   bf_set(wqe_sup, &wqe->fcp_tsend.wqe_com, 1);
+   if (rsp->rsplen == LPFC_NVMET_SUCCESS_LEN) {
+   if (ndlp->nlp_flag & NLP_SUPPRESS_RSP)
+   bf_set(wqe_sup,
+  &wqe->fcp_tsend.wqe_com, 1);
bf_set(wqe_wqes, &wqe->fcp_tsend.wqe_com, 0);
bf_set(wqe_irsp, &wqe->fcp_tsend.wqe_com, 0);
bf_set(wqe_irsplen, &wqe->fcp_tsend.wqe_com, 0);
-- 
2.13.1



[PATCH v3 18/19] lpfc: update driver version to 11.4.0.7

2018-01-30 Thread James Smart
Update the driver version to 11.4.0.7

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/lpfc/lpfc_version.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index c232bf0e8998..6f4092cb903e 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -20,7 +20,7 @@
  * included with this package. *
  ***/
 
-#define LPFC_DRIVER_VERSION "11.4.0.6"
+#define LPFC_DRIVER_VERSION "11.4.0.7"
 #define LPFC_DRIVER_NAME   "lpfc"
 
 /* Used for SLI 2/3 */
-- 
2.13.1



[PATCH v3 09/19] lpfc: Allow set of maximum outstanding SCSI cmd limit for a target parameter

2018-01-30 Thread James Smart
Make the attribute writeable.
Remove the ramp up to logic as its unnecessary, simply set depth.
Add debug message if depth changed, possibly reducing limit, yet
our outstanding count has yet to catch up with it.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/lpfc/lpfc_attr.c |  4 ++--
 drivers/scsi/lpfc/lpfc_scsi.c | 39 ---
 2 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 91df2b4e9fce..d8064e3ea0ba 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -3471,8 +3471,8 @@ LPFC_VPORT_ATTR_R(lun_queue_depth, 30, 1, 512,
 # tgt_queue_depth:  This parameter is used to limit the number of outstanding
 # commands per target port. Value range is [10,65535]. Default value is 65535.
 */
-LPFC_VPORT_ATTR_R(tgt_queue_depth, 65535, 10, 65535,
- "Max number of FCP commands we can queue to a specific target 
port");
+LPFC_VPORT_ATTR_RW(tgt_queue_depth, 65535, 10, 65535,
+  "Max number of FCP commands we can queue to a specific 
target port");
 
 /*
 # hba_queue_depth:  This parameter is used to limit the number of outstanding
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index c0cdaef4db24..dcc86936e6fc 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -3926,7 +3926,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct 
lpfc_iocbq *pIocbIn,
struct lpfc_rport_data *rdata = lpfc_cmd->rdata;
struct lpfc_nodelist *pnode = rdata->pnode;
struct scsi_cmnd *cmd;
-   int depth;
unsigned long flags;
struct lpfc_fast_path_event *fast_path_evt;
struct Scsi_Host *shost;
@@ -4132,16 +4131,11 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct 
lpfc_iocbq *pIocbIn,
}
spin_unlock_irqrestore(shost->host_lock, flags);
} else if (pnode && NLP_CHK_NODE_ACT(pnode)) {
-   if ((pnode->cmd_qdepth < vport->cfg_tgt_queue_depth) &&
-  time_after(jiffies, pnode->last_change_time +
+   if ((pnode->cmd_qdepth != vport->cfg_tgt_queue_depth) &&
+   time_after(jiffies, pnode->last_change_time +
  msecs_to_jiffies(LPFC_TGTQ_INTERVAL))) {
spin_lock_irqsave(shost->host_lock, flags);
-   depth = pnode->cmd_qdepth * LPFC_TGTQ_RAMPUP_PCENT
-   / 100;
-   depth = depth ? depth : 1;
-   pnode->cmd_qdepth += depth;
-   if (pnode->cmd_qdepth > vport->cfg_tgt_queue_depth)
-   pnode->cmd_qdepth = vport->cfg_tgt_queue_depth;
+   pnode->cmd_qdepth = vport->cfg_tgt_queue_depth;
pnode->last_change_time = jiffies;
spin_unlock_irqrestore(shost->host_lock, flags);
}
@@ -4564,9 +4558,32 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct 
scsi_cmnd *cmnd)
 */
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
goto out_tgt_busy;
-   if (atomic_read(&ndlp->cmd_pending) >= ndlp->cmd_qdepth)
+   if (atomic_read(&ndlp->cmd_pending) >= ndlp->cmd_qdepth) {
+   lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP_ERROR,
+"3377 Target Queue Full, scsi Id:%d Qdepth:%d"
+" Pending command:%d"
+" 
WWNN:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, "
+" 
WWPN:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
+ndlp->nlp_sid, ndlp->cmd_qdepth,
+atomic_read(&ndlp->cmd_pending),
+ndlp->nlp_nodename.u.wwn[0],
+ndlp->nlp_nodename.u.wwn[1],
+ndlp->nlp_nodename.u.wwn[2],
+ndlp->nlp_nodename.u.wwn[3],
+ndlp->nlp_nodename.u.wwn[4],
+ndlp->nlp_nodename.u.wwn[5],
+ndlp->nlp_nodename.u.wwn[6],
+ndlp->nlp_nodename.u.wwn[7],
+ndlp->nlp_portname.u.wwn[0],
+ndlp->nlp_portname.u.wwn[1],
+ndlp->nlp_portname.u.wwn[2],
+ndlp->nlp_portname.u.wwn[3],
+ndlp->nlp_portname.u.wwn[4],
+ndlp->nlp_portname.u.wwn[5],
+  

[PATCH v3 16/19] lpfc: Treat SCSI Write operation Underruns as an error

2018-01-30 Thread James Smart
Currently, write underruns (mismatch of amount transferred vs scsi
status and its residual) detected by the adapter are not being
flagged as an error. Its expected the target controls the data
transfer and would appropriately set the RSP values.  Only read
underruns are treated as errors.

Revise the SCSI error handling to treat write underruns as an
error as well.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/lpfc/lpfc_scsi.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index dcc86936e6fc..10c2dc0cf1fa 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -3772,20 +3772,18 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct 
lpfc_scsi_buf *lpfc_cmd,
scsi_set_resid(cmnd, be32_to_cpu(fcprsp->rspResId));
 
lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP_UNDER,
-"9025 FCP Read Underrun, expected %d, "
+"9025 FCP Underrun, expected %d, "
 "residual %d Data: x%x x%x x%x\n",
 fcpDl,
 scsi_get_resid(cmnd), fcpi_parm, cmnd->cmnd[0],
 cmnd->underflow);
 
/*
-* If there is an under run check if under run reported by
+* If there is an under run, check if under run reported by
 * storage array is same as the under run reported by HBA.
 * If this is not same, there is a dropped frame.
 */
-   if ((cmnd->sc_data_direction == DMA_FROM_DEVICE) &&
-   fcpi_parm &&
-   (scsi_get_resid(cmnd) != fcpi_parm)) {
+   if (fcpi_parm && (scsi_get_resid(cmnd) != fcpi_parm)) {
lpfc_printf_vlog(vport, KERN_WARNING,
 LOG_FCP | LOG_FCP_ERROR,
 "9026 FCP Read Check Error "
-- 
2.13.1



[PATCH v3 11/19] lpfc: Fix issue_lip if link is disabled

2018-01-30 Thread James Smart
The driver ignored checks on whether the link should be
kept administratively down after a link bounce. Correct the
checks.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/lpfc/lpfc_attr.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index d8064e3ea0ba..b79dad7b8278 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -911,7 +911,12 @@ lpfc_issue_lip(struct Scsi_Host *shost)
LPFC_MBOXQ_t *pmboxq;
int mbxstatus = MBXERR_ERROR;
 
+   /*
+* If the link is offline, disabled or BLOCK_MGMT_IO
+* it doesn't make any sense to allow issue_lip
+*/
if ((vport->fc_flag & FC_OFFLINE_MODE) ||
+   (phba->hba_flag & LINK_DISABLED) ||
(phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO))
return -EPERM;
 
-- 
2.13.1



[PATCH v3 13/19] lpfc: Fix SCSI io host reset causing kernel crash

2018-01-30 Thread James Smart
During SCSI error handling escalation to host reset, the SCSI io
routines were moved off the txcmplq, but the individual io's
ON_CMPLQ flag wasn't cleared.  Thus, a background thread saw the
io and attempted to access it as if on the txcmplq.

Clear the flag upon removal.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/lpfc/lpfc_init.c |  4 
 drivers/scsi/lpfc/lpfc_sli.c  | 13 -
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index bff5c95cf5df..aa7872a7b493 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -958,6 +958,7 @@ lpfc_hba_clean_txcmplq(struct lpfc_hba *phba)
struct lpfc_sli_ring *pring;
LIST_HEAD(completions);
int i;
+   struct lpfc_iocbq *piocb, *next_iocb;
 
if (phba->sli_rev != LPFC_SLI_REV4) {
for (i = 0; i < psli->num_rings; i++) {
@@ -983,6 +984,9 @@ lpfc_hba_clean_txcmplq(struct lpfc_hba *phba)
if (!pring)
continue;
spin_lock_irq(&pring->ring_lock);
+   list_for_each_entry_safe(piocb, next_iocb,
+&pring->txcmplq, list)
+   piocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
list_splice_init(&pring->txcmplq, &completions);
pring->txcmplq_cnt = 0;
spin_unlock_irq(&pring->ring_lock);
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 8b2919a553d6..d597e15a1974 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -3778,6 +3778,7 @@ lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba)
struct lpfc_sli *psli = &phba->sli;
struct lpfc_sli_ring  *pring;
uint32_t i;
+   struct lpfc_iocbq *piocb, *next_iocb;
 
spin_lock_irq(&phba->hbalock);
/* Indicate the I/O queues are flushed */
@@ -3792,6 +3793,9 @@ lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba)
spin_lock_irq(&pring->ring_lock);
/* Retrieve everything on txq */
list_splice_init(&pring->txq, &txq);
+   list_for_each_entry_safe(piocb, next_iocb,
+&pring->txcmplq, list)
+   piocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
/* Retrieve everything on the txcmplq */
list_splice_init(&pring->txcmplq, &txcmplq);
pring->txq_cnt = 0;
@@ -3813,6 +3817,9 @@ lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba)
spin_lock_irq(&phba->hbalock);
/* Retrieve everything on txq */
list_splice_init(&pring->txq, &txq);
+   list_for_each_entry_safe(piocb, next_iocb,
+&pring->txcmplq, list)
+   piocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
/* Retrieve everything on the txcmplq */
list_splice_init(&pring->txcmplq, &txcmplq);
pring->txq_cnt = 0;
@@ -3844,6 +3851,7 @@ lpfc_sli_flush_nvme_rings(struct lpfc_hba *phba)
LIST_HEAD(txcmplq);
struct lpfc_sli_ring  *pring;
uint32_t i;
+   struct lpfc_iocbq *piocb, *next_iocb;
 
if (phba->sli_rev < LPFC_SLI_REV4)
return;
@@ -3860,8 +3868,11 @@ lpfc_sli_flush_nvme_rings(struct lpfc_hba *phba)
for (i = 0; i < phba->cfg_nvme_io_channel; i++) {
pring = phba->sli4_hba.nvme_wq[i]->pring;
 
-   /* Retrieve everything on the txcmplq */
spin_lock_irq(&pring->ring_lock);
+   list_for_each_entry_safe(piocb, next_iocb,
+&pring->txcmplq, list)
+   piocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
+   /* Retrieve everything on the txcmplq */
list_splice_init(&pring->txcmplq, &txcmplq);
pring->txcmplq_cnt = 0;
spin_unlock_irq(&pring->ring_lock);
-- 
2.13.1



[PATCH v3 19/19] lpfc: Update 11.4.0.7 modified files for 2018 Copyright

2018-01-30 Thread James Smart
Updated Copyright in files updated 11.4.0.7

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 

---
v3:
  Revised LPFC_COPYRIGHT string for 2018 as well.
---
 drivers/scsi/lpfc/lpfc.h   | 2 +-
 drivers/scsi/lpfc/lpfc_attr.c  | 2 +-
 drivers/scsi/lpfc/lpfc_crtn.h  | 2 +-
 drivers/scsi/lpfc/lpfc_els.c   | 2 +-
 drivers/scsi/lpfc/lpfc_hbadisc.c   | 2 +-
 drivers/scsi/lpfc/lpfc_hw4.h   | 2 +-
 drivers/scsi/lpfc/lpfc_init.c  | 2 +-
 drivers/scsi/lpfc/lpfc_mbox.c  | 2 +-
 drivers/scsi/lpfc/lpfc_mem.c   | 2 +-
 drivers/scsi/lpfc/lpfc_nportdisc.c | 4 ++--
 drivers/scsi/lpfc/lpfc_nvme.c  | 2 +-
 drivers/scsi/lpfc/lpfc_nvmet.c | 2 +-
 drivers/scsi/lpfc/lpfc_nvmet.h | 2 +-
 drivers/scsi/lpfc/lpfc_scsi.c  | 2 +-
 drivers/scsi/lpfc/lpfc_sli.c   | 3 +--
 drivers/scsi/lpfc/lpfc_sli4.h  | 2 +-
 drivers/scsi/lpfc/lpfc_version.h   | 6 +++---
 17 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index d042f9118e3b..9698b9635058 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index b79dad7b8278..70bd25666243 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 3ecf50df93f4..14a86b5b51e4 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 404e1af5e2ab..ba896554a14f 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 9265906d956e..f5bbac3cadbb 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 52fe28ae50fa..8685d26e6929 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -1,7 +1,7

[PATCH v3 05/19] lpfc: Add WQ Full Logic for NVME Target

2018-01-30 Thread James Smart
I/O conditions on the nvme target may have the driver submitting
to a full hardware wq. The hardware wq is a shared resource among
all nvme controllers. When the driver hit a full wq, it failed the
io posting back to the nvme-fc transport, which then escalated it
into errors.

Correct by maintaining a sideband queue within the driver that is
added to when the WQ full condition is hit, and drained from as soon
as new WQ space opens up.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/lpfc/lpfc_crtn.h  |   1 +
 drivers/scsi/lpfc/lpfc_nvmet.c | 116 +
 drivers/scsi/lpfc/lpfc_nvmet.h |   1 +
 drivers/scsi/lpfc/lpfc_sli.c   |   3 ++
 drivers/scsi/lpfc/lpfc_sli4.h  |   5 +-
 5 files changed, 125 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 559f9aa0ed08..3ecf50df93f4 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -254,6 +254,7 @@ void lpfc_nvmet_ctxbuf_post(struct lpfc_hba *phba,
struct lpfc_nvmet_ctxbuf *ctxp);
 int lpfc_nvmet_rcv_unsol_abort(struct lpfc_vport *vport,
   struct fc_frame_header *fc_hdr);
+void lpfc_nvmet_wqfull_process(struct lpfc_hba *phba, struct lpfc_queue *wq);
 void lpfc_sli_flush_nvme_rings(struct lpfc_hba *phba);
 void lpfc_nvme_wait_for_io_drain(struct lpfc_hba *phba);
 void lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *, struct fcf_record *,
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
index 7927ac46d345..9c2acf90212c 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.c
+++ b/drivers/scsi/lpfc/lpfc_nvmet.c
@@ -71,6 +71,8 @@ static int lpfc_nvmet_unsol_fcp_issue_abort(struct lpfc_hba *,
 static int lpfc_nvmet_unsol_ls_issue_abort(struct lpfc_hba *,
   struct lpfc_nvmet_rcv_ctx *,
   uint32_t, uint16_t);
+static void lpfc_nvmet_wqfull_flush(struct lpfc_hba *, struct lpfc_queue *,
+   struct lpfc_nvmet_rcv_ctx *);
 
 void
 lpfc_nvmet_defer_release(struct lpfc_hba *phba, struct lpfc_nvmet_rcv_ctx 
*ctxp)
@@ -741,7 +743,10 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport,
struct lpfc_nvmet_rcv_ctx *ctxp =
container_of(rsp, struct lpfc_nvmet_rcv_ctx, ctx.fcp_req);
struct lpfc_hba *phba = ctxp->phba;
+   struct lpfc_queue *wq;
struct lpfc_iocbq *nvmewqeq;
+   struct lpfc_sli_ring *pring;
+   unsigned long iflags;
int rc;
 
if (phba->pport->load_flag & FC_UNLOADING) {
@@ -820,6 +825,21 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport,
return 0;
}
 
+   if (rc == -EBUSY) {
+   /*
+* WQ was full, so queue nvmewqeq to be sent after
+* WQE release CQE
+*/
+   ctxp->flag |= LPFC_NVMET_DEFER_WQFULL;
+   wq = phba->sli4_hba.nvme_wq[rsp->hwqid];
+   pring = wq->pring;
+   spin_lock_irqsave(&pring->ring_lock, iflags);
+   list_add_tail(&nvmewqeq->list, &wq->wqfull_list);
+   wq->q_flag |= HBA_NVMET_WQFULL;
+   spin_unlock_irqrestore(&pring->ring_lock, iflags);
+   return 0;
+   }
+
/* Give back resources */
atomic_inc(&lpfc_nvmep->xmt_fcp_drop);
lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR,
@@ -851,6 +871,7 @@ lpfc_nvmet_xmt_fcp_abort(struct nvmet_fc_target_port 
*tgtport,
struct lpfc_nvmet_rcv_ctx *ctxp =
container_of(req, struct lpfc_nvmet_rcv_ctx, ctx.fcp_req);
struct lpfc_hba *phba = ctxp->phba;
+   struct lpfc_queue *wq;
unsigned long flags;
 
if (phba->pport->load_flag & FC_UNLOADING)
@@ -880,6 +901,14 @@ lpfc_nvmet_xmt_fcp_abort(struct nvmet_fc_target_port 
*tgtport,
}
ctxp->flag |= LPFC_NVMET_ABORT_OP;
 
+   if (ctxp->flag & LPFC_NVMET_DEFER_WQFULL) {
+   lpfc_nvmet_unsol_fcp_issue_abort(phba, ctxp, ctxp->sid,
+ctxp->oxid);
+   wq = phba->sli4_hba.nvme_wq[ctxp->wqeq->hba_wqidx];
+   lpfc_nvmet_wqfull_flush(phba, wq, ctxp);
+   return;
+   }
+
/* An state of LPFC_NVMET_STE_RCV means we have just received
 * the NVME command and have not started processing it.
 * (by issuing any IO WQEs on this exchange yet)
@@ -1435,16 +1464,103 @@ lpfc_nvmet_rcv_unsol_abort(struct lpfc_vport *vport,
return 0;
 }
 
+static void
+lpfc_nvmet_wqfull_flush(struct lpfc_hba *phba, struct lpfc_queue *wq,
+   struct lpfc_nvmet_rcv_ctx *ctxp)
+{
+   struct lpfc_sli_ring *pring;
+   struct lpfc_io

[PATCH v3 10/19] lpfc: Fix soft lockup in lpfc worker thread during LIP testing

2018-01-30 Thread James Smart
During link bounce testing in a point-to-point topology, the
host may enter a soft lockup on the lpfc_worker thread:
Call Trace:
 lpfc_work_done+0x1f3/0x1390 [lpfc]
 lpfc_do_work+0x16f/0x180 [lpfc]
 kthread+0xc7/0xe0
 ret_from_fork+0x3f/0x70

The driver was simultaneously setting a combination of flags
that caused lpfc_do_work()to effectively spin between slow path
work and new event data, causing the lockup.

Ensure in the typical wq completions, that new event data flags
are set if the slow path flag is running. The slow path will
eventually reschedule the wq handling.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/lpfc/lpfc_hbadisc.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index b159a5c4e388..9265906d956e 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -696,8 +696,9 @@ lpfc_work_done(struct lpfc_hba *phba)
  phba->hba_flag & HBA_SP_QUEUE_EVT)) {
if (pring->flag & LPFC_STOP_IOCB_EVENT) {
pring->flag |= LPFC_DEFERRED_RING_EVENT;
-   /* Set the lpfc data pending flag */
-   set_bit(LPFC_DATA_READY, &phba->data_flags);
+   /* Preserve legacy behavior. */
+   if (!(phba->hba_flag & HBA_SP_QUEUE_EVT))
+   set_bit(LPFC_DATA_READY, &phba->data_flags);
} else {
if (phba->link_state >= LPFC_LINK_UP ||
phba->link_flag & LS_MDS_LOOPBACK) {
-- 
2.13.1



[PATCH v3 06/19] lpfc: Fix PRLI handling when topology type changes

2018-01-30 Thread James Smart
The lpfc driver does not discover a target when the topology
changes from switched-fabric to direct-connect. The target
rejects the PRLI from the initiator in direct-connect as the
driver is using the old S_ID from the switched topology.

The driver was inappropriately clearing the VP bit to register the
VPI, which is what is associated with the S_ID.

Fix by leaving the VP bit set (it was set earlier) and as the VFI
is being re-registered, set the UPDT bit.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/lpfc/lpfc_mbox.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 81fb92967b11..c32d4a323db2 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -2170,10 +2170,8 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport 
*vport, dma_addr_t phys)
/* Only FC supports upd bit */
if ((phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC) &&
(vport->fc_flag & FC_VFI_REGISTERED) &&
-   (!phba->fc_topology_changed)) {
-   bf_set(lpfc_reg_vfi_vp, reg_vfi, 0);
+   (!phba->fc_topology_changed))
bf_set(lpfc_reg_vfi_upd, reg_vfi, 1);
-   }
 
bf_set(lpfc_reg_vfi_bbcr, reg_vfi, 0);
bf_set(lpfc_reg_vfi_bbscn, reg_vfi, 0);
-- 
2.13.1



Re: [PATCH 01/13] lpfc: Rework lpfc to allow different sli4 cq and eq handlers

2018-02-06 Thread James Smart

On 2/6/2018 4:26 PM, Martin K. Petersen wrote:


James,

I was on the verge of applying this as well but saw that you intended a
re-spin. Found a few typos while poring over these patches:


Prepare the code for new hardwre by creating a sli4-based callout


hardware


table that can be set based on if_type.




ok - I'll correct what's been pointed out and repost. Thanks

-- james



[PATCH v2 07/13] lpfc: Add if_type=6 support for cycling valid bits

2018-02-06 Thread James Smart
Traditional SLI4 required the driver to clear Valid bits on
EQEs and CQEs after consuming them.

The new if_type=6 hardware will cycle the value for what is
valid on each queue itteration. The driver no longer has to
touch the valid bits. This also means all the cpu cache
dirtying and perhaps flush/refill's done by the hardware
in accessing the EQ/CQ elements is eliminated.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_hw4.h  | 18 --
 drivers/scsi/lpfc/lpfc_init.c | 11 +++
 drivers/scsi/lpfc/lpfc_sli.c  | 77 +++
 drivers/scsi/lpfc/lpfc_sli4.h |  3 ++
 4 files changed, 92 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 0c33510fe75c..dba724e1f5ee 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -1040,6 +1040,9 @@ struct eq_context {
 #define lpfc_eq_context_valid_SHIFT29
 #define lpfc_eq_context_valid_MASK 0x0001
 #define lpfc_eq_context_valid_WORD word0
+#define lpfc_eq_context_autovalid_SHIFT 28
+#define lpfc_eq_context_autovalid_MASK  0x0001
+#define lpfc_eq_context_autovalid_WORD  word0
uint32_t word1;
 #define lpfc_eq_context_count_SHIFT26
 #define lpfc_eq_context_count_MASK 0x0003
@@ -1173,6 +1176,9 @@ struct cq_context {
 #define LPFC_CQ_CNT_5120x1
 #define LPFC_CQ_CNT_1024   0x2
 #define LPFC_CQ_CNT_WORD7  0x3
+#define lpfc_cq_context_autovalid_SHIFT 15
+#define lpfc_cq_context_autovalid_MASK  0x0001
+#define lpfc_cq_context_autovalid_WORD  word0
uint32_t word1;
 #define lpfc_cq_eq_id_SHIFT22  /* Version 0 Only */
 #define lpfc_cq_eq_id_MASK 0x00FF
@@ -1231,9 +1237,9 @@ struct lpfc_mbx_cq_create_set {
 #define lpfc_mbx_cq_create_set_cqe_size_SHIFT  25
 #define lpfc_mbx_cq_create_set_cqe_size_MASK   0x0003
 #define lpfc_mbx_cq_create_set_cqe_size_WORD   word1
-#define lpfc_mbx_cq_create_set_auto_SHIFT  15
-#define lpfc_mbx_cq_create_set_auto_MASK   0x001
-#define lpfc_mbx_cq_create_set_auto_WORD   word1
+#define lpfc_mbx_cq_create_set_autovalid_SHIFT 15
+#define lpfc_mbx_cq_create_set_autovalid_MASK  0x001
+#define lpfc_mbx_cq_create_set_autovalid_WORD  word1
 #define lpfc_mbx_cq_create_set_nodelay_SHIFT   14
 #define lpfc_mbx_cq_create_set_nodelay_MASK0x0001
 #define lpfc_mbx_cq_create_set_nodelay_WORDword1
@@ -3288,6 +3294,9 @@ struct lpfc_sli4_parameters {
 #define cfg_sli_hint_2_MASK0x001f
 #define cfg_sli_hint_2_WORDword1
uint32_t word2;
+#define cfg_eqav_SHIFT 31
+#define cfg_eqav_MASK  0x0001
+#define cfg_eqav_WORD  word2
uint32_t word3;
uint32_t word4;
 #define cfg_cqv_SHIFT  14
@@ -3296,6 +3305,9 @@ struct lpfc_sli4_parameters {
 #define cfg_cqpsize_SHIFT  16
 #define cfg_cqpsize_MASK   0x00ff
 #define cfg_cqpsize_WORD   word4
+#define cfg_cqav_SHIFT 31
+#define cfg_cqav_MASK  0x0001
+#define cfg_cqav_WORD  word4
uint32_t word5;
uint32_t word6;
 #define cfg_mqv_SHIFT  14
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index c1d7436cca4a..65057e33b8b7 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -8060,6 +8060,7 @@ lpfc_alloc_nvme_wq_cq(struct lpfc_hba *phba, int wqidx)
wqidx);
return 1;
}
+   qdesc->qe_valid = 1;
phba->sli4_hba.nvme_cq[wqidx] = qdesc;
 
qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE,
@@ -8097,6 +8098,7 @@ lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx)
"0499 Failed allocate fast-path FCP CQ (%d)\n", wqidx);
return 1;
}
+   qdesc->qe_valid = 1;
phba->sli4_hba.fcp_cq[wqidx] = qdesc;
 
/* Create Fast Path FCP WQs */
@@ -8290,6 +8292,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
"0497 Failed allocate EQ (%d)\n", idx);
goto out_error;
}
+   qdesc->qe_valid = 1;
phba->sli4_hba.hba_eq[idx] = qdesc;
}
 
@@ -8315,6 +8318,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
"CQ Set (%d)\n", idx);
goto out_error;
}
+   qdesc->qe_valid = 1;
phba->sli4_hba.nvmet_cqset[idx] = qdesc;
}
}
@@ -8332,6 +8336,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)

[PATCH v2 10/13] lpfc: Fix nvme embedded io length on new hardware

2018-02-06 Thread James Smart
Newer hardware more strictly enforces buffer lenghts, causing an
mis-set value to be identified. Older hardware won't catch it.
The difference is benign on old hardware.

Set the right embedded buffer length for nvme ios.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_nvme.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 5a1a6e24a27f..c75958daf799 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -655,7 +655,7 @@ lpfc_nvme_adj_fcp_sgls(struct lpfc_vport *vport,
 
/* Word 0-2 - NVME CMND IU (embedded payload) */
wqe->generic.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_IMMED;
-   wqe->generic.bde.tus.f.bdeSize = 60;
+   wqe->generic.bde.tus.f.bdeSize = 56;
wqe->generic.bde.addrHigh = 0;
wqe->generic.bde.addrLow =  64;  /* Word 16 */
 
-- 
2.13.1



[PATCH v2 01/13] lpfc: Rework lpfc to allow different sli4 cq and eq handlers

2018-02-06 Thread James Smart
Up until now, an SLI-4 device had no variance in the way it handled
its EQs and CQs. With newer hardware, there are now differences in
doorbells and some differences in how entries are valid.

Prepare the code for new hardware by creating a sli4-based callout
table that can be set based on if_type.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_init.c |  7 +
 drivers/scsi/lpfc/lpfc_sli.c  | 63 ++-
 drivers/scsi/lpfc/lpfc_sli4.h |  5 
 3 files changed, 44 insertions(+), 31 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 465d890220d5..e24dca2b3f2f 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -9540,6 +9540,13 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba)
}
}
 
+   /* Set up the EQ/CQ register handeling functions now */
+   if (if_type <= LPFC_SLI_INTF_IF_TYPE_2) {
+   phba->sli4_hba.sli4_eq_clr_intr = lpfc_sli4_eq_clr_intr;
+   phba->sli4_hba.sli4_eq_release = lpfc_sli4_eq_release;
+   phba->sli4_hba.sli4_cq_release = lpfc_sli4_cq_release;
+   }
+
return 0;
 
 out_iounmap_all:
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index e97d080e9f65..f91caae6489a 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -299,7 +299,7 @@ lpfc_sli4_eq_get(struct lpfc_queue *q)
  * @q: The Event Queue to disable interrupts
  *
  **/
-static inline void
+inline void
 lpfc_sli4_eq_clr_intr(struct lpfc_queue *q)
 {
struct lpfc_register doorbell;
@@ -5302,41 +5302,42 @@ static void
 lpfc_sli4_arm_cqeq_intr(struct lpfc_hba *phba)
 {
int qidx;
+   struct lpfc_sli4_hba *sli4_hba = &phba->sli4_hba;
 
-   lpfc_sli4_cq_release(phba->sli4_hba.mbx_cq, LPFC_QUEUE_REARM);
-   lpfc_sli4_cq_release(phba->sli4_hba.els_cq, LPFC_QUEUE_REARM);
-   if (phba->sli4_hba.nvmels_cq)
-   lpfc_sli4_cq_release(phba->sli4_hba.nvmels_cq,
+   sli4_hba->sli4_cq_release(sli4_hba->mbx_cq, LPFC_QUEUE_REARM);
+   sli4_hba->sli4_cq_release(sli4_hba->els_cq, LPFC_QUEUE_REARM);
+   if (sli4_hba->nvmels_cq)
+   sli4_hba->sli4_cq_release(sli4_hba->nvmels_cq,
LPFC_QUEUE_REARM);
 
-   if (phba->sli4_hba.fcp_cq)
+   if (sli4_hba->fcp_cq)
for (qidx = 0; qidx < phba->cfg_fcp_io_channel; qidx++)
-   lpfc_sli4_cq_release(phba->sli4_hba.fcp_cq[qidx],
+   sli4_hba->sli4_cq_release(sli4_hba->fcp_cq[qidx],
LPFC_QUEUE_REARM);
 
-   if (phba->sli4_hba.nvme_cq)
+   if (sli4_hba->nvme_cq)
for (qidx = 0; qidx < phba->cfg_nvme_io_channel; qidx++)
-   lpfc_sli4_cq_release(phba->sli4_hba.nvme_cq[qidx],
+   sli4_hba->sli4_cq_release(sli4_hba->nvme_cq[qidx],
LPFC_QUEUE_REARM);
 
if (phba->cfg_fof)
-   lpfc_sli4_cq_release(phba->sli4_hba.oas_cq, LPFC_QUEUE_REARM);
+   sli4_hba->sli4_cq_release(sli4_hba->oas_cq, LPFC_QUEUE_REARM);
 
-   if (phba->sli4_hba.hba_eq)
+   if (sli4_hba->hba_eq)
for (qidx = 0; qidx < phba->io_channel_irqs; qidx++)
-   lpfc_sli4_eq_release(phba->sli4_hba.hba_eq[qidx],
-   LPFC_QUEUE_REARM);
+   sli4_hba->sli4_eq_release(sli4_hba->hba_eq[qidx],
+   LPFC_QUEUE_REARM);
 
if (phba->nvmet_support) {
for (qidx = 0; qidx < phba->cfg_nvmet_mrq; qidx++) {
-   lpfc_sli4_cq_release(
-   phba->sli4_hba.nvmet_cqset[qidx],
+   sli4_hba->sli4_cq_release(
+   sli4_hba->nvmet_cqset[qidx],
LPFC_QUEUE_REARM);
}
}
 
if (phba->cfg_fof)
-   lpfc_sli4_eq_release(phba->sli4_hba.fof_eq, LPFC_QUEUE_REARM);
+   sli4_hba->sli4_eq_release(sli4_hba->fof_eq, LPFC_QUEUE_REARM);
 }
 
 /**
@@ -7270,7 +7271,7 @@ lpfc_sli4_mbox_completions_pending(struct lpfc_hba *phba)
 bool
 lpfc_sli4_process_missed_mbox_completions(struct lpfc_hba *phba)
 {
-
+   struct lpfc_sli4_hba *sli4_hba = &phba->sli4_hba;
uint32_t eqidx;
struct lpfc_queue *fpeq = NULL;
struct lpfc_eqe *eqe;
@@ -7281,11 +7282,11 @@ lpfc_sli4_process_missed_mbox_completions(struct 
lpfc_hba *phba)
 
/* Find the eq associated with the mcq */
 
-   if (phba->sli4_hba.hba_eq)
+

[PATCH v2 13/13] lpfc: Update 12.0.0.0 modified files for 2018 Copyright

2018-02-06 Thread James Smart
Updated Copyright in files updated 12.0.0.0

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_bsg.c | 2 +-
 drivers/scsi/lpfc/lpfc_ct.c  | 2 +-
 drivers/scsi/lpfc/lpfc_debugfs.c | 2 +-
 drivers/scsi/lpfc/lpfc_debugfs.h | 2 +-
 drivers/scsi/lpfc/lpfc_hw.h  | 2 +-
 drivers/scsi/lpfc/lpfc_ids.h | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index 8b33b652226b..0f174ca80f67 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2009-2015 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 03a7e13a049d..ebe8ac1b88e7 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 308303d501cf..fb0dc2aeed91 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2007-2015 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
index 12fbf498a7ce..f32eaeb2225a 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.h
+++ b/drivers/scsi/lpfc/lpfc_debugfs.h
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2007-2011 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index cf83322cd4fe..08a3f1520159 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_ids.h b/drivers/scsi/lpfc/lpfc_ids.h
index 329c8d28869c..07ee34017d88 100644
--- a/drivers/scsi/lpfc/lpfc_ids.h
+++ b/drivers/scsi/lpfc/lpfc_ids.h
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
-- 
2.13.1



[PATCH v2 05/13] lpfc: Add PCI Ids for if_type=6 hardware

2018-02-06 Thread James Smart
Add PCI ids for the new G7 adapter

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_hw.h  | 1 +
 drivers/scsi/lpfc/lpfc_ids.h | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index bdc1f184f67a..d07d2fcbea34 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -1580,6 +1580,7 @@ struct lpfc_fdmi_reg_portattr {
 #define PCI_DEVICE_ID_LANCER_FCOE   0xe260
 #define PCI_DEVICE_ID_LANCER_FCOE_VF 0xe268
 #define PCI_DEVICE_ID_LANCER_G6_FC  0xe300
+#define PCI_DEVICE_ID_LANCER_G7_FC  0xf400
 #define PCI_DEVICE_ID_SAT_SMB   0xf011
 #define PCI_DEVICE_ID_SAT_MID   0xf015
 #define PCI_DEVICE_ID_RFLY  0xf095
diff --git a/drivers/scsi/lpfc/lpfc_ids.h b/drivers/scsi/lpfc/lpfc_ids.h
index 0ba3733eb36d..329c8d28869c 100644
--- a/drivers/scsi/lpfc/lpfc_ids.h
+++ b/drivers/scsi/lpfc/lpfc_ids.h
@@ -116,6 +116,8 @@ const struct pci_device_id lpfc_id_table[] = {
PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_G6_FC,
PCI_ANY_ID, PCI_ANY_ID, },
+   {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_G7_FC,
+   PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK,
PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK_VF,
-- 
2.13.1



[PATCH v2 00/13] lpfc new hardware patches for 12.0.0.0

2018-02-06 Thread James Smart
This patch set adds support for Broadcom's new G7 product that
supports G4G FC.

The patches were cut against the Martin's 4.16/scsi-queue tree.

The patches are dependent (layered on top of) the lpfc 11.4.0.7
patchset that was recently posted. See:
  https://www.spinics.net/lists/linux-scsi/msg116956.html

v2:
 Address comments:
   patch 1, 2, 4, 7 - patch description typos
   patch 6 - typo on 256GBit speed define


James Smart (13):
  lpfc: Rework lpfc to allow different sli4 cq and eq handlers
  lpfc: Rework sli4 doorbell infrastructure
  lpfc: Add SLI-4 if_type=6 support to the code base
  lpfc: Add push-to-adapter support to sli4
  lpfc: Add PCI Ids for if_type=6 hardware
  lpfc: Add 64G link speed support
  lpfc: Add if_type=6 support for cycling valid bits
  lpfc: Enable fw download on if_type=6 devices
  lpfc: Add embedded data pointers for enhanced performance
  lpfc: Fix nvme embedded io length on new hardware
  lpfc: Work around NVME cmd iu SGL type
  lpfc: update driver version to 12.0.0.0
  lpfc: Update 12.0.0.0 modified files for 2018 Copyright

 drivers/scsi/lpfc/lpfc.h |  20 +-
 drivers/scsi/lpfc/lpfc_attr.c|  85 +--
 drivers/scsi/lpfc/lpfc_bsg.c |   6 +-
 drivers/scsi/lpfc/lpfc_ct.c  |   7 +-
 drivers/scsi/lpfc/lpfc_debugfs.c |  22 +-
 drivers/scsi/lpfc/lpfc_debugfs.h |  13 +-
 drivers/scsi/lpfc/lpfc_els.c |   5 +
 drivers/scsi/lpfc/lpfc_hbadisc.c |   1 +
 drivers/scsi/lpfc/lpfc_hw.h  |  15 +-
 drivers/scsi/lpfc/lpfc_hw4.h | 115 -
 drivers/scsi/lpfc/lpfc_ids.h |   4 +-
 drivers/scsi/lpfc/lpfc_init.c| 245 +++---
 drivers/scsi/lpfc/lpfc_mbox.c|   4 +
 drivers/scsi/lpfc/lpfc_nvme.c|  69 +++--
 drivers/scsi/lpfc/lpfc_nvmet.c   |  24 ++
 drivers/scsi/lpfc/lpfc_scsi.c|   8 +-
 drivers/scsi/lpfc/lpfc_sli.c | 535 +--
 drivers/scsi/lpfc/lpfc_sli4.h|  30 ++-
 drivers/scsi/lpfc/lpfc_version.h |   2 +-
 19 files changed, 960 insertions(+), 250 deletions(-)

-- 
2.13.1



[PATCH v2 06/13] lpfc: Add 64G link speed support

2018-02-06 Thread James Smart
The G7 adapter supports 64G link speeds. Add support to the driver.

In addition, a small cleanup to replace the odd bitmap logic with
a switch case.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 

---
v2:
  address review comment of typo in define name. Define wasn't used
  anywhere yet.
---
 drivers/scsi/lpfc/lpfc.h | 14 +++--
 drivers/scsi/lpfc/lpfc_attr.c| 61 
 drivers/scsi/lpfc/lpfc_ct.c  |  5 
 drivers/scsi/lpfc/lpfc_els.c |  5 
 drivers/scsi/lpfc/lpfc_hbadisc.c |  1 +
 drivers/scsi/lpfc/lpfc_hw.h  | 12 
 drivers/scsi/lpfc/lpfc_hw4.h |  3 ++
 drivers/scsi/lpfc/lpfc_init.c| 17 +--
 drivers/scsi/lpfc/lpfc_mbox.c|  4 +++
 9 files changed, 92 insertions(+), 30 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 86ffb9756e65..7aad4a717f13 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -544,16 +544,10 @@ struct unsol_rcv_ct_ctx {
 #define LPFC_USER_LINK_SPEED_10G   10  /* 10 Gigabaud */
 #define LPFC_USER_LINK_SPEED_16G   16  /* 16 Gigabaud */
 #define LPFC_USER_LINK_SPEED_32G   32  /* 32 Gigabaud */
-#define LPFC_USER_LINK_SPEED_MAX   LPFC_USER_LINK_SPEED_32G
-#define LPFC_USER_LINK_SPEED_BITMAP  ((1ULL << LPFC_USER_LINK_SPEED_32G) | \
-(1 << LPFC_USER_LINK_SPEED_16G) | \
-(1 << LPFC_USER_LINK_SPEED_10G) | \
-(1 << LPFC_USER_LINK_SPEED_8G) | \
-(1 << LPFC_USER_LINK_SPEED_4G) | \
-(1 << LPFC_USER_LINK_SPEED_2G) | \
-(1 << LPFC_USER_LINK_SPEED_1G) | \
-(1 << LPFC_USER_LINK_SPEED_AUTO))
-#define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16, 32"
+#define LPFC_USER_LINK_SPEED_64G   64  /* 64 Gigabaud */
+#define LPFC_USER_LINK_SPEED_MAX   LPFC_USER_LINK_SPEED_64G
+
+#define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16, 32, 64"
 
 enum nemb_type {
nemb_mse = 1,
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 705c42e724c2..ec080de4e7a7 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -4126,23 +4126,32 @@ lpfc_link_speed_store(struct device *dev, struct 
device_attribute *attr,
((val == LPFC_USER_LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) ||
((val == LPFC_USER_LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)) ||
((val == LPFC_USER_LINK_SPEED_16G) && !(phba->lmt & LMT_16Gb)) ||
-   ((val == LPFC_USER_LINK_SPEED_32G) && !(phba->lmt & LMT_32Gb))) {
+   ((val == LPFC_USER_LINK_SPEED_32G) && !(phba->lmt & LMT_32Gb)) ||
+   ((val == LPFC_USER_LINK_SPEED_64G) && !(phba->lmt & LMT_64Gb))) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"2879 lpfc_link_speed attribute cannot be set "
"to %d. Speed is not supported by this port.\n",
val);
return -EINVAL;
}
-   if (val == LPFC_USER_LINK_SPEED_16G &&
-phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
+   if (val >= LPFC_USER_LINK_SPEED_16G &&
+   phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3112 lpfc_link_speed attribute cannot be set "
"to %d. Speed is not supported in loop mode.\n",
val);
return -EINVAL;
}
-   if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) &&
-   (LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) {
+
+   switch (val) {
+   case LPFC_USER_LINK_SPEED_AUTO:
+   case LPFC_USER_LINK_SPEED_1G:
+   case LPFC_USER_LINK_SPEED_2G:
+   case LPFC_USER_LINK_SPEED_4G:
+   case LPFC_USER_LINK_SPEED_8G:
+   case LPFC_USER_LINK_SPEED_16G:
+   case LPFC_USER_LINK_SPEED_32G:
+   case LPFC_USER_LINK_SPEED_64G:
prev_val = phba->cfg_link_speed;
phba->cfg_link_speed = val;
if (nolip)
@@ -4152,13 +4161,17 @@ lpfc_link_speed_store(struct device *dev, struct 
device_attribute *attr,
if (err) {
phba->cfg_link_speed = prev_val;
return -EINVAL;
-   } else
-   return strlen(buf);
+   }
+   return strlen(buf);
+   default:
+   break;
}
+
lpfc_printf_log(phba, KERN_E

[PATCH v2 02/13] lpfc: Rework sli4 doorbell infrastructure

2018-02-06 Thread James Smart
Up until now, all SLI-4 devices had the same doorbells at the same
bar locations. With newer hardware, there are now independent EQ and
CQ doorbells and the bar locations differ.

Prepare the code for new hardware by separating the eq/cq doorbell into
separate components. The components can be set based on if_type.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_debugfs.c | 20 ++--
 drivers/scsi/lpfc/lpfc_debugfs.h | 11 ++-
 drivers/scsi/lpfc/lpfc_init.c|  9 ++---
 drivers/scsi/lpfc/lpfc_sli.c |  8 
 drivers/scsi/lpfc/lpfc_sli4.h|  3 ++-
 5 files changed, 32 insertions(+), 19 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 17ea3bb04266..308303d501cf 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -3944,10 +3944,15 @@ lpfc_idiag_drbacc_read_reg(struct lpfc_hba *phba, char 
*pbuffer,
return 0;
 
switch (drbregid) {
-   case LPFC_DRB_EQCQ:
-   len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
-   "EQCQ-DRB-REG: 0x%08x\n",
-   readl(phba->sli4_hba.EQCQDBregaddr));
+   case LPFC_DRB_EQ:
+   len += snprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE-len,
+   "EQ-DRB-REG: 0x%08x\n",
+   readl(phba->sli4_hba.EQDBregaddr));
+   break;
+   case LPFC_DRB_CQ:
+   len += snprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE - len,
+   "CQ-DRB-REG: 0x%08x\n",
+   readl(phba->sli4_hba.CQDBregaddr));
break;
case LPFC_DRB_MQ:
len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
@@ -4086,8 +4091,11 @@ lpfc_idiag_drbacc_write(struct file *file, const char 
__user *buf,
idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
switch (drb_reg_id) {
-   case LPFC_DRB_EQCQ:
-   drb_reg = phba->sli4_hba.EQCQDBregaddr;
+   case LPFC_DRB_EQ:
+   drb_reg = phba->sli4_hba.EQDBregaddr;
+   break;
+   case LPFC_DRB_CQ:
+   drb_reg = phba->sli4_hba.CQDBregaddr;
break;
case LPFC_DRB_MQ:
drb_reg = phba->sli4_hba.MQDBregaddr;
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
index c4edd87bfc65..12fbf498a7ce 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.h
+++ b/drivers/scsi/lpfc/lpfc_debugfs.h
@@ -126,12 +126,13 @@
 #define LPFC_DRB_ACC_WR_CMD_ARG 2
 #define LPFC_DRB_ACC_BUF_SIZE 256
 
-#define LPFC_DRB_EQCQ 1
-#define LPFC_DRB_MQ   2
-#define LPFC_DRB_WQ   3
-#define LPFC_DRB_RQ   4
+#define LPFC_DRB_EQ   1
+#define LPFC_DRB_CQ   2
+#define LPFC_DRB_MQ   3
+#define LPFC_DRB_WQ   4
+#define LPFC_DRB_RQ   5
 
-#define LPFC_DRB_MAX  4
+#define LPFC_DRB_MAX  5
 
 #define IDIAG_DRBACC_REGID_INDX 0
 #define IDIAG_DRBACC_VALUE_INDX 1
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index e24dca2b3f2f..b2cf8eb99008 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -7430,8 +7430,9 @@ lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba, 
uint32_t if_type)
phba->sli4_hba.WQDBregaddr =
phba->sli4_hba.conf_regs_memmap_p +
LPFC_ULP0_WQ_DOORBELL;
-   phba->sli4_hba.EQCQDBregaddr =
+   phba->sli4_hba.CQDBregaddr =
phba->sli4_hba.conf_regs_memmap_p + LPFC_EQCQ_DOORBELL;
+   phba->sli4_hba.EQDBregaddr = phba->sli4_hba.CQDBregaddr;
phba->sli4_hba.MQDBregaddr =
phba->sli4_hba.conf_regs_memmap_p + LPFC_MQ_DOORBELL;
phba->sli4_hba.BMBXregaddr =
@@ -7488,8 +7489,10 @@ lpfc_sli4_bar2_register_memmap(struct lpfc_hba *phba, 
uint32_t vf)
phba->sli4_hba.WQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
vf * LPFC_VFR_PAGE_SIZE +
LPFC_ULP0_WQ_DOORBELL);
-   phba->sli4_hba.EQCQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
-   vf * LPFC_VFR_PAGE_SIZE + LPFC_EQCQ_DOORBELL);
+   phba->sli4_hba.CQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
+   vf * LPFC_VFR_PAGE_SIZE +
+   LPFC_EQCQ_DOORBELL);
+   phba->sli4_hba.EQDBregaddr = phba->sli4_hba.CQDBregaddr;
phba->sli4_hba.MQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
vf * LPFC_VFR_PAGE

[PATCH v2 03/13] lpfc: Add SLI-4 if_type=6 support to the code base

2018-02-06 Thread James Smart
New hardware supports a SLI-4 interface, but with a new if_type
variant of 6.

If_type=6 has a different PCI BAR map, separate EQ/CQ doorbells,
and some changes in doorbell formats.

Add the changes for the if_type into headers, adapter initialization
and control flows. Add new eq and cq handlers.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_bsg.c  |   4 +-
 drivers/scsi/lpfc/lpfc_hw4.h  |  54 ++-
 drivers/scsi/lpfc/lpfc_init.c | 120 +++---
 drivers/scsi/lpfc/lpfc_sli.c  | 120 --
 drivers/scsi/lpfc/lpfc_sli4.h |   3 ++
 5 files changed, 275 insertions(+), 26 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index d89816222b23..8b33b652226b 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -3867,7 +3867,7 @@ lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, 
struct bsg_job *job,
"ext_buf_cnt:%d\n", ext_buf_cnt);
} else {
/* sanity check on interface type for support */
-   if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+   if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
LPFC_SLI_INTF_IF_TYPE_2) {
rc = -ENODEV;
goto job_error;
@@ -4053,7 +4053,7 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, 
struct bsg_job *job,
"ext_buf_cnt:%d\n", ext_buf_cnt);
} else {
/* sanity check on interface type for support */
-   if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+   if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
LPFC_SLI_INTF_IF_TYPE_2)
return -ENODEV;
/* nemb_tp == nemb_hbd */
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 8685d26e6929..93fd9fd10a0f 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -84,6 +84,7 @@ struct lpfc_sli_intf {
 #define LPFC_SLI_INTF_IF_TYPE_00
 #define LPFC_SLI_INTF_IF_TYPE_11
 #define LPFC_SLI_INTF_IF_TYPE_22
+#define LPFC_SLI_INTF_IF_TYPE_66
 #define lpfc_sli_intf_sli_family_SHIFT 8
 #define lpfc_sli_intf_sli_family_MASK  0x000F
 #define lpfc_sli_intf_sli_family_WORD  word0
@@ -731,11 +732,13 @@ struct lpfc_register {
  * register sets depending on the UCNA Port's reported if_type
  * value.  For UCNA ports running SLI4 and if_type 0, they reside in
  * BAR4.  For UCNA ports running SLI4 and if_type 2, they reside in
- * BAR0.  The offsets are the same so the driver must account for
- * any base address difference.
+ * BAR0.  For FC ports running SLI4 and if_type 6, they reside in
+ * BAR2. The offsets and base address are different,  so the driver
+ * has to compute the register addresses accordingly
  */
 #define LPFC_ULP0_RQ_DOORBELL  0x00A0
 #define LPFC_ULP1_RQ_DOORBELL  0x00C0
+#define LPFC_IF6_RQ_DOORBELL   0x0080
 #define lpfc_rq_db_list_fm_num_posted_SHIFT24
 #define lpfc_rq_db_list_fm_num_posted_MASK 0x00FF
 #define lpfc_rq_db_list_fm_num_posted_WORD word0
@@ -770,6 +773,20 @@ struct lpfc_register {
 #define lpfc_wq_db_ring_fm_id_MASK  0x
 #define lpfc_wq_db_ring_fm_id_WORD  word0
 
+#define LPFC_IF6_WQ_DOORBELL   0x0040
+#define lpfc_if6_wq_db_list_fm_num_posted_SHIFT24
+#define lpfc_if6_wq_db_list_fm_num_posted_MASK 0x00FF
+#define lpfc_if6_wq_db_list_fm_num_posted_WORD word0
+#define lpfc_if6_wq_db_list_fm_dpp_SHIFT   23
+#define lpfc_if6_wq_db_list_fm_dpp_MASK0x0001
+#define lpfc_if6_wq_db_list_fm_dpp_WORDword0
+#define lpfc_if6_wq_db_list_fm_dpp_id_SHIFT16
+#define lpfc_if6_wq_db_list_fm_dpp_id_MASK 0x001F
+#define lpfc_if6_wq_db_list_fm_dpp_id_WORD word0
+#define lpfc_if6_wq_db_list_fm_id_SHIFT0
+#define lpfc_if6_wq_db_list_fm_id_MASK 0x
+#define lpfc_if6_wq_db_list_fm_id_WORD word0
+
 #define LPFC_EQCQ_DOORBELL 0x0120
 #define lpfc_eqcq_doorbell_se_SHIFT31
 #define lpfc_eqcq_doorbell_se_MASK 0x0001
@@ -805,6 +822,38 @@ struct lpfc_register {
 #define LPFC_CQID_HI_FIELD_SHIFT   10
 #define LPFC_EQID_HI_FIELD_SHIFT   9
 
+#define LPFC_IF6_CQ_DOORBELL   0x00C0
+#define lpfc_if6_cq_doorbell_se_SHIFT  31
+#define lpfc_if6_cq_doorbell_se_MASK   0x0001
+#define lpfc_if6_cq_doorbell_se_WORD   word0
+#define LPFC_IF6_CQ_SOLICIT_ENABLE_OFF 0
+#define LPFC_IF6_CQ_SOLICIT_ENABLE_ON  1
+#define lpfc_if6_cq_doorbell_arm_SHIFT 29
+#de

[PATCH v2 04/13] lpfc: Add push-to-adapter support to sli4

2018-02-06 Thread James Smart
New if_type=6 adapters support an additional BAR that provides
apertures to allow direct WQE to adapter push support - termed
Direct Packet Push (DPP). WQ creation differs slightly to ask for
a WQ to be DPP-ized. When submitting a WQE to a DPP WQ, it is
submitted to the host memory for the WQ normally, but is also
written by the host cpu directly to a BAR aperture.  Write buffer
coalescing in hardware is (hopefully) turned on, enabling single
pci write operation support. The doorbell is thing rung to indicate
the WQE is available and was pushed to the aperture.

This patch:
- Updates the WQ Create commands for the DPP options
- Adds the bar mapping for if_type=6 DPP bar
- Adds the WQE pushing to the DDP aperture received from WQ create
- Adds a new module parameter to disable DPP operation if desired.
  Default is enabled.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc.h  |   3 +-
 drivers/scsi/lpfc/lpfc_attr.c |  10 ++
 drivers/scsi/lpfc/lpfc_hw4.h  |  31 ++
 drivers/scsi/lpfc/lpfc_init.c |  18 
 drivers/scsi/lpfc/lpfc_sli.c  | 234 +++---
 drivers/scsi/lpfc/lpfc_sli4.h |  16 ++-
 6 files changed, 225 insertions(+), 87 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 9698b9635058..86ffb9756e65 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -840,7 +840,8 @@ struct lpfc_hba {
uint32_t cfg_enable_SmartSAN;
uint32_t cfg_enable_mds_diags;
uint32_t cfg_enable_fc4_type;
-   uint32_t cfg_enable_bbcr;   /*Enable BB Credit Recovery*/
+   uint32_t cfg_enable_bbcr;   /* Enable BB Credit Recovery */
+   uint32_t cfg_enable_dpp;/* Enable Direct Packet Push */
uint32_t cfg_xri_split;
 #define LPFC_ENABLE_FCP  1
 #define LPFC_ENABLE_NVME 2
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 70bd25666243..705c42e724c2 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -5204,6 +5204,14 @@ LPFC_ATTR_R(enable_mds_diags, 0, 0, 1, "Enable MDS 
Diagnostics");
  */
 LPFC_BBCR_ATTR_RW(enable_bbcr, 1, 0, 1, "Enable BBC Recovery");
 
+/*
+ * lpfc_enable_dpp: Enable DPP on G7
+ *   0  = DPP on G7 disabled
+ *   1  = DPP on G7 enabled (default)
+ * Value range is [0,1]. Default value is 1.
+ */
+LPFC_ATTR_RW(enable_dpp, 1, 0, 1, "Enable Direct Packet Push");
+
 struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_nvme_info,
&dev_attr_bg_info,
@@ -5312,6 +5320,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_lpfc_xlane_supported,
&dev_attr_lpfc_enable_mds_diags,
&dev_attr_lpfc_enable_bbcr,
+   &dev_attr_lpfc_enable_dpp,
NULL,
 };
 
@@ -6324,6 +6333,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
lpfc_fcp_io_channel_init(phba, lpfc_fcp_io_channel);
lpfc_nvme_io_channel_init(phba, lpfc_nvme_io_channel);
lpfc_enable_bbcr_init(phba, lpfc_enable_bbcr);
+   lpfc_enable_dpp_init(phba, lpfc_enable_dpp);
 
if (phba->sli_rev != LPFC_SLI_REV4) {
/* NVME only supported on SLI4 */
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 93fd9fd10a0f..60ccff6fa8b0 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -1372,6 +1372,15 @@ struct lpfc_mbx_wq_create {
 #define lpfc_mbx_wq_create_page_size_MASK  0x00FF
 #define lpfc_mbx_wq_create_page_size_WORD  word1
 #define LPFC_WQ_PAGE_SIZE_4096 0x1
+#define lpfc_mbx_wq_create_dpp_req_SHIFT   15
+#define lpfc_mbx_wq_create_dpp_req_MASK0x0001
+#define lpfc_mbx_wq_create_dpp_req_WORDword1
+#define lpfc_mbx_wq_create_doe_SHIFT   14
+#define lpfc_mbx_wq_create_doe_MASK0x0001
+#define lpfc_mbx_wq_create_doe_WORDword1
+#define lpfc_mbx_wq_create_toe_SHIFT   13
+#define lpfc_mbx_wq_create_toe_MASK0x0001
+#define lpfc_mbx_wq_create_toe_WORDword1
 #define lpfc_mbx_wq_create_wqe_size_SHIFT  8
 #define lpfc_mbx_wq_create_wqe_size_MASK   0x000F
 #define lpfc_mbx_wq_create_wqe_size_WORD   word1
@@ -1400,6 +1409,28 @@ struct lpfc_mbx_wq_create {
 #define lpfc_mbx_wq_create_db_format_MASK  0x
 #define lpfc_mbx_wq_create_db_format_WORD  word2
} response;
+   struct {
+   uint32_t word0;
+#define lpfc_mbx_wq_create_dpp_rsp_SHIFT   31
+#define lpfc_mbx_wq_create_dpp_rsp_MASK0x0001
+#define lpfc_mbx_wq_create_dpp_rsp_WORDword0
+#define lpfc_mbx_wq_create_v1_q_id_SHIFT   0
+#define lpfc_mbx_wq_create_v1_q_id_MASK0x
+#define lpfc_mbx_wq_create_v1_q_id_WORDword0
+   uint32_t word1;
+#define lpfc_mbx_wq_create_v1_bar_s

[PATCH v2 08/13] lpfc: Enable fw download on if_type=6 devices

2018-02-06 Thread James Smart
Current code is very explicit in what it allows to be downloaded.
The driver checking prevented G7 firmware download. The driver
checking is unnecessary as the device will validate what it receives.

Revise the firmware download interface checking.
Added a little debug support in case there is still a failure.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_hw4.h  |  5 +
 drivers/scsi/lpfc/lpfc_init.c | 44 ++-
 drivers/scsi/lpfc/lpfc_sli.c  |  1 +
 3 files changed, 33 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index dba724e1f5ee..be8227dfa086 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -2241,6 +2241,7 @@ struct lpfc_mbx_redisc_fcf_tbl {
  * command.
  */
 #define ADD_STATUS_OPERATION_ALREADY_ACTIVE0x67
+#define ADD_STATUS_FW_NOT_SUPPORTED0xEB
 
 struct lpfc_mbx_sli4_config {
struct mbox_header header;
@@ -4603,10 +4604,6 @@ union lpfc_wqe128 {
struct gen_req64_wqe gen_req;
 };
 
-#define LPFC_GROUP_OJECT_MAGIC_G5  0xfeaa0001
-#define LPFC_GROUP_OJECT_MAGIC_G6  0xfeaa0003
-#define LPFC_FILE_TYPE_GROUP   0xf7
-#define LPFC_FILE_ID_GROUP 0xa2
 struct lpfc_grp_hdr {
uint32_t size;
uint32_t magic_number;
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 65057e33b8b7..35eb622f58f3 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -11294,6 +11294,27 @@ lpfc_sli4_get_iocb_cnt(struct lpfc_hba *phba)
 }
 
 
+static void
+lpfc_log_write_firmware_error(struct lpfc_hba *phba, uint32_t offset,
+   uint32_t magic_number, uint32_t ftype, uint32_t fid, uint32_t fsize,
+   const struct firmware *fw)
+{
+   if (offset == ADD_STATUS_FW_NOT_SUPPORTED)
+   lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+   "3030 This firmware version is not supported on "
+   "this HBA model. Device:%x Magic:%x Type:%x "
+   "ID:%x Size %d %zd\n",
+   phba->pcidev->device, magic_number, ftype, fid,
+   fsize, fw->size);
+   else
+   lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+   "3022 FW Download failed. Device:%x Magic:%x Type:%x "
+   "ID:%x Size %d %zd\n",
+   phba->pcidev->device, magic_number, ftype, fid,
+   fsize, fw->size);
+}
+
+
 /**
  * lpfc_write_firmware - attempt to write a firmware image to the port
  * @fw: pointer to firmware image returned from request_firmware.
@@ -11321,20 +11342,10 @@ lpfc_write_firmware(const struct firmware *fw, void 
*context)
 
magic_number = be32_to_cpu(image->magic_number);
ftype = bf_get_be32(lpfc_grp_hdr_file_type, image);
-   fid = bf_get_be32(lpfc_grp_hdr_id, image),
+   fid = bf_get_be32(lpfc_grp_hdr_id, image);
fsize = be32_to_cpu(image->size);
 
INIT_LIST_HEAD(&dma_buffer_list);
-   if ((magic_number != LPFC_GROUP_OJECT_MAGIC_G5 &&
-magic_number != LPFC_GROUP_OJECT_MAGIC_G6) ||
-   ftype != LPFC_FILE_TYPE_GROUP || fsize != fw->size) {
-   lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-   "3022 Invalid FW image found. "
-   "Magic:%x Type:%x ID:%x Size %d %zd\n",
-   magic_number, ftype, fid, fsize, fw->size);
-   rc = -EINVAL;
-   goto release_out;
-   }
lpfc_decode_firmware_rev(phba, fwrev, 1);
if (strncmp(fwrev, image->revision, strnlen(image->revision, 16))) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -11375,11 +11386,18 @@ lpfc_write_firmware(const struct firmware *fw, void 
*context)
}
rc = lpfc_wr_object(phba, &dma_buffer_list,
(fw->size - offset), &offset);
-   if (rc)
+   if (rc) {
+   lpfc_log_write_firmware_error(phba, offset,
+   magic_number, ftype, fid, fsize, fw);
goto release_out;
+   }
}
rc = offset;
-   }
+   } else
+   lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+   "3029 Skipped Firmware update, Current "
+   "Version:%s New Version:%s\n",
+   fwrev, image->revision);
 
 release_out:
list_for_each_entry_safe(dmabuf, next, &dma_buffer_list, list) {
diff --git a/dr

[PATCH v2 12/13] lpfc: update driver version to 12.0.0.0

2018-02-06 Thread James Smart
Update the driver version to 12.0.0.0

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_version.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index 4adbf07880a2..b1ae62a44aae 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -20,7 +20,7 @@
  * included with this package. *
  ***/
 
-#define LPFC_DRIVER_VERSION "11.4.0.7"
+#define LPFC_DRIVER_VERSION "12.0.0.0"
 #define LPFC_DRIVER_NAME   "lpfc"
 
 /* Used for SLI 2/3 */
-- 
2.13.1



[PATCH v2 11/13] lpfc: Work around NVME cmd iu SGL type

2018-02-06 Thread James Smart
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 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc.h  |  1 +
 drivers/scsi/lpfc/lpfc_attr.c | 14 
 drivers/scsi/lpfc/lpfc_hw4.h  |  1 +
 drivers/scsi/lpfc/lpfc_init.c |  4 ++--
 drivers/scsi/lpfc/lpfc_nvme.c | 51 ++-
 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 {
uint32_t cfg_fcp_io_channel;
uint32_t cfg_suppress_rsp;
uint32_t cfg_nvme_oas;
+   uint32_t cfg_nvme_embed_cmd;
uint32_t cfg_nvme_io_channel;
uint32_t cfg_nvmet_mrq;
uint32_t cfg_enable_nvmet;
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index ec080de4e7a7..86d241642d03 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -5059,6 +5059,18 @@ LPFC_ATTR_RW(nvme_oas, 0, 0, 1,
 "Use OAS bit on NVME IOs");
 
 /*
+ * lpfc_nvme_embed_cmd: Use the oas bit when sending NVME/NVMET IOs
+ *
+ *  0  = Put NVME Command in SGL
+ *  1  = Embed NVME Command in WQE (unless G7)
+ *  2 =  Embed NVME Command in WQE (force)
+ *
+ * Value range is [0,2]. Default value is 1.
+ */
+LPFC_ATTR_RW(nvme_embed_cmd, 1, 0, 2,
+"Embed NVME Command in WQE");
+
+/*
  * lpfc_fcp_io_channel: Set the number of FCP IO channels the driver
  * will advertise it supports to the SCSI layer. This also will map to
  * the number of WQs the driver will create.
@@ -5299,6 +5311,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_lpfc_task_mgmt_tmo,
&dev_attr_lpfc_use_msi,
&dev_attr_lpfc_nvme_oas,
+   &dev_attr_lpfc_nvme_embed_cmd,
&dev_attr_lpfc_auto_imax,
&dev_attr_lpfc_fcp_imax,
&dev_attr_lpfc_fcp_cpu_map,
@@ -6323,6 +6336,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
lpfc_enable_SmartSAN_init(phba, lpfc_enable_SmartSAN);
lpfc_use_msi_init(phba, lpfc_use_msi);
lpfc_nvme_oas_init(phba, lpfc_nvme_oas);
+   lpfc_nvme_embed_cmd_init(phba, lpfc_nvme_embed_cmd);
lpfc_auto_imax_init(phba, lpfc_auto_imax);
lpfc_fcp_imax_init(phba, lpfc_fcp_imax);
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 {
 #define lpfc_mbx_rd_rev_vpd_MASK   0x0001
 #define lpfc_mbx_rd_rev_vpd_WORD   word1
uint32_t first_hw_rev;
+#define LPFC_G7_ASIC_1 0xd
uint32_t second_hw_rev;
uint32_t word4_rsvd;
uint32_t third_hw_rev;
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index f214b4ac3f9d..36b264da9e0f 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -10651,11 +10651,11 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, 
LPFC_MBOXQ_t *mboxq)
 
lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_NVME,
"6422 XIB %d: FCP %d %d "
-   "NVME %d %d %d\n",
+   "NVME %d %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);
+   phba->cfg_nvme_embed_cmd, 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) &&
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,
  

[PATCH v2 09/13] lpfc: Add embedded data pointers for enhanced performance

2018-02-06 Thread James Smart
The current driver isn't taking advantage of a performance hint whereby
the initial data buffer descriptor can be placed in the WQE as well as
the SGL.

Add the logic to detect support for the feature and to use it when
supported.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc.h   |  2 ++
 drivers/scsi/lpfc/lpfc_hw4.h   |  3 +++
 drivers/scsi/lpfc/lpfc_init.c  | 21 +
 drivers/scsi/lpfc/lpfc_nvme.c  | 18 ++
 drivers/scsi/lpfc/lpfc_nvmet.c | 24 
 drivers/scsi/lpfc/lpfc_scsi.c  |  8 ++--
 drivers/scsi/lpfc/lpfc_sli.c   | 25 +
 7 files changed, 95 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 7aad4a717f13..9136a59b1c5b 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -840,6 +840,8 @@ struct lpfc_hba {
 #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 */
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index be8227dfa086..ed5e870c58c3 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -4226,6 +4226,9 @@ struct wqe_common {
 #define wqe_irsp_SHIFT4
 #define wqe_irsp_MASK 0x0001
 #define wqe_irsp_WORD word11
+#define wqe_pbde_SHIFT5
+#define wqe_pbde_MASK 0x0001
+#define wqe_pbde_WORD word11
 #define wqe_sup_SHIFT 6
 #define wqe_sup_MASK  0x0001
 #define wqe_sup_WORD  word11
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 35eb622f58f3..f214b4ac3f9d 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -10605,6 +10605,19 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, 
LPFC_MBOXQ_t *mboxq)
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).
@@ -10636,6 +10649,14 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, 
LPFC_MBOXQ_t *mboxq)
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))
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 3a103d0895a2..5a1a6e24a27f 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -1170,6 +1170,7 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport,
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;
@@ -1237,7 +1238,24 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport,
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);

Re: [PATCH v2 06/13] lpfc: Add 64G link speed support

2018-02-07 Thread James Smart

On 2/7/2018 1:58 AM, Johannes Thumshirn wrote:

On Tue, Feb 06, 2018 at 06:28:44PM -0800, James Smart wrote:

lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-   "0469 lpfc_link_speed attribute cannot be set to %d, "
-   "allowed values are ["LPFC_LINK_SPEED_STRING"]\n", val);
+   "0469 lpfc_link_speed attribute cannot be set to %d, "
+   "allowed values are ["LPFC_LINK_SPEED_STRING"]\n", val);


lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0469 lpfc_link_speed attribute cannot be set to %d, "
"allowed values are [%s]\n",
val, LPFC_LINK_SPEED_STRING);

And possible have the whole quoted string on one line for easier grepping.
checkplatch.pl should've told you that.



Checkpatch didn't say anything interesting. We consistently have line 
spanning as the lines are fairly verbose. Not an easy way to avoid that.


Regardless, no big deal.

-- james


Re: [PATCH v2 04/13] lpfc: Add push-to-adapter support to sli4

2018-02-07 Thread James Smart

On 2/7/2018 2:27 AM, Johannes Thumshirn wrote:

On Wed, Feb 07, 2018 at 10:51:57AM +0100, Johannes Thumshirn wrote:

+   /* Enable combined writes for DPP aperture */
+   pg_addr = (unsigned long)(wq->dpp_regaddr) & PAGE_MASK;
+#ifdef CONFIG_X86
+   rc = set_memory_wc(pg_addr, 1);
+   if (rc) {
+   lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+   "3272 Cannot setup Combined "
+   "Write on WQ[%d] - disable 
DPP\n",
+   wq->queue_id);
+   phba->cfg_enable_dpp = 0;
+   }
+#else
+   phba->cfg_enable_dpp = 0;
+#endif
+   } else
+   wq->db_regaddr = phba->sli4_hba.WQDBregaddr;


I don't really like the set_memory_wc() call here. Neither do I like the ifdef
CONFIG_X86 special casing.

If you really need write combining, can't you at least use ioremap_wc()?


Coming back to this again (after talking to our ARM/POWER folks internally).
Is this really x86 specific here? I know there are servers with other 
architectures
using lpfcs out there.

I _think_ write combining should be possible on other architectures (that have
PCIe and aren't dead) as well.

The ioremap_wc() I suggested is probably wrong.

So can you please revisit this? I CCed Mark and Michael, maybe they can help
here.


yes - we really are looking for write combining. We were following the 
lead of a couple of other entities in the kernel and hadn't found the 
right combination for something other than X86. We figured we would come 
back and add the non-86 enablements later when we found the right options.


-- james




Re: [PATCH v2 04/13] lpfc: Add push-to-adapter support to sli4

2018-02-13 Thread James Smart

On 2/12/2018 9:59 PM, Michael Ellerman wrote:

Johannes Thumshirn  writes:


On Wed, Feb 07, 2018 at 10:51:57AM +0100, Johannes Thumshirn wrote:

+   /* Enable combined writes for DPP aperture */
+   pg_addr = (unsigned long)(wq->dpp_regaddr) & PAGE_MASK;
+#ifdef CONFIG_X86
+   rc = set_memory_wc(pg_addr, 1);
+   if (rc) {
+   lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+   "3272 Cannot setup Combined "
+   "Write on WQ[%d] - disable 
DPP\n",
+   wq->queue_id);
+   phba->cfg_enable_dpp = 0;
+   }
+#else
+   phba->cfg_enable_dpp = 0;
+#endif
+   } else
+   wq->db_regaddr = phba->sli4_hba.WQDBregaddr;


I don't really like the set_memory_wc() call here. Neither do I like the ifdef
CONFIG_X86 special casing.

If you really need write combining, can't you at least use ioremap_wc()?


Coming back to this again (after talking to our ARM/POWER folks internally).
Is this really x86 specific here? I know there are servers with other 
architectures
using lpfcs out there.

I _think_ write combining should be possible on other architectures (that have
PCIe and aren't dead) as well.

The ioremap_wc() I suggested is probably wrong.

So can you please revisit this? I CCed Mark and Michael, maybe they can help
here.


I'm not much of an I/O guy, but I do know that on powerpc we don't
implement set_memory_wc(). So if you're using that then you do need the
ifdef.

I couldn't easily find the rest of this thread, so I'm not sure if
ioremap_wc() is an option. We do implement that and on modern CPUs at
least it will give you something that's not just a plain uncached
mapping.


I went back and looked at things.  It does appear that we should be 
using ioremap_wc().  There's a pci routine that wrappers it, but as 
we're already are using the other routines in the wrapper, it's not very 
interesting.   Ioremap_wc seems to be supported pretty much anywhere, 
with platforms managing what it resolves to. Granted, some platforms 
may not do write combining but will relax the caching aspects (as 
Michael indicates).


The interesting thing is - when wc is truly on, we see a substantial 
difference. But in cases where wc isn't on and we perform the individual 
writes plus the flush before the doorbell write to synchronize things, 
it turns out it takes longer than if we don't use the feature. So, in 
cases where we don't have real wc, I'm going to turn it off. Based on 
what we've tested so far (includes ppc p8), we'll be leaving it enabled 
on X86 only.


-- james



[PATCH v3 00/13] lpfc new hardware patches for 12.0.0.0

2018-02-13 Thread James Smart
This patch set adds support for Broadcom's new G7 product that
supports G4G FC.

The patches were cut against the Martin's 4.17/scsi-queue tree.

v2:
 Address comments:
   patch 1, 2, 4, 7: patch description typos
   patch 6: typo on 256GBit speed define

v3:
 Add review tags
 Address comments:
   patch 4: parens, replace set_memory_wc by ioremap_wc
   patch 6: reformat strings
   patch 9: parens
   patch 13: patch title
 patch 5: add missing snippet for default id string
 patch 9, 11: log print condensed to line


James Smart (13):
  lpfc: Rework lpfc to allow different sli4 cq and eq handlers
  lpfc: Rework sli4 doorbell infrastructure
  lpfc: Add SLI-4 if_type=6 support to the code base
  lpfc: Add push-to-adapter support to sli4
  lpfc: Add PCI Ids for if_type=6 hardware
  lpfc: Add 64G link speed support
  lpfc: Add if_type=6 support for cycling valid bits
  lpfc: Enable fw download on if_type=6 devices
  lpfc: Add embedded data pointers for enhanced performance
  lpfc: Fix nvme embedded io length on new hardware
  lpfc: Work around NVME cmd iu SGL type
  lpfc: update driver version to 12.0.0.0
  lpfc: Change Copyright of 12.0.0.0 modified files to 2018

 drivers/scsi/lpfc/lpfc.h |  20 +-
 drivers/scsi/lpfc/lpfc_attr.c|  90 +--
 drivers/scsi/lpfc/lpfc_bsg.c |   6 +-
 drivers/scsi/lpfc/lpfc_ct.c  |   7 +-
 drivers/scsi/lpfc/lpfc_debugfs.c |  22 +-
 drivers/scsi/lpfc/lpfc_debugfs.h |  13 +-
 drivers/scsi/lpfc/lpfc_els.c |   5 +
 drivers/scsi/lpfc/lpfc_hbadisc.c |   1 +
 drivers/scsi/lpfc/lpfc_hw.h  |  15 +-
 drivers/scsi/lpfc/lpfc_hw4.h | 115 -
 drivers/scsi/lpfc/lpfc_ids.h |   4 +-
 drivers/scsi/lpfc/lpfc_init.c| 246 ---
 drivers/scsi/lpfc/lpfc_mbox.c|   4 +
 drivers/scsi/lpfc/lpfc_nvme.c|  69 --
 drivers/scsi/lpfc/lpfc_nvmet.c   |  24 ++
 drivers/scsi/lpfc/lpfc_scsi.c|   8 +-
 drivers/scsi/lpfc/lpfc_sli.c | 519 +--
 drivers/scsi/lpfc/lpfc_sli4.h|  30 ++-
 drivers/scsi/lpfc/lpfc_version.h |   2 +-
 19 files changed, 950 insertions(+), 250 deletions(-)

-- 
2.13.1



[PATCH v3 05/13] lpfc: Add PCI Ids for if_type=6 hardware

2018-02-13 Thread James Smart
Add PCI ids for the new G7 adapter

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 

---
v3:
  Add default adapter id string for G7 adapter
---
 drivers/scsi/lpfc/lpfc_hw.h   | 1 +
 drivers/scsi/lpfc/lpfc_ids.h  | 2 ++
 drivers/scsi/lpfc/lpfc_init.c | 3 +++
 3 files changed, 6 insertions(+)

diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index bdc1f184f67a..d07d2fcbea34 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -1580,6 +1580,7 @@ struct lpfc_fdmi_reg_portattr {
 #define PCI_DEVICE_ID_LANCER_FCOE   0xe260
 #define PCI_DEVICE_ID_LANCER_FCOE_VF 0xe268
 #define PCI_DEVICE_ID_LANCER_G6_FC  0xe300
+#define PCI_DEVICE_ID_LANCER_G7_FC  0xf400
 #define PCI_DEVICE_ID_SAT_SMB   0xf011
 #define PCI_DEVICE_ID_SAT_MID   0xf015
 #define PCI_DEVICE_ID_RFLY  0xf095
diff --git a/drivers/scsi/lpfc/lpfc_ids.h b/drivers/scsi/lpfc/lpfc_ids.h
index 0ba3733eb36d..329c8d28869c 100644
--- a/drivers/scsi/lpfc/lpfc_ids.h
+++ b/drivers/scsi/lpfc/lpfc_ids.h
@@ -116,6 +116,8 @@ const struct pci_device_id lpfc_id_table[] = {
PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_G6_FC,
PCI_ANY_ID, PCI_ANY_ID, },
+   {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_G7_FC,
+   PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK,
PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK_VF,
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 6db631ace750..4ae32a764f4b 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -2473,6 +2473,9 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t 
*mdp, uint8_t *descp)
case PCI_DEVICE_ID_LANCER_G6_FC:
m = (typeof(m)){"LPe32000", "PCIe", "Fibre Channel Adapter"};
break;
+   case PCI_DEVICE_ID_LANCER_G7_FC:
+   m = (typeof(m)){"LPe36000", "PCIe", "Fibre Channel Adapter"};
+   break;
case PCI_DEVICE_ID_SKYHAWK:
case PCI_DEVICE_ID_SKYHAWK_VF:
oneConnect = 1;
-- 
2.13.1



[PATCH v3 01/13] lpfc: Rework lpfc to allow different sli4 cq and eq handlers

2018-02-13 Thread James Smart
Up until now, an SLI-4 device had no variance in the way it handled
its EQs and CQs. With newer hardware, there are now differences in
doorbells and some differences in how entries are valid.

Prepare the code for new hardware by creating a sli4-based callout
table that can be set based on if_type.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Johannes Thumshirn 
---
 drivers/scsi/lpfc/lpfc_init.c |  7 +
 drivers/scsi/lpfc/lpfc_sli.c  | 63 ++-
 drivers/scsi/lpfc/lpfc_sli4.h |  5 
 3 files changed, 44 insertions(+), 31 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 465d890220d5..e24dca2b3f2f 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -9540,6 +9540,13 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba)
}
}
 
+   /* Set up the EQ/CQ register handeling functions now */
+   if (if_type <= LPFC_SLI_INTF_IF_TYPE_2) {
+   phba->sli4_hba.sli4_eq_clr_intr = lpfc_sli4_eq_clr_intr;
+   phba->sli4_hba.sli4_eq_release = lpfc_sli4_eq_release;
+   phba->sli4_hba.sli4_cq_release = lpfc_sli4_cq_release;
+   }
+
return 0;
 
 out_iounmap_all:
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index e97d080e9f65..f91caae6489a 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -299,7 +299,7 @@ lpfc_sli4_eq_get(struct lpfc_queue *q)
  * @q: The Event Queue to disable interrupts
  *
  **/
-static inline void
+inline void
 lpfc_sli4_eq_clr_intr(struct lpfc_queue *q)
 {
struct lpfc_register doorbell;
@@ -5302,41 +5302,42 @@ static void
 lpfc_sli4_arm_cqeq_intr(struct lpfc_hba *phba)
 {
int qidx;
+   struct lpfc_sli4_hba *sli4_hba = &phba->sli4_hba;
 
-   lpfc_sli4_cq_release(phba->sli4_hba.mbx_cq, LPFC_QUEUE_REARM);
-   lpfc_sli4_cq_release(phba->sli4_hba.els_cq, LPFC_QUEUE_REARM);
-   if (phba->sli4_hba.nvmels_cq)
-   lpfc_sli4_cq_release(phba->sli4_hba.nvmels_cq,
+   sli4_hba->sli4_cq_release(sli4_hba->mbx_cq, LPFC_QUEUE_REARM);
+   sli4_hba->sli4_cq_release(sli4_hba->els_cq, LPFC_QUEUE_REARM);
+   if (sli4_hba->nvmels_cq)
+   sli4_hba->sli4_cq_release(sli4_hba->nvmels_cq,
LPFC_QUEUE_REARM);
 
-   if (phba->sli4_hba.fcp_cq)
+   if (sli4_hba->fcp_cq)
for (qidx = 0; qidx < phba->cfg_fcp_io_channel; qidx++)
-   lpfc_sli4_cq_release(phba->sli4_hba.fcp_cq[qidx],
+   sli4_hba->sli4_cq_release(sli4_hba->fcp_cq[qidx],
LPFC_QUEUE_REARM);
 
-   if (phba->sli4_hba.nvme_cq)
+   if (sli4_hba->nvme_cq)
for (qidx = 0; qidx < phba->cfg_nvme_io_channel; qidx++)
-   lpfc_sli4_cq_release(phba->sli4_hba.nvme_cq[qidx],
+   sli4_hba->sli4_cq_release(sli4_hba->nvme_cq[qidx],
LPFC_QUEUE_REARM);
 
if (phba->cfg_fof)
-   lpfc_sli4_cq_release(phba->sli4_hba.oas_cq, LPFC_QUEUE_REARM);
+   sli4_hba->sli4_cq_release(sli4_hba->oas_cq, LPFC_QUEUE_REARM);
 
-   if (phba->sli4_hba.hba_eq)
+   if (sli4_hba->hba_eq)
for (qidx = 0; qidx < phba->io_channel_irqs; qidx++)
-   lpfc_sli4_eq_release(phba->sli4_hba.hba_eq[qidx],
-   LPFC_QUEUE_REARM);
+   sli4_hba->sli4_eq_release(sli4_hba->hba_eq[qidx],
+   LPFC_QUEUE_REARM);
 
if (phba->nvmet_support) {
for (qidx = 0; qidx < phba->cfg_nvmet_mrq; qidx++) {
-   lpfc_sli4_cq_release(
-   phba->sli4_hba.nvmet_cqset[qidx],
+   sli4_hba->sli4_cq_release(
+   sli4_hba->nvmet_cqset[qidx],
LPFC_QUEUE_REARM);
}
}
 
if (phba->cfg_fof)
-   lpfc_sli4_eq_release(phba->sli4_hba.fof_eq, LPFC_QUEUE_REARM);
+   sli4_hba->sli4_eq_release(sli4_hba->fof_eq, LPFC_QUEUE_REARM);
 }
 
 /**
@@ -7270,7 +7271,7 @@ lpfc_sli4_mbox_completions_pending(struct lpfc_hba *phba)
 bool
 lpfc_sli4_process_missed_mbox_completions(struct lpfc_hba *phba)
 {
-
+   struct lpfc_sli4_hba *sli4_hba = &phba->sli4_hba;
uint32_t eqidx;
struct lpfc_queue *fpeq = NULL;
struct lpfc_eqe *eqe;
@@ -7281,11 +7282,11 @@ lpfc_sli4_process_missed_mbox_completions(struct 
lpfc_hba *phba)
 
/* Find the eq associated with the mcq */
 
-   if (phba->sli4_hba.hba_eq)
+

[PATCH v3 02/13] lpfc: Rework sli4 doorbell infrastructure

2018-02-13 Thread James Smart
Up until now, all SLI-4 devices had the same doorbells at the same
bar locations. With newer hardware, there are now independent EQ and
CQ doorbells and the bar locations differ.

Prepare the code for new hardware by separating the eq/cq doorbell into
separate components. The components can be set based on if_type.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Johannes Thumshirn 
---
 drivers/scsi/lpfc/lpfc_debugfs.c | 20 ++--
 drivers/scsi/lpfc/lpfc_debugfs.h | 11 ++-
 drivers/scsi/lpfc/lpfc_init.c|  9 ++---
 drivers/scsi/lpfc/lpfc_sli.c |  8 
 drivers/scsi/lpfc/lpfc_sli4.h|  3 ++-
 5 files changed, 32 insertions(+), 19 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 17ea3bb04266..308303d501cf 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -3944,10 +3944,15 @@ lpfc_idiag_drbacc_read_reg(struct lpfc_hba *phba, char 
*pbuffer,
return 0;
 
switch (drbregid) {
-   case LPFC_DRB_EQCQ:
-   len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
-   "EQCQ-DRB-REG: 0x%08x\n",
-   readl(phba->sli4_hba.EQCQDBregaddr));
+   case LPFC_DRB_EQ:
+   len += snprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE-len,
+   "EQ-DRB-REG: 0x%08x\n",
+   readl(phba->sli4_hba.EQDBregaddr));
+   break;
+   case LPFC_DRB_CQ:
+   len += snprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE - len,
+   "CQ-DRB-REG: 0x%08x\n",
+   readl(phba->sli4_hba.CQDBregaddr));
break;
case LPFC_DRB_MQ:
len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
@@ -4086,8 +4091,11 @@ lpfc_idiag_drbacc_write(struct file *file, const char 
__user *buf,
idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
switch (drb_reg_id) {
-   case LPFC_DRB_EQCQ:
-   drb_reg = phba->sli4_hba.EQCQDBregaddr;
+   case LPFC_DRB_EQ:
+   drb_reg = phba->sli4_hba.EQDBregaddr;
+   break;
+   case LPFC_DRB_CQ:
+   drb_reg = phba->sli4_hba.CQDBregaddr;
break;
case LPFC_DRB_MQ:
drb_reg = phba->sli4_hba.MQDBregaddr;
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
index c4edd87bfc65..12fbf498a7ce 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.h
+++ b/drivers/scsi/lpfc/lpfc_debugfs.h
@@ -126,12 +126,13 @@
 #define LPFC_DRB_ACC_WR_CMD_ARG 2
 #define LPFC_DRB_ACC_BUF_SIZE 256
 
-#define LPFC_DRB_EQCQ 1
-#define LPFC_DRB_MQ   2
-#define LPFC_DRB_WQ   3
-#define LPFC_DRB_RQ   4
+#define LPFC_DRB_EQ   1
+#define LPFC_DRB_CQ   2
+#define LPFC_DRB_MQ   3
+#define LPFC_DRB_WQ   4
+#define LPFC_DRB_RQ   5
 
-#define LPFC_DRB_MAX  4
+#define LPFC_DRB_MAX  5
 
 #define IDIAG_DRBACC_REGID_INDX 0
 #define IDIAG_DRBACC_VALUE_INDX 1
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index e24dca2b3f2f..b2cf8eb99008 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -7430,8 +7430,9 @@ lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba, 
uint32_t if_type)
phba->sli4_hba.WQDBregaddr =
phba->sli4_hba.conf_regs_memmap_p +
LPFC_ULP0_WQ_DOORBELL;
-   phba->sli4_hba.EQCQDBregaddr =
+   phba->sli4_hba.CQDBregaddr =
phba->sli4_hba.conf_regs_memmap_p + LPFC_EQCQ_DOORBELL;
+   phba->sli4_hba.EQDBregaddr = phba->sli4_hba.CQDBregaddr;
phba->sli4_hba.MQDBregaddr =
phba->sli4_hba.conf_regs_memmap_p + LPFC_MQ_DOORBELL;
phba->sli4_hba.BMBXregaddr =
@@ -7488,8 +7489,10 @@ lpfc_sli4_bar2_register_memmap(struct lpfc_hba *phba, 
uint32_t vf)
phba->sli4_hba.WQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
vf * LPFC_VFR_PAGE_SIZE +
LPFC_ULP0_WQ_DOORBELL);
-   phba->sli4_hba.EQCQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
-   vf * LPFC_VFR_PAGE_SIZE + LPFC_EQCQ_DOORBELL);
+   phba->sli4_hba.CQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
+   vf * LPFC_VFR_PAGE_SIZE +
+   LPFC_EQCQ_DOORBELL);
+   phba->sli4_hba.EQDBregaddr = phba->sli4_hba.CQDBregaddr;
phba->sli4_hba.MQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +

[PATCH v3 08/13] lpfc: Enable fw download on if_type=6 devices

2018-02-13 Thread James Smart
Current code is very explicit in what it allows to be downloaded.
The driver checking prevented G7 firmware download. The driver
checking is unnecessary as the device will validate what it receives.

Revise the firmware download interface checking.
Added a little debug support in case there is still a failure.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Johannes Thumshirn 
---
 drivers/scsi/lpfc/lpfc_hw4.h  |  5 +
 drivers/scsi/lpfc/lpfc_init.c | 44 ++-
 drivers/scsi/lpfc/lpfc_sli.c  |  1 +
 3 files changed, 33 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index dba724e1f5ee..be8227dfa086 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -2241,6 +2241,7 @@ struct lpfc_mbx_redisc_fcf_tbl {
  * command.
  */
 #define ADD_STATUS_OPERATION_ALREADY_ACTIVE0x67
+#define ADD_STATUS_FW_NOT_SUPPORTED0xEB
 
 struct lpfc_mbx_sli4_config {
struct mbox_header header;
@@ -4603,10 +4604,6 @@ union lpfc_wqe128 {
struct gen_req64_wqe gen_req;
 };
 
-#define LPFC_GROUP_OJECT_MAGIC_G5  0xfeaa0001
-#define LPFC_GROUP_OJECT_MAGIC_G6  0xfeaa0003
-#define LPFC_FILE_TYPE_GROUP   0xf7
-#define LPFC_FILE_ID_GROUP 0xa2
 struct lpfc_grp_hdr {
uint32_t size;
uint32_t magic_number;
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index e7b0b83d4378..fc452ffa73bc 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -11296,6 +11296,27 @@ lpfc_sli4_get_iocb_cnt(struct lpfc_hba *phba)
 }
 
 
+static void
+lpfc_log_write_firmware_error(struct lpfc_hba *phba, uint32_t offset,
+   uint32_t magic_number, uint32_t ftype, uint32_t fid, uint32_t fsize,
+   const struct firmware *fw)
+{
+   if (offset == ADD_STATUS_FW_NOT_SUPPORTED)
+   lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+   "3030 This firmware version is not supported on "
+   "this HBA model. Device:%x Magic:%x Type:%x "
+   "ID:%x Size %d %zd\n",
+   phba->pcidev->device, magic_number, ftype, fid,
+   fsize, fw->size);
+   else
+   lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+   "3022 FW Download failed. Device:%x Magic:%x Type:%x "
+   "ID:%x Size %d %zd\n",
+   phba->pcidev->device, magic_number, ftype, fid,
+   fsize, fw->size);
+}
+
+
 /**
  * lpfc_write_firmware - attempt to write a firmware image to the port
  * @fw: pointer to firmware image returned from request_firmware.
@@ -11323,20 +11344,10 @@ lpfc_write_firmware(const struct firmware *fw, void 
*context)
 
magic_number = be32_to_cpu(image->magic_number);
ftype = bf_get_be32(lpfc_grp_hdr_file_type, image);
-   fid = bf_get_be32(lpfc_grp_hdr_id, image),
+   fid = bf_get_be32(lpfc_grp_hdr_id, image);
fsize = be32_to_cpu(image->size);
 
INIT_LIST_HEAD(&dma_buffer_list);
-   if ((magic_number != LPFC_GROUP_OJECT_MAGIC_G5 &&
-magic_number != LPFC_GROUP_OJECT_MAGIC_G6) ||
-   ftype != LPFC_FILE_TYPE_GROUP || fsize != fw->size) {
-   lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-   "3022 Invalid FW image found. "
-   "Magic:%x Type:%x ID:%x Size %d %zd\n",
-   magic_number, ftype, fid, fsize, fw->size);
-   rc = -EINVAL;
-   goto release_out;
-   }
lpfc_decode_firmware_rev(phba, fwrev, 1);
if (strncmp(fwrev, image->revision, strnlen(image->revision, 16))) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -11377,11 +11388,18 @@ lpfc_write_firmware(const struct firmware *fw, void 
*context)
}
rc = lpfc_wr_object(phba, &dma_buffer_list,
(fw->size - offset), &offset);
-   if (rc)
+   if (rc) {
+   lpfc_log_write_firmware_error(phba, offset,
+   magic_number, ftype, fid, fsize, fw);
goto release_out;
+   }
}
rc = offset;
-   }
+   } else
+   lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+   "3029 Skipped Firmware update, Current "
+   "Version:%s New Version:%s\n",
+   fwrev, image->revision);
 
 release_out:
list_for_each_entry_safe(dmabuf, next, &dma_b

[PATCH v3 12/13] lpfc: update driver version to 12.0.0.0

2018-02-13 Thread James Smart
Update the driver version to 12.0.0.0

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Johannes Thumshirn 
---
 drivers/scsi/lpfc/lpfc_version.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index 4adbf07880a2..b1ae62a44aae 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -20,7 +20,7 @@
  * included with this package. *
  ***/
 
-#define LPFC_DRIVER_VERSION "11.4.0.7"
+#define LPFC_DRIVER_VERSION "12.0.0.0"
 #define LPFC_DRIVER_NAME   "lpfc"
 
 /* Used for SLI 2/3 */
-- 
2.13.1



[PATCH v3 06/13] lpfc: Add 64G link speed support

2018-02-13 Thread James Smart
The G7 adapter supports 64G link speeds. Add support to the driver.

In addition, a small cleanup to replace the odd bitmap logic with
a switch case.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 

---
v2:
  address review comment of typo in define name. Define wasn't used
  anywhere yet.
v3:
  reformat printf_log 0469
---
 drivers/scsi/lpfc/lpfc.h | 14 +++--
 drivers/scsi/lpfc/lpfc_attr.c| 62 
 drivers/scsi/lpfc/lpfc_ct.c  |  5 
 drivers/scsi/lpfc/lpfc_els.c |  5 
 drivers/scsi/lpfc/lpfc_hbadisc.c |  1 +
 drivers/scsi/lpfc/lpfc_hw.h  | 12 
 drivers/scsi/lpfc/lpfc_hw4.h |  3 ++
 drivers/scsi/lpfc/lpfc_init.c| 17 +--
 drivers/scsi/lpfc/lpfc_mbox.c|  4 +++
 9 files changed, 93 insertions(+), 30 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 86ffb9756e65..7aad4a717f13 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -544,16 +544,10 @@ struct unsol_rcv_ct_ctx {
 #define LPFC_USER_LINK_SPEED_10G   10  /* 10 Gigabaud */
 #define LPFC_USER_LINK_SPEED_16G   16  /* 16 Gigabaud */
 #define LPFC_USER_LINK_SPEED_32G   32  /* 32 Gigabaud */
-#define LPFC_USER_LINK_SPEED_MAX   LPFC_USER_LINK_SPEED_32G
-#define LPFC_USER_LINK_SPEED_BITMAP  ((1ULL << LPFC_USER_LINK_SPEED_32G) | \
-(1 << LPFC_USER_LINK_SPEED_16G) | \
-(1 << LPFC_USER_LINK_SPEED_10G) | \
-(1 << LPFC_USER_LINK_SPEED_8G) | \
-(1 << LPFC_USER_LINK_SPEED_4G) | \
-(1 << LPFC_USER_LINK_SPEED_2G) | \
-(1 << LPFC_USER_LINK_SPEED_1G) | \
-(1 << LPFC_USER_LINK_SPEED_AUTO))
-#define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16, 32"
+#define LPFC_USER_LINK_SPEED_64G   64  /* 64 Gigabaud */
+#define LPFC_USER_LINK_SPEED_MAX   LPFC_USER_LINK_SPEED_64G
+
+#define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16, 32, 64"
 
 enum nemb_type {
nemb_mse = 1,
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index e90d5066f66b..bbed20a39b25 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -4115,23 +4115,32 @@ lpfc_link_speed_store(struct device *dev, struct 
device_attribute *attr,
((val == LPFC_USER_LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) ||
((val == LPFC_USER_LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)) ||
((val == LPFC_USER_LINK_SPEED_16G) && !(phba->lmt & LMT_16Gb)) ||
-   ((val == LPFC_USER_LINK_SPEED_32G) && !(phba->lmt & LMT_32Gb))) {
+   ((val == LPFC_USER_LINK_SPEED_32G) && !(phba->lmt & LMT_32Gb)) ||
+   ((val == LPFC_USER_LINK_SPEED_64G) && !(phba->lmt & LMT_64Gb))) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"2879 lpfc_link_speed attribute cannot be set "
"to %d. Speed is not supported by this port.\n",
val);
return -EINVAL;
}
-   if (val == LPFC_USER_LINK_SPEED_16G &&
-phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
+   if (val >= LPFC_USER_LINK_SPEED_16G &&
+   phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3112 lpfc_link_speed attribute cannot be set "
"to %d. Speed is not supported in loop mode.\n",
val);
return -EINVAL;
}
-   if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) &&
-   (LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) {
+
+   switch (val) {
+   case LPFC_USER_LINK_SPEED_AUTO:
+   case LPFC_USER_LINK_SPEED_1G:
+   case LPFC_USER_LINK_SPEED_2G:
+   case LPFC_USER_LINK_SPEED_4G:
+   case LPFC_USER_LINK_SPEED_8G:
+   case LPFC_USER_LINK_SPEED_16G:
+   case LPFC_USER_LINK_SPEED_32G:
+   case LPFC_USER_LINK_SPEED_64G:
prev_val = phba->cfg_link_speed;
phba->cfg_link_speed = val;
if (nolip)
@@ -4141,13 +4150,18 @@ lpfc_link_speed_store(struct device *dev, struct 
device_attribute *attr,
if (err) {
phba->cfg_link_speed = prev_val;
return -EINVAL;
-   } else
-   return strlen(buf);
+   }
+   return strlen(buf);
+   default:
+   break;
}
+

[PATCH v3 07/13] lpfc: Add if_type=6 support for cycling valid bits

2018-02-13 Thread James Smart
Traditional SLI4 required the driver to clear Valid bits on
EQEs and CQEs after consuming them.

The new if_type=6 hardware will cycle the value for what is
valid on each queue itteration. The driver no longer has to
touch the valid bits. This also means all the cpu cache
dirtying and perhaps flush/refill's done by the hardware
in accessing the EQ/CQ elements is eliminated.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Johannes Thumshirn 
---
 drivers/scsi/lpfc/lpfc_hw4.h  | 18 --
 drivers/scsi/lpfc/lpfc_init.c | 11 +++
 drivers/scsi/lpfc/lpfc_sli.c  | 77 +++
 drivers/scsi/lpfc/lpfc_sli4.h |  3 ++
 4 files changed, 92 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 0c33510fe75c..dba724e1f5ee 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -1040,6 +1040,9 @@ struct eq_context {
 #define lpfc_eq_context_valid_SHIFT29
 #define lpfc_eq_context_valid_MASK 0x0001
 #define lpfc_eq_context_valid_WORD word0
+#define lpfc_eq_context_autovalid_SHIFT 28
+#define lpfc_eq_context_autovalid_MASK  0x0001
+#define lpfc_eq_context_autovalid_WORD  word0
uint32_t word1;
 #define lpfc_eq_context_count_SHIFT26
 #define lpfc_eq_context_count_MASK 0x0003
@@ -1173,6 +1176,9 @@ struct cq_context {
 #define LPFC_CQ_CNT_5120x1
 #define LPFC_CQ_CNT_1024   0x2
 #define LPFC_CQ_CNT_WORD7  0x3
+#define lpfc_cq_context_autovalid_SHIFT 15
+#define lpfc_cq_context_autovalid_MASK  0x0001
+#define lpfc_cq_context_autovalid_WORD  word0
uint32_t word1;
 #define lpfc_cq_eq_id_SHIFT22  /* Version 0 Only */
 #define lpfc_cq_eq_id_MASK 0x00FF
@@ -1231,9 +1237,9 @@ struct lpfc_mbx_cq_create_set {
 #define lpfc_mbx_cq_create_set_cqe_size_SHIFT  25
 #define lpfc_mbx_cq_create_set_cqe_size_MASK   0x0003
 #define lpfc_mbx_cq_create_set_cqe_size_WORD   word1
-#define lpfc_mbx_cq_create_set_auto_SHIFT  15
-#define lpfc_mbx_cq_create_set_auto_MASK   0x001
-#define lpfc_mbx_cq_create_set_auto_WORD   word1
+#define lpfc_mbx_cq_create_set_autovalid_SHIFT 15
+#define lpfc_mbx_cq_create_set_autovalid_MASK  0x001
+#define lpfc_mbx_cq_create_set_autovalid_WORD  word1
 #define lpfc_mbx_cq_create_set_nodelay_SHIFT   14
 #define lpfc_mbx_cq_create_set_nodelay_MASK0x0001
 #define lpfc_mbx_cq_create_set_nodelay_WORDword1
@@ -3288,6 +3294,9 @@ struct lpfc_sli4_parameters {
 #define cfg_sli_hint_2_MASK0x001f
 #define cfg_sli_hint_2_WORDword1
uint32_t word2;
+#define cfg_eqav_SHIFT 31
+#define cfg_eqav_MASK  0x0001
+#define cfg_eqav_WORD  word2
uint32_t word3;
uint32_t word4;
 #define cfg_cqv_SHIFT  14
@@ -3296,6 +3305,9 @@ struct lpfc_sli4_parameters {
 #define cfg_cqpsize_SHIFT  16
 #define cfg_cqpsize_MASK   0x00ff
 #define cfg_cqpsize_WORD   word4
+#define cfg_cqav_SHIFT 31
+#define cfg_cqav_MASK  0x0001
+#define cfg_cqav_WORD  word4
uint32_t word5;
uint32_t word6;
 #define cfg_mqv_SHIFT  14
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 0666f91bbbe1..e7b0b83d4378 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -8063,6 +8063,7 @@ lpfc_alloc_nvme_wq_cq(struct lpfc_hba *phba, int wqidx)
wqidx);
return 1;
}
+   qdesc->qe_valid = 1;
phba->sli4_hba.nvme_cq[wqidx] = qdesc;
 
qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE,
@@ -8100,6 +8101,7 @@ lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx)
"0499 Failed allocate fast-path FCP CQ (%d)\n", wqidx);
return 1;
}
+   qdesc->qe_valid = 1;
phba->sli4_hba.fcp_cq[wqidx] = qdesc;
 
/* Create Fast Path FCP WQs */
@@ -8293,6 +8295,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
"0497 Failed allocate EQ (%d)\n", idx);
goto out_error;
}
+   qdesc->qe_valid = 1;
phba->sli4_hba.hba_eq[idx] = qdesc;
}
 
@@ -8318,6 +8321,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
"CQ Set (%d)\n", idx);
goto out_error;
}
+   qdesc->qe_valid = 1;
phba->sli4_hba.nvmet_cqset[idx] = qdesc;
}
}
@@ -8335,6 +8339,7 @@ lpfc_sli4_queue_create(s

[PATCH v3 13/13] lpfc: Change Copyright of 12.0.0.0 modified files to 2018

2018-02-13 Thread James Smart
Updated Copyright in files updated as part of 12.0.0.0

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Johannes Thumshirn 

---
v3:
  patch title
---
 drivers/scsi/lpfc/lpfc_bsg.c | 2 +-
 drivers/scsi/lpfc/lpfc_ct.c  | 2 +-
 drivers/scsi/lpfc/lpfc_debugfs.c | 2 +-
 drivers/scsi/lpfc/lpfc_debugfs.h | 2 +-
 drivers/scsi/lpfc/lpfc_hw.h  | 2 +-
 drivers/scsi/lpfc/lpfc_ids.h | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index 8b33b652226b..0f174ca80f67 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2009-2015 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 03a7e13a049d..ebe8ac1b88e7 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 308303d501cf..fb0dc2aeed91 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2007-2015 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
index 12fbf498a7ce..f32eaeb2225a 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.h
+++ b/drivers/scsi/lpfc/lpfc_debugfs.h
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2007-2011 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index cf83322cd4fe..08a3f1520159 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
diff --git a/drivers/scsi/lpfc/lpfc_ids.h b/drivers/scsi/lpfc/lpfc_ids.h
index 329c8d28869c..07ee34017d88 100644
--- a/drivers/scsi/lpfc/lpfc_ids.h
+++ b/drivers/scsi/lpfc/lpfc_ids.h
@@ -1,7 +1,7 @@
 /***
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
- * Copyright (C) 2017 Broadcom. All Rights Reserved. The term  *
+ * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.   *
  * EMULEX and SLI

[PATCH v3 04/13] lpfc: Add push-to-adapter support to sli4

2018-02-13 Thread James Smart
New if_type=6 adapters support an additional BAR that provides
apertures to allow direct WQE to adapter push support - termed
Direct Packet Push (DPP). WQ creation differs slightly to ask for
a WQ to be DPP-ized. When submitting a WQE to a DPP WQ, it is
submitted to the host memory for the WQ normally, but is also
written by the host cpu directly to a BAR aperture.  Write buffer
coalescing in hardware is (hopefully) turned on, enabling single
pci write operation support. The doorbell is thing rung to indicate
the WQE is available and was pushed to the aperture.

This patch:
- Updates the WQ Create commands for the DPP options
- Adds the bar mapping for if_type=6 DPP bar
- Adds the WQE pushing to the DDP aperture received from WQ create
- Adds a new module parameter to disable DPP operation if desired.
  Default is enabled.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 

---
v3:
  remove unnecessary parens
  use ioremap_wc() instead of set_memory_wc(). the wc property
is now set by default on the BAR. if direct push is disabled,
the BAR won't be used so it won't matter what is set on it.
Track cases where the ioremap_wc() may not succeed, leaving
bar pointer NULL. In this case, disable direct push.
  As some platforms will honor ioremap_wc() but not truly enable
wc, change default for direct push so enabled only on X86.
---
 drivers/scsi/lpfc/lpfc.h  |   3 +-
 drivers/scsi/lpfc/lpfc_attr.c |  14 +++
 drivers/scsi/lpfc/lpfc_hw4.h  |  31 ++
 drivers/scsi/lpfc/lpfc_init.c |  17 
 drivers/scsi/lpfc/lpfc_sli.c  | 218 ++
 drivers/scsi/lpfc/lpfc_sli4.h |  16 +++-
 6 files changed, 212 insertions(+), 87 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 9698b9635058..86ffb9756e65 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -840,7 +840,8 @@ struct lpfc_hba {
uint32_t cfg_enable_SmartSAN;
uint32_t cfg_enable_mds_diags;
uint32_t cfg_enable_fc4_type;
-   uint32_t cfg_enable_bbcr;   /*Enable BB Credit Recovery*/
+   uint32_t cfg_enable_bbcr;   /* Enable BB Credit Recovery */
+   uint32_t cfg_enable_dpp;/* Enable Direct Packet Push */
uint32_t cfg_xri_split;
 #define LPFC_ENABLE_FCP  1
 #define LPFC_ENABLE_NVME 2
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 7be4bdef4d42..e90d5066f66b 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -5186,6 +5186,18 @@ LPFC_ATTR_R(enable_mds_diags, 0, 0, 1, "Enable MDS 
Diagnostics");
  */
 LPFC_BBCR_ATTR_RW(enable_bbcr, 1, 0, 1, "Enable BBC Recovery");
 
+/*
+ * lpfc_enable_dpp: Enable DPP on G7
+ *   0  = DPP on G7 disabled
+ *   1  = DPP on G7 enabled (default)
+ * Value range is [0,1]. Default value is 1 on X86, 0 on other architectures.
+ */
+#ifdef CONFIG_X86
+LPFC_ATTR_RW(enable_dpp, 1, 0, 1, "Enable Direct Packet Push");
+#else
+LPFC_ATTR_RW(enable_dpp, 0, 0, 1, "Enable Direct Packet Push");
+#endif
+
 struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_nvme_info,
&dev_attr_bg_info,
@@ -5294,6 +5306,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_lpfc_xlane_supported,
&dev_attr_lpfc_enable_mds_diags,
&dev_attr_lpfc_enable_bbcr,
+   &dev_attr_lpfc_enable_dpp,
NULL,
 };
 
@@ -6306,6 +6319,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
lpfc_fcp_io_channel_init(phba, lpfc_fcp_io_channel);
lpfc_nvme_io_channel_init(phba, lpfc_nvme_io_channel);
lpfc_enable_bbcr_init(phba, lpfc_enable_bbcr);
+   lpfc_enable_dpp_init(phba, lpfc_enable_dpp);
 
if (phba->sli_rev != LPFC_SLI_REV4) {
/* NVME only supported on SLI4 */
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 93fd9fd10a0f..60ccff6fa8b0 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -1372,6 +1372,15 @@ struct lpfc_mbx_wq_create {
 #define lpfc_mbx_wq_create_page_size_MASK  0x00FF
 #define lpfc_mbx_wq_create_page_size_WORD  word1
 #define LPFC_WQ_PAGE_SIZE_4096 0x1
+#define lpfc_mbx_wq_create_dpp_req_SHIFT   15
+#define lpfc_mbx_wq_create_dpp_req_MASK0x0001
+#define lpfc_mbx_wq_create_dpp_req_WORDword1
+#define lpfc_mbx_wq_create_doe_SHIFT   14
+#define lpfc_mbx_wq_create_doe_MASK0x0001
+#define lpfc_mbx_wq_create_doe_WORDword1
+#define lpfc_mbx_wq_create_toe_SHIFT   13
+#define lpfc_mbx_wq_create_toe_MASK0x0001
+#define lpfc_mbx_wq_create_toe_WORDword1
 #define lpfc_mbx_wq_create_wqe_size_SHIFT  8
 #define lpfc_mbx_wq_create_wqe_size_MASK   0x000F
 #define lpfc_mbx_wq_create_wqe_size_WORD   word1
@@ -1400,6 +1409,28 @@ struct lpfc_mbx_wq

[PATCH v3 09/13] lpfc: Add embedded data pointers for enhanced performance

2018-02-13 Thread James Smart
The current driver isn't taking advantage of a performance hint whereby
the initial data buffer descriptor can be placed in the WQE as well as
the SGL.

Add the logic to detect support for the feature and to use it when
supported.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 

---
v3:
  remove unneeded parens
  combined 6422 msg on 1 line
---
 drivers/scsi/lpfc/lpfc.h   |  2 ++
 drivers/scsi/lpfc/lpfc_hw4.h   |  3 +++
 drivers/scsi/lpfc/lpfc_init.c  | 20 
 drivers/scsi/lpfc/lpfc_nvme.c  | 18 ++
 drivers/scsi/lpfc/lpfc_nvmet.c | 24 
 drivers/scsi/lpfc/lpfc_scsi.c  |  8 ++--
 drivers/scsi/lpfc/lpfc_sli.c   | 25 +
 7 files changed, 94 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 7aad4a717f13..9136a59b1c5b 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -840,6 +840,8 @@ struct lpfc_hba {
 #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 */
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index be8227dfa086..ed5e870c58c3 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -4226,6 +4226,9 @@ struct wqe_common {
 #define wqe_irsp_SHIFT4
 #define wqe_irsp_MASK 0x0001
 #define wqe_irsp_WORD word11
+#define wqe_pbde_SHIFT5
+#define wqe_pbde_MASK 0x0001
+#define wqe_pbde_WORD word11
 #define wqe_sup_SHIFT 6
 #define wqe_sup_MASK  0x0001
 #define wqe_sup_WORD  word11
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index fc452ffa73bc..f8af3adee21a 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -10607,6 +10607,19 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, 
LPFC_MBOXQ_t *mboxq)
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).
@@ -10638,6 +10651,13 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, 
LPFC_MBOXQ_t *mboxq)
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))
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 3a103d0895a2..5a1a6e24a27f 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -1170,6 +1170,7 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport,
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;
@@ -1237,7 +1238,24 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport,
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->

[PATCH v3 10/13] lpfc: Fix nvme embedded io length on new hardware

2018-02-13 Thread James Smart
Newer hardware more strictly enforces buffer lenghts, causing an
mis-set value to be identified. Older hardware won't catch it.
The difference is benign on old hardware.

Set the right embedded buffer length for nvme ios.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Johannes Thumshirn 
---
 drivers/scsi/lpfc/lpfc_nvme.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 5a1a6e24a27f..c75958daf799 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -655,7 +655,7 @@ lpfc_nvme_adj_fcp_sgls(struct lpfc_vport *vport,
 
/* Word 0-2 - NVME CMND IU (embedded payload) */
wqe->generic.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_IMMED;
-   wqe->generic.bde.tus.f.bdeSize = 60;
+   wqe->generic.bde.tus.f.bdeSize = 56;
wqe->generic.bde.addrHigh = 0;
wqe->generic.bde.addrLow =  64;  /* Word 16 */
 
-- 
2.13.1



[PATCH v3 03/13] lpfc: Add SLI-4 if_type=6 support to the code base

2018-02-13 Thread James Smart
New hardware supports a SLI-4 interface, but with a new if_type
variant of 6.

If_type=6 has a different PCI BAR map, separate EQ/CQ doorbells,
and some changes in doorbell formats.

Add the changes for the if_type into headers, adapter initialization
and control flows. Add new eq and cq handlers.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Johannes Thumshirn 
---
 drivers/scsi/lpfc/lpfc_bsg.c  |   4 +-
 drivers/scsi/lpfc/lpfc_hw4.h  |  54 ++-
 drivers/scsi/lpfc/lpfc_init.c | 120 +++---
 drivers/scsi/lpfc/lpfc_sli.c  | 120 --
 drivers/scsi/lpfc/lpfc_sli4.h |   3 ++
 5 files changed, 275 insertions(+), 26 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index d89816222b23..8b33b652226b 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -3867,7 +3867,7 @@ lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, 
struct bsg_job *job,
"ext_buf_cnt:%d\n", ext_buf_cnt);
} else {
/* sanity check on interface type for support */
-   if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+   if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
LPFC_SLI_INTF_IF_TYPE_2) {
rc = -ENODEV;
goto job_error;
@@ -4053,7 +4053,7 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, 
struct bsg_job *job,
"ext_buf_cnt:%d\n", ext_buf_cnt);
} else {
/* sanity check on interface type for support */
-   if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+   if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
LPFC_SLI_INTF_IF_TYPE_2)
return -ENODEV;
/* nemb_tp == nemb_hbd */
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 8685d26e6929..93fd9fd10a0f 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -84,6 +84,7 @@ struct lpfc_sli_intf {
 #define LPFC_SLI_INTF_IF_TYPE_00
 #define LPFC_SLI_INTF_IF_TYPE_11
 #define LPFC_SLI_INTF_IF_TYPE_22
+#define LPFC_SLI_INTF_IF_TYPE_66
 #define lpfc_sli_intf_sli_family_SHIFT 8
 #define lpfc_sli_intf_sli_family_MASK  0x000F
 #define lpfc_sli_intf_sli_family_WORD  word0
@@ -731,11 +732,13 @@ struct lpfc_register {
  * register sets depending on the UCNA Port's reported if_type
  * value.  For UCNA ports running SLI4 and if_type 0, they reside in
  * BAR4.  For UCNA ports running SLI4 and if_type 2, they reside in
- * BAR0.  The offsets are the same so the driver must account for
- * any base address difference.
+ * BAR0.  For FC ports running SLI4 and if_type 6, they reside in
+ * BAR2. The offsets and base address are different,  so the driver
+ * has to compute the register addresses accordingly
  */
 #define LPFC_ULP0_RQ_DOORBELL  0x00A0
 #define LPFC_ULP1_RQ_DOORBELL  0x00C0
+#define LPFC_IF6_RQ_DOORBELL   0x0080
 #define lpfc_rq_db_list_fm_num_posted_SHIFT24
 #define lpfc_rq_db_list_fm_num_posted_MASK 0x00FF
 #define lpfc_rq_db_list_fm_num_posted_WORD word0
@@ -770,6 +773,20 @@ struct lpfc_register {
 #define lpfc_wq_db_ring_fm_id_MASK  0x
 #define lpfc_wq_db_ring_fm_id_WORD  word0
 
+#define LPFC_IF6_WQ_DOORBELL   0x0040
+#define lpfc_if6_wq_db_list_fm_num_posted_SHIFT24
+#define lpfc_if6_wq_db_list_fm_num_posted_MASK 0x00FF
+#define lpfc_if6_wq_db_list_fm_num_posted_WORD word0
+#define lpfc_if6_wq_db_list_fm_dpp_SHIFT   23
+#define lpfc_if6_wq_db_list_fm_dpp_MASK0x0001
+#define lpfc_if6_wq_db_list_fm_dpp_WORDword0
+#define lpfc_if6_wq_db_list_fm_dpp_id_SHIFT16
+#define lpfc_if6_wq_db_list_fm_dpp_id_MASK 0x001F
+#define lpfc_if6_wq_db_list_fm_dpp_id_WORD word0
+#define lpfc_if6_wq_db_list_fm_id_SHIFT0
+#define lpfc_if6_wq_db_list_fm_id_MASK 0x
+#define lpfc_if6_wq_db_list_fm_id_WORD word0
+
 #define LPFC_EQCQ_DOORBELL 0x0120
 #define lpfc_eqcq_doorbell_se_SHIFT31
 #define lpfc_eqcq_doorbell_se_MASK 0x0001
@@ -805,6 +822,38 @@ struct lpfc_register {
 #define LPFC_CQID_HI_FIELD_SHIFT   10
 #define LPFC_EQID_HI_FIELD_SHIFT   9
 
+#define LPFC_IF6_CQ_DOORBELL   0x00C0
+#define lpfc_if6_cq_doorbell_se_SHIFT  31
+#define lpfc_if6_cq_doorbell_se_MASK   0x0001
+#define lpfc_if6_cq_doorbell_se_WORD   word0
+#define LPFC_IF6_CQ_SOLICIT_ENABLE_OFF 0
+#define LPFC_IF6_CQ_SOLICIT_ENABLE_ON  1
+#define lpfc_if6_cq_doorbell_

[PATCH v3 11/13] lpfc: Work around NVME cmd iu SGL type

2018-02-13 Thread James Smart
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 
Signed-off-by: James Smart 

---
v3:
  msg 6422 combined on 1 line
---
 drivers/scsi/lpfc/lpfc.h  |  1 +
 drivers/scsi/lpfc/lpfc_attr.c | 14 
 drivers/scsi/lpfc/lpfc_hw4.h  |  1 +
 drivers/scsi/lpfc/lpfc_init.c |  4 ++--
 drivers/scsi/lpfc/lpfc_nvme.c | 51 ++-
 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 {
uint32_t cfg_fcp_io_channel;
uint32_t cfg_suppress_rsp;
uint32_t cfg_nvme_oas;
+   uint32_t cfg_nvme_embed_cmd;
uint32_t cfg_nvme_io_channel;
uint32_t cfg_nvmet_mrq;
uint32_t cfg_enable_nvmet;
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index bbed20a39b25..5afa85ade6f8 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,
 "Use OAS bit on NVME IOs");
 
 /*
+ * lpfc_nvme_embed_cmd: Use the oas bit when sending NVME/NVMET IOs
+ *
+ *  0  = Put NVME Command in SGL
+ *  1  = Embed NVME Command in WQE (unless G7)
+ *  2 =  Embed NVME Command in WQE (force)
+ *
+ * Value range is [0,2]. Default value is 1.
+ */
+LPFC_ATTR_RW(nvme_embed_cmd, 1, 0, 2,
+"Embed NVME Command in WQE");
+
+/*
  * lpfc_fcp_io_channel: Set the number of FCP IO channels the driver
  * will advertise it supports to the SCSI layer. This also will map to
  * the number of WQs the driver will create.
@@ -5286,6 +5298,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_lpfc_task_mgmt_tmo,
&dev_attr_lpfc_use_msi,
&dev_attr_lpfc_nvme_oas,
+   &dev_attr_lpfc_nvme_embed_cmd,
&dev_attr_lpfc_auto_imax,
&dev_attr_lpfc_fcp_imax,
&dev_attr_lpfc_fcp_cpu_map,
@@ -6310,6 +6323,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
lpfc_enable_SmartSAN_init(phba, lpfc_enable_SmartSAN);
lpfc_use_msi_init(phba, lpfc_use_msi);
lpfc_nvme_oas_init(phba, lpfc_nvme_oas);
+   lpfc_nvme_embed_cmd_init(phba, lpfc_nvme_embed_cmd);
lpfc_auto_imax_init(phba, lpfc_auto_imax);
lpfc_fcp_imax_init(phba, lpfc_fcp_imax);
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 {
 #define lpfc_mbx_rd_rev_vpd_MASK   0x0001
 #define lpfc_mbx_rd_rev_vpd_WORD   word1
uint32_t first_hw_rev;
+#define LPFC_G7_ASIC_1 0xd
uint32_t second_hw_rev;
uint32_t word4_rsvd;
uint32_t third_hw_rev;
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index f8af3adee21a..476caeac201d 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -10652,11 +10652,11 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, 
LPFC_MBOXQ_t *mboxq)
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",
+   "6422 XIB %d: FCP %d %d NVME %d %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);
+   phba->cfg_nvme_embed_cmd, 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) &&
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,1

Re: [PATCH v3 04/13] lpfc: Add push-to-adapter support to sli4

2018-02-16 Thread James Smart

On 2/14/2018 1:30 AM, Johannes Thumshirn wrote:

On Tue, Feb 13, 2018 at 11:34:48AM -0800, James Smart wrote:
[...]

diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 3bff1f9c5df7..5e03b2c969e5 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -35,6 +35,9 @@
  #include 
  #include 
  #include 
+#ifdef CONFIG_X86
+#include 
+#endif


Not needed anymore now you've killed set_memory_wc(), isn't it?


Agree... but, we've done more timing and it turns out the ioremap_wc() 
on X86 isn't behaving quite the same as set_memory_wc().  Works, but 
it's actually slower. I think ioremap_wc() is additionally making it 
cacheable, which seems to be delaying the postings to the io bus (even 
if wc) until the memory barrier. While the set_memory_wc() seems to 
flush as soon as the cacheline is filled.


Given everything we've seen so far - I'm going back to using 
set_memory_wc() as it's the fastest latency option we've measured.





[...]


+   if (q->dpp_enable && q->phba->cfg_enable_dpp) {
+   /* write to DPP aperture taking advatage of Combined Writes */
+   tmp = (uint8_t *)wqe;
+#ifdef CONFIG_64BIT
+   for (i = 0; i < q->entry_size; i += sizeof(uint64_t))
+   writeq(*((uint64_t *)(tmp + i)), q->dpp_regaddr + i);
+#else
+   for (i = 0; i < q->entry_size; i += sizeof(uint32_t))
+   writel(*((uint32_t *)(tmp + i)), q->dpp_regaddr + i);
+#endif
+   }
+   /* ensure WQE bcopy and DPP flushed before doorbell write */


Any reason you can't use writeq() on 32 Bit as well? There's a compat version
in linux/io-64-nonatomic-hi-lo.h.


We actually ran into issues on the existence of writeq() on a 32bit 
platform. Thus this code block.


-- james




[PATCH v4 00/13] lpfc new hardware patches for 12.0.0.0

2018-02-16 Thread James Smart
This patch set adds support for Broadcom's new G7 product that
supports G4G FC.

The patches were cut against the Martin's 4.17/scsi-queue tree.

v2:
 Address comments:
   patch 1, 2, 4, 7: patch description typos
   patch 6: typo on 256GBit speed define

v3:
 Add review tags
 Address comments:
   patch 4: parens, replace set_memory_wc by ioremap_wc
   patch 6: reformat strings
   patch 9: parens
   patch 13: patch title
 patch 5: add missing snippet for default id string
 patch 9, 11: log print condensed to line

v4:
 Add review tags
 patch4: revert to using set_memory_wc


James Smart (13):
  lpfc: Rework lpfc to allow different sli4 cq and eq handlers
  lpfc: Rework sli4 doorbell infrastructure
  lpfc: Add SLI-4 if_type=6 support to the code base
  lpfc: Add push-to-adapter support to sli4
  lpfc: Add PCI Ids for if_type=6 hardware
  lpfc: Add 64G link speed support
  lpfc: Add if_type=6 support for cycling valid bits
  lpfc: Enable fw download on if_type=6 devices
  lpfc: Add embedded data pointers for enhanced performance
  lpfc: Fix nvme embedded io length on new hardware
  lpfc: Work around NVME cmd iu SGL type
  lpfc: update driver version to 12.0.0.0
  lpfc: Change Copyright of 12.0.0.0 modified files to 2018

 drivers/scsi/lpfc/lpfc.h |  20 +-
 drivers/scsi/lpfc/lpfc_attr.c|  86 +--
 drivers/scsi/lpfc/lpfc_bsg.c |   6 +-
 drivers/scsi/lpfc/lpfc_ct.c  |   7 +-
 drivers/scsi/lpfc/lpfc_debugfs.c |  22 +-
 drivers/scsi/lpfc/lpfc_debugfs.h |  13 +-
 drivers/scsi/lpfc/lpfc_els.c |   5 +
 drivers/scsi/lpfc/lpfc_hbadisc.c |   1 +
 drivers/scsi/lpfc/lpfc_hw.h  |  15 +-
 drivers/scsi/lpfc/lpfc_hw4.h | 115 -
 drivers/scsi/lpfc/lpfc_ids.h |   4 +-
 drivers/scsi/lpfc/lpfc_init.c| 247 +++---
 drivers/scsi/lpfc/lpfc_mbox.c|   4 +
 drivers/scsi/lpfc/lpfc_nvme.c|  69 +++--
 drivers/scsi/lpfc/lpfc_nvmet.c   |  24 ++
 drivers/scsi/lpfc/lpfc_scsi.c|   8 +-
 drivers/scsi/lpfc/lpfc_sli.c | 535 +--
 drivers/scsi/lpfc/lpfc_sli4.h|  30 ++-
 drivers/scsi/lpfc/lpfc_version.h |   2 +-
 19 files changed, 963 insertions(+), 250 deletions(-)

-- 
2.13.1



[PATCH v4 01/13] lpfc: Rework lpfc to allow different sli4 cq and eq handlers

2018-02-16 Thread James Smart
Up until now, an SLI-4 device had no variance in the way it handled
its EQs and CQs. With newer hardware, there are now differences in
doorbells and some differences in how entries are valid.

Prepare the code for new hardware by creating a sli4-based callout
table that can be set based on if_type.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Johannes Thumshirn 
---
 drivers/scsi/lpfc/lpfc_init.c |  7 +
 drivers/scsi/lpfc/lpfc_sli.c  | 63 ++-
 drivers/scsi/lpfc/lpfc_sli4.h |  5 
 3 files changed, 44 insertions(+), 31 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 465d890220d5..e24dca2b3f2f 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -9540,6 +9540,13 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba)
}
}
 
+   /* Set up the EQ/CQ register handeling functions now */
+   if (if_type <= LPFC_SLI_INTF_IF_TYPE_2) {
+   phba->sli4_hba.sli4_eq_clr_intr = lpfc_sli4_eq_clr_intr;
+   phba->sli4_hba.sli4_eq_release = lpfc_sli4_eq_release;
+   phba->sli4_hba.sli4_cq_release = lpfc_sli4_cq_release;
+   }
+
return 0;
 
 out_iounmap_all:
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index e97d080e9f65..f91caae6489a 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -299,7 +299,7 @@ lpfc_sli4_eq_get(struct lpfc_queue *q)
  * @q: The Event Queue to disable interrupts
  *
  **/
-static inline void
+inline void
 lpfc_sli4_eq_clr_intr(struct lpfc_queue *q)
 {
struct lpfc_register doorbell;
@@ -5302,41 +5302,42 @@ static void
 lpfc_sli4_arm_cqeq_intr(struct lpfc_hba *phba)
 {
int qidx;
+   struct lpfc_sli4_hba *sli4_hba = &phba->sli4_hba;
 
-   lpfc_sli4_cq_release(phba->sli4_hba.mbx_cq, LPFC_QUEUE_REARM);
-   lpfc_sli4_cq_release(phba->sli4_hba.els_cq, LPFC_QUEUE_REARM);
-   if (phba->sli4_hba.nvmels_cq)
-   lpfc_sli4_cq_release(phba->sli4_hba.nvmels_cq,
+   sli4_hba->sli4_cq_release(sli4_hba->mbx_cq, LPFC_QUEUE_REARM);
+   sli4_hba->sli4_cq_release(sli4_hba->els_cq, LPFC_QUEUE_REARM);
+   if (sli4_hba->nvmels_cq)
+   sli4_hba->sli4_cq_release(sli4_hba->nvmels_cq,
LPFC_QUEUE_REARM);
 
-   if (phba->sli4_hba.fcp_cq)
+   if (sli4_hba->fcp_cq)
for (qidx = 0; qidx < phba->cfg_fcp_io_channel; qidx++)
-   lpfc_sli4_cq_release(phba->sli4_hba.fcp_cq[qidx],
+   sli4_hba->sli4_cq_release(sli4_hba->fcp_cq[qidx],
LPFC_QUEUE_REARM);
 
-   if (phba->sli4_hba.nvme_cq)
+   if (sli4_hba->nvme_cq)
for (qidx = 0; qidx < phba->cfg_nvme_io_channel; qidx++)
-   lpfc_sli4_cq_release(phba->sli4_hba.nvme_cq[qidx],
+   sli4_hba->sli4_cq_release(sli4_hba->nvme_cq[qidx],
LPFC_QUEUE_REARM);
 
if (phba->cfg_fof)
-   lpfc_sli4_cq_release(phba->sli4_hba.oas_cq, LPFC_QUEUE_REARM);
+   sli4_hba->sli4_cq_release(sli4_hba->oas_cq, LPFC_QUEUE_REARM);
 
-   if (phba->sli4_hba.hba_eq)
+   if (sli4_hba->hba_eq)
for (qidx = 0; qidx < phba->io_channel_irqs; qidx++)
-   lpfc_sli4_eq_release(phba->sli4_hba.hba_eq[qidx],
-   LPFC_QUEUE_REARM);
+   sli4_hba->sli4_eq_release(sli4_hba->hba_eq[qidx],
+   LPFC_QUEUE_REARM);
 
if (phba->nvmet_support) {
for (qidx = 0; qidx < phba->cfg_nvmet_mrq; qidx++) {
-   lpfc_sli4_cq_release(
-   phba->sli4_hba.nvmet_cqset[qidx],
+   sli4_hba->sli4_cq_release(
+   sli4_hba->nvmet_cqset[qidx],
LPFC_QUEUE_REARM);
}
}
 
if (phba->cfg_fof)
-   lpfc_sli4_eq_release(phba->sli4_hba.fof_eq, LPFC_QUEUE_REARM);
+   sli4_hba->sli4_eq_release(sli4_hba->fof_eq, LPFC_QUEUE_REARM);
 }
 
 /**
@@ -7270,7 +7271,7 @@ lpfc_sli4_mbox_completions_pending(struct lpfc_hba *phba)
 bool
 lpfc_sli4_process_missed_mbox_completions(struct lpfc_hba *phba)
 {
-
+   struct lpfc_sli4_hba *sli4_hba = &phba->sli4_hba;
uint32_t eqidx;
struct lpfc_queue *fpeq = NULL;
struct lpfc_eqe *eqe;
@@ -7281,11 +7282,11 @@ lpfc_sli4_process_missed_mbox_completions(struct 
lpfc_hba *phba)
 
/* Find the eq associated with the mcq */
 
-   if (phba->sli4_hba.hba_eq)
+

[PATCH v4 02/13] lpfc: Rework sli4 doorbell infrastructure

2018-02-16 Thread James Smart
Up until now, all SLI-4 devices had the same doorbells at the same
bar locations. With newer hardware, there are now independent EQ and
CQ doorbells and the bar locations differ.

Prepare the code for new hardware by separating the eq/cq doorbell into
separate components. The components can be set based on if_type.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Johannes Thumshirn 
---
 drivers/scsi/lpfc/lpfc_debugfs.c | 20 ++--
 drivers/scsi/lpfc/lpfc_debugfs.h | 11 ++-
 drivers/scsi/lpfc/lpfc_init.c|  9 ++---
 drivers/scsi/lpfc/lpfc_sli.c |  8 
 drivers/scsi/lpfc/lpfc_sli4.h|  3 ++-
 5 files changed, 32 insertions(+), 19 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 17ea3bb04266..308303d501cf 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -3944,10 +3944,15 @@ lpfc_idiag_drbacc_read_reg(struct lpfc_hba *phba, char 
*pbuffer,
return 0;
 
switch (drbregid) {
-   case LPFC_DRB_EQCQ:
-   len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
-   "EQCQ-DRB-REG: 0x%08x\n",
-   readl(phba->sli4_hba.EQCQDBregaddr));
+   case LPFC_DRB_EQ:
+   len += snprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE-len,
+   "EQ-DRB-REG: 0x%08x\n",
+   readl(phba->sli4_hba.EQDBregaddr));
+   break;
+   case LPFC_DRB_CQ:
+   len += snprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE - len,
+   "CQ-DRB-REG: 0x%08x\n",
+   readl(phba->sli4_hba.CQDBregaddr));
break;
case LPFC_DRB_MQ:
len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
@@ -4086,8 +4091,11 @@ lpfc_idiag_drbacc_write(struct file *file, const char 
__user *buf,
idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
switch (drb_reg_id) {
-   case LPFC_DRB_EQCQ:
-   drb_reg = phba->sli4_hba.EQCQDBregaddr;
+   case LPFC_DRB_EQ:
+   drb_reg = phba->sli4_hba.EQDBregaddr;
+   break;
+   case LPFC_DRB_CQ:
+   drb_reg = phba->sli4_hba.CQDBregaddr;
break;
case LPFC_DRB_MQ:
drb_reg = phba->sli4_hba.MQDBregaddr;
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
index c4edd87bfc65..12fbf498a7ce 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.h
+++ b/drivers/scsi/lpfc/lpfc_debugfs.h
@@ -126,12 +126,13 @@
 #define LPFC_DRB_ACC_WR_CMD_ARG 2
 #define LPFC_DRB_ACC_BUF_SIZE 256
 
-#define LPFC_DRB_EQCQ 1
-#define LPFC_DRB_MQ   2
-#define LPFC_DRB_WQ   3
-#define LPFC_DRB_RQ   4
+#define LPFC_DRB_EQ   1
+#define LPFC_DRB_CQ   2
+#define LPFC_DRB_MQ   3
+#define LPFC_DRB_WQ   4
+#define LPFC_DRB_RQ   5
 
-#define LPFC_DRB_MAX  4
+#define LPFC_DRB_MAX  5
 
 #define IDIAG_DRBACC_REGID_INDX 0
 #define IDIAG_DRBACC_VALUE_INDX 1
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index e24dca2b3f2f..b2cf8eb99008 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -7430,8 +7430,9 @@ lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba, 
uint32_t if_type)
phba->sli4_hba.WQDBregaddr =
phba->sli4_hba.conf_regs_memmap_p +
LPFC_ULP0_WQ_DOORBELL;
-   phba->sli4_hba.EQCQDBregaddr =
+   phba->sli4_hba.CQDBregaddr =
phba->sli4_hba.conf_regs_memmap_p + LPFC_EQCQ_DOORBELL;
+   phba->sli4_hba.EQDBregaddr = phba->sli4_hba.CQDBregaddr;
phba->sli4_hba.MQDBregaddr =
phba->sli4_hba.conf_regs_memmap_p + LPFC_MQ_DOORBELL;
phba->sli4_hba.BMBXregaddr =
@@ -7488,8 +7489,10 @@ lpfc_sli4_bar2_register_memmap(struct lpfc_hba *phba, 
uint32_t vf)
phba->sli4_hba.WQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
vf * LPFC_VFR_PAGE_SIZE +
LPFC_ULP0_WQ_DOORBELL);
-   phba->sli4_hba.EQCQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
-   vf * LPFC_VFR_PAGE_SIZE + LPFC_EQCQ_DOORBELL);
+   phba->sli4_hba.CQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
+   vf * LPFC_VFR_PAGE_SIZE +
+   LPFC_EQCQ_DOORBELL);
+   phba->sli4_hba.EQDBregaddr = phba->sli4_hba.CQDBregaddr;
phba->sli4_hba.MQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +

[PATCH v4 03/13] lpfc: Add SLI-4 if_type=6 support to the code base

2018-02-16 Thread James Smart
New hardware supports a SLI-4 interface, but with a new if_type
variant of 6.

If_type=6 has a different PCI BAR map, separate EQ/CQ doorbells,
and some changes in doorbell formats.

Add the changes for the if_type into headers, adapter initialization
and control flows. Add new eq and cq handlers.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Johannes Thumshirn 
---
 drivers/scsi/lpfc/lpfc_bsg.c  |   4 +-
 drivers/scsi/lpfc/lpfc_hw4.h  |  54 ++-
 drivers/scsi/lpfc/lpfc_init.c | 120 +++---
 drivers/scsi/lpfc/lpfc_sli.c  | 120 --
 drivers/scsi/lpfc/lpfc_sli4.h |   3 ++
 5 files changed, 275 insertions(+), 26 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index d89816222b23..8b33b652226b 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -3867,7 +3867,7 @@ lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, 
struct bsg_job *job,
"ext_buf_cnt:%d\n", ext_buf_cnt);
} else {
/* sanity check on interface type for support */
-   if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+   if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
LPFC_SLI_INTF_IF_TYPE_2) {
rc = -ENODEV;
goto job_error;
@@ -4053,7 +4053,7 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, 
struct bsg_job *job,
"ext_buf_cnt:%d\n", ext_buf_cnt);
} else {
/* sanity check on interface type for support */
-   if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+   if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
LPFC_SLI_INTF_IF_TYPE_2)
return -ENODEV;
/* nemb_tp == nemb_hbd */
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 8685d26e6929..93fd9fd10a0f 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -84,6 +84,7 @@ struct lpfc_sli_intf {
 #define LPFC_SLI_INTF_IF_TYPE_00
 #define LPFC_SLI_INTF_IF_TYPE_11
 #define LPFC_SLI_INTF_IF_TYPE_22
+#define LPFC_SLI_INTF_IF_TYPE_66
 #define lpfc_sli_intf_sli_family_SHIFT 8
 #define lpfc_sli_intf_sli_family_MASK  0x000F
 #define lpfc_sli_intf_sli_family_WORD  word0
@@ -731,11 +732,13 @@ struct lpfc_register {
  * register sets depending on the UCNA Port's reported if_type
  * value.  For UCNA ports running SLI4 and if_type 0, they reside in
  * BAR4.  For UCNA ports running SLI4 and if_type 2, they reside in
- * BAR0.  The offsets are the same so the driver must account for
- * any base address difference.
+ * BAR0.  For FC ports running SLI4 and if_type 6, they reside in
+ * BAR2. The offsets and base address are different,  so the driver
+ * has to compute the register addresses accordingly
  */
 #define LPFC_ULP0_RQ_DOORBELL  0x00A0
 #define LPFC_ULP1_RQ_DOORBELL  0x00C0
+#define LPFC_IF6_RQ_DOORBELL   0x0080
 #define lpfc_rq_db_list_fm_num_posted_SHIFT24
 #define lpfc_rq_db_list_fm_num_posted_MASK 0x00FF
 #define lpfc_rq_db_list_fm_num_posted_WORD word0
@@ -770,6 +773,20 @@ struct lpfc_register {
 #define lpfc_wq_db_ring_fm_id_MASK  0x
 #define lpfc_wq_db_ring_fm_id_WORD  word0
 
+#define LPFC_IF6_WQ_DOORBELL   0x0040
+#define lpfc_if6_wq_db_list_fm_num_posted_SHIFT24
+#define lpfc_if6_wq_db_list_fm_num_posted_MASK 0x00FF
+#define lpfc_if6_wq_db_list_fm_num_posted_WORD word0
+#define lpfc_if6_wq_db_list_fm_dpp_SHIFT   23
+#define lpfc_if6_wq_db_list_fm_dpp_MASK0x0001
+#define lpfc_if6_wq_db_list_fm_dpp_WORDword0
+#define lpfc_if6_wq_db_list_fm_dpp_id_SHIFT16
+#define lpfc_if6_wq_db_list_fm_dpp_id_MASK 0x001F
+#define lpfc_if6_wq_db_list_fm_dpp_id_WORD word0
+#define lpfc_if6_wq_db_list_fm_id_SHIFT0
+#define lpfc_if6_wq_db_list_fm_id_MASK 0x
+#define lpfc_if6_wq_db_list_fm_id_WORD word0
+
 #define LPFC_EQCQ_DOORBELL 0x0120
 #define lpfc_eqcq_doorbell_se_SHIFT31
 #define lpfc_eqcq_doorbell_se_MASK 0x0001
@@ -805,6 +822,38 @@ struct lpfc_register {
 #define LPFC_CQID_HI_FIELD_SHIFT   10
 #define LPFC_EQID_HI_FIELD_SHIFT   9
 
+#define LPFC_IF6_CQ_DOORBELL   0x00C0
+#define lpfc_if6_cq_doorbell_se_SHIFT  31
+#define lpfc_if6_cq_doorbell_se_MASK   0x0001
+#define lpfc_if6_cq_doorbell_se_WORD   word0
+#define LPFC_IF6_CQ_SOLICIT_ENABLE_OFF 0
+#define LPFC_IF6_CQ_SOLICIT_ENABLE_ON  1
+#define lpfc_if6_cq_doorbell_

[PATCH v4 05/13] lpfc: Add PCI Ids for if_type=6 hardware

2018-02-16 Thread James Smart
Add PCI ids for the new G7 adapter

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Johannes Thumshirn 

---
v3:
  Add default adapter id string for G7 adapter
---
 drivers/scsi/lpfc/lpfc_hw.h   | 1 +
 drivers/scsi/lpfc/lpfc_ids.h  | 2 ++
 drivers/scsi/lpfc/lpfc_init.c | 3 +++
 3 files changed, 6 insertions(+)

diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index bdc1f184f67a..d07d2fcbea34 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -1580,6 +1580,7 @@ struct lpfc_fdmi_reg_portattr {
 #define PCI_DEVICE_ID_LANCER_FCOE   0xe260
 #define PCI_DEVICE_ID_LANCER_FCOE_VF 0xe268
 #define PCI_DEVICE_ID_LANCER_G6_FC  0xe300
+#define PCI_DEVICE_ID_LANCER_G7_FC  0xf400
 #define PCI_DEVICE_ID_SAT_SMB   0xf011
 #define PCI_DEVICE_ID_SAT_MID   0xf015
 #define PCI_DEVICE_ID_RFLY  0xf095
diff --git a/drivers/scsi/lpfc/lpfc_ids.h b/drivers/scsi/lpfc/lpfc_ids.h
index 0ba3733eb36d..329c8d28869c 100644
--- a/drivers/scsi/lpfc/lpfc_ids.h
+++ b/drivers/scsi/lpfc/lpfc_ids.h
@@ -116,6 +116,8 @@ const struct pci_device_id lpfc_id_table[] = {
PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_G6_FC,
PCI_ANY_ID, PCI_ANY_ID, },
+   {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_G7_FC,
+   PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK,
PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK_VF,
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 5f0c63bb0a4d..2e723cdd2c1a 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -2473,6 +2473,9 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t 
*mdp, uint8_t *descp)
case PCI_DEVICE_ID_LANCER_G6_FC:
m = (typeof(m)){"LPe32000", "PCIe", "Fibre Channel Adapter"};
break;
+   case PCI_DEVICE_ID_LANCER_G7_FC:
+   m = (typeof(m)){"LPe36000", "PCIe", "Fibre Channel Adapter"};
+   break;
case PCI_DEVICE_ID_SKYHAWK:
case PCI_DEVICE_ID_SKYHAWK_VF:
oneConnect = 1;
-- 
2.13.1



[PATCH v4 04/13] lpfc: Add push-to-adapter support to sli4

2018-02-16 Thread James Smart
New if_type=6 adapters support an additional BAR that provides
apertures to allow direct WQE to adapter push support - termed
Direct Packet Push (DPP). WQ creation differs slightly to ask for
a WQ to be DPP-ized. When submitting a WQE to a DPP WQ, it is
submitted to the host memory for the WQ normally, but is also
written by the host cpu directly to a BAR aperture.  Write buffer
coalescing in hardware is (hopefully) turned on, enabling single
pci write operation support. The doorbell is thing rung to indicate
the WQE is available and was pushed to the aperture.

This patch:
- Updates the WQ Create commands for the DPP options
- Adds the bar mapping for if_type=6 DPP bar
- Adds the WQE pushing to the DDP aperture received from WQ create
- Adds a new module parameter to disable DPP operation if desired.
  Default is enabled.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 

---
v3:
  remove unnecessary parens
  use ioremap_wc() instead of set_memory_wc(). the wc property
is now set by default on the BAR. if direct push is disabled,
the BAR won't be used so it won't matter what is set on it.
Track cases where the ioremap_wc() may not succeed, leaving
bar pointer NULL. In this case, disable direct push.
  As some platforms will honor ioremap_wc() but not truly enable
wc, change default for direct push so enabled only on X86.
v4:
  revert to original patch version using set_memory_wc() as
  benchmarking and different platform testing says its the best
  option

revert to v1 using set_memory_wc()
---
 drivers/scsi/lpfc/lpfc.h  |   3 +-
 drivers/scsi/lpfc/lpfc_attr.c |  10 ++
 drivers/scsi/lpfc/lpfc_hw4.h  |  31 ++
 drivers/scsi/lpfc/lpfc_init.c |  18 
 drivers/scsi/lpfc/lpfc_sli.c  | 234 +++---
 drivers/scsi/lpfc/lpfc_sli4.h |  16 ++-
 6 files changed, 225 insertions(+), 87 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 9698b9635058..86ffb9756e65 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -840,7 +840,8 @@ struct lpfc_hba {
uint32_t cfg_enable_SmartSAN;
uint32_t cfg_enable_mds_diags;
uint32_t cfg_enable_fc4_type;
-   uint32_t cfg_enable_bbcr;   /*Enable BB Credit Recovery*/
+   uint32_t cfg_enable_bbcr;   /* Enable BB Credit Recovery */
+   uint32_t cfg_enable_dpp;/* Enable Direct Packet Push */
uint32_t cfg_xri_split;
 #define LPFC_ENABLE_FCP  1
 #define LPFC_ENABLE_NVME 2
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 7be4bdef4d42..32f17e19e123 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -5186,6 +5186,14 @@ LPFC_ATTR_R(enable_mds_diags, 0, 0, 1, "Enable MDS 
Diagnostics");
  */
 LPFC_BBCR_ATTR_RW(enable_bbcr, 1, 0, 1, "Enable BBC Recovery");
 
+/*
+ * lpfc_enable_dpp: Enable DPP on G7
+ *   0  = DPP on G7 disabled
+ *   1  = DPP on G7 enabled (default)
+ * Value range is [0,1]. Default value is 1.
+ */
+LPFC_ATTR_RW(enable_dpp, 1, 0, 1, "Enable Direct Packet Push");
+
 struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_nvme_info,
&dev_attr_bg_info,
@@ -5294,6 +5302,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_lpfc_xlane_supported,
&dev_attr_lpfc_enable_mds_diags,
&dev_attr_lpfc_enable_bbcr,
+   &dev_attr_lpfc_enable_dpp,
NULL,
 };
 
@@ -6306,6 +6315,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
lpfc_fcp_io_channel_init(phba, lpfc_fcp_io_channel);
lpfc_nvme_io_channel_init(phba, lpfc_nvme_io_channel);
lpfc_enable_bbcr_init(phba, lpfc_enable_bbcr);
+   lpfc_enable_dpp_init(phba, lpfc_enable_dpp);
 
if (phba->sli_rev != LPFC_SLI_REV4) {
/* NVME only supported on SLI4 */
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 93fd9fd10a0f..60ccff6fa8b0 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -1372,6 +1372,15 @@ struct lpfc_mbx_wq_create {
 #define lpfc_mbx_wq_create_page_size_MASK  0x00FF
 #define lpfc_mbx_wq_create_page_size_WORD  word1
 #define LPFC_WQ_PAGE_SIZE_4096 0x1
+#define lpfc_mbx_wq_create_dpp_req_SHIFT   15
+#define lpfc_mbx_wq_create_dpp_req_MASK0x0001
+#define lpfc_mbx_wq_create_dpp_req_WORDword1
+#define lpfc_mbx_wq_create_doe_SHIFT   14
+#define lpfc_mbx_wq_create_doe_MASK0x0001
+#define lpfc_mbx_wq_create_doe_WORDword1
+#define lpfc_mbx_wq_create_toe_SHIFT   13
+#define lpfc_mbx_wq_create_toe_MASK0x0001
+#define lpfc_mbx_wq_create_toe_WORDword1
 #define lpfc_mbx_wq_create_wqe_size_SHIFT  8
 #define lpfc_mbx_wq_create_wqe_size_MASK   0x000F
 #define lpfc_mbx_wq_create_wqe_size_WORD   word1
@@ -1400,6 +1409,28 @@ struct lpfc_mbx_wq_

[PATCH v4 06/13] lpfc: Add 64G link speed support

2018-02-16 Thread James Smart
The G7 adapter supports 64G link speeds. Add support to the driver.

In addition, a small cleanup to replace the odd bitmap logic with
a switch case.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Johannes Thumshirn 

---
v2:
  address review comment of typo in define name. Define wasn't used
  anywhere yet.
v3:
  reformat printf_log 0469
---
 drivers/scsi/lpfc/lpfc.h | 14 +++--
 drivers/scsi/lpfc/lpfc_attr.c| 62 
 drivers/scsi/lpfc/lpfc_ct.c  |  5 
 drivers/scsi/lpfc/lpfc_els.c |  5 
 drivers/scsi/lpfc/lpfc_hbadisc.c |  1 +
 drivers/scsi/lpfc/lpfc_hw.h  | 12 
 drivers/scsi/lpfc/lpfc_hw4.h |  3 ++
 drivers/scsi/lpfc/lpfc_init.c| 17 +--
 drivers/scsi/lpfc/lpfc_mbox.c|  4 +++
 9 files changed, 93 insertions(+), 30 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 86ffb9756e65..7aad4a717f13 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -544,16 +544,10 @@ struct unsol_rcv_ct_ctx {
 #define LPFC_USER_LINK_SPEED_10G   10  /* 10 Gigabaud */
 #define LPFC_USER_LINK_SPEED_16G   16  /* 16 Gigabaud */
 #define LPFC_USER_LINK_SPEED_32G   32  /* 32 Gigabaud */
-#define LPFC_USER_LINK_SPEED_MAX   LPFC_USER_LINK_SPEED_32G
-#define LPFC_USER_LINK_SPEED_BITMAP  ((1ULL << LPFC_USER_LINK_SPEED_32G) | \
-(1 << LPFC_USER_LINK_SPEED_16G) | \
-(1 << LPFC_USER_LINK_SPEED_10G) | \
-(1 << LPFC_USER_LINK_SPEED_8G) | \
-(1 << LPFC_USER_LINK_SPEED_4G) | \
-(1 << LPFC_USER_LINK_SPEED_2G) | \
-(1 << LPFC_USER_LINK_SPEED_1G) | \
-(1 << LPFC_USER_LINK_SPEED_AUTO))
-#define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16, 32"
+#define LPFC_USER_LINK_SPEED_64G   64  /* 64 Gigabaud */
+#define LPFC_USER_LINK_SPEED_MAX   LPFC_USER_LINK_SPEED_64G
+
+#define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16, 32, 64"
 
 enum nemb_type {
nemb_mse = 1,
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 32f17e19e123..14f6efcf8f0b 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -4115,23 +4115,32 @@ lpfc_link_speed_store(struct device *dev, struct 
device_attribute *attr,
((val == LPFC_USER_LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) ||
((val == LPFC_USER_LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)) ||
((val == LPFC_USER_LINK_SPEED_16G) && !(phba->lmt & LMT_16Gb)) ||
-   ((val == LPFC_USER_LINK_SPEED_32G) && !(phba->lmt & LMT_32Gb))) {
+   ((val == LPFC_USER_LINK_SPEED_32G) && !(phba->lmt & LMT_32Gb)) ||
+   ((val == LPFC_USER_LINK_SPEED_64G) && !(phba->lmt & LMT_64Gb))) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"2879 lpfc_link_speed attribute cannot be set "
"to %d. Speed is not supported by this port.\n",
val);
return -EINVAL;
}
-   if (val == LPFC_USER_LINK_SPEED_16G &&
-phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
+   if (val >= LPFC_USER_LINK_SPEED_16G &&
+   phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3112 lpfc_link_speed attribute cannot be set "
"to %d. Speed is not supported in loop mode.\n",
val);
return -EINVAL;
}
-   if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) &&
-   (LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) {
+
+   switch (val) {
+   case LPFC_USER_LINK_SPEED_AUTO:
+   case LPFC_USER_LINK_SPEED_1G:
+   case LPFC_USER_LINK_SPEED_2G:
+   case LPFC_USER_LINK_SPEED_4G:
+   case LPFC_USER_LINK_SPEED_8G:
+   case LPFC_USER_LINK_SPEED_16G:
+   case LPFC_USER_LINK_SPEED_32G:
+   case LPFC_USER_LINK_SPEED_64G:
prev_val = phba->cfg_link_speed;
phba->cfg_link_speed = val;
if (nolip)
@@ -4141,13 +4150,18 @@ lpfc_link_speed_store(struct device *dev, struct 
device_attribute *attr,
if (err) {
phba->cfg_link_speed = prev_val;
return -EINVAL;
-   } else
-   return strlen(buf);
+   }
+   return strlen(buf);
+   default:
+

[PATCH v4 08/13] lpfc: Enable fw download on if_type=6 devices

2018-02-16 Thread James Smart
Current code is very explicit in what it allows to be downloaded.
The driver checking prevented G7 firmware download. The driver
checking is unnecessary as the device will validate what it receives.

Revise the firmware download interface checking.
Added a little debug support in case there is still a failure.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Johannes Thumshirn 
---
 drivers/scsi/lpfc/lpfc_hw4.h  |  5 +
 drivers/scsi/lpfc/lpfc_init.c | 44 ++-
 drivers/scsi/lpfc/lpfc_sli.c  |  1 +
 3 files changed, 33 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index dba724e1f5ee..be8227dfa086 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -2241,6 +2241,7 @@ struct lpfc_mbx_redisc_fcf_tbl {
  * command.
  */
 #define ADD_STATUS_OPERATION_ALREADY_ACTIVE0x67
+#define ADD_STATUS_FW_NOT_SUPPORTED0xEB
 
 struct lpfc_mbx_sli4_config {
struct mbox_header header;
@@ -4603,10 +4604,6 @@ union lpfc_wqe128 {
struct gen_req64_wqe gen_req;
 };
 
-#define LPFC_GROUP_OJECT_MAGIC_G5  0xfeaa0001
-#define LPFC_GROUP_OJECT_MAGIC_G6  0xfeaa0003
-#define LPFC_FILE_TYPE_GROUP   0xf7
-#define LPFC_FILE_ID_GROUP 0xa2
 struct lpfc_grp_hdr {
uint32_t size;
uint32_t magic_number;
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 96a37e4e127d..af92c3c681f7 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -11297,6 +11297,27 @@ lpfc_sli4_get_iocb_cnt(struct lpfc_hba *phba)
 }
 
 
+static void
+lpfc_log_write_firmware_error(struct lpfc_hba *phba, uint32_t offset,
+   uint32_t magic_number, uint32_t ftype, uint32_t fid, uint32_t fsize,
+   const struct firmware *fw)
+{
+   if (offset == ADD_STATUS_FW_NOT_SUPPORTED)
+   lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+   "3030 This firmware version is not supported on "
+   "this HBA model. Device:%x Magic:%x Type:%x "
+   "ID:%x Size %d %zd\n",
+   phba->pcidev->device, magic_number, ftype, fid,
+   fsize, fw->size);
+   else
+   lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+   "3022 FW Download failed. Device:%x Magic:%x Type:%x "
+   "ID:%x Size %d %zd\n",
+   phba->pcidev->device, magic_number, ftype, fid,
+   fsize, fw->size);
+}
+
+
 /**
  * lpfc_write_firmware - attempt to write a firmware image to the port
  * @fw: pointer to firmware image returned from request_firmware.
@@ -11324,20 +11345,10 @@ lpfc_write_firmware(const struct firmware *fw, void 
*context)
 
magic_number = be32_to_cpu(image->magic_number);
ftype = bf_get_be32(lpfc_grp_hdr_file_type, image);
-   fid = bf_get_be32(lpfc_grp_hdr_id, image),
+   fid = bf_get_be32(lpfc_grp_hdr_id, image);
fsize = be32_to_cpu(image->size);
 
INIT_LIST_HEAD(&dma_buffer_list);
-   if ((magic_number != LPFC_GROUP_OJECT_MAGIC_G5 &&
-magic_number != LPFC_GROUP_OJECT_MAGIC_G6) ||
-   ftype != LPFC_FILE_TYPE_GROUP || fsize != fw->size) {
-   lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-   "3022 Invalid FW image found. "
-   "Magic:%x Type:%x ID:%x Size %d %zd\n",
-   magic_number, ftype, fid, fsize, fw->size);
-   rc = -EINVAL;
-   goto release_out;
-   }
lpfc_decode_firmware_rev(phba, fwrev, 1);
if (strncmp(fwrev, image->revision, strnlen(image->revision, 16))) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -11378,11 +11389,18 @@ lpfc_write_firmware(const struct firmware *fw, void 
*context)
}
rc = lpfc_wr_object(phba, &dma_buffer_list,
(fw->size - offset), &offset);
-   if (rc)
+   if (rc) {
+   lpfc_log_write_firmware_error(phba, offset,
+   magic_number, ftype, fid, fsize, fw);
goto release_out;
+   }
}
rc = offset;
-   }
+   } else
+   lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+   "3029 Skipped Firmware update, Current "
+   "Version:%s New Version:%s\n",
+   fwrev, image->revision);
 
 release_out:
list_for_each_entry_safe(dmabuf, next, &dma_b

[PATCH v4 07/13] lpfc: Add if_type=6 support for cycling valid bits

2018-02-16 Thread James Smart
Traditional SLI4 required the driver to clear Valid bits on
EQEs and CQEs after consuming them.

The new if_type=6 hardware will cycle the value for what is
valid on each queue itteration. The driver no longer has to
touch the valid bits. This also means all the cpu cache
dirtying and perhaps flush/refill's done by the hardware
in accessing the EQ/CQ elements is eliminated.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Johannes Thumshirn 
---
 drivers/scsi/lpfc/lpfc_hw4.h  | 18 --
 drivers/scsi/lpfc/lpfc_init.c | 11 +++
 drivers/scsi/lpfc/lpfc_sli.c  | 77 +++
 drivers/scsi/lpfc/lpfc_sli4.h |  3 ++
 4 files changed, 92 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 0c33510fe75c..dba724e1f5ee 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -1040,6 +1040,9 @@ struct eq_context {
 #define lpfc_eq_context_valid_SHIFT29
 #define lpfc_eq_context_valid_MASK 0x0001
 #define lpfc_eq_context_valid_WORD word0
+#define lpfc_eq_context_autovalid_SHIFT 28
+#define lpfc_eq_context_autovalid_MASK  0x0001
+#define lpfc_eq_context_autovalid_WORD  word0
uint32_t word1;
 #define lpfc_eq_context_count_SHIFT26
 #define lpfc_eq_context_count_MASK 0x0003
@@ -1173,6 +1176,9 @@ struct cq_context {
 #define LPFC_CQ_CNT_5120x1
 #define LPFC_CQ_CNT_1024   0x2
 #define LPFC_CQ_CNT_WORD7  0x3
+#define lpfc_cq_context_autovalid_SHIFT 15
+#define lpfc_cq_context_autovalid_MASK  0x0001
+#define lpfc_cq_context_autovalid_WORD  word0
uint32_t word1;
 #define lpfc_cq_eq_id_SHIFT22  /* Version 0 Only */
 #define lpfc_cq_eq_id_MASK 0x00FF
@@ -1231,9 +1237,9 @@ struct lpfc_mbx_cq_create_set {
 #define lpfc_mbx_cq_create_set_cqe_size_SHIFT  25
 #define lpfc_mbx_cq_create_set_cqe_size_MASK   0x0003
 #define lpfc_mbx_cq_create_set_cqe_size_WORD   word1
-#define lpfc_mbx_cq_create_set_auto_SHIFT  15
-#define lpfc_mbx_cq_create_set_auto_MASK   0x001
-#define lpfc_mbx_cq_create_set_auto_WORD   word1
+#define lpfc_mbx_cq_create_set_autovalid_SHIFT 15
+#define lpfc_mbx_cq_create_set_autovalid_MASK  0x001
+#define lpfc_mbx_cq_create_set_autovalid_WORD  word1
 #define lpfc_mbx_cq_create_set_nodelay_SHIFT   14
 #define lpfc_mbx_cq_create_set_nodelay_MASK0x0001
 #define lpfc_mbx_cq_create_set_nodelay_WORDword1
@@ -3288,6 +3294,9 @@ struct lpfc_sli4_parameters {
 #define cfg_sli_hint_2_MASK0x001f
 #define cfg_sli_hint_2_WORDword1
uint32_t word2;
+#define cfg_eqav_SHIFT 31
+#define cfg_eqav_MASK  0x0001
+#define cfg_eqav_WORD  word2
uint32_t word3;
uint32_t word4;
 #define cfg_cqv_SHIFT  14
@@ -3296,6 +3305,9 @@ struct lpfc_sli4_parameters {
 #define cfg_cqpsize_SHIFT  16
 #define cfg_cqpsize_MASK   0x00ff
 #define cfg_cqpsize_WORD   word4
+#define cfg_cqav_SHIFT 31
+#define cfg_cqav_MASK  0x0001
+#define cfg_cqav_WORD  word4
uint32_t word5;
uint32_t word6;
 #define cfg_mqv_SHIFT  14
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 576ab7ec7e9d..96a37e4e127d 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -8063,6 +8063,7 @@ lpfc_alloc_nvme_wq_cq(struct lpfc_hba *phba, int wqidx)
wqidx);
return 1;
}
+   qdesc->qe_valid = 1;
phba->sli4_hba.nvme_cq[wqidx] = qdesc;
 
qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE,
@@ -8100,6 +8101,7 @@ lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx)
"0499 Failed allocate fast-path FCP CQ (%d)\n", wqidx);
return 1;
}
+   qdesc->qe_valid = 1;
phba->sli4_hba.fcp_cq[wqidx] = qdesc;
 
/* Create Fast Path FCP WQs */
@@ -8293,6 +8295,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
"0497 Failed allocate EQ (%d)\n", idx);
goto out_error;
}
+   qdesc->qe_valid = 1;
phba->sli4_hba.hba_eq[idx] = qdesc;
}
 
@@ -8318,6 +8321,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
"CQ Set (%d)\n", idx);
goto out_error;
}
+   qdesc->qe_valid = 1;
phba->sli4_hba.nvmet_cqset[idx] = qdesc;
}
}
@@ -8335,6 +8339,7 @@ lpfc_sli4_queue_create(s

[PATCH v4 10/13] lpfc: Fix nvme embedded io length on new hardware

2018-02-16 Thread James Smart
Newer hardware more strictly enforces buffer lenghts, causing an
mis-set value to be identified. Older hardware won't catch it.
The difference is benign on old hardware.

Set the right embedded buffer length for nvme ios.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Johannes Thumshirn 
---
 drivers/scsi/lpfc/lpfc_nvme.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 5a1a6e24a27f..c75958daf799 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -655,7 +655,7 @@ lpfc_nvme_adj_fcp_sgls(struct lpfc_vport *vport,
 
/* Word 0-2 - NVME CMND IU (embedded payload) */
wqe->generic.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_IMMED;
-   wqe->generic.bde.tus.f.bdeSize = 60;
+   wqe->generic.bde.tus.f.bdeSize = 56;
wqe->generic.bde.addrHigh = 0;
wqe->generic.bde.addrLow =  64;  /* Word 16 */
 
-- 
2.13.1



[PATCH v4 12/13] lpfc: update driver version to 12.0.0.0

2018-02-16 Thread James Smart
Update the driver version to 12.0.0.0

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
Reviewed-by: Johannes Thumshirn 
---
 drivers/scsi/lpfc/lpfc_version.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index 4adbf07880a2..b1ae62a44aae 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -20,7 +20,7 @@
  * included with this package. *
  ***/
 
-#define LPFC_DRIVER_VERSION "11.4.0.7"
+#define LPFC_DRIVER_VERSION "12.0.0.0"
 #define LPFC_DRIVER_NAME   "lpfc"
 
 /* Used for SLI 2/3 */
-- 
2.13.1



<    5   6   7   8   9   10   11   12   13   14   >