void c2_cq_clean(struct c2_dev *c2dev, struct c2_qp *qp, u32 mq_index) { struct c2_cq *cq; struct c2_mq *q; cq = c2_cq_get(c2dev, mq_index); if (!cq) return; spin_lock_irq(&cq->lock); q = &cq->mq; if (q && !c2_mq_empty(q)) { u16 priv = q->priv; struct c2wr_ce *msg; while (priv != be16_to_cpu(*q->shared)) { msg = (struct c2wr_ce *) (q->msg_pool.host + priv * q->msg_size); if (msg->qp_user_context == (u64) (unsigned long) qp) { msg->qp_user_context = (u64) 0; } priv = (priv + 1) % q->q_size; } } spin_unlock_irq(&cq->lock); c2_cq_put(cq); }
int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags notify_flags) { struct c2_mq_shared __iomem *shared; struct c2_cq *cq; unsigned long flags; int ret = 0; cq = to_c2cq(ibcq); shared = cq->mq.peer; if ((notify_flags & IB_CQ_SOLICITED_MASK) == IB_CQ_NEXT_COMP) writeb(C2_CQ_NOTIFICATION_TYPE_NEXT, &shared->notification_type); else if ((notify_flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED) writeb(C2_CQ_NOTIFICATION_TYPE_NEXT_SE, &shared->notification_type); else return -EINVAL; writeb(CQ_WAIT_FOR_DMA | CQ_ARMED, &shared->armed); /* * Now read back shared->armed to make the PCI * write synchronous. This is necessary for * correct cq notification semantics. */ readb(&shared->armed); if (notify_flags & IB_CQ_REPORT_MISSED_EVENTS) { spin_lock_irqsave(&cq->lock, flags); ret = !c2_mq_empty(&cq->mq); spin_unlock_irqrestore(&cq->lock, flags); } return ret; }
void c2_mq_lconsume(struct c2_mq *q, u32 wqe_count) { BUG_ON(q->magic != C2_MQ_MAGIC); BUG_ON(q->type != C2_MQ_ADAPTER_TARGET); while (wqe_count--) { BUG_ON(c2_mq_empty(q)); *q->shared = cpu_to_be16((be16_to_cpu(*q->shared)+1) % q->q_size); } }
void c2_mq_free(struct c2_mq *q) { BUG_ON(q->magic != C2_MQ_MAGIC); BUG_ON(q->type != C2_MQ_HOST_TARGET); if (!c2_mq_empty(q)) { #ifdef CCMSGMAGIC { struct c2wr_hdr __iomem *m = (struct c2wr_hdr __iomem *) (q->msg_pool.adapter + q->priv * q->msg_size); __raw_writel(cpu_to_be32(~CCWR_MAGIC), &m->magic); } #endif q->priv = (q->priv + 1) % q->q_size; /* Update peer's offset. */ __raw_writew((__force u16) cpu_to_be16(q->priv), &q->peer->shared); } }
void *c2_mq_consume(struct c2_mq *q) { BUG_ON(q->magic != C2_MQ_MAGIC); BUG_ON(q->type != C2_MQ_HOST_TARGET); if (c2_mq_empty(q)) { return NULL; } else { #ifdef DEBUG struct c2wr_hdr *m = (struct c2wr_hdr *) (q->msg_pool.host + q->priv * q->msg_size); #ifdef CCMSGMAGIC BUG_ON(m->magic != be32_to_cpu(CCWR_MAGIC)); #endif return m; #else return q->msg_pool.host + q->priv * q->msg_size; #endif } }