diff mbox

[API-NEXT,RFC,12/31] driver api: nic segments and segment pool

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

Commit Message

Christophe Milard Jan. 8, 2016, 8:29 p.m. UTC
Nic drivers use NIC segments as basic "data unit" when receiving/sending
data. NIC segments may match ODP packet fragments (and probably will in
most cases) but may not (if ODP packets implementation is not directely
manageable by the NIC HW, or simply if odp packet are not DMA mappable).
This patch defines the segments and segment pool (where NIC segments are
allocated from), as well as the different methods which can be used on
those.

Signed-off-by: Christophe Milard <christophe.milard@linaro.org>
---
 include/odp/api/nic.h | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/odp_driver.h  |   1 +
 2 files changed, 153 insertions(+)
 create mode 100644 include/odp/api/nic.h
diff mbox

Patch

diff --git a/include/odp/api/nic.h b/include/odp/api/nic.h
new file mode 100644
index 0000000..0b13afd
--- /dev/null
+++ b/include/odp/api/nic.h
@@ -0,0 +1,152 @@ 
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP API towards NIC ethernet drivers
+ */
+
+#ifndef ODP_API_NIC_H_
+#define ODP_API_NIC_H_
+
+#include <odp/api/dma.h>
+#include <odp/api/pool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @typedef odp_nic_sgmt_pool_t
+ * A nic segment pool.
+ * One  pool of nic segments is allocatated by each driver for each queue
+ * at probe time.
+ * Nic segments are allocated from this pool by the driver on RX direction,
+ * and freeed by the driver on tx.
+ */
+
+/**
+ * Create a pool of nic segment, to be used by drivers.
+ * Nic segments may match 1:1 to the underlaying ODP packets segments,
+ * but may not do so in case the ODP implementation does not provide
+ * DMA mappable ODP buffers, or when fragmentation occurs.
+ * In any case, the ODP implementation
+ * is responsible for the relationship (and possible conversion) between
+ * matching ODP packets and nic segments.
+ *
+ * @param pool odp packet pool "matching" the created segment pool.
+ * @return A newly created nic segment pool handle or
+ * ODP_NIC_SGMT_POOL_INVALID.
+ */
+odp_nic_sgmt_pool_t odp_nic_sgmt_pool_create(odp_pool_t pool_hdl);
+
+/**
+ * Create a pool of nic segment
+ * @param sgmt_pool_hdl handle to the pool to be destroyed as returned by
+ *			odp_nic_sgmt_pool_create
+ */
+void odp_nic_sgmt_pool_destroy(odp_nic_sgmt_pool_t sgmt_pool_hdl);
+
+/**
+ * Nic segment Pool information struct
+ * Used to get information about a nic segment pool.
+ * Drivers use this function to know the maximum size that may be
+ * written into the allocated nic segments.
+ * If the packet_size returned here exceeds the segment size, the the driver
+ * will use (and chain) multiple segments to receive large packets.
+ */
+typedef struct odp_nic_sgmt_pool_info_t {
+	/**< max size (bytes) of segments from this pool */
+	int nic_max_seg_size;
+	/**< max packet size (> nic_segment_size if scatter-jitter supported) */
+	int nic_max_pkt_size;
+} odp_nic_sgmt_pool_info_t;
+
+/** The function to retrieve segment pool information
+ * @param pool A odp nic segment poll handle
+ * @param info A pointer to a odp_pool_info_t to be filled
+ * @return a negative value on error
+ */
+int odp_nic_sgmt_pool_info(odp_nic_sgmt_pool_t pool,
+			   odp_nic_sgmt_pool_info_t *info);
+
+/** The function to retrieve segment pool DMA information
+ * @param pool A odp nic segment poll handle
+ * This function will return a DMA map handle (odp_dma_map_t) -possibly
+ * linked to others if the DMA region is scattered. This descriptor can be used
+ * to gain DMA access to all NIC segments allocated from this
+ * buffer.
+ * @return An ODP DMA map descriptor handle
+ */
+odp_dma_map_t odp_nic_sgmt_pool_dma_map(odp_nic_sgmt_pool_t pool);
+
+/**
+ * @typedef odp_nic_sgmt_t
+ * A nic segment.
+ * Nic segments are the data elements exchanged between ODP
+ * and nic drivers (in both direction).
+ * They may match 1:1 to the underlaying ODP packets segments,
+ * but may not do so in case the ODP implementation does not provide
+ * DMA mappable ODP buffers. In any case, the ODP implementation
+ * is responsible for the relationship (and possible conversion) between
+ * ODP packets and nic segments.
+ * Each nic segment must be DMA mappable, ie must be contiguous in the DMA
+ * space (that is, it must be contiguous physical memory in the absence of
+ * iommu).
+ * Nic segments have a "next" pointer to allow chaining. The rx side of the
+ * driver should link segments in the case the rx packet is larger than the
+ * segment size (and the max packet size is larger than the segment size).
+ * The driver should also treat linked segments as single packet on tx.
+ */
+
+/**
+ * Allocate a segment from a nic segment pool (for RX)
+ * @param pool Nic segment pool handle
+ * @return Handle of allocated segment
+ */
+odp_nic_sgmt_t odp_nic_sgmt_alloc(odp_nic_sgmt_pool_t pool);
+
+/**
+ * Free a segment
+ * @param Handle of allocated segment
+ */
+void odp_nic_sgmt_free(odp_nic_sgmt_t sgmt);
+
+/* operations on NIC segments: */
+/** returns the virtual userland address for the nic segment */
+void *odp_nic_sgmt_get_addr(odp_nic_sgmt_t segmt);
+
+/** returns the dma address (physical or iova) for the nic segment */
+odp_dma_addr_t odp_nic_sgmt_get_dma_addr(odp_nic_sgmt_t segmt);
+
+/** returns the length (writable length) of the nic segment */
+uint16_t odp_nic_sgmt_get_len(odp_nic_sgmt_t segmt);
+
+/** returns the length of the data contained in the nic segment */
+uint16_t odp_nic_sgmt_get_datalen(odp_nic_sgmt_t segmt);
+
+/** set the length of the data contained in the nic segment */
+void odp_nic_sgmt_set_datalen(odp_nic_sgmt_t segmt, uint16_t len);
+
+/**  set the segment as last segment of the packet. */
+void odp_nic_sgmt_set_last(odp_nic_sgmt_t segmt);
+
+/** get the next segment of a segment chain (or ODP_NIC_SGMT_INVALID) */
+odp_nic_sgmt_t odp_nic_sgmt_get_next(odp_nic_sgmt_t segmt);
+
+/** set the next segment of a segment chain (may be ODP_NIC_SGMT_INVALID) */
+void odp_nic_sgmt_set_next(odp_nic_sgmt_t segmt, odp_nic_sgmt_t next);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ODP_API_NIC_H_ */
diff --git a/include/odp_driver.h b/include/odp_driver.h
index 6c1eded..6fda613 100644
--- a/include/odp_driver.h
+++ b/include/odp_driver.h
@@ -23,6 +23,7 @@  extern "C" {
 #include <odp/byteorder.h>
 #include <odp/dma.h>
 #include <odp/pci.h>
+#include <odp/nic.h>
 #include <odp/align.h>
 #include <odp/sync.h>
 #include <odp/hints.h>