156dd45c0SLong Li /* SPDX-License-Identifier: BSD-3-Clause
256dd45c0SLong Li * Copyright 2022 Microsoft Corporation
356dd45c0SLong Li */
456dd45c0SLong Li
556dd45c0SLong Li #include <ethdev_driver.h>
656dd45c0SLong Li #include <rte_io.h>
756dd45c0SLong Li
856dd45c0SLong Li #include "mana.h"
956dd45c0SLong Li
1056dd45c0SLong Li uint8_t *
gdma_get_wqe_pointer(struct mana_gdma_queue * queue)1156dd45c0SLong Li gdma_get_wqe_pointer(struct mana_gdma_queue *queue)
1256dd45c0SLong Li {
1356dd45c0SLong Li uint32_t offset_in_bytes =
1456dd45c0SLong Li (queue->head * GDMA_WQE_ALIGNMENT_UNIT_SIZE) &
1556dd45c0SLong Li (queue->size - 1);
1656dd45c0SLong Li
17e2d3a3c0SLong Li DP_LOG(DEBUG, "txq sq_head %u sq_size %u offset_in_bytes %u",
1856dd45c0SLong Li queue->head, queue->size, offset_in_bytes);
1956dd45c0SLong Li
2056dd45c0SLong Li if (offset_in_bytes + GDMA_WQE_ALIGNMENT_UNIT_SIZE > queue->size)
21e2d3a3c0SLong Li DP_LOG(ERR, "fatal error: offset_in_bytes %u too big",
2256dd45c0SLong Li offset_in_bytes);
2356dd45c0SLong Li
2456dd45c0SLong Li return ((uint8_t *)queue->buffer) + offset_in_bytes;
2556dd45c0SLong Li }
2656dd45c0SLong Li
2756dd45c0SLong Li static uint32_t
write_dma_client_oob(uint8_t * work_queue_buffer_pointer,const struct gdma_work_request * work_request,uint32_t client_oob_size)2856dd45c0SLong Li write_dma_client_oob(uint8_t *work_queue_buffer_pointer,
2956dd45c0SLong Li const struct gdma_work_request *work_request,
3056dd45c0SLong Li uint32_t client_oob_size)
3156dd45c0SLong Li {
3256dd45c0SLong Li uint8_t *p = work_queue_buffer_pointer;
3356dd45c0SLong Li
3456dd45c0SLong Li struct gdma_wqe_dma_oob *header = (struct gdma_wqe_dma_oob *)p;
3556dd45c0SLong Li
3656dd45c0SLong Li memset(header, 0, sizeof(struct gdma_wqe_dma_oob));
3756dd45c0SLong Li header->num_sgl_entries = work_request->num_sgl_elements;
3856dd45c0SLong Li header->inline_client_oob_size_in_dwords =
3956dd45c0SLong Li client_oob_size / sizeof(uint32_t);
4056dd45c0SLong Li header->client_data_unit = work_request->client_data_unit;
4156dd45c0SLong Li
42e2d3a3c0SLong Li DP_LOG(DEBUG, "queue buf %p sgl %u oob_h %u du %u oob_buf %p oob_b %u",
4356dd45c0SLong Li work_queue_buffer_pointer, header->num_sgl_entries,
4456dd45c0SLong Li header->inline_client_oob_size_in_dwords,
4556dd45c0SLong Li header->client_data_unit, work_request->inline_oob_data,
4656dd45c0SLong Li work_request->inline_oob_size_in_bytes);
4756dd45c0SLong Li
4856dd45c0SLong Li p += sizeof(struct gdma_wqe_dma_oob);
4956dd45c0SLong Li if (work_request->inline_oob_data &&
5056dd45c0SLong Li work_request->inline_oob_size_in_bytes > 0) {
5156dd45c0SLong Li memcpy(p, work_request->inline_oob_data,
5256dd45c0SLong Li work_request->inline_oob_size_in_bytes);
5356dd45c0SLong Li if (client_oob_size > work_request->inline_oob_size_in_bytes)
5456dd45c0SLong Li memset(p + work_request->inline_oob_size_in_bytes, 0,
5556dd45c0SLong Li client_oob_size -
5656dd45c0SLong Li work_request->inline_oob_size_in_bytes);
5756dd45c0SLong Li }
5856dd45c0SLong Li
5956dd45c0SLong Li return sizeof(struct gdma_wqe_dma_oob) + client_oob_size;
6056dd45c0SLong Li }
6156dd45c0SLong Li
6256dd45c0SLong Li static uint32_t
write_scatter_gather_list(uint8_t * work_queue_head_pointer,uint8_t * work_queue_end_pointer,uint8_t * work_queue_cur_pointer,struct gdma_work_request * work_request)6356dd45c0SLong Li write_scatter_gather_list(uint8_t *work_queue_head_pointer,
6456dd45c0SLong Li uint8_t *work_queue_end_pointer,
6556dd45c0SLong Li uint8_t *work_queue_cur_pointer,
6656dd45c0SLong Li struct gdma_work_request *work_request)
6756dd45c0SLong Li {
6856dd45c0SLong Li struct gdma_sgl_element *sge_list;
6956dd45c0SLong Li struct gdma_sgl_element dummy_sgl[1];
7056dd45c0SLong Li uint8_t *address;
7156dd45c0SLong Li uint32_t size;
7256dd45c0SLong Li uint32_t num_sge;
7356dd45c0SLong Li uint32_t size_to_queue_end;
7456dd45c0SLong Li uint32_t sge_list_size;
7556dd45c0SLong Li
76e2d3a3c0SLong Li DP_LOG(DEBUG, "work_queue_cur_pointer %p work_request->flags %x",
7756dd45c0SLong Li work_queue_cur_pointer, work_request->flags);
7856dd45c0SLong Li
7956dd45c0SLong Li num_sge = work_request->num_sgl_elements;
8056dd45c0SLong Li sge_list = work_request->sgl;
8156dd45c0SLong Li size_to_queue_end = (uint32_t)(work_queue_end_pointer -
8256dd45c0SLong Li work_queue_cur_pointer);
8356dd45c0SLong Li
8456dd45c0SLong Li if (num_sge == 0) {
8556dd45c0SLong Li /* Per spec, the case of an empty SGL should be handled as
8656dd45c0SLong Li * follows to avoid corrupted WQE errors:
8756dd45c0SLong Li * Write one dummy SGL entry
8856dd45c0SLong Li * Set the address to 1, leave the rest as 0
8956dd45c0SLong Li */
9056dd45c0SLong Li dummy_sgl[num_sge].address = 1;
9156dd45c0SLong Li dummy_sgl[num_sge].size = 0;
9256dd45c0SLong Li dummy_sgl[num_sge].memory_key = 0;
9356dd45c0SLong Li num_sge++;
9456dd45c0SLong Li sge_list = dummy_sgl;
9556dd45c0SLong Li }
9656dd45c0SLong Li
9756dd45c0SLong Li sge_list_size = 0;
9856dd45c0SLong Li {
9956dd45c0SLong Li address = (uint8_t *)sge_list;
10056dd45c0SLong Li size = sizeof(struct gdma_sgl_element) * num_sge;
10156dd45c0SLong Li if (size_to_queue_end < size) {
10256dd45c0SLong Li memcpy(work_queue_cur_pointer, address,
10356dd45c0SLong Li size_to_queue_end);
10456dd45c0SLong Li work_queue_cur_pointer = work_queue_head_pointer;
10556dd45c0SLong Li address += size_to_queue_end;
10656dd45c0SLong Li size -= size_to_queue_end;
10756dd45c0SLong Li }
10856dd45c0SLong Li
10956dd45c0SLong Li memcpy(work_queue_cur_pointer, address, size);
11056dd45c0SLong Li sge_list_size = size;
11156dd45c0SLong Li }
11256dd45c0SLong Li
113e2d3a3c0SLong Li DP_LOG(DEBUG, "sge %u address 0x%" PRIx64 " size %u key %u list_s %u",
11456dd45c0SLong Li num_sge, sge_list->address, sge_list->size,
11556dd45c0SLong Li sge_list->memory_key, sge_list_size);
11656dd45c0SLong Li
11756dd45c0SLong Li return sge_list_size;
11856dd45c0SLong Li }
11956dd45c0SLong Li
12056dd45c0SLong Li /*
12156dd45c0SLong Li * Post a work request to queue.
12256dd45c0SLong Li */
12356dd45c0SLong Li int
gdma_post_work_request(struct mana_gdma_queue * queue,struct gdma_work_request * work_req,uint32_t * wqe_size_in_bu)12456dd45c0SLong Li gdma_post_work_request(struct mana_gdma_queue *queue,
12556dd45c0SLong Li struct gdma_work_request *work_req,
126b5dfcaecSLong Li uint32_t *wqe_size_in_bu)
12756dd45c0SLong Li {
12856dd45c0SLong Li uint32_t client_oob_size =
12956dd45c0SLong Li work_req->inline_oob_size_in_bytes >
13056dd45c0SLong Li INLINE_OOB_SMALL_SIZE_IN_BYTES ?
13156dd45c0SLong Li INLINE_OOB_LARGE_SIZE_IN_BYTES :
13256dd45c0SLong Li INLINE_OOB_SMALL_SIZE_IN_BYTES;
13356dd45c0SLong Li
13456dd45c0SLong Li uint32_t sgl_data_size = sizeof(struct gdma_sgl_element) *
13556dd45c0SLong Li RTE_MAX((uint32_t)1, work_req->num_sgl_elements);
13656dd45c0SLong Li uint32_t wqe_size =
13756dd45c0SLong Li RTE_ALIGN(sizeof(struct gdma_wqe_dma_oob) +
13856dd45c0SLong Li client_oob_size + sgl_data_size,
13956dd45c0SLong Li GDMA_WQE_ALIGNMENT_UNIT_SIZE);
14056dd45c0SLong Li uint8_t *wq_buffer_pointer;
14156dd45c0SLong Li uint32_t queue_free_units = queue->count - (queue->head - queue->tail);
14256dd45c0SLong Li
14356dd45c0SLong Li if (wqe_size / GDMA_WQE_ALIGNMENT_UNIT_SIZE > queue_free_units) {
144e2d3a3c0SLong Li DP_LOG(DEBUG, "WQE size %u queue count %u head %u tail %u",
14556dd45c0SLong Li wqe_size, queue->count, queue->head, queue->tail);
14656dd45c0SLong Li return -EBUSY;
14756dd45c0SLong Li }
14856dd45c0SLong Li
149e2d3a3c0SLong Li DP_LOG(DEBUG, "client_oob_size %u sgl_data_size %u wqe_size %u",
15056dd45c0SLong Li client_oob_size, sgl_data_size, wqe_size);
15156dd45c0SLong Li
152b5dfcaecSLong Li *wqe_size_in_bu = wqe_size / GDMA_WQE_ALIGNMENT_UNIT_SIZE;
15356dd45c0SLong Li
15456dd45c0SLong Li wq_buffer_pointer = gdma_get_wqe_pointer(queue);
15556dd45c0SLong Li wq_buffer_pointer += write_dma_client_oob(wq_buffer_pointer, work_req,
15656dd45c0SLong Li client_oob_size);
15756dd45c0SLong Li if (wq_buffer_pointer >= ((uint8_t *)queue->buffer) + queue->size)
15856dd45c0SLong Li wq_buffer_pointer -= queue->size;
15956dd45c0SLong Li
16056dd45c0SLong Li write_scatter_gather_list((uint8_t *)queue->buffer,
16156dd45c0SLong Li (uint8_t *)queue->buffer + queue->size,
16256dd45c0SLong Li wq_buffer_pointer, work_req);
16356dd45c0SLong Li
16456dd45c0SLong Li queue->head += wqe_size / GDMA_WQE_ALIGNMENT_UNIT_SIZE;
16556dd45c0SLong Li
16656dd45c0SLong Li return 0;
16756dd45c0SLong Li }
16856dd45c0SLong Li
169*26c6bdf3SWei Hu #ifdef RTE_ARCH_32
170*26c6bdf3SWei Hu union gdma_short_doorbell_entry {
171*26c6bdf3SWei Hu uint32_t as_uint32;
172*26c6bdf3SWei Hu
173*26c6bdf3SWei Hu struct {
174*26c6bdf3SWei Hu uint32_t tail_ptr_incr : 16; /* Number of CQEs */
175*26c6bdf3SWei Hu uint32_t id : 12;
176*26c6bdf3SWei Hu uint32_t reserved : 3;
177*26c6bdf3SWei Hu uint32_t arm : 1;
178*26c6bdf3SWei Hu } cq;
179*26c6bdf3SWei Hu
180*26c6bdf3SWei Hu struct {
181*26c6bdf3SWei Hu uint32_t tail_ptr_incr : 16; /* In number of bytes */
182*26c6bdf3SWei Hu uint32_t id : 12;
183*26c6bdf3SWei Hu uint32_t reserved : 4;
184*26c6bdf3SWei Hu } rq;
185*26c6bdf3SWei Hu
186*26c6bdf3SWei Hu struct {
187*26c6bdf3SWei Hu uint32_t tail_ptr_incr : 16; /* In number of bytes */
188*26c6bdf3SWei Hu uint32_t id : 12;
189*26c6bdf3SWei Hu uint32_t reserved : 4;
190*26c6bdf3SWei Hu } sq;
191*26c6bdf3SWei Hu
192*26c6bdf3SWei Hu struct {
193*26c6bdf3SWei Hu uint32_t tail_ptr_incr : 16; /* Number of EQEs */
194*26c6bdf3SWei Hu uint32_t id : 12;
195*26c6bdf3SWei Hu uint32_t reserved : 3;
196*26c6bdf3SWei Hu uint32_t arm : 1;
197*26c6bdf3SWei Hu } eq;
198*26c6bdf3SWei Hu }; /* HW DATA */
199*26c6bdf3SWei Hu
200*26c6bdf3SWei Hu enum {
201*26c6bdf3SWei Hu DOORBELL_SHORT_OFFSET_SQ = 0x10,
202*26c6bdf3SWei Hu DOORBELL_SHORT_OFFSET_RQ = 0x410,
203*26c6bdf3SWei Hu DOORBELL_SHORT_OFFSET_CQ = 0x810,
204*26c6bdf3SWei Hu DOORBELL_SHORT_OFFSET_EQ = 0xFF0,
205*26c6bdf3SWei Hu };
206*26c6bdf3SWei Hu
207*26c6bdf3SWei Hu /*
208*26c6bdf3SWei Hu * Write to hardware doorbell to notify new activity.
209*26c6bdf3SWei Hu */
210*26c6bdf3SWei Hu int
mana_ring_short_doorbell(void * db_page,enum gdma_queue_types queue_type,uint32_t queue_id,uint32_t tail_incr,uint8_t arm)211*26c6bdf3SWei Hu mana_ring_short_doorbell(void *db_page, enum gdma_queue_types queue_type,
212*26c6bdf3SWei Hu uint32_t queue_id, uint32_t tail_incr, uint8_t arm)
213*26c6bdf3SWei Hu {
214*26c6bdf3SWei Hu uint8_t *addr = db_page;
215*26c6bdf3SWei Hu union gdma_short_doorbell_entry e = {};
216*26c6bdf3SWei Hu
217*26c6bdf3SWei Hu if ((queue_id & ~GDMA_SHORT_DB_QID_MASK) ||
218*26c6bdf3SWei Hu (tail_incr & ~GDMA_SHORT_DB_INC_MASK)) {
219*26c6bdf3SWei Hu DP_LOG(ERR, "%s: queue_id %u or "
220*26c6bdf3SWei Hu "tail_incr %u overflowed, queue type %d",
221*26c6bdf3SWei Hu __func__, queue_id, tail_incr, queue_type);
222*26c6bdf3SWei Hu return -EINVAL;
223*26c6bdf3SWei Hu }
224*26c6bdf3SWei Hu
225*26c6bdf3SWei Hu switch (queue_type) {
226*26c6bdf3SWei Hu case GDMA_QUEUE_SEND:
227*26c6bdf3SWei Hu e.sq.id = queue_id;
228*26c6bdf3SWei Hu e.sq.tail_ptr_incr = tail_incr;
229*26c6bdf3SWei Hu addr += DOORBELL_SHORT_OFFSET_SQ;
230*26c6bdf3SWei Hu break;
231*26c6bdf3SWei Hu
232*26c6bdf3SWei Hu case GDMA_QUEUE_RECEIVE:
233*26c6bdf3SWei Hu e.rq.id = queue_id;
234*26c6bdf3SWei Hu e.rq.tail_ptr_incr = tail_incr;
235*26c6bdf3SWei Hu addr += DOORBELL_SHORT_OFFSET_RQ;
236*26c6bdf3SWei Hu break;
237*26c6bdf3SWei Hu
238*26c6bdf3SWei Hu case GDMA_QUEUE_COMPLETION:
239*26c6bdf3SWei Hu e.cq.id = queue_id;
240*26c6bdf3SWei Hu e.cq.tail_ptr_incr = tail_incr;
241*26c6bdf3SWei Hu e.cq.arm = arm;
242*26c6bdf3SWei Hu addr += DOORBELL_SHORT_OFFSET_CQ;
243*26c6bdf3SWei Hu break;
244*26c6bdf3SWei Hu
245*26c6bdf3SWei Hu default:
246*26c6bdf3SWei Hu DP_LOG(ERR, "Unsupported queue type %d", queue_type);
247*26c6bdf3SWei Hu return -1;
248*26c6bdf3SWei Hu }
249*26c6bdf3SWei Hu
250*26c6bdf3SWei Hu /* Ensure all writes are done before ringing doorbell */
251*26c6bdf3SWei Hu rte_wmb();
252*26c6bdf3SWei Hu
253*26c6bdf3SWei Hu DP_LOG(DEBUG, "db_page %p addr %p queue_id %u type %u tail %u arm %u",
254*26c6bdf3SWei Hu db_page, addr, queue_id, queue_type, tail_incr, arm);
255*26c6bdf3SWei Hu
256*26c6bdf3SWei Hu rte_write32(e.as_uint32, addr);
257*26c6bdf3SWei Hu return 0;
258*26c6bdf3SWei Hu }
259*26c6bdf3SWei Hu #else
26056dd45c0SLong Li union gdma_doorbell_entry {
26156dd45c0SLong Li uint64_t as_uint64;
26256dd45c0SLong Li
26356dd45c0SLong Li struct {
26456dd45c0SLong Li uint64_t id : 24;
26556dd45c0SLong Li uint64_t reserved : 8;
26656dd45c0SLong Li uint64_t tail_ptr : 31;
26756dd45c0SLong Li uint64_t arm : 1;
26856dd45c0SLong Li } cq;
26956dd45c0SLong Li
27056dd45c0SLong Li struct {
27156dd45c0SLong Li uint64_t id : 24;
27256dd45c0SLong Li uint64_t wqe_cnt : 8;
27356dd45c0SLong Li uint64_t tail_ptr : 32;
27456dd45c0SLong Li } rq;
27556dd45c0SLong Li
27656dd45c0SLong Li struct {
27756dd45c0SLong Li uint64_t id : 24;
27856dd45c0SLong Li uint64_t reserved : 8;
27956dd45c0SLong Li uint64_t tail_ptr : 32;
28056dd45c0SLong Li } sq;
28156dd45c0SLong Li
28256dd45c0SLong Li struct {
28356dd45c0SLong Li uint64_t id : 16;
28456dd45c0SLong Li uint64_t reserved : 16;
28556dd45c0SLong Li uint64_t tail_ptr : 31;
28656dd45c0SLong Li uint64_t arm : 1;
28756dd45c0SLong Li } eq;
28856dd45c0SLong Li }; /* HW DATA */
28956dd45c0SLong Li
29056dd45c0SLong Li enum {
29156dd45c0SLong Li DOORBELL_OFFSET_SQ = 0x0,
29256dd45c0SLong Li DOORBELL_OFFSET_RQ = 0x400,
29356dd45c0SLong Li DOORBELL_OFFSET_CQ = 0x800,
29456dd45c0SLong Li DOORBELL_OFFSET_EQ = 0xFF8,
29556dd45c0SLong Li };
29656dd45c0SLong Li
29756dd45c0SLong Li /*
29856dd45c0SLong Li * Write to hardware doorbell to notify new activity.
29956dd45c0SLong Li */
30056dd45c0SLong Li int
mana_ring_doorbell(void * db_page,enum gdma_queue_types queue_type,uint32_t queue_id,uint32_t tail,uint8_t arm)30156dd45c0SLong Li mana_ring_doorbell(void *db_page, enum gdma_queue_types queue_type,
302afd5d170SLong Li uint32_t queue_id, uint32_t tail, uint8_t arm)
30356dd45c0SLong Li {
30456dd45c0SLong Li uint8_t *addr = db_page;
30556dd45c0SLong Li union gdma_doorbell_entry e = {};
30656dd45c0SLong Li
30756dd45c0SLong Li switch (queue_type) {
30856dd45c0SLong Li case GDMA_QUEUE_SEND:
30956dd45c0SLong Li e.sq.id = queue_id;
31056dd45c0SLong Li e.sq.tail_ptr = tail;
31156dd45c0SLong Li addr += DOORBELL_OFFSET_SQ;
31256dd45c0SLong Li break;
31356dd45c0SLong Li
31456dd45c0SLong Li case GDMA_QUEUE_RECEIVE:
31556dd45c0SLong Li e.rq.id = queue_id;
31656dd45c0SLong Li e.rq.tail_ptr = tail;
317afd5d170SLong Li e.rq.wqe_cnt = arm;
31856dd45c0SLong Li addr += DOORBELL_OFFSET_RQ;
31956dd45c0SLong Li break;
32056dd45c0SLong Li
32156dd45c0SLong Li case GDMA_QUEUE_COMPLETION:
32256dd45c0SLong Li e.cq.id = queue_id;
32356dd45c0SLong Li e.cq.tail_ptr = tail;
324afd5d170SLong Li e.cq.arm = arm;
32556dd45c0SLong Li addr += DOORBELL_OFFSET_CQ;
32656dd45c0SLong Li break;
32756dd45c0SLong Li
32856dd45c0SLong Li default:
329e2d3a3c0SLong Li DP_LOG(ERR, "Unsupported queue type %d", queue_type);
33056dd45c0SLong Li return -1;
33156dd45c0SLong Li }
33256dd45c0SLong Li
33356dd45c0SLong Li /* Ensure all writes are done before ringing doorbell */
33456dd45c0SLong Li rte_wmb();
33556dd45c0SLong Li
336e2d3a3c0SLong Li DP_LOG(DEBUG, "db_page %p addr %p queue_id %u type %u tail %u arm %u",
337afd5d170SLong Li db_page, addr, queue_id, queue_type, tail, arm);
33856dd45c0SLong Li
33956dd45c0SLong Li rte_write64(e.as_uint64, addr);
34056dd45c0SLong Li return 0;
34156dd45c0SLong Li }
342*26c6bdf3SWei Hu #endif
34356dd45c0SLong Li
34456dd45c0SLong Li /*
34556dd45c0SLong Li * Poll completion queue for completions.
34656dd45c0SLong Li */
34731124619SLong Li uint32_t
gdma_poll_completion_queue(struct mana_gdma_queue * cq,struct gdma_comp * gdma_comp,uint32_t max_comp)34831124619SLong Li gdma_poll_completion_queue(struct mana_gdma_queue *cq,
34931124619SLong Li struct gdma_comp *gdma_comp, uint32_t max_comp)
35056dd45c0SLong Li {
35156dd45c0SLong Li struct gdma_hardware_completion_entry *cqe;
35256dd45c0SLong Li uint32_t new_owner_bits, old_owner_bits;
35356dd45c0SLong Li uint32_t cqe_owner_bits;
35431124619SLong Li uint32_t num_comp = 0;
35556dd45c0SLong Li struct gdma_hardware_completion_entry *buffer = cq->buffer;
35656dd45c0SLong Li
35731124619SLong Li while (num_comp < max_comp) {
35831124619SLong Li cqe = &buffer[cq->head % cq->count];
35931124619SLong Li new_owner_bits = (cq->head / cq->count) &
36031124619SLong Li COMPLETION_QUEUE_OWNER_MASK;
36156dd45c0SLong Li old_owner_bits = (cq->head / cq->count - 1) &
36256dd45c0SLong Li COMPLETION_QUEUE_OWNER_MASK;
36356dd45c0SLong Li cqe_owner_bits = cqe->owner_bits;
36456dd45c0SLong Li
365e2d3a3c0SLong Li DP_LOG(DEBUG, "comp cqe bits 0x%x owner bits 0x%x",
36656dd45c0SLong Li cqe_owner_bits, old_owner_bits);
36756dd45c0SLong Li
36831124619SLong Li /* No new entry */
36956dd45c0SLong Li if (cqe_owner_bits == old_owner_bits)
37031124619SLong Li break;
37156dd45c0SLong Li
37256dd45c0SLong Li if (cqe_owner_bits != new_owner_bits) {
37331124619SLong Li DRV_LOG(ERR, "CQ overflowed, ID %u cqe 0x%x new 0x%x",
37456dd45c0SLong Li cq->id, cqe_owner_bits, new_owner_bits);
37531124619SLong Li break;
37656dd45c0SLong Li }
37756dd45c0SLong Li
37831124619SLong Li gdma_comp[num_comp].cqe_data = cqe->dma_client_data;
37931124619SLong Li num_comp++;
38056dd45c0SLong Li
38156dd45c0SLong Li cq->head++;
38256dd45c0SLong Li
383e2d3a3c0SLong Li DP_LOG(DEBUG, "comp new 0x%x old 0x%x cqe 0x%x wq %u sq %u head %u",
38456dd45c0SLong Li new_owner_bits, old_owner_bits, cqe_owner_bits,
38531124619SLong Li cqe->wq_num, cqe->is_sq, cq->head);
38631124619SLong Li }
38731124619SLong Li
38831124619SLong Li /* Make sure the CQE owner bits are checked before we access the data
38931124619SLong Li * in CQE
39031124619SLong Li */
39131124619SLong Li rte_rmb();
39231124619SLong Li
39331124619SLong Li return num_comp;
39456dd45c0SLong Li }
395