/*
 * This file is part of the Chelsio FCoE driver for Linux.
 *
 * Copyright (c) 2008-2012 Chelsio Communications, Inc. All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/compiler.h>
#include <linux/slab.h>
#include <asm/page.h>
#include <linux/cache.h>

#include "csio_hw.h"
#include "csio_wr.h"
#include "csio_mb.h"
#include "csio_defs.h"

int csio_intr_coalesce_cnt;		/* value:SGE_INGRESS_RX_THRESHOLD[0] */
static int csio_sge_thresh_reg;		/* SGE_INGRESS_RX_THRESHOLD[0] */

int csio_intr_coalesce_time = 10;	/* value:SGE_TIMER_VALUE_1 */
static int csio_sge_timer_reg = 1;

#define CSIO_SET_FLBUF_SIZE(_hw, _reg, _val)				\
	csio_wr_reg32((_hw), (_val), SGE_FL_BUFFER_SIZE##_reg##_A)

static void
csio_get_flbuf_size(struct csio_hw *hw, struct csio_sge *sge, uint32_t reg)
{
	sge->sge_fl_buf_size[reg] = csio_rd_reg32(hw, SGE_FL_BUFFER_SIZE0_A +
							reg * sizeof(uint32_t));
}

/* Free list buffer size */
static inline uint32_t
csio_wr_fl_bufsz(struct csio_sge *sge, struct csio_dma_buf *buf)
{
	return sge->sge_fl_buf_size[buf->paddr & 0xF];
}

/* Size of the egress queue status page */
static inline uint32_t
csio_wr_qstat_pgsz(struct csio_hw *hw)
{
	return (hw->wrm.sge.sge_control & EGRSTATUSPAGESIZE_F) ?  128 : 64;
}

/* Ring freelist doorbell */
static inline void
csio_wr_ring_fldb(struct csio_hw *hw, struct csio_q *flq)
{
	/*
	 * Ring the doorbell only when we have atleast CSIO_QCREDIT_SZ
	 * number of bytes in the freelist queue. This translates to atleast
	 * 8 freelist buffer pointers (since each pointer is 8 bytes).
	 */
	if (flq->inc_idx >= 8) {
		csio_wr_reg32(hw, DBPRIO_F | QID_V(flq->un.fl.flid) |
				  PIDX_T5_V(flq->inc_idx / 8) | DBTYPE_F,
				  MYPF_REG(SGE_PF_KDOORBELL_A));
		flq->inc_idx &= 7;
	}
}

/* Write a 0 cidx increment value to enable SGE interrupts for this queue */
static void
csio_wr_sge_intr_enable(struct csio_hw *hw, uint16_t iqid)
{
	csio_wr_reg32(hw, CIDXINC_V(0)		|
			  INGRESSQID_V(iqid)	|
			  TIMERREG_V(X_TIMERREG_RESTART_COUNTER),
			  MYPF_REG(SGE_PF_GTS_A));
}

/*
 * csio_wr_fill_fl - Populate the FL buffers of a FL queue.
 * @hw: HW module.
 * @flq: Freelist queue.
 *
 * Fill up freelist buffer entries with buffers of size specified
 * in the size register.
 *
 */
static int
csio_wr_fill_fl(struct csio_hw *hw, struct csio_q *flq)
{
	struct csio_wrm *wrm = csio_hw_to_wrm(hw);
	struct csio_sge *sge = &wrm->sge;
	__be64 *d = (__be64 *)(flq->vstart);
	struct csio_dma_buf *buf = &flq->un.fl.bufs[0];
	uint64_t paddr;
	int sreg = flq->un.fl.sreg;
	int n = flq->credits;

	while (n--) {
		buf->len = sge->sge_fl_buf_size[sreg];
		buf->vaddr = pci_alloc_consistent(hw->pdev, buf->len,
						  &buf->paddr);
		if (!buf->vaddr) {
			csio_err(hw, "Could only fill %d buffers!\n", n + 1);
			return -ENOMEM;
		}

		paddr = buf->paddr | (sreg & 0xF);

		*d++ = cpu_to_be64(paddr);
		buf++;
	}

	return 0;
}

/*
 * csio_wr_update_fl -
 * @hw: HW module.
 * @flq: Freelist queue.
 *
 *
 */
static inline void
csio_wr_update_fl(struct csio_hw *hw, struct csio_q *flq, uint16_t n)
{

	flq->inc_idx += n;
	flq->pidx += n;
	if (unlikely(flq->pidx >= flq->credits))
		flq->pidx -= (uint16_t)flq->credits;

	CSIO_INC_STATS(flq, n_flq_refill);
}

/*
 * csio_wr_alloc_q - Allocate a WR queue and initialize it.
 * @hw: HW module
 * @qsize: Size of the queue in bytes
 * @wrsize: Since of WR in this queue, if fixed.
 * @type: Type of queue (Ingress/Egress/Freelist)
 * @owner: Module that owns this queue.
 * @nflb: Number of freelist buffers for FL.
 * @sreg: What is the FL buffer size register?
 * @iq_int_handler: Ingress queue handler in INTx mode.
 *
 * This function allocates and sets up a queue for the caller
 * of size qsize, aligned at the required boundary. This is subject to
 * be free entries being available in the queue array. If one is found,
 * it is initialized with the allocated queue, marked as being used (owner),
 * and a handle returned to the caller in form of the queue's index
 * into the q_arr array.
 * If user has indicated a freelist (by specifying nflb > 0), create
 * another queue (with its own index into q_arr) for the freelist. Allocate
 * memory for DMA buffer metadata (vaddr, len etc). Save off the freelist
 * idx in the ingress queue's flq.idx. This is how a Freelist is associated
 * with its owning ingress queue.
 */
int
csio_wr_alloc_q(struct csio_hw *hw, uint32_t qsize, uint32_t wrsize,
		uint16_t type, void *owner, uint32_t nflb, int sreg,
		iq_handler_t iq_intx_handler)
{
	struct csio_wrm *wrm = csio_hw_to_wrm(hw);
	struct csio_q	*q, *flq;
	int		free_idx = wrm->free_qidx;
	int		ret_idx = free_idx;
	uint32_t	qsz;
	int flq_idx;

	if (free_idx >= wrm->num_q) {
		csio_err(hw, "No more free queues.\n");
		return -1;
	}

	switch (type) {
	case CSIO_EGRESS:
		qsz = ALIGN(qsize, CSIO_QCREDIT_SZ) + csio_wr_qstat_pgsz(hw);
		break;
	case CSIO_INGRESS:
		switch (wrsize) {
		case 16:
		case 32:
		case 64:
		case 128:
			break;
		default:
			csio_err(hw, "Invalid Ingress queue WR size:%d\n",
				    wrsize);
			return -1;
		}

		/*
		 * Number of elements must be a multiple of 16
		 * So this includes status page size
		 */
		qsz = ALIGN(qsize/wrsize, 16) * wrsize;

		break;
	case CSIO_FREELIST:
		qsz = ALIGN(qsize/wrsize, 8) * wrsize + csio_wr_qstat_pgsz(hw);
		break;
	default:
		csio_err(hw, "Invalid queue type: 0x%x\n", type);
		return -1;
	}

	q = wrm->q_arr[free_idx];

	q->vstart = pci_zalloc_consistent(hw->pdev, qsz, &q->pstart);
	if (!q->vstart) {
		csio_err(hw,
			 "Failed to allocate DMA memory for "
			 "queue at id: %d size: %d\n", free_idx, qsize);
		return -1;
	}

	q->type		= type;
	q->owner	= owner;
	q->pidx		= q->cidx = q->inc_idx = 0;
	q->size		= qsz;
	q->wr_sz	= wrsize;	/* If using fixed size WRs */

	wrm->free_qidx++;

	if (type == CSIO_INGRESS) {
		/* Since queue area is set to zero */
		q->un.iq.genbit	= 1;

		/*
		 * Ingress queue status page size is always the size of
		 * the ingress queue entry.
		 */
		q->credits	= (qsz - q->wr_sz) / q->wr_sz;
		q->vwrap	= (void *)((uintptr_t)(q->vstart) + qsz
							- q->wr_sz);

		/* Allocate memory for FL if requested */
		if (nflb > 0) {
			flq_idx = csio_wr_alloc_q(hw, nflb * sizeof(__be64),
						  sizeof(__be64), CSIO_FREELIST,
						  owner, 0, sreg, NULL);
			if (flq_idx == -1) {
				csio_err(hw,
					 "Failed to allocate FL queue"
					 " for IQ idx:%d\n", free_idx);
				return -1;
			}

			/* Associate the new FL with the Ingress quue */
			q->un.iq.flq_idx = flq_idx;

			flq = wrm->q_arr[q->un.iq.flq_idx];
			flq->un.fl.bufs = kzalloc(flq->credits *
						  sizeof(struct csio_dma_buf),
						  GFP_KERNEL);
			if (!flq->un.fl.bufs) {
				csio_err(hw,
					 "Failed to allocate FL queue bufs"
					 " for IQ idx:%d\n", free_idx);
				return -1;
			}

			flq->un.fl.packen = 0;
			flq->un.fl.offset = 0;
			flq->un.fl.sreg = sreg;

			/* Fill up the free list buffers */
			if (csio_wr_fill_fl(hw, flq))
				return -1;

			/*
			 * Make sure in a FLQ, atleast 1 credit (8 FL buffers)
			 * remains unpopulated,otherwise HW thinks
			 * FLQ is empty.
			 */
			flq->pidx = flq->inc_idx = flq->credits - 8;
		} else {
			q->un.iq.flq_idx = -1;
		}

		/* Associate the IQ INTx handler. */
		q->un.iq.iq_intx_handler = iq_intx_handler;

		csio_q_iqid(hw, ret_idx) = CSIO_MAX_QID;

	} else if (type == CSIO_EGRESS) {
		q->credits = (qsz - csio_wr_qstat_pgsz(hw)) / CSIO_QCREDIT_SZ;
		q->vwrap   = (void *)((uintptr_t)(q->vstart) + qsz
						- csio_wr_qstat_pgsz(hw));
		csio_q_eqid(hw, ret_idx) = CSIO_MAX_QID;
	} else { /* Freelist */
		q->credits = (qsz - csio_wr_qstat_pgsz(hw)) / sizeof(__be64);
		q->vwrap   = (void *)((uintptr_t)(q->vstart) + qsz
						- csio_wr_qstat_pgsz(hw));
		csio_q_flid(hw, ret_idx) = CSIO_MAX_QID;
	}

	return ret_idx;
}

/*
 * csio_wr_iq_create_rsp - Response handler for IQ creation.
 * @hw: The HW module.
 * @mbp: Mailbox.
 * @iq_idx: Ingress queue that got created.
 *
 * Handle FW_IQ_CMD mailbox completion. Save off the assigned IQ/FL ids.
 */
static int
csio_wr_iq_create_rsp(struct csio_hw *hw, struct csio_mb *mbp, int iq_idx)
{
	struct csio_iq_params iqp;
	enum fw_retval retval;
	uint32_t iq_id;
	int flq_idx;

	memset(&iqp, 0, sizeof(struct csio_iq_params));

	csio_mb_iq_alloc_write_rsp(hw, mbp, &retval, &iqp);

	if (retval != FW_SUCCESS) {
		csio_err(hw, "IQ cmd returned 0x%x!\n", retval);
		mempool_free(mbp, hw->mb_mempool);
		return -EINVAL;
	}

	csio_q_iqid(hw, iq_idx)		= iqp.iqid;
	csio_q_physiqid(hw, iq_idx)	= iqp.physiqid;
	csio_q_pidx(hw, iq_idx)		= csio_q_cidx(hw, iq_idx) = 0;
	csio_q_inc_idx(hw, iq_idx)	= 0;

	/* Actual iq-id. */
	iq_id = iqp.iqid - hw->wrm.fw_iq_start;

	/* Set the iq-id to iq map table. */
	if (iq_id >= CSIO_MAX_IQ) {
		csio_err(hw,
			 "Exceeding MAX_IQ(%d) supported!"
			 " iqid:%d rel_iqid:%d FW iq_start:%d\n",
			 CSIO_MAX_IQ, iq_id, iqp.iqid, hw->wrm.fw_iq_start);
		mempool_free(mbp, hw->mb_mempool);
		return -EINVAL;
	}
	csio_q_set_intr_map(hw, iq_idx, iq_id);

	/*
	 * During FW_IQ_CMD, FW sets interrupt_sent bit to 1 in the SGE
	 * ingress context of this queue. This will block interrupts to
	 * this queue until the next GTS write. Therefore, we do a
	 * 0-cidx increment GTS write for this queue just to clear the
	 * interrupt_sent bit. This will re-enable interrupts to this
	 * queue.
	 */
	csio_wr_sge_intr_enable(hw, iqp.physiqid);

	flq_idx = csio_q_iq_flq_idx(hw, iq_idx);
	if (flq_idx != -1) {
		struct csio_q *flq = hw->wrm.q_arr[flq_idx];

		csio_q_flid(hw, flq_idx) = iqp.fl0id;
		csio_q_cidx(hw, flq_idx) = 0;
		csio_q_pidx(hw, flq_idx)    = csio_q_credits(hw, flq_idx) - 8;
		csio_q_inc_idx(hw, flq_idx) = csio_q_credits(hw, flq_idx) - 8;

		/* Now update SGE about the buffers allocated during init */
		csio_wr_ring_fldb(hw, flq);
	}

	mempool_free(mbp, hw->mb_mempool);

	return 0;
}

/*
 * csio_wr_iq_create - Configure an Ingress queue with FW.
 * @hw: The HW module.
 * @priv: Private data object.
 * @iq_idx: Ingress queue index in the WR module.
 * @vec: MSIX vector.
 * @portid: PCIE Channel to be associated with this queue.
 * @async: Is this a FW asynchronous message handling queue?
 * @cbfn: Completion callback.
 *
 * This API configures an ingress queue with FW by issuing a FW_IQ_CMD mailbox
 * with alloc/write bits set.
 */
int
csio_wr_iq_create(struct csio_hw *hw, void *priv, int iq_idx,
		  uint32_t vec, uint8_t portid, bool async,
		  void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct csio_mb  *mbp;
	struct csio_iq_params iqp;
	int flq_idx;

	memset(&iqp, 0, sizeof(struct csio_iq_params));
	csio_q_portid(hw, iq_idx) = portid;

	mbp = mempool_alloc(hw->mb_mempool, GFP_ATOMIC);
	if (!mbp) {
		csio_err(hw, "IQ command out of memory!\n");
		return -ENOMEM;
	}

	switch (hw->intr_mode) {
	case CSIO_IM_INTX:
	case CSIO_IM_MSI:
		/* For interrupt forwarding queue only */
		if (hw->intr_iq_idx == iq_idx)
			iqp.iqandst	= X_INTERRUPTDESTINATION_PCIE;
		else
			iqp.iqandst	= X_INTERRUPTDESTINATION_IQ;
		iqp.iqandstindex	=
			csio_q_physiqid(hw, hw->intr_iq_idx);
		break;
	case CSIO_IM_MSIX:
		iqp.iqandst		= X_INTERRUPTDESTINATION_PCIE;
		iqp.iqandstindex	= (uint16_t)vec;
		break;
	case CSIO_IM_NONE:
		mempool_free(mbp, hw->mb_mempool);
		return -EINVAL;
	}

	/* Pass in the ingress queue cmd parameters */
	iqp.pfn			= hw->pfn;
	iqp.vfn			= 0;
	iqp.iq_start		= 1;
	iqp.viid		= 0;
	iqp.type		= FW_IQ_TYPE_FL_INT_CAP;
	iqp.iqasynch		= async;
	if (csio_intr_coalesce_cnt)
		iqp.iqanus	= X_UPDATESCHEDULING_COUNTER_OPTTIMER;
	else
		iqp.iqanus	= X_UPDATESCHEDULING_TIMER;
	iqp.iqanud		= X_UPDATEDELIVERY_INTERRUPT;
	iqp.iqpciech		= portid;
	iqp.iqintcntthresh	= (uint8_t)csio_sge_thresh_reg;

	switch (csio_q_wr_sz(hw, iq_idx)) {
	case 16:
		iqp.iqesize = 0; break;
	case 32:
		iqp.iqesize = 1; break;
	case 64:
		iqp.iqesize = 2; break;
	case 128:
		iqp.iqesize = 3; break;
	}

	iqp.iqsize		= csio_q_size(hw, iq_idx) /
						csio_q_wr_sz(hw, iq_idx);
	iqp.iqaddr		= csio_q_pstart(hw, iq_idx);

	flq_idx = csio_q_iq_flq_idx(hw, iq_idx);
	if (flq_idx != -1) {
		struct csio_q *flq = hw->wrm.q_arr[flq_idx];

		iqp.fl0paden	= 1;
		iqp.fl0packen	= flq->un.fl.packen ? 1 : 0;
		iqp.fl0fbmin	= X_FETCHBURSTMIN_64B;
		iqp.fl0fbmax	= X_FETCHBURSTMAX_512B;
		iqp.fl0size	= csio_q_size(hw, flq_idx) / CSIO_QCREDIT_SZ;
		iqp.fl0addr	= csio_q_pstart(hw, flq_idx);
	}

	csio_mb_iq_alloc_write(hw, mbp, priv, CSIO_MB_DEFAULT_TMO, &iqp, cbfn);

	if (csio_mb_issue(hw, mbp)) {
		csio_err(hw, "Issue of IQ cmd failed!\n");
		mempool_free(mbp, hw->mb_mempool);
		return -EINVAL;
	}

	if (cbfn != NULL)
		return 0;

	return csio_wr_iq_create_rsp(hw, mbp, iq_idx);
}

/*
 * csio_wr_eq_create_rsp - Response handler for EQ creation.
 * @hw: The HW module.
 * @mbp: Mailbox.
 * @eq_idx: Egress queue that got created.
 *
 * Handle FW_EQ_OFLD_CMD mailbox completion. Save off the assigned EQ ids.
 */
static int
csio_wr_eq_cfg_rsp(struct csio_hw *hw, struct csio_mb *mbp, int eq_idx)
{
	struct csio_eq_params eqp;
	enum fw_retval retval;

	memset(&eqp, 0, sizeof(struct csio_eq_params));

	csio_mb_eq_ofld_alloc_write_rsp(hw, mbp, &retval, &eqp);

	if (retval != FW_SUCCESS) {
		csio_err(hw, "EQ OFLD cmd returned 0x%x!\n", retval);
		mempool_free(mbp, hw->mb_mempool);
		return -EINVAL;
	}

	csio_q_eqid(hw, eq_idx)	= (uint16_t)eqp.eqid;
	csio_q_physeqid(hw, eq_idx) = (uint16_t)eqp.physeqid;
	csio_q_pidx(hw, eq_idx)	= csio_q_cidx(hw, eq_idx) = 0;
	csio_q_inc_idx(hw, eq_idx) = 0;

	mempool_free(mbp, hw->mb_mempool);

	return 0;
}

/*
 * csio_wr_eq_create - Configure an Egress queue with FW.
 * @hw: HW module.
 * @priv: Private data.
 * @eq_idx: Egress queue index in the WR module.
 * @iq_idx: Associated ingress queue index.
 * @cbfn: Completion callback.
 *
 * This API configures a offload egress queue with FW by issuing a
 * FW_EQ_OFLD_CMD  (with alloc + write ) mailbox.
 */
int
csio_wr_eq_create(struct csio_hw *hw, void *priv, int eq_idx,
		  int iq_idx, uint8_t portid,
		  void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	struct csio_mb  *mbp;
	struct csio_eq_params eqp;

	memset(&eqp, 0, sizeof(struct csio_eq_params));

	mbp = mempool_alloc(hw->mb_mempool, GFP_ATOMIC);
	if (!mbp) {
		csio_err(hw, "EQ command out of memory!\n");
		return -ENOMEM;
	}

	eqp.pfn			= hw->pfn;
	eqp.vfn			= 0;
	eqp.eqstart		= 1;
	eqp.hostfcmode		= X_HOSTFCMODE_STATUS_PAGE;
	eqp.iqid		= csio_q_iqid(hw, iq_idx);
	eqp.fbmin		= X_FETCHBURSTMIN_64B;
	eqp.fbmax		= X_FETCHBURSTMAX_512B;
	eqp.cidxfthresh		= 0;
	eqp.pciechn		= portid;
	eqp.eqsize		= csio_q_size(hw, eq_idx) / CSIO_QCREDIT_SZ;
	eqp.eqaddr		= csio_q_pstart(hw, eq_idx);

	csio_mb_eq_ofld_alloc_write(hw, mbp, priv, CSIO_MB_DEFAULT_TMO,
				    &eqp, cbfn);

	if (csio_mb_issue(hw, mbp)) {
		csio_err(hw, "Issue of EQ OFLD cmd failed!\n");
		mempool_free(mbp, hw->mb_mempool);
		return -EINVAL;
	}

	if (cbfn != NULL)
		return 0;

	return csio_wr_eq_cfg_rsp(hw, mbp, eq_idx);
}

/*
 * csio_wr_iq_destroy_rsp - Response handler for IQ removal.
 * @hw: The HW module.
 * @mbp: Mailbox.
 * @iq_idx: Ingress queue that was freed.
 *
 * Handle FW_IQ_CMD (free) mailbox completion.
 */
static int
csio_wr_iq_destroy_rsp(struct csio_hw *hw, struct csio_mb *mbp, int iq_idx)
{
	enum fw_retval retval = csio_mb_fw_retval(mbp);
	int rv = 0;

	if (retval != FW_SUCCESS)
		rv = -EINVAL;

	mempool_free(mbp, hw->mb_mempool);

	return rv;
}

/*
 * csio_wr_iq_destroy - Free an ingress queue.
 * @hw: The HW module.
 * @priv: Private data object.
 * @iq_idx: Ingress queue index to destroy
 * @cbfn: Completion callback.
 *
 * This API frees an ingress queue by issuing the FW_IQ_CMD
 * with the free bit set.
 */
static int
csio_wr_iq_destroy(struct csio_hw *hw, void *priv, int iq_idx,
		   void (*cbfn)(struct csio_hw *, struct csio_mb *))
{
	int rv = 0;
	struct csio_mb  *mbp;
	struct csio_iq_params iqp;
	int flq_idx;

	memset(&iqp, 0, sizeof(struct csio_iq_params));

	mbp = mempool_alloc(hw->mb_mempool, GFP_ATOMIC);
	if (!mbp)
		return -ENOMEM;

	iqp.pfn		= hw->pfn;
	iqp.vfn		= 0;
	iqp.iqid	= csio_q_iqid(hw, iq_idx);
	iqp.type	= FW_IQ_TYPE_FL_INT_CAP;

	flq_idx = csio_q_iq_flq_idx(hw, iq_idx);
	if (flq_idx != -1)
		iqp.fl0id = csio_q_flid(hw, flq_idx);
	else
		iqp.fl0id = 0xFFFF;

	iqp.fl1id = 0xFFFF;

	csio_mb_iq_free(hw, mbp, priv, CSIO_MB_DEFAULT_TMO, &iqp, cbfn);

	rv = csio_mb_issue(hw, mbp);
	if (rv != 0) {
		mempool_free(mbp, hw->mb_mempool);
		return rv;
	}

	if (cbfn != NULL)
		return 0;

	return csio_wr_iq_destroy_rsp(hw, mbp, iq_idx);
}

/*
 * csio_wr_eq_destroy_rsp - Response handler for OFLD EQ creation.
 * @hw: The HW module.
 * @mbp: Mailbox.
 * @eq_idx: Egress queue that was freed.
 *
 * Handle FW_OFLD_EQ_CMD (free) mailbox completion.
 */
static int
csio_wr_eq_destroy_rsp(struct csio_hw *hw, struct csio_mb *mbp, int eq_idx)
{
	enum fw_retval retval = csio_mb_fw_retval(mbp);
	int rv = 0;

	if (retval != FW_SUCCESS)
		rv = -EINVAL;

	mempool_free(mbp, hw->mb_mempool);

	return rv;
}

/*
 * csio_wr_eq_destroy - Free an Egress queue.
 * @hw: The HW module.
 * @priv: Private data object.
 * @eq_idx: Egress queue index to destroy
 * @cbfn: Completion callback.
 *
 * This API frees an Egress queue by issuing the FW_EQ_OFLD_CMD
 * with the free bit set.
 */
static int
csio_wr_eq_destroy(struct csio_hw *hw, void *priv, int eq_idx,
		   void (*cbfn) (struct csio_hw *, struct csio_mb *))
{
	int rv = 0;
	struct csio_mb  *mbp;
	struct csio_eq_params eqp;

	memset(&eqp, 0, sizeof(struct csio_eq_params));

	mbp = mempool_alloc(hw->mb_mempool, GFP_ATOMIC);
	if (!mbp)
		return -ENOMEM;

	eqp.pfn		= hw->pfn;
	eqp.vfn		= 0;
	eqp.eqid	= csio_q_eqid(hw, eq_idx);

	csio_mb_eq_ofld_free(hw, mbp, priv, CSIO_MB_DEFAULT_TMO, &eqp, cbfn);

	rv = csio_mb_issue(hw, mbp);
	if (rv != 0) {
		mempool_free(mbp, hw->mb_mempool);
		return rv;
	}

	if (cbfn != NULL)
		return 0;

	return csio_wr_eq_destroy_rsp(hw, mbp, eq_idx);
}

/*
 * csio_wr_cleanup_eq_stpg - Cleanup Egress queue status page
 * @hw: HW module
 * @qidx: Egress queue index
 *
 * Cleanup the Egress queue status page.
 */
static void
csio_wr_cleanup_eq_stpg(struct csio_hw *hw, int qidx)
{
	struct csio_q	*q = csio_hw_to_wrm(hw)->q_arr[qidx];
	struct csio_qstatus_page *stp = (struct csio_qstatus_page *)q->vwrap;

	memset(stp, 0, sizeof(*stp));
}

/*
 * csio_wr_cleanup_iq_ftr - Cleanup Footer entries in IQ
 * @hw: HW module
 * @qidx: Ingress queue index
 *
 * Cleanup the footer entries in the given ingress queue,
 * set to 1 the internal copy of genbit.
 */
static void
csio_wr_cleanup_iq_ftr(struct csio_hw *hw, int qidx)
{
	struct csio_wrm *wrm	= csio_hw_to_wrm(hw);
	struct csio_q	*q	= wrm->q_arr[qidx];
	void *wr;
	struct csio_iqwr_footer *ftr;
	uint32_t i = 0;

	/* set to 1 since we are just about zero out genbit */
	q->un.iq.genbit = 1;

	for (i = 0; i < q->credits; i++) {
		/* Get the WR */
		wr = (void *)((uintptr_t)q->vstart +
					   (i * q->wr_sz));
		/* Get the footer */
		ftr = (struct csio_iqwr_footer *)((uintptr_t)wr +
					  (q->wr_sz - sizeof(*ftr)));
		/* Zero out footer */
		memset(ftr, 0, sizeof(*ftr));
	}
}

int
csio_wr_destroy_queues(struct csio_hw *hw, bool cmd)
{
	int i, flq_idx;
	struct csio_q *q;
	struct csio_wrm *wrm = csio_hw_to_wrm(hw);
	int rv;

	for (i = 0; i < wrm->free_qidx; i++) {
		q = wrm->q_arr[i];

		switch (q->type) {
		case CSIO_EGRESS:
			if (csio_q_eqid(hw, i) != CSIO_MAX_QID) {
				csio_wr_cleanup_eq_stpg(hw, i);
				if (!cmd) {
					csio_q_eqid(hw, i) = CSIO_MAX_QID;
					continue;
				}

				rv = csio_wr_eq_destroy(hw, NULL, i, NULL);
				if ((rv == -EBUSY) || (rv == -ETIMEDOUT))
					cmd = false;

				csio_q_eqid(hw, i) = CSIO_MAX_QID;
			}
		case CSIO_INGRESS:
			if (csio_q_iqid(hw, i) != CSIO_MAX_QID) {
				csio_wr_cleanup_iq_ftr(hw, i);
				if (!cmd) {
					csio_q_iqid(hw, i) = CSIO_MAX_QID;
					flq_idx = csio_q_iq_flq_idx(hw, i);
					if (flq_idx != -1)
						csio_q_flid(hw, flq_idx) =
								CSIO_MAX_QID;
					continue;
				}

				rv = csio_wr_iq_destroy(hw, NULL, i, NULL);
				if ((rv == -EBUSY) || (rv == -ETIMEDOUT))
					cmd = false;

				csio_q_iqid(hw, i) = CSIO_MAX_QID;
				flq_idx = csio_q_iq_flq_idx(hw, i);
				if (flq_idx != -1)
					csio_q_flid(hw, flq_idx) = CSIO_MAX_QID;
			}
		default:
			break;
		}
	}

	hw->flags &= ~CSIO_HWF_Q_FW_ALLOCED;

	return 0;
}

/*
 * csio_wr_get - Get requested size of WR entry/entries from queue.
 * @hw: HW module.
 * @qidx: Index of queue.
 * @size: Cumulative size of Work request(s).
 * @wrp: Work request pair.
 *
 * If requested credits are available, return the start address of the
 * work request in the work request pair. Set pidx accordingly and
 * return.
 *
 * NOTE about WR pair:
 * ==================
 * A WR can start towards the end of a queue, and then continue at the
 * beginning, since the queue is considered to be circular. This will
 * require a pair of address/size to be passed back to the caller -
 * hence Work request pair format.
 */
int
csio_wr_get(struct csio_hw *hw, int qidx, uint32_t size,
	    struct csio_wr_pair *wrp)
{
	struct csio_wrm *wrm = csio_hw_to_wrm(hw);
	struct csio_q *q = wrm->q_arr[qidx];
	void *cwr = (void *)((uintptr_t)(q->vstart) +
						(q->pidx * CSIO_QCREDIT_SZ));
	struct csio_qstatus_page *stp = (struct csio_qstatus_page *)q->vwrap;
	uint16_t cidx = q->cidx = ntohs(stp->cidx);
	uint16_t pidx = q->pidx;
	uint32_t req_sz	= ALIGN(size, CSIO_QCREDIT_SZ);
	int req_credits	= req_sz / CSIO_QCREDIT_SZ;
	int credits;

	CSIO_DB_ASSERT(q->owner != NULL);
	CSIO_DB_ASSERT((qidx >= 0) && (qidx < wrm->free_qidx));
	CSIO_DB_ASSERT(cidx <= q->credits);

	/* Calculate credits */
	if (pidx > cidx) {
		credits = q->credits - (pidx - cidx) - 1;
	} else if (cidx > pidx) {
		credits = cidx - pidx - 1;
	} else {
		/* cidx == pidx, empty queue */
		credits = q->credits;
		CSIO_INC_STATS(q, n_qempty);
	}

	/*
	 * Check if we have enough credits.
	 * credits = 1 implies queue is full.
	 */
	if (!credits || (req_credits > credits)) {
		CSIO_INC_STATS(q, n_qfull);
		return -EBUSY;
	}

	/*
	 * If we are here, we have enough credits to satisfy the
	 * request. Check if we are near the end of q, and if WR spills over.
	 * If it does, use the first addr/size to cover the queue until
	 * the end. Fit the remainder portion of the request at the top
	 * of queue and return it in the second addr/len. Set pidx
	 * accordingly.
	 */
	if (unlikely(((uintptr_t)cwr + req_sz) > (uintptr_t)(q->vwrap))) {
		wrp->addr1 = cwr;
		wrp->size1 = (uint32_t)((uintptr_t)q->vwrap - (uintptr_t)cwr);
		wrp->addr2 = q->vstart;
		wrp->size2 = req_sz - wrp->size1;
		q->pidx	= (uint16_t)(ALIGN(wrp->size2, CSIO_QCREDIT_SZ) /
							CSIO_QCREDIT_SZ);
		CSIO_INC_STATS(q, n_qwrap);
		CSIO_INC_STATS(q, n_eq_wr_split);
	} else {
		wrp->addr1 = cwr;
		wrp->size1 = req_sz;
		wrp->addr2 = NULL;
		wrp->size2 = 0;
		q->pidx	+= (uint16_t)req_credits;

		/* We are the end of queue, roll back pidx to top of queue */
		if (unlikely(q->pidx == q->credits)) {
			q->pidx = 0;
			CSIO_INC_STATS(q, n_qwrap);
		}
	}

	q->inc_idx = (uint16_t)req_credits;

	CSIO_INC_STATS(q, n_tot_reqs);

	return 0;
}

/*
 * csio_wr_copy_to_wrp - Copies given data into WR.
 * @data_buf - Data buffer
 * @wrp - Work request pair.
 * @wr_off - Work request offset.
 * @data_len - Data length.
 *
 * Copies the given data in Work Request. Work request pair(wrp) specifies
 * address information of Work request.
 * Returns: none
 */
void
csio_wr_copy_to_wrp(void *data_buf, struct csio_wr_pair *wrp,
		   uint32_t wr_off, uint32_t data_len)
{
	uint32_t nbytes;

	/* Number of space available in buffer addr1 of WRP */
	nbytes = ((wrp->size1 - wr_off) >= data_len) ?
					data_len : (wrp->size1 - wr_off);

	memcpy((uint8_t *) wrp->addr1 + wr_off, data_buf, nbytes);
	data_len -= nbytes;

	/* Write the remaining data from the begining of circular buffer */
	if (data_len) {
		CSIO_DB_ASSERT(data_len <= wrp->size2);
		CSIO_DB_ASSERT(wrp->addr2 != NULL);
		memcpy(wrp->addr2, (uint8_t *) data_buf + nbytes, data_len);
	}
}

/*
 * csio_wr_issue - Notify chip of Work request.
 * @hw: HW module.
 * @qidx: Index of queue.
 * @prio: 0: Low priority, 1: High priority
 *
 * Rings the SGE Doorbell by writing the current producer index of the passed
 * in queue into the register.
 *
 */
int
csio_wr_issue(struct csio_hw *hw, int qidx, bool prio)
{
	struct csio_wrm *wrm = csio_hw_to_wrm(hw);
	struct csio_q *q = wrm->q_arr[qidx];

	CSIO_DB_ASSERT((qidx >= 0) && (qidx < wrm->free_qidx));

	wmb();
	/* Ring SGE Doorbell writing q->pidx into it */
	csio_wr_reg32(hw, DBPRIO_V(prio) | QID_V(q->un.eq.physeqid) |
			  PIDX_T5_V(q->inc_idx) | DBTYPE_F,
			  MYPF_REG(SGE_PF_KDOORBELL_A));
	q->inc_idx = 0;

	return 0;
}

static inline uint32_t
csio_wr_avail_qcredits(struct csio_q *q)
{
	if (q->pidx > q->cidx)
		return q->pidx - q->cidx;
	else if (q->cidx > q->pidx)
		return q->credits - (q->cidx - q->pidx);
	else
		return 0;	/* cidx == pidx, empty queue */
}

/*
 * csio_wr_inval_flq_buf - Invalidate a free list buffer entry.
 * @hw: HW module.
 * @flq: The freelist queue.
 *
 * Invalidate the driver's version of a freelist buffer entry,
 * without freeing the associated the DMA memory. The entry
 * to be invalidated is picked up from the current Free list
 * queue cidx.
 *
 */
static inline void
csio_wr_inval_flq_buf(struct csio_hw *hw, struct csio_q *flq)
{
	flq->cidx++;
	if (flq->cidx == flq->credits) {
		flq->cidx = 0;
		CSIO_INC_STATS(flq, n_qwrap);
	}
}

/*
 * csio_wr_process_fl - Process a freelist completion.
 * @hw: HW module.
 * @q: The ingress queue attached to the Freelist.
 * @wr: The freelist completion WR in the ingress queue.
 * @len_to_qid: The lower 32-bits of the first flit of the RSP footer
 * @iq_handler: Caller's handler for this completion.
 * @priv: Private pointer of caller
 *
 */
static inline void
csio_wr_process_fl(struct csio_hw *hw, struct csio_q *q,
		   void *wr, uint32_t len_to_qid,
		   void (*iq_handler)(struct csio_hw *, void *,
				      uint32_t, struct csio_fl_dma_buf *,
				      void *),
		   void *priv)
{
	struct csio_wrm *wrm = csio_hw_to_wrm(hw);
	struct csio_sge *sge = &wrm->sge;
	struct csio_fl_dma_buf flb;
	struct csio_dma_buf *buf, *fbuf;
	uint32_t bufsz, len, lastlen = 0;
	int n;
	struct csio_q *flq = hw->wrm.q_arr[q->un.iq.flq_idx];

	CSIO_DB_ASSERT(flq != NULL);

	len = len_to_qid;

	if (len & IQWRF_NEWBUF) {
		if (flq->un.fl.offset > 0) {
			csio_wr_inval_flq_buf(hw, flq);
			flq->un.fl.offset = 0;
		}
		len = IQWRF_LEN_GET(len);
	}

	CSIO_DB_ASSERT(len != 0);

	flb.totlen = len;

	/* Consume all freelist buffers used for len bytes */
	for (n = 0, fbuf = flb.flbufs; ; n++, fbuf++) {
		buf = &flq->un.fl.bufs[flq->cidx];
		bufsz = csio_wr_fl_bufsz(sge, buf);

		fbuf->paddr	= buf->paddr;
		fbuf->vaddr	= buf->vaddr;

		flb.offset	= flq->un.fl.offset;
		lastlen		= min(bufsz, len);
		fbuf->len	= lastlen;

		len -= lastlen;
		if (!len)
			break;
		csio_wr_inval_flq_buf(hw, flq);
	}

	flb.defer_free = flq->un.fl.packen ? 0 : 1;

	iq_handler(hw, wr, q->wr_sz - sizeof(struct csio_iqwr_footer),
		   &flb, priv);

	if (flq->un.fl.packen)
		flq->un.fl.offset += ALIGN(lastlen, sge->csio_fl_align);
	else
		csio_wr_inval_flq_buf(hw, flq);

}

/*
 * csio_is_new_iqwr - Is this a new Ingress queue entry ?
 * @q: Ingress quueue.
 * @ftr: Ingress queue WR SGE footer.
 *
 * The entry is new if our generation bit matches the corresponding
 * bit in the footer of the current WR.
 */
static inline bool
csio_is_new_iqwr(struct csio_q *q, struct csio_iqwr_footer *ftr)
{
	return (q->un.iq.genbit == (ftr->u.type_gen >> IQWRF_GEN_SHIFT));
}

/*
 * csio_wr_process_iq - Process elements in Ingress queue.
 * @hw:  HW pointer
 * @qidx: Index of queue
 * @iq_handler: Handler for this queue
 * @priv: Caller's private pointer
 *
 * This routine walks through every entry of the ingress queue, calling
 * the provided iq_handler with the entry, until the generation bit
 * flips.
 */
int
csio_wr_process_iq(struct csio_hw *hw, struct csio_q *q,
		   void (*iq_handler)(struct csio_hw *, void *,
				      uint32_t, struct csio_fl_dma_buf *,
				      void *),
		   void *priv)
{
	struct csio_wrm *wrm = csio_hw_to_wrm(hw);
	void *wr = (void *)((uintptr_t)q->vstart + (q->cidx * q->wr_sz));
	struct csio_iqwr_footer *ftr;
	uint32_t wr_type, fw_qid, qid;
	struct csio_q *q_completed;
	struct csio_q *flq = csio_iq_has_fl(q) ?
					wrm->q_arr[q->un.iq.flq_idx] : NULL;
	int rv = 0;

	/* Get the footer */
	ftr = (struct csio_iqwr_footer *)((uintptr_t)wr +
					  (q->wr_sz - sizeof(*ftr)));

	/*
	 * When q wrapped around last time, driver should have inverted
	 * ic.genbit as well.
	 */
	while (csio_is_new_iqwr(q, ftr)) {

		CSIO_DB_ASSERT(((uintptr_t)wr + q->wr_sz) <=
						(uintptr_t)q->vwrap);
		rmb();
		wr_type = IQWRF_TYPE_GET(ftr->u.type_gen);

		switch (wr_type) {
		case X_RSPD_TYPE_CPL:
			/* Subtract footer from WR len */
			iq_handler(hw, wr, q->wr_sz - sizeof(*ftr), NULL, priv);
			break;
		case X_RSPD_TYPE_FLBUF:
			csio_wr_process_fl(hw, q, wr,
					   ntohl(ftr->pldbuflen_qid),
					   iq_handler, priv);
			break;
		case X_RSPD_TYPE_INTR:
			fw_qid = ntohl(ftr->pldbuflen_qid);
			qid = fw_qid - wrm->fw_iq_start;
			q_completed = hw->wrm.intr_map[qid];

			if (unlikely(qid ==
					csio_q_physiqid(hw, hw->intr_iq_idx))) {
				/*
				 * We are already in the Forward Interrupt
				 * Interrupt Queue Service! Do-not service
				 * again!
				 *
				 */
			} else {
				CSIO_DB_ASSERT(q_completed);
				CSIO_DB_ASSERT(
					q_completed->un.iq.iq_intx_handler);

				/* Call the queue handler. */
				q_completed->un.iq.iq_intx_handler(hw, NULL,
						0, NULL, (void *)q_completed);
			}
			break;
		default:
			csio_warn(hw, "Unknown resp type 0x%x received\n",
				 wr_type);
			CSIO_INC_STATS(q, n_rsp_unknown);
			break;
		}

		/*
		 * Ingress *always* has fixed size WR entries. Therefore,
		 * there should always be complete WRs towards the end of
		 * queue.
		 */
		if (((uintptr_t)wr + q->wr_sz) == (uintptr_t)q->vwrap) {

			/* Roll over to start of queue */
			q->cidx = 0;
			wr	= q->vstart;

			/* Toggle genbit */
			q->un.iq.genbit ^= 0x1;

			CSIO_INC_STATS(q, n_qwrap);
		} else {
			q->cidx++;
			wr	= (void *)((uintptr_t)(q->vstart) +
					   (q->cidx * q->wr_sz));
		}

		ftr = (struct csio_iqwr_footer *)((uintptr_t)wr +
						  (q->wr_sz - sizeof(*ftr)));
		q->inc_idx++;

	} /* while (q->un.iq.genbit == hdr->genbit) */

	/*
	 * We need to re-arm SGE interrupts in case we got a stray interrupt,
	 * especially in msix mode. With INTx, this may be a common occurence.
	 */
	if (unlikely(!q->inc_idx)) {
		CSIO_INC_STATS(q, n_stray_comp);
		rv = -EINVAL;
		goto restart;
	}

	/* Replenish free list buffers if pending falls below low water mark */
	if (flq) {
		uint32_t avail  = csio_wr_avail_qcredits(flq);
		if (avail <= 16) {
			/* Make sure in FLQ, atleast 1 credit (8 FL buffers)
			 * remains unpopulated otherwise HW thinks
			 * FLQ is empty.
			 */
			csio_wr_update_fl(hw, flq, (flq->credits - 8) - avail);
			csio_wr_ring_fldb(hw, flq);
		}
	}

restart:
	/* Now inform SGE about our incremental index value */
	csio_wr_reg32(hw, CIDXINC_V(q->inc_idx)		|
			  INGRESSQID_V(q->un.iq.physiqid)	|
			  TIMERREG_V(csio_sge_timer_reg),
			  MYPF_REG(SGE_PF_GTS_A));
	q->stats.n_tot_rsps += q->inc_idx;

	q->inc_idx = 0;

	return rv;
}

int
csio_wr_process_iq_idx(struct csio_hw *hw, int qidx,
		   void (*iq_handler)(struct csio_hw *, void *,
				      uint32_t, struct csio_fl_dma_buf *,
				      void *),
		   void *priv)
{
	struct csio_wrm *wrm	= csio_hw_to_wrm(hw);
	struct csio_q	*iq	= wrm->q_arr[qidx];

	return csio_wr_process_iq(hw, iq, iq_handler, priv);
}

static int
csio_closest_timer(struct csio_sge *s, int time)
{
	int i, delta, match = 0, min_delta = INT_MAX;

	for (i = 0; i < ARRAY_SIZE(s->timer_val); i++) {
		delta = time - s->timer_val[i];
		if (delta < 0)
			delta = -delta;
		if (delta < min_delta) {
			min_delta = delta;
			match = i;
		}
	}
	return match;
}

static int
csio_closest_thresh(struct csio_sge *s, int cnt)
{
	int i, delta, match = 0, min_delta = INT_MAX;

	for (i = 0; i < ARRAY_SIZE(s->counter_val); i++) {
		delta = cnt - s->counter_val[i];
		if (delta < 0)
			delta = -delta;
		if (delta < min_delta) {
			min_delta = delta;
			match = i;
		}
	}
	return match;
}

static void
csio_wr_fixup_host_params(struct csio_hw *hw)
{
	struct csio_wrm *wrm = csio_hw_to_wrm(hw);
	struct csio_sge *sge = &wrm->sge;
	uint32_t clsz = L1_CACHE_BYTES;
	uint32_t s_hps = PAGE_SHIFT - 10;
	uint32_t ingpad = 0;
	uint32_t stat_len = clsz > 64 ? 128 : 64;

	csio_wr_reg32(hw, HOSTPAGESIZEPF0_V(s_hps) | HOSTPAGESIZEPF1_V(s_hps) |
		      HOSTPAGESIZEPF2_V(s_hps) | HOSTPAGESIZEPF3_V(s_hps) |
		      HOSTPAGESIZEPF4_V(s_hps) | HOSTPAGESIZEPF5_V(s_hps) |
		      HOSTPAGESIZEPF6_V(s_hps) | HOSTPAGESIZEPF7_V(s_hps),
		      SGE_HOST_PAGE_SIZE_A);

	sge->csio_fl_align = clsz < 32 ? 32 : clsz;
	ingpad = ilog2(sge->csio_fl_align) - 5;

	csio_set_reg_field(hw, SGE_CONTROL_A,
			   INGPADBOUNDARY_V(INGPADBOUNDARY_M) |
			   EGRSTATUSPAGESIZE_F,
			   INGPADBOUNDARY_V(ingpad) |
			   EGRSTATUSPAGESIZE_V(stat_len != 64));

	/* FL BUFFER SIZE#0 is Page size i,e already aligned to cache line */
	csio_wr_reg32(hw, PAGE_SIZE, SGE_FL_BUFFER_SIZE0_A);

	/*
	 * If using hard params, the following will get set correctly
	 * in csio_wr_set_sge().
	 */
	if (hw->flags & CSIO_HWF_USING_SOFT_PARAMS) {
		csio_wr_reg32(hw,
			(csio_rd_reg32(hw, SGE_FL_BUFFER_SIZE2_A) +
			sge->csio_fl_align - 1) & ~(sge->csio_fl_align - 1),
			SGE_FL_BUFFER_SIZE2_A);
		csio_wr_reg32(hw,
			(csio_rd_reg32(hw, SGE_FL_BUFFER_SIZE3_A) +
			sge->csio_fl_align - 1) & ~(sge->csio_fl_align - 1),
			SGE_FL_BUFFER_SIZE3_A);
	}

	csio_wr_reg32(hw, HPZ0_V(PAGE_SHIFT - 12), ULP_RX_TDDP_PSZ_A);

	/* default value of rx_dma_offset of the NIC driver */
	csio_set_reg_field(hw, SGE_CONTROL_A,
			   PKTSHIFT_V(PKTSHIFT_M),
			   PKTSHIFT_V(CSIO_SGE_RX_DMA_OFFSET));

	csio_hw_tp_wr_bits_indirect(hw, TP_INGRESS_CONFIG_A,
				    CSUM_HAS_PSEUDO_HDR_F, 0);
}

static void
csio_init_intr_coalesce_parms(struct csio_hw *hw)
{
	struct csio_wrm *wrm = csio_hw_to_wrm(hw);
	struct csio_sge *sge = &wrm->sge;

	csio_sge_thresh_reg = csio_closest_thresh(sge, csio_intr_coalesce_cnt);
	if (csio_intr_coalesce_cnt) {
		csio_sge_thresh_reg = 0;
		csio_sge_timer_reg = X_TIMERREG_RESTART_COUNTER;
		return;
	}

	csio_sge_timer_reg = csio_closest_timer(sge, csio_intr_coalesce_time);
}

/*
 * csio_wr_get_sge - Get SGE register values.
 * @hw: HW module.
 *
 * Used by non-master functions and by master-functions relying on config file.
 */
static void
csio_wr_get_sge(struct csio_hw *hw)
{
	struct csio_wrm *wrm = csio_hw_to_wrm(hw);
	struct csio_sge *sge = &wrm->sge;
	uint32_t ingpad;
	int i;
	u32 timer_value_0_and_1, timer_value_2_and_3, timer_value_4_and_5;
	u32 ingress_rx_threshold;

	sge->sge_control = csio_rd_reg32(hw, SGE_CONTROL_A);

	ingpad = INGPADBOUNDARY_G(sge->sge_control);

	switch (ingpad) {
	case X_INGPCIEBOUNDARY_32B:
		sge->csio_fl_align = 32; break;
	case X_INGPCIEBOUNDARY_64B:
		sge->csio_fl_align = 64; break;
	case X_INGPCIEBOUNDARY_128B:
		sge->csio_fl_align = 128; break;
	case X_INGPCIEBOUNDARY_256B:
		sge->csio_fl_align = 256; break;
	case X_INGPCIEBOUNDARY_512B:
		sge->csio_fl_align = 512; break;
	case X_INGPCIEBOUNDARY_1024B:
		sge->csio_fl_align = 1024; break;
	case X_INGPCIEBOUNDARY_2048B:
		sge->csio_fl_align = 2048; break;
	case X_INGPCIEBOUNDARY_4096B:
		sge->csio_fl_align = 4096; break;
	}

	for (i = 0; i < CSIO_SGE_FL_SIZE_REGS; i++)
		csio_get_flbuf_size(hw, sge, i);

	timer_value_0_and_1 = csio_rd_reg32(hw, SGE_TIMER_VALUE_0_AND_1_A);
	timer_value_2_and_3 = csio_rd_reg32(hw, SGE_TIMER_VALUE_2_AND_3_A);
	timer_value_4_and_5 = csio_rd_reg32(hw, SGE_TIMER_VALUE_4_AND_5_A);

	sge->timer_val[0] = (uint16_t)csio_core_ticks_to_us(hw,
					TIMERVALUE0_G(timer_value_0_and_1));
	sge->timer_val[1] = (uint16_t)csio_core_ticks_to_us(hw,
					TIMERVALUE1_G(timer_value_0_and_1));
	sge->timer_val[2] = (uint16_t)csio_core_ticks_to_us(hw,
					TIMERVALUE2_G(timer_value_2_and_3));
	sge->timer_val[3] = (uint16_t)csio_core_ticks_to_us(hw,
					TIMERVALUE3_G(timer_value_2_and_3));
	sge->timer_val[4] = (uint16_t)csio_core_ticks_to_us(hw,
					TIMERVALUE4_G(timer_value_4_and_5));
	sge->timer_val[5] = (uint16_t)csio_core_ticks_to_us(hw,
					TIMERVALUE5_G(timer_value_4_and_5));

	ingress_rx_threshold = csio_rd_reg32(hw, SGE_INGRESS_RX_THRESHOLD_A);
	sge->counter_val[0] = THRESHOLD_0_G(ingress_rx_threshold);
	sge->counter_val[1] = THRESHOLD_1_G(ingress_rx_threshold);
	sge->counter_val[2] = THRESHOLD_2_G(ingress_rx_threshold);
	sge->counter_val[3] = THRESHOLD_3_G(ingress_rx_threshold);

	csio_init_intr_coalesce_parms(hw);
}

/*
 * csio_wr_set_sge - Initialize SGE registers
 * @hw: HW module.
 *
 * Used by Master function to initialize SGE registers in the absence
 * of a config file.
 */
static void
csio_wr_set_sge(struct csio_hw *hw)
{
	struct csio_wrm *wrm = csio_hw_to_wrm(hw);
	struct csio_sge *sge = &wrm->sge;
	int i;

	/*
	 * Set up our basic SGE mode to deliver CPL messages to our Ingress
	 * Queue and Packet Date to the Free List.
	 */
	csio_set_reg_field(hw, SGE_CONTROL_A, RXPKTCPLMODE_F, RXPKTCPLMODE_F);

	sge->sge_control = csio_rd_reg32(hw, SGE_CONTROL_A);

	/* sge->csio_fl_align is set up by csio_wr_fixup_host_params(). */

	/*
	 * Set up to drop DOORBELL writes when the DOORBELL FIFO overflows
	 * and generate an interrupt when this occurs so we can recover.
	 */
	csio_set_reg_field(hw, SGE_DBFIFO_STATUS_A,
			   LP_INT_THRESH_T5_V(LP_INT_THRESH_T5_M),
			   LP_INT_THRESH_T5_V(CSIO_SGE_DBFIFO_INT_THRESH));
	csio_set_reg_field(hw, SGE_DBFIFO_STATUS2_A,
			   HP_INT_THRESH_T5_V(LP_INT_THRESH_T5_M),
			   HP_INT_THRESH_T5_V(CSIO_SGE_DBFIFO_INT_THRESH));

	csio_set_reg_field(hw, SGE_DOORBELL_CONTROL_A, ENABLE_DROP_F,
			   ENABLE_DROP_F);

	/* SGE_FL_BUFFER_SIZE0 is set up by csio_wr_fixup_host_params(). */

	CSIO_SET_FLBUF_SIZE(hw, 1, CSIO_SGE_FLBUF_SIZE1);
	csio_wr_reg32(hw, (CSIO_SGE_FLBUF_SIZE2 + sge->csio_fl_align - 1)
		      & ~(sge->csio_fl_align - 1), SGE_FL_BUFFER_SIZE2_A);
	csio_wr_reg32(hw, (CSIO_SGE_FLBUF_SIZE3 + sge->csio_fl_align - 1)
		      & ~(sge->csio_fl_align - 1), SGE_FL_BUFFER_SIZE3_A);
	CSIO_SET_FLBUF_SIZE(hw, 4, CSIO_SGE_FLBUF_SIZE4);
	CSIO_SET_FLBUF_SIZE(hw, 5, CSIO_SGE_FLBUF_SIZE5);
	CSIO_SET_FLBUF_SIZE(hw, 6, CSIO_SGE_FLBUF_SIZE6);
	CSIO_SET_FLBUF_SIZE(hw, 7, CSIO_SGE_FLBUF_SIZE7);
	CSIO_SET_FLBUF_SIZE(hw, 8, CSIO_SGE_FLBUF_SIZE8);

	for (i = 0; i < CSIO_SGE_FL_SIZE_REGS; i++)
		csio_get_flbuf_size(hw, sge, i);

	/* Initialize interrupt coalescing attributes */
	sge->timer_val[0] = CSIO_SGE_TIMER_VAL_0;
	sge->timer_val[1] = CSIO_SGE_TIMER_VAL_1;
	sge->timer_val[2] = CSIO_SGE_TIMER_VAL_2;
	sge->timer_val[3] = CSIO_SGE_TIMER_VAL_3;
	sge->timer_val[4] = CSIO_SGE_TIMER_VAL_4;
	sge->timer_val[5] = CSIO_SGE_TIMER_VAL_5;

	sge->counter_val[0] = CSIO_SGE_INT_CNT_VAL_0;
	sge->counter_val[1] = CSIO_SGE_INT_CNT_VAL_1;
	sge->counter_val[2] = CSIO_SGE_INT_CNT_VAL_2;
	sge->counter_val[3] = CSIO_SGE_INT_CNT_VAL_3;

	csio_wr_reg32(hw, THRESHOLD_0_V(sge->counter_val[0]) |
		      THRESHOLD_1_V(sge->counter_val[1]) |
		      THRESHOLD_2_V(sge->counter_val[2]) |
		      THRESHOLD_3_V(sge->counter_val[3]),
		      SGE_INGRESS_RX_THRESHOLD_A);

	csio_wr_reg32(hw,
		   TIMERVALUE0_V(csio_us_to_core_ticks(hw, sge->timer_val[0])) |
		   TIMERVALUE1_V(csio_us_to_core_ticks(hw, sge->timer_val[1])),
		   SGE_TIMER_VALUE_0_AND_1_A);

	csio_wr_reg32(hw,
		   TIMERVALUE2_V(csio_us_to_core_ticks(hw, sge->timer_val[2])) |
		   TIMERVALUE3_V(csio_us_to_core_ticks(hw, sge->timer_val[3])),
		   SGE_TIMER_VALUE_2_AND_3_A);

	csio_wr_reg32(hw,
		   TIMERVALUE4_V(csio_us_to_core_ticks(hw, sge->timer_val[4])) |
		   TIMERVALUE5_V(csio_us_to_core_ticks(hw, sge->timer_val[5])),
		   SGE_TIMER_VALUE_4_AND_5_A);

	csio_init_intr_coalesce_parms(hw);
}

void
csio_wr_sge_init(struct csio_hw *hw)
{
	/*
	 * If we are master and chip is not initialized:
	 *    - If we plan to use the config file, we need to fixup some
	 *      host specific registers, and read the rest of the SGE
	 *      configuration.
	 *    - If we dont plan to use the config file, we need to initialize
	 *      SGE entirely, including fixing the host specific registers.
	 * If we are master and chip is initialized, just read and work off of
	 *	the already initialized SGE values.
	 * If we arent the master, we are only allowed to read and work off of
	 *      the already initialized SGE values.
	 *
	 * Therefore, before calling this function, we assume that the master-
	 * ship of the card, state and whether to use config file or not, have
	 * already been decided.
	 */
	if (csio_is_hw_master(hw)) {
		if (hw->fw_state != CSIO_DEV_STATE_INIT)
			csio_wr_fixup_host_params(hw);

		if (hw->flags & CSIO_HWF_USING_SOFT_PARAMS)
			csio_wr_get_sge(hw);
		else
			csio_wr_set_sge(hw);
	} else
		csio_wr_get_sge(hw);
}

/*
 * csio_wrm_init - Initialize Work request module.
 * @wrm: WR module
 * @hw: HW pointer
 *
 * Allocates memory for an array of queue pointers starting at q_arr.
 */
int
csio_wrm_init(struct csio_wrm *wrm, struct csio_hw *hw)
{
	int i;

	if (!wrm->num_q) {
		csio_err(hw, "Num queues is not set\n");
		return -EINVAL;
	}

	wrm->q_arr = kzalloc(sizeof(struct csio_q *) * wrm->num_q, GFP_KERNEL);
	if (!wrm->q_arr)
		goto err;

	for (i = 0; i < wrm->num_q; i++) {
		wrm->q_arr[i] = kzalloc(sizeof(struct csio_q), GFP_KERNEL);
		if (!wrm->q_arr[i]) {
			while (--i >= 0)
				kfree(wrm->q_arr[i]);
			goto err_free_arr;
		}
	}
	wrm->free_qidx	= 0;

	return 0;

err_free_arr:
	kfree(wrm->q_arr);
err:
	return -ENOMEM;
}

/*
 * csio_wrm_exit - Initialize Work request module.
 * @wrm: WR module
 * @hw: HW module
 *
 * Uninitialize WR module. Free q_arr and pointers in it.
 * We have the additional job of freeing the DMA memory associated
 * with the queues.
 */
void
csio_wrm_exit(struct csio_wrm *wrm, struct csio_hw *hw)
{
	int i;
	uint32_t j;
	struct csio_q *q;
	struct csio_dma_buf *buf;

	for (i = 0; i < wrm->num_q; i++) {
		q = wrm->q_arr[i];

		if (wrm->free_qidx && (i < wrm->free_qidx)) {
			if (q->type == CSIO_FREELIST) {
				if (!q->un.fl.bufs)
					continue;
				for (j = 0; j < q->credits; j++) {
					buf = &q->un.fl.bufs[j];
					if (!buf->vaddr)
						continue;
					pci_free_consistent(hw->pdev, buf->len,
							    buf->vaddr,
							    buf->paddr);
				}
				kfree(q->un.fl.bufs);
			}
			pci_free_consistent(hw->pdev, q->size,
					    q->vstart, q->pstart);
		}
		kfree(q);
	}

	hw->flags &= ~CSIO_HWF_Q_MEM_ALLOCED;

	kfree(wrm->q_arr);
}
