aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-generic/odp_packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linux-generic/odp_packet.c')
-rw-r--r--platform/linux-generic/odp_packet.c181
1 files changed, 176 insertions, 5 deletions
diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c
index fdf711735..0986056e6 100644
--- a/platform/linux-generic/odp_packet.c
+++ b/platform/linux-generic/odp_packet.c
@@ -18,6 +18,7 @@
#include <odp/api/plat/byteorder_inlines.h>
#include <odp/api/packet_io.h>
#include <odp/api/plat/pktio_inlines.h>
+#include <odp/api/proto_stats.h>
/* Inlined API functions */
#include <odp/api/plat/event_inlines.h>
@@ -134,10 +135,11 @@ static inline void *packet_tail(odp_packet_hdr_t *pkt_hdr)
static inline uint32_t seg_headroom(odp_packet_hdr_t *pkt_seg)
{
odp_buffer_hdr_t *hdr = &pkt_seg->buf_hdr;
+ pool_t *pool = hdr->pool_ptr;
uint8_t *base = hdr->base_data;
uint8_t *head = pkt_seg->seg_data;
- return CONFIG_PACKET_HEADROOM + (head - base);
+ return pool->headroom + (head - base);
}
static inline uint32_t seg_tailroom(odp_packet_hdr_t *pkt_seg)
@@ -690,7 +692,7 @@ odp_packet_t odp_packet_alloc(odp_pool_t pool_hdl, uint32_t len)
odp_packet_t pkt;
int num, num_seg;
- if (odp_unlikely(pool->params.type != ODP_POOL_PACKET)) {
+ if (odp_unlikely(pool->type != ODP_POOL_PACKET)) {
_odp_errno = EINVAL;
return ODP_PACKET_INVALID;
}
@@ -713,7 +715,7 @@ int odp_packet_alloc_multi(odp_pool_t pool_hdl, uint32_t len,
pool_t *pool = pool_entry_from_hdl(pool_hdl);
int num, num_seg;
- if (odp_unlikely(pool->params.type != ODP_POOL_PACKET)) {
+ if (odp_unlikely(pool->type != ODP_POOL_PACKET)) {
_odp_errno = EINVAL;
return -1;
}
@@ -1747,8 +1749,8 @@ int _odp_packet_copy_md_to_packet(odp_packet_t srcpkt, odp_packet_t dstpkt)
odp_packet_hdr_t *dsthdr = packet_hdr(dstpkt);
pool_t *src_pool = srchdr->buf_hdr.pool_ptr;
pool_t *dst_pool = dsthdr->buf_hdr.pool_ptr;
- uint32_t src_uarea_size = src_pool->params.pkt.uarea_size;
- uint32_t dst_uarea_size = dst_pool->params.pkt.uarea_size;
+ uint32_t src_uarea_size = src_pool->param_uarea_size;
+ uint32_t dst_uarea_size = dst_pool->param_uarea_size;
dsthdr->input = srchdr->input;
dsthdr->dst_queue = srchdr->dst_queue;
@@ -2949,3 +2951,172 @@ odp_packet_reass_partial_state(odp_packet_t pkt, odp_packet_t frags[],
(void)res;
return -ENOTSUP;
}
+
+static inline odp_packet_hdr_t *packet_buf_to_hdr(odp_packet_buf_t pkt_buf)
+{
+ return (odp_packet_hdr_t *)(uintptr_t)pkt_buf;
+}
+
+void *odp_packet_buf_head(odp_packet_buf_t pkt_buf)
+{
+ odp_packet_hdr_t *pkt_hdr = packet_buf_to_hdr(pkt_buf);
+ pool_t *pool = pkt_hdr->buf_hdr.pool_ptr;
+ uint32_t head_offset = sizeof(odp_packet_hdr_t) + pool->ext_param.pkt.app_header_size;
+
+ if (odp_unlikely(pool->pool_ext == 0)) {
+ ODP_ERR("Not an external memory pool\n");
+ return NULL;
+ }
+
+ return (uint8_t *)pkt_hdr + head_offset;
+}
+
+uint32_t odp_packet_buf_size(odp_packet_buf_t pkt_buf)
+{
+ odp_packet_hdr_t *pkt_hdr = packet_buf_to_hdr(pkt_buf);
+ pool_t *pool = pkt_hdr->buf_hdr.pool_ptr;
+ uint32_t head_offset = sizeof(odp_packet_hdr_t) + pool->ext_param.pkt.app_header_size;
+
+ return pool->ext_param.pkt.buf_size - head_offset;
+}
+
+uint32_t odp_packet_buf_data_offset(odp_packet_buf_t pkt_buf)
+{
+ odp_packet_hdr_t *pkt_hdr = packet_buf_to_hdr(pkt_buf);
+
+ return (uintptr_t)pkt_hdr->seg_data - (uintptr_t)odp_packet_buf_head(pkt_buf);
+}
+
+uint32_t odp_packet_buf_data_len(odp_packet_buf_t pkt_buf)
+{
+ odp_packet_hdr_t *pkt_hdr = packet_buf_to_hdr(pkt_buf);
+
+ return pkt_hdr->seg_len;
+}
+
+void odp_packet_buf_data_set(odp_packet_buf_t pkt_buf, uint32_t data_offset, uint32_t data_len)
+{
+ odp_packet_hdr_t *pkt_hdr = packet_buf_to_hdr(pkt_buf);
+ uint8_t *head = odp_packet_buf_head(pkt_buf);
+
+ pkt_hdr->seg_len = data_len;
+ pkt_hdr->seg_data = head + data_offset;
+}
+
+odp_packet_buf_t odp_packet_buf_from_head(odp_pool_t pool_hdl, void *head)
+{
+ pool_t *pool = pool_entry_from_hdl(pool_hdl);
+ uint32_t head_offset = sizeof(odp_packet_hdr_t) + pool->ext_param.pkt.app_header_size;
+
+ if (odp_unlikely(pool->type != ODP_POOL_PACKET)) {
+ ODP_ERR("Not a packet pool\n");
+ return ODP_PACKET_BUF_INVALID;
+ }
+
+ if (odp_unlikely(pool->pool_ext == 0)) {
+ ODP_ERR("Not an external memory pool\n");
+ return ODP_PACKET_BUF_INVALID;
+ }
+
+ return (odp_packet_buf_t)((uintptr_t)head - head_offset);
+}
+
+uint32_t odp_packet_disassemble(odp_packet_t pkt, odp_packet_buf_t pkt_buf[], uint32_t num)
+{
+ uint32_t i;
+ odp_packet_seg_t seg;
+ odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
+ pool_t *pool = pkt_hdr->buf_hdr.pool_ptr;
+ uint32_t num_segs = odp_packet_num_segs(pkt);
+
+ if (odp_unlikely(pool->type != ODP_POOL_PACKET)) {
+ ODP_ERR("Not a packet pool\n");
+ return 0;
+ }
+
+ if (odp_unlikely(pool->pool_ext == 0)) {
+ ODP_ERR("Not an external memory pool\n");
+ return 0;
+ }
+
+ if (odp_unlikely(num < num_segs)) {
+ ODP_ERR("Not enough buffer handles %u. Packet has %u segments.\n", num, num_segs);
+ return 0;
+ }
+
+ seg = odp_packet_first_seg(pkt);
+
+ for (i = 0; i < num_segs; i++) {
+ pkt_buf[i] = (odp_packet_buf_t)(uintptr_t)packet_seg_to_hdr(seg);
+ seg = odp_packet_next_seg(pkt, seg);
+ }
+
+ return num_segs;
+}
+
+odp_packet_t odp_packet_reassemble(odp_pool_t pool_hdl, odp_packet_buf_t pkt_buf[], uint32_t num)
+{
+ uint32_t i, data_len, tailroom;
+ odp_packet_hdr_t *cur_seg, *next_seg;
+ odp_packet_hdr_t *pkt_hdr = (odp_packet_hdr_t *)(uintptr_t)pkt_buf[0];
+ uint32_t headroom = odp_packet_buf_data_offset(pkt_buf[0]);
+
+ pool_t *pool = pool_entry_from_hdl(pool_hdl);
+
+ if (odp_unlikely(pool->type != ODP_POOL_PACKET)) {
+ ODP_ERR("Not a packet pool\n");
+ return ODP_PACKET_INVALID;
+ }
+
+ if (odp_unlikely(pool->pool_ext == 0)) {
+ ODP_ERR("Not an external memory pool\n");
+ return ODP_PACKET_INVALID;
+ }
+
+ if (odp_unlikely(num == 0)) {
+ ODP_ERR("Bad number of buffers: %u\n", num);
+ return ODP_PACKET_INVALID;
+ }
+
+ cur_seg = pkt_hdr;
+ data_len = 0;
+
+ for (i = 0; i < num; i++) {
+ next_seg = NULL;
+ if (i < num - 1)
+ next_seg = (odp_packet_hdr_t *)(uintptr_t)pkt_buf[i + 1];
+
+ data_len += cur_seg->seg_len;
+ cur_seg->seg_next = next_seg;
+ cur_seg = next_seg;
+ }
+
+ tailroom = pool->ext_param.pkt.buf_size - sizeof(odp_packet_hdr_t);
+ tailroom -= pool->ext_param.pkt.app_header_size;
+ tailroom -= odp_packet_buf_data_len(pkt_buf[num - 1]);
+
+ pkt_hdr->seg_count = num;
+ pkt_hdr->frame_len = data_len;
+ pkt_hdr->headroom = headroom;
+ pkt_hdr->tailroom = tailroom;
+
+ /* Reset metadata */
+ pkt_hdr->subtype = ODP_EVENT_PACKET_BASIC;
+ pkt_hdr->input = ODP_PKTIO_INVALID;
+ packet_parse_reset(pkt_hdr, 1);
+
+ return packet_handle(pkt_hdr);
+}
+
+void odp_packet_proto_stats_request(odp_packet_t pkt, odp_packet_proto_stats_opt_t *opt)
+{
+ (void)pkt;
+ (void)opt;
+}
+
+odp_proto_stats_t odp_packet_proto_stats(odp_packet_t pkt)
+{
+ (void)pkt;
+
+ return ODP_PROTO_STATS_INVALID;
+}