diff mbox

[API-NEXT,RFC,13/31] linux-generic: nic driver segment implementation

Message ID 1452285014-60320-14-git-send-email-christophe.milard@linaro.org
State New
Headers show

Commit Message

Christophe Milard Jan. 8, 2016, 8:29 p.m. UTC
Implementation for NIC driver segments and segment pool and related
methods.
As in linux generic, nic segments matches ODP packets, most of these
functions are just wrappers around packet function equivalents.

Signed-off-by: Christophe Milard <christophe.milard@linaro.org>
---
 include/odp/api/nic.h                              |   5 +
 platform/linux-generic/Makefile.am                 |   3 +
 platform/linux-generic/include/odp/nic.h           |  39 +++++
 .../linux-generic/include/odp/plat/nic_types.h     |  46 ++++++
 .../linux-generic/include/odp/plat/pool_types.h    |   3 +-
 platform/linux-generic/odp_nic.c                   | 163 +++++++++++++++++++++
 6 files changed, 258 insertions(+), 1 deletion(-)
 create mode 100644 platform/linux-generic/include/odp/nic.h
 create mode 100644 platform/linux-generic/include/odp/plat/nic_types.h
 create mode 100644 platform/linux-generic/odp_nic.c
diff mbox

Patch

diff --git a/include/odp/api/nic.h b/include/odp/api/nic.h
index 0b13afd..3846608 100644
--- a/include/odp/api/nic.h
+++ b/include/odp/api/nic.h
@@ -20,6 +20,11 @@ 
 extern "C" {
 #endif
 
+/** @defgroup odp_drivers ODP DRIVERS
+ * Interface ODP-driver
+ *  @{
+ */
+
 /**
  * @typedef odp_nic_sgmt_pool_t
  * A nic segment pool.
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index a070cb3..c47bf52 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -34,6 +34,7 @@  odpinclude_HEADERS = \
 		  $(srcdir)/include/odp/hash.h \
 		  $(srcdir)/include/odp/hints.h \
 		  $(srcdir)/include/odp/init.h \
+		  $(srcdir)/include/odp/nic.h \
 		  $(srcdir)/include/odp/packet_flags.h \
 		  $(srcdir)/include/odp/packet.h \
 		  $(srcdir)/include/odp/packet_io.h \
@@ -71,6 +72,7 @@  odpplatinclude_HEADERS = \
 		  $(srcdir)/include/odp/plat/crypto_types.h \
 		  $(srcdir)/include/odp/plat/dma_types.h \
 		  $(srcdir)/include/odp/plat/event_types.h \
+		  $(srcdir)/include/odp/plat/nic_types.h \
 		  $(srcdir)/include/odp/plat/packet_types.h \
 		  $(srcdir)/include/odp/plat/packet_io_types.h \
 		  $(srcdir)/include/odp/plat/pci_types.h \
@@ -143,6 +145,7 @@  __LIB__libodp_la_SOURCES = \
 			   odp_init.c \
 			   odp_impl.c \
 			   odp_name_table.c \
+			   odp_nic.c \
 			   odp_packet.c \
 			   odp_packet_flags.c \
 			   odp_packet_io.c \
diff --git a/platform/linux-generic/include/odp/nic.h b/platform/linux-generic/include/odp/nic.h
new file mode 100644
index 0000000..b991bc3
--- /dev/null
+++ b/platform/linux-generic/include/odp/nic.h
@@ -0,0 +1,39 @@ 
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP nic driver interface
+ */
+
+#ifndef ODP_PLAT_NIC_H_
+#define ODP_PLAT_NIC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp/std_types.h>
+#include <odp/dma.h>
+#include <odp/shared_memory.h>
+#include <odp/plat/nic_types.h>
+
+/** @ingroup odp_nic
+ *  @{
+ */
+
+/**
+ * @}
+ */
+
+#include <odp/api/nic.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/include/odp/plat/nic_types.h b/platform/linux-generic/include/odp/plat/nic_types.h
new file mode 100644
index 0000000..2cec1b4
--- /dev/null
+++ b/platform/linux-generic/include/odp/plat/nic_types.h
@@ -0,0 +1,46 @@ 
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP NIC driver interface
+ */
+
+#ifndef ODP_NIC_TYPES_H_
+#define ODP_NIC_TYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp/std_types.h>
+#include <odp/plat/strong_types.h>
+#include <odp/plat/pool_types.h>
+
+/** @addtogroup odp_nic
+ *  @{
+ */
+
+/** Nic segment pool */
+typedef ODP_HANDLE_T(odp_nic_sgmt_pool_t);
+/** Invalid nic segment pool */
+#define ODP_NIC_SGMT_POOL_INVALID  _odp_cast_scalar(odp_nic_sgmt_pool_t, -1)
+
+/** Nic segment */
+typedef ODP_HANDLE_T(odp_nic_sgmt_t);
+/** Invalid nic segment */
+#define ODP_NIC_SGMT_INVALID _odp_cast_scalar(odp_nic_sgmt_t, -1)
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/include/odp/plat/pool_types.h b/platform/linux-generic/include/odp/plat/pool_types.h
index 4b32c29..c77e6be 100644
--- a/platform/linux-generic/include/odp/plat/pool_types.h
+++ b/platform/linux-generic/include/odp/plat/pool_types.h
@@ -28,7 +28,8 @@  extern "C" {
 
 typedef ODP_HANDLE_T(odp_pool_t);
 
-#define ODP_POOL_INVALID _odp_cast_scalar(odp_pool_t, 0xffffffff)
+#define ODP_POOL_INVALID  _odp_cast_scalar(odp_pool_t, 0xffffffff)
+#define ODP_POOL_ALL_PKTS _odp_cast_scalar(odp_pool_t, 0xfffffffe)
 
 /**
  * Pool type
diff --git a/platform/linux-generic/odp_nic.c b/platform/linux-generic/odp_nic.c
new file mode 100644
index 0000000..0cd1c19
--- /dev/null
+++ b/platform/linux-generic/odp_nic.c
@@ -0,0 +1,163 @@ 
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#include <odp/nic.h>
+#include <odp/pool.h>
+#include <odp_packet_io_internal.h>
+
+/* operations on NIC segments pools: */
+odp_nic_sgmt_pool_t odp_nic_sgmt_pool_create(odp_pool_t pool_hdl)
+{
+	odp_pool_info_t info;
+
+	if (pool_hdl == ODP_POOL_ALL_PKTS)
+		return (odp_nic_sgmt_pool_t)pool_hdl;
+
+	if (odp_pool_info(pool_hdl, &info) < 0)
+		return ODP_NIC_SGMT_POOL_INVALID;
+
+	if (info.params.type != ODP_POOL_PACKET)
+		return ODP_NIC_SGMT_POOL_INVALID;
+
+	/* in the linux implementation, segment pools maps packet pools: */
+	return (odp_nic_sgmt_pool_t)pool_hdl;
+}
+
+void odp_nic_sgmt_pool_destroy(odp_nic_sgmt_pool_t sgmt_pool_hdl ODP_UNUSED)
+{
+	/* nothing to do on this linux implementation */
+}
+
+int odp_nic_sgmt_pool_info(odp_nic_sgmt_pool_t pool,
+			   odp_nic_sgmt_pool_info_t *info)
+{
+	odp_pool_info_t pool_info;
+
+	if (!info)
+		return -1;
+
+	if ((odp_pool_t)pool == ODP_POOL_ALL_PKTS)
+		return -1;
+
+	if (odp_pool_info((odp_pool_t)pool, &pool_info) < 0)
+		return -1;
+
+	if (pool_info.params.type != ODP_POOL_PACKET)
+		return -1;
+
+	/*
+	 * in linux generic, the packet are not really fragmented:
+	 * one segment covers the whole packet.
+	 * therefore the size of the segment is the size of the packet
+	 * minus the default tail and headroom
+	 */
+	info->nic_max_seg_size = pool_info.params.pkt.len
+				       - ODP_CONFIG_PACKET_HEADROOM
+				       - ODP_CONFIG_PACKET_TAILROOM;
+	info->nic_max_pkt_size = info->nic_max_seg_size;
+
+	return 0;
+}
+
+odp_dma_map_t odp_nic_sgmt_pool_dma_map(odp_nic_sgmt_pool_t pool)
+{
+	odp_pool_info_t pool_info;
+
+	if ((odp_pool_t)pool == ODP_POOL_ALL_PKTS)
+		return _odp_pool_get_dma_map((odp_pool_t)pool);
+
+	if (odp_pool_info((odp_pool_t)pool, &pool_info) < 0)
+		return ODP_DMA_REGION_INVALID;
+
+	if (pool_info.params.type != ODP_POOL_PACKET)
+		return ODP_DMA_REGION_INVALID;
+
+	return _odp_pool_get_dma_map((odp_pool_t)pool);
+}
+
+/* operations on NIC segments: */
+odp_nic_sgmt_t odp_nic_sgmt_alloc(odp_nic_sgmt_pool_t pool)
+{
+	odp_packet_t packet;
+	odp_pool_t packet_pool;
+
+	/* in the linux implementation, nic segments 1:1 map to odp packets */
+	packet_pool = (odp_pool_t)pool;
+	packet = packet_alloc(packet_pool, 0, 1);
+	if (odp_likely(packet != ODP_PACKET_INVALID)) {
+		/* following call is empty on linux, but just as a reminder...*/
+		odp_nic_sgmt_set_next((odp_nic_sgmt_t)packet,
+				      ODP_NIC_SGMT_INVALID);
+		return (odp_nic_sgmt_t)packet;
+	} else {
+		return ODP_NIC_SGMT_INVALID;
+	}
+}
+
+void odp_nic_sgmt_free(odp_nic_sgmt_t sgmt)
+{
+	if (odp_likely(sgmt != ODP_NIC_SGMT_INVALID))
+		odp_packet_free((odp_packet_t)sgmt);
+}
+
+/** returns the virtual userland address for the segment */
+void *odp_nic_sgmt_get_addr(odp_nic_sgmt_t segmt)
+{
+	return odp_packet_data((odp_packet_t)segmt);
+}
+
+/** returns the dma address for the segment */
+odp_dma_addr_t odp_nic_sgmt_get_dma_addr(odp_nic_sgmt_t segmt)
+{
+	/*FIXME: using the virtual address as dma address will only work
+	  with iommu and a single process. */
+	return (odp_dma_addr_t)odp_packet_data((odp_packet_t)segmt);
+}
+
+/** returns the writable length for the segment */
+uint16_t odp_nic_sgmt_get_len(odp_nic_sgmt_t segmt)
+{
+	return odp_packet_buf_len((odp_packet_t)segmt) -
+	       odp_packet_headroom((odp_packet_t)segmt);
+}
+
+/** returns the data length (in bytes) for the segment */
+uint16_t odp_nic_sgmt_get_datalen(odp_nic_sgmt_t segmt)
+{
+	return odp_packet_len((odp_packet_t)segmt);
+}
+
+/**  set the data length (in bytes) for the segment */
+void odp_nic_sgmt_set_datalen(odp_nic_sgmt_t segmt, uint16_t len)
+{
+	odp_packet_pull_tail((odp_packet_t)segmt,
+			     odp_packet_len((odp_packet_t)segmt) - len);
+}
+
+/** get the next segment of a segment chain (or ODP_NIC_SGMT_INVALID) */
+odp_nic_sgmt_t odp_nic_sgmt_get_next(
+	__attribute__((__unused__)) odp_nic_sgmt_t segmt)
+{
+	/* not needed on linux generic as packet are contiguous */
+	return ODP_NIC_SGMT_INVALID;
+}
+
+/** set the next segment of a segment chain (may be ODP_NIC_SGMT_INVALID) */
+void odp_nic_sgmt_set_next(
+	__attribute__((__unused__)) odp_nic_sgmt_t segmt,
+	__attribute__((__unused__)) odp_nic_sgmt_t next)
+{
+	/* not needed on linux generic as packet are contiguous */
+}
+
+/**  set the segment as last segment of the packet. */
+void odp_nic_sgmt_set_last(odp_nic_sgmt_t segmt)
+{
+	odp_packet_hdr_t *pkt_hdr;
+
+	pkt_hdr = odp_packet_hdr((odp_packet_t)segmt);
+	packet_parse_l2(pkt_hdr);
+}