/*******************************************************************
 * This file is part of the Emulex Linux Device Driver for         *
 * Fibre Channel Host Bus Adapters.                                *
 * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term *
 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.  *
 * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
 * EMULEX and SLI are trademarks of Emulex.                        *
 * www.broadcom.com                                                *
 * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
 *                                                                 *
 * This program is free software; you can redistribute it and/or   *
 * modify it under the terms of version 2 of the GNU General       *
 * Public License as published by the Free Software Foundation.    *
 * This program is distributed in the hope that it will be useful. *
 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
 * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
 * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
 * more details, a copy of which can be found in the file COPYING  *
 * included with this package.                                     *
 *******************************************************************/

#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/idr.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/ctype.h>
#include <linux/aer.h>
#include <linux/slab.h>
#include <linux/firmware.h>
#include <linux/miscdevice.h>
#include <linux/percpu.h>
#include <linux/msi.h>
#include <linux/irq.h>
#include <linux/bitops.h>
#include <linux/crash_dump.h>
#include <linux/cpu.h>
#include <linux/cpuhotplug.h>

#include <scsi/scsi.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport_fc.h>
#include <scsi/scsi_tcq.h>
#include <scsi/fc/fc_fs.h>

#include "lpfc_hw4.h"
#include "lpfc_hw.h"
#include "lpfc_sli.h"
#include "lpfc_sli4.h"
#include "lpfc_nl.h"
#include "lpfc_disc.h"
#include "lpfc.h"
#include "lpfc_scsi.h"
#include "lpfc_nvme.h"
#include "lpfc_logmsg.h"
#include "lpfc_crtn.h"
#include "lpfc_vport.h"
#include "lpfc_version.h"
#include "lpfc_ids.h"

static enum cpuhp_state lpfc_cpuhp_state;
/* Used when mapping IRQ vectors in a driver centric manner */
static uint32_t lpfc_present_cpu;
static bool lpfc_pldv_detect;

static void __lpfc_cpuhp_remove(struct lpfc_hba *phba);
static void lpfc_cpuhp_remove(struct lpfc_hba *phba);
static void lpfc_cpuhp_add(struct lpfc_hba *phba);
static void lpfc_get_hba_model_desc(struct lpfc_hba *, uint8_t *, uint8_t *);
static int lpfc_post_rcv_buf(struct lpfc_hba *);
static int lpfc_sli4_queue_verify(struct lpfc_hba *);
static int lpfc_create_bootstrap_mbox(struct lpfc_hba *);
static int lpfc_setup_endian_order(struct lpfc_hba *);
static void lpfc_destroy_bootstrap_mbox(struct lpfc_hba *);
static void lpfc_free_els_sgl_list(struct lpfc_hba *);
static void lpfc_free_nvmet_sgl_list(struct lpfc_hba *);
static void lpfc_init_sgl_list(struct lpfc_hba *);
static int lpfc_init_active_sgl_array(struct lpfc_hba *);
static void lpfc_free_active_sgl(struct lpfc_hba *);
static int lpfc_hba_down_post_s3(struct lpfc_hba *phba);
static int lpfc_hba_down_post_s4(struct lpfc_hba *phba);
static int lpfc_sli4_cq_event_pool_create(struct lpfc_hba *);
static void lpfc_sli4_cq_event_pool_destroy(struct lpfc_hba *);
static void lpfc_sli4_cq_event_release_all(struct lpfc_hba *);
static void lpfc_sli4_disable_intr(struct lpfc_hba *);
static uint32_t lpfc_sli4_enable_intr(struct lpfc_hba *, uint32_t);
static void lpfc_sli4_oas_verify(struct lpfc_hba *phba);
static uint16_t lpfc_find_cpu_handle(struct lpfc_hba *, uint16_t, int);
static void lpfc_setup_bg(struct lpfc_hba *, struct Scsi_Host *);
static int lpfc_sli4_cgn_parm_chg_evt(struct lpfc_hba *);

static struct scsi_transport_template *lpfc_transport_template = NULL;
static struct scsi_transport_template *lpfc_vport_transport_template = NULL;
static DEFINE_IDR(lpfc_hba_index);
#define LPFC_NVMET_BUF_POST 254
static int lpfc_vmid_res_alloc(struct lpfc_hba *phba, struct lpfc_vport *vport);

/**
 * lpfc_config_port_prep - Perform lpfc initialization prior to config port
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine will do LPFC initialization prior to issuing the CONFIG_PORT
 * mailbox command. It retrieves the revision information from the HBA and
 * collects the Vital Product Data (VPD) about the HBA for preparing the
 * configuration of the HBA.
 *
 * Return codes:
 *   0 - success.
 *   -ERESTART - requests the SLI layer to reset the HBA and try again.
 *   Any other value - indicates an error.
 **/
int
lpfc_config_port_prep(struct lpfc_hba *phba)
{
	lpfc_vpd_t *vp = &phba->vpd;
	int i = 0, rc;
	LPFC_MBOXQ_t *pmb;
	MAILBOX_t *mb;
	char *lpfc_vpd_data = NULL;
	uint16_t offset = 0;
	static char licensed[56] =
		    "key unlock for use with gnu public licensed code only\0";
	static int init_key = 1;

	pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (!pmb) {
		phba->link_state = LPFC_HBA_ERROR;
		return -ENOMEM;
	}

	mb = &pmb->u.mb;
	phba->link_state = LPFC_INIT_MBX_CMDS;

	if (lpfc_is_LC_HBA(phba->pcidev->device)) {
		if (init_key) {
			uint32_t *ptext = (uint32_t *) licensed;

			for (i = 0; i < 56; i += sizeof (uint32_t), ptext++)
				*ptext = cpu_to_be32(*ptext);
			init_key = 0;
		}

		lpfc_read_nv(phba, pmb);
		memset((char*)mb->un.varRDnvp.rsvd3, 0,
			sizeof (mb->un.varRDnvp.rsvd3));
		memcpy((char*)mb->un.varRDnvp.rsvd3, licensed,
			 sizeof (licensed));

		rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);

		if (rc != MBX_SUCCESS) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"0324 Config Port initialization "
					"error, mbxCmd x%x READ_NVPARM, "
					"mbxStatus x%x\n",
					mb->mbxCommand, mb->mbxStatus);
			mempool_free(pmb, phba->mbox_mem_pool);
			return -ERESTART;
		}
		memcpy(phba->wwnn, (char *)mb->un.varRDnvp.nodename,
		       sizeof(phba->wwnn));
		memcpy(phba->wwpn, (char *)mb->un.varRDnvp.portname,
		       sizeof(phba->wwpn));
	}

	/*
	 * Clear all option bits except LPFC_SLI3_BG_ENABLED,
	 * which was already set in lpfc_get_cfgparam()
	 */
	phba->sli3_options &= (uint32_t)LPFC_SLI3_BG_ENABLED;

	/* Setup and issue mailbox READ REV command */
	lpfc_read_rev(phba, pmb);
	rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
	if (rc != MBX_SUCCESS) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0439 Adapter failed to init, mbxCmd x%x "
				"READ_REV, mbxStatus x%x\n",
				mb->mbxCommand, mb->mbxStatus);
		mempool_free( pmb, phba->mbox_mem_pool);
		return -ERESTART;
	}


	/*
	 * The value of rr must be 1 since the driver set the cv field to 1.
	 * This setting requires the FW to set all revision fields.
	 */
	if (mb->un.varRdRev.rr == 0) {
		vp->rev.rBit = 0;
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0440 Adapter failed to init, READ_REV has "
				"missing revision information.\n");
		mempool_free(pmb, phba->mbox_mem_pool);
		return -ERESTART;
	}

	if (phba->sli_rev == 3 && !mb->un.varRdRev.v3rsp) {
		mempool_free(pmb, phba->mbox_mem_pool);
		return -EINVAL;
	}

	/* Save information as VPD data */
	vp->rev.rBit = 1;
	memcpy(&vp->sli3Feat, &mb->un.varRdRev.sli3Feat, sizeof(uint32_t));
	vp->rev.sli1FwRev = mb->un.varRdRev.sli1FwRev;
	memcpy(vp->rev.sli1FwName, (char*) mb->un.varRdRev.sli1FwName, 16);
	vp->rev.sli2FwRev = mb->un.varRdRev.sli2FwRev;
	memcpy(vp->rev.sli2FwName, (char *) mb->un.varRdRev.sli2FwName, 16);
	vp->rev.biuRev = mb->un.varRdRev.biuRev;
	vp->rev.smRev = mb->un.varRdRev.smRev;
	vp->rev.smFwRev = mb->un.varRdRev.un.smFwRev;
	vp->rev.endecRev = mb->un.varRdRev.endecRev;
	vp->rev.fcphHigh = mb->un.varRdRev.fcphHigh;
	vp->rev.fcphLow = mb->un.varRdRev.fcphLow;
	vp->rev.feaLevelHigh = mb->un.varRdRev.feaLevelHigh;
	vp->rev.feaLevelLow = mb->un.varRdRev.feaLevelLow;
	vp->rev.postKernRev = mb->un.varRdRev.postKernRev;
	vp->rev.opFwRev = mb->un.varRdRev.opFwRev;

	/* If the sli feature level is less then 9, we must
	 * tear down all RPIs and VPIs on link down if NPIV
	 * is enabled.
	 */
	if (vp->rev.feaLevelHigh < 9)
		phba->sli3_options |= LPFC_SLI3_VPORT_TEARDOWN;

	if (lpfc_is_LC_HBA(phba->pcidev->device))
		memcpy(phba->RandomData, (char *)&mb->un.varWords[24],
						sizeof (phba->RandomData));

	/* Get adapter VPD information */
	lpfc_vpd_data = kmalloc(DMP_VPD_SIZE, GFP_KERNEL);
	if (!lpfc_vpd_data)
		goto out_free_mbox;
	do {
		lpfc_dump_mem(phba, pmb, offset, DMP_REGION_VPD);
		rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);

		if (rc != MBX_SUCCESS) {
			lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
					"0441 VPD not present on adapter, "
					"mbxCmd x%x DUMP VPD, mbxStatus x%x\n",
					mb->mbxCommand, mb->mbxStatus);
			mb->un.varDmp.word_cnt = 0;
		}
		/* dump mem may return a zero when finished or we got a
		 * mailbox error, either way we are done.
		 */
		if (mb->un.varDmp.word_cnt == 0)
			break;

		if (mb->un.varDmp.word_cnt > DMP_VPD_SIZE - offset)
			mb->un.varDmp.word_cnt = DMP_VPD_SIZE - offset;
		lpfc_sli_pcimem_bcopy(((uint8_t *)mb) + DMP_RSP_OFFSET,
				      lpfc_vpd_data + offset,
				      mb->un.varDmp.word_cnt);
		offset += mb->un.varDmp.word_cnt;
	} while (mb->un.varDmp.word_cnt && offset < DMP_VPD_SIZE);

	lpfc_parse_vpd(phba, lpfc_vpd_data, offset);

	kfree(lpfc_vpd_data);
out_free_mbox:
	mempool_free(pmb, phba->mbox_mem_pool);
	return 0;
}

/**
 * lpfc_config_async_cmpl - Completion handler for config async event mbox cmd
 * @phba: pointer to lpfc hba data structure.
 * @pmboxq: pointer to the driver internal queue element for mailbox command.
 *
 * This is the completion handler for driver's configuring asynchronous event
 * mailbox command to the device. If the mailbox command returns successfully,
 * it will set internal async event support flag to 1; otherwise, it will
 * set internal async event support flag to 0.
 **/
static void
lpfc_config_async_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq)
{
	if (pmboxq->u.mb.mbxStatus == MBX_SUCCESS)
		phba->temp_sensor_support = 1;
	else
		phba->temp_sensor_support = 0;
	mempool_free(pmboxq, phba->mbox_mem_pool);
	return;
}

/**
 * lpfc_dump_wakeup_param_cmpl - dump memory mailbox command completion handler
 * @phba: pointer to lpfc hba data structure.
 * @pmboxq: pointer to the driver internal queue element for mailbox command.
 *
 * This is the completion handler for dump mailbox command for getting
 * wake up parameters. When this command complete, the response contain
 * Option rom version of the HBA. This function translate the version number
 * into a human readable string and store it in OptionROMVersion.
 **/
static void
lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
{
	struct prog_id *prg;
	uint32_t prog_id_word;
	char dist = ' ';
	/* character array used for decoding dist type. */
	char dist_char[] = "nabx";

	if (pmboxq->u.mb.mbxStatus != MBX_SUCCESS) {
		mempool_free(pmboxq, phba->mbox_mem_pool);
		return;
	}

	prg = (struct prog_id *) &prog_id_word;

	/* word 7 contain option rom version */
	prog_id_word = pmboxq->u.mb.un.varWords[7];

	/* Decode the Option rom version word to a readable string */
	if (prg->dist < 4)
		dist = dist_char[prg->dist];

	if ((prg->dist == 3) && (prg->num == 0))
		snprintf(phba->OptionROMVersion, 32, "%d.%d%d",
			prg->ver, prg->rev, prg->lev);
	else
		snprintf(phba->OptionROMVersion, 32, "%d.%d%d%c%d",
			prg->ver, prg->rev, prg->lev,
			dist, prg->num);
	mempool_free(pmboxq, phba->mbox_mem_pool);
	return;
}

/**
 * lpfc_update_vport_wwn - Updates the fc_nodename, fc_portname,
 *	cfg_soft_wwnn, cfg_soft_wwpn
 * @vport: pointer to lpfc vport data structure.
 *
 *
 * Return codes
 *   None.
 **/
void
lpfc_update_vport_wwn(struct lpfc_vport *vport)
{
	uint8_t vvvl = vport->fc_sparam.cmn.valid_vendor_ver_level;
	u32 *fawwpn_key = (u32 *)&vport->fc_sparam.un.vendorVersion[0];

	/* If the soft name exists then update it using the service params */
	if (vport->phba->cfg_soft_wwnn)
		u64_to_wwn(vport->phba->cfg_soft_wwnn,
			   vport->fc_sparam.nodeName.u.wwn);
	if (vport->phba->cfg_soft_wwpn)
		u64_to_wwn(vport->phba->cfg_soft_wwpn,
			   vport->fc_sparam.portName.u.wwn);

	/*
	 * If the name is empty or there exists a soft name
	 * then copy the service params name, otherwise use the fc name
	 */
	if (vport->fc_nodename.u.wwn[0] == 0 || vport->phba->cfg_soft_wwnn)
		memcpy(&vport->fc_nodename, &vport->fc_sparam.nodeName,
			sizeof(struct lpfc_name));
	else
		memcpy(&vport->fc_sparam.nodeName, &vport->fc_nodename,
			sizeof(struct lpfc_name));

	/*
	 * If the port name has changed, then set the Param changes flag
	 * to unreg the login
	 */
	if (vport->fc_portname.u.wwn[0] != 0 &&
		memcmp(&vport->fc_portname, &vport->fc_sparam.portName,
			sizeof(struct lpfc_name)))
		vport->vport_flag |= FAWWPN_PARAM_CHG;

	if (vport->fc_portname.u.wwn[0] == 0 ||
	    vport->phba->cfg_soft_wwpn ||
	    (vvvl == 1 && cpu_to_be32(*fawwpn_key) == FAPWWN_KEY_VENDOR) ||
	    vport->vport_flag & FAWWPN_SET) {
		memcpy(&vport->fc_portname, &vport->fc_sparam.portName,
			sizeof(struct lpfc_name));
		vport->vport_flag &= ~FAWWPN_SET;
		if (vvvl == 1 && cpu_to_be32(*fawwpn_key) == FAPWWN_KEY_VENDOR)
			vport->vport_flag |= FAWWPN_SET;
	}
	else
		memcpy(&vport->fc_sparam.portName, &vport->fc_portname,
			sizeof(struct lpfc_name));
}

/**
 * lpfc_config_port_post - Perform lpfc initialization after config port
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine will do LPFC initialization after the CONFIG_PORT mailbox
 * command call. It performs all internal resource and state setups on the
 * port: post IOCB buffers, enable appropriate host interrupt attentions,
 * ELS ring timers, etc.
 *
 * Return codes
 *   0 - success.
 *   Any other value - error.
 **/
int
lpfc_config_port_post(struct lpfc_hba *phba)
{
	struct lpfc_vport *vport = phba->pport;
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
	LPFC_MBOXQ_t *pmb;
	MAILBOX_t *mb;
	struct lpfc_dmabuf *mp;
	struct lpfc_sli *psli = &phba->sli;
	uint32_t status, timeout;
	int i, j;
	int rc;

	spin_lock_irq(&phba->hbalock);
	/*
	 * If the Config port completed correctly the HBA is not
	 * over heated any more.
	 */
	if (phba->over_temp_state == HBA_OVER_TEMP)
		phba->over_temp_state = HBA_NORMAL_TEMP;
	spin_unlock_irq(&phba->hbalock);

	pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (!pmb) {
		phba->link_state = LPFC_HBA_ERROR;
		return -ENOMEM;
	}
	mb = &pmb->u.mb;

	/* Get login parameters for NID.  */
	rc = lpfc_read_sparam(phba, pmb, 0);
	if (rc) {
		mempool_free(pmb, phba->mbox_mem_pool);
		return -ENOMEM;
	}

	pmb->vport = vport;
	if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0448 Adapter failed init, mbxCmd x%x "
				"READ_SPARM mbxStatus x%x\n",
				mb->mbxCommand, mb->mbxStatus);
		phba->link_state = LPFC_HBA_ERROR;
		mp = (struct lpfc_dmabuf *)pmb->ctx_buf;
		mempool_free(pmb, phba->mbox_mem_pool);
		lpfc_mbuf_free(phba, mp->virt, mp->phys);
		kfree(mp);
		return -EIO;
	}

	mp = (struct lpfc_dmabuf *)pmb->ctx_buf;

	memcpy(&vport->fc_sparam, mp->virt, sizeof (struct serv_parm));
	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	kfree(mp);
	pmb->ctx_buf = NULL;
	lpfc_update_vport_wwn(vport);

	/* Update the fc_host data structures with new wwn. */
	fc_host_node_name(shost) = wwn_to_u64(vport->fc_nodename.u.wwn);
	fc_host_port_name(shost) = wwn_to_u64(vport->fc_portname.u.wwn);
	fc_host_max_npiv_vports(shost) = phba->max_vpi;

	/* If no serial number in VPD data, use low 6 bytes of WWNN */
	/* This should be consolidated into parse_vpd ? - mr */
	if (phba->SerialNumber[0] == 0) {
		uint8_t *outptr;

		outptr = &vport->fc_nodename.u.s.IEEE[0];
		for (i = 0; i < 12; i++) {
			status = *outptr++;
			j = ((status & 0xf0) >> 4);
			if (j <= 9)
				phba->SerialNumber[i] =
				    (char)((uint8_t) 0x30 + (uint8_t) j);
			else
				phba->SerialNumber[i] =
				    (char)((uint8_t) 0x61 + (uint8_t) (j - 10));
			i++;
			j = (status & 0xf);
			if (j <= 9)
				phba->SerialNumber[i] =
				    (char)((uint8_t) 0x30 + (uint8_t) j);
			else
				phba->SerialNumber[i] =
				    (char)((uint8_t) 0x61 + (uint8_t) (j - 10));
		}
	}

	lpfc_read_config(phba, pmb);
	pmb->vport = vport;
	if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0453 Adapter failed to init, mbxCmd x%x "
				"READ_CONFIG, mbxStatus x%x\n",
				mb->mbxCommand, mb->mbxStatus);
		phba->link_state = LPFC_HBA_ERROR;
		mempool_free( pmb, phba->mbox_mem_pool);
		return -EIO;
	}

	/* Check if the port is disabled */
	lpfc_sli_read_link_ste(phba);

	/* Reset the DFT_HBA_Q_DEPTH to the max xri  */
	if (phba->cfg_hba_queue_depth > mb->un.varRdConfig.max_xri) {
		lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
				"3359 HBA queue depth changed from %d to %d\n",
				phba->cfg_hba_queue_depth,
				mb->un.varRdConfig.max_xri);
		phba->cfg_hba_queue_depth = mb->un.varRdConfig.max_xri;
	}

	phba->lmt = mb->un.varRdConfig.lmt;

	/* Get the default values for Model Name and Description */
	lpfc_get_hba_model_desc(phba, phba->ModelName, phba->ModelDesc);

	phba->link_state = LPFC_LINK_DOWN;

	/* Only process IOCBs on ELS ring till hba_state is READY */
	if (psli->sli3_ring[LPFC_EXTRA_RING].sli.sli3.cmdringaddr)
		psli->sli3_ring[LPFC_EXTRA_RING].flag |= LPFC_STOP_IOCB_EVENT;
	if (psli->sli3_ring[LPFC_FCP_RING].sli.sli3.cmdringaddr)
		psli->sli3_ring[LPFC_FCP_RING].flag |= LPFC_STOP_IOCB_EVENT;

	/* Post receive buffers for desired rings */
	if (phba->sli_rev != 3)
		lpfc_post_rcv_buf(phba);

	/*
	 * Configure HBA MSI-X attention conditions to messages if MSI-X mode
	 */
	if (phba->intr_type == MSIX) {
		rc = lpfc_config_msi(phba, pmb);
		if (rc) {
			mempool_free(pmb, phba->mbox_mem_pool);
			return -EIO;
		}
		rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
		if (rc != MBX_SUCCESS) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"0352 Config MSI mailbox command "
					"failed, mbxCmd x%x, mbxStatus x%x\n",
					pmb->u.mb.mbxCommand,
					pmb->u.mb.mbxStatus);
			mempool_free(pmb, phba->mbox_mem_pool);
			return -EIO;
		}
	}

	spin_lock_irq(&phba->hbalock);
	/* Initialize ERATT handling flag */
	phba->hba_flag &= ~HBA_ERATT_HANDLED;

	/* Enable appropriate host interrupts */
	if (lpfc_readl(phba->HCregaddr, &status)) {
		spin_unlock_irq(&phba->hbalock);
		return -EIO;
	}
	status |= HC_MBINT_ENA | HC_ERINT_ENA | HC_LAINT_ENA;
	if (psli->num_rings > 0)
		status |= HC_R0INT_ENA;
	if (psli->num_rings > 1)
		status |= HC_R1INT_ENA;
	if (psli->num_rings > 2)
		status |= HC_R2INT_ENA;
	if (psli->num_rings > 3)
		status |= HC_R3INT_ENA;

	if ((phba->cfg_poll & ENABLE_FCP_RING_POLLING) &&
	    (phba->cfg_poll & DISABLE_FCP_RING_INT))
		status &= ~(HC_R0INT_ENA);

	writel(status, phba->HCregaddr);
	readl(phba->HCregaddr); /* flush */
	spin_unlock_irq(&phba->hbalock);

	/* Set up ring-0 (ELS) timer */
	timeout = phba->fc_ratov * 2;
	mod_timer(&vport->els_tmofunc,
		  jiffies + msecs_to_jiffies(1000 * timeout));
	/* Set up heart beat (HB) timer */
	mod_timer(&phba->hb_tmofunc,
		  jiffies + msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL));
	phba->hba_flag &= ~(HBA_HBEAT_INP | HBA_HBEAT_TMO);
	phba->last_completion_time = jiffies;
	/* Set up error attention (ERATT) polling timer */
	mod_timer(&phba->eratt_poll,
		  jiffies + msecs_to_jiffies(1000 * phba->eratt_poll_interval));

	if (phba->hba_flag & LINK_DISABLED) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2598 Adapter Link is disabled.\n");
		lpfc_down_link(phba, pmb);
		pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
		rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
		if ((rc != MBX_SUCCESS) && (rc != MBX_BUSY)) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"2599 Adapter failed to issue DOWN_LINK"
					" mbox command rc 0x%x\n", rc);

			mempool_free(pmb, phba->mbox_mem_pool);
			return -EIO;
		}
	} else if (phba->cfg_suppress_link_up == LPFC_INITIALIZE_LINK) {
		mempool_free(pmb, phba->mbox_mem_pool);
		rc = phba->lpfc_hba_init_link(phba, MBX_NOWAIT);
		if (rc)
			return rc;
	}
	/* MBOX buffer will be freed in mbox compl */
	pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (!pmb) {
		phba->link_state = LPFC_HBA_ERROR;
		return -ENOMEM;
	}

	lpfc_config_async(phba, pmb, LPFC_ELS_RING);
	pmb->mbox_cmpl = lpfc_config_async_cmpl;
	pmb->vport = phba->pport;
	rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);

	if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0456 Adapter failed to issue "
				"ASYNCEVT_ENABLE mbox status x%x\n",
				rc);
		mempool_free(pmb, phba->mbox_mem_pool);
	}

	/* Get Option rom version */
	pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (!pmb) {
		phba->link_state = LPFC_HBA_ERROR;
		return -ENOMEM;
	}

	lpfc_dump_wakeup_param(phba, pmb);
	pmb->mbox_cmpl = lpfc_dump_wakeup_param_cmpl;
	pmb->vport = phba->pport;
	rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);

	if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0435 Adapter failed "
				"to get Option ROM version status x%x\n", rc);
		mempool_free(pmb, phba->mbox_mem_pool);
	}

	return 0;
}

/**
 * lpfc_sli4_refresh_params - update driver copy of params.
 * @phba: Pointer to HBA context object.
 *
 * This is called to refresh driver copy of dynamic fields from the
 * common_get_sli4_parameters descriptor.
 **/
int
lpfc_sli4_refresh_params(struct lpfc_hba *phba)
{
	LPFC_MBOXQ_t *mboxq;
	struct lpfc_mqe *mqe;
	struct lpfc_sli4_parameters *mbx_sli4_parameters;
	int length, rc;

	mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (!mboxq)
		return -ENOMEM;

	mqe = &mboxq->u.mqe;
	/* Read the port's SLI4 Config Parameters */
	length = (sizeof(struct lpfc_mbx_get_sli4_parameters) -
		  sizeof(struct lpfc_sli4_cfg_mhdr));
	lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
			 LPFC_MBOX_OPCODE_GET_SLI4_PARAMETERS,
			 length, LPFC_SLI4_MBX_EMBED);

	rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
	if (unlikely(rc)) {
		mempool_free(mboxq, phba->mbox_mem_pool);
		return rc;
	}
	mbx_sli4_parameters = &mqe->un.get_sli4_parameters.sli4_parameters;
	phba->sli4_hba.pc_sli4_params.mi_ver =
			bf_get(cfg_mi_ver, mbx_sli4_parameters);
	phba->sli4_hba.pc_sli4_params.cmf =
			bf_get(cfg_cmf, mbx_sli4_parameters);
	phba->sli4_hba.pc_sli4_params.pls =
			bf_get(cfg_pvl, mbx_sli4_parameters);

	mempool_free(mboxq, phba->mbox_mem_pool);
	return rc;
}

/**
 * lpfc_hba_init_link - Initialize the FC link
 * @phba: pointer to lpfc hba data structure.
 * @flag: mailbox command issue mode - either MBX_POLL or MBX_NOWAIT
 *
 * This routine will issue the INIT_LINK mailbox command call.
 * It is available to other drivers through the lpfc_hba data
 * structure for use as a delayed link up mechanism with the
 * module parameter lpfc_suppress_link_up.
 *
 * Return code
 *		0 - success
 *		Any other value - error
 **/
static int
lpfc_hba_init_link(struct lpfc_hba *phba, uint32_t flag)
{
	return lpfc_hba_init_link_fc_topology(phba, phba->cfg_topology, flag);
}

/**
 * lpfc_hba_init_link_fc_topology - Initialize FC link with desired topology
 * @phba: pointer to lpfc hba data structure.
 * @fc_topology: desired fc topology.
 * @flag: mailbox command issue mode - either MBX_POLL or MBX_NOWAIT
 *
 * This routine will issue the INIT_LINK mailbox command call.
 * It is available to other drivers through the lpfc_hba data
 * structure for use as a delayed link up mechanism with the
 * module parameter lpfc_suppress_link_up.
 *
 * Return code
 *              0 - success
 *              Any other value - error
 **/
int
lpfc_hba_init_link_fc_topology(struct lpfc_hba *phba, uint32_t fc_topology,
			       uint32_t flag)
{
	struct lpfc_vport *vport = phba->pport;
	LPFC_MBOXQ_t *pmb;
	MAILBOX_t *mb;
	int rc;

	pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (!pmb) {
		phba->link_state = LPFC_HBA_ERROR;
		return -ENOMEM;
	}
	mb = &pmb->u.mb;
	pmb->vport = vport;

	if ((phba->cfg_link_speed > LPFC_USER_LINK_SPEED_MAX) ||
	    ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_1G) &&
	     !(phba->lmt & LMT_1Gb)) ||
	    ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_2G) &&
	     !(phba->lmt & LMT_2Gb)) ||
	    ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_4G) &&
	     !(phba->lmt & LMT_4Gb)) ||
	    ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_8G) &&
	     !(phba->lmt & LMT_8Gb)) ||
	    ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_10G) &&
	     !(phba->lmt & LMT_10Gb)) ||
	    ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G) &&
	     !(phba->lmt & LMT_16Gb)) ||
	    ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_32G) &&
	     !(phba->lmt & LMT_32Gb)) ||
	    ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_64G) &&
	     !(phba->lmt & LMT_64Gb))) {
		/* Reset link speed to auto */
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"1302 Invalid speed for this board:%d "
				"Reset link speed to auto.\n",
				phba->cfg_link_speed);
			phba->cfg_link_speed = LPFC_USER_LINK_SPEED_AUTO;
	}
	lpfc_init_link(phba, pmb, fc_topology, phba->cfg_link_speed);
	pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
	if (phba->sli_rev < LPFC_SLI_REV4)
		lpfc_set_loopback_flag(phba);
	rc = lpfc_sli_issue_mbox(phba, pmb, flag);
	if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0498 Adapter failed to init, mbxCmd x%x "
				"INIT_LINK, mbxStatus x%x\n",
				mb->mbxCommand, mb->mbxStatus);
		if (phba->sli_rev <= LPFC_SLI_REV3) {
			/* Clear all interrupt enable conditions */
			writel(0, phba->HCregaddr);
			readl(phba->HCregaddr); /* flush */
			/* Clear all pending interrupts */
			writel(0xffffffff, phba->HAregaddr);
			readl(phba->HAregaddr); /* flush */
		}
		phba->link_state = LPFC_HBA_ERROR;
		if (rc != MBX_BUSY || flag == MBX_POLL)
			mempool_free(pmb, phba->mbox_mem_pool);
		return -EIO;
	}
	phba->cfg_suppress_link_up = LPFC_INITIALIZE_LINK;
	if (flag == MBX_POLL)
		mempool_free(pmb, phba->mbox_mem_pool);

	return 0;
}

/**
 * lpfc_hba_down_link - this routine downs the FC link
 * @phba: pointer to lpfc hba data structure.
 * @flag: mailbox command issue mode - either MBX_POLL or MBX_NOWAIT
 *
 * This routine will issue the DOWN_LINK mailbox command call.
 * It is available to other drivers through the lpfc_hba data
 * structure for use to stop the link.
 *
 * Return code
 *		0 - success
 *		Any other value - error
 **/
static int
lpfc_hba_down_link(struct lpfc_hba *phba, uint32_t flag)
{
	LPFC_MBOXQ_t *pmb;
	int rc;

	pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (!pmb) {
		phba->link_state = LPFC_HBA_ERROR;
		return -ENOMEM;
	}

	lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
			"0491 Adapter Link is disabled.\n");
	lpfc_down_link(phba, pmb);
	pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
	rc = lpfc_sli_issue_mbox(phba, pmb, flag);
	if ((rc != MBX_SUCCESS) && (rc != MBX_BUSY)) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2522 Adapter failed to issue DOWN_LINK"
				" mbox command rc 0x%x\n", rc);

		mempool_free(pmb, phba->mbox_mem_pool);
		return -EIO;
	}
	if (flag == MBX_POLL)
		mempool_free(pmb, phba->mbox_mem_pool);

	return 0;
}

/**
 * lpfc_hba_down_prep - Perform lpfc uninitialization prior to HBA reset
 * @phba: pointer to lpfc HBA data structure.
 *
 * This routine will do LPFC uninitialization before the HBA is reset when
 * bringing down the SLI Layer.
 *
 * Return codes
 *   0 - success.
 *   Any other value - error.
 **/
int
lpfc_hba_down_prep(struct lpfc_hba *phba)
{
	struct lpfc_vport **vports;
	int i;

	if (phba->sli_rev <= LPFC_SLI_REV3) {
		/* Disable interrupts */
		writel(0, phba->HCregaddr);
		readl(phba->HCregaddr); /* flush */
	}

	if (phba->pport->load_flag & FC_UNLOADING)
		lpfc_cleanup_discovery_resources(phba->pport);
	else {
		vports = lpfc_create_vport_work_array(phba);
		if (vports != NULL)
			for (i = 0; i <= phba->max_vports &&
				vports[i] != NULL; i++)
				lpfc_cleanup_discovery_resources(vports[i]);
		lpfc_destroy_vport_work_array(phba, vports);
	}
	return 0;
}

/**
 * lpfc_sli4_free_sp_events - Cleanup sp_queue_events to free
 * rspiocb which got deferred
 *
 * @phba: pointer to lpfc HBA data structure.
 *
 * This routine will cleanup completed slow path events after HBA is reset
 * when bringing down the SLI Layer.
 *
 *
 * Return codes
 *   void.
 **/
static void
lpfc_sli4_free_sp_events(struct lpfc_hba *phba)
{
	struct lpfc_iocbq *rspiocbq;
	struct hbq_dmabuf *dmabuf;
	struct lpfc_cq_event *cq_event;

	spin_lock_irq(&phba->hbalock);
	phba->hba_flag &= ~HBA_SP_QUEUE_EVT;
	spin_unlock_irq(&phba->hbalock);

	while (!list_empty(&phba->sli4_hba.sp_queue_event)) {
		/* Get the response iocb from the head of work queue */
		spin_lock_irq(&phba->hbalock);
		list_remove_head(&phba->sli4_hba.sp_queue_event,
				 cq_event, struct lpfc_cq_event, list);
		spin_unlock_irq(&phba->hbalock);

		switch (bf_get(lpfc_wcqe_c_code, &cq_event->cqe.wcqe_cmpl)) {
		case CQE_CODE_COMPL_WQE:
			rspiocbq = container_of(cq_event, struct lpfc_iocbq,
						 cq_event);
			lpfc_sli_release_iocbq(phba, rspiocbq);
			break;
		case CQE_CODE_RECEIVE:
		case CQE_CODE_RECEIVE_V1:
			dmabuf = container_of(cq_event, struct hbq_dmabuf,
					      cq_event);
			lpfc_in_buf_free(phba, &dmabuf->dbuf);
		}
	}
}

/**
 * lpfc_hba_free_post_buf - Perform lpfc uninitialization after HBA reset
 * @phba: pointer to lpfc HBA data structure.
 *
 * This routine will cleanup posted ELS buffers after the HBA is reset
 * when bringing down the SLI Layer.
 *
 *
 * Return codes
 *   void.
 **/
static void
lpfc_hba_free_post_buf(struct lpfc_hba *phba)
{
	struct lpfc_sli *psli = &phba->sli;
	struct lpfc_sli_ring *pring;
	struct lpfc_dmabuf *mp, *next_mp;
	LIST_HEAD(buflist);
	int count;

	if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)
		lpfc_sli_hbqbuf_free_all(phba);
	else {
		/* Cleanup preposted buffers on the ELS ring */
		pring = &psli->sli3_ring[LPFC_ELS_RING];
		spin_lock_irq(&phba->hbalock);
		list_splice_init(&pring->postbufq, &buflist);
		spin_unlock_irq(&phba->hbalock);

		count = 0;
		list_for_each_entry_safe(mp, next_mp, &buflist, list) {
			list_del(&mp->list);
			count++;
			lpfc_mbuf_free(phba, mp->virt, mp->phys);
			kfree(mp);
		}

		spin_lock_irq(&phba->hbalock);
		pring->postbufq_cnt -= count;
		spin_unlock_irq(&phba->hbalock);
	}
}

/**
 * lpfc_hba_clean_txcmplq - Perform lpfc uninitialization after HBA reset
 * @phba: pointer to lpfc HBA data structure.
 *
 * This routine will cleanup the txcmplq after the HBA is reset when bringing
 * down the SLI Layer.
 *
 * Return codes
 *   void
 **/
static void
lpfc_hba_clean_txcmplq(struct lpfc_hba *phba)
{
	struct lpfc_sli *psli = &phba->sli;
	struct lpfc_queue *qp = NULL;
	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++) {
			pring = &psli->sli3_ring[i];
			spin_lock_irq(&phba->hbalock);
			/* At this point in time the HBA is either reset or DOA
			 * Nothing should be on txcmplq as it will
			 * NEVER complete.
			 */
			list_splice_init(&pring->txcmplq, &completions);
			pring->txcmplq_cnt = 0;
			spin_unlock_irq(&phba->hbalock);

			lpfc_sli_abort_iocb_ring(phba, pring);
		}
		/* Cancel all the IOCBs from the completions list */
		lpfc_sli_cancel_iocbs(phba, &completions,
				      IOSTAT_LOCAL_REJECT, IOERR_SLI_ABORTED);
		return;
	}
	list_for_each_entry(qp, &phba->sli4_hba.lpfc_wq_list, wq_list) {
		pring = qp->pring;
		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);
		lpfc_sli_abort_iocb_ring(phba, pring);
	}
	/* Cancel all the IOCBs from the completions list */
	lpfc_sli_cancel_iocbs(phba, &completions,
			      IOSTAT_LOCAL_REJECT, IOERR_SLI_ABORTED);
}

/**
 * lpfc_hba_down_post_s3 - Perform lpfc uninitialization after HBA reset
 * @phba: pointer to lpfc HBA data structure.
 *
 * This routine will do uninitialization after the HBA is reset when bring
 * down the SLI Layer.
 *
 * Return codes
 *   0 - success.
 *   Any other value - error.
 **/
static int
lpfc_hba_down_post_s3(struct lpfc_hba *phba)
{
	lpfc_hba_free_post_buf(phba);
	lpfc_hba_clean_txcmplq(phba);
	return 0;
}

/**
 * lpfc_hba_down_post_s4 - Perform lpfc uninitialization after HBA reset
 * @phba: pointer to lpfc HBA data structure.
 *
 * This routine will do uninitialization after the HBA is reset when bring
 * down the SLI Layer.
 *
 * Return codes
 *   0 - success.
 *   Any other value - error.
 **/
static int
lpfc_hba_down_post_s4(struct lpfc_hba *phba)
{
	struct lpfc_io_buf *psb, *psb_next;
	struct lpfc_async_xchg_ctx *ctxp, *ctxp_next;
	struct lpfc_sli4_hdw_queue *qp;
	LIST_HEAD(aborts);
	LIST_HEAD(nvme_aborts);
	LIST_HEAD(nvmet_aborts);
	struct lpfc_sglq *sglq_entry = NULL;
	int cnt, idx;


	lpfc_sli_hbqbuf_free_all(phba);
	lpfc_hba_clean_txcmplq(phba);

	/* At this point in time the HBA is either reset or DOA. Either
	 * way, nothing should be on lpfc_abts_els_sgl_list, it needs to be
	 * on the lpfc_els_sgl_list so that it can either be freed if the
	 * driver is unloading or reposted if the driver is restarting
	 * the port.
	 */

	/* sgl_list_lock required because worker thread uses this
	 * list.
	 */
	spin_lock_irq(&phba->sli4_hba.sgl_list_lock);
	list_for_each_entry(sglq_entry,
		&phba->sli4_hba.lpfc_abts_els_sgl_list, list)
		sglq_entry->state = SGL_FREED;

	list_splice_init(&phba->sli4_hba.lpfc_abts_els_sgl_list,
			&phba->sli4_hba.lpfc_els_sgl_list);


	spin_unlock_irq(&phba->sli4_hba.sgl_list_lock);

	/* abts_xxxx_buf_list_lock required because worker thread uses this
	 * list.
	 */
	spin_lock_irq(&phba->hbalock);
	cnt = 0;
	for (idx = 0; idx < phba->cfg_hdw_queue; idx++) {
		qp = &phba->sli4_hba.hdwq[idx];

		spin_lock(&qp->abts_io_buf_list_lock);
		list_splice_init(&qp->lpfc_abts_io_buf_list,
				 &aborts);

		list_for_each_entry_safe(psb, psb_next, &aborts, list) {
			psb->pCmd = NULL;
			psb->status = IOSTAT_SUCCESS;
			cnt++;
		}
		spin_lock(&qp->io_buf_list_put_lock);
		list_splice_init(&aborts, &qp->lpfc_io_buf_list_put);
		qp->put_io_bufs += qp->abts_scsi_io_bufs;
		qp->put_io_bufs += qp->abts_nvme_io_bufs;
		qp->abts_scsi_io_bufs = 0;
		qp->abts_nvme_io_bufs = 0;
		spin_unlock(&qp->io_buf_list_put_lock);
		spin_unlock(&qp->abts_io_buf_list_lock);
	}
	spin_unlock_irq(&phba->hbalock);

	if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
		spin_lock_irq(&phba->sli4_hba.abts_nvmet_buf_list_lock);
		list_splice_init(&phba->sli4_hba.lpfc_abts_nvmet_ctx_list,
				 &nvmet_aborts);
		spin_unlock_irq(&phba->sli4_hba.abts_nvmet_buf_list_lock);
		list_for_each_entry_safe(ctxp, ctxp_next, &nvmet_aborts, list) {
			ctxp->flag &= ~(LPFC_NVME_XBUSY | LPFC_NVME_ABORT_OP);
			lpfc_nvmet_ctxbuf_post(phba, ctxp->ctxbuf);
		}
	}

	lpfc_sli4_free_sp_events(phba);
	return cnt;
}

/**
 * lpfc_hba_down_post - Wrapper func for hba down post routine
 * @phba: pointer to lpfc HBA data structure.
 *
 * This routine wraps the actual SLI3 or SLI4 routine for performing
 * uninitialization after the HBA is reset when bring down the SLI Layer.
 *
 * Return codes
 *   0 - success.
 *   Any other value - error.
 **/
int
lpfc_hba_down_post(struct lpfc_hba *phba)
{
	return (*phba->lpfc_hba_down_post)(phba);
}

/**
 * lpfc_hb_timeout - The HBA-timer timeout handler
 * @t: timer context used to obtain the pointer to lpfc hba data structure.
 *
 * This is the HBA-timer timeout handler registered to the lpfc driver. When
 * this timer fires, a HBA timeout event shall be posted to the lpfc driver
 * work-port-events bitmap and the worker thread is notified. This timeout
 * event will be used by the worker thread to invoke the actual timeout
 * handler routine, lpfc_hb_timeout_handler. Any periodical operations will
 * be performed in the timeout handler and the HBA timeout event bit shall
 * be cleared by the worker thread after it has taken the event bitmap out.
 **/
static void
lpfc_hb_timeout(struct timer_list *t)
{
	struct lpfc_hba *phba;
	uint32_t tmo_posted;
	unsigned long iflag;

	phba = from_timer(phba, t, hb_tmofunc);

	/* Check for heart beat timeout conditions */
	spin_lock_irqsave(&phba->pport->work_port_lock, iflag);
	tmo_posted = phba->pport->work_port_events & WORKER_HB_TMO;
	if (!tmo_posted)
		phba->pport->work_port_events |= WORKER_HB_TMO;
	spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag);

	/* Tell the worker thread there is work to do */
	if (!tmo_posted)
		lpfc_worker_wake_up(phba);
	return;
}

/**
 * lpfc_rrq_timeout - The RRQ-timer timeout handler
 * @t: timer context used to obtain the pointer to lpfc hba data structure.
 *
 * This is the RRQ-timer timeout handler registered to the lpfc driver. When
 * this timer fires, a RRQ timeout event shall be posted to the lpfc driver
 * work-port-events bitmap and the worker thread is notified. This timeout
 * event will be used by the worker thread to invoke the actual timeout
 * handler routine, lpfc_rrq_handler. Any periodical operations will
 * be performed in the timeout handler and the RRQ timeout event bit shall
 * be cleared by the worker thread after it has taken the event bitmap out.
 **/
static void
lpfc_rrq_timeout(struct timer_list *t)
{
	struct lpfc_hba *phba;
	unsigned long iflag;

	phba = from_timer(phba, t, rrq_tmr);
	spin_lock_irqsave(&phba->pport->work_port_lock, iflag);
	if (!(phba->pport->load_flag & FC_UNLOADING))
		phba->hba_flag |= HBA_RRQ_ACTIVE;
	else
		phba->hba_flag &= ~HBA_RRQ_ACTIVE;
	spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag);

	if (!(phba->pport->load_flag & FC_UNLOADING))
		lpfc_worker_wake_up(phba);
}

/**
 * lpfc_hb_mbox_cmpl - The lpfc heart-beat mailbox command callback function
 * @phba: pointer to lpfc hba data structure.
 * @pmboxq: pointer to the driver internal queue element for mailbox command.
 *
 * This is the callback function to the lpfc heart-beat mailbox command.
 * If configured, the lpfc driver issues the heart-beat mailbox command to
 * the HBA every LPFC_HB_MBOX_INTERVAL (current 5) seconds. At the time the
 * heart-beat mailbox command is issued, the driver shall set up heart-beat
 * timeout timer to LPFC_HB_MBOX_TIMEOUT (current 30) seconds and marks
 * heart-beat outstanding state. Once the mailbox command comes back and
 * no error conditions detected, the heart-beat mailbox command timer is
 * reset to LPFC_HB_MBOX_INTERVAL seconds and the heart-beat outstanding
 * state is cleared for the next heart-beat. If the timer expired with the
 * heart-beat outstanding state set, the driver will put the HBA offline.
 **/
static void
lpfc_hb_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq)
{
	unsigned long drvr_flag;

	spin_lock_irqsave(&phba->hbalock, drvr_flag);
	phba->hba_flag &= ~(HBA_HBEAT_INP | HBA_HBEAT_TMO);
	spin_unlock_irqrestore(&phba->hbalock, drvr_flag);

	/* Check and reset heart-beat timer if necessary */
	mempool_free(pmboxq, phba->mbox_mem_pool);
	if (!(phba->pport->fc_flag & FC_OFFLINE_MODE) &&
		!(phba->link_state == LPFC_HBA_ERROR) &&
		!(phba->pport->load_flag & FC_UNLOADING))
		mod_timer(&phba->hb_tmofunc,
			  jiffies +
			  msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL));
	return;
}

/*
 * lpfc_idle_stat_delay_work - idle_stat tracking
 *
 * This routine tracks per-cq idle_stat and determines polling decisions.
 *
 * Return codes:
 *   None
 **/
static void
lpfc_idle_stat_delay_work(struct work_struct *work)
{
	struct lpfc_hba *phba = container_of(to_delayed_work(work),
					     struct lpfc_hba,
					     idle_stat_delay_work);
	struct lpfc_queue *cq;
	struct lpfc_sli4_hdw_queue *hdwq;
	struct lpfc_idle_stat *idle_stat;
	u32 i, idle_percent;
	u64 wall, wall_idle, diff_wall, diff_idle, busy_time;

	if (phba->pport->load_flag & FC_UNLOADING)
		return;

	if (phba->link_state == LPFC_HBA_ERROR ||
	    phba->pport->fc_flag & FC_OFFLINE_MODE ||
	    phba->cmf_active_mode != LPFC_CFG_OFF)
		goto requeue;

	for_each_present_cpu(i) {
		hdwq = &phba->sli4_hba.hdwq[phba->sli4_hba.cpu_map[i].hdwq];
		cq = hdwq->io_cq;

		/* Skip if we've already handled this cq's primary CPU */
		if (cq->chann != i)
			continue;

		idle_stat = &phba->sli4_hba.idle_stat[i];

		/* get_cpu_idle_time returns values as running counters. Thus,
		 * to know the amount for this period, the prior counter values
		 * need to be subtracted from the current counter values.
		 * From there, the idle time stat can be calculated as a
		 * percentage of 100 - the sum of the other consumption times.
		 */
		wall_idle = get_cpu_idle_time(i, &wall, 1);
		diff_idle = wall_idle - idle_stat->prev_idle;
		diff_wall = wall - idle_stat->prev_wall;

		if (diff_wall <= diff_idle)
			busy_time = 0;
		else
			busy_time = diff_wall - diff_idle;

		idle_percent = div64_u64(100 * busy_time, diff_wall);
		idle_percent = 100 - idle_percent;

		if (idle_percent < 15)
			cq->poll_mode = LPFC_QUEUE_WORK;
		else
			cq->poll_mode = LPFC_IRQ_POLL;

		idle_stat->prev_idle = wall_idle;
		idle_stat->prev_wall = wall;
	}

requeue:
	schedule_delayed_work(&phba->idle_stat_delay_work,
			      msecs_to_jiffies(LPFC_IDLE_STAT_DELAY));
}

static void
lpfc_hb_eq_delay_work(struct work_struct *work)
{
	struct lpfc_hba *phba = container_of(to_delayed_work(work),
					     struct lpfc_hba, eq_delay_work);
	struct lpfc_eq_intr_info *eqi, *eqi_new;
	struct lpfc_queue *eq, *eq_next;
	unsigned char *ena_delay = NULL;
	uint32_t usdelay;
	int i;

	if (!phba->cfg_auto_imax || phba->pport->load_flag & FC_UNLOADING)
		return;

	if (phba->link_state == LPFC_HBA_ERROR ||
	    phba->pport->fc_flag & FC_OFFLINE_MODE)
		goto requeue;

	ena_delay = kcalloc(phba->sli4_hba.num_possible_cpu, sizeof(*ena_delay),
			    GFP_KERNEL);
	if (!ena_delay)
		goto requeue;

	for (i = 0; i < phba->cfg_irq_chann; i++) {
		/* Get the EQ corresponding to the IRQ vector */
		eq = phba->sli4_hba.hba_eq_hdl[i].eq;
		if (!eq)
			continue;
		if (eq->q_mode || eq->q_flag & HBA_EQ_DELAY_CHK) {
			eq->q_flag &= ~HBA_EQ_DELAY_CHK;
			ena_delay[eq->last_cpu] = 1;
		}
	}

	for_each_present_cpu(i) {
		eqi = per_cpu_ptr(phba->sli4_hba.eq_info, i);
		if (ena_delay[i]) {
			usdelay = (eqi->icnt >> 10) * LPFC_EQ_DELAY_STEP;
			if (usdelay > LPFC_MAX_AUTO_EQ_DELAY)
				usdelay = LPFC_MAX_AUTO_EQ_DELAY;
		} else {
			usdelay = 0;
		}

		eqi->icnt = 0;

		list_for_each_entry_safe(eq, eq_next, &eqi->list, cpu_list) {
			if (unlikely(eq->last_cpu != i)) {
				eqi_new = per_cpu_ptr(phba->sli4_hba.eq_info,
						      eq->last_cpu);
				list_move_tail(&eq->cpu_list, &eqi_new->list);
				continue;
			}
			if (usdelay != eq->q_mode)
				lpfc_modify_hba_eq_delay(phba, eq->hdwq, 1,
							 usdelay);
		}
	}

	kfree(ena_delay);

requeue:
	queue_delayed_work(phba->wq, &phba->eq_delay_work,
			   msecs_to_jiffies(LPFC_EQ_DELAY_MSECS));
}

/**
 * lpfc_hb_mxp_handler - Multi-XRI pools handler to adjust XRI distribution
 * @phba: pointer to lpfc hba data structure.
 *
 * For each heartbeat, this routine does some heuristic methods to adjust
 * XRI distribution. The goal is to fully utilize free XRIs.
 **/
static void lpfc_hb_mxp_handler(struct lpfc_hba *phba)
{
	u32 i;
	u32 hwq_count;

	hwq_count = phba->cfg_hdw_queue;
	for (i = 0; i < hwq_count; i++) {
		/* Adjust XRIs in private pool */
		lpfc_adjust_pvt_pool_count(phba, i);

		/* Adjust high watermark */
		lpfc_adjust_high_watermark(phba, i);

#ifdef LPFC_MXP_STAT
		/* Snapshot pbl, pvt and busy count */
		lpfc_snapshot_mxp(phba, i);
#endif
	}
}

/**
 * lpfc_issue_hb_mbox - Issues heart-beat mailbox command
 * @phba: pointer to lpfc hba data structure.
 *
 * If a HB mbox is not already in progrees, this routine will allocate
 * a LPFC_MBOXQ_t, populate it with a MBX_HEARTBEAT (0x31) command,
 * and issue it. The HBA_HBEAT_INP flag means the command is in progress.
 **/
int
lpfc_issue_hb_mbox(struct lpfc_hba *phba)
{
	LPFC_MBOXQ_t *pmboxq;
	int retval;

	/* Is a Heartbeat mbox already in progress */
	if (phba->hba_flag & HBA_HBEAT_INP)
		return 0;

	pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (!pmboxq)
		return -ENOMEM;

	lpfc_heart_beat(phba, pmboxq);
	pmboxq->mbox_cmpl = lpfc_hb_mbox_cmpl;
	pmboxq->vport = phba->pport;
	retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT);

	if (retval != MBX_BUSY && retval != MBX_SUCCESS) {
		mempool_free(pmboxq, phba->mbox_mem_pool);
		return -ENXIO;
	}
	phba->hba_flag |= HBA_HBEAT_INP;

	return 0;
}

/**
 * lpfc_issue_hb_tmo - Signals heartbeat timer to issue mbox command
 * @phba: pointer to lpfc hba data structure.
 *
 * The heartbeat timer (every 5 sec) will fire. If the HBA_HBEAT_TMO
 * flag is set, it will force a MBX_HEARTBEAT mbox command, regardless
 * of the value of lpfc_enable_hba_heartbeat.
 * If lpfc_enable_hba_heartbeat is set, the timeout routine will always
 * try to issue a MBX_HEARTBEAT mbox command.
 **/
void
lpfc_issue_hb_tmo(struct lpfc_hba *phba)
{
	if (phba->cfg_enable_hba_heartbeat)
		return;
	phba->hba_flag |= HBA_HBEAT_TMO;
}

/**
 * lpfc_hb_timeout_handler - The HBA-timer timeout handler
 * @phba: pointer to lpfc hba data structure.
 *
 * This is the actual HBA-timer timeout handler to be invoked by the worker
 * thread whenever the HBA timer fired and HBA-timeout event posted. This
 * handler performs any periodic operations needed for the device. If such
 * periodic event has already been attended to either in the interrupt handler
 * or by processing slow-ring or fast-ring events within the HBA-timer
 * timeout window (LPFC_HB_MBOX_INTERVAL), this handler just simply resets
 * the timer for the next timeout period. If lpfc heart-beat mailbox command
 * is configured and there is no heart-beat mailbox command outstanding, a
 * heart-beat mailbox is issued and timer set properly. Otherwise, if there
 * has been a heart-beat mailbox command outstanding, the HBA shall be put
 * to offline.
 **/
void
lpfc_hb_timeout_handler(struct lpfc_hba *phba)
{
	struct lpfc_vport **vports;
	struct lpfc_dmabuf *buf_ptr;
	int retval = 0;
	int i, tmo;
	struct lpfc_sli *psli = &phba->sli;
	LIST_HEAD(completions);

	if (phba->cfg_xri_rebalancing) {
		/* Multi-XRI pools handler */
		lpfc_hb_mxp_handler(phba);
	}

	vports = lpfc_create_vport_work_array(phba);
	if (vports != NULL)
		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
			lpfc_rcv_seq_check_edtov(vports[i]);
			lpfc_fdmi_change_check(vports[i]);
		}
	lpfc_destroy_vport_work_array(phba, vports);

	if ((phba->link_state == LPFC_HBA_ERROR) ||
		(phba->pport->load_flag & FC_UNLOADING) ||
		(phba->pport->fc_flag & FC_OFFLINE_MODE))
		return;

	if (phba->elsbuf_cnt &&
		(phba->elsbuf_cnt == phba->elsbuf_prev_cnt)) {
		spin_lock_irq(&phba->hbalock);
		list_splice_init(&phba->elsbuf, &completions);
		phba->elsbuf_cnt = 0;
		phba->elsbuf_prev_cnt = 0;
		spin_unlock_irq(&phba->hbalock);

		while (!list_empty(&completions)) {
			list_remove_head(&completions, buf_ptr,
				struct lpfc_dmabuf, list);
			lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
			kfree(buf_ptr);
		}
	}
	phba->elsbuf_prev_cnt = phba->elsbuf_cnt;

	/* If there is no heart beat outstanding, issue a heartbeat command */
	if (phba->cfg_enable_hba_heartbeat) {
		/* If IOs are completing, no need to issue a MBX_HEARTBEAT */
		spin_lock_irq(&phba->pport->work_port_lock);
		if (time_after(phba->last_completion_time +
				msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL),
				jiffies)) {
			spin_unlock_irq(&phba->pport->work_port_lock);
			if (phba->hba_flag & HBA_HBEAT_INP)
				tmo = (1000 * LPFC_HB_MBOX_TIMEOUT);
			else
				tmo = (1000 * LPFC_HB_MBOX_INTERVAL);
			goto out;
		}
		spin_unlock_irq(&phba->pport->work_port_lock);

		/* Check if a MBX_HEARTBEAT is already in progress */
		if (phba->hba_flag & HBA_HBEAT_INP) {
			/*
			 * If heart beat timeout called with HBA_HBEAT_INP set
			 * we need to give the hb mailbox cmd a chance to
			 * complete or TMO.
			 */
			lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
				"0459 Adapter heartbeat still outstanding: "
				"last compl time was %d ms.\n",
				jiffies_to_msecs(jiffies
					 - phba->last_completion_time));
			tmo = (1000 * LPFC_HB_MBOX_TIMEOUT);
		} else {
			if ((!(psli->sli_flag & LPFC_SLI_MBOX_ACTIVE)) &&
				(list_empty(&psli->mboxq))) {

				retval = lpfc_issue_hb_mbox(phba);
				if (retval) {
					tmo = (1000 * LPFC_HB_MBOX_INTERVAL);
					goto out;
				}
				phba->skipped_hb = 0;
			} else if (time_before_eq(phba->last_completion_time,
					phba->skipped_hb)) {
				lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
					"2857 Last completion time not "
					" updated in %d ms\n",
					jiffies_to_msecs(jiffies
						 - phba->last_completion_time));
			} else
				phba->skipped_hb = jiffies;

			tmo = (1000 * LPFC_HB_MBOX_TIMEOUT);
			goto out;
		}
	} else {
		/* Check to see if we want to force a MBX_HEARTBEAT */
		if (phba->hba_flag & HBA_HBEAT_TMO) {
			retval = lpfc_issue_hb_mbox(phba);
			if (retval)
				tmo = (1000 * LPFC_HB_MBOX_INTERVAL);
			else
				tmo = (1000 * LPFC_HB_MBOX_TIMEOUT);
			goto out;
		}
		tmo = (1000 * LPFC_HB_MBOX_INTERVAL);
	}
out:
	mod_timer(&phba->hb_tmofunc, jiffies + msecs_to_jiffies(tmo));
}

/**
 * lpfc_offline_eratt - Bring lpfc offline on hardware error attention
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is called to bring the HBA offline when HBA hardware error
 * other than Port Error 6 has been detected.
 **/
static void
lpfc_offline_eratt(struct lpfc_hba *phba)
{
	struct lpfc_sli   *psli = &phba->sli;

	spin_lock_irq(&phba->hbalock);
	psli->sli_flag &= ~LPFC_SLI_ACTIVE;
	spin_unlock_irq(&phba->hbalock);
	lpfc_offline_prep(phba, LPFC_MBX_NO_WAIT);

	lpfc_offline(phba);
	lpfc_reset_barrier(phba);
	spin_lock_irq(&phba->hbalock);
	lpfc_sli_brdreset(phba);
	spin_unlock_irq(&phba->hbalock);
	lpfc_hba_down_post(phba);
	lpfc_sli_brdready(phba, HS_MBRDY);
	lpfc_unblock_mgmt_io(phba);
	phba->link_state = LPFC_HBA_ERROR;
	return;
}

/**
 * lpfc_sli4_offline_eratt - Bring lpfc offline on SLI4 hardware error attention
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is called to bring a SLI4 HBA offline when HBA hardware error
 * other than Port Error 6 has been detected.
 **/
void
lpfc_sli4_offline_eratt(struct lpfc_hba *phba)
{
	spin_lock_irq(&phba->hbalock);
	if (phba->link_state == LPFC_HBA_ERROR &&
	    phba->hba_flag & HBA_PCI_ERR) {
		spin_unlock_irq(&phba->hbalock);
		return;
	}
	phba->link_state = LPFC_HBA_ERROR;
	spin_unlock_irq(&phba->hbalock);

	lpfc_offline_prep(phba, LPFC_MBX_NO_WAIT);
	lpfc_sli_flush_io_rings(phba);
	lpfc_offline(phba);
	lpfc_hba_down_post(phba);
	lpfc_unblock_mgmt_io(phba);
}

/**
 * lpfc_handle_deferred_eratt - The HBA hardware deferred error handler
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to handle the deferred HBA hardware error
 * conditions. This type of error is indicated by HBA by setting ER1
 * and another ER bit in the host status register. The driver will
 * wait until the ER1 bit clears before handling the error condition.
 **/
static void
lpfc_handle_deferred_eratt(struct lpfc_hba *phba)
{
	uint32_t old_host_status = phba->work_hs;
	struct lpfc_sli *psli = &phba->sli;

	/* If the pci channel is offline, ignore possible errors,
	 * since we cannot communicate with the pci card anyway.
	 */
	if (pci_channel_offline(phba->pcidev)) {
		spin_lock_irq(&phba->hbalock);
		phba->hba_flag &= ~DEFER_ERATT;
		spin_unlock_irq(&phba->hbalock);
		return;
	}

	lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
			"0479 Deferred Adapter Hardware Error "
			"Data: x%x x%x x%x\n",
			phba->work_hs, phba->work_status[0],
			phba->work_status[1]);

	spin_lock_irq(&phba->hbalock);
	psli->sli_flag &= ~LPFC_SLI_ACTIVE;
	spin_unlock_irq(&phba->hbalock);


	/*
	 * Firmware stops when it triggred erratt. That could cause the I/Os
	 * dropped by the firmware. Error iocb (I/O) on txcmplq and let the
	 * SCSI layer retry it after re-establishing link.
	 */
	lpfc_sli_abort_fcp_rings(phba);

	/*
	 * There was a firmware error. Take the hba offline and then
	 * attempt to restart it.
	 */
	lpfc_offline_prep(phba, LPFC_MBX_WAIT);
	lpfc_offline(phba);

	/* Wait for the ER1 bit to clear.*/
	while (phba->work_hs & HS_FFER1) {
		msleep(100);
		if (lpfc_readl(phba->HSregaddr, &phba->work_hs)) {
			phba->work_hs = UNPLUG_ERR ;
			break;
		}
		/* If driver is unloading let the worker thread continue */
		if (phba->pport->load_flag & FC_UNLOADING) {
			phba->work_hs = 0;
			break;
		}
	}

	/*
	 * This is to ptrotect against a race condition in which
	 * first write to the host attention register clear the
	 * host status register.
	 */
	if ((!phba->work_hs) && (!(phba->pport->load_flag & FC_UNLOADING)))
		phba->work_hs = old_host_status & ~HS_FFER1;

	spin_lock_irq(&phba->hbalock);
	phba->hba_flag &= ~DEFER_ERATT;
	spin_unlock_irq(&phba->hbalock);
	phba->work_status[0] = readl(phba->MBslimaddr + 0xa8);
	phba->work_status[1] = readl(phba->MBslimaddr + 0xac);
}

static void
lpfc_board_errevt_to_mgmt(struct lpfc_hba *phba)
{
	struct lpfc_board_event_header board_event;
	struct Scsi_Host *shost;

	board_event.event_type = FC_REG_BOARD_EVENT;
	board_event.subcategory = LPFC_EVENT_PORTINTERR;
	shost = lpfc_shost_from_vport(phba->pport);
	fc_host_post_vendor_event(shost, fc_get_event_number(),
				  sizeof(board_event),
				  (char *) &board_event,
				  LPFC_NL_VENDOR_ID);
}

/**
 * lpfc_handle_eratt_s3 - The SLI3 HBA hardware error handler
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to handle the following HBA hardware error
 * conditions:
 * 1 - HBA error attention interrupt
 * 2 - DMA ring index out of range
 * 3 - Mailbox command came back as unknown
 **/
static void
lpfc_handle_eratt_s3(struct lpfc_hba *phba)
{
	struct lpfc_vport *vport = phba->pport;
	struct lpfc_sli   *psli = &phba->sli;
	uint32_t event_data;
	unsigned long temperature;
	struct temp_event temp_event_data;
	struct Scsi_Host  *shost;

	/* If the pci channel is offline, ignore possible errors,
	 * since we cannot communicate with the pci card anyway.
	 */
	if (pci_channel_offline(phba->pcidev)) {
		spin_lock_irq(&phba->hbalock);
		phba->hba_flag &= ~DEFER_ERATT;
		spin_unlock_irq(&phba->hbalock);
		return;
	}

	/* If resets are disabled then leave the HBA alone and return */
	if (!phba->cfg_enable_hba_reset)
		return;

	/* Send an internal error event to mgmt application */
	lpfc_board_errevt_to_mgmt(phba);

	if (phba->hba_flag & DEFER_ERATT)
		lpfc_handle_deferred_eratt(phba);

	if ((phba->work_hs & HS_FFER6) || (phba->work_hs & HS_FFER8)) {
		if (phba->work_hs & HS_FFER6)
			/* Re-establishing Link */
			lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
					"1301 Re-establishing Link "
					"Data: x%x x%x x%x\n",
					phba->work_hs, phba->work_status[0],
					phba->work_status[1]);
		if (phba->work_hs & HS_FFER8)
			/* Device Zeroization */
			lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
					"2861 Host Authentication device "
					"zeroization Data:x%x x%x x%x\n",
					phba->work_hs, phba->work_status[0],
					phba->work_status[1]);

		spin_lock_irq(&phba->hbalock);
		psli->sli_flag &= ~LPFC_SLI_ACTIVE;
		spin_unlock_irq(&phba->hbalock);

		/*
		* Firmware stops when it triggled erratt with HS_FFER6.
		* That could cause the I/Os dropped by the firmware.
		* Error iocb (I/O) on txcmplq and let the SCSI layer
		* retry it after re-establishing link.
		*/
		lpfc_sli_abort_fcp_rings(phba);

		/*
		 * There was a firmware error.  Take the hba offline and then
		 * attempt to restart it.
		 */
		lpfc_offline_prep(phba, LPFC_MBX_NO_WAIT);
		lpfc_offline(phba);
		lpfc_sli_brdrestart(phba);
		if (lpfc_online(phba) == 0) {	/* Initialize the HBA */
			lpfc_unblock_mgmt_io(phba);
			return;
		}
		lpfc_unblock_mgmt_io(phba);
	} else if (phba->work_hs & HS_CRIT_TEMP) {
		temperature = readl(phba->MBslimaddr + TEMPERATURE_OFFSET);
		temp_event_data.event_type = FC_REG_TEMPERATURE_EVENT;
		temp_event_data.event_code = LPFC_CRIT_TEMP;
		temp_event_data.data = (uint32_t)temperature;

		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0406 Adapter maximum temperature exceeded "
				"(%ld), taking this port offline "
				"Data: x%x x%x x%x\n",
				temperature, phba->work_hs,
				phba->work_status[0], phba->work_status[1]);

		shost = lpfc_shost_from_vport(phba->pport);
		fc_host_post_vendor_event(shost, fc_get_event_number(),
					  sizeof(temp_event_data),
					  (char *) &temp_event_data,
					  SCSI_NL_VID_TYPE_PCI
					  | PCI_VENDOR_ID_EMULEX);

		spin_lock_irq(&phba->hbalock);
		phba->over_temp_state = HBA_OVER_TEMP;
		spin_unlock_irq(&phba->hbalock);
		lpfc_offline_eratt(phba);

	} else {
		/* The if clause above forces this code path when the status
		 * failure is a value other than FFER6. Do not call the offline
		 * twice. This is the adapter hardware error path.
		 */
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0457 Adapter Hardware Error "
				"Data: x%x x%x x%x\n",
				phba->work_hs,
				phba->work_status[0], phba->work_status[1]);

		event_data = FC_REG_DUMP_EVENT;
		shost = lpfc_shost_from_vport(vport);
		fc_host_post_vendor_event(shost, fc_get_event_number(),
				sizeof(event_data), (char *) &event_data,
				SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX);

		lpfc_offline_eratt(phba);
	}
	return;
}

/**
 * lpfc_sli4_port_sta_fn_reset - The SLI4 function reset due to port status reg
 * @phba: pointer to lpfc hba data structure.
 * @mbx_action: flag for mailbox shutdown action.
 * @en_rn_msg: send reset/port recovery message.
 * This routine is invoked to perform an SLI4 port PCI function reset in
 * response to port status register polling attention. It waits for port
 * status register (ERR, RDY, RN) bits before proceeding with function reset.
 * During this process, interrupt vectors are freed and later requested
 * for handling possible port resource change.
 **/
static int
lpfc_sli4_port_sta_fn_reset(struct lpfc_hba *phba, int mbx_action,
			    bool en_rn_msg)
{
	int rc;
	uint32_t intr_mode;
	LPFC_MBOXQ_t *mboxq;

	if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) >=
	    LPFC_SLI_INTF_IF_TYPE_2) {
		/*
		 * On error status condition, driver need to wait for port
		 * ready before performing reset.
		 */
		rc = lpfc_sli4_pdev_status_reg_wait(phba);
		if (rc)
			return rc;
	}

	/* need reset: attempt for port recovery */
	if (en_rn_msg)
		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
				"2887 Reset Needed: Attempting Port "
				"Recovery...\n");

	/* If we are no wait, the HBA has been reset and is not
	 * functional, thus we should clear
	 * (LPFC_SLI_ACTIVE | LPFC_SLI_MBOX_ACTIVE) flags.
	 */
	if (mbx_action == LPFC_MBX_NO_WAIT) {
		spin_lock_irq(&phba->hbalock);
		phba->sli.sli_flag &= ~LPFC_SLI_ACTIVE;
		if (phba->sli.mbox_active) {
			mboxq = phba->sli.mbox_active;
			mboxq->u.mb.mbxStatus = MBX_NOT_FINISHED;
			__lpfc_mbox_cmpl_put(phba, mboxq);
			phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
			phba->sli.mbox_active = NULL;
		}
		spin_unlock_irq(&phba->hbalock);
	}

	lpfc_offline_prep(phba, mbx_action);
	lpfc_sli_flush_io_rings(phba);
	lpfc_offline(phba);
	/* release interrupt for possible resource change */
	lpfc_sli4_disable_intr(phba);
	rc = lpfc_sli_brdrestart(phba);
	if (rc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"6309 Failed to restart board\n");
		return rc;
	}
	/* request and enable interrupt */
	intr_mode = lpfc_sli4_enable_intr(phba, phba->intr_mode);
	if (intr_mode == LPFC_INTR_ERROR) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3175 Failed to enable interrupt\n");
		return -EIO;
	}
	phba->intr_mode = intr_mode;
	rc = lpfc_online(phba);
	if (rc == 0)
		lpfc_unblock_mgmt_io(phba);

	return rc;
}

/**
 * lpfc_handle_eratt_s4 - The SLI4 HBA hardware error handler
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to handle the SLI4 HBA hardware error attention
 * conditions.
 **/
static void
lpfc_handle_eratt_s4(struct lpfc_hba *phba)
{
	struct lpfc_vport *vport = phba->pport;
	uint32_t event_data;
	struct Scsi_Host *shost;
	uint32_t if_type;
	struct lpfc_register portstat_reg = {0};
	uint32_t reg_err1, reg_err2;
	uint32_t uerrlo_reg, uemasklo_reg;
	uint32_t smphr_port_status = 0, pci_rd_rc1, pci_rd_rc2;
	bool en_rn_msg = true;
	struct temp_event temp_event_data;
	struct lpfc_register portsmphr_reg;
	int rc, i;

	/* If the pci channel is offline, ignore possible errors, since
	 * we cannot communicate with the pci card anyway.
	 */
	if (pci_channel_offline(phba->pcidev)) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3166 pci channel is offline\n");
		return;
	}

	memset(&portsmphr_reg, 0, sizeof(portsmphr_reg));
	if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
	switch (if_type) {
	case LPFC_SLI_INTF_IF_TYPE_0:
		pci_rd_rc1 = lpfc_readl(
				phba->sli4_hba.u.if_type0.UERRLOregaddr,
				&uerrlo_reg);
		pci_rd_rc2 = lpfc_readl(
				phba->sli4_hba.u.if_type0.UEMASKLOregaddr,
				&uemasklo_reg);
		/* consider PCI bus read error as pci_channel_offline */
		if (pci_rd_rc1 == -EIO && pci_rd_rc2 == -EIO)
			return;
		if (!(phba->hba_flag & HBA_RECOVERABLE_UE)) {
			lpfc_sli4_offline_eratt(phba);
			return;
		}
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"7623 Checking UE recoverable");

		for (i = 0; i < phba->sli4_hba.ue_to_sr / 1000; i++) {
			if (lpfc_readl(phba->sli4_hba.PSMPHRregaddr,
				       &portsmphr_reg.word0))
				continue;

			smphr_port_status = bf_get(lpfc_port_smphr_port_status,
						   &portsmphr_reg);
			if ((smphr_port_status & LPFC_PORT_SEM_MASK) ==
			    LPFC_PORT_SEM_UE_RECOVERABLE)
				break;
			/*Sleep for 1Sec, before checking SEMAPHORE */
			msleep(1000);
		}

		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"4827 smphr_port_status x%x : Waited %dSec",
				smphr_port_status, i);

		/* Recoverable UE, reset the HBA device */
		if ((smphr_port_status & LPFC_PORT_SEM_MASK) ==
		    LPFC_PORT_SEM_UE_RECOVERABLE) {
			for (i = 0; i < 20; i++) {
				msleep(1000);
				if (!lpfc_readl(phba->sli4_hba.PSMPHRregaddr,
				    &portsmphr_reg.word0) &&
				    (LPFC_POST_STAGE_PORT_READY ==
				     bf_get(lpfc_port_smphr_port_status,
				     &portsmphr_reg))) {
					rc = lpfc_sli4_port_sta_fn_reset(phba,
						LPFC_MBX_NO_WAIT, en_rn_msg);
					if (rc == 0)
						return;
					lpfc_printf_log(phba, KERN_ERR,
						LOG_TRACE_EVENT,
						"4215 Failed to recover UE");
					break;
				}
			}
		}
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"7624 Firmware not ready: Failing UE recovery,"
				" waited %dSec", i);
		phba->link_state = LPFC_HBA_ERROR;
		break;

	case LPFC_SLI_INTF_IF_TYPE_2:
	case LPFC_SLI_INTF_IF_TYPE_6:
		pci_rd_rc1 = lpfc_readl(
				phba->sli4_hba.u.if_type2.STATUSregaddr,
				&portstat_reg.word0);
		/* consider PCI bus read error as pci_channel_offline */
		if (pci_rd_rc1 == -EIO) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3151 PCI bus read access failure: x%x\n",
				readl(phba->sli4_hba.u.if_type2.STATUSregaddr));
			lpfc_sli4_offline_eratt(phba);
			return;
		}
		reg_err1 = readl(phba->sli4_hba.u.if_type2.ERR1regaddr);
		reg_err2 = readl(phba->sli4_hba.u.if_type2.ERR2regaddr);
		if (bf_get(lpfc_sliport_status_oti, &portstat_reg)) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"2889 Port Overtemperature event, "
					"taking port offline Data: x%x x%x\n",
					reg_err1, reg_err2);

			phba->sfp_alarm |= LPFC_TRANSGRESSION_HIGH_TEMPERATURE;
			temp_event_data.event_type = FC_REG_TEMPERATURE_EVENT;
			temp_event_data.event_code = LPFC_CRIT_TEMP;
			temp_event_data.data = 0xFFFFFFFF;

			shost = lpfc_shost_from_vport(phba->pport);
			fc_host_post_vendor_event(shost, fc_get_event_number(),
						  sizeof(temp_event_data),
						  (char *)&temp_event_data,
						  SCSI_NL_VID_TYPE_PCI
						  | PCI_VENDOR_ID_EMULEX);

			spin_lock_irq(&phba->hbalock);
			phba->over_temp_state = HBA_OVER_TEMP;
			spin_unlock_irq(&phba->hbalock);
			lpfc_sli4_offline_eratt(phba);
			return;
		}
		if (reg_err1 == SLIPORT_ERR1_REG_ERR_CODE_2 &&
		    reg_err2 == SLIPORT_ERR2_REG_FW_RESTART) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"3143 Port Down: Firmware Update "
					"Detected\n");
			en_rn_msg = false;
		} else if (reg_err1 == SLIPORT_ERR1_REG_ERR_CODE_2 &&
			 reg_err2 == SLIPORT_ERR2_REG_FORCED_DUMP)
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"3144 Port Down: Debug Dump\n");
		else if (reg_err1 == SLIPORT_ERR1_REG_ERR_CODE_2 &&
			 reg_err2 == SLIPORT_ERR2_REG_FUNC_PROVISON)
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"3145 Port Down: Provisioning\n");

		/* If resets are disabled then leave the HBA alone and return */
		if (!phba->cfg_enable_hba_reset)
			return;

		/* Check port status register for function reset */
		rc = lpfc_sli4_port_sta_fn_reset(phba, LPFC_MBX_NO_WAIT,
				en_rn_msg);
		if (rc == 0) {
			/* don't report event on forced debug dump */
			if (reg_err1 == SLIPORT_ERR1_REG_ERR_CODE_2 &&
			    reg_err2 == SLIPORT_ERR2_REG_FORCED_DUMP)
				return;
			else
				break;
		}
		/* fall through for not able to recover */
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3152 Unrecoverable error\n");
		phba->link_state = LPFC_HBA_ERROR;
		break;
	case LPFC_SLI_INTF_IF_TYPE_1:
	default:
		break;
	}
	lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
			"3123 Report dump event to upper layer\n");
	/* Send an internal error event to mgmt application */
	lpfc_board_errevt_to_mgmt(phba);

	event_data = FC_REG_DUMP_EVENT;
	shost = lpfc_shost_from_vport(vport);
	fc_host_post_vendor_event(shost, fc_get_event_number(),
				  sizeof(event_data), (char *) &event_data,
				  SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX);
}

/**
 * lpfc_handle_eratt - Wrapper func for handling hba error attention
 * @phba: pointer to lpfc HBA data structure.
 *
 * This routine wraps the actual SLI3 or SLI4 hba error attention handling
 * routine from the API jump table function pointer from the lpfc_hba struct.
 *
 * Return codes
 *   0 - success.
 *   Any other value - error.
 **/
void
lpfc_handle_eratt(struct lpfc_hba *phba)
{
	(*phba->lpfc_handle_eratt)(phba);
}

/**
 * lpfc_handle_latt - The HBA link event handler
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked from the worker thread to handle a HBA host
 * attention link event. SLI3 only.
 **/
void
lpfc_handle_latt(struct lpfc_hba *phba)
{
	struct lpfc_vport *vport = phba->pport;
	struct lpfc_sli   *psli = &phba->sli;
	LPFC_MBOXQ_t *pmb;
	volatile uint32_t control;
	struct lpfc_dmabuf *mp;
	int rc = 0;

	pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (!pmb) {
		rc = 1;
		goto lpfc_handle_latt_err_exit;
	}

	mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
	if (!mp) {
		rc = 2;
		goto lpfc_handle_latt_free_pmb;
	}

	mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
	if (!mp->virt) {
		rc = 3;
		goto lpfc_handle_latt_free_mp;
	}

	/* Cleanup any outstanding ELS commands */
	lpfc_els_flush_all_cmd(phba);

	psli->slistat.link_event++;
	lpfc_read_topology(phba, pmb, mp);
	pmb->mbox_cmpl = lpfc_mbx_cmpl_read_topology;
	pmb->vport = vport;
	/* Block ELS IOCBs until we have processed this mbox command */
	phba->sli.sli3_ring[LPFC_ELS_RING].flag |= LPFC_STOP_IOCB_EVENT;
	rc = lpfc_sli_issue_mbox (phba, pmb, MBX_NOWAIT);
	if (rc == MBX_NOT_FINISHED) {
		rc = 4;
		goto lpfc_handle_latt_free_mbuf;
	}

	/* Clear Link Attention in HA REG */
	spin_lock_irq(&phba->hbalock);
	writel(HA_LATT, phba->HAregaddr);
	readl(phba->HAregaddr); /* flush */
	spin_unlock_irq(&phba->hbalock);

	return;

lpfc_handle_latt_free_mbuf:
	phba->sli.sli3_ring[LPFC_ELS_RING].flag &= ~LPFC_STOP_IOCB_EVENT;
	lpfc_mbuf_free(phba, mp->virt, mp->phys);
lpfc_handle_latt_free_mp:
	kfree(mp);
lpfc_handle_latt_free_pmb:
	mempool_free(pmb, phba->mbox_mem_pool);
lpfc_handle_latt_err_exit:
	/* Enable Link attention interrupts */
	spin_lock_irq(&phba->hbalock);
	psli->sli_flag |= LPFC_PROCESS_LA;
	control = readl(phba->HCregaddr);
	control |= HC_LAINT_ENA;
	writel(control, phba->HCregaddr);
	readl(phba->HCregaddr); /* flush */

	/* Clear Link Attention in HA REG */
	writel(HA_LATT, phba->HAregaddr);
	readl(phba->HAregaddr); /* flush */
	spin_unlock_irq(&phba->hbalock);
	lpfc_linkdown(phba);
	phba->link_state = LPFC_HBA_ERROR;

	lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
			"0300 LATT: Cannot issue READ_LA: Data:%d\n", rc);

	return;
}

/**
 * lpfc_parse_vpd - Parse VPD (Vital Product Data)
 * @phba: pointer to lpfc hba data structure.
 * @vpd: pointer to the vital product data.
 * @len: length of the vital product data in bytes.
 *
 * This routine parses the Vital Product Data (VPD). The VPD is treated as
 * an array of characters. In this routine, the ModelName, ProgramType, and
 * ModelDesc, etc. fields of the phba data structure will be populated.
 *
 * Return codes
 *   0 - pointer to the VPD passed in is NULL
 *   1 - success
 **/
int
lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len)
{
	uint8_t lenlo, lenhi;
	int Length;
	int i, j;
	int finished = 0;
	int index = 0;

	if (!vpd)
		return 0;

	/* Vital Product */
	lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
			"0455 Vital Product Data: x%x x%x x%x x%x\n",
			(uint32_t) vpd[0], (uint32_t) vpd[1], (uint32_t) vpd[2],
			(uint32_t) vpd[3]);
	while (!finished && (index < (len - 4))) {
		switch (vpd[index]) {
		case 0x82:
		case 0x91:
			index += 1;
			lenlo = vpd[index];
			index += 1;
			lenhi = vpd[index];
			index += 1;
			i = ((((unsigned short)lenhi) << 8) + lenlo);
			index += i;
			break;
		case 0x90:
			index += 1;
			lenlo = vpd[index];
			index += 1;
			lenhi = vpd[index];
			index += 1;
			Length = ((((unsigned short)lenhi) << 8) + lenlo);
			if (Length > len - index)
				Length = len - index;
			while (Length > 0) {
			/* Look for Serial Number */
			if ((vpd[index] == 'S') && (vpd[index+1] == 'N')) {
				index += 2;
				i = vpd[index];
				index += 1;
				j = 0;
				Length -= (3+i);
				while(i--) {
					phba->SerialNumber[j++] = vpd[index++];
					if (j == 31)
						break;
				}
				phba->SerialNumber[j] = 0;
				continue;
			}
			else if ((vpd[index] == 'V') && (vpd[index+1] == '1')) {
				phba->vpd_flag |= VPD_MODEL_DESC;
				index += 2;
				i = vpd[index];
				index += 1;
				j = 0;
				Length -= (3+i);
				while(i--) {
					phba->ModelDesc[j++] = vpd[index++];
					if (j == 255)
						break;
				}
				phba->ModelDesc[j] = 0;
				continue;
			}
			else if ((vpd[index] == 'V') && (vpd[index+1] == '2')) {
				phba->vpd_flag |= VPD_MODEL_NAME;
				index += 2;
				i = vpd[index];
				index += 1;
				j = 0;
				Length -= (3+i);
				while(i--) {
					phba->ModelName[j++] = vpd[index++];
					if (j == 79)
						break;
				}
				phba->ModelName[j] = 0;
				continue;
			}
			else if ((vpd[index] == 'V') && (vpd[index+1] == '3')) {
				phba->vpd_flag |= VPD_PROGRAM_TYPE;
				index += 2;
				i = vpd[index];
				index += 1;
				j = 0;
				Length -= (3+i);
				while(i--) {
					phba->ProgramType[j++] = vpd[index++];
					if (j == 255)
						break;
				}
				phba->ProgramType[j] = 0;
				continue;
			}
			else if ((vpd[index] == 'V') && (vpd[index+1] == '4')) {
				phba->vpd_flag |= VPD_PORT;
				index += 2;
				i = vpd[index];
				index += 1;
				j = 0;
				Length -= (3+i);
				while(i--) {
					if ((phba->sli_rev == LPFC_SLI_REV4) &&
					    (phba->sli4_hba.pport_name_sta ==
					     LPFC_SLI4_PPNAME_GET)) {
						j++;
						index++;
					} else
						phba->Port[j++] = vpd[index++];
					if (j == 19)
						break;
				}
				if ((phba->sli_rev != LPFC_SLI_REV4) ||
				    (phba->sli4_hba.pport_name_sta ==
				     LPFC_SLI4_PPNAME_NON))
					phba->Port[j] = 0;
				continue;
			}
			else {
				index += 2;
				i = vpd[index];
				index += 1;
				index += i;
				Length -= (3 + i);
			}
		}
		finished = 0;
		break;
		case 0x78:
			finished = 1;
			break;
		default:
			index ++;
			break;
		}
	}

	return(1);
}

/**
 * lpfc_get_hba_model_desc - Retrieve HBA device model name and description
 * @phba: pointer to lpfc hba data structure.
 * @mdp: pointer to the data structure to hold the derived model name.
 * @descp: pointer to the data structure to hold the derived description.
 *
 * This routine retrieves HBA's description based on its registered PCI device
 * ID. The @descp passed into this function points to an array of 256 chars. It
 * shall be returned with the model name, maximum speed, and the host bus type.
 * The @mdp passed into this function points to an array of 80 chars. When the
 * function returns, the @mdp will be filled with the model name.
 **/
static void
lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
{
	lpfc_vpd_t *vp;
	uint16_t dev_id = phba->pcidev->device;
	int max_speed;
	int GE = 0;
	int oneConnect = 0; /* default is not a oneConnect */
	struct {
		char *name;
		char *bus;
		char *function;
	} m = {"<Unknown>", "", ""};

	if (mdp && mdp[0] != '\0'
		&& descp && descp[0] != '\0')
		return;

	if (phba->lmt & LMT_64Gb)
		max_speed = 64;
	else if (phba->lmt & LMT_32Gb)
		max_speed = 32;
	else if (phba->lmt & LMT_16Gb)
		max_speed = 16;
	else if (phba->lmt & LMT_10Gb)
		max_speed = 10;
	else if (phba->lmt & LMT_8Gb)
		max_speed = 8;
	else if (phba->lmt & LMT_4Gb)
		max_speed = 4;
	else if (phba->lmt & LMT_2Gb)
		max_speed = 2;
	else if (phba->lmt & LMT_1Gb)
		max_speed = 1;
	else
		max_speed = 0;

	vp = &phba->vpd;

	switch (dev_id) {
	case PCI_DEVICE_ID_FIREFLY:
		m = (typeof(m)){"LP6000", "PCI",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_SUPERFLY:
		if (vp->rev.biuRev >= 1 && vp->rev.biuRev <= 3)
			m = (typeof(m)){"LP7000", "PCI", ""};
		else
			m = (typeof(m)){"LP7000E", "PCI", ""};
		m.function = "Obsolete, Unsupported Fibre Channel Adapter";
		break;
	case PCI_DEVICE_ID_DRAGONFLY:
		m = (typeof(m)){"LP8000", "PCI",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_CENTAUR:
		if (FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID)
			m = (typeof(m)){"LP9002", "PCI", ""};
		else
			m = (typeof(m)){"LP9000", "PCI", ""};
		m.function = "Obsolete, Unsupported Fibre Channel Adapter";
		break;
	case PCI_DEVICE_ID_RFLY:
		m = (typeof(m)){"LP952", "PCI",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_PEGASUS:
		m = (typeof(m)){"LP9802", "PCI-X",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_THOR:
		m = (typeof(m)){"LP10000", "PCI-X",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_VIPER:
		m = (typeof(m)){"LPX1000",  "PCI-X",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_PFLY:
		m = (typeof(m)){"LP982", "PCI-X",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_TFLY:
		m = (typeof(m)){"LP1050", "PCI-X",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_HELIOS:
		m = (typeof(m)){"LP11000", "PCI-X2",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_HELIOS_SCSP:
		m = (typeof(m)){"LP11000-SP", "PCI-X2",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_HELIOS_DCSP:
		m = (typeof(m)){"LP11002-SP",  "PCI-X2",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_NEPTUNE:
		m = (typeof(m)){"LPe1000", "PCIe",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_NEPTUNE_SCSP:
		m = (typeof(m)){"LPe1000-SP", "PCIe",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_NEPTUNE_DCSP:
		m = (typeof(m)){"LPe1002-SP", "PCIe",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_BMID:
		m = (typeof(m)){"LP1150", "PCI-X2", "Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_BSMB:
		m = (typeof(m)){"LP111", "PCI-X2",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_ZEPHYR:
		m = (typeof(m)){"LPe11000", "PCIe", "Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_ZEPHYR_SCSP:
		m = (typeof(m)){"LPe11000", "PCIe", "Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_ZEPHYR_DCSP:
		m = (typeof(m)){"LP2105", "PCIe", "FCoE Adapter"};
		GE = 1;
		break;
	case PCI_DEVICE_ID_ZMID:
		m = (typeof(m)){"LPe1150", "PCIe", "Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_ZSMB:
		m = (typeof(m)){"LPe111", "PCIe", "Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_LP101:
		m = (typeof(m)){"LP101", "PCI-X",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_LP10000S:
		m = (typeof(m)){"LP10000-S", "PCI",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_LP11000S:
		m = (typeof(m)){"LP11000-S", "PCI-X2",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_LPE11000S:
		m = (typeof(m)){"LPe11000-S", "PCIe",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_SAT:
		m = (typeof(m)){"LPe12000", "PCIe", "Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_SAT_MID:
		m = (typeof(m)){"LPe1250", "PCIe", "Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_SAT_SMB:
		m = (typeof(m)){"LPe121", "PCIe", "Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_SAT_DCSP:
		m = (typeof(m)){"LPe12002-SP", "PCIe", "Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_SAT_SCSP:
		m = (typeof(m)){"LPe12000-SP", "PCIe", "Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_SAT_S:
		m = (typeof(m)){"LPe12000-S", "PCIe", "Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_HORNET:
		m = (typeof(m)){"LP21000", "PCIe",
				"Obsolete, Unsupported FCoE Adapter"};
		GE = 1;
		break;
	case PCI_DEVICE_ID_PROTEUS_VF:
		m = (typeof(m)){"LPev12000", "PCIe IOV",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_PROTEUS_PF:
		m = (typeof(m)){"LPev12000", "PCIe IOV",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_PROTEUS_S:
		m = (typeof(m)){"LPemv12002-S", "PCIe IOV",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_TIGERSHARK:
		oneConnect = 1;
		m = (typeof(m)){"OCe10100", "PCIe", "FCoE"};
		break;
	case PCI_DEVICE_ID_TOMCAT:
		oneConnect = 1;
		m = (typeof(m)){"OCe11100", "PCIe", "FCoE"};
		break;
	case PCI_DEVICE_ID_FALCON:
		m = (typeof(m)){"LPSe12002-ML1-E", "PCIe",
				"EmulexSecure Fibre"};
		break;
	case PCI_DEVICE_ID_BALIUS:
		m = (typeof(m)){"LPVe12002", "PCIe Shared I/O",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_LANCER_FC:
		m = (typeof(m)){"LPe16000", "PCIe", "Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_LANCER_FC_VF:
		m = (typeof(m)){"LPe16000", "PCIe",
				"Obsolete, Unsupported Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_LANCER_FCOE:
		oneConnect = 1;
		m = (typeof(m)){"OCe15100", "PCIe", "FCoE"};
		break;
	case PCI_DEVICE_ID_LANCER_FCOE_VF:
		oneConnect = 1;
		m = (typeof(m)){"OCe15100", "PCIe",
				"Obsolete, Unsupported FCoE"};
		break;
	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_LANCER_G7P_FC:
		m = (typeof(m)){"LPe38000", "PCIe", "Fibre Channel Adapter"};
		break;
	case PCI_DEVICE_ID_SKYHAWK:
	case PCI_DEVICE_ID_SKYHAWK_VF:
		oneConnect = 1;
		m = (typeof(m)){"OCe14000", "PCIe", "FCoE"};
		break;
	default:
		m = (typeof(m)){"Unknown", "", ""};
		break;
	}

	if (mdp && mdp[0] == '\0')
		snprintf(mdp, 79,"%s", m.name);
	/*
	 * oneConnect hba requires special processing, they are all initiators
	 * and we put the port number on the end
	 */
	if (descp && descp[0] == '\0') {
		if (oneConnect)
			snprintf(descp, 255,
				"Emulex OneConnect %s, %s Initiator %s",
				m.name, m.function,
				phba->Port);
		else if (max_speed == 0)
			snprintf(descp, 255,
				"Emulex %s %s %s",
				m.name, m.bus, m.function);
		else
			snprintf(descp, 255,
				"Emulex %s %d%s %s %s",
				m.name, max_speed, (GE) ? "GE" : "Gb",
				m.bus, m.function);
	}
}

/**
 * lpfc_post_buffer - Post IOCB(s) with DMA buffer descriptor(s) to a IOCB ring
 * @phba: pointer to lpfc hba data structure.
 * @pring: pointer to a IOCB ring.
 * @cnt: the number of IOCBs to be posted to the IOCB ring.
 *
 * This routine posts a given number of IOCBs with the associated DMA buffer
 * descriptors specified by the cnt argument to the given IOCB ring.
 *
 * Return codes
 *   The number of IOCBs NOT able to be posted to the IOCB ring.
 **/
int
lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt)
{
	IOCB_t *icmd;
	struct lpfc_iocbq *iocb;
	struct lpfc_dmabuf *mp1, *mp2;

	cnt += pring->missbufcnt;

	/* While there are buffers to post */
	while (cnt > 0) {
		/* Allocate buffer for  command iocb */
		iocb = lpfc_sli_get_iocbq(phba);
		if (iocb == NULL) {
			pring->missbufcnt = cnt;
			return cnt;
		}
		icmd = &iocb->iocb;

		/* 2 buffers can be posted per command */
		/* Allocate buffer to post */
		mp1 = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
		if (mp1)
		    mp1->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &mp1->phys);
		if (!mp1 || !mp1->virt) {
			kfree(mp1);
			lpfc_sli_release_iocbq(phba, iocb);
			pring->missbufcnt = cnt;
			return cnt;
		}

		INIT_LIST_HEAD(&mp1->list);
		/* Allocate buffer to post */
		if (cnt > 1) {
			mp2 = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
			if (mp2)
				mp2->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
							    &mp2->phys);
			if (!mp2 || !mp2->virt) {
				kfree(mp2);
				lpfc_mbuf_free(phba, mp1->virt, mp1->phys);
				kfree(mp1);
				lpfc_sli_release_iocbq(phba, iocb);
				pring->missbufcnt = cnt;
				return cnt;
			}

			INIT_LIST_HEAD(&mp2->list);
		} else {
			mp2 = NULL;
		}

		icmd->un.cont64[0].addrHigh = putPaddrHigh(mp1->phys);
		icmd->un.cont64[0].addrLow = putPaddrLow(mp1->phys);
		icmd->un.cont64[0].tus.f.bdeSize = FCELSSIZE;
		icmd->ulpBdeCount = 1;
		cnt--;
		if (mp2) {
			icmd->un.cont64[1].addrHigh = putPaddrHigh(mp2->phys);
			icmd->un.cont64[1].addrLow = putPaddrLow(mp2->phys);
			icmd->un.cont64[1].tus.f.bdeSize = FCELSSIZE;
			cnt--;
			icmd->ulpBdeCount = 2;
		}

		icmd->ulpCommand = CMD_QUE_RING_BUF64_CN;
		icmd->ulpLe = 1;

		if (lpfc_sli_issue_iocb(phba, pring->ringno, iocb, 0) ==
		    IOCB_ERROR) {
			lpfc_mbuf_free(phba, mp1->virt, mp1->phys);
			kfree(mp1);
			cnt++;
			if (mp2) {
				lpfc_mbuf_free(phba, mp2->virt, mp2->phys);
				kfree(mp2);
				cnt++;
			}
			lpfc_sli_release_iocbq(phba, iocb);
			pring->missbufcnt = cnt;
			return cnt;
		}
		lpfc_sli_ringpostbuf_put(phba, pring, mp1);
		if (mp2)
			lpfc_sli_ringpostbuf_put(phba, pring, mp2);
	}
	pring->missbufcnt = 0;
	return 0;
}

/**
 * lpfc_post_rcv_buf - Post the initial receive IOCB buffers to ELS ring
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine posts initial receive IOCB buffers to the ELS ring. The
 * current number of initial IOCB buffers specified by LPFC_BUF_RING0 is
 * set to 64 IOCBs. SLI3 only.
 *
 * Return codes
 *   0 - success (currently always success)
 **/
static int
lpfc_post_rcv_buf(struct lpfc_hba *phba)
{
	struct lpfc_sli *psli = &phba->sli;

	/* Ring 0, ELS / CT buffers */
	lpfc_post_buffer(phba, &psli->sli3_ring[LPFC_ELS_RING], LPFC_BUF_RING0);
	/* Ring 2 - FCP no buffers needed */

	return 0;
}

#define S(N,V) (((V)<<(N))|((V)>>(32-(N))))

/**
 * lpfc_sha_init - Set up initial array of hash table entries
 * @HashResultPointer: pointer to an array as hash table.
 *
 * This routine sets up the initial values to the array of hash table entries
 * for the LC HBAs.
 **/
static void
lpfc_sha_init(uint32_t * HashResultPointer)
{
	HashResultPointer[0] = 0x67452301;
	HashResultPointer[1] = 0xEFCDAB89;
	HashResultPointer[2] = 0x98BADCFE;
	HashResultPointer[3] = 0x10325476;
	HashResultPointer[4] = 0xC3D2E1F0;
}

/**
 * lpfc_sha_iterate - Iterate initial hash table with the working hash table
 * @HashResultPointer: pointer to an initial/result hash table.
 * @HashWorkingPointer: pointer to an working hash table.
 *
 * This routine iterates an initial hash table pointed by @HashResultPointer
 * with the values from the working hash table pointeed by @HashWorkingPointer.
 * The results are putting back to the initial hash table, returned through
 * the @HashResultPointer as the result hash table.
 **/
static void
lpfc_sha_iterate(uint32_t * HashResultPointer, uint32_t * HashWorkingPointer)
{
	int t;
	uint32_t TEMP;
	uint32_t A, B, C, D, E;
	t = 16;
	do {
		HashWorkingPointer[t] =
		    S(1,
		      HashWorkingPointer[t - 3] ^ HashWorkingPointer[t -
								     8] ^
		      HashWorkingPointer[t - 14] ^ HashWorkingPointer[t - 16]);
	} while (++t <= 79);
	t = 0;
	A = HashResultPointer[0];
	B = HashResultPointer[1];
	C = HashResultPointer[2];
	D = HashResultPointer[3];
	E = HashResultPointer[4];

	do {
		if (t < 20) {
			TEMP = ((B & C) | ((~B) & D)) + 0x5A827999;
		} else if (t < 40) {
			TEMP = (B ^ C ^ D) + 0x6ED9EBA1;
		} else if (t < 60) {
			TEMP = ((B & C) | (B & D) | (C & D)) + 0x8F1BBCDC;
		} else {
			TEMP = (B ^ C ^ D) + 0xCA62C1D6;
		}
		TEMP += S(5, A) + E + HashWorkingPointer[t];
		E = D;
		D = C;
		C = S(30, B);
		B = A;
		A = TEMP;
	} while (++t <= 79);

	HashResultPointer[0] += A;
	HashResultPointer[1] += B;
	HashResultPointer[2] += C;
	HashResultPointer[3] += D;
	HashResultPointer[4] += E;

}

/**
 * lpfc_challenge_key - Create challenge key based on WWPN of the HBA
 * @RandomChallenge: pointer to the entry of host challenge random number array.
 * @HashWorking: pointer to the entry of the working hash array.
 *
 * This routine calculates the working hash array referred by @HashWorking
 * from the challenge random numbers associated with the host, referred by
 * @RandomChallenge. The result is put into the entry of the working hash
 * array and returned by reference through @HashWorking.
 **/
static void
lpfc_challenge_key(uint32_t * RandomChallenge, uint32_t * HashWorking)
{
	*HashWorking = (*RandomChallenge ^ *HashWorking);
}

/**
 * lpfc_hba_init - Perform special handling for LC HBA initialization
 * @phba: pointer to lpfc hba data structure.
 * @hbainit: pointer to an array of unsigned 32-bit integers.
 *
 * This routine performs the special handling for LC HBA initialization.
 **/
void
lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit)
{
	int t;
	uint32_t *HashWorking;
	uint32_t *pwwnn = (uint32_t *) phba->wwnn;

	HashWorking = kcalloc(80, sizeof(uint32_t), GFP_KERNEL);
	if (!HashWorking)
		return;

	HashWorking[0] = HashWorking[78] = *pwwnn++;
	HashWorking[1] = HashWorking[79] = *pwwnn;

	for (t = 0; t < 7; t++)
		lpfc_challenge_key(phba->RandomData + t, HashWorking + t);

	lpfc_sha_init(hbainit);
	lpfc_sha_iterate(hbainit, HashWorking);
	kfree(HashWorking);
}

/**
 * lpfc_cleanup - Performs vport cleanups before deleting a vport
 * @vport: pointer to a virtual N_Port data structure.
 *
 * This routine performs the necessary cleanups before deleting the @vport.
 * It invokes the discovery state machine to perform necessary state
 * transitions and to release the ndlps associated with the @vport. Note,
 * the physical port is treated as @vport 0.
 **/
void
lpfc_cleanup(struct lpfc_vport *vport)
{
	struct lpfc_hba   *phba = vport->phba;
	struct lpfc_nodelist *ndlp, *next_ndlp;
	int i = 0;

	if (phba->link_state > LPFC_LINK_DOWN)
		lpfc_port_link_failure(vport);

	/* Clean up VMID resources */
	if (lpfc_is_vmid_enabled(phba))
		lpfc_vmid_vport_cleanup(vport);

	list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
		if (vport->port_type != LPFC_PHYSICAL_PORT &&
		    ndlp->nlp_DID == Fabric_DID) {
			/* Just free up ndlp with Fabric_DID for vports */
			lpfc_nlp_put(ndlp);
			continue;
		}

		if (ndlp->nlp_DID == Fabric_Cntl_DID &&
		    ndlp->nlp_state == NLP_STE_UNUSED_NODE) {
			lpfc_nlp_put(ndlp);
			continue;
		}

		/* Fabric Ports not in UNMAPPED state are cleaned up in the
		 * DEVICE_RM event.
		 */
		if (ndlp->nlp_type & NLP_FABRIC &&
		    ndlp->nlp_state == NLP_STE_UNMAPPED_NODE)
			lpfc_disc_state_machine(vport, ndlp, NULL,
					NLP_EVT_DEVICE_RECOVERY);

		if (!(ndlp->fc4_xpt_flags & (NVME_XPT_REGD|SCSI_XPT_REGD)))
			lpfc_disc_state_machine(vport, ndlp, NULL,
					NLP_EVT_DEVICE_RM);
	}

	/* At this point, ALL ndlp's should be gone
	 * because of the previous NLP_EVT_DEVICE_RM.
	 * Lets wait for this to happen, if needed.
	 */
	while (!list_empty(&vport->fc_nodes)) {
		if (i++ > 3000) {
			lpfc_printf_vlog(vport, KERN_ERR,
					 LOG_TRACE_EVENT,
				"0233 Nodelist not empty\n");
			list_for_each_entry_safe(ndlp, next_ndlp,
						&vport->fc_nodes, nlp_listp) {
				lpfc_printf_vlog(ndlp->vport, KERN_ERR,
						 LOG_TRACE_EVENT,
						 "0282 did:x%x ndlp:x%px "
						 "refcnt:%d xflags x%x nflag x%x\n",
						 ndlp->nlp_DID, (void *)ndlp,
						 kref_read(&ndlp->kref),
						 ndlp->fc4_xpt_flags,
						 ndlp->nlp_flag);
			}
			break;
		}

		/* Wait for any activity on ndlps to settle */
		msleep(10);
	}
	lpfc_cleanup_vports_rrqs(vport, NULL);
}

/**
 * lpfc_stop_vport_timers - Stop all the timers associated with a vport
 * @vport: pointer to a virtual N_Port data structure.
 *
 * This routine stops all the timers associated with a @vport. This function
 * is invoked before disabling or deleting a @vport. Note that the physical
 * port is treated as @vport 0.
 **/
void
lpfc_stop_vport_timers(struct lpfc_vport *vport)
{
	del_timer_sync(&vport->els_tmofunc);
	del_timer_sync(&vport->delayed_disc_tmo);
	lpfc_can_disctmo(vport);
	return;
}

/**
 * __lpfc_sli4_stop_fcf_redisc_wait_timer - Stop FCF rediscovery wait timer
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine stops the SLI4 FCF rediscover wait timer if it's on. The
 * caller of this routine should already hold the host lock.
 **/
void
__lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba)
{
	/* Clear pending FCF rediscovery wait flag */
	phba->fcf.fcf_flag &= ~FCF_REDISC_PEND;

	/* Now, try to stop the timer */
	del_timer(&phba->fcf.redisc_wait);
}

/**
 * lpfc_sli4_stop_fcf_redisc_wait_timer - Stop FCF rediscovery wait timer
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine stops the SLI4 FCF rediscover wait timer if it's on. It
 * checks whether the FCF rediscovery wait timer is pending with the host
 * lock held before proceeding with disabling the timer and clearing the
 * wait timer pendig flag.
 **/
void
lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba)
{
	spin_lock_irq(&phba->hbalock);
	if (!(phba->fcf.fcf_flag & FCF_REDISC_PEND)) {
		/* FCF rediscovery timer already fired or stopped */
		spin_unlock_irq(&phba->hbalock);
		return;
	}
	__lpfc_sli4_stop_fcf_redisc_wait_timer(phba);
	/* Clear failover in progress flags */
	phba->fcf.fcf_flag &= ~(FCF_DEAD_DISC | FCF_ACVL_DISC);
	spin_unlock_irq(&phba->hbalock);
}

/**
 * lpfc_cmf_stop - Stop CMF processing
 * @phba: pointer to lpfc hba data structure.
 *
 * This is called when the link goes down or if CMF mode is turned OFF.
 * It is also called when going offline or unloaded just before the
 * congestion info buffer is unregistered.
 **/
void
lpfc_cmf_stop(struct lpfc_hba *phba)
{
	int cpu;
	struct lpfc_cgn_stat *cgs;

	/* We only do something if CMF is enabled */
	if (!phba->sli4_hba.pc_sli4_params.cmf)
		return;

	lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
			"6221 Stop CMF / Cancel Timer\n");

	/* Cancel the CMF timer */
	hrtimer_cancel(&phba->cmf_timer);

	/* Zero CMF counters */
	atomic_set(&phba->cmf_busy, 0);
	for_each_present_cpu(cpu) {
		cgs = per_cpu_ptr(phba->cmf_stat, cpu);
		atomic64_set(&cgs->total_bytes, 0);
		atomic64_set(&cgs->rcv_bytes, 0);
		atomic_set(&cgs->rx_io_cnt, 0);
		atomic64_set(&cgs->rx_latency, 0);
	}
	atomic_set(&phba->cmf_bw_wait, 0);

	/* Resume any blocked IO - Queue unblock on workqueue */
	queue_work(phba->wq, &phba->unblock_request_work);
}

static inline uint64_t
lpfc_get_max_line_rate(struct lpfc_hba *phba)
{
	uint64_t rate = lpfc_sli_port_speed_get(phba);

	return ((((unsigned long)rate) * 1024 * 1024) / 10);
}

void
lpfc_cmf_signal_init(struct lpfc_hba *phba)
{
	lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
			"6223 Signal CMF init\n");

	/* Use the new fc_linkspeed to recalculate */
	phba->cmf_interval_rate = LPFC_CMF_INTERVAL;
	phba->cmf_max_line_rate = lpfc_get_max_line_rate(phba);
	phba->cmf_link_byte_count = div_u64(phba->cmf_max_line_rate *
					    phba->cmf_interval_rate, 1000);
	phba->cmf_max_bytes_per_interval = phba->cmf_link_byte_count;

	/* This is a signal to firmware to sync up CMF BW with link speed */
	lpfc_issue_cmf_sync_wqe(phba, 0, 0);
}

/**
 * lpfc_cmf_start - Start CMF processing
 * @phba: pointer to lpfc hba data structure.
 *
 * This is called when the link comes up or if CMF mode is turned OFF
 * to Monitor or Managed.
 **/
void
lpfc_cmf_start(struct lpfc_hba *phba)
{
	struct lpfc_cgn_stat *cgs;
	int cpu;

	/* We only do something if CMF is enabled */
	if (!phba->sli4_hba.pc_sli4_params.cmf ||
	    phba->cmf_active_mode == LPFC_CFG_OFF)
		return;

	/* Reinitialize congestion buffer info */
	lpfc_init_congestion_buf(phba);

	atomic_set(&phba->cgn_fabric_warn_cnt, 0);
	atomic_set(&phba->cgn_fabric_alarm_cnt, 0);
	atomic_set(&phba->cgn_sync_alarm_cnt, 0);
	atomic_set(&phba->cgn_sync_warn_cnt, 0);

	atomic_set(&phba->cmf_busy, 0);
	for_each_present_cpu(cpu) {
		cgs = per_cpu_ptr(phba->cmf_stat, cpu);
		atomic64_set(&cgs->total_bytes, 0);
		atomic64_set(&cgs->rcv_bytes, 0);
		atomic_set(&cgs->rx_io_cnt, 0);
		atomic64_set(&cgs->rx_latency, 0);
	}
	phba->cmf_latency.tv_sec = 0;
	phba->cmf_latency.tv_nsec = 0;

	lpfc_cmf_signal_init(phba);

	lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
			"6222 Start CMF / Timer\n");

	phba->cmf_timer_cnt = 0;
	hrtimer_start(&phba->cmf_timer,
		      ktime_set(0, LPFC_CMF_INTERVAL * 1000000),
		      HRTIMER_MODE_REL);
	/* Setup for latency check in IO cmpl routines */
	ktime_get_real_ts64(&phba->cmf_latency);

	atomic_set(&phba->cmf_bw_wait, 0);
	atomic_set(&phba->cmf_stop_io, 0);
}

/**
 * lpfc_stop_hba_timers - Stop all the timers associated with an HBA
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine stops all the timers associated with a HBA. This function is
 * invoked before either putting a HBA offline or unloading the driver.
 **/
void
lpfc_stop_hba_timers(struct lpfc_hba *phba)
{
	if (phba->pport)
		lpfc_stop_vport_timers(phba->pport);
	cancel_delayed_work_sync(&phba->eq_delay_work);
	cancel_delayed_work_sync(&phba->idle_stat_delay_work);
	del_timer_sync(&phba->sli.mbox_tmo);
	del_timer_sync(&phba->fabric_block_timer);
	del_timer_sync(&phba->eratt_poll);
	del_timer_sync(&phba->hb_tmofunc);
	if (phba->sli_rev == LPFC_SLI_REV4) {
		del_timer_sync(&phba->rrq_tmr);
		phba->hba_flag &= ~HBA_RRQ_ACTIVE;
	}
	phba->hba_flag &= ~(HBA_HBEAT_INP | HBA_HBEAT_TMO);

	switch (phba->pci_dev_grp) {
	case LPFC_PCI_DEV_LP:
		/* Stop any LightPulse device specific driver timers */
		del_timer_sync(&phba->fcp_poll_timer);
		break;
	case LPFC_PCI_DEV_OC:
		/* Stop any OneConnect device specific driver timers */
		lpfc_sli4_stop_fcf_redisc_wait_timer(phba);
		break;
	default:
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0297 Invalid device group (x%x)\n",
				phba->pci_dev_grp);
		break;
	}
	return;
}

/**
 * lpfc_block_mgmt_io - Mark a HBA's management interface as blocked
 * @phba: pointer to lpfc hba data structure.
 * @mbx_action: flag for mailbox no wait action.
 *
 * This routine marks a HBA's management interface as blocked. Once the HBA's
 * management interface is marked as blocked, all the user space access to
 * the HBA, whether they are from sysfs interface or libdfc interface will
 * all be blocked. The HBA is set to block the management interface when the
 * driver prepares the HBA interface for online or offline.
 **/
static void
lpfc_block_mgmt_io(struct lpfc_hba *phba, int mbx_action)
{
	unsigned long iflag;
	uint8_t actcmd = MBX_HEARTBEAT;
	unsigned long timeout;

	spin_lock_irqsave(&phba->hbalock, iflag);
	phba->sli.sli_flag |= LPFC_BLOCK_MGMT_IO;
	spin_unlock_irqrestore(&phba->hbalock, iflag);
	if (mbx_action == LPFC_MBX_NO_WAIT)
		return;
	timeout = msecs_to_jiffies(LPFC_MBOX_TMO * 1000) + jiffies;
	spin_lock_irqsave(&phba->hbalock, iflag);
	if (phba->sli.mbox_active) {
		actcmd = phba->sli.mbox_active->u.mb.mbxCommand;
		/* 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,
				phba->sli.mbox_active) * 1000) + jiffies;
	}
	spin_unlock_irqrestore(&phba->hbalock, iflag);

	/* 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)) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"2813 Mgmt IO is Blocked %x "
					"- mbox cmd %x still active\n",
					phba->sli.sli_flag, actcmd);
			break;
		}
	}
}

/**
 * lpfc_sli4_node_prep - Assign RPIs for active nodes.
 * @phba: pointer to lpfc hba data structure.
 *
 * Allocate RPIs for all active remote nodes. This is needed whenever
 * an SLI4 adapter is reset and the driver is not unloading. Its purpose
 * is to fixup the temporary rpi assignments.
 **/
void
lpfc_sli4_node_prep(struct lpfc_hba *phba)
{
	struct lpfc_nodelist  *ndlp, *next_ndlp;
	struct lpfc_vport **vports;
	int i, rpi;

	if (phba->sli_rev != LPFC_SLI_REV4)
		return;

	vports = lpfc_create_vport_work_array(phba);
	if (vports == NULL)
		return;

	for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
		if (vports[i]->load_flag & FC_UNLOADING)
			continue;

		list_for_each_entry_safe(ndlp, next_ndlp,
					 &vports[i]->fc_nodes,
					 nlp_listp) {
			rpi = lpfc_sli4_alloc_rpi(phba);
			if (rpi == LPFC_RPI_ALLOC_ERROR) {
				/* TODO print log? */
				continue;
			}
			ndlp->nlp_rpi = rpi;
			lpfc_printf_vlog(ndlp->vport, KERN_INFO,
					 LOG_NODE | LOG_DISCOVERY,
					 "0009 Assign RPI x%x to ndlp x%px "
					 "DID:x%06x flg:x%x\n",
					 ndlp->nlp_rpi, ndlp, ndlp->nlp_DID,
					 ndlp->nlp_flag);
		}
	}
	lpfc_destroy_vport_work_array(phba, vports);
}

/**
 * lpfc_create_expedite_pool - create expedite pool
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine moves a batch of XRIs from lpfc_io_buf_list_put of HWQ 0
 * to expedite pool. Mark them as expedite.
 **/
static void lpfc_create_expedite_pool(struct lpfc_hba *phba)
{
	struct lpfc_sli4_hdw_queue *qp;
	struct lpfc_io_buf *lpfc_ncmd;
	struct lpfc_io_buf *lpfc_ncmd_next;
	struct lpfc_epd_pool *epd_pool;
	unsigned long iflag;

	epd_pool = &phba->epd_pool;
	qp = &phba->sli4_hba.hdwq[0];

	spin_lock_init(&epd_pool->lock);
	spin_lock_irqsave(&qp->io_buf_list_put_lock, iflag);
	spin_lock(&epd_pool->lock);
	INIT_LIST_HEAD(&epd_pool->list);
	list_for_each_entry_safe(lpfc_ncmd, lpfc_ncmd_next,
				 &qp->lpfc_io_buf_list_put, list) {
		list_move_tail(&lpfc_ncmd->list, &epd_pool->list);
		lpfc_ncmd->expedite = true;
		qp->put_io_bufs--;
		epd_pool->count++;
		if (epd_pool->count >= XRI_BATCH)
			break;
	}
	spin_unlock(&epd_pool->lock);
	spin_unlock_irqrestore(&qp->io_buf_list_put_lock, iflag);
}

/**
 * lpfc_destroy_expedite_pool - destroy expedite pool
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine returns XRIs from expedite pool to lpfc_io_buf_list_put
 * of HWQ 0. Clear the mark.
 **/
static void lpfc_destroy_expedite_pool(struct lpfc_hba *phba)
{
	struct lpfc_sli4_hdw_queue *qp;
	struct lpfc_io_buf *lpfc_ncmd;
	struct lpfc_io_buf *lpfc_ncmd_next;
	struct lpfc_epd_pool *epd_pool;
	unsigned long iflag;

	epd_pool = &phba->epd_pool;
	qp = &phba->sli4_hba.hdwq[0];

	spin_lock_irqsave(&qp->io_buf_list_put_lock, iflag);
	spin_lock(&epd_pool->lock);
	list_for_each_entry_safe(lpfc_ncmd, lpfc_ncmd_next,
				 &epd_pool->list, list) {
		list_move_tail(&lpfc_ncmd->list,
			       &qp->lpfc_io_buf_list_put);
		lpfc_ncmd->flags = false;
		qp->put_io_bufs++;
		epd_pool->count--;
	}
	spin_unlock(&epd_pool->lock);
	spin_unlock_irqrestore(&qp->io_buf_list_put_lock, iflag);
}

/**
 * lpfc_create_multixri_pools - create multi-XRI pools
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine initialize public, private per HWQ. Then, move XRIs from
 * lpfc_io_buf_list_put to public pool. High and low watermark are also
 * Initialized.
 **/
void lpfc_create_multixri_pools(struct lpfc_hba *phba)
{
	u32 i, j;
	u32 hwq_count;
	u32 count_per_hwq;
	struct lpfc_io_buf *lpfc_ncmd;
	struct lpfc_io_buf *lpfc_ncmd_next;
	unsigned long iflag;
	struct lpfc_sli4_hdw_queue *qp;
	struct lpfc_multixri_pool *multixri_pool;
	struct lpfc_pbl_pool *pbl_pool;
	struct lpfc_pvt_pool *pvt_pool;

	lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
			"1234 num_hdw_queue=%d num_present_cpu=%d common_xri_cnt=%d\n",
			phba->cfg_hdw_queue, phba->sli4_hba.num_present_cpu,
			phba->sli4_hba.io_xri_cnt);

	if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME)
		lpfc_create_expedite_pool(phba);

	hwq_count = phba->cfg_hdw_queue;
	count_per_hwq = phba->sli4_hba.io_xri_cnt / hwq_count;

	for (i = 0; i < hwq_count; i++) {
		multixri_pool = kzalloc(sizeof(*multixri_pool), GFP_KERNEL);

		if (!multixri_pool) {
			lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
					"1238 Failed to allocate memory for "
					"multixri_pool\n");

			if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME)
				lpfc_destroy_expedite_pool(phba);

			j = 0;
			while (j < i) {
				qp = &phba->sli4_hba.hdwq[j];
				kfree(qp->p_multixri_pool);
				j++;
			}
			phba->cfg_xri_rebalancing = 0;
			return;
		}

		qp = &phba->sli4_hba.hdwq[i];
		qp->p_multixri_pool = multixri_pool;

		multixri_pool->xri_limit = count_per_hwq;
		multixri_pool->rrb_next_hwqid = i;

		/* Deal with public free xri pool */
		pbl_pool = &multixri_pool->pbl_pool;
		spin_lock_init(&pbl_pool->lock);
		spin_lock_irqsave(&qp->io_buf_list_put_lock, iflag);
		spin_lock(&pbl_pool->lock);
		INIT_LIST_HEAD(&pbl_pool->list);
		list_for_each_entry_safe(lpfc_ncmd, lpfc_ncmd_next,
					 &qp->lpfc_io_buf_list_put, list) {
			list_move_tail(&lpfc_ncmd->list, &pbl_pool->list);
			qp->put_io_bufs--;
			pbl_pool->count++;
		}
		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"1235 Moved %d buffers from PUT list over to pbl_pool[%d]\n",
				pbl_pool->count, i);
		spin_unlock(&pbl_pool->lock);
		spin_unlock_irqrestore(&qp->io_buf_list_put_lock, iflag);

		/* Deal with private free xri pool */
		pvt_pool = &multixri_pool->pvt_pool;
		pvt_pool->high_watermark = multixri_pool->xri_limit / 2;
		pvt_pool->low_watermark = XRI_BATCH;
		spin_lock_init(&pvt_pool->lock);
		spin_lock_irqsave(&pvt_pool->lock, iflag);
		INIT_LIST_HEAD(&pvt_pool->list);
		pvt_pool->count = 0;
		spin_unlock_irqrestore(&pvt_pool->lock, iflag);
	}
}

/**
 * lpfc_destroy_multixri_pools - destroy multi-XRI pools
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine returns XRIs from public/private to lpfc_io_buf_list_put.
 **/
static void lpfc_destroy_multixri_pools(struct lpfc_hba *phba)
{
	u32 i;
	u32 hwq_count;
	struct lpfc_io_buf *lpfc_ncmd;
	struct lpfc_io_buf *lpfc_ncmd_next;
	unsigned long iflag;
	struct lpfc_sli4_hdw_queue *qp;
	struct lpfc_multixri_pool *multixri_pool;
	struct lpfc_pbl_pool *pbl_pool;
	struct lpfc_pvt_pool *pvt_pool;

	if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME)
		lpfc_destroy_expedite_pool(phba);

	if (!(phba->pport->load_flag & FC_UNLOADING))
		lpfc_sli_flush_io_rings(phba);

	hwq_count = phba->cfg_hdw_queue;

	for (i = 0; i < hwq_count; i++) {
		qp = &phba->sli4_hba.hdwq[i];
		multixri_pool = qp->p_multixri_pool;
		if (!multixri_pool)
			continue;

		qp->p_multixri_pool = NULL;

		spin_lock_irqsave(&qp->io_buf_list_put_lock, iflag);

		/* Deal with public free xri pool */
		pbl_pool = &multixri_pool->pbl_pool;
		spin_lock(&pbl_pool->lock);

		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"1236 Moving %d buffers from pbl_pool[%d] TO PUT list\n",
				pbl_pool->count, i);

		list_for_each_entry_safe(lpfc_ncmd, lpfc_ncmd_next,
					 &pbl_pool->list, list) {
			list_move_tail(&lpfc_ncmd->list,
				       &qp->lpfc_io_buf_list_put);
			qp->put_io_bufs++;
			pbl_pool->count--;
		}

		INIT_LIST_HEAD(&pbl_pool->list);
		pbl_pool->count = 0;

		spin_unlock(&pbl_pool->lock);

		/* Deal with private free xri pool */
		pvt_pool = &multixri_pool->pvt_pool;
		spin_lock(&pvt_pool->lock);

		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"1237 Moving %d buffers from pvt_pool[%d] TO PUT list\n",
				pvt_pool->count, i);

		list_for_each_entry_safe(lpfc_ncmd, lpfc_ncmd_next,
					 &pvt_pool->list, list) {
			list_move_tail(&lpfc_ncmd->list,
				       &qp->lpfc_io_buf_list_put);
			qp->put_io_bufs++;
			pvt_pool->count--;
		}

		INIT_LIST_HEAD(&pvt_pool->list);
		pvt_pool->count = 0;

		spin_unlock(&pvt_pool->lock);
		spin_unlock_irqrestore(&qp->io_buf_list_put_lock, iflag);

		kfree(multixri_pool);
	}
}

/**
 * lpfc_online - Initialize and bring a HBA online
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine initializes the HBA and brings a HBA online. During this
 * process, the management interface is blocked to prevent user space access
 * to the HBA interfering with the driver initialization.
 *
 * Return codes
 *   0 - successful
 *   1 - failed
 **/
int
lpfc_online(struct lpfc_hba *phba)
{
	struct lpfc_vport *vport;
	struct lpfc_vport **vports;
	int i, error = 0;
	bool vpis_cleared = false;

	if (!phba)
		return 0;
	vport = phba->pport;

	if (!(vport->fc_flag & FC_OFFLINE_MODE))
		return 0;

	lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
			"0458 Bring Adapter online\n");

	lpfc_block_mgmt_io(phba, LPFC_MBX_WAIT);

	if (phba->sli_rev == LPFC_SLI_REV4) {
		if (lpfc_sli4_hba_setup(phba)) { /* Initialize SLI4 HBA */
			lpfc_unblock_mgmt_io(phba);
			return 1;
		}
		spin_lock_irq(&phba->hbalock);
		if (!phba->sli4_hba.max_cfg_param.vpi_used)
			vpis_cleared = true;
		spin_unlock_irq(&phba->hbalock);

		/* Reestablish the local initiator port.
		 * The offline process destroyed the previous lport.
		 */
		if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME &&
				!phba->nvmet_support) {
			error = lpfc_nvme_create_localport(phba->pport);
			if (error)
				lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"6132 NVME restore reg failed "
					"on nvmei error x%x\n", error);
		}
	} else {
		lpfc_sli_queue_init(phba);
		if (lpfc_sli_hba_setup(phba)) {	/* Initialize SLI2/SLI3 HBA */
			lpfc_unblock_mgmt_io(phba);
			return 1;
		}
	}

	vports = lpfc_create_vport_work_array(phba);
	if (vports != NULL) {
		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
			struct Scsi_Host *shost;
			shost = lpfc_shost_from_vport(vports[i]);
			spin_lock_irq(shost->host_lock);
			vports[i]->fc_flag &= ~FC_OFFLINE_MODE;
			if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
				vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
			if (phba->sli_rev == LPFC_SLI_REV4) {
				vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
				if ((vpis_cleared) &&
				    (vports[i]->port_type !=
					LPFC_PHYSICAL_PORT))
					vports[i]->vpi = 0;
			}
			spin_unlock_irq(shost->host_lock);
		}
	}
	lpfc_destroy_vport_work_array(phba, vports);

	if (phba->cfg_xri_rebalancing)
		lpfc_create_multixri_pools(phba);

	lpfc_cpuhp_add(phba);

	lpfc_unblock_mgmt_io(phba);
	return 0;
}

/**
 * lpfc_unblock_mgmt_io - Mark a HBA's management interface to be not blocked
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine marks a HBA's management interface as not blocked. Once the
 * HBA's management interface is marked as not blocked, all the user space
 * access to the HBA, whether they are from sysfs interface or libdfc
 * interface will be allowed. The HBA is set to block the management interface
 * when the driver prepares the HBA interface for online or offline and then
 * set to unblock the management interface afterwards.
 **/
void
lpfc_unblock_mgmt_io(struct lpfc_hba * phba)
{
	unsigned long iflag;

	spin_lock_irqsave(&phba->hbalock, iflag);
	phba->sli.sli_flag &= ~LPFC_BLOCK_MGMT_IO;
	spin_unlock_irqrestore(&phba->hbalock, iflag);
}

/**
 * lpfc_offline_prep - Prepare a HBA to be brought offline
 * @phba: pointer to lpfc hba data structure.
 * @mbx_action: flag for mailbox shutdown action.
 *
 * This routine is invoked to prepare a HBA to be brought offline. It performs
 * unregistration login to all the nodes on all vports and flushes the mailbox
 * queue to make it ready to be brought offline.
 **/
void
lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action)
{
	struct lpfc_vport *vport = phba->pport;
	struct lpfc_nodelist  *ndlp, *next_ndlp;
	struct lpfc_vport **vports;
	struct Scsi_Host *shost;
	int i;
	int offline = 0;

	if (vport->fc_flag & FC_OFFLINE_MODE)
		return;

	lpfc_block_mgmt_io(phba, mbx_action);

	lpfc_linkdown(phba);

	offline =  pci_channel_offline(phba->pcidev);

	/* Issue an unreg_login to all nodes on all vports */
	vports = lpfc_create_vport_work_array(phba);
	if (vports != NULL) {
		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
			if (vports[i]->load_flag & FC_UNLOADING)
				continue;
			shost = lpfc_shost_from_vport(vports[i]);
			spin_lock_irq(shost->host_lock);
			vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED;
			vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
			vports[i]->fc_flag &= ~FC_VFI_REGISTERED;
			spin_unlock_irq(shost->host_lock);

			shost =	lpfc_shost_from_vport(vports[i]);
			list_for_each_entry_safe(ndlp, next_ndlp,
						 &vports[i]->fc_nodes,
						 nlp_listp) {

				spin_lock_irq(&ndlp->lock);
				ndlp->nlp_flag &= ~NLP_NPR_ADISC;
				spin_unlock_irq(&ndlp->lock);

				if (offline) {
					spin_lock_irq(&ndlp->lock);
					ndlp->nlp_flag &= ~(NLP_UNREG_INP |
							    NLP_RPI_REGISTERED);
					spin_unlock_irq(&ndlp->lock);
				} else {
					lpfc_unreg_rpi(vports[i], ndlp);
				}
				/*
				 * Whenever an SLI4 port goes offline, free the
				 * RPI. Get a new RPI when the adapter port
				 * comes back online.
				 */
				if (phba->sli_rev == LPFC_SLI_REV4) {
					lpfc_printf_vlog(vports[i], KERN_INFO,
						 LOG_NODE | LOG_DISCOVERY,
						 "0011 Free RPI x%x on "
						 "ndlp: x%px did x%x\n",
						 ndlp->nlp_rpi, ndlp,
						 ndlp->nlp_DID);
					lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi);
					ndlp->nlp_rpi = LPFC_RPI_ALLOC_ERROR;
				}

				if (ndlp->nlp_type & NLP_FABRIC) {
					lpfc_disc_state_machine(vports[i], ndlp,
						NULL, NLP_EVT_DEVICE_RECOVERY);

					/* Don't remove the node unless the node
					 * has been unregistered with the
					 * transport, and we're not in recovery
					 * before dev_loss_tmo triggered.
					 * Otherwise, let dev_loss take care of
					 * the node.
					 */
					if (!(ndlp->save_flags &
					      NLP_IN_RECOV_POST_DEV_LOSS) &&
					    !(ndlp->fc4_xpt_flags &
					      (NVME_XPT_REGD | SCSI_XPT_REGD)))
						lpfc_disc_state_machine
							(vports[i], ndlp,
							 NULL,
							 NLP_EVT_DEVICE_RM);
				}
			}
		}
	}
	lpfc_destroy_vport_work_array(phba, vports);

	lpfc_sli_mbox_sys_shutdown(phba, mbx_action);

	if (phba->wq)
		flush_workqueue(phba->wq);
}

/**
 * lpfc_offline - Bring a HBA offline
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine actually brings a HBA offline. It stops all the timers
 * associated with the HBA, brings down the SLI layer, and eventually
 * marks the HBA as in offline state for the upper layer protocol.
 **/
void
lpfc_offline(struct lpfc_hba *phba)
{
	struct Scsi_Host  *shost;
	struct lpfc_vport **vports;
	int i;

	if (phba->pport->fc_flag & FC_OFFLINE_MODE)
		return;

	/* stop port and all timers associated with this hba */
	lpfc_stop_port(phba);

	/* Tear down the local and target port registrations.  The
	 * nvme transports need to cleanup.
	 */
	lpfc_nvmet_destroy_targetport(phba);
	lpfc_nvme_destroy_localport(phba->pport);

	vports = lpfc_create_vport_work_array(phba);
	if (vports != NULL)
		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++)
			lpfc_stop_vport_timers(vports[i]);
	lpfc_destroy_vport_work_array(phba, vports);
	lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
			"0460 Bring Adapter offline\n");
	/* Bring down the SLI Layer and cleanup.  The HBA is offline
	   now.  */
	lpfc_sli_hba_down(phba);
	spin_lock_irq(&phba->hbalock);
	phba->work_ha = 0;
	spin_unlock_irq(&phba->hbalock);
	vports = lpfc_create_vport_work_array(phba);
	if (vports != NULL)
		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
			shost = lpfc_shost_from_vport(vports[i]);
			spin_lock_irq(shost->host_lock);
			vports[i]->work_port_events = 0;
			vports[i]->fc_flag |= FC_OFFLINE_MODE;
			spin_unlock_irq(shost->host_lock);
		}
	lpfc_destroy_vport_work_array(phba, vports);
	/* If OFFLINE flag is clear (i.e. unloading), cpuhp removal is handled
	 * in hba_unset
	 */
	if (phba->pport->fc_flag & FC_OFFLINE_MODE)
		__lpfc_cpuhp_remove(phba);

	if (phba->cfg_xri_rebalancing)
		lpfc_destroy_multixri_pools(phba);
}

/**
 * lpfc_scsi_free - Free all the SCSI buffers and IOCBs from driver lists
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is to free all the SCSI buffers and IOCBs from the driver
 * list back to kernel. It is called from lpfc_pci_remove_one to free
 * the internal resources before the device is removed from the system.
 **/
static void
lpfc_scsi_free(struct lpfc_hba *phba)
{
	struct lpfc_io_buf *sb, *sb_next;

	if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP))
		return;

	spin_lock_irq(&phba->hbalock);

	/* Release all the lpfc_scsi_bufs maintained by this host. */

	spin_lock(&phba->scsi_buf_list_put_lock);
	list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list_put,
				 list) {
		list_del(&sb->list);
		dma_pool_free(phba->lpfc_sg_dma_buf_pool, sb->data,
			      sb->dma_handle);
		kfree(sb);
		phba->total_scsi_bufs--;
	}
	spin_unlock(&phba->scsi_buf_list_put_lock);

	spin_lock(&phba->scsi_buf_list_get_lock);
	list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list_get,
				 list) {
		list_del(&sb->list);
		dma_pool_free(phba->lpfc_sg_dma_buf_pool, sb->data,
			      sb->dma_handle);
		kfree(sb);
		phba->total_scsi_bufs--;
	}
	spin_unlock(&phba->scsi_buf_list_get_lock);
	spin_unlock_irq(&phba->hbalock);
}

/**
 * lpfc_io_free - Free all the IO buffers and IOCBs from driver lists
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is to free all the IO buffers and IOCBs from the driver
 * list back to kernel. It is called from lpfc_pci_remove_one to free
 * the internal resources before the device is removed from the system.
 **/
void
lpfc_io_free(struct lpfc_hba *phba)
{
	struct lpfc_io_buf *lpfc_ncmd, *lpfc_ncmd_next;
	struct lpfc_sli4_hdw_queue *qp;
	int idx;

	for (idx = 0; idx < phba->cfg_hdw_queue; idx++) {
		qp = &phba->sli4_hba.hdwq[idx];
		/* Release all the lpfc_nvme_bufs maintained by this host. */
		spin_lock(&qp->io_buf_list_put_lock);
		list_for_each_entry_safe(lpfc_ncmd, lpfc_ncmd_next,
					 &qp->lpfc_io_buf_list_put,
					 list) {
			list_del(&lpfc_ncmd->list);
			qp->put_io_bufs--;
			dma_pool_free(phba->lpfc_sg_dma_buf_pool,
				      lpfc_ncmd->data, lpfc_ncmd->dma_handle);
			if (phba->cfg_xpsgl && !phba->nvmet_support)
				lpfc_put_sgl_per_hdwq(phba, lpfc_ncmd);
			lpfc_put_cmd_rsp_buf_per_hdwq(phba, lpfc_ncmd);
			kfree(lpfc_ncmd);
			qp->total_io_bufs--;
		}
		spin_unlock(&qp->io_buf_list_put_lock);

		spin_lock(&qp->io_buf_list_get_lock);
		list_for_each_entry_safe(lpfc_ncmd, lpfc_ncmd_next,
					 &qp->lpfc_io_buf_list_get,
					 list) {
			list_del(&lpfc_ncmd->list);
			qp->get_io_bufs--;
			dma_pool_free(phba->lpfc_sg_dma_buf_pool,
				      lpfc_ncmd->data, lpfc_ncmd->dma_handle);
			if (phba->cfg_xpsgl && !phba->nvmet_support)
				lpfc_put_sgl_per_hdwq(phba, lpfc_ncmd);
			lpfc_put_cmd_rsp_buf_per_hdwq(phba, lpfc_ncmd);
			kfree(lpfc_ncmd);
			qp->total_io_bufs--;
		}
		spin_unlock(&qp->io_buf_list_get_lock);
	}
}

/**
 * lpfc_sli4_els_sgl_update - update ELS xri-sgl sizing and mapping
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine first calculates the sizes of the current els and allocated
 * scsi sgl lists, and then goes through all sgls to updates the physical
 * XRIs assigned due to port function reset. During port initialization, the
 * current els and allocated scsi sgl lists are 0s.
 *
 * Return codes
 *   0 - successful (for now, it always returns 0)
 **/
int
lpfc_sli4_els_sgl_update(struct lpfc_hba *phba)
{
	struct lpfc_sglq *sglq_entry = NULL, *sglq_entry_next = NULL;
	uint16_t i, lxri, xri_cnt, els_xri_cnt;
	LIST_HEAD(els_sgl_list);
	int rc;

	/*
	 * update on pci function's els xri-sgl list
	 */
	els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba);

	if (els_xri_cnt > phba->sli4_hba.els_xri_cnt) {
		/* els xri-sgl expanded */
		xri_cnt = els_xri_cnt - phba->sli4_hba.els_xri_cnt;
		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
				"3157 ELS xri-sgl count increased from "
				"%d to %d\n", phba->sli4_hba.els_xri_cnt,
				els_xri_cnt);
		/* allocate the additional els sgls */
		for (i = 0; i < xri_cnt; i++) {
			sglq_entry = kzalloc(sizeof(struct lpfc_sglq),
					     GFP_KERNEL);
			if (sglq_entry == NULL) {
				lpfc_printf_log(phba, KERN_ERR,
						LOG_TRACE_EVENT,
						"2562 Failure to allocate an "
						"ELS sgl entry:%d\n", i);
				rc = -ENOMEM;
				goto out_free_mem;
			}
			sglq_entry->buff_type = GEN_BUFF_TYPE;
			sglq_entry->virt = lpfc_mbuf_alloc(phba, 0,
							   &sglq_entry->phys);
			if (sglq_entry->virt == NULL) {
				kfree(sglq_entry);
				lpfc_printf_log(phba, KERN_ERR,
						LOG_TRACE_EVENT,
						"2563 Failure to allocate an "
						"ELS mbuf:%d\n", i);
				rc = -ENOMEM;
				goto out_free_mem;
			}
			sglq_entry->sgl = sglq_entry->virt;
			memset(sglq_entry->sgl, 0, LPFC_BPL_SIZE);
			sglq_entry->state = SGL_FREED;
			list_add_tail(&sglq_entry->list, &els_sgl_list);
		}
		spin_lock_irq(&phba->sli4_hba.sgl_list_lock);
		list_splice_init(&els_sgl_list,
				 &phba->sli4_hba.lpfc_els_sgl_list);
		spin_unlock_irq(&phba->sli4_hba.sgl_list_lock);
	} else if (els_xri_cnt < phba->sli4_hba.els_xri_cnt) {
		/* els xri-sgl shrinked */
		xri_cnt = phba->sli4_hba.els_xri_cnt - els_xri_cnt;
		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
				"3158 ELS xri-sgl count decreased from "
				"%d to %d\n", phba->sli4_hba.els_xri_cnt,
				els_xri_cnt);
		spin_lock_irq(&phba->sli4_hba.sgl_list_lock);
		list_splice_init(&phba->sli4_hba.lpfc_els_sgl_list,
				 &els_sgl_list);
		/* release extra els sgls from list */
		for (i = 0; i < xri_cnt; i++) {
			list_remove_head(&els_sgl_list,
					 sglq_entry, struct lpfc_sglq, list);
			if (sglq_entry) {
				__lpfc_mbuf_free(phba, sglq_entry->virt,
						 sglq_entry->phys);
				kfree(sglq_entry);
			}
		}
		list_splice_init(&els_sgl_list,
				 &phba->sli4_hba.lpfc_els_sgl_list);
		spin_unlock_irq(&phba->sli4_hba.sgl_list_lock);
	} else
		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
				"3163 ELS xri-sgl count unchanged: %d\n",
				els_xri_cnt);
	phba->sli4_hba.els_xri_cnt = els_xri_cnt;

	/* update xris to els sgls on the list */
	sglq_entry = NULL;
	sglq_entry_next = NULL;
	list_for_each_entry_safe(sglq_entry, sglq_entry_next,
				 &phba->sli4_hba.lpfc_els_sgl_list, list) {
		lxri = lpfc_sli4_next_xritag(phba);
		if (lxri == NO_XRI) {
			lpfc_printf_log(phba, KERN_ERR,
					LOG_TRACE_EVENT,
					"2400 Failed to allocate xri for "
					"ELS sgl\n");
			rc = -ENOMEM;
			goto out_free_mem;
		}
		sglq_entry->sli4_lxritag = lxri;
		sglq_entry->sli4_xritag = phba->sli4_hba.xri_ids[lxri];
	}
	return 0;

out_free_mem:
	lpfc_free_els_sgl_list(phba);
	return rc;
}

/**
 * lpfc_sli4_nvmet_sgl_update - update xri-sgl sizing and mapping
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine first calculates the sizes of the current els and allocated
 * scsi sgl lists, and then goes through all sgls to updates the physical
 * XRIs assigned due to port function reset. During port initialization, the
 * current els and allocated scsi sgl lists are 0s.
 *
 * Return codes
 *   0 - successful (for now, it always returns 0)
 **/
int
lpfc_sli4_nvmet_sgl_update(struct lpfc_hba *phba)
{
	struct lpfc_sglq *sglq_entry = NULL, *sglq_entry_next = NULL;
	uint16_t i, lxri, xri_cnt, els_xri_cnt;
	uint16_t nvmet_xri_cnt;
	LIST_HEAD(nvmet_sgl_list);
	int rc;

	/*
	 * update on pci function's nvmet xri-sgl list
	 */
	els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba);

	/* For NVMET, ALL remaining XRIs are dedicated for IO processing */
	nvmet_xri_cnt = phba->sli4_hba.max_cfg_param.max_xri - els_xri_cnt;
	if (nvmet_xri_cnt > phba->sli4_hba.nvmet_xri_cnt) {
		/* els xri-sgl expanded */
		xri_cnt = nvmet_xri_cnt - phba->sli4_hba.nvmet_xri_cnt;
		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
				"6302 NVMET xri-sgl cnt grew from %d to %d\n",
				phba->sli4_hba.nvmet_xri_cnt, nvmet_xri_cnt);
		/* allocate the additional nvmet sgls */
		for (i = 0; i < xri_cnt; i++) {
			sglq_entry = kzalloc(sizeof(struct lpfc_sglq),
					     GFP_KERNEL);
			if (sglq_entry == NULL) {
				lpfc_printf_log(phba, KERN_ERR,
						LOG_TRACE_EVENT,
						"6303 Failure to allocate an "
						"NVMET sgl entry:%d\n", i);
				rc = -ENOMEM;
				goto out_free_mem;
			}
			sglq_entry->buff_type = NVMET_BUFF_TYPE;
			sglq_entry->virt = lpfc_nvmet_buf_alloc(phba, 0,
							   &sglq_entry->phys);
			if (sglq_entry->virt == NULL) {
				kfree(sglq_entry);
				lpfc_printf_log(phba, KERN_ERR,
						LOG_TRACE_EVENT,
						"6304 Failure to allocate an "
						"NVMET buf:%d\n", i);
				rc = -ENOMEM;
				goto out_free_mem;
			}
			sglq_entry->sgl = sglq_entry->virt;
			memset(sglq_entry->sgl, 0,
			       phba->cfg_sg_dma_buf_size);
			sglq_entry->state = SGL_FREED;
			list_add_tail(&sglq_entry->list, &nvmet_sgl_list);
		}
		spin_lock_irq(&phba->hbalock);
		spin_lock(&phba->sli4_hba.sgl_list_lock);
		list_splice_init(&nvmet_sgl_list,
				 &phba->sli4_hba.lpfc_nvmet_sgl_list);
		spin_unlock(&phba->sli4_hba.sgl_list_lock);
		spin_unlock_irq(&phba->hbalock);
	} else if (nvmet_xri_cnt < phba->sli4_hba.nvmet_xri_cnt) {
		/* nvmet xri-sgl shrunk */
		xri_cnt = phba->sli4_hba.nvmet_xri_cnt - nvmet_xri_cnt;
		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
				"6305 NVMET xri-sgl count decreased from "
				"%d to %d\n", phba->sli4_hba.nvmet_xri_cnt,
				nvmet_xri_cnt);
		spin_lock_irq(&phba->hbalock);
		spin_lock(&phba->sli4_hba.sgl_list_lock);
		list_splice_init(&phba->sli4_hba.lpfc_nvmet_sgl_list,
				 &nvmet_sgl_list);
		/* release extra nvmet sgls from list */
		for (i = 0; i < xri_cnt; i++) {
			list_remove_head(&nvmet_sgl_list,
					 sglq_entry, struct lpfc_sglq, list);
			if (sglq_entry) {
				lpfc_nvmet_buf_free(phba, sglq_entry->virt,
						    sglq_entry->phys);
				kfree(sglq_entry);
			}
		}
		list_splice_init(&nvmet_sgl_list,
				 &phba->sli4_hba.lpfc_nvmet_sgl_list);
		spin_unlock(&phba->sli4_hba.sgl_list_lock);
		spin_unlock_irq(&phba->hbalock);
	} else
		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
				"6306 NVMET xri-sgl count unchanged: %d\n",
				nvmet_xri_cnt);
	phba->sli4_hba.nvmet_xri_cnt = nvmet_xri_cnt;

	/* update xris to nvmet sgls on the list */
	sglq_entry = NULL;
	sglq_entry_next = NULL;
	list_for_each_entry_safe(sglq_entry, sglq_entry_next,
				 &phba->sli4_hba.lpfc_nvmet_sgl_list, list) {
		lxri = lpfc_sli4_next_xritag(phba);
		if (lxri == NO_XRI) {
			lpfc_printf_log(phba, KERN_ERR,
					LOG_TRACE_EVENT,
					"6307 Failed to allocate xri for "
					"NVMET sgl\n");
			rc = -ENOMEM;
			goto out_free_mem;
		}
		sglq_entry->sli4_lxritag = lxri;
		sglq_entry->sli4_xritag = phba->sli4_hba.xri_ids[lxri];
	}
	return 0;

out_free_mem:
	lpfc_free_nvmet_sgl_list(phba);
	return rc;
}

int
lpfc_io_buf_flush(struct lpfc_hba *phba, struct list_head *cbuf)
{
	LIST_HEAD(blist);
	struct lpfc_sli4_hdw_queue *qp;
	struct lpfc_io_buf *lpfc_cmd;
	struct lpfc_io_buf *iobufp, *prev_iobufp;
	int idx, cnt, xri, inserted;

	cnt = 0;
	for (idx = 0; idx < phba->cfg_hdw_queue; idx++) {
		qp = &phba->sli4_hba.hdwq[idx];
		spin_lock_irq(&qp->io_buf_list_get_lock);
		spin_lock(&qp->io_buf_list_put_lock);

		/* Take everything off the get and put lists */
		list_splice_init(&qp->lpfc_io_buf_list_get, &blist);
		list_splice(&qp->lpfc_io_buf_list_put, &blist);
		INIT_LIST_HEAD(&qp->lpfc_io_buf_list_get);
		INIT_LIST_HEAD(&qp->lpfc_io_buf_list_put);
		cnt += qp->get_io_bufs + qp->put_io_bufs;
		qp->get_io_bufs = 0;
		qp->put_io_bufs = 0;
		qp->total_io_bufs = 0;
		spin_unlock(&qp->io_buf_list_put_lock);
		spin_unlock_irq(&qp->io_buf_list_get_lock);
	}

	/*
	 * Take IO buffers off blist and put on cbuf sorted by XRI.
	 * This is because POST_SGL takes a sequential range of XRIs
	 * to post to the firmware.
	 */
	for (idx = 0; idx < cnt; idx++) {
		list_remove_head(&blist, lpfc_cmd, struct lpfc_io_buf, list);
		if (!lpfc_cmd)
			return cnt;
		if (idx == 0) {
			list_add_tail(&lpfc_cmd->list, cbuf);
			continue;
		}
		xri = lpfc_cmd->cur_iocbq.sli4_xritag;
		inserted = 0;
		prev_iobufp = NULL;
		list_for_each_entry(iobufp, cbuf, list) {
			if (xri < iobufp->cur_iocbq.sli4_xritag) {
				if (prev_iobufp)
					list_add(&lpfc_cmd->list,
						 &prev_iobufp->list);
				else
					list_add(&lpfc_cmd->list, cbuf);
				inserted = 1;
				break;
			}
			prev_iobufp = iobufp;
		}
		if (!inserted)
			list_add_tail(&lpfc_cmd->list, cbuf);
	}
	return cnt;
}

int
lpfc_io_buf_replenish(struct lpfc_hba *phba, struct list_head *cbuf)
{
	struct lpfc_sli4_hdw_queue *qp;
	struct lpfc_io_buf *lpfc_cmd;
	int idx, cnt;

	qp = phba->sli4_hba.hdwq;
	cnt = 0;
	while (!list_empty(cbuf)) {
		for (idx = 0; idx < phba->cfg_hdw_queue; idx++) {
			list_remove_head(cbuf, lpfc_cmd,
					 struct lpfc_io_buf, list);
			if (!lpfc_cmd)
				return cnt;
			cnt++;
			qp = &phba->sli4_hba.hdwq[idx];
			lpfc_cmd->hdwq_no = idx;
			lpfc_cmd->hdwq = qp;
			lpfc_cmd->cur_iocbq.wqe_cmpl = NULL;
			lpfc_cmd->cur_iocbq.iocb_cmpl = NULL;
			spin_lock(&qp->io_buf_list_put_lock);
			list_add_tail(&lpfc_cmd->list,
				      &qp->lpfc_io_buf_list_put);
			qp->put_io_bufs++;
			qp->total_io_bufs++;
			spin_unlock(&qp->io_buf_list_put_lock);
		}
	}
	return cnt;
}

/**
 * lpfc_sli4_io_sgl_update - update xri-sgl sizing and mapping
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine first calculates the sizes of the current els and allocated
 * scsi sgl lists, and then goes through all sgls to updates the physical
 * XRIs assigned due to port function reset. During port initialization, the
 * current els and allocated scsi sgl lists are 0s.
 *
 * Return codes
 *   0 - successful (for now, it always returns 0)
 **/
int
lpfc_sli4_io_sgl_update(struct lpfc_hba *phba)
{
	struct lpfc_io_buf *lpfc_ncmd = NULL, *lpfc_ncmd_next = NULL;
	uint16_t i, lxri, els_xri_cnt;
	uint16_t io_xri_cnt, io_xri_max;
	LIST_HEAD(io_sgl_list);
	int rc, cnt;

	/*
	 * update on pci function's allocated nvme xri-sgl list
	 */

	/* maximum number of xris available for nvme buffers */
	els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba);
	io_xri_max = phba->sli4_hba.max_cfg_param.max_xri - els_xri_cnt;
	phba->sli4_hba.io_xri_max = io_xri_max;

	lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
			"6074 Current allocated XRI sgl count:%d, "
			"maximum XRI count:%d\n",
			phba->sli4_hba.io_xri_cnt,
			phba->sli4_hba.io_xri_max);

	cnt = lpfc_io_buf_flush(phba, &io_sgl_list);

	if (phba->sli4_hba.io_xri_cnt > phba->sli4_hba.io_xri_max) {
		/* max nvme xri shrunk below the allocated nvme buffers */
		io_xri_cnt = phba->sli4_hba.io_xri_cnt -
					phba->sli4_hba.io_xri_max;
		/* release the extra allocated nvme buffers */
		for (i = 0; i < io_xri_cnt; i++) {
			list_remove_head(&io_sgl_list, lpfc_ncmd,
					 struct lpfc_io_buf, list);
			if (lpfc_ncmd) {
				dma_pool_free(phba->lpfc_sg_dma_buf_pool,
					      lpfc_ncmd->data,
					      lpfc_ncmd->dma_handle);
				kfree(lpfc_ncmd);
			}
		}
		phba->sli4_hba.io_xri_cnt -= io_xri_cnt;
	}

	/* update xris associated to remaining allocated nvme buffers */
	lpfc_ncmd = NULL;
	lpfc_ncmd_next = NULL;
	phba->sli4_hba.io_xri_cnt = cnt;
	list_for_each_entry_safe(lpfc_ncmd, lpfc_ncmd_next,
				 &io_sgl_list, list) {
		lxri = lpfc_sli4_next_xritag(phba);
		if (lxri == NO_XRI) {
			lpfc_printf_log(phba, KERN_ERR,
					LOG_TRACE_EVENT,
					"6075 Failed to allocate xri for "
					"nvme buffer\n");
			rc = -ENOMEM;
			goto out_free_mem;
		}
		lpfc_ncmd->cur_iocbq.sli4_lxritag = lxri;
		lpfc_ncmd->cur_iocbq.sli4_xritag = phba->sli4_hba.xri_ids[lxri];
	}
	cnt = lpfc_io_buf_replenish(phba, &io_sgl_list);
	return 0;

out_free_mem:
	lpfc_io_free(phba);
	return rc;
}

/**
 * lpfc_new_io_buf - IO buffer allocator for HBA with SLI4 IF spec
 * @phba: Pointer to lpfc hba data structure.
 * @num_to_alloc: The requested number of buffers to allocate.
 *
 * This routine allocates nvme buffers for device with SLI-4 interface spec,
 * the nvme buffer contains all the necessary information needed to initiate
 * an I/O. After allocating up to @num_to_allocate IO buffers and put
 * them on a list, it post them to the port by using SGL block post.
 *
 * Return codes:
 *   int - number of IO buffers that were allocated and posted.
 *   0 = failure, less than num_to_alloc is a partial failure.
 **/
int
lpfc_new_io_buf(struct lpfc_hba *phba, int num_to_alloc)
{
	struct lpfc_io_buf *lpfc_ncmd;
	struct lpfc_iocbq *pwqeq;
	uint16_t iotag, lxri = 0;
	int bcnt, num_posted;
	LIST_HEAD(prep_nblist);
	LIST_HEAD(post_nblist);
	LIST_HEAD(nvme_nblist);

	phba->sli4_hba.io_xri_cnt = 0;
	for (bcnt = 0; bcnt < num_to_alloc; bcnt++) {
		lpfc_ncmd = kzalloc(sizeof(*lpfc_ncmd), GFP_KERNEL);
		if (!lpfc_ncmd)
			break;
		/*
		 * Get memory from the pci pool to map the virt space to
		 * pci bus space for an I/O. The DMA buffer includes the
		 * number of SGE's necessary to support the sg_tablesize.
		 */
		lpfc_ncmd->data = dma_pool_zalloc(phba->lpfc_sg_dma_buf_pool,
						  GFP_KERNEL,
						  &lpfc_ncmd->dma_handle);
		if (!lpfc_ncmd->data) {
			kfree(lpfc_ncmd);
			break;
		}

		if (phba->cfg_xpsgl && !phba->nvmet_support) {
			INIT_LIST_HEAD(&lpfc_ncmd->dma_sgl_xtra_list);
		} else {
			/*
			 * 4K Page alignment is CRITICAL to BlockGuard, double
			 * check to be sure.
			 */
			if ((phba->sli3_options & LPFC_SLI3_BG_ENABLED) &&
			    (((unsigned long)(lpfc_ncmd->data) &
			    (unsigned long)(SLI4_PAGE_SIZE - 1)) != 0)) {
				lpfc_printf_log(phba, KERN_ERR,
						LOG_TRACE_EVENT,
						"3369 Memory alignment err: "
						"addr=%lx\n",
						(unsigned long)lpfc_ncmd->data);
				dma_pool_free(phba->lpfc_sg_dma_buf_pool,
					      lpfc_ncmd->data,
					      lpfc_ncmd->dma_handle);
				kfree(lpfc_ncmd);
				break;
			}
		}

		INIT_LIST_HEAD(&lpfc_ncmd->dma_cmd_rsp_list);

		lxri = lpfc_sli4_next_xritag(phba);
		if (lxri == NO_XRI) {
			dma_pool_free(phba->lpfc_sg_dma_buf_pool,
				      lpfc_ncmd->data, lpfc_ncmd->dma_handle);
			kfree(lpfc_ncmd);
			break;
		}
		pwqeq = &lpfc_ncmd->cur_iocbq;

		/* Allocate iotag for lpfc_ncmd->cur_iocbq. */
		iotag = lpfc_sli_next_iotag(phba, pwqeq);
		if (iotag == 0) {
			dma_pool_free(phba->lpfc_sg_dma_buf_pool,
				      lpfc_ncmd->data, lpfc_ncmd->dma_handle);
			kfree(lpfc_ncmd);
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"6121 Failed to allocate IOTAG for"
					" XRI:0x%x\n", lxri);
			lpfc_sli4_free_xri(phba, lxri);
			break;
		}
		pwqeq->sli4_lxritag = lxri;
		pwqeq->sli4_xritag = phba->sli4_hba.xri_ids[lxri];
		pwqeq->context1 = lpfc_ncmd;

		/* Initialize local short-hand pointers. */
		lpfc_ncmd->dma_sgl = lpfc_ncmd->data;
		lpfc_ncmd->dma_phys_sgl = lpfc_ncmd->dma_handle;
		lpfc_ncmd->cur_iocbq.context1 = lpfc_ncmd;
		spin_lock_init(&lpfc_ncmd->buf_lock);

		/* add the nvme buffer to a post list */
		list_add_tail(&lpfc_ncmd->list, &post_nblist);
		phba->sli4_hba.io_xri_cnt++;
	}
	lpfc_printf_log(phba, KERN_INFO, LOG_NVME,
			"6114 Allocate %d out of %d requested new NVME "
			"buffers\n", bcnt, num_to_alloc);

	/* post the list of nvme buffer sgls to port if available */
	if (!list_empty(&post_nblist))
		num_posted = lpfc_sli4_post_io_sgl_list(
				phba, &post_nblist, bcnt);
	else
		num_posted = 0;

	return num_posted;
}

static uint64_t
lpfc_get_wwpn(struct lpfc_hba *phba)
{
	uint64_t wwn;
	int rc;
	LPFC_MBOXQ_t *mboxq;
	MAILBOX_t *mb;

	mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
						GFP_KERNEL);
	if (!mboxq)
		return (uint64_t)-1;

	/* First get WWN of HBA instance */
	lpfc_read_nv(phba, mboxq);
	rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
	if (rc != MBX_SUCCESS) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"6019 Mailbox failed , mbxCmd x%x "
				"READ_NV, mbxStatus x%x\n",
				bf_get(lpfc_mqe_command, &mboxq->u.mqe),
				bf_get(lpfc_mqe_status, &mboxq->u.mqe));
		mempool_free(mboxq, phba->mbox_mem_pool);
		return (uint64_t) -1;
	}
	mb = &mboxq->u.mb;
	memcpy(&wwn, (char *)mb->un.varRDnvp.portname, sizeof(uint64_t));
	/* wwn is WWPN of HBA instance */
	mempool_free(mboxq, phba->mbox_mem_pool);
	if (phba->sli_rev == LPFC_SLI_REV4)
		return be64_to_cpu(wwn);
	else
		return rol64(wwn, 32);
}

/**
 * lpfc_vmid_res_alloc - Allocates resources for VMID
 * @phba: pointer to lpfc hba data structure.
 * @vport: pointer to vport data structure
 *
 * This routine allocated the resources needed for the VMID.
 *
 * Return codes
 *	0 on Success
 *	Non-0 on Failure
 */
static int
lpfc_vmid_res_alloc(struct lpfc_hba *phba, struct lpfc_vport *vport)
{
	/* VMID feature is supported only on SLI4 */
	if (phba->sli_rev == LPFC_SLI_REV3) {
		phba->cfg_vmid_app_header = 0;
		phba->cfg_vmid_priority_tagging = 0;
	}

	if (lpfc_is_vmid_enabled(phba)) {
		vport->vmid =
		    kcalloc(phba->cfg_max_vmid, sizeof(struct lpfc_vmid),
			    GFP_KERNEL);
		if (!vport->vmid)
			return -ENOMEM;

		rwlock_init(&vport->vmid_lock);

		/* Set the VMID parameters for the vport */
		vport->vmid_priority_tagging = phba->cfg_vmid_priority_tagging;
		vport->vmid_inactivity_timeout =
		    phba->cfg_vmid_inactivity_timeout;
		vport->max_vmid = phba->cfg_max_vmid;
		vport->cur_vmid_cnt = 0;

		vport->vmid_priority_range = bitmap_zalloc
			(LPFC_VMID_MAX_PRIORITY_RANGE, GFP_KERNEL);

		if (!vport->vmid_priority_range) {
			kfree(vport->vmid);
			return -ENOMEM;
		}

		hash_init(vport->hash_table);
	}
	return 0;
}

/**
 * lpfc_create_port - Create an FC port
 * @phba: pointer to lpfc hba data structure.
 * @instance: a unique integer ID to this FC port.
 * @dev: pointer to the device data structure.
 *
 * This routine creates a FC port for the upper layer protocol. The FC port
 * can be created on top of either a physical port or a virtual port provided
 * by the HBA. This routine also allocates a SCSI host data structure (shost)
 * and associates the FC port created before adding the shost into the SCSI
 * layer.
 *
 * Return codes
 *   @vport - pointer to the virtual N_Port data structure.
 *   NULL - port create failed.
 **/
struct lpfc_vport *
lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
{
	struct lpfc_vport *vport;
	struct Scsi_Host  *shost = NULL;
	struct scsi_host_template *template;
	int error = 0;
	int i;
	uint64_t wwn;
	bool use_no_reset_hba = false;
	int rc;

	if (lpfc_no_hba_reset_cnt) {
		if (phba->sli_rev < LPFC_SLI_REV4 &&
		    dev == &phba->pcidev->dev) {
			/* Reset the port first */
			lpfc_sli_brdrestart(phba);
			rc = lpfc_sli_chipset_init(phba);
			if (rc)
				return NULL;
		}
		wwn = lpfc_get_wwpn(phba);
	}

	for (i = 0; i < lpfc_no_hba_reset_cnt; i++) {
		if (wwn == lpfc_no_hba_reset[i]) {
			lpfc_printf_log(phba, KERN_ERR,
					LOG_TRACE_EVENT,
					"6020 Setting use_no_reset port=%llx\n",
					wwn);
			use_no_reset_hba = true;
			break;
		}
	}

	/* Seed template for SCSI host registration */
	if (dev == &phba->pcidev->dev) {
		template = &phba->port_template;

		if (phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP) {
			/* Seed physical port template */
			memcpy(template, &lpfc_template, sizeof(*template));

			if (use_no_reset_hba)
				/* template is for a no reset SCSI Host */
				template->eh_host_reset_handler = NULL;

			/* Template for all vports this physical port creates */
			memcpy(&phba->vport_template, &lpfc_template,
			       sizeof(*template));
			phba->vport_template.shost_groups = lpfc_vport_groups;
			phba->vport_template.eh_bus_reset_handler = NULL;
			phba->vport_template.eh_host_reset_handler = NULL;
			phba->vport_template.vendor_id = 0;

			/* Initialize the host templates with updated value */
			if (phba->sli_rev == LPFC_SLI_REV4) {
				template->sg_tablesize = phba->cfg_scsi_seg_cnt;
				phba->vport_template.sg_tablesize =
					phba->cfg_scsi_seg_cnt;
			} else {
				template->sg_tablesize = phba->cfg_sg_seg_cnt;
				phba->vport_template.sg_tablesize =
					phba->cfg_sg_seg_cnt;
			}

		} else {
			/* NVMET is for physical port only */
			memcpy(template, &lpfc_template_nvme,
			       sizeof(*template));
		}
	} else {
		template = &phba->vport_template;
	}

	shost = scsi_host_alloc(template, sizeof(struct lpfc_vport));
	if (!shost)
		goto out;

	vport = (struct lpfc_vport *) shost->hostdata;
	vport->phba = phba;
	vport->load_flag |= FC_LOADING;
	vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
	vport->fc_rscn_flush = 0;
	lpfc_get_vport_cfgparam(vport);

	/* Adjust value in vport */
	vport->cfg_enable_fc4_type = phba->cfg_enable_fc4_type;

	shost->unique_id = instance;
	shost->max_id = LPFC_MAX_TARGET;
	shost->max_lun = vport->cfg_max_luns;
	shost->this_id = -1;
	shost->max_cmd_len = 16;

	if (phba->sli_rev == LPFC_SLI_REV4) {
		if (!phba->cfg_fcp_mq_threshold ||
		    phba->cfg_fcp_mq_threshold > phba->cfg_hdw_queue)
			phba->cfg_fcp_mq_threshold = phba->cfg_hdw_queue;

		shost->nr_hw_queues = min_t(int, 2 * num_possible_nodes(),
					    phba->cfg_fcp_mq_threshold);

		shost->dma_boundary =
			phba->sli4_hba.pc_sli4_params.sge_supp_len-1;

		if (phba->cfg_xpsgl && !phba->nvmet_support)
			shost->sg_tablesize = LPFC_MAX_SG_TABLESIZE;
		else
			shost->sg_tablesize = phba->cfg_scsi_seg_cnt;
	} else
		/* SLI-3 has a limited number of hardware queues (3),
		 * thus there is only one for FCP processing.
		 */
		shost->nr_hw_queues = 1;

	/*
	 * Set initial can_queue value since 0 is no longer supported and
	 * scsi_add_host will fail. This will be adjusted later based on the
	 * max xri value determined in hba setup.
	 */
	shost->can_queue = phba->cfg_hba_queue_depth - 10;
	if (dev != &phba->pcidev->dev) {
		shost->transportt = lpfc_vport_transport_template;
		vport->port_type = LPFC_NPIV_PORT;
	} else {
		shost->transportt = lpfc_transport_template;
		vport->port_type = LPFC_PHYSICAL_PORT;
	}

	lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_FCP,
			"9081 CreatePort TMPLATE type %x TBLsize %d "
			"SEGcnt %d/%d\n",
			vport->port_type, shost->sg_tablesize,
			phba->cfg_scsi_seg_cnt, phba->cfg_sg_seg_cnt);

	/* Allocate the resources for VMID */
	rc = lpfc_vmid_res_alloc(phba, vport);

	if (rc)
		goto out;

	/* Initialize all internally managed lists. */
	INIT_LIST_HEAD(&vport->fc_nodes);
	INIT_LIST_HEAD(&vport->rcv_buffer_list);
	spin_lock_init(&vport->work_port_lock);

	timer_setup(&vport->fc_disctmo, lpfc_disc_timeout, 0);

	timer_setup(&vport->els_tmofunc, lpfc_els_timeout, 0);

	timer_setup(&vport->delayed_disc_tmo, lpfc_delayed_disc_tmo, 0);

	if (phba->sli3_options & LPFC_SLI3_BG_ENABLED)
		lpfc_setup_bg(phba, shost);

	error = scsi_add_host_with_dma(shost, dev, &phba->pcidev->dev);
	if (error)
		goto out_put_shost;

	spin_lock_irq(&phba->port_list_lock);
	list_add_tail(&vport->listentry, &phba->port_list);
	spin_unlock_irq(&phba->port_list_lock);
	return vport;

out_put_shost:
	kfree(vport->vmid);
	bitmap_free(vport->vmid_priority_range);
	scsi_host_put(shost);
out:
	return NULL;
}

/**
 * destroy_port -  destroy an FC port
 * @vport: pointer to an lpfc virtual N_Port data structure.
 *
 * This routine destroys a FC port from the upper layer protocol. All the
 * resources associated with the port are released.
 **/
void
destroy_port(struct lpfc_vport *vport)
{
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
	struct lpfc_hba  *phba = vport->phba;

	lpfc_debugfs_terminate(vport);
	fc_remove_host(shost);
	scsi_remove_host(shost);

	spin_lock_irq(&phba->port_list_lock);
	list_del_init(&vport->listentry);
	spin_unlock_irq(&phba->port_list_lock);

	lpfc_cleanup(vport);
	return;
}

/**
 * lpfc_get_instance - Get a unique integer ID
 *
 * This routine allocates a unique integer ID from lpfc_hba_index pool. It
 * uses the kernel idr facility to perform the task.
 *
 * Return codes:
 *   instance - a unique integer ID allocated as the new instance.
 *   -1 - lpfc get instance failed.
 **/
int
lpfc_get_instance(void)
{
	int ret;

	ret = idr_alloc(&lpfc_hba_index, NULL, 0, 0, GFP_KERNEL);
	return ret < 0 ? -1 : ret;
}

/**
 * lpfc_scan_finished - method for SCSI layer to detect whether scan is done
 * @shost: pointer to SCSI host data structure.
 * @time: elapsed time of the scan in jiffies.
 *
 * This routine is called by the SCSI layer with a SCSI host to determine
 * whether the scan host is finished.
 *
 * Note: there is no scan_start function as adapter initialization will have
 * asynchronously kicked off the link initialization.
 *
 * Return codes
 *   0 - SCSI host scan is not over yet.
 *   1 - SCSI host scan is over.
 **/
int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time)
{
	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
	struct lpfc_hba   *phba = vport->phba;
	int stat = 0;

	spin_lock_irq(shost->host_lock);

	if (vport->load_flag & FC_UNLOADING) {
		stat = 1;
		goto finished;
	}
	if (time >= msecs_to_jiffies(30 * 1000)) {
		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"0461 Scanning longer than 30 "
				"seconds.  Continuing initialization\n");
		stat = 1;
		goto finished;
	}
	if (time >= msecs_to_jiffies(15 * 1000) &&
	    phba->link_state <= LPFC_LINK_DOWN) {
		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"0465 Link down longer than 15 "
				"seconds.  Continuing initialization\n");
		stat = 1;
		goto finished;
	}

	if (vport->port_state != LPFC_VPORT_READY)
		goto finished;
	if (vport->num_disc_nodes || vport->fc_prli_sent)
		goto finished;
	if (vport->fc_map_cnt == 0 && time < msecs_to_jiffies(2 * 1000))
		goto finished;
	if ((phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE) != 0)
		goto finished;

	stat = 1;

finished:
	spin_unlock_irq(shost->host_lock);
	return stat;
}

static void lpfc_host_supported_speeds_set(struct Scsi_Host *shost)
{
	struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
	struct lpfc_hba   *phba = vport->phba;

	fc_host_supported_speeds(shost) = 0;
	/*
	 * Avoid reporting supported link speed for FCoE as it can't be
	 * controlled via FCoE.
	 */
	if (phba->hba_flag & HBA_FCOE_MODE)
		return;

	if (phba->lmt & LMT_256Gb)
		fc_host_supported_speeds(shost) |= FC_PORTSPEED_256GBIT;
	if (phba->lmt & LMT_128Gb)
		fc_host_supported_speeds(shost) |= FC_PORTSPEED_128GBIT;
	if (phba->lmt & LMT_64Gb)
		fc_host_supported_speeds(shost) |= FC_PORTSPEED_64GBIT;
	if (phba->lmt & LMT_32Gb)
		fc_host_supported_speeds(shost) |= FC_PORTSPEED_32GBIT;
	if (phba->lmt & LMT_16Gb)
		fc_host_supported_speeds(shost) |= FC_PORTSPEED_16GBIT;
	if (phba->lmt & LMT_10Gb)
		fc_host_supported_speeds(shost) |= FC_PORTSPEED_10GBIT;
	if (phba->lmt & LMT_8Gb)
		fc_host_supported_speeds(shost) |= FC_PORTSPEED_8GBIT;
	if (phba->lmt & LMT_4Gb)
		fc_host_supported_speeds(shost) |= FC_PORTSPEED_4GBIT;
	if (phba->lmt & LMT_2Gb)
		fc_host_supported_speeds(shost) |= FC_PORTSPEED_2GBIT;
	if (phba->lmt & LMT_1Gb)
		fc_host_supported_speeds(shost) |= FC_PORTSPEED_1GBIT;
}

/**
 * lpfc_host_attrib_init - Initialize SCSI host attributes on a FC port
 * @shost: pointer to SCSI host data structure.
 *
 * This routine initializes a given SCSI host attributes on a FC port. The
 * SCSI host can be either on top of a physical port or a virtual port.
 **/
void lpfc_host_attrib_init(struct Scsi_Host *shost)
{
	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
	struct lpfc_hba   *phba = vport->phba;
	/*
	 * Set fixed host attributes.  Must done after lpfc_sli_hba_setup().
	 */

	fc_host_node_name(shost) = wwn_to_u64(vport->fc_nodename.u.wwn);
	fc_host_port_name(shost) = wwn_to_u64(vport->fc_portname.u.wwn);
	fc_host_supported_classes(shost) = FC_COS_CLASS3;

	memset(fc_host_supported_fc4s(shost), 0,
	       sizeof(fc_host_supported_fc4s(shost)));
	fc_host_supported_fc4s(shost)[2] = 1;
	fc_host_supported_fc4s(shost)[7] = 1;

	lpfc_vport_symbolic_node_name(vport, fc_host_symbolic_name(shost),
				 sizeof fc_host_symbolic_name(shost));

	lpfc_host_supported_speeds_set(shost);

	fc_host_maxframe_size(shost) =
		(((uint32_t) vport->fc_sparam.cmn.bbRcvSizeMsb & 0x0F) << 8) |
		(uint32_t) vport->fc_sparam.cmn.bbRcvSizeLsb;

	fc_host_dev_loss_tmo(shost) = vport->cfg_devloss_tmo;

	/* This value is also unchanging */
	memset(fc_host_active_fc4s(shost), 0,
	       sizeof(fc_host_active_fc4s(shost)));
	fc_host_active_fc4s(shost)[2] = 1;
	fc_host_active_fc4s(shost)[7] = 1;

	fc_host_max_npiv_vports(shost) = phba->max_vpi;
	spin_lock_irq(shost->host_lock);
	vport->load_flag &= ~FC_LOADING;
	spin_unlock_irq(shost->host_lock);
}

/**
 * lpfc_stop_port_s3 - Stop SLI3 device port
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to stop an SLI3 device port, it stops the device
 * from generating interrupts and stops the device driver's timers for the
 * device.
 **/
static void
lpfc_stop_port_s3(struct lpfc_hba *phba)
{
	/* Clear all interrupt enable conditions */
	writel(0, phba->HCregaddr);
	readl(phba->HCregaddr); /* flush */
	/* Clear all pending interrupts */
	writel(0xffffffff, phba->HAregaddr);
	readl(phba->HAregaddr); /* flush */

	/* Reset some HBA SLI setup states */
	lpfc_stop_hba_timers(phba);
	phba->pport->work_port_events = 0;
}

/**
 * lpfc_stop_port_s4 - Stop SLI4 device port
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to stop an SLI4 device port, it stops the device
 * from generating interrupts and stops the device driver's timers for the
 * device.
 **/
static void
lpfc_stop_port_s4(struct lpfc_hba *phba)
{
	/* Reset some HBA SLI4 setup states */
	lpfc_stop_hba_timers(phba);
	if (phba->pport)
		phba->pport->work_port_events = 0;
	phba->sli4_hba.intr_enable = 0;
}

/**
 * lpfc_stop_port - Wrapper function for stopping hba port
 * @phba: Pointer to HBA context object.
 *
 * This routine wraps the actual SLI3 or SLI4 hba stop port routine from
 * the API jump table function pointer from the lpfc_hba struct.
 **/
void
lpfc_stop_port(struct lpfc_hba *phba)
{
	phba->lpfc_stop_port(phba);

	if (phba->wq)
		flush_workqueue(phba->wq);
}

/**
 * lpfc_fcf_redisc_wait_start_timer - Start fcf rediscover wait timer
 * @phba: Pointer to hba for which this call is being executed.
 *
 * This routine starts the timer waiting for the FCF rediscovery to complete.
 **/
void
lpfc_fcf_redisc_wait_start_timer(struct lpfc_hba *phba)
{
	unsigned long fcf_redisc_wait_tmo =
		(jiffies + msecs_to_jiffies(LPFC_FCF_REDISCOVER_WAIT_TMO));
	/* Start fcf rediscovery wait period timer */
	mod_timer(&phba->fcf.redisc_wait, fcf_redisc_wait_tmo);
	spin_lock_irq(&phba->hbalock);
	/* Allow action to new fcf asynchronous event */
	phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_SCAN_DONE);
	/* Mark the FCF rediscovery pending state */
	phba->fcf.fcf_flag |= FCF_REDISC_PEND;
	spin_unlock_irq(&phba->hbalock);
}

/**
 * lpfc_sli4_fcf_redisc_wait_tmo - FCF table rediscover wait timeout
 * @t: Timer context used to obtain the pointer to lpfc hba data structure.
 *
 * This routine is invoked when waiting for FCF table rediscover has been
 * timed out. If new FCF record(s) has (have) been discovered during the
 * wait period, a new FCF event shall be added to the FCOE async event
 * list, and then worker thread shall be waked up for processing from the
 * worker thread context.
 **/
static void
lpfc_sli4_fcf_redisc_wait_tmo(struct timer_list *t)
{
	struct lpfc_hba *phba = from_timer(phba, t, fcf.redisc_wait);

	/* Don't send FCF rediscovery event if timer cancelled */
	spin_lock_irq(&phba->hbalock);
	if (!(phba->fcf.fcf_flag & FCF_REDISC_PEND)) {
		spin_unlock_irq(&phba->hbalock);
		return;
	}
	/* Clear FCF rediscovery timer pending flag */
	phba->fcf.fcf_flag &= ~FCF_REDISC_PEND;
	/* FCF rediscovery event to worker thread */
	phba->fcf.fcf_flag |= FCF_REDISC_EVT;
	spin_unlock_irq(&phba->hbalock);
	lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
			"2776 FCF rediscover quiescent timer expired\n");
	/* wake up worker thread */
	lpfc_worker_wake_up(phba);
}

/**
 * lpfc_vmid_poll - VMID timeout detection
 * @t: Timer context used to obtain the pointer to lpfc hba data structure.
 *
 * This routine is invoked when there is no I/O on by a VM for the specified
 * amount of time. When this situation is detected, the VMID has to be
 * deregistered from the switch and all the local resources freed. The VMID
 * will be reassigned to the VM once the I/O begins.
 **/
static void
lpfc_vmid_poll(struct timer_list *t)
{
	struct lpfc_hba *phba = from_timer(phba, t, inactive_vmid_poll);
	u32 wake_up = 0;

	/* check if there is a need to issue QFPA */
	if (phba->pport->vmid_priority_tagging) {
		wake_up = 1;
		phba->pport->work_port_events |= WORKER_CHECK_VMID_ISSUE_QFPA;
	}

	/* Is the vmid inactivity timer enabled */
	if (phba->pport->vmid_inactivity_timeout ||
	    phba->pport->load_flag & FC_DEREGISTER_ALL_APP_ID) {
		wake_up = 1;
		phba->pport->work_port_events |= WORKER_CHECK_INACTIVE_VMID;
	}

	if (wake_up)
		lpfc_worker_wake_up(phba);

	/* restart the timer for the next iteration */
	mod_timer(&phba->inactive_vmid_poll, jiffies + msecs_to_jiffies(1000 *
							LPFC_VMID_TIMER));
}

/**
 * lpfc_sli4_parse_latt_fault - Parse sli4 link-attention link fault code
 * @phba: pointer to lpfc hba data structure.
 * @acqe_link: pointer to the async link completion queue entry.
 *
 * This routine is to parse the SLI4 link-attention link fault code.
 **/
static void
lpfc_sli4_parse_latt_fault(struct lpfc_hba *phba,
			   struct lpfc_acqe_link *acqe_link)
{
	switch (bf_get(lpfc_acqe_link_fault, acqe_link)) {
	case LPFC_ASYNC_LINK_FAULT_NONE:
	case LPFC_ASYNC_LINK_FAULT_LOCAL:
	case LPFC_ASYNC_LINK_FAULT_REMOTE:
	case LPFC_ASYNC_LINK_FAULT_LR_LRR:
		break;
	default:
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0398 Unknown link fault code: x%x\n",
				bf_get(lpfc_acqe_link_fault, acqe_link));
		break;
	}
}

/**
 * lpfc_sli4_parse_latt_type - Parse sli4 link attention type
 * @phba: pointer to lpfc hba data structure.
 * @acqe_link: pointer to the async link completion queue entry.
 *
 * This routine is to parse the SLI4 link attention type and translate it
 * into the base driver's link attention type coding.
 *
 * Return: Link attention type in terms of base driver's coding.
 **/
static uint8_t
lpfc_sli4_parse_latt_type(struct lpfc_hba *phba,
			  struct lpfc_acqe_link *acqe_link)
{
	uint8_t att_type;

	switch (bf_get(lpfc_acqe_link_status, acqe_link)) {
	case LPFC_ASYNC_LINK_STATUS_DOWN:
	case LPFC_ASYNC_LINK_STATUS_LOGICAL_DOWN:
		att_type = LPFC_ATT_LINK_DOWN;
		break;
	case LPFC_ASYNC_LINK_STATUS_UP:
		/* Ignore physical link up events - wait for logical link up */
		att_type = LPFC_ATT_RESERVED;
		break;
	case LPFC_ASYNC_LINK_STATUS_LOGICAL_UP:
		att_type = LPFC_ATT_LINK_UP;
		break;
	default:
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0399 Invalid link attention type: x%x\n",
				bf_get(lpfc_acqe_link_status, acqe_link));
		att_type = LPFC_ATT_RESERVED;
		break;
	}
	return att_type;
}

/**
 * lpfc_sli_port_speed_get - Get sli3 link speed code to link speed
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is to get an SLI3 FC port's link speed in Mbps.
 *
 * Return: link speed in terms of Mbps.
 **/
uint32_t
lpfc_sli_port_speed_get(struct lpfc_hba *phba)
{
	uint32_t link_speed;

	if (!lpfc_is_link_up(phba))
		return 0;

	if (phba->sli_rev <= LPFC_SLI_REV3) {
		switch (phba->fc_linkspeed) {
		case LPFC_LINK_SPEED_1GHZ:
			link_speed = 1000;
			break;
		case LPFC_LINK_SPEED_2GHZ:
			link_speed = 2000;
			break;
		case LPFC_LINK_SPEED_4GHZ:
			link_speed = 4000;
			break;
		case LPFC_LINK_SPEED_8GHZ:
			link_speed = 8000;
			break;
		case LPFC_LINK_SPEED_10GHZ:
			link_speed = 10000;
			break;
		case LPFC_LINK_SPEED_16GHZ:
			link_speed = 16000;
			break;
		default:
			link_speed = 0;
		}
	} else {
		if (phba->sli4_hba.link_state.logical_speed)
			link_speed =
			      phba->sli4_hba.link_state.logical_speed;
		else
			link_speed = phba->sli4_hba.link_state.speed;
	}
	return link_speed;
}

/**
 * lpfc_sli4_port_speed_parse - Parse async evt link speed code to link speed
 * @phba: pointer to lpfc hba data structure.
 * @evt_code: asynchronous event code.
 * @speed_code: asynchronous event link speed code.
 *
 * This routine is to parse the giving SLI4 async event link speed code into
 * value of Mbps for the link speed.
 *
 * Return: link speed in terms of Mbps.
 **/
static uint32_t
lpfc_sli4_port_speed_parse(struct lpfc_hba *phba, uint32_t evt_code,
			   uint8_t speed_code)
{
	uint32_t port_speed;

	switch (evt_code) {
	case LPFC_TRAILER_CODE_LINK:
		switch (speed_code) {
		case LPFC_ASYNC_LINK_SPEED_ZERO:
			port_speed = 0;
			break;
		case LPFC_ASYNC_LINK_SPEED_10MBPS:
			port_speed = 10;
			break;
		case LPFC_ASYNC_LINK_SPEED_100MBPS:
			port_speed = 100;
			break;
		case LPFC_ASYNC_LINK_SPEED_1GBPS:
			port_speed = 1000;
			break;
		case LPFC_ASYNC_LINK_SPEED_10GBPS:
			port_speed = 10000;
			break;
		case LPFC_ASYNC_LINK_SPEED_20GBPS:
			port_speed = 20000;
			break;
		case LPFC_ASYNC_LINK_SPEED_25GBPS:
			port_speed = 25000;
			break;
		case LPFC_ASYNC_LINK_SPEED_40GBPS:
			port_speed = 40000;
			break;
		case LPFC_ASYNC_LINK_SPEED_100GBPS:
			port_speed = 100000;
			break;
		default:
			port_speed = 0;
		}
		break;
	case LPFC_TRAILER_CODE_FC:
		switch (speed_code) {
		case LPFC_FC_LA_SPEED_UNKNOWN:
			port_speed = 0;
			break;
		case LPFC_FC_LA_SPEED_1G:
			port_speed = 1000;
			break;
		case LPFC_FC_LA_SPEED_2G:
			port_speed = 2000;
			break;
		case LPFC_FC_LA_SPEED_4G:
			port_speed = 4000;
			break;
		case LPFC_FC_LA_SPEED_8G:
			port_speed = 8000;
			break;
		case LPFC_FC_LA_SPEED_10G:
			port_speed = 10000;
			break;
		case LPFC_FC_LA_SPEED_16G:
			port_speed = 16000;
			break;
		case LPFC_FC_LA_SPEED_32G:
			port_speed = 32000;
			break;
		case LPFC_FC_LA_SPEED_64G:
			port_speed = 64000;
			break;
		case LPFC_FC_LA_SPEED_128G:
			port_speed = 128000;
			break;
		case LPFC_FC_LA_SPEED_256G:
			port_speed = 256000;
			break;
		default:
			port_speed = 0;
		}
		break;
	default:
		port_speed = 0;
	}
	return port_speed;
}

/**
 * lpfc_sli4_async_link_evt - Process the asynchronous FCoE link event
 * @phba: pointer to lpfc hba data structure.
 * @acqe_link: pointer to the async link completion queue entry.
 *
 * This routine is to handle the SLI4 asynchronous FCoE link event.
 **/
static void
lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
			 struct lpfc_acqe_link *acqe_link)
{
	struct lpfc_dmabuf *mp;
	LPFC_MBOXQ_t *pmb;
	MAILBOX_t *mb;
	struct lpfc_mbx_read_top *la;
	uint8_t att_type;
	int rc;

	att_type = lpfc_sli4_parse_latt_type(phba, acqe_link);
	if (att_type != LPFC_ATT_LINK_DOWN && att_type != LPFC_ATT_LINK_UP)
		return;
	phba->fcoe_eventtag = acqe_link->event_tag;
	pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (!pmb) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0395 The mboxq allocation failed\n");
		return;
	}
	mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
	if (!mp) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0396 The lpfc_dmabuf allocation failed\n");
		goto out_free_pmb;
	}
	mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
	if (!mp->virt) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0397 The mbuf allocation failed\n");
		goto out_free_dmabuf;
	}

	/* Cleanup any outstanding ELS commands */
	lpfc_els_flush_all_cmd(phba);

	/* Block ELS IOCBs until we have done process link event */
	phba->sli4_hba.els_wq->pring->flag |= LPFC_STOP_IOCB_EVENT;

	/* Update link event statistics */
	phba->sli.slistat.link_event++;

	/* Create lpfc_handle_latt mailbox command from link ACQE */
	lpfc_read_topology(phba, pmb, mp);
	pmb->mbox_cmpl = lpfc_mbx_cmpl_read_topology;
	pmb->vport = phba->pport;

	/* Keep the link status for extra SLI4 state machine reference */
	phba->sli4_hba.link_state.speed =
			lpfc_sli4_port_speed_parse(phba, LPFC_TRAILER_CODE_LINK,
				bf_get(lpfc_acqe_link_speed, acqe_link));
	phba->sli4_hba.link_state.duplex =
				bf_get(lpfc_acqe_link_duplex, acqe_link);
	phba->sli4_hba.link_state.status =
				bf_get(lpfc_acqe_link_status, acqe_link);
	phba->sli4_hba.link_state.type =
				bf_get(lpfc_acqe_link_type, acqe_link);
	phba->sli4_hba.link_state.number =
				bf_get(lpfc_acqe_link_number, acqe_link);
	phba->sli4_hba.link_state.fault =
				bf_get(lpfc_acqe_link_fault, acqe_link);
	phba->sli4_hba.link_state.logical_speed =
			bf_get(lpfc_acqe_logical_link_speed, acqe_link) * 10;

	lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
			"2900 Async FC/FCoE Link event - Speed:%dGBit "
			"duplex:x%x LA Type:x%x Port Type:%d Port Number:%d "
			"Logical speed:%dMbps Fault:%d\n",
			phba->sli4_hba.link_state.speed,
			phba->sli4_hba.link_state.topology,
			phba->sli4_hba.link_state.status,
			phba->sli4_hba.link_state.type,
			phba->sli4_hba.link_state.number,
			phba->sli4_hba.link_state.logical_speed,
			phba->sli4_hba.link_state.fault);
	/*
	 * For FC Mode: issue the READ_TOPOLOGY mailbox command to fetch
	 * topology info. Note: Optional for non FC-AL ports.
	 */
	if (!(phba->hba_flag & HBA_FCOE_MODE)) {
		rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
		if (rc == MBX_NOT_FINISHED)
			goto out_free_dmabuf;
		return;
	}
	/*
	 * For FCoE Mode: fill in all the topology information we need and call
	 * the READ_TOPOLOGY completion routine to continue without actually
	 * sending the READ_TOPOLOGY mailbox command to the port.
	 */
	/* Initialize completion status */
	mb = &pmb->u.mb;
	mb->mbxStatus = MBX_SUCCESS;

	/* Parse port fault information field */
	lpfc_sli4_parse_latt_fault(phba, acqe_link);

	/* Parse and translate link attention fields */
	la = (struct lpfc_mbx_read_top *) &pmb->u.mb.un.varReadTop;
	la->eventTag = acqe_link->event_tag;
	bf_set(lpfc_mbx_read_top_att_type, la, att_type);
	bf_set(lpfc_mbx_read_top_link_spd, la,
	       (bf_get(lpfc_acqe_link_speed, acqe_link)));

	/* Fake the the following irrelvant fields */
	bf_set(lpfc_mbx_read_top_topology, la, LPFC_TOPOLOGY_PT_PT);
	bf_set(lpfc_mbx_read_top_alpa_granted, la, 0);
	bf_set(lpfc_mbx_read_top_il, la, 0);
	bf_set(lpfc_mbx_read_top_pb, la, 0);
	bf_set(lpfc_mbx_read_top_fa, la, 0);
	bf_set(lpfc_mbx_read_top_mm, la, 0);

	/* Invoke the lpfc_handle_latt mailbox command callback function */
	lpfc_mbx_cmpl_read_topology(phba, pmb);

	return;

out_free_dmabuf:
	kfree(mp);
out_free_pmb:
	mempool_free(pmb, phba->mbox_mem_pool);
}

/**
 * lpfc_async_link_speed_to_read_top - Parse async evt link speed code to read
 * topology.
 * @phba: pointer to lpfc hba data structure.
 * @speed_code: asynchronous event link speed code.
 *
 * This routine is to parse the giving SLI4 async event link speed code into
 * value of Read topology link speed.
 *
 * Return: link speed in terms of Read topology.
 **/
static uint8_t
lpfc_async_link_speed_to_read_top(struct lpfc_hba *phba, uint8_t speed_code)
{
	uint8_t port_speed;

	switch (speed_code) {
	case LPFC_FC_LA_SPEED_1G:
		port_speed = LPFC_LINK_SPEED_1GHZ;
		break;
	case LPFC_FC_LA_SPEED_2G:
		port_speed = LPFC_LINK_SPEED_2GHZ;
		break;
	case LPFC_FC_LA_SPEED_4G:
		port_speed = LPFC_LINK_SPEED_4GHZ;
		break;
	case LPFC_FC_LA_SPEED_8G:
		port_speed = LPFC_LINK_SPEED_8GHZ;
		break;
	case LPFC_FC_LA_SPEED_16G:
		port_speed = LPFC_LINK_SPEED_16GHZ;
		break;
	case LPFC_FC_LA_SPEED_32G:
		port_speed = LPFC_LINK_SPEED_32GHZ;
		break;
	case LPFC_FC_LA_SPEED_64G:
		port_speed = LPFC_LINK_SPEED_64GHZ;
		break;
	case LPFC_FC_LA_SPEED_128G:
		port_speed = LPFC_LINK_SPEED_128GHZ;
		break;
	case LPFC_FC_LA_SPEED_256G:
		port_speed = LPFC_LINK_SPEED_256GHZ;
		break;
	default:
		port_speed = 0;
		break;
	}

	return port_speed;
}

void
lpfc_cgn_dump_rxmonitor(struct lpfc_hba *phba)
{
	struct rxtable_entry *entry;
	int cnt = 0, head, tail, last, start;

	head = atomic_read(&phba->rxtable_idx_head);
	tail = atomic_read(&phba->rxtable_idx_tail);
	if (!phba->rxtable || head == tail) {
		lpfc_printf_log(phba, KERN_ERR, LOG_CGN_MGMT,
				"4411 Rxtable is empty\n");
		return;
	}
	last = tail;
	start = head;

	/* Display the last LPFC_MAX_RXMONITOR_DUMP entries from the rxtable */
	while (start != last) {
		if (start)
			start--;
		else
			start = LPFC_MAX_RXMONITOR_ENTRY - 1;
		entry = &phba->rxtable[start];
		lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
				"4410 %02d: MBPI %lld Xmit %lld Cmpl %lld "
				"Lat %lld ASz %lld Info %02d BWUtil %d "
				"Int %d slot %d\n",
				cnt, entry->max_bytes_per_interval,
				entry->total_bytes, entry->rcv_bytes,
				entry->avg_io_latency, entry->avg_io_size,
				entry->cmf_info, entry->timer_utilization,
				entry->timer_interval, start);
		cnt++;
		if (cnt >= LPFC_MAX_RXMONITOR_DUMP)
			return;
	}
}

/**
 * lpfc_cgn_update_stat - Save data into congestion stats buffer
 * @phba: pointer to lpfc hba data structure.
 * @dtag: FPIN descriptor received
 *
 * Increment the FPIN received counter/time when it happens.
 */
void
lpfc_cgn_update_stat(struct lpfc_hba *phba, uint32_t dtag)
{
	struct lpfc_cgn_info *cp;
	struct tm broken;
	struct timespec64 cur_time;
	u32 cnt;
	u16 value;

	/* Make sure we have a congestion info buffer */
	if (!phba->cgn_i)
		return;
	cp = (struct lpfc_cgn_info *)phba->cgn_i->virt;
	ktime_get_real_ts64(&cur_time);
	time64_to_tm(cur_time.tv_sec, 0, &broken);

	/* Update congestion statistics */
	switch (dtag) {
	case ELS_DTAG_LNK_INTEGRITY:
		cnt = le32_to_cpu(cp->link_integ_notification);
		cnt++;
		cp->link_integ_notification = cpu_to_le32(cnt);

		cp->cgn_stat_lnk_month = broken.tm_mon + 1;
		cp->cgn_stat_lnk_day = broken.tm_mday;
		cp->cgn_stat_lnk_year = broken.tm_year - 100;
		cp->cgn_stat_lnk_hour = broken.tm_hour;
		cp->cgn_stat_lnk_min = broken.tm_min;
		cp->cgn_stat_lnk_sec = broken.tm_sec;
		break;
	case ELS_DTAG_DELIVERY:
		cnt = le32_to_cpu(cp->delivery_notification);
		cnt++;
		cp->delivery_notification = cpu_to_le32(cnt);

		cp->cgn_stat_del_month = broken.tm_mon + 1;
		cp->cgn_stat_del_day = broken.tm_mday;
		cp->cgn_stat_del_year = broken.tm_year - 100;
		cp->cgn_stat_del_hour = broken.tm_hour;
		cp->cgn_stat_del_min = broken.tm_min;
		cp->cgn_stat_del_sec = broken.tm_sec;
		break;
	case ELS_DTAG_PEER_CONGEST:
		cnt = le32_to_cpu(cp->cgn_peer_notification);
		cnt++;
		cp->cgn_peer_notification = cpu_to_le32(cnt);

		cp->cgn_stat_peer_month = broken.tm_mon + 1;
		cp->cgn_stat_peer_day = broken.tm_mday;
		cp->cgn_stat_peer_year = broken.tm_year - 100;
		cp->cgn_stat_peer_hour = broken.tm_hour;
		cp->cgn_stat_peer_min = broken.tm_min;
		cp->cgn_stat_peer_sec = broken.tm_sec;
		break;
	case ELS_DTAG_CONGESTION:
		cnt = le32_to_cpu(cp->cgn_notification);
		cnt++;
		cp->cgn_notification = cpu_to_le32(cnt);

		cp->cgn_stat_cgn_month = broken.tm_mon + 1;
		cp->cgn_stat_cgn_day = broken.tm_mday;
		cp->cgn_stat_cgn_year = broken.tm_year - 100;
		cp->cgn_stat_cgn_hour = broken.tm_hour;
		cp->cgn_stat_cgn_min = broken.tm_min;
		cp->cgn_stat_cgn_sec = broken.tm_sec;
	}
	if (phba->cgn_fpin_frequency &&
	    phba->cgn_fpin_frequency != LPFC_FPIN_INIT_FREQ) {
		value = LPFC_CGN_TIMER_TO_MIN / phba->cgn_fpin_frequency;
		cp->cgn_stat_npm = value;
	}
	value = lpfc_cgn_calc_crc32(cp, LPFC_CGN_INFO_SZ,
				    LPFC_CGN_CRC32_SEED);
	cp->cgn_info_crc = cpu_to_le32(value);
}

/**
 * lpfc_cgn_save_evt_cnt - Save data into registered congestion buffer
 * @phba: pointer to lpfc hba data structure.
 *
 * Save the congestion event data every minute.
 * On the hour collapse all the minute data into hour data. Every day
 * collapse all the hour data into daily data. Separate driver
 * and fabrc congestion event counters that will be saved out
 * to the registered congestion buffer every minute.
 */
static void
lpfc_cgn_save_evt_cnt(struct lpfc_hba *phba)
{
	struct lpfc_cgn_info *cp;
	struct tm broken;
	struct timespec64 cur_time;
	uint32_t i, index;
	uint16_t value, mvalue;
	uint64_t bps;
	uint32_t mbps;
	uint32_t dvalue, wvalue, lvalue, avalue;
	uint64_t latsum;
	__le16 *ptr;
	__le32 *lptr;
	__le16 *mptr;

	/* Make sure we have a congestion info buffer */
	if (!phba->cgn_i)
		return;
	cp = (struct lpfc_cgn_info *)phba->cgn_i->virt;

	if (time_before(jiffies, phba->cgn_evt_timestamp))
		return;
	phba->cgn_evt_timestamp = jiffies +
			msecs_to_jiffies(LPFC_CGN_TIMER_TO_MIN);
	phba->cgn_evt_minute++;

	/* We should get to this point in the routine on 1 minute intervals */

	ktime_get_real_ts64(&cur_time);
	time64_to_tm(cur_time.tv_sec, 0, &broken);

	if (phba->cgn_fpin_frequency &&
	    phba->cgn_fpin_frequency != LPFC_FPIN_INIT_FREQ) {
		value = LPFC_CGN_TIMER_TO_MIN / phba->cgn_fpin_frequency;
		cp->cgn_stat_npm = value;
	}

	/* Read and clear the latency counters for this minute */
	lvalue = atomic_read(&phba->cgn_latency_evt_cnt);
	latsum = atomic64_read(&phba->cgn_latency_evt);
	atomic_set(&phba->cgn_latency_evt_cnt, 0);
	atomic64_set(&phba->cgn_latency_evt, 0);

	/* We need to store MB/sec bandwidth in the congestion information.
	 * block_cnt is count of 512 byte blocks for the entire minute,
	 * bps will get bytes per sec before finally converting to MB/sec.
	 */
	bps = div_u64(phba->rx_block_cnt, LPFC_SEC_MIN) * 512;
	phba->rx_block_cnt = 0;
	mvalue = bps / (1024 * 1024); /* convert to MB/sec */

	/* Every minute */
	/* cgn parameters */
	cp->cgn_info_mode = phba->cgn_p.cgn_param_mode;
	cp->cgn_info_level0 = phba->cgn_p.cgn_param_level0;
	cp->cgn_info_level1 = phba->cgn_p.cgn_param_level1;
	cp->cgn_info_level2 = phba->cgn_p.cgn_param_level2;

	/* Fill in default LUN qdepth */
	value = (uint16_t)(phba->pport->cfg_lun_queue_depth);
	cp->cgn_lunq = cpu_to_le16(value);

	/* Record congestion buffer info - every minute
	 * cgn_driver_evt_cnt (Driver events)
	 * cgn_fabric_warn_cnt (Congestion Warnings)
	 * cgn_latency_evt_cnt / cgn_latency_evt (IO Latency)
	 * cgn_fabric_alarm_cnt (Congestion Alarms)
	 */
	index = ++cp->cgn_index_minute;
	if (cp->cgn_index_minute == LPFC_MIN_HOUR) {
		cp->cgn_index_minute = 0;
		index = 0;
	}

	/* Get the number of driver events in this sample and reset counter */
	dvalue = atomic_read(&phba->cgn_driver_evt_cnt);
	atomic_set(&phba->cgn_driver_evt_cnt, 0);

	/* Get the number of warning events - FPIN and Signal for this minute */
	wvalue = 0;
	if ((phba->cgn_reg_fpin & LPFC_CGN_FPIN_WARN) ||
	    phba->cgn_reg_signal == EDC_CG_SIG_WARN_ONLY ||
	    phba->cgn_reg_signal == EDC_CG_SIG_WARN_ALARM)
		wvalue = atomic_read(&phba->cgn_fabric_warn_cnt);
	atomic_set(&phba->cgn_fabric_warn_cnt, 0);

	/* Get the number of alarm events - FPIN and Signal for this minute */
	avalue = 0;
	if ((phba->cgn_reg_fpin & LPFC_CGN_FPIN_ALARM) ||
	    phba->cgn_reg_signal == EDC_CG_SIG_WARN_ALARM)
		avalue = atomic_read(&phba->cgn_fabric_alarm_cnt);
	atomic_set(&phba->cgn_fabric_alarm_cnt, 0);

	/* Collect the driver, warning, alarm and latency counts for this
	 * minute into the driver congestion buffer.
	 */
	ptr = &cp->cgn_drvr_min[index];
	value = (uint16_t)dvalue;
	*ptr = cpu_to_le16(value);

	ptr = &cp->cgn_warn_min[index];
	value = (uint16_t)wvalue;
	*ptr = cpu_to_le16(value);

	ptr = &cp->cgn_alarm_min[index];
	value = (uint16_t)avalue;
	*ptr = cpu_to_le16(value);

	lptr = &cp->cgn_latency_min[index];
	if (lvalue) {
		lvalue = (uint32_t)div_u64(latsum, lvalue);
		*lptr = cpu_to_le32(lvalue);
	} else {
		*lptr = 0;
	}

	/* Collect the bandwidth value into the driver's congesion buffer. */
	mptr = &cp->cgn_bw_min[index];
	*mptr = cpu_to_le16(mvalue);

	lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
			"2418 Congestion Info - minute (%d): %d %d %d %d %d\n",
			index, dvalue, wvalue, *lptr, mvalue, avalue);

	/* Every hour */
	if ((phba->cgn_evt_minute % LPFC_MIN_HOUR) == 0) {
		/* Record congestion buffer info - every hour
		 * Collapse all minutes into an hour
		 */
		index = ++cp->cgn_index_hour;
		if (cp->cgn_index_hour == LPFC_HOUR_DAY) {
			cp->cgn_index_hour = 0;
			index = 0;
		}

		dvalue = 0;
		wvalue = 0;
		lvalue = 0;
		avalue = 0;
		mvalue = 0;
		mbps = 0;
		for (i = 0; i < LPFC_MIN_HOUR; i++) {
			dvalue += le16_to_cpu(cp->cgn_drvr_min[i]);
			wvalue += le16_to_cpu(cp->cgn_warn_min[i]);
			lvalue += le32_to_cpu(cp->cgn_latency_min[i]);
			mbps += le16_to_cpu(cp->cgn_bw_min[i]);
			avalue += le16_to_cpu(cp->cgn_alarm_min[i]);
		}
		if (lvalue)		/* Avg of latency averages */
			lvalue /= LPFC_MIN_HOUR;
		if (mbps)		/* Avg of Bandwidth averages */
			mvalue = mbps / LPFC_MIN_HOUR;

		lptr = &cp->cgn_drvr_hr[index];
		*lptr = cpu_to_le32(dvalue);
		lptr = &cp->cgn_warn_hr[index];
		*lptr = cpu_to_le32(wvalue);
		lptr = &cp->cgn_latency_hr[index];
		*lptr = cpu_to_le32(lvalue);
		mptr = &cp->cgn_bw_hr[index];
		*mptr = cpu_to_le16(mvalue);
		lptr = &cp->cgn_alarm_hr[index];
		*lptr = cpu_to_le32(avalue);

		lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
				"2419 Congestion Info - hour "
				"(%d): %d %d %d %d %d\n",
				index, dvalue, wvalue, lvalue, mvalue, avalue);
	}

	/* Every day */
	if ((phba->cgn_evt_minute % LPFC_MIN_DAY) == 0) {
		/* Record congestion buffer info - every hour
		 * Collapse all hours into a day. Rotate days
		 * after LPFC_MAX_CGN_DAYS.
		 */
		index = ++cp->cgn_index_day;
		if (cp->cgn_index_day == LPFC_MAX_CGN_DAYS) {
			cp->cgn_index_day = 0;
			index = 0;
		}

		/* Anytime we overwrite daily index 0, after we wrap,
		 * we will be overwriting the oldest day, so we must
		 * update the congestion data start time for that day.
		 * That start time should have previously been saved after
		 * we wrote the last days worth of data.
		 */
		if ((phba->hba_flag & HBA_CGN_DAY_WRAP) && index == 0) {
			time64_to_tm(phba->cgn_daily_ts.tv_sec, 0, &broken);

			cp->cgn_info_month = broken.tm_mon + 1;
			cp->cgn_info_day = broken.tm_mday;
			cp->cgn_info_year = broken.tm_year - 100;
			cp->cgn_info_hour = broken.tm_hour;
			cp->cgn_info_minute = broken.tm_min;
			cp->cgn_info_second = broken.tm_sec;

			lpfc_printf_log
				(phba, KERN_INFO, LOG_CGN_MGMT,
				"2646 CGNInfo idx0 Start Time: "
				"%d/%d/%d %d:%d:%d\n",
				cp->cgn_info_day, cp->cgn_info_month,
				cp->cgn_info_year, cp->cgn_info_hour,
				cp->cgn_info_minute, cp->cgn_info_second);
		}

		dvalue = 0;
		wvalue = 0;
		lvalue = 0;
		mvalue = 0;
		mbps = 0;
		avalue = 0;
		for (i = 0; i < LPFC_HOUR_DAY; i++) {
			dvalue += le32_to_cpu(cp->cgn_drvr_hr[i]);
			wvalue += le32_to_cpu(cp->cgn_warn_hr[i]);
			lvalue += le32_to_cpu(cp->cgn_latency_hr[i]);
			mbps += le16_to_cpu(cp->cgn_bw_hr[i]);
			avalue += le32_to_cpu(cp->cgn_alarm_hr[i]);
		}
		if (lvalue)		/* Avg of latency averages */
			lvalue /= LPFC_HOUR_DAY;
		if (mbps)		/* Avg of Bandwidth averages */
			mvalue = mbps / LPFC_HOUR_DAY;

		lptr = &cp->cgn_drvr_day[index];
		*lptr = cpu_to_le32(dvalue);
		lptr = &cp->cgn_warn_day[index];
		*lptr = cpu_to_le32(wvalue);
		lptr = &cp->cgn_latency_day[index];
		*lptr = cpu_to_le32(lvalue);
		mptr = &cp->cgn_bw_day[index];
		*mptr = cpu_to_le16(mvalue);
		lptr = &cp->cgn_alarm_day[index];
		*lptr = cpu_to_le32(avalue);

		lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
				"2420 Congestion Info - daily (%d): "
				"%d %d %d %d %d\n",
				index, dvalue, wvalue, lvalue, mvalue, avalue);

		/* We just wrote LPFC_MAX_CGN_DAYS of data,
		 * so we are wrapped on any data after this.
		 * Save this as the start time for the next day.
		 */
		if (index == (LPFC_MAX_CGN_DAYS - 1)) {
			phba->hba_flag |= HBA_CGN_DAY_WRAP;
			ktime_get_real_ts64(&phba->cgn_daily_ts);
		}
	}

	/* Use the frequency found in the last rcv'ed FPIN */
	value = phba->cgn_fpin_frequency;
	if (phba->cgn_reg_fpin & LPFC_CGN_FPIN_WARN)
		cp->cgn_warn_freq = cpu_to_le16(value);
	if (phba->cgn_reg_fpin & LPFC_CGN_FPIN_ALARM)
		cp->cgn_alarm_freq = cpu_to_le16(value);

	/* Frequency (in ms) Signal Warning/Signal Congestion Notifications
	 * are received by the HBA
	 */
	value = phba->cgn_sig_freq;

	if (phba->cgn_reg_signal == EDC_CG_SIG_WARN_ONLY ||
	    phba->cgn_reg_signal == EDC_CG_SIG_WARN_ALARM)
		cp->cgn_warn_freq = cpu_to_le16(value);
	if (phba->cgn_reg_signal == EDC_CG_SIG_WARN_ALARM)
		cp->cgn_alarm_freq = cpu_to_le16(value);

	lvalue = lpfc_cgn_calc_crc32(cp, LPFC_CGN_INFO_SZ,
				     LPFC_CGN_CRC32_SEED);
	cp->cgn_info_crc = cpu_to_le32(lvalue);
}

/**
 * lpfc_calc_cmf_latency - latency from start of rxate timer interval
 * @phba: The Hba for which this call is being executed.
 *
 * The routine calculates the latency from the beginning of the CMF timer
 * interval to the current point in time. It is called from IO completion
 * when we exceed our Bandwidth limitation for the time interval.
 */
uint32_t
lpfc_calc_cmf_latency(struct lpfc_hba *phba)
{
	struct timespec64 cmpl_time;
	uint32_t msec = 0;

	ktime_get_real_ts64(&cmpl_time);

	/* This routine works on a ms granularity so sec and usec are
	 * converted accordingly.
	 */
	if (cmpl_time.tv_sec == phba->cmf_latency.tv_sec) {
		msec = (cmpl_time.tv_nsec - phba->cmf_latency.tv_nsec) /
			NSEC_PER_MSEC;
	} else {
		if (cmpl_time.tv_nsec >= phba->cmf_latency.tv_nsec) {
			msec = (cmpl_time.tv_sec -
				phba->cmf_latency.tv_sec) * MSEC_PER_SEC;
			msec += ((cmpl_time.tv_nsec -
				  phba->cmf_latency.tv_nsec) / NSEC_PER_MSEC);
		} else {
			msec = (cmpl_time.tv_sec - phba->cmf_latency.tv_sec -
				1) * MSEC_PER_SEC;
			msec += (((NSEC_PER_SEC - phba->cmf_latency.tv_nsec) +
				 cmpl_time.tv_nsec) / NSEC_PER_MSEC);
		}
	}
	return msec;
}

/**
 * lpfc_cmf_timer -  This is the timer function for one congestion
 * rate interval.
 * @timer: Pointer to the high resolution timer that expired
 */
static enum hrtimer_restart
lpfc_cmf_timer(struct hrtimer *timer)
{
	struct lpfc_hba *phba = container_of(timer, struct lpfc_hba,
					     cmf_timer);
	struct rxtable_entry *entry;
	uint32_t io_cnt;
	uint32_t head, tail;
	uint32_t busy, max_read;
	uint64_t total, rcv, lat, mbpi, extra;
	int timer_interval = LPFC_CMF_INTERVAL;
	uint32_t ms;
	struct lpfc_cgn_stat *cgs;
	int cpu;

	/* Only restart the timer if congestion mgmt is on */
	if (phba->cmf_active_mode == LPFC_CFG_OFF ||
	    !phba->cmf_latency.tv_sec) {
		lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
				"6224 CMF timer exit: %d %lld\n",
				phba->cmf_active_mode,
				(uint64_t)phba->cmf_latency.tv_sec);
		return HRTIMER_NORESTART;
	}

	/* If pport is not ready yet, just exit and wait for
	 * the next timer cycle to hit.
	 */
	if (!phba->pport)
		goto skip;

	/* Do not block SCSI IO while in the timer routine since
	 * total_bytes will be cleared
	 */
	atomic_set(&phba->cmf_stop_io, 1);

	/* First we need to calculate the actual ms between
	 * the last timer interrupt and this one. We ask for
	 * LPFC_CMF_INTERVAL, however the actual time may
	 * vary depending on system overhead.
	 */
	ms = lpfc_calc_cmf_latency(phba);


	/* Immediately after we calculate the time since the last
	 * timer interrupt, set the start time for the next
	 * interrupt
	 */
	ktime_get_real_ts64(&phba->cmf_latency);

	phba->cmf_link_byte_count =
		div_u64(phba->cmf_max_line_rate * LPFC_CMF_INTERVAL, 1000);

	/* Collect all the stats from the prior timer interval */
	total = 0;
	io_cnt = 0;
	lat = 0;
	rcv = 0;
	for_each_present_cpu(cpu) {
		cgs = per_cpu_ptr(phba->cmf_stat, cpu);
		total += atomic64_xchg(&cgs->total_bytes, 0);
		io_cnt += atomic_xchg(&cgs->rx_io_cnt, 0);
		lat += atomic64_xchg(&cgs->rx_latency, 0);
		rcv += atomic64_xchg(&cgs->rcv_bytes, 0);
	}

	/* Before we issue another CMF_SYNC_WQE, retrieve the BW
	 * returned from the last CMF_SYNC_WQE issued, from
	 * cmf_last_sync_bw. This will be the target BW for
	 * this next timer interval.
	 */
	if (phba->cmf_active_mode == LPFC_CFG_MANAGED &&
	    phba->link_state != LPFC_LINK_DOWN &&
	    phba->hba_flag & HBA_SETUP) {
		mbpi = phba->cmf_last_sync_bw;
		phba->cmf_last_sync_bw = 0;
		extra = 0;

		/* Calculate any extra bytes needed to account for the
		 * timer accuracy. If we are less than LPFC_CMF_INTERVAL
		 * add an extra 3% slop factor, equal to LPFC_CMF_INTERVAL
		 * add an extra 2%. The goal is to equalize total with a
		 * time > LPFC_CMF_INTERVAL or <= LPFC_CMF_INTERVAL + 1
		 */
		if (ms == LPFC_CMF_INTERVAL)
			extra = div_u64(total, 50);
		else if (ms < LPFC_CMF_INTERVAL)
			extra = div_u64(total, 33);
		lpfc_issue_cmf_sync_wqe(phba, LPFC_CMF_INTERVAL, total + extra);
	} else {
		/* For Monitor mode or link down we want mbpi
		 * to be the full link speed
		 */
		mbpi = phba->cmf_link_byte_count;
	}
	phba->cmf_timer_cnt++;

	if (io_cnt) {
		/* Update congestion info buffer latency in us */
		atomic_add(io_cnt, &phba->cgn_latency_evt_cnt);
		atomic64_add(lat, &phba->cgn_latency_evt);
	}
	busy = atomic_xchg(&phba->cmf_busy, 0);
	max_read = atomic_xchg(&phba->rx_max_read_cnt, 0);

	/* Calculate MBPI for the next timer interval */
	if (mbpi) {
		if (mbpi > phba->cmf_link_byte_count ||
		    phba->cmf_active_mode == LPFC_CFG_MONITOR)
			mbpi = phba->cmf_link_byte_count;

		/* Change max_bytes_per_interval to what the prior
		 * CMF_SYNC_WQE cmpl indicated.
		 */
		if (mbpi != phba->cmf_max_bytes_per_interval)
			phba->cmf_max_bytes_per_interval = mbpi;
	}

	/* Save rxmonitor information for debug */
	if (phba->rxtable) {
		head = atomic_xchg(&phba->rxtable_idx_head,
				   LPFC_RXMONITOR_TABLE_IN_USE);
		entry = &phba->rxtable[head];
		entry->total_bytes = total;
		entry->rcv_bytes = rcv;
		entry->cmf_busy = busy;
		entry->cmf_info = phba->cmf_active_info;
		if (io_cnt) {
			entry->avg_io_latency = div_u64(lat, io_cnt);
			entry->avg_io_size = div_u64(rcv, io_cnt);
		} else {
			entry->avg_io_latency = 0;
			entry->avg_io_size = 0;
		}
		entry->max_read_cnt = max_read;
		entry->io_cnt = io_cnt;
		entry->max_bytes_per_interval = mbpi;
		if (phba->cmf_active_mode == LPFC_CFG_MANAGED)
			entry->timer_utilization = phba->cmf_last_ts;
		else
			entry->timer_utilization = ms;
		entry->timer_interval = ms;
		phba->cmf_last_ts = 0;

		/* Increment rxtable index */
		head = (head + 1) % LPFC_MAX_RXMONITOR_ENTRY;
		tail = atomic_read(&phba->rxtable_idx_tail);
		if (head == tail) {
			tail = (tail + 1) % LPFC_MAX_RXMONITOR_ENTRY;
			atomic_set(&phba->rxtable_idx_tail, tail);
		}
		atomic_set(&phba->rxtable_idx_head, head);
	}

	if (phba->cmf_active_mode == LPFC_CFG_MONITOR) {
		/* If Monitor mode, check if we are oversubscribed
		 * against the full line rate.
		 */
		if (mbpi && total > mbpi)
			atomic_inc(&phba->cgn_driver_evt_cnt);
	}
	phba->rx_block_cnt += div_u64(rcv, 512);  /* save 512 byte block cnt */

	/* Each minute save Fabric and Driver congestion information */
	lpfc_cgn_save_evt_cnt(phba);

	/* Since we need to call lpfc_cgn_save_evt_cnt every minute, on the
	 * minute, adjust our next timer interval, if needed, to ensure a
	 * 1 minute granularity when we get the next timer interrupt.
	 */
	if (time_after(jiffies + msecs_to_jiffies(LPFC_CMF_INTERVAL),
		       phba->cgn_evt_timestamp)) {
		timer_interval = jiffies_to_msecs(phba->cgn_evt_timestamp -
						  jiffies);
		if (timer_interval <= 0)
			timer_interval = LPFC_CMF_INTERVAL;

		/* If we adjust timer_interval, max_bytes_per_interval
		 * needs to be adjusted as well.
		 */
		phba->cmf_link_byte_count = div_u64(phba->cmf_max_line_rate *
						    timer_interval, 1000);
		if (phba->cmf_active_mode == LPFC_CFG_MONITOR)
			phba->cmf_max_bytes_per_interval =
				phba->cmf_link_byte_count;
	}

	/* Since total_bytes has already been zero'ed, its okay to unblock
	 * after max_bytes_per_interval is setup.
	 */
	if (atomic_xchg(&phba->cmf_bw_wait, 0))
		queue_work(phba->wq, &phba->unblock_request_work);

	/* SCSI IO is now unblocked */
	atomic_set(&phba->cmf_stop_io, 0);

skip:
	hrtimer_forward_now(timer,
			    ktime_set(0, timer_interval * NSEC_PER_MSEC));
	return HRTIMER_RESTART;
}

#define trunk_link_status(__idx)\
	bf_get(lpfc_acqe_fc_la_trunk_config_port##__idx, acqe_fc) ?\
	       ((phba->trunk_link.link##__idx.state == LPFC_LINK_UP) ?\
		"Link up" : "Link down") : "NA"
/* Did port __idx reported an error */
#define trunk_port_fault(__idx)\
	bf_get(lpfc_acqe_fc_la_trunk_config_port##__idx, acqe_fc) ?\
	       (port_fault & (1 << __idx) ? "YES" : "NO") : "NA"

static void
lpfc_update_trunk_link_status(struct lpfc_hba *phba,
			      struct lpfc_acqe_fc_la *acqe_fc)
{
	uint8_t port_fault = bf_get(lpfc_acqe_fc_la_trunk_linkmask, acqe_fc);
	uint8_t err = bf_get(lpfc_acqe_fc_la_trunk_fault, acqe_fc);

	phba->sli4_hba.link_state.speed =
		lpfc_sli4_port_speed_parse(phba, LPFC_TRAILER_CODE_FC,
				bf_get(lpfc_acqe_fc_la_speed, acqe_fc));

	phba->sli4_hba.link_state.logical_speed =
				bf_get(lpfc_acqe_fc_la_llink_spd, acqe_fc) * 10;
	/* We got FC link speed, convert to fc_linkspeed (READ_TOPOLOGY) */
	phba->fc_linkspeed =
		 lpfc_async_link_speed_to_read_top(
				phba,
				bf_get(lpfc_acqe_fc_la_speed, acqe_fc));

	if (bf_get(lpfc_acqe_fc_la_trunk_config_port0, acqe_fc)) {
		phba->trunk_link.link0.state =
			bf_get(lpfc_acqe_fc_la_trunk_link_status_port0, acqe_fc)
			? LPFC_LINK_UP : LPFC_LINK_DOWN;
		phba->trunk_link.link0.fault = port_fault & 0x1 ? err : 0;
	}
	if (bf_get(lpfc_acqe_fc_la_trunk_config_port1, acqe_fc)) {
		phba->trunk_link.link1.state =
			bf_get(lpfc_acqe_fc_la_trunk_link_status_port1, acqe_fc)
			? LPFC_LINK_UP : LPFC_LINK_DOWN;
		phba->trunk_link.link1.fault = port_fault & 0x2 ? err : 0;
	}
	if (bf_get(lpfc_acqe_fc_la_trunk_config_port2, acqe_fc)) {
		phba->trunk_link.link2.state =
			bf_get(lpfc_acqe_fc_la_trunk_link_status_port2, acqe_fc)
			? LPFC_LINK_UP : LPFC_LINK_DOWN;
		phba->trunk_link.link2.fault = port_fault & 0x4 ? err : 0;
	}
	if (bf_get(lpfc_acqe_fc_la_trunk_config_port3, acqe_fc)) {
		phba->trunk_link.link3.state =
			bf_get(lpfc_acqe_fc_la_trunk_link_status_port3, acqe_fc)
			? LPFC_LINK_UP : LPFC_LINK_DOWN;
		phba->trunk_link.link3.fault = port_fault & 0x8 ? err : 0;
	}

	lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
			"2910 Async FC Trunking Event - Speed:%d\n"
			"\tLogical speed:%d "
			"port0: %s port1: %s port2: %s port3: %s\n",
			phba->sli4_hba.link_state.speed,
			phba->sli4_hba.link_state.logical_speed,
			trunk_link_status(0), trunk_link_status(1),
			trunk_link_status(2), trunk_link_status(3));

	if (phba->cmf_active_mode != LPFC_CFG_OFF)
		lpfc_cmf_signal_init(phba);

	if (port_fault)
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3202 trunk error:0x%x (%s) seen on port0:%s "
				/*
				 * SLI-4: We have only 0xA error codes
				 * defined as of now. print an appropriate
				 * message in case driver needs to be updated.
				 */
				"port1:%s port2:%s port3:%s\n", err, err > 0xA ?
				"UNDEFINED. update driver." : trunk_errmsg[err],
				trunk_port_fault(0), trunk_port_fault(1),
				trunk_port_fault(2), trunk_port_fault(3));
}


/**
 * lpfc_sli4_async_fc_evt - Process the asynchronous FC link event
 * @phba: pointer to lpfc hba data structure.
 * @acqe_fc: pointer to the async fc completion queue entry.
 *
 * This routine is to handle the SLI4 asynchronous FC event. It will simply log
 * that the event was received and then issue a read_topology mailbox command so
 * that the rest of the driver will treat it the same as SLI3.
 **/
static void
lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc)
{
	struct lpfc_dmabuf *mp;
	LPFC_MBOXQ_t *pmb;
	MAILBOX_t *mb;
	struct lpfc_mbx_read_top *la;
	int rc;

	if (bf_get(lpfc_trailer_type, acqe_fc) !=
	    LPFC_FC_LA_EVENT_TYPE_FC_LINK) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2895 Non FC link Event detected.(%d)\n",
				bf_get(lpfc_trailer_type, acqe_fc));
		return;
	}

	if (bf_get(lpfc_acqe_fc_la_att_type, acqe_fc) ==
	    LPFC_FC_LA_TYPE_TRUNKING_EVENT) {
		lpfc_update_trunk_link_status(phba, acqe_fc);
		return;
	}

	/* Keep the link status for extra SLI4 state machine reference */
	phba->sli4_hba.link_state.speed =
			lpfc_sli4_port_speed_parse(phba, LPFC_TRAILER_CODE_FC,
				bf_get(lpfc_acqe_fc_la_speed, acqe_fc));
	phba->sli4_hba.link_state.duplex = LPFC_ASYNC_LINK_DUPLEX_FULL;
	phba->sli4_hba.link_state.topology =
				bf_get(lpfc_acqe_fc_la_topology, acqe_fc);
	phba->sli4_hba.link_state.status =
				bf_get(lpfc_acqe_fc_la_att_type, acqe_fc);
	phba->sli4_hba.link_state.type =
				bf_get(lpfc_acqe_fc_la_port_type, acqe_fc);
	phba->sli4_hba.link_state.number =
				bf_get(lpfc_acqe_fc_la_port_number, acqe_fc);
	phba->sli4_hba.link_state.fault =
				bf_get(lpfc_acqe_link_fault, acqe_fc);

	if (bf_get(lpfc_acqe_fc_la_att_type, acqe_fc) ==
	    LPFC_FC_LA_TYPE_LINK_DOWN)
		phba->sli4_hba.link_state.logical_speed = 0;
	else if	(!phba->sli4_hba.conf_trunk)
		phba->sli4_hba.link_state.logical_speed =
				bf_get(lpfc_acqe_fc_la_llink_spd, acqe_fc) * 10;

	lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
			"2896 Async FC event - Speed:%dGBaud Topology:x%x "
			"LA Type:x%x Port Type:%d Port Number:%d Logical speed:"
			"%dMbps Fault:%d\n",
			phba->sli4_hba.link_state.speed,
			phba->sli4_hba.link_state.topology,
			phba->sli4_hba.link_state.status,
			phba->sli4_hba.link_state.type,
			phba->sli4_hba.link_state.number,
			phba->sli4_hba.link_state.logical_speed,
			phba->sli4_hba.link_state.fault);
	pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (!pmb) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2897 The mboxq allocation failed\n");
		return;
	}
	mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
	if (!mp) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2898 The lpfc_dmabuf allocation failed\n");
		goto out_free_pmb;
	}
	mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
	if (!mp->virt) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2899 The mbuf allocation failed\n");
		goto out_free_dmabuf;
	}

	/* Cleanup any outstanding ELS commands */
	lpfc_els_flush_all_cmd(phba);

	/* Block ELS IOCBs until we have done process link event */
	phba->sli4_hba.els_wq->pring->flag |= LPFC_STOP_IOCB_EVENT;

	/* Update link event statistics */
	phba->sli.slistat.link_event++;

	/* Create lpfc_handle_latt mailbox command from link ACQE */
	lpfc_read_topology(phba, pmb, mp);
	pmb->mbox_cmpl = lpfc_mbx_cmpl_read_topology;
	pmb->vport = phba->pport;

	if (phba->sli4_hba.link_state.status != LPFC_FC_LA_TYPE_LINK_UP) {
		phba->link_flag &= ~(LS_MDS_LINK_DOWN | LS_MDS_LOOPBACK);

		switch (phba->sli4_hba.link_state.status) {
		case LPFC_FC_LA_TYPE_MDS_LINK_DOWN:
			phba->link_flag |= LS_MDS_LINK_DOWN;
			break;
		case LPFC_FC_LA_TYPE_MDS_LOOPBACK:
			phba->link_flag |= LS_MDS_LOOPBACK;
			break;
		default:
			break;
		}

		/* Initialize completion status */
		mb = &pmb->u.mb;
		mb->mbxStatus = MBX_SUCCESS;

		/* Parse port fault information field */
		lpfc_sli4_parse_latt_fault(phba, (void *)acqe_fc);

		/* Parse and translate link attention fields */
		la = (struct lpfc_mbx_read_top *)&pmb->u.mb.un.varReadTop;
		la->eventTag = acqe_fc->event_tag;

		if (phba->sli4_hba.link_state.status ==
		    LPFC_FC_LA_TYPE_UNEXP_WWPN) {
			bf_set(lpfc_mbx_read_top_att_type, la,
			       LPFC_FC_LA_TYPE_UNEXP_WWPN);
		} else {
			bf_set(lpfc_mbx_read_top_att_type, la,
			       LPFC_FC_LA_TYPE_LINK_DOWN);
		}
		/* Invoke the mailbox command callback function */
		lpfc_mbx_cmpl_read_topology(phba, pmb);

		return;
	}

	rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
	if (rc == MBX_NOT_FINISHED)
		goto out_free_dmabuf;
	return;

out_free_dmabuf:
	kfree(mp);
out_free_pmb:
	mempool_free(pmb, phba->mbox_mem_pool);
}

/**
 * lpfc_sli4_async_sli_evt - Process the asynchronous SLI link event
 * @phba: pointer to lpfc hba data structure.
 * @acqe_sli: pointer to the async SLI completion queue entry.
 *
 * This routine is to handle the SLI4 asynchronous SLI events.
 **/
static void
lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli)
{
	char port_name;
	char message[128];
	uint8_t status;
	uint8_t evt_type;
	uint8_t operational = 0;
	struct temp_event temp_event_data;
	struct lpfc_acqe_misconfigured_event *misconfigured;
	struct lpfc_acqe_cgn_signal *cgn_signal;
	struct Scsi_Host  *shost;
	struct lpfc_vport **vports;
	int rc, i, cnt;

	evt_type = bf_get(lpfc_trailer_type, acqe_sli);

	lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
			"2901 Async SLI event - Type:%d, Event Data: x%08x "
			"x%08x x%08x x%08x\n", evt_type,
			acqe_sli->event_data1, acqe_sli->event_data2,
			acqe_sli->reserved, acqe_sli->trailer);

	port_name = phba->Port[0];
	if (port_name == 0x00)
		port_name = '?'; /* get port name is empty */

	switch (evt_type) {
	case LPFC_SLI_EVENT_TYPE_OVER_TEMP:
		temp_event_data.event_type = FC_REG_TEMPERATURE_EVENT;
		temp_event_data.event_code = LPFC_THRESHOLD_TEMP;
		temp_event_data.data = (uint32_t)acqe_sli->event_data1;

		lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
				"3190 Over Temperature:%d Celsius- Port Name %c\n",
				acqe_sli->event_data1, port_name);

		phba->sfp_warning |= LPFC_TRANSGRESSION_HIGH_TEMPERATURE;
		shost = lpfc_shost_from_vport(phba->pport);
		fc_host_post_vendor_event(shost, fc_get_event_number(),
					  sizeof(temp_event_data),
					  (char *)&temp_event_data,
					  SCSI_NL_VID_TYPE_PCI
					  | PCI_VENDOR_ID_EMULEX);
		break;
	case LPFC_SLI_EVENT_TYPE_NORM_TEMP:
		temp_event_data.event_type = FC_REG_TEMPERATURE_EVENT;
		temp_event_data.event_code = LPFC_NORMAL_TEMP;
		temp_event_data.data = (uint32_t)acqe_sli->event_data1;

		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
				"3191 Normal Temperature:%d Celsius - Port Name %c\n",
				acqe_sli->event_data1, port_name);

		shost = lpfc_shost_from_vport(phba->pport);
		fc_host_post_vendor_event(shost, fc_get_event_number(),
					  sizeof(temp_event_data),
					  (char *)&temp_event_data,
					  SCSI_NL_VID_TYPE_PCI
					  | PCI_VENDOR_ID_EMULEX);
		break;
	case LPFC_SLI_EVENT_TYPE_MISCONFIGURED:
		misconfigured = (struct lpfc_acqe_misconfigured_event *)
					&acqe_sli->event_data1;

		/* fetch the status for this port */
		switch (phba->sli4_hba.lnk_info.lnk_no) {
		case LPFC_LINK_NUMBER_0:
			status = bf_get(lpfc_sli_misconfigured_port0_state,
					&misconfigured->theEvent);
			operational = bf_get(lpfc_sli_misconfigured_port0_op,
					&misconfigured->theEvent);
			break;
		case LPFC_LINK_NUMBER_1:
			status = bf_get(lpfc_sli_misconfigured_port1_state,
					&misconfigured->theEvent);
			operational = bf_get(lpfc_sli_misconfigured_port1_op,
					&misconfigured->theEvent);
			break;
		case LPFC_LINK_NUMBER_2:
			status = bf_get(lpfc_sli_misconfigured_port2_state,
					&misconfigured->theEvent);
			operational = bf_get(lpfc_sli_misconfigured_port2_op,
					&misconfigured->theEvent);
			break;
		case LPFC_LINK_NUMBER_3:
			status = bf_get(lpfc_sli_misconfigured_port3_state,
					&misconfigured->theEvent);
			operational = bf_get(lpfc_sli_misconfigured_port3_op,
					&misconfigured->theEvent);
			break;
		default:
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"3296 "
					"LPFC_SLI_EVENT_TYPE_MISCONFIGURED "
					"event: Invalid link %d",
					phba->sli4_hba.lnk_info.lnk_no);
			return;
		}

		/* Skip if optic state unchanged */
		if (phba->sli4_hba.lnk_info.optic_state == status)
			return;

		switch (status) {
		case LPFC_SLI_EVENT_STATUS_VALID:
			sprintf(message, "Physical Link is functional");
			break;
		case LPFC_SLI_EVENT_STATUS_NOT_PRESENT:
			sprintf(message, "Optics faulted/incorrectly "
				"installed/not installed - Reseat optics, "
				"if issue not resolved, replace.");
			break;
		case LPFC_SLI_EVENT_STATUS_WRONG_TYPE:
			sprintf(message,
				"Optics of two types installed - Remove one "
				"optic or install matching pair of optics.");
			break;
		case LPFC_SLI_EVENT_STATUS_UNSUPPORTED:
			sprintf(message, "Incompatible optics - Replace with "
				"compatible optics for card to function.");
			break;
		case LPFC_SLI_EVENT_STATUS_UNQUALIFIED:
			sprintf(message, "Unqualified optics - Replace with "
				"Avago optics for Warranty and Technical "
				"Support - Link is%s operational",
				(operational) ? " not" : "");
			break;
		case LPFC_SLI_EVENT_STATUS_UNCERTIFIED:
			sprintf(message, "Uncertified optics - Replace with "
				"Avago-certified optics to enable link "
				"operation - Link is%s operational",
				(operational) ? " not" : "");
			break;
		default:
			/* firmware is reporting a status we don't know about */
			sprintf(message, "Unknown event status x%02x", status);
			break;
		}

		/* Issue READ_CONFIG mbox command to refresh supported speeds */
		rc = lpfc_sli4_read_config(phba);
		if (rc) {
			phba->lmt = 0;
			lpfc_printf_log(phba, KERN_ERR,
					LOG_TRACE_EVENT,
					"3194 Unable to retrieve supported "
					"speeds, rc = 0x%x\n", rc);
		}
		rc = lpfc_sli4_refresh_params(phba);
		if (rc) {
			lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
					"3174 Unable to update pls support, "
					"rc x%x\n", rc);
		}
		vports = lpfc_create_vport_work_array(phba);
		if (vports != NULL) {
			for (i = 0; i <= phba->max_vports && vports[i] != NULL;
					i++) {
				shost = lpfc_shost_from_vport(vports[i]);
				lpfc_host_supported_speeds_set(shost);
			}
		}
		lpfc_destroy_vport_work_array(phba, vports);

		phba->sli4_hba.lnk_info.optic_state = status;
		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
				"3176 Port Name %c %s\n", port_name, message);
		break;
	case LPFC_SLI_EVENT_TYPE_REMOTE_DPORT:
		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
				"3192 Remote DPort Test Initiated - "
				"Event Data1:x%08x Event Data2: x%08x\n",
				acqe_sli->event_data1, acqe_sli->event_data2);
		break;
	case LPFC_SLI_EVENT_TYPE_PORT_PARAMS_CHG:
		/* Call FW to obtain active parms */
		lpfc_sli4_cgn_parm_chg_evt(phba);
		break;
	case LPFC_SLI_EVENT_TYPE_MISCONF_FAWWN:
		/* Misconfigured WWN. Reports that the SLI Port is configured
		 * to use FA-WWN, but the attached device doesn’t support it.
		 * No driver action is required.
		 * Event Data1 - N.A, Event Data2 - N.A
		 */
		lpfc_log_msg(phba, KERN_WARNING, LOG_SLI,
			     "2699 Misconfigured FA-WWN - Attached device does "
			     "not support FA-WWN\n");
		break;
	case LPFC_SLI_EVENT_TYPE_EEPROM_FAILURE:
		/* EEPROM failure. No driver action is required */
		lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
			     "2518 EEPROM failure - "
			     "Event Data1: x%08x Event Data2: x%08x\n",
			     acqe_sli->event_data1, acqe_sli->event_data2);
		break;
	case LPFC_SLI_EVENT_TYPE_CGN_SIGNAL:
		if (phba->cmf_active_mode == LPFC_CFG_OFF)
			break;
		cgn_signal = (struct lpfc_acqe_cgn_signal *)
					&acqe_sli->event_data1;
		phba->cgn_acqe_cnt++;

		cnt = bf_get(lpfc_warn_acqe, cgn_signal);
		atomic64_add(cnt, &phba->cgn_acqe_stat.warn);
		atomic64_add(cgn_signal->alarm_cnt, &phba->cgn_acqe_stat.alarm);

		/* no threshold for CMF, even 1 signal will trigger an event */

		/* Alarm overrides warning, so check that first */
		if (cgn_signal->alarm_cnt) {
			if (phba->cgn_reg_signal == EDC_CG_SIG_WARN_ALARM) {
				/* Keep track of alarm cnt for cgn_info */
				atomic_add(cgn_signal->alarm_cnt,
					   &phba->cgn_fabric_alarm_cnt);
				/* Keep track of alarm cnt for CMF_SYNC_WQE */
				atomic_add(cgn_signal->alarm_cnt,
					   &phba->cgn_sync_alarm_cnt);
			}
		} else if (cnt) {
			/* signal action needs to be taken */
			if (phba->cgn_reg_signal == EDC_CG_SIG_WARN_ONLY ||
			    phba->cgn_reg_signal == EDC_CG_SIG_WARN_ALARM) {
				/* Keep track of warning cnt for cgn_info */
				atomic_add(cnt, &phba->cgn_fabric_warn_cnt);
				/* Keep track of warning cnt for CMF_SYNC_WQE */
				atomic_add(cnt, &phba->cgn_sync_warn_cnt);
			}
		}
		break;
	default:
		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
				"3193 Unrecognized SLI event, type: 0x%x",
				evt_type);
		break;
	}
}

/**
 * lpfc_sli4_perform_vport_cvl - Perform clear virtual link on a vport
 * @vport: pointer to vport data structure.
 *
 * This routine is to perform Clear Virtual Link (CVL) on a vport in
 * response to a CVL event.
 *
 * Return the pointer to the ndlp with the vport if successful, otherwise
 * return NULL.
 **/
static struct lpfc_nodelist *
lpfc_sli4_perform_vport_cvl(struct lpfc_vport *vport)
{
	struct lpfc_nodelist *ndlp;
	struct Scsi_Host *shost;
	struct lpfc_hba *phba;

	if (!vport)
		return NULL;
	phba = vport->phba;
	if (!phba)
		return NULL;
	ndlp = lpfc_findnode_did(vport, Fabric_DID);
	if (!ndlp) {
		/* Cannot find existing Fabric ndlp, so allocate a new one */
		ndlp = lpfc_nlp_init(vport, Fabric_DID);
		if (!ndlp)
			return NULL;
		/* Set the node type */
		ndlp->nlp_type |= NLP_FABRIC;
		/* Put ndlp onto node list */
		lpfc_enqueue_node(vport, ndlp);
	}
	if ((phba->pport->port_state < LPFC_FLOGI) &&
		(phba->pport->port_state != LPFC_VPORT_FAILED))
		return NULL;
	/* If virtual link is not yet instantiated ignore CVL */
	if ((vport != phba->pport) && (vport->port_state < LPFC_FDISC)
		&& (vport->port_state != LPFC_VPORT_FAILED))
		return NULL;
	shost = lpfc_shost_from_vport(vport);
	if (!shost)
		return NULL;
	lpfc_linkdown_port(vport);
	lpfc_cleanup_pending_mbox(vport);
	spin_lock_irq(shost->host_lock);
	vport->fc_flag |= FC_VPORT_CVL_RCVD;
	spin_unlock_irq(shost->host_lock);

	return ndlp;
}

/**
 * lpfc_sli4_perform_all_vport_cvl - Perform clear virtual link on all vports
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is to perform Clear Virtual Link (CVL) on all vports in
 * response to a FCF dead event.
 **/
static void
lpfc_sli4_perform_all_vport_cvl(struct lpfc_hba *phba)
{
	struct lpfc_vport **vports;
	int i;

	vports = lpfc_create_vport_work_array(phba);
	if (vports)
		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++)
			lpfc_sli4_perform_vport_cvl(vports[i]);
	lpfc_destroy_vport_work_array(phba, vports);
}

/**
 * lpfc_sli4_async_fip_evt - Process the asynchronous FCoE FIP event
 * @phba: pointer to lpfc hba data structure.
 * @acqe_fip: pointer to the async fcoe completion queue entry.
 *
 * This routine is to handle the SLI4 asynchronous fcoe event.
 **/
static void
lpfc_sli4_async_fip_evt(struct lpfc_hba *phba,
			struct lpfc_acqe_fip *acqe_fip)
{
	uint8_t event_type = bf_get(lpfc_trailer_type, acqe_fip);
	int rc;
	struct lpfc_vport *vport;
	struct lpfc_nodelist *ndlp;
	int active_vlink_present;
	struct lpfc_vport **vports;
	int i;

	phba->fc_eventTag = acqe_fip->event_tag;
	phba->fcoe_eventtag = acqe_fip->event_tag;
	switch (event_type) {
	case LPFC_FIP_EVENT_TYPE_NEW_FCF:
	case LPFC_FIP_EVENT_TYPE_FCF_PARAM_MOD:
		if (event_type == LPFC_FIP_EVENT_TYPE_NEW_FCF)
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"2546 New FCF event, evt_tag:x%x, "
					"index:x%x\n",
					acqe_fip->event_tag,
					acqe_fip->index);
		else
			lpfc_printf_log(phba, KERN_WARNING, LOG_FIP |
					LOG_DISCOVERY,
					"2788 FCF param modified event, "
					"evt_tag:x%x, index:x%x\n",
					acqe_fip->event_tag,
					acqe_fip->index);
		if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
			/*
			 * During period of FCF discovery, read the FCF
			 * table record indexed by the event to update
			 * FCF roundrobin failover eligible FCF bmask.
			 */
			lpfc_printf_log(phba, KERN_INFO, LOG_FIP |
					LOG_DISCOVERY,
					"2779 Read FCF (x%x) for updating "
					"roundrobin FCF failover bmask\n",
					acqe_fip->index);
			rc = lpfc_sli4_read_fcf_rec(phba, acqe_fip->index);
		}

		/* If the FCF discovery is in progress, do nothing. */
		spin_lock_irq(&phba->hbalock);
		if (phba->hba_flag & FCF_TS_INPROG) {
			spin_unlock_irq(&phba->hbalock);
			break;
		}
		/* If fast FCF failover rescan event is pending, do nothing */
		if (phba->fcf.fcf_flag & (FCF_REDISC_EVT | FCF_REDISC_PEND)) {
			spin_unlock_irq(&phba->hbalock);
			break;
		}

		/* If the FCF has been in discovered state, do nothing. */
		if (phba->fcf.fcf_flag & FCF_SCAN_DONE) {
			spin_unlock_irq(&phba->hbalock);
			break;
		}
		spin_unlock_irq(&phba->hbalock);

		/* Otherwise, scan the entire FCF table and re-discover SAN */
		lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
				"2770 Start FCF table scan per async FCF "
				"event, evt_tag:x%x, index:x%x\n",
				acqe_fip->event_tag, acqe_fip->index);
		rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba,
						     LPFC_FCOE_FCF_GET_FIRST);
		if (rc)
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"2547 Issue FCF scan read FCF mailbox "
					"command failed (x%x)\n", rc);
		break;

	case LPFC_FIP_EVENT_TYPE_FCF_TABLE_FULL:
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2548 FCF Table full count 0x%x tag 0x%x\n",
				bf_get(lpfc_acqe_fip_fcf_count, acqe_fip),
				acqe_fip->event_tag);
		break;

	case LPFC_FIP_EVENT_TYPE_FCF_DEAD:
		phba->fcoe_cvl_eventtag = acqe_fip->event_tag;
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2549 FCF (x%x) disconnected from network, "
				 "tag:x%x\n", acqe_fip->index,
				 acqe_fip->event_tag);
		/*
		 * If we are in the middle of FCF failover process, clear
		 * the corresponding FCF bit in the roundrobin bitmap.
		 */
		spin_lock_irq(&phba->hbalock);
		if ((phba->fcf.fcf_flag & FCF_DISCOVERY) &&
		    (phba->fcf.current_rec.fcf_indx != acqe_fip->index)) {
			spin_unlock_irq(&phba->hbalock);
			/* Update FLOGI FCF failover eligible FCF bmask */
			lpfc_sli4_fcf_rr_index_clear(phba, acqe_fip->index);
			break;
		}
		spin_unlock_irq(&phba->hbalock);

		/* If the event is not for currently used fcf do nothing */
		if (phba->fcf.current_rec.fcf_indx != acqe_fip->index)
			break;

		/*
		 * Otherwise, request the port to rediscover the entire FCF
		 * table for a fast recovery from case that the current FCF
		 * is no longer valid as we are not in the middle of FCF
		 * failover process already.
		 */
		spin_lock_irq(&phba->hbalock);
		/* Mark the fast failover process in progress */
		phba->fcf.fcf_flag |= FCF_DEAD_DISC;
		spin_unlock_irq(&phba->hbalock);

		lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
				"2771 Start FCF fast failover process due to "
				"FCF DEAD event: evt_tag:x%x, fcf_index:x%x "
				"\n", acqe_fip->event_tag, acqe_fip->index);
		rc = lpfc_sli4_redisc_fcf_table(phba);
		if (rc) {
			lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
					LOG_TRACE_EVENT,
					"2772 Issue FCF rediscover mailbox "
					"command failed, fail through to FCF "
					"dead event\n");
			spin_lock_irq(&phba->hbalock);
			phba->fcf.fcf_flag &= ~FCF_DEAD_DISC;
			spin_unlock_irq(&phba->hbalock);
			/*
			 * Last resort will fail over by treating this
			 * as a link down to FCF registration.
			 */
			lpfc_sli4_fcf_dead_failthrough(phba);
		} else {
			/* Reset FCF roundrobin bmask for new discovery */
			lpfc_sli4_clear_fcf_rr_bmask(phba);
			/*
			 * Handling fast FCF failover to a DEAD FCF event is
			 * considered equalivant to receiving CVL to all vports.
			 */
			lpfc_sli4_perform_all_vport_cvl(phba);
		}
		break;
	case LPFC_FIP_EVENT_TYPE_CVL:
		phba->fcoe_cvl_eventtag = acqe_fip->event_tag;
		lpfc_printf_log(phba, KERN_ERR,
				LOG_TRACE_EVENT,
			"2718 Clear Virtual Link Received for VPI 0x%x"
			" tag 0x%x\n", acqe_fip->index, acqe_fip->event_tag);

		vport = lpfc_find_vport_by_vpid(phba,
						acqe_fip->index);
		ndlp = lpfc_sli4_perform_vport_cvl(vport);
		if (!ndlp)
			break;
		active_vlink_present = 0;

		vports = lpfc_create_vport_work_array(phba);
		if (vports) {
			for (i = 0; i <= phba->max_vports && vports[i] != NULL;
					i++) {
				if ((!(vports[i]->fc_flag &
					FC_VPORT_CVL_RCVD)) &&
					(vports[i]->port_state > LPFC_FDISC)) {
					active_vlink_present = 1;
					break;
				}
			}
			lpfc_destroy_vport_work_array(phba, vports);
		}

		/*
		 * Don't re-instantiate if vport is marked for deletion.
		 * If we are here first then vport_delete is going to wait
		 * for discovery to complete.
		 */
		if (!(vport->load_flag & FC_UNLOADING) &&
					active_vlink_present) {
			/*
			 * If there are other active VLinks present,
			 * re-instantiate the Vlink using FDISC.
			 */
			mod_timer(&ndlp->nlp_delayfunc,
				  jiffies + msecs_to_jiffies(1000));
			spin_lock_irq(&ndlp->lock);
			ndlp->nlp_flag |= NLP_DELAY_TMO;
			spin_unlock_irq(&ndlp->lock);
			ndlp->nlp_last_elscmd = ELS_CMD_FDISC;
			vport->port_state = LPFC_FDISC;
		} else {
			/*
			 * Otherwise, we request port to rediscover
			 * the entire FCF table for a fast recovery
			 * from possible case that the current FCF
			 * is no longer valid if we are not already
			 * in the FCF failover process.
			 */
			spin_lock_irq(&phba->hbalock);
			if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
				spin_unlock_irq(&phba->hbalock);
				break;
			}
			/* Mark the fast failover process in progress */
			phba->fcf.fcf_flag |= FCF_ACVL_DISC;
			spin_unlock_irq(&phba->hbalock);
			lpfc_printf_log(phba, KERN_INFO, LOG_FIP |
					LOG_DISCOVERY,
					"2773 Start FCF failover per CVL, "
					"evt_tag:x%x\n", acqe_fip->event_tag);
			rc = lpfc_sli4_redisc_fcf_table(phba);
			if (rc) {
				lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
						LOG_TRACE_EVENT,
						"2774 Issue FCF rediscover "
						"mailbox command failed, "
						"through to CVL event\n");
				spin_lock_irq(&phba->hbalock);
				phba->fcf.fcf_flag &= ~FCF_ACVL_DISC;
				spin_unlock_irq(&phba->hbalock);
				/*
				 * Last resort will be re-try on the
				 * the current registered FCF entry.
				 */
				lpfc_retry_pport_discovery(phba);
			} else
				/*
				 * Reset FCF roundrobin bmask for new
				 * discovery.
				 */
				lpfc_sli4_clear_fcf_rr_bmask(phba);
		}
		break;
	default:
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0288 Unknown FCoE event type 0x%x event tag "
				"0x%x\n", event_type, acqe_fip->event_tag);
		break;
	}
}

/**
 * lpfc_sli4_async_dcbx_evt - Process the asynchronous dcbx event
 * @phba: pointer to lpfc hba data structure.
 * @acqe_dcbx: pointer to the async dcbx completion queue entry.
 *
 * This routine is to handle the SLI4 asynchronous dcbx event.
 **/
static void
lpfc_sli4_async_dcbx_evt(struct lpfc_hba *phba,
			 struct lpfc_acqe_dcbx *acqe_dcbx)
{
	phba->fc_eventTag = acqe_dcbx->event_tag;
	lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
			"0290 The SLI4 DCBX asynchronous event is not "
			"handled yet\n");
}

/**
 * lpfc_sli4_async_grp5_evt - Process the asynchronous group5 event
 * @phba: pointer to lpfc hba data structure.
 * @acqe_grp5: pointer to the async grp5 completion queue entry.
 *
 * This routine is to handle the SLI4 asynchronous grp5 event. A grp5 event
 * is an asynchronous notified of a logical link speed change.  The Port
 * reports the logical link speed in units of 10Mbps.
 **/
static void
lpfc_sli4_async_grp5_evt(struct lpfc_hba *phba,
			 struct lpfc_acqe_grp5 *acqe_grp5)
{
	uint16_t prev_ll_spd;

	phba->fc_eventTag = acqe_grp5->event_tag;
	phba->fcoe_eventtag = acqe_grp5->event_tag;
	prev_ll_spd = phba->sli4_hba.link_state.logical_speed;
	phba->sli4_hba.link_state.logical_speed =
		(bf_get(lpfc_acqe_grp5_llink_spd, acqe_grp5)) * 10;
	lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
			"2789 GRP5 Async Event: Updating logical link speed "
			"from %dMbps to %dMbps\n", prev_ll_spd,
			phba->sli4_hba.link_state.logical_speed);
}

/**
 * lpfc_sli4_async_cmstat_evt - Process the asynchronous cmstat event
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is to handle the SLI4 asynchronous cmstat event. A cmstat event
 * is an asynchronous notification of a request to reset CM stats.
 **/
static void
lpfc_sli4_async_cmstat_evt(struct lpfc_hba *phba)
{
	if (!phba->cgn_i)
		return;
	lpfc_init_congestion_stat(phba);
}

/**
 * lpfc_cgn_params_val - Validate FW congestion parameters.
 * @phba: pointer to lpfc hba data structure.
 * @p_cfg_param: pointer to FW provided congestion parameters.
 *
 * This routine validates the congestion parameters passed
 * by the FW to the driver via an ACQE event.
 **/
static void
lpfc_cgn_params_val(struct lpfc_hba *phba, struct lpfc_cgn_param *p_cfg_param)
{
	spin_lock_irq(&phba->hbalock);

	if (!lpfc_rangecheck(p_cfg_param->cgn_param_mode, LPFC_CFG_OFF,
			     LPFC_CFG_MONITOR)) {
		lpfc_printf_log(phba, KERN_ERR, LOG_CGN_MGMT,
				"6225 CMF mode param out of range: %d\n",
				 p_cfg_param->cgn_param_mode);
		p_cfg_param->cgn_param_mode = LPFC_CFG_OFF;
	}

	spin_unlock_irq(&phba->hbalock);
}

/**
 * lpfc_cgn_params_parse - Process a FW cong parm change event
 * @phba: pointer to lpfc hba data structure.
 * @p_cgn_param: pointer to a data buffer with the FW cong params.
 * @len: the size of pdata in bytes.
 *
 * This routine validates the congestion management buffer signature
 * from the FW, validates the contents and makes corrections for
 * valid, in-range values.  If the signature magic is correct and
 * after parameter validation, the contents are copied to the driver's
 * @phba structure. If the magic is incorrect, an error message is
 * logged.
 **/
static void
lpfc_cgn_params_parse(struct lpfc_hba *phba,
		      struct lpfc_cgn_param *p_cgn_param, uint32_t len)
{
	struct lpfc_cgn_info *cp;
	uint32_t crc, oldmode;

	/* Make sure the FW has encoded the correct magic number to
	 * validate the congestion parameter in FW memory.
	 */
	if (p_cgn_param->cgn_param_magic == LPFC_CFG_PARAM_MAGIC_NUM) {
		lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT | LOG_INIT,
				"4668 FW cgn parm buffer data: "
				"magic 0x%x version %d mode %d "
				"level0 %d level1 %d "
				"level2 %d byte13 %d "
				"byte14 %d byte15 %d "
				"byte11 %d byte12 %d activeMode %d\n",
				p_cgn_param->cgn_param_magic,
				p_cgn_param->cgn_param_version,
				p_cgn_param->cgn_param_mode,
				p_cgn_param->cgn_param_level0,
				p_cgn_param->cgn_param_level1,
				p_cgn_param->cgn_param_level2,
				p_cgn_param->byte13,
				p_cgn_param->byte14,
				p_cgn_param->byte15,
				p_cgn_param->byte11,
				p_cgn_param->byte12,
				phba->cmf_active_mode);

		oldmode = phba->cmf_active_mode;

		/* Any parameters out of range are corrected to defaults
		 * by this routine.  No need to fail.
		 */
		lpfc_cgn_params_val(phba, p_cgn_param);

		/* Parameters are verified, move them into driver storage */
		spin_lock_irq(&phba->hbalock);
		memcpy(&phba->cgn_p, p_cgn_param,
		       sizeof(struct lpfc_cgn_param));

		/* Update parameters in congestion info buffer now */
		if (phba->cgn_i) {
			cp = (struct lpfc_cgn_info *)phba->cgn_i->virt;
			cp->cgn_info_mode = phba->cgn_p.cgn_param_mode;
			cp->cgn_info_level0 = phba->cgn_p.cgn_param_level0;
			cp->cgn_info_level1 = phba->cgn_p.cgn_param_level1;
			cp->cgn_info_level2 = phba->cgn_p.cgn_param_level2;
			crc = lpfc_cgn_calc_crc32(cp, LPFC_CGN_INFO_SZ,
						  LPFC_CGN_CRC32_SEED);
			cp->cgn_info_crc = cpu_to_le32(crc);
		}
		spin_unlock_irq(&phba->hbalock);

		phba->cmf_active_mode = phba->cgn_p.cgn_param_mode;

		switch (oldmode) {
		case LPFC_CFG_OFF:
			if (phba->cgn_p.cgn_param_mode != LPFC_CFG_OFF) {
				/* Turning CMF on */
				lpfc_cmf_start(phba);

				if (phba->link_state >= LPFC_LINK_UP) {
					phba->cgn_reg_fpin =
						phba->cgn_init_reg_fpin;
					phba->cgn_reg_signal =
						phba->cgn_init_reg_signal;
					lpfc_issue_els_edc(phba->pport, 0);
				}
			}
			break;
		case LPFC_CFG_MANAGED:
			switch (phba->cgn_p.cgn_param_mode) {
			case LPFC_CFG_OFF:
				/* Turning CMF off */
				lpfc_cmf_stop(phba);
				if (phba->link_state >= LPFC_LINK_UP)
					lpfc_issue_els_edc(phba->pport, 0);
				break;
			case LPFC_CFG_MONITOR:
				lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
						"4661 Switch from MANAGED to "
						"`MONITOR mode\n");
				phba->cmf_max_bytes_per_interval =
					phba->cmf_link_byte_count;

				/* Resume blocked IO - unblock on workqueue */
				queue_work(phba->wq,
					   &phba->unblock_request_work);
				break;
			}
			break;
		case LPFC_CFG_MONITOR:
			switch (phba->cgn_p.cgn_param_mode) {
			case LPFC_CFG_OFF:
				/* Turning CMF off */
				lpfc_cmf_stop(phba);
				if (phba->link_state >= LPFC_LINK_UP)
					lpfc_issue_els_edc(phba->pport, 0);
				break;
			case LPFC_CFG_MANAGED:
				lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
						"4662 Switch from MONITOR to "
						"MANAGED mode\n");
				lpfc_cmf_signal_init(phba);
				break;
			}
			break;
		}
	} else {
		lpfc_printf_log(phba, KERN_ERR, LOG_CGN_MGMT | LOG_INIT,
				"4669 FW cgn parm buf wrong magic 0x%x "
				"version %d\n", p_cgn_param->cgn_param_magic,
				p_cgn_param->cgn_param_version);
	}
}

/**
 * lpfc_sli4_cgn_params_read - Read and Validate FW congestion parameters.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine issues a read_object mailbox command to
 * get the congestion management parameters from the FW
 * parses it and updates the driver maintained values.
 *
 * Returns
 *  0     if the object was empty
 *  -Eval if an error was encountered
 *  Count if bytes were read from object
 **/
int
lpfc_sli4_cgn_params_read(struct lpfc_hba *phba)
{
	int ret = 0;
	struct lpfc_cgn_param *p_cgn_param = NULL;
	u32 *pdata = NULL;
	u32 len = 0;

	/* Find out if the FW has a new set of congestion parameters. */
	len = sizeof(struct lpfc_cgn_param);
	pdata = kzalloc(len, GFP_KERNEL);
	ret = lpfc_read_object(phba, (char *)LPFC_PORT_CFG_NAME,
			       pdata, len);

	/* 0 means no data.  A negative means error.  A positive means
	 * bytes were copied.
	 */
	if (!ret) {
		lpfc_printf_log(phba, KERN_ERR, LOG_CGN_MGMT | LOG_INIT,
				"4670 CGN RD OBJ returns no data\n");
		goto rd_obj_err;
	} else if (ret < 0) {
		/* Some error.  Just exit and return it to the caller.*/
		goto rd_obj_err;
	}

	lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT | LOG_INIT,
			"6234 READ CGN PARAMS Successful %d\n", len);

	/* Parse data pointer over len and update the phba congestion
	 * parameters with values passed back.  The receive rate values
	 * may have been altered in FW, but take no action here.
	 */
	p_cgn_param = (struct lpfc_cgn_param *)pdata;
	lpfc_cgn_params_parse(phba, p_cgn_param, len);

 rd_obj_err:
	kfree(pdata);
	return ret;
}

/**
 * lpfc_sli4_cgn_parm_chg_evt - Process a FW congestion param change event
 * @phba: pointer to lpfc hba data structure.
 *
 * The FW generated Async ACQE SLI event calls this routine when
 * the event type is an SLI Internal Port Event and the Event Code
 * indicates a change to the FW maintained congestion parameters.
 *
 * This routine executes a Read_Object mailbox call to obtain the
 * current congestion parameters maintained in FW and corrects
 * the driver's active congestion parameters.
 *
 * The acqe event is not passed because there is no further data
 * required.
 *
 * Returns nonzero error if event processing encountered an error.
 * Zero otherwise for success.
 **/
static int
lpfc_sli4_cgn_parm_chg_evt(struct lpfc_hba *phba)
{
	int ret = 0;

	if (!phba->sli4_hba.pc_sli4_params.cmf) {
		lpfc_printf_log(phba, KERN_ERR, LOG_CGN_MGMT | LOG_INIT,
				"4664 Cgn Evt when E2E off. Drop event\n");
		return -EACCES;
	}

	/* If the event is claiming an empty object, it's ok.  A write
	 * could have cleared it.  Only error is a negative return
	 * status.
	 */
	ret = lpfc_sli4_cgn_params_read(phba);
	if (ret < 0) {
		lpfc_printf_log(phba, KERN_ERR, LOG_CGN_MGMT | LOG_INIT,
				"4667 Error reading Cgn Params (%d)\n",
				ret);
	} else if (!ret) {
		lpfc_printf_log(phba, KERN_ERR, LOG_CGN_MGMT | LOG_INIT,
				"4673 CGN Event empty object.\n");
	}
	return ret;
}

/**
 * lpfc_sli4_async_event_proc - Process all the pending asynchronous event
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked by the worker thread to process all the pending
 * SLI4 asynchronous events.
 **/
void lpfc_sli4_async_event_proc(struct lpfc_hba *phba)
{
	struct lpfc_cq_event *cq_event;
	unsigned long iflags;

	/* First, declare the async event has been handled */
	spin_lock_irqsave(&phba->hbalock, iflags);
	phba->hba_flag &= ~ASYNC_EVENT;
	spin_unlock_irqrestore(&phba->hbalock, iflags);

	/* Now, handle all the async events */
	spin_lock_irqsave(&phba->sli4_hba.asynce_list_lock, iflags);
	while (!list_empty(&phba->sli4_hba.sp_asynce_work_queue)) {
		list_remove_head(&phba->sli4_hba.sp_asynce_work_queue,
				 cq_event, struct lpfc_cq_event, list);
		spin_unlock_irqrestore(&phba->sli4_hba.asynce_list_lock,
				       iflags);

		/* Process the asynchronous event */
		switch (bf_get(lpfc_trailer_code, &cq_event->cqe.mcqe_cmpl)) {
		case LPFC_TRAILER_CODE_LINK:
			lpfc_sli4_async_link_evt(phba,
						 &cq_event->cqe.acqe_link);
			break;
		case LPFC_TRAILER_CODE_FCOE:
			lpfc_sli4_async_fip_evt(phba, &cq_event->cqe.acqe_fip);
			break;
		case LPFC_TRAILER_CODE_DCBX:
			lpfc_sli4_async_dcbx_evt(phba,
						 &cq_event->cqe.acqe_dcbx);
			break;
		case LPFC_TRAILER_CODE_GRP5:
			lpfc_sli4_async_grp5_evt(phba,
						 &cq_event->cqe.acqe_grp5);
			break;
		case LPFC_TRAILER_CODE_FC:
			lpfc_sli4_async_fc_evt(phba, &cq_event->cqe.acqe_fc);
			break;
		case LPFC_TRAILER_CODE_SLI:
			lpfc_sli4_async_sli_evt(phba, &cq_event->cqe.acqe_sli);
			break;
		case LPFC_TRAILER_CODE_CMSTAT:
			lpfc_sli4_async_cmstat_evt(phba);
			break;
		default:
			lpfc_printf_log(phba, KERN_ERR,
					LOG_TRACE_EVENT,
					"1804 Invalid asynchronous event code: "
					"x%x\n", bf_get(lpfc_trailer_code,
					&cq_event->cqe.mcqe_cmpl));
			break;
		}

		/* Free the completion event processed to the free pool */
		lpfc_sli4_cq_event_release(phba, cq_event);
		spin_lock_irqsave(&phba->sli4_hba.asynce_list_lock, iflags);
	}
	spin_unlock_irqrestore(&phba->sli4_hba.asynce_list_lock, iflags);
}

/**
 * lpfc_sli4_fcf_redisc_event_proc - Process fcf table rediscovery event
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked by the worker thread to process FCF table
 * rediscovery pending completion event.
 **/
void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *phba)
{
	int rc;

	spin_lock_irq(&phba->hbalock);
	/* Clear FCF rediscovery timeout event */
	phba->fcf.fcf_flag &= ~FCF_REDISC_EVT;
	/* Clear driver fast failover FCF record flag */
	phba->fcf.failover_rec.flag = 0;
	/* Set state for FCF fast failover */
	phba->fcf.fcf_flag |= FCF_REDISC_FOV;
	spin_unlock_irq(&phba->hbalock);

	/* Scan FCF table from the first entry to re-discover SAN */
	lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
			"2777 Start post-quiescent FCF table scan\n");
	rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST);
	if (rc)
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2747 Issue FCF scan read FCF mailbox "
				"command failed 0x%x\n", rc);
}

/**
 * lpfc_api_table_setup - Set up per hba pci-device group func api jump table
 * @phba: pointer to lpfc hba data structure.
 * @dev_grp: The HBA PCI-Device group number.
 *
 * This routine is invoked to set up the per HBA PCI-Device group function
 * API jump table entries.
 *
 * Return: 0 if success, otherwise -ENODEV
 **/
int
lpfc_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp)
{
	int rc;

	/* Set up lpfc PCI-device group */
	phba->pci_dev_grp = dev_grp;

	/* The LPFC_PCI_DEV_OC uses SLI4 */
	if (dev_grp == LPFC_PCI_DEV_OC)
		phba->sli_rev = LPFC_SLI_REV4;

	/* Set up device INIT API function jump table */
	rc = lpfc_init_api_table_setup(phba, dev_grp);
	if (rc)
		return -ENODEV;
	/* Set up SCSI API function jump table */
	rc = lpfc_scsi_api_table_setup(phba, dev_grp);
	if (rc)
		return -ENODEV;
	/* Set up SLI API function jump table */
	rc = lpfc_sli_api_table_setup(phba, dev_grp);
	if (rc)
		return -ENODEV;
	/* Set up MBOX API function jump table */
	rc = lpfc_mbox_api_table_setup(phba, dev_grp);
	if (rc)
		return -ENODEV;

	return 0;
}

/**
 * lpfc_log_intr_mode - Log the active interrupt mode
 * @phba: pointer to lpfc hba data structure.
 * @intr_mode: active interrupt mode adopted.
 *
 * This routine it invoked to log the currently used active interrupt mode
 * to the device.
 **/
static void lpfc_log_intr_mode(struct lpfc_hba *phba, uint32_t intr_mode)
{
	switch (intr_mode) {
	case 0:
		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"0470 Enable INTx interrupt mode.\n");
		break;
	case 1:
		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"0481 Enabled MSI interrupt mode.\n");
		break;
	case 2:
		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"0480 Enabled MSI-X interrupt mode.\n");
		break;
	default:
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0482 Illegal interrupt mode.\n");
		break;
	}
	return;
}

/**
 * lpfc_enable_pci_dev - Enable a generic PCI device.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to enable the PCI device that is common to all
 * PCI devices.
 *
 * Return codes
 * 	0 - successful
 * 	other values - error
 **/
static int
lpfc_enable_pci_dev(struct lpfc_hba *phba)
{
	struct pci_dev *pdev;

	/* Obtain PCI device reference */
	if (!phba->pcidev)
		goto out_error;
	else
		pdev = phba->pcidev;
	/* Enable PCI device */
	if (pci_enable_device_mem(pdev))
		goto out_error;
	/* Request PCI resource for the device */
	if (pci_request_mem_regions(pdev, LPFC_DRIVER_NAME))
		goto out_disable_device;
	/* Set up device as PCI master and save state for EEH */
	pci_set_master(pdev);
	pci_try_set_mwi(pdev);
	pci_save_state(pdev);

	/* PCIe EEH recovery on powerpc platforms needs fundamental reset */
	if (pci_is_pcie(pdev))
		pdev->needs_freset = 1;

	return 0;

out_disable_device:
	pci_disable_device(pdev);
out_error:
	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
			"1401 Failed to enable pci device\n");
	return -ENODEV;
}

/**
 * lpfc_disable_pci_dev - Disable a generic PCI device.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to disable the PCI device that is common to all
 * PCI devices.
 **/
static void
lpfc_disable_pci_dev(struct lpfc_hba *phba)
{
	struct pci_dev *pdev;

	/* Obtain PCI device reference */
	if (!phba->pcidev)
		return;
	else
		pdev = phba->pcidev;
	/* Release PCI resource and disable PCI device */
	pci_release_mem_regions(pdev);
	pci_disable_device(pdev);

	return;
}

/**
 * lpfc_reset_hba - Reset a hba
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to reset a hba device. It brings the HBA
 * offline, performs a board restart, and then brings the board back
 * online. The lpfc_offline calls lpfc_sli_hba_down which will clean up
 * on outstanding mailbox commands.
 **/
void
lpfc_reset_hba(struct lpfc_hba *phba)
{
	/* If resets are disabled then set error state and return. */
	if (!phba->cfg_enable_hba_reset) {
		phba->link_state = LPFC_HBA_ERROR;
		return;
	}

	/* If not LPFC_SLI_ACTIVE, force all IO to be flushed */
	if (phba->sli.sli_flag & LPFC_SLI_ACTIVE) {
		lpfc_offline_prep(phba, LPFC_MBX_WAIT);
	} else {
		lpfc_offline_prep(phba, LPFC_MBX_NO_WAIT);
		lpfc_sli_flush_io_rings(phba);
	}
	lpfc_offline(phba);
	lpfc_sli_brdrestart(phba);
	lpfc_online(phba);
	lpfc_unblock_mgmt_io(phba);
}

/**
 * lpfc_sli_sriov_nr_virtfn_get - Get the number of sr-iov virtual functions
 * @phba: pointer to lpfc hba data structure.
 *
 * This function enables the PCI SR-IOV virtual functions to a physical
 * function. It invokes the PCI SR-IOV api with the @nr_vfn provided to
 * enable the number of virtual functions to the physical function. As
 * not all devices support SR-IOV, the return code from the pci_enable_sriov()
 * API call does not considered as an error condition for most of the device.
 **/
uint16_t
lpfc_sli_sriov_nr_virtfn_get(struct lpfc_hba *phba)
{
	struct pci_dev *pdev = phba->pcidev;
	uint16_t nr_virtfn;
	int pos;

	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
	if (pos == 0)
		return 0;

	pci_read_config_word(pdev, pos + PCI_SRIOV_TOTAL_VF, &nr_virtfn);
	return nr_virtfn;
}

/**
 * lpfc_sli_probe_sriov_nr_virtfn - Enable a number of sr-iov virtual functions
 * @phba: pointer to lpfc hba data structure.
 * @nr_vfn: number of virtual functions to be enabled.
 *
 * This function enables the PCI SR-IOV virtual functions to a physical
 * function. It invokes the PCI SR-IOV api with the @nr_vfn provided to
 * enable the number of virtual functions to the physical function. As
 * not all devices support SR-IOV, the return code from the pci_enable_sriov()
 * API call does not considered as an error condition for most of the device.
 **/
int
lpfc_sli_probe_sriov_nr_virtfn(struct lpfc_hba *phba, int nr_vfn)
{
	struct pci_dev *pdev = phba->pcidev;
	uint16_t max_nr_vfn;
	int rc;

	max_nr_vfn = lpfc_sli_sriov_nr_virtfn_get(phba);
	if (nr_vfn > max_nr_vfn) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3057 Requested vfs (%d) greater than "
				"supported vfs (%d)", nr_vfn, max_nr_vfn);
		return -EINVAL;
	}

	rc = pci_enable_sriov(pdev, nr_vfn);
	if (rc) {
		lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
				"2806 Failed to enable sriov on this device "
				"with vfn number nr_vf:%d, rc:%d\n",
				nr_vfn, rc);
	} else
		lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
				"2807 Successful enable sriov on this device "
				"with vfn number nr_vf:%d\n", nr_vfn);
	return rc;
}

static void
lpfc_unblock_requests_work(struct work_struct *work)
{
	struct lpfc_hba *phba = container_of(work, struct lpfc_hba,
					     unblock_request_work);

	lpfc_unblock_requests(phba);
}

/**
 * lpfc_setup_driver_resource_phase1 - Phase1 etup driver internal resources.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to set up the driver internal resources before the
 * device specific resource setup to support the HBA device it attached to.
 *
 * Return codes
 *	0 - successful
 *	other values - error
 **/
static int
lpfc_setup_driver_resource_phase1(struct lpfc_hba *phba)
{
	struct lpfc_sli *psli = &phba->sli;

	/*
	 * Driver resources common to all SLI revisions
	 */
	atomic_set(&phba->fast_event_count, 0);
	atomic_set(&phba->dbg_log_idx, 0);
	atomic_set(&phba->dbg_log_cnt, 0);
	atomic_set(&phba->dbg_log_dmping, 0);
	spin_lock_init(&phba->hbalock);

	/* Initialize port_list spinlock */
	spin_lock_init(&phba->port_list_lock);
	INIT_LIST_HEAD(&phba->port_list);

	INIT_LIST_HEAD(&phba->work_list);
	init_waitqueue_head(&phba->wait_4_mlo_m_q);

	/* Initialize the wait queue head for the kernel thread */
	init_waitqueue_head(&phba->work_waitq);

	lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
			"1403 Protocols supported %s %s %s\n",
			((phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP) ?
				"SCSI" : " "),
			((phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) ?
				"NVME" : " "),
			(phba->nvmet_support ? "NVMET" : " "));

	/* Initialize the IO buffer list used by driver for SLI3 SCSI */
	spin_lock_init(&phba->scsi_buf_list_get_lock);
	INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list_get);
	spin_lock_init(&phba->scsi_buf_list_put_lock);
	INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list_put);

	/* Initialize the fabric iocb list */
	INIT_LIST_HEAD(&phba->fabric_iocb_list);

	/* Initialize list to save ELS buffers */
	INIT_LIST_HEAD(&phba->elsbuf);

	/* Initialize FCF connection rec list */
	INIT_LIST_HEAD(&phba->fcf_conn_rec_list);

	/* Initialize OAS configuration list */
	spin_lock_init(&phba->devicelock);
	INIT_LIST_HEAD(&phba->luns);

	/* MBOX heartbeat timer */
	timer_setup(&psli->mbox_tmo, lpfc_mbox_timeout, 0);
	/* Fabric block timer */
	timer_setup(&phba->fabric_block_timer, lpfc_fabric_block_timeout, 0);
	/* EA polling mode timer */
	timer_setup(&phba->eratt_poll, lpfc_poll_eratt, 0);
	/* Heartbeat timer */
	timer_setup(&phba->hb_tmofunc, lpfc_hb_timeout, 0);

	INIT_DELAYED_WORK(&phba->eq_delay_work, lpfc_hb_eq_delay_work);

	INIT_DELAYED_WORK(&phba->idle_stat_delay_work,
			  lpfc_idle_stat_delay_work);
	INIT_WORK(&phba->unblock_request_work, lpfc_unblock_requests_work);
	return 0;
}

/**
 * lpfc_sli_driver_resource_setup - Setup driver internal resources for SLI3 dev
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to set up the driver internal resources specific to
 * support the SLI-3 HBA device it attached to.
 *
 * Return codes
 * 0 - successful
 * other values - error
 **/
static int
lpfc_sli_driver_resource_setup(struct lpfc_hba *phba)
{
	int rc, entry_sz;

	/*
	 * Initialize timers used by driver
	 */

	/* FCP polling mode timer */
	timer_setup(&phba->fcp_poll_timer, lpfc_poll_timeout, 0);

	/* Host attention work mask setup */
	phba->work_ha_mask = (HA_ERATT | HA_MBATT | HA_LATT);
	phba->work_ha_mask |= (HA_RXMASK << (LPFC_ELS_RING * 4));

	/* Get all the module params for configuring this host */
	lpfc_get_cfgparam(phba);
	/* Set up phase-1 common device driver resources */

	rc = lpfc_setup_driver_resource_phase1(phba);
	if (rc)
		return -ENODEV;

	if (phba->pcidev->device == PCI_DEVICE_ID_HORNET) {
		phba->menlo_flag |= HBA_MENLO_SUPPORT;
		/* check for menlo minimum sg count */
		if (phba->cfg_sg_seg_cnt < LPFC_DEFAULT_MENLO_SG_SEG_CNT)
			phba->cfg_sg_seg_cnt = LPFC_DEFAULT_MENLO_SG_SEG_CNT;
	}

	if (!phba->sli.sli3_ring)
		phba->sli.sli3_ring = kcalloc(LPFC_SLI3_MAX_RING,
					      sizeof(struct lpfc_sli_ring),
					      GFP_KERNEL);
	if (!phba->sli.sli3_ring)
		return -ENOMEM;

	/*
	 * Since lpfc_sg_seg_cnt is module parameter, the sg_dma_buf_size
	 * used to create the sg_dma_buf_pool must be dynamically calculated.
	 */

	if (phba->sli_rev == LPFC_SLI_REV4)
		entry_sz = sizeof(struct sli4_sge);
	else
		entry_sz = sizeof(struct ulp_bde64);

	/* There are going to be 2 reserved BDEs: 1 FCP cmnd + 1 FCP rsp */
	if (phba->cfg_enable_bg) {
		/*
		 * The scsi_buf for a T10-DIF I/O will hold the FCP cmnd,
		 * the FCP rsp, and a BDE for each. Sice we have no control
		 * over how many protection data segments the SCSI Layer
		 * will hand us (ie: there could be one for every block
		 * in the IO), we just allocate enough BDEs to accomidate
		 * our max amount and we need to limit lpfc_sg_seg_cnt to
		 * minimize the risk of running out.
		 */
		phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) +
			sizeof(struct fcp_rsp) +
			(LPFC_MAX_SG_SEG_CNT * entry_sz);

		if (phba->cfg_sg_seg_cnt > LPFC_MAX_SG_SEG_CNT_DIF)
			phba->cfg_sg_seg_cnt = LPFC_MAX_SG_SEG_CNT_DIF;

		/* Total BDEs in BPL for scsi_sg_list and scsi_sg_prot_list */
		phba->cfg_total_seg_cnt = LPFC_MAX_SG_SEG_CNT;
	} else {
		/*
		 * The scsi_buf for a regular I/O will hold the FCP cmnd,
		 * the FCP rsp, a BDE for each, and a BDE for up to
		 * cfg_sg_seg_cnt data segments.
		 */
		phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) +
			sizeof(struct fcp_rsp) +
			((phba->cfg_sg_seg_cnt + 2) * entry_sz);

		/* Total BDEs in BPL for scsi_sg_list */
		phba->cfg_total_seg_cnt = phba->cfg_sg_seg_cnt + 2;
	}

	lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_FCP,
			"9088 INIT sg_tablesize:%d dmabuf_size:%d total_bde:%d\n",
			phba->cfg_sg_seg_cnt, phba->cfg_sg_dma_buf_size,
			phba->cfg_total_seg_cnt);

	phba->max_vpi = LPFC_MAX_VPI;
	/* This will be set to correct value after config_port mbox */
	phba->max_vports = 0;

	/*
	 * Initialize the SLI Layer to run with lpfc HBAs.
	 */
	lpfc_sli_setup(phba);
	lpfc_sli_queue_init(phba);

	/* Allocate device driver memory */
	if (lpfc_mem_alloc(phba, BPL_ALIGN_SZ))
		return -ENOMEM;

	phba->lpfc_sg_dma_buf_pool =
		dma_pool_create("lpfc_sg_dma_buf_pool",
				&phba->pcidev->dev, phba->cfg_sg_dma_buf_size,
				BPL_ALIGN_SZ, 0);

	if (!phba->lpfc_sg_dma_buf_pool)
		goto fail_free_mem;

	phba->lpfc_cmd_rsp_buf_pool =
			dma_pool_create("lpfc_cmd_rsp_buf_pool",
					&phba->pcidev->dev,
					sizeof(struct fcp_cmnd) +
					sizeof(struct fcp_rsp),
					BPL_ALIGN_SZ, 0);

	if (!phba->lpfc_cmd_rsp_buf_pool)
		goto fail_free_dma_buf_pool;

	/*
	 * Enable sr-iov virtual functions if supported and configured
	 * through the module parameter.
	 */
	if (phba->cfg_sriov_nr_virtfn > 0) {
		rc = lpfc_sli_probe_sriov_nr_virtfn(phba,
						 phba->cfg_sriov_nr_virtfn);
		if (rc) {
			lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
					"2808 Requested number of SR-IOV "
					"virtual functions (%d) is not "
					"supported\n",
					phba->cfg_sriov_nr_virtfn);
			phba->cfg_sriov_nr_virtfn = 0;
		}
	}

	return 0;

fail_free_dma_buf_pool:
	dma_pool_destroy(phba->lpfc_sg_dma_buf_pool);
	phba->lpfc_sg_dma_buf_pool = NULL;
fail_free_mem:
	lpfc_mem_free(phba);
	return -ENOMEM;
}

/**
 * lpfc_sli_driver_resource_unset - Unset drvr internal resources for SLI3 dev
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to unset the driver internal resources set up
 * specific for supporting the SLI-3 HBA device it attached to.
 **/
static void
lpfc_sli_driver_resource_unset(struct lpfc_hba *phba)
{
	/* Free device driver memory allocated */
	lpfc_mem_free_all(phba);

	return;
}

/**
 * lpfc_sli4_driver_resource_setup - Setup drvr internal resources for SLI4 dev
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to set up the driver internal resources specific to
 * support the SLI-4 HBA device it attached to.
 *
 * Return codes
 * 	0 - successful
 * 	other values - error
 **/
static int
lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
{
	LPFC_MBOXQ_t *mboxq;
	MAILBOX_t *mb;
	int rc, i, max_buf_size;
	int longs;
	int extra;
	uint64_t wwn;
	u32 if_type;
	u32 if_fam;

	phba->sli4_hba.num_present_cpu = lpfc_present_cpu;
	phba->sli4_hba.num_possible_cpu = cpumask_last(cpu_possible_mask) + 1;
	phba->sli4_hba.curr_disp_cpu = 0;

	/* Get all the module params for configuring this host */
	lpfc_get_cfgparam(phba);

	/* Set up phase-1 common device driver resources */
	rc = lpfc_setup_driver_resource_phase1(phba);
	if (rc)
		return -ENODEV;

	/* Before proceed, wait for POST done and device ready */
	rc = lpfc_sli4_post_status_check(phba);
	if (rc)
		return -ENODEV;

	/* Allocate all driver workqueues here */

	/* The lpfc_wq workqueue for deferred irq use */
	phba->wq = alloc_workqueue("lpfc_wq", WQ_MEM_RECLAIM, 0);

	/*
	 * Initialize timers used by driver
	 */

	timer_setup(&phba->rrq_tmr, lpfc_rrq_timeout, 0);

	/* FCF rediscover timer */
	timer_setup(&phba->fcf.redisc_wait, lpfc_sli4_fcf_redisc_wait_tmo, 0);

	/* CMF congestion timer */
	hrtimer_init(&phba->cmf_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	phba->cmf_timer.function = lpfc_cmf_timer;

	/*
	 * Control structure for handling external multi-buffer mailbox
	 * command pass-through.
	 */
	memset((uint8_t *)&phba->mbox_ext_buf_ctx, 0,
		sizeof(struct lpfc_mbox_ext_buf_ctx));
	INIT_LIST_HEAD(&phba->mbox_ext_buf_ctx.ext_dmabuf_list);

	phba->max_vpi = LPFC_MAX_VPI;

	/* This will be set to correct value after the read_config mbox */
	phba->max_vports = 0;

	/* Program the default value of vlan_id and fc_map */
	phba->valid_vlan = 0;
	phba->fc_map[0] = LPFC_FCOE_FCF_MAP0;
	phba->fc_map[1] = LPFC_FCOE_FCF_MAP1;
	phba->fc_map[2] = LPFC_FCOE_FCF_MAP2;

	/*
	 * For SLI4, instead of using ring 0 (LPFC_FCP_RING) for FCP commands
	 * we will associate a new ring, for each EQ/CQ/WQ tuple.
	 * The WQ create will allocate the ring.
	 */

	/* Initialize buffer queue management fields */
	INIT_LIST_HEAD(&phba->hbqs[LPFC_ELS_HBQ].hbq_buffer_list);
	phba->hbqs[LPFC_ELS_HBQ].hbq_alloc_buffer = lpfc_sli4_rb_alloc;
	phba->hbqs[LPFC_ELS_HBQ].hbq_free_buffer = lpfc_sli4_rb_free;

	/* for VMID idle timeout if VMID is enabled */
	if (lpfc_is_vmid_enabled(phba))
		timer_setup(&phba->inactive_vmid_poll, lpfc_vmid_poll, 0);

	/*
	 * Initialize the SLI Layer to run with lpfc SLI4 HBAs.
	 */
	/* Initialize the Abort buffer list used by driver */
	spin_lock_init(&phba->sli4_hba.abts_io_buf_list_lock);
	INIT_LIST_HEAD(&phba->sli4_hba.lpfc_abts_io_buf_list);

	if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
		/* Initialize the Abort nvme buffer list used by driver */
		spin_lock_init(&phba->sli4_hba.abts_nvmet_buf_list_lock);
		INIT_LIST_HEAD(&phba->sli4_hba.lpfc_abts_nvmet_ctx_list);
		INIT_LIST_HEAD(&phba->sli4_hba.lpfc_nvmet_io_wait_list);
		spin_lock_init(&phba->sli4_hba.t_active_list_lock);
		INIT_LIST_HEAD(&phba->sli4_hba.t_active_ctx_list);
	}

	/* This abort list used by worker thread */
	spin_lock_init(&phba->sli4_hba.sgl_list_lock);
	spin_lock_init(&phba->sli4_hba.nvmet_io_wait_lock);
	spin_lock_init(&phba->sli4_hba.asynce_list_lock);
	spin_lock_init(&phba->sli4_hba.els_xri_abrt_list_lock);

	/*
	 * Initialize driver internal slow-path work queues
	 */

	/* Driver internel slow-path CQ Event pool */
	INIT_LIST_HEAD(&phba->sli4_hba.sp_cqe_event_pool);
	/* Response IOCB work queue list */
	INIT_LIST_HEAD(&phba->sli4_hba.sp_queue_event);
	/* Asynchronous event CQ Event work queue list */
	INIT_LIST_HEAD(&phba->sli4_hba.sp_asynce_work_queue);
	/* Slow-path XRI aborted CQ Event work queue list */
	INIT_LIST_HEAD(&phba->sli4_hba.sp_els_xri_aborted_work_queue);
	/* Receive queue CQ Event work queue list */
	INIT_LIST_HEAD(&phba->sli4_hba.sp_unsol_work_queue);

	/* Initialize extent block lists. */
	INIT_LIST_HEAD(&phba->sli4_hba.lpfc_rpi_blk_list);
	INIT_LIST_HEAD(&phba->sli4_hba.lpfc_xri_blk_list);
	INIT_LIST_HEAD(&phba->sli4_hba.lpfc_vfi_blk_list);
	INIT_LIST_HEAD(&phba->lpfc_vpi_blk_list);

	/* Initialize mboxq lists. If the early init routines fail
	 * these lists need to be correctly initialized.
	 */
	INIT_LIST_HEAD(&phba->sli.mboxq);
	INIT_LIST_HEAD(&phba->sli.mboxq_cmpl);

	/* initialize optic_state to 0xFF */
	phba->sli4_hba.lnk_info.optic_state = 0xff;

	/* Allocate device driver memory */
	rc = lpfc_mem_alloc(phba, SGL_ALIGN_SZ);
	if (rc)
		return -ENOMEM;

	/* IF Type 2 ports get initialized now. */
	if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) >=
	    LPFC_SLI_INTF_IF_TYPE_2) {
		rc = lpfc_pci_function_reset(phba);
		if (unlikely(rc)) {
			rc = -ENODEV;
			goto out_free_mem;
		}
		phba->temp_sensor_support = 1;
	}

	/* Create the bootstrap mailbox command */
	rc = lpfc_create_bootstrap_mbox(phba);
	if (unlikely(rc))
		goto out_free_mem;

	/* Set up the host's endian order with the device. */
	rc = lpfc_setup_endian_order(phba);
	if (unlikely(rc))
		goto out_free_bsmbx;

	/* Set up the hba's configuration parameters. */
	rc = lpfc_sli4_read_config(phba);
	if (unlikely(rc))
		goto out_free_bsmbx;
	rc = lpfc_mem_alloc_active_rrq_pool_s4(phba);
	if (unlikely(rc))
		goto out_free_bsmbx;

	/* IF Type 0 ports get initialized now. */
	if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
	    LPFC_SLI_INTF_IF_TYPE_0) {
		rc = lpfc_pci_function_reset(phba);
		if (unlikely(rc))
			goto out_free_bsmbx;
	}

	mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
						       GFP_KERNEL);
	if (!mboxq) {
		rc = -ENOMEM;
		goto out_free_bsmbx;
	}

	/* Check for NVMET being configured */
	phba->nvmet_support = 0;
	if (lpfc_enable_nvmet_cnt) {

		/* First get WWN of HBA instance */
		lpfc_read_nv(phba, mboxq);
		rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
		if (rc != MBX_SUCCESS) {
			lpfc_printf_log(phba, KERN_ERR,
					LOG_TRACE_EVENT,
					"6016 Mailbox failed , mbxCmd x%x "
					"READ_NV, mbxStatus x%x\n",
					bf_get(lpfc_mqe_command, &mboxq->u.mqe),
					bf_get(lpfc_mqe_status, &mboxq->u.mqe));
			mempool_free(mboxq, phba->mbox_mem_pool);
			rc = -EIO;
			goto out_free_bsmbx;
		}
		mb = &mboxq->u.mb;
		memcpy(&wwn, (char *)mb->un.varRDnvp.nodename,
		       sizeof(uint64_t));
		wwn = cpu_to_be64(wwn);
		phba->sli4_hba.wwnn.u.name = wwn;
		memcpy(&wwn, (char *)mb->un.varRDnvp.portname,
		       sizeof(uint64_t));
		/* wwn is WWPN of HBA instance */
		wwn = cpu_to_be64(wwn);
		phba->sli4_hba.wwpn.u.name = wwn;

		/* Check to see if it matches any module parameter */
		for (i = 0; i < lpfc_enable_nvmet_cnt; i++) {
			if (wwn == lpfc_enable_nvmet[i]) {
#if (IS_ENABLED(CONFIG_NVME_TARGET_FC))
				if (lpfc_nvmet_mem_alloc(phba))
					break;

				phba->nvmet_support = 1; /* a match */

				lpfc_printf_log(phba, KERN_ERR,
						LOG_TRACE_EVENT,
						"6017 NVME Target %016llx\n",
						wwn);
#else
				lpfc_printf_log(phba, KERN_ERR,
						LOG_TRACE_EVENT,
						"6021 Can't enable NVME Target."
						" NVME_TARGET_FC infrastructure"
						" is not in kernel\n");
#endif
				/* Not supported for NVMET */
				phba->cfg_xri_rebalancing = 0;
				if (phba->irq_chann_mode == NHT_MODE) {
					phba->cfg_irq_chann =
						phba->sli4_hba.num_present_cpu;
					phba->cfg_hdw_queue =
						phba->sli4_hba.num_present_cpu;
					phba->irq_chann_mode = NORMAL_MODE;
				}
				break;
			}
		}
	}

	lpfc_nvme_mod_param_dep(phba);

	/*
	 * Get sli4 parameters that override parameters from Port capabilities.
	 * If this call fails, it isn't critical unless the SLI4 parameters come
	 * back in conflict.
	 */
	rc = lpfc_get_sli4_parameters(phba, mboxq);
	if (rc) {
		if_type = bf_get(lpfc_sli_intf_if_type,
				 &phba->sli4_hba.sli_intf);
		if_fam = bf_get(lpfc_sli_intf_sli_family,
				&phba->sli4_hba.sli_intf);
		if (phba->sli4_hba.extents_in_use &&
		    phba->sli4_hba.rpi_hdrs_in_use) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"2999 Unsupported SLI4 Parameters "
					"Extents and RPI headers enabled.\n");
			if (if_type == LPFC_SLI_INTF_IF_TYPE_0 &&
			    if_fam ==  LPFC_SLI_INTF_FAMILY_BE2) {
				mempool_free(mboxq, phba->mbox_mem_pool);
				rc = -EIO;
				goto out_free_bsmbx;
			}
		}
		if (!(if_type == LPFC_SLI_INTF_IF_TYPE_0 &&
		      if_fam == LPFC_SLI_INTF_FAMILY_BE2)) {
			mempool_free(mboxq, phba->mbox_mem_pool);
			rc = -EIO;
			goto out_free_bsmbx;
		}
	}

	/*
	 * 1 for cmd, 1 for rsp, NVME adds an extra one
	 * for boundary conditions in its max_sgl_segment template.
	 */
	extra = 2;
	if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME)
		extra++;

	/*
	 * It doesn't matter what family our adapter is in, we are
	 * limited to 2 Pages, 512 SGEs, for our SGL.
	 * There are going to be 2 reserved SGEs: 1 FCP cmnd + 1 FCP rsp
	 */
	max_buf_size = (2 * SLI4_PAGE_SIZE);

	/*
	 * Since lpfc_sg_seg_cnt is module param, the sg_dma_buf_size
	 * used to create the sg_dma_buf_pool must be calculated.
	 */
	if (phba->sli3_options & LPFC_SLI3_BG_ENABLED) {
		/* Both cfg_enable_bg and cfg_external_dif code paths */

		/*
		 * The scsi_buf for a T10-DIF I/O holds the FCP cmnd,
		 * the FCP rsp, and a SGE. Sice we have no control
		 * over how many protection segments the SCSI Layer
		 * will hand us (ie: there could be one for every block
		 * in the IO), just allocate enough SGEs to accomidate
		 * our max amount and we need to limit lpfc_sg_seg_cnt
		 * to minimize the risk of running out.
		 */
		phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) +
				sizeof(struct fcp_rsp) + max_buf_size;

		/* Total SGEs for scsi_sg_list and scsi_sg_prot_list */
		phba->cfg_total_seg_cnt = LPFC_MAX_SGL_SEG_CNT;

		/*
		 * If supporting DIF, reduce the seg count for scsi to
		 * allow room for the DIF sges.
		 */
		if (phba->cfg_enable_bg &&
		    phba->cfg_sg_seg_cnt > LPFC_MAX_BG_SLI4_SEG_CNT_DIF)
			phba->cfg_scsi_seg_cnt = LPFC_MAX_BG_SLI4_SEG_CNT_DIF;
		else
			phba->cfg_scsi_seg_cnt = phba->cfg_sg_seg_cnt;

	} else {
		/*
		 * The scsi_buf for a regular I/O holds the FCP cmnd,
		 * the FCP rsp, a SGE for each, and a SGE for up to
		 * cfg_sg_seg_cnt data segments.
		 */
		phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) +
				sizeof(struct fcp_rsp) +
				((phba->cfg_sg_seg_cnt + extra) *
				sizeof(struct sli4_sge));

		/* Total SGEs for scsi_sg_list */
		phba->cfg_total_seg_cnt = phba->cfg_sg_seg_cnt + extra;
		phba->cfg_scsi_seg_cnt = phba->cfg_sg_seg_cnt;

		/*
		 * NOTE: if (phba->cfg_sg_seg_cnt + extra) <= 256 we only
		 * need to post 1 page for the SGL.
		 */
	}

	if (phba->cfg_xpsgl && !phba->nvmet_support)
		phba->cfg_sg_dma_buf_size = LPFC_DEFAULT_XPSGL_SIZE;
	else if (phba->cfg_sg_dma_buf_size  <= LPFC_MIN_SG_SLI4_BUF_SZ)
		phba->cfg_sg_dma_buf_size = LPFC_MIN_SG_SLI4_BUF_SZ;
	else
		phba->cfg_sg_dma_buf_size =
				SLI4_PAGE_ALIGN(phba->cfg_sg_dma_buf_size);

	phba->border_sge_num = phba->cfg_sg_dma_buf_size /
			       sizeof(struct sli4_sge);

	/* Limit to LPFC_MAX_NVME_SEG_CNT for NVME. */
	if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
		if (phba->cfg_sg_seg_cnt > LPFC_MAX_NVME_SEG_CNT) {
			lpfc_printf_log(phba, KERN_INFO, LOG_NVME | LOG_INIT,
					"6300 Reducing NVME sg segment "
					"cnt to %d\n",
					LPFC_MAX_NVME_SEG_CNT);
			phba->cfg_nvme_seg_cnt = LPFC_MAX_NVME_SEG_CNT;
		} else
			phba->cfg_nvme_seg_cnt = phba->cfg_sg_seg_cnt;
	}

	lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_FCP,
			"9087 sg_seg_cnt:%d dmabuf_size:%d "
			"total:%d scsi:%d nvme:%d\n",
			phba->cfg_sg_seg_cnt, phba->cfg_sg_dma_buf_size,
			phba->cfg_total_seg_cnt,  phba->cfg_scsi_seg_cnt,
			phba->cfg_nvme_seg_cnt);

	if (phba->cfg_sg_dma_buf_size < SLI4_PAGE_SIZE)
		i = phba->cfg_sg_dma_buf_size;
	else
		i = SLI4_PAGE_SIZE;

	phba->lpfc_sg_dma_buf_pool =
			dma_pool_create("lpfc_sg_dma_buf_pool",
					&phba->pcidev->dev,
					phba->cfg_sg_dma_buf_size,
					i, 0);
	if (!phba->lpfc_sg_dma_buf_pool)
		goto out_free_bsmbx;

	phba->lpfc_cmd_rsp_buf_pool =
			dma_pool_create("lpfc_cmd_rsp_buf_pool",
					&phba->pcidev->dev,
					sizeof(struct fcp_cmnd) +
					sizeof(struct fcp_rsp),
					i, 0);
	if (!phba->lpfc_cmd_rsp_buf_pool)
		goto out_free_sg_dma_buf;

	mempool_free(mboxq, phba->mbox_mem_pool);

	/* Verify OAS is supported */
	lpfc_sli4_oas_verify(phba);

	/* Verify RAS support on adapter */
	lpfc_sli4_ras_init(phba);

	/* Verify all the SLI4 queues */
	rc = lpfc_sli4_queue_verify(phba);
	if (rc)
		goto out_free_cmd_rsp_buf;

	/* Create driver internal CQE event pool */
	rc = lpfc_sli4_cq_event_pool_create(phba);
	if (rc)
		goto out_free_cmd_rsp_buf;

	/* Initialize sgl lists per host */
	lpfc_init_sgl_list(phba);

	/* Allocate and initialize active sgl array */
	rc = lpfc_init_active_sgl_array(phba);
	if (rc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"1430 Failed to initialize sgl list.\n");
		goto out_destroy_cq_event_pool;
	}
	rc = lpfc_sli4_init_rpi_hdrs(phba);
	if (rc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"1432 Failed to initialize rpi headers.\n");
		goto out_free_active_sgl;
	}

	/* Allocate eligible FCF bmask memory for FCF roundrobin failover */
	longs = (LPFC_SLI4_FCF_TBL_INDX_MAX + BITS_PER_LONG - 1)/BITS_PER_LONG;
	phba->fcf.fcf_rr_bmask = kcalloc(longs, sizeof(unsigned long),
					 GFP_KERNEL);
	if (!phba->fcf.fcf_rr_bmask) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2759 Failed allocate memory for FCF round "
				"robin failover bmask\n");
		rc = -ENOMEM;
		goto out_remove_rpi_hdrs;
	}

	phba->sli4_hba.hba_eq_hdl = kcalloc(phba->cfg_irq_chann,
					    sizeof(struct lpfc_hba_eq_hdl),
					    GFP_KERNEL);
	if (!phba->sli4_hba.hba_eq_hdl) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2572 Failed allocate memory for "
				"fast-path per-EQ handle array\n");
		rc = -ENOMEM;
		goto out_free_fcf_rr_bmask;
	}

	phba->sli4_hba.cpu_map = kcalloc(phba->sli4_hba.num_possible_cpu,
					sizeof(struct lpfc_vector_map_info),
					GFP_KERNEL);
	if (!phba->sli4_hba.cpu_map) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3327 Failed allocate memory for msi-x "
				"interrupt vector mapping\n");
		rc = -ENOMEM;
		goto out_free_hba_eq_hdl;
	}

	phba->sli4_hba.eq_info = alloc_percpu(struct lpfc_eq_intr_info);
	if (!phba->sli4_hba.eq_info) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3321 Failed allocation for per_cpu stats\n");
		rc = -ENOMEM;
		goto out_free_hba_cpu_map;
	}

	phba->sli4_hba.idle_stat = kcalloc(phba->sli4_hba.num_possible_cpu,
					   sizeof(*phba->sli4_hba.idle_stat),
					   GFP_KERNEL);
	if (!phba->sli4_hba.idle_stat) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3390 Failed allocation for idle_stat\n");
		rc = -ENOMEM;
		goto out_free_hba_eq_info;
	}

#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
	phba->sli4_hba.c_stat = alloc_percpu(struct lpfc_hdwq_stat);
	if (!phba->sli4_hba.c_stat) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3332 Failed allocating per cpu hdwq stats\n");
		rc = -ENOMEM;
		goto out_free_hba_idle_stat;
	}
#endif

	phba->cmf_stat = alloc_percpu(struct lpfc_cgn_stat);
	if (!phba->cmf_stat) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3331 Failed allocating per cpu cgn stats\n");
		rc = -ENOMEM;
		goto out_free_hba_hdwq_info;
	}

	/*
	 * Enable sr-iov virtual functions if supported and configured
	 * through the module parameter.
	 */
	if (phba->cfg_sriov_nr_virtfn > 0) {
		rc = lpfc_sli_probe_sriov_nr_virtfn(phba,
						 phba->cfg_sriov_nr_virtfn);
		if (rc) {
			lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
					"3020 Requested number of SR-IOV "
					"virtual functions (%d) is not "
					"supported\n",
					phba->cfg_sriov_nr_virtfn);
			phba->cfg_sriov_nr_virtfn = 0;
		}
	}

	return 0;

out_free_hba_hdwq_info:
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
	free_percpu(phba->sli4_hba.c_stat);
out_free_hba_idle_stat:
#endif
	kfree(phba->sli4_hba.idle_stat);
out_free_hba_eq_info:
	free_percpu(phba->sli4_hba.eq_info);
out_free_hba_cpu_map:
	kfree(phba->sli4_hba.cpu_map);
out_free_hba_eq_hdl:
	kfree(phba->sli4_hba.hba_eq_hdl);
out_free_fcf_rr_bmask:
	kfree(phba->fcf.fcf_rr_bmask);
out_remove_rpi_hdrs:
	lpfc_sli4_remove_rpi_hdrs(phba);
out_free_active_sgl:
	lpfc_free_active_sgl(phba);
out_destroy_cq_event_pool:
	lpfc_sli4_cq_event_pool_destroy(phba);
out_free_cmd_rsp_buf:
	dma_pool_destroy(phba->lpfc_cmd_rsp_buf_pool);
	phba->lpfc_cmd_rsp_buf_pool = NULL;
out_free_sg_dma_buf:
	dma_pool_destroy(phba->lpfc_sg_dma_buf_pool);
	phba->lpfc_sg_dma_buf_pool = NULL;
out_free_bsmbx:
	lpfc_destroy_bootstrap_mbox(phba);
out_free_mem:
	lpfc_mem_free(phba);
	return rc;
}

/**
 * lpfc_sli4_driver_resource_unset - Unset drvr internal resources for SLI4 dev
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to unset the driver internal resources set up
 * specific for supporting the SLI-4 HBA device it attached to.
 **/
static void
lpfc_sli4_driver_resource_unset(struct lpfc_hba *phba)
{
	struct lpfc_fcf_conn_entry *conn_entry, *next_conn_entry;

	free_percpu(phba->sli4_hba.eq_info);
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
	free_percpu(phba->sli4_hba.c_stat);
#endif
	free_percpu(phba->cmf_stat);
	kfree(phba->sli4_hba.idle_stat);

	/* Free memory allocated for msi-x interrupt vector to CPU mapping */
	kfree(phba->sli4_hba.cpu_map);
	phba->sli4_hba.num_possible_cpu = 0;
	phba->sli4_hba.num_present_cpu = 0;
	phba->sli4_hba.curr_disp_cpu = 0;
	cpumask_clear(&phba->sli4_hba.irq_aff_mask);

	/* Free memory allocated for fast-path work queue handles */
	kfree(phba->sli4_hba.hba_eq_hdl);

	/* Free the allocated rpi headers. */
	lpfc_sli4_remove_rpi_hdrs(phba);
	lpfc_sli4_remove_rpis(phba);

	/* Free eligible FCF index bmask */
	kfree(phba->fcf.fcf_rr_bmask);

	/* Free the ELS sgl list */
	lpfc_free_active_sgl(phba);
	lpfc_free_els_sgl_list(phba);
	lpfc_free_nvmet_sgl_list(phba);

	/* Free the completion queue EQ event pool */
	lpfc_sli4_cq_event_release_all(phba);
	lpfc_sli4_cq_event_pool_destroy(phba);

	/* Release resource identifiers. */
	lpfc_sli4_dealloc_resource_identifiers(phba);

	/* Free the bsmbx region. */
	lpfc_destroy_bootstrap_mbox(phba);

	/* Free the SLI Layer memory with SLI4 HBAs */
	lpfc_mem_free_all(phba);

	/* Free the current connect table */
	list_for_each_entry_safe(conn_entry, next_conn_entry,
		&phba->fcf_conn_rec_list, list) {
		list_del_init(&conn_entry->list);
		kfree(conn_entry);
	}

	return;
}

/**
 * lpfc_init_api_table_setup - Set up init api function jump table
 * @phba: The hba struct for which this call is being executed.
 * @dev_grp: The HBA PCI-Device group number.
 *
 * This routine sets up the device INIT interface API function jump table
 * in @phba struct.
 *
 * Returns: 0 - success, -ENODEV - failure.
 **/
int
lpfc_init_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp)
{
	phba->lpfc_hba_init_link = lpfc_hba_init_link;
	phba->lpfc_hba_down_link = lpfc_hba_down_link;
	phba->lpfc_selective_reset = lpfc_selective_reset;
	switch (dev_grp) {
	case LPFC_PCI_DEV_LP:
		phba->lpfc_hba_down_post = lpfc_hba_down_post_s3;
		phba->lpfc_handle_eratt = lpfc_handle_eratt_s3;
		phba->lpfc_stop_port = lpfc_stop_port_s3;
		break;
	case LPFC_PCI_DEV_OC:
		phba->lpfc_hba_down_post = lpfc_hba_down_post_s4;
		phba->lpfc_handle_eratt = lpfc_handle_eratt_s4;
		phba->lpfc_stop_port = lpfc_stop_port_s4;
		break;
	default:
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"1431 Invalid HBA PCI-device group: 0x%x\n",
				dev_grp);
		return -ENODEV;
	}
	return 0;
}

/**
 * lpfc_setup_driver_resource_phase2 - Phase2 setup driver internal resources.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to set up the driver internal resources after the
 * device specific resource setup to support the HBA device it attached to.
 *
 * Return codes
 * 	0 - successful
 * 	other values - error
 **/
static int
lpfc_setup_driver_resource_phase2(struct lpfc_hba *phba)
{
	int error;

	/* Startup the kernel thread for this host adapter. */
	phba->worker_thread = kthread_run(lpfc_do_work, phba,
					  "lpfc_worker_%d", phba->brd_no);
	if (IS_ERR(phba->worker_thread)) {
		error = PTR_ERR(phba->worker_thread);
		return error;
	}

	return 0;
}

/**
 * lpfc_unset_driver_resource_phase2 - Phase2 unset driver internal resources.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to unset the driver internal resources set up after
 * the device specific resource setup for supporting the HBA device it
 * attached to.
 **/
static void
lpfc_unset_driver_resource_phase2(struct lpfc_hba *phba)
{
	if (phba->wq) {
		flush_workqueue(phba->wq);
		destroy_workqueue(phba->wq);
		phba->wq = NULL;
	}

	/* Stop kernel worker thread */
	if (phba->worker_thread)
		kthread_stop(phba->worker_thread);
}

/**
 * lpfc_free_iocb_list - Free iocb list.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to free the driver's IOCB list and memory.
 **/
void
lpfc_free_iocb_list(struct lpfc_hba *phba)
{
	struct lpfc_iocbq *iocbq_entry = NULL, *iocbq_next = NULL;

	spin_lock_irq(&phba->hbalock);
	list_for_each_entry_safe(iocbq_entry, iocbq_next,
				 &phba->lpfc_iocb_list, list) {
		list_del(&iocbq_entry->list);
		kfree(iocbq_entry);
		phba->total_iocbq_bufs--;
	}
	spin_unlock_irq(&phba->hbalock);

	return;
}

/**
 * lpfc_init_iocb_list - Allocate and initialize iocb list.
 * @phba: pointer to lpfc hba data structure.
 * @iocb_count: number of requested iocbs
 *
 * This routine is invoked to allocate and initizlize the driver's IOCB
 * list and set up the IOCB tag array accordingly.
 *
 * Return codes
 *	0 - successful
 *	other values - error
 **/
int
lpfc_init_iocb_list(struct lpfc_hba *phba, int iocb_count)
{
	struct lpfc_iocbq *iocbq_entry = NULL;
	uint16_t iotag;
	int i;

	/* Initialize and populate the iocb list per host.  */
	INIT_LIST_HEAD(&phba->lpfc_iocb_list);
	for (i = 0; i < iocb_count; i++) {
		iocbq_entry = kzalloc(sizeof(struct lpfc_iocbq), GFP_KERNEL);
		if (iocbq_entry == NULL) {
			printk(KERN_ERR "%s: only allocated %d iocbs of "
				"expected %d count. Unloading driver.\n",
				__func__, i, iocb_count);
			goto out_free_iocbq;
		}

		iotag = lpfc_sli_next_iotag(phba, iocbq_entry);
		if (iotag == 0) {
			kfree(iocbq_entry);
			printk(KERN_ERR "%s: failed to allocate IOTAG. "
				"Unloading driver.\n", __func__);
			goto out_free_iocbq;
		}
		iocbq_entry->sli4_lxritag = NO_XRI;
		iocbq_entry->sli4_xritag = NO_XRI;

		spin_lock_irq(&phba->hbalock);
		list_add(&iocbq_entry->list, &phba->lpfc_iocb_list);
		phba->total_iocbq_bufs++;
		spin_unlock_irq(&phba->hbalock);
	}

	return 0;

out_free_iocbq:
	lpfc_free_iocb_list(phba);

	return -ENOMEM;
}

/**
 * lpfc_free_sgl_list - Free a given sgl list.
 * @phba: pointer to lpfc hba data structure.
 * @sglq_list: pointer to the head of sgl list.
 *
 * This routine is invoked to free a give sgl list and memory.
 **/
void
lpfc_free_sgl_list(struct lpfc_hba *phba, struct list_head *sglq_list)
{
	struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL;

	list_for_each_entry_safe(sglq_entry, sglq_next, sglq_list, list) {
		list_del(&sglq_entry->list);
		lpfc_mbuf_free(phba, sglq_entry->virt, sglq_entry->phys);
		kfree(sglq_entry);
	}
}

/**
 * lpfc_free_els_sgl_list - Free els sgl list.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to free the driver's els sgl list and memory.
 **/
static void
lpfc_free_els_sgl_list(struct lpfc_hba *phba)
{
	LIST_HEAD(sglq_list);

	/* Retrieve all els sgls from driver list */
	spin_lock_irq(&phba->sli4_hba.sgl_list_lock);
	list_splice_init(&phba->sli4_hba.lpfc_els_sgl_list, &sglq_list);
	spin_unlock_irq(&phba->sli4_hba.sgl_list_lock);

	/* Now free the sgl list */
	lpfc_free_sgl_list(phba, &sglq_list);
}

/**
 * lpfc_free_nvmet_sgl_list - Free nvmet sgl list.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to free the driver's nvmet sgl list and memory.
 **/
static void
lpfc_free_nvmet_sgl_list(struct lpfc_hba *phba)
{
	struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL;
	LIST_HEAD(sglq_list);

	/* Retrieve all nvmet sgls from driver list */
	spin_lock_irq(&phba->hbalock);
	spin_lock(&phba->sli4_hba.sgl_list_lock);
	list_splice_init(&phba->sli4_hba.lpfc_nvmet_sgl_list, &sglq_list);
	spin_unlock(&phba->sli4_hba.sgl_list_lock);
	spin_unlock_irq(&phba->hbalock);

	/* Now free the sgl list */
	list_for_each_entry_safe(sglq_entry, sglq_next, &sglq_list, list) {
		list_del(&sglq_entry->list);
		lpfc_nvmet_buf_free(phba, sglq_entry->virt, sglq_entry->phys);
		kfree(sglq_entry);
	}

	/* Update the nvmet_xri_cnt to reflect no current sgls.
	 * The next initialization cycle sets the count and allocates
	 * the sgls over again.
	 */
	phba->sli4_hba.nvmet_xri_cnt = 0;
}

/**
 * lpfc_init_active_sgl_array - Allocate the buf to track active ELS XRIs.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to allocate the driver's active sgl memory.
 * This array will hold the sglq_entry's for active IOs.
 **/
static int
lpfc_init_active_sgl_array(struct lpfc_hba *phba)
{
	int size;
	size = sizeof(struct lpfc_sglq *);
	size *= phba->sli4_hba.max_cfg_param.max_xri;

	phba->sli4_hba.lpfc_sglq_active_list =
		kzalloc(size, GFP_KERNEL);
	if (!phba->sli4_hba.lpfc_sglq_active_list)
		return -ENOMEM;
	return 0;
}

/**
 * lpfc_free_active_sgl - Free the buf that tracks active ELS XRIs.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to walk through the array of active sglq entries
 * and free all of the resources.
 * This is just a place holder for now.
 **/
static void
lpfc_free_active_sgl(struct lpfc_hba *phba)
{
	kfree(phba->sli4_hba.lpfc_sglq_active_list);
}

/**
 * lpfc_init_sgl_list - Allocate and initialize sgl list.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to allocate and initizlize the driver's sgl
 * list and set up the sgl xritag tag array accordingly.
 *
 **/
static void
lpfc_init_sgl_list(struct lpfc_hba *phba)
{
	/* Initialize and populate the sglq list per host/VF. */
	INIT_LIST_HEAD(&phba->sli4_hba.lpfc_els_sgl_list);
	INIT_LIST_HEAD(&phba->sli4_hba.lpfc_abts_els_sgl_list);
	INIT_LIST_HEAD(&phba->sli4_hba.lpfc_nvmet_sgl_list);
	INIT_LIST_HEAD(&phba->sli4_hba.lpfc_abts_nvmet_ctx_list);

	/* els xri-sgl book keeping */
	phba->sli4_hba.els_xri_cnt = 0;

	/* nvme xri-buffer book keeping */
	phba->sli4_hba.io_xri_cnt = 0;
}

/**
 * lpfc_sli4_init_rpi_hdrs - Post the rpi header memory region to the port
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to post rpi header templates to the
 * port for those SLI4 ports that do not support extents.  This routine
 * posts a PAGE_SIZE memory region to the port to hold up to
 * PAGE_SIZE modulo 64 rpi context headers.  This is an initialization routine
 * and should be called only when interrupts are disabled.
 *
 * Return codes
 * 	0 - successful
 *	-ERROR - otherwise.
 **/
int
lpfc_sli4_init_rpi_hdrs(struct lpfc_hba *phba)
{
	int rc = 0;
	struct lpfc_rpi_hdr *rpi_hdr;

	INIT_LIST_HEAD(&phba->sli4_hba.lpfc_rpi_hdr_list);
	if (!phba->sli4_hba.rpi_hdrs_in_use)
		return rc;
	if (phba->sli4_hba.extents_in_use)
		return -EIO;

	rpi_hdr = lpfc_sli4_create_rpi_hdr(phba);
	if (!rpi_hdr) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0391 Error during rpi post operation\n");
		lpfc_sli4_remove_rpis(phba);
		rc = -ENODEV;
	}

	return rc;
}

/**
 * lpfc_sli4_create_rpi_hdr - Allocate an rpi header memory region
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to allocate a single 4KB memory region to
 * support rpis and stores them in the phba.  This single region
 * provides support for up to 64 rpis.  The region is used globally
 * by the device.
 *
 * Returns:
 *   A valid rpi hdr on success.
 *   A NULL pointer on any failure.
 **/
struct lpfc_rpi_hdr *
lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba)
{
	uint16_t rpi_limit, curr_rpi_range;
	struct lpfc_dmabuf *dmabuf;
	struct lpfc_rpi_hdr *rpi_hdr;

	/*
	 * If the SLI4 port supports extents, posting the rpi header isn't
	 * required.  Set the expected maximum count and let the actual value
	 * get set when extents are fully allocated.
	 */
	if (!phba->sli4_hba.rpi_hdrs_in_use)
		return NULL;
	if (phba->sli4_hba.extents_in_use)
		return NULL;

	/* The limit on the logical index is just the max_rpi count. */
	rpi_limit = phba->sli4_hba.max_cfg_param.max_rpi;

	spin_lock_irq(&phba->hbalock);
	/*
	 * Establish the starting RPI in this header block.  The starting
	 * rpi is normalized to a zero base because the physical rpi is
	 * port based.
	 */
	curr_rpi_range = phba->sli4_hba.next_rpi;
	spin_unlock_irq(&phba->hbalock);

	/* Reached full RPI range */
	if (curr_rpi_range == rpi_limit)
		return NULL;

	/*
	 * First allocate the protocol header region for the port.  The
	 * port expects a 4KB DMA-mapped memory region that is 4K aligned.
	 */
	dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
	if (!dmabuf)
		return NULL;

	dmabuf->virt = dma_alloc_coherent(&phba->pcidev->dev,
					  LPFC_HDR_TEMPLATE_SIZE,
					  &dmabuf->phys, GFP_KERNEL);
	if (!dmabuf->virt) {
		rpi_hdr = NULL;
		goto err_free_dmabuf;
	}

	if (!IS_ALIGNED(dmabuf->phys, LPFC_HDR_TEMPLATE_SIZE)) {
		rpi_hdr = NULL;
		goto err_free_coherent;
	}

	/* Save the rpi header data for cleanup later. */
	rpi_hdr = kzalloc(sizeof(struct lpfc_rpi_hdr), GFP_KERNEL);
	if (!rpi_hdr)
		goto err_free_coherent;

	rpi_hdr->dmabuf = dmabuf;
	rpi_hdr->len = LPFC_HDR_TEMPLATE_SIZE;
	rpi_hdr->page_count = 1;
	spin_lock_irq(&phba->hbalock);

	/* The rpi_hdr stores the logical index only. */
	rpi_hdr->start_rpi = curr_rpi_range;
	rpi_hdr->next_rpi = phba->sli4_hba.next_rpi + LPFC_RPI_HDR_COUNT;
	list_add_tail(&rpi_hdr->list, &phba->sli4_hba.lpfc_rpi_hdr_list);

	spin_unlock_irq(&phba->hbalock);
	return rpi_hdr;

 err_free_coherent:
	dma_free_coherent(&phba->pcidev->dev, LPFC_HDR_TEMPLATE_SIZE,
			  dmabuf->virt, dmabuf->phys);
 err_free_dmabuf:
	kfree(dmabuf);
	return NULL;
}

/**
 * lpfc_sli4_remove_rpi_hdrs - Remove all rpi header memory regions
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to remove all memory resources allocated
 * to support rpis for SLI4 ports not supporting extents. This routine
 * presumes the caller has released all rpis consumed by fabric or port
 * logins and is prepared to have the header pages removed.
 **/
void
lpfc_sli4_remove_rpi_hdrs(struct lpfc_hba *phba)
{
	struct lpfc_rpi_hdr *rpi_hdr, *next_rpi_hdr;

	if (!phba->sli4_hba.rpi_hdrs_in_use)
		goto exit;

	list_for_each_entry_safe(rpi_hdr, next_rpi_hdr,
				 &phba->sli4_hba.lpfc_rpi_hdr_list, list) {
		list_del(&rpi_hdr->list);
		dma_free_coherent(&phba->pcidev->dev, rpi_hdr->len,
				  rpi_hdr->dmabuf->virt, rpi_hdr->dmabuf->phys);
		kfree(rpi_hdr->dmabuf);
		kfree(rpi_hdr);
	}
 exit:
	/* There are no rpis available to the port now. */
	phba->sli4_hba.next_rpi = 0;
}

/**
 * lpfc_hba_alloc - Allocate driver hba data structure for a device.
 * @pdev: pointer to pci device data structure.
 *
 * This routine is invoked to allocate the driver hba data structure for an
 * HBA device. If the allocation is successful, the phba reference to the
 * PCI device data structure is set.
 *
 * Return codes
 *      pointer to @phba - successful
 *      NULL - error
 **/
static struct lpfc_hba *
lpfc_hba_alloc(struct pci_dev *pdev)
{
	struct lpfc_hba *phba;

	/* Allocate memory for HBA structure */
	phba = kzalloc(sizeof(struct lpfc_hba), GFP_KERNEL);
	if (!phba) {
		dev_err(&pdev->dev, "failed to allocate hba struct\n");
		return NULL;
	}

	/* Set reference to PCI device in HBA structure */
	phba->pcidev = pdev;

	/* Assign an unused board number */
	phba->brd_no = lpfc_get_instance();
	if (phba->brd_no < 0) {
		kfree(phba);
		return NULL;
	}
	phba->eratt_poll_interval = LPFC_ERATT_POLL_INTERVAL;

	spin_lock_init(&phba->ct_ev_lock);
	INIT_LIST_HEAD(&phba->ct_ev_waiters);

	return phba;
}

/**
 * lpfc_hba_free - Free driver hba data structure with a device.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to free the driver hba data structure with an
 * HBA device.
 **/
static void
lpfc_hba_free(struct lpfc_hba *phba)
{
	if (phba->sli_rev == LPFC_SLI_REV4)
		kfree(phba->sli4_hba.hdwq);

	/* Release the driver assigned board number */
	idr_remove(&lpfc_hba_index, phba->brd_no);

	/* Free memory allocated with sli3 rings */
	kfree(phba->sli.sli3_ring);
	phba->sli.sli3_ring = NULL;

	kfree(phba);
	return;
}

/**
 * lpfc_create_shost - Create hba physical port with associated scsi host.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to create HBA physical port and associate a SCSI
 * host with it.
 *
 * Return codes
 *      0 - successful
 *      other values - error
 **/
static int
lpfc_create_shost(struct lpfc_hba *phba)
{
	struct lpfc_vport *vport;
	struct Scsi_Host  *shost;

	/* Initialize HBA FC structure */
	phba->fc_edtov = FF_DEF_EDTOV;
	phba->fc_ratov = FF_DEF_RATOV;
	phba->fc_altov = FF_DEF_ALTOV;
	phba->fc_arbtov = FF_DEF_ARBTOV;

	atomic_set(&phba->sdev_cnt, 0);
	vport = lpfc_create_port(phba, phba->brd_no, &phba->pcidev->dev);
	if (!vport)
		return -ENODEV;

	shost = lpfc_shost_from_vport(vport);
	phba->pport = vport;

	if (phba->nvmet_support) {
		/* Only 1 vport (pport) will support NVME target */
		phba->targetport = NULL;
		phba->cfg_enable_fc4_type = LPFC_ENABLE_NVME;
		lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_NVME_DISC,
				"6076 NVME Target Found\n");
	}

	lpfc_debugfs_initialize(vport);
	/* Put reference to SCSI host to driver's device private data */
	pci_set_drvdata(phba->pcidev, shost);

	/*
	 * At this point we are fully registered with PSA. In addition,
	 * any initial discovery should be completed.
	 */
	vport->load_flag |= FC_ALLOW_FDMI;
	if (phba->cfg_enable_SmartSAN ||
	    (phba->cfg_fdmi_on == LPFC_FDMI_SUPPORT)) {

		/* Setup appropriate attribute masks */
		vport->fdmi_hba_mask = LPFC_FDMI2_HBA_ATTR;
		if (phba->cfg_enable_SmartSAN)
			vport->fdmi_port_mask = LPFC_FDMI2_SMART_ATTR;
		else
			vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR;
	}
	return 0;
}

/**
 * lpfc_destroy_shost - Destroy hba physical port with associated scsi host.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to destroy HBA physical port and the associated
 * SCSI host.
 **/
static void
lpfc_destroy_shost(struct lpfc_hba *phba)
{
	struct lpfc_vport *vport = phba->pport;

	/* Destroy physical port that associated with the SCSI host */
	destroy_port(vport);

	return;
}

/**
 * lpfc_setup_bg - Setup Block guard structures and debug areas.
 * @phba: pointer to lpfc hba data structure.
 * @shost: the shost to be used to detect Block guard settings.
 *
 * This routine sets up the local Block guard protocol settings for @shost.
 * This routine also allocates memory for debugging bg buffers.
 **/
static void
lpfc_setup_bg(struct lpfc_hba *phba, struct Scsi_Host *shost)
{
	uint32_t old_mask;
	uint32_t old_guard;

	if (phba->cfg_prot_mask && phba->cfg_prot_guard) {
		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"1478 Registering BlockGuard with the "
				"SCSI layer\n");

		old_mask = phba->cfg_prot_mask;
		old_guard = phba->cfg_prot_guard;

		/* Only allow supported values */
		phba->cfg_prot_mask &= (SHOST_DIF_TYPE1_PROTECTION |
			SHOST_DIX_TYPE0_PROTECTION |
			SHOST_DIX_TYPE1_PROTECTION);
		phba->cfg_prot_guard &= (SHOST_DIX_GUARD_IP |
					 SHOST_DIX_GUARD_CRC);

		/* DIF Type 1 protection for profiles AST1/C1 is end to end */
		if (phba->cfg_prot_mask == SHOST_DIX_TYPE1_PROTECTION)
			phba->cfg_prot_mask |= SHOST_DIF_TYPE1_PROTECTION;

		if (phba->cfg_prot_mask && phba->cfg_prot_guard) {
			if ((old_mask != phba->cfg_prot_mask) ||
				(old_guard != phba->cfg_prot_guard))
				lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"1475 Registering BlockGuard with the "
					"SCSI layer: mask %d  guard %d\n",
					phba->cfg_prot_mask,
					phba->cfg_prot_guard);

			scsi_host_set_prot(shost, phba->cfg_prot_mask);
			scsi_host_set_guard(shost, phba->cfg_prot_guard);
		} else
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"1479 Not Registering BlockGuard with the SCSI "
				"layer, Bad protection parameters: %d %d\n",
				old_mask, old_guard);
	}
}

/**
 * lpfc_post_init_setup - Perform necessary device post initialization setup.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to perform all the necessary post initialization
 * setup for the device.
 **/
static void
lpfc_post_init_setup(struct lpfc_hba *phba)
{
	struct Scsi_Host  *shost;
	struct lpfc_adapter_event_header adapter_event;

	/* Get the default values for Model Name and Description */
	lpfc_get_hba_model_desc(phba, phba->ModelName, phba->ModelDesc);

	/*
	 * hba setup may have changed the hba_queue_depth so we need to
	 * adjust the value of can_queue.
	 */
	shost = pci_get_drvdata(phba->pcidev);
	shost->can_queue = phba->cfg_hba_queue_depth - 10;

	lpfc_host_attrib_init(shost);

	if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
		spin_lock_irq(shost->host_lock);
		lpfc_poll_start_timer(phba);
		spin_unlock_irq(shost->host_lock);
	}

	lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
			"0428 Perform SCSI scan\n");
	/* Send board arrival event to upper layer */
	adapter_event.event_type = FC_REG_ADAPTER_EVENT;
	adapter_event.subcategory = LPFC_EVENT_ARRIVAL;
	fc_host_post_vendor_event(shost, fc_get_event_number(),
				  sizeof(adapter_event),
				  (char *) &adapter_event,
				  LPFC_NL_VENDOR_ID);
	return;
}

/**
 * lpfc_sli_pci_mem_setup - Setup SLI3 HBA PCI memory space.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to set up the PCI device memory space for device
 * with SLI-3 interface spec.
 *
 * Return codes
 * 	0 - successful
 * 	other values - error
 **/
static int
lpfc_sli_pci_mem_setup(struct lpfc_hba *phba)
{
	struct pci_dev *pdev = phba->pcidev;
	unsigned long bar0map_len, bar2map_len;
	int i, hbq_count;
	void *ptr;
	int error;

	if (!pdev)
		return -ENODEV;

	/* Set the device DMA mask size */
	error = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
	if (error)
		error = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
	if (error)
		return error;
	error = -ENODEV;

	/* Get the bus address of Bar0 and Bar2 and the number of bytes
	 * required by each mapping.
	 */
	phba->pci_bar0_map = pci_resource_start(pdev, 0);
	bar0map_len = pci_resource_len(pdev, 0);

	phba->pci_bar2_map = pci_resource_start(pdev, 2);
	bar2map_len = pci_resource_len(pdev, 2);

	/* Map HBA SLIM to a kernel virtual address. */
	phba->slim_memmap_p = ioremap(phba->pci_bar0_map, bar0map_len);
	if (!phba->slim_memmap_p) {
		dev_printk(KERN_ERR, &pdev->dev,
			   "ioremap failed for SLIM memory.\n");
		goto out;
	}

	/* Map HBA Control Registers to a kernel virtual address. */
	phba->ctrl_regs_memmap_p = ioremap(phba->pci_bar2_map, bar2map_len);
	if (!phba->ctrl_regs_memmap_p) {
		dev_printk(KERN_ERR, &pdev->dev,
			   "ioremap failed for HBA control registers.\n");
		goto out_iounmap_slim;
	}

	/* Allocate memory for SLI-2 structures */
	phba->slim2p.virt = dma_alloc_coherent(&pdev->dev, SLI2_SLIM_SIZE,
					       &phba->slim2p.phys, GFP_KERNEL);
	if (!phba->slim2p.virt)
		goto out_iounmap;

	phba->mbox = phba->slim2p.virt + offsetof(struct lpfc_sli2_slim, mbx);
	phba->mbox_ext = (phba->slim2p.virt +
		offsetof(struct lpfc_sli2_slim, mbx_ext_words));
	phba->pcb = (phba->slim2p.virt + offsetof(struct lpfc_sli2_slim, pcb));
	phba->IOCBs = (phba->slim2p.virt +
		       offsetof(struct lpfc_sli2_slim, IOCBs));

	phba->hbqslimp.virt = dma_alloc_coherent(&pdev->dev,
						 lpfc_sli_hbq_size(),
						 &phba->hbqslimp.phys,
						 GFP_KERNEL);
	if (!phba->hbqslimp.virt)
		goto out_free_slim;

	hbq_count = lpfc_sli_hbq_count();
	ptr = phba->hbqslimp.virt;
	for (i = 0; i < hbq_count; ++i) {
		phba->hbqs[i].hbq_virt = ptr;
		INIT_LIST_HEAD(&phba->hbqs[i].hbq_buffer_list);
		ptr += (lpfc_hbq_defs[i]->entry_count *
			sizeof(struct lpfc_hbq_entry));
	}
	phba->hbqs[LPFC_ELS_HBQ].hbq_alloc_buffer = lpfc_els_hbq_alloc;
	phba->hbqs[LPFC_ELS_HBQ].hbq_free_buffer = lpfc_els_hbq_free;

	memset(phba->hbqslimp.virt, 0, lpfc_sli_hbq_size());

	phba->MBslimaddr = phba->slim_memmap_p;
	phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET;
	phba->CAregaddr = phba->ctrl_regs_memmap_p + CA_REG_OFFSET;
	phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET;
	phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET;

	return 0;

out_free_slim:
	dma_free_coherent(&pdev->dev, SLI2_SLIM_SIZE,
			  phba->slim2p.virt, phba->slim2p.phys);
out_iounmap:
	iounmap(phba->ctrl_regs_memmap_p);
out_iounmap_slim:
	iounmap(phba->slim_memmap_p);
out:
	return error;
}

/**
 * lpfc_sli_pci_mem_unset - Unset SLI3 HBA PCI memory space.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to unset the PCI device memory space for device
 * with SLI-3 interface spec.
 **/
static void
lpfc_sli_pci_mem_unset(struct lpfc_hba *phba)
{
	struct pci_dev *pdev;

	/* Obtain PCI device reference */
	if (!phba->pcidev)
		return;
	else
		pdev = phba->pcidev;

	/* Free coherent DMA memory allocated */
	dma_free_coherent(&pdev->dev, lpfc_sli_hbq_size(),
			  phba->hbqslimp.virt, phba->hbqslimp.phys);
	dma_free_coherent(&pdev->dev, SLI2_SLIM_SIZE,
			  phba->slim2p.virt, phba->slim2p.phys);

	/* I/O memory unmap */
	iounmap(phba->ctrl_regs_memmap_p);
	iounmap(phba->slim_memmap_p);

	return;
}

/**
 * lpfc_sli4_post_status_check - Wait for SLI4 POST done and check status
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to wait for SLI4 device Power On Self Test (POST)
 * done and check status.
 *
 * Return 0 if successful, otherwise -ENODEV.
 **/
int
lpfc_sli4_post_status_check(struct lpfc_hba *phba)
{
	struct lpfc_register portsmphr_reg, uerrlo_reg, uerrhi_reg;
	struct lpfc_register reg_data;
	int i, port_error = 0;
	uint32_t if_type;

	memset(&portsmphr_reg, 0, sizeof(portsmphr_reg));
	memset(&reg_data, 0, sizeof(reg_data));
	if (!phba->sli4_hba.PSMPHRregaddr)
		return -ENODEV;

	/* Wait up to 30 seconds for the SLI Port POST done and ready */
	for (i = 0; i < 3000; i++) {
		if (lpfc_readl(phba->sli4_hba.PSMPHRregaddr,
			&portsmphr_reg.word0) ||
			(bf_get(lpfc_port_smphr_perr, &portsmphr_reg))) {
			/* Port has a fatal POST error, break out */
			port_error = -ENODEV;
			break;
		}
		if (LPFC_POST_STAGE_PORT_READY ==
		    bf_get(lpfc_port_smphr_port_status, &portsmphr_reg))
			break;
		msleep(10);
	}

	/*
	 * If there was a port error during POST, then don't proceed with
	 * other register reads as the data may not be valid.  Just exit.
	 */
	if (port_error) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
			"1408 Port Failed POST - portsmphr=0x%x, "
			"perr=x%x, sfi=x%x, nip=x%x, ipc=x%x, scr1=x%x, "
			"scr2=x%x, hscratch=x%x, pstatus=x%x\n",
			portsmphr_reg.word0,
			bf_get(lpfc_port_smphr_perr, &portsmphr_reg),
			bf_get(lpfc_port_smphr_sfi, &portsmphr_reg),
			bf_get(lpfc_port_smphr_nip, &portsmphr_reg),
			bf_get(lpfc_port_smphr_ipc, &portsmphr_reg),
			bf_get(lpfc_port_smphr_scr1, &portsmphr_reg),
			bf_get(lpfc_port_smphr_scr2, &portsmphr_reg),
			bf_get(lpfc_port_smphr_host_scratch, &portsmphr_reg),
			bf_get(lpfc_port_smphr_port_status, &portsmphr_reg));
	} else {
		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"2534 Device Info: SLIFamily=0x%x, "
				"SLIRev=0x%x, IFType=0x%x, SLIHint_1=0x%x, "
				"SLIHint_2=0x%x, FT=0x%x\n",
				bf_get(lpfc_sli_intf_sli_family,
				       &phba->sli4_hba.sli_intf),
				bf_get(lpfc_sli_intf_slirev,
				       &phba->sli4_hba.sli_intf),
				bf_get(lpfc_sli_intf_if_type,
				       &phba->sli4_hba.sli_intf),
				bf_get(lpfc_sli_intf_sli_hint1,
				       &phba->sli4_hba.sli_intf),
				bf_get(lpfc_sli_intf_sli_hint2,
				       &phba->sli4_hba.sli_intf),
				bf_get(lpfc_sli_intf_func_type,
				       &phba->sli4_hba.sli_intf));
		/*
		 * Check for other Port errors during the initialization
		 * process.  Fail the load if the port did not come up
		 * correctly.
		 */
		if_type = bf_get(lpfc_sli_intf_if_type,
				 &phba->sli4_hba.sli_intf);
		switch (if_type) {
		case LPFC_SLI_INTF_IF_TYPE_0:
			phba->sli4_hba.ue_mask_lo =
			      readl(phba->sli4_hba.u.if_type0.UEMASKLOregaddr);
			phba->sli4_hba.ue_mask_hi =
			      readl(phba->sli4_hba.u.if_type0.UEMASKHIregaddr);
			uerrlo_reg.word0 =
			      readl(phba->sli4_hba.u.if_type0.UERRLOregaddr);
			uerrhi_reg.word0 =
				readl(phba->sli4_hba.u.if_type0.UERRHIregaddr);
			if ((~phba->sli4_hba.ue_mask_lo & uerrlo_reg.word0) ||
			    (~phba->sli4_hba.ue_mask_hi & uerrhi_reg.word0)) {
				lpfc_printf_log(phba, KERN_ERR,
						LOG_TRACE_EVENT,
						"1422 Unrecoverable Error "
						"Detected during POST "
						"uerr_lo_reg=0x%x, "
						"uerr_hi_reg=0x%x, "
						"ue_mask_lo_reg=0x%x, "
						"ue_mask_hi_reg=0x%x\n",
						uerrlo_reg.word0,
						uerrhi_reg.word0,
						phba->sli4_hba.ue_mask_lo,
						phba->sli4_hba.ue_mask_hi);
				port_error = -ENODEV;
			}
			break;
		case LPFC_SLI_INTF_IF_TYPE_2:
		case LPFC_SLI_INTF_IF_TYPE_6:
			/* Final checks.  The port status should be clean. */
			if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
				&reg_data.word0) ||
				(bf_get(lpfc_sliport_status_err, &reg_data) &&
				 !bf_get(lpfc_sliport_status_rn, &reg_data))) {
				phba->work_status[0] =
					readl(phba->sli4_hba.u.if_type2.
					      ERR1regaddr);
				phba->work_status[1] =
					readl(phba->sli4_hba.u.if_type2.
					      ERR2regaddr);
				lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"2888 Unrecoverable port error "
					"following POST: port status reg "
					"0x%x, port_smphr reg 0x%x, "
					"error 1=0x%x, error 2=0x%x\n",
					reg_data.word0,
					portsmphr_reg.word0,
					phba->work_status[0],
					phba->work_status[1]);
				port_error = -ENODEV;
				break;
			}

			if (lpfc_pldv_detect &&
			    bf_get(lpfc_sli_intf_sli_family,
				   &phba->sli4_hba.sli_intf) ==
					LPFC_SLI_INTF_FAMILY_G6)
				pci_write_config_byte(phba->pcidev,
						      LPFC_SLI_INTF, CFG_PLD);
			break;
		case LPFC_SLI_INTF_IF_TYPE_1:
		default:
			break;
		}
	}
	return port_error;
}

/**
 * lpfc_sli4_bar0_register_memmap - Set up SLI4 BAR0 register memory map.
 * @phba: pointer to lpfc hba data structure.
 * @if_type:  The SLI4 interface type getting configured.
 *
 * This routine is invoked to set up SLI4 BAR0 PCI config space register
 * memory map.
 **/
static void
lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba, uint32_t if_type)
{
	switch (if_type) {
	case LPFC_SLI_INTF_IF_TYPE_0:
		phba->sli4_hba.u.if_type0.UERRLOregaddr =
			phba->sli4_hba.conf_regs_memmap_p + LPFC_UERR_STATUS_LO;
		phba->sli4_hba.u.if_type0.UERRHIregaddr =
			phba->sli4_hba.conf_regs_memmap_p + LPFC_UERR_STATUS_HI;
		phba->sli4_hba.u.if_type0.UEMASKLOregaddr =
			phba->sli4_hba.conf_regs_memmap_p + LPFC_UE_MASK_LO;
		phba->sli4_hba.u.if_type0.UEMASKHIregaddr =
			phba->sli4_hba.conf_regs_memmap_p + LPFC_UE_MASK_HI;
		phba->sli4_hba.SLIINTFregaddr =
			phba->sli4_hba.conf_regs_memmap_p + LPFC_SLI_INTF;
		break;
	case LPFC_SLI_INTF_IF_TYPE_2:
		phba->sli4_hba.u.if_type2.EQDregaddr =
			phba->sli4_hba.conf_regs_memmap_p +
						LPFC_CTL_PORT_EQ_DELAY_OFFSET;
		phba->sli4_hba.u.if_type2.ERR1regaddr =
			phba->sli4_hba.conf_regs_memmap_p +
						LPFC_CTL_PORT_ER1_OFFSET;
		phba->sli4_hba.u.if_type2.ERR2regaddr =
			phba->sli4_hba.conf_regs_memmap_p +
						LPFC_CTL_PORT_ER2_OFFSET;
		phba->sli4_hba.u.if_type2.CTRLregaddr =
			phba->sli4_hba.conf_regs_memmap_p +
						LPFC_CTL_PORT_CTL_OFFSET;
		phba->sli4_hba.u.if_type2.STATUSregaddr =
			phba->sli4_hba.conf_regs_memmap_p +
						LPFC_CTL_PORT_STA_OFFSET;
		phba->sli4_hba.SLIINTFregaddr =
			phba->sli4_hba.conf_regs_memmap_p + LPFC_SLI_INTF;
		phba->sli4_hba.PSMPHRregaddr =
			phba->sli4_hba.conf_regs_memmap_p +
						LPFC_CTL_PORT_SEM_OFFSET;
		phba->sli4_hba.RQDBregaddr =
			phba->sli4_hba.conf_regs_memmap_p +
						LPFC_ULP0_RQ_DOORBELL;
		phba->sli4_hba.WQDBregaddr =
			phba->sli4_hba.conf_regs_memmap_p +
						LPFC_ULP0_WQ_DOORBELL;
		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 =
			phba->sli4_hba.conf_regs_memmap_p + LPFC_BMBX;
		break;
	case LPFC_SLI_INTF_IF_TYPE_6:
		phba->sli4_hba.u.if_type2.EQDregaddr =
			phba->sli4_hba.conf_regs_memmap_p +
						LPFC_CTL_PORT_EQ_DELAY_OFFSET;
		phba->sli4_hba.u.if_type2.ERR1regaddr =
			phba->sli4_hba.conf_regs_memmap_p +
						LPFC_CTL_PORT_ER1_OFFSET;
		phba->sli4_hba.u.if_type2.ERR2regaddr =
			phba->sli4_hba.conf_regs_memmap_p +
						LPFC_CTL_PORT_ER2_OFFSET;
		phba->sli4_hba.u.if_type2.CTRLregaddr =
			phba->sli4_hba.conf_regs_memmap_p +
						LPFC_CTL_PORT_CTL_OFFSET;
		phba->sli4_hba.u.if_type2.STATUSregaddr =
			phba->sli4_hba.conf_regs_memmap_p +
						LPFC_CTL_PORT_STA_OFFSET;
		phba->sli4_hba.PSMPHRregaddr =
			phba->sli4_hba.conf_regs_memmap_p +
						LPFC_CTL_PORT_SEM_OFFSET;
		phba->sli4_hba.BMBXregaddr =
			phba->sli4_hba.conf_regs_memmap_p + LPFC_BMBX;
		break;
	case LPFC_SLI_INTF_IF_TYPE_1:
	default:
		dev_printk(KERN_ERR, &phba->pcidev->dev,
			   "FATAL - unsupported SLI4 interface type - %d\n",
			   if_type);
		break;
	}
}

/**
 * lpfc_sli4_bar1_register_memmap - Set up SLI4 BAR1 register memory map.
 * @phba: pointer to lpfc hba data structure.
 * @if_type: sli if type to operate on.
 *
 * This routine is invoked to set up SLI4 BAR1 register memory map.
 **/
static void
lpfc_sli4_bar1_register_memmap(struct lpfc_hba *phba, uint32_t if_type)
{
	switch (if_type) {
	case LPFC_SLI_INTF_IF_TYPE_0:
		phba->sli4_hba.PSMPHRregaddr =
			phba->sli4_hba.ctrl_regs_memmap_p +
			LPFC_SLIPORT_IF0_SMPHR;
		phba->sli4_hba.ISRregaddr = phba->sli4_hba.ctrl_regs_memmap_p +
			LPFC_HST_ISR0;
		phba->sli4_hba.IMRregaddr = phba->sli4_hba.ctrl_regs_memmap_p +
			LPFC_HST_IMR0;
		phba->sli4_hba.ISCRregaddr = phba->sli4_hba.ctrl_regs_memmap_p +
			LPFC_HST_ISCR0;
		break;
	case LPFC_SLI_INTF_IF_TYPE_6:
		phba->sli4_hba.RQDBregaddr = phba->sli4_hba.drbl_regs_memmap_p +
			LPFC_IF6_RQ_DOORBELL;
		phba->sli4_hba.WQDBregaddr = phba->sli4_hba.drbl_regs_memmap_p +
			LPFC_IF6_WQ_DOORBELL;
		phba->sli4_hba.CQDBregaddr = phba->sli4_hba.drbl_regs_memmap_p +
			LPFC_IF6_CQ_DOORBELL;
		phba->sli4_hba.EQDBregaddr = phba->sli4_hba.drbl_regs_memmap_p +
			LPFC_IF6_EQ_DOORBELL;
		phba->sli4_hba.MQDBregaddr = phba->sli4_hba.drbl_regs_memmap_p +
			LPFC_IF6_MQ_DOORBELL;
		break;
	case LPFC_SLI_INTF_IF_TYPE_2:
	case LPFC_SLI_INTF_IF_TYPE_1:
	default:
		dev_err(&phba->pcidev->dev,
			   "FATAL - unsupported SLI4 interface type - %d\n",
			   if_type);
		break;
	}
}

/**
 * lpfc_sli4_bar2_register_memmap - Set up SLI4 BAR2 register memory map.
 * @phba: pointer to lpfc hba data structure.
 * @vf: virtual function number
 *
 * This routine is invoked to set up SLI4 BAR2 doorbell register memory map
 * based on the given viftual function number, @vf.
 *
 * Return 0 if successful, otherwise -ENODEV.
 **/
static int
lpfc_sli4_bar2_register_memmap(struct lpfc_hba *phba, uint32_t vf)
{
	if (vf > LPFC_VIR_FUNC_MAX)
		return -ENODEV;

	phba->sli4_hba.RQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
				vf * LPFC_VFR_PAGE_SIZE +
					LPFC_ULP0_RQ_DOORBELL);
	phba->sli4_hba.WQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
				vf * LPFC_VFR_PAGE_SIZE +
					LPFC_ULP0_WQ_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_SIZE + LPFC_MQ_DOORBELL);
	phba->sli4_hba.BMBXregaddr = (phba->sli4_hba.drbl_regs_memmap_p +
				vf * LPFC_VFR_PAGE_SIZE + LPFC_BMBX);
	return 0;
}

/**
 * lpfc_create_bootstrap_mbox - Create the bootstrap mailbox
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to create the bootstrap mailbox
 * region consistent with the SLI-4 interface spec.  This
 * routine allocates all memory necessary to communicate
 * mailbox commands to the port and sets up all alignment
 * needs.  No locks are expected to be held when calling
 * this routine.
 *
 * Return codes
 * 	0 - successful
 * 	-ENOMEM - could not allocated memory.
 **/
static int
lpfc_create_bootstrap_mbox(struct lpfc_hba *phba)
{
	uint32_t bmbx_size;
	struct lpfc_dmabuf *dmabuf;
	struct dma_address *dma_address;
	uint32_t pa_addr;
	uint64_t phys_addr;

	dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
	if (!dmabuf)
		return -ENOMEM;

	/*
	 * The bootstrap mailbox region is comprised of 2 parts
	 * plus an alignment restriction of 16 bytes.
	 */
	bmbx_size = sizeof(struct lpfc_bmbx_create) + (LPFC_ALIGN_16_BYTE - 1);
	dmabuf->virt = dma_alloc_coherent(&phba->pcidev->dev, bmbx_size,
					  &dmabuf->phys, GFP_KERNEL);
	if (!dmabuf->virt) {
		kfree(dmabuf);
		return -ENOMEM;
	}

	/*
	 * Initialize the bootstrap mailbox pointers now so that the register
	 * operations are simple later.  The mailbox dma address is required
	 * to be 16-byte aligned.  Also align the virtual memory as each
	 * maibox is copied into the bmbx mailbox region before issuing the
	 * command to the port.
	 */
	phba->sli4_hba.bmbx.dmabuf = dmabuf;
	phba->sli4_hba.bmbx.bmbx_size = bmbx_size;

	phba->sli4_hba.bmbx.avirt = PTR_ALIGN(dmabuf->virt,
					      LPFC_ALIGN_16_BYTE);
	phba->sli4_hba.bmbx.aphys = ALIGN(dmabuf->phys,
					      LPFC_ALIGN_16_BYTE);

	/*
	 * Set the high and low physical addresses now.  The SLI4 alignment
	 * requirement is 16 bytes and the mailbox is posted to the port
	 * as two 30-bit addresses.  The other data is a bit marking whether
	 * the 30-bit address is the high or low address.
	 * Upcast bmbx aphys to 64bits so shift instruction compiles
	 * clean on 32 bit machines.
	 */
	dma_address = &phba->sli4_hba.bmbx.dma_address;
	phys_addr = (uint64_t)phba->sli4_hba.bmbx.aphys;
	pa_addr = (uint32_t) ((phys_addr >> 34) & 0x3fffffff);
	dma_address->addr_hi = (uint32_t) ((pa_addr << 2) |
					   LPFC_BMBX_BIT1_ADDR_HI);

	pa_addr = (uint32_t) ((phba->sli4_hba.bmbx.aphys >> 4) & 0x3fffffff);
	dma_address->addr_lo = (uint32_t) ((pa_addr << 2) |
					   LPFC_BMBX_BIT1_ADDR_LO);
	return 0;
}

/**
 * lpfc_destroy_bootstrap_mbox - Destroy all bootstrap mailbox resources
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to teardown the bootstrap mailbox
 * region and release all host resources. This routine requires
 * the caller to ensure all mailbox commands recovered, no
 * additional mailbox comands are sent, and interrupts are disabled
 * before calling this routine.
 *
 **/
static void
lpfc_destroy_bootstrap_mbox(struct lpfc_hba *phba)
{
	dma_free_coherent(&phba->pcidev->dev,
			  phba->sli4_hba.bmbx.bmbx_size,
			  phba->sli4_hba.bmbx.dmabuf->virt,
			  phba->sli4_hba.bmbx.dmabuf->phys);

	kfree(phba->sli4_hba.bmbx.dmabuf);
	memset(&phba->sli4_hba.bmbx, 0, sizeof(struct lpfc_bmbx));
}

static const char * const lpfc_topo_to_str[] = {
	"Loop then P2P",
	"Loopback",
	"P2P Only",
	"Unsupported",
	"Loop Only",
	"Unsupported",
	"P2P then Loop",
};

#define	LINK_FLAGS_DEF	0x0
#define	LINK_FLAGS_P2P	0x1
#define	LINK_FLAGS_LOOP	0x2
/**
 * lpfc_map_topology - Map the topology read from READ_CONFIG
 * @phba: pointer to lpfc hba data structure.
 * @rd_config: pointer to read config data
 *
 * This routine is invoked to map the topology values as read
 * from the read config mailbox command. If the persistent
 * topology feature is supported, the firmware will provide the
 * saved topology information to be used in INIT_LINK
 **/
static void
lpfc_map_topology(struct lpfc_hba *phba, struct lpfc_mbx_read_config *rd_config)
{
	u8 ptv, tf, pt;

	ptv = bf_get(lpfc_mbx_rd_conf_ptv, rd_config);
	tf = bf_get(lpfc_mbx_rd_conf_tf, rd_config);
	pt = bf_get(lpfc_mbx_rd_conf_pt, rd_config);

	lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
			"2027 Read Config Data : ptv:0x%x, tf:0x%x pt:0x%x",
			 ptv, tf, pt);
	if (!ptv) {
		lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
				"2019 FW does not support persistent topology "
				"Using driver parameter defined value [%s]",
				lpfc_topo_to_str[phba->cfg_topology]);
		return;
	}
	/* FW supports persistent topology - override module parameter value */
	phba->hba_flag |= HBA_PERSISTENT_TOPO;

	/* if ASIC_GEN_NUM >= 0xC) */
	if ((bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
		    LPFC_SLI_INTF_IF_TYPE_6) ||
	    (bf_get(lpfc_sli_intf_sli_family, &phba->sli4_hba.sli_intf) ==
		    LPFC_SLI_INTF_FAMILY_G6)) {
		if (!tf) {
			phba->cfg_topology = ((pt == LINK_FLAGS_LOOP)
					? FLAGS_TOPOLOGY_MODE_LOOP
					: FLAGS_TOPOLOGY_MODE_PT_PT);
		} else {
			phba->hba_flag &= ~HBA_PERSISTENT_TOPO;
		}
	} else { /* G5 */
		if (tf) {
			/* If topology failover set - pt is '0' or '1' */
			phba->cfg_topology = (pt ? FLAGS_TOPOLOGY_MODE_PT_LOOP :
					      FLAGS_TOPOLOGY_MODE_LOOP_PT);
		} else {
			phba->cfg_topology = ((pt == LINK_FLAGS_P2P)
					? FLAGS_TOPOLOGY_MODE_PT_PT
					: FLAGS_TOPOLOGY_MODE_LOOP);
		}
	}
	if (phba->hba_flag & HBA_PERSISTENT_TOPO) {
		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
				"2020 Using persistent topology value [%s]",
				lpfc_topo_to_str[phba->cfg_topology]);
	} else {
		lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
				"2021 Invalid topology values from FW "
				"Using driver parameter defined value [%s]",
				lpfc_topo_to_str[phba->cfg_topology]);
	}
}

/**
 * lpfc_sli4_read_config - Get the config parameters.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to read the configuration parameters from the HBA.
 * The configuration parameters are used to set the base and maximum values
 * for RPI's XRI's VPI's VFI's and FCFIs. These values also affect the resource
 * allocation for the port.
 *
 * Return codes
 * 	0 - successful
 * 	-ENOMEM - No available memory
 *      -EIO - The mailbox failed to complete successfully.
 **/
int
lpfc_sli4_read_config(struct lpfc_hba *phba)
{
	LPFC_MBOXQ_t *pmb;
	struct lpfc_mbx_read_config *rd_config;
	union  lpfc_sli4_cfg_shdr *shdr;
	uint32_t shdr_status, shdr_add_status;
	struct lpfc_mbx_get_func_cfg *get_func_cfg;
	struct lpfc_rsrc_desc_fcfcoe *desc;
	char *pdesc_0;
	uint16_t forced_link_speed;
	uint32_t if_type, qmin;
	int length, i, rc = 0, rc2;

	pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (!pmb) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2011 Unable to allocate memory for issuing "
				"SLI_CONFIG_SPECIAL mailbox command\n");
		return -ENOMEM;
	}

	lpfc_read_config(phba, pmb);

	rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
	if (rc != MBX_SUCCESS) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2012 Mailbox failed , mbxCmd x%x "
				"READ_CONFIG, mbxStatus x%x\n",
				bf_get(lpfc_mqe_command, &pmb->u.mqe),
				bf_get(lpfc_mqe_status, &pmb->u.mqe));
		rc = -EIO;
	} else {
		rd_config = &pmb->u.mqe.un.rd_config;
		if (bf_get(lpfc_mbx_rd_conf_lnk_ldv, rd_config)) {
			phba->sli4_hba.lnk_info.lnk_dv = LPFC_LNK_DAT_VAL;
			phba->sli4_hba.lnk_info.lnk_tp =
				bf_get(lpfc_mbx_rd_conf_lnk_type, rd_config);
			phba->sli4_hba.lnk_info.lnk_no =
				bf_get(lpfc_mbx_rd_conf_lnk_numb, rd_config);
			lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
					"3081 lnk_type:%d, lnk_numb:%d\n",
					phba->sli4_hba.lnk_info.lnk_tp,
					phba->sli4_hba.lnk_info.lnk_no);
		} else
			lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
					"3082 Mailbox (x%x) returned ldv:x0\n",
					bf_get(lpfc_mqe_command, &pmb->u.mqe));
		if (bf_get(lpfc_mbx_rd_conf_bbscn_def, rd_config)) {
			phba->bbcredit_support = 1;
			phba->sli4_hba.bbscn_params.word0 = rd_config->word8;
		}

		phba->sli4_hba.conf_trunk =
			bf_get(lpfc_mbx_rd_conf_trunk, rd_config);
		phba->sli4_hba.extents_in_use =
			bf_get(lpfc_mbx_rd_conf_extnts_inuse, rd_config);
		phba->sli4_hba.max_cfg_param.max_xri =
			bf_get(lpfc_mbx_rd_conf_xri_count, rd_config);
		/* Reduce resource usage in kdump environment */
		if (is_kdump_kernel() &&
		    phba->sli4_hba.max_cfg_param.max_xri > 512)
			phba->sli4_hba.max_cfg_param.max_xri = 512;
		phba->sli4_hba.max_cfg_param.xri_base =
			bf_get(lpfc_mbx_rd_conf_xri_base, rd_config);
		phba->sli4_hba.max_cfg_param.max_vpi =
			bf_get(lpfc_mbx_rd_conf_vpi_count, rd_config);
		/* Limit the max we support */
		if (phba->sli4_hba.max_cfg_param.max_vpi > LPFC_MAX_VPORTS)
			phba->sli4_hba.max_cfg_param.max_vpi = LPFC_MAX_VPORTS;
		phba->sli4_hba.max_cfg_param.vpi_base =
			bf_get(lpfc_mbx_rd_conf_vpi_base, rd_config);
		phba->sli4_hba.max_cfg_param.max_rpi =
			bf_get(lpfc_mbx_rd_conf_rpi_count, rd_config);
		phba->sli4_hba.max_cfg_param.rpi_base =
			bf_get(lpfc_mbx_rd_conf_rpi_base, rd_config);
		phba->sli4_hba.max_cfg_param.max_vfi =
			bf_get(lpfc_mbx_rd_conf_vfi_count, rd_config);
		phba->sli4_hba.max_cfg_param.vfi_base =
			bf_get(lpfc_mbx_rd_conf_vfi_base, rd_config);
		phba->sli4_hba.max_cfg_param.max_fcfi =
			bf_get(lpfc_mbx_rd_conf_fcfi_count, rd_config);
		phba->sli4_hba.max_cfg_param.max_eq =
			bf_get(lpfc_mbx_rd_conf_eq_count, rd_config);
		phba->sli4_hba.max_cfg_param.max_rq =
			bf_get(lpfc_mbx_rd_conf_rq_count, rd_config);
		phba->sli4_hba.max_cfg_param.max_wq =
			bf_get(lpfc_mbx_rd_conf_wq_count, rd_config);
		phba->sli4_hba.max_cfg_param.max_cq =
			bf_get(lpfc_mbx_rd_conf_cq_count, rd_config);
		phba->lmt = bf_get(lpfc_mbx_rd_conf_lmt, rd_config);
		phba->sli4_hba.next_xri = phba->sli4_hba.max_cfg_param.xri_base;
		phba->vpi_base = phba->sli4_hba.max_cfg_param.vpi_base;
		phba->vfi_base = phba->sli4_hba.max_cfg_param.vfi_base;
		phba->max_vpi = (phba->sli4_hba.max_cfg_param.max_vpi > 0) ?
				(phba->sli4_hba.max_cfg_param.max_vpi - 1) : 0;
		phba->max_vports = phba->max_vpi;

		/* Next decide on FPIN or Signal E2E CGN support
		 * For congestion alarms and warnings valid combination are:
		 * 1. FPIN alarms / FPIN warnings
		 * 2. Signal alarms / Signal warnings
		 * 3. FPIN alarms / Signal warnings
		 * 4. Signal alarms / FPIN warnings
		 *
		 * Initialize the adapter frequency to 100 mSecs
		 */
		phba->cgn_reg_fpin = LPFC_CGN_FPIN_BOTH;
		phba->cgn_reg_signal = EDC_CG_SIG_NOTSUPPORTED;
		phba->cgn_sig_freq = lpfc_fabric_cgn_frequency;

		if (lpfc_use_cgn_signal) {
			if (bf_get(lpfc_mbx_rd_conf_wcs, rd_config)) {
				phba->cgn_reg_signal = EDC_CG_SIG_WARN_ONLY;
				phba->cgn_reg_fpin &= ~LPFC_CGN_FPIN_WARN;
			}
			if (bf_get(lpfc_mbx_rd_conf_acs, rd_config)) {
				/* MUST support both alarm and warning
				 * because EDC does not support alarm alone.
				 */
				if (phba->cgn_reg_signal !=
				    EDC_CG_SIG_WARN_ONLY) {
					/* Must support both or none */
					phba->cgn_reg_fpin = LPFC_CGN_FPIN_BOTH;
					phba->cgn_reg_signal =
						EDC_CG_SIG_NOTSUPPORTED;
				} else {
					phba->cgn_reg_signal =
						EDC_CG_SIG_WARN_ALARM;
					phba->cgn_reg_fpin =
						LPFC_CGN_FPIN_NONE;
				}
			}
		}

		/* Set the congestion initial signal and fpin values. */
		phba->cgn_init_reg_fpin = phba->cgn_reg_fpin;
		phba->cgn_init_reg_signal = phba->cgn_reg_signal;

		lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
				"6446 READ_CONFIG reg_sig x%x reg_fpin:x%x\n",
				phba->cgn_reg_signal, phba->cgn_reg_fpin);

		lpfc_map_topology(phba, rd_config);
		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
				"2003 cfg params Extents? %d "
				"XRI(B:%d M:%d), "
				"VPI(B:%d M:%d) "
				"VFI(B:%d M:%d) "
				"RPI(B:%d M:%d) "
				"FCFI:%d EQ:%d CQ:%d WQ:%d RQ:%d lmt:x%x\n",
				phba->sli4_hba.extents_in_use,
				phba->sli4_hba.max_cfg_param.xri_base,
				phba->sli4_hba.max_cfg_param.max_xri,
				phba->sli4_hba.max_cfg_param.vpi_base,
				phba->sli4_hba.max_cfg_param.max_vpi,
				phba->sli4_hba.max_cfg_param.vfi_base,
				phba->sli4_hba.max_cfg_param.max_vfi,
				phba->sli4_hba.max_cfg_param.rpi_base,
				phba->sli4_hba.max_cfg_param.max_rpi,
				phba->sli4_hba.max_cfg_param.max_fcfi,
				phba->sli4_hba.max_cfg_param.max_eq,
				phba->sli4_hba.max_cfg_param.max_cq,
				phba->sli4_hba.max_cfg_param.max_wq,
				phba->sli4_hba.max_cfg_param.max_rq,
				phba->lmt);

		/*
		 * Calculate queue resources based on how
		 * many WQ/CQ/EQs are available.
		 */
		qmin = phba->sli4_hba.max_cfg_param.max_wq;
		if (phba->sli4_hba.max_cfg_param.max_cq < qmin)
			qmin = phba->sli4_hba.max_cfg_param.max_cq;
		if (phba->sli4_hba.max_cfg_param.max_eq < qmin)
			qmin = phba->sli4_hba.max_cfg_param.max_eq;
		/*
		 * Whats left after this can go toward NVME / FCP.
		 * The minus 4 accounts for ELS, NVME LS, MBOX
		 * plus one extra. When configured for
		 * NVMET, FCP io channel WQs are not created.
		 */
		qmin -= 4;

		/* Check to see if there is enough for NVME */
		if ((phba->cfg_irq_chann > qmin) ||
		    (phba->cfg_hdw_queue > qmin)) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"2005 Reducing Queues - "
					"FW resource limitation: "
					"WQ %d CQ %d EQ %d: min %d: "
					"IRQ %d HDWQ %d\n",
					phba->sli4_hba.max_cfg_param.max_wq,
					phba->sli4_hba.max_cfg_param.max_cq,
					phba->sli4_hba.max_cfg_param.max_eq,
					qmin, phba->cfg_irq_chann,
					phba->cfg_hdw_queue);

			if (phba->cfg_irq_chann > qmin)
				phba->cfg_irq_chann = qmin;
			if (phba->cfg_hdw_queue > qmin)
				phba->cfg_hdw_queue = qmin;
		}
	}

	if (rc)
		goto read_cfg_out;

	/* Update link speed if forced link speed is supported */
	if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
	if (if_type >= LPFC_SLI_INTF_IF_TYPE_2) {
		forced_link_speed =
			bf_get(lpfc_mbx_rd_conf_link_speed, rd_config);
		if (forced_link_speed) {
			phba->hba_flag |= HBA_FORCED_LINK_SPEED;

			switch (forced_link_speed) {
			case LINK_SPEED_1G:
				phba->cfg_link_speed =
					LPFC_USER_LINK_SPEED_1G;
				break;
			case LINK_SPEED_2G:
				phba->cfg_link_speed =
					LPFC_USER_LINK_SPEED_2G;
				break;
			case LINK_SPEED_4G:
				phba->cfg_link_speed =
					LPFC_USER_LINK_SPEED_4G;
				break;
			case LINK_SPEED_8G:
				phba->cfg_link_speed =
					LPFC_USER_LINK_SPEED_8G;
				break;
			case LINK_SPEED_10G:
				phba->cfg_link_speed =
					LPFC_USER_LINK_SPEED_10G;
				break;
			case LINK_SPEED_16G:
				phba->cfg_link_speed =
					LPFC_USER_LINK_SPEED_16G;
				break;
			case LINK_SPEED_32G:
				phba->cfg_link_speed =
					LPFC_USER_LINK_SPEED_32G;
				break;
			case LINK_SPEED_64G:
				phba->cfg_link_speed =
					LPFC_USER_LINK_SPEED_64G;
				break;
			case 0xffff:
				phba->cfg_link_speed =
					LPFC_USER_LINK_SPEED_AUTO;
				break;
			default:
				lpfc_printf_log(phba, KERN_ERR,
						LOG_TRACE_EVENT,
						"0047 Unrecognized link "
						"speed : %d\n",
						forced_link_speed);
				phba->cfg_link_speed =
					LPFC_USER_LINK_SPEED_AUTO;
			}
		}
	}

	/* Reset the DFT_HBA_Q_DEPTH to the max xri  */
	length = phba->sli4_hba.max_cfg_param.max_xri -
			lpfc_sli4_get_els_iocb_cnt(phba);
	if (phba->cfg_hba_queue_depth > length) {
		lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
				"3361 HBA queue depth changed from %d to %d\n",
				phba->cfg_hba_queue_depth, length);
		phba->cfg_hba_queue_depth = length;
	}

	if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
	    LPFC_SLI_INTF_IF_TYPE_2)
		goto read_cfg_out;

	/* get the pf# and vf# for SLI4 if_type 2 port */
	length = (sizeof(struct lpfc_mbx_get_func_cfg) -
		  sizeof(struct lpfc_sli4_cfg_mhdr));
	lpfc_sli4_config(phba, pmb, LPFC_MBOX_SUBSYSTEM_COMMON,
			 LPFC_MBOX_OPCODE_GET_FUNCTION_CONFIG,
			 length, LPFC_SLI4_MBX_EMBED);

	rc2 = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
	shdr = (union lpfc_sli4_cfg_shdr *)
				&pmb->u.mqe.un.sli4_config.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);
	if (rc2 || shdr_status || shdr_add_status) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3026 Mailbox failed , mbxCmd x%x "
				"GET_FUNCTION_CONFIG, mbxStatus x%x\n",
				bf_get(lpfc_mqe_command, &pmb->u.mqe),
				bf_get(lpfc_mqe_status, &pmb->u.mqe));
		goto read_cfg_out;
	}

	/* search for fc_fcoe resrouce descriptor */
	get_func_cfg = &pmb->u.mqe.un.get_func_cfg;

	pdesc_0 = (char *)&get_func_cfg->func_cfg.desc[0];
	desc = (struct lpfc_rsrc_desc_fcfcoe *)pdesc_0;
	length = bf_get(lpfc_rsrc_desc_fcfcoe_length, desc);
	if (length == LPFC_RSRC_DESC_TYPE_FCFCOE_V0_RSVD)
		length = LPFC_RSRC_DESC_TYPE_FCFCOE_V0_LENGTH;
	else if (length != LPFC_RSRC_DESC_TYPE_FCFCOE_V1_LENGTH)
		goto read_cfg_out;

	for (i = 0; i < LPFC_RSRC_DESC_MAX_NUM; i++) {
		desc = (struct lpfc_rsrc_desc_fcfcoe *)(pdesc_0 + length * i);
		if (LPFC_RSRC_DESC_TYPE_FCFCOE ==
		    bf_get(lpfc_rsrc_desc_fcfcoe_type, desc)) {
			phba->sli4_hba.iov.pf_number =
				bf_get(lpfc_rsrc_desc_fcfcoe_pfnum, desc);
			phba->sli4_hba.iov.vf_number =
				bf_get(lpfc_rsrc_desc_fcfcoe_vfnum, desc);
			break;
		}
	}

	if (i < LPFC_RSRC_DESC_MAX_NUM)
		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
				"3027 GET_FUNCTION_CONFIG: pf_number:%d, "
				"vf_number:%d\n", phba->sli4_hba.iov.pf_number,
				phba->sli4_hba.iov.vf_number);
	else
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3028 GET_FUNCTION_CONFIG: failed to find "
				"Resource Descriptor:x%x\n",
				LPFC_RSRC_DESC_TYPE_FCFCOE);

read_cfg_out:
	mempool_free(pmb, phba->mbox_mem_pool);
	return rc;
}

/**
 * lpfc_setup_endian_order - Write endian order to an SLI4 if_type 0 port.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to setup the port-side endian order when
 * the port if_type is 0.  This routine has no function for other
 * if_types.
 *
 * Return codes
 * 	0 - successful
 * 	-ENOMEM - No available memory
 *      -EIO - The mailbox failed to complete successfully.
 **/
static int
lpfc_setup_endian_order(struct lpfc_hba *phba)
{
	LPFC_MBOXQ_t *mboxq;
	uint32_t if_type, rc = 0;
	uint32_t endian_mb_data[2] = {HOST_ENDIAN_LOW_WORD0,
				      HOST_ENDIAN_HIGH_WORD1};

	if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
	switch (if_type) {
	case LPFC_SLI_INTF_IF_TYPE_0:
		mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
						       GFP_KERNEL);
		if (!mboxq) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"0492 Unable to allocate memory for "
					"issuing SLI_CONFIG_SPECIAL mailbox "
					"command\n");
			return -ENOMEM;
		}

		/*
		 * The SLI4_CONFIG_SPECIAL mailbox command requires the first
		 * two words to contain special data values and no other data.
		 */
		memset(mboxq, 0, sizeof(LPFC_MBOXQ_t));
		memcpy(&mboxq->u.mqe, &endian_mb_data, sizeof(endian_mb_data));
		rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
		if (rc != MBX_SUCCESS) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"0493 SLI_CONFIG_SPECIAL mailbox "
					"failed with status x%x\n",
					rc);
			rc = -EIO;
		}
		mempool_free(mboxq, phba->mbox_mem_pool);
		break;
	case LPFC_SLI_INTF_IF_TYPE_6:
	case LPFC_SLI_INTF_IF_TYPE_2:
	case LPFC_SLI_INTF_IF_TYPE_1:
	default:
		break;
	}
	return rc;
}

/**
 * lpfc_sli4_queue_verify - Verify and update EQ counts
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to check the user settable queue counts for EQs.
 * After this routine is called the counts will be set to valid values that
 * adhere to the constraints of the system's interrupt vectors and the port's
 * queue resources.
 *
 * Return codes
 *      0 - successful
 *      -ENOMEM - No available memory
 **/
static int
lpfc_sli4_queue_verify(struct lpfc_hba *phba)
{
	/*
	 * Sanity check for configured queue parameters against the run-time
	 * device parameters
	 */

	if (phba->nvmet_support) {
		if (phba->cfg_hdw_queue < phba->cfg_nvmet_mrq)
			phba->cfg_nvmet_mrq = phba->cfg_hdw_queue;
		if (phba->cfg_nvmet_mrq > LPFC_NVMET_MRQ_MAX)
			phba->cfg_nvmet_mrq = LPFC_NVMET_MRQ_MAX;
	}

	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
			"2574 IO channels: hdwQ %d IRQ %d MRQ: %d\n",
			phba->cfg_hdw_queue, phba->cfg_irq_chann,
			phba->cfg_nvmet_mrq);

	/* Get EQ depth from module parameter, fake the default for now */
	phba->sli4_hba.eq_esize = LPFC_EQE_SIZE_4B;
	phba->sli4_hba.eq_ecount = LPFC_EQE_DEF_COUNT;

	/* Get CQ depth from module parameter, fake the default for now */
	phba->sli4_hba.cq_esize = LPFC_CQE_SIZE;
	phba->sli4_hba.cq_ecount = LPFC_CQE_DEF_COUNT;
	return 0;
}

static int
lpfc_alloc_io_wq_cq(struct lpfc_hba *phba, int idx)
{
	struct lpfc_queue *qdesc;
	u32 wqesize;
	int cpu;

	cpu = lpfc_find_cpu_handle(phba, idx, LPFC_FIND_BY_HDWQ);
	/* Create Fast Path IO CQs */
	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,
					      LPFC_CQE_EXP_COUNT, cpu);

	else
		qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
					      phba->sli4_hba.cq_esize,
					      phba->sli4_hba.cq_ecount, cpu);
	if (!qdesc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0499 Failed allocate fast-path IO CQ (%d)\n",
				idx);
		return 1;
	}
	qdesc->qe_valid = 1;
	qdesc->hdwq = idx;
	qdesc->chann = cpu;
	phba->sli4_hba.hdwq[idx].io_cq = qdesc;

	/* Create Fast Path IO WQs */
	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,
					      wqesize,
					      LPFC_WQE_EXP_COUNT, cpu);
	} else
		qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
					      phba->sli4_hba.wq_esize,
					      phba->sli4_hba.wq_ecount, cpu);

	if (!qdesc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0503 Failed allocate fast-path IO WQ (%d)\n",
				idx);
		return 1;
	}
	qdesc->hdwq = idx;
	qdesc->chann = cpu;
	phba->sli4_hba.hdwq[idx].io_wq = qdesc;
	list_add_tail(&qdesc->wq_list, &phba->sli4_hba.lpfc_wq_list);
	return 0;
}

/**
 * lpfc_sli4_queue_create - Create all the SLI4 queues
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to allocate all the SLI4 queues for the FCoE HBA
 * operation. For each SLI4 queue type, the parameters such as queue entry
 * count (queue depth) shall be taken from the module parameter. For now,
 * we just use some constant number as place holder.
 *
 * Return codes
 *      0 - successful
 *      -ENOMEM - No availble memory
 *      -EIO - The mailbox failed to complete successfully.
 **/
int
lpfc_sli4_queue_create(struct lpfc_hba *phba)
{
	struct lpfc_queue *qdesc;
	int idx, cpu, eqcpu;
	struct lpfc_sli4_hdw_queue *qp;
	struct lpfc_vector_map_info *cpup;
	struct lpfc_vector_map_info *eqcpup;
	struct lpfc_eq_intr_info *eqi;

	/*
	 * Create HBA Record arrays.
	 * Both NVME and FCP will share that same vectors / EQs
	 */
	phba->sli4_hba.mq_esize = LPFC_MQE_SIZE;
	phba->sli4_hba.mq_ecount = LPFC_MQE_DEF_COUNT;
	phba->sli4_hba.wq_esize = LPFC_WQE_SIZE;
	phba->sli4_hba.wq_ecount = LPFC_WQE_DEF_COUNT;
	phba->sli4_hba.rq_esize = LPFC_RQE_SIZE;
	phba->sli4_hba.rq_ecount = LPFC_RQE_DEF_COUNT;
	phba->sli4_hba.eq_esize = LPFC_EQE_SIZE_4B;
	phba->sli4_hba.eq_ecount = LPFC_EQE_DEF_COUNT;
	phba->sli4_hba.cq_esize = LPFC_CQE_SIZE;
	phba->sli4_hba.cq_ecount = LPFC_CQE_DEF_COUNT;

	if (!phba->sli4_hba.hdwq) {
		phba->sli4_hba.hdwq = kcalloc(
			phba->cfg_hdw_queue, sizeof(struct lpfc_sli4_hdw_queue),
			GFP_KERNEL);
		if (!phba->sli4_hba.hdwq) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"6427 Failed allocate memory for "
					"fast-path Hardware Queue array\n");
			goto out_error;
		}
		/* Prepare hardware queues to take IO buffers */
		for (idx = 0; idx < phba->cfg_hdw_queue; idx++) {
			qp = &phba->sli4_hba.hdwq[idx];
			spin_lock_init(&qp->io_buf_list_get_lock);
			spin_lock_init(&qp->io_buf_list_put_lock);
			INIT_LIST_HEAD(&qp->lpfc_io_buf_list_get);
			INIT_LIST_HEAD(&qp->lpfc_io_buf_list_put);
			qp->get_io_bufs = 0;
			qp->put_io_bufs = 0;
			qp->total_io_bufs = 0;
			spin_lock_init(&qp->abts_io_buf_list_lock);
			INIT_LIST_HEAD(&qp->lpfc_abts_io_buf_list);
			qp->abts_scsi_io_bufs = 0;
			qp->abts_nvme_io_bufs = 0;
			INIT_LIST_HEAD(&qp->sgl_list);
			INIT_LIST_HEAD(&qp->cmd_rsp_buf_list);
			spin_lock_init(&qp->hdwq_lock);
		}
	}

	if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
		if (phba->nvmet_support) {
			phba->sli4_hba.nvmet_cqset = kcalloc(
					phba->cfg_nvmet_mrq,
					sizeof(struct lpfc_queue *),
					GFP_KERNEL);
			if (!phba->sli4_hba.nvmet_cqset) {
				lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"3121 Fail allocate memory for "
					"fast-path CQ set array\n");
				goto out_error;
			}
			phba->sli4_hba.nvmet_mrq_hdr = kcalloc(
					phba->cfg_nvmet_mrq,
					sizeof(struct lpfc_queue *),
					GFP_KERNEL);
			if (!phba->sli4_hba.nvmet_mrq_hdr) {
				lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"3122 Fail allocate memory for "
					"fast-path RQ set hdr array\n");
				goto out_error;
			}
			phba->sli4_hba.nvmet_mrq_data = kcalloc(
					phba->cfg_nvmet_mrq,
					sizeof(struct lpfc_queue *),
					GFP_KERNEL);
			if (!phba->sli4_hba.nvmet_mrq_data) {
				lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"3124 Fail allocate memory for "
					"fast-path RQ set data array\n");
				goto out_error;
			}
		}
	}

	INIT_LIST_HEAD(&phba->sli4_hba.lpfc_wq_list);

	/* Create HBA Event Queues (EQs) */
	for_each_present_cpu(cpu) {
		/* We only want to create 1 EQ per vector, even though
		 * multiple CPUs might be using that vector. so only
		 * selects the CPUs that are LPFC_CPU_FIRST_IRQ.
		 */
		cpup = &phba->sli4_hba.cpu_map[cpu];
		if (!(cpup->flag & LPFC_CPU_FIRST_IRQ))
			continue;

		/* Get a ptr to the Hardware Queue associated with this CPU */
		qp = &phba->sli4_hba.hdwq[cpup->hdwq];

		/* Allocate an EQ */
		qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
					      phba->sli4_hba.eq_esize,
					      phba->sli4_hba.eq_ecount, cpu);
		if (!qdesc) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"0497 Failed allocate EQ (%d)\n",
					cpup->hdwq);
			goto out_error;
		}
		qdesc->qe_valid = 1;
		qdesc->hdwq = cpup->hdwq;
		qdesc->chann = cpu; /* First CPU this EQ is affinitized to */
		qdesc->last_cpu = qdesc->chann;

		/* Save the allocated EQ in the Hardware Queue */
		qp->hba_eq = qdesc;

		eqi = per_cpu_ptr(phba->sli4_hba.eq_info, qdesc->last_cpu);
		list_add(&qdesc->cpu_list, &eqi->list);
	}

	/* Now we need to populate the other Hardware Queues, that share
	 * an IRQ vector, with the associated EQ ptr.
	 */
	for_each_present_cpu(cpu) {
		cpup = &phba->sli4_hba.cpu_map[cpu];

		/* Check for EQ already allocated in previous loop */
		if (cpup->flag & LPFC_CPU_FIRST_IRQ)
			continue;

		/* Check for multiple CPUs per hdwq */
		qp = &phba->sli4_hba.hdwq[cpup->hdwq];
		if (qp->hba_eq)
			continue;

		/* We need to share an EQ for this hdwq */
		eqcpu = lpfc_find_cpu_handle(phba, cpup->eq, LPFC_FIND_BY_EQ);
		eqcpup = &phba->sli4_hba.cpu_map[eqcpu];
		qp->hba_eq = phba->sli4_hba.hdwq[eqcpup->hdwq].hba_eq;
	}

	/* Allocate IO Path SLI4 CQ/WQs */
	for (idx = 0; idx < phba->cfg_hdw_queue; idx++) {
		if (lpfc_alloc_io_wq_cq(phba, idx))
			goto out_error;
	}

	if (phba->nvmet_support) {
		for (idx = 0; idx < phba->cfg_nvmet_mrq; idx++) {
			cpu = lpfc_find_cpu_handle(phba, idx,
						   LPFC_FIND_BY_HDWQ);
			qdesc = lpfc_sli4_queue_alloc(phba,
						      LPFC_DEFAULT_PAGE_SIZE,
						      phba->sli4_hba.cq_esize,
						      phba->sli4_hba.cq_ecount,
						      cpu);
			if (!qdesc) {
				lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
						"3142 Failed allocate NVME "
						"CQ Set (%d)\n", idx);
				goto out_error;
			}
			qdesc->qe_valid = 1;
			qdesc->hdwq = idx;
			qdesc->chann = cpu;
			phba->sli4_hba.nvmet_cqset[idx] = qdesc;
		}
	}

	/*
	 * Create Slow Path Completion Queues (CQs)
	 */

	cpu = lpfc_find_cpu_handle(phba, 0, LPFC_FIND_BY_EQ);
	/* Create slow-path Mailbox Command Complete Queue */
	qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
				      phba->sli4_hba.cq_esize,
				      phba->sli4_hba.cq_ecount, cpu);
	if (!qdesc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0500 Failed allocate slow-path mailbox CQ\n");
		goto out_error;
	}
	qdesc->qe_valid = 1;
	phba->sli4_hba.mbx_cq = qdesc;

	/* Create slow-path ELS Complete Queue */
	qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
				      phba->sli4_hba.cq_esize,
				      phba->sli4_hba.cq_ecount, cpu);
	if (!qdesc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0501 Failed allocate slow-path ELS CQ\n");
		goto out_error;
	}
	qdesc->qe_valid = 1;
	qdesc->chann = cpu;
	phba->sli4_hba.els_cq = qdesc;


	/*
	 * Create Slow Path Work Queues (WQs)
	 */

	/* Create Mailbox Command Queue */

	qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
				      phba->sli4_hba.mq_esize,
				      phba->sli4_hba.mq_ecount, cpu);
	if (!qdesc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0505 Failed allocate slow-path MQ\n");
		goto out_error;
	}
	qdesc->chann = cpu;
	phba->sli4_hba.mbx_wq = qdesc;

	/*
	 * Create ELS Work Queues
	 */

	/* Create slow-path ELS Work Queue */
	qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
				      phba->sli4_hba.wq_esize,
				      phba->sli4_hba.wq_ecount, cpu);
	if (!qdesc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0504 Failed allocate slow-path ELS WQ\n");
		goto out_error;
	}
	qdesc->chann = cpu;
	phba->sli4_hba.els_wq = qdesc;
	list_add_tail(&qdesc->wq_list, &phba->sli4_hba.lpfc_wq_list);

	if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
		/* Create NVME LS Complete Queue */
		qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
					      phba->sli4_hba.cq_esize,
					      phba->sli4_hba.cq_ecount, cpu);
		if (!qdesc) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"6079 Failed allocate NVME LS CQ\n");
			goto out_error;
		}
		qdesc->chann = cpu;
		qdesc->qe_valid = 1;
		phba->sli4_hba.nvmels_cq = qdesc;

		/* Create NVME LS Work Queue */
		qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
					      phba->sli4_hba.wq_esize,
					      phba->sli4_hba.wq_ecount, cpu);
		if (!qdesc) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"6080 Failed allocate NVME LS WQ\n");
			goto out_error;
		}
		qdesc->chann = cpu;
		phba->sli4_hba.nvmels_wq = qdesc;
		list_add_tail(&qdesc->wq_list, &phba->sli4_hba.lpfc_wq_list);
	}

	/*
	 * Create Receive Queue (RQ)
	 */

	/* Create Receive Queue for header */
	qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
				      phba->sli4_hba.rq_esize,
				      phba->sli4_hba.rq_ecount, cpu);
	if (!qdesc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0506 Failed allocate receive HRQ\n");
		goto out_error;
	}
	phba->sli4_hba.hdr_rq = qdesc;

	/* Create Receive Queue for data */
	qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
				      phba->sli4_hba.rq_esize,
				      phba->sli4_hba.rq_ecount, cpu);
	if (!qdesc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0507 Failed allocate receive DRQ\n");
		goto out_error;
	}
	phba->sli4_hba.dat_rq = qdesc;

	if ((phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) &&
	    phba->nvmet_support) {
		for (idx = 0; idx < phba->cfg_nvmet_mrq; idx++) {
			cpu = lpfc_find_cpu_handle(phba, idx,
						   LPFC_FIND_BY_HDWQ);
			/* Create NVMET Receive Queue for header */
			qdesc = lpfc_sli4_queue_alloc(phba,
						      LPFC_DEFAULT_PAGE_SIZE,
						      phba->sli4_hba.rq_esize,
						      LPFC_NVMET_RQE_DEF_COUNT,
						      cpu);
			if (!qdesc) {
				lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
						"3146 Failed allocate "
						"receive HRQ\n");
				goto out_error;
			}
			qdesc->hdwq = idx;
			phba->sli4_hba.nvmet_mrq_hdr[idx] = qdesc;

			/* Only needed for header of RQ pair */
			qdesc->rqbp = kzalloc_node(sizeof(*qdesc->rqbp),
						   GFP_KERNEL,
						   cpu_to_node(cpu));
			if (qdesc->rqbp == NULL) {
				lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
						"6131 Failed allocate "
						"Header RQBP\n");
				goto out_error;
			}

			/* Put list in known state in case driver load fails. */
			INIT_LIST_HEAD(&qdesc->rqbp->rqb_buffer_list);

			/* Create NVMET Receive Queue for data */
			qdesc = lpfc_sli4_queue_alloc(phba,
						      LPFC_DEFAULT_PAGE_SIZE,
						      phba->sli4_hba.rq_esize,
						      LPFC_NVMET_RQE_DEF_COUNT,
						      cpu);
			if (!qdesc) {
				lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
						"3156 Failed allocate "
						"receive DRQ\n");
				goto out_error;
			}
			qdesc->hdwq = idx;
			phba->sli4_hba.nvmet_mrq_data[idx] = qdesc;
		}
	}

	/* Clear NVME stats */
	if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
		for (idx = 0; idx < phba->cfg_hdw_queue; idx++) {
			memset(&phba->sli4_hba.hdwq[idx].nvme_cstat, 0,
			       sizeof(phba->sli4_hba.hdwq[idx].nvme_cstat));
		}
	}

	/* Clear SCSI stats */
	if (phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP) {
		for (idx = 0; idx < phba->cfg_hdw_queue; idx++) {
			memset(&phba->sli4_hba.hdwq[idx].scsi_cstat, 0,
			       sizeof(phba->sli4_hba.hdwq[idx].scsi_cstat));
		}
	}

	return 0;

out_error:
	lpfc_sli4_queue_destroy(phba);
	return -ENOMEM;
}

static inline void
__lpfc_sli4_release_queue(struct lpfc_queue **qp)
{
	if (*qp != NULL) {
		lpfc_sli4_queue_free(*qp);
		*qp = NULL;
	}
}

static inline void
lpfc_sli4_release_queues(struct lpfc_queue ***qs, int max)
{
	int idx;

	if (*qs == NULL)
		return;

	for (idx = 0; idx < max; idx++)
		__lpfc_sli4_release_queue(&(*qs)[idx]);

	kfree(*qs);
	*qs = NULL;
}

static inline void
lpfc_sli4_release_hdwq(struct lpfc_hba *phba)
{
	struct lpfc_sli4_hdw_queue *hdwq;
	struct lpfc_queue *eq;
	uint32_t idx;

	hdwq = phba->sli4_hba.hdwq;

	/* Loop thru all Hardware Queues */
	for (idx = 0; idx < phba->cfg_hdw_queue; idx++) {
		/* Free the CQ/WQ corresponding to the Hardware Queue */
		lpfc_sli4_queue_free(hdwq[idx].io_cq);
		lpfc_sli4_queue_free(hdwq[idx].io_wq);
		hdwq[idx].hba_eq = NULL;
		hdwq[idx].io_cq = NULL;
		hdwq[idx].io_wq = NULL;
		if (phba->cfg_xpsgl && !phba->nvmet_support)
			lpfc_free_sgl_per_hdwq(phba, &hdwq[idx]);
		lpfc_free_cmd_rsp_buf_per_hdwq(phba, &hdwq[idx]);
	}
	/* Loop thru all IRQ vectors */
	for (idx = 0; idx < phba->cfg_irq_chann; idx++) {
		/* Free the EQ corresponding to the IRQ vector */
		eq = phba->sli4_hba.hba_eq_hdl[idx].eq;
		lpfc_sli4_queue_free(eq);
		phba->sli4_hba.hba_eq_hdl[idx].eq = NULL;
	}
}

/**
 * lpfc_sli4_queue_destroy - Destroy all the SLI4 queues
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to release all the SLI4 queues with the FCoE HBA
 * operation.
 *
 * Return codes
 *      0 - successful
 *      -ENOMEM - No available memory
 *      -EIO - The mailbox failed to complete successfully.
 **/
void
lpfc_sli4_queue_destroy(struct lpfc_hba *phba)
{
	/*
	 * Set FREE_INIT before beginning to free the queues.
	 * Wait until the users of queues to acknowledge to
	 * release queues by clearing FREE_WAIT.
	 */
	spin_lock_irq(&phba->hbalock);
	phba->sli.sli_flag |= LPFC_QUEUE_FREE_INIT;
	while (phba->sli.sli_flag & LPFC_QUEUE_FREE_WAIT) {
		spin_unlock_irq(&phba->hbalock);
		msleep(20);
		spin_lock_irq(&phba->hbalock);
	}
	spin_unlock_irq(&phba->hbalock);

	lpfc_sli4_cleanup_poll_list(phba);

	/* Release HBA eqs */
	if (phba->sli4_hba.hdwq)
		lpfc_sli4_release_hdwq(phba);

	if (phba->nvmet_support) {
		lpfc_sli4_release_queues(&phba->sli4_hba.nvmet_cqset,
					 phba->cfg_nvmet_mrq);

		lpfc_sli4_release_queues(&phba->sli4_hba.nvmet_mrq_hdr,
					 phba->cfg_nvmet_mrq);
		lpfc_sli4_release_queues(&phba->sli4_hba.nvmet_mrq_data,
					 phba->cfg_nvmet_mrq);
	}

	/* Release mailbox command work queue */
	__lpfc_sli4_release_queue(&phba->sli4_hba.mbx_wq);

	/* Release ELS work queue */
	__lpfc_sli4_release_queue(&phba->sli4_hba.els_wq);

	/* Release ELS work queue */
	__lpfc_sli4_release_queue(&phba->sli4_hba.nvmels_wq);

	/* Release unsolicited receive queue */
	__lpfc_sli4_release_queue(&phba->sli4_hba.hdr_rq);
	__lpfc_sli4_release_queue(&phba->sli4_hba.dat_rq);

	/* Release ELS complete queue */
	__lpfc_sli4_release_queue(&phba->sli4_hba.els_cq);

	/* Release NVME LS complete queue */
	__lpfc_sli4_release_queue(&phba->sli4_hba.nvmels_cq);

	/* Release mailbox command complete queue */
	__lpfc_sli4_release_queue(&phba->sli4_hba.mbx_cq);

	/* Everything on this list has been freed */
	INIT_LIST_HEAD(&phba->sli4_hba.lpfc_wq_list);

	/* Done with freeing the queues */
	spin_lock_irq(&phba->hbalock);
	phba->sli.sli_flag &= ~LPFC_QUEUE_FREE_INIT;
	spin_unlock_irq(&phba->hbalock);
}

int
lpfc_free_rq_buffer(struct lpfc_hba *phba, struct lpfc_queue *rq)
{
	struct lpfc_rqb *rqbp;
	struct lpfc_dmabuf *h_buf;
	struct rqb_dmabuf *rqb_buffer;

	rqbp = rq->rqbp;
	while (!list_empty(&rqbp->rqb_buffer_list)) {
		list_remove_head(&rqbp->rqb_buffer_list, h_buf,
				 struct lpfc_dmabuf, list);

		rqb_buffer = container_of(h_buf, struct rqb_dmabuf, hbuf);
		(rqbp->rqb_free_buffer)(phba, rqb_buffer);
		rqbp->buffer_count--;
	}
	return 1;
}

static int
lpfc_create_wq_cq(struct lpfc_hba *phba, struct lpfc_queue *eq,
	struct lpfc_queue *cq, struct lpfc_queue *wq, uint16_t *cq_map,
	int qidx, uint32_t qtype)
{
	struct lpfc_sli_ring *pring;
	int rc;

	if (!eq || !cq || !wq) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
			"6085 Fast-path %s (%d) not allocated\n",
			((eq) ? ((cq) ? "WQ" : "CQ") : "EQ"), qidx);
		return -ENOMEM;
	}

	/* create the Cq first */
	rc = lpfc_cq_create(phba, cq, eq,
			(qtype == LPFC_MBOX) ? LPFC_MCQ : LPFC_WCQ, qtype);
	if (rc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"6086 Failed setup of CQ (%d), rc = 0x%x\n",
				qidx, (uint32_t)rc);
		return rc;
	}

	if (qtype != LPFC_MBOX) {
		/* Setup cq_map for fast lookup */
		if (cq_map)
			*cq_map = cq->queue_id;

		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
			"6087 CQ setup: cq[%d]-id=%d, parent eq[%d]-id=%d\n",
			qidx, cq->queue_id, qidx, eq->queue_id);

		/* create the wq */
		rc = lpfc_wq_create(phba, wq, cq, qtype);
		if (rc) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"4618 Fail setup fastpath WQ (%d), rc = 0x%x\n",
				qidx, (uint32_t)rc);
			/* no need to tear down cq - caller will do so */
			return rc;
		}

		/* Bind this CQ/WQ to the NVME ring */
		pring = wq->pring;
		pring->sli.sli4.wqp = (void *)wq;
		cq->pring = pring;

		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
			"2593 WQ setup: wq[%d]-id=%d assoc=%d, cq[%d]-id=%d\n",
			qidx, wq->queue_id, wq->assoc_qid, qidx, cq->queue_id);
	} else {
		rc = lpfc_mq_create(phba, wq, cq, LPFC_MBOX);
		if (rc) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"0539 Failed setup of slow-path MQ: "
					"rc = 0x%x\n", rc);
			/* no need to tear down cq - caller will do so */
			return rc;
		}

		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
			"2589 MBX MQ setup: wq-id=%d, parent cq-id=%d\n",
			phba->sli4_hba.mbx_wq->queue_id,
			phba->sli4_hba.mbx_cq->queue_id);
	}

	return 0;
}

/**
 * lpfc_setup_cq_lookup - Setup the CQ lookup table
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine will populate the cq_lookup table by all
 * available CQ queue_id's.
 **/
static void
lpfc_setup_cq_lookup(struct lpfc_hba *phba)
{
	struct lpfc_queue *eq, *childq;
	int qidx;

	memset(phba->sli4_hba.cq_lookup, 0,
	       (sizeof(struct lpfc_queue *) * (phba->sli4_hba.cq_max + 1)));
	/* Loop thru all IRQ vectors */
	for (qidx = 0; qidx < phba->cfg_irq_chann; qidx++) {
		/* Get the EQ corresponding to the IRQ vector */
		eq = phba->sli4_hba.hba_eq_hdl[qidx].eq;
		if (!eq)
			continue;
		/* Loop through all CQs associated with that EQ */
		list_for_each_entry(childq, &eq->child_list, list) {
			if (childq->queue_id > phba->sli4_hba.cq_max)
				continue;
			if (childq->subtype == LPFC_IO)
				phba->sli4_hba.cq_lookup[childq->queue_id] =
					childq;
		}
	}
}

/**
 * lpfc_sli4_queue_setup - Set up all the SLI4 queues
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to set up all the SLI4 queues for the FCoE HBA
 * operation.
 *
 * Return codes
 *      0 - successful
 *      -ENOMEM - No available memory
 *      -EIO - The mailbox failed to complete successfully.
 **/
int
lpfc_sli4_queue_setup(struct lpfc_hba *phba)
{
	uint32_t shdr_status, shdr_add_status;
	union lpfc_sli4_cfg_shdr *shdr;
	struct lpfc_vector_map_info *cpup;
	struct lpfc_sli4_hdw_queue *qp;
	LPFC_MBOXQ_t *mboxq;
	int qidx, cpu;
	uint32_t length, usdelay;
	int rc = -ENOMEM;

	/* Check for dual-ULP support */
	mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (!mboxq) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3249 Unable to allocate memory for "
				"QUERY_FW_CFG mailbox command\n");
		return -ENOMEM;
	}
	length = (sizeof(struct lpfc_mbx_query_fw_config) -
		  sizeof(struct lpfc_sli4_cfg_mhdr));
	lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
			 LPFC_MBOX_OPCODE_QUERY_FW_CFG,
			 length, LPFC_SLI4_MBX_EMBED);

	rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);

	shdr = (union lpfc_sli4_cfg_shdr *)
			&mboxq->u.mqe.un.sli4_config.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);
	if (shdr_status || shdr_add_status || rc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3250 QUERY_FW_CFG mailbox failed with status "
				"x%x add_status x%x, mbx status x%x\n",
				shdr_status, shdr_add_status, rc);
		mempool_free(mboxq, phba->mbox_mem_pool);
		rc = -ENXIO;
		goto out_error;
	}

	phba->sli4_hba.fw_func_mode =
			mboxq->u.mqe.un.query_fw_cfg.rsp.function_mode;
	phba->sli4_hba.ulp0_mode = mboxq->u.mqe.un.query_fw_cfg.rsp.ulp0_mode;
	phba->sli4_hba.ulp1_mode = mboxq->u.mqe.un.query_fw_cfg.rsp.ulp1_mode;
	phba->sli4_hba.physical_port =
			mboxq->u.mqe.un.query_fw_cfg.rsp.physical_port;
	lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
			"3251 QUERY_FW_CFG: func_mode:x%x, ulp0_mode:x%x, "
			"ulp1_mode:x%x\n", phba->sli4_hba.fw_func_mode,
			phba->sli4_hba.ulp0_mode, phba->sli4_hba.ulp1_mode);

	mempool_free(mboxq, phba->mbox_mem_pool);

	/*
	 * Set up HBA Event Queues (EQs)
	 */
	qp = phba->sli4_hba.hdwq;

	/* Set up HBA event queue */
	if (!qp) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3147 Fast-path EQs not allocated\n");
		rc = -ENOMEM;
		goto out_error;
	}

	/* Loop thru all IRQ vectors */
	for (qidx = 0; qidx < phba->cfg_irq_chann; qidx++) {
		/* Create HBA Event Queues (EQs) in order */
		for_each_present_cpu(cpu) {
			cpup = &phba->sli4_hba.cpu_map[cpu];

			/* Look for the CPU thats using that vector with
			 * LPFC_CPU_FIRST_IRQ set.
			 */
			if (!(cpup->flag & LPFC_CPU_FIRST_IRQ))
				continue;
			if (qidx != cpup->eq)
				continue;

			/* Create an EQ for that vector */
			rc = lpfc_eq_create(phba, qp[cpup->hdwq].hba_eq,
					    phba->cfg_fcp_imax);
			if (rc) {
				lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
						"0523 Failed setup of fast-path"
						" EQ (%d), rc = 0x%x\n",
						cpup->eq, (uint32_t)rc);
				goto out_destroy;
			}

			/* Save the EQ for that vector in the hba_eq_hdl */
			phba->sli4_hba.hba_eq_hdl[cpup->eq].eq =
				qp[cpup->hdwq].hba_eq;

			lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
					"2584 HBA EQ setup: queue[%d]-id=%d\n",
					cpup->eq,
					qp[cpup->hdwq].hba_eq->queue_id);
		}
	}

	/* Loop thru all Hardware Queues */
	for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) {
		cpu = lpfc_find_cpu_handle(phba, qidx, LPFC_FIND_BY_HDWQ);
		cpup = &phba->sli4_hba.cpu_map[cpu];

		/* Create the CQ/WQ corresponding to the Hardware Queue */
		rc = lpfc_create_wq_cq(phba,
				       phba->sli4_hba.hdwq[cpup->hdwq].hba_eq,
				       qp[qidx].io_cq,
				       qp[qidx].io_wq,
				       &phba->sli4_hba.hdwq[qidx].io_cq_map,
				       qidx,
				       LPFC_IO);
		if (rc) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"0535 Failed to setup fastpath "
					"IO WQ/CQ (%d), rc = 0x%x\n",
					qidx, (uint32_t)rc);
			goto out_destroy;
		}
	}

	/*
	 * Set up Slow Path Complete Queues (CQs)
	 */

	/* Set up slow-path MBOX CQ/MQ */

	if (!phba->sli4_hba.mbx_cq || !phba->sli4_hba.mbx_wq) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0528 %s not allocated\n",
				phba->sli4_hba.mbx_cq ?
				"Mailbox WQ" : "Mailbox CQ");
		rc = -ENOMEM;
		goto out_destroy;
	}

	rc = lpfc_create_wq_cq(phba, qp[0].hba_eq,
			       phba->sli4_hba.mbx_cq,
			       phba->sli4_hba.mbx_wq,
			       NULL, 0, LPFC_MBOX);
	if (rc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
			"0529 Failed setup of mailbox WQ/CQ: rc = 0x%x\n",
			(uint32_t)rc);
		goto out_destroy;
	}
	if (phba->nvmet_support) {
		if (!phba->sli4_hba.nvmet_cqset) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"3165 Fast-path NVME CQ Set "
					"array not allocated\n");
			rc = -ENOMEM;
			goto out_destroy;
		}
		if (phba->cfg_nvmet_mrq > 1) {
			rc = lpfc_cq_create_set(phba,
					phba->sli4_hba.nvmet_cqset,
					qp,
					LPFC_WCQ, LPFC_NVMET);
			if (rc) {
				lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
						"3164 Failed setup of NVME CQ "
						"Set, rc = 0x%x\n",
						(uint32_t)rc);
				goto out_destroy;
			}
		} else {
			/* Set up NVMET Receive Complete Queue */
			rc = lpfc_cq_create(phba, phba->sli4_hba.nvmet_cqset[0],
					    qp[0].hba_eq,
					    LPFC_WCQ, LPFC_NVMET);
			if (rc) {
				lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
						"6089 Failed setup NVMET CQ: "
						"rc = 0x%x\n", (uint32_t)rc);
				goto out_destroy;
			}
			phba->sli4_hba.nvmet_cqset[0]->chann = 0;

			lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
					"6090 NVMET CQ setup: cq-id=%d, "
					"parent eq-id=%d\n",
					phba->sli4_hba.nvmet_cqset[0]->queue_id,
					qp[0].hba_eq->queue_id);
		}
	}

	/* Set up slow-path ELS WQ/CQ */
	if (!phba->sli4_hba.els_cq || !phba->sli4_hba.els_wq) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0530 ELS %s not allocated\n",
				phba->sli4_hba.els_cq ? "WQ" : "CQ");
		rc = -ENOMEM;
		goto out_destroy;
	}
	rc = lpfc_create_wq_cq(phba, qp[0].hba_eq,
			       phba->sli4_hba.els_cq,
			       phba->sli4_hba.els_wq,
			       NULL, 0, LPFC_ELS);
	if (rc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0525 Failed setup of ELS WQ/CQ: rc = 0x%x\n",
				(uint32_t)rc);
		goto out_destroy;
	}
	lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
			"2590 ELS WQ setup: wq-id=%d, parent cq-id=%d\n",
			phba->sli4_hba.els_wq->queue_id,
			phba->sli4_hba.els_cq->queue_id);

	if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
		/* Set up NVME LS Complete Queue */
		if (!phba->sli4_hba.nvmels_cq || !phba->sli4_hba.nvmels_wq) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"6091 LS %s not allocated\n",
					phba->sli4_hba.nvmels_cq ? "WQ" : "CQ");
			rc = -ENOMEM;
			goto out_destroy;
		}
		rc = lpfc_create_wq_cq(phba, qp[0].hba_eq,
				       phba->sli4_hba.nvmels_cq,
				       phba->sli4_hba.nvmels_wq,
				       NULL, 0, LPFC_NVME_LS);
		if (rc) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"0526 Failed setup of NVVME LS WQ/CQ: "
					"rc = 0x%x\n", (uint32_t)rc);
			goto out_destroy;
		}

		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"6096 ELS WQ setup: wq-id=%d, "
				"parent cq-id=%d\n",
				phba->sli4_hba.nvmels_wq->queue_id,
				phba->sli4_hba.nvmels_cq->queue_id);
	}

	/*
	 * Create NVMET Receive Queue (RQ)
	 */
	if (phba->nvmet_support) {
		if ((!phba->sli4_hba.nvmet_cqset) ||
		    (!phba->sli4_hba.nvmet_mrq_hdr) ||
		    (!phba->sli4_hba.nvmet_mrq_data)) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"6130 MRQ CQ Queues not "
					"allocated\n");
			rc = -ENOMEM;
			goto out_destroy;
		}
		if (phba->cfg_nvmet_mrq > 1) {
			rc = lpfc_mrq_create(phba,
					     phba->sli4_hba.nvmet_mrq_hdr,
					     phba->sli4_hba.nvmet_mrq_data,
					     phba->sli4_hba.nvmet_cqset,
					     LPFC_NVMET);
			if (rc) {
				lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
						"6098 Failed setup of NVMET "
						"MRQ: rc = 0x%x\n",
						(uint32_t)rc);
				goto out_destroy;
			}

		} else {
			rc = lpfc_rq_create(phba,
					    phba->sli4_hba.nvmet_mrq_hdr[0],
					    phba->sli4_hba.nvmet_mrq_data[0],
					    phba->sli4_hba.nvmet_cqset[0],
					    LPFC_NVMET);
			if (rc) {
				lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
						"6057 Failed setup of NVMET "
						"Receive Queue: rc = 0x%x\n",
						(uint32_t)rc);
				goto out_destroy;
			}

			lpfc_printf_log(
				phba, KERN_INFO, LOG_INIT,
				"6099 NVMET RQ setup: hdr-rq-id=%d, "
				"dat-rq-id=%d parent cq-id=%d\n",
				phba->sli4_hba.nvmet_mrq_hdr[0]->queue_id,
				phba->sli4_hba.nvmet_mrq_data[0]->queue_id,
				phba->sli4_hba.nvmet_cqset[0]->queue_id);

		}
	}

	if (!phba->sli4_hba.hdr_rq || !phba->sli4_hba.dat_rq) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0540 Receive Queue not allocated\n");
		rc = -ENOMEM;
		goto out_destroy;
	}

	rc = lpfc_rq_create(phba, phba->sli4_hba.hdr_rq, phba->sli4_hba.dat_rq,
			    phba->sli4_hba.els_cq, LPFC_USOL);
	if (rc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0541 Failed setup of Receive Queue: "
				"rc = 0x%x\n", (uint32_t)rc);
		goto out_destroy;
	}

	lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
			"2592 USL RQ setup: hdr-rq-id=%d, dat-rq-id=%d "
			"parent cq-id=%d\n",
			phba->sli4_hba.hdr_rq->queue_id,
			phba->sli4_hba.dat_rq->queue_id,
			phba->sli4_hba.els_cq->queue_id);

	if (phba->cfg_fcp_imax)
		usdelay = LPFC_SEC_TO_USEC / phba->cfg_fcp_imax;
	else
		usdelay = 0;

	for (qidx = 0; qidx < phba->cfg_irq_chann;
	     qidx += LPFC_MAX_EQ_DELAY_EQID_CNT)
		lpfc_modify_hba_eq_delay(phba, qidx, LPFC_MAX_EQ_DELAY_EQID_CNT,
					 usdelay);

	if (phba->sli4_hba.cq_max) {
		kfree(phba->sli4_hba.cq_lookup);
		phba->sli4_hba.cq_lookup = kcalloc((phba->sli4_hba.cq_max + 1),
			sizeof(struct lpfc_queue *), GFP_KERNEL);
		if (!phba->sli4_hba.cq_lookup) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"0549 Failed setup of CQ Lookup table: "
					"size 0x%x\n", phba->sli4_hba.cq_max);
			rc = -ENOMEM;
			goto out_destroy;
		}
		lpfc_setup_cq_lookup(phba);
	}
	return 0;

out_destroy:
	lpfc_sli4_queue_unset(phba);
out_error:
	return rc;
}

/**
 * lpfc_sli4_queue_unset - Unset all the SLI4 queues
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to unset all the SLI4 queues with the FCoE HBA
 * operation.
 *
 * Return codes
 *      0 - successful
 *      -ENOMEM - No available memory
 *      -EIO - The mailbox failed to complete successfully.
 **/
void
lpfc_sli4_queue_unset(struct lpfc_hba *phba)
{
	struct lpfc_sli4_hdw_queue *qp;
	struct lpfc_queue *eq;
	int qidx;

	/* Unset mailbox command work queue */
	if (phba->sli4_hba.mbx_wq)
		lpfc_mq_destroy(phba, phba->sli4_hba.mbx_wq);

	/* Unset NVME LS work queue */
	if (phba->sli4_hba.nvmels_wq)
		lpfc_wq_destroy(phba, phba->sli4_hba.nvmels_wq);

	/* Unset ELS work queue */
	if (phba->sli4_hba.els_wq)
		lpfc_wq_destroy(phba, phba->sli4_hba.els_wq);

	/* Unset unsolicited receive queue */
	if (phba->sli4_hba.hdr_rq)
		lpfc_rq_destroy(phba, phba->sli4_hba.hdr_rq,
				phba->sli4_hba.dat_rq);

	/* Unset mailbox command complete queue */
	if (phba->sli4_hba.mbx_cq)
		lpfc_cq_destroy(phba, phba->sli4_hba.mbx_cq);

	/* Unset ELS complete queue */
	if (phba->sli4_hba.els_cq)
		lpfc_cq_destroy(phba, phba->sli4_hba.els_cq);

	/* Unset NVME LS complete queue */
	if (phba->sli4_hba.nvmels_cq)
		lpfc_cq_destroy(phba, phba->sli4_hba.nvmels_cq);

	if (phba->nvmet_support) {
		/* Unset NVMET MRQ queue */
		if (phba->sli4_hba.nvmet_mrq_hdr) {
			for (qidx = 0; qidx < phba->cfg_nvmet_mrq; qidx++)
				lpfc_rq_destroy(
					phba,
					phba->sli4_hba.nvmet_mrq_hdr[qidx],
					phba->sli4_hba.nvmet_mrq_data[qidx]);
		}

		/* Unset NVMET CQ Set complete queue */
		if (phba->sli4_hba.nvmet_cqset) {
			for (qidx = 0; qidx < phba->cfg_nvmet_mrq; qidx++)
				lpfc_cq_destroy(
					phba, phba->sli4_hba.nvmet_cqset[qidx]);
		}
	}

	/* Unset fast-path SLI4 queues */
	if (phba->sli4_hba.hdwq) {
		/* Loop thru all Hardware Queues */
		for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) {
			/* Destroy the CQ/WQ corresponding to Hardware Queue */
			qp = &phba->sli4_hba.hdwq[qidx];
			lpfc_wq_destroy(phba, qp->io_wq);
			lpfc_cq_destroy(phba, qp->io_cq);
		}
		/* Loop thru all IRQ vectors */
		for (qidx = 0; qidx < phba->cfg_irq_chann; qidx++) {
			/* Destroy the EQ corresponding to the IRQ vector */
			eq = phba->sli4_hba.hba_eq_hdl[qidx].eq;
			lpfc_eq_destroy(phba, eq);
		}
	}

	kfree(phba->sli4_hba.cq_lookup);
	phba->sli4_hba.cq_lookup = NULL;
	phba->sli4_hba.cq_max = 0;
}

/**
 * lpfc_sli4_cq_event_pool_create - Create completion-queue event free pool
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to allocate and set up a pool of completion queue
 * events. The body of the completion queue event is a completion queue entry
 * CQE. For now, this pool is used for the interrupt service routine to queue
 * the following HBA completion queue events for the worker thread to process:
 *   - Mailbox asynchronous events
 *   - Receive queue completion unsolicited events
 * Later, this can be used for all the slow-path events.
 *
 * Return codes
 *      0 - successful
 *      -ENOMEM - No available memory
 **/
static int
lpfc_sli4_cq_event_pool_create(struct lpfc_hba *phba)
{
	struct lpfc_cq_event *cq_event;
	int i;

	for (i = 0; i < (4 * phba->sli4_hba.cq_ecount); i++) {
		cq_event = kmalloc(sizeof(struct lpfc_cq_event), GFP_KERNEL);
		if (!cq_event)
			goto out_pool_create_fail;
		list_add_tail(&cq_event->list,
			      &phba->sli4_hba.sp_cqe_event_pool);
	}
	return 0;

out_pool_create_fail:
	lpfc_sli4_cq_event_pool_destroy(phba);
	return -ENOMEM;
}

/**
 * lpfc_sli4_cq_event_pool_destroy - Free completion-queue event free pool
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to free the pool of completion queue events at
 * driver unload time. Note that, it is the responsibility of the driver
 * cleanup routine to free all the outstanding completion-queue events
 * allocated from this pool back into the pool before invoking this routine
 * to destroy the pool.
 **/
static void
lpfc_sli4_cq_event_pool_destroy(struct lpfc_hba *phba)
{
	struct lpfc_cq_event *cq_event, *next_cq_event;

	list_for_each_entry_safe(cq_event, next_cq_event,
				 &phba->sli4_hba.sp_cqe_event_pool, list) {
		list_del(&cq_event->list);
		kfree(cq_event);
	}
}

/**
 * __lpfc_sli4_cq_event_alloc - Allocate a completion-queue event from free pool
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is the lock free version of the API invoked to allocate a
 * completion-queue event from the free pool.
 *
 * Return: Pointer to the newly allocated completion-queue event if successful
 *         NULL otherwise.
 **/
struct lpfc_cq_event *
__lpfc_sli4_cq_event_alloc(struct lpfc_hba *phba)
{
	struct lpfc_cq_event *cq_event = NULL;

	list_remove_head(&phba->sli4_hba.sp_cqe_event_pool, cq_event,
			 struct lpfc_cq_event, list);
	return cq_event;
}

/**
 * lpfc_sli4_cq_event_alloc - Allocate a completion-queue event from free pool
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is the lock version of the API invoked to allocate a
 * completion-queue event from the free pool.
 *
 * Return: Pointer to the newly allocated completion-queue event if successful
 *         NULL otherwise.
 **/
struct lpfc_cq_event *
lpfc_sli4_cq_event_alloc(struct lpfc_hba *phba)
{
	struct lpfc_cq_event *cq_event;
	unsigned long iflags;

	spin_lock_irqsave(&phba->hbalock, iflags);
	cq_event = __lpfc_sli4_cq_event_alloc(phba);
	spin_unlock_irqrestore(&phba->hbalock, iflags);
	return cq_event;
}

/**
 * __lpfc_sli4_cq_event_release - Release a completion-queue event to free pool
 * @phba: pointer to lpfc hba data structure.
 * @cq_event: pointer to the completion queue event to be freed.
 *
 * This routine is the lock free version of the API invoked to release a
 * completion-queue event back into the free pool.
 **/
void
__lpfc_sli4_cq_event_release(struct lpfc_hba *phba,
			     struct lpfc_cq_event *cq_event)
{
	list_add_tail(&cq_event->list, &phba->sli4_hba.sp_cqe_event_pool);
}

/**
 * lpfc_sli4_cq_event_release - Release a completion-queue event to free pool
 * @phba: pointer to lpfc hba data structure.
 * @cq_event: pointer to the completion queue event to be freed.
 *
 * This routine is the lock version of the API invoked to release a
 * completion-queue event back into the free pool.
 **/
void
lpfc_sli4_cq_event_release(struct lpfc_hba *phba,
			   struct lpfc_cq_event *cq_event)
{
	unsigned long iflags;
	spin_lock_irqsave(&phba->hbalock, iflags);
	__lpfc_sli4_cq_event_release(phba, cq_event);
	spin_unlock_irqrestore(&phba->hbalock, iflags);
}

/**
 * lpfc_sli4_cq_event_release_all - Release all cq events to the free pool
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is to free all the pending completion-queue events to the
 * back into the free pool for device reset.
 **/
static void
lpfc_sli4_cq_event_release_all(struct lpfc_hba *phba)
{
	LIST_HEAD(cq_event_list);
	struct lpfc_cq_event *cq_event;
	unsigned long iflags;

	/* Retrieve all the pending WCQEs from pending WCQE lists */

	/* Pending ELS XRI abort events */
	spin_lock_irqsave(&phba->sli4_hba.els_xri_abrt_list_lock, iflags);
	list_splice_init(&phba->sli4_hba.sp_els_xri_aborted_work_queue,
			 &cq_event_list);
	spin_unlock_irqrestore(&phba->sli4_hba.els_xri_abrt_list_lock, iflags);

	/* Pending asynnc events */
	spin_lock_irqsave(&phba->sli4_hba.asynce_list_lock, iflags);
	list_splice_init(&phba->sli4_hba.sp_asynce_work_queue,
			 &cq_event_list);
	spin_unlock_irqrestore(&phba->sli4_hba.asynce_list_lock, iflags);

	while (!list_empty(&cq_event_list)) {
		list_remove_head(&cq_event_list, cq_event,
				 struct lpfc_cq_event, list);
		lpfc_sli4_cq_event_release(phba, cq_event);
	}
}

/**
 * lpfc_pci_function_reset - Reset pci function.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to request a PCI function reset. It will destroys
 * all resources assigned to the PCI function which originates this request.
 *
 * Return codes
 *      0 - successful
 *      -ENOMEM - No available memory
 *      -EIO - The mailbox failed to complete successfully.
 **/
int
lpfc_pci_function_reset(struct lpfc_hba *phba)
{
	LPFC_MBOXQ_t *mboxq;
	uint32_t rc = 0, if_type;
	uint32_t shdr_status, shdr_add_status;
	uint32_t rdy_chk;
	uint32_t port_reset = 0;
	union lpfc_sli4_cfg_shdr *shdr;
	struct lpfc_register reg_data;
	uint16_t devid;

	if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
	switch (if_type) {
	case LPFC_SLI_INTF_IF_TYPE_0:
		mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
						       GFP_KERNEL);
		if (!mboxq) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"0494 Unable to allocate memory for "
					"issuing SLI_FUNCTION_RESET mailbox "
					"command\n");
			return -ENOMEM;
		}

		/* Setup PCI function reset mailbox-ioctl command */
		lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
				 LPFC_MBOX_OPCODE_FUNCTION_RESET, 0,
				 LPFC_SLI4_MBX_EMBED);
		rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
		shdr = (union lpfc_sli4_cfg_shdr *)
			&mboxq->u.mqe.un.sli4_config.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);
		mempool_free(mboxq, phba->mbox_mem_pool);
		if (shdr_status || shdr_add_status || rc) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"0495 SLI_FUNCTION_RESET mailbox "
					"failed with status x%x add_status x%x,"
					" mbx status x%x\n",
					shdr_status, shdr_add_status, rc);
			rc = -ENXIO;
		}
		break;
	case LPFC_SLI_INTF_IF_TYPE_2:
	case LPFC_SLI_INTF_IF_TYPE_6:
wait:
		/*
		 * Poll the Port Status Register and wait for RDY for
		 * up to 30 seconds. If the port doesn't respond, treat
		 * it as an error.
		 */
		for (rdy_chk = 0; rdy_chk < 1500; rdy_chk++) {
			if (lpfc_readl(phba->sli4_hba.u.if_type2.
				STATUSregaddr, &reg_data.word0)) {
				rc = -ENODEV;
				goto out;
			}
			if (bf_get(lpfc_sliport_status_rdy, &reg_data))
				break;
			msleep(20);
		}

		if (!bf_get(lpfc_sliport_status_rdy, &reg_data)) {
			phba->work_status[0] = readl(
				phba->sli4_hba.u.if_type2.ERR1regaddr);
			phba->work_status[1] = readl(
				phba->sli4_hba.u.if_type2.ERR2regaddr);
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"2890 Port not ready, port status reg "
					"0x%x error 1=0x%x, error 2=0x%x\n",
					reg_data.word0,
					phba->work_status[0],
					phba->work_status[1]);
			rc = -ENODEV;
			goto out;
		}

		if (bf_get(lpfc_sliport_status_pldv, &reg_data))
			lpfc_pldv_detect = true;

		if (!port_reset) {
			/*
			 * Reset the port now
			 */
			reg_data.word0 = 0;
			bf_set(lpfc_sliport_ctrl_end, &reg_data,
			       LPFC_SLIPORT_LITTLE_ENDIAN);
			bf_set(lpfc_sliport_ctrl_ip, &reg_data,
			       LPFC_SLIPORT_INIT_PORT);
			writel(reg_data.word0, phba->sli4_hba.u.if_type2.
			       CTRLregaddr);
			/* flush */
			pci_read_config_word(phba->pcidev,
					     PCI_DEVICE_ID, &devid);

			port_reset = 1;
			msleep(20);
			goto wait;
		} else if (bf_get(lpfc_sliport_status_rn, &reg_data)) {
			rc = -ENODEV;
			goto out;
		}
		break;

	case LPFC_SLI_INTF_IF_TYPE_1:
	default:
		break;
	}

out:
	/* Catch the not-ready port failure after a port reset. */
	if (rc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3317 HBA not functional: IP Reset Failed "
				"try: echo fw_reset > board_mode\n");
		rc = -ENODEV;
	}

	return rc;
}

/**
 * lpfc_sli4_pci_mem_setup - Setup SLI4 HBA PCI memory space.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to set up the PCI device memory space for device
 * with SLI-4 interface spec.
 *
 * Return codes
 * 	0 - successful
 * 	other values - error
 **/
static int
lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba)
{
	struct pci_dev *pdev = phba->pcidev;
	unsigned long bar0map_len, bar1map_len, bar2map_len;
	int error;
	uint32_t if_type;

	if (!pdev)
		return -ENODEV;

	/* Set the device DMA mask size */
	error = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
	if (error)
		error = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
	if (error)
		return error;

	/*
	 * The BARs and register set definitions and offset locations are
	 * dependent on the if_type.
	 */
	if (pci_read_config_dword(pdev, LPFC_SLI_INTF,
				  &phba->sli4_hba.sli_intf.word0)) {
		return -ENODEV;
	}

	/* There is no SLI3 failback for SLI4 devices. */
	if (bf_get(lpfc_sli_intf_valid, &phba->sli4_hba.sli_intf) !=
	    LPFC_SLI_INTF_VALID) {
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"2894 SLI_INTF reg contents invalid "
				"sli_intf reg 0x%x\n",
				phba->sli4_hba.sli_intf.word0);
		return -ENODEV;
	}

	if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
	/*
	 * Get the bus address of SLI4 device Bar regions and the
	 * number of bytes required by each mapping. The mapping of the
	 * particular PCI BARs regions is dependent on the type of
	 * SLI4 device.
	 */
	if (pci_resource_start(pdev, PCI_64BIT_BAR0)) {
		phba->pci_bar0_map = pci_resource_start(pdev, PCI_64BIT_BAR0);
		bar0map_len = pci_resource_len(pdev, PCI_64BIT_BAR0);

		/*
		 * Map SLI4 PCI Config Space Register base to a kernel virtual
		 * addr
		 */
		phba->sli4_hba.conf_regs_memmap_p =
			ioremap(phba->pci_bar0_map, bar0map_len);
		if (!phba->sli4_hba.conf_regs_memmap_p) {
			dev_printk(KERN_ERR, &pdev->dev,
				   "ioremap failed for SLI4 PCI config "
				   "registers.\n");
			return -ENODEV;
		}
		phba->pci_bar0_memmap_p = phba->sli4_hba.conf_regs_memmap_p;
		/* Set up BAR0 PCI config space register memory map */
		lpfc_sli4_bar0_register_memmap(phba, if_type);
	} else {
		phba->pci_bar0_map = pci_resource_start(pdev, 1);
		bar0map_len = pci_resource_len(pdev, 1);
		if (if_type >= LPFC_SLI_INTF_IF_TYPE_2) {
			dev_printk(KERN_ERR, &pdev->dev,
			   "FATAL - No BAR0 mapping for SLI4, if_type 2\n");
			return -ENODEV;
		}
		phba->sli4_hba.conf_regs_memmap_p =
				ioremap(phba->pci_bar0_map, bar0map_len);
		if (!phba->sli4_hba.conf_regs_memmap_p) {
			dev_printk(KERN_ERR, &pdev->dev,
				"ioremap failed for SLI4 PCI config "
				"registers.\n");
			return -ENODEV;
		}
		lpfc_sli4_bar0_register_memmap(phba, if_type);
	}

	if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
		if (pci_resource_start(pdev, PCI_64BIT_BAR2)) {
			/*
			 * Map SLI4 if type 0 HBA Control Register base to a
			 * kernel virtual address and setup the registers.
			 */
			phba->pci_bar1_map = pci_resource_start(pdev,
								PCI_64BIT_BAR2);
			bar1map_len = pci_resource_len(pdev, PCI_64BIT_BAR2);
			phba->sli4_hba.ctrl_regs_memmap_p =
					ioremap(phba->pci_bar1_map,
						bar1map_len);
			if (!phba->sli4_hba.ctrl_regs_memmap_p) {
				dev_err(&pdev->dev,
					   "ioremap failed for SLI4 HBA "
					    "control registers.\n");
				error = -ENOMEM;
				goto out_iounmap_conf;
			}
			phba->pci_bar2_memmap_p =
					 phba->sli4_hba.ctrl_regs_memmap_p;
			lpfc_sli4_bar1_register_memmap(phba, if_type);
		} else {
			error = -ENOMEM;
			goto out_iounmap_conf;
		}
	}

	if ((if_type == LPFC_SLI_INTF_IF_TYPE_6) &&
	    (pci_resource_start(pdev, PCI_64BIT_BAR2))) {
		/*
		 * Map SLI4 if type 6 HBA Doorbell Register base to a kernel
		 * virtual address and setup the registers.
		 */
		phba->pci_bar1_map = pci_resource_start(pdev, PCI_64BIT_BAR2);
		bar1map_len = pci_resource_len(pdev, PCI_64BIT_BAR2);
		phba->sli4_hba.drbl_regs_memmap_p =
				ioremap(phba->pci_bar1_map, bar1map_len);
		if (!phba->sli4_hba.drbl_regs_memmap_p) {
			dev_err(&pdev->dev,
			   "ioremap failed for SLI4 HBA doorbell registers.\n");
			error = -ENOMEM;
			goto out_iounmap_conf;
		}
		phba->pci_bar2_memmap_p = phba->sli4_hba.drbl_regs_memmap_p;
		lpfc_sli4_bar1_register_memmap(phba, if_type);
	}

	if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
		if (pci_resource_start(pdev, PCI_64BIT_BAR4)) {
			/*
			 * Map SLI4 if type 0 HBA Doorbell Register base to
			 * a kernel virtual address and setup the registers.
			 */
			phba->pci_bar2_map = pci_resource_start(pdev,
								PCI_64BIT_BAR4);
			bar2map_len = pci_resource_len(pdev, PCI_64BIT_BAR4);
			phba->sli4_hba.drbl_regs_memmap_p =
					ioremap(phba->pci_bar2_map,
						bar2map_len);
			if (!phba->sli4_hba.drbl_regs_memmap_p) {
				dev_err(&pdev->dev,
					   "ioremap failed for SLI4 HBA"
					   " doorbell registers.\n");
				error = -ENOMEM;
				goto out_iounmap_ctrl;
			}
			phba->pci_bar4_memmap_p =
					phba->sli4_hba.drbl_regs_memmap_p;
			error = lpfc_sli4_bar2_register_memmap(phba, LPFC_VF0);
			if (error)
				goto out_iounmap_all;
		} else {
			error = -ENOMEM;
			goto out_iounmap_all;
		}
	}

	if (if_type == LPFC_SLI_INTF_IF_TYPE_6 &&
	    pci_resource_start(pdev, PCI_64BIT_BAR4)) {
		/*
		 * Map SLI4 if type 6 HBA DPP Register base to a kernel
		 * virtual address and setup the registers.
		 */
		phba->pci_bar2_map = pci_resource_start(pdev, PCI_64BIT_BAR4);
		bar2map_len = pci_resource_len(pdev, PCI_64BIT_BAR4);
		phba->sli4_hba.dpp_regs_memmap_p =
				ioremap(phba->pci_bar2_map, bar2map_len);
		if (!phba->sli4_hba.dpp_regs_memmap_p) {
			dev_err(&pdev->dev,
			   "ioremap failed for SLI4 HBA dpp registers.\n");
			error = -ENOMEM;
			goto out_iounmap_ctrl;
		}
		phba->pci_bar4_memmap_p = phba->sli4_hba.dpp_regs_memmap_p;
	}

	/* Set up the EQ/CQ register handeling functions now */
	switch (if_type) {
	case LPFC_SLI_INTF_IF_TYPE_0:
	case LPFC_SLI_INTF_IF_TYPE_2:
		phba->sli4_hba.sli4_eq_clr_intr = lpfc_sli4_eq_clr_intr;
		phba->sli4_hba.sli4_write_eq_db = lpfc_sli4_write_eq_db;
		phba->sli4_hba.sli4_write_cq_db = lpfc_sli4_write_cq_db;
		break;
	case LPFC_SLI_INTF_IF_TYPE_6:
		phba->sli4_hba.sli4_eq_clr_intr = lpfc_sli4_if6_eq_clr_intr;
		phba->sli4_hba.sli4_write_eq_db = lpfc_sli4_if6_write_eq_db;
		phba->sli4_hba.sli4_write_cq_db = lpfc_sli4_if6_write_cq_db;
		break;
	default:
		break;
	}

	return 0;

out_iounmap_all:
	iounmap(phba->sli4_hba.drbl_regs_memmap_p);
out_iounmap_ctrl:
	iounmap(phba->sli4_hba.ctrl_regs_memmap_p);
out_iounmap_conf:
	iounmap(phba->sli4_hba.conf_regs_memmap_p);

	return error;
}

/**
 * lpfc_sli4_pci_mem_unset - Unset SLI4 HBA PCI memory space.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to unset the PCI device memory space for device
 * with SLI-4 interface spec.
 **/
static void
lpfc_sli4_pci_mem_unset(struct lpfc_hba *phba)
{
	uint32_t if_type;
	if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);

	switch (if_type) {
	case LPFC_SLI_INTF_IF_TYPE_0:
		iounmap(phba->sli4_hba.drbl_regs_memmap_p);
		iounmap(phba->sli4_hba.ctrl_regs_memmap_p);
		iounmap(phba->sli4_hba.conf_regs_memmap_p);
		break;
	case LPFC_SLI_INTF_IF_TYPE_2:
		iounmap(phba->sli4_hba.conf_regs_memmap_p);
		break;
	case LPFC_SLI_INTF_IF_TYPE_6:
		iounmap(phba->sli4_hba.drbl_regs_memmap_p);
		iounmap(phba->sli4_hba.conf_regs_memmap_p);
		if (phba->sli4_hba.dpp_regs_memmap_p)
			iounmap(phba->sli4_hba.dpp_regs_memmap_p);
		break;
	case LPFC_SLI_INTF_IF_TYPE_1:
	default:
		dev_printk(KERN_ERR, &phba->pcidev->dev,
			   "FATAL - unsupported SLI4 interface type - %d\n",
			   if_type);
		break;
	}
}

/**
 * lpfc_sli_enable_msix - Enable MSI-X interrupt mode on SLI-3 device
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to enable the MSI-X interrupt vectors to device
 * with SLI-3 interface specs.
 *
 * Return codes
 *   0 - successful
 *   other values - error
 **/
static int
lpfc_sli_enable_msix(struct lpfc_hba *phba)
{
	int rc;
	LPFC_MBOXQ_t *pmb;

	/* Set up MSI-X multi-message vectors */
	rc = pci_alloc_irq_vectors(phba->pcidev,
			LPFC_MSIX_VECTORS, LPFC_MSIX_VECTORS, PCI_IRQ_MSIX);
	if (rc < 0) {
		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"0420 PCI enable MSI-X failed (%d)\n", rc);
		goto vec_fail_out;
	}

	/*
	 * Assign MSI-X vectors to interrupt handlers
	 */

	/* vector-0 is associated to slow-path handler */
	rc = request_irq(pci_irq_vector(phba->pcidev, 0),
			 &lpfc_sli_sp_intr_handler, 0,
			 LPFC_SP_DRIVER_HANDLER_NAME, phba);
	if (rc) {
		lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
				"0421 MSI-X slow-path request_irq failed "
				"(%d)\n", rc);
		goto msi_fail_out;
	}

	/* vector-1 is associated to fast-path handler */
	rc = request_irq(pci_irq_vector(phba->pcidev, 1),
			 &lpfc_sli_fp_intr_handler, 0,
			 LPFC_FP_DRIVER_HANDLER_NAME, phba);

	if (rc) {
		lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
				"0429 MSI-X fast-path request_irq failed "
				"(%d)\n", rc);
		goto irq_fail_out;
	}

	/*
	 * Configure HBA MSI-X attention conditions to messages
	 */
	pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);

	if (!pmb) {
		rc = -ENOMEM;
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0474 Unable to allocate memory for issuing "
				"MBOX_CONFIG_MSI command\n");
		goto mem_fail_out;
	}
	rc = lpfc_config_msi(phba, pmb);
	if (rc)
		goto mbx_fail_out;
	rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
	if (rc != MBX_SUCCESS) {
		lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
				"0351 Config MSI mailbox command failed, "
				"mbxCmd x%x, mbxStatus x%x\n",
				pmb->u.mb.mbxCommand, pmb->u.mb.mbxStatus);
		goto mbx_fail_out;
	}

	/* Free memory allocated for mailbox command */
	mempool_free(pmb, phba->mbox_mem_pool);
	return rc;

mbx_fail_out:
	/* Free memory allocated for mailbox command */
	mempool_free(pmb, phba->mbox_mem_pool);

mem_fail_out:
	/* free the irq already requested */
	free_irq(pci_irq_vector(phba->pcidev, 1), phba);

irq_fail_out:
	/* free the irq already requested */
	free_irq(pci_irq_vector(phba->pcidev, 0), phba);

msi_fail_out:
	/* Unconfigure MSI-X capability structure */
	pci_free_irq_vectors(phba->pcidev);

vec_fail_out:
	return rc;
}

/**
 * lpfc_sli_enable_msi - Enable MSI interrupt mode on SLI-3 device.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to enable the MSI interrupt mode to device with
 * SLI-3 interface spec. The kernel function pci_enable_msi() is called to
 * enable the MSI vector. The device driver is responsible for calling the
 * request_irq() to register MSI vector with a interrupt the handler, which
 * is done in this function.
 *
 * Return codes
 * 	0 - successful
 * 	other values - error
 */
static int
lpfc_sli_enable_msi(struct lpfc_hba *phba)
{
	int rc;

	rc = pci_enable_msi(phba->pcidev);
	if (!rc)
		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"0462 PCI enable MSI mode success.\n");
	else {
		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"0471 PCI enable MSI mode failed (%d)\n", rc);
		return rc;
	}

	rc = request_irq(phba->pcidev->irq, lpfc_sli_intr_handler,
			 0, LPFC_DRIVER_NAME, phba);
	if (rc) {
		pci_disable_msi(phba->pcidev);
		lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
				"0478 MSI request_irq failed (%d)\n", rc);
	}
	return rc;
}

/**
 * lpfc_sli_enable_intr - Enable device interrupt to SLI-3 device.
 * @phba: pointer to lpfc hba data structure.
 * @cfg_mode: Interrupt configuration mode (INTx, MSI or MSI-X).
 *
 * This routine is invoked to enable device interrupt and associate driver's
 * interrupt handler(s) to interrupt vector(s) to device with SLI-3 interface
 * spec. Depends on the interrupt mode configured to the driver, the driver
 * will try to fallback from the configured interrupt mode to an interrupt
 * mode which is supported by the platform, kernel, and device in the order
 * of:
 * MSI-X -> MSI -> IRQ.
 *
 * Return codes
 *   0 - successful
 *   other values - error
 **/
static uint32_t
lpfc_sli_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode)
{
	uint32_t intr_mode = LPFC_INTR_ERROR;
	int retval;

	/* Need to issue conf_port mbox cmd before conf_msi mbox cmd */
	retval = lpfc_sli_config_port(phba, LPFC_SLI_REV3);
	if (retval)
		return intr_mode;
	phba->hba_flag &= ~HBA_NEEDS_CFG_PORT;

	if (cfg_mode == 2) {
		/* Now, try to enable MSI-X interrupt mode */
		retval = lpfc_sli_enable_msix(phba);
		if (!retval) {
			/* Indicate initialization to MSI-X mode */
			phba->intr_type = MSIX;
			intr_mode = 2;
		}
	}

	/* Fallback to MSI if MSI-X initialization failed */
	if (cfg_mode >= 1 && phba->intr_type == NONE) {
		retval = lpfc_sli_enable_msi(phba);
		if (!retval) {
			/* Indicate initialization to MSI mode */
			phba->intr_type = MSI;
			intr_mode = 1;
		}
	}

	/* Fallback to INTx if both MSI-X/MSI initalization failed */
	if (phba->intr_type == NONE) {
		retval = request_irq(phba->pcidev->irq, lpfc_sli_intr_handler,
				     IRQF_SHARED, LPFC_DRIVER_NAME, phba);
		if (!retval) {
			/* Indicate initialization to INTx mode */
			phba->intr_type = INTx;
			intr_mode = 0;
		}
	}
	return intr_mode;
}

/**
 * lpfc_sli_disable_intr - Disable device interrupt to SLI-3 device.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to disable device interrupt and disassociate the
 * driver's interrupt handler(s) from interrupt vector(s) to device with
 * SLI-3 interface spec. Depending on the interrupt mode, the driver will
 * release the interrupt vector(s) for the message signaled interrupt.
 **/
static void
lpfc_sli_disable_intr(struct lpfc_hba *phba)
{
	int nr_irqs, i;

	if (phba->intr_type == MSIX)
		nr_irqs = LPFC_MSIX_VECTORS;
	else
		nr_irqs = 1;

	for (i = 0; i < nr_irqs; i++)
		free_irq(pci_irq_vector(phba->pcidev, i), phba);
	pci_free_irq_vectors(phba->pcidev);

	/* Reset interrupt management states */
	phba->intr_type = NONE;
	phba->sli.slistat.sli_intr = 0;
}

/**
 * lpfc_find_cpu_handle - Find the CPU that corresponds to the specified Queue
 * @phba: pointer to lpfc hba data structure.
 * @id: EQ vector index or Hardware Queue index
 * @match: LPFC_FIND_BY_EQ = match by EQ
 *         LPFC_FIND_BY_HDWQ = match by Hardware Queue
 * Return the CPU that matches the selection criteria
 */
static uint16_t
lpfc_find_cpu_handle(struct lpfc_hba *phba, uint16_t id, int match)
{
	struct lpfc_vector_map_info *cpup;
	int cpu;

	/* Loop through all CPUs */
	for_each_present_cpu(cpu) {
		cpup = &phba->sli4_hba.cpu_map[cpu];

		/* If we are matching by EQ, there may be multiple CPUs using
		 * using the same vector, so select the one with
		 * LPFC_CPU_FIRST_IRQ set.
		 */
		if ((match == LPFC_FIND_BY_EQ) &&
		    (cpup->flag & LPFC_CPU_FIRST_IRQ) &&
		    (cpup->eq == id))
			return cpu;

		/* If matching by HDWQ, select the first CPU that matches */
		if ((match == LPFC_FIND_BY_HDWQ) && (cpup->hdwq == id))
			return cpu;
	}
	return 0;
}

#ifdef CONFIG_X86
/**
 * lpfc_find_hyper - Determine if the CPU map entry is hyper-threaded
 * @phba: pointer to lpfc hba data structure.
 * @cpu: CPU map index
 * @phys_id: CPU package physical id
 * @core_id: CPU core id
 */
static int
lpfc_find_hyper(struct lpfc_hba *phba, int cpu,
		uint16_t phys_id, uint16_t core_id)
{
	struct lpfc_vector_map_info *cpup;
	int idx;

	for_each_present_cpu(idx) {
		cpup = &phba->sli4_hba.cpu_map[idx];
		/* Does the cpup match the one we are looking for */
		if ((cpup->phys_id == phys_id) &&
		    (cpup->core_id == core_id) &&
		    (cpu != idx))
			return 1;
	}
	return 0;
}
#endif

/*
 * lpfc_assign_eq_map_info - Assigns eq for vector_map structure
 * @phba: pointer to lpfc hba data structure.
 * @eqidx: index for eq and irq vector
 * @flag: flags to set for vector_map structure
 * @cpu: cpu used to index vector_map structure
 *
 * The routine assigns eq info into vector_map structure
 */
static inline void
lpfc_assign_eq_map_info(struct lpfc_hba *phba, uint16_t eqidx, uint16_t flag,
			unsigned int cpu)
{
	struct lpfc_vector_map_info *cpup = &phba->sli4_hba.cpu_map[cpu];
	struct lpfc_hba_eq_hdl *eqhdl = lpfc_get_eq_hdl(eqidx);

	cpup->eq = eqidx;
	cpup->flag |= flag;

	lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
			"3336 Set Affinity: CPU %d irq %d eq %d flag x%x\n",
			cpu, eqhdl->irq, cpup->eq, cpup->flag);
}

/**
 * lpfc_cpu_map_array_init - Initialize cpu_map structure
 * @phba: pointer to lpfc hba data structure.
 *
 * The routine initializes the cpu_map array structure
 */
static void
lpfc_cpu_map_array_init(struct lpfc_hba *phba)
{
	struct lpfc_vector_map_info *cpup;
	struct lpfc_eq_intr_info *eqi;
	int cpu;

	for_each_possible_cpu(cpu) {
		cpup = &phba->sli4_hba.cpu_map[cpu];
		cpup->phys_id = LPFC_VECTOR_MAP_EMPTY;
		cpup->core_id = LPFC_VECTOR_MAP_EMPTY;
		cpup->hdwq = LPFC_VECTOR_MAP_EMPTY;
		cpup->eq = LPFC_VECTOR_MAP_EMPTY;
		cpup->flag = 0;
		eqi = per_cpu_ptr(phba->sli4_hba.eq_info, cpu);
		INIT_LIST_HEAD(&eqi->list);
		eqi->icnt = 0;
	}
}

/**
 * lpfc_hba_eq_hdl_array_init - Initialize hba_eq_hdl structure
 * @phba: pointer to lpfc hba data structure.
 *
 * The routine initializes the hba_eq_hdl array structure
 */
static void
lpfc_hba_eq_hdl_array_init(struct lpfc_hba *phba)
{
	struct lpfc_hba_eq_hdl *eqhdl;
	int i;

	for (i = 0; i < phba->cfg_irq_chann; i++) {
		eqhdl = lpfc_get_eq_hdl(i);
		eqhdl->irq = LPFC_VECTOR_MAP_EMPTY;
		eqhdl->phba = phba;
	}
}

/**
 * lpfc_cpu_affinity_check - Check vector CPU affinity mappings
 * @phba: pointer to lpfc hba data structure.
 * @vectors: number of msix vectors allocated.
 *
 * The routine will figure out the CPU affinity assignment for every
 * MSI-X vector allocated for the HBA.
 * In addition, the CPU to IO channel mapping will be calculated
 * and the phba->sli4_hba.cpu_map array will reflect this.
 */
static void
lpfc_cpu_affinity_check(struct lpfc_hba *phba, int vectors)
{
	int i, cpu, idx, next_idx, new_cpu, start_cpu, first_cpu;
	int max_phys_id, min_phys_id;
	int max_core_id, min_core_id;
	struct lpfc_vector_map_info *cpup;
	struct lpfc_vector_map_info *new_cpup;
#ifdef CONFIG_X86
	struct cpuinfo_x86 *cpuinfo;
#endif
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
	struct lpfc_hdwq_stat *c_stat;
#endif

	max_phys_id = 0;
	min_phys_id = LPFC_VECTOR_MAP_EMPTY;
	max_core_id = 0;
	min_core_id = LPFC_VECTOR_MAP_EMPTY;

	/* Update CPU map with physical id and core id of each CPU */
	for_each_present_cpu(cpu) {
		cpup = &phba->sli4_hba.cpu_map[cpu];
#ifdef CONFIG_X86
		cpuinfo = &cpu_data(cpu);
		cpup->phys_id = cpuinfo->phys_proc_id;
		cpup->core_id = cpuinfo->cpu_core_id;
		if (lpfc_find_hyper(phba, cpu, cpup->phys_id, cpup->core_id))
			cpup->flag |= LPFC_CPU_MAP_HYPER;
#else
		/* No distinction between CPUs for other platforms */
		cpup->phys_id = 0;
		cpup->core_id = cpu;
#endif

		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"3328 CPU %d physid %d coreid %d flag x%x\n",
				cpu, cpup->phys_id, cpup->core_id, cpup->flag);

		if (cpup->phys_id > max_phys_id)
			max_phys_id = cpup->phys_id;
		if (cpup->phys_id < min_phys_id)
			min_phys_id = cpup->phys_id;

		if (cpup->core_id > max_core_id)
			max_core_id = cpup->core_id;
		if (cpup->core_id < min_core_id)
			min_core_id = cpup->core_id;
	}

	/* After looking at each irq vector assigned to this pcidev, its
	 * possible to see that not ALL CPUs have been accounted for.
	 * Next we will set any unassigned (unaffinitized) cpu map
	 * entries to a IRQ on the same phys_id.
	 */
	first_cpu = cpumask_first(cpu_present_mask);
	start_cpu = first_cpu;

	for_each_present_cpu(cpu) {
		cpup = &phba->sli4_hba.cpu_map[cpu];

		/* Is this CPU entry unassigned */
		if (cpup->eq == LPFC_VECTOR_MAP_EMPTY) {
			/* Mark CPU as IRQ not assigned by the kernel */
			cpup->flag |= LPFC_CPU_MAP_UNASSIGN;

			/* If so, find a new_cpup thats on the the SAME
			 * phys_id as cpup. start_cpu will start where we
			 * left off so all unassigned entries don't get assgined
			 * the IRQ of the first entry.
			 */
			new_cpu = start_cpu;
			for (i = 0; i < phba->sli4_hba.num_present_cpu; i++) {
				new_cpup = &phba->sli4_hba.cpu_map[new_cpu];
				if (!(new_cpup->flag & LPFC_CPU_MAP_UNASSIGN) &&
				    (new_cpup->eq != LPFC_VECTOR_MAP_EMPTY) &&
				    (new_cpup->phys_id == cpup->phys_id))
					goto found_same;
				new_cpu = cpumask_next(
					new_cpu, cpu_present_mask);
				if (new_cpu == nr_cpumask_bits)
					new_cpu = first_cpu;
			}
			/* At this point, we leave the CPU as unassigned */
			continue;
found_same:
			/* We found a matching phys_id, so copy the IRQ info */
			cpup->eq = new_cpup->eq;

			/* Bump start_cpu to the next slot to minmize the
			 * chance of having multiple unassigned CPU entries
			 * selecting the same IRQ.
			 */
			start_cpu = cpumask_next(new_cpu, cpu_present_mask);
			if (start_cpu == nr_cpumask_bits)
				start_cpu = first_cpu;

			lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
					"3337 Set Affinity: CPU %d "
					"eq %d from peer cpu %d same "
					"phys_id (%d)\n",
					cpu, cpup->eq, new_cpu,
					cpup->phys_id);
		}
	}

	/* Set any unassigned cpu map entries to a IRQ on any phys_id */
	start_cpu = first_cpu;

	for_each_present_cpu(cpu) {
		cpup = &phba->sli4_hba.cpu_map[cpu];

		/* Is this entry unassigned */
		if (cpup->eq == LPFC_VECTOR_MAP_EMPTY) {
			/* Mark it as IRQ not assigned by the kernel */
			cpup->flag |= LPFC_CPU_MAP_UNASSIGN;

			/* If so, find a new_cpup thats on ANY phys_id
			 * as the cpup. start_cpu will start where we
			 * left off so all unassigned entries don't get
			 * assigned the IRQ of the first entry.
			 */
			new_cpu = start_cpu;
			for (i = 0; i < phba->sli4_hba.num_present_cpu; i++) {
				new_cpup = &phba->sli4_hba.cpu_map[new_cpu];
				if (!(new_cpup->flag & LPFC_CPU_MAP_UNASSIGN) &&
				    (new_cpup->eq != LPFC_VECTOR_MAP_EMPTY))
					goto found_any;
				new_cpu = cpumask_next(
					new_cpu, cpu_present_mask);
				if (new_cpu == nr_cpumask_bits)
					new_cpu = first_cpu;
			}
			/* We should never leave an entry unassigned */
			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
					"3339 Set Affinity: CPU %d "
					"eq %d UNASSIGNED\n",
					cpup->hdwq, cpup->eq);
			continue;
found_any:
			/* We found an available entry, copy the IRQ info */
			cpup->eq = new_cpup->eq;

			/* Bump start_cpu to the next slot to minmize the
			 * chance of having multiple unassigned CPU entries
			 * selecting the same IRQ.
			 */
			start_cpu = cpumask_next(new_cpu, cpu_present_mask);
			if (start_cpu == nr_cpumask_bits)
				start_cpu = first_cpu;

			lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
					"3338 Set Affinity: CPU %d "
					"eq %d from peer cpu %d (%d/%d)\n",
					cpu, cpup->eq, new_cpu,
					new_cpup->phys_id, new_cpup->core_id);
		}
	}

	/* Assign hdwq indices that are unique across all cpus in the map
	 * that are also FIRST_CPUs.
	 */
	idx = 0;
	for_each_present_cpu(cpu) {
		cpup = &phba->sli4_hba.cpu_map[cpu];

		/* Only FIRST IRQs get a hdwq index assignment. */
		if (!(cpup->flag & LPFC_CPU_FIRST_IRQ))
			continue;

		/* 1 to 1, the first LPFC_CPU_FIRST_IRQ cpus to a unique hdwq */
		cpup->hdwq = idx;
		idx++;
		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"3333 Set Affinity: CPU %d (phys %d core %d): "
				"hdwq %d eq %d flg x%x\n",
				cpu, cpup->phys_id, cpup->core_id,
				cpup->hdwq, cpup->eq, cpup->flag);
	}
	/* Associate a hdwq with each cpu_map entry
	 * This will be 1 to 1 - hdwq to cpu, unless there are less
	 * hardware queues then CPUs. For that case we will just round-robin
	 * the available hardware queues as they get assigned to CPUs.
	 * The next_idx is the idx from the FIRST_CPU loop above to account
	 * for irq_chann < hdwq.  The idx is used for round-robin assignments
	 * and needs to start at 0.
	 */
	next_idx = idx;
	start_cpu = 0;
	idx = 0;
	for_each_present_cpu(cpu) {
		cpup = &phba->sli4_hba.cpu_map[cpu];

		/* FIRST cpus are already mapped. */
		if (cpup->flag & LPFC_CPU_FIRST_IRQ)
			continue;

		/* If the cfg_irq_chann < cfg_hdw_queue, set the hdwq
		 * of the unassigned cpus to the next idx so that all
		 * hdw queues are fully utilized.
		 */
		if (next_idx < phba->cfg_hdw_queue) {
			cpup->hdwq = next_idx;
			next_idx++;
			continue;
		}

		/* Not a First CPU and all hdw_queues are used.  Reuse a
		 * Hardware Queue for another CPU, so be smart about it
		 * and pick one that has its IRQ/EQ mapped to the same phys_id
		 * (CPU package) and core_id.
		 */
		new_cpu = start_cpu;
		for (i = 0; i < phba->sli4_hba.num_present_cpu; i++) {
			new_cpup = &phba->sli4_hba.cpu_map[new_cpu];
			if (new_cpup->hdwq != LPFC_VECTOR_MAP_EMPTY &&
			    new_cpup->phys_id == cpup->phys_id &&
			    new_cpup->core_id == cpup->core_id) {
				goto found_hdwq;
			}
			new_cpu = cpumask_next(new_cpu, cpu_present_mask);
			if (new_cpu == nr_cpumask_bits)
				new_cpu = first_cpu;
		}

		/* If we can't match both phys_id and core_id,
		 * settle for just a phys_id match.
		 */
		new_cpu = start_cpu;
		for (i = 0; i < phba->sli4_hba.num_present_cpu; i++) {
			new_cpup = &phba->sli4_hba.cpu_map[new_cpu];
			if (new_cpup->hdwq != LPFC_VECTOR_MAP_EMPTY &&
			    new_cpup->phys_id == cpup->phys_id)
				goto found_hdwq;

			new_cpu = cpumask_next(new_cpu, cpu_present_mask);
			if (new_cpu == nr_cpumask_bits)
				new_cpu = first_cpu;
		}

		/* Otherwise just round robin on cfg_hdw_queue */
		cpup->hdwq = idx % phba->cfg_hdw_queue;
		idx++;
		goto logit;
 found_hdwq:
		/* We found an available entry, copy the IRQ info */
		start_cpu = cpumask_next(new_cpu, cpu_present_mask);
		if (start_cpu == nr_cpumask_bits)
			start_cpu = first_cpu;
		cpup->hdwq = new_cpup->hdwq;
 logit:
		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"3335 Set Affinity: CPU %d (phys %d core %d): "
				"hdwq %d eq %d flg x%x\n",
				cpu, cpup->phys_id, cpup->core_id,
				cpup->hdwq, cpup->eq, cpup->flag);
	}

	/*
	 * Initialize the cpu_map slots for not-present cpus in case
	 * a cpu is hot-added. Perform a simple hdwq round robin assignment.
	 */
	idx = 0;
	for_each_possible_cpu(cpu) {
		cpup = &phba->sli4_hba.cpu_map[cpu];
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
		c_stat = per_cpu_ptr(phba->sli4_hba.c_stat, cpu);
		c_stat->hdwq_no = cpup->hdwq;
#endif
		if (cpup->hdwq != LPFC_VECTOR_MAP_EMPTY)
			continue;

		cpup->hdwq = idx++ % phba->cfg_hdw_queue;
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
		c_stat->hdwq_no = cpup->hdwq;
#endif
		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"3340 Set Affinity: not present "
				"CPU %d hdwq %d\n",
				cpu, cpup->hdwq);
	}

	/* The cpu_map array will be used later during initialization
	 * when EQ / CQ / WQs are allocated and configured.
	 */
	return;
}

/**
 * lpfc_cpuhp_get_eq
 *
 * @phba:   pointer to lpfc hba data structure.
 * @cpu:    cpu going offline
 * @eqlist: eq list to append to
 */
static int
lpfc_cpuhp_get_eq(struct lpfc_hba *phba, unsigned int cpu,
		  struct list_head *eqlist)
{
	const struct cpumask *maskp;
	struct lpfc_queue *eq;
	struct cpumask *tmp;
	u16 idx;

	tmp = kzalloc(cpumask_size(), GFP_KERNEL);
	if (!tmp)
		return -ENOMEM;

	for (idx = 0; idx < phba->cfg_irq_chann; idx++) {
		maskp = pci_irq_get_affinity(phba->pcidev, idx);
		if (!maskp)
			continue;
		/*
		 * if irq is not affinitized to the cpu going
		 * then we don't need to poll the eq attached
		 * to it.
		 */
		if (!cpumask_and(tmp, maskp, cpumask_of(cpu)))
			continue;
		/* get the cpus that are online and are affini-
		 * tized to this irq vector.  If the count is
		 * more than 1 then cpuhp is not going to shut-
		 * down this vector.  Since this cpu has not
		 * gone offline yet, we need >1.
		 */
		cpumask_and(tmp, maskp, cpu_online_mask);
		if (cpumask_weight(tmp) > 1)
			continue;

		/* Now that we have an irq to shutdown, get the eq
		 * mapped to this irq.  Note: multiple hdwq's in
		 * the software can share an eq, but eventually
		 * only eq will be mapped to this vector
		 */
		eq = phba->sli4_hba.hba_eq_hdl[idx].eq;
		list_add(&eq->_poll_list, eqlist);
	}
	kfree(tmp);
	return 0;
}

static void __lpfc_cpuhp_remove(struct lpfc_hba *phba)
{
	if (phba->sli_rev != LPFC_SLI_REV4)
		return;

	cpuhp_state_remove_instance_nocalls(lpfc_cpuhp_state,
					    &phba->cpuhp);
	/*
	 * unregistering the instance doesn't stop the polling
	 * timer. Wait for the poll timer to retire.
	 */
	synchronize_rcu();
	del_timer_sync(&phba->cpuhp_poll_timer);
}

static void lpfc_cpuhp_remove(struct lpfc_hba *phba)
{
	if (phba->pport->fc_flag & FC_OFFLINE_MODE)
		return;

	__lpfc_cpuhp_remove(phba);
}

static void lpfc_cpuhp_add(struct lpfc_hba *phba)
{
	if (phba->sli_rev != LPFC_SLI_REV4)
		return;

	rcu_read_lock();

	if (!list_empty(&phba->poll_list))
		mod_timer(&phba->cpuhp_poll_timer,
			  jiffies + msecs_to_jiffies(LPFC_POLL_HB));

	rcu_read_unlock();

	cpuhp_state_add_instance_nocalls(lpfc_cpuhp_state,
					 &phba->cpuhp);
}

static int __lpfc_cpuhp_checks(struct lpfc_hba *phba, int *retval)
{
	if (phba->pport->load_flag & FC_UNLOADING) {
		*retval = -EAGAIN;
		return true;
	}

	if (phba->sli_rev != LPFC_SLI_REV4) {
		*retval = 0;
		return true;
	}

	/* proceed with the hotplug */
	return false;
}

/**
 * lpfc_irq_set_aff - set IRQ affinity
 * @eqhdl: EQ handle
 * @cpu: cpu to set affinity
 *
 **/
static inline void
lpfc_irq_set_aff(struct lpfc_hba_eq_hdl *eqhdl, unsigned int cpu)
{
	cpumask_clear(&eqhdl->aff_mask);
	cpumask_set_cpu(cpu, &eqhdl->aff_mask);
	irq_set_status_flags(eqhdl->irq, IRQ_NO_BALANCING);
	irq_set_affinity_hint(eqhdl->irq, &eqhdl->aff_mask);
}

/**
 * lpfc_irq_clear_aff - clear IRQ affinity
 * @eqhdl: EQ handle
 *
 **/
static inline void
lpfc_irq_clear_aff(struct lpfc_hba_eq_hdl *eqhdl)
{
	cpumask_clear(&eqhdl->aff_mask);
	irq_clear_status_flags(eqhdl->irq, IRQ_NO_BALANCING);
}

/**
 * lpfc_irq_rebalance - rebalances IRQ affinity according to cpuhp event
 * @phba: pointer to HBA context object.
 * @cpu: cpu going offline/online
 * @offline: true, cpu is going offline. false, cpu is coming online.
 *
 * If cpu is going offline, we'll try our best effort to find the next
 * online cpu on the phba's original_mask and migrate all offlining IRQ
 * affinities.
 *
 * If cpu is coming online, reaffinitize the IRQ back to the onlining cpu.
 *
 * Note: Call only if NUMA or NHT mode is enabled, otherwise rely on
 *	 PCI_IRQ_AFFINITY to auto-manage IRQ affinity.
 *
 **/
static void
lpfc_irq_rebalance(struct lpfc_hba *phba, unsigned int cpu, bool offline)
{
	struct lpfc_vector_map_info *cpup;
	struct cpumask *aff_mask;
	unsigned int cpu_select, cpu_next, idx;
	const struct cpumask *orig_mask;

	if (phba->irq_chann_mode == NORMAL_MODE)
		return;

	orig_mask = &phba->sli4_hba.irq_aff_mask;

	if (!cpumask_test_cpu(cpu, orig_mask))
		return;

	cpup = &phba->sli4_hba.cpu_map[cpu];

	if (!(cpup->flag & LPFC_CPU_FIRST_IRQ))
		return;

	if (offline) {
		/* Find next online CPU on original mask */
		cpu_next = cpumask_next_wrap(cpu, orig_mask, cpu, true);
		cpu_select = lpfc_next_online_cpu(orig_mask, cpu_next);

		/* Found a valid CPU */
		if ((cpu_select < nr_cpu_ids) && (cpu_select != cpu)) {
			/* Go through each eqhdl and ensure offlining
			 * cpu aff_mask is migrated
			 */
			for (idx = 0; idx < phba->cfg_irq_chann; idx++) {
				aff_mask = lpfc_get_aff_mask(idx);

				/* Migrate affinity */
				if (cpumask_test_cpu(cpu, aff_mask))
					lpfc_irq_set_aff(lpfc_get_eq_hdl(idx),
							 cpu_select);
			}
		} else {
			/* Rely on irqbalance if no online CPUs left on NUMA */
			for (idx = 0; idx < phba->cfg_irq_chann; idx++)
				lpfc_irq_clear_aff(lpfc_get_eq_hdl(idx));
		}
	} else {
		/* Migrate affinity back to this CPU */
		lpfc_irq_set_aff(lpfc_get_eq_hdl(cpup->eq), cpu);
	}
}

static int lpfc_cpu_offline(unsigned int cpu, struct hlist_node *node)
{
	struct lpfc_hba *phba = hlist_entry_safe(node, struct lpfc_hba, cpuhp);
	struct lpfc_queue *eq, *next;
	LIST_HEAD(eqlist);
	int retval;

	if (!phba) {
		WARN_ONCE(!phba, "cpu: %u. phba:NULL", raw_smp_processor_id());
		return 0;
	}

	if (__lpfc_cpuhp_checks(phba, &retval))
		return retval;

	lpfc_irq_rebalance(phba, cpu, true);

	retval = lpfc_cpuhp_get_eq(phba, cpu, &eqlist);
	if (retval)
		return retval;

	/* start polling on these eq's */
	list_for_each_entry_safe(eq, next, &eqlist, _poll_list) {
		list_del_init(&eq->_poll_list);
		lpfc_sli4_start_polling(eq);
	}

	return 0;
}

static int lpfc_cpu_online(unsigned int cpu, struct hlist_node *node)
{
	struct lpfc_hba *phba = hlist_entry_safe(node, struct lpfc_hba, cpuhp);
	struct lpfc_queue *eq, *next;
	unsigned int n;
	int retval;

	if (!phba) {
		WARN_ONCE(!phba, "cpu: %u. phba:NULL", raw_smp_processor_id());
		return 0;
	}

	if (__lpfc_cpuhp_checks(phba, &retval))
		return retval;

	lpfc_irq_rebalance(phba, cpu, false);

	list_for_each_entry_safe(eq, next, &phba->poll_list, _poll_list) {
		n = lpfc_find_cpu_handle(phba, eq->hdwq, LPFC_FIND_BY_HDWQ);
		if (n == cpu)
			lpfc_sli4_stop_polling(eq);
	}

	return 0;
}

/**
 * lpfc_sli4_enable_msix - Enable MSI-X interrupt mode to SLI-4 device
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to enable the MSI-X interrupt vectors to device
 * with SLI-4 interface spec.  It also allocates MSI-X vectors and maps them
 * to cpus on the system.
 *
 * When cfg_irq_numa is enabled, the adapter will only allocate vectors for
 * the number of cpus on the same numa node as this adapter.  The vectors are
 * allocated without requesting OS affinity mapping.  A vector will be
 * allocated and assigned to each online and offline cpu.  If the cpu is
 * online, then affinity will be set to that cpu.  If the cpu is offline, then
 * affinity will be set to the nearest peer cpu within the numa node that is
 * online.  If there are no online cpus within the numa node, affinity is not
 * assigned and the OS may do as it pleases. Note: cpu vector affinity mapping
 * is consistent with the way cpu online/offline is handled when cfg_irq_numa is
 * configured.
 *
 * If numa mode is not enabled and there is more than 1 vector allocated, then
 * the driver relies on the managed irq interface where the OS assigns vector to
 * cpu affinity.  The driver will then use that affinity mapping to setup its
 * cpu mapping table.
 *
 * Return codes
 * 0 - successful
 * other values - error
 **/
static int
lpfc_sli4_enable_msix(struct lpfc_hba *phba)
{
	int vectors, rc, index;
	char *name;
	const struct cpumask *aff_mask = NULL;
	unsigned int cpu = 0, cpu_cnt = 0, cpu_select = nr_cpu_ids;
	struct lpfc_vector_map_info *cpup;
	struct lpfc_hba_eq_hdl *eqhdl;
	const struct cpumask *maskp;
	unsigned int flags = PCI_IRQ_MSIX;

	/* Set up MSI-X multi-message vectors */
	vectors = phba->cfg_irq_chann;

	if (phba->irq_chann_mode != NORMAL_MODE)
		aff_mask = &phba->sli4_hba.irq_aff_mask;

	if (aff_mask) {
		cpu_cnt = cpumask_weight(aff_mask);
		vectors = min(phba->cfg_irq_chann, cpu_cnt);

		/* cpu: iterates over aff_mask including offline or online
		 * cpu_select: iterates over online aff_mask to set affinity
		 */
		cpu = cpumask_first(aff_mask);
		cpu_select = lpfc_next_online_cpu(aff_mask, cpu);
	} else {
		flags |= PCI_IRQ_AFFINITY;
	}

	rc = pci_alloc_irq_vectors(phba->pcidev, 1, vectors, flags);
	if (rc < 0) {
		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"0484 PCI enable MSI-X failed (%d)\n", rc);
		goto vec_fail_out;
	}
	vectors = rc;

	/* Assign MSI-X vectors to interrupt handlers */
	for (index = 0; index < vectors; index++) {
		eqhdl = lpfc_get_eq_hdl(index);
		name = eqhdl->handler_name;
		memset(name, 0, LPFC_SLI4_HANDLER_NAME_SZ);
		snprintf(name, LPFC_SLI4_HANDLER_NAME_SZ,
			 LPFC_DRIVER_HANDLER_NAME"%d", index);

		eqhdl->idx = index;
		rc = request_irq(pci_irq_vector(phba->pcidev, index),
			 &lpfc_sli4_hba_intr_handler, 0,
			 name, eqhdl);
		if (rc) {
			lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
					"0486 MSI-X fast-path (%d) "
					"request_irq failed (%d)\n", index, rc);
			goto cfg_fail_out;
		}

		eqhdl->irq = pci_irq_vector(phba->pcidev, index);

		if (aff_mask) {
			/* If found a neighboring online cpu, set affinity */
			if (cpu_select < nr_cpu_ids)
				lpfc_irq_set_aff(eqhdl, cpu_select);

			/* Assign EQ to cpu_map */
			lpfc_assign_eq_map_info(phba, index,
						LPFC_CPU_FIRST_IRQ,
						cpu);

			/* Iterate to next offline or online cpu in aff_mask */
			cpu = cpumask_next(cpu, aff_mask);

			/* Find next online cpu in aff_mask to set affinity */
			cpu_select = lpfc_next_online_cpu(aff_mask, cpu);
		} else if (vectors == 1) {
			cpu = cpumask_first(cpu_present_mask);
			lpfc_assign_eq_map_info(phba, index, LPFC_CPU_FIRST_IRQ,
						cpu);
		} else {
			maskp = pci_irq_get_affinity(phba->pcidev, index);

			/* Loop through all CPUs associated with vector index */
			for_each_cpu_and(cpu, maskp, cpu_present_mask) {
				cpup = &phba->sli4_hba.cpu_map[cpu];

				/* If this is the first CPU thats assigned to
				 * this vector, set LPFC_CPU_FIRST_IRQ.
				 *
				 * With certain platforms its possible that irq
				 * vectors are affinitized to all the cpu's.
				 * This can result in each cpu_map.eq to be set
				 * to the last vector, resulting in overwrite
				 * of all the previous cpu_map.eq.  Ensure that
				 * each vector receives a place in cpu_map.
				 * Later call to lpfc_cpu_affinity_check will
				 * ensure we are nicely balanced out.
				 */
				if (cpup->eq != LPFC_VECTOR_MAP_EMPTY)
					continue;
				lpfc_assign_eq_map_info(phba, index,
							LPFC_CPU_FIRST_IRQ,
							cpu);
				break;
			}
		}
	}

	if (vectors != phba->cfg_irq_chann) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3238 Reducing IO channels to match number of "
				"MSI-X vectors, requested %d got %d\n",
				phba->cfg_irq_chann, vectors);
		if (phba->cfg_irq_chann > vectors)
			phba->cfg_irq_chann = vectors;
	}

	return rc;

cfg_fail_out:
	/* free the irq already requested */
	for (--index; index >= 0; index--) {
		eqhdl = lpfc_get_eq_hdl(index);
		lpfc_irq_clear_aff(eqhdl);
		irq_set_affinity_hint(eqhdl->irq, NULL);
		free_irq(eqhdl->irq, eqhdl);
	}

	/* Unconfigure MSI-X capability structure */
	pci_free_irq_vectors(phba->pcidev);

vec_fail_out:
	return rc;
}

/**
 * lpfc_sli4_enable_msi - Enable MSI interrupt mode to SLI-4 device
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to enable the MSI interrupt mode to device with
 * SLI-4 interface spec. The kernel function pci_alloc_irq_vectors() is
 * called to enable the MSI vector. The device driver is responsible for
 * calling the request_irq() to register MSI vector with a interrupt the
 * handler, which is done in this function.
 *
 * Return codes
 * 	0 - successful
 * 	other values - error
 **/
static int
lpfc_sli4_enable_msi(struct lpfc_hba *phba)
{
	int rc, index;
	unsigned int cpu;
	struct lpfc_hba_eq_hdl *eqhdl;

	rc = pci_alloc_irq_vectors(phba->pcidev, 1, 1,
				   PCI_IRQ_MSI | PCI_IRQ_AFFINITY);
	if (rc > 0)
		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"0487 PCI enable MSI mode success.\n");
	else {
		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
				"0488 PCI enable MSI mode failed (%d)\n", rc);
		return rc ? rc : -1;
	}

	rc = request_irq(phba->pcidev->irq, lpfc_sli4_intr_handler,
			 0, LPFC_DRIVER_NAME, phba);
	if (rc) {
		pci_free_irq_vectors(phba->pcidev);
		lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
				"0490 MSI request_irq failed (%d)\n", rc);
		return rc;
	}

	eqhdl = lpfc_get_eq_hdl(0);
	eqhdl->irq = pci_irq_vector(phba->pcidev, 0);

	cpu = cpumask_first(cpu_present_mask);
	lpfc_assign_eq_map_info(phba, 0, LPFC_CPU_FIRST_IRQ, cpu);

	for (index = 0; index < phba->cfg_irq_chann; index++) {
		eqhdl = lpfc_get_eq_hdl(index);
		eqhdl->idx = index;
	}

	return 0;
}

/**
 * lpfc_sli4_enable_intr - Enable device interrupt to SLI-4 device
 * @phba: pointer to lpfc hba data structure.
 * @cfg_mode: Interrupt configuration mode (INTx, MSI or MSI-X).
 *
 * This routine is invoked to enable device interrupt and associate driver's
 * interrupt handler(s) to interrupt vector(s) to device with SLI-4
 * interface spec. Depends on the interrupt mode configured to the driver,
 * the driver will try to fallback from the configured interrupt mode to an
 * interrupt mode which is supported by the platform, kernel, and device in
 * the order of:
 * MSI-X -> MSI -> IRQ.
 *
 * Return codes
 * 	0 - successful
 * 	other values - error
 **/
static uint32_t
lpfc_sli4_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode)
{
	uint32_t intr_mode = LPFC_INTR_ERROR;
	int retval, idx;

	if (cfg_mode == 2) {
		/* Preparation before conf_msi mbox cmd */
		retval = 0;
		if (!retval) {
			/* Now, try to enable MSI-X interrupt mode */
			retval = lpfc_sli4_enable_msix(phba);
			if (!retval) {
				/* Indicate initialization to MSI-X mode */
				phba->intr_type = MSIX;
				intr_mode = 2;
			}
		}
	}

	/* Fallback to MSI if MSI-X initialization failed */
	if (cfg_mode >= 1 && phba->intr_type == NONE) {
		retval = lpfc_sli4_enable_msi(phba);
		if (!retval) {
			/* Indicate initialization to MSI mode */
			phba->intr_type = MSI;
			intr_mode = 1;
		}
	}

	/* Fallback to INTx if both MSI-X/MSI initalization failed */
	if (phba->intr_type == NONE) {
		retval = request_irq(phba->pcidev->irq, lpfc_sli4_intr_handler,
				     IRQF_SHARED, LPFC_DRIVER_NAME, phba);
		if (!retval) {
			struct lpfc_hba_eq_hdl *eqhdl;
			unsigned int cpu;

			/* Indicate initialization to INTx mode */
			phba->intr_type = INTx;
			intr_mode = 0;

			eqhdl = lpfc_get_eq_hdl(0);
			eqhdl->irq = pci_irq_vector(phba->pcidev, 0);

			cpu = cpumask_first(cpu_present_mask);
			lpfc_assign_eq_map_info(phba, 0, LPFC_CPU_FIRST_IRQ,
						cpu);
			for (idx = 0; idx < phba->cfg_irq_chann; idx++) {
				eqhdl = lpfc_get_eq_hdl(idx);
				eqhdl->idx = idx;
			}
		}
	}
	return intr_mode;
}

/**
 * lpfc_sli4_disable_intr - Disable device interrupt to SLI-4 device
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to disable device interrupt and disassociate
 * the driver's interrupt handler(s) from interrupt vector(s) to device
 * with SLI-4 interface spec. Depending on the interrupt mode, the driver
 * will release the interrupt vector(s) for the message signaled interrupt.
 **/
static void
lpfc_sli4_disable_intr(struct lpfc_hba *phba)
{
	/* Disable the currently initialized interrupt mode */
	if (phba->intr_type == MSIX) {
		int index;
		struct lpfc_hba_eq_hdl *eqhdl;

		/* Free up MSI-X multi-message vectors */
		for (index = 0; index < phba->cfg_irq_chann; index++) {
			eqhdl = lpfc_get_eq_hdl(index);
			lpfc_irq_clear_aff(eqhdl);
			irq_set_affinity_hint(eqhdl->irq, NULL);
			free_irq(eqhdl->irq, eqhdl);
		}
	} else {
		free_irq(phba->pcidev->irq, phba);
	}

	pci_free_irq_vectors(phba->pcidev);

	/* Reset interrupt management states */
	phba->intr_type = NONE;
	phba->sli.slistat.sli_intr = 0;
}

/**
 * lpfc_unset_hba - Unset SLI3 hba device initialization
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is invoked to unset the HBA device initialization steps to
 * a device with SLI-3 interface spec.
 **/
static void
lpfc_unset_hba(struct lpfc_hba *phba)
{
	struct lpfc_vport *vport = phba->pport;
	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);

	spin_lock_irq(shost->host_lock);
	vport->load_flag |= FC_UNLOADING;
	spin_unlock_irq(shost->host_lock);

	kfree(phba->vpi_bmask);
	kfree(phba->vpi_ids);

	lpfc_stop_hba_timers(phba);

	phba->pport->work_port_events = 0;

	lpfc_sli_hba_down(phba);

	lpfc_sli_brdrestart(phba);

	lpfc_sli_disable_intr(phba);

	return;
}

/**
 * lpfc_sli4_xri_exchange_busy_wait - Wait for device XRI exchange busy
 * @phba: Pointer to HBA context object.
 *
 * This function is called in the SLI4 code path to wait for completion
 * of device's XRIs exchange busy. It will check the XRI exchange busy
 * on outstanding FCP and ELS I/Os every 10ms for up to 10 seconds; after
 * that, it will check the XRI exchange busy on outstanding FCP and ELS
 * I/Os every 30 seconds, log error message, and wait forever. Only when
 * all XRI exchange busy complete, the driver unload shall proceed with
 * invoking the function reset ioctl mailbox command to the CNA and the
 * the rest of the driver unload resource release.
 **/
static void
lpfc_sli4_xri_exchange_busy_wait(struct lpfc_hba *phba)
{
	struct lpfc_sli4_hdw_queue *qp;
	int idx, ccnt;
	int wait_time = 0;
	int io_xri_cmpl = 1;
	int nvmet_xri_cmpl = 1;
	int els_xri_cmpl = list_empty(&phba->sli4_hba.lpfc_abts_els_sgl_list);

	/* Driver just aborted IOs during the hba_unset process.  Pause
	 * here to give the HBA time to complete the IO and get entries
	 * into the abts lists.
	 */
	msleep(LPFC_XRI_EXCH_BUSY_WAIT_T1 * 5);

	/* Wait for NVME pending IO to flush back to transport. */
	if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME)
		lpfc_nvme_wait_for_io_drain(phba);

	ccnt = 0;
	for (idx = 0; idx < phba->cfg_hdw_queue; idx++) {
		qp = &phba->sli4_hba.hdwq[idx];
		io_xri_cmpl = list_empty(&qp->lpfc_abts_io_buf_list);
		if (!io_xri_cmpl) /* if list is NOT empty */
			ccnt++;
	}
	if (ccnt)
		io_xri_cmpl = 0;

	if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
		nvmet_xri_cmpl =
			list_empty(&phba->sli4_hba.lpfc_abts_nvmet_ctx_list);
	}

	while (!els_xri_cmpl || !io_xri_cmpl || !nvmet_xri_cmpl) {
		if (wait_time > LPFC_XRI_EXCH_BUSY_WAIT_TMO) {
			if (!nvmet_xri_cmpl)
				lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
						"6424 NVMET XRI exchange busy "
						"wait time: %d seconds.\n",
						wait_time/1000);
			if (!io_xri_cmpl)
				lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
						"6100 IO XRI exchange busy "
						"wait time: %d seconds.\n",
						wait_time/1000);
			if (!els_xri_cmpl)
				lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
						"2878 ELS XRI exchange busy "
						"wait time: %d seconds.\n",
						wait_time/1000);
			msleep(LPFC_XRI_EXCH_BUSY_WAIT_T2);
			wait_time += LPFC_XRI_EXCH_BUSY_WAIT_T2;
		} else {
			msleep(LPFC_XRI_EXCH_BUSY_WAIT_T1);
			wait_time += LPFC_XRI_EXCH_BUSY_WAIT_T1;
		}

		ccnt = 0;
		for (idx = 0; idx < phba->cfg_hdw_queue; idx++) {
			qp = &phba->sli4_hba.hdwq[idx];
			io_xri_cmpl = list_empty(
			    &qp->lpfc_abts_io_buf_list);
			if (!io_xri_cmpl) /* if list is NOT empty */
				ccnt++;
		}
		if (ccnt)
			io_xri_cmpl = 0;

		if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
			nvmet_xri_cmpl = list_empty(
				&phba->sli4_hba.lpfc_abts_nvmet_ctx_list);
		}
		els_xri_cmpl =
			list_empty(&phba->sli4_hba.lpfc_abts_els_sgl_list);

	}
}

/**
 * lpfc_sli4_hba_unset - Unset the fcoe hba
 * @phba: Pointer to HBA context object.
 *
 * This function is called in the SLI4 code path to reset the HBA's FCoE
 * function. The caller is not required to hold any lock. This routine
 * issues PCI function reset mailbox command to reset the FCoE function.
 * At the end of the function, it calls lpfc_hba_down_post function to
 * free any pending commands.
 **/
static void
lpfc_sli4_hba_unset(struct lpfc_hba *phba)
{
	int wait_cnt = 0;
	LPFC_MBOXQ_t *mboxq;
	struct pci_dev *pdev = phba->pcidev;

	lpfc_stop_hba_timers(phba);
	hrtimer_cancel(&phba->cmf_timer);

	if (phba->pport)
		phba->sli4_hba.intr_enable = 0;

	/*
	 * Gracefully wait out the potential current outstanding asynchronous
	 * mailbox command.
	 */

	/* First, block any pending async mailbox command from posted */
	spin_lock_irq(&phba->hbalock);
	phba->sli.sli_flag |= LPFC_SLI_ASYNC_MBX_BLK;
	spin_unlock_irq(&phba->hbalock);
	/* Now, trying to wait it out if we can */
	while (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE) {
		msleep(10);
		if (++wait_cnt > LPFC_ACTIVE_MBOX_WAIT_CNT)
			break;
	}
	/* Forcefully release the outstanding mailbox command if timed out */
	if (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE) {
		spin_lock_irq(&phba->hbalock);
		mboxq = phba->sli.mbox_active;
		mboxq->u.mb.mbxStatus = MBX_NOT_FINISHED;
		__lpfc_mbox_cmpl_put(phba, mboxq);
		phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
		phba->sli.mbox_active = NULL;
		spin_unlock_irq(&phba->hbalock);
	}

	/* Abort all iocbs associated with the hba */
	lpfc_sli_hba_iocb_abort(phba);

	/* Wait for completion of device XRI exchange busy */
	lpfc_sli4_xri_exchange_busy_wait(phba);

	/* per-phba callback de-registration for hotplug event */
	if (phba->pport)
		lpfc_cpuhp_remove(phba);

	/* Disable PCI subsystem interrupt */
	lpfc_sli4_disable_intr(phba);

	/* Disable SR-IOV if enabled */
	if (phba->cfg_sriov_nr_virtfn)
		pci_disable_sriov(pdev);

	/* Stop kthread signal shall trigger work_done one more time */
	kthread_stop(phba->worker_thread);

	/* Disable FW logging to host memory */
	lpfc_ras_stop_fwlog(phba);

	/* Unset the queues shared with the hardware then release all
	 * allocated resources.
	 */
	lpfc_sli4_queue_unset(phba);
	lpfc_sli4_queue_destroy(phba);

	/* Reset SLI4 HBA FCoE function */
	lpfc_pci_function_reset(phba);

	/* Free RAS DMA memory */
	if (phba->ras_fwlog.ras_enabled)
		lpfc_sli4_ras_dma_free(phba);

	/* Stop the SLI4 device port */
	if (phba->pport)
		phba->pport->work_port_events = 0;
}

static uint32_t
lpfc_cgn_crc32(uint32_t crc, u8 byte)
{
	uint32_t msb = 0;
	uint32_t bit;

	for (bit = 0; bit < 8; bit++) {
		msb = (crc >> 31) & 1;
		crc <<= 1;

		if (msb ^ (byte & 1)) {
			crc ^= LPFC_CGN_CRC32_MAGIC_NUMBER;
			crc |= 1;
		}
		byte >>= 1;
	}
	return crc;
}

static uint32_t
lpfc_cgn_reverse_bits(uint32_t wd)
{
	uint32_t result = 0;
	uint32_t i;

	for (i = 0; i < 32; i++) {
		result <<= 1;
		result |= (1 & (wd >> i));
	}
	return result;
}

/*
 * The routine corresponds with the algorithm the HBA firmware
 * uses to validate the data integrity.
 */
uint32_t
lpfc_cgn_calc_crc32(void *ptr, uint32_t byteLen, uint32_t crc)
{
	uint32_t  i;
	uint32_t result;
	uint8_t  *data = (uint8_t *)ptr;

	for (i = 0; i < byteLen; ++i)
		crc = lpfc_cgn_crc32(crc, data[i]);

	result = ~lpfc_cgn_reverse_bits(crc);
	return result;
}

void
lpfc_init_congestion_buf(struct lpfc_hba *phba)
{
	struct lpfc_cgn_info *cp;
	struct timespec64 cmpl_time;
	struct tm broken;
	uint16_t size;
	uint32_t crc;

	lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
			"6235 INIT Congestion Buffer %p\n", phba->cgn_i);

	if (!phba->cgn_i)
		return;
	cp = (struct lpfc_cgn_info *)phba->cgn_i->virt;

	atomic_set(&phba->cgn_fabric_warn_cnt, 0);
	atomic_set(&phba->cgn_fabric_alarm_cnt, 0);
	atomic_set(&phba->cgn_sync_alarm_cnt, 0);
	atomic_set(&phba->cgn_sync_warn_cnt, 0);

	atomic_set(&phba->cgn_driver_evt_cnt, 0);
	atomic_set(&phba->cgn_latency_evt_cnt, 0);
	atomic64_set(&phba->cgn_latency_evt, 0);
	phba->cgn_evt_minute = 0;
	phba->hba_flag &= ~HBA_CGN_DAY_WRAP;

	memset(cp, 0xff, LPFC_CGN_DATA_SIZE);
	cp->cgn_info_size = cpu_to_le16(LPFC_CGN_INFO_SZ);
	cp->cgn_info_version = LPFC_CGN_INFO_V3;

	/* cgn parameters */
	cp->cgn_info_mode = phba->cgn_p.cgn_param_mode;
	cp->cgn_info_level0 = phba->cgn_p.cgn_param_level0;
	cp->cgn_info_level1 = phba->cgn_p.cgn_param_level1;
	cp->cgn_info_level2 = phba->cgn_p.cgn_param_level2;

	ktime_get_real_ts64(&cmpl_time);
	time64_to_tm(cmpl_time.tv_sec, 0, &broken);

	cp->cgn_info_month = broken.tm_mon + 1;
	cp->cgn_info_day = broken.tm_mday;
	cp->cgn_info_year = broken.tm_year - 100; /* relative to 2000 */
	cp->cgn_info_hour = broken.tm_hour;
	cp->cgn_info_minute = broken.tm_min;
	cp->cgn_info_second = broken.tm_sec;

	lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT | LOG_INIT,
			"2643 CGNInfo Init: Start Time "
			"%d/%d/%d %d:%d:%d\n",
			cp->cgn_info_day, cp->cgn_info_month,
			cp->cgn_info_year, cp->cgn_info_hour,
			cp->cgn_info_minute, cp->cgn_info_second);

	/* Fill in default LUN qdepth */
	if (phba->pport) {
		size = (uint16_t)(phba->pport->cfg_lun_queue_depth);
		cp->cgn_lunq = cpu_to_le16(size);
	}

	/* last used Index initialized to 0xff already */

	cp->cgn_warn_freq = cpu_to_le16(LPFC_FPIN_INIT_FREQ);
	cp->cgn_alarm_freq = cpu_to_le16(LPFC_FPIN_INIT_FREQ);
	crc = lpfc_cgn_calc_crc32(cp, LPFC_CGN_INFO_SZ, LPFC_CGN_CRC32_SEED);
	cp->cgn_info_crc = cpu_to_le32(crc);

	phba->cgn_evt_timestamp = jiffies +
		msecs_to_jiffies(LPFC_CGN_TIMER_TO_MIN);
}

void
lpfc_init_congestion_stat(struct lpfc_hba *phba)
{
	struct lpfc_cgn_info *cp;
	struct timespec64 cmpl_time;
	struct tm broken;
	uint32_t crc;

	lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
			"6236 INIT Congestion Stat %p\n", phba->cgn_i);

	if (!phba->cgn_i)
		return;

	cp = (struct lpfc_cgn_info *)phba->cgn_i->virt;
	memset(&cp->cgn_stat_npm, 0, LPFC_CGN_STAT_SIZE);

	ktime_get_real_ts64(&cmpl_time);
	time64_to_tm(cmpl_time.tv_sec, 0, &broken);

	cp->cgn_stat_month = broken.tm_mon + 1;
	cp->cgn_stat_day = broken.tm_mday;
	cp->cgn_stat_year = broken.tm_year - 100; /* relative to 2000 */
	cp->cgn_stat_hour = broken.tm_hour;
	cp->cgn_stat_minute = broken.tm_min;

	lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT | LOG_INIT,
			"2647 CGNstat Init: Start Time "
			"%d/%d/%d %d:%d\n",
			cp->cgn_stat_day, cp->cgn_stat_month,
			cp->cgn_stat_year, cp->cgn_stat_hour,
			cp->cgn_stat_minute);

	crc = lpfc_cgn_calc_crc32(cp, LPFC_CGN_INFO_SZ, LPFC_CGN_CRC32_SEED);
	cp->cgn_info_crc = cpu_to_le32(crc);
}

/**
 * __lpfc_reg_congestion_buf - register congestion info buffer with HBA
 * @phba: Pointer to hba context object.
 * @reg: flag to determine register or unregister.
 */
static int
__lpfc_reg_congestion_buf(struct lpfc_hba *phba, int reg)
{
	struct lpfc_mbx_reg_congestion_buf *reg_congestion_buf;
	union  lpfc_sli4_cfg_shdr *shdr;
	uint32_t shdr_status, shdr_add_status;
	LPFC_MBOXQ_t *mboxq;
	int length, rc;

	if (!phba->cgn_i)
		return -ENXIO;

	mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (!mboxq) {
		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
				"2641 REG_CONGESTION_BUF mbox allocation fail: "
				"HBA state x%x reg %d\n",
				phba->pport->port_state, reg);
		return -ENOMEM;
	}

	length = (sizeof(struct lpfc_mbx_reg_congestion_buf) -
		sizeof(struct lpfc_sli4_cfg_mhdr));
	lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
			 LPFC_MBOX_OPCODE_REG_CONGESTION_BUF, length,
			 LPFC_SLI4_MBX_EMBED);
	reg_congestion_buf = &mboxq->u.mqe.un.reg_congestion_buf;
	bf_set(lpfc_mbx_reg_cgn_buf_type, reg_congestion_buf, 1);
	if (reg > 0)
		bf_set(lpfc_mbx_reg_cgn_buf_cnt, reg_congestion_buf, 1);
	else
		bf_set(lpfc_mbx_reg_cgn_buf_cnt, reg_congestion_buf, 0);
	reg_congestion_buf->length = sizeof(struct lpfc_cgn_info);
	reg_congestion_buf->addr_lo =
		putPaddrLow(phba->cgn_i->phys);
	reg_congestion_buf->addr_hi =
		putPaddrHigh(phba->cgn_i->phys);

	rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
	shdr = (union lpfc_sli4_cfg_shdr *)
		&mboxq->u.mqe.un.sli4_config.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);
	mempool_free(mboxq, phba->mbox_mem_pool);
	if (shdr_status || shdr_add_status || rc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"2642 REG_CONGESTION_BUF mailbox "
				"failed with status x%x add_status x%x,"
				" mbx status x%x reg %d\n",
				shdr_status, shdr_add_status, rc, reg);
		return -ENXIO;
	}
	return 0;
}

int
lpfc_unreg_congestion_buf(struct lpfc_hba *phba)
{
	lpfc_cmf_stop(phba);
	return __lpfc_reg_congestion_buf(phba, 0);
}

int
lpfc_reg_congestion_buf(struct lpfc_hba *phba)
{
	return __lpfc_reg_congestion_buf(phba, 1);
}

/**
 * lpfc_get_sli4_parameters - Get the SLI4 Config PARAMETERS.
 * @phba: Pointer to HBA context object.
 * @mboxq: Pointer to the mailboxq memory for the mailbox command response.
 *
 * This function is called in the SLI4 code path to read the port's
 * sli4 capabilities.
 *
 * This function may be be called from any context that can block-wait
 * for the completion.  The expectation is that this routine is called
 * typically from probe_one or from the online routine.
 **/
int
lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
{
	int rc;
	struct lpfc_mqe *mqe = &mboxq->u.mqe;
	struct lpfc_pc_sli4_params *sli4_params;
	uint32_t mbox_tmo;
	int length;
	bool exp_wqcq_pages = true;
	struct lpfc_sli4_parameters *mbx_sli4_parameters;

	/*
	 * By default, the driver assumes the SLI4 port requires RPI
	 * header postings.  The SLI4_PARAM response will correct this
	 * assumption.
	 */
	phba->sli4_hba.rpi_hdrs_in_use = 1;

	/* Read the port's SLI4 Config Parameters */
	length = (sizeof(struct lpfc_mbx_get_sli4_parameters) -
		  sizeof(struct lpfc_sli4_cfg_mhdr));
	lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
			 LPFC_MBOX_OPCODE_GET_SLI4_PARAMETERS,
			 length, LPFC_SLI4_MBX_EMBED);
	if (!phba->sli4_hba.intr_enable)
		rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
	else {
		mbox_tmo = lpfc_mbox_tmo_val(phba, mboxq);
		rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo);
	}
	if (unlikely(rc))
		return rc;
	sli4_params = &phba->sli4_hba.pc_sli4_params;
	mbx_sli4_parameters = &mqe->un.get_sli4_parameters.sli4_parameters;
	sli4_params->if_type = bf_get(cfg_if_type, mbx_sli4_parameters);
	sli4_params->sli_rev = bf_get(cfg_sli_rev, mbx_sli4_parameters);
	sli4_params->sli_family = bf_get(cfg_sli_family, mbx_sli4_parameters);
	sli4_params->featurelevel_1 = bf_get(cfg_sli_hint_1,
					     mbx_sli4_parameters);
	sli4_params->featurelevel_2 = bf_get(cfg_sli_hint_2,
					     mbx_sli4_parameters);
	if (bf_get(cfg_phwq, mbx_sli4_parameters))
		phba->sli3_options |= LPFC_SLI4_PHWQ_ENABLED;
	else
		phba->sli3_options &= ~LPFC_SLI4_PHWQ_ENABLED;
	sli4_params->sge_supp_len = mbx_sli4_parameters->sge_supp_len;
	sli4_params->loopbk_scope = bf_get(cfg_loopbk_scope,
					   mbx_sli4_parameters);
	sli4_params->oas_supported = bf_get(cfg_oas, mbx_sli4_parameters);
	sli4_params->cqv = bf_get(cfg_cqv, mbx_sli4_parameters);
	sli4_params->mqv = bf_get(cfg_mqv, mbx_sli4_parameters);
	sli4_params->wqv = bf_get(cfg_wqv, mbx_sli4_parameters);
	sli4_params->rqv = bf_get(cfg_rqv, mbx_sli4_parameters);
	sli4_params->eqav = bf_get(cfg_eqav, mbx_sli4_parameters);
	sli4_params->cqav = bf_get(cfg_cqav, mbx_sli4_parameters);
	sli4_params->wqsize = bf_get(cfg_wqsize, mbx_sli4_parameters);
	sli4_params->bv1s = bf_get(cfg_bv1s, mbx_sli4_parameters);
	sli4_params->pls = bf_get(cfg_pvl, mbx_sli4_parameters);
	sli4_params->sgl_pages_max = bf_get(cfg_sgl_page_cnt,
					    mbx_sli4_parameters);
	sli4_params->wqpcnt = bf_get(cfg_wqpcnt, mbx_sli4_parameters);
	sli4_params->sgl_pp_align = bf_get(cfg_sgl_pp_align,
					   mbx_sli4_parameters);
	phba->sli4_hba.extents_in_use = bf_get(cfg_ext, mbx_sli4_parameters);
	phba->sli4_hba.rpi_hdrs_in_use = bf_get(cfg_hdrr, mbx_sli4_parameters);

	/* Check for Extended Pre-Registered SGL support */
	phba->cfg_xpsgl = bf_get(cfg_xpsgl, mbx_sli4_parameters);

	/* Check for firmware nvme support */
	rc = (bf_get(cfg_nvme, mbx_sli4_parameters) &&
		     bf_get(cfg_xib, mbx_sli4_parameters));

	if (rc) {
		/* Save this to indicate the Firmware supports NVME */
		sli4_params->nvme = 1;

		/* Firmware NVME support, check driver FC4 NVME support */
		if (phba->cfg_enable_fc4_type == LPFC_ENABLE_FCP) {
			lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_NVME,
					"6133 Disabling NVME support: "
					"FC4 type not supported: x%x\n",
					phba->cfg_enable_fc4_type);
			goto fcponly;
		}
	} else {
		/* No firmware NVME support, check driver FC4 NVME support */
		sli4_params->nvme = 0;
		if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
			lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_NVME,
					"6101 Disabling NVME support: Not "
					"supported by firmware (%d %d) x%x\n",
					bf_get(cfg_nvme, mbx_sli4_parameters),
					bf_get(cfg_xib, mbx_sli4_parameters),
					phba->cfg_enable_fc4_type);
fcponly:
			phba->nvmet_support = 0;
			phba->cfg_nvmet_mrq = 0;
			phba->cfg_nvme_seg_cnt = 0;

			/* If no FC4 type support, move to just SCSI support */
			if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP))
				return -ENODEV;
			phba->cfg_enable_fc4_type = LPFC_ENABLE_FCP;
		}
	}

	/* If the NVME FC4 type is enabled, scale the sg_seg_cnt to
	 * accommodate 512K and 1M IOs in a single nvme buf.
	 */
	if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME)
		phba->cfg_sg_seg_cnt = LPFC_MAX_NVME_SEG_CNT;

	/* Enable embedded Payload BDE if support is indicated */
	if (bf_get(cfg_pbde, mbx_sli4_parameters))
		phba->cfg_enable_pbde = 1;
	else
		phba->cfg_enable_pbde = 0;

	/*
	 * 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;

	/* Make sure that sge_supp_len can be handled by the driver */
	if (sli4_params->sge_supp_len > LPFC_MAX_SGE_SIZE)
		sli4_params->sge_supp_len = LPFC_MAX_SGE_SIZE;

	/*
	 * 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;

	lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_NVME,
			"6422 XIB %d PBDE %d: FCP %d NVME %d %d %d\n",
			bf_get(cfg_xib, mbx_sli4_parameters),
			phba->cfg_enable_pbde,
			phba->fcp_embed_io, sli4_params->nvme,
			phba->cfg_nvme_embed_cmd, phba->cfg_suppress_rsp);

	if ((bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
	    LPFC_SLI_INTF_IF_TYPE_2) &&
	    (bf_get(lpfc_sli_intf_sli_family, &phba->sli4_hba.sli_intf) ==
		 LPFC_SLI_INTF_FAMILY_LNCR_A0))
		exp_wqcq_pages = false;

	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) &&
	    exp_wqcq_pages &&
	    (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
	 */
	if (bf_get(cfg_mds_diags, mbx_sli4_parameters))
		phba->mds_diags_support = 1;
	else
		phba->mds_diags_support = 0;

	/*
	 * Check if the SLI port supports NSLER
	 */
	if (bf_get(cfg_nsler, mbx_sli4_parameters))
		phba->nsler = 1;
	else
		phba->nsler = 0;

	return 0;
}

/**
 * lpfc_pci_probe_one_s3 - PCI probe func to reg SLI-3 device to PCI subsystem.
 * @pdev: pointer to PCI device
 * @pid: pointer to PCI device identifier
 *
 * This routine is to be called to attach a device with SLI-3 interface spec
 * to the PCI subsystem. When an Emulex HBA with SLI-3 interface spec is
 * presented on PCI bus, the kernel PCI subsystem looks at PCI device-specific
 * information of the device and driver to see if the driver state that it can
 * support this kind of device. If the match is successful, the driver core
 * invokes this routine. If this routine determines it can claim the HBA, it
 * does all the initialization that it needs to do to handle the HBA properly.
 *
 * Return code
 * 	0 - driver can claim the device
 * 	negative value - driver can not claim the device
 **/
static int
lpfc_pci_probe_one_s3(struct pci_dev *pdev, const struct pci_device_id *pid)
{
	struct lpfc_hba   *phba;
	struct lpfc_vport *vport = NULL;
	struct Scsi_Host  *shost = NULL;
	int error;
	uint32_t cfg_mode, intr_mode;

	/* Allocate memory for HBA structure */
	phba = lpfc_hba_alloc(pdev);
	if (!phba)
		return -ENOMEM;

	/* Perform generic PCI device enabling operation */
	error = lpfc_enable_pci_dev(phba);
	if (error)
		goto out_free_phba;

	/* Set up SLI API function jump table for PCI-device group-0 HBAs */
	error = lpfc_api_table_setup(phba, LPFC_PCI_DEV_LP);
	if (error)
		goto out_disable_pci_dev;

	/* Set up SLI-3 specific device PCI memory space */
	error = lpfc_sli_pci_mem_setup(phba);
	if (error) {
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"1402 Failed to set up pci memory space.\n");
		goto out_disable_pci_dev;
	}

	/* Set up SLI-3 specific device driver resources */
	error = lpfc_sli_driver_resource_setup(phba);
	if (error) {
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"1404 Failed to set up driver resource.\n");
		goto out_unset_pci_mem_s3;
	}

	/* Initialize and populate the iocb list per host */

	error = lpfc_init_iocb_list(phba, LPFC_IOCB_LIST_CNT);
	if (error) {
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"1405 Failed to initialize iocb list.\n");
		goto out_unset_driver_resource_s3;
	}

	/* Set up common device driver resources */
	error = lpfc_setup_driver_resource_phase2(phba);
	if (error) {
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"1406 Failed to set up driver resource.\n");
		goto out_free_iocb_list;
	}

	/* Get the default values for Model Name and Description */
	lpfc_get_hba_model_desc(phba, phba->ModelName, phba->ModelDesc);

	/* Create SCSI host to the physical port */
	error = lpfc_create_shost(phba);
	if (error) {
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"1407 Failed to create scsi host.\n");
		goto out_unset_driver_resource;
	}

	/* Configure sysfs attributes */
	vport = phba->pport;
	error = lpfc_alloc_sysfs_attr(vport);
	if (error) {
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"1476 Failed to allocate sysfs attr\n");
		goto out_destroy_shost;
	}

	shost = lpfc_shost_from_vport(vport); /* save shost for error cleanup */
	/* Now, trying to enable interrupt and bring up the device */
	cfg_mode = phba->cfg_use_msi;
	while (true) {
		/* Put device to a known state before enabling interrupt */
		lpfc_stop_port(phba);
		/* Configure and enable interrupt */
		intr_mode = lpfc_sli_enable_intr(phba, cfg_mode);
		if (intr_mode == LPFC_INTR_ERROR) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"0431 Failed to enable interrupt.\n");
			error = -ENODEV;
			goto out_free_sysfs_attr;
		}
		/* SLI-3 HBA setup */
		if (lpfc_sli_hba_setup(phba)) {
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
					"1477 Failed to set up hba\n");
			error = -ENODEV;
			goto out_remove_device;
		}

		/* Wait 50ms for the interrupts of previous mailbox commands */
		msleep(50);
		/* Check active interrupts on message signaled interrupts */
		if (intr_mode == 0 ||
		    phba->sli.slistat.sli_intr > LPFC_MSIX_VECTORS) {
			/* Log the current active interrupt mode */
			phba->intr_mode = intr_mode;
			lpfc_log_intr_mode(phba, intr_mode);
			break;
		} else {
			lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
					"0447 Configure interrupt mode (%d) "
					"failed active interrupt test.\n",
					intr_mode);
			/* Disable the current interrupt mode */
			lpfc_sli_disable_intr(phba);
			/* Try next level of interrupt mode */
			cfg_mode = --intr_mode;
		}
	}

	/* Perform post initialization setup */
	lpfc_post_init_setup(phba);

	/* Check if there are static vports to be created. */
	lpfc_create_static_vport(phba);

	return 0;

out_remove_device:
	lpfc_unset_hba(phba);
out_free_sysfs_attr:
	lpfc_free_sysfs_attr(vport);
out_destroy_shost:
	lpfc_destroy_shost(phba);
out_unset_driver_resource:
	lpfc_unset_driver_resource_phase2(phba);
out_free_iocb_list:
	lpfc_free_iocb_list(phba);
out_unset_driver_resource_s3:
	lpfc_sli_driver_resource_unset(phba);
out_unset_pci_mem_s3:
	lpfc_sli_pci_mem_unset(phba);
out_disable_pci_dev:
	lpfc_disable_pci_dev(phba);
	if (shost)
		scsi_host_put(shost);
out_free_phba:
	lpfc_hba_free(phba);
	return error;
}

/**
 * lpfc_pci_remove_one_s3 - PCI func to unreg SLI-3 device from PCI subsystem.
 * @pdev: pointer to PCI device
 *
 * This routine is to be called to disattach a device with SLI-3 interface
 * spec from PCI subsystem. When an Emulex HBA with SLI-3 interface spec is
 * removed from PCI bus, it performs all the necessary cleanup for the HBA
 * device to be removed from the PCI subsystem properly.
 **/
static void
lpfc_pci_remove_one_s3(struct pci_dev *pdev)
{
	struct Scsi_Host  *shost = pci_get_drvdata(pdev);
	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
	struct lpfc_vport **vports;
	struct lpfc_hba   *phba = vport->phba;
	int i;

	spin_lock_irq(&phba->hbalock);
	vport->load_flag |= FC_UNLOADING;
	spin_unlock_irq(&phba->hbalock);

	lpfc_free_sysfs_attr(vport);

	/* Release all the vports against this physical port */
	vports = lpfc_create_vport_work_array(phba);
	if (vports != NULL)
		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
			if (vports[i]->port_type == LPFC_PHYSICAL_PORT)
				continue;
			fc_vport_terminate(vports[i]->fc_vport);
		}
	lpfc_destroy_vport_work_array(phba, vports);

	/* Remove FC host with the physical port */
	fc_remove_host(shost);
	scsi_remove_host(shost);

	/* Clean up all nodes, mailboxes and IOs. */
	lpfc_cleanup(vport);

	/*
	 * Bring down the SLI Layer. This step disable all interrupts,
	 * clears the rings, discards all mailbox commands, and resets
	 * the HBA.
	 */

	/* HBA interrupt will be disabled after this call */
	lpfc_sli_hba_down(phba);
	/* Stop kthread signal shall trigger work_done one more time */
	kthread_stop(phba->worker_thread);
	/* Final cleanup of txcmplq and reset the HBA */
	lpfc_sli_brdrestart(phba);

	kfree(phba->vpi_bmask);
	kfree(phba->vpi_ids);

	lpfc_stop_hba_timers(phba);
	spin_lock_irq(&phba->port_list_lock);
	list_del_init(&vport->listentry);
	spin_unlock_irq(&phba->port_list_lock);

	lpfc_debugfs_terminate(vport);

	/* Disable SR-IOV if enabled */
	if (phba->cfg_sriov_nr_virtfn)
		pci_disable_sriov(pdev);

	/* Disable interrupt */
	lpfc_sli_disable_intr(phba);

	scsi_host_put(shost);

	/*
	 * Call scsi_free before mem_free since scsi bufs are released to their
	 * corresponding pools here.
	 */
	lpfc_scsi_free(phba);
	lpfc_free_iocb_list(phba);

	lpfc_mem_free_all(phba);

	dma_free_coherent(&pdev->dev, lpfc_sli_hbq_size(),
			  phba->hbqslimp.virt, phba->hbqslimp.phys);

	/* Free resources associated with SLI2 interface */
	dma_free_coherent(&pdev->dev, SLI2_SLIM_SIZE,
			  phba->slim2p.virt, phba->slim2p.phys);

	/* unmap adapter SLIM and Control Registers */
	iounmap(phba->ctrl_regs_memmap_p);
	iounmap(phba->slim_memmap_p);

	lpfc_hba_free(phba);

	pci_release_mem_regions(pdev);
	pci_disable_device(pdev);
}

/**
 * lpfc_pci_suspend_one_s3 - PCI func to suspend SLI-3 device for power mgmnt
 * @dev_d: pointer to device
 *
 * This routine is to be called from the kernel's PCI subsystem to support
 * system Power Management (PM) to device with SLI-3 interface spec. When
 * PM invokes this method, it quiesces the device by stopping the driver's
 * worker thread for the device, turning off device's interrupt and DMA,
 * and bring the device offline. Note that as the driver implements the
 * minimum PM requirements to a power-aware driver's PM support for the
 * suspend/resume -- all the possible PM messages (SUSPEND, HIBERNATE, FREEZE)
 * to the suspend() method call will be treated as SUSPEND and the driver will
 * fully reinitialize its device during resume() method call, the driver will
 * set device to PCI_D3hot state in PCI config space instead of setting it
 * according to the @msg provided by the PM.
 *
 * Return code
 * 	0 - driver suspended the device
 * 	Error otherwise
 **/
static int __maybe_unused
lpfc_pci_suspend_one_s3(struct device *dev_d)
{
	struct Scsi_Host *shost = dev_get_drvdata(dev_d);
	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;

	lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
			"0473 PCI device Power Management suspend.\n");

	/* Bring down the device */
	lpfc_offline_prep(phba, LPFC_MBX_WAIT);
	lpfc_offline(phba);
	kthread_stop(phba->worker_thread);

	/* Disable interrupt from device */
	lpfc_sli_disable_intr(phba);

	return 0;
}

/**
 * lpfc_pci_resume_one_s3 - PCI func to resume SLI-3 device for power mgmnt
 * @dev_d: pointer to device
 *
 * This routine is to be called from the kernel's PCI subsystem to support
 * system Power Management (PM) to device with SLI-3 interface spec. When PM
 * invokes this method, it restores the device's PCI config space state and
 * fully reinitializes the device and brings it online. Note that as the
 * driver implements the minimum PM requirements to a power-aware driver's
 * PM for suspend/resume -- all the possible PM messages (SUSPEND, HIBERNATE,
 * FREEZE) to the suspend() method call will be treated as SUSPEND and the
 * driver will fully reinitialize its device during resume() method call,
 * the device will be set to PCI_D0 directly in PCI config space before
 * restoring the state.
 *
 * Return code
 * 	0 - driver suspended the device
 * 	Error otherwise
 **/
static int __maybe_unused
lpfc_pci_resume_one_s3(struct device *dev_d)
{
	struct Scsi_Host *shost = dev_get_drvdata(dev_d);
	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
	uint32_t intr_mode;
	int error;

	lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
			"0452 PCI device Power Management resume.\n");

	/* Startup the kernel thread for this host adapter. */
	phba->worker_thread = kthread_run(lpfc_do_work, phba,
					"lpfc_worker_%d", phba->brd_no);
	if (IS_ERR(phba->worker_thread)) {
		error = PTR_ERR(phba->worker_thread);
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"0434 PM resume failed to start worker "
				"thread: error=x%x.\n", error);
		return error;
	}

	/* Init cpu_map array */
	lpfc_cpu_map_array_init(phba);
	/* Init hba_eq_hdl array */
	lpfc_hba_eq_hdl_array_init(phba);
	/* Configure and enable interrupt */
	intr_mode = lpfc_sli_enable_intr(phba, phba->intr_mode);
	if (intr_mode == LPFC_INTR_ERROR) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0430 PM resume Failed to enable interrupt\n");
		return -EIO;
	} else
		phba->intr_mode = intr_mode;

	/* Restart HBA and bring it online */
	lpfc_sli_brdrestart(phba);
	lpfc_online(phba);

	/* Log the current active interrupt mode */
	lpfc_log_intr_mode(phba, phba->intr_mode);

	return 0;
}

/**
 * lpfc_sli_prep_dev_for_recover - Prepare SLI3 device for pci slot recover
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is called to prepare the SLI3 device for PCI slot recover. It
 * aborts all the outstanding SCSI I/Os to the pci device.
 **/
static void
lpfc_sli_prep_dev_for_recover(struct lpfc_hba *phba)
{
	lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
			"2723 PCI channel I/O abort preparing for recovery\n");

	/*
	 * There may be errored I/Os through HBA, abort all I/Os on txcmplq
	 * and let the SCSI mid-layer to retry them to recover.
	 */
	lpfc_sli_abort_fcp_rings(phba);
}

/**
 * lpfc_sli_prep_dev_for_reset - Prepare SLI3 device for pci slot reset
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is called to prepare the SLI3 device for PCI slot reset. It
 * disables the device interrupt and pci device, and aborts the internal FCP
 * pending I/Os.
 **/
static void
lpfc_sli_prep_dev_for_reset(struct lpfc_hba *phba)
{
	lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
			"2710 PCI channel disable preparing for reset\n");

	/* Block any management I/Os to the device */
	lpfc_block_mgmt_io(phba, LPFC_MBX_WAIT);

	/* Block all SCSI devices' I/Os on the host */
	lpfc_scsi_dev_block(phba);

	/* Flush all driver's outstanding SCSI I/Os as we are to reset */
	lpfc_sli_flush_io_rings(phba);

	/* stop all timers */
	lpfc_stop_hba_timers(phba);

	/* Disable interrupt and pci device */
	lpfc_sli_disable_intr(phba);
	pci_disable_device(phba->pcidev);
}

/**
 * lpfc_sli_prep_dev_for_perm_failure - Prepare SLI3 dev for pci slot disable
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is called to prepare the SLI3 device for PCI slot permanently
 * disabling. It blocks the SCSI transport layer traffic and flushes the FCP
 * pending I/Os.
 **/
static void
lpfc_sli_prep_dev_for_perm_failure(struct lpfc_hba *phba)
{
	lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
			"2711 PCI channel permanent disable for failure\n");
	/* Block all SCSI devices' I/Os on the host */
	lpfc_scsi_dev_block(phba);

	/* stop all timers */
	lpfc_stop_hba_timers(phba);

	/* Clean up all driver's outstanding SCSI I/Os */
	lpfc_sli_flush_io_rings(phba);
}

/**
 * lpfc_io_error_detected_s3 - Method for handling SLI-3 device PCI I/O error
 * @pdev: pointer to PCI device.
 * @state: the current PCI connection state.
 *
 * This routine is called from the PCI subsystem for I/O error handling to
 * device with SLI-3 interface spec. This function is called by the PCI
 * subsystem after a PCI bus error affecting this device has been detected.
 * When this function is invoked, it will need to stop all the I/Os and
 * interrupt(s) to the device. Once that is done, it will return
 * PCI_ERS_RESULT_NEED_RESET for the PCI subsystem to perform proper recovery
 * as desired.
 *
 * Return codes
 * 	PCI_ERS_RESULT_CAN_RECOVER - can be recovered with reset_link
 * 	PCI_ERS_RESULT_NEED_RESET - need to reset before recovery
 * 	PCI_ERS_RESULT_DISCONNECT - device could not be recovered
 **/
static pci_ers_result_t
lpfc_io_error_detected_s3(struct pci_dev *pdev, pci_channel_state_t state)
{
	struct Scsi_Host *shost = pci_get_drvdata(pdev);
	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;

	switch (state) {
	case pci_channel_io_normal:
		/* Non-fatal error, prepare for recovery */
		lpfc_sli_prep_dev_for_recover(phba);
		return PCI_ERS_RESULT_CAN_RECOVER;
	case pci_channel_io_frozen:
		/* Fatal error, prepare for slot reset */
		lpfc_sli_prep_dev_for_reset(phba);
		return PCI_ERS_RESULT_NEED_RESET;
	case pci_channel_io_perm_failure:
		/* Permanent failure, prepare for device down */
		lpfc_sli_prep_dev_for_perm_failure(phba);
		return PCI_ERS_RESULT_DISCONNECT;
	default:
		/* Unknown state, prepare and request slot reset */
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0472 Unknown PCI error state: x%x\n", state);
		lpfc_sli_prep_dev_for_reset(phba);
		return PCI_ERS_RESULT_NEED_RESET;
	}
}

/**
 * lpfc_io_slot_reset_s3 - Method for restarting PCI SLI-3 device from scratch.
 * @pdev: pointer to PCI device.
 *
 * This routine is called from the PCI subsystem for error handling to
 * device with SLI-3 interface spec. This is called after PCI bus has been
 * reset to restart the PCI card from scratch, as if from a cold-boot.
 * During the PCI subsystem error recovery, after driver returns
 * PCI_ERS_RESULT_NEED_RESET, the PCI subsystem will perform proper error
 * recovery and then call this routine before calling the .resume method
 * to recover the device. This function will initialize the HBA device,
 * enable the interrupt, but it will just put the HBA to offline state
 * without passing any I/O traffic.
 *
 * Return codes
 * 	PCI_ERS_RESULT_RECOVERED - the device has been recovered
 * 	PCI_ERS_RESULT_DISCONNECT - device could not be recovered
 */
static pci_ers_result_t
lpfc_io_slot_reset_s3(struct pci_dev *pdev)
{
	struct Scsi_Host *shost = pci_get_drvdata(pdev);
	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
	struct lpfc_sli *psli = &phba->sli;
	uint32_t intr_mode;

	dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n");
	if (pci_enable_device_mem(pdev)) {
		printk(KERN_ERR "lpfc: Cannot re-enable "
			"PCI device after reset.\n");
		return PCI_ERS_RESULT_DISCONNECT;
	}

	pci_restore_state(pdev);

	/*
	 * As the new kernel behavior of pci_restore_state() API call clears
	 * device saved_state flag, need to save the restored state again.
	 */
	pci_save_state(pdev);

	if (pdev->is_busmaster)
		pci_set_master(pdev);

	spin_lock_irq(&phba->hbalock);
	psli->sli_flag &= ~LPFC_SLI_ACTIVE;
	spin_unlock_irq(&phba->hbalock);

	/* Configure and enable interrupt */
	intr_mode = lpfc_sli_enable_intr(phba, phba->intr_mode);
	if (intr_mode == LPFC_INTR_ERROR) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0427 Cannot re-enable interrupt after "
				"slot reset.\n");
		return PCI_ERS_RESULT_DISCONNECT;
	} else
		phba->intr_mode = intr_mode;

	/* Take device offline, it will perform cleanup */
	lpfc_offline_prep(phba, LPFC_MBX_WAIT);
	lpfc_offline(phba);
	lpfc_sli_brdrestart(phba);

	/* Log the current active interrupt mode */
	lpfc_log_intr_mode(phba, phba->intr_mode);

	return PCI_ERS_RESULT_RECOVERED;
}

/**
 * lpfc_io_resume_s3 - Method for resuming PCI I/O operation on SLI-3 device.
 * @pdev: pointer to PCI device
 *
 * This routine is called from the PCI subsystem for error handling to device
 * with SLI-3 interface spec. It is called when kernel error recovery tells
 * the lpfc driver that it is ok to resume normal PCI operation after PCI bus
 * error recovery. After this call, traffic can start to flow from this device
 * again.
 */
static void
lpfc_io_resume_s3(struct pci_dev *pdev)
{
	struct Scsi_Host *shost = pci_get_drvdata(pdev);
	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;

	/* Bring device online, it will be no-op for non-fatal error resume */
	lpfc_online(phba);
}

/**
 * lpfc_sli4_get_els_iocb_cnt - Calculate the # of ELS IOCBs to reserve
 * @phba: pointer to lpfc hba data structure.
 *
 * returns the number of ELS/CT IOCBs to reserve
 **/
int
lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *phba)
{
	int max_xri = phba->sli4_hba.max_cfg_param.max_xri;

	if (phba->sli_rev == LPFC_SLI_REV4) {
		if (max_xri <= 100)
			return 10;
		else if (max_xri <= 256)
			return 25;
		else if (max_xri <= 512)
			return 50;
		else if (max_xri <= 1024)
			return 100;
		else if (max_xri <= 1536)
			return 150;
		else if (max_xri <= 2048)
			return 200;
		else
			return 250;
	} else
		return 0;
}

/**
 * lpfc_sli4_get_iocb_cnt - Calculate the # of total IOCBs to reserve
 * @phba: pointer to lpfc hba data structure.
 *
 * returns the number of ELS/CT + NVMET IOCBs to reserve
 **/
int
lpfc_sli4_get_iocb_cnt(struct lpfc_hba *phba)
{
	int max_xri = lpfc_sli4_get_els_iocb_cnt(phba);

	if (phba->nvmet_support)
		max_xri += LPFC_NVMET_BUF_POST;
	return max_xri;
}


static int
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)
{
	int rc;
	u8 sli_family;

	sli_family = bf_get(lpfc_sli_intf_sli_family, &phba->sli4_hba.sli_intf);
	/* Three cases:  (1) FW was not supported on the detected adapter.
	 * (2) FW update has been locked out administratively.
	 * (3) Some other error during FW update.
	 * In each case, an unmaskable message is written to the console
	 * for admin diagnosis.
	 */
	if (offset == ADD_STATUS_FW_NOT_SUPPORTED ||
	    (sli_family == LPFC_SLI_INTF_FAMILY_G6 &&
	     magic_number != MAGIC_NUMBER_G6) ||
	    (sli_family == LPFC_SLI_INTF_FAMILY_G7 &&
	     magic_number != MAGIC_NUMBER_G7) ||
	    (sli_family == LPFC_SLI_INTF_FAMILY_G7P &&
	     magic_number != MAGIC_NUMBER_G7P)) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"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);
		rc = -EINVAL;
	} else if (offset == ADD_STATUS_FW_DOWNLOAD_HW_DISABLED) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3021 Firmware downloads have been prohibited "
				"by a system configuration setting on "
				"Device:%x Magic:%x Type:%x ID:%x Size %d "
				"%zd\n",
				phba->pcidev->device, magic_number, ftype, fid,
				fsize, fw->size);
		rc = -EACCES;
	} else {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3022 FW Download failed. Add Status x%x "
				"Device:%x Magic:%x Type:%x ID:%x Size %d "
				"%zd\n",
				offset, phba->pcidev->device, magic_number,
				ftype, fid, fsize, fw->size);
		rc = -EIO;
	}
	return rc;
}

/**
 * lpfc_write_firmware - attempt to write a firmware image to the port
 * @fw: pointer to firmware image returned from request_firmware.
 * @context: pointer to firmware image returned from request_firmware.
 *
 **/
static void
lpfc_write_firmware(const struct firmware *fw, void *context)
{
	struct lpfc_hba *phba = (struct lpfc_hba *)context;
	char fwrev[FW_REV_STR_SIZE];
	struct lpfc_grp_hdr *image;
	struct list_head dma_buffer_list;
	int i, rc = 0;
	struct lpfc_dmabuf *dmabuf, *next;
	uint32_t offset = 0, temp_offset = 0;
	uint32_t magic_number, ftype, fid, fsize;

	/* It can be null in no-wait mode, sanity check */
	if (!fw) {
		rc = -ENXIO;
		goto out;
	}
	image = (struct lpfc_grp_hdr *)fw->data;

	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);
	fsize = be32_to_cpu(image->size);

	INIT_LIST_HEAD(&dma_buffer_list);
	lpfc_decode_firmware_rev(phba, fwrev, 1);
	if (strncmp(fwrev, image->revision, strnlen(image->revision, 16))) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3023 Updating Firmware, Current Version:%s "
				"New Version:%s\n",
				fwrev, image->revision);
		for (i = 0; i < LPFC_MBX_WR_CONFIG_MAX_BDE; i++) {
			dmabuf = kzalloc(sizeof(struct lpfc_dmabuf),
					 GFP_KERNEL);
			if (!dmabuf) {
				rc = -ENOMEM;
				goto release_out;
			}
			dmabuf->virt = dma_alloc_coherent(&phba->pcidev->dev,
							  SLI4_PAGE_SIZE,
							  &dmabuf->phys,
							  GFP_KERNEL);
			if (!dmabuf->virt) {
				kfree(dmabuf);
				rc = -ENOMEM;
				goto release_out;
			}
			list_add_tail(&dmabuf->list, &dma_buffer_list);
		}
		while (offset < fw->size) {
			temp_offset = offset;
			list_for_each_entry(dmabuf, &dma_buffer_list, list) {
				if (temp_offset + SLI4_PAGE_SIZE > fw->size) {
					memcpy(dmabuf->virt,
					       fw->data + temp_offset,
					       fw->size - temp_offset);
					temp_offset = fw->size;
					break;
				}
				memcpy(dmabuf->virt, fw->data + temp_offset,
				       SLI4_PAGE_SIZE);
				temp_offset += SLI4_PAGE_SIZE;
			}
			rc = lpfc_wr_object(phba, &dma_buffer_list,
				    (fw->size - offset), &offset);
			if (rc) {
				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_TRACE_EVENT,
				"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) {
		list_del(&dmabuf->list);
		dma_free_coherent(&phba->pcidev->dev, SLI4_PAGE_SIZE,
				  dmabuf->virt, dmabuf->phys);
		kfree(dmabuf);
	}
	release_firmware(fw);
out:
	if (rc < 0)
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3062 Firmware update error, status %d.\n", rc);
	else
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"3024 Firmware update success: size %d.\n", rc);
}

/**
 * lpfc_sli4_request_firmware_update - Request linux generic firmware upgrade
 * @phba: pointer to lpfc hba data structure.
 * @fw_upgrade: which firmware to update.
 *
 * This routine is called to perform Linux generic firmware upgrade on device
 * that supports such feature.
 **/
int
lpfc_sli4_request_firmware_update(struct lpfc_hba *phba, uint8_t fw_upgrade)
{
	uint8_t file_name[ELX_MODEL_NAME_SIZE];
	int ret;
	const struct firmware *fw;

	/* Only supported on SLI4 interface type 2 for now */
	if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
	    LPFC_SLI_INTF_IF_TYPE_2)
		return -EPERM;

	snprintf(file_name, ELX_MODEL_NAME_SIZE, "%s.grp", phba->ModelName);

	if (fw_upgrade == INT_FW_UPGRADE) {
		ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT,
					file_name, &phba->pcidev->dev,
					GFP_KERNEL, (void *)phba,
					lpfc_write_firmware);
	} else if (fw_upgrade == RUN_FW_UPGRADE) {
		ret = request_firmware(&fw, file_name, &phba->pcidev->dev);
		if (!ret)
			lpfc_write_firmware(fw, (void *)phba);
	} else {
		ret = -EINVAL;
	}

	return ret;
}

/**
 * lpfc_pci_probe_one_s4 - PCI probe func to reg SLI-4 device to PCI subsys
 * @pdev: pointer to PCI device
 * @pid: pointer to PCI device identifier
 *
 * This routine is called from the kernel's PCI subsystem to device with
 * SLI-4 interface spec. When an Emulex HBA with SLI-4 interface spec is
 * presented on PCI bus, the kernel PCI subsystem looks at PCI device-specific
 * information of the device and driver to see if the driver state that it
 * can support this kind of device. If the match is successful, the driver
 * core invokes this routine. If this routine determines it can claim the HBA,
 * it does all the initialization that it needs to do to handle the HBA
 * properly.
 *
 * Return code
 * 	0 - driver can claim the device
 * 	negative value - driver can not claim the device
 **/
static int
lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
{
	struct lpfc_hba   *phba;
	struct lpfc_vport *vport = NULL;
	struct Scsi_Host  *shost = NULL;
	int error;
	uint32_t cfg_mode, intr_mode;

	/* Allocate memory for HBA structure */
	phba = lpfc_hba_alloc(pdev);
	if (!phba)
		return -ENOMEM;

	INIT_LIST_HEAD(&phba->poll_list);

	/* Perform generic PCI device enabling operation */
	error = lpfc_enable_pci_dev(phba);
	if (error)
		goto out_free_phba;

	/* Set up SLI API function jump table for PCI-device group-1 HBAs */
	error = lpfc_api_table_setup(phba, LPFC_PCI_DEV_OC);
	if (error)
		goto out_disable_pci_dev;

	/* Set up SLI-4 specific device PCI memory space */
	error = lpfc_sli4_pci_mem_setup(phba);
	if (error) {
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"1410 Failed to set up pci memory space.\n");
		goto out_disable_pci_dev;
	}

	/* Set up SLI-4 Specific device driver resources */
	error = lpfc_sli4_driver_resource_setup(phba);
	if (error) {
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"1412 Failed to set up driver resource.\n");
		goto out_unset_pci_mem_s4;
	}

	INIT_LIST_HEAD(&phba->active_rrq_list);
	INIT_LIST_HEAD(&phba->fcf.fcf_pri_list);

	/* Set up common device driver resources */
	error = lpfc_setup_driver_resource_phase2(phba);
	if (error) {
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"1414 Failed to set up driver resource.\n");
		goto out_unset_driver_resource_s4;
	}

	/* Get the default values for Model Name and Description */
	lpfc_get_hba_model_desc(phba, phba->ModelName, phba->ModelDesc);

	/* Now, trying to enable interrupt and bring up the device */
	cfg_mode = phba->cfg_use_msi;

	/* Put device to a known state before enabling interrupt */
	phba->pport = NULL;
	lpfc_stop_port(phba);

	/* Init cpu_map array */
	lpfc_cpu_map_array_init(phba);

	/* Init hba_eq_hdl array */
	lpfc_hba_eq_hdl_array_init(phba);

	/* Configure and enable interrupt */
	intr_mode = lpfc_sli4_enable_intr(phba, cfg_mode);
	if (intr_mode == LPFC_INTR_ERROR) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0426 Failed to enable interrupt.\n");
		error = -ENODEV;
		goto out_unset_driver_resource;
	}
	/* Default to single EQ for non-MSI-X */
	if (phba->intr_type != MSIX) {
		phba->cfg_irq_chann = 1;
		if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
			if (phba->nvmet_support)
				phba->cfg_nvmet_mrq = 1;
		}
	}
	lpfc_cpu_affinity_check(phba, phba->cfg_irq_chann);

	/* Create SCSI host to the physical port */
	error = lpfc_create_shost(phba);
	if (error) {
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"1415 Failed to create scsi host.\n");
		goto out_disable_intr;
	}
	vport = phba->pport;
	shost = lpfc_shost_from_vport(vport); /* save shost for error cleanup */

	/* Configure sysfs attributes */
	error = lpfc_alloc_sysfs_attr(vport);
	if (error) {
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"1416 Failed to allocate sysfs attr\n");
		goto out_destroy_shost;
	}

	/* Set up SLI-4 HBA */
	if (lpfc_sli4_hba_setup(phba)) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"1421 Failed to set up hba\n");
		error = -ENODEV;
		goto out_free_sysfs_attr;
	}

	/* Log the current active interrupt mode */
	phba->intr_mode = intr_mode;
	lpfc_log_intr_mode(phba, intr_mode);

	/* Perform post initialization setup */
	lpfc_post_init_setup(phba);

	/* NVME support in FW earlier in the driver load corrects the
	 * FC4 type making a check for nvme_support unnecessary.
	 */
	if (phba->nvmet_support == 0) {
		if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
			/* Create NVME binding with nvme_fc_transport. This
			 * ensures the vport is initialized.  If the localport
			 * create fails, it should not unload the driver to
			 * support field issues.
			 */
			error = lpfc_nvme_create_localport(vport);
			if (error) {
				lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
						"6004 NVME registration "
						"failed, error x%x\n",
						error);
			}
		}
	}

	/* check for firmware upgrade or downgrade */
	if (phba->cfg_request_firmware_upgrade)
		lpfc_sli4_request_firmware_update(phba, INT_FW_UPGRADE);

	/* Check if there are static vports to be created. */
	lpfc_create_static_vport(phba);

	/* Enable RAS FW log support */
	lpfc_sli4_ras_setup(phba);

	timer_setup(&phba->cpuhp_poll_timer, lpfc_sli4_poll_hbtimer, 0);
	cpuhp_state_add_instance_nocalls(lpfc_cpuhp_state, &phba->cpuhp);

	return 0;

out_free_sysfs_attr:
	lpfc_free_sysfs_attr(vport);
out_destroy_shost:
	lpfc_destroy_shost(phba);
out_disable_intr:
	lpfc_sli4_disable_intr(phba);
out_unset_driver_resource:
	lpfc_unset_driver_resource_phase2(phba);
out_unset_driver_resource_s4:
	lpfc_sli4_driver_resource_unset(phba);
out_unset_pci_mem_s4:
	lpfc_sli4_pci_mem_unset(phba);
out_disable_pci_dev:
	lpfc_disable_pci_dev(phba);
	if (shost)
		scsi_host_put(shost);
out_free_phba:
	lpfc_hba_free(phba);
	return error;
}

/**
 * lpfc_pci_remove_one_s4 - PCI func to unreg SLI-4 device from PCI subsystem
 * @pdev: pointer to PCI device
 *
 * This routine is called from the kernel's PCI subsystem to device with
 * SLI-4 interface spec. When an Emulex HBA with SLI-4 interface spec is
 * removed from PCI bus, it performs all the necessary cleanup for the HBA
 * device to be removed from the PCI subsystem properly.
 **/
static void
lpfc_pci_remove_one_s4(struct pci_dev *pdev)
{
	struct Scsi_Host *shost = pci_get_drvdata(pdev);
	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
	struct lpfc_vport **vports;
	struct lpfc_hba *phba = vport->phba;
	int i;

	/* Mark the device unloading flag */
	spin_lock_irq(&phba->hbalock);
	vport->load_flag |= FC_UNLOADING;
	spin_unlock_irq(&phba->hbalock);
	if (phba->cgn_i)
		lpfc_unreg_congestion_buf(phba);

	lpfc_free_sysfs_attr(vport);

	/* Release all the vports against this physical port */
	vports = lpfc_create_vport_work_array(phba);
	if (vports != NULL)
		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
			if (vports[i]->port_type == LPFC_PHYSICAL_PORT)
				continue;
			fc_vport_terminate(vports[i]->fc_vport);
		}
	lpfc_destroy_vport_work_array(phba, vports);

	/* Remove FC host with the physical port */
	fc_remove_host(shost);
	scsi_remove_host(shost);

	/* Perform ndlp cleanup on the physical port.  The nvme and nvmet
	 * localports are destroyed after to cleanup all transport memory.
	 */
	lpfc_cleanup(vport);
	lpfc_nvmet_destroy_targetport(phba);
	lpfc_nvme_destroy_localport(vport);

	/* De-allocate multi-XRI pools */
	if (phba->cfg_xri_rebalancing)
		lpfc_destroy_multixri_pools(phba);

	/*
	 * 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_stop_hba_timers(phba);
	spin_lock_irq(&phba->port_list_lock);
	list_del_init(&vport->listentry);
	spin_unlock_irq(&phba->port_list_lock);

	/* Perform scsi free before driver resource_unset since scsi
	 * buffers are released to their corresponding pools here.
	 */
	lpfc_io_free(phba);
	lpfc_free_iocb_list(phba);
	lpfc_sli4_hba_unset(phba);

	lpfc_unset_driver_resource_phase2(phba);
	lpfc_sli4_driver_resource_unset(phba);

	/* Unmap adapter Control and Doorbell registers */
	lpfc_sli4_pci_mem_unset(phba);

	/* Release PCI resources and disable device's PCI function */
	scsi_host_put(shost);
	lpfc_disable_pci_dev(phba);

	/* Finally, free the driver's device data structure */
	lpfc_hba_free(phba);

	return;
}

/**
 * lpfc_pci_suspend_one_s4 - PCI func to suspend SLI-4 device for power mgmnt
 * @dev_d: pointer to device
 *
 * This routine is called from the kernel's PCI subsystem to support system
 * Power Management (PM) to device with SLI-4 interface spec. When PM invokes
 * this method, it quiesces the device by stopping the driver's worker
 * thread for the device, turning off device's interrupt and DMA, and bring
 * the device offline. Note that as the driver implements the minimum PM
 * requirements to a power-aware driver's PM support for suspend/resume -- all
 * the possible PM messages (SUSPEND, HIBERNATE, FREEZE) to the suspend()
 * method call will be treated as SUSPEND and the driver will fully
 * reinitialize its device during resume() method call, the driver will set
 * device to PCI_D3hot state in PCI config space instead of setting it
 * according to the @msg provided by the PM.
 *
 * Return code
 * 	0 - driver suspended the device
 * 	Error otherwise
 **/
static int __maybe_unused
lpfc_pci_suspend_one_s4(struct device *dev_d)
{
	struct Scsi_Host *shost = dev_get_drvdata(dev_d);
	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;

	lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
			"2843 PCI device Power Management suspend.\n");

	/* Bring down the device */
	lpfc_offline_prep(phba, LPFC_MBX_WAIT);
	lpfc_offline(phba);
	kthread_stop(phba->worker_thread);

	/* Disable interrupt from device */
	lpfc_sli4_disable_intr(phba);
	lpfc_sli4_queue_destroy(phba);

	return 0;
}

/**
 * lpfc_pci_resume_one_s4 - PCI func to resume SLI-4 device for power mgmnt
 * @dev_d: pointer to device
 *
 * This routine is called from the kernel's PCI subsystem to support system
 * Power Management (PM) to device with SLI-4 interface spac. When PM invokes
 * this method, it restores the device's PCI config space state and fully
 * reinitializes the device and brings it online. Note that as the driver
 * implements the minimum PM requirements to a power-aware driver's PM for
 * suspend/resume -- all the possible PM messages (SUSPEND, HIBERNATE, FREEZE)
 * to the suspend() method call will be treated as SUSPEND and the driver
 * will fully reinitialize its device during resume() method call, the device
 * will be set to PCI_D0 directly in PCI config space before restoring the
 * state.
 *
 * Return code
 * 	0 - driver suspended the device
 * 	Error otherwise
 **/
static int __maybe_unused
lpfc_pci_resume_one_s4(struct device *dev_d)
{
	struct Scsi_Host *shost = dev_get_drvdata(dev_d);
	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
	uint32_t intr_mode;
	int error;

	lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
			"0292 PCI device Power Management resume.\n");

	 /* Startup the kernel thread for this host adapter. */
	phba->worker_thread = kthread_run(lpfc_do_work, phba,
					"lpfc_worker_%d", phba->brd_no);
	if (IS_ERR(phba->worker_thread)) {
		error = PTR_ERR(phba->worker_thread);
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"0293 PM resume failed to start worker "
				"thread: error=x%x.\n", error);
		return error;
	}

	/* Configure and enable interrupt */
	intr_mode = lpfc_sli4_enable_intr(phba, phba->intr_mode);
	if (intr_mode == LPFC_INTR_ERROR) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0294 PM resume Failed to enable interrupt\n");
		return -EIO;
	} else
		phba->intr_mode = intr_mode;

	/* Restart HBA and bring it online */
	lpfc_sli_brdrestart(phba);
	lpfc_online(phba);

	/* Log the current active interrupt mode */
	lpfc_log_intr_mode(phba, phba->intr_mode);

	return 0;
}

/**
 * lpfc_sli4_prep_dev_for_recover - Prepare SLI4 device for pci slot recover
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is called to prepare the SLI4 device for PCI slot recover. It
 * aborts all the outstanding SCSI I/Os to the pci device.
 **/
static void
lpfc_sli4_prep_dev_for_recover(struct lpfc_hba *phba)
{
	lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
			"2828 PCI channel I/O abort preparing for recovery\n");
	/*
	 * There may be errored I/Os through HBA, abort all I/Os on txcmplq
	 * and let the SCSI mid-layer to retry them to recover.
	 */
	lpfc_sli_abort_fcp_rings(phba);
}

/**
 * lpfc_sli4_prep_dev_for_reset - Prepare SLI4 device for pci slot reset
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is called to prepare the SLI4 device for PCI slot reset. It
 * disables the device interrupt and pci device, and aborts the internal FCP
 * pending I/Os.
 **/
static void
lpfc_sli4_prep_dev_for_reset(struct lpfc_hba *phba)
{
	lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
			"2826 PCI channel disable preparing for reset\n");

	/* Block any management I/Os to the device */
	lpfc_block_mgmt_io(phba, LPFC_MBX_NO_WAIT);

	/* Block all SCSI devices' I/Os on the host */
	lpfc_scsi_dev_block(phba);

	/* Flush all driver's outstanding I/Os as we are to reset */
	lpfc_sli_flush_io_rings(phba);

	/* stop all timers */
	lpfc_stop_hba_timers(phba);

	/* Disable interrupt and pci device */
	lpfc_sli4_disable_intr(phba);
	lpfc_sli4_queue_destroy(phba);
	pci_disable_device(phba->pcidev);
}

/**
 * lpfc_sli4_prep_dev_for_perm_failure - Prepare SLI4 dev for pci slot disable
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine is called to prepare the SLI4 device for PCI slot permanently
 * disabling. It blocks the SCSI transport layer traffic and flushes the FCP
 * pending I/Os.
 **/
static void
lpfc_sli4_prep_dev_for_perm_failure(struct lpfc_hba *phba)
{
	lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
			"2827 PCI channel permanent disable for failure\n");

	/* Block all SCSI devices' I/Os on the host */
	lpfc_scsi_dev_block(phba);

	/* stop all timers */
	lpfc_stop_hba_timers(phba);

	/* Clean up all driver's outstanding I/Os */
	lpfc_sli_flush_io_rings(phba);
}

/**
 * lpfc_io_error_detected_s4 - Method for handling PCI I/O error to SLI-4 device
 * @pdev: pointer to PCI device.
 * @state: the current PCI connection state.
 *
 * This routine is called from the PCI subsystem for error handling to device
 * with SLI-4 interface spec. This function is called by the PCI subsystem
 * after a PCI bus error affecting this device has been detected. When this
 * function is invoked, it will need to stop all the I/Os and interrupt(s)
 * to the device. Once that is done, it will return PCI_ERS_RESULT_NEED_RESET
 * for the PCI subsystem to perform proper recovery as desired.
 *
 * Return codes
 * 	PCI_ERS_RESULT_NEED_RESET - need to reset before recovery
 * 	PCI_ERS_RESULT_DISCONNECT - device could not be recovered
 **/
static pci_ers_result_t
lpfc_io_error_detected_s4(struct pci_dev *pdev, pci_channel_state_t state)
{
	struct Scsi_Host *shost = pci_get_drvdata(pdev);
	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;

	switch (state) {
	case pci_channel_io_normal:
		/* Non-fatal error, prepare for recovery */
		lpfc_sli4_prep_dev_for_recover(phba);
		return PCI_ERS_RESULT_CAN_RECOVER;
	case pci_channel_io_frozen:
		phba->hba_flag |= HBA_PCI_ERR;
		/* Fatal error, prepare for slot reset */
		lpfc_sli4_prep_dev_for_reset(phba);
		return PCI_ERS_RESULT_NEED_RESET;
	case pci_channel_io_perm_failure:
		phba->hba_flag |= HBA_PCI_ERR;
		/* Permanent failure, prepare for device down */
		lpfc_sli4_prep_dev_for_perm_failure(phba);
		return PCI_ERS_RESULT_DISCONNECT;
	default:
		phba->hba_flag |= HBA_PCI_ERR;
		/* Unknown state, prepare and request slot reset */
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2825 Unknown PCI error state: x%x\n", state);
		lpfc_sli4_prep_dev_for_reset(phba);
		return PCI_ERS_RESULT_NEED_RESET;
	}
}

/**
 * lpfc_io_slot_reset_s4 - Method for restart PCI SLI-4 device from scratch
 * @pdev: pointer to PCI device.
 *
 * This routine is called from the PCI subsystem for error handling to device
 * with SLI-4 interface spec. It is called after PCI bus has been reset to
 * restart the PCI card from scratch, as if from a cold-boot. During the
 * PCI subsystem error recovery, after the driver returns
 * PCI_ERS_RESULT_NEED_RESET, the PCI subsystem will perform proper error
 * recovery and then call this routine before calling the .resume method to
 * recover the device. This function will initialize the HBA device, enable
 * the interrupt, but it will just put the HBA to offline state without
 * passing any I/O traffic.
 *
 * Return codes
 * 	PCI_ERS_RESULT_RECOVERED - the device has been recovered
 * 	PCI_ERS_RESULT_DISCONNECT - device could not be recovered
 */
static pci_ers_result_t
lpfc_io_slot_reset_s4(struct pci_dev *pdev)
{
	struct Scsi_Host *shost = pci_get_drvdata(pdev);
	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
	struct lpfc_sli *psli = &phba->sli;
	uint32_t intr_mode;

	dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n");
	if (pci_enable_device_mem(pdev)) {
		printk(KERN_ERR "lpfc: Cannot re-enable "
			"PCI device after reset.\n");
		return PCI_ERS_RESULT_DISCONNECT;
	}

	pci_restore_state(pdev);

	phba->hba_flag &= ~HBA_PCI_ERR;
	/*
	 * As the new kernel behavior of pci_restore_state() API call clears
	 * device saved_state flag, need to save the restored state again.
	 */
	pci_save_state(pdev);

	if (pdev->is_busmaster)
		pci_set_master(pdev);

	spin_lock_irq(&phba->hbalock);
	psli->sli_flag &= ~LPFC_SLI_ACTIVE;
	spin_unlock_irq(&phba->hbalock);

	/* Configure and enable interrupt */
	intr_mode = lpfc_sli4_enable_intr(phba, phba->intr_mode);
	if (intr_mode == LPFC_INTR_ERROR) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2824 Cannot re-enable interrupt after "
				"slot reset.\n");
		return PCI_ERS_RESULT_DISCONNECT;
	} else
		phba->intr_mode = intr_mode;
	lpfc_cpu_affinity_check(phba, phba->cfg_irq_chann);

	/* Log the current active interrupt mode */
	lpfc_log_intr_mode(phba, phba->intr_mode);

	return PCI_ERS_RESULT_RECOVERED;
}

/**
 * lpfc_io_resume_s4 - Method for resuming PCI I/O operation to SLI-4 device
 * @pdev: pointer to PCI device
 *
 * This routine is called from the PCI subsystem for error handling to device
 * with SLI-4 interface spec. It is called when kernel error recovery tells
 * the lpfc driver that it is ok to resume normal PCI operation after PCI bus
 * error recovery. After this call, traffic can start to flow from this device
 * again.
 **/
static void
lpfc_io_resume_s4(struct pci_dev *pdev)
{
	struct Scsi_Host *shost = pci_get_drvdata(pdev);
	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;

	/*
	 * In case of slot reset, as function reset is performed through
	 * mailbox command which needs DMA to be enabled, this operation
	 * has to be moved to the io resume phase. Taking device offline
	 * will perform the necessary cleanup.
	 */
	if (!(phba->sli.sli_flag & LPFC_SLI_ACTIVE)) {
		/* Perform device reset */
		lpfc_offline_prep(phba, LPFC_MBX_WAIT);
		lpfc_offline(phba);
		lpfc_sli_brdrestart(phba);
		/* Bring the device back online */
		lpfc_online(phba);
	}
}

/**
 * lpfc_pci_probe_one - lpfc PCI probe func to reg dev to PCI subsystem
 * @pdev: pointer to PCI device
 * @pid: pointer to PCI device identifier
 *
 * This routine is to be registered to the kernel's PCI subsystem. When an
 * Emulex HBA device is presented on PCI bus, the kernel PCI subsystem looks
 * at PCI device-specific information of the device and driver to see if the
 * driver state that it can support this kind of device. If the match is
 * successful, the driver core invokes this routine. This routine dispatches
 * the action to the proper SLI-3 or SLI-4 device probing routine, which will
 * do all the initialization that it needs to do to handle the HBA device
 * properly.
 *
 * Return code
 * 	0 - driver can claim the device
 * 	negative value - driver can not claim the device
 **/
static int
lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
{
	int rc;
	struct lpfc_sli_intf intf;

	if (pci_read_config_dword(pdev, LPFC_SLI_INTF, &intf.word0))
		return -ENODEV;

	if ((bf_get(lpfc_sli_intf_valid, &intf) == LPFC_SLI_INTF_VALID) &&
	    (bf_get(lpfc_sli_intf_slirev, &intf) == LPFC_SLI_INTF_REV_SLI4))
		rc = lpfc_pci_probe_one_s4(pdev, pid);
	else
		rc = lpfc_pci_probe_one_s3(pdev, pid);

	return rc;
}

/**
 * lpfc_pci_remove_one - lpfc PCI func to unreg dev from PCI subsystem
 * @pdev: pointer to PCI device
 *
 * This routine is to be registered to the kernel's PCI subsystem. When an
 * Emulex HBA is removed from PCI bus, the driver core invokes this routine.
 * This routine dispatches the action to the proper SLI-3 or SLI-4 device
 * remove routine, which will perform all the necessary cleanup for the
 * device to be removed from the PCI subsystem properly.
 **/
static void
lpfc_pci_remove_one(struct pci_dev *pdev)
{
	struct Scsi_Host *shost = pci_get_drvdata(pdev);
	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;

	switch (phba->pci_dev_grp) {
	case LPFC_PCI_DEV_LP:
		lpfc_pci_remove_one_s3(pdev);
		break;
	case LPFC_PCI_DEV_OC:
		lpfc_pci_remove_one_s4(pdev);
		break;
	default:
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"1424 Invalid PCI device group: 0x%x\n",
				phba->pci_dev_grp);
		break;
	}
	return;
}

/**
 * lpfc_pci_suspend_one - lpfc PCI func to suspend dev for power management
 * @dev: pointer to device
 *
 * This routine is to be registered to the kernel's PCI subsystem to support
 * system Power Management (PM). When PM invokes this method, it dispatches
 * the action to the proper SLI-3 or SLI-4 device suspend routine, which will
 * suspend the device.
 *
 * Return code
 * 	0 - driver suspended the device
 * 	Error otherwise
 **/
static int __maybe_unused
lpfc_pci_suspend_one(struct device *dev)
{
	struct Scsi_Host *shost = dev_get_drvdata(dev);
	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
	int rc = -ENODEV;

	switch (phba->pci_dev_grp) {
	case LPFC_PCI_DEV_LP:
		rc = lpfc_pci_suspend_one_s3(dev);
		break;
	case LPFC_PCI_DEV_OC:
		rc = lpfc_pci_suspend_one_s4(dev);
		break;
	default:
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"1425 Invalid PCI device group: 0x%x\n",
				phba->pci_dev_grp);
		break;
	}
	return rc;
}

/**
 * lpfc_pci_resume_one - lpfc PCI func to resume dev for power management
 * @dev: pointer to device
 *
 * This routine is to be registered to the kernel's PCI subsystem to support
 * system Power Management (PM). When PM invokes this method, it dispatches
 * the action to the proper SLI-3 or SLI-4 device resume routine, which will
 * resume the device.
 *
 * Return code
 * 	0 - driver suspended the device
 * 	Error otherwise
 **/
static int __maybe_unused
lpfc_pci_resume_one(struct device *dev)
{
	struct Scsi_Host *shost = dev_get_drvdata(dev);
	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
	int rc = -ENODEV;

	switch (phba->pci_dev_grp) {
	case LPFC_PCI_DEV_LP:
		rc = lpfc_pci_resume_one_s3(dev);
		break;
	case LPFC_PCI_DEV_OC:
		rc = lpfc_pci_resume_one_s4(dev);
		break;
	default:
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"1426 Invalid PCI device group: 0x%x\n",
				phba->pci_dev_grp);
		break;
	}
	return rc;
}

/**
 * lpfc_io_error_detected - lpfc method for handling PCI I/O error
 * @pdev: pointer to PCI device.
 * @state: the current PCI connection state.
 *
 * This routine is registered to the PCI subsystem for error handling. This
 * function is called by the PCI subsystem after a PCI bus error affecting
 * this device has been detected. When this routine is invoked, it dispatches
 * the action to the proper SLI-3 or SLI-4 device error detected handling
 * routine, which will perform the proper error detected operation.
 *
 * Return codes
 * 	PCI_ERS_RESULT_NEED_RESET - need to reset before recovery
 * 	PCI_ERS_RESULT_DISCONNECT - device could not be recovered
 **/
static pci_ers_result_t
lpfc_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
{
	struct Scsi_Host *shost = pci_get_drvdata(pdev);
	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
	pci_ers_result_t rc = PCI_ERS_RESULT_DISCONNECT;

	if (phba->link_state == LPFC_HBA_ERROR &&
	    phba->hba_flag & HBA_IOQ_FLUSH)
		return PCI_ERS_RESULT_NEED_RESET;

	switch (phba->pci_dev_grp) {
	case LPFC_PCI_DEV_LP:
		rc = lpfc_io_error_detected_s3(pdev, state);
		break;
	case LPFC_PCI_DEV_OC:
		rc = lpfc_io_error_detected_s4(pdev, state);
		break;
	default:
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"1427 Invalid PCI device group: 0x%x\n",
				phba->pci_dev_grp);
		break;
	}
	return rc;
}

/**
 * lpfc_io_slot_reset - lpfc method for restart PCI dev from scratch
 * @pdev: pointer to PCI device.
 *
 * This routine is registered to the PCI subsystem for error handling. This
 * function is called after PCI bus has been reset to restart the PCI card
 * from scratch, as if from a cold-boot. When this routine is invoked, it
 * dispatches the action to the proper SLI-3 or SLI-4 device reset handling
 * routine, which will perform the proper device reset.
 *
 * Return codes
 * 	PCI_ERS_RESULT_RECOVERED - the device has been recovered
 * 	PCI_ERS_RESULT_DISCONNECT - device could not be recovered
 **/
static pci_ers_result_t
lpfc_io_slot_reset(struct pci_dev *pdev)
{
	struct Scsi_Host *shost = pci_get_drvdata(pdev);
	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
	pci_ers_result_t rc = PCI_ERS_RESULT_DISCONNECT;

	switch (phba->pci_dev_grp) {
	case LPFC_PCI_DEV_LP:
		rc = lpfc_io_slot_reset_s3(pdev);
		break;
	case LPFC_PCI_DEV_OC:
		rc = lpfc_io_slot_reset_s4(pdev);
		break;
	default:
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"1428 Invalid PCI device group: 0x%x\n",
				phba->pci_dev_grp);
		break;
	}
	return rc;
}

/**
 * lpfc_io_resume - lpfc method for resuming PCI I/O operation
 * @pdev: pointer to PCI device
 *
 * This routine is registered to the PCI subsystem for error handling. It
 * is called when kernel error recovery tells the lpfc driver that it is
 * OK to resume normal PCI operation after PCI bus error recovery. When
 * this routine is invoked, it dispatches the action to the proper SLI-3
 * or SLI-4 device io_resume routine, which will resume the device operation.
 **/
static void
lpfc_io_resume(struct pci_dev *pdev)
{
	struct Scsi_Host *shost = pci_get_drvdata(pdev);
	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;

	switch (phba->pci_dev_grp) {
	case LPFC_PCI_DEV_LP:
		lpfc_io_resume_s3(pdev);
		break;
	case LPFC_PCI_DEV_OC:
		lpfc_io_resume_s4(pdev);
		break;
	default:
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"1429 Invalid PCI device group: 0x%x\n",
				phba->pci_dev_grp);
		break;
	}
	return;
}

/**
 * lpfc_sli4_oas_verify - Verify OAS is supported by this adapter
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine checks to see if OAS is supported for this adapter. If
 * supported, the configure Flash Optimized Fabric flag is set.  Otherwise,
 * the enable oas flag is cleared and the pool created for OAS device data
 * is destroyed.
 *
 **/
static void
lpfc_sli4_oas_verify(struct lpfc_hba *phba)
{

	if (!phba->cfg_EnableXLane)
		return;

	if (phba->sli4_hba.pc_sli4_params.oas_supported) {
		phba->cfg_fof = 1;
	} else {
		phba->cfg_fof = 0;
		mempool_destroy(phba->device_data_mem_pool);
		phba->device_data_mem_pool = NULL;
	}

	return;
}

/**
 * lpfc_sli4_ras_init - Verify RAS-FW log is supported by this adapter
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine checks to see if RAS is supported by the adapter. Check the
 * function through which RAS support enablement is to be done.
 **/
void
lpfc_sli4_ras_init(struct lpfc_hba *phba)
{
	/* if ASIC_GEN_NUM >= 0xC) */
	if ((bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
		    LPFC_SLI_INTF_IF_TYPE_6) ||
	    (bf_get(lpfc_sli_intf_sli_family, &phba->sli4_hba.sli_intf) ==
		    LPFC_SLI_INTF_FAMILY_G6)) {
		phba->ras_fwlog.ras_hwsupport = true;
		if (phba->cfg_ras_fwlog_func == PCI_FUNC(phba->pcidev->devfn) &&
		    phba->cfg_ras_fwlog_buffsize)
			phba->ras_fwlog.ras_enabled = true;
		else
			phba->ras_fwlog.ras_enabled = false;
	} else {
		phba->ras_fwlog.ras_hwsupport = false;
	}
}


MODULE_DEVICE_TABLE(pci, lpfc_id_table);

static const struct pci_error_handlers lpfc_err_handler = {
	.error_detected = lpfc_io_error_detected,
	.slot_reset = lpfc_io_slot_reset,
	.resume = lpfc_io_resume,
};

static SIMPLE_DEV_PM_OPS(lpfc_pci_pm_ops_one,
			 lpfc_pci_suspend_one,
			 lpfc_pci_resume_one);

static struct pci_driver lpfc_driver = {
	.name		= LPFC_DRIVER_NAME,
	.id_table	= lpfc_id_table,
	.probe		= lpfc_pci_probe_one,
	.remove		= lpfc_pci_remove_one,
	.shutdown	= lpfc_pci_remove_one,
	.driver.pm	= &lpfc_pci_pm_ops_one,
	.err_handler    = &lpfc_err_handler,
};

static const struct file_operations lpfc_mgmt_fop = {
	.owner = THIS_MODULE,
};

static struct miscdevice lpfc_mgmt_dev = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = "lpfcmgmt",
	.fops = &lpfc_mgmt_fop,
};

/**
 * lpfc_init - lpfc module initialization routine
 *
 * This routine is to be invoked when the lpfc module is loaded into the
 * kernel. The special kernel macro module_init() is used to indicate the
 * role of this routine to the kernel as lpfc module entry point.
 *
 * Return codes
 *   0 - successful
 *   -ENOMEM - FC attach transport failed
 *   all others - failed
 */
static int __init
lpfc_init(void)
{
	int error = 0;

	pr_info(LPFC_MODULE_DESC "\n");
	pr_info(LPFC_COPYRIGHT "\n");

	error = misc_register(&lpfc_mgmt_dev);
	if (error)
		printk(KERN_ERR "Could not register lpfcmgmt device, "
			"misc_register returned with status %d", error);

	error = -ENOMEM;
	lpfc_transport_functions.vport_create = lpfc_vport_create;
	lpfc_transport_functions.vport_delete = lpfc_vport_delete;
	lpfc_transport_template =
				fc_attach_transport(&lpfc_transport_functions);
	if (lpfc_transport_template == NULL)
		goto unregister;
	lpfc_vport_transport_template =
		fc_attach_transport(&lpfc_vport_transport_functions);
	if (lpfc_vport_transport_template == NULL) {
		fc_release_transport(lpfc_transport_template);
		goto unregister;
	}
	lpfc_wqe_cmd_template();
	lpfc_nvmet_cmd_template();

	/* Initialize in case vector mapping is needed */
	lpfc_present_cpu = num_present_cpus();

	lpfc_pldv_detect = false;

	error = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
					"lpfc/sli4:online",
					lpfc_cpu_online, lpfc_cpu_offline);
	if (error < 0)
		goto cpuhp_failure;
	lpfc_cpuhp_state = error;

	error = pci_register_driver(&lpfc_driver);
	if (error)
		goto unwind;

	return error;

unwind:
	cpuhp_remove_multi_state(lpfc_cpuhp_state);
cpuhp_failure:
	fc_release_transport(lpfc_transport_template);
	fc_release_transport(lpfc_vport_transport_template);
unregister:
	misc_deregister(&lpfc_mgmt_dev);

	return error;
}

void lpfc_dmp_dbg(struct lpfc_hba *phba)
{
	unsigned int start_idx;
	unsigned int dbg_cnt;
	unsigned int temp_idx;
	int i;
	int j = 0;
	unsigned long rem_nsec, iflags;
	bool log_verbose = false;
	struct lpfc_vport *port_iterator;

	/* Don't dump messages if we explicitly set log_verbose for the
	 * physical port or any vport.
	 */
	if (phba->cfg_log_verbose)
		return;

	spin_lock_irqsave(&phba->port_list_lock, iflags);
	list_for_each_entry(port_iterator, &phba->port_list, listentry) {
		if (port_iterator->load_flag & FC_UNLOADING)
			continue;
		if (scsi_host_get(lpfc_shost_from_vport(port_iterator))) {
			if (port_iterator->cfg_log_verbose)
				log_verbose = true;

			scsi_host_put(lpfc_shost_from_vport(port_iterator));

			if (log_verbose) {
				spin_unlock_irqrestore(&phba->port_list_lock,
						       iflags);
				return;
			}
		}
	}
	spin_unlock_irqrestore(&phba->port_list_lock, iflags);

	if (atomic_cmpxchg(&phba->dbg_log_dmping, 0, 1) != 0)
		return;

	start_idx = (unsigned int)atomic_read(&phba->dbg_log_idx) % DBG_LOG_SZ;
	dbg_cnt = (unsigned int)atomic_read(&phba->dbg_log_cnt);
	if (!dbg_cnt)
		goto out;
	temp_idx = start_idx;
	if (dbg_cnt >= DBG_LOG_SZ) {
		dbg_cnt = DBG_LOG_SZ;
		temp_idx -= 1;
	} else {
		if ((start_idx + dbg_cnt) > (DBG_LOG_SZ - 1)) {
			temp_idx = (start_idx + dbg_cnt) % DBG_LOG_SZ;
		} else {
			if (start_idx < dbg_cnt)
				start_idx = DBG_LOG_SZ - (dbg_cnt - start_idx);
			else
				start_idx -= dbg_cnt;
		}
	}
	dev_info(&phba->pcidev->dev, "start %d end %d cnt %d\n",
		 start_idx, temp_idx, dbg_cnt);

	for (i = 0; i < dbg_cnt; i++) {
		if ((start_idx + i) < DBG_LOG_SZ)
			temp_idx = (start_idx + i) % DBG_LOG_SZ;
		else
			temp_idx = j++;
		rem_nsec = do_div(phba->dbg_log[temp_idx].t_ns, NSEC_PER_SEC);
		dev_info(&phba->pcidev->dev, "%d: [%5lu.%06lu] %s",
			 temp_idx,
			 (unsigned long)phba->dbg_log[temp_idx].t_ns,
			 rem_nsec / 1000,
			 phba->dbg_log[temp_idx].log);
	}
out:
	atomic_set(&phba->dbg_log_cnt, 0);
	atomic_set(&phba->dbg_log_dmping, 0);
}

__printf(2, 3)
void lpfc_dbg_print(struct lpfc_hba *phba, const char *fmt, ...)
{
	unsigned int idx;
	va_list args;
	int dbg_dmping = atomic_read(&phba->dbg_log_dmping);
	struct va_format vaf;


	va_start(args, fmt);
	if (unlikely(dbg_dmping)) {
		vaf.fmt = fmt;
		vaf.va = &args;
		dev_info(&phba->pcidev->dev, "%pV", &vaf);
		va_end(args);
		return;
	}
	idx = (unsigned int)atomic_fetch_add(1, &phba->dbg_log_idx) %
		DBG_LOG_SZ;

	atomic_inc(&phba->dbg_log_cnt);

	vscnprintf(phba->dbg_log[idx].log,
		   sizeof(phba->dbg_log[idx].log), fmt, args);
	va_end(args);

	phba->dbg_log[idx].t_ns = local_clock();
}

/**
 * lpfc_exit - lpfc module removal routine
 *
 * This routine is invoked when the lpfc module is removed from the kernel.
 * The special kernel macro module_exit() is used to indicate the role of
 * this routine to the kernel as lpfc module exit point.
 */
static void __exit
lpfc_exit(void)
{
	misc_deregister(&lpfc_mgmt_dev);
	pci_unregister_driver(&lpfc_driver);
	cpuhp_remove_multi_state(lpfc_cpuhp_state);
	fc_release_transport(lpfc_transport_template);
	fc_release_transport(lpfc_vport_transport_template);
	idr_destroy(&lpfc_hba_index);
}

module_init(lpfc_init);
module_exit(lpfc_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION(LPFC_MODULE_DESC);
MODULE_AUTHOR("Broadcom");
MODULE_VERSION("0:" LPFC_DRIVER_VERSION);
