+int
+memif_buffer_enq_tx (memif_conn_handle_t conn, uint16_t qid,
+ memif_buffer_t * bufs, uint16_t count,
+ uint16_t * count_out)
+{
+ memif_connection_t *c = (memif_connection_t *) conn;
+ if (EXPECT_FALSE (c == NULL))
+ return MEMIF_ERR_NOCONN;
+ if (EXPECT_FALSE (c->fd < 0))
+ return MEMIF_ERR_DISCONNECTED;
+ uint8_t num =
+ (c->args.is_master) ? c->run_args.num_m2s_rings : c->
+ run_args.num_s2m_rings;
+ if (EXPECT_FALSE (qid >= num))
+ return MEMIF_ERR_QID;
+ if (EXPECT_FALSE (!count_out))
+ return MEMIF_ERR_INVAL_ARG;
+ if (EXPECT_FALSE (c->args.is_master))
+ return MEMIF_ERR_INVAL_ARG;
+
+ memif_queue_t *mq = &c->tx_queues[qid];
+ memif_ring_t *ring = mq->ring;
+ memif_buffer_t *b0;
+ uint16_t mask = (1 << mq->log2_ring_size) - 1;
+ uint16_t ring_size;
+ uint16_t slot, ns;
+ int err = MEMIF_ERR_SUCCESS; /* 0 */
+ *count_out = 0;
+
+ ring_size = (1 << mq->log2_ring_size);
+ slot = (c->args.is_master) ? ring->tail : ring->head;
+ slot += mq->alloc_bufs;
+
+ /* can only be called by slave */
+ ns = ring_size - (ring->head + mq->alloc_bufs) + ring->tail;
+
+ b0 = bufs;
+
+ while (count && ns)
+ {
+ if (EXPECT_FALSE ((b0->flags & MEMIF_BUFFER_FLAG_RX) == 0))
+ {
+ /* not a valid buffer */
+ count--;
+ continue;
+ }
+ b0->flags &= ~MEMIF_BUFFER_FLAG_RX;
+
+ ((memif_ring_t *) b0->ring)->desc[b0->desc_index & mask].offset = ring->desc[slot & mask].offset; /* put free buffer on rx ring */
+
+ ring->desc[slot & mask].offset =
+ (uint32_t) (b0->data -
+ c->regions[ring->desc[slot & mask].region].addr);
+ ring->desc[slot & mask].flags |=
+ (b0->flags & MEMIF_BUFFER_FLAG_NEXT) ? MEMIF_DESC_FLAG_NEXT : 0;
+
+ b0->desc_index = slot;
+
+ mq->alloc_bufs++;
+ slot++;
+
+ count--;
+ ns--;
+ b0++;
+ *count_out += 1;
+ }
+
+ DBG ("allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
+ mq->alloc_bufs);
+
+ if (count)
+ {
+ DBG ("ring buffer full! qid: %u", qid);
+ err = MEMIF_ERR_NOBUF_RING;
+ }
+
+ return err;
+}
+