FreeBSD/contrib/ofed/libcxgb4/src/cq.c
/*
 * Get one cq entry from c4iw and map it to openib.
 *
 * Returns:
 *	0			cqe returned
 *	-ENODATA		EMPTY;
 *	-EAGAIN			caller must try again
 *	any other -errno	fatal error
 */
Get one cq entry from c4iw and map it to openib.
Returns:
0                       cqe returned
-ENODATA                EMPTY;
-EAGAIN                 caller must try again
any other -errno        fatal error
Get one cq entry from c4iw and map it to openib . Returns : 0 cqe returned - ENODATA EMPTY ; - EAGAIN caller must try again any other - errno fatal error
static int c4iw_poll_cq_one(struct c4iw_cq *chp, struct ibv_wc *wc)
{
	struct c4iw_qp *qhp = NULL;
	struct t4_cqe cqe, *rd_cqe;
	struct t4_wq *wq;
	u32 credit = 0;
	u8 cqe_flushed;
	u64 cookie = 0;
	int ret;
	ret = t4_next_cqe(&chp->cq, &rd_cqe);
	if (ret) {
#ifdef STALL_DETECTION
		if (ret == -ENODATA && stall_to && !chp->dumped) {
			struct timeval t;
			gettimeofday(&t, NULL);
			if ((t.tv_sec - chp->time.tv_sec) > stall_to) {
				dump_state();
				chp->dumped = 1;
			}
		}
#endif
		return ret;
	}
#ifdef STALL_DETECTION
	gettimeofday(&chp->time, NULL);
#endif
	qhp = get_qhp(chp->rhp, CQE_QPID(rd_cqe));
	if (!qhp)
		wq = NULL;
	else {
		pthread_spin_lock(&qhp->lock);
		wq = &(qhp->wq);
	}
	ret = poll_cq(wq, &(chp->cq), &cqe, &cqe_flushed, &cookie, &credit);
	if (ret)
		goto out;
	INC_STAT(cqe);
	wc->wr_id = cookie;
	wc->qp_num = qhp->wq.sq.qid;
	wc->vendor_err = CQE_STATUS(&cqe);
	wc->wc_flags = 0;
	PDBG("%s qpid 0x%x type %d opcode %d status 0x%x wrid hi 0x%x "
	     "lo 0x%x cookie 0x%llx\n", __func__,
	     CQE_QPID(&cqe), CQE_TYPE(&cqe),
	     CQE_OPCODE(&cqe), CQE_STATUS(&cqe), CQE_WRID_HI(&cqe),
	     CQE_WRID_LOW(&cqe), (unsigned long long)cookie);
	if (CQE_TYPE(&cqe) == 0) {
		if (!CQE_STATUS(&cqe))
			wc->byte_len = CQE_LEN(&cqe);
		else
			wc->byte_len = 0;
		wc->opcode = IBV_WC_RECV;
	} else {
		switch (CQE_OPCODE(&cqe)) {
		case FW_RI_RDMA_WRITE:
			wc->opcode = IBV_WC_RDMA_WRITE;
			break;
		case FW_RI_READ_REQ:
			wc->opcode = IBV_WC_RDMA_READ;
			wc->byte_len = CQE_LEN(&cqe);
			break;
		case FW_RI_SEND:
		case FW_RI_SEND_WITH_SE:
		case FW_RI_SEND_WITH_INV:
		case FW_RI_SEND_WITH_SE_INV:
			wc->opcode = IBV_WC_SEND;
			break;
		case FW_RI_BIND_MW:
			wc->opcode = IBV_WC_BIND_MW;
			break;
		default:
			PDBG("Unexpected opcode %d "
			     "in the CQE received for QPID=0x%0x\n",
			     CQE_OPCODE(&cqe), CQE_QPID(&cqe));
			ret = -EINVAL;
			goto out;
		}
	}
	if (cqe_flushed)
		wc->status = IBV_WC_WR_FLUSH_ERR;
	else {
		switch (CQE_STATUS(&cqe)) {
		case T4_ERR_SUCCESS:
			wc->status = IBV_WC_SUCCESS;
			break;
		case T4_ERR_STAG:
			wc->status = IBV_WC_LOC_ACCESS_ERR;
			break;
		case T4_ERR_PDID:
			wc->status = IBV_WC_LOC_PROT_ERR;
			break;
		case T4_ERR_QPID:
		case T4_ERR_ACCESS:
			wc->status = IBV_WC_LOC_ACCESS_ERR;
			break;
		case T4_ERR_WRAP:
			wc->status = IBV_WC_GENERAL_ERR;
			break;
		case T4_ERR_BOUND:
			wc->status = IBV_WC_LOC_LEN_ERR;
			break;
		case T4_ERR_INVALIDATE_SHARED_MR:
		case T4_ERR_INVALIDATE_MR_WITH_MW_BOUND:
			wc->status = IBV_WC_MW_BIND_ERR;
			break;
		case T4_ERR_CRC:
		case T4_ERR_MARKER:
		case T4_ERR_PDU_LEN_ERR:
		case T4_ERR_OUT_OF_RQE:
		case T4_ERR_DDP_VERSION:
		case T4_ERR_RDMA_VERSION:
		case T4_ERR_DDP_QUEUE_NUM:
		case T4_ERR_MSN:
		case T4_ERR_TBIT:
		case T4_ERR_MO:
		case T4_ERR_MSN_RANGE:
		case T4_ERR_IRD_OVERFLOW:
		case T4_ERR_OPCODE:
		case T4_ERR_INTERNAL_ERR:
			wc->status = IBV_WC_FATAL_ERR;
			break;
		case T4_ERR_SWFLUSH:
			wc->status = IBV_WC_WR_FLUSH_ERR;
			break;
		default:
			PDBG("Unexpected cqe_status 0x%x for QPID=0x%0x\n",
			     CQE_STATUS(&cqe), CQE_QPID(&cqe));
			wc->status = IBV_WC_FATAL_ERR;
		}
	}
	if (wc->status && wc->status != IBV_WC_WR_FLUSH_ERR)
		syslog(LOG_NOTICE, "cxgb4 app err cqid %u qpid %u "
			"type %u opcode %u status 0x%x\n",
			chp->cq.cqid, CQE_QPID(&cqe), CQE_TYPE(&cqe),
			CQE_OPCODE(&cqe), CQE_STATUS(&cqe));
out:
	if (wq)
		pthread_spin_unlock(&qhp->lock);
	return ret;
}
static int c4iw_poll_cq_one ( struct c4iw_cq * chp , struct ibv_wc * wc ) { struct c4iw_qp * qhp = NULL ; struct t4_cqe cqe , * rd_cqe ; struct t4_wq * wq ; u32 credit = 0 ; u8 cqe_flushed ; u64 cookie = 0 ; int ret ; ret = t4_next_cqe ( & chp -> cq , & rd_cqe ) ; if ( ret ) { #ifdef STALL_DETECTION if ( ret == - ENODATA && stall_to && ! chp -> dumped ) { struct timeval t ; gettimeofday ( & t , NULL ) ; if ( ( t . tv_sec - chp -> time . tv_sec ) > stall_to ) { dump_state ( ) ; chp -> dumped = 1 ; } } #endif return ret ; } #ifdef STALL_DETECTION gettimeofday ( & chp -> time , NULL ) ; #endif qhp = get_qhp ( chp -> rhp , CQE_QPID ( rd_cqe ) ) ; if ( ! qhp ) wq = NULL ; else { pthread_spin_lock ( & qhp -> lock ) ; wq = & ( qhp -> wq ) ; } ret = poll_cq ( wq , & ( chp -> cq ) , & cqe , & cqe_flushed , & cookie , & credit ) ; if ( ret ) goto out ; INC_STAT ( cqe ) ; wc -> wr_id = cookie ; wc -> qp_num = qhp -> wq . sq . qid ; wc -> vendor_err = CQE_STATUS ( & cqe ) ; wc -> wc_flags = 0 ; PDBG ( " " " \n " , __func__ , CQE_QPID ( & cqe ) , CQE_TYPE ( & cqe ) , CQE_OPCODE ( & cqe ) , CQE_STATUS ( & cqe ) , CQE_WRID_HI ( & cqe ) , CQE_WRID_LOW ( & cqe ) , ( unsigned long long ) cookie ) ; if ( CQE_TYPE ( & cqe ) == 0 ) { if ( ! CQE_STATUS ( & cqe ) ) wc -> byte_len = CQE_LEN ( & cqe ) ; else wc -> byte_len = 0 ; wc -> opcode = IBV_WC_RECV ; } else { switch ( CQE_OPCODE ( & cqe ) ) { case FW_RI_RDMA_WRITE : wc -> opcode = IBV_WC_RDMA_WRITE ; break ; case FW_RI_READ_REQ : wc -> opcode = IBV_WC_RDMA_READ ; wc -> byte_len = CQE_LEN ( & cqe ) ; break ; case FW_RI_SEND : case FW_RI_SEND_WITH_SE : case FW_RI_SEND_WITH_INV : case FW_RI_SEND_WITH_SE_INV : wc -> opcode = IBV_WC_SEND ; break ; case FW_RI_BIND_MW : wc -> opcode = IBV_WC_BIND_MW ; break ; default : PDBG ( " " " \n " , CQE_OPCODE ( & cqe ) , CQE_QPID ( & cqe ) ) ; ret = - EINVAL ; goto out ; } } if ( cqe_flushed ) wc -> status = IBV_WC_WR_FLUSH_ERR ; else { switch ( CQE_STATUS ( & cqe ) ) { case T4_ERR_SUCCESS : wc -> status = IBV_WC_SUCCESS ; break ; case T4_ERR_STAG : wc -> status = IBV_WC_LOC_ACCESS_ERR ; break ; case T4_ERR_PDID : wc -> status = IBV_WC_LOC_PROT_ERR ; break ; case T4_ERR_QPID : case T4_ERR_ACCESS : wc -> status = IBV_WC_LOC_ACCESS_ERR ; break ; case T4_ERR_WRAP : wc -> status = IBV_WC_GENERAL_ERR ; break ; case T4_ERR_BOUND : wc -> status = IBV_WC_LOC_LEN_ERR ; break ; case T4_ERR_INVALIDATE_SHARED_MR : case T4_ERR_INVALIDATE_MR_WITH_MW_BOUND : wc -> status = IBV_WC_MW_BIND_ERR ; break ; case T4_ERR_CRC : case T4_ERR_MARKER : case T4_ERR_PDU_LEN_ERR : case T4_ERR_OUT_OF_RQE : case T4_ERR_DDP_VERSION : case T4_ERR_RDMA_VERSION : case T4_ERR_DDP_QUEUE_NUM : case T4_ERR_MSN : case T4_ERR_TBIT : case T4_ERR_MO : case T4_ERR_MSN_RANGE : case T4_ERR_IRD_OVERFLOW : case T4_ERR_OPCODE : case T4_ERR_INTERNAL_ERR : wc -> status = IBV_WC_FATAL_ERR ; break ; case T4_ERR_SWFLUSH : wc -> status = IBV_WC_WR_FLUSH_ERR ; break ; default : PDBG ( " \n " , CQE_STATUS ( & cqe ) , CQE_QPID ( & cqe ) ) ; wc -> status = IBV_WC_FATAL_ERR ; } } if ( wc -> status && wc -> status != IBV_WC_WR_FLUSH_ERR ) syslog ( LOG_NOTICE , " " " \n " , chp -> cq . cqid , CQE_QPID ( & cqe ) , CQE_TYPE ( & cqe ) , CQE_OPCODE ( & cqe ) , CQE_STATUS ( & cqe ) ) ; out : if ( wq ) pthread_spin_unlock ( & qhp -> lock ) ; return ret ; }
Get one cq entry from c4iw and map it to openib.
Get one cq entry from c4iw and map it to openib .