/*
 * QLogic iSCSI HBA Driver
 * Copyright (c)   2003-2013 QLogic Corporation
 *
 * See LICENSE.qla4xxx for copyright and licensing details.
 */

#include <linux/ratelimit.h>

#include "ql4_def.h"
#include "ql4_version.h"
#include "ql4_glbl.h"
#include "ql4_dbg.h"
#include "ql4_inline.h"

uint32_t qla4_83xx_rd_reg(struct scsi_qla_host *ha, ulong addr)
{
	return readl((void __iomem *)(ha->nx_pcibase + addr));
}

void qla4_83xx_wr_reg(struct scsi_qla_host *ha, ulong addr, uint32_t val)
{
	writel(val, (void __iomem *)(ha->nx_pcibase + addr));
}

static int qla4_83xx_set_win_base(struct scsi_qla_host *ha, uint32_t addr)
{
	uint32_t val;
	int ret_val = QLA_SUCCESS;

	qla4_83xx_wr_reg(ha, QLA83XX_CRB_WIN_FUNC(ha->func_num), addr);
	val = qla4_83xx_rd_reg(ha, QLA83XX_CRB_WIN_FUNC(ha->func_num));
	if (val != addr) {
		ql4_printk(KERN_ERR, ha, "%s: Failed to set register window : addr written 0x%x, read 0x%x!\n",
			   __func__, addr, val);
		ret_val = QLA_ERROR;
	}

	return ret_val;
}

int qla4_83xx_rd_reg_indirect(struct scsi_qla_host *ha, uint32_t addr,
			      uint32_t *data)
{
	int ret_val;

	ret_val = qla4_83xx_set_win_base(ha, addr);

	if (ret_val == QLA_SUCCESS) {
		*data = qla4_83xx_rd_reg(ha, QLA83XX_WILDCARD);
	} else {
		*data = 0xffffffff;
		ql4_printk(KERN_ERR, ha, "%s: failed read of addr 0x%x!\n",
			   __func__, addr);
	}

	return ret_val;
}

int qla4_83xx_wr_reg_indirect(struct scsi_qla_host *ha, uint32_t addr,
			      uint32_t data)
{
	int ret_val;

	ret_val = qla4_83xx_set_win_base(ha, addr);

	if (ret_val == QLA_SUCCESS)
		qla4_83xx_wr_reg(ha, QLA83XX_WILDCARD, data);
	else
		ql4_printk(KERN_ERR, ha, "%s: failed wrt to addr 0x%x, data 0x%x\n",
			   __func__, addr, data);

	return ret_val;
}

static int qla4_83xx_flash_lock(struct scsi_qla_host *ha)
{
	int lock_owner;
	int timeout = 0;
	uint32_t lock_status = 0;
	int ret_val = QLA_SUCCESS;

	while (lock_status == 0) {
		lock_status = qla4_83xx_rd_reg(ha, QLA83XX_FLASH_LOCK);
		if (lock_status)
			break;

		if (++timeout >= QLA83XX_FLASH_LOCK_TIMEOUT / 20) {
			lock_owner = qla4_83xx_rd_reg(ha,
						      QLA83XX_FLASH_LOCK_ID);
			ql4_printk(KERN_ERR, ha, "%s: flash lock by func %d failed, held by func %d\n",
				   __func__, ha->func_num, lock_owner);
			ret_val = QLA_ERROR;
			break;
		}
		msleep(20);
	}

	qla4_83xx_wr_reg(ha, QLA83XX_FLASH_LOCK_ID, ha->func_num);
	return ret_val;
}

static void qla4_83xx_flash_unlock(struct scsi_qla_host *ha)
{
	/* Reading FLASH_UNLOCK register unlocks the Flash */
	qla4_83xx_wr_reg(ha, QLA83XX_FLASH_LOCK_ID, 0xFF);
	qla4_83xx_rd_reg(ha, QLA83XX_FLASH_UNLOCK);
}

int qla4_83xx_flash_read_u32(struct scsi_qla_host *ha, uint32_t flash_addr,
			     uint8_t *p_data, int u32_word_count)
{
	int i;
	uint32_t u32_word;
	uint32_t addr = flash_addr;
	int ret_val = QLA_SUCCESS;

	ret_val = qla4_83xx_flash_lock(ha);
	if (ret_val == QLA_ERROR)
		goto exit_lock_error;

	if (addr & 0x03) {
		ql4_printk(KERN_ERR, ha, "%s: Illegal addr = 0x%x\n",
			   __func__, addr);
		ret_val = QLA_ERROR;
		goto exit_flash_read;
	}

	for (i = 0; i < u32_word_count; i++) {
		ret_val = qla4_83xx_wr_reg_indirect(ha,
						    QLA83XX_FLASH_DIRECT_WINDOW,
						    (addr & 0xFFFF0000));
		if (ret_val == QLA_ERROR) {
			ql4_printk(KERN_ERR, ha, "%s: failed to write addr 0x%x to FLASH_DIRECT_WINDOW\n!",
				   __func__, addr);
			goto exit_flash_read;
		}

		ret_val = qla4_83xx_rd_reg_indirect(ha,
						QLA83XX_FLASH_DIRECT_DATA(addr),
						&u32_word);
		if (ret_val == QLA_ERROR) {
			ql4_printk(KERN_ERR, ha, "%s: failed to read addr 0x%x!\n",
				   __func__, addr);
			goto exit_flash_read;
		}

		*(__le32 *)p_data = le32_to_cpu(u32_word);
		p_data = p_data + 4;
		addr = addr + 4;
	}

exit_flash_read:
	qla4_83xx_flash_unlock(ha);

exit_lock_error:
	return ret_val;
}

int qla4_83xx_lockless_flash_read_u32(struct scsi_qla_host *ha,
				      uint32_t flash_addr, uint8_t *p_data,
				      int u32_word_count)
{
	uint32_t i;
	uint32_t u32_word;
	uint32_t flash_offset;
	uint32_t addr = flash_addr;
	int ret_val = QLA_SUCCESS;

	flash_offset = addr & (QLA83XX_FLASH_SECTOR_SIZE - 1);

	if (addr & 0x3) {
		ql4_printk(KERN_ERR, ha, "%s: Illegal addr = 0x%x\n",
			   __func__, addr);
		ret_val = QLA_ERROR;
		goto exit_lockless_read;
	}

	ret_val = qla4_83xx_wr_reg_indirect(ha, QLA83XX_FLASH_DIRECT_WINDOW,
					    addr);
	if (ret_val == QLA_ERROR) {
		ql4_printk(KERN_ERR, ha, "%s: failed to write addr 0x%x to FLASH_DIRECT_WINDOW!\n",
			   __func__, addr);
		goto exit_lockless_read;
	}

	/* Check if data is spread across multiple sectors  */
	if ((flash_offset + (u32_word_count * sizeof(uint32_t))) >
	    (QLA83XX_FLASH_SECTOR_SIZE - 1)) {

		/* Multi sector read */
		for (i = 0; i < u32_word_count; i++) {
			ret_val = qla4_83xx_rd_reg_indirect(ha,
						QLA83XX_FLASH_DIRECT_DATA(addr),
						&u32_word);
			if (ret_val == QLA_ERROR) {
				ql4_printk(KERN_ERR, ha, "%s: failed to read addr 0x%x!\n",
					   __func__, addr);
				goto exit_lockless_read;
			}

			*(__le32 *)p_data  = le32_to_cpu(u32_word);
			p_data = p_data + 4;
			addr = addr + 4;
			flash_offset = flash_offset + 4;

			if (flash_offset > (QLA83XX_FLASH_SECTOR_SIZE - 1)) {
				/* This write is needed once for each sector */
				ret_val = qla4_83xx_wr_reg_indirect(ha,
						   QLA83XX_FLASH_DIRECT_WINDOW,
						   addr);
				if (ret_val == QLA_ERROR) {
					ql4_printk(KERN_ERR, ha, "%s: failed to write addr 0x%x to FLASH_DIRECT_WINDOW!\n",
						   __func__, addr);
					goto exit_lockless_read;
				}
				flash_offset = 0;
			}
		}
	} else {
		/* Single sector read */
		for (i = 0; i < u32_word_count; i++) {
			ret_val = qla4_83xx_rd_reg_indirect(ha,
						QLA83XX_FLASH_DIRECT_DATA(addr),
						&u32_word);
			if (ret_val == QLA_ERROR) {
				ql4_printk(KERN_ERR, ha, "%s: failed to read addr 0x%x!\n",
					   __func__, addr);
				goto exit_lockless_read;
			}

			*(__le32 *)p_data = le32_to_cpu(u32_word);
			p_data = p_data + 4;
			addr = addr + 4;
		}
	}

exit_lockless_read:
	return ret_val;
}

void qla4_83xx_rom_lock_recovery(struct scsi_qla_host *ha)
{
	if (qla4_83xx_flash_lock(ha))
		ql4_printk(KERN_INFO, ha, "%s: Resetting rom lock\n", __func__);

	/*
	 * We got the lock, or someone else is holding the lock
	 * since we are restting, forcefully unlock
	 */
	qla4_83xx_flash_unlock(ha);
}

#define INTENT_TO_RECOVER	0x01
#define PROCEED_TO_RECOVER	0x02

static int qla4_83xx_lock_recovery(struct scsi_qla_host *ha)
{

	uint32_t lock = 0, lockid;
	int ret_val = QLA_ERROR;

	lockid = ha->isp_ops->rd_reg_direct(ha, QLA83XX_DRV_LOCKRECOVERY);

	/* Check for other Recovery in progress, go wait */
	if ((lockid & 0x3) != 0)
		goto exit_lock_recovery;

	/* Intent to Recover */
	ha->isp_ops->wr_reg_direct(ha, QLA83XX_DRV_LOCKRECOVERY,
				   (ha->func_num << 2) | INTENT_TO_RECOVER);

	msleep(200);

	/* Check Intent to Recover is advertised */
	lockid = ha->isp_ops->rd_reg_direct(ha, QLA83XX_DRV_LOCKRECOVERY);
	if ((lockid & 0x3C) != (ha->func_num << 2))
		goto exit_lock_recovery;

	ql4_printk(KERN_INFO, ha, "%s: IDC Lock recovery initiated for func %d\n",
		   __func__, ha->func_num);

	/* Proceed to Recover */
	ha->isp_ops->wr_reg_direct(ha, QLA83XX_DRV_LOCKRECOVERY,
				   (ha->func_num << 2) | PROCEED_TO_RECOVER);

	/* Force Unlock */
	ha->isp_ops->wr_reg_direct(ha, QLA83XX_DRV_LOCK_ID, 0xFF);
	ha->isp_ops->rd_reg_direct(ha, QLA83XX_DRV_UNLOCK);

	/* Clear bits 0-5 in IDC_RECOVERY register*/
	ha->isp_ops->wr_reg_direct(ha, QLA83XX_DRV_LOCKRECOVERY, 0);

	/* Get lock */
	lock = ha->isp_ops->rd_reg_direct(ha, QLA83XX_DRV_LOCK);
	if (lock) {
		lockid = ha->isp_ops->rd_reg_direct(ha, QLA83XX_DRV_LOCK_ID);
		lockid = ((lockid + (1 << 8)) & ~0xFF) | ha->func_num;
		ha->isp_ops->wr_reg_direct(ha, QLA83XX_DRV_LOCK_ID, lockid);
		ret_val = QLA_SUCCESS;
	}

exit_lock_recovery:
	return ret_val;
}

#define	QLA83XX_DRV_LOCK_MSLEEP		200

int qla4_83xx_drv_lock(struct scsi_qla_host *ha)
{
	int timeout = 0;
	uint32_t status = 0;
	int ret_val = QLA_SUCCESS;
	uint32_t first_owner = 0;
	uint32_t tmo_owner = 0;
	uint32_t lock_id;
	uint32_t func_num;
	uint32_t lock_cnt;

	while (status == 0) {
		status = qla4_83xx_rd_reg(ha, QLA83XX_DRV_LOCK);
		if (status) {
			/* Increment Counter (8-31) and update func_num (0-7) on
			 * getting a successful lock  */
			lock_id = qla4_83xx_rd_reg(ha, QLA83XX_DRV_LOCK_ID);
			lock_id = ((lock_id + (1 << 8)) & ~0xFF) | ha->func_num;
			qla4_83xx_wr_reg(ha, QLA83XX_DRV_LOCK_ID, lock_id);
			break;
		}

		if (timeout == 0)
			/* Save counter + ID of function holding the lock for
			 * first failure */
			first_owner = ha->isp_ops->rd_reg_direct(ha,
							  QLA83XX_DRV_LOCK_ID);

		if (++timeout >=
		    (QLA83XX_DRV_LOCK_TIMEOUT / QLA83XX_DRV_LOCK_MSLEEP)) {
			tmo_owner = qla4_83xx_rd_reg(ha, QLA83XX_DRV_LOCK_ID);
			func_num = tmo_owner & 0xFF;
			lock_cnt = tmo_owner >> 8;
			ql4_printk(KERN_INFO, ha, "%s: Lock by func %d failed after 2s, lock held by func %d, lock count %d, first_owner %d\n",
				   __func__, ha->func_num, func_num, lock_cnt,
				   (first_owner & 0xFF));

			if (first_owner != tmo_owner) {
				/* Some other driver got lock, OR same driver
				 * got lock again (counter value changed), when
				 * we were waiting for lock.
				 * Retry for another 2 sec */
				ql4_printk(KERN_INFO, ha, "%s: IDC lock failed for func %d\n",
					   __func__, ha->func_num);
				timeout = 0;
			} else {
				/* Same driver holding lock > 2sec.
				 * Force Recovery */
				ret_val = qla4_83xx_lock_recovery(ha);
				if (ret_val == QLA_SUCCESS) {
					/* Recovered and got lock */
					ql4_printk(KERN_INFO, ha, "%s: IDC lock Recovery by %d successful\n",
						   __func__, ha->func_num);
					break;
				}
				/* Recovery Failed, some other function
				 * has the lock, wait for 2secs and retry */
				ql4_printk(KERN_INFO, ha, "%s: IDC lock Recovery by %d failed, Retrying timeout\n",
					   __func__, ha->func_num);
				timeout = 0;
			}
		}
		msleep(QLA83XX_DRV_LOCK_MSLEEP);
	}

	return ret_val;
}

void qla4_83xx_drv_unlock(struct scsi_qla_host *ha)
{
	int id;

	id = qla4_83xx_rd_reg(ha, QLA83XX_DRV_LOCK_ID);

	if ((id & 0xFF) != ha->func_num) {
		ql4_printk(KERN_ERR, ha, "%s: IDC Unlock by %d failed, lock owner is %d\n",
			   __func__, ha->func_num, (id & 0xFF));
		return;
	}

	/* Keep lock counter value, update the ha->func_num to 0xFF */
	qla4_83xx_wr_reg(ha, QLA83XX_DRV_LOCK_ID, (id | 0xFF));
	qla4_83xx_rd_reg(ha, QLA83XX_DRV_UNLOCK);
}

void qla4_83xx_set_idc_dontreset(struct scsi_qla_host *ha)
{
	uint32_t idc_ctrl;

	idc_ctrl = qla4_83xx_rd_reg(ha, QLA83XX_IDC_DRV_CTRL);
	idc_ctrl |= DONTRESET_BIT0;
	qla4_83xx_wr_reg(ha, QLA83XX_IDC_DRV_CTRL, idc_ctrl);
	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: idc_ctrl = %d\n", __func__,
			  idc_ctrl));
}

void qla4_83xx_clear_idc_dontreset(struct scsi_qla_host *ha)
{
	uint32_t idc_ctrl;

	idc_ctrl = qla4_83xx_rd_reg(ha, QLA83XX_IDC_DRV_CTRL);
	idc_ctrl &= ~DONTRESET_BIT0;
	qla4_83xx_wr_reg(ha, QLA83XX_IDC_DRV_CTRL, idc_ctrl);
	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: idc_ctrl = %d\n", __func__,
			  idc_ctrl));
}

int qla4_83xx_idc_dontreset(struct scsi_qla_host *ha)
{
	uint32_t idc_ctrl;

	idc_ctrl = qla4_83xx_rd_reg(ha, QLA83XX_IDC_DRV_CTRL);
	return idc_ctrl & DONTRESET_BIT0;
}

/*-------------------------IDC State Machine ---------------------*/

enum {
	UNKNOWN_CLASS = 0,
	NIC_CLASS,
	FCOE_CLASS,
	ISCSI_CLASS
};

struct device_info {
	int func_num;
	int device_type;
	int port_num;
};

int qla4_83xx_can_perform_reset(struct scsi_qla_host *ha)
{
	uint32_t drv_active;
	uint32_t dev_part, dev_part1, dev_part2;
	int i;
	struct device_info device_map[16];
	int func_nibble;
	int nibble;
	int nic_present = 0;
	int iscsi_present = 0;
	int iscsi_func_low = 0;

	/* Use the dev_partition register to determine the PCI function number
	 * and then check drv_active register to see which driver is loaded */
	dev_part1 = qla4_83xx_rd_reg(ha,
				     ha->reg_tbl[QLA8XXX_CRB_DEV_PART_INFO]);
	dev_part2 = qla4_83xx_rd_reg(ha, QLA83XX_CRB_DEV_PART_INFO2);
	drv_active = qla4_83xx_rd_reg(ha, ha->reg_tbl[QLA8XXX_CRB_DRV_ACTIVE]);

	/* Each function has 4 bits in dev_partition Info register,
	 * Lower 2 bits - device type, Upper 2 bits - physical port number */
	dev_part = dev_part1;
	for (i = nibble = 0; i <= 15; i++, nibble++) {
		func_nibble = dev_part & (0xF << (nibble * 4));
		func_nibble >>= (nibble * 4);
		device_map[i].func_num = i;
		device_map[i].device_type = func_nibble & 0x3;
		device_map[i].port_num = func_nibble & 0xC;

		if (device_map[i].device_type == NIC_CLASS) {
			if (drv_active & (1 << device_map[i].func_num)) {
				nic_present++;
				break;
			}
		} else if (device_map[i].device_type == ISCSI_CLASS) {
			if (drv_active & (1 << device_map[i].func_num)) {
				if (!iscsi_present ||
				    (iscsi_present &&
				     (iscsi_func_low > device_map[i].func_num)))
					iscsi_func_low = device_map[i].func_num;

				iscsi_present++;
			}
		}

		/* For function_num[8..15] get info from dev_part2 register */
		if (nibble == 7) {
			nibble = 0;
			dev_part = dev_part2;
		}
	}

	/* NIC, iSCSI and FCOE are the Reset owners based on order, NIC gets
	 * precedence over iSCSI and FCOE and iSCSI over FCOE, based on drivers
	 * present. */
	if (!nic_present && (ha->func_num == iscsi_func_low)) {
		DEBUG2(ql4_printk(KERN_INFO, ha,
				  "%s: can reset - NIC not present and lower iSCSI function is %d\n",
				  __func__, ha->func_num));
		return 1;
	}

	return 0;
}

/**
 * qla4_83xx_need_reset_handler - Code to start reset sequence
 * @ha: pointer to adapter structure
 *
 * Note: IDC lock must be held upon entry
 **/
void qla4_83xx_need_reset_handler(struct scsi_qla_host *ha)
{
	uint32_t dev_state, drv_state, drv_active;
	unsigned long reset_timeout, dev_init_timeout;

	ql4_printk(KERN_INFO, ha, "%s: Performing ISP error recovery\n",
		   __func__);

	if (!test_bit(AF_8XXX_RST_OWNER, &ha->flags)) {
		DEBUG2(ql4_printk(KERN_INFO, ha, "%s: reset acknowledged\n",
				  __func__));
		qla4_8xxx_set_rst_ready(ha);

		/* Non-reset owners ACK Reset and wait for device INIT state
		 * as part of Reset Recovery by Reset Owner */
		dev_init_timeout = jiffies + (ha->nx_dev_init_timeout * HZ);

		do {
			if (time_after_eq(jiffies, dev_init_timeout)) {
				ql4_printk(KERN_INFO, ha, "%s: Non Reset owner dev init timeout\n",
					   __func__);
				break;
			}

			ha->isp_ops->idc_unlock(ha);
			msleep(1000);
			ha->isp_ops->idc_lock(ha);

			dev_state = qla4_8xxx_rd_direct(ha,
							QLA8XXX_CRB_DEV_STATE);
		} while (dev_state == QLA8XXX_DEV_NEED_RESET);
	} else {
		qla4_8xxx_set_rst_ready(ha);
		reset_timeout = jiffies + (ha->nx_reset_timeout * HZ);
		drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
		drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);

		ql4_printk(KERN_INFO, ha, "%s: drv_state = 0x%x, drv_active = 0x%x\n",
			   __func__, drv_state, drv_active);

		while (drv_state != drv_active) {
			if (time_after_eq(jiffies, reset_timeout)) {
				ql4_printk(KERN_INFO, ha, "%s: %s: RESET TIMEOUT! drv_state: 0x%08x, drv_active: 0x%08x\n",
					   __func__, DRIVER_NAME, drv_state,
					   drv_active);
				break;
			}

			ha->isp_ops->idc_unlock(ha);
			msleep(1000);
			ha->isp_ops->idc_lock(ha);

			drv_state = qla4_8xxx_rd_direct(ha,
							QLA8XXX_CRB_DRV_STATE);
			drv_active = qla4_8xxx_rd_direct(ha,
							QLA8XXX_CRB_DRV_ACTIVE);
		}

		if (drv_state != drv_active) {
			ql4_printk(KERN_INFO, ha, "%s: Reset_owner turning off drv_active of non-acking function 0x%x\n",
				   __func__, (drv_active ^ drv_state));
			drv_active = drv_active & drv_state;
			qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_ACTIVE,
					    drv_active);
		}

		clear_bit(AF_8XXX_RST_OWNER, &ha->flags);
		/* Start Reset Recovery */
		qla4_8xxx_device_bootstrap(ha);
	}
}

void qla4_83xx_get_idc_param(struct scsi_qla_host *ha)
{
	uint32_t idc_params, ret_val;

	ret_val = qla4_83xx_flash_read_u32(ha, QLA83XX_IDC_PARAM_ADDR,
					   (uint8_t *)&idc_params, 1);
	if (ret_val == QLA_SUCCESS) {
		ha->nx_dev_init_timeout = idc_params & 0xFFFF;
		ha->nx_reset_timeout = (idc_params >> 16) & 0xFFFF;
	} else {
		ha->nx_dev_init_timeout = ROM_DEV_INIT_TIMEOUT;
		ha->nx_reset_timeout = ROM_DRV_RESET_ACK_TIMEOUT;
	}

	DEBUG2(ql4_printk(KERN_DEBUG, ha,
			  "%s: ha->nx_dev_init_timeout = %d, ha->nx_reset_timeout = %d\n",
			  __func__, ha->nx_dev_init_timeout,
			  ha->nx_reset_timeout));
}

/*-------------------------Reset Sequence Functions-----------------------*/

static void qla4_83xx_dump_reset_seq_hdr(struct scsi_qla_host *ha)
{
	uint8_t *phdr;

	if (!ha->reset_tmplt.buff) {
		ql4_printk(KERN_ERR, ha, "%s: Error: Invalid reset_seq_template\n",
			   __func__);
		return;
	}

	phdr = ha->reset_tmplt.buff;

	DEBUG2(ql4_printk(KERN_INFO, ha,
			  "Reset Template: 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n",
			  *phdr, *(phdr+1), *(phdr+2), *(phdr+3), *(phdr+4),
			  *(phdr+5), *(phdr+6), *(phdr+7), *(phdr + 8),
			  *(phdr+9), *(phdr+10), *(phdr+11), *(phdr+12),
			  *(phdr+13), *(phdr+14), *(phdr+15)));
}

static int qla4_83xx_copy_bootloader(struct scsi_qla_host *ha)
{
	uint8_t *p_cache;
	uint32_t src, count, size;
	uint64_t dest;
	int ret_val = QLA_SUCCESS;

	src = QLA83XX_BOOTLOADER_FLASH_ADDR;
	dest = qla4_83xx_rd_reg(ha, QLA83XX_BOOTLOADER_ADDR);
	size = qla4_83xx_rd_reg(ha, QLA83XX_BOOTLOADER_SIZE);

	/* 128 bit alignment check */
	if (size & 0xF)
		size = (size + 16) & ~0xF;

	/* 16 byte count */
	count = size/16;

	p_cache = vmalloc(size);
	if (p_cache == NULL) {
		ql4_printk(KERN_ERR, ha, "%s: Failed to allocate memory for boot loader cache\n",
			   __func__);
		ret_val = QLA_ERROR;
		goto exit_copy_bootloader;
	}

	ret_val = qla4_83xx_lockless_flash_read_u32(ha, src, p_cache,
						    size / sizeof(uint32_t));
	if (ret_val == QLA_ERROR) {
		ql4_printk(KERN_ERR, ha, "%s: Error reading firmware from flash\n",
			   __func__);
		goto exit_copy_error;
	}
	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Read firmware from flash\n",
			  __func__));

	/* 128 bit/16 byte write to MS memory */
	ret_val = qla4_8xxx_ms_mem_write_128b(ha, dest, (uint32_t *)p_cache,
					      count);
	if (ret_val == QLA_ERROR) {
		ql4_printk(KERN_ERR, ha, "%s: Error writing firmware to MS\n",
			   __func__);
		goto exit_copy_error;
	}

	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Wrote firmware size %d to MS\n",
			  __func__, size));

exit_copy_error:
	vfree(p_cache);

exit_copy_bootloader:
	return ret_val;
}

static int qla4_83xx_check_cmd_peg_status(struct scsi_qla_host *ha)
{
	uint32_t val, ret_val = QLA_ERROR;
	int retries = CRB_CMDPEG_CHECK_RETRY_COUNT;

	do {
		val = qla4_83xx_rd_reg(ha, QLA83XX_CMDPEG_STATE);
		if (val == PHAN_INITIALIZE_COMPLETE) {
			DEBUG2(ql4_printk(KERN_INFO, ha,
					  "%s: Command Peg initialization complete. State=0x%x\n",
					  __func__, val));
			ret_val = QLA_SUCCESS;
			break;
		}
		msleep(CRB_CMDPEG_CHECK_DELAY);
	} while (--retries);

	return ret_val;
}

/**
 * qla4_83xx_poll_reg - Poll the given CRB addr for duration msecs till
 * value read ANDed with test_mask is equal to test_result.
 *
 * @ha : Pointer to adapter structure
 * @addr : CRB register address
 * @duration : Poll for total of "duration" msecs
 * @test_mask : Mask value read with "test_mask"
 * @test_result : Compare (value&test_mask) with test_result.
 **/
static int qla4_83xx_poll_reg(struct scsi_qla_host *ha, uint32_t addr,
			      int duration, uint32_t test_mask,
			      uint32_t test_result)
{
	uint32_t value;
	uint8_t retries;
	int ret_val = QLA_SUCCESS;

	ret_val = qla4_83xx_rd_reg_indirect(ha, addr, &value);
	if (ret_val == QLA_ERROR)
		goto exit_poll_reg;

	retries = duration / 10;
	do {
		if ((value & test_mask) != test_result) {
			msleep(duration / 10);
			ret_val = qla4_83xx_rd_reg_indirect(ha, addr, &value);
			if (ret_val == QLA_ERROR)
				goto exit_poll_reg;

			ret_val = QLA_ERROR;
		} else {
			ret_val = QLA_SUCCESS;
			break;
		}
	} while (retries--);

exit_poll_reg:
	if (ret_val == QLA_ERROR) {
		ha->reset_tmplt.seq_error++;
		ql4_printk(KERN_ERR, ha, "%s: Poll Failed:  0x%08x 0x%08x 0x%08x\n",
			   __func__, value, test_mask, test_result);
	}

	return ret_val;
}

static int qla4_83xx_reset_seq_checksum_test(struct scsi_qla_host *ha)
{
	uint32_t sum =  0;
	uint16_t *buff = (uint16_t *)ha->reset_tmplt.buff;
	int u16_count =  ha->reset_tmplt.hdr->size / sizeof(uint16_t);
	int ret_val;

	while (u16_count-- > 0)
		sum += *buff++;

	while (sum >> 16)
		sum = (sum & 0xFFFF) +  (sum >> 16);

	/* checksum of 0 indicates a valid template */
	if (~sum) {
		ret_val = QLA_SUCCESS;
	} else {
		ql4_printk(KERN_ERR, ha, "%s: Reset seq checksum failed\n",
			   __func__);
		ret_val = QLA_ERROR;
	}

	return ret_val;
}

/**
 * qla4_83xx_read_reset_template - Read Reset Template from Flash
 * @ha: Pointer to adapter structure
 **/
void qla4_83xx_read_reset_template(struct scsi_qla_host *ha)
{
	uint8_t *p_buff;
	uint32_t addr, tmplt_hdr_def_size, tmplt_hdr_size;
	uint32_t ret_val;

	ha->reset_tmplt.seq_error = 0;
	ha->reset_tmplt.buff = vmalloc(QLA83XX_RESTART_TEMPLATE_SIZE);
	if (ha->reset_tmplt.buff == NULL) {
		ql4_printk(KERN_ERR, ha, "%s: Failed to allocate reset template resources\n",
			   __func__);
		goto exit_read_reset_template;
	}

	p_buff = ha->reset_tmplt.buff;
	addr = QLA83XX_RESET_TEMPLATE_ADDR;

	tmplt_hdr_def_size = sizeof(struct qla4_83xx_reset_template_hdr) /
				    sizeof(uint32_t);

	DEBUG2(ql4_printk(KERN_INFO, ha,
			  "%s: Read template hdr size %d from Flash\n",
			  __func__, tmplt_hdr_def_size));

	/* Copy template header from flash */
	ret_val = qla4_83xx_flash_read_u32(ha, addr, p_buff,
					   tmplt_hdr_def_size);
	if (ret_val != QLA_SUCCESS) {
		ql4_printk(KERN_ERR, ha, "%s: Failed to read reset template\n",
			   __func__);
		goto exit_read_template_error;
	}

	ha->reset_tmplt.hdr =
		(struct qla4_83xx_reset_template_hdr *)ha->reset_tmplt.buff;

	/* Validate the template header size and signature */
	tmplt_hdr_size = ha->reset_tmplt.hdr->hdr_size/sizeof(uint32_t);
	if ((tmplt_hdr_size != tmplt_hdr_def_size) ||
	    (ha->reset_tmplt.hdr->signature != RESET_TMPLT_HDR_SIGNATURE)) {
		ql4_printk(KERN_ERR, ha, "%s: Template Header size %d is invalid, tmplt_hdr_def_size %d\n",
			   __func__, tmplt_hdr_size, tmplt_hdr_def_size);
		goto exit_read_template_error;
	}

	addr = QLA83XX_RESET_TEMPLATE_ADDR + ha->reset_tmplt.hdr->hdr_size;
	p_buff = ha->reset_tmplt.buff + ha->reset_tmplt.hdr->hdr_size;
	tmplt_hdr_def_size = (ha->reset_tmplt.hdr->size -
			      ha->reset_tmplt.hdr->hdr_size) / sizeof(uint32_t);

	DEBUG2(ql4_printk(KERN_INFO, ha,
			  "%s: Read rest of the template size %d\n",
			  __func__, ha->reset_tmplt.hdr->size));

	/* Copy rest of the template */
	ret_val = qla4_83xx_flash_read_u32(ha, addr, p_buff,
					   tmplt_hdr_def_size);
	if (ret_val != QLA_SUCCESS) {
		ql4_printk(KERN_ERR, ha, "%s: Failed to read reset template\n",
			   __func__);
		goto exit_read_template_error;
	}

	/* Integrity check */
	if (qla4_83xx_reset_seq_checksum_test(ha)) {
		ql4_printk(KERN_ERR, ha, "%s: Reset Seq checksum failed!\n",
			   __func__);
		goto exit_read_template_error;
	}
	DEBUG2(ql4_printk(KERN_INFO, ha,
			  "%s: Reset Seq checksum passed, Get stop, start and init seq offsets\n",
			  __func__));

	/* Get STOP, START, INIT sequence offsets */
	ha->reset_tmplt.init_offset = ha->reset_tmplt.buff +
				      ha->reset_tmplt.hdr->init_seq_offset;
	ha->reset_tmplt.start_offset = ha->reset_tmplt.buff +
				       ha->reset_tmplt.hdr->start_seq_offset;
	ha->reset_tmplt.stop_offset = ha->reset_tmplt.buff +
				      ha->reset_tmplt.hdr->hdr_size;
	qla4_83xx_dump_reset_seq_hdr(ha);

	goto exit_read_reset_template;

exit_read_template_error:
	vfree(ha->reset_tmplt.buff);

exit_read_reset_template:
	return;
}

/**
 * qla4_83xx_read_write_crb_reg - Read from raddr and write value to waddr.
 *
 * @ha : Pointer to adapter structure
 * @raddr : CRB address to read from
 * @waddr : CRB address to write to
 **/
static void qla4_83xx_read_write_crb_reg(struct scsi_qla_host *ha,
					 uint32_t raddr, uint32_t waddr)
{
	uint32_t value;

	qla4_83xx_rd_reg_indirect(ha, raddr, &value);
	qla4_83xx_wr_reg_indirect(ha, waddr, value);
}

/**
 * qla4_83xx_rmw_crb_reg - Read Modify Write crb register
 *
 * This function read value from raddr, AND with test_mask,
 * Shift Left,Right/OR/XOR with values RMW header and write value to waddr.
 *
 * @ha : Pointer to adapter structure
 * @raddr : CRB address to read from
 * @waddr : CRB address to write to
 * @p_rmw_hdr : header with shift/or/xor values.
 **/
static void qla4_83xx_rmw_crb_reg(struct scsi_qla_host *ha, uint32_t raddr,
				  uint32_t waddr,
				  struct qla4_83xx_rmw *p_rmw_hdr)
{
	uint32_t value;

	if (p_rmw_hdr->index_a)
		value = ha->reset_tmplt.array[p_rmw_hdr->index_a];
	else
		qla4_83xx_rd_reg_indirect(ha, raddr, &value);

	value &= p_rmw_hdr->test_mask;
	value <<= p_rmw_hdr->shl;
	value >>= p_rmw_hdr->shr;
	value |= p_rmw_hdr->or_value;
	value ^= p_rmw_hdr->xor_value;

	qla4_83xx_wr_reg_indirect(ha, waddr, value);

	return;
}

static void qla4_83xx_write_list(struct scsi_qla_host *ha,
				 struct qla4_83xx_reset_entry_hdr *p_hdr)
{
	struct qla4_83xx_entry *p_entry;
	uint32_t i;

	p_entry = (struct qla4_83xx_entry *)
		  ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));

	for (i = 0; i < p_hdr->count; i++, p_entry++) {
		qla4_83xx_wr_reg_indirect(ha, p_entry->arg1, p_entry->arg2);
		if (p_hdr->delay)
			udelay((uint32_t)(p_hdr->delay));
	}
}

static void qla4_83xx_read_write_list(struct scsi_qla_host *ha,
				      struct qla4_83xx_reset_entry_hdr *p_hdr)
{
	struct qla4_83xx_entry *p_entry;
	uint32_t i;

	p_entry = (struct qla4_83xx_entry *)
		  ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));

	for (i = 0; i < p_hdr->count; i++, p_entry++) {
		qla4_83xx_read_write_crb_reg(ha, p_entry->arg1, p_entry->arg2);
		if (p_hdr->delay)
			udelay((uint32_t)(p_hdr->delay));
	}
}

static void qla4_83xx_poll_list(struct scsi_qla_host *ha,
				struct qla4_83xx_reset_entry_hdr *p_hdr)
{
	long delay;
	struct qla4_83xx_entry *p_entry;
	struct qla4_83xx_poll *p_poll;
	uint32_t i;
	uint32_t value;

	p_poll = (struct qla4_83xx_poll *)
		 ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));

	/* Entries start after 8 byte qla4_83xx_poll, poll header contains
	 * the test_mask, test_value. */
	p_entry = (struct qla4_83xx_entry *)((char *)p_poll +
					     sizeof(struct qla4_83xx_poll));

	delay = (long)p_hdr->delay;
	if (!delay) {
		for (i = 0; i < p_hdr->count; i++, p_entry++) {
			qla4_83xx_poll_reg(ha, p_entry->arg1, delay,
					   p_poll->test_mask,
					   p_poll->test_value);
		}
	} else {
		for (i = 0; i < p_hdr->count; i++, p_entry++) {
			if (qla4_83xx_poll_reg(ha, p_entry->arg1, delay,
					       p_poll->test_mask,
					       p_poll->test_value)) {
				qla4_83xx_rd_reg_indirect(ha, p_entry->arg1,
							  &value);
				qla4_83xx_rd_reg_indirect(ha, p_entry->arg2,
							  &value);
			}
		}
	}
}

static void qla4_83xx_poll_write_list(struct scsi_qla_host *ha,
				      struct qla4_83xx_reset_entry_hdr *p_hdr)
{
	long delay;
	struct qla4_83xx_quad_entry *p_entry;
	struct qla4_83xx_poll *p_poll;
	uint32_t i;

	p_poll = (struct qla4_83xx_poll *)
		 ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
	p_entry = (struct qla4_83xx_quad_entry *)
		  ((char *)p_poll + sizeof(struct qla4_83xx_poll));
	delay = (long)p_hdr->delay;

	for (i = 0; i < p_hdr->count; i++, p_entry++) {
		qla4_83xx_wr_reg_indirect(ha, p_entry->dr_addr,
					  p_entry->dr_value);
		qla4_83xx_wr_reg_indirect(ha, p_entry->ar_addr,
					  p_entry->ar_value);
		if (delay) {
			if (qla4_83xx_poll_reg(ha, p_entry->ar_addr, delay,
					       p_poll->test_mask,
					       p_poll->test_value)) {
				DEBUG2(ql4_printk(KERN_INFO, ha,
						  "%s: Timeout Error: poll list, item_num %d, entry_num %d\n",
						  __func__, i,
						  ha->reset_tmplt.seq_index));
			}
		}
	}
}

static void qla4_83xx_read_modify_write(struct scsi_qla_host *ha,
					struct qla4_83xx_reset_entry_hdr *p_hdr)
{
	struct qla4_83xx_entry *p_entry;
	struct qla4_83xx_rmw *p_rmw_hdr;
	uint32_t i;

	p_rmw_hdr = (struct qla4_83xx_rmw *)
		    ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
	p_entry = (struct qla4_83xx_entry *)
		  ((char *)p_rmw_hdr + sizeof(struct qla4_83xx_rmw));

	for (i = 0; i < p_hdr->count; i++, p_entry++) {
		qla4_83xx_rmw_crb_reg(ha, p_entry->arg1, p_entry->arg2,
				      p_rmw_hdr);
		if (p_hdr->delay)
			udelay((uint32_t)(p_hdr->delay));
	}
}

static void qla4_83xx_pause(struct scsi_qla_host *ha,
			    struct qla4_83xx_reset_entry_hdr *p_hdr)
{
	if (p_hdr->delay)
		mdelay((uint32_t)((long)p_hdr->delay));
}

static void qla4_83xx_poll_read_list(struct scsi_qla_host *ha,
				     struct qla4_83xx_reset_entry_hdr *p_hdr)
{
	long delay;
	int index;
	struct qla4_83xx_quad_entry *p_entry;
	struct qla4_83xx_poll *p_poll;
	uint32_t i;
	uint32_t value;

	p_poll = (struct qla4_83xx_poll *)
		 ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
	p_entry = (struct qla4_83xx_quad_entry *)
		  ((char *)p_poll + sizeof(struct qla4_83xx_poll));
	delay = (long)p_hdr->delay;

	for (i = 0; i < p_hdr->count; i++, p_entry++) {
		qla4_83xx_wr_reg_indirect(ha, p_entry->ar_addr,
					  p_entry->ar_value);
		if (delay) {
			if (qla4_83xx_poll_reg(ha, p_entry->ar_addr, delay,
					       p_poll->test_mask,
					       p_poll->test_value)) {
				DEBUG2(ql4_printk(KERN_INFO, ha,
						  "%s: Timeout Error: poll list, Item_num %d, entry_num %d\n",
						  __func__, i,
						  ha->reset_tmplt.seq_index));
			} else {
				index = ha->reset_tmplt.array_index;
				qla4_83xx_rd_reg_indirect(ha, p_entry->dr_addr,
							  &value);
				ha->reset_tmplt.array[index++] = value;

				if (index == QLA83XX_MAX_RESET_SEQ_ENTRIES)
					ha->reset_tmplt.array_index = 1;
			}
		}
	}
}

static void qla4_83xx_seq_end(struct scsi_qla_host *ha,
			      struct qla4_83xx_reset_entry_hdr *p_hdr)
{
	ha->reset_tmplt.seq_end = 1;
}

static void qla4_83xx_template_end(struct scsi_qla_host *ha,
				   struct qla4_83xx_reset_entry_hdr *p_hdr)
{
	ha->reset_tmplt.template_end = 1;

	if (ha->reset_tmplt.seq_error == 0) {
		DEBUG2(ql4_printk(KERN_INFO, ha,
				  "%s: Reset sequence completed SUCCESSFULLY.\n",
				  __func__));
	} else {
		ql4_printk(KERN_ERR, ha, "%s: Reset sequence completed with some timeout errors.\n",
			   __func__);
	}
}

/**
 * qla4_83xx_process_reset_template - Process reset template.
 *
 * Process all entries in reset template till entry with SEQ_END opcode,
 * which indicates end of the reset template processing. Each entry has a
 * Reset Entry header, entry opcode/command, with size of the entry, number
 * of entries in sub-sequence and delay in microsecs or timeout in millisecs.
 *
 * @ha : Pointer to adapter structure
 * @p_buff : Common reset entry header.
 **/
static void qla4_83xx_process_reset_template(struct scsi_qla_host *ha,
					     char *p_buff)
{
	int index, entries;
	struct qla4_83xx_reset_entry_hdr *p_hdr;
	char *p_entry = p_buff;

	ha->reset_tmplt.seq_end = 0;
	ha->reset_tmplt.template_end = 0;
	entries = ha->reset_tmplt.hdr->entries;
	index = ha->reset_tmplt.seq_index;

	for (; (!ha->reset_tmplt.seq_end) && (index  < entries); index++) {

		p_hdr = (struct qla4_83xx_reset_entry_hdr *)p_entry;
		switch (p_hdr->cmd) {
		case OPCODE_NOP:
			break;
		case OPCODE_WRITE_LIST:
			qla4_83xx_write_list(ha, p_hdr);
			break;
		case OPCODE_READ_WRITE_LIST:
			qla4_83xx_read_write_list(ha, p_hdr);
			break;
		case OPCODE_POLL_LIST:
			qla4_83xx_poll_list(ha, p_hdr);
			break;
		case OPCODE_POLL_WRITE_LIST:
			qla4_83xx_poll_write_list(ha, p_hdr);
			break;
		case OPCODE_READ_MODIFY_WRITE:
			qla4_83xx_read_modify_write(ha, p_hdr);
			break;
		case OPCODE_SEQ_PAUSE:
			qla4_83xx_pause(ha, p_hdr);
			break;
		case OPCODE_SEQ_END:
			qla4_83xx_seq_end(ha, p_hdr);
			break;
		case OPCODE_TMPL_END:
			qla4_83xx_template_end(ha, p_hdr);
			break;
		case OPCODE_POLL_READ_LIST:
			qla4_83xx_poll_read_list(ha, p_hdr);
			break;
		default:
			ql4_printk(KERN_ERR, ha, "%s: Unknown command ==> 0x%04x on entry = %d\n",
				   __func__, p_hdr->cmd, index);
			break;
		}

		/* Set pointer to next entry in the sequence. */
		p_entry += p_hdr->size;
	}

	ha->reset_tmplt.seq_index = index;
}

static void qla4_83xx_process_stop_seq(struct scsi_qla_host *ha)
{
	ha->reset_tmplt.seq_index = 0;
	qla4_83xx_process_reset_template(ha, ha->reset_tmplt.stop_offset);

	if (ha->reset_tmplt.seq_end != 1)
		ql4_printk(KERN_ERR, ha, "%s: Abrupt STOP Sub-Sequence end.\n",
			   __func__);
}

static void qla4_83xx_process_start_seq(struct scsi_qla_host *ha)
{
	qla4_83xx_process_reset_template(ha, ha->reset_tmplt.start_offset);

	if (ha->reset_tmplt.template_end != 1)
		ql4_printk(KERN_ERR, ha, "%s: Abrupt START Sub-Sequence end.\n",
			   __func__);
}

static void qla4_83xx_process_init_seq(struct scsi_qla_host *ha)
{
	qla4_83xx_process_reset_template(ha, ha->reset_tmplt.init_offset);

	if (ha->reset_tmplt.seq_end != 1)
		ql4_printk(KERN_ERR, ha, "%s: Abrupt INIT Sub-Sequence end.\n",
			   __func__);
}

static int qla4_83xx_restart(struct scsi_qla_host *ha)
{
	int ret_val = QLA_SUCCESS;
	uint32_t idc_ctrl;

	qla4_83xx_process_stop_seq(ha);

	/*
	 * Collect minidump.
	 * If IDC_CTRL BIT1 is set, clear it on going to INIT state and
	 * don't collect minidump
	 */
	idc_ctrl = qla4_83xx_rd_reg(ha, QLA83XX_IDC_DRV_CTRL);
	if (idc_ctrl & GRACEFUL_RESET_BIT1) {
		qla4_83xx_wr_reg(ha, QLA83XX_IDC_DRV_CTRL,
				 (idc_ctrl & ~GRACEFUL_RESET_BIT1));
		ql4_printk(KERN_INFO, ha, "%s: Graceful RESET: Not collecting minidump\n",
			   __func__);
	} else {
		qla4_8xxx_get_minidump(ha);
	}

	qla4_83xx_process_init_seq(ha);

	if (qla4_83xx_copy_bootloader(ha)) {
		ql4_printk(KERN_ERR, ha, "%s: Copy bootloader, firmware restart failed!\n",
			   __func__);
		ret_val = QLA_ERROR;
		goto exit_restart;
	}

	qla4_83xx_wr_reg(ha, QLA83XX_FW_IMAGE_VALID, QLA83XX_BOOT_FROM_FLASH);
	qla4_83xx_process_start_seq(ha);

exit_restart:
	return ret_val;
}

int qla4_83xx_start_firmware(struct scsi_qla_host *ha)
{
	int ret_val = QLA_SUCCESS;

	ret_val = qla4_83xx_restart(ha);
	if (ret_val == QLA_ERROR) {
		ql4_printk(KERN_ERR, ha, "%s: Restart error\n", __func__);
		goto exit_start_fw;
	} else {
		DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Restart done\n",
				  __func__));
	}

	ret_val = qla4_83xx_check_cmd_peg_status(ha);
	if (ret_val == QLA_ERROR)
		ql4_printk(KERN_ERR, ha, "%s: Peg not initialized\n",
			   __func__);

exit_start_fw:
	return ret_val;
}

/*----------------------Interrupt Related functions ---------------------*/

static void qla4_83xx_disable_iocb_intrs(struct scsi_qla_host *ha)
{
	if (test_and_clear_bit(AF_83XX_IOCB_INTR_ON, &ha->flags))
		qla4_8xxx_intr_disable(ha);
}

static void qla4_83xx_disable_mbox_intrs(struct scsi_qla_host *ha)
{
	uint32_t mb_int, ret;

	if (test_and_clear_bit(AF_83XX_MBOX_INTR_ON, &ha->flags)) {
		ret = readl(&ha->qla4_83xx_reg->mbox_int);
		mb_int = ret & ~INT_ENABLE_FW_MB;
		writel(mb_int, &ha->qla4_83xx_reg->mbox_int);
		writel(1, &ha->qla4_83xx_reg->leg_int_mask);
	}
}

void qla4_83xx_disable_intrs(struct scsi_qla_host *ha)
{
	qla4_83xx_disable_mbox_intrs(ha);
	qla4_83xx_disable_iocb_intrs(ha);
}

static void qla4_83xx_enable_iocb_intrs(struct scsi_qla_host *ha)
{
	if (!test_bit(AF_83XX_IOCB_INTR_ON, &ha->flags)) {
		qla4_8xxx_intr_enable(ha);
		set_bit(AF_83XX_IOCB_INTR_ON, &ha->flags);
	}
}

void qla4_83xx_enable_mbox_intrs(struct scsi_qla_host *ha)
{
	uint32_t mb_int;

	if (!test_bit(AF_83XX_MBOX_INTR_ON, &ha->flags)) {
		mb_int = INT_ENABLE_FW_MB;
		writel(mb_int, &ha->qla4_83xx_reg->mbox_int);
		writel(0, &ha->qla4_83xx_reg->leg_int_mask);
		set_bit(AF_83XX_MBOX_INTR_ON, &ha->flags);
	}
}


void qla4_83xx_enable_intrs(struct scsi_qla_host *ha)
{
	qla4_83xx_enable_mbox_intrs(ha);
	qla4_83xx_enable_iocb_intrs(ha);
}


void qla4_83xx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
			      int incount)
{
	int i;

	/* Load all mailbox registers, except mailbox 0. */
	for (i = 1; i < incount; i++)
		writel(mbx_cmd[i], &ha->qla4_83xx_reg->mailbox_in[i]);

	writel(mbx_cmd[0], &ha->qla4_83xx_reg->mailbox_in[0]);

	/* Set Host Interrupt register to 1, to tell the firmware that
	 * a mailbox command is pending. Firmware after reading the
	 * mailbox command, clears the host interrupt register */
	writel(HINT_MBX_INT_PENDING, &ha->qla4_83xx_reg->host_intr);
}

void qla4_83xx_process_mbox_intr(struct scsi_qla_host *ha, int outcount)
{
	int intr_status;

	intr_status = readl(&ha->qla4_83xx_reg->risc_intr);
	if (intr_status) {
		ha->mbox_status_count = outcount;
		ha->isp_ops->interrupt_service_routine(ha, intr_status);
	}
}

/**
 * qla4_83xx_isp_reset - Resets ISP and aborts all outstanding commands.
 * @ha: pointer to host adapter structure.
 **/
int qla4_83xx_isp_reset(struct scsi_qla_host *ha)
{
	int rval;
	uint32_t dev_state;

	ha->isp_ops->idc_lock(ha);
	dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);

	if (ql4xdontresethba)
		qla4_83xx_set_idc_dontreset(ha);

	if (dev_state == QLA8XXX_DEV_READY) {
		/* If IDC_CTRL DONTRESETHBA_BIT0 is set dont do reset
		 * recovery */
		if (qla4_83xx_idc_dontreset(ha) == DONTRESET_BIT0) {
			ql4_printk(KERN_ERR, ha, "%s: Reset recovery disabled\n",
				   __func__);
			rval = QLA_ERROR;
			goto exit_isp_reset;
		}

		DEBUG2(ql4_printk(KERN_INFO, ha, "%s: HW State: NEED RESET\n",
				  __func__));
		qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
				    QLA8XXX_DEV_NEED_RESET);

	} else {
		/* If device_state is NEED_RESET, go ahead with
		 * Reset,irrespective of ql4xdontresethba. This is to allow a
		 * non-reset-owner to force a reset. Non-reset-owner sets
		 * the IDC_CTRL BIT0 to prevent Reset-owner from doing a Reset
		 * and then forces a Reset by setting device_state to
		 * NEED_RESET. */
		DEBUG2(ql4_printk(KERN_INFO, ha,
				  "%s: HW state already set to NEED_RESET\n",
				  __func__));
	}

	/* For ISP8324 and ISP8042, Reset owner is NIC, iSCSI or FCOE based on
	 * priority and which drivers are present. Unlike ISP8022, the function
	 * setting NEED_RESET, may not be the Reset owner. */
	if (qla4_83xx_can_perform_reset(ha))
		set_bit(AF_8XXX_RST_OWNER, &ha->flags);

	ha->isp_ops->idc_unlock(ha);
	rval = qla4_8xxx_device_state_handler(ha);

	ha->isp_ops->idc_lock(ha);
	qla4_8xxx_clear_rst_ready(ha);
exit_isp_reset:
	ha->isp_ops->idc_unlock(ha);

	if (rval == QLA_SUCCESS)
		clear_bit(AF_FW_RECOVERY, &ha->flags);

	return rval;
}

static void qla4_83xx_dump_pause_control_regs(struct scsi_qla_host *ha)
{
	u32 val = 0, val1 = 0;
	int i, status = QLA_SUCCESS;

	status = qla4_83xx_rd_reg_indirect(ha, QLA83XX_SRE_SHIM_CONTROL, &val);
	DEBUG2(ql4_printk(KERN_INFO, ha, "SRE-Shim Ctrl:0x%x\n", val));

	/* Port 0 Rx Buffer Pause Threshold Registers. */
	DEBUG2(ql4_printk(KERN_INFO, ha,
		"Port 0 Rx Buffer Pause Threshold Registers[TC7..TC0]:"));
	for (i = 0; i < 8; i++) {
		status = qla4_83xx_rd_reg_indirect(ha,
				QLA83XX_PORT0_RXB_PAUSE_THRS + (i * 0x4), &val);
		DEBUG2(pr_info("0x%x ", val));
	}

	DEBUG2(pr_info("\n"));

	/* Port 1 Rx Buffer Pause Threshold Registers. */
	DEBUG2(ql4_printk(KERN_INFO, ha,
		"Port 1 Rx Buffer Pause Threshold Registers[TC7..TC0]:"));
	for (i = 0; i < 8; i++) {
		status = qla4_83xx_rd_reg_indirect(ha,
				QLA83XX_PORT1_RXB_PAUSE_THRS + (i * 0x4), &val);
		DEBUG2(pr_info("0x%x  ", val));
	}

	DEBUG2(pr_info("\n"));

	/* Port 0 RxB Traffic Class Max Cell Registers. */
	DEBUG2(ql4_printk(KERN_INFO, ha,
		"Port 0 RxB Traffic Class Max Cell Registers[3..0]:"));
	for (i = 0; i < 4; i++) {
		status = qla4_83xx_rd_reg_indirect(ha,
			       QLA83XX_PORT0_RXB_TC_MAX_CELL + (i * 0x4), &val);
		DEBUG2(pr_info("0x%x  ", val));
	}

	DEBUG2(pr_info("\n"));

	/* Port 1 RxB Traffic Class Max Cell Registers. */
	DEBUG2(ql4_printk(KERN_INFO, ha,
		"Port 1 RxB Traffic Class Max Cell Registers[3..0]:"));
	for (i = 0; i < 4; i++) {
		status = qla4_83xx_rd_reg_indirect(ha,
			       QLA83XX_PORT1_RXB_TC_MAX_CELL + (i * 0x4), &val);
		DEBUG2(pr_info("0x%x  ", val));
	}

	DEBUG2(pr_info("\n"));

	/* Port 0 RxB Rx Traffic Class Stats. */
	DEBUG2(ql4_printk(KERN_INFO, ha,
			  "Port 0 RxB Rx Traffic Class Stats [TC7..TC0]"));
	for (i = 7; i >= 0; i--) {
		status = qla4_83xx_rd_reg_indirect(ha,
						   QLA83XX_PORT0_RXB_TC_STATS,
						   &val);
		val &= ~(0x7 << 29);    /* Reset bits 29 to 31 */
		qla4_83xx_wr_reg_indirect(ha, QLA83XX_PORT0_RXB_TC_STATS,
					  (val | (i << 29)));
		status = qla4_83xx_rd_reg_indirect(ha,
						   QLA83XX_PORT0_RXB_TC_STATS,
						   &val);
		DEBUG2(pr_info("0x%x  ", val));
	}

	DEBUG2(pr_info("\n"));

	/* Port 1 RxB Rx Traffic Class Stats. */
	DEBUG2(ql4_printk(KERN_INFO, ha,
			  "Port 1 RxB Rx Traffic Class Stats [TC7..TC0]"));
	for (i = 7; i >= 0; i--) {
		status = qla4_83xx_rd_reg_indirect(ha,
						   QLA83XX_PORT1_RXB_TC_STATS,
						   &val);
		val &= ~(0x7 << 29);    /* Reset bits 29 to 31 */
		qla4_83xx_wr_reg_indirect(ha, QLA83XX_PORT1_RXB_TC_STATS,
					  (val | (i << 29)));
		status = qla4_83xx_rd_reg_indirect(ha,
						   QLA83XX_PORT1_RXB_TC_STATS,
						   &val);
		DEBUG2(pr_info("0x%x  ", val));
	}

	DEBUG2(pr_info("\n"));

	status = qla4_83xx_rd_reg_indirect(ha, QLA83XX_PORT2_IFB_PAUSE_THRS,
					   &val);
	status = qla4_83xx_rd_reg_indirect(ha, QLA83XX_PORT3_IFB_PAUSE_THRS,
					   &val1);

	DEBUG2(ql4_printk(KERN_INFO, ha,
			  "IFB-Pause Thresholds: Port 2:0x%x, Port 3:0x%x\n",
			  val, val1));
}

static void __qla4_83xx_disable_pause(struct scsi_qla_host *ha)
{
	int i;

	/* set SRE-Shim Control Register */
	qla4_83xx_wr_reg_indirect(ha, QLA83XX_SRE_SHIM_CONTROL,
				  QLA83XX_SET_PAUSE_VAL);

	for (i = 0; i < 8; i++) {
		/* Port 0 Rx Buffer Pause Threshold Registers. */
		qla4_83xx_wr_reg_indirect(ha,
				      QLA83XX_PORT0_RXB_PAUSE_THRS + (i * 0x4),
				      QLA83XX_SET_PAUSE_VAL);
		/* Port 1 Rx Buffer Pause Threshold Registers. */
		qla4_83xx_wr_reg_indirect(ha,
				      QLA83XX_PORT1_RXB_PAUSE_THRS + (i * 0x4),
				      QLA83XX_SET_PAUSE_VAL);
	}

	for (i = 0; i < 4; i++) {
		/* Port 0 RxB Traffic Class Max Cell Registers. */
		qla4_83xx_wr_reg_indirect(ha,
				     QLA83XX_PORT0_RXB_TC_MAX_CELL + (i * 0x4),
				     QLA83XX_SET_TC_MAX_CELL_VAL);
		/* Port 1 RxB Traffic Class Max Cell Registers. */
		qla4_83xx_wr_reg_indirect(ha,
				     QLA83XX_PORT1_RXB_TC_MAX_CELL + (i * 0x4),
				     QLA83XX_SET_TC_MAX_CELL_VAL);
	}

	qla4_83xx_wr_reg_indirect(ha, QLA83XX_PORT2_IFB_PAUSE_THRS,
				  QLA83XX_SET_PAUSE_VAL);
	qla4_83xx_wr_reg_indirect(ha, QLA83XX_PORT3_IFB_PAUSE_THRS,
				  QLA83XX_SET_PAUSE_VAL);

	ql4_printk(KERN_INFO, ha, "Disabled pause frames successfully.\n");
}

/**
 * qla4_83xx_eport_init - Initialize EPort.
 * @ha: Pointer to host adapter structure.
 *
 * If EPort hardware is in reset state before disabling pause, there would be
 * serious hardware wedging issues. To prevent this perform eport init everytime
 * before disabling pause frames.
 **/
static void qla4_83xx_eport_init(struct scsi_qla_host *ha)
{
	/* Clear the 8 registers */
	qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_REG, 0x0);
	qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_PORT0, 0x0);
	qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_PORT1, 0x0);
	qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_PORT2, 0x0);
	qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_PORT3, 0x0);
	qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_SRE_SHIM, 0x0);
	qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_EPG_SHIM, 0x0);
	qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_ETHER_PCS, 0x0);

	/* Write any value to Reset Control register */
	qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_CONTROL, 0xFF);

	ql4_printk(KERN_INFO, ha, "EPORT is out of reset.\n");
}

void qla4_83xx_disable_pause(struct scsi_qla_host *ha)
{
	ha->isp_ops->idc_lock(ha);
	/* Before disabling pause frames, ensure that eport is not in reset */
	qla4_83xx_eport_init(ha);
	qla4_83xx_dump_pause_control_regs(ha);
	__qla4_83xx_disable_pause(ha);
	ha->isp_ops->idc_unlock(ha);
}

/**
 * qla4_83xx_is_detached - Check if we are marked invisible.
 * @ha: Pointer to host adapter structure.
 **/
int qla4_83xx_is_detached(struct scsi_qla_host *ha)
{
	uint32_t drv_active;

	drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);

	if (test_bit(AF_INIT_DONE, &ha->flags) &&
	    !(drv_active & (1 << ha->func_num))) {
		DEBUG2(ql4_printk(KERN_INFO, ha, "%s: drv_active = 0x%X\n",
				  __func__, drv_active));
		return QLA_SUCCESS;
	}

	return QLA_ERROR;
}
