/*
 * Copyright (c) 2005-2008 Chelsio, 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/skbuff.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/dma-mapping.h>
#include <net/arp.h>
#include "common.h"
#include "regs.h"
#include "sge_defs.h"
#include "t3_cpl.h"
#include "firmware_exports.h"
#include "cxgb3_offload.h"

#define USE_GTS 0

#define SGE_RX_SM_BUF_SIZE 1536

#define SGE_RX_COPY_THRES  256
#define SGE_RX_PULL_LEN    128

#define SGE_PG_RSVD SMP_CACHE_BYTES
/*
 * Page chunk size for FL0 buffers if FL0 is to be populated with page chunks.
 * It must be a divisor of PAGE_SIZE.  If set to 0 FL0 will use sk_buffs
 * directly.
 */
#define FL0_PG_CHUNK_SIZE  2048
#define FL0_PG_ORDER 0
#define FL0_PG_ALLOC_SIZE (PAGE_SIZE << FL0_PG_ORDER)
#define FL1_PG_CHUNK_SIZE (PAGE_SIZE > 8192 ? 16384 : 8192)
#define FL1_PG_ORDER (PAGE_SIZE > 8192 ? 0 : 1)
#define FL1_PG_ALLOC_SIZE (PAGE_SIZE << FL1_PG_ORDER)

#define SGE_RX_DROP_THRES 16
#define RX_RECLAIM_PERIOD (HZ/4)

/*
 * Max number of Rx buffers we replenish at a time.
 */
#define MAX_RX_REFILL 16U
/*
 * Period of the Tx buffer reclaim timer.  This timer does not need to run
 * frequently as Tx buffers are usually reclaimed by new Tx packets.
 */
#define TX_RECLAIM_PERIOD (HZ / 4)
#define TX_RECLAIM_TIMER_CHUNK 64U
#define TX_RECLAIM_CHUNK 16U

/* WR size in bytes */
#define WR_LEN (WR_FLITS * 8)

/*
 * Types of Tx queues in each queue set.  Order here matters, do not change.
 */
enum { TXQ_ETH, TXQ_OFLD, TXQ_CTRL };

/* Values for sge_txq.flags */
enum {
	TXQ_RUNNING = 1 << 0,	/* fetch engine is running */
	TXQ_LAST_PKT_DB = 1 << 1,	/* last packet rang the doorbell */
};

struct tx_desc {
	__be64 flit[TX_DESC_FLITS];
};

struct rx_desc {
	__be32 addr_lo;
	__be32 len_gen;
	__be32 gen2;
	__be32 addr_hi;
};

struct tx_sw_desc {		/* SW state per Tx descriptor */
	struct sk_buff *skb;
	u8 eop;       /* set if last descriptor for packet */
	u8 addr_idx;  /* buffer index of first SGL entry in descriptor */
	u8 fragidx;   /* first page fragment associated with descriptor */
	s8 sflit;     /* start flit of first SGL entry in descriptor */
};

struct rx_sw_desc {                /* SW state per Rx descriptor */
	union {
		struct sk_buff *skb;
		struct fl_pg_chunk pg_chunk;
	};
	DECLARE_PCI_UNMAP_ADDR(dma_addr);
};

struct rsp_desc {		/* response queue descriptor */
	struct rss_header rss_hdr;
	__be32 flags;
	__be32 len_cq;
	u8 imm_data[47];
	u8 intr_gen;
};

/*
 * Holds unmapping information for Tx packets that need deferred unmapping.
 * This structure lives at skb->head and must be allocated by callers.
 */
struct deferred_unmap_info {
	struct pci_dev *pdev;
	dma_addr_t addr[MAX_SKB_FRAGS + 1];
};

/*
 * Maps a number of flits to the number of Tx descriptors that can hold them.
 * The formula is
 *
 * desc = 1 + (flits - 2) / (WR_FLITS - 1).
 *
 * HW allows up to 4 descriptors to be combined into a WR.
 */
static u8 flit_desc_map[] = {
	0,
#if SGE_NUM_GENBITS == 1
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
	4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
#elif SGE_NUM_GENBITS == 2
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
	4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
#else
# error "SGE_NUM_GENBITS must be 1 or 2"
#endif
};

static inline struct sge_qset *fl_to_qset(const struct sge_fl *q, int qidx)
{
	return container_of(q, struct sge_qset, fl[qidx]);
}

static inline struct sge_qset *rspq_to_qset(const struct sge_rspq *q)
{
	return container_of(q, struct sge_qset, rspq);
}

static inline struct sge_qset *txq_to_qset(const struct sge_txq *q, int qidx)
{
	return container_of(q, struct sge_qset, txq[qidx]);
}

/**
 *	refill_rspq - replenish an SGE response queue
 *	@adapter: the adapter
 *	@q: the response queue to replenish
 *	@credits: how many new responses to make available
 *
 *	Replenishes a response queue by making the supplied number of responses
 *	available to HW.
 */
static inline void refill_rspq(struct adapter *adapter,
			       const struct sge_rspq *q, unsigned int credits)
{
	rmb();
	t3_write_reg(adapter, A_SG_RSPQ_CREDIT_RETURN,
		     V_RSPQ(q->cntxt_id) | V_CREDITS(credits));
}

/**
 *	need_skb_unmap - does the platform need unmapping of sk_buffs?
 *
 *	Returns true if the platform needs sk_buff unmapping.  The compiler
 *	optimizes away unecessary code if this returns true.
 */
static inline int need_skb_unmap(void)
{
	/*
	 * This structure is used to tell if the platform needs buffer
	 * unmapping by checking if DECLARE_PCI_UNMAP_ADDR defines anything.
	 */
	struct dummy {
		DECLARE_PCI_UNMAP_ADDR(addr);
	};

	return sizeof(struct dummy) != 0;
}

/**
 *	unmap_skb - unmap a packet main body and its page fragments
 *	@skb: the packet
 *	@q: the Tx queue containing Tx descriptors for the packet
 *	@cidx: index of Tx descriptor
 *	@pdev: the PCI device
 *
 *	Unmap the main body of an sk_buff and its page fragments, if any.
 *	Because of the fairly complicated structure of our SGLs and the desire
 *	to conserve space for metadata, the information necessary to unmap an
 *	sk_buff is spread across the sk_buff itself (buffer lengths), the HW Tx
 *	descriptors (the physical addresses of the various data buffers), and
 *	the SW descriptor state (assorted indices).  The send functions
 *	initialize the indices for the first packet descriptor so we can unmap
 *	the buffers held in the first Tx descriptor here, and we have enough
 *	information at this point to set the state for the next Tx descriptor.
 *
 *	Note that it is possible to clean up the first descriptor of a packet
 *	before the send routines have written the next descriptors, but this
 *	race does not cause any problem.  We just end up writing the unmapping
 *	info for the descriptor first.
 */
static inline void unmap_skb(struct sk_buff *skb, struct sge_txq *q,
			     unsigned int cidx, struct pci_dev *pdev)
{
	const struct sg_ent *sgp;
	struct tx_sw_desc *d = &q->sdesc[cidx];
	int nfrags, frag_idx, curflit, j = d->addr_idx;

	sgp = (struct sg_ent *)&q->desc[cidx].flit[d->sflit];
	frag_idx = d->fragidx;

	if (frag_idx == 0 && skb_headlen(skb)) {
		pci_unmap_single(pdev, be64_to_cpu(sgp->addr[0]),
				 skb_headlen(skb), PCI_DMA_TODEVICE);
		j = 1;
	}

	curflit = d->sflit + 1 + j;
	nfrags = skb_shinfo(skb)->nr_frags;

	while (frag_idx < nfrags && curflit < WR_FLITS) {
		pci_unmap_page(pdev, be64_to_cpu(sgp->addr[j]),
			       skb_shinfo(skb)->frags[frag_idx].size,
			       PCI_DMA_TODEVICE);
		j ^= 1;
		if (j == 0) {
			sgp++;
			curflit++;
		}
		curflit++;
		frag_idx++;
	}

	if (frag_idx < nfrags) {   /* SGL continues into next Tx descriptor */
		d = cidx + 1 == q->size ? q->sdesc : d + 1;
		d->fragidx = frag_idx;
		d->addr_idx = j;
		d->sflit = curflit - WR_FLITS - j; /* sflit can be -1 */
	}
}

/**
 *	free_tx_desc - reclaims Tx descriptors and their buffers
 *	@adapter: the adapter
 *	@q: the Tx queue to reclaim descriptors from
 *	@n: the number of descriptors to reclaim
 *
 *	Reclaims Tx descriptors from an SGE Tx queue and frees the associated
 *	Tx buffers.  Called with the Tx queue lock held.
 */
static void free_tx_desc(struct adapter *adapter, struct sge_txq *q,
			 unsigned int n)
{
	struct tx_sw_desc *d;
	struct pci_dev *pdev = adapter->pdev;
	unsigned int cidx = q->cidx;

	const int need_unmap = need_skb_unmap() &&
			       q->cntxt_id >= FW_TUNNEL_SGEEC_START;

	d = &q->sdesc[cidx];
	while (n--) {
		if (d->skb) {	/* an SGL is present */
			if (need_unmap)
				unmap_skb(d->skb, q, cidx, pdev);
			if (d->eop)
				kfree_skb(d->skb);
		}
		++d;
		if (++cidx == q->size) {
			cidx = 0;
			d = q->sdesc;
		}
	}
	q->cidx = cidx;
}

/**
 *	reclaim_completed_tx - reclaims completed Tx descriptors
 *	@adapter: the adapter
 *	@q: the Tx queue to reclaim completed descriptors from
 *	@chunk: maximum number of descriptors to reclaim
 *
 *	Reclaims Tx descriptors that the SGE has indicated it has processed,
 *	and frees the associated buffers if possible.  Called with the Tx
 *	queue's lock held.
 */
static inline unsigned int reclaim_completed_tx(struct adapter *adapter,
						struct sge_txq *q,
						unsigned int chunk)
{
	unsigned int reclaim = q->processed - q->cleaned;

	reclaim = min(chunk, reclaim);
	if (reclaim) {
		free_tx_desc(adapter, q, reclaim);
		q->cleaned += reclaim;
		q->in_use -= reclaim;
	}
	return q->processed - q->cleaned;
}

/**
 *	should_restart_tx - are there enough resources to restart a Tx queue?
 *	@q: the Tx queue
 *
 *	Checks if there are enough descriptors to restart a suspended Tx queue.
 */
static inline int should_restart_tx(const struct sge_txq *q)
{
	unsigned int r = q->processed - q->cleaned;

	return q->in_use - r < (q->size >> 1);
}

static void clear_rx_desc(struct pci_dev *pdev, const struct sge_fl *q,
			  struct rx_sw_desc *d)
{
	if (q->use_pages && d->pg_chunk.page) {
		(*d->pg_chunk.p_cnt)--;
		if (!*d->pg_chunk.p_cnt)
			pci_unmap_page(pdev,
				       d->pg_chunk.mapping,
				       q->alloc_size, PCI_DMA_FROMDEVICE);

		put_page(d->pg_chunk.page);
		d->pg_chunk.page = NULL;
	} else {
		pci_unmap_single(pdev, pci_unmap_addr(d, dma_addr),
				 q->buf_size, PCI_DMA_FROMDEVICE);
		kfree_skb(d->skb);
		d->skb = NULL;
	}
}

/**
 *	free_rx_bufs - free the Rx buffers on an SGE free list
 *	@pdev: the PCI device associated with the adapter
 *	@rxq: the SGE free list to clean up
 *
 *	Release the buffers on an SGE free-buffer Rx queue.  HW fetching from
 *	this queue should be stopped before calling this function.
 */
static void free_rx_bufs(struct pci_dev *pdev, struct sge_fl *q)
{
	unsigned int cidx = q->cidx;

	while (q->credits--) {
		struct rx_sw_desc *d = &q->sdesc[cidx];


		clear_rx_desc(pdev, q, d);
		if (++cidx == q->size)
			cidx = 0;
	}

	if (q->pg_chunk.page) {
		__free_pages(q->pg_chunk.page, q->order);
		q->pg_chunk.page = NULL;
	}
}

/**
 *	add_one_rx_buf - add a packet buffer to a free-buffer list
 *	@va:  buffer start VA
 *	@len: the buffer length
 *	@d: the HW Rx descriptor to write
 *	@sd: the SW Rx descriptor to write
 *	@gen: the generation bit value
 *	@pdev: the PCI device associated with the adapter
 *
 *	Add a buffer of the given length to the supplied HW and SW Rx
 *	descriptors.
 */
static inline int add_one_rx_buf(void *va, unsigned int len,
				 struct rx_desc *d, struct rx_sw_desc *sd,
				 unsigned int gen, struct pci_dev *pdev)
{
	dma_addr_t mapping;

	mapping = pci_map_single(pdev, va, len, PCI_DMA_FROMDEVICE);
	if (unlikely(pci_dma_mapping_error(pdev, mapping)))
		return -ENOMEM;

	pci_unmap_addr_set(sd, dma_addr, mapping);

	d->addr_lo = cpu_to_be32(mapping);
	d->addr_hi = cpu_to_be32((u64) mapping >> 32);
	wmb();
	d->len_gen = cpu_to_be32(V_FLD_GEN1(gen));
	d->gen2 = cpu_to_be32(V_FLD_GEN2(gen));
	return 0;
}

static inline int add_one_rx_chunk(dma_addr_t mapping, struct rx_desc *d,
				   unsigned int gen)
{
	d->addr_lo = cpu_to_be32(mapping);
	d->addr_hi = cpu_to_be32((u64) mapping >> 32);
	wmb();
	d->len_gen = cpu_to_be32(V_FLD_GEN1(gen));
	d->gen2 = cpu_to_be32(V_FLD_GEN2(gen));
	return 0;
}

static int alloc_pg_chunk(struct adapter *adapter, struct sge_fl *q,
			  struct rx_sw_desc *sd, gfp_t gfp,
			  unsigned int order)
{
	if (!q->pg_chunk.page) {
		dma_addr_t mapping;

		q->pg_chunk.page = alloc_pages(gfp, order);
		if (unlikely(!q->pg_chunk.page))
			return -ENOMEM;
		q->pg_chunk.va = page_address(q->pg_chunk.page);
		q->pg_chunk.p_cnt = q->pg_chunk.va + (PAGE_SIZE << order) -
				    SGE_PG_RSVD;
		q->pg_chunk.offset = 0;
		mapping = pci_map_page(adapter->pdev, q->pg_chunk.page,
				       0, q->alloc_size, PCI_DMA_FROMDEVICE);
		q->pg_chunk.mapping = mapping;
	}
	sd->pg_chunk = q->pg_chunk;

	prefetch(sd->pg_chunk.p_cnt);

	q->pg_chunk.offset += q->buf_size;
	if (q->pg_chunk.offset == (PAGE_SIZE << order))
		q->pg_chunk.page = NULL;
	else {
		q->pg_chunk.va += q->buf_size;
		get_page(q->pg_chunk.page);
	}

	if (sd->pg_chunk.offset == 0)
		*sd->pg_chunk.p_cnt = 1;
	else
		*sd->pg_chunk.p_cnt += 1;

	return 0;
}

static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q)
{
	if (q->pend_cred >= q->credits / 4) {
		q->pend_cred = 0;
		wmb();
		t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
	}
}

/**
 *	refill_fl - refill an SGE free-buffer list
 *	@adapter: the adapter
 *	@q: the free-list to refill
 *	@n: the number of new buffers to allocate
 *	@gfp: the gfp flags for allocating new buffers
 *
 *	(Re)populate an SGE free-buffer list with up to @n new packet buffers,
 *	allocated with the supplied gfp flags.  The caller must assure that
 *	@n does not exceed the queue's capacity.
 */
static int refill_fl(struct adapter *adap, struct sge_fl *q, int n, gfp_t gfp)
{
	struct rx_sw_desc *sd = &q->sdesc[q->pidx];
	struct rx_desc *d = &q->desc[q->pidx];
	unsigned int count = 0;

	while (n--) {
		dma_addr_t mapping;
		int err;

		if (q->use_pages) {
			if (unlikely(alloc_pg_chunk(adap, q, sd, gfp,
						    q->order))) {
nomem:				q->alloc_failed++;
				break;
			}
			mapping = sd->pg_chunk.mapping + sd->pg_chunk.offset;
			pci_unmap_addr_set(sd, dma_addr, mapping);

			add_one_rx_chunk(mapping, d, q->gen);
			pci_dma_sync_single_for_device(adap->pdev, mapping,
						q->buf_size - SGE_PG_RSVD,
						PCI_DMA_FROMDEVICE);
		} else {
			void *buf_start;

			struct sk_buff *skb = alloc_skb(q->buf_size, gfp);
			if (!skb)
				goto nomem;

			sd->skb = skb;
			buf_start = skb->data;
			err = add_one_rx_buf(buf_start, q->buf_size, d, sd,
					     q->gen, adap->pdev);
			if (unlikely(err)) {
				clear_rx_desc(adap->pdev, q, sd);
				break;
			}
		}

		d++;
		sd++;
		if (++q->pidx == q->size) {
			q->pidx = 0;
			q->gen ^= 1;
			sd = q->sdesc;
			d = q->desc;
		}
		count++;
	}

	q->credits += count;
	q->pend_cred += count;
	ring_fl_db(adap, q);

	return count;
}

static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl)
{
	refill_fl(adap, fl, min(MAX_RX_REFILL, fl->size - fl->credits),
		  GFP_ATOMIC | __GFP_COMP);
}

/**
 *	recycle_rx_buf - recycle a receive buffer
 *	@adapter: the adapter
 *	@q: the SGE free list
 *	@idx: index of buffer to recycle
 *
 *	Recycles the specified buffer on the given free list by adding it at
 *	the next available slot on the list.
 */
static void recycle_rx_buf(struct adapter *adap, struct sge_fl *q,
			   unsigned int idx)
{
	struct rx_desc *from = &q->desc[idx];
	struct rx_desc *to = &q->desc[q->pidx];

	q->sdesc[q->pidx] = q->sdesc[idx];
	to->addr_lo = from->addr_lo;	/* already big endian */
	to->addr_hi = from->addr_hi;	/* likewise */
	wmb();
	to->len_gen = cpu_to_be32(V_FLD_GEN1(q->gen));
	to->gen2 = cpu_to_be32(V_FLD_GEN2(q->gen));

	if (++q->pidx == q->size) {
		q->pidx = 0;
		q->gen ^= 1;
	}

	q->credits++;
	q->pend_cred++;
	ring_fl_db(adap, q);
}

/**
 *	alloc_ring - allocate resources for an SGE descriptor ring
 *	@pdev: the PCI device
 *	@nelem: the number of descriptors
 *	@elem_size: the size of each descriptor
 *	@sw_size: the size of the SW state associated with each ring element
 *	@phys: the physical address of the allocated ring
 *	@metadata: address of the array holding the SW state for the ring
 *
 *	Allocates resources for an SGE descriptor ring, such as Tx queues,
 *	free buffer lists, or response queues.  Each SGE ring requires
 *	space for its HW descriptors plus, optionally, space for the SW state
 *	associated with each HW entry (the metadata).  The function returns
 *	three values: the virtual address for the HW ring (the return value
 *	of the function), the physical address of the HW ring, and the address
 *	of the SW ring.
 */
static void *alloc_ring(struct pci_dev *pdev, size_t nelem, size_t elem_size,
			size_t sw_size, dma_addr_t * phys, void *metadata)
{
	size_t len = nelem * elem_size;
	void *s = NULL;
	void *p = dma_alloc_coherent(&pdev->dev, len, phys, GFP_KERNEL);

	if (!p)
		return NULL;
	if (sw_size && metadata) {
		s = kcalloc(nelem, sw_size, GFP_KERNEL);

		if (!s) {
			dma_free_coherent(&pdev->dev, len, p, *phys);
			return NULL;
		}
		*(void **)metadata = s;
	}
	memset(p, 0, len);
	return p;
}

/**
 *	t3_reset_qset - reset a sge qset
 *	@q: the queue set
 *
 *	Reset the qset structure.
 *	the NAPI structure is preserved in the event of
 *	the qset's reincarnation, for example during EEH recovery.
 */
static void t3_reset_qset(struct sge_qset *q)
{
	if (q->adap &&
	    !(q->adap->flags & NAPI_INIT)) {
		memset(q, 0, sizeof(*q));
		return;
	}

	q->adap = NULL;
	memset(&q->rspq, 0, sizeof(q->rspq));
	memset(q->fl, 0, sizeof(struct sge_fl) * SGE_RXQ_PER_SET);
	memset(q->txq, 0, sizeof(struct sge_txq) * SGE_TXQ_PER_SET);
	q->txq_stopped = 0;
	q->tx_reclaim_timer.function = NULL; /* for t3_stop_sge_timers() */
	q->rx_reclaim_timer.function = NULL;
	q->nomem = 0;
	napi_free_frags(&q->napi);
}


/**
 *	free_qset - free the resources of an SGE queue set
 *	@adapter: the adapter owning the queue set
 *	@q: the queue set
 *
 *	Release the HW and SW resources associated with an SGE queue set, such
 *	as HW contexts, packet buffers, and descriptor rings.  Traffic to the
 *	queue set must be quiesced prior to calling this.
 */
static void t3_free_qset(struct adapter *adapter, struct sge_qset *q)
{
	int i;
	struct pci_dev *pdev = adapter->pdev;

	for (i = 0; i < SGE_RXQ_PER_SET; ++i)
		if (q->fl[i].desc) {
			spin_lock_irq(&adapter->sge.reg_lock);
			t3_sge_disable_fl(adapter, q->fl[i].cntxt_id);
			spin_unlock_irq(&adapter->sge.reg_lock);
			free_rx_bufs(pdev, &q->fl[i]);
			kfree(q->fl[i].sdesc);
			dma_free_coherent(&pdev->dev,
					  q->fl[i].size *
					  sizeof(struct rx_desc), q->fl[i].desc,
					  q->fl[i].phys_addr);
		}

	for (i = 0; i < SGE_TXQ_PER_SET; ++i)
		if (q->txq[i].desc) {
			spin_lock_irq(&adapter->sge.reg_lock);
			t3_sge_enable_ecntxt(adapter, q->txq[i].cntxt_id, 0);
			spin_unlock_irq(&adapter->sge.reg_lock);
			if (q->txq[i].sdesc) {
				free_tx_desc(adapter, &q->txq[i],
					     q->txq[i].in_use);
				kfree(q->txq[i].sdesc);
			}
			dma_free_coherent(&pdev->dev,
					  q->txq[i].size *
					  sizeof(struct tx_desc),
					  q->txq[i].desc, q->txq[i].phys_addr);
			__skb_queue_purge(&q->txq[i].sendq);
		}

	if (q->rspq.desc) {
		spin_lock_irq(&adapter->sge.reg_lock);
		t3_sge_disable_rspcntxt(adapter, q->rspq.cntxt_id);
		spin_unlock_irq(&adapter->sge.reg_lock);
		dma_free_coherent(&pdev->dev,
				  q->rspq.size * sizeof(struct rsp_desc),
				  q->rspq.desc, q->rspq.phys_addr);
	}

	t3_reset_qset(q);
}

/**
 *	init_qset_cntxt - initialize an SGE queue set context info
 *	@qs: the queue set
 *	@id: the queue set id
 *
 *	Initializes the TIDs and context ids for the queues of a queue set.
 */
static void init_qset_cntxt(struct sge_qset *qs, unsigned int id)
{
	qs->rspq.cntxt_id = id;
	qs->fl[0].cntxt_id = 2 * id;
	qs->fl[1].cntxt_id = 2 * id + 1;
	qs->txq[TXQ_ETH].cntxt_id = FW_TUNNEL_SGEEC_START + id;
	qs->txq[TXQ_ETH].token = FW_TUNNEL_TID_START + id;
	qs->txq[TXQ_OFLD].cntxt_id = FW_OFLD_SGEEC_START + id;
	qs->txq[TXQ_CTRL].cntxt_id = FW_CTRL_SGEEC_START + id;
	qs->txq[TXQ_CTRL].token = FW_CTRL_TID_START + id;
}

/**
 *	sgl_len - calculates the size of an SGL of the given capacity
 *	@n: the number of SGL entries
 *
 *	Calculates the number of flits needed for a scatter/gather list that
 *	can hold the given number of entries.
 */
static inline unsigned int sgl_len(unsigned int n)
{
	/* alternatively: 3 * (n / 2) + 2 * (n & 1) */
	return (3 * n) / 2 + (n & 1);
}

/**
 *	flits_to_desc - returns the num of Tx descriptors for the given flits
 *	@n: the number of flits
 *
 *	Calculates the number of Tx descriptors needed for the supplied number
 *	of flits.
 */
static inline unsigned int flits_to_desc(unsigned int n)
{
	BUG_ON(n >= ARRAY_SIZE(flit_desc_map));
	return flit_desc_map[n];
}

/**
 *	get_packet - return the next ingress packet buffer from a free list
 *	@adap: the adapter that received the packet
 *	@fl: the SGE free list holding the packet
 *	@len: the packet length including any SGE padding
 *	@drop_thres: # of remaining buffers before we start dropping packets
 *
 *	Get the next packet from a free list and complete setup of the
 *	sk_buff.  If the packet is small we make a copy and recycle the
 *	original buffer, otherwise we use the original buffer itself.  If a
 *	positive drop threshold is supplied packets are dropped and their
 *	buffers recycled if (a) the number of remaining buffers is under the
 *	threshold and the packet is too big to copy, or (b) the packet should
 *	be copied but there is no memory for the copy.
 */
static struct sk_buff *get_packet(struct adapter *adap, struct sge_fl *fl,
				  unsigned int len, unsigned int drop_thres)
{
	struct sk_buff *skb = NULL;
	struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];

	prefetch(sd->skb->data);
	fl->credits--;

	if (len <= SGE_RX_COPY_THRES) {
		skb = alloc_skb(len, GFP_ATOMIC);
		if (likely(skb != NULL)) {
			__skb_put(skb, len);
			pci_dma_sync_single_for_cpu(adap->pdev,
					    pci_unmap_addr(sd, dma_addr), len,
					    PCI_DMA_FROMDEVICE);
			memcpy(skb->data, sd->skb->data, len);
			pci_dma_sync_single_for_device(adap->pdev,
					    pci_unmap_addr(sd, dma_addr), len,
					    PCI_DMA_FROMDEVICE);
		} else if (!drop_thres)
			goto use_orig_buf;
recycle:
		recycle_rx_buf(adap, fl, fl->cidx);
		return skb;
	}

	if (unlikely(fl->credits < drop_thres) &&
	    refill_fl(adap, fl, min(MAX_RX_REFILL, fl->size - fl->credits - 1),
		      GFP_ATOMIC | __GFP_COMP) == 0)
		goto recycle;

use_orig_buf:
	pci_unmap_single(adap->pdev, pci_unmap_addr(sd, dma_addr),
			 fl->buf_size, PCI_DMA_FROMDEVICE);
	skb = sd->skb;
	skb_put(skb, len);
	__refill_fl(adap, fl);
	return skb;
}

/**
 *	get_packet_pg - return the next ingress packet buffer from a free list
 *	@adap: the adapter that received the packet
 *	@fl: the SGE free list holding the packet
 *	@len: the packet length including any SGE padding
 *	@drop_thres: # of remaining buffers before we start dropping packets
 *
 *	Get the next packet from a free list populated with page chunks.
 *	If the packet is small we make a copy and recycle the original buffer,
 *	otherwise we attach the original buffer as a page fragment to a fresh
 *	sk_buff.  If a positive drop threshold is supplied packets are dropped
 *	and their buffers recycled if (a) the number of remaining buffers is
 *	under the threshold and the packet is too big to copy, or (b) there's
 *	no system memory.
 *
 * 	Note: this function is similar to @get_packet but deals with Rx buffers
 * 	that are page chunks rather than sk_buffs.
 */
static struct sk_buff *get_packet_pg(struct adapter *adap, struct sge_fl *fl,
				     struct sge_rspq *q, unsigned int len,
				     unsigned int drop_thres)
{
	struct sk_buff *newskb, *skb;
	struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];

	dma_addr_t dma_addr = pci_unmap_addr(sd, dma_addr);

	newskb = skb = q->pg_skb;
	if (!skb && (len <= SGE_RX_COPY_THRES)) {
		newskb = alloc_skb(len, GFP_ATOMIC);
		if (likely(newskb != NULL)) {
			__skb_put(newskb, len);
			pci_dma_sync_single_for_cpu(adap->pdev, dma_addr, len,
					    PCI_DMA_FROMDEVICE);
			memcpy(newskb->data, sd->pg_chunk.va, len);
			pci_dma_sync_single_for_device(adap->pdev, dma_addr,
						       len,
						       PCI_DMA_FROMDEVICE);
		} else if (!drop_thres)
			return NULL;
recycle:
		fl->credits--;
		recycle_rx_buf(adap, fl, fl->cidx);
		q->rx_recycle_buf++;
		return newskb;
	}

	if (unlikely(q->rx_recycle_buf || (!skb && fl->credits <= drop_thres)))
		goto recycle;

	prefetch(sd->pg_chunk.p_cnt);

	if (!skb)
		newskb = alloc_skb(SGE_RX_PULL_LEN, GFP_ATOMIC);

	if (unlikely(!newskb)) {
		if (!drop_thres)
			return NULL;
		goto recycle;
	}

	pci_dma_sync_single_for_cpu(adap->pdev, dma_addr, len,
				    PCI_DMA_FROMDEVICE);
	(*sd->pg_chunk.p_cnt)--;
	if (!*sd->pg_chunk.p_cnt && sd->pg_chunk.page != fl->pg_chunk.page)
		pci_unmap_page(adap->pdev,
			       sd->pg_chunk.mapping,
			       fl->alloc_size,
			       PCI_DMA_FROMDEVICE);
	if (!skb) {
		__skb_put(newskb, SGE_RX_PULL_LEN);
		memcpy(newskb->data, sd->pg_chunk.va, SGE_RX_PULL_LEN);
		skb_fill_page_desc(newskb, 0, sd->pg_chunk.page,
				   sd->pg_chunk.offset + SGE_RX_PULL_LEN,
				   len - SGE_RX_PULL_LEN);
		newskb->len = len;
		newskb->data_len = len - SGE_RX_PULL_LEN;
		newskb->truesize += newskb->data_len;
	} else {
		skb_fill_page_desc(newskb, skb_shinfo(newskb)->nr_frags,
				   sd->pg_chunk.page,
				   sd->pg_chunk.offset, len);
		newskb->len += len;
		newskb->data_len += len;
		newskb->truesize += len;
	}

	fl->credits--;
	/*
	 * We do not refill FLs here, we let the caller do it to overlap a
	 * prefetch.
	 */
	return newskb;
}

/**
 *	get_imm_packet - return the next ingress packet buffer from a response
 *	@resp: the response descriptor containing the packet data
 *
 *	Return a packet containing the immediate data of the given response.
 */
static inline struct sk_buff *get_imm_packet(const struct rsp_desc *resp)
{
	struct sk_buff *skb = alloc_skb(IMMED_PKT_SIZE, GFP_ATOMIC);

	if (skb) {
		__skb_put(skb, IMMED_PKT_SIZE);
		skb_copy_to_linear_data(skb, resp->imm_data, IMMED_PKT_SIZE);
	}
	return skb;
}

/**
 *	calc_tx_descs - calculate the number of Tx descriptors for a packet
 *	@skb: the packet
 *
 * 	Returns the number of Tx descriptors needed for the given Ethernet
 * 	packet.  Ethernet packets require addition of WR and CPL headers.
 */
static inline unsigned int calc_tx_descs(const struct sk_buff *skb)
{
	unsigned int flits;

	if (skb->len <= WR_LEN - sizeof(struct cpl_tx_pkt))
		return 1;

	flits = sgl_len(skb_shinfo(skb)->nr_frags + 1) + 2;
	if (skb_shinfo(skb)->gso_size)
		flits++;
	return flits_to_desc(flits);
}

/**
 *	make_sgl - populate a scatter/gather list for a packet
 *	@skb: the packet
 *	@sgp: the SGL to populate
 *	@start: start address of skb main body data to include in the SGL
 *	@len: length of skb main body data to include in the SGL
 *	@pdev: the PCI device
 *
 *	Generates a scatter/gather list for the buffers that make up a packet
 *	and returns the SGL size in 8-byte words.  The caller must size the SGL
 *	appropriately.
 */
static inline unsigned int make_sgl(const struct sk_buff *skb,
				    struct sg_ent *sgp, unsigned char *start,
				    unsigned int len, struct pci_dev *pdev)
{
	dma_addr_t mapping;
	unsigned int i, j = 0, nfrags;

	if (len) {
		mapping = pci_map_single(pdev, start, len, PCI_DMA_TODEVICE);
		sgp->len[0] = cpu_to_be32(len);
		sgp->addr[0] = cpu_to_be64(mapping);
		j = 1;
	}

	nfrags = skb_shinfo(skb)->nr_frags;
	for (i = 0; i < nfrags; i++) {
		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];

		mapping = pci_map_page(pdev, frag->page, frag->page_offset,
				       frag->size, PCI_DMA_TODEVICE);
		sgp->len[j] = cpu_to_be32(frag->size);
		sgp->addr[j] = cpu_to_be64(mapping);
		j ^= 1;
		if (j == 0)
			++sgp;
	}
	if (j)
		sgp->len[j] = 0;
	return ((nfrags + (len != 0)) * 3) / 2 + j;
}

/**
 *	check_ring_tx_db - check and potentially ring a Tx queue's doorbell
 *	@adap: the adapter
 *	@q: the Tx queue
 *
 *	Ring the doorbel if a Tx queue is asleep.  There is a natural race,
 *	where the HW is going to sleep just after we checked, however,
 *	then the interrupt handler will detect the outstanding TX packet
 *	and ring the doorbell for us.
 *
 *	When GTS is disabled we unconditionally ring the doorbell.
 */
static inline void check_ring_tx_db(struct adapter *adap, struct sge_txq *q)
{
#if USE_GTS
	clear_bit(TXQ_LAST_PKT_DB, &q->flags);
	if (test_and_set_bit(TXQ_RUNNING, &q->flags) == 0) {
		set_bit(TXQ_LAST_PKT_DB, &q->flags);
		t3_write_reg(adap, A_SG_KDOORBELL,
			     F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
	}
#else
	wmb();			/* write descriptors before telling HW */
	t3_write_reg(adap, A_SG_KDOORBELL,
		     F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
#endif
}

static inline void wr_gen2(struct tx_desc *d, unsigned int gen)
{
#if SGE_NUM_GENBITS == 2
	d->flit[TX_DESC_FLITS - 1] = cpu_to_be64(gen);
#endif
}

/**
 *	write_wr_hdr_sgl - write a WR header and, optionally, SGL
 *	@ndesc: number of Tx descriptors spanned by the SGL
 *	@skb: the packet corresponding to the WR
 *	@d: first Tx descriptor to be written
 *	@pidx: index of above descriptors
 *	@q: the SGE Tx queue
 *	@sgl: the SGL
 *	@flits: number of flits to the start of the SGL in the first descriptor
 *	@sgl_flits: the SGL size in flits
 *	@gen: the Tx descriptor generation
 *	@wr_hi: top 32 bits of WR header based on WR type (big endian)
 *	@wr_lo: low 32 bits of WR header based on WR type (big endian)
 *
 *	Write a work request header and an associated SGL.  If the SGL is
 *	small enough to fit into one Tx descriptor it has already been written
 *	and we just need to write the WR header.  Otherwise we distribute the
 *	SGL across the number of descriptors it spans.
 */
static void write_wr_hdr_sgl(unsigned int ndesc, struct sk_buff *skb,
			     struct tx_desc *d, unsigned int pidx,
			     const struct sge_txq *q,
			     const struct sg_ent *sgl,
			     unsigned int flits, unsigned int sgl_flits,
			     unsigned int gen, __be32 wr_hi,
			     __be32 wr_lo)
{
	struct work_request_hdr *wrp = (struct work_request_hdr *)d;
	struct tx_sw_desc *sd = &q->sdesc[pidx];

	sd->skb = skb;
	if (need_skb_unmap()) {
		sd->fragidx = 0;
		sd->addr_idx = 0;
		sd->sflit = flits;
	}

	if (likely(ndesc == 1)) {
		sd->eop = 1;
		wrp->wr_hi = htonl(F_WR_SOP | F_WR_EOP | V_WR_DATATYPE(1) |
				   V_WR_SGLSFLT(flits)) | wr_hi;
		wmb();
		wrp->wr_lo = htonl(V_WR_LEN(flits + sgl_flits) |
				   V_WR_GEN(gen)) | wr_lo;
		wr_gen2(d, gen);
	} else {
		unsigned int ogen = gen;
		const u64 *fp = (const u64 *)sgl;
		struct work_request_hdr *wp = wrp;

		wrp->wr_hi = htonl(F_WR_SOP | V_WR_DATATYPE(1) |
				   V_WR_SGLSFLT(flits)) | wr_hi;

		while (sgl_flits) {
			unsigned int avail = WR_FLITS - flits;

			if (avail > sgl_flits)
				avail = sgl_flits;
			memcpy(&d->flit[flits], fp, avail * sizeof(*fp));
			sgl_flits -= avail;
			ndesc--;
			if (!sgl_flits)
				break;

			fp += avail;
			d++;
			sd->eop = 0;
			sd++;
			if (++pidx == q->size) {
				pidx = 0;
				gen ^= 1;
				d = q->desc;
				sd = q->sdesc;
			}

			sd->skb = skb;
			wrp = (struct work_request_hdr *)d;
			wrp->wr_hi = htonl(V_WR_DATATYPE(1) |
					   V_WR_SGLSFLT(1)) | wr_hi;
			wrp->wr_lo = htonl(V_WR_LEN(min(WR_FLITS,
							sgl_flits + 1)) |
					   V_WR_GEN(gen)) | wr_lo;
			wr_gen2(d, gen);
			flits = 1;
		}
		sd->eop = 1;
		wrp->wr_hi |= htonl(F_WR_EOP);
		wmb();
		wp->wr_lo = htonl(V_WR_LEN(WR_FLITS) | V_WR_GEN(ogen)) | wr_lo;
		wr_gen2((struct tx_desc *)wp, ogen);
		WARN_ON(ndesc != 0);
	}
}

/**
 *	write_tx_pkt_wr - write a TX_PKT work request
 *	@adap: the adapter
 *	@skb: the packet to send
 *	@pi: the egress interface
 *	@pidx: index of the first Tx descriptor to write
 *	@gen: the generation value to use
 *	@q: the Tx queue
 *	@ndesc: number of descriptors the packet will occupy
 *	@compl: the value of the COMPL bit to use
 *
 *	Generate a TX_PKT work request to send the supplied packet.
 */
static void write_tx_pkt_wr(struct adapter *adap, struct sk_buff *skb,
			    const struct port_info *pi,
			    unsigned int pidx, unsigned int gen,
			    struct sge_txq *q, unsigned int ndesc,
			    unsigned int compl)
{
	unsigned int flits, sgl_flits, cntrl, tso_info;
	struct sg_ent *sgp, sgl[MAX_SKB_FRAGS / 2 + 1];
	struct tx_desc *d = &q->desc[pidx];
	struct cpl_tx_pkt *cpl = (struct cpl_tx_pkt *)d;

	cpl->len = htonl(skb->len);
	cntrl = V_TXPKT_INTF(pi->port_id);

	if (vlan_tx_tag_present(skb) && pi->vlan_grp)
		cntrl |= F_TXPKT_VLAN_VLD | V_TXPKT_VLAN(vlan_tx_tag_get(skb));

	tso_info = V_LSO_MSS(skb_shinfo(skb)->gso_size);
	if (tso_info) {
		int eth_type;
		struct cpl_tx_pkt_lso *hdr = (struct cpl_tx_pkt_lso *)cpl;

		d->flit[2] = 0;
		cntrl |= V_TXPKT_OPCODE(CPL_TX_PKT_LSO);
		hdr->cntrl = htonl(cntrl);
		eth_type = skb_network_offset(skb) == ETH_HLEN ?
		    CPL_ETH_II : CPL_ETH_II_VLAN;
		tso_info |= V_LSO_ETH_TYPE(eth_type) |
		    V_LSO_IPHDR_WORDS(ip_hdr(skb)->ihl) |
		    V_LSO_TCPHDR_WORDS(tcp_hdr(skb)->doff);
		hdr->lso_info = htonl(tso_info);
		flits = 3;
	} else {
		cntrl |= V_TXPKT_OPCODE(CPL_TX_PKT);
		cntrl |= F_TXPKT_IPCSUM_DIS;	/* SW calculates IP csum */
		cntrl |= V_TXPKT_L4CSUM_DIS(skb->ip_summed != CHECKSUM_PARTIAL);
		cpl->cntrl = htonl(cntrl);

		if (skb->len <= WR_LEN - sizeof(*cpl)) {
			q->sdesc[pidx].skb = NULL;
			if (!skb->data_len)
				skb_copy_from_linear_data(skb, &d->flit[2],
							  skb->len);
			else
				skb_copy_bits(skb, 0, &d->flit[2], skb->len);

			flits = (skb->len + 7) / 8 + 2;
			cpl->wr.wr_hi = htonl(V_WR_BCNTLFLT(skb->len & 7) |
					      V_WR_OP(FW_WROPCODE_TUNNEL_TX_PKT)
					      | F_WR_SOP | F_WR_EOP | compl);
			wmb();
			cpl->wr.wr_lo = htonl(V_WR_LEN(flits) | V_WR_GEN(gen) |
					      V_WR_TID(q->token));
			wr_gen2(d, gen);
			kfree_skb(skb);
			return;
		}

		flits = 2;
	}

	sgp = ndesc == 1 ? (struct sg_ent *)&d->flit[flits] : sgl;
	sgl_flits = make_sgl(skb, sgp, skb->data, skb_headlen(skb), adap->pdev);

	write_wr_hdr_sgl(ndesc, skb, d, pidx, q, sgl, flits, sgl_flits, gen,
			 htonl(V_WR_OP(FW_WROPCODE_TUNNEL_TX_PKT) | compl),
			 htonl(V_WR_TID(q->token)));
}

static inline void t3_stop_tx_queue(struct netdev_queue *txq,
				    struct sge_qset *qs, struct sge_txq *q)
{
	netif_tx_stop_queue(txq);
	set_bit(TXQ_ETH, &qs->txq_stopped);
	q->stops++;
}

/**
 *	eth_xmit - add a packet to the Ethernet Tx queue
 *	@skb: the packet
 *	@dev: the egress net device
 *
 *	Add a packet to an SGE Tx queue.  Runs with softirqs disabled.
 */
netdev_tx_t t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
{
	int qidx;
	unsigned int ndesc, pidx, credits, gen, compl;
	const struct port_info *pi = netdev_priv(dev);
	struct adapter *adap = pi->adapter;
	struct netdev_queue *txq;
	struct sge_qset *qs;
	struct sge_txq *q;

	/*
	 * The chip min packet length is 9 octets but play safe and reject
	 * anything shorter than an Ethernet header.
	 */
	if (unlikely(skb->len < ETH_HLEN)) {
		dev_kfree_skb(skb);
		return NETDEV_TX_OK;
	}

	qidx = skb_get_queue_mapping(skb);
	qs = &pi->qs[qidx];
	q = &qs->txq[TXQ_ETH];
	txq = netdev_get_tx_queue(dev, qidx);

	reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK);

	credits = q->size - q->in_use;
	ndesc = calc_tx_descs(skb);

	if (unlikely(credits < ndesc)) {
		t3_stop_tx_queue(txq, qs, q);
		dev_err(&adap->pdev->dev,
			"%s: Tx ring %u full while queue awake!\n",
			dev->name, q->cntxt_id & 7);
		return NETDEV_TX_BUSY;
	}

	q->in_use += ndesc;
	if (unlikely(credits - ndesc < q->stop_thres)) {
		t3_stop_tx_queue(txq, qs, q);

		if (should_restart_tx(q) &&
		    test_and_clear_bit(TXQ_ETH, &qs->txq_stopped)) {
			q->restarts++;
			netif_tx_start_queue(txq);
		}
	}

	gen = q->gen;
	q->unacked += ndesc;
	compl = (q->unacked & 8) << (S_WR_COMPL - 3);
	q->unacked &= 7;
	pidx = q->pidx;
	q->pidx += ndesc;
	if (q->pidx >= q->size) {
		q->pidx -= q->size;
		q->gen ^= 1;
	}

	/* update port statistics */
	if (skb->ip_summed == CHECKSUM_COMPLETE)
		qs->port_stats[SGE_PSTAT_TX_CSUM]++;
	if (skb_shinfo(skb)->gso_size)
		qs->port_stats[SGE_PSTAT_TSO]++;
	if (vlan_tx_tag_present(skb) && pi->vlan_grp)
		qs->port_stats[SGE_PSTAT_VLANINS]++;

	/*
	 * We do not use Tx completion interrupts to free DMAd Tx packets.
	 * This is good for performance but means that we rely on new Tx
	 * packets arriving to run the destructors of completed packets,
	 * which open up space in their sockets' send queues.  Sometimes
	 * we do not get such new packets causing Tx to stall.  A single
	 * UDP transmitter is a good example of this situation.  We have
	 * a clean up timer that periodically reclaims completed packets
	 * but it doesn't run often enough (nor do we want it to) to prevent
	 * lengthy stalls.  A solution to this problem is to run the
	 * destructor early, after the packet is queued but before it's DMAd.
	 * A cons is that we lie to socket memory accounting, but the amount
	 * of extra memory is reasonable (limited by the number of Tx
	 * descriptors), the packets do actually get freed quickly by new
	 * packets almost always, and for protocols like TCP that wait for
	 * acks to really free up the data the extra memory is even less.
	 * On the positive side we run the destructors on the sending CPU
	 * rather than on a potentially different completing CPU, usually a
	 * good thing.  We also run them without holding our Tx queue lock,
	 * unlike what reclaim_completed_tx() would otherwise do.
	 *
	 * Run the destructor before telling the DMA engine about the packet
	 * to make sure it doesn't complete and get freed prematurely.
	 */
	if (likely(!skb_shared(skb)))
		skb_orphan(skb);

	write_tx_pkt_wr(adap, skb, pi, pidx, gen, q, ndesc, compl);
	check_ring_tx_db(adap, q);
	return NETDEV_TX_OK;
}

/**
 *	write_imm - write a packet into a Tx descriptor as immediate data
 *	@d: the Tx descriptor to write
 *	@skb: the packet
 *	@len: the length of packet data to write as immediate data
 *	@gen: the generation bit value to write
 *
 *	Writes a packet as immediate data into a Tx descriptor.  The packet
 *	contains a work request at its beginning.  We must write the packet
 *	carefully so the SGE doesn't read it accidentally before it's written
 *	in its entirety.
 */
static inline void write_imm(struct tx_desc *d, struct sk_buff *skb,
			     unsigned int len, unsigned int gen)
{
	struct work_request_hdr *from = (struct work_request_hdr *)skb->data;
	struct work_request_hdr *to = (struct work_request_hdr *)d;

	if (likely(!skb->data_len))
		memcpy(&to[1], &from[1], len - sizeof(*from));
	else
		skb_copy_bits(skb, sizeof(*from), &to[1], len - sizeof(*from));

	to->wr_hi = from->wr_hi | htonl(F_WR_SOP | F_WR_EOP |
					V_WR_BCNTLFLT(len & 7));
	wmb();
	to->wr_lo = from->wr_lo | htonl(V_WR_GEN(gen) |
					V_WR_LEN((len + 7) / 8));
	wr_gen2(d, gen);
	kfree_skb(skb);
}

/**
 *	check_desc_avail - check descriptor availability on a send queue
 *	@adap: the adapter
 *	@q: the send queue
 *	@skb: the packet needing the descriptors
 *	@ndesc: the number of Tx descriptors needed
 *	@qid: the Tx queue number in its queue set (TXQ_OFLD or TXQ_CTRL)
 *
 *	Checks if the requested number of Tx descriptors is available on an
 *	SGE send queue.  If the queue is already suspended or not enough
 *	descriptors are available the packet is queued for later transmission.
 *	Must be called with the Tx queue locked.
 *
 *	Returns 0 if enough descriptors are available, 1 if there aren't
 *	enough descriptors and the packet has been queued, and 2 if the caller
 *	needs to retry because there weren't enough descriptors at the
 *	beginning of the call but some freed up in the mean time.
 */
static inline int check_desc_avail(struct adapter *adap, struct sge_txq *q,
				   struct sk_buff *skb, unsigned int ndesc,
				   unsigned int qid)
{
	if (unlikely(!skb_queue_empty(&q->sendq))) {
	      addq_exit:__skb_queue_tail(&q->sendq, skb);
		return 1;
	}
	if (unlikely(q->size - q->in_use < ndesc)) {
		struct sge_qset *qs = txq_to_qset(q, qid);

		set_bit(qid, &qs->txq_stopped);
		smp_mb__after_clear_bit();

		if (should_restart_tx(q) &&
		    test_and_clear_bit(qid, &qs->txq_stopped))
			return 2;

		q->stops++;
		goto addq_exit;
	}
	return 0;
}

/**
 *	reclaim_completed_tx_imm - reclaim completed control-queue Tx descs
 *	@q: the SGE control Tx queue
 *
 *	This is a variant of reclaim_completed_tx() that is used for Tx queues
 *	that send only immediate data (presently just the control queues) and
 *	thus do not have any sk_buffs to release.
 */
static inline void reclaim_completed_tx_imm(struct sge_txq *q)
{
	unsigned int reclaim = q->processed - q->cleaned;

	q->in_use -= reclaim;
	q->cleaned += reclaim;
}

static inline int immediate(const struct sk_buff *skb)
{
	return skb->len <= WR_LEN;
}

/**
 *	ctrl_xmit - send a packet through an SGE control Tx queue
 *	@adap: the adapter
 *	@q: the control queue
 *	@skb: the packet
 *
 *	Send a packet through an SGE control Tx queue.  Packets sent through
 *	a control queue must fit entirely as immediate data in a single Tx
 *	descriptor and have no page fragments.
 */
static int ctrl_xmit(struct adapter *adap, struct sge_txq *q,
		     struct sk_buff *skb)
{
	int ret;
	struct work_request_hdr *wrp = (struct work_request_hdr *)skb->data;

	if (unlikely(!immediate(skb))) {
		WARN_ON(1);
		dev_kfree_skb(skb);
		return NET_XMIT_SUCCESS;
	}

	wrp->wr_hi |= htonl(F_WR_SOP | F_WR_EOP);
	wrp->wr_lo = htonl(V_WR_TID(q->token));

	spin_lock(&q->lock);
      again:reclaim_completed_tx_imm(q);

	ret = check_desc_avail(adap, q, skb, 1, TXQ_CTRL);
	if (unlikely(ret)) {
		if (ret == 1) {
			spin_unlock(&q->lock);
			return NET_XMIT_CN;
		}
		goto again;
	}

	write_imm(&q->desc[q->pidx], skb, skb->len, q->gen);

	q->in_use++;
	if (++q->pidx >= q->size) {
		q->pidx = 0;
		q->gen ^= 1;
	}
	spin_unlock(&q->lock);
	wmb();
	t3_write_reg(adap, A_SG_KDOORBELL,
		     F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
	return NET_XMIT_SUCCESS;
}

/**
 *	restart_ctrlq - restart a suspended control queue
 *	@qs: the queue set cotaining the control queue
 *
 *	Resumes transmission on a suspended Tx control queue.
 */
static void restart_ctrlq(unsigned long data)
{
	struct sk_buff *skb;
	struct sge_qset *qs = (struct sge_qset *)data;
	struct sge_txq *q = &qs->txq[TXQ_CTRL];

	spin_lock(&q->lock);
      again:reclaim_completed_tx_imm(q);

	while (q->in_use < q->size &&
	       (skb = __skb_dequeue(&q->sendq)) != NULL) {

		write_imm(&q->desc[q->pidx], skb, skb->len, q->gen);

		if (++q->pidx >= q->size) {
			q->pidx = 0;
			q->gen ^= 1;
		}
		q->in_use++;
	}

	if (!skb_queue_empty(&q->sendq)) {
		set_bit(TXQ_CTRL, &qs->txq_stopped);
		smp_mb__after_clear_bit();

		if (should_restart_tx(q) &&
		    test_and_clear_bit(TXQ_CTRL, &qs->txq_stopped))
			goto again;
		q->stops++;
	}

	spin_unlock(&q->lock);
	wmb();
	t3_write_reg(qs->adap, A_SG_KDOORBELL,
		     F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
}

/*
 * Send a management message through control queue 0
 */
int t3_mgmt_tx(struct adapter *adap, struct sk_buff *skb)
{
	int ret;
	local_bh_disable();
	ret = ctrl_xmit(adap, &adap->sge.qs[0].txq[TXQ_CTRL], skb);
	local_bh_enable();

	return ret;
}

/**
 *	deferred_unmap_destructor - unmap a packet when it is freed
 *	@skb: the packet
 *
 *	This is the packet destructor used for Tx packets that need to remain
 *	mapped until they are freed rather than until their Tx descriptors are
 *	freed.
 */
static void deferred_unmap_destructor(struct sk_buff *skb)
{
	int i;
	const dma_addr_t *p;
	const struct skb_shared_info *si;
	const struct deferred_unmap_info *dui;

	dui = (struct deferred_unmap_info *)skb->head;
	p = dui->addr;

	if (skb->tail - skb->transport_header)
		pci_unmap_single(dui->pdev, *p++,
				 skb->tail - skb->transport_header,
				 PCI_DMA_TODEVICE);

	si = skb_shinfo(skb);
	for (i = 0; i < si->nr_frags; i++)
		pci_unmap_page(dui->pdev, *p++, si->frags[i].size,
			       PCI_DMA_TODEVICE);
}

static void setup_deferred_unmapping(struct sk_buff *skb, struct pci_dev *pdev,
				     const struct sg_ent *sgl, int sgl_flits)
{
	dma_addr_t *p;
	struct deferred_unmap_info *dui;

	dui = (struct deferred_unmap_info *)skb->head;
	dui->pdev = pdev;
	for (p = dui->addr; sgl_flits >= 3; sgl++, sgl_flits -= 3) {
		*p++ = be64_to_cpu(sgl->addr[0]);
		*p++ = be64_to_cpu(sgl->addr[1]);
	}
	if (sgl_flits)
		*p = be64_to_cpu(sgl->addr[0]);
}

/**
 *	write_ofld_wr - write an offload work request
 *	@adap: the adapter
 *	@skb: the packet to send
 *	@q: the Tx queue
 *	@pidx: index of the first Tx descriptor to write
 *	@gen: the generation value to use
 *	@ndesc: number of descriptors the packet will occupy
 *
 *	Write an offload work request to send the supplied packet.  The packet
 *	data already carry the work request with most fields populated.
 */
static void write_ofld_wr(struct adapter *adap, struct sk_buff *skb,
			  struct sge_txq *q, unsigned int pidx,
			  unsigned int gen, unsigned int ndesc)
{
	unsigned int sgl_flits, flits;
	struct work_request_hdr *from;
	struct sg_ent *sgp, sgl[MAX_SKB_FRAGS / 2 + 1];
	struct tx_desc *d = &q->desc[pidx];

	if (immediate(skb)) {
		q->sdesc[pidx].skb = NULL;
		write_imm(d, skb, skb->len, gen);
		return;
	}

	/* Only TX_DATA builds SGLs */

	from = (struct work_request_hdr *)skb->data;
	memcpy(&d->flit[1], &from[1],
	       skb_transport_offset(skb) - sizeof(*from));

	flits = skb_transport_offset(skb) / 8;
	sgp = ndesc == 1 ? (struct sg_ent *)&d->flit[flits] : sgl;
	sgl_flits = make_sgl(skb, sgp, skb_transport_header(skb),
			     skb->tail - skb->transport_header,
			     adap->pdev);
	if (need_skb_unmap()) {
		setup_deferred_unmapping(skb, adap->pdev, sgp, sgl_flits);
		skb->destructor = deferred_unmap_destructor;
	}

	write_wr_hdr_sgl(ndesc, skb, d, pidx, q, sgl, flits, sgl_flits,
			 gen, from->wr_hi, from->wr_lo);
}

/**
 *	calc_tx_descs_ofld - calculate # of Tx descriptors for an offload packet
 *	@skb: the packet
 *
 * 	Returns the number of Tx descriptors needed for the given offload
 * 	packet.  These packets are already fully constructed.
 */
static inline unsigned int calc_tx_descs_ofld(const struct sk_buff *skb)
{
	unsigned int flits, cnt;

	if (skb->len <= WR_LEN)
		return 1;	/* packet fits as immediate data */

	flits = skb_transport_offset(skb) / 8;	/* headers */
	cnt = skb_shinfo(skb)->nr_frags;
	if (skb->tail != skb->transport_header)
		cnt++;
	return flits_to_desc(flits + sgl_len(cnt));
}

/**
 *	ofld_xmit - send a packet through an offload queue
 *	@adap: the adapter
 *	@q: the Tx offload queue
 *	@skb: the packet
 *
 *	Send an offload packet through an SGE offload queue.
 */
static int ofld_xmit(struct adapter *adap, struct sge_txq *q,
		     struct sk_buff *skb)
{
	int ret;
	unsigned int ndesc = calc_tx_descs_ofld(skb), pidx, gen;

	spin_lock(&q->lock);
again:	reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK);

	ret = check_desc_avail(adap, q, skb, ndesc, TXQ_OFLD);
	if (unlikely(ret)) {
		if (ret == 1) {
			skb->priority = ndesc;	/* save for restart */
			spin_unlock(&q->lock);
			return NET_XMIT_CN;
		}
		goto again;
	}

	gen = q->gen;
	q->in_use += ndesc;
	pidx = q->pidx;
	q->pidx += ndesc;
	if (q->pidx >= q->size) {
		q->pidx -= q->size;
		q->gen ^= 1;
	}
	spin_unlock(&q->lock);

	write_ofld_wr(adap, skb, q, pidx, gen, ndesc);
	check_ring_tx_db(adap, q);
	return NET_XMIT_SUCCESS;
}

/**
 *	restart_offloadq - restart a suspended offload queue
 *	@qs: the queue set cotaining the offload queue
 *
 *	Resumes transmission on a suspended Tx offload queue.
 */
static void restart_offloadq(unsigned long data)
{
	struct sk_buff *skb;
	struct sge_qset *qs = (struct sge_qset *)data;
	struct sge_txq *q = &qs->txq[TXQ_OFLD];
	const struct port_info *pi = netdev_priv(qs->netdev);
	struct adapter *adap = pi->adapter;

	spin_lock(&q->lock);
again:	reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK);

	while ((skb = skb_peek(&q->sendq)) != NULL) {
		unsigned int gen, pidx;
		unsigned int ndesc = skb->priority;

		if (unlikely(q->size - q->in_use < ndesc)) {
			set_bit(TXQ_OFLD, &qs->txq_stopped);
			smp_mb__after_clear_bit();

			if (should_restart_tx(q) &&
			    test_and_clear_bit(TXQ_OFLD, &qs->txq_stopped))
				goto again;
			q->stops++;
			break;
		}

		gen = q->gen;
		q->in_use += ndesc;
		pidx = q->pidx;
		q->pidx += ndesc;
		if (q->pidx >= q->size) {
			q->pidx -= q->size;
			q->gen ^= 1;
		}
		__skb_unlink(skb, &q->sendq);
		spin_unlock(&q->lock);

		write_ofld_wr(adap, skb, q, pidx, gen, ndesc);
		spin_lock(&q->lock);
	}
	spin_unlock(&q->lock);

#if USE_GTS
	set_bit(TXQ_RUNNING, &q->flags);
	set_bit(TXQ_LAST_PKT_DB, &q->flags);
#endif
	wmb();
	t3_write_reg(adap, A_SG_KDOORBELL,
		     F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
}

/**
 *	queue_set - return the queue set a packet should use
 *	@skb: the packet
 *
 *	Maps a packet to the SGE queue set it should use.  The desired queue
 *	set is carried in bits 1-3 in the packet's priority.
 */
static inline int queue_set(const struct sk_buff *skb)
{
	return skb->priority >> 1;
}

/**
 *	is_ctrl_pkt - return whether an offload packet is a control packet
 *	@skb: the packet
 *
 *	Determines whether an offload packet should use an OFLD or a CTRL
 *	Tx queue.  This is indicated by bit 0 in the packet's priority.
 */
static inline int is_ctrl_pkt(const struct sk_buff *skb)
{
	return skb->priority & 1;
}

/**
 *	t3_offload_tx - send an offload packet
 *	@tdev: the offload device to send to
 *	@skb: the packet
 *
 *	Sends an offload packet.  We use the packet priority to select the
 *	appropriate Tx queue as follows: bit 0 indicates whether the packet
 *	should be sent as regular or control, bits 1-3 select the queue set.
 */
int t3_offload_tx(struct t3cdev *tdev, struct sk_buff *skb)
{
	struct adapter *adap = tdev2adap(tdev);
	struct sge_qset *qs = &adap->sge.qs[queue_set(skb)];

	if (unlikely(is_ctrl_pkt(skb)))
		return ctrl_xmit(adap, &qs->txq[TXQ_CTRL], skb);

	return ofld_xmit(adap, &qs->txq[TXQ_OFLD], skb);
}

/**
 *	offload_enqueue - add an offload packet to an SGE offload receive queue
 *	@q: the SGE response queue
 *	@skb: the packet
 *
 *	Add a new offload packet to an SGE response queue's offload packet
 *	queue.  If the packet is the first on the queue it schedules the RX
 *	softirq to process the queue.
 */
static inline void offload_enqueue(struct sge_rspq *q, struct sk_buff *skb)
{
	int was_empty = skb_queue_empty(&q->rx_queue);

	__skb_queue_tail(&q->rx_queue, skb);

	if (was_empty) {
		struct sge_qset *qs = rspq_to_qset(q);

		napi_schedule(&qs->napi);
	}
}

/**
 *	deliver_partial_bundle - deliver a (partial) bundle of Rx offload pkts
 *	@tdev: the offload device that will be receiving the packets
 *	@q: the SGE response queue that assembled the bundle
 *	@skbs: the partial bundle
 *	@n: the number of packets in the bundle
 *
 *	Delivers a (partial) bundle of Rx offload packets to an offload device.
 */
static inline void deliver_partial_bundle(struct t3cdev *tdev,
					  struct sge_rspq *q,
					  struct sk_buff *skbs[], int n)
{
	if (n) {
		q->offload_bundles++;
		tdev->recv(tdev, skbs, n);
	}
}

/**
 *	ofld_poll - NAPI handler for offload packets in interrupt mode
 *	@dev: the network device doing the polling
 *	@budget: polling budget
 *
 *	The NAPI handler for offload packets when a response queue is serviced
 *	by the hard interrupt handler, i.e., when it's operating in non-polling
 *	mode.  Creates small packet batches and sends them through the offload
 *	receive handler.  Batches need to be of modest size as we do prefetches
 *	on the packets in each.
 */
static int ofld_poll(struct napi_struct *napi, int budget)
{
	struct sge_qset *qs = container_of(napi, struct sge_qset, napi);
	struct sge_rspq *q = &qs->rspq;
	struct adapter *adapter = qs->adap;
	int work_done = 0;

	while (work_done < budget) {
		struct sk_buff *skb, *tmp, *skbs[RX_BUNDLE_SIZE];
		struct sk_buff_head queue;
		int ngathered;

		spin_lock_irq(&q->lock);
		__skb_queue_head_init(&queue);
		skb_queue_splice_init(&q->rx_queue, &queue);
		if (skb_queue_empty(&queue)) {
			napi_complete(napi);
			spin_unlock_irq(&q->lock);
			return work_done;
		}
		spin_unlock_irq(&q->lock);

		ngathered = 0;
		skb_queue_walk_safe(&queue, skb, tmp) {
			if (work_done >= budget)
				break;
			work_done++;

			__skb_unlink(skb, &queue);
			prefetch(skb->data);
			skbs[ngathered] = skb;
			if (++ngathered == RX_BUNDLE_SIZE) {
				q->offload_bundles++;
				adapter->tdev.recv(&adapter->tdev, skbs,
						   ngathered);
				ngathered = 0;
			}
		}
		if (!skb_queue_empty(&queue)) {
			/* splice remaining packets back onto Rx queue */
			spin_lock_irq(&q->lock);
			skb_queue_splice(&queue, &q->rx_queue);
			spin_unlock_irq(&q->lock);
		}
		deliver_partial_bundle(&adapter->tdev, q, skbs, ngathered);
	}

	return work_done;
}

/**
 *	rx_offload - process a received offload packet
 *	@tdev: the offload device receiving the packet
 *	@rq: the response queue that received the packet
 *	@skb: the packet
 *	@rx_gather: a gather list of packets if we are building a bundle
 *	@gather_idx: index of the next available slot in the bundle
 *
 *	Process an ingress offload pakcet and add it to the offload ingress
 *	queue. 	Returns the index of the next available slot in the bundle.
 */
static inline int rx_offload(struct t3cdev *tdev, struct sge_rspq *rq,
			     struct sk_buff *skb, struct sk_buff *rx_gather[],
			     unsigned int gather_idx)
{
	skb_reset_mac_header(skb);
	skb_reset_network_header(skb);
	skb_reset_transport_header(skb);

	if (rq->polling) {
		rx_gather[gather_idx++] = skb;
		if (gather_idx == RX_BUNDLE_SIZE) {
			tdev->recv(tdev, rx_gather, RX_BUNDLE_SIZE);
			gather_idx = 0;
			rq->offload_bundles++;
		}
	} else
		offload_enqueue(rq, skb);

	return gather_idx;
}

/**
 *	restart_tx - check whether to restart suspended Tx queues
 *	@qs: the queue set to resume
 *
 *	Restarts suspended Tx queues of an SGE queue set if they have enough
 *	free resources to resume operation.
 */
static void restart_tx(struct sge_qset *qs)
{
	if (test_bit(TXQ_ETH, &qs->txq_stopped) &&
	    should_restart_tx(&qs->txq[TXQ_ETH]) &&
	    test_and_clear_bit(TXQ_ETH, &qs->txq_stopped)) {
		qs->txq[TXQ_ETH].restarts++;
		if (netif_running(qs->netdev))
			netif_tx_wake_queue(qs->tx_q);
	}

	if (test_bit(TXQ_OFLD, &qs->txq_stopped) &&
	    should_restart_tx(&qs->txq[TXQ_OFLD]) &&
	    test_and_clear_bit(TXQ_OFLD, &qs->txq_stopped)) {
		qs->txq[TXQ_OFLD].restarts++;
		tasklet_schedule(&qs->txq[TXQ_OFLD].qresume_tsk);
	}
	if (test_bit(TXQ_CTRL, &qs->txq_stopped) &&
	    should_restart_tx(&qs->txq[TXQ_CTRL]) &&
	    test_and_clear_bit(TXQ_CTRL, &qs->txq_stopped)) {
		qs->txq[TXQ_CTRL].restarts++;
		tasklet_schedule(&qs->txq[TXQ_CTRL].qresume_tsk);
	}
}

/**
 *	cxgb3_arp_process - process an ARP request probing a private IP address
 *	@adapter: the adapter
 *	@skb: the skbuff containing the ARP request
 *
 *	Check if the ARP request is probing the private IP address
 *	dedicated to iSCSI, generate an ARP reply if so.
 */
static void cxgb3_arp_process(struct port_info *pi, struct sk_buff *skb)
{
	struct net_device *dev = skb->dev;
	struct arphdr *arp;
	unsigned char *arp_ptr;
	unsigned char *sha;
	__be32 sip, tip;

	if (!dev)
		return;

	skb_reset_network_header(skb);
	arp = arp_hdr(skb);

	if (arp->ar_op != htons(ARPOP_REQUEST))
		return;

	arp_ptr = (unsigned char *)(arp + 1);
	sha = arp_ptr;
	arp_ptr += dev->addr_len;
	memcpy(&sip, arp_ptr, sizeof(sip));
	arp_ptr += sizeof(sip);
	arp_ptr += dev->addr_len;
	memcpy(&tip, arp_ptr, sizeof(tip));

	if (tip != pi->iscsi_ipv4addr)
		return;

	arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
		 pi->iscsic.mac_addr, sha);

}

static inline int is_arp(struct sk_buff *skb)
{
	return skb->protocol == htons(ETH_P_ARP);
}

static void cxgb3_process_iscsi_prov_pack(struct port_info *pi,
					struct sk_buff *skb)
{
	if (is_arp(skb)) {
		cxgb3_arp_process(pi, skb);
		return;
	}

	if (pi->iscsic.recv)
		pi->iscsic.recv(pi, skb);

}

/**
 *	rx_eth - process an ingress ethernet packet
 *	@adap: the adapter
 *	@rq: the response queue that received the packet
 *	@skb: the packet
 *	@pad: amount of padding at the start of the buffer
 *
 *	Process an ingress ethernet pakcet and deliver it to the stack.
 *	The padding is 2 if the packet was delivered in an Rx buffer and 0
 *	if it was immediate data in a response.
 */
static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
		   struct sk_buff *skb, int pad, int lro)
{
	struct cpl_rx_pkt *p = (struct cpl_rx_pkt *)(skb->data + pad);
	struct sge_qset *qs = rspq_to_qset(rq);
	struct port_info *pi;

	skb_pull(skb, sizeof(*p) + pad);
	skb->protocol = eth_type_trans(skb, adap->port[p->iff]);
	pi = netdev_priv(skb->dev);
	if ((pi->rx_offload & T3_RX_CSUM) && p->csum_valid &&
	    p->csum == htons(0xffff) && !p->fragment) {
		qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
		skb->ip_summed = CHECKSUM_UNNECESSARY;
	} else
		skb->ip_summed = CHECKSUM_NONE;
	skb_record_rx_queue(skb, qs - &adap->sge.qs[0]);

	if (unlikely(p->vlan_valid)) {
		struct vlan_group *grp = pi->vlan_grp;

		qs->port_stats[SGE_PSTAT_VLANEX]++;
		if (likely(grp))
			if (lro)
				vlan_gro_receive(&qs->napi, grp,
						 ntohs(p->vlan), skb);
			else {
				if (unlikely(pi->iscsic.flags)) {
					unsigned short vtag = ntohs(p->vlan) &
								VLAN_VID_MASK;
					skb->dev = vlan_group_get_device(grp,
									 vtag);
					cxgb3_process_iscsi_prov_pack(pi, skb);
				}
				__vlan_hwaccel_rx(skb, grp, ntohs(p->vlan),
					  	  rq->polling);
			}
		else
			dev_kfree_skb_any(skb);
	} else if (rq->polling) {
		if (lro)
			napi_gro_receive(&qs->napi, skb);
		else {
			if (unlikely(pi->iscsic.flags))
				cxgb3_process_iscsi_prov_pack(pi, skb);
			netif_receive_skb(skb);
		}
	} else
		netif_rx(skb);
}

static inline int is_eth_tcp(u32 rss)
{
	return G_HASHTYPE(ntohl(rss)) == RSS_HASH_4_TUPLE;
}

/**
 *	lro_add_page - add a page chunk to an LRO session
 *	@adap: the adapter
 *	@qs: the associated queue set
 *	@fl: the free list containing the page chunk to add
 *	@len: packet length
 *	@complete: Indicates the last fragment of a frame
 *
 *	Add a received packet contained in a page chunk to an existing LRO
 *	session.
 */
static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
			 struct sge_fl *fl, int len, int complete)
{
	struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
	struct port_info *pi = netdev_priv(qs->netdev);
	struct sk_buff *skb = NULL;
	struct cpl_rx_pkt *cpl;
	struct skb_frag_struct *rx_frag;
	int nr_frags;
	int offset = 0;

	if (!qs->nomem) {
		skb = napi_get_frags(&qs->napi);
		qs->nomem = !skb;
	}

	fl->credits--;

	pci_dma_sync_single_for_cpu(adap->pdev,
				    pci_unmap_addr(sd, dma_addr),
				    fl->buf_size - SGE_PG_RSVD,
				    PCI_DMA_FROMDEVICE);

	(*sd->pg_chunk.p_cnt)--;
	if (!*sd->pg_chunk.p_cnt && sd->pg_chunk.page != fl->pg_chunk.page)
		pci_unmap_page(adap->pdev,
			       sd->pg_chunk.mapping,
			       fl->alloc_size,
			       PCI_DMA_FROMDEVICE);

	if (!skb) {
		put_page(sd->pg_chunk.page);
		if (complete)
			qs->nomem = 0;
		return;
	}

	rx_frag = skb_shinfo(skb)->frags;
	nr_frags = skb_shinfo(skb)->nr_frags;

	if (!nr_frags) {
		offset = 2 + sizeof(struct cpl_rx_pkt);
		cpl = qs->lro_va = sd->pg_chunk.va + 2;

		if ((pi->rx_offload & T3_RX_CSUM) &&
		     cpl->csum_valid && cpl->csum == htons(0xffff)) {
			skb->ip_summed = CHECKSUM_UNNECESSARY;
			qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
		} else
			skb->ip_summed = CHECKSUM_NONE;
	} else
		cpl = qs->lro_va;

	len -= offset;

	rx_frag += nr_frags;
	rx_frag->page = sd->pg_chunk.page;
	rx_frag->page_offset = sd->pg_chunk.offset + offset;
	rx_frag->size = len;

	skb->len += len;
	skb->data_len += len;
	skb->truesize += len;
	skb_shinfo(skb)->nr_frags++;

	if (!complete)
		return;

	skb_record_rx_queue(skb, qs - &adap->sge.qs[0]);

	if (unlikely(cpl->vlan_valid)) {
		struct vlan_group *grp = pi->vlan_grp;

		if (likely(grp != NULL)) {
			vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan));
			return;
		}
	}
	napi_gro_frags(&qs->napi);
}

/**
 *	handle_rsp_cntrl_info - handles control information in a response
 *	@qs: the queue set corresponding to the response
 *	@flags: the response control flags
 *
 *	Handles the control information of an SGE response, such as GTS
 *	indications and completion credits for the queue set's Tx queues.
 *	HW coalesces credits, we don't do any extra SW coalescing.
 */
static inline void handle_rsp_cntrl_info(struct sge_qset *qs, u32 flags)
{
	unsigned int credits;

#if USE_GTS
	if (flags & F_RSPD_TXQ0_GTS)
		clear_bit(TXQ_RUNNING, &qs->txq[TXQ_ETH].flags);
#endif

	credits = G_RSPD_TXQ0_CR(flags);
	if (credits)
		qs->txq[TXQ_ETH].processed += credits;

	credits = G_RSPD_TXQ2_CR(flags);
	if (credits)
		qs->txq[TXQ_CTRL].processed += credits;

# if USE_GTS
	if (flags & F_RSPD_TXQ1_GTS)
		clear_bit(TXQ_RUNNING, &qs->txq[TXQ_OFLD].flags);
# endif
	credits = G_RSPD_TXQ1_CR(flags);
	if (credits)
		qs->txq[TXQ_OFLD].processed += credits;
}

/**
 *	check_ring_db - check if we need to ring any doorbells
 *	@adapter: the adapter
 *	@qs: the queue set whose Tx queues are to be examined
 *	@sleeping: indicates which Tx queue sent GTS
 *
 *	Checks if some of a queue set's Tx queues need to ring their doorbells
 *	to resume transmission after idling while they still have unprocessed
 *	descriptors.
 */
static void check_ring_db(struct adapter *adap, struct sge_qset *qs,
			  unsigned int sleeping)
{
	if (sleeping & F_RSPD_TXQ0_GTS) {
		struct sge_txq *txq = &qs->txq[TXQ_ETH];

		if (txq->cleaned + txq->in_use != txq->processed &&
		    !test_and_set_bit(TXQ_LAST_PKT_DB, &txq->flags)) {
			set_bit(TXQ_RUNNING, &txq->flags);
			t3_write_reg(adap, A_SG_KDOORBELL, F_SELEGRCNTX |
				     V_EGRCNTX(txq->cntxt_id));
		}
	}

	if (sleeping & F_RSPD_TXQ1_GTS) {
		struct sge_txq *txq = &qs->txq[TXQ_OFLD];

		if (txq->cleaned + txq->in_use != txq->processed &&
		    !test_and_set_bit(TXQ_LAST_PKT_DB, &txq->flags)) {
			set_bit(TXQ_RUNNING, &txq->flags);
			t3_write_reg(adap, A_SG_KDOORBELL, F_SELEGRCNTX |
				     V_EGRCNTX(txq->cntxt_id));
		}
	}
}

/**
 *	is_new_response - check if a response is newly written
 *	@r: the response descriptor
 *	@q: the response queue
 *
 *	Returns true if a response descriptor contains a yet unprocessed
 *	response.
 */
static inline int is_new_response(const struct rsp_desc *r,
				  const struct sge_rspq *q)
{
	return (r->intr_gen & F_RSPD_GEN2) == q->gen;
}

static inline void clear_rspq_bufstate(struct sge_rspq * const q)
{
	q->pg_skb = NULL;
	q->rx_recycle_buf = 0;
}

#define RSPD_GTS_MASK  (F_RSPD_TXQ0_GTS | F_RSPD_TXQ1_GTS)
#define RSPD_CTRL_MASK (RSPD_GTS_MASK | \
			V_RSPD_TXQ0_CR(M_RSPD_TXQ0_CR) | \
			V_RSPD_TXQ1_CR(M_RSPD_TXQ1_CR) | \
			V_RSPD_TXQ2_CR(M_RSPD_TXQ2_CR))

/* How long to delay the next interrupt in case of memory shortage, in 0.1us. */
#define NOMEM_INTR_DELAY 2500

/**
 *	process_responses - process responses from an SGE response queue
 *	@adap: the adapter
 *	@qs: the queue set to which the response queue belongs
 *	@budget: how many responses can be processed in this round
 *
 *	Process responses from an SGE response queue up to the supplied budget.
 *	Responses include received packets as well as credits and other events
 *	for the queues that belong to the response queue's queue set.
 *	A negative budget is effectively unlimited.
 *
 *	Additionally choose the interrupt holdoff time for the next interrupt
 *	on this queue.  If the system is under memory shortage use a fairly
 *	long delay to help recovery.
 */
static int process_responses(struct adapter *adap, struct sge_qset *qs,
			     int budget)
{
	struct sge_rspq *q = &qs->rspq;
	struct rsp_desc *r = &q->desc[q->cidx];
	int budget_left = budget;
	unsigned int sleeping = 0;
	struct sk_buff *offload_skbs[RX_BUNDLE_SIZE];
	int ngathered = 0;

	q->next_holdoff = q->holdoff_tmr;

	while (likely(budget_left && is_new_response(r, q))) {
		int packet_complete, eth, ethpad = 2, lro = qs->lro_enabled;
		struct sk_buff *skb = NULL;
		u32 len, flags;
		__be32 rss_hi, rss_lo;

		rmb();
		eth = r->rss_hdr.opcode == CPL_RX_PKT;
		rss_hi = *(const __be32 *)r;
		rss_lo = r->rss_hdr.rss_hash_val;
		flags = ntohl(r->flags);

		if (unlikely(flags & F_RSPD_ASYNC_NOTIF)) {
			skb = alloc_skb(AN_PKT_SIZE, GFP_ATOMIC);
			if (!skb)
				goto no_mem;

			memcpy(__skb_put(skb, AN_PKT_SIZE), r, AN_PKT_SIZE);
			skb->data[0] = CPL_ASYNC_NOTIF;
			rss_hi = htonl(CPL_ASYNC_NOTIF << 24);
			q->async_notif++;
		} else if (flags & F_RSPD_IMM_DATA_VALID) {
			skb = get_imm_packet(r);
			if (unlikely(!skb)) {
no_mem:
				q->next_holdoff = NOMEM_INTR_DELAY;
				q->nomem++;
				/* consume one credit since we tried */
				budget_left--;
				break;
			}
			q->imm_data++;
			ethpad = 0;
		} else if ((len = ntohl(r->len_cq)) != 0) {
			struct sge_fl *fl;

			lro &= eth && is_eth_tcp(rss_hi);

			fl = (len & F_RSPD_FLQ) ? &qs->fl[1] : &qs->fl[0];
			if (fl->use_pages) {
				void *addr = fl->sdesc[fl->cidx].pg_chunk.va;

				prefetch(addr);
#if L1_CACHE_BYTES < 128
				prefetch(addr + L1_CACHE_BYTES);
#endif
				__refill_fl(adap, fl);
				if (lro > 0) {
					lro_add_page(adap, qs, fl,
						     G_RSPD_LEN(len),
						     flags & F_RSPD_EOP);
					 goto next_fl;
				}

				skb = get_packet_pg(adap, fl, q,
						    G_RSPD_LEN(len),
						    eth ?
						    SGE_RX_DROP_THRES : 0);
				q->pg_skb = skb;
			} else
				skb = get_packet(adap, fl, G_RSPD_LEN(len),
						 eth ? SGE_RX_DROP_THRES : 0);
			if (unlikely(!skb)) {
				if (!eth)
					goto no_mem;
				q->rx_drops++;
			} else if (unlikely(r->rss_hdr.opcode == CPL_TRACE_PKT))
				__skb_pull(skb, 2);
next_fl:
			if (++fl->cidx == fl->size)
				fl->cidx = 0;
		} else
			q->pure_rsps++;

		if (flags & RSPD_CTRL_MASK) {
			sleeping |= flags & RSPD_GTS_MASK;
			handle_rsp_cntrl_info(qs, flags);
		}

		r++;
		if (unlikely(++q->cidx == q->size)) {
			q->cidx = 0;
			q->gen ^= 1;
			r = q->desc;
		}
		prefetch(r);

		if (++q->credits >= (q->size / 4)) {
			refill_rspq(adap, q, q->credits);
			q->credits = 0;
		}

		packet_complete = flags &
				  (F_RSPD_EOP | F_RSPD_IMM_DATA_VALID |
				   F_RSPD_ASYNC_NOTIF);

		if (skb != NULL && packet_complete) {
			if (eth)
				rx_eth(adap, q, skb, ethpad, lro);
			else {
				q->offload_pkts++;
				/* Preserve the RSS info in csum & priority */
				skb->csum = rss_hi;
				skb->priority = rss_lo;
				ngathered = rx_offload(&adap->tdev, q, skb,
						       offload_skbs,
						       ngathered);
			}

			if (flags & F_RSPD_EOP)
				clear_rspq_bufstate(q);
		}
		--budget_left;
	}

	deliver_partial_bundle(&adap->tdev, q, offload_skbs, ngathered);

	if (sleeping)
		check_ring_db(adap, qs, sleeping);

	smp_mb();		/* commit Tx queue .processed updates */
	if (unlikely(qs->txq_stopped != 0))
		restart_tx(qs);

	budget -= budget_left;
	return budget;
}

static inline int is_pure_response(const struct rsp_desc *r)
{
	__be32 n = r->flags & htonl(F_RSPD_ASYNC_NOTIF | F_RSPD_IMM_DATA_VALID);

	return (n | r->len_cq) == 0;
}

/**
 *	napi_rx_handler - the NAPI handler for Rx processing
 *	@napi: the napi instance
 *	@budget: how many packets we can process in this round
 *
 *	Handler for new data events when using NAPI.
 */
static int napi_rx_handler(struct napi_struct *napi, int budget)
{
	struct sge_qset *qs = container_of(napi, struct sge_qset, napi);
	struct adapter *adap = qs->adap;
	int work_done = process_responses(adap, qs, budget);

	if (likely(work_done < budget)) {
		napi_complete(napi);

		/*
		 * Because we don't atomically flush the following
		 * write it is possible that in very rare cases it can
		 * reach the device in a way that races with a new
		 * response being written plus an error interrupt
		 * causing the NAPI interrupt handler below to return
		 * unhandled status to the OS.  To protect against
		 * this would require flushing the write and doing
		 * both the write and the flush with interrupts off.
		 * Way too expensive and unjustifiable given the
		 * rarity of the race.
		 *
		 * The race cannot happen at all with MSI-X.
		 */
		t3_write_reg(adap, A_SG_GTS, V_RSPQ(qs->rspq.cntxt_id) |
			     V_NEWTIMER(qs->rspq.next_holdoff) |
			     V_NEWINDEX(qs->rspq.cidx));
	}
	return work_done;
}

/*
 * Returns true if the device is already scheduled for polling.
 */
static inline int napi_is_scheduled(struct napi_struct *napi)
{
	return test_bit(NAPI_STATE_SCHED, &napi->state);
}

/**
 *	process_pure_responses - process pure responses from a response queue
 *	@adap: the adapter
 *	@qs: the queue set owning the response queue
 *	@r: the first pure response to process
 *
 *	A simpler version of process_responses() that handles only pure (i.e.,
 *	non data-carrying) responses.  Such respones are too light-weight to
 *	justify calling a softirq under NAPI, so we handle them specially in
 *	the interrupt handler.  The function is called with a pointer to a
 *	response, which the caller must ensure is a valid pure response.
 *
 *	Returns 1 if it encounters a valid data-carrying response, 0 otherwise.
 */
static int process_pure_responses(struct adapter *adap, struct sge_qset *qs,
				  struct rsp_desc *r)
{
	struct sge_rspq *q = &qs->rspq;
	unsigned int sleeping = 0;

	do {
		u32 flags = ntohl(r->flags);

		r++;
		if (unlikely(++q->cidx == q->size)) {
			q->cidx = 0;
			q->gen ^= 1;
			r = q->desc;
		}
		prefetch(r);

		if (flags & RSPD_CTRL_MASK) {
			sleeping |= flags & RSPD_GTS_MASK;
			handle_rsp_cntrl_info(qs, flags);
		}

		q->pure_rsps++;
		if (++q->credits >= (q->size / 4)) {
			refill_rspq(adap, q, q->credits);
			q->credits = 0;
		}
		if (!is_new_response(r, q))
			break;
		rmb();
	} while (is_pure_response(r));

	if (sleeping)
		check_ring_db(adap, qs, sleeping);

	smp_mb();		/* commit Tx queue .processed updates */
	if (unlikely(qs->txq_stopped != 0))
		restart_tx(qs);

	return is_new_response(r, q);
}

/**
 *	handle_responses - decide what to do with new responses in NAPI mode
 *	@adap: the adapter
 *	@q: the response queue
 *
 *	This is used by the NAPI interrupt handlers to decide what to do with
 *	new SGE responses.  If there are no new responses it returns -1.  If
 *	there are new responses and they are pure (i.e., non-data carrying)
 *	it handles them straight in hard interrupt context as they are very
 *	cheap and don't deliver any packets.  Finally, if there are any data
 *	signaling responses it schedules the NAPI handler.  Returns 1 if it
 *	schedules NAPI, 0 if all new responses were pure.
 *
 *	The caller must ascertain NAPI is not already running.
 */
static inline int handle_responses(struct adapter *adap, struct sge_rspq *q)
{
	struct sge_qset *qs = rspq_to_qset(q);
	struct rsp_desc *r = &q->desc[q->cidx];

	if (!is_new_response(r, q))
		return -1;
	rmb();
	if (is_pure_response(r) && process_pure_responses(adap, qs, r) == 0) {
		t3_write_reg(adap, A_SG_GTS, V_RSPQ(q->cntxt_id) |
			     V_NEWTIMER(q->holdoff_tmr) | V_NEWINDEX(q->cidx));
		return 0;
	}
	napi_schedule(&qs->napi);
	return 1;
}

/*
 * The MSI-X interrupt handler for an SGE response queue for the non-NAPI case
 * (i.e., response queue serviced in hard interrupt).
 */
irqreturn_t t3_sge_intr_msix(int irq, void *cookie)
{
	struct sge_qset *qs = cookie;
	struct adapter *adap = qs->adap;
	struct sge_rspq *q = &qs->rspq;

	spin_lock(&q->lock);
	if (process_responses(adap, qs, -1) == 0)
		q->unhandled_irqs++;
	t3_write_reg(adap, A_SG_GTS, V_RSPQ(q->cntxt_id) |
		     V_NEWTIMER(q->next_holdoff) | V_NEWINDEX(q->cidx));
	spin_unlock(&q->lock);
	return IRQ_HANDLED;
}

/*
 * The MSI-X interrupt handler for an SGE response queue for the NAPI case
 * (i.e., response queue serviced by NAPI polling).
 */
static irqreturn_t t3_sge_intr_msix_napi(int irq, void *cookie)
{
	struct sge_qset *qs = cookie;
	struct sge_rspq *q = &qs->rspq;

	spin_lock(&q->lock);

	if (handle_responses(qs->adap, q) < 0)
		q->unhandled_irqs++;
	spin_unlock(&q->lock);
	return IRQ_HANDLED;
}

/*
 * The non-NAPI MSI interrupt handler.  This needs to handle data events from
 * SGE response queues as well as error and other async events as they all use
 * the same MSI vector.  We use one SGE response queue per port in this mode
 * and protect all response queues with queue 0's lock.
 */
static irqreturn_t t3_intr_msi(int irq, void *cookie)
{
	int new_packets = 0;
	struct adapter *adap = cookie;
	struct sge_rspq *q = &adap->sge.qs[0].rspq;

	spin_lock(&q->lock);

	if (process_responses(adap, &adap->sge.qs[0], -1)) {
		t3_write_reg(adap, A_SG_GTS, V_RSPQ(q->cntxt_id) |
			     V_NEWTIMER(q->next_holdoff) | V_NEWINDEX(q->cidx));
		new_packets = 1;
	}

	if (adap->params.nports == 2 &&
	    process_responses(adap, &adap->sge.qs[1], -1)) {
		struct sge_rspq *q1 = &adap->sge.qs[1].rspq;

		t3_write_reg(adap, A_SG_GTS, V_RSPQ(q1->cntxt_id) |
			     V_NEWTIMER(q1->next_holdoff) |
			     V_NEWINDEX(q1->cidx));
		new_packets = 1;
	}

	if (!new_packets && t3_slow_intr_handler(adap) == 0)
		q->unhandled_irqs++;

	spin_unlock(&q->lock);
	return IRQ_HANDLED;
}

static int rspq_check_napi(struct sge_qset *qs)
{
	struct sge_rspq *q = &qs->rspq;

	if (!napi_is_scheduled(&qs->napi) &&
	    is_new_response(&q->desc[q->cidx], q)) {
		napi_schedule(&qs->napi);
		return 1;
	}
	return 0;
}

/*
 * The MSI interrupt handler for the NAPI case (i.e., response queues serviced
 * by NAPI polling).  Handles data events from SGE response queues as well as
 * error and other async events as they all use the same MSI vector.  We use
 * one SGE response queue per port in this mode and protect all response
 * queues with queue 0's lock.
 */
static irqreturn_t t3_intr_msi_napi(int irq, void *cookie)
{
	int new_packets;
	struct adapter *adap = cookie;
	struct sge_rspq *q = &adap->sge.qs[0].rspq;

	spin_lock(&q->lock);

	new_packets = rspq_check_napi(&adap->sge.qs[0]);
	if (adap->params.nports == 2)
		new_packets += rspq_check_napi(&adap->sge.qs[1]);
	if (!new_packets && t3_slow_intr_handler(adap) == 0)
		q->unhandled_irqs++;

	spin_unlock(&q->lock);
	return IRQ_HANDLED;
}

/*
 * A helper function that processes responses and issues GTS.
 */
static inline int process_responses_gts(struct adapter *adap,
					struct sge_rspq *rq)
{
	int work;

	work = process_responses(adap, rspq_to_qset(rq), -1);
	t3_write_reg(adap, A_SG_GTS, V_RSPQ(rq->cntxt_id) |
		     V_NEWTIMER(rq->next_holdoff) | V_NEWINDEX(rq->cidx));
	return work;
}

/*
 * The legacy INTx interrupt handler.  This needs to handle data events from
 * SGE response queues as well as error and other async events as they all use
 * the same interrupt pin.  We use one SGE response queue per port in this mode
 * and protect all response queues with queue 0's lock.
 */
static irqreturn_t t3_intr(int irq, void *cookie)
{
	int work_done, w0, w1;
	struct adapter *adap = cookie;
	struct sge_rspq *q0 = &adap->sge.qs[0].rspq;
	struct sge_rspq *q1 = &adap->sge.qs[1].rspq;

	spin_lock(&q0->lock);

	w0 = is_new_response(&q0->desc[q0->cidx], q0);
	w1 = adap->params.nports == 2 &&
	    is_new_response(&q1->desc[q1->cidx], q1);

	if (likely(w0 | w1)) {
		t3_write_reg(adap, A_PL_CLI, 0);
		t3_read_reg(adap, A_PL_CLI);	/* flush */

		if (likely(w0))
			process_responses_gts(adap, q0);

		if (w1)
			process_responses_gts(adap, q1);

		work_done = w0 | w1;
	} else
		work_done = t3_slow_intr_handler(adap);

	spin_unlock(&q0->lock);
	return IRQ_RETVAL(work_done != 0);
}

/*
 * Interrupt handler for legacy INTx interrupts for T3B-based cards.
 * Handles data events from SGE response queues as well as error and other
 * async events as they all use the same interrupt pin.  We use one SGE
 * response queue per port in this mode and protect all response queues with
 * queue 0's lock.
 */
static irqreturn_t t3b_intr(int irq, void *cookie)
{
	u32 map;
	struct adapter *adap = cookie;
	struct sge_rspq *q0 = &adap->sge.qs[0].rspq;

	t3_write_reg(adap, A_PL_CLI, 0);
	map = t3_read_reg(adap, A_SG_DATA_INTR);

	if (unlikely(!map))	/* shared interrupt, most likely */
		return IRQ_NONE;

	spin_lock(&q0->lock);

	if (unlikely(map & F_ERRINTR))
		t3_slow_intr_handler(adap);

	if (likely(map & 1))
		process_responses_gts(adap, q0);

	if (map & 2)
		process_responses_gts(adap, &adap->sge.qs[1].rspq);

	spin_unlock(&q0->lock);
	return IRQ_HANDLED;
}

/*
 * NAPI interrupt handler for legacy INTx interrupts for T3B-based cards.
 * Handles data events from SGE response queues as well as error and other
 * async events as they all use the same interrupt pin.  We use one SGE
 * response queue per port in this mode and protect all response queues with
 * queue 0's lock.
 */
static irqreturn_t t3b_intr_napi(int irq, void *cookie)
{
	u32 map;
	struct adapter *adap = cookie;
	struct sge_qset *qs0 = &adap->sge.qs[0];
	struct sge_rspq *q0 = &qs0->rspq;

	t3_write_reg(adap, A_PL_CLI, 0);
	map = t3_read_reg(adap, A_SG_DATA_INTR);

	if (unlikely(!map))	/* shared interrupt, most likely */
		return IRQ_NONE;

	spin_lock(&q0->lock);

	if (unlikely(map & F_ERRINTR))
		t3_slow_intr_handler(adap);

	if (likely(map & 1))
		napi_schedule(&qs0->napi);

	if (map & 2)
		napi_schedule(&adap->sge.qs[1].napi);

	spin_unlock(&q0->lock);
	return IRQ_HANDLED;
}

/**
 *	t3_intr_handler - select the top-level interrupt handler
 *	@adap: the adapter
 *	@polling: whether using NAPI to service response queues
 *
 *	Selects the top-level interrupt handler based on the type of interrupts
 *	(MSI-X, MSI, or legacy) and whether NAPI will be used to service the
 *	response queues.
 */
irq_handler_t t3_intr_handler(struct adapter *adap, int polling)
{
	if (adap->flags & USING_MSIX)
		return polling ? t3_sge_intr_msix_napi : t3_sge_intr_msix;
	if (adap->flags & USING_MSI)
		return polling ? t3_intr_msi_napi : t3_intr_msi;
	if (adap->params.rev > 0)
		return polling ? t3b_intr_napi : t3b_intr;
	return t3_intr;
}

#define SGE_PARERR (F_CPPARITYERROR | F_OCPARITYERROR | F_RCPARITYERROR | \
		    F_IRPARITYERROR | V_ITPARITYERROR(M_ITPARITYERROR) | \
		    V_FLPARITYERROR(M_FLPARITYERROR) | F_LODRBPARITYERROR | \
		    F_HIDRBPARITYERROR | F_LORCQPARITYERROR | \
		    F_HIRCQPARITYERROR)
#define SGE_FRAMINGERR (F_UC_REQ_FRAMINGERROR | F_R_REQ_FRAMINGERROR)
#define SGE_FATALERR (SGE_PARERR | SGE_FRAMINGERR | F_RSPQCREDITOVERFOW | \
		      F_RSPQDISABLED)

/**
 *	t3_sge_err_intr_handler - SGE async event interrupt handler
 *	@adapter: the adapter
 *
 *	Interrupt handler for SGE asynchronous (non-data) events.
 */
void t3_sge_err_intr_handler(struct adapter *adapter)
{
	unsigned int v, status = t3_read_reg(adapter, A_SG_INT_CAUSE) &
				 ~F_FLEMPTY;

	if (status & SGE_PARERR)
		CH_ALERT(adapter, "SGE parity error (0x%x)\n",
			 status & SGE_PARERR);
	if (status & SGE_FRAMINGERR)
		CH_ALERT(adapter, "SGE framing error (0x%x)\n",
			 status & SGE_FRAMINGERR);

	if (status & F_RSPQCREDITOVERFOW)
		CH_ALERT(adapter, "SGE response queue credit overflow\n");

	if (status & F_RSPQDISABLED) {
		v = t3_read_reg(adapter, A_SG_RSPQ_FL_STATUS);

		CH_ALERT(adapter,
			 "packet delivered to disabled response queue "
			 "(0x%x)\n", (v >> S_RSPQ0DISABLED) & 0xff);
	}

	if (status & (F_HIPIODRBDROPERR | F_LOPIODRBDROPERR))
		queue_work(cxgb3_wq, &adapter->db_drop_task);

	if (status & (F_HIPRIORITYDBFULL | F_LOPRIORITYDBFULL))
		queue_work(cxgb3_wq, &adapter->db_full_task);

	if (status & (F_HIPRIORITYDBEMPTY | F_LOPRIORITYDBEMPTY))
		queue_work(cxgb3_wq, &adapter->db_empty_task);

	t3_write_reg(adapter, A_SG_INT_CAUSE, status);
	if (status &  SGE_FATALERR)
		t3_fatal_err(adapter);
}

/**
 *	sge_timer_tx - perform periodic maintenance of an SGE qset
 *	@data: the SGE queue set to maintain
 *
 *	Runs periodically from a timer to perform maintenance of an SGE queue
 *	set.  It performs two tasks:
 *
 *	Cleans up any completed Tx descriptors that may still be pending.
 *	Normal descriptor cleanup happens when new packets are added to a Tx
 *	queue so this timer is relatively infrequent and does any cleanup only
 *	if the Tx queue has not seen any new packets in a while.  We make a
 *	best effort attempt to reclaim descriptors, in that we don't wait
 *	around if we cannot get a queue's lock (which most likely is because
 *	someone else is queueing new packets and so will also handle the clean
 *	up).  Since control queues use immediate data exclusively we don't
 *	bother cleaning them up here.
 *
 */
static void sge_timer_tx(unsigned long data)
{
	struct sge_qset *qs = (struct sge_qset *)data;
	struct port_info *pi = netdev_priv(qs->netdev);
	struct adapter *adap = pi->adapter;
	unsigned int tbd[SGE_TXQ_PER_SET] = {0, 0};
	unsigned long next_period;

	if (__netif_tx_trylock(qs->tx_q)) {
                tbd[TXQ_ETH] = reclaim_completed_tx(adap, &qs->txq[TXQ_ETH],
                                                     TX_RECLAIM_TIMER_CHUNK);
		__netif_tx_unlock(qs->tx_q);
	}

	if (spin_trylock(&qs->txq[TXQ_OFLD].lock)) {
		tbd[TXQ_OFLD] = reclaim_completed_tx(adap, &qs->txq[TXQ_OFLD],
						     TX_RECLAIM_TIMER_CHUNK);
		spin_unlock(&qs->txq[TXQ_OFLD].lock);
	}

	next_period = TX_RECLAIM_PERIOD >>
                      (max(tbd[TXQ_ETH], tbd[TXQ_OFLD]) /
                      TX_RECLAIM_TIMER_CHUNK);
	mod_timer(&qs->tx_reclaim_timer, jiffies + next_period);
}

/*
 *	sge_timer_rx - perform periodic maintenance of an SGE qset
 *	@data: the SGE queue set to maintain
 *
 *	a) Replenishes Rx queues that have run out due to memory shortage.
 *	Normally new Rx buffers are added when existing ones are consumed but
 *	when out of memory a queue can become empty.  We try to add only a few
 *	buffers here, the queue will be replenished fully as these new buffers
 *	are used up if memory shortage has subsided.
 *
 *	b) Return coalesced response queue credits in case a response queue is
 *	starved.
 *
 */
static void sge_timer_rx(unsigned long data)
{
	spinlock_t *lock;
	struct sge_qset *qs = (struct sge_qset *)data;
	struct port_info *pi = netdev_priv(qs->netdev);
	struct adapter *adap = pi->adapter;
	u32 status;

	lock = adap->params.rev > 0 ?
	       &qs->rspq.lock : &adap->sge.qs[0].rspq.lock;

	if (!spin_trylock_irq(lock))
		goto out;

	if (napi_is_scheduled(&qs->napi))
		goto unlock;

	if (adap->params.rev < 4) {
		status = t3_read_reg(adap, A_SG_RSPQ_FL_STATUS);

		if (status & (1 << qs->rspq.cntxt_id)) {
			qs->rspq.starved++;
			if (qs->rspq.credits) {
				qs->rspq.credits--;
				refill_rspq(adap, &qs->rspq, 1);
				qs->rspq.restarted++;
				t3_write_reg(adap, A_SG_RSPQ_FL_STATUS,
					     1 << qs->rspq.cntxt_id);
			}
		}
	}

	if (qs->fl[0].credits < qs->fl[0].size)
		__refill_fl(adap, &qs->fl[0]);
	if (qs->fl[1].credits < qs->fl[1].size)
		__refill_fl(adap, &qs->fl[1]);

unlock:
	spin_unlock_irq(lock);
out:
	mod_timer(&qs->rx_reclaim_timer, jiffies + RX_RECLAIM_PERIOD);
}

/**
 *	t3_update_qset_coalesce - update coalescing settings for a queue set
 *	@qs: the SGE queue set
 *	@p: new queue set parameters
 *
 *	Update the coalescing settings for an SGE queue set.  Nothing is done
 *	if the queue set is not initialized yet.
 */
void t3_update_qset_coalesce(struct sge_qset *qs, const struct qset_params *p)
{
	qs->rspq.holdoff_tmr = max(p->coalesce_usecs * 10, 1U);/* can't be 0 */
	qs->rspq.polling = p->polling;
	qs->napi.poll = p->polling ? napi_rx_handler : ofld_poll;
}

/**
 *	t3_sge_alloc_qset - initialize an SGE queue set
 *	@adapter: the adapter
 *	@id: the queue set id
 *	@nports: how many Ethernet ports will be using this queue set
 *	@irq_vec_idx: the IRQ vector index for response queue interrupts
 *	@p: configuration parameters for this queue set
 *	@ntxq: number of Tx queues for the queue set
 *	@netdev: net device associated with this queue set
 *	@netdevq: net device TX queue associated with this queue set
 *
 *	Allocate resources and initialize an SGE queue set.  A queue set
 *	comprises a response queue, two Rx free-buffer queues, and up to 3
 *	Tx queues.  The Tx queues are assigned roles in the order Ethernet
 *	queue, offload queue, and control queue.
 */
int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
		      int irq_vec_idx, const struct qset_params *p,
		      int ntxq, struct net_device *dev,
		      struct netdev_queue *netdevq)
{
	int i, avail, ret = -ENOMEM;
	struct sge_qset *q = &adapter->sge.qs[id];

	init_qset_cntxt(q, id);
	setup_timer(&q->tx_reclaim_timer, sge_timer_tx, (unsigned long)q);
	setup_timer(&q->rx_reclaim_timer, sge_timer_rx, (unsigned long)q);

	q->fl[0].desc = alloc_ring(adapter->pdev, p->fl_size,
				   sizeof(struct rx_desc),
				   sizeof(struct rx_sw_desc),
				   &q->fl[0].phys_addr, &q->fl[0].sdesc);
	if (!q->fl[0].desc)
		goto err;

	q->fl[1].desc = alloc_ring(adapter->pdev, p->jumbo_size,
				   sizeof(struct rx_desc),
				   sizeof(struct rx_sw_desc),
				   &q->fl[1].phys_addr, &q->fl[1].sdesc);
	if (!q->fl[1].desc)
		goto err;

	q->rspq.desc = alloc_ring(adapter->pdev, p->rspq_size,
				  sizeof(struct rsp_desc), 0,
				  &q->rspq.phys_addr, NULL);
	if (!q->rspq.desc)
		goto err;

	for (i = 0; i < ntxq; ++i) {
		/*
		 * The control queue always uses immediate data so does not
		 * need to keep track of any sk_buffs.
		 */
		size_t sz = i == TXQ_CTRL ? 0 : sizeof(struct tx_sw_desc);

		q->txq[i].desc = alloc_ring(adapter->pdev, p->txq_size[i],
					    sizeof(struct tx_desc), sz,
					    &q->txq[i].phys_addr,
					    &q->txq[i].sdesc);
		if (!q->txq[i].desc)
			goto err;

		q->txq[i].gen = 1;
		q->txq[i].size = p->txq_size[i];
		spin_lock_init(&q->txq[i].lock);
		skb_queue_head_init(&q->txq[i].sendq);
	}

	tasklet_init(&q->txq[TXQ_OFLD].qresume_tsk, restart_offloadq,
		     (unsigned long)q);
	tasklet_init(&q->txq[TXQ_CTRL].qresume_tsk, restart_ctrlq,
		     (unsigned long)q);

	q->fl[0].gen = q->fl[1].gen = 1;
	q->fl[0].size = p->fl_size;
	q->fl[1].size = p->jumbo_size;

	q->rspq.gen = 1;
	q->rspq.size = p->rspq_size;
	spin_lock_init(&q->rspq.lock);
	skb_queue_head_init(&q->rspq.rx_queue);

	q->txq[TXQ_ETH].stop_thres = nports *
	    flits_to_desc(sgl_len(MAX_SKB_FRAGS + 1) + 3);

#if FL0_PG_CHUNK_SIZE > 0
	q->fl[0].buf_size = FL0_PG_CHUNK_SIZE;
#else
	q->fl[0].buf_size = SGE_RX_SM_BUF_SIZE + sizeof(struct cpl_rx_data);
#endif
#if FL1_PG_CHUNK_SIZE > 0
	q->fl[1].buf_size = FL1_PG_CHUNK_SIZE;
#else
	q->fl[1].buf_size = is_offload(adapter) ?
		(16 * 1024) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) :
		MAX_FRAME_SIZE + 2 + sizeof(struct cpl_rx_pkt);
#endif

	q->fl[0].use_pages = FL0_PG_CHUNK_SIZE > 0;
	q->fl[1].use_pages = FL1_PG_CHUNK_SIZE > 0;
	q->fl[0].order = FL0_PG_ORDER;
	q->fl[1].order = FL1_PG_ORDER;
	q->fl[0].alloc_size = FL0_PG_ALLOC_SIZE;
	q->fl[1].alloc_size = FL1_PG_ALLOC_SIZE;

	spin_lock_irq(&adapter->sge.reg_lock);

	/* FL threshold comparison uses < */
	ret = t3_sge_init_rspcntxt(adapter, q->rspq.cntxt_id, irq_vec_idx,
				   q->rspq.phys_addr, q->rspq.size,
				   q->fl[0].buf_size - SGE_PG_RSVD, 1, 0);
	if (ret)
		goto err_unlock;

	for (i = 0; i < SGE_RXQ_PER_SET; ++i) {
		ret = t3_sge_init_flcntxt(adapter, q->fl[i].cntxt_id, 0,
					  q->fl[i].phys_addr, q->fl[i].size,
					  q->fl[i].buf_size - SGE_PG_RSVD,
					  p->cong_thres, 1, 0);
		if (ret)
			goto err_unlock;
	}

	ret = t3_sge_init_ecntxt(adapter, q->txq[TXQ_ETH].cntxt_id, USE_GTS,
				 SGE_CNTXT_ETH, id, q->txq[TXQ_ETH].phys_addr,
				 q->txq[TXQ_ETH].size, q->txq[TXQ_ETH].token,
				 1, 0);
	if (ret)
		goto err_unlock;

	if (ntxq > 1) {
		ret = t3_sge_init_ecntxt(adapter, q->txq[TXQ_OFLD].cntxt_id,
					 USE_GTS, SGE_CNTXT_OFLD, id,
					 q->txq[TXQ_OFLD].phys_addr,
					 q->txq[TXQ_OFLD].size, 0, 1, 0);
		if (ret)
			goto err_unlock;
	}

	if (ntxq > 2) {
		ret = t3_sge_init_ecntxt(adapter, q->txq[TXQ_CTRL].cntxt_id, 0,
					 SGE_CNTXT_CTRL, id,
					 q->txq[TXQ_CTRL].phys_addr,
					 q->txq[TXQ_CTRL].size,
					 q->txq[TXQ_CTRL].token, 1, 0);
		if (ret)
			goto err_unlock;
	}

	spin_unlock_irq(&adapter->sge.reg_lock);

	q->adap = adapter;
	q->netdev = dev;
	q->tx_q = netdevq;
	t3_update_qset_coalesce(q, p);

	avail = refill_fl(adapter, &q->fl[0], q->fl[0].size,
			  GFP_KERNEL | __GFP_COMP);
	if (!avail) {
		CH_ALERT(adapter, "free list queue 0 initialization failed\n");
		goto err;
	}
	if (avail < q->fl[0].size)
		CH_WARN(adapter, "free list queue 0 enabled with %d credits\n",
			avail);

	avail = refill_fl(adapter, &q->fl[1], q->fl[1].size,
			  GFP_KERNEL | __GFP_COMP);
	if (avail < q->fl[1].size)
		CH_WARN(adapter, "free list queue 1 enabled with %d credits\n",
			avail);
	refill_rspq(adapter, &q->rspq, q->rspq.size - 1);

	t3_write_reg(adapter, A_SG_GTS, V_RSPQ(q->rspq.cntxt_id) |
		     V_NEWTIMER(q->rspq.holdoff_tmr));

	return 0;

err_unlock:
	spin_unlock_irq(&adapter->sge.reg_lock);
err:
	t3_free_qset(adapter, q);
	return ret;
}

/**
 *      t3_start_sge_timers - start SGE timer call backs
 *      @adap: the adapter
 *
 *      Starts each SGE queue set's timer call back
 */
void t3_start_sge_timers(struct adapter *adap)
{
	int i;

	for (i = 0; i < SGE_QSETS; ++i) {
		struct sge_qset *q = &adap->sge.qs[i];

	if (q->tx_reclaim_timer.function)
		mod_timer(&q->tx_reclaim_timer, jiffies + TX_RECLAIM_PERIOD);

	if (q->rx_reclaim_timer.function)
		mod_timer(&q->rx_reclaim_timer, jiffies + RX_RECLAIM_PERIOD);
	}
}

/**
 *	t3_stop_sge_timers - stop SGE timer call backs
 *	@adap: the adapter
 *
 *	Stops each SGE queue set's timer call back
 */
void t3_stop_sge_timers(struct adapter *adap)
{
	int i;

	for (i = 0; i < SGE_QSETS; ++i) {
		struct sge_qset *q = &adap->sge.qs[i];

		if (q->tx_reclaim_timer.function)
			del_timer_sync(&q->tx_reclaim_timer);
		if (q->rx_reclaim_timer.function)
			del_timer_sync(&q->rx_reclaim_timer);
	}
}

/**
 *	t3_free_sge_resources - free SGE resources
 *	@adap: the adapter
 *
 *	Frees resources used by the SGE queue sets.
 */
void t3_free_sge_resources(struct adapter *adap)
{
	int i;

	for (i = 0; i < SGE_QSETS; ++i)
		t3_free_qset(adap, &adap->sge.qs[i]);
}

/**
 *	t3_sge_start - enable SGE
 *	@adap: the adapter
 *
 *	Enables the SGE for DMAs.  This is the last step in starting packet
 *	transfers.
 */
void t3_sge_start(struct adapter *adap)
{
	t3_set_reg_field(adap, A_SG_CONTROL, F_GLOBALENABLE, F_GLOBALENABLE);
}

/**
 *	t3_sge_stop - disable SGE operation
 *	@adap: the adapter
 *
 *	Disables the DMA engine.  This can be called in emeregencies (e.g.,
 *	from error interrupts) or from normal process context.  In the latter
 *	case it also disables any pending queue restart tasklets.  Note that
 *	if it is called in interrupt context it cannot disable the restart
 *	tasklets as it cannot wait, however the tasklets will have no effect
 *	since the doorbells are disabled and the driver will call this again
 *	later from process context, at which time the tasklets will be stopped
 *	if they are still running.
 */
void t3_sge_stop(struct adapter *adap)
{
	t3_set_reg_field(adap, A_SG_CONTROL, F_GLOBALENABLE, 0);
	if (!in_interrupt()) {
		int i;

		for (i = 0; i < SGE_QSETS; ++i) {
			struct sge_qset *qs = &adap->sge.qs[i];

			tasklet_kill(&qs->txq[TXQ_OFLD].qresume_tsk);
			tasklet_kill(&qs->txq[TXQ_CTRL].qresume_tsk);
		}
	}
}

/**
 *	t3_sge_init - initialize SGE
 *	@adap: the adapter
 *	@p: the SGE parameters
 *
 *	Performs SGE initialization needed every time after a chip reset.
 *	We do not initialize any of the queue sets here, instead the driver
 *	top-level must request those individually.  We also do not enable DMA
 *	here, that should be done after the queues have been set up.
 */
void t3_sge_init(struct adapter *adap, struct sge_params *p)
{
	unsigned int ctrl, ups = ffs(pci_resource_len(adap->pdev, 2) >> 12);

	ctrl = F_DROPPKT | V_PKTSHIFT(2) | F_FLMODE | F_AVOIDCQOVFL |
	    F_CQCRDTCTRL | F_CONGMODE | F_TNLFLMODE | F_FATLPERREN |
	    V_HOSTPAGESIZE(PAGE_SHIFT - 11) | F_BIGENDIANINGRESS |
	    V_USERSPACESIZE(ups ? ups - 1 : 0) | F_ISCSICOALESCING;
#if SGE_NUM_GENBITS == 1
	ctrl |= F_EGRGENCTRL;
#endif
	if (adap->params.rev > 0) {
		if (!(adap->flags & (USING_MSIX | USING_MSI)))
			ctrl |= F_ONEINTMULTQ | F_OPTONEINTMULTQ;
	}
	t3_write_reg(adap, A_SG_CONTROL, ctrl);
	t3_write_reg(adap, A_SG_EGR_RCQ_DRB_THRSH, V_HIRCQDRBTHRSH(512) |
		     V_LORCQDRBTHRSH(512));
	t3_write_reg(adap, A_SG_TIMER_TICK, core_ticks_per_usec(adap) / 10);
	t3_write_reg(adap, A_SG_CMDQ_CREDIT_TH, V_THRESHOLD(32) |
		     V_TIMEOUT(200 * core_ticks_per_usec(adap)));
	t3_write_reg(adap, A_SG_HI_DRB_HI_THRSH,
		     adap->params.rev < T3_REV_C ? 1000 : 500);
	t3_write_reg(adap, A_SG_HI_DRB_LO_THRSH, 256);
	t3_write_reg(adap, A_SG_LO_DRB_HI_THRSH, 1000);
	t3_write_reg(adap, A_SG_LO_DRB_LO_THRSH, 256);
	t3_write_reg(adap, A_SG_OCO_BASE, V_BASE1(0xfff));
	t3_write_reg(adap, A_SG_DRB_PRI_THRESH, 63 * 1024);
}

/**
 *	t3_sge_prep - one-time SGE initialization
 *	@adap: the associated adapter
 *	@p: SGE parameters
 *
 *	Performs one-time initialization of SGE SW state.  Includes determining
 *	defaults for the assorted SGE parameters, which admins can change until
 *	they are used to initialize the SGE.
 */
void t3_sge_prep(struct adapter *adap, struct sge_params *p)
{
	int i;

	p->max_pkt_size = (16 * 1024) - sizeof(struct cpl_rx_data) -
	    SKB_DATA_ALIGN(sizeof(struct skb_shared_info));

	for (i = 0; i < SGE_QSETS; ++i) {
		struct qset_params *q = p->qset + i;

		q->polling = adap->params.rev > 0;
		q->coalesce_usecs = 5;
		q->rspq_size = 1024;
		q->fl_size = 1024;
 		q->jumbo_size = 512;
		q->txq_size[TXQ_ETH] = 1024;
		q->txq_size[TXQ_OFLD] = 1024;
		q->txq_size[TXQ_CTRL] = 256;
		q->cong_thres = 0;
	}

	spin_lock_init(&adap->sge.reg_lock);
}

/**
 *	t3_get_desc - dump an SGE descriptor for debugging purposes
 *	@qs: the queue set
 *	@qnum: identifies the specific queue (0..2: Tx, 3:response, 4..5: Rx)
 *	@idx: the descriptor index in the queue
 *	@data: where to dump the descriptor contents
 *
 *	Dumps the contents of a HW descriptor of an SGE queue.  Returns the
 *	size of the descriptor.
 */
int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx,
		unsigned char *data)
{
	if (qnum >= 6)
		return -EINVAL;

	if (qnum < 3) {
		if (!qs->txq[qnum].desc || idx >= qs->txq[qnum].size)
			return -EINVAL;
		memcpy(data, &qs->txq[qnum].desc[idx], sizeof(struct tx_desc));
		return sizeof(struct tx_desc);
	}

	if (qnum == 3) {
		if (!qs->rspq.desc || idx >= qs->rspq.size)
			return -EINVAL;
		memcpy(data, &qs->rspq.desc[idx], sizeof(struct rsp_desc));
		return sizeof(struct rsp_desc);
	}

	qnum -= 4;
	if (!qs->fl[qnum].desc || idx >= qs->fl[qnum].size)
		return -EINVAL;
	memcpy(data, &qs->fl[qnum].desc[idx], sizeof(struct rx_desc));
	return sizeof(struct rx_desc);
}
