/*
 * cxgb3i_offload.c: Chelsio S3xx iscsi offloaded tcp connection management
 *
 * Copyright (C) 2003-2008 Chelsio Communications.  All rights reserved.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the LICENSE file included in this
 * release for licensing terms and conditions.
 *
 * Written by:	Dimitris Michailidis (dm@chelsio.com)
 *		Karen Xie (kxie@chelsio.com)
 */

#include <linux/if_vlan.h>
#include <linux/version.h>

#include "cxgb3_defs.h"
#include "cxgb3_ctl_defs.h"
#include "firmware_exports.h"
#include "cxgb3i_offload.h"
#include "cxgb3i_pdu.h"
#include "cxgb3i_ddp.h"

#ifdef __DEBUG_C3CN_CONN__
#define c3cn_conn_debug		cxgb3i_log_debug
#else
#define c3cn_conn_debug(fmt...)
#endif

#ifdef __DEBUG_C3CN_TX__
#define c3cn_tx_debug		cxgb3i_log_debug
#else
#define c3cn_tx_debug(fmt...)
#endif

#ifdef __DEBUG_C3CN_RX__
#define c3cn_rx_debug		cxgb3i_log_debug
#else
#define c3cn_rx_debug(fmt...)
#endif

/*
 * module parameters releated to offloaded iscsi connection
 */
static int cxgb3_rcv_win = 256 * 1024;
module_param(cxgb3_rcv_win, int, 0644);
MODULE_PARM_DESC(cxgb3_rcv_win, "TCP receive window in bytes (default=256KB)");

static int cxgb3_snd_win = 128 * 1024;
module_param(cxgb3_snd_win, int, 0644);
MODULE_PARM_DESC(cxgb3_snd_win, "TCP send window in bytes (default=128KB)");

static int cxgb3_rx_credit_thres = 10 * 1024;
module_param(cxgb3_rx_credit_thres, int, 0644);
MODULE_PARM_DESC(rx_credit_thres,
		 "RX credits return threshold in bytes (default=10KB)");

static unsigned int cxgb3_max_connect = 8 * 1024;
module_param(cxgb3_max_connect, uint, 0644);
MODULE_PARM_DESC(cxgb3_max_connect, "Max. # of connections (default=8092)");

static unsigned int cxgb3_sport_base = 20000;
module_param(cxgb3_sport_base, uint, 0644);
MODULE_PARM_DESC(cxgb3_sport_base, "starting port number (default=20000)");

/*
 * cxgb3i tcp connection data(per adapter) list
 */
static LIST_HEAD(cdata_list);
static DEFINE_RWLOCK(cdata_rwlock);

static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion);
static void c3cn_release_offload_resources(struct s3_conn *c3cn);

/*
 * iscsi source port management
 *
 * Find a free source port in the port allocation map. We use a very simple
 * rotor scheme to look for the next free port.
 *
 * If a source port has been specified make sure that it doesn't collide with
 * our normal source port allocation map.  If it's outside the range of our
 * allocation/deallocation scheme just let them use it.
 *
 * If the source port is outside our allocation range, the caller is
 * responsible for keeping track of their port usage.
 */
static int c3cn_get_port(struct s3_conn *c3cn, struct cxgb3i_sdev_data *cdata)
{
	unsigned int start;
	int idx;

	if (!cdata)
		goto error_out;

	if (c3cn->saddr.sin_port) {
		cxgb3i_log_error("connect, sin_port NON-ZERO %u.\n",
				 c3cn->saddr.sin_port);
		return -EADDRINUSE;
	}

	spin_lock_bh(&cdata->lock);
	start = idx = cdata->sport_next;
	do {
		if (++idx >= cxgb3_max_connect)
			idx = 0;
		if (!cdata->sport_conn[idx]) {
			c3cn->saddr.sin_port = htons(cxgb3_sport_base + idx);
			cdata->sport_next = idx;
			cdata->sport_conn[idx] = c3cn;
			spin_unlock_bh(&cdata->lock);

			c3cn_conn_debug("%s reserve port %u.\n",
					cdata->cdev->name,
					cxgb3_sport_base + idx);
			return 0;
		}
	} while (idx != start);
	spin_unlock_bh(&cdata->lock);

error_out:
	return -EADDRNOTAVAIL;
}

static void c3cn_put_port(struct s3_conn *c3cn)
{
	if (!c3cn->cdev)
		return;

	if (c3cn->saddr.sin_port) {
		struct cxgb3i_sdev_data *cdata = CXGB3_SDEV_DATA(c3cn->cdev);
		int idx = ntohs(c3cn->saddr.sin_port) - cxgb3_sport_base;

		c3cn->saddr.sin_port = 0;
		if (idx < 0 || idx >= cxgb3_max_connect)
			return;
		spin_lock_bh(&cdata->lock);
		cdata->sport_conn[idx] = NULL;
		spin_unlock_bh(&cdata->lock);
		c3cn_conn_debug("%s, release port %u.\n",
				cdata->cdev->name, cxgb3_sport_base + idx);
	}
}

static inline void c3cn_set_flag(struct s3_conn *c3cn, enum c3cn_flags flag)
{
	__set_bit(flag, &c3cn->flags);
	c3cn_conn_debug("c3cn 0x%p, set %d, s %u, f 0x%lx.\n",
			c3cn, flag, c3cn->state, c3cn->flags);
}

static inline void c3cn_clear_flag(struct s3_conn *c3cn, enum c3cn_flags flag)
{
	__clear_bit(flag, &c3cn->flags);
	c3cn_conn_debug("c3cn 0x%p, clear %d, s %u, f 0x%lx.\n",
			c3cn, flag, c3cn->state, c3cn->flags);
}

static inline int c3cn_flag(struct s3_conn *c3cn, enum c3cn_flags flag)
{
	if (c3cn == NULL)
		return 0;
	return test_bit(flag, &c3cn->flags);
}

static void c3cn_set_state(struct s3_conn *c3cn, int state)
{
	c3cn_conn_debug("c3cn 0x%p state -> %u.\n", c3cn, state);
	c3cn->state = state;
}

static inline void c3cn_hold(struct s3_conn *c3cn)
{
	atomic_inc(&c3cn->refcnt);
}

static inline void c3cn_put(struct s3_conn *c3cn)
{
	if (atomic_dec_and_test(&c3cn->refcnt)) {
		c3cn_conn_debug("free c3cn 0x%p, s %u, f 0x%lx.\n",
				c3cn, c3cn->state, c3cn->flags);
		kfree(c3cn);
	}
}

static void c3cn_closed(struct s3_conn *c3cn)
{
	c3cn_conn_debug("c3cn 0x%p, state %u, flag 0x%lx.\n",
			 c3cn, c3cn->state, c3cn->flags);

	c3cn_put_port(c3cn);
	c3cn_release_offload_resources(c3cn);
	c3cn_set_state(c3cn, C3CN_STATE_CLOSED);
	cxgb3i_conn_closing(c3cn);
}

/*
 * CPL (Chelsio Protocol Language) defines a message passing interface between
 * the host driver and T3 asic.
 * The section below implments CPLs that related to iscsi tcp connection
 * open/close/abort and data send/receive.
 */

/*
 * CPL connection active open request: host ->
 */
static unsigned int find_best_mtu(const struct t3c_data *d, unsigned short mtu)
{
	int i = 0;

	while (i < d->nmtus - 1 && d->mtus[i + 1] <= mtu)
		++i;
	return i;
}

static unsigned int select_mss(struct s3_conn *c3cn, unsigned int pmtu)
{
	unsigned int idx;
	struct dst_entry *dst = c3cn->dst_cache;
	struct t3cdev *cdev = c3cn->cdev;
	const struct t3c_data *td = T3C_DATA(cdev);
	u16 advmss = dst_metric(dst, RTAX_ADVMSS);

	if (advmss > pmtu - 40)
		advmss = pmtu - 40;
	if (advmss < td->mtus[0] - 40)
		advmss = td->mtus[0] - 40;
	idx = find_best_mtu(td, advmss + 40);
	return idx;
}

static inline int compute_wscale(int win)
{
	int wscale = 0;
	while (wscale < 14 && (65535<<wscale) < win)
		wscale++;
	return wscale;
}

static inline unsigned int calc_opt0h(struct s3_conn *c3cn)
{
	int wscale = compute_wscale(cxgb3_rcv_win);
	return  V_KEEP_ALIVE(1) |
		F_TCAM_BYPASS |
		V_WND_SCALE(wscale) |
		V_MSS_IDX(c3cn->mss_idx);
}

static inline unsigned int calc_opt0l(struct s3_conn *c3cn)
{
	return  V_ULP_MODE(ULP_MODE_ISCSI) |
		V_RCV_BUFSIZ(cxgb3_rcv_win>>10);
}

static void make_act_open_req(struct s3_conn *c3cn, struct sk_buff *skb,
			      unsigned int atid, const struct l2t_entry *e)
{
	struct cpl_act_open_req *req;

	c3cn_conn_debug("c3cn 0x%p, atid 0x%x.\n", c3cn, atid);

	skb->priority = CPL_PRIORITY_SETUP;
	req = (struct cpl_act_open_req *)__skb_put(skb, sizeof(*req));
	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ACT_OPEN_REQ, atid));
	req->local_port = c3cn->saddr.sin_port;
	req->peer_port = c3cn->daddr.sin_port;
	req->local_ip = c3cn->saddr.sin_addr.s_addr;
	req->peer_ip = c3cn->daddr.sin_addr.s_addr;
	req->opt0h = htonl(calc_opt0h(c3cn) | V_L2T_IDX(e->idx) |
			   V_TX_CHANNEL(e->smt_idx));
	req->opt0l = htonl(calc_opt0l(c3cn));
	req->params = 0;
}

static void fail_act_open(struct s3_conn *c3cn, int errno)
{
	c3cn_conn_debug("c3cn 0x%p, state %u, flag 0x%lx.\n",
			c3cn, c3cn->state, c3cn->flags);
	c3cn->err = errno;
	c3cn_closed(c3cn);
}

static void act_open_req_arp_failure(struct t3cdev *dev, struct sk_buff *skb)
{
	struct s3_conn *c3cn = (struct s3_conn *)skb->sk;

	c3cn_conn_debug("c3cn 0x%p, state %u.\n", c3cn, c3cn->state);

	c3cn_hold(c3cn);
	spin_lock_bh(&c3cn->lock);
	if (c3cn->state == C3CN_STATE_CONNECTING)
		fail_act_open(c3cn, EHOSTUNREACH);
	spin_unlock_bh(&c3cn->lock);
	c3cn_put(c3cn);
	__kfree_skb(skb);
}

/*
 * CPL connection close request: host ->
 *
 * Close a connection by sending a CPL_CLOSE_CON_REQ message and queue it to
 * the write queue (i.e., after any unsent txt data).
 */
static void skb_entail(struct s3_conn *c3cn, struct sk_buff *skb,
		       int flags)
{
	skb_tcp_seq(skb) = c3cn->write_seq;
	skb_flags(skb) = flags;
	__skb_queue_tail(&c3cn->write_queue, skb);
}

static void send_close_req(struct s3_conn *c3cn)
{
	struct sk_buff *skb = c3cn->cpl_close;
	struct cpl_close_con_req *req = (struct cpl_close_con_req *)skb->head;
	unsigned int tid = c3cn->tid;

	c3cn_conn_debug("c3cn 0x%p, state 0x%x, flag 0x%lx.\n",
			c3cn, c3cn->state, c3cn->flags);

	c3cn->cpl_close = NULL;

	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_CLOSE_CON));
	req->wr.wr_lo = htonl(V_WR_TID(tid));
	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_CON_REQ, tid));
	req->rsvd = htonl(c3cn->write_seq);

	skb_entail(c3cn, skb, C3CB_FLAG_NO_APPEND);
	if (c3cn->state != C3CN_STATE_CONNECTING)
		c3cn_push_tx_frames(c3cn, 1);
}

/*
 * CPL connection abort request: host ->
 *
 * Send an ABORT_REQ message. Makes sure we do not send multiple ABORT_REQs
 * for the same connection and also that we do not try to send a message
 * after the connection has closed.
 */
static void abort_arp_failure(struct t3cdev *cdev, struct sk_buff *skb)
{
	struct cpl_abort_req *req = cplhdr(skb);

	c3cn_conn_debug("tdev 0x%p.\n", cdev);

	req->cmd = CPL_ABORT_NO_RST;
	cxgb3_ofld_send(cdev, skb);
}

static inline void c3cn_purge_write_queue(struct s3_conn *c3cn)
{
	struct sk_buff *skb;

	while ((skb = __skb_dequeue(&c3cn->write_queue)))
		__kfree_skb(skb);
}

static void send_abort_req(struct s3_conn *c3cn)
{
	struct sk_buff *skb = c3cn->cpl_abort_req;
	struct cpl_abort_req *req;
	unsigned int tid = c3cn->tid;

	if (unlikely(c3cn->state == C3CN_STATE_ABORTING) || !skb ||
		     !c3cn->cdev)
		return;

	c3cn_set_state(c3cn, C3CN_STATE_ABORTING);

	c3cn_conn_debug("c3cn 0x%p, flag ABORT_RPL + ABORT_SHUT.\n", c3cn);

	c3cn_set_flag(c3cn, C3CN_ABORT_RPL_PENDING);

	/* Purge the send queue so we don't send anything after an abort. */
	c3cn_purge_write_queue(c3cn);

	c3cn->cpl_abort_req = NULL;
	req = (struct cpl_abort_req *)skb->head;

	skb->priority = CPL_PRIORITY_DATA;
	set_arp_failure_handler(skb, abort_arp_failure);

	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_HOST_ABORT_CON_REQ));
	req->wr.wr_lo = htonl(V_WR_TID(tid));
	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ABORT_REQ, tid));
	req->rsvd0 = htonl(c3cn->snd_nxt);
	req->rsvd1 = !c3cn_flag(c3cn, C3CN_TX_DATA_SENT);
	req->cmd = CPL_ABORT_SEND_RST;

	l2t_send(c3cn->cdev, skb, c3cn->l2t);
}

/*
 * CPL connection abort reply: host ->
 *
 * Send an ABORT_RPL message in response of the ABORT_REQ received.
 */
static void send_abort_rpl(struct s3_conn *c3cn, int rst_status)
{
	struct sk_buff *skb = c3cn->cpl_abort_rpl;
	struct cpl_abort_rpl *rpl = (struct cpl_abort_rpl *)skb->head;

	c3cn->cpl_abort_rpl = NULL;

	skb->priority = CPL_PRIORITY_DATA;
	rpl->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_HOST_ABORT_CON_RPL));
	rpl->wr.wr_lo = htonl(V_WR_TID(c3cn->tid));
	OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, c3cn->tid));
	rpl->cmd = rst_status;

	cxgb3_ofld_send(c3cn->cdev, skb);
}

/*
 * CPL connection rx data ack: host ->
 * Send RX credits through an RX_DATA_ACK CPL message. Returns the number of
 * credits sent.
 */
static u32 send_rx_credits(struct s3_conn *c3cn, u32 credits, u32 dack)
{
	struct sk_buff *skb;
	struct cpl_rx_data_ack *req;

	skb = alloc_skb(sizeof(*req), GFP_ATOMIC);
	if (!skb)
		return 0;

	req = (struct cpl_rx_data_ack *)__skb_put(skb, sizeof(*req));
	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, c3cn->tid));
	req->credit_dack = htonl(dack | V_RX_CREDITS(credits));
	skb->priority = CPL_PRIORITY_ACK;
	cxgb3_ofld_send(c3cn->cdev, skb);
	return credits;
}

/*
 * CPL connection tx data: host ->
 *
 * Send iscsi PDU via TX_DATA CPL message. Returns the number of
 * credits sent.
 * Each TX_DATA consumes work request credit (wrs), so we need to keep track of
 * how many we've used so far and how many are pending (i.e., yet ack'ed by T3).
 */

/*
 * For ULP connections HW may inserts digest bytes into the pdu. Those digest
 * bytes are not sent by the host but are part of the TCP payload and therefore
 * consume TCP sequence space.
 */
static const unsigned int cxgb3_ulp_extra_len[] = { 0, 4, 4, 8 };
static inline unsigned int ulp_extra_len(const struct sk_buff *skb)
{
	return cxgb3_ulp_extra_len[skb_ulp_mode(skb) & 3];
}

static unsigned int wrlen __read_mostly;

/*
 * The number of WRs needed for an skb depends on the number of fragments
 * in the skb and whether it has any payload in its main body.  This maps the
 * length of the gather list represented by an skb into the # of necessary WRs.
 * The extra two fragments are for iscsi bhs and payload padding.
 */
#define SKB_WR_LIST_SIZE	(MAX_SKB_FRAGS + 2)
static unsigned int skb_wrs[SKB_WR_LIST_SIZE] __read_mostly;

static void s3_init_wr_tab(unsigned int wr_len)
{
	int i;

	if (skb_wrs[1])		/* already initialized */
		return;

	for (i = 1; i < SKB_WR_LIST_SIZE; i++) {
		int sgl_len = (3 * i) / 2 + (i & 1);

		sgl_len += 3;
		skb_wrs[i] = (sgl_len <= wr_len
			      ? 1 : 1 + (sgl_len - 2) / (wr_len - 1));
	}

	wrlen = wr_len * 8;
}

static inline void reset_wr_list(struct s3_conn *c3cn)
{
	c3cn->wr_pending_head = c3cn->wr_pending_tail = NULL;
}

/*
 * Add a WR to a connections's list of pending WRs.  This is a singly-linked
 * list of sk_buffs operating as a FIFO.  The head is kept in wr_pending_head
 * and the tail in wr_pending_tail.
 */
static inline void enqueue_wr(struct s3_conn *c3cn,
			      struct sk_buff *skb)
{
	skb_tx_wr_next(skb) = NULL;

	/*
	 * We want to take an extra reference since both us and the driver
	 * need to free the packet before it's really freed. We know there's
	 * just one user currently so we use atomic_set rather than skb_get
	 * to avoid the atomic op.
	 */
	atomic_set(&skb->users, 2);

	if (!c3cn->wr_pending_head)
		c3cn->wr_pending_head = skb;
	else
		skb_tx_wr_next(c3cn->wr_pending_tail) = skb;
	c3cn->wr_pending_tail = skb;
}

static int count_pending_wrs(struct s3_conn *c3cn)
{
	int n = 0;
	const struct sk_buff *skb = c3cn->wr_pending_head;

	while (skb) {
		n += skb->csum;
		skb = skb_tx_wr_next(skb);
	}
	return n;
}

static inline struct sk_buff *peek_wr(const struct s3_conn *c3cn)
{
	return c3cn->wr_pending_head;
}

static inline void free_wr_skb(struct sk_buff *skb)
{
	kfree_skb(skb);
}

static inline struct sk_buff *dequeue_wr(struct s3_conn *c3cn)
{
	struct sk_buff *skb = c3cn->wr_pending_head;

	if (likely(skb)) {
		/* Don't bother clearing the tail */
		c3cn->wr_pending_head = skb_tx_wr_next(skb);
		skb_tx_wr_next(skb) = NULL;
	}
	return skb;
}

static void purge_wr_queue(struct s3_conn *c3cn)
{
	struct sk_buff *skb;
	while ((skb = dequeue_wr(c3cn)) != NULL)
		free_wr_skb(skb);
}

static inline void make_tx_data_wr(struct s3_conn *c3cn, struct sk_buff *skb,
				   int len, int req_completion)
{
	struct tx_data_wr *req;

	skb_reset_transport_header(skb);
	req = (struct tx_data_wr *)__skb_push(skb, sizeof(*req));
	req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA) |
			(req_completion ? F_WR_COMPL : 0));
	req->wr_lo = htonl(V_WR_TID(c3cn->tid));
	req->sndseq = htonl(c3cn->snd_nxt);
	/* len includes the length of any HW ULP additions */
	req->len = htonl(len);
	req->param = htonl(V_TX_PORT(c3cn->l2t->smt_idx));
	/* V_TX_ULP_SUBMODE sets both the mode and submode */
	req->flags = htonl(V_TX_ULP_SUBMODE(skb_ulp_mode(skb)) |
			   V_TX_SHOVE((skb_peek(&c3cn->write_queue) ? 0 : 1)));

	if (!c3cn_flag(c3cn, C3CN_TX_DATA_SENT)) {
		req->flags |= htonl(V_TX_ACK_PAGES(2) | F_TX_INIT |
				    V_TX_CPU_IDX(c3cn->qset));
		/* Sendbuffer is in units of 32KB. */
		req->param |= htonl(V_TX_SNDBUF(cxgb3_snd_win >> 15));
		c3cn_set_flag(c3cn, C3CN_TX_DATA_SENT);
	}
}

/**
 * c3cn_push_tx_frames -- start transmit
 * @c3cn: the offloaded connection
 * @req_completion: request wr_ack or not
 *
 * Prepends TX_DATA_WR or CPL_CLOSE_CON_REQ headers to buffers waiting in a
 * connection's send queue and sends them on to T3.  Must be called with the
 * connection's lock held.  Returns the amount of send buffer space that was
 * freed as a result of sending queued data to T3.
 */
static void arp_failure_discard(struct t3cdev *cdev, struct sk_buff *skb)
{
	kfree_skb(skb);
}

static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion)
{
	int total_size = 0;
	struct sk_buff *skb;
	struct t3cdev *cdev;
	struct cxgb3i_sdev_data *cdata;

	if (unlikely(c3cn->state == C3CN_STATE_CONNECTING ||
		     c3cn->state == C3CN_STATE_CLOSE_WAIT_1 ||
		     c3cn->state >= C3CN_STATE_ABORTING)) {
		c3cn_tx_debug("c3cn 0x%p, in closing state %u.\n",
			      c3cn, c3cn->state);
		return 0;
	}

	cdev = c3cn->cdev;
	cdata = CXGB3_SDEV_DATA(cdev);

	while (c3cn->wr_avail
	       && (skb = skb_peek(&c3cn->write_queue)) != NULL) {
		int len = skb->len;	/* length before skb_push */
		int frags = skb_shinfo(skb)->nr_frags + (len != skb->data_len);
		int wrs_needed = skb_wrs[frags];

		if (wrs_needed > 1 && len + sizeof(struct tx_data_wr) <= wrlen)
			wrs_needed = 1;

		WARN_ON(frags >= SKB_WR_LIST_SIZE || wrs_needed < 1);

		if (c3cn->wr_avail < wrs_needed) {
			c3cn_tx_debug("c3cn 0x%p, skb len %u/%u, frag %u, "
				      "wr %d < %u.\n",
				      c3cn, skb->len, skb->data_len, frags,
				      wrs_needed, c3cn->wr_avail);
			break;
		}

		__skb_unlink(skb, &c3cn->write_queue);
		skb->priority = CPL_PRIORITY_DATA;
		skb->csum = wrs_needed;	/* remember this until the WR_ACK */
		c3cn->wr_avail -= wrs_needed;
		c3cn->wr_unacked += wrs_needed;
		enqueue_wr(c3cn, skb);

		c3cn_tx_debug("c3cn 0x%p, enqueue, skb len %u/%u, frag %u, "
				"wr %d, left %u, unack %u.\n",
				c3cn, skb->len, skb->data_len, frags,
				wrs_needed, c3cn->wr_avail, c3cn->wr_unacked);


		if (likely(skb_flags(skb) & C3CB_FLAG_NEED_HDR)) {
			if ((req_completion &&
				c3cn->wr_unacked == wrs_needed) ||
			    (skb_flags(skb) & C3CB_FLAG_COMPL) ||
			    c3cn->wr_unacked >= c3cn->wr_max / 2) {
				req_completion = 1;
				c3cn->wr_unacked = 0;
			}
			len += ulp_extra_len(skb);
			make_tx_data_wr(c3cn, skb, len, req_completion);
			c3cn->snd_nxt += len;
			skb_flags(skb) &= ~C3CB_FLAG_NEED_HDR;
		}

		total_size += skb->truesize;
		set_arp_failure_handler(skb, arp_failure_discard);
		l2t_send(cdev, skb, c3cn->l2t);
	}
	return total_size;
}

/*
 * process_cpl_msg: -> host
 * Top-level CPL message processing used by most CPL messages that
 * pertain to connections.
 */
static inline void process_cpl_msg(void (*fn)(struct s3_conn *,
					      struct sk_buff *),
				   struct s3_conn *c3cn,
				   struct sk_buff *skb)
{
	spin_lock_bh(&c3cn->lock);
	fn(c3cn, skb);
	spin_unlock_bh(&c3cn->lock);
}

/*
 * process_cpl_msg_ref: -> host
 * Similar to process_cpl_msg() but takes an extra connection reference around
 * the call to the handler.  Should be used if the handler may drop a
 * connection reference.
 */
static inline void process_cpl_msg_ref(void (*fn) (struct s3_conn *,
						   struct sk_buff *),
				       struct s3_conn *c3cn,
				       struct sk_buff *skb)
{
	c3cn_hold(c3cn);
	process_cpl_msg(fn, c3cn, skb);
	c3cn_put(c3cn);
}

/*
 * Process a CPL_ACT_ESTABLISH message: -> host
 * Updates connection state from an active establish CPL message.  Runs with
 * the connection lock held.
 */

static inline void s3_free_atid(struct t3cdev *cdev, unsigned int tid)
{
	struct s3_conn *c3cn = cxgb3_free_atid(cdev, tid);
	if (c3cn)
		c3cn_put(c3cn);
}

static void c3cn_established(struct s3_conn *c3cn, u32 snd_isn,
			     unsigned int opt)
{
	c3cn_conn_debug("c3cn 0x%p, state %u.\n", c3cn, c3cn->state);

	c3cn->write_seq = c3cn->snd_nxt = c3cn->snd_una = snd_isn;

	/*
	 * Causes the first RX_DATA_ACK to supply any Rx credits we couldn't
	 * pass through opt0.
	 */
	if (cxgb3_rcv_win > (M_RCV_BUFSIZ << 10))
		c3cn->rcv_wup -= cxgb3_rcv_win - (M_RCV_BUFSIZ << 10);

	dst_confirm(c3cn->dst_cache);

	smp_mb();

	c3cn_set_state(c3cn, C3CN_STATE_ESTABLISHED);
}

static void process_act_establish(struct s3_conn *c3cn, struct sk_buff *skb)
{
	struct cpl_act_establish *req = cplhdr(skb);
	u32 rcv_isn = ntohl(req->rcv_isn);	/* real RCV_ISN + 1 */

	c3cn_conn_debug("c3cn 0x%p, state %u, flag 0x%lx.\n",
			c3cn, c3cn->state, c3cn->flags);

	if (unlikely(c3cn->state != C3CN_STATE_CONNECTING))
		cxgb3i_log_error("TID %u expected SYN_SENT, got EST., s %u\n",
				 c3cn->tid, c3cn->state);

	c3cn->copied_seq = c3cn->rcv_wup = c3cn->rcv_nxt = rcv_isn;
	c3cn_established(c3cn, ntohl(req->snd_isn), ntohs(req->tcp_opt));

	__kfree_skb(skb);

	if (unlikely(c3cn_flag(c3cn, C3CN_ACTIVE_CLOSE_NEEDED)))
		/* upper layer has requested closing */
		send_abort_req(c3cn);
	else {
		if (skb_queue_len(&c3cn->write_queue))
			c3cn_push_tx_frames(c3cn, 1);
		cxgb3i_conn_tx_open(c3cn);
	}
}

static int do_act_establish(struct t3cdev *cdev, struct sk_buff *skb,
			    void *ctx)
{
	struct cpl_act_establish *req = cplhdr(skb);
	unsigned int tid = GET_TID(req);
	unsigned int atid = G_PASS_OPEN_TID(ntohl(req->tos_tid));
	struct s3_conn *c3cn = ctx;
	struct cxgb3i_sdev_data *cdata = CXGB3_SDEV_DATA(cdev);

	c3cn_conn_debug("rcv, tid 0x%x, c3cn 0x%p, s %u, f 0x%lx.\n",
			tid, c3cn, c3cn->state, c3cn->flags);

	c3cn->tid = tid;
	c3cn_hold(c3cn);
	cxgb3_insert_tid(cdata->cdev, cdata->client, c3cn, tid);
	s3_free_atid(cdev, atid);

	c3cn->qset = G_QNUM(ntohl(skb->csum));

	process_cpl_msg(process_act_establish, c3cn, skb);
	return 0;
}

/*
 * Process a CPL_ACT_OPEN_RPL message: -> host
 * Handle active open failures.
 */
static int act_open_rpl_status_to_errno(int status)
{
	switch (status) {
	case CPL_ERR_CONN_RESET:
		return ECONNREFUSED;
	case CPL_ERR_ARP_MISS:
		return EHOSTUNREACH;
	case CPL_ERR_CONN_TIMEDOUT:
		return ETIMEDOUT;
	case CPL_ERR_TCAM_FULL:
		return ENOMEM;
	case CPL_ERR_CONN_EXIST:
		cxgb3i_log_error("ACTIVE_OPEN_RPL: 4-tuple in use\n");
		return EADDRINUSE;
	default:
		return EIO;
	}
}

static void act_open_retry_timer(unsigned long data)
{
	struct sk_buff *skb;
	struct s3_conn *c3cn = (struct s3_conn *)data;

	c3cn_conn_debug("c3cn 0x%p, state %u.\n", c3cn, c3cn->state);

	spin_lock_bh(&c3cn->lock);
	skb = alloc_skb(sizeof(struct cpl_act_open_req), GFP_ATOMIC);
	if (!skb)
		fail_act_open(c3cn, ENOMEM);
	else {
		skb->sk = (struct sock *)c3cn;
		set_arp_failure_handler(skb, act_open_req_arp_failure);
		make_act_open_req(c3cn, skb, c3cn->tid, c3cn->l2t);
		l2t_send(c3cn->cdev, skb, c3cn->l2t);
	}
	spin_unlock_bh(&c3cn->lock);
	c3cn_put(c3cn);
}

static void process_act_open_rpl(struct s3_conn *c3cn, struct sk_buff *skb)
{
	struct cpl_act_open_rpl *rpl = cplhdr(skb);

	c3cn_conn_debug("c3cn 0x%p, state %u, flag 0x%lx.\n",
			c3cn, c3cn->state, c3cn->flags);

	if (rpl->status == CPL_ERR_CONN_EXIST &&
	    c3cn->retry_timer.function != act_open_retry_timer) {
		c3cn->retry_timer.function = act_open_retry_timer;
		if (!mod_timer(&c3cn->retry_timer, jiffies + HZ / 2))
			c3cn_hold(c3cn);
	} else
		fail_act_open(c3cn, act_open_rpl_status_to_errno(rpl->status));
	__kfree_skb(skb);
}

static int do_act_open_rpl(struct t3cdev *cdev, struct sk_buff *skb, void *ctx)
{
	struct s3_conn *c3cn = ctx;
	struct cpl_act_open_rpl *rpl = cplhdr(skb);

	c3cn_conn_debug("rcv, status 0x%x, c3cn 0x%p, s %u, f 0x%lx.\n",
			rpl->status, c3cn, c3cn->state, c3cn->flags);

	if (rpl->status != CPL_ERR_TCAM_FULL &&
	    rpl->status != CPL_ERR_CONN_EXIST &&
	    rpl->status != CPL_ERR_ARP_MISS)
		cxgb3_queue_tid_release(cdev, GET_TID(rpl));

	process_cpl_msg_ref(process_act_open_rpl, c3cn, skb);
	return 0;
}

/*
 * Process PEER_CLOSE CPL messages: -> host
 * Handle peer FIN.
 */
static void process_peer_close(struct s3_conn *c3cn, struct sk_buff *skb)
{
	c3cn_conn_debug("c3cn 0x%p, state %u, flag 0x%lx.\n",
			c3cn, c3cn->state, c3cn->flags);

	if (c3cn_flag(c3cn, C3CN_ABORT_RPL_PENDING))
		goto out;

	switch (c3cn->state) {
	case C3CN_STATE_ESTABLISHED:
		c3cn_set_state(c3cn, C3CN_STATE_PASSIVE_CLOSE);
		break;
	case C3CN_STATE_ACTIVE_CLOSE:
		c3cn_set_state(c3cn, C3CN_STATE_CLOSE_WAIT_2);
		break;
	case C3CN_STATE_CLOSE_WAIT_1:
		c3cn_closed(c3cn);
		break;
	case C3CN_STATE_ABORTING:
		break;
	default:
		cxgb3i_log_error("%s: peer close, TID %u in bad state %u\n",
				 c3cn->cdev->name, c3cn->tid, c3cn->state);
	}

	cxgb3i_conn_closing(c3cn);
out:
	__kfree_skb(skb);
}

static int do_peer_close(struct t3cdev *cdev, struct sk_buff *skb, void *ctx)
{
	struct s3_conn *c3cn = ctx;

	c3cn_conn_debug("rcv, c3cn 0x%p, s %u, f 0x%lx.\n",
			c3cn, c3cn->state, c3cn->flags);
	process_cpl_msg_ref(process_peer_close, c3cn, skb);
	return 0;
}

/*
 * Process CLOSE_CONN_RPL CPL message: -> host
 * Process a peer ACK to our FIN.
 */
static void process_close_con_rpl(struct s3_conn *c3cn, struct sk_buff *skb)
{
	struct cpl_close_con_rpl *rpl = cplhdr(skb);

	c3cn_conn_debug("c3cn 0x%p, state %u, flag 0x%lx.\n",
			c3cn, c3cn->state, c3cn->flags);

	c3cn->snd_una = ntohl(rpl->snd_nxt) - 1;	/* exclude FIN */

	if (c3cn_flag(c3cn, C3CN_ABORT_RPL_PENDING))
		goto out;

	switch (c3cn->state) {
	case C3CN_STATE_ACTIVE_CLOSE:
		c3cn_set_state(c3cn, C3CN_STATE_CLOSE_WAIT_1);
		break;
	case C3CN_STATE_CLOSE_WAIT_1:
	case C3CN_STATE_CLOSE_WAIT_2:
		c3cn_closed(c3cn);
		break;
	case C3CN_STATE_ABORTING:
		break;
	default:
		cxgb3i_log_error("%s: close_rpl, TID %u in bad state %u\n",
				 c3cn->cdev->name, c3cn->tid, c3cn->state);
	}

out:
	kfree_skb(skb);
}

static int do_close_con_rpl(struct t3cdev *cdev, struct sk_buff *skb,
			    void *ctx)
{
	struct s3_conn *c3cn = ctx;

	c3cn_conn_debug("rcv, c3cn 0x%p, s %u, f 0x%lx.\n",
			 c3cn, c3cn->state, c3cn->flags);

	process_cpl_msg_ref(process_close_con_rpl, c3cn, skb);
	return 0;
}

/*
 * Process ABORT_REQ_RSS CPL message: -> host
 * Process abort requests.  If we are waiting for an ABORT_RPL we ignore this
 * request except that we need to reply to it.
 */

static int abort_status_to_errno(struct s3_conn *c3cn, int abort_reason,
				 int *need_rst)
{
	switch (abort_reason) {
	case CPL_ERR_BAD_SYN: /* fall through */
	case CPL_ERR_CONN_RESET:
		return c3cn->state > C3CN_STATE_ESTABLISHED ?
			EPIPE : ECONNRESET;
	case CPL_ERR_XMIT_TIMEDOUT:
	case CPL_ERR_PERSIST_TIMEDOUT:
	case CPL_ERR_FINWAIT2_TIMEDOUT:
	case CPL_ERR_KEEPALIVE_TIMEDOUT:
		return ETIMEDOUT;
	default:
		return EIO;
	}
}

static void process_abort_req(struct s3_conn *c3cn, struct sk_buff *skb)
{
	int rst_status = CPL_ABORT_NO_RST;
	const struct cpl_abort_req_rss *req = cplhdr(skb);

	c3cn_conn_debug("c3cn 0x%p, state %u, flag 0x%lx.\n",
			c3cn, c3cn->state, c3cn->flags);

	if (!c3cn_flag(c3cn, C3CN_ABORT_REQ_RCVD)) {
		c3cn_set_flag(c3cn, C3CN_ABORT_REQ_RCVD);
		c3cn_set_state(c3cn, C3CN_STATE_ABORTING);
		__kfree_skb(skb);
		return;
	}

	c3cn_clear_flag(c3cn, C3CN_ABORT_REQ_RCVD);
	send_abort_rpl(c3cn, rst_status);

	if (!c3cn_flag(c3cn, C3CN_ABORT_RPL_PENDING)) {
		c3cn->err =
		    abort_status_to_errno(c3cn, req->status, &rst_status);
		c3cn_closed(c3cn);
	}
}

static int do_abort_req(struct t3cdev *cdev, struct sk_buff *skb, void *ctx)
{
	const struct cpl_abort_req_rss *req = cplhdr(skb);
	struct s3_conn *c3cn = ctx;

	c3cn_conn_debug("rcv, c3cn 0x%p, s 0x%x, f 0x%lx.\n",
			c3cn, c3cn->state, c3cn->flags);

	if (req->status == CPL_ERR_RTX_NEG_ADVICE ||
	    req->status == CPL_ERR_PERSIST_NEG_ADVICE) {
		__kfree_skb(skb);
		return 0;
	}

	process_cpl_msg_ref(process_abort_req, c3cn, skb);
	return 0;
}

/*
 * Process ABORT_RPL_RSS CPL message: -> host
 * Process abort replies.  We only process these messages if we anticipate
 * them as the coordination between SW and HW in this area is somewhat lacking
 * and sometimes we get ABORT_RPLs after we are done with the connection that
 * originated the ABORT_REQ.
 */
static void process_abort_rpl(struct s3_conn *c3cn, struct sk_buff *skb)
{
	c3cn_conn_debug("c3cn 0x%p, state %u, flag 0x%lx.\n",
			c3cn, c3cn->state, c3cn->flags);

	if (c3cn_flag(c3cn, C3CN_ABORT_RPL_PENDING)) {
		if (!c3cn_flag(c3cn, C3CN_ABORT_RPL_RCVD))
			c3cn_set_flag(c3cn, C3CN_ABORT_RPL_RCVD);
		else {
			c3cn_clear_flag(c3cn, C3CN_ABORT_RPL_RCVD);
			c3cn_clear_flag(c3cn, C3CN_ABORT_RPL_PENDING);
			if (c3cn_flag(c3cn, C3CN_ABORT_REQ_RCVD))
				cxgb3i_log_error("%s tid %u, ABORT_RPL_RSS\n",
						 c3cn->cdev->name, c3cn->tid);
			c3cn_closed(c3cn);
		}
	}
	__kfree_skb(skb);
}

static int do_abort_rpl(struct t3cdev *cdev, struct sk_buff *skb, void *ctx)
{
	struct cpl_abort_rpl_rss *rpl = cplhdr(skb);
	struct s3_conn *c3cn = ctx;

	c3cn_conn_debug("rcv, status 0x%x, c3cn 0x%p, s %u, 0x%lx.\n",
			rpl->status, c3cn, c3cn ? c3cn->state : 0,
			c3cn ? c3cn->flags : 0UL);

	/*
	 * Ignore replies to post-close aborts indicating that the abort was
	 * requested too late.  These connections are terminated when we get
	 * PEER_CLOSE or CLOSE_CON_RPL and by the time the abort_rpl_rss
	 * arrives the TID is either no longer used or it has been recycled.
	 */
	if (rpl->status == CPL_ERR_ABORT_FAILED)
		goto discard;

	/*
	 * Sometimes we've already closed the connection, e.g., a post-close
	 * abort races with ABORT_REQ_RSS, the latter frees the connection
	 * expecting the ABORT_REQ will fail with CPL_ERR_ABORT_FAILED,
	 * but FW turns the ABORT_REQ into a regular one and so we get
	 * ABORT_RPL_RSS with status 0 and no connection.
	 */
	if (!c3cn)
		goto discard;

	process_cpl_msg_ref(process_abort_rpl, c3cn, skb);
	return 0;

discard:
	__kfree_skb(skb);
	return 0;
}

/*
 * Process RX_ISCSI_HDR CPL message: -> host
 * Handle received PDUs, the payload could be DDP'ed. If not, the payload
 * follow after the bhs.
 */
static void process_rx_iscsi_hdr(struct s3_conn *c3cn, struct sk_buff *skb)
{
	struct cpl_iscsi_hdr *hdr_cpl = cplhdr(skb);
	struct cpl_iscsi_hdr_norss data_cpl;
	struct cpl_rx_data_ddp_norss ddp_cpl;
	unsigned int hdr_len, data_len, status;
	unsigned int len;
	int err;

	if (unlikely(c3cn->state >= C3CN_STATE_PASSIVE_CLOSE)) {
		if (c3cn->state != C3CN_STATE_ABORTING)
			send_abort_req(c3cn);
		__kfree_skb(skb);
		return;
	}

	skb_tcp_seq(skb) = ntohl(hdr_cpl->seq);
	skb_flags(skb) = 0;

	skb_reset_transport_header(skb);
	__skb_pull(skb, sizeof(struct cpl_iscsi_hdr));

	len = hdr_len = ntohs(hdr_cpl->len);
	/* msg coalesce is off or not enough data received */
	if (skb->len <= hdr_len) {
		cxgb3i_log_error("%s: TID %u, ISCSI_HDR, skb len %u < %u.\n",
				 c3cn->cdev->name, c3cn->tid,
				 skb->len, hdr_len);
		goto abort_conn;
	}

	err = skb_copy_bits(skb, skb->len - sizeof(ddp_cpl), &ddp_cpl,
			    sizeof(ddp_cpl));
	if (err < 0)
		goto abort_conn;

	skb_ulp_mode(skb) = ULP2_FLAG_DATA_READY;
	skb_rx_pdulen(skb) = ntohs(ddp_cpl.len);
	skb_rx_ddigest(skb) = ntohl(ddp_cpl.ulp_crc);
	status = ntohl(ddp_cpl.ddp_status);

	c3cn_rx_debug("rx skb 0x%p, len %u, pdulen %u, ddp status 0x%x.\n",
		      skb, skb->len, skb_rx_pdulen(skb), status);

	if (status & (1 << RX_DDP_STATUS_HCRC_SHIFT))
		skb_ulp_mode(skb) |= ULP2_FLAG_HCRC_ERROR;
	if (status & (1 << RX_DDP_STATUS_DCRC_SHIFT))
		skb_ulp_mode(skb) |= ULP2_FLAG_DCRC_ERROR;
	if (status & (1 << RX_DDP_STATUS_PAD_SHIFT))
		skb_ulp_mode(skb) |= ULP2_FLAG_PAD_ERROR;

	if (skb->len > (hdr_len + sizeof(ddp_cpl))) {
		err = skb_copy_bits(skb, hdr_len, &data_cpl, sizeof(data_cpl));
		if (err < 0)
			goto abort_conn;
		data_len = ntohs(data_cpl.len);
		len += sizeof(data_cpl) + data_len;
	} else if (status & (1 << RX_DDP_STATUS_DDP_SHIFT))
		skb_ulp_mode(skb) |= ULP2_FLAG_DATA_DDPED;

	c3cn->rcv_nxt = ntohl(ddp_cpl.seq) + skb_rx_pdulen(skb);
	__pskb_trim(skb, len);
	__skb_queue_tail(&c3cn->receive_queue, skb);
	cxgb3i_conn_pdu_ready(c3cn);

	return;

abort_conn:
	send_abort_req(c3cn);
	__kfree_skb(skb);
}

static int do_iscsi_hdr(struct t3cdev *t3dev, struct sk_buff *skb, void *ctx)
{
	struct s3_conn *c3cn = ctx;

	process_cpl_msg(process_rx_iscsi_hdr, c3cn, skb);
	return 0;
}

/*
 * Process TX_DATA_ACK CPL messages: -> host
 * Process an acknowledgment of WR completion.  Advance snd_una and send the
 * next batch of work requests from the write queue.
 */
static void check_wr_invariants(struct s3_conn *c3cn)
{
	int pending = count_pending_wrs(c3cn);

	if (unlikely(c3cn->wr_avail + pending != c3cn->wr_max))
		cxgb3i_log_error("TID %u: credit imbalance: avail %u, "
				"pending %u, total should be %u\n",
				c3cn->tid, c3cn->wr_avail, pending,
				c3cn->wr_max);
}

static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb)
{
	struct cpl_wr_ack *hdr = cplhdr(skb);
	unsigned int credits = ntohs(hdr->credits);
	u32 snd_una = ntohl(hdr->snd_una);

	c3cn_tx_debug("%u WR credits, avail %u, unack %u, TID %u, state %u.\n",
			credits, c3cn->wr_avail, c3cn->wr_unacked,
			c3cn->tid, c3cn->state);

	c3cn->wr_avail += credits;
	if (c3cn->wr_unacked > c3cn->wr_max - c3cn->wr_avail)
		c3cn->wr_unacked = c3cn->wr_max - c3cn->wr_avail;

	while (credits) {
		struct sk_buff *p = peek_wr(c3cn);

		if (unlikely(!p)) {
			cxgb3i_log_error("%u WR_ACK credits for TID %u with "
					 "nothing pending, state %u\n",
					 credits, c3cn->tid, c3cn->state);
			break;
		}
		if (unlikely(credits < p->csum)) {
			struct tx_data_wr *w = cplhdr(p);
			cxgb3i_log_error("TID %u got %u WR credits need %u, "
					 "len %u, main body %u, frags %u, "
					 "seq # %u, ACK una %u, ACK nxt %u, "
					 "WR_AVAIL %u, WRs pending %u\n",
					 c3cn->tid, credits, p->csum, p->len,
					 p->len - p->data_len,
					 skb_shinfo(p)->nr_frags,
					 ntohl(w->sndseq), snd_una,
					 ntohl(hdr->snd_nxt), c3cn->wr_avail,
					 count_pending_wrs(c3cn) - credits);
			p->csum -= credits;
			break;
		} else {
			dequeue_wr(c3cn);
			credits -= p->csum;
			free_wr_skb(p);
		}
	}

	check_wr_invariants(c3cn);

	if (unlikely(before(snd_una, c3cn->snd_una))) {
		cxgb3i_log_error("TID %u, unexpected sequence # %u in WR_ACK "
				 "snd_una %u\n",
				 c3cn->tid, snd_una, c3cn->snd_una);
		goto out_free;
	}

	if (c3cn->snd_una != snd_una) {
		c3cn->snd_una = snd_una;
		dst_confirm(c3cn->dst_cache);
	}

	if (skb_queue_len(&c3cn->write_queue)) {
		if (c3cn_push_tx_frames(c3cn, 0))
			cxgb3i_conn_tx_open(c3cn);
	} else
		cxgb3i_conn_tx_open(c3cn);
out_free:
	__kfree_skb(skb);
}

static int do_wr_ack(struct t3cdev *cdev, struct sk_buff *skb, void *ctx)
{
	struct s3_conn *c3cn = ctx;

	process_cpl_msg(process_wr_ack, c3cn, skb);
	return 0;
}

/*
 * for each connection, pre-allocate skbs needed for close/abort requests. So
 * that we can service the request right away.
 */
static void c3cn_free_cpl_skbs(struct s3_conn *c3cn)
{
	if (c3cn->cpl_close)
		kfree_skb(c3cn->cpl_close);
	if (c3cn->cpl_abort_req)
		kfree_skb(c3cn->cpl_abort_req);
	if (c3cn->cpl_abort_rpl)
		kfree_skb(c3cn->cpl_abort_rpl);
}

static int c3cn_alloc_cpl_skbs(struct s3_conn *c3cn)
{
	c3cn->cpl_close = alloc_skb(sizeof(struct cpl_close_con_req),
				   GFP_KERNEL);
	if (!c3cn->cpl_close)
		return -ENOMEM;
	skb_put(c3cn->cpl_close, sizeof(struct cpl_close_con_req));

	c3cn->cpl_abort_req = alloc_skb(sizeof(struct cpl_abort_req),
					GFP_KERNEL);
	if (!c3cn->cpl_abort_req)
		goto free_cpl_skbs;
	skb_put(c3cn->cpl_abort_req, sizeof(struct cpl_abort_req));

	c3cn->cpl_abort_rpl = alloc_skb(sizeof(struct cpl_abort_rpl),
					GFP_KERNEL);
	if (!c3cn->cpl_abort_rpl)
		goto free_cpl_skbs;
	skb_put(c3cn->cpl_abort_rpl, sizeof(struct cpl_abort_rpl));

	return 0;

free_cpl_skbs:
	c3cn_free_cpl_skbs(c3cn);
	return -ENOMEM;
}

/**
 * c3cn_release_offload_resources - release offload resource
 * @c3cn: the offloaded iscsi tcp connection.
 * Release resources held by an offload connection (TID, L2T entry, etc.)
 */
static void c3cn_release_offload_resources(struct s3_conn *c3cn)
{
	struct t3cdev *cdev = c3cn->cdev;
	unsigned int tid = c3cn->tid;

	c3cn->qset = 0;
	c3cn_free_cpl_skbs(c3cn);

	if (c3cn->wr_avail != c3cn->wr_max) {
		purge_wr_queue(c3cn);
		reset_wr_list(c3cn);
	}

	if (cdev) {
		if (c3cn->l2t) {
			l2t_release(L2DATA(cdev), c3cn->l2t);
			c3cn->l2t = NULL;
		}
		if (c3cn->state == C3CN_STATE_CONNECTING)
			/* we have ATID */
			s3_free_atid(cdev, tid);
		else {
			/* we have TID */
			cxgb3_remove_tid(cdev, (void *)c3cn, tid);
			c3cn_put(c3cn);
		}
	}

	c3cn->dst_cache = NULL;
	c3cn->cdev = NULL;
}

/**
 * cxgb3i_c3cn_create - allocate and initialize an s3_conn structure
 * returns the s3_conn structure allocated.
 */
struct s3_conn *cxgb3i_c3cn_create(void)
{
	struct s3_conn *c3cn;

	c3cn = kzalloc(sizeof(*c3cn), GFP_KERNEL);
	if (!c3cn)
		return NULL;

	/* pre-allocate close/abort cpl, so we don't need to wait for memory
	   when close/abort is requested. */
	if (c3cn_alloc_cpl_skbs(c3cn) < 0)
		goto free_c3cn;

	c3cn_conn_debug("alloc c3cn 0x%p.\n", c3cn);

	c3cn->flags = 0;
	spin_lock_init(&c3cn->lock);
	atomic_set(&c3cn->refcnt, 1);
	skb_queue_head_init(&c3cn->receive_queue);
	skb_queue_head_init(&c3cn->write_queue);
	setup_timer(&c3cn->retry_timer, NULL, (unsigned long)c3cn);
	rwlock_init(&c3cn->callback_lock);

	return c3cn;

free_c3cn:
	kfree(c3cn);
	return NULL;
}

static void c3cn_active_close(struct s3_conn *c3cn)
{
	int data_lost;
	int close_req = 0;

	c3cn_conn_debug("c3cn 0x%p, state %u, flag 0x%lx.\n",
			 c3cn, c3cn->state, c3cn->flags);

	dst_confirm(c3cn->dst_cache);

	c3cn_hold(c3cn);
	spin_lock_bh(&c3cn->lock);

	data_lost = skb_queue_len(&c3cn->receive_queue);
	__skb_queue_purge(&c3cn->receive_queue);

	switch (c3cn->state) {
	case C3CN_STATE_CLOSED:
	case C3CN_STATE_ACTIVE_CLOSE:
	case C3CN_STATE_CLOSE_WAIT_1:
	case C3CN_STATE_CLOSE_WAIT_2:
	case C3CN_STATE_ABORTING:
		/* nothing need to be done */
		break;
	case C3CN_STATE_CONNECTING:
		/* defer until cpl_act_open_rpl or cpl_act_establish */
		c3cn_set_flag(c3cn, C3CN_ACTIVE_CLOSE_NEEDED);
		break;
	case C3CN_STATE_ESTABLISHED:
		close_req = 1;
		c3cn_set_state(c3cn, C3CN_STATE_ACTIVE_CLOSE);
		break;
	case C3CN_STATE_PASSIVE_CLOSE:
		close_req = 1;
		c3cn_set_state(c3cn, C3CN_STATE_CLOSE_WAIT_2);
		break;
	}

	if (close_req) {
		if (data_lost)
			/* Unread data was tossed, zap the connection. */
			send_abort_req(c3cn);
		else
			send_close_req(c3cn);
	}

	spin_unlock_bh(&c3cn->lock);
	c3cn_put(c3cn);
}

/**
 * cxgb3i_c3cn_release - close and release an iscsi tcp connection and any
 * 	resource held
 * @c3cn: the iscsi tcp connection
 */
void cxgb3i_c3cn_release(struct s3_conn *c3cn)
{
	c3cn_conn_debug("c3cn 0x%p, s %u, f 0x%lx.\n",
			c3cn, c3cn->state, c3cn->flags);
	if (unlikely(c3cn->state == C3CN_STATE_CONNECTING))
		c3cn_set_flag(c3cn, C3CN_ACTIVE_CLOSE_NEEDED);
	else if (likely(c3cn->state != C3CN_STATE_CLOSED))
		c3cn_active_close(c3cn);
	c3cn_put(c3cn);
}

static int is_cxgb3_dev(struct net_device *dev)
{
	struct cxgb3i_sdev_data *cdata;

	write_lock(&cdata_rwlock);
	list_for_each_entry(cdata, &cdata_list, list) {
		struct adap_ports *ports = &cdata->ports;
		int i;

		for (i = 0; i < ports->nports; i++)
			if (dev == ports->lldevs[i]) {
				write_unlock(&cdata_rwlock);
				return 1;
			}
	}
	write_unlock(&cdata_rwlock);
	return 0;
}

/**
 * cxgb3_egress_dev - return the cxgb3 egress device
 * @root_dev: the root device anchoring the search
 * @c3cn: the connection used to determine egress port in bonding mode
 * @context: in bonding mode, indicates a connection set up or failover
 *
 * Return egress device or NULL if the egress device isn't one of our ports.
 */
static struct net_device *cxgb3_egress_dev(struct net_device *root_dev,
					   struct s3_conn *c3cn,
					   int context)
{
	while (root_dev) {
		if (root_dev->priv_flags & IFF_802_1Q_VLAN)
			root_dev = vlan_dev_real_dev(root_dev);
		else if (is_cxgb3_dev(root_dev))
			return root_dev;
		else
			return NULL;
	}
	return NULL;
}

static struct rtable *find_route(struct net_device *dev,
				 __be32 saddr, __be32 daddr,
				 __be16 sport, __be16 dport)
{
	struct rtable *rt;
	struct flowi fl = {
		.oif = dev ? dev->ifindex : 0,
		.nl_u = {
			 .ip4_u = {
				   .daddr = daddr,
				   .saddr = saddr,
				   .tos = 0 } },
		.proto = IPPROTO_TCP,
		.uli_u = {
			  .ports = {
				    .sport = sport,
				    .dport = dport } } };

	if (ip_route_output_flow(&init_net, &rt, &fl, NULL, 0))
		return NULL;
	return rt;
}

/*
 * Assign offload parameters to some connection fields.
 */
static void init_offload_conn(struct s3_conn *c3cn,
			      struct t3cdev *cdev,
			      struct dst_entry *dst)
{
	BUG_ON(c3cn->cdev != cdev);
	c3cn->wr_max = c3cn->wr_avail = T3C_DATA(cdev)->max_wrs - 1;
	c3cn->wr_unacked = 0;
	c3cn->mss_idx = select_mss(c3cn, dst_mtu(dst));

	reset_wr_list(c3cn);
}

static int initiate_act_open(struct s3_conn *c3cn, struct net_device *dev)
{
	struct cxgb3i_sdev_data *cdata = NDEV2CDATA(dev);
	struct t3cdev *cdev = cdata->cdev;
	struct dst_entry *dst = c3cn->dst_cache;
	struct sk_buff *skb;

	c3cn_conn_debug("c3cn 0x%p, state %u, flag 0x%lx.\n",
			c3cn, c3cn->state, c3cn->flags);
	/*
	 * Initialize connection data.  Note that the flags and ULP mode are
	 * initialized higher up ...
	 */
	c3cn->dev = dev;
	c3cn->cdev = cdev;
	c3cn->tid = cxgb3_alloc_atid(cdev, cdata->client, c3cn);
	if (c3cn->tid < 0)
		goto out_err;

	c3cn->qset = 0;
	c3cn->l2t = t3_l2t_get(cdev, dst->neighbour, dev);
	if (!c3cn->l2t)
		goto free_tid;

	skb = alloc_skb(sizeof(struct cpl_act_open_req), GFP_KERNEL);
	if (!skb)
		goto free_l2t;

	skb->sk = (struct sock *)c3cn;
	set_arp_failure_handler(skb, act_open_req_arp_failure);

	c3cn_hold(c3cn);

	init_offload_conn(c3cn, cdev, dst);
	c3cn->err = 0;

	make_act_open_req(c3cn, skb, c3cn->tid, c3cn->l2t);
	l2t_send(cdev, skb, c3cn->l2t);
	return 0;

free_l2t:
	l2t_release(L2DATA(cdev), c3cn->l2t);
free_tid:
	s3_free_atid(cdev, c3cn->tid);
	c3cn->tid = 0;
out_err:
	return -1;
}


/**
 * cxgb3i_c3cn_connect - initiates an iscsi tcp connection to a given address
 * @c3cn: the iscsi tcp connection
 * @usin: destination address
 *
 * return 0 if active open request is sent, < 0 otherwise.
 */
int cxgb3i_c3cn_connect(struct net_device *dev, struct s3_conn *c3cn,
			struct sockaddr_in *usin)
{
	struct rtable *rt;
	struct cxgb3i_sdev_data *cdata;
	struct t3cdev *cdev;
	__be32 sipv4;
	int err;

	c3cn_conn_debug("c3cn 0x%p, dev 0x%p.\n", c3cn, dev);

	if (usin->sin_family != AF_INET)
		return -EAFNOSUPPORT;

	c3cn->daddr.sin_port = usin->sin_port;
	c3cn->daddr.sin_addr.s_addr = usin->sin_addr.s_addr;

	rt = find_route(dev, c3cn->saddr.sin_addr.s_addr,
			c3cn->daddr.sin_addr.s_addr,
			c3cn->saddr.sin_port,
			c3cn->daddr.sin_port);
	if (rt == NULL) {
		c3cn_conn_debug("NO route to 0x%x, port %u, dev %s.\n",
				c3cn->daddr.sin_addr.s_addr,
				ntohs(c3cn->daddr.sin_port),
				dev ? dev->name : "any");
		return -ENETUNREACH;
	}

	if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) {
		c3cn_conn_debug("multi-cast route to 0x%x, port %u, dev %s.\n",
				c3cn->daddr.sin_addr.s_addr,
				ntohs(c3cn->daddr.sin_port),
				dev ? dev->name : "any");
		ip_rt_put(rt);
		return -ENETUNREACH;
	}

	if (!c3cn->saddr.sin_addr.s_addr)
		c3cn->saddr.sin_addr.s_addr = rt->rt_src;

	/* now commit destination to connection */
	c3cn->dst_cache = &rt->u.dst;

	/* try to establish an offloaded connection */
	dev = cxgb3_egress_dev(c3cn->dst_cache->dev, c3cn, 0);
	if (dev == NULL) {
		c3cn_conn_debug("c3cn 0x%p, egress dev NULL.\n", c3cn);
		return -ENETUNREACH;
	}
	cdata = NDEV2CDATA(dev);
	cdev = cdata->cdev;

	/* get a source port if one hasn't been provided */
	err = c3cn_get_port(c3cn, cdata);
	if (err)
		return err;

	c3cn_conn_debug("c3cn 0x%p get port %u.\n",
			c3cn, ntohs(c3cn->saddr.sin_port));

	sipv4 = cxgb3i_get_private_ipv4addr(dev);
	if (!sipv4) {
		c3cn_conn_debug("c3cn 0x%p, iscsi ip not configured.\n", c3cn);
		sipv4 = c3cn->saddr.sin_addr.s_addr;
		cxgb3i_set_private_ipv4addr(dev, sipv4);
	} else
		c3cn->saddr.sin_addr.s_addr = sipv4;

	c3cn_conn_debug("c3cn 0x%p, %u.%u.%u.%u,%u-%u.%u.%u.%u,%u SYN_SENT.\n",
			c3cn, NIPQUAD(c3cn->saddr.sin_addr.s_addr),
			ntohs(c3cn->saddr.sin_port),
			NIPQUAD(c3cn->daddr.sin_addr.s_addr),
			ntohs(c3cn->daddr.sin_port));

	c3cn_set_state(c3cn, C3CN_STATE_CONNECTING);
	if (!initiate_act_open(c3cn, dev))
		return 0;

	/*
	 * If we get here, we don't have an offload connection so simply
	 * return a failure.
	 */
	err = -ENOTSUPP;

	/*
	 * This trashes the connection and releases the local port,
	 * if necessary.
	 */
	c3cn_conn_debug("c3cn 0x%p -> CLOSED.\n", c3cn);
	c3cn_set_state(c3cn, C3CN_STATE_CLOSED);
	ip_rt_put(rt);
	c3cn_put_port(c3cn);
	return err;
}

/**
 * cxgb3i_c3cn_rx_credits - ack received tcp data.
 * @c3cn: iscsi tcp connection
 * @copied: # of bytes processed
 *
 * Called after some received data has been read.  It returns RX credits
 * to the HW for the amount of data processed.
 */
void cxgb3i_c3cn_rx_credits(struct s3_conn *c3cn, int copied)
{
	struct t3cdev *cdev;
	int must_send;
	u32 credits, dack = 0;

	if (c3cn->state != C3CN_STATE_ESTABLISHED)
		return;

	credits = c3cn->copied_seq - c3cn->rcv_wup;
	if (unlikely(!credits))
		return;

	cdev = c3cn->cdev;

	if (unlikely(cxgb3_rx_credit_thres == 0))
		return;

	dack = F_RX_DACK_CHANGE | V_RX_DACK_MODE(1);

	/*
	 * For coalescing to work effectively ensure the receive window has
	 * at least 16KB left.
	 */
	must_send = credits + 16384 >= cxgb3_rcv_win;

	if (must_send || credits >= cxgb3_rx_credit_thres)
		c3cn->rcv_wup += send_rx_credits(c3cn, credits, dack);
}

/**
 * cxgb3i_c3cn_send_pdus - send the skbs containing iscsi pdus
 * @c3cn: iscsi tcp connection
 * @skb: skb contains the iscsi pdu
 *
 * Add a list of skbs to a connection send queue. The skbs must comply with
 * the max size limit of the device and have a headroom of at least
 * TX_HEADER_LEN bytes.
 * Return # of bytes queued.
 */
int cxgb3i_c3cn_send_pdus(struct s3_conn *c3cn, struct sk_buff *skb)
{
	struct sk_buff *next;
	int err, copied = 0;

	spin_lock_bh(&c3cn->lock);

	if (c3cn->state != C3CN_STATE_ESTABLISHED) {
		c3cn_tx_debug("c3cn 0x%p, not in est. state %u.\n",
			      c3cn, c3cn->state);
		err = -EAGAIN;
		goto out_err;
	}

	if (c3cn->err) {
		c3cn_tx_debug("c3cn 0x%p, err %d.\n", c3cn, c3cn->err);
		err = -EPIPE;
		goto out_err;
	}

	if (c3cn->write_seq - c3cn->snd_una >= cxgb3_snd_win) {
		c3cn_tx_debug("c3cn 0x%p, snd %u - %u > %u.\n",
				c3cn, c3cn->write_seq, c3cn->snd_una,
				cxgb3_snd_win);
		err = -ENOBUFS;
		goto out_err;
	}

	while (skb) {
		int frags = skb_shinfo(skb)->nr_frags +
				(skb->len != skb->data_len);

		if (unlikely(skb_headroom(skb) < TX_HEADER_LEN)) {
			c3cn_tx_debug("c3cn 0x%p, skb head.\n", c3cn);
			err = -EINVAL;
			goto out_err;
		}

		if (frags >= SKB_WR_LIST_SIZE) {
			cxgb3i_log_error("c3cn 0x%p, tx frags %d, len %u,%u.\n",
					 c3cn, skb_shinfo(skb)->nr_frags,
					 skb->len, skb->data_len);
			err = -EINVAL;
			goto out_err;
		}

		next = skb->next;
		skb->next = NULL;
		skb_entail(c3cn, skb, C3CB_FLAG_NO_APPEND | C3CB_FLAG_NEED_HDR);
		copied += skb->len;
		c3cn->write_seq += skb->len + ulp_extra_len(skb);
		skb = next;
	}
done:
	if (likely(skb_queue_len(&c3cn->write_queue)))
		c3cn_push_tx_frames(c3cn, 1);
	spin_unlock_bh(&c3cn->lock);
	return copied;

out_err:
	if (copied == 0 && err == -EPIPE)
		copied = c3cn->err ? c3cn->err : -EPIPE;
	else
		copied = err;
	goto done;
}

static void sdev_data_cleanup(struct cxgb3i_sdev_data *cdata)
{
	struct adap_ports *ports = &cdata->ports;
	struct s3_conn *c3cn;
	int i;

	for (i = 0; i < cxgb3_max_connect; i++) {
		if (cdata->sport_conn[i]) {
			c3cn = cdata->sport_conn[i];
			cdata->sport_conn[i] = NULL;

			spin_lock_bh(&c3cn->lock);
			c3cn->cdev = NULL;
			c3cn_set_flag(c3cn, C3CN_OFFLOAD_DOWN);
			c3cn_closed(c3cn);
			spin_unlock_bh(&c3cn->lock);
		}
	}

	for (i = 0; i < ports->nports; i++)
		NDEV2CDATA(ports->lldevs[i]) = NULL;

	cxgb3i_free_big_mem(cdata);
}

void cxgb3i_sdev_cleanup(void)
{
	struct cxgb3i_sdev_data *cdata;

	write_lock(&cdata_rwlock);
	list_for_each_entry(cdata, &cdata_list, list) {
		list_del(&cdata->list);
		sdev_data_cleanup(cdata);
	}
	write_unlock(&cdata_rwlock);
}

int cxgb3i_sdev_init(cxgb3_cpl_handler_func *cpl_handlers)
{
	cpl_handlers[CPL_ACT_ESTABLISH] = do_act_establish;
	cpl_handlers[CPL_ACT_OPEN_RPL] = do_act_open_rpl;
	cpl_handlers[CPL_PEER_CLOSE] = do_peer_close;
	cpl_handlers[CPL_ABORT_REQ_RSS] = do_abort_req;
	cpl_handlers[CPL_ABORT_RPL_RSS] = do_abort_rpl;
	cpl_handlers[CPL_CLOSE_CON_RPL] = do_close_con_rpl;
	cpl_handlers[CPL_TX_DMA_ACK] = do_wr_ack;
	cpl_handlers[CPL_ISCSI_HDR] = do_iscsi_hdr;

	if (cxgb3_max_connect > CXGB3I_MAX_CONN)
		cxgb3_max_connect = CXGB3I_MAX_CONN;
	return 0;
}

/**
 * cxgb3i_sdev_add - allocate and initialize resources for each adapter found
 * @cdev:	t3cdev adapter
 * @client:	cxgb3 driver client
 */
void cxgb3i_sdev_add(struct t3cdev *cdev, struct cxgb3_client *client)
{
	struct cxgb3i_sdev_data *cdata;
	struct ofld_page_info rx_page_info;
	unsigned int wr_len;
	int mapsize = cxgb3_max_connect * sizeof(struct s3_conn *);
	int i;

	cdata =  cxgb3i_alloc_big_mem(sizeof(*cdata) + mapsize, GFP_KERNEL);
	if (!cdata) {
		cxgb3i_log_warn("t3dev 0x%p, offload up, OOM %d.\n",
				cdev, mapsize);
		return;
	}

	if (cdev->ctl(cdev, GET_WR_LEN, &wr_len) < 0 ||
	    cdev->ctl(cdev, GET_PORTS, &cdata->ports) < 0 ||
	    cdev->ctl(cdev, GET_RX_PAGE_INFO, &rx_page_info) < 0) {
		cxgb3i_log_warn("t3dev 0x%p, offload up, ioctl failed.\n",
				cdev);
		goto free_cdata;
	}

	s3_init_wr_tab(wr_len);

	spin_lock_init(&cdata->lock);
	INIT_LIST_HEAD(&cdata->list);
	cdata->cdev = cdev;
	cdata->client = client;

	for (i = 0; i < cdata->ports.nports; i++)
		NDEV2CDATA(cdata->ports.lldevs[i]) = cdata;

	write_lock(&cdata_rwlock);
	list_add_tail(&cdata->list, &cdata_list);
	write_unlock(&cdata_rwlock);

	cxgb3i_log_info("t3dev 0x%p, offload up, added.\n", cdev);
	return;

free_cdata:
	cxgb3i_free_big_mem(cdata);
}

/**
 * cxgb3i_sdev_remove - free the allocated resources for the adapter
 * @cdev:	t3cdev adapter
 */
void cxgb3i_sdev_remove(struct t3cdev *cdev)
{
	struct cxgb3i_sdev_data *cdata = CXGB3_SDEV_DATA(cdev);

	cxgb3i_log_info("t3dev 0x%p, offload down, remove.\n", cdev);

	write_lock(&cdata_rwlock);
	list_del(&cdata->list);
	write_unlock(&cdata_rwlock);

	sdev_data_cleanup(cdata);
}
