[SCSI] lpfc 8.3.3 : Fix various SLI-3 vs SLI-4 differences

Contains the following changes
- Set the CT field of FDISC to 3
- Fixed over allocation of SCSI buffers on SLI4
- Removed unused jump table entries
- Increase LPFC_WQE_DEF_COUNT to 256
- Updated FDISC context to VPI
- Fixed immediate SCSI command for LUN reset translation to WQE
- Extended mailbox handling to allow MBX_POLL commands in between async
  MBQ commands
- Fixed SID used for FDISC
- Fix crash when accessing ctlregs from sysfs for SLI4 HBAs
- Fix SLI4 firmware version not being saved or displayed correctly
- Expand CQID field in WQE structure to 16 bits
- Fix post header template mailbox command timing out
- Removed FCoE PCI device ID 0x0705

Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index ff04daf..b8cf0a1 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -4211,27 +4211,6 @@
 		return -EIO;
 	}
 
-	lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI,
-			"(%d):0380 Mailbox cmd x%x Status x%x "
-			"Data: x%x x%x x%x x%x x%x x%x x%x x%x x%x "
-			"x%x x%x x%x x%x x%x x%x x%x x%x x%x "
-			"CQ: x%x x%x x%x x%x\n",
-			mboxq->vport ? mboxq->vport->vpi : 0,
-			bf_get(lpfc_mqe_command, mqe),
-			bf_get(lpfc_mqe_status, mqe),
-			mqe->un.mb_words[0], mqe->un.mb_words[1],
-			mqe->un.mb_words[2], mqe->un.mb_words[3],
-			mqe->un.mb_words[4], mqe->un.mb_words[5],
-			mqe->un.mb_words[6], mqe->un.mb_words[7],
-			mqe->un.mb_words[8], mqe->un.mb_words[9],
-			mqe->un.mb_words[10], mqe->un.mb_words[11],
-			mqe->un.mb_words[12], mqe->un.mb_words[13],
-			mqe->un.mb_words[14], mqe->un.mb_words[15],
-			mqe->un.mb_words[16], mqe->un.mb_words[50],
-			mboxq->mcqe.word0,
-			mboxq->mcqe.mcqe_tag0, 	mboxq->mcqe.mcqe_tag1,
-			mboxq->mcqe.trailer);
-
 	/*
 	 * The available vpd length cannot be bigger than the
 	 * DMA buffer passed to the port.  Catch the less than
@@ -4337,21 +4316,18 @@
 		goto out_free_vpd;
 
 	mqe = &mboxq->u.mqe;
-	if ((bf_get(lpfc_mbx_rd_rev_sli_lvl,
-		    &mqe->un.read_rev) != LPFC_SLI_REV4) ||
-	    (bf_get(lpfc_mbx_rd_rev_fcoe, &mqe->un.read_rev) == 0)) {
+	phba->sli_rev = bf_get(lpfc_mbx_rd_rev_sli_lvl, &mqe->un.read_rev);
+	if (bf_get(lpfc_mbx_rd_rev_fcoe, &mqe->un.read_rev))
+		phba->hba_flag |= HBA_FCOE_SUPPORT;
+	if (phba->sli_rev != LPFC_SLI_REV4 ||
+	    !(phba->hba_flag & HBA_FCOE_SUPPORT)) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
 			"0376 READ_REV Error. SLI Level %d "
 			"FCoE enabled %d\n",
-			bf_get(lpfc_mbx_rd_rev_sli_lvl, &mqe->un.read_rev),
-			bf_get(lpfc_mbx_rd_rev_fcoe, &mqe->un.read_rev));
+			phba->sli_rev, phba->hba_flag & HBA_FCOE_SUPPORT);
 		rc = -EIO;
 		goto out_free_vpd;
 	}
-	/* Single threaded at this point, no need for lock */
-	spin_lock_irq(&phba->hbalock);
-	phba->hba_flag |= HBA_FCOE_SUPPORT;
-	spin_unlock_irq(&phba->hbalock);
 	/*
 	 * Evaluate the read rev and vpd data. Populate the driver
 	 * state with the results. If this routine fails, the failure
@@ -4365,8 +4341,32 @@
 		rc = 0;
 	}
 
-	/* By now, we should determine the SLI revision, hard code for now */
-	phba->sli_rev = LPFC_SLI_REV4;
+	/* Save information as VPD data */
+	phba->vpd.rev.biuRev = mqe->un.read_rev.first_hw_rev;
+	phba->vpd.rev.smRev = mqe->un.read_rev.second_hw_rev;
+	phba->vpd.rev.endecRev = mqe->un.read_rev.third_hw_rev;
+	phba->vpd.rev.fcphHigh = bf_get(lpfc_mbx_rd_rev_fcph_high,
+					 &mqe->un.read_rev);
+	phba->vpd.rev.fcphLow = bf_get(lpfc_mbx_rd_rev_fcph_low,
+				       &mqe->un.read_rev);
+	phba->vpd.rev.feaLevelHigh = bf_get(lpfc_mbx_rd_rev_ftr_lvl_high,
+					    &mqe->un.read_rev);
+	phba->vpd.rev.feaLevelLow = bf_get(lpfc_mbx_rd_rev_ftr_lvl_low,
+					   &mqe->un.read_rev);
+	phba->vpd.rev.sli1FwRev = mqe->un.read_rev.fw_id_rev;
+	memcpy(phba->vpd.rev.sli1FwName, mqe->un.read_rev.fw_name, 16);
+	phba->vpd.rev.sli2FwRev = mqe->un.read_rev.ulp_fw_id_rev;
+	memcpy(phba->vpd.rev.sli2FwName, mqe->un.read_rev.ulp_fw_name, 16);
+	phba->vpd.rev.opFwRev = mqe->un.read_rev.fw_id_rev;
+	memcpy(phba->vpd.rev.opFwName, mqe->un.read_rev.fw_name, 16);
+	lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI,
+			"(%d):0380 READ_REV Status x%x "
+			"fw_rev:%s fcphHi:%x fcphLo:%x flHi:%x flLo:%x\n",
+			mboxq->vport ? mboxq->vport->vpi : 0,
+			bf_get(lpfc_mqe_status, mqe),
+			phba->vpd.rev.opFwName,
+			phba->vpd.rev.fcphHigh, phba->vpd.rev.fcphLow,
+			phba->vpd.rev.feaLevelHigh, phba->vpd.rev.feaLevelLow);
 
 	/*
 	 * Discover the port's supported feature set and match it against the
@@ -5030,6 +5030,92 @@
 }
 
 /**
+ * lpfc_sli4_async_mbox_block - Block posting SLI4 asynchronous mailbox command
+ * @phba: Pointer to HBA context object.
+ *
+ * The function blocks the posting of SLI4 asynchronous mailbox commands from
+ * the driver internal pending mailbox queue. It will then try to wait out the
+ * possible outstanding mailbox command before return.
+ *
+ * Returns:
+ * 	0 - the outstanding mailbox command completed; otherwise, the wait for
+ * 	the outstanding mailbox command timed out.
+ **/
+static int
+lpfc_sli4_async_mbox_block(struct lpfc_hba *phba)
+{
+	struct lpfc_sli *psli = &phba->sli;
+	uint8_t actcmd = MBX_HEARTBEAT;
+	int rc = 0;
+	unsigned long timeout;
+
+	/* Mark the asynchronous mailbox command posting as blocked */
+	spin_lock_irq(&phba->hbalock);
+	psli->sli_flag |= LPFC_SLI_ASYNC_MBX_BLK;
+	if (phba->sli.mbox_active)
+		actcmd = phba->sli.mbox_active->u.mb.mbxCommand;
+	spin_unlock_irq(&phba->hbalock);
+	/* Determine how long we might wait for the active mailbox
+	 * command to be gracefully completed by firmware.
+	 */
+	timeout = msecs_to_jiffies(lpfc_mbox_tmo_val(phba, actcmd) * 1000) +
+				   jiffies;
+	/* Wait for the outstnading mailbox command to complete */
+	while (phba->sli.mbox_active) {
+		/* Check active mailbox complete status every 2ms */
+		msleep(2);
+		if (time_after(jiffies, timeout)) {
+			/* Timeout, marked the outstanding cmd not complete */
+			rc = 1;
+			break;
+		}
+	}
+
+	/* Can not cleanly block async mailbox command, fails it */
+	if (rc) {
+		spin_lock_irq(&phba->hbalock);
+		psli->sli_flag &= ~LPFC_SLI_ASYNC_MBX_BLK;
+		spin_unlock_irq(&phba->hbalock);
+	}
+	return rc;
+}
+
+/**
+ * lpfc_sli4_async_mbox_unblock - Block posting SLI4 async mailbox command
+ * @phba: Pointer to HBA context object.
+ *
+ * The function unblocks and resume posting of SLI4 asynchronous mailbox
+ * commands from the driver internal pending mailbox queue. It makes sure
+ * that there is no outstanding mailbox command before resuming posting
+ * asynchronous mailbox commands. If, for any reason, there is outstanding
+ * mailbox command, it will try to wait it out before resuming asynchronous
+ * mailbox command posting.
+ **/
+static void
+lpfc_sli4_async_mbox_unblock(struct lpfc_hba *phba)
+{
+	struct lpfc_sli *psli = &phba->sli;
+
+	spin_lock_irq(&phba->hbalock);
+	if (!(psli->sli_flag & LPFC_SLI_ASYNC_MBX_BLK)) {
+		/* Asynchronous mailbox posting is not blocked, do nothing */
+		spin_unlock_irq(&phba->hbalock);
+		return;
+	}
+
+	/* Outstanding synchronous mailbox command is guaranteed to be done,
+	 * successful or timeout, after timing-out the outstanding mailbox
+	 * command shall always be removed, so just unblock posting async
+	 * mailbox command and resume
+	 */
+	psli->sli_flag &= ~LPFC_SLI_ASYNC_MBX_BLK;
+	spin_unlock_irq(&phba->hbalock);
+
+	/* wake up worker thread to post asynchronlous mailbox command */
+	lpfc_worker_wake_up(phba);
+}
+
+/**
  * lpfc_sli4_post_sync_mbox - Post an SLI4 mailbox to the bootstrap mailbox
  * @phba: Pointer to HBA context object.
  * @mboxq: Pointer to mailbox object.
@@ -5204,14 +5290,35 @@
 					psli->sli_flag, flag);
 		return rc;
 	} else if (flag == MBX_POLL) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
-				"(%d):2542 Mailbox command x%x (x%x) "
-				"cannot issue Data: x%x x%x\n",
+		lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_SLI,
+				"(%d):2542 Try to issue mailbox command "
+				"x%x (x%x) synchronously ahead of async"
+				"mailbox command queue: x%x x%x\n",
 				mboxq->vport ? mboxq->vport->vpi : 0,
 				mboxq->u.mb.mbxCommand,
 				lpfc_sli4_mbox_opcode_get(phba, mboxq),
 				psli->sli_flag, flag);
-		return -EIO;
+		/* Try to block the asynchronous mailbox posting */
+		rc = lpfc_sli4_async_mbox_block(phba);
+		if (!rc) {
+			/* Successfully blocked, now issue sync mbox cmd */
+			rc = lpfc_sli4_post_sync_mbox(phba, mboxq);
+			if (rc != MBX_SUCCESS)
+				lpfc_printf_log(phba, KERN_ERR,
+						LOG_MBOX | LOG_SLI,
+						"(%d):2597 Mailbox command "
+						"x%x (x%x) cannot issue "
+						"Data: x%x x%x\n",
+						mboxq->vport ?
+						mboxq->vport->vpi : 0,
+						mboxq->u.mb.mbxCommand,
+						lpfc_sli4_mbox_opcode_get(phba,
+								mboxq),
+						psli->sli_flag, flag);
+			/* Unblock the async mailbox posting afterward */
+			lpfc_sli4_async_mbox_unblock(phba);
+		}
+		return rc;
 	}
 
 	/* Now, interrupt mode asynchrous mailbox command */
@@ -5814,11 +5921,6 @@
 		bf_set(lpfc_wqe_gen_context, &wqe->generic,
 				iocbq->iocb.ulpContext);
 
-		if (iocbq->vport->fc_myDID != 0) {
-			bf_set(els_req64_sid, &wqe->els_req,
-				 iocbq->vport->fc_myDID);
-			bf_set(els_req64_sp, &wqe->els_req, 1);
-		}
 		bf_set(lpfc_wqe_gen_ct, &wqe->generic, ct);
 		bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0);
 		/* CCP CCPE PV PRI in word10 were set in the memcpy */
@@ -5877,14 +5979,19 @@
 		 * is set and we are sending our 2nd or greater command on
 		 * this exchange.
 		 */
-
-	/* ALLOW read & write to fall through to ICMD64 */
-	case CMD_FCP_ICMND64_CR:
 		/* Always open the exchange */
 		bf_set(wqe_xc, &wqe->fcp_iread.wqe_com, 0);
 
 		wqe->words[10] &= 0xffff0000; /* zero out ebde count */
 		bf_set(lpfc_wqe_gen_pu, &wqe->generic, iocbq->iocb.ulpPU);
+		break;
+	case CMD_FCP_ICMND64_CR:
+		/* Always open the exchange */
+		bf_set(wqe_xc, &wqe->fcp_iread.wqe_com, 0);
+
+		wqe->words[4] = 0;
+		wqe->words[10] &= 0xffff0000; /* zero out ebde count */
+		bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0);
 	break;
 	case CMD_GEN_REQUEST64_CR:
 		/* word3 command length is described as byte offset to the
@@ -11020,10 +11127,7 @@
 	       rpi_page->start_rpi);
 	hdr_tmpl->rpi_paddr_lo = putPaddrLow(rpi_page->dmabuf->phys);
 	hdr_tmpl->rpi_paddr_hi = putPaddrHigh(rpi_page->dmabuf->phys);
-	if (!phba->sli4_hba.intr_enable)
-		rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
-	else
-		rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo);
+	rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
 	shdr = (union lpfc_sli4_cfg_shdr *) &hdr_tmpl->header.cfg_shdr;
 	shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
 	shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);