diff mbox

[API-NEXT,PATCHv2,6/7] linux-generic: packet: implement new packet APIs

Message ID 1461615258-17929-7-git-send-email-bill.fischofer@linaro.org
State New
Headers show

Commit Message

Bill Fischofer April 25, 2016, 8:14 p.m. UTC
Implement the following new Packet APIs:

odp_packet_align()
odp_packet_concat()
odp_packet_split()
odp_packet_copy_part()
odp_packet_copy_data()
odp_packet_move_data()

Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org>
---
 platform/linux-generic/odp_packet.c | 105 ++++++++++++++++++++++++++++++++++++
 1 file changed, 105 insertions(+)
diff mbox

Patch

diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c
index d84a3cc..0b447e4 100644
--- a/platform/linux-generic/odp_packet.c
+++ b/platform/linux-generic/odp_packet.c
@@ -673,6 +673,80 @@  int odp_packet_rem_data(odp_packet_t *pkt_ptr, uint32_t offset, uint32_t len)
 	return 1;
 }
 
+int odp_packet_align(odp_packet_t *pkt, uint32_t offset, uint32_t len,
+		     uint32_t align)
+{
+	int rc;
+	uint32_t shift;
+	uint32_t seglen = 0;  /* GCC */
+	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(*pkt);
+	void *addr = packet_map(pkt_hdr, offset, &seglen);
+	uint64_t uaddr = (uint64_t)addr;
+	uint64_t misalign;
+
+	if (align > ODP_CACHE_LINE_SIZE)
+		align = ODP_CACHE_LINE_SIZE;
+
+	if (seglen >= len) {
+		misalign = align <= 1 ? 0 :
+			ODP_ALIGN_ROUNDUP(uaddr, align) - uaddr;
+		if (misalign == 0)
+			return 0;
+		shift = align - misalign;
+	} else {
+		if (len > pkt_hdr->buf_hdr.segsize)
+			return -1;
+		shift  = len - seglen;
+		uaddr -= shift;
+		misalign = align <= 1 ? 0 :
+			ODP_ALIGN_ROUNDUP(uaddr, align) - uaddr;
+		if (misalign)
+			shift += align - misalign;
+	}
+
+	rc = odp_packet_extend_head(pkt, shift, NULL, NULL);
+	if (rc < 0)
+		return rc;
+
+	(void)odp_packet_move_data(*pkt, 0, shift,
+				   odp_packet_len(*pkt) - shift);
+
+	(void)odp_packet_trunc_tail(pkt, shift, NULL, NULL);
+	return 1;
+}
+
+int odp_packet_concat(odp_packet_t *dst, odp_packet_t src)
+{
+	uint32_t dst_len = odp_packet_len(*dst);
+	uint32_t src_len = odp_packet_len(src);
+
+	if (odp_packet_extend_tail(dst, src_len, NULL, NULL) >= 0) {
+		(void)odp_packet_copy_from_pkt(*dst, dst_len,
+					       src, 0, src_len);
+		if (src != *dst)
+			odp_packet_free(src);
+		return 0;
+	}
+
+	return -1;
+}
+
+int odp_packet_split(odp_packet_t *pkt, uint32_t len, odp_packet_t *tail)
+{
+	uint32_t pktlen = odp_packet_len(*pkt);
+
+	if (len >= pktlen || tail == NULL)
+		return -1;
+
+	*tail = odp_packet_copy_part(*pkt, len, pktlen - len,
+				     odp_packet_pool(*pkt));
+
+	if (*tail == ODP_PACKET_INVALID)
+		return -1;
+
+	return odp_packet_trunc_tail(pkt, pktlen - len, NULL, NULL);
+}
+
 /*
  *
  * Copy
@@ -708,6 +782,22 @@  odp_packet_t odp_packet_copy(odp_packet_t pkt, odp_pool_t pool)
 	return newpkt;
 }
 
+odp_packet_t odp_packet_copy_part(odp_packet_t pkt, uint32_t offset,
+				  uint32_t len, odp_pool_t pool)
+{
+	uint32_t pktlen = odp_packet_len(pkt);
+	odp_packet_t newpkt;
+
+	if (offset >= pktlen || offset + len > pktlen)
+		return ODP_PACKET_INVALID;
+
+	newpkt = odp_packet_alloc(pool, len);
+	if (newpkt != ODP_PACKET_INVALID)
+		odp_packet_copy_from_pkt(newpkt, 0, pkt, offset, len);
+
+	return newpkt;
+}
+
 int odp_packet_copy_to_mem(odp_packet_t pkt, uint32_t offset,
 			   uint32_t len, void *dst)
 {
@@ -809,6 +899,21 @@  int odp_packet_copy_from_pkt(odp_packet_t dst, uint32_t dst_offset,
 
 	return 0;
 }
+
+int odp_packet_copy_data(odp_packet_t pkt, uint32_t dst_offset,
+			 uint32_t src_offset, uint32_t len)
+{
+	return odp_packet_copy_from_pkt(pkt, dst_offset,
+					pkt, src_offset, len);
+}
+
+int odp_packet_move_data(odp_packet_t pkt, uint32_t dst_offset,
+			 uint32_t src_offset, uint32_t len)
+{
+	return odp_packet_copy_from_pkt(pkt, dst_offset,
+					pkt, src_offset, len);
+}
+
 /*
  *
  * Debugging