/*
 * QLogic Fibre Channel HBA Driver
 * Copyright (c)  2003-2011 QLogic Corporation
 *
 * See LICENSE.qla2xxx for copyright and licensing details.
 */
#include "qla_def.h"
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/ratelimit.h>
#include <linux/vmalloc.h>
#include <scsi/scsi_tcq.h>

#define MASK(n)			((1ULL<<(n))-1)
#define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | \
	((addr >> 25) & 0x3ff))
#define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | \
	((addr >> 25) & 0x3ff))
#define MS_WIN(addr) (addr & 0x0ffc0000)
#define QLA82XX_PCI_MN_2M   (0)
#define QLA82XX_PCI_MS_2M   (0x80000)
#define QLA82XX_PCI_OCM0_2M (0xc0000)
#define VALID_OCM_ADDR(addr) (((addr) & 0x3f800) != 0x3f800)
#define GET_MEM_OFFS_2M(addr) (addr & MASK(18))
#define BLOCK_PROTECT_BITS 0x0F

/* CRB window related */
#define CRB_BLK(off)	((off >> 20) & 0x3f)
#define CRB_SUBBLK(off)	((off >> 16) & 0xf)
#define CRB_WINDOW_2M	(0x130060)
#define QLA82XX_PCI_CAMQM_2M_END	(0x04800800UL)
#define CRB_HI(off)	((qla82xx_crb_hub_agt[CRB_BLK(off)] << 20) | \
			((off) & 0xf0000))
#define QLA82XX_PCI_CAMQM_2M_BASE	(0x000ff800UL)
#define CRB_INDIRECT_2M	(0x1e0000UL)

#define MAX_CRB_XFORM 60
static unsigned long crb_addr_xform[MAX_CRB_XFORM];
int qla82xx_crb_table_initialized;

#define qla82xx_crb_addr_transform(name) \
	(crb_addr_xform[QLA82XX_HW_PX_MAP_CRB_##name] = \
	QLA82XX_HW_CRB_HUB_AGT_ADR_##name << 20)

static void qla82xx_crb_addr_transform_setup(void)
{
	qla82xx_crb_addr_transform(XDMA);
	qla82xx_crb_addr_transform(TIMR);
	qla82xx_crb_addr_transform(SRE);
	qla82xx_crb_addr_transform(SQN3);
	qla82xx_crb_addr_transform(SQN2);
	qla82xx_crb_addr_transform(SQN1);
	qla82xx_crb_addr_transform(SQN0);
	qla82xx_crb_addr_transform(SQS3);
	qla82xx_crb_addr_transform(SQS2);
	qla82xx_crb_addr_transform(SQS1);
	qla82xx_crb_addr_transform(SQS0);
	qla82xx_crb_addr_transform(RPMX7);
	qla82xx_crb_addr_transform(RPMX6);
	qla82xx_crb_addr_transform(RPMX5);
	qla82xx_crb_addr_transform(RPMX4);
	qla82xx_crb_addr_transform(RPMX3);
	qla82xx_crb_addr_transform(RPMX2);
	qla82xx_crb_addr_transform(RPMX1);
	qla82xx_crb_addr_transform(RPMX0);
	qla82xx_crb_addr_transform(ROMUSB);
	qla82xx_crb_addr_transform(SN);
	qla82xx_crb_addr_transform(QMN);
	qla82xx_crb_addr_transform(QMS);
	qla82xx_crb_addr_transform(PGNI);
	qla82xx_crb_addr_transform(PGND);
	qla82xx_crb_addr_transform(PGN3);
	qla82xx_crb_addr_transform(PGN2);
	qla82xx_crb_addr_transform(PGN1);
	qla82xx_crb_addr_transform(PGN0);
	qla82xx_crb_addr_transform(PGSI);
	qla82xx_crb_addr_transform(PGSD);
	qla82xx_crb_addr_transform(PGS3);
	qla82xx_crb_addr_transform(PGS2);
	qla82xx_crb_addr_transform(PGS1);
	qla82xx_crb_addr_transform(PGS0);
	qla82xx_crb_addr_transform(PS);
	qla82xx_crb_addr_transform(PH);
	qla82xx_crb_addr_transform(NIU);
	qla82xx_crb_addr_transform(I2Q);
	qla82xx_crb_addr_transform(EG);
	qla82xx_crb_addr_transform(MN);
	qla82xx_crb_addr_transform(MS);
	qla82xx_crb_addr_transform(CAS2);
	qla82xx_crb_addr_transform(CAS1);
	qla82xx_crb_addr_transform(CAS0);
	qla82xx_crb_addr_transform(CAM);
	qla82xx_crb_addr_transform(C2C1);
	qla82xx_crb_addr_transform(C2C0);
	qla82xx_crb_addr_transform(SMB);
	qla82xx_crb_addr_transform(OCM0);
	/*
	 * Used only in P3 just define it for P2 also.
	 */
	qla82xx_crb_addr_transform(I2C0);

	qla82xx_crb_table_initialized = 1;
}

struct crb_128M_2M_block_map crb_128M_2M_map[64] = {
	{{{0, 0,         0,         0} } },
	{{{1, 0x0100000, 0x0102000, 0x120000},
	{1, 0x0110000, 0x0120000, 0x130000},
	{1, 0x0120000, 0x0122000, 0x124000},
	{1, 0x0130000, 0x0132000, 0x126000},
	{1, 0x0140000, 0x0142000, 0x128000},
	{1, 0x0150000, 0x0152000, 0x12a000},
	{1, 0x0160000, 0x0170000, 0x110000},
	{1, 0x0170000, 0x0172000, 0x12e000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{1, 0x01e0000, 0x01e0800, 0x122000},
	{0, 0x0000000, 0x0000000, 0x000000} } } ,
	{{{1, 0x0200000, 0x0210000, 0x180000} } },
	{{{0, 0,         0,         0} } },
	{{{1, 0x0400000, 0x0401000, 0x169000} } },
	{{{1, 0x0500000, 0x0510000, 0x140000} } },
	{{{1, 0x0600000, 0x0610000, 0x1c0000} } },
	{{{1, 0x0700000, 0x0704000, 0x1b8000} } },
	{{{1, 0x0800000, 0x0802000, 0x170000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{1, 0x08f0000, 0x08f2000, 0x172000} } },
	{{{1, 0x0900000, 0x0902000, 0x174000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{1, 0x09f0000, 0x09f2000, 0x176000} } },
	{{{0, 0x0a00000, 0x0a02000, 0x178000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{1, 0x0af0000, 0x0af2000, 0x17a000} } },
	{{{0, 0x0b00000, 0x0b02000, 0x17c000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{1, 0x0bf0000, 0x0bf2000, 0x17e000} } },
	{{{1, 0x0c00000, 0x0c04000, 0x1d4000} } },
	{{{1, 0x0d00000, 0x0d04000, 0x1a4000} } },
	{{{1, 0x0e00000, 0x0e04000, 0x1a0000} } },
	{{{1, 0x0f00000, 0x0f01000, 0x164000} } },
	{{{0, 0x1000000, 0x1004000, 0x1a8000} } },
	{{{1, 0x1100000, 0x1101000, 0x160000} } },
	{{{1, 0x1200000, 0x1201000, 0x161000} } },
	{{{1, 0x1300000, 0x1301000, 0x162000} } },
	{{{1, 0x1400000, 0x1401000, 0x163000} } },
	{{{1, 0x1500000, 0x1501000, 0x165000} } },
	{{{1, 0x1600000, 0x1601000, 0x166000} } },
	{{{0, 0,         0,         0} } },
	{{{0, 0,         0,         0} } },
	{{{0, 0,         0,         0} } },
	{{{0, 0,         0,         0} } },
	{{{0, 0,         0,         0} } },
	{{{0, 0,         0,         0} } },
	{{{1, 0x1d00000, 0x1d10000, 0x190000} } },
	{{{1, 0x1e00000, 0x1e01000, 0x16a000} } },
	{{{1, 0x1f00000, 0x1f10000, 0x150000} } },
	{{{0} } },
	{{{1, 0x2100000, 0x2102000, 0x120000},
	{1, 0x2110000, 0x2120000, 0x130000},
	{1, 0x2120000, 0x2122000, 0x124000},
	{1, 0x2130000, 0x2132000, 0x126000},
	{1, 0x2140000, 0x2142000, 0x128000},
	{1, 0x2150000, 0x2152000, 0x12a000},
	{1, 0x2160000, 0x2170000, 0x110000},
	{1, 0x2170000, 0x2172000, 0x12e000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000},
	{0, 0x0000000, 0x0000000, 0x000000} } },
	{{{1, 0x2200000, 0x2204000, 0x1b0000} } },
	{{{0} } },
	{{{0} } },
	{{{0} } },
	{{{0} } },
	{{{0} } },
	{{{1, 0x2800000, 0x2804000, 0x1a4000} } },
	{{{1, 0x2900000, 0x2901000, 0x16b000} } },
	{{{1, 0x2a00000, 0x2a00400, 0x1ac400} } },
	{{{1, 0x2b00000, 0x2b00400, 0x1ac800} } },
	{{{1, 0x2c00000, 0x2c00400, 0x1acc00} } },
	{{{1, 0x2d00000, 0x2d00400, 0x1ad000} } },
	{{{1, 0x2e00000, 0x2e00400, 0x1ad400} } },
	{{{1, 0x2f00000, 0x2f00400, 0x1ad800} } },
	{{{1, 0x3000000, 0x3000400, 0x1adc00} } },
	{{{0, 0x3100000, 0x3104000, 0x1a8000} } },
	{{{1, 0x3200000, 0x3204000, 0x1d4000} } },
	{{{1, 0x3300000, 0x3304000, 0x1a0000} } },
	{{{0} } },
	{{{1, 0x3500000, 0x3500400, 0x1ac000} } },
	{{{1, 0x3600000, 0x3600400, 0x1ae000} } },
	{{{1, 0x3700000, 0x3700400, 0x1ae400} } },
	{{{1, 0x3800000, 0x3804000, 0x1d0000} } },
	{{{1, 0x3900000, 0x3904000, 0x1b4000} } },
	{{{1, 0x3a00000, 0x3a04000, 0x1d8000} } },
	{{{0} } },
	{{{0} } },
	{{{1, 0x3d00000, 0x3d04000, 0x1dc000} } },
	{{{1, 0x3e00000, 0x3e01000, 0x167000} } },
	{{{1, 0x3f00000, 0x3f01000, 0x168000} } }
};

/*
 * top 12 bits of crb internal address (hub, agent)
 */
unsigned qla82xx_crb_hub_agt[64] = {
	0,
	QLA82XX_HW_CRB_HUB_AGT_ADR_PS,
	QLA82XX_HW_CRB_HUB_AGT_ADR_MN,
	QLA82XX_HW_CRB_HUB_AGT_ADR_MS,
	0,
	QLA82XX_HW_CRB_HUB_AGT_ADR_SRE,
	QLA82XX_HW_CRB_HUB_AGT_ADR_NIU,
	QLA82XX_HW_CRB_HUB_AGT_ADR_QMN,
	QLA82XX_HW_CRB_HUB_AGT_ADR_SQN0,
	QLA82XX_HW_CRB_HUB_AGT_ADR_SQN1,
	QLA82XX_HW_CRB_HUB_AGT_ADR_SQN2,
	QLA82XX_HW_CRB_HUB_AGT_ADR_SQN3,
	QLA82XX_HW_CRB_HUB_AGT_ADR_I2Q,
	QLA82XX_HW_CRB_HUB_AGT_ADR_TIMR,
	QLA82XX_HW_CRB_HUB_AGT_ADR_ROMUSB,
	QLA82XX_HW_CRB_HUB_AGT_ADR_PGN4,
	QLA82XX_HW_CRB_HUB_AGT_ADR_XDMA,
	QLA82XX_HW_CRB_HUB_AGT_ADR_PGN0,
	QLA82XX_HW_CRB_HUB_AGT_ADR_PGN1,
	QLA82XX_HW_CRB_HUB_AGT_ADR_PGN2,
	QLA82XX_HW_CRB_HUB_AGT_ADR_PGN3,
	QLA82XX_HW_CRB_HUB_AGT_ADR_PGND,
	QLA82XX_HW_CRB_HUB_AGT_ADR_PGNI,
	QLA82XX_HW_CRB_HUB_AGT_ADR_PGS0,
	QLA82XX_HW_CRB_HUB_AGT_ADR_PGS1,
	QLA82XX_HW_CRB_HUB_AGT_ADR_PGS2,
	QLA82XX_HW_CRB_HUB_AGT_ADR_PGS3,
	0,
	QLA82XX_HW_CRB_HUB_AGT_ADR_PGSI,
	QLA82XX_HW_CRB_HUB_AGT_ADR_SN,
	0,
	QLA82XX_HW_CRB_HUB_AGT_ADR_EG,
	0,
	QLA82XX_HW_CRB_HUB_AGT_ADR_PS,
	QLA82XX_HW_CRB_HUB_AGT_ADR_CAM,
	0,
	0,
	0,
	0,
	0,
	QLA82XX_HW_CRB_HUB_AGT_ADR_TIMR,
	0,
	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX1,
	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX2,
	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX3,
	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX4,
	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX5,
	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX6,
	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX7,
	QLA82XX_HW_CRB_HUB_AGT_ADR_XDMA,
	QLA82XX_HW_CRB_HUB_AGT_ADR_I2Q,
	QLA82XX_HW_CRB_HUB_AGT_ADR_ROMUSB,
	0,
	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX0,
	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX8,
	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX9,
	QLA82XX_HW_CRB_HUB_AGT_ADR_OCM0,
	0,
	QLA82XX_HW_CRB_HUB_AGT_ADR_SMB,
	QLA82XX_HW_CRB_HUB_AGT_ADR_I2C0,
	QLA82XX_HW_CRB_HUB_AGT_ADR_I2C1,
	0,
	QLA82XX_HW_CRB_HUB_AGT_ADR_PGNC,
	0,
};

/* Device states */
char *q_dev_state[] = {
	 "Unknown",
	"Cold",
	"Initializing",
	"Ready",
	"Need Reset",
	"Need Quiescent",
	"Failed",
	"Quiescent",
};

char *qdev_state(uint32_t dev_state)
{
	return q_dev_state[dev_state];
}

/*
 * In: 'off' is offset from CRB space in 128M pci map
 * Out: 'off' is 2M pci map addr
 * side effect: lock crb window
 */
static void
qla82xx_pci_set_crbwindow_2M(struct qla_hw_data *ha, ulong *off)
{
	u32 win_read;
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);

	ha->crb_win = CRB_HI(*off);
	writel(ha->crb_win,
		(void *)(CRB_WINDOW_2M + ha->nx_pcibase));

	/* Read back value to make sure write has gone through before trying
	 * to use it.
	 */
	win_read = RD_REG_DWORD((void *)(CRB_WINDOW_2M + ha->nx_pcibase));
	if (win_read != ha->crb_win) {
		ql_dbg(ql_dbg_p3p, vha, 0xb000,
		    "%s: Written crbwin (0x%x) "
		    "!= Read crbwin (0x%x), off=0x%lx.\n",
		    __func__, ha->crb_win, win_read, *off);
	}
	*off = (*off & MASK(16)) + CRB_INDIRECT_2M + ha->nx_pcibase;
}

static inline unsigned long
qla82xx_pci_set_crbwindow(struct qla_hw_data *ha, u64 off)
{
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
	/* See if we are currently pointing to the region we want to use next */
	if ((off >= QLA82XX_CRB_PCIX_HOST) && (off < QLA82XX_CRB_DDR_NET)) {
		/* No need to change window. PCIX and PCIEregs are in both
		 * regs are in both windows.
		 */
		return off;
	}

	if ((off >= QLA82XX_CRB_PCIX_HOST) && (off < QLA82XX_CRB_PCIX_HOST2)) {
		/* We are in first CRB window */
		if (ha->curr_window != 0)
			WARN_ON(1);
		return off;
	}

	if ((off > QLA82XX_CRB_PCIX_HOST2) && (off < QLA82XX_CRB_MAX)) {
		/* We are in second CRB window */
		off = off - QLA82XX_CRB_PCIX_HOST2 + QLA82XX_CRB_PCIX_HOST;

		if (ha->curr_window != 1)
			return off;

		/* We are in the QM or direct access
		 * register region - do nothing
		 */
		if ((off >= QLA82XX_PCI_DIRECT_CRB) &&
			(off < QLA82XX_PCI_CAMQM_MAX))
			return off;
	}
	/* strange address given */
	ql_dbg(ql_dbg_p3p, vha, 0xb001,
	    "%s: Warning: unm_nic_pci_set_crbwindow "
	    "called with an unknown address(%llx).\n",
	    QLA2XXX_DRIVER_NAME, off);
	return off;
}

static int
qla82xx_pci_get_crb_addr_2M(struct qla_hw_data *ha, ulong *off)
{
	struct crb_128M_2M_sub_block_map *m;

	if (*off >= QLA82XX_CRB_MAX)
		return -1;

	if (*off >= QLA82XX_PCI_CAMQM && (*off < QLA82XX_PCI_CAMQM_2M_END)) {
		*off = (*off - QLA82XX_PCI_CAMQM) +
		    QLA82XX_PCI_CAMQM_2M_BASE + ha->nx_pcibase;
		return 0;
	}

	if (*off < QLA82XX_PCI_CRBSPACE)
		return -1;

	*off -= QLA82XX_PCI_CRBSPACE;

	/* Try direct map */
	m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];

	if (m->valid && (m->start_128M <= *off) && (m->end_128M > *off)) {
		*off = *off + m->start_2M - m->start_128M + ha->nx_pcibase;
		return 0;
	}
	/* Not in direct map, use crb window */
	return 1;
}

#define CRB_WIN_LOCK_TIMEOUT 100000000
static int qla82xx_crb_win_lock(struct qla_hw_data *ha)
{
	int done = 0, timeout = 0;

	while (!done) {
		/* acquire semaphore3 from PCI HW block */
		done = qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM7_LOCK));
		if (done == 1)
			break;
		if (timeout >= CRB_WIN_LOCK_TIMEOUT)
			return -1;
		timeout++;
	}
	qla82xx_wr_32(ha, QLA82XX_CRB_WIN_LOCK_ID, ha->portnum);
	return 0;
}

int
qla82xx_wr_32(struct qla_hw_data *ha, ulong off, u32 data)
{
	unsigned long flags = 0;
	int rv;

	rv = qla82xx_pci_get_crb_addr_2M(ha, &off);

	BUG_ON(rv == -1);

	if (rv == 1) {
		write_lock_irqsave(&ha->hw_lock, flags);
		qla82xx_crb_win_lock(ha);
		qla82xx_pci_set_crbwindow_2M(ha, &off);
	}

	writel(data, (void __iomem *)off);

	if (rv == 1) {
		qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM7_UNLOCK));
		write_unlock_irqrestore(&ha->hw_lock, flags);
	}
	return 0;
}

int
qla82xx_rd_32(struct qla_hw_data *ha, ulong off)
{
	unsigned long flags = 0;
	int rv;
	u32 data;

	rv = qla82xx_pci_get_crb_addr_2M(ha, &off);

	BUG_ON(rv == -1);

	if (rv == 1) {
		write_lock_irqsave(&ha->hw_lock, flags);
		qla82xx_crb_win_lock(ha);
		qla82xx_pci_set_crbwindow_2M(ha, &off);
	}
	data = RD_REG_DWORD((void __iomem *)off);

	if (rv == 1) {
		qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM7_UNLOCK));
		write_unlock_irqrestore(&ha->hw_lock, flags);
	}
	return data;
}

#define IDC_LOCK_TIMEOUT 100000000
int qla82xx_idc_lock(struct qla_hw_data *ha)
{
	int i;
	int done = 0, timeout = 0;

	while (!done) {
		/* acquire semaphore5 from PCI HW block */
		done = qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM5_LOCK));
		if (done == 1)
			break;
		if (timeout >= IDC_LOCK_TIMEOUT)
			return -1;

		timeout++;

		/* Yield CPU */
		if (!in_interrupt())
			schedule();
		else {
			for (i = 0; i < 20; i++)
				cpu_relax();
		}
	}

	return 0;
}

void qla82xx_idc_unlock(struct qla_hw_data *ha)
{
	qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM5_UNLOCK));
}

/*  PCI Windowing for DDR regions.  */
#define QLA82XX_ADDR_IN_RANGE(addr, low, high) \
	(((addr) <= (high)) && ((addr) >= (low)))
/*
 * check memory access boundary.
 * used by test agent. support ddr access only for now
 */
static unsigned long
qla82xx_pci_mem_bound_check(struct qla_hw_data *ha,
	unsigned long long addr, int size)
{
	if (!QLA82XX_ADDR_IN_RANGE(addr, QLA82XX_ADDR_DDR_NET,
		QLA82XX_ADDR_DDR_NET_MAX) ||
		!QLA82XX_ADDR_IN_RANGE(addr + size - 1, QLA82XX_ADDR_DDR_NET,
		QLA82XX_ADDR_DDR_NET_MAX) ||
		((size != 1) && (size != 2) && (size != 4) && (size != 8)))
			return 0;
	else
		return 1;
}

int qla82xx_pci_set_window_warning_count;

static unsigned long
qla82xx_pci_set_window(struct qla_hw_data *ha, unsigned long long addr)
{
	int window;
	u32 win_read;
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);

	if (QLA82XX_ADDR_IN_RANGE(addr, QLA82XX_ADDR_DDR_NET,
		QLA82XX_ADDR_DDR_NET_MAX)) {
		/* DDR network side */
		window = MN_WIN(addr);
		ha->ddr_mn_window = window;
		qla82xx_wr_32(ha,
			ha->mn_win_crb | QLA82XX_PCI_CRBSPACE, window);
		win_read = qla82xx_rd_32(ha,
			ha->mn_win_crb | QLA82XX_PCI_CRBSPACE);
		if ((win_read << 17) != window) {
			ql_dbg(ql_dbg_p3p, vha, 0xb003,
			    "%s: Written MNwin (0x%x) != Read MNwin (0x%x).\n",
			    __func__, window, win_read);
		}
		addr = GET_MEM_OFFS_2M(addr) + QLA82XX_PCI_DDR_NET;
	} else if (QLA82XX_ADDR_IN_RANGE(addr, QLA82XX_ADDR_OCM0,
		QLA82XX_ADDR_OCM0_MAX)) {
		unsigned int temp1;
		if ((addr & 0x00ff800) == 0xff800) {
			ql_log(ql_log_warn, vha, 0xb004,
			    "%s: QM access not handled.\n", __func__);
			addr = -1UL;
		}
		window = OCM_WIN(addr);
		ha->ddr_mn_window = window;
		qla82xx_wr_32(ha,
			ha->mn_win_crb | QLA82XX_PCI_CRBSPACE, window);
		win_read = qla82xx_rd_32(ha,
			ha->mn_win_crb | QLA82XX_PCI_CRBSPACE);
		temp1 = ((window & 0x1FF) << 7) |
		    ((window & 0x0FFFE0000) >> 17);
		if (win_read != temp1) {
			ql_log(ql_log_warn, vha, 0xb005,
			    "%s: Written OCMwin (0x%x) != Read OCMwin (0x%x).\n",
			    __func__, temp1, win_read);
		}
		addr = GET_MEM_OFFS_2M(addr) + QLA82XX_PCI_OCM0_2M;

	} else if (QLA82XX_ADDR_IN_RANGE(addr, QLA82XX_ADDR_QDR_NET,
		QLA82XX_P3_ADDR_QDR_NET_MAX)) {
		/* QDR network side */
		window = MS_WIN(addr);
		ha->qdr_sn_window = window;
		qla82xx_wr_32(ha,
			ha->ms_win_crb | QLA82XX_PCI_CRBSPACE, window);
		win_read = qla82xx_rd_32(ha,
			ha->ms_win_crb | QLA82XX_PCI_CRBSPACE);
		if (win_read != window) {
			ql_log(ql_log_warn, vha, 0xb006,
			    "%s: Written MSwin (0x%x) != Read MSwin (0x%x).\n",
			    __func__, window, win_read);
		}
		addr = GET_MEM_OFFS_2M(addr) + QLA82XX_PCI_QDR_NET;
	} else {
		/*
		 * peg gdb frequently accesses memory that doesn't exist,
		 * this limits the chit chat so debugging isn't slowed down.
		 */
		if ((qla82xx_pci_set_window_warning_count++ < 8) ||
		    (qla82xx_pci_set_window_warning_count%64 == 0)) {
			ql_log(ql_log_warn, vha, 0xb007,
			    "%s: Warning:%s Unknown address range!.\n",
			    __func__, QLA2XXX_DRIVER_NAME);
		}
		addr = -1UL;
	}
	return addr;
}

/* check if address is in the same windows as the previous access */
static int qla82xx_pci_is_same_window(struct qla_hw_data *ha,
	unsigned long long addr)
{
	int			window;
	unsigned long long	qdr_max;

	qdr_max = QLA82XX_P3_ADDR_QDR_NET_MAX;

	/* DDR network side */
	if (QLA82XX_ADDR_IN_RANGE(addr, QLA82XX_ADDR_DDR_NET,
		QLA82XX_ADDR_DDR_NET_MAX))
		BUG();
	else if (QLA82XX_ADDR_IN_RANGE(addr, QLA82XX_ADDR_OCM0,
		QLA82XX_ADDR_OCM0_MAX))
		return 1;
	else if (QLA82XX_ADDR_IN_RANGE(addr, QLA82XX_ADDR_OCM1,
		QLA82XX_ADDR_OCM1_MAX))
		return 1;
	else if (QLA82XX_ADDR_IN_RANGE(addr, QLA82XX_ADDR_QDR_NET, qdr_max)) {
		/* QDR network side */
		window = ((addr - QLA82XX_ADDR_QDR_NET) >> 22) & 0x3f;
		if (ha->qdr_sn_window == window)
			return 1;
	}
	return 0;
}

static int qla82xx_pci_mem_read_direct(struct qla_hw_data *ha,
	u64 off, void *data, int size)
{
	unsigned long   flags;
	void           *addr = NULL;
	int             ret = 0;
	u64             start;
	uint8_t         *mem_ptr = NULL;
	unsigned long   mem_base;
	unsigned long   mem_page;
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);

	write_lock_irqsave(&ha->hw_lock, flags);

	/*
	 * If attempting to access unknown address or straddle hw windows,
	 * do not access.
	 */
	start = qla82xx_pci_set_window(ha, off);
	if ((start == -1UL) ||
		(qla82xx_pci_is_same_window(ha, off + size - 1) == 0)) {
		write_unlock_irqrestore(&ha->hw_lock, flags);
		ql_log(ql_log_fatal, vha, 0xb008,
		    "%s out of bound pci memory "
		    "access, offset is 0x%llx.\n",
		    QLA2XXX_DRIVER_NAME, off);
		return -1;
	}

	write_unlock_irqrestore(&ha->hw_lock, flags);
	mem_base = pci_resource_start(ha->pdev, 0);
	mem_page = start & PAGE_MASK;
	/* Map two pages whenever user tries to access addresses in two
	* consecutive pages.
	*/
	if (mem_page != ((start + size - 1) & PAGE_MASK))
		mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2);
	else
		mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
	if (mem_ptr == 0UL) {
		*(u8  *)data = 0;
		return -1;
	}
	addr = mem_ptr;
	addr += start & (PAGE_SIZE - 1);
	write_lock_irqsave(&ha->hw_lock, flags);

	switch (size) {
	case 1:
		*(u8  *)data = readb(addr);
		break;
	case 2:
		*(u16 *)data = readw(addr);
		break;
	case 4:
		*(u32 *)data = readl(addr);
		break;
	case 8:
		*(u64 *)data = readq(addr);
		break;
	default:
		ret = -1;
		break;
	}
	write_unlock_irqrestore(&ha->hw_lock, flags);

	if (mem_ptr)
		iounmap(mem_ptr);
	return ret;
}

static int
qla82xx_pci_mem_write_direct(struct qla_hw_data *ha,
	u64 off, void *data, int size)
{
	unsigned long   flags;
	void           *addr = NULL;
	int             ret = 0;
	u64             start;
	uint8_t         *mem_ptr = NULL;
	unsigned long   mem_base;
	unsigned long   mem_page;
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);

	write_lock_irqsave(&ha->hw_lock, flags);

	/*
	 * If attempting to access unknown address or straddle hw windows,
	 * do not access.
	 */
	start = qla82xx_pci_set_window(ha, off);
	if ((start == -1UL) ||
		(qla82xx_pci_is_same_window(ha, off + size - 1) == 0)) {
		write_unlock_irqrestore(&ha->hw_lock, flags);
		ql_log(ql_log_fatal, vha, 0xb009,
		    "%s out of bount memory "
		    "access, offset is 0x%llx.\n",
		    QLA2XXX_DRIVER_NAME, off);
		return -1;
	}

	write_unlock_irqrestore(&ha->hw_lock, flags);
	mem_base = pci_resource_start(ha->pdev, 0);
	mem_page = start & PAGE_MASK;
	/* Map two pages whenever user tries to access addresses in two
	 * consecutive pages.
	 */
	if (mem_page != ((start + size - 1) & PAGE_MASK))
		mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE*2);
	else
		mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
	if (mem_ptr == 0UL)
		return -1;

	addr = mem_ptr;
	addr += start & (PAGE_SIZE - 1);
	write_lock_irqsave(&ha->hw_lock, flags);

	switch (size) {
	case 1:
		writeb(*(u8  *)data, addr);
		break;
	case 2:
		writew(*(u16 *)data, addr);
		break;
	case 4:
		writel(*(u32 *)data, addr);
		break;
	case 8:
		writeq(*(u64 *)data, addr);
		break;
	default:
		ret = -1;
		break;
	}
	write_unlock_irqrestore(&ha->hw_lock, flags);
	if (mem_ptr)
		iounmap(mem_ptr);
	return ret;
}

#define MTU_FUDGE_FACTOR 100
static unsigned long
qla82xx_decode_crb_addr(unsigned long addr)
{
	int i;
	unsigned long base_addr, offset, pci_base;

	if (!qla82xx_crb_table_initialized)
		qla82xx_crb_addr_transform_setup();

	pci_base = ADDR_ERROR;
	base_addr = addr & 0xfff00000;
	offset = addr & 0x000fffff;

	for (i = 0; i < MAX_CRB_XFORM; i++) {
		if (crb_addr_xform[i] == base_addr) {
			pci_base = i << 20;
			break;
		}
	}
	if (pci_base == ADDR_ERROR)
		return pci_base;
	return pci_base + offset;
}

static long rom_max_timeout = 100;
static long qla82xx_rom_lock_timeout = 100;

static int
qla82xx_rom_lock(struct qla_hw_data *ha)
{
	int done = 0, timeout = 0;

	while (!done) {
		/* acquire semaphore2 from PCI HW block */
		done = qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_LOCK));
		if (done == 1)
			break;
		if (timeout >= qla82xx_rom_lock_timeout)
			return -1;
		timeout++;
	}
	qla82xx_wr_32(ha, QLA82XX_ROM_LOCK_ID, ROM_LOCK_DRIVER);
	return 0;
}

static void
qla82xx_rom_unlock(struct qla_hw_data *ha)
{
	qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK));
}

static int
qla82xx_wait_rom_busy(struct qla_hw_data *ha)
{
	long timeout = 0;
	long done = 0 ;
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);

	while (done == 0) {
		done = qla82xx_rd_32(ha, QLA82XX_ROMUSB_GLB_STATUS);
		done &= 4;
		timeout++;
		if (timeout >= rom_max_timeout) {
			ql_dbg(ql_dbg_p3p, vha, 0xb00a,
			    "%s: Timeout reached waiting for rom busy.\n",
			    QLA2XXX_DRIVER_NAME);
			return -1;
		}
	}
	return 0;
}

static int
qla82xx_wait_rom_done(struct qla_hw_data *ha)
{
	long timeout = 0;
	long done = 0 ;
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);

	while (done == 0) {
		done = qla82xx_rd_32(ha, QLA82XX_ROMUSB_GLB_STATUS);
		done &= 2;
		timeout++;
		if (timeout >= rom_max_timeout) {
			ql_dbg(ql_dbg_p3p, vha, 0xb00b,
			    "%s: Timeout reached waiting for rom done.\n",
			    QLA2XXX_DRIVER_NAME);
			return -1;
		}
	}
	return 0;
}

static int
qla82xx_do_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp)
{
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);

	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ADDRESS, addr);
	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 3);
	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, 0xb);
	qla82xx_wait_rom_busy(ha);
	if (qla82xx_wait_rom_done(ha)) {
		ql_log(ql_log_fatal, vha, 0x00ba,
		    "Error waiting for rom done.\n");
		return -1;
	}
	/* Reset abyte_cnt and dummy_byte_cnt */
	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
	udelay(10);
	cond_resched();
	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 0);
	*valp = qla82xx_rd_32(ha, QLA82XX_ROMUSB_ROM_RDATA);
	return 0;
}

static int
qla82xx_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp)
{
	int ret, loops = 0;
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);

	while ((qla82xx_rom_lock(ha) != 0) && (loops < 50000)) {
		udelay(100);
		schedule();
		loops++;
	}
	if (loops >= 50000) {
		ql_log(ql_log_fatal, vha, 0x00b9,
		    "Failed to aquire SEM2 lock.\n");
		return -1;
	}
	ret = qla82xx_do_rom_fast_read(ha, addr, valp);
	qla82xx_rom_unlock(ha);
	return ret;
}

static int
qla82xx_read_status_reg(struct qla_hw_data *ha, uint32_t *val)
{
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_RDSR);
	qla82xx_wait_rom_busy(ha);
	if (qla82xx_wait_rom_done(ha)) {
		ql_log(ql_log_warn, vha, 0xb00c,
		    "Error waiting for rom done.\n");
		return -1;
	}
	*val = qla82xx_rd_32(ha, QLA82XX_ROMUSB_ROM_RDATA);
	return 0;
}

static int
qla82xx_flash_wait_write_finish(struct qla_hw_data *ha)
{
	long timeout = 0;
	uint32_t done = 1 ;
	uint32_t val;
	int ret = 0;
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);

	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 0);
	while ((done != 0) && (ret == 0)) {
		ret = qla82xx_read_status_reg(ha, &val);
		done = val & 1;
		timeout++;
		udelay(10);
		cond_resched();
		if (timeout >= 50000) {
			ql_log(ql_log_warn, vha, 0xb00d,
			    "Timeout reached waiting for write finish.\n");
			return -1;
		}
	}
	return ret;
}

static int
qla82xx_flash_set_write_enable(struct qla_hw_data *ha)
{
	uint32_t val;
	qla82xx_wait_rom_busy(ha);
	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 0);
	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_WREN);
	qla82xx_wait_rom_busy(ha);
	if (qla82xx_wait_rom_done(ha))
		return -1;
	if (qla82xx_read_status_reg(ha, &val) != 0)
		return -1;
	if ((val & 2) != 2)
		return -1;
	return 0;
}

static int
qla82xx_write_status_reg(struct qla_hw_data *ha, uint32_t val)
{
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
	if (qla82xx_flash_set_write_enable(ha))
		return -1;
	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_WDATA, val);
	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, 0x1);
	if (qla82xx_wait_rom_done(ha)) {
		ql_log(ql_log_warn, vha, 0xb00e,
		    "Error waiting for rom done.\n");
		return -1;
	}
	return qla82xx_flash_wait_write_finish(ha);
}

static int
qla82xx_write_disable_flash(struct qla_hw_data *ha)
{
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_WRDI);
	if (qla82xx_wait_rom_done(ha)) {
		ql_log(ql_log_warn, vha, 0xb00f,
		    "Error waiting for rom done.\n");
		return -1;
	}
	return 0;
}

static int
ql82xx_rom_lock_d(struct qla_hw_data *ha)
{
	int loops = 0;
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);

	while ((qla82xx_rom_lock(ha) != 0) && (loops < 50000)) {
		udelay(100);
		cond_resched();
		loops++;
	}
	if (loops >= 50000) {
		ql_log(ql_log_warn, vha, 0xb010,
		    "ROM lock failed.\n");
		return -1;
	}
	return 0;
}

static int
qla82xx_write_flash_dword(struct qla_hw_data *ha, uint32_t flashaddr,
	uint32_t data)
{
	int ret = 0;
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);

	ret = ql82xx_rom_lock_d(ha);
	if (ret < 0) {
		ql_log(ql_log_warn, vha, 0xb011,
		    "ROM lock failed.\n");
		return ret;
	}

	if (qla82xx_flash_set_write_enable(ha))
		goto done_write;

	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_WDATA, data);
	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ADDRESS, flashaddr);
	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 3);
	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_PP);
	qla82xx_wait_rom_busy(ha);
	if (qla82xx_wait_rom_done(ha)) {
		ql_log(ql_log_warn, vha, 0xb012,
		    "Error waiting for rom done.\n");
		ret = -1;
		goto done_write;
	}

	ret = qla82xx_flash_wait_write_finish(ha);

done_write:
	qla82xx_rom_unlock(ha);
	return ret;
}

/* This routine does CRB initialize sequence
 *  to put the ISP into operational state
 */
static int
qla82xx_pinit_from_rom(scsi_qla_host_t *vha)
{
	int addr, val;
	int i ;
	struct crb_addr_pair *buf;
	unsigned long off;
	unsigned offset, n;
	struct qla_hw_data *ha = vha->hw;

	struct crb_addr_pair {
		long addr;
		long data;
	};

	/* Halt all the indiviual PEGs and other blocks of the ISP */
	qla82xx_rom_lock(ha);

	/* disable all I2Q */
	qla82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x10, 0x0);
	qla82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x14, 0x0);
	qla82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x18, 0x0);
	qla82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x1c, 0x0);
	qla82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x20, 0x0);
	qla82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x24, 0x0);

	/* disable all niu interrupts */
	qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x40, 0xff);
	/* disable xge rx/tx */
	qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x70000, 0x00);
	/* disable xg1 rx/tx */
	qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x80000, 0x00);
	/* disable sideband mac */
	qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x90000, 0x00);
	/* disable ap0 mac */
	qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0xa0000, 0x00);
	/* disable ap1 mac */
	qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0xb0000, 0x00);

	/* halt sre */
	val = qla82xx_rd_32(ha, QLA82XX_CRB_SRE + 0x1000);
	qla82xx_wr_32(ha, QLA82XX_CRB_SRE + 0x1000, val & (~(0x1)));

	/* halt epg */
	qla82xx_wr_32(ha, QLA82XX_CRB_EPG + 0x1300, 0x1);

	/* halt timers */
	qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x0, 0x0);
	qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x8, 0x0);
	qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x10, 0x0);
	qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x18, 0x0);
	qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x100, 0x0);
	qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x200, 0x0);

	/* halt pegs */
	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x3c, 1);
	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_1 + 0x3c, 1);
	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_2 + 0x3c, 1);
	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_3 + 0x3c, 1);
	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_4 + 0x3c, 1);
	msleep(20);

	/* big hammer */
	if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
		/* don't reset CAM block on reset */
		qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xfeffffff);
	else
		qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xffffffff);

	/* reset ms */
	val = qla82xx_rd_32(ha, QLA82XX_CRB_QDR_NET + 0xe4);
	val |= (1 << 1);
	qla82xx_wr_32(ha, QLA82XX_CRB_QDR_NET + 0xe4, val);
	msleep(20);

	/* unreset ms */
	val = qla82xx_rd_32(ha, QLA82XX_CRB_QDR_NET + 0xe4);
	val &= ~(1 << 1);
	qla82xx_wr_32(ha, QLA82XX_CRB_QDR_NET + 0xe4, val);
	msleep(20);

	qla82xx_rom_unlock(ha);

	/* Read the signature value from the flash.
	 * Offset 0: Contain signature (0xcafecafe)
	 * Offset 4: Offset and number of addr/value pairs
	 * that present in CRB initialize sequence
	 */
	if (qla82xx_rom_fast_read(ha, 0, &n) != 0 || n != 0xcafecafeUL ||
	    qla82xx_rom_fast_read(ha, 4, &n) != 0) {
		ql_log(ql_log_fatal, vha, 0x006e,
		    "Error Reading crb_init area: n: %08x.\n", n);
		return -1;
	}

	/* Offset in flash = lower 16 bits
	 * Number of enteries = upper 16 bits
	 */
	offset = n & 0xffffU;
	n = (n >> 16) & 0xffffU;

	/* number of addr/value pair should not exceed 1024 enteries */
	if (n  >= 1024) {
		ql_log(ql_log_fatal, vha, 0x0071,
		    "Card flash not initialized:n=0x%x.\n", n);
		return -1;
	}

	ql_log(ql_log_info, vha, 0x0072,
	    "%d CRB init values found in ROM.\n", n);

	buf = kmalloc(n * sizeof(struct crb_addr_pair), GFP_KERNEL);
	if (buf == NULL) {
		ql_log(ql_log_fatal, vha, 0x010c,
		    "Unable to allocate memory.\n");
		return -1;
	}

	for (i = 0; i < n; i++) {
		if (qla82xx_rom_fast_read(ha, 8*i + 4*offset, &val) != 0 ||
		    qla82xx_rom_fast_read(ha, 8*i + 4*offset + 4, &addr) != 0) {
			kfree(buf);
			return -1;
		}

		buf[i].addr = addr;
		buf[i].data = val;
	}

	for (i = 0; i < n; i++) {
		/* Translate internal CRB initialization
		 * address to PCI bus address
		 */
		off = qla82xx_decode_crb_addr((unsigned long)buf[i].addr) +
		    QLA82XX_PCI_CRBSPACE;
		/* Not all CRB  addr/value pair to be written,
		 * some of them are skipped
		 */

		/* skipping cold reboot MAGIC */
		if (off == QLA82XX_CAM_RAM(0x1fc))
			continue;

		/* do not reset PCI */
		if (off == (ROMUSB_GLB + 0xbc))
			continue;

		/* skip core clock, so that firmware can increase the clock */
		if (off == (ROMUSB_GLB + 0xc8))
			continue;

		/* skip the function enable register */
		if (off == QLA82XX_PCIE_REG(PCIE_SETUP_FUNCTION))
			continue;

		if (off == QLA82XX_PCIE_REG(PCIE_SETUP_FUNCTION2))
			continue;

		if ((off & 0x0ff00000) == QLA82XX_CRB_SMB)
			continue;

		if ((off & 0x0ff00000) == QLA82XX_CRB_DDR_NET)
			continue;

		if (off == ADDR_ERROR) {
			ql_log(ql_log_fatal, vha, 0x0116,
			    "Unknow addr: 0x%08lx.\n", buf[i].addr);
			continue;
		}

		qla82xx_wr_32(ha, off, buf[i].data);

		/* ISP requires much bigger delay to settle down,
		 * else crb_window returns 0xffffffff
		 */
		if (off == QLA82XX_ROMUSB_GLB_SW_RESET)
			msleep(1000);

		/* ISP requires millisec delay between
		 * successive CRB register updation
		 */
		msleep(1);
	}

	kfree(buf);

	/* Resetting the data and instruction cache */
	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_D+0xec, 0x1e);
	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_D+0x4c, 8);
	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_I+0x4c, 8);

	/* Clear all protocol processing engines */
	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0+0x8, 0);
	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0+0xc, 0);
	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_1+0x8, 0);
	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_1+0xc, 0);
	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_2+0x8, 0);
	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_2+0xc, 0);
	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_3+0x8, 0);
	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_3+0xc, 0);
	return 0;
}

static int
qla82xx_pci_mem_write_2M(struct qla_hw_data *ha,
		u64 off, void *data, int size)
{
	int i, j, ret = 0, loop, sz[2], off0;
	int scale, shift_amount, startword;
	uint32_t temp;
	uint64_t off8, mem_crb, tmpw, word[2] = {0, 0};

	/*
	 * If not MN, go check for MS or invalid.
	 */
	if (off >= QLA82XX_ADDR_QDR_NET && off <= QLA82XX_P3_ADDR_QDR_NET_MAX)
		mem_crb = QLA82XX_CRB_QDR_NET;
	else {
		mem_crb = QLA82XX_CRB_DDR_NET;
		if (qla82xx_pci_mem_bound_check(ha, off, size) == 0)
			return qla82xx_pci_mem_write_direct(ha,
			    off, data, size);
	}

	off0 = off & 0x7;
	sz[0] = (size < (8 - off0)) ? size : (8 - off0);
	sz[1] = size - sz[0];

	off8 = off & 0xfffffff0;
	loop = (((off & 0xf) + size - 1) >> 4) + 1;
	shift_amount = 4;
	scale = 2;
	startword = (off & 0xf)/8;

	for (i = 0; i < loop; i++) {
		if (qla82xx_pci_mem_read_2M(ha, off8 +
		    (i << shift_amount), &word[i * scale], 8))
			return -1;
	}

	switch (size) {
	case 1:
		tmpw = *((uint8_t *)data);
		break;
	case 2:
		tmpw = *((uint16_t *)data);
		break;
	case 4:
		tmpw = *((uint32_t *)data);
		break;
	case 8:
	default:
		tmpw = *((uint64_t *)data);
		break;
	}

	if (sz[0] == 8) {
		word[startword] = tmpw;
	} else {
		word[startword] &=
			~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
		word[startword] |= tmpw << (off0 * 8);
	}
	if (sz[1] != 0) {
		word[startword+1] &= ~(~0ULL << (sz[1] * 8));
		word[startword+1] |= tmpw >> (sz[0] * 8);
	}

	for (i = 0; i < loop; i++) {
		temp = off8 + (i << shift_amount);
		qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_ADDR_LO, temp);
		temp = 0;
		qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_ADDR_HI, temp);
		temp = word[i * scale] & 0xffffffff;
		qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_WRDATA_LO, temp);
		temp = (word[i * scale] >> 32) & 0xffffffff;
		qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_WRDATA_HI, temp);
		temp = word[i*scale + 1] & 0xffffffff;
		qla82xx_wr_32(ha, mem_crb +
		    MIU_TEST_AGT_WRDATA_UPPER_LO, temp);
		temp = (word[i*scale + 1] >> 32) & 0xffffffff;
		qla82xx_wr_32(ha, mem_crb +
		    MIU_TEST_AGT_WRDATA_UPPER_HI, temp);

		temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
		qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
		temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
		qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);

		for (j = 0; j < MAX_CTL_CHECK; j++) {
			temp = qla82xx_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL);
			if ((temp & MIU_TA_CTL_BUSY) == 0)
				break;
		}

		if (j >= MAX_CTL_CHECK) {
			if (printk_ratelimit())
				dev_err(&ha->pdev->dev,
				    "failed to write through agent.\n");
			ret = -1;
			break;
		}
	}

	return ret;
}

static int
qla82xx_fw_load_from_flash(struct qla_hw_data *ha)
{
	int  i;
	long size = 0;
	long flashaddr = ha->flt_region_bootload << 2;
	long memaddr = BOOTLD_START;
	u64 data;
	u32 high, low;
	size = (IMAGE_START - BOOTLD_START) / 8;

	for (i = 0; i < size; i++) {
		if ((qla82xx_rom_fast_read(ha, flashaddr, (int *)&low)) ||
		    (qla82xx_rom_fast_read(ha, flashaddr + 4, (int *)&high))) {
			return -1;
		}
		data = ((u64)high << 32) | low ;
		qla82xx_pci_mem_write_2M(ha, memaddr, &data, 8);
		flashaddr += 8;
		memaddr += 8;

		if (i % 0x1000 == 0)
			msleep(1);
	}
	udelay(100);
	read_lock(&ha->hw_lock);
	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x18, 0x1020);
	qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0x80001e);
	read_unlock(&ha->hw_lock);
	return 0;
}

int
qla82xx_pci_mem_read_2M(struct qla_hw_data *ha,
		u64 off, void *data, int size)
{
	int i, j = 0, k, start, end, loop, sz[2], off0[2];
	int	      shift_amount;
	uint32_t      temp;
	uint64_t      off8, val, mem_crb, word[2] = {0, 0};

	/*
	 * If not MN, go check for MS or invalid.
	 */

	if (off >= QLA82XX_ADDR_QDR_NET && off <= QLA82XX_P3_ADDR_QDR_NET_MAX)
		mem_crb = QLA82XX_CRB_QDR_NET;
	else {
		mem_crb = QLA82XX_CRB_DDR_NET;
		if (qla82xx_pci_mem_bound_check(ha, off, size) == 0)
			return qla82xx_pci_mem_read_direct(ha,
			    off, data, size);
	}

	off8 = off & 0xfffffff0;
	off0[0] = off & 0xf;
	sz[0] = (size < (16 - off0[0])) ? size : (16 - off0[0]);
	shift_amount = 4;
	loop = ((off0[0] + size - 1) >> shift_amount) + 1;
	off0[1] = 0;
	sz[1] = size - sz[0];

	for (i = 0; i < loop; i++) {
		temp = off8 + (i << shift_amount);
		qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
		temp = 0;
		qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
		temp = MIU_TA_CTL_ENABLE;
		qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
		temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
		qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);

		for (j = 0; j < MAX_CTL_CHECK; j++) {
			temp = qla82xx_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL);
			if ((temp & MIU_TA_CTL_BUSY) == 0)
				break;
		}

		if (j >= MAX_CTL_CHECK) {
			if (printk_ratelimit())
				dev_err(&ha->pdev->dev,
				    "failed to read through agent.\n");
			break;
		}

		start = off0[i] >> 2;
		end   = (off0[i] + sz[i] - 1) >> 2;
		for (k = start; k <= end; k++) {
			temp = qla82xx_rd_32(ha,
					mem_crb + MIU_TEST_AGT_RDDATA(k));
			word[i] |= ((uint64_t)temp << (32 * (k & 1)));
		}
	}

	if (j >= MAX_CTL_CHECK)
		return -1;

	if ((off0[0] & 7) == 0) {
		val = word[0];
	} else {
		val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
			((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
	}

	switch (size) {
	case 1:
		*(uint8_t  *)data = val;
		break;
	case 2:
		*(uint16_t *)data = val;
		break;
	case 4:
		*(uint32_t *)data = val;
		break;
	case 8:
		*(uint64_t *)data = val;
		break;
	}
	return 0;
}


static struct qla82xx_uri_table_desc *
qla82xx_get_table_desc(const u8 *unirom, int section)
{
	uint32_t i;
	struct qla82xx_uri_table_desc *directory =
		(struct qla82xx_uri_table_desc *)&unirom[0];
	__le32 offset;
	__le32 tab_type;
	__le32 entries = cpu_to_le32(directory->num_entries);

	for (i = 0; i < entries; i++) {
		offset = cpu_to_le32(directory->findex) +
		    (i * cpu_to_le32(directory->entry_size));
		tab_type = cpu_to_le32(*((u32 *)&unirom[offset] + 8));

		if (tab_type == section)
			return (struct qla82xx_uri_table_desc *)&unirom[offset];
	}

	return NULL;
}

static struct qla82xx_uri_data_desc *
qla82xx_get_data_desc(struct qla_hw_data *ha,
	u32 section, u32 idx_offset)
{
	const u8 *unirom = ha->hablob->fw->data;
	int idx = cpu_to_le32(*((int *)&unirom[ha->file_prd_off] + idx_offset));
	struct qla82xx_uri_table_desc *tab_desc = NULL;
	__le32 offset;

	tab_desc = qla82xx_get_table_desc(unirom, section);
	if (!tab_desc)
		return NULL;

	offset = cpu_to_le32(tab_desc->findex) +
	    (cpu_to_le32(tab_desc->entry_size) * idx);

	return (struct qla82xx_uri_data_desc *)&unirom[offset];
}

static u8 *
qla82xx_get_bootld_offset(struct qla_hw_data *ha)
{
	u32 offset = BOOTLD_START;
	struct qla82xx_uri_data_desc *uri_desc = NULL;

	if (ha->fw_type == QLA82XX_UNIFIED_ROMIMAGE) {
		uri_desc = qla82xx_get_data_desc(ha,
		    QLA82XX_URI_DIR_SECT_BOOTLD, QLA82XX_URI_BOOTLD_IDX_OFF);
		if (uri_desc)
			offset = cpu_to_le32(uri_desc->findex);
	}

	return (u8 *)&ha->hablob->fw->data[offset];
}

static __le32
qla82xx_get_fw_size(struct qla_hw_data *ha)
{
	struct qla82xx_uri_data_desc *uri_desc = NULL;

	if (ha->fw_type == QLA82XX_UNIFIED_ROMIMAGE) {
		uri_desc =  qla82xx_get_data_desc(ha, QLA82XX_URI_DIR_SECT_FW,
		    QLA82XX_URI_FIRMWARE_IDX_OFF);
		if (uri_desc)
			return cpu_to_le32(uri_desc->size);
	}

	return cpu_to_le32(*(u32 *)&ha->hablob->fw->data[FW_SIZE_OFFSET]);
}

static u8 *
qla82xx_get_fw_offs(struct qla_hw_data *ha)
{
	u32 offset = IMAGE_START;
	struct qla82xx_uri_data_desc *uri_desc = NULL;

	if (ha->fw_type == QLA82XX_UNIFIED_ROMIMAGE) {
		uri_desc = qla82xx_get_data_desc(ha, QLA82XX_URI_DIR_SECT_FW,
			QLA82XX_URI_FIRMWARE_IDX_OFF);
		if (uri_desc)
			offset = cpu_to_le32(uri_desc->findex);
	}

	return (u8 *)&ha->hablob->fw->data[offset];
}

/* PCI related functions */
char *
qla82xx_pci_info_str(struct scsi_qla_host *vha, char *str)
{
	int pcie_reg;
	struct qla_hw_data *ha = vha->hw;
	char lwstr[6];
	uint16_t lnk;

	pcie_reg = pci_find_capability(ha->pdev, PCI_CAP_ID_EXP);
	pci_read_config_word(ha->pdev, pcie_reg + PCI_EXP_LNKSTA, &lnk);
	ha->link_width = (lnk >> 4) & 0x3f;

	strcpy(str, "PCIe (");
	strcat(str, "2.5Gb/s ");
	snprintf(lwstr, sizeof(lwstr), "x%d)", ha->link_width);
	strcat(str, lwstr);
	return str;
}

int qla82xx_pci_region_offset(struct pci_dev *pdev, int region)
{
	unsigned long val = 0;
	u32 control;

	switch (region) {
	case 0:
		val = 0;
		break;
	case 1:
		pci_read_config_dword(pdev, QLA82XX_PCI_REG_MSIX_TBL, &control);
		val = control + QLA82XX_MSIX_TBL_SPACE;
		break;
	}
	return val;
}


int
qla82xx_iospace_config(struct qla_hw_data *ha)
{
	uint32_t len = 0;

	if (pci_request_regions(ha->pdev, QLA2XXX_DRIVER_NAME)) {
		ql_log_pci(ql_log_fatal, ha->pdev, 0x000c,
		    "Failed to reserver selected regions.\n");
		goto iospace_error_exit;
	}

	/* Use MMIO operations for all accesses. */
	if (!(pci_resource_flags(ha->pdev, 0) & IORESOURCE_MEM)) {
		ql_log_pci(ql_log_fatal, ha->pdev, 0x000d,
		    "Region #0 not an MMIO resource, aborting.\n");
		goto iospace_error_exit;
	}

	len = pci_resource_len(ha->pdev, 0);
	ha->nx_pcibase =
	    (unsigned long)ioremap(pci_resource_start(ha->pdev, 0), len);
	if (!ha->nx_pcibase) {
		ql_log_pci(ql_log_fatal, ha->pdev, 0x000e,
		    "Cannot remap pcibase MMIO, aborting.\n");
		pci_release_regions(ha->pdev);
		goto iospace_error_exit;
	}

	/* Mapping of IO base pointer */
	ha->iobase = (device_reg_t __iomem *)((uint8_t *)ha->nx_pcibase +
	    0xbc000 + (ha->pdev->devfn << 11));

	if (!ql2xdbwr) {
		ha->nxdb_wr_ptr =
		    (unsigned long)ioremap((pci_resource_start(ha->pdev, 4) +
		    (ha->pdev->devfn << 12)), 4);
		if (!ha->nxdb_wr_ptr) {
			ql_log_pci(ql_log_fatal, ha->pdev, 0x000f,
			    "Cannot remap MMIO, aborting.\n");
			pci_release_regions(ha->pdev);
			goto iospace_error_exit;
		}

		/* Mapping of IO base pointer,
		 * door bell read and write pointer
		 */
		ha->nxdb_rd_ptr = (uint8_t *) ha->nx_pcibase + (512 * 1024) +
		    (ha->pdev->devfn * 8);
	} else {
		ha->nxdb_wr_ptr = (ha->pdev->devfn == 6 ?
			QLA82XX_CAMRAM_DB1 :
			QLA82XX_CAMRAM_DB2);
	}

	ha->max_req_queues = ha->max_rsp_queues = 1;
	ha->msix_count = ha->max_rsp_queues + 1;
	ql_dbg_pci(ql_dbg_multiq, ha->pdev, 0xc006,
	    "nx_pci_base=%p iobase=%p "
	    "max_req_queues=%d msix_count=%d.\n",
	    (void *)ha->nx_pcibase, ha->iobase,
	    ha->max_req_queues, ha->msix_count);
	ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0010,
	    "nx_pci_base=%p iobase=%p "
	    "max_req_queues=%d msix_count=%d.\n",
	    (void *)ha->nx_pcibase, ha->iobase,
	    ha->max_req_queues, ha->msix_count);
	return 0;

iospace_error_exit:
	return -ENOMEM;
}

/* GS related functions */

/* Initialization related functions */

/**
 * qla82xx_pci_config() - Setup ISP82xx PCI configuration registers.
 * @ha: HA context
 *
 * Returns 0 on success.
*/
int
qla82xx_pci_config(scsi_qla_host_t *vha)
{
	struct qla_hw_data *ha = vha->hw;
	int ret;

	pci_set_master(ha->pdev);
	ret = pci_set_mwi(ha->pdev);
	ha->chip_revision = ha->pdev->revision;
	ql_dbg(ql_dbg_init, vha, 0x0043,
	    "Chip revision:%d.\n",
	    ha->chip_revision);
	return 0;
}

/**
 * qla82xx_reset_chip() - Setup ISP82xx PCI configuration registers.
 * @ha: HA context
 *
 * Returns 0 on success.
 */
void
qla82xx_reset_chip(scsi_qla_host_t *vha)
{
	struct qla_hw_data *ha = vha->hw;
	ha->isp_ops->disable_intrs(ha);
}

void qla82xx_config_rings(struct scsi_qla_host *vha)
{
	struct qla_hw_data *ha = vha->hw;
	struct device_reg_82xx __iomem *reg = &ha->iobase->isp82;
	struct init_cb_81xx *icb;
	struct req_que *req = ha->req_q_map[0];
	struct rsp_que *rsp = ha->rsp_q_map[0];

	/* Setup ring parameters in initialization control block. */
	icb = (struct init_cb_81xx *)ha->init_cb;
	icb->request_q_outpointer = __constant_cpu_to_le16(0);
	icb->response_q_inpointer = __constant_cpu_to_le16(0);
	icb->request_q_length = cpu_to_le16(req->length);
	icb->response_q_length = cpu_to_le16(rsp->length);
	icb->request_q_address[0] = cpu_to_le32(LSD(req->dma));
	icb->request_q_address[1] = cpu_to_le32(MSD(req->dma));
	icb->response_q_address[0] = cpu_to_le32(LSD(rsp->dma));
	icb->response_q_address[1] = cpu_to_le32(MSD(rsp->dma));

	WRT_REG_DWORD((unsigned long  __iomem *)&reg->req_q_out[0], 0);
	WRT_REG_DWORD((unsigned long  __iomem *)&reg->rsp_q_in[0], 0);
	WRT_REG_DWORD((unsigned long  __iomem *)&reg->rsp_q_out[0], 0);
}

void qla82xx_reset_adapter(struct scsi_qla_host *vha)
{
	struct qla_hw_data *ha = vha->hw;
	vha->flags.online = 0;
	qla2x00_try_to_stop_firmware(vha);
	ha->isp_ops->disable_intrs(ha);
}

static int
qla82xx_fw_load_from_blob(struct qla_hw_data *ha)
{
	u64 *ptr64;
	u32 i, flashaddr, size;
	__le64 data;

	size = (IMAGE_START - BOOTLD_START) / 8;

	ptr64 = (u64 *)qla82xx_get_bootld_offset(ha);
	flashaddr = BOOTLD_START;

	for (i = 0; i < size; i++) {
		data = cpu_to_le64(ptr64[i]);
		if (qla82xx_pci_mem_write_2M(ha, flashaddr, &data, 8))
			return -EIO;
		flashaddr += 8;
	}

	flashaddr = FLASH_ADDR_START;
	size = (__force u32)qla82xx_get_fw_size(ha) / 8;
	ptr64 = (u64 *)qla82xx_get_fw_offs(ha);

	for (i = 0; i < size; i++) {
		data = cpu_to_le64(ptr64[i]);

		if (qla82xx_pci_mem_write_2M(ha, flashaddr, &data, 8))
			return -EIO;
		flashaddr += 8;
	}
	udelay(100);

	/* Write a magic value to CAMRAM register
	 * at a specified offset to indicate
	 * that all data is written and
	 * ready for firmware to initialize.
	 */
	qla82xx_wr_32(ha, QLA82XX_CAM_RAM(0x1fc), QLA82XX_BDINFO_MAGIC);

	read_lock(&ha->hw_lock);
	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x18, 0x1020);
	qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0x80001e);
	read_unlock(&ha->hw_lock);
	return 0;
}

static int
qla82xx_set_product_offset(struct qla_hw_data *ha)
{
	struct qla82xx_uri_table_desc *ptab_desc = NULL;
	const uint8_t *unirom = ha->hablob->fw->data;
	uint32_t i;
	__le32 entries;
	__le32 flags, file_chiprev, offset;
	uint8_t chiprev = ha->chip_revision;
	/* Hardcoding mn_present flag for P3P */
	int mn_present = 0;
	uint32_t flagbit;

	ptab_desc = qla82xx_get_table_desc(unirom,
		 QLA82XX_URI_DIR_SECT_PRODUCT_TBL);
       if (!ptab_desc)
		return -1;

	entries = cpu_to_le32(ptab_desc->num_entries);

	for (i = 0; i < entries; i++) {
		offset = cpu_to_le32(ptab_desc->findex) +
			(i * cpu_to_le32(ptab_desc->entry_size));
		flags = cpu_to_le32(*((int *)&unirom[offset] +
			QLA82XX_URI_FLAGS_OFF));
		file_chiprev = cpu_to_le32(*((int *)&unirom[offset] +
			QLA82XX_URI_CHIP_REV_OFF));

		flagbit = mn_present ? 1 : 2;

		if ((chiprev == file_chiprev) && ((1ULL << flagbit) & flags)) {
			ha->file_prd_off = offset;
			return 0;
		}
	}
	return -1;
}

int
qla82xx_validate_firmware_blob(scsi_qla_host_t *vha, uint8_t fw_type)
{
	__le32 val;
	uint32_t min_size;
	struct qla_hw_data *ha = vha->hw;
	const struct firmware *fw = ha->hablob->fw;

	ha->fw_type = fw_type;

	if (fw_type == QLA82XX_UNIFIED_ROMIMAGE) {
		if (qla82xx_set_product_offset(ha))
			return -EINVAL;

		min_size = QLA82XX_URI_FW_MIN_SIZE;
	} else {
		val = cpu_to_le32(*(u32 *)&fw->data[QLA82XX_FW_MAGIC_OFFSET]);
		if ((__force u32)val != QLA82XX_BDINFO_MAGIC)
			return -EINVAL;

		min_size = QLA82XX_FW_MIN_SIZE;
	}

	if (fw->size < min_size)
		return -EINVAL;
	return 0;
}

static int
qla82xx_check_cmdpeg_state(struct qla_hw_data *ha)
{
	u32 val = 0;
	int retries = 60;
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);

	do {
		read_lock(&ha->hw_lock);
		val = qla82xx_rd_32(ha, CRB_CMDPEG_STATE);
		read_unlock(&ha->hw_lock);

		switch (val) {
		case PHAN_INITIALIZE_COMPLETE:
		case PHAN_INITIALIZE_ACK:
			return QLA_SUCCESS;
		case PHAN_INITIALIZE_FAILED:
			break;
		default:
			break;
		}
		ql_log(ql_log_info, vha, 0x00a8,
		    "CRB_CMDPEG_STATE: 0x%x and retries:0x%x.\n",
		    val, retries);

		msleep(500);

	} while (--retries);

	ql_log(ql_log_fatal, vha, 0x00a9,
	    "Cmd Peg initialization failed: 0x%x.\n", val);

	val = qla82xx_rd_32(ha, QLA82XX_ROMUSB_GLB_PEGTUNE_DONE);
	read_lock(&ha->hw_lock);
	qla82xx_wr_32(ha, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED);
	read_unlock(&ha->hw_lock);
	return QLA_FUNCTION_FAILED;
}

static int
qla82xx_check_rcvpeg_state(struct qla_hw_data *ha)
{
	u32 val = 0;
	int retries = 60;
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);

	do {
		read_lock(&ha->hw_lock);
		val = qla82xx_rd_32(ha, CRB_RCVPEG_STATE);
		read_unlock(&ha->hw_lock);

		switch (val) {
		case PHAN_INITIALIZE_COMPLETE:
		case PHAN_INITIALIZE_ACK:
			return QLA_SUCCESS;
		case PHAN_INITIALIZE_FAILED:
			break;
		default:
			break;
		}
		ql_log(ql_log_info, vha, 0x00ab,
		    "CRB_RCVPEG_STATE: 0x%x and retries: 0x%x.\n",
		    val, retries);

		msleep(500);

	} while (--retries);

	ql_log(ql_log_fatal, vha, 0x00ac,
	    "Rcv Peg initializatin failed: 0x%x.\n", val);
	read_lock(&ha->hw_lock);
	qla82xx_wr_32(ha, CRB_RCVPEG_STATE, PHAN_INITIALIZE_FAILED);
	read_unlock(&ha->hw_lock);
	return QLA_FUNCTION_FAILED;
}

/* ISR related functions */
uint32_t qla82xx_isr_int_target_mask_enable[8] = {
	ISR_INT_TARGET_MASK, ISR_INT_TARGET_MASK_F1,
	ISR_INT_TARGET_MASK_F2, ISR_INT_TARGET_MASK_F3,
	ISR_INT_TARGET_MASK_F4, ISR_INT_TARGET_MASK_F5,
	ISR_INT_TARGET_MASK_F7, ISR_INT_TARGET_MASK_F7
};

uint32_t qla82xx_isr_int_target_status[8] = {
	ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1,
	ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3,
	ISR_INT_TARGET_STATUS_F4, ISR_INT_TARGET_STATUS_F5,
	ISR_INT_TARGET_STATUS_F7, ISR_INT_TARGET_STATUS_F7
};

static struct qla82xx_legacy_intr_set legacy_intr[] = \
	QLA82XX_LEGACY_INTR_CONFIG;

/*
 * qla82xx_mbx_completion() - Process mailbox command completions.
 * @ha: SCSI driver HA context
 * @mb0: Mailbox0 register
 */
static void
qla82xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
{
	uint16_t	cnt;
	uint16_t __iomem *wptr;
	struct qla_hw_data *ha = vha->hw;
	struct device_reg_82xx __iomem *reg = &ha->iobase->isp82;
	wptr = (uint16_t __iomem *)&reg->mailbox_out[1];

	/* Load return mailbox registers. */
	ha->flags.mbox_int = 1;
	ha->mailbox_out[0] = mb0;

	for (cnt = 1; cnt < ha->mbx_count; cnt++) {
		ha->mailbox_out[cnt] = RD_REG_WORD(wptr);
		wptr++;
	}

	if (!ha->mcp)
		ql_dbg(ql_dbg_async, vha, 0x5053,
		    "MBX pointer ERROR.\n");
}

/*
 * qla82xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
 * @irq:
 * @dev_id: SCSI driver HA context
 * @regs:
 *
 * Called by system whenever the host adapter generates an interrupt.
 *
 * Returns handled flag.
 */
irqreturn_t
qla82xx_intr_handler(int irq, void *dev_id)
{
	scsi_qla_host_t	*vha;
	struct qla_hw_data *ha;
	struct rsp_que *rsp;
	struct device_reg_82xx __iomem *reg;
	int status = 0, status1 = 0;
	unsigned long	flags;
	unsigned long	iter;
	uint32_t	stat = 0;
	uint16_t	mb[4];

	rsp = (struct rsp_que *) dev_id;
	if (!rsp) {
		printk(KERN_INFO
			"%s(): NULL response queue pointer.\n", __func__);
		return IRQ_NONE;
	}
	ha = rsp->hw;

	if (!ha->flags.msi_enabled) {
		status = qla82xx_rd_32(ha, ISR_INT_VECTOR);
		if (!(status & ha->nx_legacy_intr.int_vec_bit))
			return IRQ_NONE;

		status1 = qla82xx_rd_32(ha, ISR_INT_STATE_REG);
		if (!ISR_IS_LEGACY_INTR_TRIGGERED(status1))
			return IRQ_NONE;
	}

	/* clear the interrupt */
	qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff);

	/* read twice to ensure write is flushed */
	qla82xx_rd_32(ha, ISR_INT_VECTOR);
	qla82xx_rd_32(ha, ISR_INT_VECTOR);

	reg = &ha->iobase->isp82;

	spin_lock_irqsave(&ha->hardware_lock, flags);
	vha = pci_get_drvdata(ha->pdev);
	for (iter = 1; iter--; ) {

		if (RD_REG_DWORD(&reg->host_int)) {
			stat = RD_REG_DWORD(&reg->host_status);

			switch (stat & 0xff) {
			case 0x1:
			case 0x2:
			case 0x10:
			case 0x11:
				qla82xx_mbx_completion(vha, MSW(stat));
				status |= MBX_INTERRUPT;
				break;
			case 0x12:
				mb[0] = MSW(stat);
				mb[1] = RD_REG_WORD(&reg->mailbox_out[1]);
				mb[2] = RD_REG_WORD(&reg->mailbox_out[2]);
				mb[3] = RD_REG_WORD(&reg->mailbox_out[3]);
				qla2x00_async_event(vha, rsp, mb);
				break;
			case 0x13:
				qla24xx_process_response_queue(vha, rsp);
				break;
			default:
				ql_dbg(ql_dbg_async, vha, 0x5054,
				    "Unrecognized interrupt type (%d).\n",
				    stat & 0xff);
				break;
			}
		}
		WRT_REG_DWORD(&reg->host_int, 0);
	}
	spin_unlock_irqrestore(&ha->hardware_lock, flags);
	if (!ha->flags.msi_enabled)
		qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);

#ifdef QL_DEBUG_LEVEL_17
	if (!irq && ha->flags.eeh_busy)
		ql_log(ql_log_warn, vha, 0x503d,
		    "isr:status %x, cmd_flags %lx, mbox_int %x, stat %x.\n",
		    status, ha->mbx_cmd_flags, ha->flags.mbox_int, stat);
#endif

	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
	    (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
		set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
		complete(&ha->mbx_intr_comp);
	}
	return IRQ_HANDLED;
}

irqreturn_t
qla82xx_msix_default(int irq, void *dev_id)
{
	scsi_qla_host_t	*vha;
	struct qla_hw_data *ha;
	struct rsp_que *rsp;
	struct device_reg_82xx __iomem *reg;
	int status = 0;
	unsigned long flags;
	uint32_t stat = 0;
	uint16_t mb[4];

	rsp = (struct rsp_que *) dev_id;
	if (!rsp) {
		printk(KERN_INFO
			"%s(): NULL response queue pointer.\n", __func__);
		return IRQ_NONE;
	}
	ha = rsp->hw;

	reg = &ha->iobase->isp82;

	spin_lock_irqsave(&ha->hardware_lock, flags);
	vha = pci_get_drvdata(ha->pdev);
	do {
		if (RD_REG_DWORD(&reg->host_int)) {
			stat = RD_REG_DWORD(&reg->host_status);

			switch (stat & 0xff) {
			case 0x1:
			case 0x2:
			case 0x10:
			case 0x11:
				qla82xx_mbx_completion(vha, MSW(stat));
				status |= MBX_INTERRUPT;
				break;
			case 0x12:
				mb[0] = MSW(stat);
				mb[1] = RD_REG_WORD(&reg->mailbox_out[1]);
				mb[2] = RD_REG_WORD(&reg->mailbox_out[2]);
				mb[3] = RD_REG_WORD(&reg->mailbox_out[3]);
				qla2x00_async_event(vha, rsp, mb);
				break;
			case 0x13:
				qla24xx_process_response_queue(vha, rsp);
				break;
			default:
				ql_dbg(ql_dbg_async, vha, 0x5041,
				    "Unrecognized interrupt type (%d).\n",
				    stat & 0xff);
				break;
			}
		}
		WRT_REG_DWORD(&reg->host_int, 0);
	} while (0);

	spin_unlock_irqrestore(&ha->hardware_lock, flags);

#ifdef QL_DEBUG_LEVEL_17
	if (!irq && ha->flags.eeh_busy)
		ql_log(ql_log_warn, vha, 0x5044,
		    "isr:status %x, cmd_flags %lx, mbox_int %x, stat %x.\n",
		    status, ha->mbx_cmd_flags, ha->flags.mbox_int, stat);
#endif

	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
		(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
			set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
			complete(&ha->mbx_intr_comp);
	}
	return IRQ_HANDLED;
}

irqreturn_t
qla82xx_msix_rsp_q(int irq, void *dev_id)
{
	scsi_qla_host_t	*vha;
	struct qla_hw_data *ha;
	struct rsp_que *rsp;
	struct device_reg_82xx __iomem *reg;
	unsigned long flags;

	rsp = (struct rsp_que *) dev_id;
	if (!rsp) {
		printk(KERN_INFO
			"%s(): NULL response queue pointer.\n", __func__);
		return IRQ_NONE;
	}

	ha = rsp->hw;
	reg = &ha->iobase->isp82;
	spin_lock_irqsave(&ha->hardware_lock, flags);
	vha = pci_get_drvdata(ha->pdev);
	qla24xx_process_response_queue(vha, rsp);
	WRT_REG_DWORD(&reg->host_int, 0);
	spin_unlock_irqrestore(&ha->hardware_lock, flags);
	return IRQ_HANDLED;
}

void
qla82xx_poll(int irq, void *dev_id)
{
	scsi_qla_host_t	*vha;
	struct qla_hw_data *ha;
	struct rsp_que *rsp;
	struct device_reg_82xx __iomem *reg;
	int status = 0;
	uint32_t stat;
	uint16_t mb[4];
	unsigned long flags;

	rsp = (struct rsp_que *) dev_id;
	if (!rsp) {
		printk(KERN_INFO
			"%s(): NULL response queue pointer.\n", __func__);
		return;
	}
	ha = rsp->hw;

	reg = &ha->iobase->isp82;
	spin_lock_irqsave(&ha->hardware_lock, flags);
	vha = pci_get_drvdata(ha->pdev);

	if (RD_REG_DWORD(&reg->host_int)) {
		stat = RD_REG_DWORD(&reg->host_status);
		switch (stat & 0xff) {
		case 0x1:
		case 0x2:
		case 0x10:
		case 0x11:
			qla82xx_mbx_completion(vha, MSW(stat));
			status |= MBX_INTERRUPT;
			break;
		case 0x12:
			mb[0] = MSW(stat);
			mb[1] = RD_REG_WORD(&reg->mailbox_out[1]);
			mb[2] = RD_REG_WORD(&reg->mailbox_out[2]);
			mb[3] = RD_REG_WORD(&reg->mailbox_out[3]);
			qla2x00_async_event(vha, rsp, mb);
			break;
		case 0x13:
			qla24xx_process_response_queue(vha, rsp);
			break;
		default:
			ql_dbg(ql_dbg_p3p, vha, 0xb013,
			    "Unrecognized interrupt type (%d).\n",
			    stat * 0xff);
			break;
		}
	}
	WRT_REG_DWORD(&reg->host_int, 0);
	spin_unlock_irqrestore(&ha->hardware_lock, flags);
}

void
qla82xx_enable_intrs(struct qla_hw_data *ha)
{
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
	qla82xx_mbx_intr_enable(vha);
	spin_lock_irq(&ha->hardware_lock);
	qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
	spin_unlock_irq(&ha->hardware_lock);
	ha->interrupts_on = 1;
}

void
qla82xx_disable_intrs(struct qla_hw_data *ha)
{
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
	qla82xx_mbx_intr_disable(vha);
	spin_lock_irq(&ha->hardware_lock);
	qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0x0400);
	spin_unlock_irq(&ha->hardware_lock);
	ha->interrupts_on = 0;
}

void qla82xx_init_flags(struct qla_hw_data *ha)
{
	struct qla82xx_legacy_intr_set *nx_legacy_intr;

	/* ISP 8021 initializations */
	rwlock_init(&ha->hw_lock);
	ha->qdr_sn_window = -1;
	ha->ddr_mn_window = -1;
	ha->curr_window = 255;
	ha->portnum = PCI_FUNC(ha->pdev->devfn);
	nx_legacy_intr = &legacy_intr[ha->portnum];
	ha->nx_legacy_intr.int_vec_bit = nx_legacy_intr->int_vec_bit;
	ha->nx_legacy_intr.tgt_status_reg = nx_legacy_intr->tgt_status_reg;
	ha->nx_legacy_intr.tgt_mask_reg = nx_legacy_intr->tgt_mask_reg;
	ha->nx_legacy_intr.pci_int_reg = nx_legacy_intr->pci_int_reg;
}

inline void
qla82xx_set_drv_active(scsi_qla_host_t *vha)
{
	uint32_t drv_active;
	struct qla_hw_data *ha = vha->hw;

	drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);

	/* If reset value is all FF's, initialize DRV_ACTIVE */
	if (drv_active == 0xffffffff) {
		qla82xx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE,
			QLA82XX_DRV_NOT_ACTIVE);
		drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
	}
	drv_active |= (QLA82XX_DRV_ACTIVE << (ha->portnum * 4));
	qla82xx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, drv_active);
}

inline void
qla82xx_clear_drv_active(struct qla_hw_data *ha)
{
	uint32_t drv_active;

	drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
	drv_active &= ~(QLA82XX_DRV_ACTIVE << (ha->portnum * 4));
	qla82xx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, drv_active);
}

static inline int
qla82xx_need_reset(struct qla_hw_data *ha)
{
	uint32_t drv_state;
	int rval;

	if (ha->flags.isp82xx_reset_owner)
		return 1;
	else {
		drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
		rval = drv_state & (QLA82XX_DRVST_RST_RDY << (ha->portnum * 4));
		return rval;
	}
}

static inline void
qla82xx_set_rst_ready(struct qla_hw_data *ha)
{
	uint32_t drv_state;
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);

	drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);

	/* If reset value is all FF's, initialize DRV_STATE */
	if (drv_state == 0xffffffff) {
		qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, QLA82XX_DRVST_NOT_RDY);
		drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
	}
	drv_state |= (QLA82XX_DRVST_RST_RDY << (ha->portnum * 4));
	ql_dbg(ql_dbg_init, vha, 0x00bb,
	    "drv_state = 0x%08x.\n", drv_state);
	qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, drv_state);
}

static inline void
qla82xx_clear_rst_ready(struct qla_hw_data *ha)
{
	uint32_t drv_state;

	drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
	drv_state &= ~(QLA82XX_DRVST_RST_RDY << (ha->portnum * 4));
	qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, drv_state);
}

static inline void
qla82xx_set_qsnt_ready(struct qla_hw_data *ha)
{
	uint32_t qsnt_state;

	qsnt_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
	qsnt_state |= (QLA82XX_DRVST_QSNT_RDY << (ha->portnum * 4));
	qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, qsnt_state);
}

void
qla82xx_clear_qsnt_ready(scsi_qla_host_t *vha)
{
	struct qla_hw_data *ha = vha->hw;
	uint32_t qsnt_state;

	qsnt_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
	qsnt_state &= ~(QLA82XX_DRVST_QSNT_RDY << (ha->portnum * 4));
	qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, qsnt_state);
}

static int
qla82xx_load_fw(scsi_qla_host_t *vha)
{
	int rst;
	struct fw_blob *blob;
	struct qla_hw_data *ha = vha->hw;

	if (qla82xx_pinit_from_rom(vha) != QLA_SUCCESS) {
		ql_log(ql_log_fatal, vha, 0x009f,
		    "Error during CRB initialization.\n");
		return QLA_FUNCTION_FAILED;
	}
	udelay(500);

	/* Bring QM and CAMRAM out of reset */
	rst = qla82xx_rd_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET);
	rst &= ~((1 << 28) | (1 << 24));
	qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, rst);

	/*
	 * FW Load priority:
	 * 1) Operational firmware residing in flash.
	 * 2) Firmware via request-firmware interface (.bin file).
	 */
	if (ql2xfwloadbin == 2)
		goto try_blob_fw;

	ql_log(ql_log_info, vha, 0x00a0,
	    "Attempting to load firmware from flash.\n");

	if (qla82xx_fw_load_from_flash(ha) == QLA_SUCCESS) {
		ql_log(ql_log_info, vha, 0x00a1,
		    "Firmware loaded successully from flash.\n");
		return QLA_SUCCESS;
	} else {
		ql_log(ql_log_warn, vha, 0x0108,
		    "Firmware load from flash failed.\n");
	}

try_blob_fw:
	ql_log(ql_log_info, vha, 0x00a2,
	    "Attempting to load firmware from blob.\n");

	/* Load firmware blob. */
	blob = ha->hablob = qla2x00_request_firmware(vha);
	if (!blob) {
		ql_log(ql_log_fatal, vha, 0x00a3,
		    "Firmware image not preset.\n");
		goto fw_load_failed;
	}

	/* Validating firmware blob */
	if (qla82xx_validate_firmware_blob(vha,
		QLA82XX_FLASH_ROMIMAGE)) {
		/* Fallback to URI format */
		if (qla82xx_validate_firmware_blob(vha,
			QLA82XX_UNIFIED_ROMIMAGE)) {
			ql_log(ql_log_fatal, vha, 0x00a4,
			    "No valid firmware image found.\n");
			return QLA_FUNCTION_FAILED;
		}
	}

	if (qla82xx_fw_load_from_blob(ha) == QLA_SUCCESS) {
		ql_log(ql_log_info, vha, 0x00a5,
		    "Firmware loaded successfully from binary blob.\n");
		return QLA_SUCCESS;
	} else {
		ql_log(ql_log_fatal, vha, 0x00a6,
		    "Firmware load failed for binary blob.\n");
		blob->fw = NULL;
		blob = NULL;
		goto fw_load_failed;
	}
	return QLA_SUCCESS;

fw_load_failed:
	return QLA_FUNCTION_FAILED;
}

int
qla82xx_start_firmware(scsi_qla_host_t *vha)
{
	int           pcie_cap;
	uint16_t      lnk;
	struct qla_hw_data *ha = vha->hw;

	/* scrub dma mask expansion register */
	qla82xx_wr_32(ha, CRB_DMA_SHIFT, QLA82XX_DMA_SHIFT_VALUE);

	/* Put both the PEG CMD and RCV PEG to default state
	 * of 0 before resetting the hardware
	 */
	qla82xx_wr_32(ha, CRB_CMDPEG_STATE, 0);
	qla82xx_wr_32(ha, CRB_RCVPEG_STATE, 0);

	/* Overwrite stale initialization register values */
	qla82xx_wr_32(ha, QLA82XX_PEG_HALT_STATUS1, 0);
	qla82xx_wr_32(ha, QLA82XX_PEG_HALT_STATUS2, 0);

	if (qla82xx_load_fw(vha) != QLA_SUCCESS) {
		ql_log(ql_log_fatal, vha, 0x00a7,
		    "Error trying to start fw.\n");
		return QLA_FUNCTION_FAILED;
	}

	/* Handshake with the card before we register the devices. */
	if (qla82xx_check_cmdpeg_state(ha) != QLA_SUCCESS) {
		ql_log(ql_log_fatal, vha, 0x00aa,
		    "Error during card handshake.\n");
		return QLA_FUNCTION_FAILED;
	}

	/* Negotiated Link width */
	pcie_cap = pci_find_capability(ha->pdev, PCI_CAP_ID_EXP);
	pci_read_config_word(ha->pdev, pcie_cap + PCI_EXP_LNKSTA, &lnk);
	ha->link_width = (lnk >> 4) & 0x3f;

	/* Synchronize with Receive peg */
	return qla82xx_check_rcvpeg_state(ha);
}

static uint32_t *
qla82xx_read_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
	uint32_t length)
{
	uint32_t i;
	uint32_t val;
	struct qla_hw_data *ha = vha->hw;

	/* Dword reads to flash. */
	for (i = 0; i < length/4; i++, faddr += 4) {
		if (qla82xx_rom_fast_read(ha, faddr, &val)) {
			ql_log(ql_log_warn, vha, 0x0106,
			    "Do ROM fast read failed.\n");
			goto done_read;
		}
		dwptr[i] = __constant_cpu_to_le32(val);
	}
done_read:
	return dwptr;
}

static int
qla82xx_unprotect_flash(struct qla_hw_data *ha)
{
	int ret;
	uint32_t val;
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);

	ret = ql82xx_rom_lock_d(ha);
	if (ret < 0) {
		ql_log(ql_log_warn, vha, 0xb014,
		    "ROM Lock failed.\n");
		return ret;
	}

	ret = qla82xx_read_status_reg(ha, &val);
	if (ret < 0)
		goto done_unprotect;

	val &= ~(BLOCK_PROTECT_BITS << 2);
	ret = qla82xx_write_status_reg(ha, val);
	if (ret < 0) {
		val |= (BLOCK_PROTECT_BITS << 2);
		qla82xx_write_status_reg(ha, val);
	}

	if (qla82xx_write_disable_flash(ha) != 0)
		ql_log(ql_log_warn, vha, 0xb015,
		    "Write disable failed.\n");

done_unprotect:
	qla82xx_rom_unlock(ha);
	return ret;
}

static int
qla82xx_protect_flash(struct qla_hw_data *ha)
{
	int ret;
	uint32_t val;
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);

	ret = ql82xx_rom_lock_d(ha);
	if (ret < 0) {
		ql_log(ql_log_warn, vha, 0xb016,
		    "ROM Lock failed.\n");
		return ret;
	}

	ret = qla82xx_read_status_reg(ha, &val);
	if (ret < 0)
		goto done_protect;

	val |= (BLOCK_PROTECT_BITS << 2);
	/* LOCK all sectors */
	ret = qla82xx_write_status_reg(ha, val);
	if (ret < 0)
		ql_log(ql_log_warn, vha, 0xb017,
		    "Write status register failed.\n");

	if (qla82xx_write_disable_flash(ha) != 0)
		ql_log(ql_log_warn, vha, 0xb018,
		    "Write disable failed.\n");
done_protect:
	qla82xx_rom_unlock(ha);
	return ret;
}

static int
qla82xx_erase_sector(struct qla_hw_data *ha, int addr)
{
	int ret = 0;
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);

	ret = ql82xx_rom_lock_d(ha);
	if (ret < 0) {
		ql_log(ql_log_warn, vha, 0xb019,
		    "ROM Lock failed.\n");
		return ret;
	}

	qla82xx_flash_set_write_enable(ha);
	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ADDRESS, addr);
	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 3);
	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_SE);

	if (qla82xx_wait_rom_done(ha)) {
		ql_log(ql_log_warn, vha, 0xb01a,
		    "Error waiting for rom done.\n");
		ret = -1;
		goto done;
	}
	ret = qla82xx_flash_wait_write_finish(ha);
done:
	qla82xx_rom_unlock(ha);
	return ret;
}

/*
 * Address and length are byte address
 */
uint8_t *
qla82xx_read_optrom_data(struct scsi_qla_host *vha, uint8_t *buf,
	uint32_t offset, uint32_t length)
{
	scsi_block_requests(vha->host);
	qla82xx_read_flash_data(vha, (uint32_t *)buf, offset, length);
	scsi_unblock_requests(vha->host);
	return buf;
}

static int
qla82xx_write_flash_data(struct scsi_qla_host *vha, uint32_t *dwptr,
	uint32_t faddr, uint32_t dwords)
{
	int ret;
	uint32_t liter;
	uint32_t sec_mask, rest_addr;
	dma_addr_t optrom_dma;
	void *optrom = NULL;
	int page_mode = 0;
	struct qla_hw_data *ha = vha->hw;

	ret = -1;

	/* Prepare burst-capable write on supported ISPs. */
	if (page_mode && !(faddr & 0xfff) &&
	    dwords > OPTROM_BURST_DWORDS) {
		optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE,
		    &optrom_dma, GFP_KERNEL);
		if (!optrom) {
			ql_log(ql_log_warn, vha, 0xb01b,
			    "Unable to allocate memory "
			    "for optron burst write (%x KB).\n",
			    OPTROM_BURST_SIZE / 1024);
		}
	}

	rest_addr = ha->fdt_block_size - 1;
	sec_mask = ~rest_addr;

	ret = qla82xx_unprotect_flash(ha);
	if (ret) {
		ql_log(ql_log_warn, vha, 0xb01c,
		    "Unable to unprotect flash for update.\n");
		goto write_done;
	}

	for (liter = 0; liter < dwords; liter++, faddr += 4, dwptr++) {
		/* Are we at the beginning of a sector? */
		if ((faddr & rest_addr) == 0) {

			ret = qla82xx_erase_sector(ha, faddr);
			if (ret) {
				ql_log(ql_log_warn, vha, 0xb01d,
				    "Unable to erase sector: address=%x.\n",
				    faddr);
				break;
			}
		}

		/* Go with burst-write. */
		if (optrom && (liter + OPTROM_BURST_DWORDS) <= dwords) {
			/* Copy data to DMA'ble buffer. */
			memcpy(optrom, dwptr, OPTROM_BURST_SIZE);

			ret = qla2x00_load_ram(vha, optrom_dma,
			    (ha->flash_data_off | faddr),
			    OPTROM_BURST_DWORDS);
			if (ret != QLA_SUCCESS) {
				ql_log(ql_log_warn, vha, 0xb01e,
				    "Unable to burst-write optrom segment "
				    "(%x/%x/%llx).\n", ret,
				    (ha->flash_data_off | faddr),
				    (unsigned long long)optrom_dma);
				ql_log(ql_log_warn, vha, 0xb01f,
				    "Reverting to slow-write.\n");

				dma_free_coherent(&ha->pdev->dev,
				    OPTROM_BURST_SIZE, optrom, optrom_dma);
				optrom = NULL;
			} else {
				liter += OPTROM_BURST_DWORDS - 1;
				faddr += OPTROM_BURST_DWORDS - 1;
				dwptr += OPTROM_BURST_DWORDS - 1;
				continue;
			}
		}

		ret = qla82xx_write_flash_dword(ha, faddr,
		    cpu_to_le32(*dwptr));
		if (ret) {
			ql_dbg(ql_dbg_p3p, vha, 0xb020,
			    "Unable to program flash address=%x data=%x.\n",
			    faddr, *dwptr);
			break;
		}
	}

	ret = qla82xx_protect_flash(ha);
	if (ret)
		ql_log(ql_log_warn, vha, 0xb021,
		    "Unable to protect flash after update.\n");
write_done:
	if (optrom)
		dma_free_coherent(&ha->pdev->dev,
		    OPTROM_BURST_SIZE, optrom, optrom_dma);
	return ret;
}

int
qla82xx_write_optrom_data(struct scsi_qla_host *vha, uint8_t *buf,
	uint32_t offset, uint32_t length)
{
	int rval;

	/* Suspend HBA. */
	scsi_block_requests(vha->host);
	rval = qla82xx_write_flash_data(vha, (uint32_t *)buf, offset,
		length >> 2);
	scsi_unblock_requests(vha->host);

	/* Convert return ISP82xx to generic */
	if (rval)
		rval = QLA_FUNCTION_FAILED;
	else
		rval = QLA_SUCCESS;
	return rval;
}

void
qla82xx_start_iocbs(scsi_qla_host_t *vha)
{
	struct qla_hw_data *ha = vha->hw;
	struct req_que *req = ha->req_q_map[0];
	struct device_reg_82xx __iomem *reg;
	uint32_t dbval;

	/* Adjust ring index. */
	req->ring_index++;
	if (req->ring_index == req->length) {
		req->ring_index = 0;
		req->ring_ptr = req->ring;
	} else
		req->ring_ptr++;

	reg = &ha->iobase->isp82;
	dbval = 0x04 | (ha->portnum << 5);

	dbval = dbval | (req->id << 8) | (req->ring_index << 16);
	if (ql2xdbwr)
		qla82xx_wr_32(ha, ha->nxdb_wr_ptr, dbval);
	else {
		WRT_REG_DWORD((unsigned long __iomem *)ha->nxdb_wr_ptr, dbval);
		wmb();
		while (RD_REG_DWORD(ha->nxdb_rd_ptr) != dbval) {
			WRT_REG_DWORD((unsigned long  __iomem *)ha->nxdb_wr_ptr,
				dbval);
			wmb();
		}
	}
}

void qla82xx_rom_lock_recovery(struct qla_hw_data *ha)
{
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);

	if (qla82xx_rom_lock(ha))
		/* Someone else is holding the lock. */
		ql_log(ql_log_info, vha, 0xb022,
		    "Resetting rom_lock.\n");

	/*
	 * Either we got the lock, or someone
	 * else died while holding it.
	 * In either case, unlock.
	 */
	qla82xx_rom_unlock(ha);
}

/*
 * qla82xx_device_bootstrap
 *    Initialize device, set DEV_READY, start fw
 *
 * Note:
 *      IDC lock must be held upon entry
 *
 * Return:
 *    Success : 0
 *    Failed  : 1
 */
static int
qla82xx_device_bootstrap(scsi_qla_host_t *vha)
{
	int rval = QLA_SUCCESS;
	int i, timeout;
	uint32_t old_count, count;
	struct qla_hw_data *ha = vha->hw;
	int need_reset = 0, peg_stuck = 1;

	need_reset = qla82xx_need_reset(ha);

	old_count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);

	for (i = 0; i < 10; i++) {
		timeout = msleep_interruptible(200);
		if (timeout) {
			qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
				QLA82XX_DEV_FAILED);
			return QLA_FUNCTION_FAILED;
		}

		count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
		if (count != old_count)
			peg_stuck = 0;
	}

	if (need_reset) {
		/* We are trying to perform a recovery here. */
		if (peg_stuck)
			qla82xx_rom_lock_recovery(ha);
		goto dev_initialize;
	} else  {
		/* Start of day for this ha context. */
		if (peg_stuck) {
			/* Either we are the first or recovery in progress. */
			qla82xx_rom_lock_recovery(ha);
			goto dev_initialize;
		} else
			/* Firmware already running. */
			goto dev_ready;
	}

	return rval;

dev_initialize:
	/* set to DEV_INITIALIZING */
	ql_log(ql_log_info, vha, 0x009e,
	    "HW State: INITIALIZING.\n");
	qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_INITIALIZING);

	/* Driver that sets device state to initializating sets IDC version */
	qla82xx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION, QLA82XX_IDC_VERSION);

	qla82xx_idc_unlock(ha);
	rval = qla82xx_start_firmware(vha);
	qla82xx_idc_lock(ha);

	if (rval != QLA_SUCCESS) {
		ql_log(ql_log_fatal, vha, 0x00ad,
		    "HW State: FAILED.\n");
		qla82xx_clear_drv_active(ha);
		qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_FAILED);
		return rval;
	}

dev_ready:
	ql_log(ql_log_info, vha, 0x00ae,
	    "HW State: READY.\n");
	qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_READY);

	return QLA_SUCCESS;
}

/*
* qla82xx_need_qsnt_handler
*    Code to start quiescence sequence
*
* Note:
*      IDC lock must be held upon entry
*
* Return: void
*/

static void
qla82xx_need_qsnt_handler(scsi_qla_host_t *vha)
{
	struct qla_hw_data *ha = vha->hw;
	uint32_t dev_state, drv_state, drv_active;
	unsigned long reset_timeout;

	if (vha->flags.online) {
		/*Block any further I/O and wait for pending cmnds to complete*/
		qla82xx_quiescent_state_cleanup(vha);
	}

	/* Set the quiescence ready bit */
	qla82xx_set_qsnt_ready(ha);

	/*wait for 30 secs for other functions to ack */
	reset_timeout = jiffies + (30 * HZ);

	drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
	drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
	/* Its 2 that is written when qsnt is acked, moving one bit */
	drv_active = drv_active << 0x01;

	while (drv_state != drv_active) {

		if (time_after_eq(jiffies, reset_timeout)) {
			/* quiescence timeout, other functions didn't ack
			 * changing the state to DEV_READY
			 */
			ql_log(ql_log_info, vha, 0xb023,
			    "%s : QUIESCENT TIMEOUT.\n", QLA2XXX_DRIVER_NAME);
			ql_log(ql_log_info, vha, 0xb024,
			    "DRV_ACTIVE:%d DRV_STATE:%d.\n",
			    drv_active, drv_state);
			qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
			    QLA82XX_DEV_READY);
			ql_log(ql_log_info, vha, 0xb025,
			    "HW State: DEV_READY.\n");
			qla82xx_idc_unlock(ha);
			qla2x00_perform_loop_resync(vha);
			qla82xx_idc_lock(ha);

			qla82xx_clear_qsnt_ready(vha);
			return;
		}

		qla82xx_idc_unlock(ha);
		msleep(1000);
		qla82xx_idc_lock(ha);

		drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
		drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
		drv_active = drv_active << 0x01;
	}
	dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
	/* everyone acked so set the state to DEV_QUIESCENCE */
	if (dev_state == QLA82XX_DEV_NEED_QUIESCENT) {
		ql_log(ql_log_info, vha, 0xb026,
		    "HW State: DEV_QUIESCENT.\n");
		qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_QUIESCENT);
	}
}

/*
* qla82xx_wait_for_state_change
*    Wait for device state to change from given current state
*
* Note:
*     IDC lock must not be held upon entry
*
* Return:
*    Changed device state.
*/
uint32_t
qla82xx_wait_for_state_change(scsi_qla_host_t *vha, uint32_t curr_state)
{
	struct qla_hw_data *ha = vha->hw;
	uint32_t dev_state;

	do {
		msleep(1000);
		qla82xx_idc_lock(ha);
		dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
		qla82xx_idc_unlock(ha);
	} while (dev_state == curr_state);

	return dev_state;
}

static void
qla82xx_dev_failed_handler(scsi_qla_host_t *vha)
{
	struct qla_hw_data *ha = vha->hw;

	/* Disable the board */
	ql_log(ql_log_fatal, vha, 0x00b8,
	    "Disabling the board.\n");

	qla82xx_idc_lock(ha);
	qla82xx_clear_drv_active(ha);
	qla82xx_idc_unlock(ha);

	/* Set DEV_FAILED flag to disable timer */
	vha->device_flags |= DFLG_DEV_FAILED;
	qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16);
	qla2x00_mark_all_devices_lost(vha, 0);
	vha->flags.online = 0;
	vha->flags.init_done = 0;
}

/*
 * qla82xx_need_reset_handler
 *    Code to start reset sequence
 *
 * Note:
 *      IDC lock must be held upon entry
 *
 * Return:
 *    Success : 0
 *    Failed  : 1
 */
static void
qla82xx_need_reset_handler(scsi_qla_host_t *vha)
{
	uint32_t dev_state, drv_state, drv_active;
	uint32_t active_mask = 0;
	unsigned long reset_timeout;
	struct qla_hw_data *ha = vha->hw;
	struct req_que *req = ha->req_q_map[0];

	if (vha->flags.online) {
		qla82xx_idc_unlock(ha);
		qla2x00_abort_isp_cleanup(vha);
		ha->isp_ops->get_flash_version(vha, req->ring);
		ha->isp_ops->nvram_config(vha);
		qla82xx_idc_lock(ha);
	}

	drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
	if (!ha->flags.isp82xx_reset_owner) {
		ql_dbg(ql_dbg_p3p, vha, 0xb028,
		    "reset_acknowledged by 0x%x\n", ha->portnum);
		qla82xx_set_rst_ready(ha);
	} else {
		active_mask = ~(QLA82XX_DRV_ACTIVE << (ha->portnum * 4));
		drv_active &= active_mask;
		ql_dbg(ql_dbg_p3p, vha, 0xb029,
		    "active_mask: 0x%08x\n", active_mask);
	}

	/* wait for 10 seconds for reset ack from all functions */
	reset_timeout = jiffies + (ha->nx_reset_timeout * HZ);

	drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
	drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
	dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);

	ql_dbg(ql_dbg_p3p, vha, 0xb02a,
	    "drv_state: 0x%08x, drv_active: 0x%08x, "
	    "dev_state: 0x%08x, active_mask: 0x%08x\n",
	    drv_state, drv_active, dev_state, active_mask);

	while (drv_state != drv_active &&
	    dev_state != QLA82XX_DEV_INITIALIZING) {
		if (time_after_eq(jiffies, reset_timeout)) {
			ql_log(ql_log_warn, vha, 0x00b5,
			    "Reset timeout.\n");
			break;
		}
		qla82xx_idc_unlock(ha);
		msleep(1000);
		qla82xx_idc_lock(ha);
		drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
		drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
		if (ha->flags.isp82xx_reset_owner)
			drv_active &= active_mask;
		dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
	}

	ql_dbg(ql_dbg_p3p, vha, 0xb02b,
	    "drv_state: 0x%08x, drv_active: 0x%08x, "
	    "dev_state: 0x%08x, active_mask: 0x%08x\n",
	    drv_state, drv_active, dev_state, active_mask);

	ql_log(ql_log_info, vha, 0x00b6,
	    "Device state is 0x%x = %s.\n",
	    dev_state,
	    dev_state < MAX_STATES ? qdev_state(dev_state) : "Unknown");

	/* Force to DEV_COLD unless someone else is starting a reset */
	if (dev_state != QLA82XX_DEV_INITIALIZING &&
	    dev_state != QLA82XX_DEV_COLD) {
		ql_log(ql_log_info, vha, 0x00b7,
		    "HW State: COLD/RE-INIT.\n");
		qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_COLD);
		if (ql2xmdenable) {
			if (qla82xx_md_collect(vha))
				ql_log(ql_log_warn, vha, 0xb02c,
				    "Not able to collect minidump.\n");
		} else
			ql_log(ql_log_warn, vha, 0xb04f,
			    "Minidump disabled.\n");
	}
}

int
qla82xx_check_md_needed(scsi_qla_host_t *vha)
{
	struct qla_hw_data *ha = vha->hw;
	uint16_t fw_major_version, fw_minor_version, fw_subminor_version;
	int rval = QLA_SUCCESS;

	fw_major_version = ha->fw_major_version;
	fw_minor_version = ha->fw_minor_version;
	fw_subminor_version = ha->fw_subminor_version;

	rval = qla2x00_get_fw_version(vha, &ha->fw_major_version,
	    &ha->fw_minor_version, &ha->fw_subminor_version,
	    &ha->fw_attributes, &ha->fw_memory_size,
	    ha->mpi_version, &ha->mpi_capabilities,
	    ha->phy_version);

	if (rval != QLA_SUCCESS)
		return rval;

	if (ql2xmdenable) {
		if (!ha->fw_dumped) {
			if (fw_major_version != ha->fw_major_version ||
			    fw_minor_version != ha->fw_minor_version ||
			    fw_subminor_version != ha->fw_subminor_version) {

				ql_log(ql_log_info, vha, 0xb02d,
				    "Firmware version differs "
				    "Previous version: %d:%d:%d - "
				    "New version: %d:%d:%d\n",
				    ha->fw_major_version,
				    ha->fw_minor_version,
				    ha->fw_subminor_version,
				    fw_major_version, fw_minor_version,
				    fw_subminor_version);
				/* Release MiniDump resources */
				qla82xx_md_free(vha);
				/* ALlocate MiniDump resources */
				qla82xx_md_prep(vha);
			}
		} else
			ql_log(ql_log_info, vha, 0xb02e,
			    "Firmware dump available to retrieve\n");
	}
	return rval;
}


int
qla82xx_check_fw_alive(scsi_qla_host_t *vha)
{
	uint32_t fw_heartbeat_counter;
	int status = 0;

	fw_heartbeat_counter = qla82xx_rd_32(vha->hw,
		QLA82XX_PEG_ALIVE_COUNTER);
	/* all 0xff, assume AER/EEH in progress, ignore */
	if (fw_heartbeat_counter == 0xffffffff) {
		ql_dbg(ql_dbg_timer, vha, 0x6003,
		    "FW heartbeat counter is 0xffffffff, "
		    "returning status=%d.\n", status);
		return status;
	}
	if (vha->fw_heartbeat_counter == fw_heartbeat_counter) {
		vha->seconds_since_last_heartbeat++;
		/* FW not alive after 2 seconds */
		if (vha->seconds_since_last_heartbeat == 2) {
			vha->seconds_since_last_heartbeat = 0;
			status = 1;
		}
	} else
		vha->seconds_since_last_heartbeat = 0;
	vha->fw_heartbeat_counter = fw_heartbeat_counter;
	if (status)
		ql_dbg(ql_dbg_timer, vha, 0x6004,
		    "Returning status=%d.\n", status);
	return status;
}

/*
 * qla82xx_device_state_handler
 *	Main state handler
 *
 * Note:
 *      IDC lock must be held upon entry
 *
 * Return:
 *    Success : 0
 *    Failed  : 1
 */
int
qla82xx_device_state_handler(scsi_qla_host_t *vha)
{
	uint32_t dev_state;
	uint32_t old_dev_state;
	int rval = QLA_SUCCESS;
	unsigned long dev_init_timeout;
	struct qla_hw_data *ha = vha->hw;
	int loopcount = 0;

	qla82xx_idc_lock(ha);
	if (!vha->flags.init_done)
		qla82xx_set_drv_active(vha);

	dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
	old_dev_state = dev_state;
	ql_log(ql_log_info, vha, 0x009b,
	    "Device state is 0x%x = %s.\n",
	    dev_state,
	    dev_state < MAX_STATES ? qdev_state(dev_state) : "Unknown");

	/* wait for 30 seconds for device to go ready */
	dev_init_timeout = jiffies + (ha->nx_dev_init_timeout * HZ);

	while (1) {

		if (time_after_eq(jiffies, dev_init_timeout)) {
			ql_log(ql_log_fatal, vha, 0x009c,
			    "Device init failed.\n");
			rval = QLA_FUNCTION_FAILED;
			break;
		}
		dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
		if (old_dev_state != dev_state) {
			loopcount = 0;
			old_dev_state = dev_state;
		}
		if (loopcount < 5) {
			ql_log(ql_log_info, vha, 0x009d,
			    "Device state is 0x%x = %s.\n",
			    dev_state,
			    dev_state < MAX_STATES ? qdev_state(dev_state) :
			    "Unknown");
		}

		switch (dev_state) {
		case QLA82XX_DEV_READY:
			ha->flags.isp82xx_reset_owner = 0;
			goto exit;
		case QLA82XX_DEV_COLD:
			rval = qla82xx_device_bootstrap(vha);
			break;
		case QLA82XX_DEV_INITIALIZING:
			qla82xx_idc_unlock(ha);
			msleep(1000);
			qla82xx_idc_lock(ha);
			break;
		case QLA82XX_DEV_NEED_RESET:
			if (!ql2xdontresethba)
				qla82xx_need_reset_handler(vha);
			else {
				qla82xx_idc_unlock(ha);
				msleep(1000);
				qla82xx_idc_lock(ha);
			}
			dev_init_timeout = jiffies +
			    (ha->nx_dev_init_timeout * HZ);
			break;
		case QLA82XX_DEV_NEED_QUIESCENT:
			qla82xx_need_qsnt_handler(vha);
			/* Reset timeout value after quiescence handler */
			dev_init_timeout = jiffies + (ha->nx_dev_init_timeout\
							 * HZ);
			break;
		case QLA82XX_DEV_QUIESCENT:
			/* Owner will exit and other will wait for the state
			 * to get changed
			 */
			if (ha->flags.quiesce_owner)
				goto exit;

			qla82xx_idc_unlock(ha);
			msleep(1000);
			qla82xx_idc_lock(ha);

			/* Reset timeout value after quiescence handler */
			dev_init_timeout = jiffies + (ha->nx_dev_init_timeout\
							 * HZ);
			break;
		case QLA82XX_DEV_FAILED:
			qla82xx_dev_failed_handler(vha);
			rval = QLA_FUNCTION_FAILED;
			goto exit;
		default:
			qla82xx_idc_unlock(ha);
			msleep(1000);
			qla82xx_idc_lock(ha);
		}
		loopcount++;
	}
exit:
	qla82xx_idc_unlock(ha);
	return rval;
}

void qla82xx_clear_pending_mbx(scsi_qla_host_t *vha)
{
	struct qla_hw_data *ha = vha->hw;

	if (ha->flags.mbox_busy) {
		ha->flags.mbox_int = 1;
		ha->flags.mbox_busy = 0;
		ql_log(ql_log_warn, vha, 0x6010,
		    "Doing premature completion of mbx command.\n");
		if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags))
			complete(&ha->mbx_intr_comp);
	}
}

void qla82xx_watchdog(scsi_qla_host_t *vha)
{
	uint32_t dev_state, halt_status;
	struct qla_hw_data *ha = vha->hw;

	/* don't poll if reset is going on */
	if (!ha->flags.isp82xx_reset_hdlr_active) {
		dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
		if (dev_state == QLA82XX_DEV_NEED_RESET &&
		    !test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) {
			ql_log(ql_log_warn, vha, 0x6001,
			    "Adapter reset needed.\n");
			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
			qla2xxx_wake_dpc(vha);
		} else if (dev_state == QLA82XX_DEV_NEED_QUIESCENT &&
			!test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags)) {
			ql_log(ql_log_warn, vha, 0x6002,
			    "Quiescent needed.\n");
			set_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags);
			qla2xxx_wake_dpc(vha);
		} else {
			if (qla82xx_check_fw_alive(vha)) {
				ql_dbg(ql_dbg_timer, vha, 0x6011,
				    "disabling pause transmit on port 0 & 1.\n");
				qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,
				    CRB_NIU_XG_PAUSE_CTL_P0|CRB_NIU_XG_PAUSE_CTL_P1);
				halt_status = qla82xx_rd_32(ha,
				    QLA82XX_PEG_HALT_STATUS1);
				ql_log(ql_log_info, vha, 0x6005,
				    "dumping hw/fw registers:.\n "
				    " PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,.\n "
				    " PEG_NET_0_PC: 0x%x, PEG_NET_1_PC: 0x%x,.\n "
				    " PEG_NET_2_PC: 0x%x, PEG_NET_3_PC: 0x%x,.\n "
				    " PEG_NET_4_PC: 0x%x.\n", halt_status,
				    qla82xx_rd_32(ha, QLA82XX_PEG_HALT_STATUS2),
				    qla82xx_rd_32(ha,
					    QLA82XX_CRB_PEG_NET_0 + 0x3c),
				    qla82xx_rd_32(ha,
					    QLA82XX_CRB_PEG_NET_1 + 0x3c),
				    qla82xx_rd_32(ha,
					    QLA82XX_CRB_PEG_NET_2 + 0x3c),
				    qla82xx_rd_32(ha,
					    QLA82XX_CRB_PEG_NET_3 + 0x3c),
				    qla82xx_rd_32(ha,
					    QLA82XX_CRB_PEG_NET_4 + 0x3c));
				if (LSW(MSB(halt_status)) == 0x67)
					ql_log(ql_log_warn, vha, 0xb052,
					    "Firmware aborted with "
					    "error code 0x00006700. Device is "
					    "being reset.\n");
				if (halt_status & HALT_STATUS_UNRECOVERABLE) {
					set_bit(ISP_UNRECOVERABLE,
					    &vha->dpc_flags);
				} else {
					ql_log(ql_log_info, vha, 0x6006,
					    "Detect abort  needed.\n");
					set_bit(ISP_ABORT_NEEDED,
					    &vha->dpc_flags);
				}
				qla2xxx_wake_dpc(vha);
				ha->flags.isp82xx_fw_hung = 1;
				ql_log(ql_log_warn, vha, 0x6007, "Firmware hung.\n");
				qla82xx_clear_pending_mbx(vha);
			}
		}
	}
}

int qla82xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
{
	int rval;
	rval = qla82xx_device_state_handler(vha);
	return rval;
}

void
qla82xx_set_reset_owner(scsi_qla_host_t *vha)
{
	struct qla_hw_data *ha = vha->hw;
	uint32_t dev_state;

	dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
	if (dev_state == QLA82XX_DEV_READY) {
		ql_log(ql_log_info, vha, 0xb02f,
		    "HW State: NEED RESET\n");
		qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
			QLA82XX_DEV_NEED_RESET);
		ha->flags.isp82xx_reset_owner = 1;
		ql_dbg(ql_dbg_p3p, vha, 0xb030,
		    "reset_owner is 0x%x\n", ha->portnum);
	} else
		ql_log(ql_log_info, vha, 0xb031,
		    "Device state is 0x%x = %s.\n",
		    dev_state,
		    dev_state < MAX_STATES ? qdev_state(dev_state) : "Unknown");
}

/*
 *  qla82xx_abort_isp
 *      Resets ISP and aborts all outstanding commands.
 *
 * Input:
 *      ha           = adapter block pointer.
 *
 * Returns:
 *      0 = success
 */
int
qla82xx_abort_isp(scsi_qla_host_t *vha)
{
	int rval;
	struct qla_hw_data *ha = vha->hw;

	if (vha->device_flags & DFLG_DEV_FAILED) {
		ql_log(ql_log_warn, vha, 0x8024,
		    "Device in failed state, exiting.\n");
		return QLA_SUCCESS;
	}
	ha->flags.isp82xx_reset_hdlr_active = 1;

	qla82xx_idc_lock(ha);
	qla82xx_set_reset_owner(vha);
	qla82xx_idc_unlock(ha);

	rval = qla82xx_device_state_handler(vha);

	qla82xx_idc_lock(ha);
	qla82xx_clear_rst_ready(ha);
	qla82xx_idc_unlock(ha);

	if (rval == QLA_SUCCESS) {
		ha->flags.isp82xx_fw_hung = 0;
		ha->flags.isp82xx_reset_hdlr_active = 0;
		qla82xx_restart_isp(vha);
	}

	if (rval) {
		vha->flags.online = 1;
		if (test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
			if (ha->isp_abort_cnt == 0) {
				ql_log(ql_log_warn, vha, 0x8027,
				    "ISP error recover failed - board "
				    "disabled.\n");
				/*
				 * The next call disables the board
				 * completely.
				 */
				ha->isp_ops->reset_adapter(vha);
				vha->flags.online = 0;
				clear_bit(ISP_ABORT_RETRY,
				    &vha->dpc_flags);
				rval = QLA_SUCCESS;
			} else { /* schedule another ISP abort */
				ha->isp_abort_cnt--;
				ql_log(ql_log_warn, vha, 0x8036,
				    "ISP abort - retry remaining %d.\n",
				    ha->isp_abort_cnt);
				rval = QLA_FUNCTION_FAILED;
			}
		} else {
			ha->isp_abort_cnt = MAX_RETRIES_OF_ISP_ABORT;
			ql_dbg(ql_dbg_taskm, vha, 0x8029,
			    "ISP error recovery - retrying (%d) more times.\n",
			    ha->isp_abort_cnt);
			set_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
			rval = QLA_FUNCTION_FAILED;
		}
	}
	return rval;
}

/*
 *  qla82xx_fcoe_ctx_reset
 *      Perform a quick reset and aborts all outstanding commands.
 *      This will only perform an FCoE context reset and avoids a full blown
 *      chip reset.
 *
 * Input:
 *      ha = adapter block pointer.
 *      is_reset_path = flag for identifying the reset path.
 *
 * Returns:
 *      0 = success
 */
int qla82xx_fcoe_ctx_reset(scsi_qla_host_t *vha)
{
	int rval = QLA_FUNCTION_FAILED;

	if (vha->flags.online) {
		/* Abort all outstanding commands, so as to be requeued later */
		qla2x00_abort_isp_cleanup(vha);
	}

	/* Stop currently executing firmware.
	 * This will destroy existing FCoE context at the F/W end.
	 */
	qla2x00_try_to_stop_firmware(vha);

	/* Restart. Creates a new FCoE context on INIT_FIRMWARE. */
	rval = qla82xx_restart_isp(vha);

	return rval;
}

/*
 * qla2x00_wait_for_fcoe_ctx_reset
 *    Wait till the FCoE context is reset.
 *
 * Note:
 *    Does context switching here.
 *    Release SPIN_LOCK (if any) before calling this routine.
 *
 * Return:
 *    Success (fcoe_ctx reset is done) : 0
 *    Failed  (fcoe_ctx reset not completed within max loop timout ) : 1
 */
int qla2x00_wait_for_fcoe_ctx_reset(scsi_qla_host_t *vha)
{
	int status = QLA_FUNCTION_FAILED;
	unsigned long wait_reset;

	wait_reset = jiffies + (MAX_LOOP_TIMEOUT * HZ);
	while ((test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags) ||
	    test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
	    && time_before(jiffies, wait_reset)) {

		set_current_state(TASK_UNINTERRUPTIBLE);
		schedule_timeout(HZ);

		if (!test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags) &&
		    !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) {
			status = QLA_SUCCESS;
			break;
		}
	}
	ql_dbg(ql_dbg_p3p, vha, 0xb027,
	       "%s: status=%d.\n", __func__, status);

	return status;
}

void
qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha)
{
	int i;
	unsigned long flags;
	struct qla_hw_data *ha = vha->hw;

	/* Check if 82XX firmware is alive or not
	 * We may have arrived here from NEED_RESET
	 * detection only
	 */
	if (!ha->flags.isp82xx_fw_hung) {
		for (i = 0; i < 2; i++) {
			msleep(1000);
			if (qla82xx_check_fw_alive(vha)) {
				ha->flags.isp82xx_fw_hung = 1;
				qla82xx_clear_pending_mbx(vha);
				break;
			}
		}
	}
	ql_dbg(ql_dbg_init, vha, 0x00b0,
	    "Entered %s fw_hung=%d.\n",
	    __func__, ha->flags.isp82xx_fw_hung);

	/* Abort all commands gracefully if fw NOT hung */
	if (!ha->flags.isp82xx_fw_hung) {
		int cnt, que;
		srb_t *sp;
		struct req_que *req;

		spin_lock_irqsave(&ha->hardware_lock, flags);
		for (que = 0; que < ha->max_req_queues; que++) {
			req = ha->req_q_map[que];
			if (!req)
				continue;
			for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
				sp = req->outstanding_cmds[cnt];
				if (sp) {
					if (!sp->ctx ||
					    (sp->flags & SRB_FCP_CMND_DMA_VALID)) {
						spin_unlock_irqrestore(
						    &ha->hardware_lock, flags);
						if (ha->isp_ops->abort_command(sp)) {
							ql_log(ql_log_info, vha,
							    0x00b1,
							    "mbx abort failed.\n");
						} else {
							ql_log(ql_log_info, vha,
							    0x00b2,
							    "mbx abort success.\n");
						}
						spin_lock_irqsave(&ha->hardware_lock, flags);
					}
				}
			}
		}
		spin_unlock_irqrestore(&ha->hardware_lock, flags);

		/* Wait for pending cmds (physical and virtual) to complete */
		if (!qla2x00_eh_wait_for_pending_commands(vha, 0, 0,
		    WAIT_HOST) == QLA_SUCCESS) {
			ql_dbg(ql_dbg_init, vha, 0x00b3,
			    "Done wait for "
			    "pending commands.\n");
		}
	}
}

/* Minidump related functions */
int
qla82xx_md_rw_32(struct qla_hw_data *ha, uint32_t off, u32 data, uint8_t flag)
{
	uint32_t  off_value, rval = 0;

	WRT_REG_DWORD((void *)(CRB_WINDOW_2M + ha->nx_pcibase),
	    (off & 0xFFFF0000));

	/* Read back value to make sure write has gone through */
	RD_REG_DWORD((void *)(CRB_WINDOW_2M + ha->nx_pcibase));
	off_value  = (off & 0x0000FFFF);

	if (flag)
		WRT_REG_DWORD((void *)
		    (off_value + CRB_INDIRECT_2M + ha->nx_pcibase),
		    data);
	else
		rval = RD_REG_DWORD((void *)
		    (off_value + CRB_INDIRECT_2M + ha->nx_pcibase));

	return rval;
}

static int
qla82xx_minidump_process_control(scsi_qla_host_t *vha,
	qla82xx_md_entry_hdr_t *entry_hdr, uint32_t **d_ptr)
{
	struct qla_hw_data *ha = vha->hw;
	struct qla82xx_md_entry_crb *crb_entry;
	uint32_t read_value, opcode, poll_time;
	uint32_t addr, index, crb_addr;
	unsigned long wtime;
	struct qla82xx_md_template_hdr *tmplt_hdr;
	uint32_t rval = QLA_SUCCESS;
	int i;

	tmplt_hdr = (struct qla82xx_md_template_hdr *)ha->md_tmplt_hdr;
	crb_entry = (struct qla82xx_md_entry_crb *)entry_hdr;
	crb_addr = crb_entry->addr;

	for (i = 0; i < crb_entry->op_count; i++) {
		opcode = crb_entry->crb_ctrl.opcode;
		if (opcode & QLA82XX_DBG_OPCODE_WR) {
			qla82xx_md_rw_32(ha, crb_addr,
			    crb_entry->value_1, 1);
			opcode &= ~QLA82XX_DBG_OPCODE_WR;
		}

		if (opcode & QLA82XX_DBG_OPCODE_RW) {
			read_value = qla82xx_md_rw_32(ha, crb_addr, 0, 0);
			qla82xx_md_rw_32(ha, crb_addr, read_value, 1);
			opcode &= ~QLA82XX_DBG_OPCODE_RW;
		}

		if (opcode & QLA82XX_DBG_OPCODE_AND) {
			read_value = qla82xx_md_rw_32(ha, crb_addr, 0, 0);
			read_value &= crb_entry->value_2;
			opcode &= ~QLA82XX_DBG_OPCODE_AND;
			if (opcode & QLA82XX_DBG_OPCODE_OR) {
				read_value |= crb_entry->value_3;
				opcode &= ~QLA82XX_DBG_OPCODE_OR;
			}
			qla82xx_md_rw_32(ha, crb_addr, read_value, 1);
		}

		if (opcode & QLA82XX_DBG_OPCODE_OR) {
			read_value = qla82xx_md_rw_32(ha, crb_addr, 0, 0);
			read_value |= crb_entry->value_3;
			qla82xx_md_rw_32(ha, crb_addr, read_value, 1);
			opcode &= ~QLA82XX_DBG_OPCODE_OR;
		}

		if (opcode & QLA82XX_DBG_OPCODE_POLL) {
			poll_time = crb_entry->crb_strd.poll_timeout;
			wtime = jiffies + poll_time;
			read_value = qla82xx_md_rw_32(ha, crb_addr, 0, 0);

			do {
				if ((read_value & crb_entry->value_2)
				    == crb_entry->value_1)
					break;
				else if (time_after_eq(jiffies, wtime)) {
					/* capturing dump failed */
					rval = QLA_FUNCTION_FAILED;
					break;
				} else
					read_value = qla82xx_md_rw_32(ha,
					    crb_addr, 0, 0);
			} while (1);
			opcode &= ~QLA82XX_DBG_OPCODE_POLL;
		}

		if (opcode & QLA82XX_DBG_OPCODE_RDSTATE) {
			if (crb_entry->crb_strd.state_index_a) {
				index = crb_entry->crb_strd.state_index_a;
				addr = tmplt_hdr->saved_state_array[index];
			} else
				addr = crb_addr;

			read_value = qla82xx_md_rw_32(ha, addr, 0, 0);
			index = crb_entry->crb_ctrl.state_index_v;
			tmplt_hdr->saved_state_array[index] = read_value;
			opcode &= ~QLA82XX_DBG_OPCODE_RDSTATE;
		}

		if (opcode & QLA82XX_DBG_OPCODE_WRSTATE) {
			if (crb_entry->crb_strd.state_index_a) {
				index = crb_entry->crb_strd.state_index_a;
				addr = tmplt_hdr->saved_state_array[index];
			} else
				addr = crb_addr;

			if (crb_entry->crb_ctrl.state_index_v) {
				index = crb_entry->crb_ctrl.state_index_v;
				read_value =
				    tmplt_hdr->saved_state_array[index];
			} else
				read_value = crb_entry->value_1;

			qla82xx_md_rw_32(ha, addr, read_value, 1);
			opcode &= ~QLA82XX_DBG_OPCODE_WRSTATE;
		}

		if (opcode & QLA82XX_DBG_OPCODE_MDSTATE) {
			index = crb_entry->crb_ctrl.state_index_v;
			read_value = tmplt_hdr->saved_state_array[index];
			read_value <<= crb_entry->crb_ctrl.shl;
			read_value >>= crb_entry->crb_ctrl.shr;
			if (crb_entry->value_2)
				read_value &= crb_entry->value_2;
			read_value |= crb_entry->value_3;
			read_value += crb_entry->value_1;
			tmplt_hdr->saved_state_array[index] = read_value;
			opcode &= ~QLA82XX_DBG_OPCODE_MDSTATE;
		}
		crb_addr += crb_entry->crb_strd.addr_stride;
	}
	return rval;
}

static void
qla82xx_minidump_process_rdocm(scsi_qla_host_t *vha,
	qla82xx_md_entry_hdr_t *entry_hdr, uint32_t **d_ptr)
{
	struct qla_hw_data *ha = vha->hw;
	uint32_t r_addr, r_stride, loop_cnt, i, r_value;
	struct qla82xx_md_entry_rdocm *ocm_hdr;
	uint32_t *data_ptr = *d_ptr;

	ocm_hdr = (struct qla82xx_md_entry_rdocm *)entry_hdr;
	r_addr = ocm_hdr->read_addr;
	r_stride = ocm_hdr->read_addr_stride;
	loop_cnt = ocm_hdr->op_count;

	for (i = 0; i < loop_cnt; i++) {
		r_value = RD_REG_DWORD((void *)(r_addr + ha->nx_pcibase));
		*data_ptr++ = cpu_to_le32(r_value);
		r_addr += r_stride;
	}
	*d_ptr = data_ptr;
}

static void
qla82xx_minidump_process_rdmux(scsi_qla_host_t *vha,
	qla82xx_md_entry_hdr_t *entry_hdr, uint32_t **d_ptr)
{
	struct qla_hw_data *ha = vha->hw;
	uint32_t r_addr, s_stride, s_addr, s_value, loop_cnt, i, r_value;
	struct qla82xx_md_entry_mux *mux_hdr;
	uint32_t *data_ptr = *d_ptr;

	mux_hdr = (struct qla82xx_md_entry_mux *)entry_hdr;
	r_addr = mux_hdr->read_addr;
	s_addr = mux_hdr->select_addr;
	s_stride = mux_hdr->select_value_stride;
	s_value = mux_hdr->select_value;
	loop_cnt = mux_hdr->op_count;

	for (i = 0; i < loop_cnt; i++) {
		qla82xx_md_rw_32(ha, s_addr, s_value, 1);
		r_value = qla82xx_md_rw_32(ha, r_addr, 0, 0);
		*data_ptr++ = cpu_to_le32(s_value);
		*data_ptr++ = cpu_to_le32(r_value);
		s_value += s_stride;
	}
	*d_ptr = data_ptr;
}

static void
qla82xx_minidump_process_rdcrb(scsi_qla_host_t *vha,
	qla82xx_md_entry_hdr_t *entry_hdr, uint32_t **d_ptr)
{
	struct qla_hw_data *ha = vha->hw;
	uint32_t r_addr, r_stride, loop_cnt, i, r_value;
	struct qla82xx_md_entry_crb *crb_hdr;
	uint32_t *data_ptr = *d_ptr;

	crb_hdr = (struct qla82xx_md_entry_crb *)entry_hdr;
	r_addr = crb_hdr->addr;
	r_stride = crb_hdr->crb_strd.addr_stride;
	loop_cnt = crb_hdr->op_count;

	for (i = 0; i < loop_cnt; i++) {
		r_value = qla82xx_md_rw_32(ha, r_addr, 0, 0);
		*data_ptr++ = cpu_to_le32(r_addr);
		*data_ptr++ = cpu_to_le32(r_value);
		r_addr += r_stride;
	}
	*d_ptr = data_ptr;
}

static int
qla82xx_minidump_process_l2tag(scsi_qla_host_t *vha,
	qla82xx_md_entry_hdr_t *entry_hdr, uint32_t **d_ptr)
{
	struct qla_hw_data *ha = vha->hw;
	uint32_t addr, r_addr, c_addr, t_r_addr;
	uint32_t i, k, loop_count, t_value, r_cnt, r_value;
	unsigned long p_wait, w_time, p_mask;
	uint32_t c_value_w, c_value_r;
	struct qla82xx_md_entry_cache *cache_hdr;
	int rval = QLA_FUNCTION_FAILED;
	uint32_t *data_ptr = *d_ptr;

	cache_hdr = (struct qla82xx_md_entry_cache *)entry_hdr;
	loop_count = cache_hdr->op_count;
	r_addr = cache_hdr->read_addr;
	c_addr = cache_hdr->control_addr;
	c_value_w = cache_hdr->cache_ctrl.write_value;

	t_r_addr = cache_hdr->tag_reg_addr;
	t_value = cache_hdr->addr_ctrl.init_tag_value;
	r_cnt = cache_hdr->read_ctrl.read_addr_cnt;
	p_wait = cache_hdr->cache_ctrl.poll_wait;
	p_mask = cache_hdr->cache_ctrl.poll_mask;

	for (i = 0; i < loop_count; i++) {
		qla82xx_md_rw_32(ha, t_r_addr, t_value, 1);
		if (c_value_w)
			qla82xx_md_rw_32(ha, c_addr, c_value_w, 1);

		if (p_mask) {
			w_time = jiffies + p_wait;
			do {
				c_value_r = qla82xx_md_rw_32(ha, c_addr, 0, 0);
				if ((c_value_r & p_mask) == 0)
					break;
				else if (time_after_eq(jiffies, w_time)) {
					/* capturing dump failed */
					ql_dbg(ql_dbg_p3p, vha, 0xb032,
					    "c_value_r: 0x%x, poll_mask: 0x%lx, "
					    "w_time: 0x%lx\n",
					    c_value_r, p_mask, w_time);
					return rval;
				}
			} while (1);
		}

		addr = r_addr;
		for (k = 0; k < r_cnt; k++) {
			r_value = qla82xx_md_rw_32(ha, addr, 0, 0);
			*data_ptr++ = cpu_to_le32(r_value);
			addr += cache_hdr->read_ctrl.read_addr_stride;
		}
		t_value += cache_hdr->addr_ctrl.tag_value_stride;
	}
	*d_ptr = data_ptr;
	return QLA_SUCCESS;
}

static void
qla82xx_minidump_process_l1cache(scsi_qla_host_t *vha,
	qla82xx_md_entry_hdr_t *entry_hdr, uint32_t **d_ptr)
{
	struct qla_hw_data *ha = vha->hw;
	uint32_t addr, r_addr, c_addr, t_r_addr;
	uint32_t i, k, loop_count, t_value, r_cnt, r_value;
	uint32_t c_value_w;
	struct qla82xx_md_entry_cache *cache_hdr;
	uint32_t *data_ptr = *d_ptr;

	cache_hdr = (struct qla82xx_md_entry_cache *)entry_hdr;
	loop_count = cache_hdr->op_count;
	r_addr = cache_hdr->read_addr;
	c_addr = cache_hdr->control_addr;
	c_value_w = cache_hdr->cache_ctrl.write_value;

	t_r_addr = cache_hdr->tag_reg_addr;
	t_value = cache_hdr->addr_ctrl.init_tag_value;
	r_cnt = cache_hdr->read_ctrl.read_addr_cnt;

	for (i = 0; i < loop_count; i++) {
		qla82xx_md_rw_32(ha, t_r_addr, t_value, 1);
		qla82xx_md_rw_32(ha, c_addr, c_value_w, 1);
		addr = r_addr;
		for (k = 0; k < r_cnt; k++) {
			r_value = qla82xx_md_rw_32(ha, addr, 0, 0);
			*data_ptr++ = cpu_to_le32(r_value);
			addr += cache_hdr->read_ctrl.read_addr_stride;
		}
		t_value += cache_hdr->addr_ctrl.tag_value_stride;
	}
	*d_ptr = data_ptr;
}

static void
qla82xx_minidump_process_queue(scsi_qla_host_t *vha,
	qla82xx_md_entry_hdr_t *entry_hdr, uint32_t **d_ptr)
{
	struct qla_hw_data *ha = vha->hw;
	uint32_t s_addr, r_addr;
	uint32_t r_stride, r_value, r_cnt, qid = 0;
	uint32_t i, k, loop_cnt;
	struct qla82xx_md_entry_queue *q_hdr;
	uint32_t *data_ptr = *d_ptr;

	q_hdr = (struct qla82xx_md_entry_queue *)entry_hdr;
	s_addr = q_hdr->select_addr;
	r_cnt = q_hdr->rd_strd.read_addr_cnt;
	r_stride = q_hdr->rd_strd.read_addr_stride;
	loop_cnt = q_hdr->op_count;

	for (i = 0; i < loop_cnt; i++) {
		qla82xx_md_rw_32(ha, s_addr, qid, 1);
		r_addr = q_hdr->read_addr;
		for (k = 0; k < r_cnt; k++) {
			r_value = qla82xx_md_rw_32(ha, r_addr, 0, 0);
			*data_ptr++ = cpu_to_le32(r_value);
			r_addr += r_stride;
		}
		qid += q_hdr->q_strd.queue_id_stride;
	}
	*d_ptr = data_ptr;
}

static void
qla82xx_minidump_process_rdrom(scsi_qla_host_t *vha,
	qla82xx_md_entry_hdr_t *entry_hdr, uint32_t **d_ptr)
{
	struct qla_hw_data *ha = vha->hw;
	uint32_t r_addr, r_value;
	uint32_t i, loop_cnt;
	struct qla82xx_md_entry_rdrom *rom_hdr;
	uint32_t *data_ptr = *d_ptr;

	rom_hdr = (struct qla82xx_md_entry_rdrom *)entry_hdr;
	r_addr = rom_hdr->read_addr;
	loop_cnt = rom_hdr->read_data_size/sizeof(uint32_t);

	for (i = 0; i < loop_cnt; i++) {
		qla82xx_md_rw_32(ha, MD_DIRECT_ROM_WINDOW,
		    (r_addr & 0xFFFF0000), 1);
		r_value = qla82xx_md_rw_32(ha,
		    MD_DIRECT_ROM_READ_BASE +
		    (r_addr & 0x0000FFFF), 0, 0);
		*data_ptr++ = cpu_to_le32(r_value);
		r_addr += sizeof(uint32_t);
	}
	*d_ptr = data_ptr;
}

static int
qla82xx_minidump_process_rdmem(scsi_qla_host_t *vha,
	qla82xx_md_entry_hdr_t *entry_hdr, uint32_t **d_ptr)
{
	struct qla_hw_data *ha = vha->hw;
	uint32_t r_addr, r_value, r_data;
	uint32_t i, j, loop_cnt;
	struct qla82xx_md_entry_rdmem *m_hdr;
	unsigned long flags;
	int rval = QLA_FUNCTION_FAILED;
	uint32_t *data_ptr = *d_ptr;

	m_hdr = (struct qla82xx_md_entry_rdmem *)entry_hdr;
	r_addr = m_hdr->read_addr;
	loop_cnt = m_hdr->read_data_size/16;

	if (r_addr & 0xf) {
		ql_log(ql_log_warn, vha, 0xb033,
		    "Read addr 0x%x not 16 bytes alligned\n", r_addr);
		return rval;
	}

	if (m_hdr->read_data_size % 16) {
		ql_log(ql_log_warn, vha, 0xb034,
		    "Read data[0x%x] not multiple of 16 bytes\n",
		    m_hdr->read_data_size);
		return rval;
	}

	ql_dbg(ql_dbg_p3p, vha, 0xb035,
	    "[%s]: rdmem_addr: 0x%x, read_data_size: 0x%x, loop_cnt: 0x%x\n",
	    __func__, r_addr, m_hdr->read_data_size, loop_cnt);

	write_lock_irqsave(&ha->hw_lock, flags);
	for (i = 0; i < loop_cnt; i++) {
		qla82xx_md_rw_32(ha, MD_MIU_TEST_AGT_ADDR_LO, r_addr, 1);
		r_value = 0;
		qla82xx_md_rw_32(ha, MD_MIU_TEST_AGT_ADDR_HI, r_value, 1);
		r_value = MIU_TA_CTL_ENABLE;
		qla82xx_md_rw_32(ha, MD_MIU_TEST_AGT_CTRL, r_value, 1);
		r_value = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
		qla82xx_md_rw_32(ha, MD_MIU_TEST_AGT_CTRL, r_value, 1);

		for (j = 0; j < MAX_CTL_CHECK; j++) {
			r_value = qla82xx_md_rw_32(ha,
			    MD_MIU_TEST_AGT_CTRL, 0, 0);
			if ((r_value & MIU_TA_CTL_BUSY) == 0)
				break;
		}

		if (j >= MAX_CTL_CHECK) {
			printk_ratelimited(KERN_ERR
			    "failed to read through agent\n");
			write_unlock_irqrestore(&ha->hw_lock, flags);
			return rval;
		}

		for (j = 0; j < 4; j++) {
			r_data = qla82xx_md_rw_32(ha,
			    MD_MIU_TEST_AGT_RDDATA[j], 0, 0);
			*data_ptr++ = cpu_to_le32(r_data);
		}
		r_addr += 16;
	}
	write_unlock_irqrestore(&ha->hw_lock, flags);
	*d_ptr = data_ptr;
	return QLA_SUCCESS;
}

static int
qla82xx_validate_template_chksum(scsi_qla_host_t *vha)
{
	struct qla_hw_data *ha = vha->hw;
	uint64_t chksum = 0;
	uint32_t *d_ptr = (uint32_t *)ha->md_tmplt_hdr;
	int count = ha->md_template_size/sizeof(uint32_t);

	while (count-- > 0)
		chksum += *d_ptr++;
	while (chksum >> 32)
		chksum = (chksum & 0xFFFFFFFF) + (chksum >> 32);
	return ~chksum;
}

static void
qla82xx_mark_entry_skipped(scsi_qla_host_t *vha,
	qla82xx_md_entry_hdr_t *entry_hdr, int index)
{
	entry_hdr->d_ctrl.driver_flags |= QLA82XX_DBG_SKIPPED_FLAG;
	ql_dbg(ql_dbg_p3p, vha, 0xb036,
	    "Skipping entry[%d]: "
	    "ETYPE[0x%x]-ELEVEL[0x%x]\n",
	    index, entry_hdr->entry_type,
	    entry_hdr->d_ctrl.entry_capture_mask);
}

int
qla82xx_md_collect(scsi_qla_host_t *vha)
{
	struct qla_hw_data *ha = vha->hw;
	int no_entry_hdr = 0;
	qla82xx_md_entry_hdr_t *entry_hdr;
	struct qla82xx_md_template_hdr *tmplt_hdr;
	uint32_t *data_ptr;
	uint32_t total_data_size = 0, f_capture_mask, data_collected = 0;
	int i = 0, rval = QLA_FUNCTION_FAILED;

	tmplt_hdr = (struct qla82xx_md_template_hdr *)ha->md_tmplt_hdr;
	data_ptr = (uint32_t *)ha->md_dump;

	if (ha->fw_dumped) {
		ql_log(ql_log_info, vha, 0xb037,
		    "Firmware dump available to retrive\n");
		goto md_failed;
	}

	ha->fw_dumped = 0;

	if (!ha->md_tmplt_hdr || !ha->md_dump) {
		ql_log(ql_log_warn, vha, 0xb038,
		    "Memory not allocated for minidump capture\n");
		goto md_failed;
	}

	if (qla82xx_validate_template_chksum(vha)) {
		ql_log(ql_log_info, vha, 0xb039,
		    "Template checksum validation error\n");
		goto md_failed;
	}

	no_entry_hdr = tmplt_hdr->num_of_entries;
	ql_dbg(ql_dbg_p3p, vha, 0xb03a,
	    "No of entry headers in Template: 0x%x\n", no_entry_hdr);

	ql_dbg(ql_dbg_p3p, vha, 0xb03b,
	    "Capture Mask obtained: 0x%x\n", tmplt_hdr->capture_debug_level);

	f_capture_mask = tmplt_hdr->capture_debug_level & 0xFF;

	/* Validate whether required debug level is set */
	if ((f_capture_mask & 0x3) != 0x3) {
		ql_log(ql_log_warn, vha, 0xb03c,
		    "Minimum required capture mask[0x%x] level not set\n",
		    f_capture_mask);
		goto md_failed;
	}
	tmplt_hdr->driver_capture_mask = ql2xmdcapmask;

	tmplt_hdr->driver_info[0] = vha->host_no;
	tmplt_hdr->driver_info[1] = (QLA_DRIVER_MAJOR_VER << 24) |
	    (QLA_DRIVER_MINOR_VER << 16) | (QLA_DRIVER_PATCH_VER << 8) |
	    QLA_DRIVER_BETA_VER;

	total_data_size = ha->md_dump_size;

	ql_dbg(ql_log_info, vha, 0xb03d,
	    "Total minidump data_size 0x%x to be captured\n", total_data_size);

	/* Check whether template obtained is valid */
	if (tmplt_hdr->entry_type != QLA82XX_TLHDR) {
		ql_log(ql_log_warn, vha, 0xb04e,
		    "Bad template header entry type: 0x%x obtained\n",
		    tmplt_hdr->entry_type);
		goto md_failed;
	}

	entry_hdr = (qla82xx_md_entry_hdr_t *) \
	    (((uint8_t *)ha->md_tmplt_hdr) + tmplt_hdr->first_entry_offset);

	/* Walk through the entry headers */
	for (i = 0; i < no_entry_hdr; i++) {

		if (data_collected > total_data_size) {
			ql_log(ql_log_warn, vha, 0xb03e,
			    "More MiniDump data collected: [0x%x]\n",
			    data_collected);
			goto md_failed;
		}

		if (!(entry_hdr->d_ctrl.entry_capture_mask &
		    ql2xmdcapmask)) {
			entry_hdr->d_ctrl.driver_flags |=
			    QLA82XX_DBG_SKIPPED_FLAG;
			ql_dbg(ql_dbg_p3p, vha, 0xb03f,
			    "Skipping entry[%d]: "
			    "ETYPE[0x%x]-ELEVEL[0x%x]\n",
			    i, entry_hdr->entry_type,
			    entry_hdr->d_ctrl.entry_capture_mask);
			goto skip_nxt_entry;
		}

		ql_dbg(ql_dbg_p3p, vha, 0xb040,
		    "[%s]: data ptr[%d]: %p, entry_hdr: %p\n"
		    "entry_type: 0x%x, captrue_mask: 0x%x\n",
		    __func__, i, data_ptr, entry_hdr,
		    entry_hdr->entry_type,
		    entry_hdr->d_ctrl.entry_capture_mask);

		ql_dbg(ql_dbg_p3p, vha, 0xb041,
		    "Data collected: [0x%x], Dump size left:[0x%x]\n",
		    data_collected, (ha->md_dump_size - data_collected));

		/* Decode the entry type and take
		 * required action to capture debug data */
		switch (entry_hdr->entry_type) {
		case QLA82XX_RDEND:
			qla82xx_mark_entry_skipped(vha, entry_hdr, i);
			break;
		case QLA82XX_CNTRL:
			rval = qla82xx_minidump_process_control(vha,
			    entry_hdr, &data_ptr);
			if (rval != QLA_SUCCESS) {
				qla82xx_mark_entry_skipped(vha, entry_hdr, i);
				goto md_failed;
			}
			break;
		case QLA82XX_RDCRB:
			qla82xx_minidump_process_rdcrb(vha,
			    entry_hdr, &data_ptr);
			break;
		case QLA82XX_RDMEM:
			rval = qla82xx_minidump_process_rdmem(vha,
			    entry_hdr, &data_ptr);
			if (rval != QLA_SUCCESS) {
				qla82xx_mark_entry_skipped(vha, entry_hdr, i);
				goto md_failed;
			}
			break;
		case QLA82XX_BOARD:
		case QLA82XX_RDROM:
			qla82xx_minidump_process_rdrom(vha,
			    entry_hdr, &data_ptr);
			break;
		case QLA82XX_L2DTG:
		case QLA82XX_L2ITG:
		case QLA82XX_L2DAT:
		case QLA82XX_L2INS:
			rval = qla82xx_minidump_process_l2tag(vha,
			    entry_hdr, &data_ptr);
			if (rval != QLA_SUCCESS) {
				qla82xx_mark_entry_skipped(vha, entry_hdr, i);
				goto md_failed;
			}
			break;
		case QLA82XX_L1DAT:
		case QLA82XX_L1INS:
			qla82xx_minidump_process_l1cache(vha,
			    entry_hdr, &data_ptr);
			break;
		case QLA82XX_RDOCM:
			qla82xx_minidump_process_rdocm(vha,
			    entry_hdr, &data_ptr);
			break;
		case QLA82XX_RDMUX:
			qla82xx_minidump_process_rdmux(vha,
			    entry_hdr, &data_ptr);
			break;
		case QLA82XX_QUEUE:
			qla82xx_minidump_process_queue(vha,
			    entry_hdr, &data_ptr);
			break;
		case QLA82XX_RDNOP:
		default:
			qla82xx_mark_entry_skipped(vha, entry_hdr, i);
			break;
		}

		ql_dbg(ql_dbg_p3p, vha, 0xb042,
		    "[%s]: data ptr[%d]: %p\n", __func__, i, data_ptr);

		data_collected = (uint8_t *)data_ptr -
		    (uint8_t *)ha->md_dump;
skip_nxt_entry:
		entry_hdr = (qla82xx_md_entry_hdr_t *) \
		    (((uint8_t *)entry_hdr) + entry_hdr->entry_size);
	}

	if (data_collected != total_data_size) {
		ql_dbg(ql_log_warn, vha, 0xb043,
		    "MiniDump data mismatch: Data collected: [0x%x],"
		    "total_data_size:[0x%x]\n",
		    data_collected, total_data_size);
		goto md_failed;
	}

	ql_log(ql_log_info, vha, 0xb044,
	    "Firmware dump saved to temp buffer (%ld/%p %ld/%p).\n",
	    vha->host_no, ha->md_tmplt_hdr, vha->host_no, ha->md_dump);
	ha->fw_dumped = 1;
	qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);

md_failed:
	return rval;
}

int
qla82xx_md_alloc(scsi_qla_host_t *vha)
{
	struct qla_hw_data *ha = vha->hw;
	int i, k;
	struct qla82xx_md_template_hdr *tmplt_hdr;

	tmplt_hdr = (struct qla82xx_md_template_hdr *)ha->md_tmplt_hdr;

	if (ql2xmdcapmask < 0x3 || ql2xmdcapmask > 0x7F) {
		ql2xmdcapmask = tmplt_hdr->capture_debug_level & 0xFF;
		ql_log(ql_log_info, vha, 0xb045,
		    "Forcing driver capture mask to firmware default capture mask: 0x%x.\n",
		    ql2xmdcapmask);
	}

	for (i = 0x2, k = 1; (i & QLA82XX_DEFAULT_CAP_MASK); i <<= 1, k++) {
		if (i & ql2xmdcapmask)
			ha->md_dump_size += tmplt_hdr->capture_size_array[k];
	}

	if (ha->md_dump) {
		ql_log(ql_log_warn, vha, 0xb046,
		    "Firmware dump previously allocated.\n");
		return 1;
	}

	ha->md_dump = vmalloc(ha->md_dump_size);
	if (ha->md_dump == NULL) {
		ql_log(ql_log_warn, vha, 0xb047,
		    "Unable to allocate memory for Minidump size "
		    "(0x%x).\n", ha->md_dump_size);
		return 1;
	}
	return 0;
}

void
qla82xx_md_free(scsi_qla_host_t *vha)
{
	struct qla_hw_data *ha = vha->hw;

	/* Release the template header allocated */
	if (ha->md_tmplt_hdr) {
		ql_log(ql_log_info, vha, 0xb048,
		    "Free MiniDump template: %p, size (%d KB)\n",
		    ha->md_tmplt_hdr, ha->md_template_size / 1024);
		dma_free_coherent(&ha->pdev->dev, ha->md_template_size,
		    ha->md_tmplt_hdr, ha->md_tmplt_hdr_dma);
		ha->md_tmplt_hdr = 0;
	}

	/* Release the template data buffer allocated */
	if (ha->md_dump) {
		ql_log(ql_log_info, vha, 0xb049,
		    "Free MiniDump memory: %p, size (%d KB)\n",
		    ha->md_dump, ha->md_dump_size / 1024);
		vfree(ha->md_dump);
		ha->md_dump_size = 0;
		ha->md_dump = 0;
	}
}

void
qla82xx_md_prep(scsi_qla_host_t *vha)
{
	struct qla_hw_data *ha = vha->hw;
	int rval;

	/* Get Minidump template size */
	rval = qla82xx_md_get_template_size(vha);
	if (rval == QLA_SUCCESS) {
		ql_log(ql_log_info, vha, 0xb04a,
		    "MiniDump Template size obtained (%d KB)\n",
		    ha->md_template_size / 1024);

		/* Get Minidump template */
		rval = qla82xx_md_get_template(vha);
		if (rval == QLA_SUCCESS) {
			ql_dbg(ql_dbg_p3p, vha, 0xb04b,
			    "MiniDump Template obtained\n");

			/* Allocate memory for minidump */
			rval = qla82xx_md_alloc(vha);
			if (rval == QLA_SUCCESS)
				ql_log(ql_log_info, vha, 0xb04c,
				    "MiniDump memory allocated (%d KB)\n",
				    ha->md_dump_size / 1024);
			else {
				ql_log(ql_log_info, vha, 0xb04d,
				    "Free MiniDump template: %p, size: (%d KB)\n",
				    ha->md_tmplt_hdr,
				    ha->md_template_size / 1024);
				dma_free_coherent(&ha->pdev->dev,
				    ha->md_template_size,
				    ha->md_tmplt_hdr, ha->md_tmplt_hdr_dma);
				ha->md_tmplt_hdr = 0;
			}

		}
	}
}

int
qla82xx_beacon_on(struct scsi_qla_host *vha)
{

	int rval;
	struct qla_hw_data *ha = vha->hw;
	qla82xx_idc_lock(ha);
	rval = qla82xx_mbx_beacon_ctl(vha, 1);

	if (rval) {
		ql_log(ql_log_warn, vha, 0xb050,
		    "mbx set led config failed in %s\n", __func__);
		goto exit;
	}
	ha->beacon_blink_led = 1;
exit:
	qla82xx_idc_unlock(ha);
	return rval;
}

int
qla82xx_beacon_off(struct scsi_qla_host *vha)
{

	int rval;
	struct qla_hw_data *ha = vha->hw;
	qla82xx_idc_lock(ha);
	rval = qla82xx_mbx_beacon_ctl(vha, 0);

	if (rval) {
		ql_log(ql_log_warn, vha, 0xb051,
		    "mbx set led config failed in %s\n", __func__);
		goto exit;
	}
	ha->beacon_blink_led = 0;
exit:
	qla82xx_idc_unlock(ha);
	return rval;
}
