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

#include <linux/delay.h>

#include "c2.h"
#include "c2_vq.h"
#include "c2_status.h"

#define C2_MAX_ORD_PER_QP 128
#define C2_MAX_IRD_PER_QP 128

#define C2_HINT_MAKE(q_index, hint_count) (((q_index) << 16) | hint_count)
#define C2_HINT_GET_INDEX(hint) (((hint) & 0x7FFF0000) >> 16)
#define C2_HINT_GET_COUNT(hint) ((hint) & 0x0000FFFF)

#define NO_SUPPORT -1
static const u8 c2_opcode[] = {
	[IB_WR_SEND] = C2_WR_TYPE_SEND,
	[IB_WR_SEND_WITH_IMM] = NO_SUPPORT,
	[IB_WR_RDMA_WRITE] = C2_WR_TYPE_RDMA_WRITE,
	[IB_WR_RDMA_WRITE_WITH_IMM] = NO_SUPPORT,
	[IB_WR_RDMA_READ] = C2_WR_TYPE_RDMA_READ,
	[IB_WR_ATOMIC_CMP_AND_SWP] = NO_SUPPORT,
	[IB_WR_ATOMIC_FETCH_AND_ADD] = NO_SUPPORT,
};

static int to_c2_state(enum ib_qp_state ib_state)
{
	switch (ib_state) {
	case IB_QPS_RESET:
		return C2_QP_STATE_IDLE;
	case IB_QPS_RTS:
		return C2_QP_STATE_RTS;
	case IB_QPS_SQD:
		return C2_QP_STATE_CLOSING;
	case IB_QPS_SQE:
		return C2_QP_STATE_CLOSING;
	case IB_QPS_ERR:
		return C2_QP_STATE_ERROR;
	default:
		return -1;
	}
}

static int to_ib_state(enum c2_qp_state c2_state)
{
	switch (c2_state) {
	case C2_QP_STATE_IDLE:
		return IB_QPS_RESET;
	case C2_QP_STATE_CONNECTING:
		return IB_QPS_RTR;
	case C2_QP_STATE_RTS:
		return IB_QPS_RTS;
	case C2_QP_STATE_CLOSING:
		return IB_QPS_SQD;
	case C2_QP_STATE_ERROR:
		return IB_QPS_ERR;
	case C2_QP_STATE_TERMINATE:
		return IB_QPS_SQE;
	default:
		return -1;
	}
}

static const char *to_ib_state_str(int ib_state)
{
	static const char *state_str[] = {
		"IB_QPS_RESET",
		"IB_QPS_INIT",
		"IB_QPS_RTR",
		"IB_QPS_RTS",
		"IB_QPS_SQD",
		"IB_QPS_SQE",
		"IB_QPS_ERR"
	};
	if (ib_state < IB_QPS_RESET ||
	    ib_state > IB_QPS_ERR)
		return "<invalid IB QP state>";

	ib_state -= IB_QPS_RESET;
	return state_str[ib_state];
}

void c2_set_qp_state(struct c2_qp *qp, int c2_state)
{
	int new_state = to_ib_state(c2_state);

	pr_debug("%s: qp[%p] state modify %s --> %s\n",
	       __FUNCTION__,
		qp,
		to_ib_state_str(qp->state),
		to_ib_state_str(new_state));
	qp->state = new_state;
}

#define C2_QP_NO_ATTR_CHANGE 0xFFFFFFFF

int c2_qp_modify(struct c2_dev *c2dev, struct c2_qp *qp,
		 struct ib_qp_attr *attr, int attr_mask)
{
	struct c2wr_qp_modify_req wr;
	struct c2wr_qp_modify_rep *reply;
	struct c2_vq_req *vq_req;
	unsigned long flags;
	u8 next_state;
	int err;

	pr_debug("%s:%d qp=%p, %s --> %s\n",
		__FUNCTION__, __LINE__,
		qp,
		to_ib_state_str(qp->state),
		to_ib_state_str(attr->qp_state));

	vq_req = vq_req_alloc(c2dev);
	if (!vq_req)
		return -ENOMEM;

	c2_wr_set_id(&wr, CCWR_QP_MODIFY);
	wr.hdr.context = (unsigned long) vq_req;
	wr.rnic_handle = c2dev->adapter_handle;
	wr.qp_handle = qp->adapter_handle;
	wr.ord = cpu_to_be32(C2_QP_NO_ATTR_CHANGE);
	wr.ird = cpu_to_be32(C2_QP_NO_ATTR_CHANGE);
	wr.sq_depth = cpu_to_be32(C2_QP_NO_ATTR_CHANGE);
	wr.rq_depth = cpu_to_be32(C2_QP_NO_ATTR_CHANGE);

	if (attr_mask & IB_QP_STATE) {
		/* Ensure the state is valid */
		if (attr->qp_state < 0 || attr->qp_state > IB_QPS_ERR) {
			err = -EINVAL;
			goto bail0;
		}

		wr.next_qp_state = cpu_to_be32(to_c2_state(attr->qp_state));

		if (attr->qp_state == IB_QPS_ERR) {
			spin_lock_irqsave(&qp->lock, flags);
			if (qp->cm_id && qp->state == IB_QPS_RTS) {
				pr_debug("Generating CLOSE event for QP-->ERR, "
					"qp=%p, cm_id=%p\n",qp,qp->cm_id);
				/* Generate an CLOSE event */
				vq_req->cm_id = qp->cm_id;
				vq_req->event = IW_CM_EVENT_CLOSE;
			}
			spin_unlock_irqrestore(&qp->lock, flags);
		}
		next_state =  attr->qp_state;

	} else if (attr_mask & IB_QP_CUR_STATE) {

		if (attr->cur_qp_state != IB_QPS_RTR &&
		    attr->cur_qp_state != IB_QPS_RTS &&
		    attr->cur_qp_state != IB_QPS_SQD &&
		    attr->cur_qp_state != IB_QPS_SQE) {
			err = -EINVAL;
			goto bail0;
		} else
			wr.next_qp_state =
			    cpu_to_be32(to_c2_state(attr->cur_qp_state));

		next_state = attr->cur_qp_state;

	} else {
		err = 0;
		goto bail0;
	}

	/* reference the request struct */
	vq_req_get(c2dev, vq_req);

	err = vq_send_wr(c2dev, (union c2wr *) & wr);
	if (err) {
		vq_req_put(c2dev, vq_req);
		goto bail0;
	}

	err = vq_wait_for_reply(c2dev, vq_req);
	if (err)
		goto bail0;

	reply = (struct c2wr_qp_modify_rep *) (unsigned long) vq_req->reply_msg;
	if (!reply) {
		err = -ENOMEM;
		goto bail0;
	}

	err = c2_errno(reply);
	if (!err)
		qp->state = next_state;
#ifdef DEBUG
	else
		pr_debug("%s: c2_errno=%d\n", __FUNCTION__, err);
#endif
	/*
	 * If we're going to error and generating the event here, then
	 * we need to remove the reference because there will be no
	 * close event generated by the adapter
	*/
	spin_lock_irqsave(&qp->lock, flags);
	if (vq_req->event==IW_CM_EVENT_CLOSE && qp->cm_id) {
		qp->cm_id->rem_ref(qp->cm_id);
		qp->cm_id = NULL;
	}
	spin_unlock_irqrestore(&qp->lock, flags);

	vq_repbuf_free(c2dev, reply);
      bail0:
	vq_req_free(c2dev, vq_req);

	pr_debug("%s:%d qp=%p, cur_state=%s\n",
		__FUNCTION__, __LINE__,
		qp,
		to_ib_state_str(qp->state));
	return err;
}

int c2_qp_set_read_limits(struct c2_dev *c2dev, struct c2_qp *qp,
			  int ord, int ird)
{
	struct c2wr_qp_modify_req wr;
	struct c2wr_qp_modify_rep *reply;
	struct c2_vq_req *vq_req;
	int err;

	vq_req = vq_req_alloc(c2dev);
	if (!vq_req)
		return -ENOMEM;

	c2_wr_set_id(&wr, CCWR_QP_MODIFY);
	wr.hdr.context = (unsigned long) vq_req;
	wr.rnic_handle = c2dev->adapter_handle;
	wr.qp_handle = qp->adapter_handle;
	wr.ord = cpu_to_be32(ord);
	wr.ird = cpu_to_be32(ird);
	wr.sq_depth = cpu_to_be32(C2_QP_NO_ATTR_CHANGE);
	wr.rq_depth = cpu_to_be32(C2_QP_NO_ATTR_CHANGE);
	wr.next_qp_state = cpu_to_be32(C2_QP_NO_ATTR_CHANGE);

	/* reference the request struct */
	vq_req_get(c2dev, vq_req);

	err = vq_send_wr(c2dev, (union c2wr *) & wr);
	if (err) {
		vq_req_put(c2dev, vq_req);
		goto bail0;
	}

	err = vq_wait_for_reply(c2dev, vq_req);
	if (err)
		goto bail0;

	reply = (struct c2wr_qp_modify_rep *) (unsigned long)
		vq_req->reply_msg;
	if (!reply) {
		err = -ENOMEM;
		goto bail0;
	}

	err = c2_errno(reply);
	vq_repbuf_free(c2dev, reply);
      bail0:
	vq_req_free(c2dev, vq_req);
	return err;
}

static int destroy_qp(struct c2_dev *c2dev, struct c2_qp *qp)
{
	struct c2_vq_req *vq_req;
	struct c2wr_qp_destroy_req wr;
	struct c2wr_qp_destroy_rep *reply;
	unsigned long flags;
	int err;

	/*
	 * Allocate a verb request message
	 */
	vq_req = vq_req_alloc(c2dev);
	if (!vq_req) {
		return -ENOMEM;
	}

	/*
	 * Initialize the WR
	 */
	c2_wr_set_id(&wr, CCWR_QP_DESTROY);
	wr.hdr.context = (unsigned long) vq_req;
	wr.rnic_handle = c2dev->adapter_handle;
	wr.qp_handle = qp->adapter_handle;

	/*
	 * reference the request struct.  dereferenced in the int handler.
	 */
	vq_req_get(c2dev, vq_req);

	spin_lock_irqsave(&qp->lock, flags);
	if (qp->cm_id && qp->state == IB_QPS_RTS) {
		pr_debug("destroy_qp: generating CLOSE event for QP-->ERR, "
			"qp=%p, cm_id=%p\n",qp,qp->cm_id);
		/* Generate an CLOSE event */
		vq_req->qp = qp;
		vq_req->cm_id = qp->cm_id;
		vq_req->event = IW_CM_EVENT_CLOSE;
	}
	spin_unlock_irqrestore(&qp->lock, flags);

	/*
	 * Send WR to adapter
	 */
	err = vq_send_wr(c2dev, (union c2wr *) & wr);
	if (err) {
		vq_req_put(c2dev, vq_req);
		goto bail0;
	}

	/*
	 * Wait for reply from adapter
	 */
	err = vq_wait_for_reply(c2dev, vq_req);
	if (err) {
		goto bail0;
	}

	/*
	 * Process reply
	 */
	reply = (struct c2wr_qp_destroy_rep *) (unsigned long) (vq_req->reply_msg);
	if (!reply) {
		err = -ENOMEM;
		goto bail0;
	}

	spin_lock_irqsave(&qp->lock, flags);
	if (qp->cm_id) {
		qp->cm_id->rem_ref(qp->cm_id);
		qp->cm_id = NULL;
	}
	spin_unlock_irqrestore(&qp->lock, flags);

	vq_repbuf_free(c2dev, reply);
      bail0:
	vq_req_free(c2dev, vq_req);
	return err;
}

static int c2_alloc_qpn(struct c2_dev *c2dev, struct c2_qp *qp)
{
	int ret;

        do {
		spin_lock_irq(&c2dev->qp_table.lock);
		ret = idr_get_new_above(&c2dev->qp_table.idr, qp,
					c2dev->qp_table.last++, &qp->qpn);
		spin_unlock_irq(&c2dev->qp_table.lock);
        } while ((ret == -EAGAIN) &&
	 	 idr_pre_get(&c2dev->qp_table.idr, GFP_KERNEL));
	return ret;
}

static void c2_free_qpn(struct c2_dev *c2dev, int qpn)
{
	spin_lock_irq(&c2dev->qp_table.lock);
	idr_remove(&c2dev->qp_table.idr, qpn);
	spin_unlock_irq(&c2dev->qp_table.lock);
}

struct c2_qp *c2_find_qpn(struct c2_dev *c2dev, int qpn)
{
	unsigned long flags;
	struct c2_qp *qp;

	spin_lock_irqsave(&c2dev->qp_table.lock, flags);
	qp = idr_find(&c2dev->qp_table.idr, qpn);
	spin_unlock_irqrestore(&c2dev->qp_table.lock, flags);
	return qp;
}

int c2_alloc_qp(struct c2_dev *c2dev,
		struct c2_pd *pd,
		struct ib_qp_init_attr *qp_attrs, struct c2_qp *qp)
{
	struct c2wr_qp_create_req wr;
	struct c2wr_qp_create_rep *reply;
	struct c2_vq_req *vq_req;
	struct c2_cq *send_cq = to_c2cq(qp_attrs->send_cq);
	struct c2_cq *recv_cq = to_c2cq(qp_attrs->recv_cq);
	unsigned long peer_pa;
	u32 q_size, msg_size, mmap_size;
	void __iomem *mmap;
	int err;

	err = c2_alloc_qpn(c2dev, qp);
	if (err)
		return err;
	qp->ibqp.qp_num = qp->qpn;
	qp->ibqp.qp_type = IB_QPT_RC;

	/* Allocate the SQ and RQ shared pointers */
	qp->sq_mq.shared = c2_alloc_mqsp(c2dev, c2dev->kern_mqsp_pool,
					 &qp->sq_mq.shared_dma, GFP_KERNEL);
	if (!qp->sq_mq.shared) {
		err = -ENOMEM;
		goto bail0;
	}

	qp->rq_mq.shared = c2_alloc_mqsp(c2dev, c2dev->kern_mqsp_pool,
					 &qp->rq_mq.shared_dma, GFP_KERNEL);
	if (!qp->rq_mq.shared) {
		err = -ENOMEM;
		goto bail1;
	}

	/* Allocate the verbs request */
	vq_req = vq_req_alloc(c2dev);
	if (vq_req == NULL) {
		err = -ENOMEM;
		goto bail2;
	}

	/* Initialize the work request */
	memset(&wr, 0, sizeof(wr));
	c2_wr_set_id(&wr, CCWR_QP_CREATE);
	wr.hdr.context = (unsigned long) vq_req;
	wr.rnic_handle = c2dev->adapter_handle;
	wr.sq_cq_handle = send_cq->adapter_handle;
	wr.rq_cq_handle = recv_cq->adapter_handle;
	wr.sq_depth = cpu_to_be32(qp_attrs->cap.max_send_wr + 1);
	wr.rq_depth = cpu_to_be32(qp_attrs->cap.max_recv_wr + 1);
	wr.srq_handle = 0;
	wr.flags = cpu_to_be32(QP_RDMA_READ | QP_RDMA_WRITE | QP_MW_BIND |
			       QP_ZERO_STAG | QP_RDMA_READ_RESPONSE);
	wr.send_sgl_depth = cpu_to_be32(qp_attrs->cap.max_send_sge);
	wr.recv_sgl_depth = cpu_to_be32(qp_attrs->cap.max_recv_sge);
	wr.rdma_write_sgl_depth = cpu_to_be32(qp_attrs->cap.max_send_sge);
	wr.shared_sq_ht = cpu_to_be64(qp->sq_mq.shared_dma);
	wr.shared_rq_ht = cpu_to_be64(qp->rq_mq.shared_dma);
	wr.ord = cpu_to_be32(C2_MAX_ORD_PER_QP);
	wr.ird = cpu_to_be32(C2_MAX_IRD_PER_QP);
	wr.pd_id = pd->pd_id;
	wr.user_context = (unsigned long) qp;

	vq_req_get(c2dev, vq_req);

	/* Send the WR to the adapter */
	err = vq_send_wr(c2dev, (union c2wr *) & wr);
	if (err) {
		vq_req_put(c2dev, vq_req);
		goto bail3;
	}

	/* Wait for the verb reply  */
	err = vq_wait_for_reply(c2dev, vq_req);
	if (err) {
		goto bail3;
	}

	/* Process the reply */
	reply = (struct c2wr_qp_create_rep *) (unsigned long) (vq_req->reply_msg);
	if (!reply) {
		err = -ENOMEM;
		goto bail3;
	}

	if ((err = c2_wr_get_result(reply)) != 0) {
		goto bail4;
	}

	/* Fill in the kernel QP struct */
	atomic_set(&qp->refcount, 1);
	qp->adapter_handle = reply->qp_handle;
	qp->state = IB_QPS_RESET;
	qp->send_sgl_depth = qp_attrs->cap.max_send_sge;
	qp->rdma_write_sgl_depth = qp_attrs->cap.max_send_sge;
	qp->recv_sgl_depth = qp_attrs->cap.max_recv_sge;

	/* Initialize the SQ MQ */
	q_size = be32_to_cpu(reply->sq_depth);
	msg_size = be32_to_cpu(reply->sq_msg_size);
	peer_pa = c2dev->pa + be32_to_cpu(reply->sq_mq_start);
	mmap_size = PAGE_ALIGN(sizeof(struct c2_mq_shared) + msg_size * q_size);
	mmap = ioremap_nocache(peer_pa, mmap_size);
	if (!mmap) {
		err = -ENOMEM;
		goto bail5;
	}

	c2_mq_req_init(&qp->sq_mq,
		       be32_to_cpu(reply->sq_mq_index),
		       q_size,
		       msg_size,
		       mmap + sizeof(struct c2_mq_shared),	/* pool start */
		       mmap,				/* peer */
		       C2_MQ_ADAPTER_TARGET);

	/* Initialize the RQ mq */
	q_size = be32_to_cpu(reply->rq_depth);
	msg_size = be32_to_cpu(reply->rq_msg_size);
	peer_pa = c2dev->pa + be32_to_cpu(reply->rq_mq_start);
	mmap_size = PAGE_ALIGN(sizeof(struct c2_mq_shared) + msg_size * q_size);
	mmap = ioremap_nocache(peer_pa, mmap_size);
	if (!mmap) {
		err = -ENOMEM;
		goto bail6;
	}

	c2_mq_req_init(&qp->rq_mq,
		       be32_to_cpu(reply->rq_mq_index),
		       q_size,
		       msg_size,
		       mmap + sizeof(struct c2_mq_shared),	/* pool start */
		       mmap,				/* peer */
		       C2_MQ_ADAPTER_TARGET);

	vq_repbuf_free(c2dev, reply);
	vq_req_free(c2dev, vq_req);

	return 0;

      bail6:
	iounmap(qp->sq_mq.peer);
      bail5:
	destroy_qp(c2dev, qp);
      bail4:
	vq_repbuf_free(c2dev, reply);
      bail3:
	vq_req_free(c2dev, vq_req);
      bail2:
	c2_free_mqsp(qp->rq_mq.shared);
      bail1:
	c2_free_mqsp(qp->sq_mq.shared);
      bail0:
	c2_free_qpn(c2dev, qp->qpn);
	return err;
}

static inline void c2_lock_cqs(struct c2_cq *send_cq, struct c2_cq *recv_cq)
{
	if (send_cq == recv_cq)
		spin_lock_irq(&send_cq->lock);
	else if (send_cq > recv_cq) {
		spin_lock_irq(&send_cq->lock);
		spin_lock_nested(&recv_cq->lock, SINGLE_DEPTH_NESTING);
	} else {
		spin_lock_irq(&recv_cq->lock);
		spin_lock_nested(&send_cq->lock, SINGLE_DEPTH_NESTING);
	}
}

static inline void c2_unlock_cqs(struct c2_cq *send_cq, struct c2_cq *recv_cq)
{
	if (send_cq == recv_cq)
		spin_unlock_irq(&send_cq->lock);
	else if (send_cq > recv_cq) {
		spin_unlock(&recv_cq->lock);
		spin_unlock_irq(&send_cq->lock);
	} else {
		spin_unlock(&send_cq->lock);
		spin_unlock_irq(&recv_cq->lock);
	}
}

void c2_free_qp(struct c2_dev *c2dev, struct c2_qp *qp)
{
	struct c2_cq *send_cq;
	struct c2_cq *recv_cq;

	send_cq = to_c2cq(qp->ibqp.send_cq);
	recv_cq = to_c2cq(qp->ibqp.recv_cq);

	/*
	 * Lock CQs here, so that CQ polling code can do QP lookup
	 * without taking a lock.
	 */
	c2_lock_cqs(send_cq, recv_cq);
	c2_free_qpn(c2dev, qp->qpn);
	c2_unlock_cqs(send_cq, recv_cq);

	/*
	 * Destory qp in the rnic...
	 */
	destroy_qp(c2dev, qp);

	/*
	 * Mark any unreaped CQEs as null and void.
	 */
	c2_cq_clean(c2dev, qp, send_cq->cqn);
	if (send_cq != recv_cq)
		c2_cq_clean(c2dev, qp, recv_cq->cqn);
	/*
	 * Unmap the MQs and return the shared pointers
	 * to the message pool.
	 */
	iounmap(qp->sq_mq.peer);
	iounmap(qp->rq_mq.peer);
	c2_free_mqsp(qp->sq_mq.shared);
	c2_free_mqsp(qp->rq_mq.shared);

	atomic_dec(&qp->refcount);
	wait_event(qp->wait, !atomic_read(&qp->refcount));
}

/*
 * Function: move_sgl
 *
 * Description:
 * Move an SGL from the user's work request struct into a CCIL Work Request
 * message, swapping to WR byte order and ensure the total length doesn't
 * overflow.
 *
 * IN:
 * dst		- ptr to CCIL Work Request message SGL memory.
 * src		- ptr to the consumers SGL memory.
 *
 * OUT: none
 *
 * Return:
 * CCIL status codes.
 */
static int
move_sgl(struct c2_data_addr * dst, struct ib_sge *src, int count, u32 * p_len,
	 u8 * actual_count)
{
	u32 tot = 0;		/* running total */
	u8 acount = 0;		/* running total non-0 len sge's */

	while (count > 0) {
		/*
		 * If the addition of this SGE causes the
		 * total SGL length to exceed 2^32-1, then
		 * fail-n-bail.
		 *
		 * If the current total plus the next element length
		 * wraps, then it will go negative and be less than the
		 * current total...
		 */
		if ((tot + src->length) < tot) {
			return -EINVAL;
		}
		/*
		 * Bug: 1456 (as well as 1498 & 1643)
		 * Skip over any sge's supplied with len=0
		 */
		if (src->length) {
			tot += src->length;
			dst->stag = cpu_to_be32(src->lkey);
			dst->to = cpu_to_be64(src->addr);
			dst->length = cpu_to_be32(src->length);
			dst++;
			acount++;
		}
		src++;
		count--;
	}

	if (acount == 0) {
		/*
		 * Bug: 1476 (as well as 1498, 1456 and 1643)
		 * Setup the SGL in the WR to make it easier for the RNIC.
		 * This way, the FW doesn't have to deal with special cases.
		 * Setting length=0 should be sufficient.
		 */
		dst->stag = 0;
		dst->to = 0;
		dst->length = 0;
	}

	*p_len = tot;
	*actual_count = acount;
	return 0;
}

/*
 * Function: c2_activity (private function)
 *
 * Description:
 * Post an mq index to the host->adapter activity fifo.
 *
 * IN:
 * c2dev	- ptr to c2dev structure
 * mq_index	- mq index to post
 * shared	- value most recently written to shared
 *
 * OUT:
 *
 * Return:
 * none
 */
static inline void c2_activity(struct c2_dev *c2dev, u32 mq_index, u16 shared)
{
	/*
	 * First read the register to see if the FIFO is full, and if so,
	 * spin until it's not.  This isn't perfect -- there is no
	 * synchronization among the clients of the register, but in
	 * practice it prevents multiple CPU from hammering the bus
	 * with PCI RETRY. Note that when this does happen, the card
	 * cannot get on the bus and the card and system hang in a
	 * deadlock -- thus the need for this code. [TOT]
	 */
	while (readl(c2dev->regs + PCI_BAR0_ADAPTER_HINT) & 0x80000000)
		udelay(10);

	__raw_writel(C2_HINT_MAKE(mq_index, shared),
		     c2dev->regs + PCI_BAR0_ADAPTER_HINT);
}

/*
 * Function: qp_wr_post
 *
 * Description:
 * This in-line function allocates a MQ msg, then moves the host-copy of
 * the completed WR into msg.  Then it posts the message.
 *
 * IN:
 * q		- ptr to user MQ.
 * wr		- ptr to host-copy of the WR.
 * qp		- ptr to user qp
 * size		- Number of bytes to post.  Assumed to be divisible by 4.
 *
 * OUT: none
 *
 * Return:
 * CCIL status codes.
 */
static int qp_wr_post(struct c2_mq *q, union c2wr * wr, struct c2_qp *qp, u32 size)
{
	union c2wr *msg;

	msg = c2_mq_alloc(q);
	if (msg == NULL) {
		return -EINVAL;
	}
#ifdef CCMSGMAGIC
	((c2wr_hdr_t *) wr)->magic = cpu_to_be32(CCWR_MAGIC);
#endif

	/*
	 * Since all header fields in the WR are the same as the
	 * CQE, set the following so the adapter need not.
	 */
	c2_wr_set_result(wr, CCERR_PENDING);

	/*
	 * Copy the wr down to the adapter
	 */
	memcpy((void *) msg, (void *) wr, size);

	c2_mq_produce(q);
	return 0;
}


int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,
		 struct ib_send_wr **bad_wr)
{
	struct c2_dev *c2dev = to_c2dev(ibqp->device);
	struct c2_qp *qp = to_c2qp(ibqp);
	union c2wr wr;
	unsigned long lock_flags;
	int err = 0;

	u32 flags;
	u32 tot_len;
	u8 actual_sge_count;
	u32 msg_size;

	if (qp->state > IB_QPS_RTS)
		return -EINVAL;

	while (ib_wr) {

		flags = 0;
		wr.sqwr.sq_hdr.user_hdr.hdr.context = ib_wr->wr_id;
		if (ib_wr->send_flags & IB_SEND_SIGNALED) {
			flags |= SQ_SIGNALED;
		}

		switch (ib_wr->opcode) {
		case IB_WR_SEND:
			if (ib_wr->send_flags & IB_SEND_SOLICITED) {
				c2_wr_set_id(&wr, C2_WR_TYPE_SEND_SE);
				msg_size = sizeof(struct c2wr_send_req);
			} else {
				c2_wr_set_id(&wr, C2_WR_TYPE_SEND);
				msg_size = sizeof(struct c2wr_send_req);
			}

			wr.sqwr.send.remote_stag = 0;
			msg_size += sizeof(struct c2_data_addr) * ib_wr->num_sge;
			if (ib_wr->num_sge > qp->send_sgl_depth) {
				err = -EINVAL;
				break;
			}
			if (ib_wr->send_flags & IB_SEND_FENCE) {
				flags |= SQ_READ_FENCE;
			}
			err = move_sgl((struct c2_data_addr *) & (wr.sqwr.send.data),
				       ib_wr->sg_list,
				       ib_wr->num_sge,
				       &tot_len, &actual_sge_count);
			wr.sqwr.send.sge_len = cpu_to_be32(tot_len);
			c2_wr_set_sge_count(&wr, actual_sge_count);
			break;
		case IB_WR_RDMA_WRITE:
			c2_wr_set_id(&wr, C2_WR_TYPE_RDMA_WRITE);
			msg_size = sizeof(struct c2wr_rdma_write_req) +
			    (sizeof(struct c2_data_addr) * ib_wr->num_sge);
			if (ib_wr->num_sge > qp->rdma_write_sgl_depth) {
				err = -EINVAL;
				break;
			}
			if (ib_wr->send_flags & IB_SEND_FENCE) {
				flags |= SQ_READ_FENCE;
			}
			wr.sqwr.rdma_write.remote_stag =
			    cpu_to_be32(ib_wr->wr.rdma.rkey);
			wr.sqwr.rdma_write.remote_to =
			    cpu_to_be64(ib_wr->wr.rdma.remote_addr);
			err = move_sgl((struct c2_data_addr *)
				       & (wr.sqwr.rdma_write.data),
				       ib_wr->sg_list,
				       ib_wr->num_sge,
				       &tot_len, &actual_sge_count);
			wr.sqwr.rdma_write.sge_len = cpu_to_be32(tot_len);
			c2_wr_set_sge_count(&wr, actual_sge_count);
			break;
		case IB_WR_RDMA_READ:
			c2_wr_set_id(&wr, C2_WR_TYPE_RDMA_READ);
			msg_size = sizeof(struct c2wr_rdma_read_req);

			/* IWarp only suppots 1 sge for RDMA reads */
			if (ib_wr->num_sge > 1) {
				err = -EINVAL;
				break;
			}

			/*
			 * Move the local and remote stag/to/len into the WR.
			 */
			wr.sqwr.rdma_read.local_stag =
			    cpu_to_be32(ib_wr->sg_list->lkey);
			wr.sqwr.rdma_read.local_to =
			    cpu_to_be64(ib_wr->sg_list->addr);
			wr.sqwr.rdma_read.remote_stag =
			    cpu_to_be32(ib_wr->wr.rdma.rkey);
			wr.sqwr.rdma_read.remote_to =
			    cpu_to_be64(ib_wr->wr.rdma.remote_addr);
			wr.sqwr.rdma_read.length =
			    cpu_to_be32(ib_wr->sg_list->length);
			break;
		default:
			/* error */
			msg_size = 0;
			err = -EINVAL;
			break;
		}

		/*
		 * If we had an error on the last wr build, then
		 * break out.  Possible errors include bogus WR
		 * type, and a bogus SGL length...
		 */
		if (err) {
			break;
		}

		/*
		 * Store flags
		 */
		c2_wr_set_flags(&wr, flags);

		/*
		 * Post the puppy!
		 */
		spin_lock_irqsave(&qp->lock, lock_flags);
		err = qp_wr_post(&qp->sq_mq, &wr, qp, msg_size);
		if (err) {
			spin_unlock_irqrestore(&qp->lock, lock_flags);
			break;
		}

		/*
		 * Enqueue mq index to activity FIFO.
		 */
		c2_activity(c2dev, qp->sq_mq.index, qp->sq_mq.hint_count);
		spin_unlock_irqrestore(&qp->lock, lock_flags);

		ib_wr = ib_wr->next;
	}

	if (err)
		*bad_wr = ib_wr;
	return err;
}

int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr,
		    struct ib_recv_wr **bad_wr)
{
	struct c2_dev *c2dev = to_c2dev(ibqp->device);
	struct c2_qp *qp = to_c2qp(ibqp);
	union c2wr wr;
	unsigned long lock_flags;
	int err = 0;

	if (qp->state > IB_QPS_RTS)
		return -EINVAL;

	/*
	 * Try and post each work request
	 */
	while (ib_wr) {
		u32 tot_len;
		u8 actual_sge_count;

		if (ib_wr->num_sge > qp->recv_sgl_depth) {
			err = -EINVAL;
			break;
		}

		/*
		 * Create local host-copy of the WR
		 */
		wr.rqwr.rq_hdr.user_hdr.hdr.context = ib_wr->wr_id;
		c2_wr_set_id(&wr, CCWR_RECV);
		c2_wr_set_flags(&wr, 0);

		/* sge_count is limited to eight bits. */
		BUG_ON(ib_wr->num_sge >= 256);
		err = move_sgl((struct c2_data_addr *) & (wr.rqwr.data),
			       ib_wr->sg_list,
			       ib_wr->num_sge, &tot_len, &actual_sge_count);
		c2_wr_set_sge_count(&wr, actual_sge_count);

		/*
		 * If we had an error on the last wr build, then
		 * break out.  Possible errors include bogus WR
		 * type, and a bogus SGL length...
		 */
		if (err) {
			break;
		}

		spin_lock_irqsave(&qp->lock, lock_flags);
		err = qp_wr_post(&qp->rq_mq, &wr, qp, qp->rq_mq.msg_size);
		if (err) {
			spin_unlock_irqrestore(&qp->lock, lock_flags);
			break;
		}

		/*
		 * Enqueue mq index to activity FIFO
		 */
		c2_activity(c2dev, qp->rq_mq.index, qp->rq_mq.hint_count);
		spin_unlock_irqrestore(&qp->lock, lock_flags);

		ib_wr = ib_wr->next;
	}

	if (err)
		*bad_wr = ib_wr;
	return err;
}

void __devinit c2_init_qp_table(struct c2_dev *c2dev)
{
	spin_lock_init(&c2dev->qp_table.lock);
	idr_init(&c2dev->qp_table.idr);
}

void __devexit c2_cleanup_qp_table(struct c2_dev *c2dev)
{
	idr_destroy(&c2dev->qp_table.idr);
}
