Implemented multi-queue API with dummy single queue support.
Enables testing the API and provides stubbs for actual
multi-queue implementations. Not optimized.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 .../include/odp/plat/packet_io_types.h             |  14 +-
 .../linux-generic/include/odp_packet_io_internal.h |  46 ++++
 platform/linux-generic/odp_packet_io.c             | 280 +++++++++++++++++++++
 platform/linux-generic/pktio/loop.c                |  10 +-
 platform/linux-generic/pktio/netmap.c              |  10 +-
 platform/linux-generic/pktio/pcap.c                |  10 +-
 platform/linux-generic/pktio/socket.c              |  10 +-
 platform/linux-generic/pktio/socket_mmap.c         |  10 +-
 8 files changed, 382 insertions(+), 8 deletions(-)

diff --git a/platform/linux-generic/include/odp/plat/packet_io_types.h 
b/platform/linux-generic/include/odp/plat/packet_io_types.h
index 1086463..25f7151 100644
--- a/platform/linux-generic/include/odp/plat/packet_io_types.h
+++ b/platform/linux-generic/include/odp/plat/packet_io_types.h
@@ -21,16 +21,24 @@ extern "C" {
 #include <odp/std_types.h>
 #include <odp/plat/strong_types.h>
 
-/** @addtogroup odp_packet_io ODP PACKET IO
+/** @addtogroup odp_packet_io
  *  Operations on a packet.
  *  @{
  */
 
 typedef ODP_HANDLE_T(odp_pktio_t);
 
-typedef ODP_HANDLE_T(odp_pktin_queue_t);
+/** @internal */
+typedef struct odp_pktin_queue_t {
+       odp_pktio_t pktio; /**< @internal pktio handle */
+       int index;         /**< @internal pktio queue index */
+} odp_pktin_queue_t;
 
-typedef ODP_HANDLE_T(odp_pktout_queue_t);
+/** @internal */
+typedef struct odp_pktout_queue_t {
+       odp_pktio_t pktio; /**< @internal pktio handle */
+       int index;         /**< @internal pktio queue index */
+} odp_pktout_queue_t;
 
 #define ODP_PKTIO_INVALID _odp_cast_scalar(odp_pktio_t, 0)
 
diff --git a/platform/linux-generic/include/odp_packet_io_internal.h 
b/platform/linux-generic/include/odp_packet_io_internal.h
index a46c6fe..2b6d116 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -32,6 +32,8 @@ extern "C" {
 
 #define PKTIO_NAME_LEN 256
 
+#define PKTIO_MAX_QUEUES 64
+
 /** Determine if a socket read/write error should be reported. Transient errors
  *  that simply require the caller to retry are ignored, the _send/_recv APIs
  *  are non-blocking and it is the caller's responsibility to retry if the
@@ -87,6 +89,17 @@ struct pktio_entry {
        char name[PKTIO_NAME_LEN];      /**< name of pktio provided to
                                           pktio_open() */
        odp_pktio_param_t param;
+
+       /* Storage for queue handles
+        * Multi-queue support is pktio driver specific */
+       struct {
+               odp_queue_t        queue;
+               odp_pktin_queue_t  pktin;
+       } in_queue[PKTIO_MAX_QUEUES];
+
+       struct {
+               odp_pktout_queue_t pktout;
+       } out_queue[PKTIO_MAX_QUEUES];
 };
 
 typedef union {
@@ -116,6 +129,21 @@ typedef struct pktio_if_ops {
        int (*promisc_mode_set)(pktio_entry_t *pktio_entry,  int enable);
        int (*promisc_mode_get)(pktio_entry_t *pktio_entry);
        int (*mac_get)(pktio_entry_t *pktio_entry, void *mac_addr);
+       int (*capability)(pktio_entry_t *pktio_entry,
+                         odp_pktio_capability_t *capa);
+       int (*input_queues_config)(pktio_entry_t *pktio_entry,
+                                  const odp_pktio_input_queue_param_t *param);
+       int (*output_queues_config)(pktio_entry_t *pktio_entry,
+                                   const odp_pktio_output_queue_param_t *p);
+       int (*in_queues)(pktio_entry_t *entry, odp_queue_t queues[], int num);
+       int (*pktin_queues)(pktio_entry_t *entry, odp_pktin_queue_t queues[],
+                           int num);
+       int (*pktout_queues)(pktio_entry_t *entry, odp_pktout_queue_t queues[],
+                            int num);
+       int (*recv_queue)(pktio_entry_t *entry, int index,
+                         odp_packet_t packets[], int num);
+       int (*send_queue)(pktio_entry_t *entry, int index,
+                         odp_packet_t packets[], int num);
 } pktio_if_ops_t;
 
 extern void *pktio_entry_ptr[];
@@ -151,6 +179,24 @@ static inline void pktio_cls_enabled_set(pktio_entry_t 
*entry, int ena)
 
 int pktin_poll(pktio_entry_t *entry);
 
+/*
+ * Dummy single queue implementations of multi-queue API
+ */
+int single_capability(odp_pktio_capability_t *capa);
+int single_input_queues_config(pktio_entry_t *entry,
+                              const odp_pktio_input_queue_param_t *param);
+int single_output_queues_config(pktio_entry_t *entry,
+                               const odp_pktio_output_queue_param_t *param);
+int single_in_queues(pktio_entry_t *entry, odp_queue_t queues[], int num);
+int single_pktin_queues(pktio_entry_t *entry, odp_pktin_queue_t queues[],
+                       int num);
+int single_pktout_queues(pktio_entry_t *entry, odp_pktout_queue_t queues[],
+                        int num);
+int single_recv_queue(pktio_entry_t *entry, int index, odp_packet_t packets[],
+                     int num);
+int single_send_queue(pktio_entry_t *entry, int index, odp_packet_t packets[],
+                     int num);
+
 extern const pktio_if_ops_t netmap_pktio_ops;
 extern const pktio_if_ops_t sock_mmsg_pktio_ops;
 extern const pktio_if_ops_t sock_mmap_pktio_ops;
diff --git a/platform/linux-generic/odp_packet_io.c 
b/platform/linux-generic/odp_packet_io.c
index 14fb0c5..b6b009d 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -817,6 +817,16 @@ void odp_pktio_param_init(odp_pktio_param_t *params)
        memset(params, 0, sizeof(odp_pktio_param_t));
 }
 
+void odp_pktio_input_queue_param_init(odp_pktio_input_queue_param_t *param)
+{
+       memset(param, 0, sizeof(odp_pktio_input_queue_param_t));
+}
+
+void odp_pktio_output_queue_param_init(odp_pktio_output_queue_param_t *param)
+{
+       memset(param, 0, sizeof(odp_pktio_output_queue_param_t));
+}
+
 void odp_pktio_print(odp_pktio_t id)
 {
        pktio_entry_t *entry;
@@ -905,3 +915,273 @@ int odp_pktio_term_global(void)
 
        return ret;
 }
+
+int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa)
+{
+       pktio_entry_t *entry;
+
+       entry = get_pktio_entry(pktio);
+       if (entry == NULL) {
+               ODP_DBG("pktio entry %d does not exist\n", pktio);
+               return -1;
+       }
+
+       if (entry->s.ops->capability)
+               return entry->s.ops->capability(entry, capa);
+
+       return single_capability(capa);
+}
+
+int odp_pktio_input_queues_config(odp_pktio_t pktio,
+                                 const odp_pktio_input_queue_param_t *param)
+{
+       pktio_entry_t *entry;
+
+       if (param == NULL)
+               return -1;
+
+       entry = get_pktio_entry(pktio);
+       if (entry == NULL) {
+               ODP_DBG("pktio entry %d does not exist\n", pktio);
+               return -1;
+       }
+
+       if (entry->s.ops->input_queues_config)
+               return entry->s.ops->input_queues_config(entry, param);
+
+       return single_input_queues_config(entry, param);
+}
+
+int odp_pktio_output_queues_config(odp_pktio_t pktio,
+                                  const odp_pktio_output_queue_param_t *param)
+{
+       pktio_entry_t *entry;
+       odp_pktio_output_mode_t mode;
+
+       if (param == NULL)
+               return -1;
+
+       entry = get_pktio_entry(pktio);
+       if (entry == NULL) {
+               ODP_DBG("pktio entry %d does not exist\n", pktio);
+               return -1;
+       }
+
+       mode = entry->s.param.out_mode;
+
+       if (mode != ODP_PKTOUT_MODE_SEND)
+               return -1;
+
+       if (entry->s.ops->output_queues_config)
+               return entry->s.ops->output_queues_config(entry, param);
+
+       return single_output_queues_config(entry, param);
+}
+
+int odp_pktio_in_queues(odp_pktio_t pktio, odp_queue_t queues[], int num)
+{
+       pktio_entry_t *entry;
+       odp_pktio_input_mode_t mode;
+
+       entry = get_pktio_entry(pktio);
+       if (entry == NULL) {
+               ODP_DBG("pktio entry %d does not exist\n", pktio);
+               return -1;
+       }
+
+       mode = entry->s.param.in_mode;
+
+       if (mode != ODP_PKTIN_MODE_POLL &&
+           mode != ODP_PKTIN_MODE_SCHED)
+               return -1;
+
+       if (entry->s.ops->in_queues)
+               return entry->s.ops->in_queues(entry, queues, num);
+
+       return single_in_queues(entry, queues, num);
+}
+
+int odp_pktio_pktin_queues(odp_pktio_t pktio, odp_pktin_queue_t queues[],
+                          int num)
+{
+       pktio_entry_t *entry;
+       odp_pktio_input_mode_t mode;
+
+       entry = get_pktio_entry(pktio);
+       if (entry == NULL) {
+               ODP_DBG("pktio entry %d does not exist\n", pktio);
+               return -1;
+       }
+
+       mode = entry->s.param.in_mode;
+
+       if (mode != ODP_PKTIN_MODE_RECV)
+               return -1;
+
+       if (entry->s.ops->pktin_queues)
+               return entry->s.ops->pktin_queues(entry, queues, num);
+
+       return single_pktin_queues(entry, queues, num);
+}
+
+int odp_pktio_pktout_queues(odp_pktio_t pktio, odp_pktout_queue_t queues[],
+                           int num)
+{
+       pktio_entry_t *entry;
+       odp_pktio_output_mode_t mode;
+
+       entry = get_pktio_entry(pktio);
+       if (entry == NULL) {
+               ODP_DBG("pktio entry %d does not exist\n", pktio);
+               return -1;
+       }
+
+       mode = entry->s.param.out_mode;
+
+       if (mode != ODP_PKTOUT_MODE_SEND)
+               return -1;
+
+       if (entry->s.ops->pktout_queues)
+               return entry->s.ops->pktout_queues(entry, queues, num);
+
+       return single_pktout_queues(entry, queues, num);
+}
+
+int odp_pktio_recv_queue(odp_pktin_queue_t queue, odp_packet_t packets[],
+                        int num)
+{
+       pktio_entry_t *entry;
+       odp_pktio_t pktio = queue.pktio;
+
+       entry = get_pktio_entry(pktio);
+       if (entry == NULL) {
+               ODP_DBG("pktio entry %d does not exist\n", pktio);
+               return -1;
+       }
+
+       if (entry->s.ops->recv_queue)
+               return entry->s.ops->recv_queue(entry, queue.index,
+                                               packets, num);
+
+       return single_recv_queue(entry, queue.index, packets, num);
+}
+
+int odp_pktio_send_queue(odp_pktout_queue_t queue, odp_packet_t packets[],
+                        int num)
+{
+       pktio_entry_t *entry;
+       odp_pktio_t pktio = queue.pktio;
+
+       entry = get_pktio_entry(pktio);
+       if (entry == NULL) {
+               ODP_DBG("pktio entry %d does not exist\n", pktio);
+               return -1;
+       }
+
+       if (entry->s.ops->send_queue)
+               return entry->s.ops->send_queue(entry, queue.index,
+                                               packets, num);
+
+       return single_send_queue(entry, queue.index, packets, num);
+}
+
+int single_capability(odp_pktio_capability_t *capa)
+{
+       memset(capa, 0, sizeof(odp_pktio_capability_t));
+       capa->max_input_queues  = 1;
+       capa->max_output_queues = 1;
+
+       return 0;
+}
+
+int single_input_queues_config(pktio_entry_t *entry,
+                              const odp_pktio_input_queue_param_t *param)
+{
+       odp_queue_t queue;
+       odp_pktio_input_mode_t mode;
+
+       mode = entry->s.param.in_mode;
+
+       if (param->num_queues != 1)
+               return -1;
+
+       if (mode == ODP_PKTIN_MODE_DISABLED)
+               return -1;
+
+       if (mode == ODP_PKTIN_MODE_POLL ||
+           mode == ODP_PKTIN_MODE_SCHED) {
+               odp_queue_type_t type = ODP_QUEUE_TYPE_POLL;
+
+               if (mode == ODP_PKTIN_MODE_SCHED)
+                       type = ODP_QUEUE_TYPE_SCHED;
+
+               /* cast needed since queue_param is not defined as const in
+                * in odp_queue_create() */
+               queue = odp_queue_create("pktio_in", type,
+                                        (odp_queue_param_t *)
+                                        &param->queue_param);
+
+               if (queue == ODP_QUEUE_INVALID)
+                       return -1;
+
+               entry->s.in_queue[0].queue = queue;
+       } else {
+               entry->s.in_queue[0].queue       = ODP_QUEUE_INVALID;
+               entry->s.in_queue[0].pktin.pktio = entry->s.handle;
+               entry->s.in_queue[0].pktin.index = 0;
+       }
+
+       return 0;
+}
+
+int single_output_queues_config(pktio_entry_t *entry,
+                               const odp_pktio_output_queue_param_t *param)
+{
+       if (param->num_queues != 1)
+               return -1;
+
+       entry->s.out_queue[0].pktout.pktio = entry->s.handle;
+       entry->s.out_queue[0].pktout.index = 0;
+
+       return 0;
+}
+
+int single_in_queues(pktio_entry_t *entry, odp_queue_t queues[], int num)
+{
+       if (queues && num > 0)
+               queues[0] = entry->s.in_queue[0].queue;
+
+       return 1;
+}
+
+int single_pktin_queues(pktio_entry_t *entry, odp_pktin_queue_t queues[],
+                       int num)
+{
+       if (queues && num > 0)
+               queues[0] = entry->s.in_queue[0].pktin;
+
+       return 1;
+}
+
+int single_pktout_queues(pktio_entry_t *entry, odp_pktout_queue_t queues[],
+                        int num)
+{
+       if (queues && num > 0)
+               queues[0] = entry->s.out_queue[0].pktout;
+
+       return 1;
+}
+
+int single_recv_queue(pktio_entry_t *entry, int index, odp_packet_t packets[],
+                     int num)
+{
+       (void)index;
+       return odp_pktio_recv(entry->s.handle, packets, num);
+}
+
+int single_send_queue(pktio_entry_t *entry, int index, odp_packet_t packets[],
+                     int num)
+{
+       (void)index;
+       return odp_pktio_send(entry->s.handle, packets, num);
+}
diff --git a/platform/linux-generic/pktio/loop.c 
b/platform/linux-generic/pktio/loop.c
index 44da917..47a42ff 100644
--- a/platform/linux-generic/pktio/loop.c
+++ b/platform/linux-generic/pktio/loop.c
@@ -120,5 +120,13 @@ const pktio_if_ops_t loopback_pktio_ops = {
        .mtu_get = loopback_mtu_get,
        .promisc_mode_set = loopback_promisc_mode_set,
        .promisc_mode_get = loopback_promisc_mode_get,
-       .mac_get = loopback_mac_addr_get
+       .mac_get = loopback_mac_addr_get,
+       .capability = NULL,
+       .input_queues_config = NULL,
+       .output_queues_config = NULL,
+       .in_queues = NULL,
+       .pktin_queues = NULL,
+       .pktout_queues = NULL,
+       .recv_queue = NULL,
+       .send_queue = NULL
 };
diff --git a/platform/linux-generic/pktio/netmap.c 
b/platform/linux-generic/pktio/netmap.c
index 20a144d..c4db4b5 100644
--- a/platform/linux-generic/pktio/netmap.c
+++ b/platform/linux-generic/pktio/netmap.c
@@ -347,7 +347,15 @@ const pktio_if_ops_t netmap_pktio_ops = {
        .mtu_get = netmap_mtu_get,
        .promisc_mode_set = netmap_promisc_mode_set,
        .promisc_mode_get = netmap_promisc_mode_get,
-       .mac_get = netmap_mac_addr_get
+       .mac_get = netmap_mac_addr_get,
+       .capability = NULL,
+       .input_queues_config = NULL,
+       .output_queues_config = NULL,
+       .in_queues = NULL,
+       .pktin_queues = NULL,
+       .pktout_queues = NULL,
+       .recv_queue = NULL,
+       .send_queue = NULL
 };
 
 #endif /* ODP_NETMAP */
diff --git a/platform/linux-generic/pktio/pcap.c 
b/platform/linux-generic/pktio/pcap.c
index 94b506d..d1ac1b0 100644
--- a/platform/linux-generic/pktio/pcap.c
+++ b/platform/linux-generic/pktio/pcap.c
@@ -378,5 +378,13 @@ const pktio_if_ops_t pcap_pktio_ops = {
        .mtu_get = pcapif_mtu_get,
        .promisc_mode_set = pcapif_promisc_mode_set,
        .promisc_mode_get = pcapif_promisc_mode_get,
-       .mac_get = pcapif_mac_addr_get
+       .mac_get = pcapif_mac_addr_get,
+       .capability = NULL,
+       .input_queues_config = NULL,
+       .output_queues_config = NULL,
+       .in_queues = NULL,
+       .pktin_queues = NULL,
+       .pktout_queues = NULL,
+       .recv_queue = NULL,
+       .send_queue = NULL
 };
diff --git a/platform/linux-generic/pktio/socket.c 
b/platform/linux-generic/pktio/socket.c
index 56b0a8b..d9baca3 100644
--- a/platform/linux-generic/pktio/socket.c
+++ b/platform/linux-generic/pktio/socket.c
@@ -480,5 +480,13 @@ const pktio_if_ops_t sock_mmsg_pktio_ops = {
        .mtu_get = sock_mtu_get,
        .promisc_mode_set = sock_promisc_mode_set,
        .promisc_mode_get = sock_promisc_mode_get,
-       .mac_get = sock_mac_addr_get
+       .mac_get = sock_mac_addr_get,
+       .capability = NULL,
+       .input_queues_config = NULL,
+       .output_queues_config = NULL,
+       .in_queues = NULL,
+       .pktin_queues = NULL,
+       .pktout_queues = NULL,
+       .recv_queue = NULL,
+       .send_queue = NULL
 };
diff --git a/platform/linux-generic/pktio/socket_mmap.c 
b/platform/linux-generic/pktio/socket_mmap.c
index 6bbe525..b2adfa6 100644
--- a/platform/linux-generic/pktio/socket_mmap.c
+++ b/platform/linux-generic/pktio/socket_mmap.c
@@ -554,5 +554,13 @@ const pktio_if_ops_t sock_mmap_pktio_ops = {
        .mtu_get = sock_mmap_mtu_get,
        .promisc_mode_set = sock_mmap_promisc_mode_set,
        .promisc_mode_get = sock_mmap_promisc_mode_get,
-       .mac_get = sock_mmap_mac_addr_get
+       .mac_get = sock_mmap_mac_addr_get,
+       .capability = NULL,
+       .input_queues_config = NULL,
+       .output_queues_config = NULL,
+       .in_queues = NULL,
+       .pktin_queues = NULL,
+       .pktout_queues = NULL,
+       .recv_queue = NULL,
+       .send_queue = NULL
 };
-- 
2.6.2

_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to