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

#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
#include <linux/ip.h>
#include <net/ipv6.h>
#include <net/tcp.h>
#include <linux/dma-mapping.h>

#include "t4vf_common.h"
#include "t4vf_defs.h"

#include "../cxgb4/t4_regs.h"
#include "../cxgb4/t4fw_api.h"
#include "../cxgb4/t4_msg.h"

/*
 * Decoded Adapter Parameters.
 */
static u32 FL_PG_ORDER;		/* large page allocation size */
static u32 STAT_LEN;		/* length of status page at ring end */
static u32 PKTSHIFT;		/* padding between CPL and packet data */
static u32 FL_ALIGN;		/* response queue message alignment */

/*
 * Constants ...
 */
enum {
	/*
	 * Egress Queue sizes, producer and consumer indices are all in units
	 * of Egress Context Units bytes.  Note that as far as the hardware is
	 * concerned, the free list is an Egress Queue (the host produces free
	 * buffers which the hardware consumes) and free list entries are
	 * 64-bit PCI DMA addresses.
	 */
	EQ_UNIT = SGE_EQ_IDXSIZE,
	FL_PER_EQ_UNIT = EQ_UNIT / sizeof(__be64),
	TXD_PER_EQ_UNIT = EQ_UNIT / sizeof(__be64),

	/*
	 * Max number of TX descriptors we clean up at a time.  Should be
	 * modest as freeing skbs isn't cheap and it happens while holding
	 * locks.  We just need to free packets faster than they arrive, we
	 * eventually catch up and keep the amortized cost reasonable.
	 */
	MAX_TX_RECLAIM = 16,

	/*
	 * Max number of Rx buffers we replenish at a time.  Again keep this
	 * modest, allocating buffers isn't cheap either.
	 */
	MAX_RX_REFILL = 16,

	/*
	 * Period of the Rx queue check timer.  This timer is infrequent as it
	 * has something to do only when the system experiences severe memory
	 * shortage.
	 */
	RX_QCHECK_PERIOD = (HZ / 2),

	/*
	 * Period of the TX queue check timer and the maximum number of TX
	 * descriptors to be reclaimed by the TX timer.
	 */
	TX_QCHECK_PERIOD = (HZ / 2),
	MAX_TIMER_TX_RECLAIM = 100,

	/*
	 * An FL with <= FL_STARVE_THRES buffers is starving and a periodic
	 * timer will attempt to refill it.
	 */
	FL_STARVE_THRES = 4,

	/*
	 * Suspend an Ethernet TX queue with fewer available descriptors than
	 * this.  We always want to have room for a maximum sized packet:
	 * inline immediate data + MAX_SKB_FRAGS. This is the same as
	 * calc_tx_flits() for a TSO packet with nr_frags == MAX_SKB_FRAGS
	 * (see that function and its helpers for a description of the
	 * calculation).
	 */
	ETHTXQ_MAX_FRAGS = MAX_SKB_FRAGS + 1,
	ETHTXQ_MAX_SGL_LEN = ((3 * (ETHTXQ_MAX_FRAGS-1))/2 +
				   ((ETHTXQ_MAX_FRAGS-1) & 1) +
				   2),
	ETHTXQ_MAX_HDR = (sizeof(struct fw_eth_tx_pkt_vm_wr) +
			  sizeof(struct cpl_tx_pkt_lso_core) +
			  sizeof(struct cpl_tx_pkt_core)) / sizeof(__be64),
	ETHTXQ_MAX_FLITS = ETHTXQ_MAX_SGL_LEN + ETHTXQ_MAX_HDR,

	ETHTXQ_STOP_THRES = 1 + DIV_ROUND_UP(ETHTXQ_MAX_FLITS, TXD_PER_EQ_UNIT),

	/*
	 * Max TX descriptor space we allow for an Ethernet packet to be
	 * inlined into a WR.  This is limited by the maximum value which
	 * we can specify for immediate data in the firmware Ethernet TX
	 * Work Request.
	 */
	MAX_IMM_TX_PKT_LEN = FW_WR_IMMDLEN_MASK,

	/*
	 * Max size of a WR sent through a control TX queue.
	 */
	MAX_CTRL_WR_LEN = 256,

	/*
	 * Maximum amount of data which we'll ever need to inline into a
	 * TX ring: max(MAX_IMM_TX_PKT_LEN, MAX_CTRL_WR_LEN).
	 */
	MAX_IMM_TX_LEN = (MAX_IMM_TX_PKT_LEN > MAX_CTRL_WR_LEN
			  ? MAX_IMM_TX_PKT_LEN
			  : MAX_CTRL_WR_LEN),

	/*
	 * For incoming packets less than RX_COPY_THRES, we copy the data into
	 * an skb rather than referencing the data.  We allocate enough
	 * in-line room in skb's to accommodate pulling in RX_PULL_LEN bytes
	 * of the data (header).
	 */
	RX_COPY_THRES = 256,
	RX_PULL_LEN = 128,
};

/*
 * Can't define this in the above enum because PKTSHIFT isn't a constant in
 * the VF Driver ...
 */
#define RX_PKT_PULL_LEN (RX_PULL_LEN + PKTSHIFT)

/*
 * Software state per TX descriptor.
 */
struct tx_sw_desc {
	struct sk_buff *skb;		/* socket buffer of TX data source */
	struct ulptx_sgl *sgl;		/* scatter/gather list in TX Queue */
};

/*
 * Software state per RX Free List descriptor.  We keep track of the allocated
 * FL page, its size, and its PCI DMA address (if the page is mapped).  The FL
 * page size and its PCI DMA mapped state are stored in the low bits of the
 * PCI DMA address as per below.
 */
struct rx_sw_desc {
	struct page *page;		/* Free List page buffer */
	dma_addr_t dma_addr;		/* PCI DMA address (if mapped) */
					/*   and flags (see below) */
};

/*
 * The low bits of rx_sw_desc.dma_addr have special meaning.  Note that the
 * SGE also uses the low 4 bits to determine the size of the buffer.  It uses
 * those bits to index into the SGE_FL_BUFFER_SIZE[index] register array.
 * Since we only use SGE_FL_BUFFER_SIZE0 and SGE_FL_BUFFER_SIZE1, these low 4
 * bits can only contain a 0 or a 1 to indicate which size buffer we're giving
 * to the SGE.  Thus, our software state of "is the buffer mapped for DMA" is
 * maintained in an inverse sense so the hardware never sees that bit high.
 */
enum {
	RX_LARGE_BUF    = 1 << 0,	/* buffer is SGE_FL_BUFFER_SIZE[1] */
	RX_UNMAPPED_BUF = 1 << 1,	/* buffer is not mapped */
};

/**
 *	get_buf_addr - return DMA buffer address of software descriptor
 *	@sdesc: pointer to the software buffer descriptor
 *
 *	Return the DMA buffer address of a software descriptor (stripping out
 *	our low-order flag bits).
 */
static inline dma_addr_t get_buf_addr(const struct rx_sw_desc *sdesc)
{
	return sdesc->dma_addr & ~(dma_addr_t)(RX_LARGE_BUF | RX_UNMAPPED_BUF);
}

/**
 *	is_buf_mapped - is buffer mapped for DMA?
 *	@sdesc: pointer to the software buffer descriptor
 *
 *	Determine whether the buffer associated with a software descriptor in
 *	mapped for DMA or not.
 */
static inline bool is_buf_mapped(const struct rx_sw_desc *sdesc)
{
	return !(sdesc->dma_addr & RX_UNMAPPED_BUF);
}

/**
 *	need_skb_unmap - does the platform need unmapping of sk_buffs?
 *
 *	Returns true if the platfrom 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 platfrom needs buffer
	 * unmapping by checking if DECLARE_PCI_UNMAP_ADDR defines anything.
	 */
	struct dummy {
		DECLARE_PCI_UNMAP_ADDR(addr);
	};

	return sizeof(struct dummy) != 0;
}

/**
 *	txq_avail - return the number of available slots in a TX queue
 *	@tq: the TX queue
 *
 *	Returns the number of available descriptors in a TX queue.
 */
static inline unsigned int txq_avail(const struct sge_txq *tq)
{
	return tq->size - 1 - tq->in_use;
}

/**
 *	fl_cap - return the capacity of a Free List
 *	@fl: the Free List
 *
 *	Returns the capacity of a Free List.  The capacity is less than the
 *	size because an Egress Queue Index Unit worth of descriptors needs to
 *	be left unpopulated, otherwise the Producer and Consumer indices PIDX
 *	and CIDX will match and the hardware will think the FL is empty.
 */
static inline unsigned int fl_cap(const struct sge_fl *fl)
{
	return fl->size - FL_PER_EQ_UNIT;
}

/**
 *	fl_starving - return whether a Free List is starving.
 *	@fl: the Free List
 *
 *	Tests specified Free List to see whether the number of buffers
 *	available to the hardware has falled below our "starvation"
 *	threshhold.
 */
static inline bool fl_starving(const struct sge_fl *fl)
{
	return fl->avail - fl->pend_cred <= FL_STARVE_THRES;
}

/**
 *	map_skb -  map an skb for DMA to the device
 *	@dev: the egress net device
 *	@skb: the packet to map
 *	@addr: a pointer to the base of the DMA mapping array
 *
 *	Map an skb for DMA to the device and return an array of DMA addresses.
 */
static int map_skb(struct device *dev, const struct sk_buff *skb,
		   dma_addr_t *addr)
{
	const skb_frag_t *fp, *end;
	const struct skb_shared_info *si;

	*addr = dma_map_single(dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
	if (dma_mapping_error(dev, *addr))
		goto out_err;

	si = skb_shinfo(skb);
	end = &si->frags[si->nr_frags];
	for (fp = si->frags; fp < end; fp++) {
		*++addr = dma_map_page(dev, fp->page, fp->page_offset, fp->size,
				       DMA_TO_DEVICE);
		if (dma_mapping_error(dev, *addr))
			goto unwind;
	}
	return 0;

unwind:
	while (fp-- > si->frags)
		dma_unmap_page(dev, *--addr, fp->size, DMA_TO_DEVICE);
	dma_unmap_single(dev, addr[-1], skb_headlen(skb), DMA_TO_DEVICE);

out_err:
	return -ENOMEM;
}

static void unmap_sgl(struct device *dev, const struct sk_buff *skb,
		      const struct ulptx_sgl *sgl, const struct sge_txq *tq)
{
	const struct ulptx_sge_pair *p;
	unsigned int nfrags = skb_shinfo(skb)->nr_frags;

	if (likely(skb_headlen(skb)))
		dma_unmap_single(dev, be64_to_cpu(sgl->addr0),
				 be32_to_cpu(sgl->len0), DMA_TO_DEVICE);
	else {
		dma_unmap_page(dev, be64_to_cpu(sgl->addr0),
			       be32_to_cpu(sgl->len0), DMA_TO_DEVICE);
		nfrags--;
	}

	/*
	 * the complexity below is because of the possibility of a wrap-around
	 * in the middle of an SGL
	 */
	for (p = sgl->sge; nfrags >= 2; nfrags -= 2) {
		if (likely((u8 *)(p + 1) <= (u8 *)tq->stat)) {
unmap:
			dma_unmap_page(dev, be64_to_cpu(p->addr[0]),
				       be32_to_cpu(p->len[0]), DMA_TO_DEVICE);
			dma_unmap_page(dev, be64_to_cpu(p->addr[1]),
				       be32_to_cpu(p->len[1]), DMA_TO_DEVICE);
			p++;
		} else if ((u8 *)p == (u8 *)tq->stat) {
			p = (const struct ulptx_sge_pair *)tq->desc;
			goto unmap;
		} else if ((u8 *)p + 8 == (u8 *)tq->stat) {
			const __be64 *addr = (const __be64 *)tq->desc;

			dma_unmap_page(dev, be64_to_cpu(addr[0]),
				       be32_to_cpu(p->len[0]), DMA_TO_DEVICE);
			dma_unmap_page(dev, be64_to_cpu(addr[1]),
				       be32_to_cpu(p->len[1]), DMA_TO_DEVICE);
			p = (const struct ulptx_sge_pair *)&addr[2];
		} else {
			const __be64 *addr = (const __be64 *)tq->desc;

			dma_unmap_page(dev, be64_to_cpu(p->addr[0]),
				       be32_to_cpu(p->len[0]), DMA_TO_DEVICE);
			dma_unmap_page(dev, be64_to_cpu(addr[0]),
				       be32_to_cpu(p->len[1]), DMA_TO_DEVICE);
			p = (const struct ulptx_sge_pair *)&addr[1];
		}
	}
	if (nfrags) {
		__be64 addr;

		if ((u8 *)p == (u8 *)tq->stat)
			p = (const struct ulptx_sge_pair *)tq->desc;
		addr = ((u8 *)p + 16 <= (u8 *)tq->stat
			? p->addr[0]
			: *(const __be64 *)tq->desc);
		dma_unmap_page(dev, be64_to_cpu(addr), be32_to_cpu(p->len[0]),
			       DMA_TO_DEVICE);
	}
}

/**
 *	free_tx_desc - reclaims TX descriptors and their buffers
 *	@adapter: the adapter
 *	@tq: the TX queue to reclaim descriptors from
 *	@n: the number of descriptors to reclaim
 *	@unmap: whether the buffers should be unmapped for DMA
 *
 *	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 *tq,
			 unsigned int n, bool unmap)
{
	struct tx_sw_desc *sdesc;
	unsigned int cidx = tq->cidx;
	struct device *dev = adapter->pdev_dev;

	const int need_unmap = need_skb_unmap() && unmap;

	sdesc = &tq->sdesc[cidx];
	while (n--) {
		/*
		 * If we kept a reference to the original TX skb, we need to
		 * unmap it from PCI DMA space (if required) and free it.
		 */
		if (sdesc->skb) {
			if (need_unmap)
				unmap_sgl(dev, sdesc->skb, sdesc->sgl, tq);
			kfree_skb(sdesc->skb);
			sdesc->skb = NULL;
		}

		sdesc++;
		if (++cidx == tq->size) {
			cidx = 0;
			sdesc = tq->sdesc;
		}
	}
	tq->cidx = cidx;
}

/*
 * Return the number of reclaimable descriptors in a TX queue.
 */
static inline int reclaimable(const struct sge_txq *tq)
{
	int hw_cidx = be16_to_cpu(tq->stat->cidx);
	int reclaimable = hw_cidx - tq->cidx;
	if (reclaimable < 0)
		reclaimable += tq->size;
	return reclaimable;
}

/**
 *	reclaim_completed_tx - reclaims completed TX descriptors
 *	@adapter: the adapter
 *	@tq: the TX queue to reclaim completed descriptors from
 *	@unmap: whether the buffers should be unmapped for DMA
 *
 *	Reclaims TX descriptors that the SGE has indicated it has processed,
 *	and frees the associated buffers if possible.  Called with the TX
 *	queue locked.
 */
static inline void reclaim_completed_tx(struct adapter *adapter,
					struct sge_txq *tq,
					bool unmap)
{
	int avail = reclaimable(tq);

	if (avail) {
		/*
		 * Limit the amount of clean up work we do at a time to keep
		 * the TX lock hold time O(1).
		 */
		if (avail > MAX_TX_RECLAIM)
			avail = MAX_TX_RECLAIM;

		free_tx_desc(adapter, tq, avail, unmap);
		tq->in_use -= avail;
	}
}

/**
 *	get_buf_size - return the size of an RX Free List buffer.
 *	@sdesc: pointer to the software buffer descriptor
 */
static inline int get_buf_size(const struct rx_sw_desc *sdesc)
{
	return FL_PG_ORDER > 0 && (sdesc->dma_addr & RX_LARGE_BUF)
		? (PAGE_SIZE << FL_PG_ORDER)
		: PAGE_SIZE;
}

/**
 *	free_rx_bufs - free RX buffers on an SGE Free List
 *	@adapter: the adapter
 *	@fl: the SGE Free List to free buffers from
 *	@n: how many buffers to free
 *
 *	Release the next @n buffers on an SGE Free List RX queue.   The
 *	buffers must be made inaccessible to hardware before calling this
 *	function.
 */
static void free_rx_bufs(struct adapter *adapter, struct sge_fl *fl, int n)
{
	while (n--) {
		struct rx_sw_desc *sdesc = &fl->sdesc[fl->cidx];

		if (is_buf_mapped(sdesc))
			dma_unmap_page(adapter->pdev_dev, get_buf_addr(sdesc),
				       get_buf_size(sdesc), PCI_DMA_FROMDEVICE);
		put_page(sdesc->page);
		sdesc->page = NULL;
		if (++fl->cidx == fl->size)
			fl->cidx = 0;
		fl->avail--;
	}
}

/**
 *	unmap_rx_buf - unmap the current RX buffer on an SGE Free List
 *	@adapter: the adapter
 *	@fl: the SGE Free List
 *
 *	Unmap the current buffer on an SGE Free List RX queue.   The
 *	buffer must be made inaccessible to HW before calling this function.
 *
 *	This is similar to @free_rx_bufs above but does not free the buffer.
 *	Do note that the FL still loses any further access to the buffer.
 *	This is used predominantly to "transfer ownership" of an FL buffer
 *	to another entity (typically an skb's fragment list).
 */
static void unmap_rx_buf(struct adapter *adapter, struct sge_fl *fl)
{
	struct rx_sw_desc *sdesc = &fl->sdesc[fl->cidx];

	if (is_buf_mapped(sdesc))
		dma_unmap_page(adapter->pdev_dev, get_buf_addr(sdesc),
			       get_buf_size(sdesc), PCI_DMA_FROMDEVICE);
	sdesc->page = NULL;
	if (++fl->cidx == fl->size)
		fl->cidx = 0;
	fl->avail--;
}

/**
 *	ring_fl_db - righ doorbell on free list
 *	@adapter: the adapter
 *	@fl: the Free List whose doorbell should be rung ...
 *
 *	Tell the Scatter Gather Engine that there are new free list entries
 *	available.
 */
static inline void ring_fl_db(struct adapter *adapter, struct sge_fl *fl)
{
	/*
	 * The SGE keeps track of its Producer and Consumer Indices in terms
	 * of Egress Queue Units so we can only tell it about integral numbers
	 * of multiples of Free List Entries per Egress Queue Units ...
	 */
	if (fl->pend_cred >= FL_PER_EQ_UNIT) {
		wmb();
		t4_write_reg(adapter, T4VF_SGE_BASE_ADDR + SGE_VF_KDOORBELL,
			     DBPRIO |
			     QID(fl->cntxt_id) |
			     PIDX(fl->pend_cred / FL_PER_EQ_UNIT));
		fl->pend_cred %= FL_PER_EQ_UNIT;
	}
}

/**
 *	set_rx_sw_desc - initialize software RX buffer descriptor
 *	@sdesc: pointer to the softwore RX buffer descriptor
 *	@page: pointer to the page data structure backing the RX buffer
 *	@dma_addr: PCI DMA address (possibly with low-bit flags)
 */
static inline void set_rx_sw_desc(struct rx_sw_desc *sdesc, struct page *page,
				  dma_addr_t dma_addr)
{
	sdesc->page = page;
	sdesc->dma_addr = dma_addr;
}

/*
 * Support for poisoning RX buffers ...
 */
#define POISON_BUF_VAL -1

static inline void poison_buf(struct page *page, size_t sz)
{
#if POISON_BUF_VAL >= 0
	memset(page_address(page), POISON_BUF_VAL, sz);
#endif
}

/**
 *	refill_fl - refill an SGE RX buffer ring
 *	@adapter: the adapter
 *	@fl: the Free List ring to refill
 *	@n: the number of new buffers to allocate
 *	@gfp: the gfp flags for the allocations
 *
 *	(Re)populate an SGE free-buffer queue 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 -- i.e. (cidx == pidx) _IN
 *	EGRESS QUEUE UNITS_ indicates an empty Free List!  Returns the number
 *	of buffers allocated.  If afterwards the queue is found critically low,
 *	mark it as starving in the bitmap of starving FLs.
 */
static unsigned int refill_fl(struct adapter *adapter, struct sge_fl *fl,
			      int n, gfp_t gfp)
{
	struct page *page;
	dma_addr_t dma_addr;
	unsigned int cred = fl->avail;
	__be64 *d = &fl->desc[fl->pidx];
	struct rx_sw_desc *sdesc = &fl->sdesc[fl->pidx];

	/*
	 * Sanity: ensure that the result of adding n Free List buffers
	 * won't result in wrapping the SGE's Producer Index around to
	 * it's Consumer Index thereby indicating an empty Free List ...
	 */
	BUG_ON(fl->avail + n > fl->size - FL_PER_EQ_UNIT);

	/*
	 * If we support large pages, prefer large buffers and fail over to
	 * small pages if we can't allocate large pages to satisfy the refill.
	 * If we don't support large pages, drop directly into the small page
	 * allocation code.
	 */
	if (FL_PG_ORDER == 0)
		goto alloc_small_pages;

	while (n) {
		page = alloc_pages(gfp | __GFP_COMP | __GFP_NOWARN,
				   FL_PG_ORDER);
		if (unlikely(!page)) {
			/*
			 * We've failed inour attempt to allocate a "large
			 * page".  Fail over to the "small page" allocation
			 * below.
			 */
			fl->large_alloc_failed++;
			break;
		}
		poison_buf(page, PAGE_SIZE << FL_PG_ORDER);

		dma_addr = dma_map_page(adapter->pdev_dev, page, 0,
					PAGE_SIZE << FL_PG_ORDER,
					PCI_DMA_FROMDEVICE);
		if (unlikely(dma_mapping_error(adapter->pdev_dev, dma_addr))) {
			/*
			 * We've run out of DMA mapping space.  Free up the
			 * buffer and return with what we've managed to put
			 * into the free list.  We don't want to fail over to
			 * the small page allocation below in this case
			 * because DMA mapping resources are typically
			 * critical resources once they become scarse.
			 */
			__free_pages(page, FL_PG_ORDER);
			goto out;
		}
		dma_addr |= RX_LARGE_BUF;
		*d++ = cpu_to_be64(dma_addr);

		set_rx_sw_desc(sdesc, page, dma_addr);
		sdesc++;

		fl->avail++;
		if (++fl->pidx == fl->size) {
			fl->pidx = 0;
			sdesc = fl->sdesc;
			d = fl->desc;
		}
		n--;
	}

alloc_small_pages:
	while (n--) {
		page = __netdev_alloc_page(adapter->port[0],
					   gfp | __GFP_NOWARN);
		if (unlikely(!page)) {
			fl->alloc_failed++;
			break;
		}
		poison_buf(page, PAGE_SIZE);

		dma_addr = dma_map_page(adapter->pdev_dev, page, 0, PAGE_SIZE,
				       PCI_DMA_FROMDEVICE);
		if (unlikely(dma_mapping_error(adapter->pdev_dev, dma_addr))) {
			netdev_free_page(adapter->port[0], page);
			break;
		}
		*d++ = cpu_to_be64(dma_addr);

		set_rx_sw_desc(sdesc, page, dma_addr);
		sdesc++;

		fl->avail++;
		if (++fl->pidx == fl->size) {
			fl->pidx = 0;
			sdesc = fl->sdesc;
			d = fl->desc;
		}
	}

out:
	/*
	 * Update our accounting state to incorporate the new Free List
	 * buffers, tell the hardware about them and return the number of
	 * bufers which we were able to allocate.
	 */
	cred = fl->avail - cred;
	fl->pend_cred += cred;
	ring_fl_db(adapter, fl);

	if (unlikely(fl_starving(fl))) {
		smp_wmb();
		set_bit(fl->cntxt_id, adapter->sge.starving_fl);
	}

	return cred;
}

/*
 * Refill a Free List to its capacity or the Maximum Refill Increment,
 * whichever is smaller ...
 */
static inline void __refill_fl(struct adapter *adapter, struct sge_fl *fl)
{
	refill_fl(adapter, fl,
		  min((unsigned int)MAX_RX_REFILL, fl_cap(fl) - fl->avail),
		  GFP_ATOMIC);
}

/**
 *	alloc_ring - allocate resources for an SGE descriptor ring
 *	@dev: the PCI device's core device
 *	@nelem: the number of descriptors
 *	@hwsize: the size of each hardware descriptor
 *	@swsize: the size of each software descriptor
 *	@busaddrp: the physical PCI bus address of the allocated ring
 *	@swringp: return address pointer for software ring
 *	@stat_size: extra space in hardware ring for status information
 *
 *	Allocates resources for an SGE descriptor ring, such as TX queues,
 *	free buffer lists, response queues, etc.  Each SGE ring requires
 *	space for its hardware descriptors plus, optionally, space for software
 *	state associated with each hardware entry (the metadata).  The function
 *	returns three values: the virtual address for the hardware ring (the
 *	return value of the function), the PCI bus address of the hardware
 *	ring (in *busaddrp), and the address of the software ring (in swringp).
 *	Both the hardware and software rings are returned zeroed out.
 */
static void *alloc_ring(struct device *dev, size_t nelem, size_t hwsize,
			size_t swsize, dma_addr_t *busaddrp, void *swringp,
			size_t stat_size)
{
	/*
	 * Allocate the hardware ring and PCI DMA bus address space for said.
	 */
	size_t hwlen = nelem * hwsize + stat_size;
	void *hwring = dma_alloc_coherent(dev, hwlen, busaddrp, GFP_KERNEL);

	if (!hwring)
		return NULL;

	/*
	 * If the caller wants a software ring, allocate it and return a
	 * pointer to it in *swringp.
	 */
	BUG_ON((swsize != 0) != (swringp != NULL));
	if (swsize) {
		void *swring = kcalloc(nelem, swsize, GFP_KERNEL);

		if (!swring) {
			dma_free_coherent(dev, hwlen, hwring, *busaddrp);
			return NULL;
		}
		*(void **)swringp = swring;
	}

	/*
	 * Zero out the hardware ring and return its address as our function
	 * value.
	 */
	memset(hwring, 0, hwlen);
	return hwring;
}

/**
 *	sgl_len - calculates the size of an SGL of the given capacity
 *	@n: the number of SGL entries
 *
 *	Calculates the number of flits (8-byte units) needed for a Direct
 *	Scatter/Gather List that can hold the given number of entries.
 */
static inline unsigned int sgl_len(unsigned int n)
{
	/*
	 * A Direct Scatter Gather List uses 32-bit lengths and 64-bit PCI DMA
	 * addresses.  The DSGL Work Request starts off with a 32-bit DSGL
	 * ULPTX header, then Length0, then Address0, then, for 1 <= i <= N,
	 * repeated sequences of { Length[i], Length[i+1], Address[i],
	 * Address[i+1] } (this ensures that all addresses are on 64-bit
	 * boundaries).  If N is even, then Length[N+1] should be set to 0 and
	 * Address[N+1] is omitted.
	 *
	 * The following calculation incorporates all of the above.  It's
	 * somewhat hard to follow but, briefly: the "+2" accounts for the
	 * first two flits which include the DSGL header, Length0 and
	 * Address0; the "(3*(n-1))/2" covers the main body of list entries (3
	 * flits for every pair of the remaining N) +1 if (n-1) is odd; and
	 * finally the "+((n-1)&1)" adds the one remaining flit needed if
	 * (n-1) is odd ...
	 */
	n--;
	return (3 * n) / 2 + (n & 1) + 2;
}

/**
 *	flits_to_desc - returns the num of TX descriptors for the given flits
 *	@flits: the number of flits
 *
 *	Returns the number of TX descriptors needed for the supplied number
 *	of flits.
 */
static inline unsigned int flits_to_desc(unsigned int flits)
{
	BUG_ON(flits > SGE_MAX_WR_LEN / sizeof(__be64));
	return DIV_ROUND_UP(flits, TXD_PER_EQ_UNIT);
}

/**
 *	is_eth_imm - can an Ethernet packet be sent as immediate data?
 *	@skb: the packet
 *
 *	Returns whether an Ethernet packet is small enough to fit completely as
 *	immediate data.
 */
static inline int is_eth_imm(const struct sk_buff *skb)
{
	/*
	 * The VF Driver uses the FW_ETH_TX_PKT_VM_WR firmware Work Request
	 * which does not accommodate immediate data.  We could dike out all
	 * of the support code for immediate data but that would tie our hands
	 * too much if we ever want to enhace the firmware.  It would also
	 * create more differences between the PF and VF Drivers.
	 */
	return false;
}

/**
 *	calc_tx_flits - calculate the number of flits for a packet TX WR
 *	@skb: the packet
 *
 *	Returns the number of flits needed for a TX Work Request for the
 *	given Ethernet packet, including the needed WR and CPL headers.
 */
static inline unsigned int calc_tx_flits(const struct sk_buff *skb)
{
	unsigned int flits;

	/*
	 * If the skb is small enough, we can pump it out as a work request
	 * with only immediate data.  In that case we just have to have the
	 * TX Packet header plus the skb data in the Work Request.
	 */
	if (is_eth_imm(skb))
		return DIV_ROUND_UP(skb->len + sizeof(struct cpl_tx_pkt),
				    sizeof(__be64));

	/*
	 * Otherwise, we're going to have to construct a Scatter gather list
	 * of the skb body and fragments.  We also include the flits necessary
	 * for the TX Packet Work Request and CPL.  We always have a firmware
	 * Write Header (incorporated as part of the cpl_tx_pkt_lso and
	 * cpl_tx_pkt structures), followed by either a TX Packet Write CPL
	 * message or, if we're doing a Large Send Offload, an LSO CPL message
	 * with an embeded TX Packet Write CPL message.
	 */
	flits = sgl_len(skb_shinfo(skb)->nr_frags + 1);
	if (skb_shinfo(skb)->gso_size)
		flits += (sizeof(struct fw_eth_tx_pkt_vm_wr) +
			  sizeof(struct cpl_tx_pkt_lso_core) +
			  sizeof(struct cpl_tx_pkt_core)) / sizeof(__be64);
	else
		flits += (sizeof(struct fw_eth_tx_pkt_vm_wr) +
			  sizeof(struct cpl_tx_pkt_core)) / sizeof(__be64);
	return flits;
}

/**
 *	write_sgl - populate a Scatter/Gather List for a packet
 *	@skb: the packet
 *	@tq: the TX queue we are writing into
 *	@sgl: starting location for writing the SGL
 *	@end: points right after the end of the SGL
 *	@start: start offset into skb main-body data to include in the SGL
 *	@addr: the list of DMA bus addresses for the SGL elements
 *
 *	Generates a Scatter/Gather List for the buffers that make up a packet.
 *	The caller must provide adequate space for the SGL that will be written.
 *	The SGL includes all of the packet's page fragments and the data in its
 *	main body except for the first @start bytes.  @pos must be 16-byte
 *	aligned and within a TX descriptor with available space.  @end points
 *	write after the end of the SGL but does not account for any potential
 *	wrap around, i.e., @end > @tq->stat.
 */
static void write_sgl(const struct sk_buff *skb, struct sge_txq *tq,
		      struct ulptx_sgl *sgl, u64 *end, unsigned int start,
		      const dma_addr_t *addr)
{
	unsigned int i, len;
	struct ulptx_sge_pair *to;
	const struct skb_shared_info *si = skb_shinfo(skb);
	unsigned int nfrags = si->nr_frags;
	struct ulptx_sge_pair buf[MAX_SKB_FRAGS / 2 + 1];

	len = skb_headlen(skb) - start;
	if (likely(len)) {
		sgl->len0 = htonl(len);
		sgl->addr0 = cpu_to_be64(addr[0] + start);
		nfrags++;
	} else {
		sgl->len0 = htonl(si->frags[0].size);
		sgl->addr0 = cpu_to_be64(addr[1]);
	}

	sgl->cmd_nsge = htonl(ULPTX_CMD(ULP_TX_SC_DSGL) |
			      ULPTX_NSGE(nfrags));
	if (likely(--nfrags == 0))
		return;
	/*
	 * Most of the complexity below deals with the possibility we hit the
	 * end of the queue in the middle of writing the SGL.  For this case
	 * only we create the SGL in a temporary buffer and then copy it.
	 */
	to = (u8 *)end > (u8 *)tq->stat ? buf : sgl->sge;

	for (i = (nfrags != si->nr_frags); nfrags >= 2; nfrags -= 2, to++) {
		to->len[0] = cpu_to_be32(si->frags[i].size);
		to->len[1] = cpu_to_be32(si->frags[++i].size);
		to->addr[0] = cpu_to_be64(addr[i]);
		to->addr[1] = cpu_to_be64(addr[++i]);
	}
	if (nfrags) {
		to->len[0] = cpu_to_be32(si->frags[i].size);
		to->len[1] = cpu_to_be32(0);
		to->addr[0] = cpu_to_be64(addr[i + 1]);
	}
	if (unlikely((u8 *)end > (u8 *)tq->stat)) {
		unsigned int part0 = (u8 *)tq->stat - (u8 *)sgl->sge, part1;

		if (likely(part0))
			memcpy(sgl->sge, buf, part0);
		part1 = (u8 *)end - (u8 *)tq->stat;
		memcpy(tq->desc, (u8 *)buf + part0, part1);
		end = (void *)tq->desc + part1;
	}
	if ((uintptr_t)end & 8)           /* 0-pad to multiple of 16 */
		*(u64 *)end = 0;
}

/**
 *	check_ring_tx_db - check and potentially ring a TX queue's doorbell
 *	@adapter: the adapter
 *	@tq: the TX queue
 *	@n: number of new descriptors to give to HW
 *
 *	Ring the doorbel for a TX queue.
 */
static inline void ring_tx_db(struct adapter *adapter, struct sge_txq *tq,
			      int n)
{
	/*
	 * Warn if we write doorbells with the wrong priority and write
	 * descriptors before telling HW.
	 */
	WARN_ON((QID(tq->cntxt_id) | PIDX(n)) & DBPRIO);
	wmb();
	t4_write_reg(adapter, T4VF_SGE_BASE_ADDR + SGE_VF_KDOORBELL,
		     QID(tq->cntxt_id) | PIDX(n));
}

/**
 *	inline_tx_skb - inline a packet's data into TX descriptors
 *	@skb: the packet
 *	@tq: the TX queue where the packet will be inlined
 *	@pos: starting position in the TX queue to inline the packet
 *
 *	Inline a packet's contents directly into TX descriptors, starting at
 *	the given position within the TX DMA ring.
 *	Most of the complexity of this operation is dealing with wrap arounds
 *	in the middle of the packet we want to inline.
 */
static void inline_tx_skb(const struct sk_buff *skb, const struct sge_txq *tq,
			  void *pos)
{
	u64 *p;
	int left = (void *)tq->stat - pos;

	if (likely(skb->len <= left)) {
		if (likely(!skb->data_len))
			skb_copy_from_linear_data(skb, pos, skb->len);
		else
			skb_copy_bits(skb, 0, pos, skb->len);
		pos += skb->len;
	} else {
		skb_copy_bits(skb, 0, pos, left);
		skb_copy_bits(skb, left, tq->desc, skb->len - left);
		pos = (void *)tq->desc + (skb->len - left);
	}

	/* 0-pad to multiple of 16 */
	p = PTR_ALIGN(pos, 8);
	if ((uintptr_t)p & 8)
		*p = 0;
}

/*
 * Figure out what HW csum a packet wants and return the appropriate control
 * bits.
 */
static u64 hwcsum(const struct sk_buff *skb)
{
	int csum_type;
	const struct iphdr *iph = ip_hdr(skb);

	if (iph->version == 4) {
		if (iph->protocol == IPPROTO_TCP)
			csum_type = TX_CSUM_TCPIP;
		else if (iph->protocol == IPPROTO_UDP)
			csum_type = TX_CSUM_UDPIP;
		else {
nocsum:
			/*
			 * unknown protocol, disable HW csum
			 * and hope a bad packet is detected
			 */
			return TXPKT_L4CSUM_DIS;
		}
	} else {
		/*
		 * this doesn't work with extension headers
		 */
		const struct ipv6hdr *ip6h = (const struct ipv6hdr *)iph;

		if (ip6h->nexthdr == IPPROTO_TCP)
			csum_type = TX_CSUM_TCPIP6;
		else if (ip6h->nexthdr == IPPROTO_UDP)
			csum_type = TX_CSUM_UDPIP6;
		else
			goto nocsum;
	}

	if (likely(csum_type >= TX_CSUM_TCPIP))
		return TXPKT_CSUM_TYPE(csum_type) |
			TXPKT_IPHDR_LEN(skb_network_header_len(skb)) |
			TXPKT_ETHHDR_LEN(skb_network_offset(skb) - ETH_HLEN);
	else {
		int start = skb_transport_offset(skb);

		return TXPKT_CSUM_TYPE(csum_type) |
			TXPKT_CSUM_START(start) |
			TXPKT_CSUM_LOC(start + skb->csum_offset);
	}
}

/*
 * Stop an Ethernet TX queue and record that state change.
 */
static void txq_stop(struct sge_eth_txq *txq)
{
	netif_tx_stop_queue(txq->txq);
	txq->q.stops++;
}

/*
 * Advance our software state for a TX queue by adding n in use descriptors.
 */
static inline void txq_advance(struct sge_txq *tq, unsigned int n)
{
	tq->in_use += n;
	tq->pidx += n;
	if (tq->pidx >= tq->size)
		tq->pidx -= tq->size;
}

/**
 *	t4vf_eth_xmit - add a packet to an Ethernet TX queue
 *	@skb: the packet
 *	@dev: the egress net device
 *
 *	Add a packet to an SGE Ethernet TX queue.  Runs with softirqs disabled.
 */
int t4vf_eth_xmit(struct sk_buff *skb, struct net_device *dev)
{
	u64 cntrl, *end;
	int qidx, credits;
	unsigned int flits, ndesc;
	struct adapter *adapter;
	struct sge_eth_txq *txq;
	const struct port_info *pi;
	struct fw_eth_tx_pkt_vm_wr *wr;
	struct cpl_tx_pkt_core *cpl;
	const struct skb_shared_info *ssi;
	dma_addr_t addr[MAX_SKB_FRAGS + 1];
	const size_t fw_hdr_copy_len = (sizeof(wr->ethmacdst) +
					sizeof(wr->ethmacsrc) +
					sizeof(wr->ethtype) +
					sizeof(wr->vlantci));

	/*
	 * The chip minimum packet length is 10 octets but the firmware
	 * command that we are using requires that we copy the Ethernet header
	 * (including the VLAN tag) into the header so we reject anything
	 * smaller than that ...
	 */
	if (unlikely(skb->len < fw_hdr_copy_len))
		goto out_free;

	/*
	 * Figure out which TX Queue we're going to use.
	 */
	pi = netdev_priv(dev);
	adapter = pi->adapter;
	qidx = skb_get_queue_mapping(skb);
	BUG_ON(qidx >= pi->nqsets);
	txq = &adapter->sge.ethtxq[pi->first_qset + qidx];

	/*
	 * Take this opportunity to reclaim any TX Descriptors whose DMA
	 * transfers have completed.
	 */
	reclaim_completed_tx(adapter, &txq->q, true);

	/*
	 * Calculate the number of flits and TX Descriptors we're going to
	 * need along with how many TX Descriptors will be left over after
	 * we inject our Work Request.
	 */
	flits = calc_tx_flits(skb);
	ndesc = flits_to_desc(flits);
	credits = txq_avail(&txq->q) - ndesc;

	if (unlikely(credits < 0)) {
		/*
		 * Not enough room for this packet's Work Request.  Stop the
		 * TX Queue and return a "busy" condition.  The queue will get
		 * started later on when the firmware informs us that space
		 * has opened up.
		 */
		txq_stop(txq);
		dev_err(adapter->pdev_dev,
			"%s: TX ring %u full while queue awake!\n",
			dev->name, qidx);
		return NETDEV_TX_BUSY;
	}

	if (!is_eth_imm(skb) &&
	    unlikely(map_skb(adapter->pdev_dev, skb, addr) < 0)) {
		/*
		 * We need to map the skb into PCI DMA space (because it can't
		 * be in-lined directly into the Work Request) and the mapping
		 * operation failed.  Record the error and drop the packet.
		 */
		txq->mapping_err++;
		goto out_free;
	}

	if (unlikely(credits < ETHTXQ_STOP_THRES)) {
		/*
		 * After we're done injecting the Work Request for this
		 * packet, we'll be below our "stop threshhold" so stop the TX
		 * Queue now.  The queue will get started later on when the
		 * firmware informs us that space has opened up.
		 */
		txq_stop(txq);
	}

	/*
	 * Start filling in our Work Request.  Note that we do _not_ handle
	 * the WR Header wrapping around the TX Descriptor Ring.  If our
	 * maximum header size ever exceeds one TX Descriptor, we'll need to
	 * do something else here.
	 */
	BUG_ON(DIV_ROUND_UP(ETHTXQ_MAX_HDR, TXD_PER_EQ_UNIT) > 1);
	wr = (void *)&txq->q.desc[txq->q.pidx];
	wr->equiq_to_len16 = cpu_to_be32(FW_WR_LEN16(DIV_ROUND_UP(flits, 2)));
	wr->r3[0] = cpu_to_be64(0);
	wr->r3[1] = cpu_to_be64(0);
	skb_copy_from_linear_data(skb, (void *)wr->ethmacdst, fw_hdr_copy_len);
	end = (u64 *)wr + flits;

	/*
	 * If this is a Large Send Offload packet we'll put in an LSO CPL
	 * message with an encapsulated TX Packet CPL message.  Otherwise we
	 * just use a TX Packet CPL message.
	 */
	ssi = skb_shinfo(skb);
	if (ssi->gso_size) {
		struct cpl_tx_pkt_lso_core *lso = (void *)(wr + 1);
		bool v6 = (ssi->gso_type & SKB_GSO_TCPV6) != 0;
		int l3hdr_len = skb_network_header_len(skb);
		int eth_xtra_len = skb_network_offset(skb) - ETH_HLEN;

		wr->op_immdlen =
			cpu_to_be32(FW_WR_OP(FW_ETH_TX_PKT_VM_WR) |
				    FW_WR_IMMDLEN(sizeof(*lso) +
						  sizeof(*cpl)));
		/*
		 * Fill in the LSO CPL message.
		 */
		lso->lso_ctrl =
			cpu_to_be32(LSO_OPCODE(CPL_TX_PKT_LSO) |
				    LSO_FIRST_SLICE |
				    LSO_LAST_SLICE |
				    LSO_IPV6(v6) |
				    LSO_ETHHDR_LEN(eth_xtra_len/4) |
				    LSO_IPHDR_LEN(l3hdr_len/4) |
				    LSO_TCPHDR_LEN(tcp_hdr(skb)->doff));
		lso->ipid_ofst = cpu_to_be16(0);
		lso->mss = cpu_to_be16(ssi->gso_size);
		lso->seqno_offset = cpu_to_be32(0);
		lso->len = cpu_to_be32(skb->len);

		/*
		 * Set up TX Packet CPL pointer, control word and perform
		 * accounting.
		 */
		cpl = (void *)(lso + 1);
		cntrl = (TXPKT_CSUM_TYPE(v6 ? TX_CSUM_TCPIP6 : TX_CSUM_TCPIP) |
			 TXPKT_IPHDR_LEN(l3hdr_len) |
			 TXPKT_ETHHDR_LEN(eth_xtra_len));
		txq->tso++;
		txq->tx_cso += ssi->gso_segs;
	} else {
		int len;

		len = is_eth_imm(skb) ? skb->len + sizeof(*cpl) : sizeof(*cpl);
		wr->op_immdlen =
			cpu_to_be32(FW_WR_OP(FW_ETH_TX_PKT_VM_WR) |
				    FW_WR_IMMDLEN(len));

		/*
		 * Set up TX Packet CPL pointer, control word and perform
		 * accounting.
		 */
		cpl = (void *)(wr + 1);
		if (skb->ip_summed == CHECKSUM_PARTIAL) {
			cntrl = hwcsum(skb) | TXPKT_IPCSUM_DIS;
			txq->tx_cso++;
		} else
			cntrl = TXPKT_L4CSUM_DIS | TXPKT_IPCSUM_DIS;
	}

	/*
	 * If there's a VLAN tag present, add that to the list of things to
	 * do in this Work Request.
	 */
	if (vlan_tx_tag_present(skb)) {
		txq->vlan_ins++;
		cntrl |= TXPKT_VLAN_VLD | TXPKT_VLAN(vlan_tx_tag_get(skb));
	}

	/*
	 * Fill in the TX Packet CPL message header.
	 */
	cpl->ctrl0 = cpu_to_be32(TXPKT_OPCODE(CPL_TX_PKT_XT) |
				 TXPKT_INTF(pi->port_id) |
				 TXPKT_PF(0));
	cpl->pack = cpu_to_be16(0);
	cpl->len = cpu_to_be16(skb->len);
	cpl->ctrl1 = cpu_to_be64(cntrl);

#ifdef T4_TRACE
	T4_TRACE5(adapter->tb[txq->q.cntxt_id & 7],
		  "eth_xmit: ndesc %u, credits %u, pidx %u, len %u, frags %u",
		  ndesc, credits, txq->q.pidx, skb->len, ssi->nr_frags);
#endif

	/*
	 * Fill in the body of the TX Packet CPL message with either in-lined
	 * data or a Scatter/Gather List.
	 */
	if (is_eth_imm(skb)) {
		/*
		 * In-line the packet's data and free the skb since we don't
		 * need it any longer.
		 */
		inline_tx_skb(skb, &txq->q, cpl + 1);
		dev_kfree_skb(skb);
	} else {
		/*
		 * Write the skb's Scatter/Gather list into the TX Packet CPL
		 * message and retain a pointer to the skb so we can free it
		 * later when its DMA completes.  (We store the skb pointer
		 * in the Software Descriptor corresponding to the last TX
		 * Descriptor used by the Work Request.)
		 *
		 * The retained skb will be freed when the corresponding TX
		 * Descriptors are reclaimed after their DMAs complete.
		 * However, this could take quite a while since, in general,
		 * the hardware is set up to be lazy about sending DMA
		 * completion notifications to us and we mostly perform TX
		 * reclaims in the transmit routine.
		 *
		 * This is good for performamce 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 con 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.
		 *
		 * Run the destructor before telling the DMA engine about the
		 * packet to make sure it doesn't complete and get freed
		 * prematurely.
		 */
		struct ulptx_sgl *sgl = (struct ulptx_sgl *)(cpl + 1);
		struct sge_txq *tq = &txq->q;
		int last_desc;

		/*
		 * If the Work Request header was an exact multiple of our TX
		 * Descriptor length, then it's possible that the starting SGL
		 * pointer lines up exactly with the end of our TX Descriptor
		 * ring.  If that's the case, wrap around to the beginning
		 * here ...
		 */
		if (unlikely((void *)sgl == (void *)tq->stat)) {
			sgl = (void *)tq->desc;
			end = (void *)((void *)tq->desc +
				       ((void *)end - (void *)tq->stat));
		}

		write_sgl(skb, tq, sgl, end, 0, addr);
		skb_orphan(skb);

		last_desc = tq->pidx + ndesc - 1;
		if (last_desc >= tq->size)
			last_desc -= tq->size;
		tq->sdesc[last_desc].skb = skb;
		tq->sdesc[last_desc].sgl = sgl;
	}

	/*
	 * Advance our internal TX Queue state, tell the hardware about
	 * the new TX descriptors and return success.
	 */
	txq_advance(&txq->q, ndesc);
	dev->trans_start = jiffies;
	ring_tx_db(adapter, &txq->q, ndesc);
	return NETDEV_TX_OK;

out_free:
	/*
	 * An error of some sort happened.  Free the TX skb and tell the
	 * OS that we've "dealt" with the packet ...
	 */
	dev_kfree_skb(skb);
	return NETDEV_TX_OK;
}

/**
 *	t4vf_pktgl_free - free a packet gather list
 *	@gl: the gather list
 *
 *	Releases the pages of a packet gather list.  We do not own the last
 *	page on the list and do not free it.
 */
void t4vf_pktgl_free(const struct pkt_gl *gl)
{
	int frag;

	frag = gl->nfrags - 1;
	while (frag--)
		put_page(gl->frags[frag].page);
}

/**
 *	copy_frags - copy fragments from gather list into skb_shared_info
 *	@si: destination skb shared info structure
 *	@gl: source internal packet gather list
 *	@offset: packet start offset in first page
 *
 *	Copy an internal packet gather list into a Linux skb_shared_info
 *	structure.
 */
static inline void copy_frags(struct skb_shared_info *si,
			      const struct pkt_gl *gl,
			      unsigned int offset)
{
	unsigned int n;

	/* usually there's just one frag */
	si->frags[0].page = gl->frags[0].page;
	si->frags[0].page_offset = gl->frags[0].page_offset + offset;
	si->frags[0].size = gl->frags[0].size - offset;
	si->nr_frags = gl->nfrags;

	n = gl->nfrags - 1;
	if (n)
		memcpy(&si->frags[1], &gl->frags[1], n * sizeof(skb_frag_t));

	/* get a reference to the last page, we don't own it */
	get_page(gl->frags[n].page);
}

/**
 *	do_gro - perform Generic Receive Offload ingress packet processing
 *	@rxq: ingress RX Ethernet Queue
 *	@gl: gather list for ingress packet
 *	@pkt: CPL header for last packet fragment
 *
 *	Perform Generic Receive Offload (GRO) ingress packet processing.
 *	We use the standard Linux GRO interfaces for this.
 */
static void do_gro(struct sge_eth_rxq *rxq, const struct pkt_gl *gl,
		   const struct cpl_rx_pkt *pkt)
{
	int ret;
	struct sk_buff *skb;

	skb = napi_get_frags(&rxq->rspq.napi);
	if (unlikely(!skb)) {
		t4vf_pktgl_free(gl);
		rxq->stats.rx_drops++;
		return;
	}

	copy_frags(skb_shinfo(skb), gl, PKTSHIFT);
	skb->len = gl->tot_len - PKTSHIFT;
	skb->data_len = skb->len;
	skb->truesize += skb->data_len;
	skb->ip_summed = CHECKSUM_UNNECESSARY;
	skb_record_rx_queue(skb, rxq->rspq.idx);

	if (unlikely(pkt->vlan_ex)) {
		struct port_info *pi = netdev_priv(rxq->rspq.netdev);
		struct vlan_group *grp = pi->vlan_grp;

		rxq->stats.vlan_ex++;
		if (likely(grp)) {
			ret = vlan_gro_frags(&rxq->rspq.napi, grp,
					     be16_to_cpu(pkt->vlan));
			goto stats;
		}
	}
	ret = napi_gro_frags(&rxq->rspq.napi);

stats:
	if (ret == GRO_HELD)
		rxq->stats.lro_pkts++;
	else if (ret == GRO_MERGED || ret == GRO_MERGED_FREE)
		rxq->stats.lro_merged++;
	rxq->stats.pkts++;
	rxq->stats.rx_cso++;
}

/**
 *	t4vf_ethrx_handler - process an ingress ethernet packet
 *	@rspq: the response queue that received the packet
 *	@rsp: the response queue descriptor holding the RX_PKT message
 *	@gl: the gather list of packet fragments
 *
 *	Process an ingress ethernet packet and deliver it to the stack.
 */
int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp,
		       const struct pkt_gl *gl)
{
	struct sk_buff *skb;
	struct port_info *pi;
	struct skb_shared_info *ssi;
	const struct cpl_rx_pkt *pkt = (void *)&rsp[1];
	bool csum_ok = pkt->csum_calc && !pkt->err_vec;
	unsigned int len = be16_to_cpu(pkt->len);
	struct sge_eth_rxq *rxq = container_of(rspq, struct sge_eth_rxq, rspq);

	/*
	 * If this is a good TCP packet and we have Generic Receive Offload
	 * enabled, handle the packet in the GRO path.
	 */
	if ((pkt->l2info & cpu_to_be32(RXF_TCP)) &&
	    (rspq->netdev->features & NETIF_F_GRO) && csum_ok &&
	    !pkt->ip_frag) {
		do_gro(rxq, gl, pkt);
		return 0;
	}

	/*
	 * If the ingress packet is small enough, allocate an skb large enough
	 * for all of the data and copy it inline.  Otherwise, allocate an skb
	 * with enough room to pull in the header and reference the rest of
	 * the data via the skb fragment list.
	 */
	if (len <= RX_COPY_THRES) {
		/* small packets have only one fragment */
		skb = alloc_skb(gl->frags[0].size, GFP_ATOMIC);
		if (!skb)
			goto nomem;
		__skb_put(skb, gl->frags[0].size);
		skb_copy_to_linear_data(skb, gl->va, gl->frags[0].size);
	} else {
		skb = alloc_skb(RX_PKT_PULL_LEN, GFP_ATOMIC);
		if (!skb)
			goto nomem;
		__skb_put(skb, RX_PKT_PULL_LEN);
		skb_copy_to_linear_data(skb, gl->va, RX_PKT_PULL_LEN);

		ssi = skb_shinfo(skb);
		ssi->frags[0].page = gl->frags[0].page;
		ssi->frags[0].page_offset = (gl->frags[0].page_offset +
					     RX_PKT_PULL_LEN);
		ssi->frags[0].size = gl->frags[0].size - RX_PKT_PULL_LEN;
		if (gl->nfrags > 1)
			memcpy(&ssi->frags[1], &gl->frags[1],
			       (gl->nfrags-1) * sizeof(skb_frag_t));
		ssi->nr_frags = gl->nfrags;
		skb->len = len + PKTSHIFT;
		skb->data_len = skb->len - RX_PKT_PULL_LEN;
		skb->truesize += skb->data_len;

		/* Get a reference for the last page, we don't own it */
		get_page(gl->frags[gl->nfrags - 1].page);
	}

	__skb_pull(skb, PKTSHIFT);
	skb->protocol = eth_type_trans(skb, rspq->netdev);
	skb_record_rx_queue(skb, rspq->idx);
	skb->dev->last_rx = jiffies;                  /* XXX removed 2.6.29 */
	pi = netdev_priv(skb->dev);
	rxq->stats.pkts++;

	if (csum_ok && (pi->rx_offload & RX_CSO) && !pkt->err_vec &&
	    (be32_to_cpu(pkt->l2info) & (RXF_UDP|RXF_TCP))) {
		if (!pkt->ip_frag)
			skb->ip_summed = CHECKSUM_UNNECESSARY;
		else {
			__sum16 c = (__force __sum16)pkt->csum;
			skb->csum = csum_unfold(c);
			skb->ip_summed = CHECKSUM_COMPLETE;
		}
		rxq->stats.rx_cso++;
	} else
		skb->ip_summed = CHECKSUM_NONE;

	if (unlikely(pkt->vlan_ex)) {
		struct vlan_group *grp = pi->vlan_grp;

		rxq->stats.vlan_ex++;
		if (likely(grp))
			vlan_hwaccel_receive_skb(skb, grp,
						 be16_to_cpu(pkt->vlan));
		else
			dev_kfree_skb_any(skb);
	} else
		netif_receive_skb(skb);

	return 0;

nomem:
	t4vf_pktgl_free(gl);
	rxq->stats.rx_drops++;
	return 0;
}

/**
 *	is_new_response - check if a response is newly written
 *	@rc: the response control descriptor
 *	@rspq: the response queue
 *
 *	Returns true if a response descriptor contains a yet unprocessed
 *	response.
 */
static inline bool is_new_response(const struct rsp_ctrl *rc,
				   const struct sge_rspq *rspq)
{
	return RSPD_GEN(rc->type_gen) == rspq->gen;
}

/**
 *	restore_rx_bufs - put back a packet's RX buffers
 *	@gl: the packet gather list
 *	@fl: the SGE Free List
 *	@nfrags: how many fragments in @si
 *
 *	Called when we find out that the current packet, @si, can't be
 *	processed right away for some reason.  This is a very rare event and
 *	there's no effort to make this suspension/resumption process
 *	particularly efficient.
 *
 *	We implement the suspension by putting all of the RX buffers associated
 *	with the current packet back on the original Free List.  The buffers
 *	have already been unmapped and are left unmapped, we mark them as
 *	unmapped in order to prevent further unmapping attempts.  (Effectively
 *	this function undoes the series of @unmap_rx_buf calls which were done
 *	to create the current packet's gather list.)  This leaves us ready to
 *	restart processing of the packet the next time we start processing the
 *	RX Queue ...
 */
static void restore_rx_bufs(const struct pkt_gl *gl, struct sge_fl *fl,
			    int frags)
{
	struct rx_sw_desc *sdesc;

	while (frags--) {
		if (fl->cidx == 0)
			fl->cidx = fl->size - 1;
		else
			fl->cidx--;
		sdesc = &fl->sdesc[fl->cidx];
		sdesc->page = gl->frags[frags].page;
		sdesc->dma_addr |= RX_UNMAPPED_BUF;
		fl->avail++;
	}
}

/**
 *	rspq_next - advance to the next entry in a response queue
 *	@rspq: the queue
 *
 *	Updates the state of a response queue to advance it to the next entry.
 */
static inline void rspq_next(struct sge_rspq *rspq)
{
	rspq->cur_desc = (void *)rspq->cur_desc + rspq->iqe_len;
	if (unlikely(++rspq->cidx == rspq->size)) {
		rspq->cidx = 0;
		rspq->gen ^= 1;
		rspq->cur_desc = rspq->desc;
	}
}

/**
 *	process_responses - process responses from an SGE response queue
 *	@rspq: the ingress response queue to process
 *	@budget: how many responses can be processed in this round
 *
 *	Process responses from a Scatter Gather Engine response queue up to
 *	the supplied budget.  Responses include received packets as well as
 *	control messages from firmware or hardware.
 *
 *	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.
 */
int process_responses(struct sge_rspq *rspq, int budget)
{
	struct sge_eth_rxq *rxq = container_of(rspq, struct sge_eth_rxq, rspq);
	int budget_left = budget;

	while (likely(budget_left)) {
		int ret, rsp_type;
		const struct rsp_ctrl *rc;

		rc = (void *)rspq->cur_desc + (rspq->iqe_len - sizeof(*rc));
		if (!is_new_response(rc, rspq))
			break;

		/*
		 * Figure out what kind of response we've received from the
		 * SGE.
		 */
		rmb();
		rsp_type = RSPD_TYPE(rc->type_gen);
		if (likely(rsp_type == RSP_TYPE_FLBUF)) {
			skb_frag_t *fp;
			struct pkt_gl gl;
			const struct rx_sw_desc *sdesc;
			u32 bufsz, frag;
			u32 len = be32_to_cpu(rc->pldbuflen_qid);

			/*
			 * If we get a "new buffer" message from the SGE we
			 * need to move on to the next Free List buffer.
			 */
			if (len & RSPD_NEWBUF) {
				/*
				 * We get one "new buffer" message when we
				 * first start up a queue so we need to ignore
				 * it when our offset into the buffer is 0.
				 */
				if (likely(rspq->offset > 0)) {
					free_rx_bufs(rspq->adapter, &rxq->fl,
						     1);
					rspq->offset = 0;
				}
				len = RSPD_LEN(len);
			}

			/*
			 * Gather packet fragments.
			 */
			for (frag = 0, fp = gl.frags; /**/; frag++, fp++) {
				BUG_ON(frag >= MAX_SKB_FRAGS);
				BUG_ON(rxq->fl.avail == 0);
				sdesc = &rxq->fl.sdesc[rxq->fl.cidx];
				bufsz = get_buf_size(sdesc);
				fp->page = sdesc->page;
				fp->page_offset = rspq->offset;
				fp->size = min(bufsz, len);
				len -= fp->size;
				if (!len)
					break;
				unmap_rx_buf(rspq->adapter, &rxq->fl);
			}
			gl.nfrags = frag+1;

			/*
			 * Last buffer remains mapped so explicitly make it
			 * coherent for CPU access and start preloading first
			 * cache line ...
			 */
			dma_sync_single_for_cpu(rspq->adapter->pdev_dev,
						get_buf_addr(sdesc),
						fp->size, DMA_FROM_DEVICE);
			gl.va = (page_address(gl.frags[0].page) +
				 gl.frags[0].page_offset);
			prefetch(gl.va);

			/*
			 * Hand the new ingress packet to the handler for
			 * this Response Queue.
			 */
			ret = rspq->handler(rspq, rspq->cur_desc, &gl);
			if (likely(ret == 0))
				rspq->offset += ALIGN(fp->size, FL_ALIGN);
			else
				restore_rx_bufs(&gl, &rxq->fl, frag);
		} else if (likely(rsp_type == RSP_TYPE_CPL)) {
			ret = rspq->handler(rspq, rspq->cur_desc, NULL);
		} else {
			WARN_ON(rsp_type > RSP_TYPE_CPL);
			ret = 0;
		}

		if (unlikely(ret)) {
			/*
			 * Couldn't process descriptor, back off for recovery.
			 * We use the SGE's last timer which has the longest
			 * interrupt coalescing value ...
			 */
			const int NOMEM_TIMER_IDX = SGE_NTIMERS-1;
			rspq->next_intr_params =
				QINTR_TIMER_IDX(NOMEM_TIMER_IDX);
			break;
		}

		rspq_next(rspq);
		budget_left--;
	}

	/*
	 * If this is a Response Queue with an associated Free List and
	 * at least two Egress Queue units available in the Free List
	 * for new buffer pointers, refill the Free List.
	 */
	if (rspq->offset >= 0 &&
	    rxq->fl.size - rxq->fl.avail >= 2*FL_PER_EQ_UNIT)
		__refill_fl(rspq->adapter, &rxq->fl);
	return budget - budget_left;
}

/**
 *	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.  This does not need any
 *	locking or protection from interrupts as data interrupts are off at
 *	this point and other adapter interrupts do not interfere (the latter
 *	in not a concern at all with MSI-X as non-data interrupts then have
 *	a separate handler).
 */
static int napi_rx_handler(struct napi_struct *napi, int budget)
{
	unsigned int intr_params;
	struct sge_rspq *rspq = container_of(napi, struct sge_rspq, napi);
	int work_done = process_responses(rspq, budget);

	if (likely(work_done < budget)) {
		napi_complete(napi);
		intr_params = rspq->next_intr_params;
		rspq->next_intr_params = rspq->intr_params;
	} else
		intr_params = QINTR_TIMER_IDX(SGE_TIMER_UPD_CIDX);

	t4_write_reg(rspq->adapter,
		     T4VF_SGE_BASE_ADDR + SGE_VF_GTS,
		     CIDXINC(work_done) |
		     INGRESSQID((u32)rspq->cntxt_id) |
		     SEINTARM(intr_params));
	return work_done;
}

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

	napi_schedule(&rspq->napi);
	return IRQ_HANDLED;
}

/*
 * Process the indirect interrupt entries in the interrupt queue and kick off
 * NAPI for each queue that has generated an entry.
 */
static unsigned int process_intrq(struct adapter *adapter)
{
	struct sge *s = &adapter->sge;
	struct sge_rspq *intrq = &s->intrq;
	unsigned int work_done;

	spin_lock(&adapter->sge.intrq_lock);
	for (work_done = 0; ; work_done++) {
		const struct rsp_ctrl *rc;
		unsigned int qid, iq_idx;
		struct sge_rspq *rspq;

		/*
		 * Grab the next response from the interrupt queue and bail
		 * out if it's not a new response.
		 */
		rc = (void *)intrq->cur_desc + (intrq->iqe_len - sizeof(*rc));
		if (!is_new_response(rc, intrq))
			break;

		/*
		 * If the response isn't a forwarded interrupt message issue a
		 * error and go on to the next response message.  This should
		 * never happen ...
		 */
		rmb();
		if (unlikely(RSPD_TYPE(rc->type_gen) != RSP_TYPE_INTR)) {
			dev_err(adapter->pdev_dev,
				"Unexpected INTRQ response type %d\n",
				RSPD_TYPE(rc->type_gen));
			continue;
		}

		/*
		 * Extract the Queue ID from the interrupt message and perform
		 * sanity checking to make sure it really refers to one of our
		 * Ingress Queues which is active and matches the queue's ID.
		 * None of these error conditions should ever happen so we may
		 * want to either make them fatal and/or conditionalized under
		 * DEBUG.
		 */
		qid = RSPD_QID(be32_to_cpu(rc->pldbuflen_qid));
		iq_idx = IQ_IDX(s, qid);
		if (unlikely(iq_idx >= MAX_INGQ)) {
			dev_err(adapter->pdev_dev,
				"Ingress QID %d out of range\n", qid);
			continue;
		}
		rspq = s->ingr_map[iq_idx];
		if (unlikely(rspq == NULL)) {
			dev_err(adapter->pdev_dev,
				"Ingress QID %d RSPQ=NULL\n", qid);
			continue;
		}
		if (unlikely(rspq->abs_id != qid)) {
			dev_err(adapter->pdev_dev,
				"Ingress QID %d refers to RSPQ %d\n",
				qid, rspq->abs_id);
			continue;
		}

		/*
		 * Schedule NAPI processing on the indicated Response Queue
		 * and move on to the next entry in the Forwarded Interrupt
		 * Queue.
		 */
		napi_schedule(&rspq->napi);
		rspq_next(intrq);
	}

	t4_write_reg(adapter, T4VF_SGE_BASE_ADDR + SGE_VF_GTS,
		     CIDXINC(work_done) |
		     INGRESSQID(intrq->cntxt_id) |
		     SEINTARM(intrq->intr_params));

	spin_unlock(&adapter->sge.intrq_lock);

	return work_done;
}

/*
 * The MSI interrupt handler handles data events from SGE response queues as
 * well as error and other async events as they all use the same MSI vector.
 */
irqreturn_t t4vf_intr_msi(int irq, void *cookie)
{
	struct adapter *adapter = cookie;

	process_intrq(adapter);
	return IRQ_HANDLED;
}

/**
 *	t4vf_intr_handler - select the top-level interrupt handler
 *	@adapter: the adapter
 *
 *	Selects the top-level interrupt handler based on the type of interrupts
 *	(MSI-X or MSI).
 */
irq_handler_t t4vf_intr_handler(struct adapter *adapter)
{
	BUG_ON((adapter->flags & (USING_MSIX|USING_MSI)) == 0);
	if (adapter->flags & USING_MSIX)
		return t4vf_sge_intr_msix;
	else
		return t4vf_intr_msi;
}

/**
 *	sge_rx_timer_cb - perform periodic maintenance of SGE RX queues
 *	@data: the adapter
 *
 *	Runs periodically from a timer to perform maintenance of SGE RX queues.
 *
 *	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 schedule NAPI to do
 *	the actual refill.
 */
static void sge_rx_timer_cb(unsigned long data)
{
	struct adapter *adapter = (struct adapter *)data;
	struct sge *s = &adapter->sge;
	unsigned int i;

	/*
	 * Scan the "Starving Free Lists" flag array looking for any Free
	 * Lists in need of more free buffers.  If we find one and it's not
	 * being actively polled, then bump its "starving" counter and attempt
	 * to refill it.  If we're successful in adding enough buffers to push
	 * the Free List over the starving threshold, then we can clear its
	 * "starving" status.
	 */
	for (i = 0; i < ARRAY_SIZE(s->starving_fl); i++) {
		unsigned long m;

		for (m = s->starving_fl[i]; m; m &= m - 1) {
			unsigned int id = __ffs(m) + i * BITS_PER_LONG;
			struct sge_fl *fl = s->egr_map[id];

			clear_bit(id, s->starving_fl);
			smp_mb__after_clear_bit();

			/*
			 * Since we are accessing fl without a lock there's a
			 * small probability of a false positive where we
			 * schedule napi but the FL is no longer starving.
			 * No biggie.
			 */
			if (fl_starving(fl)) {
				struct sge_eth_rxq *rxq;

				rxq = container_of(fl, struct sge_eth_rxq, fl);
				if (napi_reschedule(&rxq->rspq.napi))
					fl->starving++;
				else
					set_bit(id, s->starving_fl);
			}
		}
	}

	/*
	 * Reschedule the next scan for starving Free Lists ...
	 */
	mod_timer(&s->rx_timer, jiffies + RX_QCHECK_PERIOD);
}

/**
 *	sge_tx_timer_cb - perform periodic maintenance of SGE Tx queues
 *	@data: the adapter
 *
 *	Runs periodically from a timer to perform maintenance of SGE TX queues.
 *
 *	b) Reclaims completed Tx packets for the Ethernet queues.  Normally
 *	packets are cleaned up by new Tx packets, this timer cleans up packets
 *	when no new packets are being submitted.  This is essential for pktgen,
 *	at least.
 */
static void sge_tx_timer_cb(unsigned long data)
{
	struct adapter *adapter = (struct adapter *)data;
	struct sge *s = &adapter->sge;
	unsigned int i, budget;

	budget = MAX_TIMER_TX_RECLAIM;
	i = s->ethtxq_rover;
	do {
		struct sge_eth_txq *txq = &s->ethtxq[i];

		if (reclaimable(&txq->q) && __netif_tx_trylock(txq->txq)) {
			int avail = reclaimable(&txq->q);

			if (avail > budget)
				avail = budget;

			free_tx_desc(adapter, &txq->q, avail, true);
			txq->q.in_use -= avail;
			__netif_tx_unlock(txq->txq);

			budget -= avail;
			if (!budget)
				break;
		}

		i++;
		if (i >= s->ethqsets)
			i = 0;
	} while (i != s->ethtxq_rover);
	s->ethtxq_rover = i;

	/*
	 * If we found too many reclaimable packets schedule a timer in the
	 * near future to continue where we left off.  Otherwise the next timer
	 * will be at its normal interval.
	 */
	mod_timer(&s->tx_timer, jiffies + (budget ? TX_QCHECK_PERIOD : 2));
}

/**
 *	t4vf_sge_alloc_rxq - allocate an SGE RX Queue
 *	@adapter: the adapter
 *	@rspq: pointer to to the new rxq's Response Queue to be filled in
 *	@iqasynch: if 0, a normal rspq; if 1, an asynchronous event queue
 *	@dev: the network device associated with the new rspq
 *	@intr_dest: MSI-X vector index (overriden in MSI mode)
 *	@fl: pointer to the new rxq's Free List to be filled in
 *	@hnd: the interrupt handler to invoke for the rspq
 */
int t4vf_sge_alloc_rxq(struct adapter *adapter, struct sge_rspq *rspq,
		       bool iqasynch, struct net_device *dev,
		       int intr_dest,
		       struct sge_fl *fl, rspq_handler_t hnd)
{
	struct port_info *pi = netdev_priv(dev);
	struct fw_iq_cmd cmd, rpl;
	int ret, iqandst, flsz = 0;

	/*
	 * If we're using MSI interrupts and we're not initializing the
	 * Forwarded Interrupt Queue itself, then set up this queue for
	 * indirect interrupts to the Forwarded Interrupt Queue.  Obviously
	 * the Forwarded Interrupt Queue must be set up before any other
	 * ingress queue ...
	 */
	if ((adapter->flags & USING_MSI) && rspq != &adapter->sge.intrq) {
		iqandst = SGE_INTRDST_IQ;
		intr_dest = adapter->sge.intrq.abs_id;
	} else
		iqandst = SGE_INTRDST_PCI;

	/*
	 * Allocate the hardware ring for the Response Queue.  The size needs
	 * to be a multiple of 16 which includes the mandatory status entry
	 * (regardless of whether the Status Page capabilities are enabled or
	 * not).
	 */
	rspq->size = roundup(rspq->size, 16);
	rspq->desc = alloc_ring(adapter->pdev_dev, rspq->size, rspq->iqe_len,
				0, &rspq->phys_addr, NULL, 0);
	if (!rspq->desc)
		return -ENOMEM;

	/*
	 * Fill in the Ingress Queue Command.  Note: Ideally this code would
	 * be in t4vf_hw.c but there are so many parameters and dependencies
	 * on our Linux SGE state that we would end up having to pass tons of
	 * parameters.  We'll have to think about how this might be migrated
	 * into OS-independent common code ...
	 */
	memset(&cmd, 0, sizeof(cmd));
	cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_IQ_CMD) |
				    FW_CMD_REQUEST |
				    FW_CMD_WRITE |
				    FW_CMD_EXEC);
	cmd.alloc_to_len16 = cpu_to_be32(FW_IQ_CMD_ALLOC |
					 FW_IQ_CMD_IQSTART(1) |
					 FW_LEN16(cmd));
	cmd.type_to_iqandstindex =
		cpu_to_be32(FW_IQ_CMD_TYPE(FW_IQ_TYPE_FL_INT_CAP) |
			    FW_IQ_CMD_IQASYNCH(iqasynch) |
			    FW_IQ_CMD_VIID(pi->viid) |
			    FW_IQ_CMD_IQANDST(iqandst) |
			    FW_IQ_CMD_IQANUS(1) |
			    FW_IQ_CMD_IQANUD(SGE_UPDATEDEL_INTR) |
			    FW_IQ_CMD_IQANDSTINDEX(intr_dest));
	cmd.iqdroprss_to_iqesize =
		cpu_to_be16(FW_IQ_CMD_IQPCIECH(pi->port_id) |
			    FW_IQ_CMD_IQGTSMODE |
			    FW_IQ_CMD_IQINTCNTTHRESH(rspq->pktcnt_idx) |
			    FW_IQ_CMD_IQESIZE(ilog2(rspq->iqe_len) - 4));
	cmd.iqsize = cpu_to_be16(rspq->size);
	cmd.iqaddr = cpu_to_be64(rspq->phys_addr);

	if (fl) {
		/*
		 * Allocate the ring for the hardware free list (with space
		 * for its status page) along with the associated software
		 * descriptor ring.  The free list size needs to be a multiple
		 * of the Egress Queue Unit.
		 */
		fl->size = roundup(fl->size, FL_PER_EQ_UNIT);
		fl->desc = alloc_ring(adapter->pdev_dev, fl->size,
				      sizeof(__be64), sizeof(struct rx_sw_desc),
				      &fl->addr, &fl->sdesc, STAT_LEN);
		if (!fl->desc) {
			ret = -ENOMEM;
			goto err;
		}

		/*
		 * Calculate the size of the hardware free list ring plus
		 * status page (which the SGE will place at the end of the
		 * free list ring) in Egress Queue Units.
		 */
		flsz = (fl->size / FL_PER_EQ_UNIT +
			STAT_LEN / EQ_UNIT);

		/*
		 * Fill in all the relevant firmware Ingress Queue Command
		 * fields for the free list.
		 */
		cmd.iqns_to_fl0congen =
			cpu_to_be32(
				FW_IQ_CMD_FL0HOSTFCMODE(SGE_HOSTFCMODE_NONE) |
				FW_IQ_CMD_FL0PACKEN |
				FW_IQ_CMD_FL0PADEN);
		cmd.fl0dcaen_to_fl0cidxfthresh =
			cpu_to_be16(
				FW_IQ_CMD_FL0FBMIN(SGE_FETCHBURSTMIN_64B) |
				FW_IQ_CMD_FL0FBMAX(SGE_FETCHBURSTMAX_512B));
		cmd.fl0size = cpu_to_be16(flsz);
		cmd.fl0addr = cpu_to_be64(fl->addr);
	}

	/*
	 * Issue the firmware Ingress Queue Command and extract the results if
	 * it completes successfully.
	 */
	ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
	if (ret)
		goto err;

	netif_napi_add(dev, &rspq->napi, napi_rx_handler, 64);
	rspq->cur_desc = rspq->desc;
	rspq->cidx = 0;
	rspq->gen = 1;
	rspq->next_intr_params = rspq->intr_params;
	rspq->cntxt_id = be16_to_cpu(rpl.iqid);
	rspq->abs_id = be16_to_cpu(rpl.physiqid);
	rspq->size--;			/* subtract status entry */
	rspq->adapter = adapter;
	rspq->netdev = dev;
	rspq->handler = hnd;

	/* set offset to -1 to distinguish ingress queues without FL */
	rspq->offset = fl ? 0 : -1;

	if (fl) {
		fl->cntxt_id = be16_to_cpu(rpl.fl0id);
		fl->avail = 0;
		fl->pend_cred = 0;
		fl->pidx = 0;
		fl->cidx = 0;
		fl->alloc_failed = 0;
		fl->large_alloc_failed = 0;
		fl->starving = 0;
		refill_fl(adapter, fl, fl_cap(fl), GFP_KERNEL);
	}

	return 0;

err:
	/*
	 * An error occurred.  Clean up our partial allocation state and
	 * return the error.
	 */
	if (rspq->desc) {
		dma_free_coherent(adapter->pdev_dev, rspq->size * rspq->iqe_len,
				  rspq->desc, rspq->phys_addr);
		rspq->desc = NULL;
	}
	if (fl && fl->desc) {
		kfree(fl->sdesc);
		fl->sdesc = NULL;
		dma_free_coherent(adapter->pdev_dev, flsz * EQ_UNIT,
				  fl->desc, fl->addr);
		fl->desc = NULL;
	}
	return ret;
}

/**
 *	t4vf_sge_alloc_eth_txq - allocate an SGE Ethernet TX Queue
 *	@adapter: the adapter
 *	@txq: pointer to the new txq to be filled in
 *	@devq: the network TX queue associated with the new txq
 *	@iqid: the relative ingress queue ID to which events relating to
 *		the new txq should be directed
 */
int t4vf_sge_alloc_eth_txq(struct adapter *adapter, struct sge_eth_txq *txq,
			   struct net_device *dev, struct netdev_queue *devq,
			   unsigned int iqid)
{
	int ret, nentries;
	struct fw_eq_eth_cmd cmd, rpl;
	struct port_info *pi = netdev_priv(dev);

	/*
	 * Calculate the size of the hardware TX Queue (including the
	 * status age on the end) in units of TX Descriptors.
	 */
	nentries = txq->q.size + STAT_LEN / sizeof(struct tx_desc);

	/*
	 * Allocate the hardware ring for the TX ring (with space for its
	 * status page) along with the associated software descriptor ring.
	 */
	txq->q.desc = alloc_ring(adapter->pdev_dev, txq->q.size,
				 sizeof(struct tx_desc),
				 sizeof(struct tx_sw_desc),
				 &txq->q.phys_addr, &txq->q.sdesc, STAT_LEN);
	if (!txq->q.desc)
		return -ENOMEM;

	/*
	 * Fill in the Egress Queue Command.  Note: As with the direct use of
	 * the firmware Ingress Queue COmmand above in our RXQ allocation
	 * routine, ideally, this code would be in t4vf_hw.c.  Again, we'll
	 * have to see if there's some reasonable way to parameterize it
	 * into the common code ...
	 */
	memset(&cmd, 0, sizeof(cmd));
	cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_EQ_ETH_CMD) |
				    FW_CMD_REQUEST |
				    FW_CMD_WRITE |
				    FW_CMD_EXEC);
	cmd.alloc_to_len16 = cpu_to_be32(FW_EQ_ETH_CMD_ALLOC |
					 FW_EQ_ETH_CMD_EQSTART |
					 FW_LEN16(cmd));
	cmd.viid_pkd = cpu_to_be32(FW_EQ_ETH_CMD_VIID(pi->viid));
	cmd.fetchszm_to_iqid =
		cpu_to_be32(FW_EQ_ETH_CMD_HOSTFCMODE(SGE_HOSTFCMODE_STPG) |
			    FW_EQ_ETH_CMD_PCIECHN(pi->port_id) |
			    FW_EQ_ETH_CMD_IQID(iqid));
	cmd.dcaen_to_eqsize =
		cpu_to_be32(FW_EQ_ETH_CMD_FBMIN(SGE_FETCHBURSTMIN_64B) |
			    FW_EQ_ETH_CMD_FBMAX(SGE_FETCHBURSTMAX_512B) |
			    FW_EQ_ETH_CMD_CIDXFTHRESH(SGE_CIDXFLUSHTHRESH_32) |
			    FW_EQ_ETH_CMD_EQSIZE(nentries));
	cmd.eqaddr = cpu_to_be64(txq->q.phys_addr);

	/*
	 * Issue the firmware Egress Queue Command and extract the results if
	 * it completes successfully.
	 */
	ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
	if (ret) {
		/*
		 * The girmware Ingress Queue Command failed for some reason.
		 * Free up our partial allocation state and return the error.
		 */
		kfree(txq->q.sdesc);
		txq->q.sdesc = NULL;
		dma_free_coherent(adapter->pdev_dev,
				  nentries * sizeof(struct tx_desc),
				  txq->q.desc, txq->q.phys_addr);
		txq->q.desc = NULL;
		return ret;
	}

	txq->q.in_use = 0;
	txq->q.cidx = 0;
	txq->q.pidx = 0;
	txq->q.stat = (void *)&txq->q.desc[txq->q.size];
	txq->q.cntxt_id = FW_EQ_ETH_CMD_EQID_GET(be32_to_cpu(rpl.eqid_pkd));
	txq->q.abs_id =
		FW_EQ_ETH_CMD_PHYSEQID_GET(be32_to_cpu(rpl.physeqid_pkd));
	txq->txq = devq;
	txq->tso = 0;
	txq->tx_cso = 0;
	txq->vlan_ins = 0;
	txq->q.stops = 0;
	txq->q.restarts = 0;
	txq->mapping_err = 0;
	return 0;
}

/*
 * Free the DMA map resources associated with a TX queue.
 */
static void free_txq(struct adapter *adapter, struct sge_txq *tq)
{
	dma_free_coherent(adapter->pdev_dev,
			  tq->size * sizeof(*tq->desc) + STAT_LEN,
			  tq->desc, tq->phys_addr);
	tq->cntxt_id = 0;
	tq->sdesc = NULL;
	tq->desc = NULL;
}

/*
 * Free the resources associated with a response queue (possibly including a
 * free list).
 */
static void free_rspq_fl(struct adapter *adapter, struct sge_rspq *rspq,
			 struct sge_fl *fl)
{
	unsigned int flid = fl ? fl->cntxt_id : 0xffff;

	t4vf_iq_free(adapter, FW_IQ_TYPE_FL_INT_CAP,
		     rspq->cntxt_id, flid, 0xffff);
	dma_free_coherent(adapter->pdev_dev, (rspq->size + 1) * rspq->iqe_len,
			  rspq->desc, rspq->phys_addr);
	netif_napi_del(&rspq->napi);
	rspq->netdev = NULL;
	rspq->cntxt_id = 0;
	rspq->abs_id = 0;
	rspq->desc = NULL;

	if (fl) {
		free_rx_bufs(adapter, fl, fl->avail);
		dma_free_coherent(adapter->pdev_dev,
				  fl->size * sizeof(*fl->desc) + STAT_LEN,
				  fl->desc, fl->addr);
		kfree(fl->sdesc);
		fl->sdesc = NULL;
		fl->cntxt_id = 0;
		fl->desc = NULL;
	}
}

/**
 *	t4vf_free_sge_resources - free SGE resources
 *	@adapter: the adapter
 *
 *	Frees resources used by the SGE queue sets.
 */
void t4vf_free_sge_resources(struct adapter *adapter)
{
	struct sge *s = &adapter->sge;
	struct sge_eth_rxq *rxq = s->ethrxq;
	struct sge_eth_txq *txq = s->ethtxq;
	struct sge_rspq *evtq = &s->fw_evtq;
	struct sge_rspq *intrq = &s->intrq;
	int qs;

	for (qs = 0; qs < adapter->sge.ethqsets; qs++) {
		if (rxq->rspq.desc)
			free_rspq_fl(adapter, &rxq->rspq, &rxq->fl);
		if (txq->q.desc) {
			t4vf_eth_eq_free(adapter, txq->q.cntxt_id);
			free_tx_desc(adapter, &txq->q, txq->q.in_use, true);
			kfree(txq->q.sdesc);
			free_txq(adapter, &txq->q);
		}
	}
	if (evtq->desc)
		free_rspq_fl(adapter, evtq, NULL);
	if (intrq->desc)
		free_rspq_fl(adapter, intrq, NULL);
}

/**
 *	t4vf_sge_start - enable SGE operation
 *	@adapter: the adapter
 *
 *	Start tasklets and timers associated with the DMA engine.
 */
void t4vf_sge_start(struct adapter *adapter)
{
	adapter->sge.ethtxq_rover = 0;
	mod_timer(&adapter->sge.rx_timer, jiffies + RX_QCHECK_PERIOD);
	mod_timer(&adapter->sge.tx_timer, jiffies + TX_QCHECK_PERIOD);
}

/**
 *	t4vf_sge_stop - disable SGE operation
 *	@adapter: the adapter
 *
 *	Stop tasklets and timers associated with the DMA engine.  Note that
 *	this is effective only if measures have been taken to disable any HW
 *	events that may restart them.
 */
void t4vf_sge_stop(struct adapter *adapter)
{
	struct sge *s = &adapter->sge;

	if (s->rx_timer.function)
		del_timer_sync(&s->rx_timer);
	if (s->tx_timer.function)
		del_timer_sync(&s->tx_timer);
}

/**
 *	t4vf_sge_init - initialize SGE
 *	@adapter: the adapter
 *
 *	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.
 */
int t4vf_sge_init(struct adapter *adapter)
{
	struct sge_params *sge_params = &adapter->params.sge;
	u32 fl0 = sge_params->sge_fl_buffer_size[0];
	u32 fl1 = sge_params->sge_fl_buffer_size[1];
	struct sge *s = &adapter->sge;

	/*
	 * Start by vetting the basic SGE parameters which have been set up by
	 * the Physical Function Driver.  Ideally we should be able to deal
	 * with _any_ configuration.  Practice is different ...
	 */
	if (fl0 != PAGE_SIZE || (fl1 != 0 && fl1 <= fl0)) {
		dev_err(adapter->pdev_dev, "bad SGE FL buffer sizes [%d, %d]\n",
			fl0, fl1);
		return -EINVAL;
	}
	if ((sge_params->sge_control & RXPKTCPLMODE) == 0) {
		dev_err(adapter->pdev_dev, "bad SGE CPL MODE\n");
		return -EINVAL;
	}

	/*
	 * Now translate the adapter parameters into our internal forms.
	 */
	if (fl1)
		FL_PG_ORDER = ilog2(fl1) - PAGE_SHIFT;
	STAT_LEN = ((sge_params->sge_control & EGRSTATUSPAGESIZE) ? 128 : 64);
	PKTSHIFT = PKTSHIFT_GET(sge_params->sge_control);
	FL_ALIGN = 1 << (INGPADBOUNDARY_GET(sge_params->sge_control) +
			 SGE_INGPADBOUNDARY_SHIFT);

	/*
	 * Set up tasklet timers.
	 */
	setup_timer(&s->rx_timer, sge_rx_timer_cb, (unsigned long)adapter);
	setup_timer(&s->tx_timer, sge_tx_timer_cb, (unsigned long)adapter);

	/*
	 * Initialize Forwarded Interrupt Queue lock.
	 */
	spin_lock_init(&s->intrq_lock);

	return 0;
}
