{
__be32 *wqe = wqe_ptr;
- UNREFERENCED_PARAMETER(qp_ptr);
+ UNUSED_PARAM_WOWPP(qp_ptr);
+ UNUSED_PARAM_WOWPP(print_lvl);
(void) wqe; /* avoid warning if mthca_dbg compiled away... */
HCA_PRINT(print_lvl,HCA_DBG_QP,("WQE contents QPN 0x%06x \n",qp_ptr->qpn));
return max_data_size;
}
-static inline int mthca_max_inline_data(struct mthca_pd *pd, int max_data_size)
+static inline int mthca_max_inline_data(int max_data_size)
{
- /* We don't support inline data for kernel QPs (yet). */
- return pd->ibpd.ucontext ? max_data_size - MTHCA_INLINE_HEADER_SIZE : 0;
+ return max_data_size - MTHCA_INLINE_HEADER_SIZE ;
}
static void mthca_adjust_qp_caps(struct mthca_dev *dev,
- struct mthca_pd *pd,
struct mthca_qp *qp)
{
int max_data_size = mthca_max_data_size(dev, qp,
min(dev->limits.max_desc_sz, 1 << qp->sq.wqe_shift));
- qp->max_inline_data = mthca_max_inline_data(pd, max_data_size);
+ qp->max_inline_data = mthca_max_inline_data( max_data_size);
qp->sq.max_gs = min(dev->limits.max_sg,
(int)(max_data_size / sizeof (struct mthca_data_seg)));
return ret;
}
- mthca_adjust_qp_caps(dev, pd, qp);
+ mthca_adjust_qp_caps(dev, qp);
/*
* If this is a userspace QP, we're done now. The doorbells
}
static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap,
- struct mthca_pd *pd, struct mthca_qp *qp)
+ struct mthca_qp *qp)
{
int max_data_size = mthca_max_data_size(dev, qp, dev->limits.max_desc_sz);
cap->max_recv_wr > (u32)dev->limits.max_wqes ||
cap->max_send_sge > (u32)dev->limits.max_sg ||
cap->max_recv_sge > (u32)dev->limits.max_sg ||
- cap->max_inline_data > (u32)mthca_max_inline_data(pd, max_data_size))
+ cap->max_inline_data > (u32)mthca_max_inline_data(max_data_size))
return -EINVAL;
/*
default: return -EINVAL;
}
- err = mthca_set_qp_size(dev, cap, pd, qp);
+ err = mthca_set_qp_size(dev, cap, qp);
if (err)
return err;
SPIN_LOCK_PREP(lhr);
SPIN_LOCK_PREP(lht);
- err = mthca_set_qp_size(dev, cap, pd, &sqp->qp);
+ err = mthca_set_qp_size(dev, cap, &sqp->qp);
if (err)
return err;
return 0;
cq = to_mcq(ib_cq);
- spin_lock(&cq->lock, &lh);
+ spin_lock_dpc(&cq->lock, &lh);
cur = wq->head - wq->tail;
- spin_unlock(&lh);
+ spin_unlock_dpc(&lh);
return (int)cur + nreq >= wq->max;
}
int ind;
u8 op0 = 0;
enum ib_wr_opcode opcode;
- SPIN_LOCK_PREP(lh);
+ SPIN_LOCK_PREP(lh);
spin_lock_irqsave(&qp->sq.lock, &lh);
-
+
/* XXX check that state is OK to post send */
ind = qp->sq.next_ind;
*bad_wr = wr;
goto out;
}
+ if (wr->send_opt & IB_SEND_OPT_INLINE) {
+ if (wr->num_ds) {
+ struct mthca_inline_seg *seg = (struct mthca_inline_seg *)wqe;
+ uint32_t s = 0;
+
+ wqe += sizeof *seg;
+ for (i = 0; i < (int)wr->num_ds; ++i) {
+ struct _ib_local_ds *sge = &wr->ds_array[i];
+
+ s += sge->length;
+
+ if (s > (uint32_t)qp->max_inline_data) {
+ err = -EINVAL;
+ if (bad_wr)
+ *bad_wr = wr;
+ goto out;
+ }
+
+ memcpy(wqe, (void *) (ULONG_PTR) sge->vaddr,
+ sge->length);
+ wqe += sge->length;
+ }
- for (i = 0; i < (int)wr->num_ds; ++i) {
- ((struct mthca_data_seg *) wqe)->byte_count =
- cl_hton32(wr->ds_array[i].length);
- ((struct mthca_data_seg *) wqe)->lkey =
- cl_hton32(wr->ds_array[i].lkey);
- ((struct mthca_data_seg *) wqe)->addr =
- cl_hton64(wr->ds_array[i].vaddr);
- wqe += sizeof (struct mthca_data_seg);
- size += sizeof (struct mthca_data_seg) / 16;
- HCA_PRINT(TRACE_LEVEL_VERBOSE ,HCA_DBG_QP ,("SQ %06x [%02x] lkey 0x%08x vaddr 0x%I64x 0x%x\n",qp->qpn,i,
- (wr->ds_array[i].lkey),(wr->ds_array[i].vaddr),wr->ds_array[i].length));
- }
+ seg->byte_count = cl_hton32(MTHCA_INLINE_SEG | s);
+ size += align(s + sizeof *seg, 16) / 16;
+ }
+ } else {
+
+ for (i = 0; i < (int)wr->num_ds; ++i) {
+ ((struct mthca_data_seg *) wqe)->byte_count =
+ cl_hton32(wr->ds_array[i].length);
+ ((struct mthca_data_seg *) wqe)->lkey =
+ cl_hton32(wr->ds_array[i].lkey);
+ ((struct mthca_data_seg *) wqe)->addr =
+ cl_hton64(wr->ds_array[i].vaddr);
+ wqe += sizeof (struct mthca_data_seg);
+ size += sizeof (struct mthca_data_seg) / 16;
+ HCA_PRINT(TRACE_LEVEL_VERBOSE ,HCA_DBG_QP ,("SQ %06x [%02x] lkey 0x%08x vaddr 0x%I64x 0x%x\n",qp->qpn,i,
+ (wr->ds_array[i].lkey),(wr->ds_array[i].vaddr),wr->ds_array[i].length));
+ }
+ }
/* Add one more inline data segment for ICRC */
if (qp->transport == MLX) {
qp->sq.next_ind = ind;
qp->sq.head += nreq;
-
- spin_unlock_irqrestore(&lh);
+
+ spin_unlock_irqrestore(&lh);
return err;
}
*bad_wr = wr;
goto out;
}
+ if (wr->send_opt & IB_SEND_OPT_INLINE) {
+ if (wr->num_ds) {
+ struct mthca_inline_seg *seg = (struct mthca_inline_seg *)wqe;
+ uint32_t s = 0;
+
+ wqe += sizeof *seg;
+ for (i = 0; i < (int)wr->num_ds; ++i) {
+ struct _ib_local_ds *sge = &wr->ds_array[i];
+
+ s += sge->length;
+
+ if (s > (uint32_t)qp->max_inline_data) {
+ err = -EINVAL;
+ if (bad_wr)
+ *bad_wr = wr;
+ goto out;
+ }
+
+ memcpy(wqe, (void *) (uintptr_t) sge->vaddr,
+ sge->length);
+ wqe += sge->length;
+ }
- for (i = 0; i < (int)wr->num_ds; ++i) {
- ((struct mthca_data_seg *) wqe)->byte_count =
- cl_hton32(wr->ds_array[i].length);
- ((struct mthca_data_seg *) wqe)->lkey =
- cl_hton32(wr->ds_array[i].lkey);
- ((struct mthca_data_seg *) wqe)->addr =
- cl_hton64(wr->ds_array[i].vaddr);
- wqe += sizeof (struct mthca_data_seg);
- size += sizeof (struct mthca_data_seg) / 16;
- }
+ seg->byte_count = cl_hton32(MTHCA_INLINE_SEG | s);
+ size += align(s + sizeof *seg, 16) / 16;
+ }
+ } else {
+ for (i = 0; i < (int)wr->num_ds; ++i) {
+ ((struct mthca_data_seg *) wqe)->byte_count =
+ cl_hton32(wr->ds_array[i].length);
+ ((struct mthca_data_seg *) wqe)->lkey =
+ cl_hton32(wr->ds_array[i].lkey);
+ ((struct mthca_data_seg *) wqe)->addr =
+ cl_hton64(wr->ds_array[i].vaddr);
+ wqe += sizeof (struct mthca_data_seg);
+ size += sizeof (struct mthca_data_seg) / 16;
+ }
+ }
/* Add one more inline data segment for ICRC */
if (qp->transport == MLX) {