/*
 * 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(__be32 saddr, __be32 daddr,
				 __be16 sport, __be16 dport)
{
	struct rtable *rt;
	struct flowi fl = {
		.oif = 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 s3_conn *c3cn, struct sockaddr_in *usin)
{
	struct rtable *rt;
	struct net_device *dev;
	struct cxgb3i_sdev_data *cdata;
	struct t3cdev *cdev;
	__be32 sipv4;
	int err;

	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(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.\n",
				c3cn->daddr.sin_addr.s_addr,
				ntohs(c3cn->daddr.sin_port));
		return -ENETUNREACH;
	}

	if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) {
		c3cn_conn_debug("multi-cast route to 0x%x, port %u.\n",
				c3cn->daddr.sin_addr.s_addr,
				ntohs(c3cn->daddr.sin_port));
		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);
}
