From: Honnappa Nagarahalli <[email protected]>

Created abstract queue type. Queue APIs and functions towards the
internal components are converted into function pointers.

Signed-off-by: Honnappa Nagarahalli <[email protected]>
---
/** Email created from pull request 43 (nagarahalli:api-next-mod-queue1)
 ** https://github.com/Linaro/odp/pull/43
 ** Patch: https://github.com/Linaro/odp/pull/43.patch
 ** Base sha: 57783b35f4383bdfdd146f2a3333bbc8bb995896
 ** Merge commit sha: 9b21e1979ace878bb44efcfb9b40922b706ea7e8
 **/
 platform/linux-generic/Makefile.am                 |   2 +
 .../include/odp_classification_datamodel.h         |   4 +-
 .../linux-generic/include/odp_packet_io_queue.h    |  20 +-
 platform/linux-generic/include/odp_queue_if.h      | 104 ++++++++
 .../linux-generic/include/odp_queue_internal.h     |  41 +---
 platform/linux-generic/include/odp_schedule_if.h   |   2 +-
 .../include/odp_traffic_mngr_internal.h            |   4 +-
 platform/linux-generic/odp_classification.c        |  10 +-
 platform/linux-generic/odp_init.c                  |  17 +-
 platform/linux-generic/odp_packet_io.c             |  90 ++++---
 platform/linux-generic/odp_queue.c                 | 261 +++++++++++++++------
 platform/linux-generic/odp_queue_if.c              | 103 ++++++++
 platform/linux-generic/odp_schedule.c              |   6 +-
 platform/linux-generic/odp_schedule_iquery.c       |   6 +-
 platform/linux-generic/odp_schedule_sp.c           |   4 +-
 platform/linux-generic/odp_traffic_mngr.c          |  21 +-
 platform/linux-generic/pktio/loop.c                |  13 +-
 17 files changed, 515 insertions(+), 193 deletions(-)
 create mode 100644 platform/linux-generic/include/odp_queue_if.h
 create mode 100644 platform/linux-generic/odp_queue_if.c

diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index 79f0e70c..58c73767 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -170,6 +170,7 @@ noinst_HEADERS = \
                  ${srcdir}/include/odp_posix_extensions.h \
                  ${srcdir}/include/odp_queue_internal.h \
                  ${srcdir}/include/odp_ring_internal.h \
+                 ${srcdir}/include/odp_queue_if.h \
                  ${srcdir}/include/odp_schedule_if.h \
                  ${srcdir}/include/odp_sorted_list_internal.h \
                  ${srcdir}/include/odp_shm_internal.h \
@@ -225,6 +226,7 @@ __LIB__libodp_linux_la_SOURCES = \
                           odp_pkt_queue.c \
                           odp_pool.c \
                           odp_queue.c \
+                          odp_queue_if.c \
                           odp_rwlock.c \
                           odp_rwlock_recursive.c \
                           odp_schedule.c \
diff --git a/platform/linux-generic/include/odp_classification_datamodel.h 
b/platform/linux-generic/include/odp_classification_datamodel.h
index 9df756bf..fbe10cb4 100644
--- a/platform/linux-generic/include/odp_classification_datamodel.h
+++ b/platform/linux-generic/include/odp_classification_datamodel.h
@@ -24,7 +24,7 @@ extern "C" {
 #include <odp_pool_internal.h>
 #include <odp_packet_internal.h>
 #include <odp_packet_io_internal.h>
-#include <odp_queue_internal.h>
+#include <odp_queue_if.h>
 #include <protocols/ip.h>
 
 /* Maximum Class Of Service Entry */
@@ -85,7 +85,7 @@ typedef struct pmr_term_value {
 Class Of Service
 */
 struct cos_s {
-       queue_entry_t *queue;           /* Associated Queue */
+       queue_t queue;                  /* Associated Queue */
        odp_pool_t pool;                /* Associated Buffer pool */
        union pmr_u *pmr[ODP_PMR_PER_COS_MAX];  /* Chained PMR */
        union cos_u *linked_cos[ODP_PMR_PER_COS_MAX]; /* Chained CoS with PMR*/
diff --git a/platform/linux-generic/include/odp_packet_io_queue.h 
b/platform/linux-generic/include/odp_packet_io_queue.h
index d1d4b225..71333ddc 100644
--- a/platform/linux-generic/include/odp_packet_io_queue.h
+++ b/platform/linux-generic/include/odp_packet_io_queue.h
@@ -18,7 +18,7 @@
 extern "C" {
 #endif
 
-#include <odp_queue_internal.h>
+#include <odp_queue_if.h>
 #include <odp_buffer_internal.h>
 #include <odp_config_internal.h>
 
@@ -28,20 +28,18 @@ extern "C" {
 ODP_STATIC_ASSERT(ODP_PKTIN_QUEUE_MAX_BURST >= QUEUE_MULTI_MAX,
                  "ODP_PKTIN_DEQ_MULTI_MAX_ERROR");
 
-int pktin_enqueue(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr);
-odp_buffer_hdr_t *pktin_dequeue(queue_entry_t *queue);
+int pktin_enqueue(queue_t queue, odp_buffer_hdr_t *buf_hdr);
+odp_buffer_hdr_t *pktin_dequeue(queue_t queue);
 
-int pktin_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int 
num);
-int pktin_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int 
num);
+int pktin_enq_multi(queue_t queue, odp_buffer_hdr_t *buf_hdr[], int num);
+int pktin_deq_multi(queue_t queue, odp_buffer_hdr_t *buf_hdr[], int num);
 
 
-int pktout_enqueue(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr);
-odp_buffer_hdr_t *pktout_dequeue(queue_entry_t *queue);
+int pktout_enqueue(queue_t queue, odp_buffer_hdr_t *buf_hdr);
+odp_buffer_hdr_t *pktout_dequeue(queue_t queue);
 
-int pktout_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[],
-                    int num);
-int pktout_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[],
-                    int num);
+int pktout_enq_multi(queue_t queue, odp_buffer_hdr_t *buf_hdr[], int num);
+int pktout_deq_multi(queue_t queue, odp_buffer_hdr_t *buf_hdr[], int num);
 
 #ifdef __cplusplus
 }
diff --git a/platform/linux-generic/include/odp_queue_if.h 
b/platform/linux-generic/include/odp_queue_if.h
new file mode 100644
index 00000000..4359435f
--- /dev/null
+++ b/platform/linux-generic/include/odp_queue_if.h
@@ -0,0 +1,104 @@
+/* Copyright (c) 2017, ARM Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#ifndef ODP_QUEUE_IF_H_
+#define ODP_QUEUE_IF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp/api/queue.h>
+#include <odp/api/schedule.h>
+#include <odp/api/packet_io.h>
+#include <odp_forward_typedefs_internal.h>
+
+#define QUEUE_MULTI_MAX CONFIG_BURST_SIZE
+
+/* Queue API functions */
+typedef struct {
+       odp_queue_t (*queue_create)(const char *name,
+                                   const odp_queue_param_t *param);
+       int (*queue_destroy)(odp_queue_t queue);
+       odp_queue_t (*queue_lookup)(const char *name);
+       int (*queue_capability)(odp_queue_capability_t *capa);
+       int (*queue_context_set)(odp_queue_t queue, void *context,
+                                uint32_t len);
+       void *(*queue_context)(odp_queue_t queue);
+       int (*queue_enq)(odp_queue_t queue, odp_event_t ev);
+       int (*queue_enq_multi)(odp_queue_t queue, const odp_event_t events[],
+                              int num);
+       odp_event_t (*queue_deq)(odp_queue_t queue);
+       int (*queue_deq_multi)(odp_queue_t queue, odp_event_t events[],
+                              int num);
+       odp_queue_type_t (*queue_type)(odp_queue_t queue);
+       odp_schedule_sync_t (*queue_sched_type)(odp_queue_t queue);
+       odp_schedule_prio_t (*queue_sched_prio)(odp_queue_t queue);
+       odp_schedule_group_t (*queue_sched_group)(odp_queue_t queue);
+       int (*queue_lock_count)(odp_queue_t queue);
+       uint64_t (*queue_to_u64)(odp_queue_t hdl);
+       void (*queue_param_init)(odp_queue_param_t *param);
+       int (*queue_info)(odp_queue_t queue, odp_queue_info_t *info);
+} queue_api_t;
+
+/* Internal abstract queue handle */
+typedef struct { char dummy; } _queue_t;
+typedef _queue_t *queue_t;
+
+typedef int (*queue_init_global_fn_t)(void);
+typedef int (*queue_term_global_fn_t)(void);
+typedef int (*queue_init_local_fn_t)(void);
+typedef int (*queue_term_local_fn_t)(void);
+typedef queue_t (*queue_from_ext_fn_t)(odp_queue_t handle);
+typedef odp_queue_t (*queue_to_ext_fn_t)(queue_t handle);
+typedef int (*queue_enq_fn_t)(queue_t handle, odp_buffer_hdr_t *);
+typedef int (*queue_enq_multi_fn_t)(queue_t handle, odp_buffer_hdr_t **, int);
+typedef odp_buffer_hdr_t *(*queue_deq_fn_t)(queue_t handle);
+typedef int (*queue_deq_multi_fn_t)(queue_t handle, odp_buffer_hdr_t **, int);
+typedef odp_pktout_queue_t (*queue_get_pktout_fn_t)(queue_t handle);
+typedef void (*queue_set_pktout_fn_t)(queue_t handle, odp_pktio_t pktio,
+                                     int index);
+typedef odp_pktin_queue_t (*queue_get_pktin_fn_t)(queue_t handle);
+typedef void (*queue_set_pktin_fn_t)(queue_t handle, odp_pktio_t pktio,
+                                    int index);
+typedef void (*queue_set_enq_fn_t)(queue_t handle, queue_enq_fn_t func);
+typedef void (*queue_set_enq_multi_fn_t)(queue_t handle,
+                                        queue_enq_multi_fn_t func);
+typedef void (*queue_set_deq_fn_t)(queue_t handle, queue_deq_fn_t func);
+typedef void (*queue_set_deq_multi_fn_t)(queue_t handle,
+                                        queue_deq_multi_fn_t func);
+typedef void (*queue_set_type_fn_t)(queue_t handle, odp_queue_type_t type);
+
+/* Queue functions towards other internal components */
+typedef struct {
+       queue_init_global_fn_t init_global;
+       queue_term_global_fn_t term_global;
+       queue_init_local_fn_t init_local;
+       queue_term_local_fn_t term_local;
+       queue_from_ext_fn_t from_ext;
+       queue_to_ext_fn_t to_ext;
+       queue_enq_fn_t enq;
+       queue_enq_multi_fn_t enq_multi;
+       queue_deq_fn_t deq;
+       queue_deq_multi_fn_t deq_multi;
+       queue_get_pktout_fn_t get_pktout;
+       queue_set_pktout_fn_t set_pktout;
+       queue_get_pktin_fn_t get_pktin;
+       queue_set_pktin_fn_t set_pktin;
+       queue_set_enq_fn_t set_enq_fn;
+       queue_set_enq_multi_fn_t set_enq_multi_fn;
+       queue_set_deq_fn_t set_deq_fn;
+       queue_set_deq_multi_fn_t set_deq_multi_fn;
+       queue_set_type_fn_t set_type;
+} queue_fn_t;
+
+extern const queue_fn_t *queue_fn;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/include/odp_queue_internal.h 
b/platform/linux-generic/include/odp_queue_internal.h
index 560f826e..0c31ce8a 100644
--- a/platform/linux-generic/include/odp_queue_internal.h
+++ b/platform/linux-generic/include/odp_queue_internal.h
@@ -20,7 +20,7 @@ extern "C" {
 
 #include <odp/api/queue.h>
 #include <odp_forward_typedefs_internal.h>
-#include <odp_schedule_if.h>
+#include <odp_queue_if.h>
 #include <odp_buffer_internal.h>
 #include <odp_align_internal.h>
 #include <odp/api/packet_io.h>
@@ -29,26 +29,12 @@ extern "C" {
 #include <odp/api/ticketlock.h>
 #include <odp_config_internal.h>
 
-#define QUEUE_MULTI_MAX CONFIG_BURST_SIZE
-
 #define QUEUE_STATUS_FREE         0
 #define QUEUE_STATUS_DESTROYED    1
 #define QUEUE_STATUS_READY        2
 #define QUEUE_STATUS_NOTSCHED     3
 #define QUEUE_STATUS_SCHED        4
 
-
-/* forward declaration */
-union queue_entry_u;
-
-typedef int (*enq_func_t)(union queue_entry_u *, odp_buffer_hdr_t *);
-typedef        odp_buffer_hdr_t *(*deq_func_t)(union queue_entry_u *);
-
-typedef int (*enq_multi_func_t)(union queue_entry_u *,
-                               odp_buffer_hdr_t **, int);
-typedef        int (*deq_multi_func_t)(union queue_entry_u *,
-                               odp_buffer_hdr_t **, int);
-
 struct queue_entry_s {
        odp_ticketlock_t  lock ODP_ALIGNED_CACHE;
 
@@ -63,10 +49,10 @@ struct queue_entry_s {
                odp_atomic_u64_t  lock[CONFIG_QUEUE_MAX_ORD_LOCKS];
        } ordered ODP_ALIGNED_CACHE;
 
-       enq_func_t       enqueue ODP_ALIGNED_CACHE;
-       deq_func_t       dequeue;
-       enq_multi_func_t enqueue_multi;
-       deq_multi_func_t dequeue_multi;
+       queue_enq_fn_t       enqueue ODP_ALIGNED_CACHE;
+       queue_deq_fn_t       dequeue;
+       queue_enq_multi_fn_t enqueue_multi;
+       queue_deq_multi_fn_t dequeue_multi;
 
        uint32_t          index;
        odp_queue_t       handle;
@@ -82,15 +68,8 @@ union queue_entry_u {
        uint8_t pad[ROUNDUP_CACHE_LINE(sizeof(struct queue_entry_s))];
 };
 
-
 queue_entry_t *get_qentry(uint32_t queue_id);
 
-int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr);
-odp_buffer_hdr_t *queue_deq(queue_entry_t *queue);
-
-int queue_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int 
num);
-int queue_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int 
num);
-
 void queue_lock(queue_entry_t *queue);
 void queue_unlock(queue_entry_t *queue);
 
@@ -99,12 +78,14 @@ static inline uint32_t queue_to_id(odp_queue_t handle)
        return _odp_typeval(handle) - 1;
 }
 
-static inline queue_entry_t *queue_to_qentry(odp_queue_t handle)
+static inline queue_entry_t *qentry_from_int(queue_t handle)
 {
-       uint32_t queue_id;
+       return (queue_entry_t *)(void *)(handle);
+}
 
-       queue_id = queue_to_id(handle);
-       return get_qentry(queue_id);
+static inline queue_t qentry_to_int(queue_entry_t *qentry)
+{
+       return (queue_t)(qentry);
 }
 
 #ifdef __cplusplus
diff --git a/platform/linux-generic/include/odp_schedule_if.h 
b/platform/linux-generic/include/odp_schedule_if.h
index 530d157f..9adacef7 100644
--- a/platform/linux-generic/include/odp_schedule_if.h
+++ b/platform/linux-generic/include/odp_schedule_if.h
@@ -26,7 +26,7 @@ typedef int (*schedule_init_queue_fn_t)(uint32_t queue_index,
 typedef void (*schedule_destroy_queue_fn_t)(uint32_t queue_index);
 typedef int (*schedule_sched_queue_fn_t)(uint32_t queue_index);
 typedef int (*schedule_unsched_queue_fn_t)(uint32_t queue_index);
-typedef int (*schedule_ord_enq_multi_fn_t)(uint32_t queue_index,
+typedef int (*schedule_ord_enq_multi_fn_t)(queue_t handle,
                                           void *buf_hdr[], int num, int *ret);
 typedef int (*schedule_init_global_fn_t)(void);
 typedef int (*schedule_term_global_fn_t)(void);
diff --git a/platform/linux-generic/include/odp_traffic_mngr_internal.h 
b/platform/linux-generic/include/odp_traffic_mngr_internal.h
index 9f821fe4..e8254f5e 100644
--- a/platform/linux-generic/include/odp_traffic_mngr_internal.h
+++ b/platform/linux-generic/include/odp_traffic_mngr_internal.h
@@ -29,7 +29,7 @@ extern "C" {
 #include <odp_internal.h>
 #include <odp_debug_internal.h>
 #include <odp_buffer_internal.h>
-#include <odp_queue_internal.h>
+#include <odp_queue_if.h>
 #include <odp_packet_internal.h>
 
 typedef struct stat  file_stat_t;
@@ -286,7 +286,7 @@ struct tm_queue_obj_s {
        uint8_t tm_idx;
        uint8_t delayed_cnt;
        uint8_t blocked_cnt;
-       queue_entry_t tm_qentry;
+       queue_t tm_qentry;
 };
 
 struct tm_node_obj_s {
diff --git a/platform/linux-generic/odp_classification.c 
b/platform/linux-generic/odp_classification.c
index 7ebc47d7..5f153e73 100644
--- a/platform/linux-generic/odp_classification.c
+++ b/platform/linux-generic/odp_classification.c
@@ -157,14 +157,14 @@ int odp_cls_capability(odp_cls_capability_t *capability)
 odp_cos_t odp_cls_cos_create(const char *name, odp_cls_cos_param_t *param)
 {
        int i, j;
-       queue_entry_t *queue;
+       queue_t queue;
        odp_cls_drop_t drop_policy;
 
        /* Packets are dropped if Queue or Pool is invalid*/
        if (param->queue == ODP_QUEUE_INVALID)
                queue = NULL;
        else
-               queue = queue_to_qentry(param->queue);
+               queue = queue_fn->from_ext(param->queue);
 
        drop_policy = param->drop_policy;
 
@@ -266,7 +266,7 @@ int odp_cos_queue_set(odp_cos_t cos_id, odp_queue_t 
queue_id)
        if (queue_id == ODP_QUEUE_INVALID)
                cos->s.queue = NULL;
        else
-               cos->s.queue = queue_to_qentry(queue_id);
+               cos->s.queue = queue_fn->from_ext(queue_id);
        return 0;
 }
 
@@ -282,7 +282,7 @@ odp_queue_t odp_cos_queue(odp_cos_t cos_id)
        if (!cos->s.queue)
                return ODP_QUEUE_INVALID;
 
-       return cos->s.queue->s.handle;
+       return queue_fn->to_ext(cos->s.queue);
 }
 
 int odp_cos_drop_set(odp_cos_t cos_id, odp_cls_drop_t drop_policy)
@@ -846,7 +846,7 @@ int cls_classify_packet(pktio_entry_t *entry, const uint8_t 
*base,
 
        *pool = cos->s.pool;
        pkt_hdr->p.input_flags.dst_queue = 1;
-       pkt_hdr->dst_queue = cos->s.queue->s.handle;
+       pkt_hdr->dst_queue = queue_fn->to_ext(cos->s.queue);
 
        return 0;
 }
diff --git a/platform/linux-generic/odp_init.c 
b/platform/linux-generic/odp_init.c
index 685e02fa..31bd7c73 100644
--- a/platform/linux-generic/odp_init.c
+++ b/platform/linux-generic/odp_init.c
@@ -218,7 +218,7 @@ int odp_init_global(odp_instance_t *instance,
        }
        stage = POOL_INIT;
 
-       if (odp_queue_init_global()) {
+       if (queue_fn->init_global()) {
                ODP_ERR("ODP queue init failed.\n");
                goto init_failed;
        }
@@ -346,7 +346,7 @@ int _odp_term_global(enum init_stage stage)
                /* Fall through */
 
        case QUEUE_INIT:
-               if (odp_queue_term_global()) {
+               if (queue_fn->term_global()) {
                        ODP_ERR("ODP queue term failed.\n");
                        rc = -1;
                }
@@ -441,6 +441,12 @@ int odp_init_local(odp_instance_t instance, 
odp_thread_type_t thr_type)
        }
        stage = POOL_INIT;
 
+       if (queue_fn->init_local()) {
+               ODP_ERR("ODP queue local init failed.\n");
+               goto init_fail;
+       }
+       stage = QUEUE_INIT;
+
        if (sched_fn->init_local()) {
                ODP_ERR("ODP schedule local init failed.\n");
                goto init_fail;
@@ -474,6 +480,13 @@ int _odp_term_local(enum init_stage stage)
                }
                /* Fall through */
 
+       case QUEUE_INIT:
+               if (queue_fn->term_local()) {
+                       ODP_ERR("ODP queue local term failed.\n");
+                       rc = -1;
+               }
+               /* Fall through */
+
        case POOL_INIT:
                if (odp_pool_term_local()) {
                        ODP_ERR("ODP buffer pool local term failed.\n");
diff --git a/platform/linux-generic/odp_packet_io.c 
b/platform/linux-generic/odp_packet_io.c
index 877978ba..8fb5b5ee 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -16,7 +16,7 @@
 #include <odp/api/shared_memory.h>
 #include <odp_packet_socket.h>
 #include <odp_config_internal.h>
-#include <odp_queue_internal.h>
+#include <odp_queue_if.h>
 #include <odp_schedule_if.h>
 #include <odp_classification_internal.h>
 #include <odp_debug_internal.h>
@@ -568,11 +568,11 @@ static inline int pktin_recv_buf(odp_pktin_queue_t queue,
                buf_hdr = buf_hdl_to_hdr(buf);
 
                if (pkt_hdr->p.input_flags.dst_queue) {
-                       queue_entry_t *dst_queue;
+                       queue_t dst_queue;
                        int ret;
 
-                       dst_queue = queue_to_qentry(pkt_hdr->dst_queue);
-                       ret = queue_enq(dst_queue, buf_hdr);
+                       dst_queue = queue_fn->from_ext(pkt_hdr->dst_queue);
+                       ret = queue_fn->enq(dst_queue, buf_hdr);
                        if (ret < 0)
                                odp_packet_free(pkt);
                        continue;
@@ -582,45 +582,42 @@ static inline int pktin_recv_buf(odp_pktin_queue_t queue,
        return num_rx;
 }
 
-int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr)
+int pktout_enqueue(queue_t qentry, odp_buffer_hdr_t *buf_hdr)
 {
        odp_packet_t pkt = _odp_packet_from_buffer(buf_hdr->handle.handle);
        int len = 1;
        int nbr;
 
-       if (sched_fn->ord_enq_multi(qentry->s.index, (void **)buf_hdr, len,
-                                   &nbr))
+       if (sched_fn->ord_enq_multi(qentry, (void **)buf_hdr, len, &nbr))
                return (nbr == len ? 0 : -1);
 
-       nbr = odp_pktout_send(qentry->s.pktout, &pkt, len);
+       nbr = odp_pktout_send(queue_fn->get_pktout(qentry), &pkt, len);
        return (nbr == len ? 0 : -1);
 }
 
-odp_buffer_hdr_t *pktout_dequeue(queue_entry_t *qentry ODP_UNUSED)
+odp_buffer_hdr_t *pktout_dequeue(queue_t qentry ODP_UNUSED)
 {
        ODP_ABORT("attempted dequeue from a pktout queue");
        return NULL;
 }
 
-int pktout_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[],
-                    int num)
+int pktout_enq_multi(queue_t qentry, odp_buffer_hdr_t *buf_hdr[], int num)
 {
        odp_packet_t pkt_tbl[QUEUE_MULTI_MAX];
        int nbr;
        int i;
 
-       if (sched_fn->ord_enq_multi(qentry->s.index, (void **)buf_hdr, num,
-                                   &nbr))
+       if (sched_fn->ord_enq_multi(qentry, (void **)buf_hdr, num, &nbr))
                return nbr;
 
        for (i = 0; i < num; ++i)
                pkt_tbl[i] = _odp_packet_from_buffer(buf_hdr[i]->handle.handle);
 
-       nbr = odp_pktout_send(qentry->s.pktout, pkt_tbl, num);
+       nbr = odp_pktout_send(queue_fn->get_pktout(qentry), pkt_tbl, num);
        return nbr;
 }
 
-int pktout_deq_multi(queue_entry_t *qentry ODP_UNUSED,
+int pktout_deq_multi(queue_t qentry ODP_UNUSED,
                     odp_buffer_hdr_t *buf_hdr[] ODP_UNUSED,
                     int num ODP_UNUSED)
 {
@@ -628,48 +625,49 @@ int pktout_deq_multi(queue_entry_t *qentry ODP_UNUSED,
        return 0;
 }
 
-int pktin_enqueue(queue_entry_t *qentry ODP_UNUSED,
+int pktin_enqueue(queue_t qentry ODP_UNUSED,
                  odp_buffer_hdr_t *buf_hdr ODP_UNUSED)
 {
        ODP_ABORT("attempted enqueue to a pktin queue");
        return -1;
 }
 
-odp_buffer_hdr_t *pktin_dequeue(queue_entry_t *qentry)
+odp_buffer_hdr_t *pktin_dequeue(queue_t qentry)
 {
        odp_buffer_hdr_t *buf_hdr;
        odp_buffer_hdr_t *hdr_tbl[QUEUE_MULTI_MAX];
        int pkts;
 
-       buf_hdr = queue_deq(qentry);
+       buf_hdr = queue_fn->deq(qentry);
        if (buf_hdr != NULL)
                return buf_hdr;
 
-       pkts = pktin_recv_buf(qentry->s.pktin, hdr_tbl, QUEUE_MULTI_MAX);
+       pkts = pktin_recv_buf(queue_fn->get_pktin(qentry),
+                             hdr_tbl, QUEUE_MULTI_MAX);
 
        if (pkts <= 0)
                return NULL;
 
        if (pkts > 1)
-               queue_enq_multi(qentry, &hdr_tbl[1], pkts - 1);
+               queue_fn->enq_multi(qentry, &hdr_tbl[1], pkts - 1);
        buf_hdr = hdr_tbl[0];
        return buf_hdr;
 }
 
-int pktin_enq_multi(queue_entry_t *qentry ODP_UNUSED,
+int pktin_enq_multi(queue_t qentry ODP_UNUSED,
                    odp_buffer_hdr_t *buf_hdr[] ODP_UNUSED, int num ODP_UNUSED)
 {
        ODP_ABORT("attempted enqueue to a pktin queue");
        return 0;
 }
 
-int pktin_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], int 
num)
+int pktin_deq_multi(queue_t qentry, odp_buffer_hdr_t *buf_hdr[], int num)
 {
        int nbr;
        odp_buffer_hdr_t *hdr_tbl[QUEUE_MULTI_MAX];
        int pkts, i, j;
 
-       nbr = queue_deq_multi(qentry, buf_hdr, num);
+       nbr = queue_fn->deq_multi(qentry, buf_hdr, num);
        if (odp_unlikely(nbr > num))
                ODP_ABORT("queue_deq_multi req: %d, returned %d\n", num, nbr);
 
@@ -679,7 +677,8 @@ int pktin_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t 
*buf_hdr[], int num)
        if (nbr == num)
                return nbr;
 
-       pkts = pktin_recv_buf(qentry->s.pktin, hdr_tbl, QUEUE_MULTI_MAX);
+       pkts = pktin_recv_buf(queue_fn->get_pktin(qentry),
+                             hdr_tbl, QUEUE_MULTI_MAX);
        if (pkts <= 0)
                return nbr;
 
@@ -691,7 +690,7 @@ int pktin_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t 
*buf_hdr[], int num)
                hdr_tbl[j] = hdr_tbl[i];
 
        if (j)
-               queue_enq_multi(qentry, hdr_tbl, j);
+               queue_fn->enq_multi(qentry, hdr_tbl, j);
        return nbr;
 }
 
@@ -713,7 +712,7 @@ int sched_cb_pktin_poll(int pktio_index, int num_queue, int 
index[])
        }
 
        for (idx = 0; idx < num_queue; idx++) {
-               queue_entry_t *qentry;
+               queue_t qentry;
                odp_queue_t queue;
                odp_pktin_queue_t pktin = entry->s.in_queue[index[idx]].pktin;
 
@@ -728,8 +727,8 @@ int sched_cb_pktin_poll(int pktio_index, int num_queue, int 
index[])
                }
 
                queue = entry->s.in_queue[index[idx]].queue;
-               qentry = queue_to_qentry(queue);
-               queue_enq_multi(qentry, hdr_tbl, num);
+               qentry = queue_fn->from_ext(queue);
+               queue_fn->enq_multi(qentry, hdr_tbl, num);
        }
 
        return 0;
@@ -1273,16 +1272,16 @@ int odp_pktin_queue_config(odp_pktio_t pktio,
                        }
 
                        if (mode == ODP_PKTIN_MODE_QUEUE) {
-                               queue_entry_t *qentry;
-
-                               qentry = queue_to_qentry(queue);
-                               qentry->s.pktin.index  = i;
-                               qentry->s.pktin.pktio  = pktio;
-
-                               qentry->s.enqueue = pktin_enqueue;
-                               qentry->s.dequeue = pktin_dequeue;
-                               qentry->s.enqueue_multi = pktin_enq_multi;
-                               qentry->s.dequeue_multi = pktin_deq_multi;
+                               queue_t qentry;
+
+                               qentry = queue_fn->from_ext(queue);
+                               queue_fn->set_pktin(qentry, pktio, i);
+                               queue_fn->set_enq_fn(qentry, pktin_enqueue);
+                               queue_fn->set_deq_fn(qentry, pktin_dequeue);
+                               queue_fn->set_enq_multi_fn(qentry,
+                                                          pktin_enq_multi);
+                               queue_fn->set_deq_multi_fn(qentry,
+                                                          pktin_deq_multi);
                        }
 
                        entry->s.in_queue[i].queue = queue;
@@ -1379,7 +1378,7 @@ int odp_pktout_queue_config(odp_pktio_t pktio,
                for (i = 0; i < num_queues; i++) {
                        odp_queue_t queue;
                        odp_queue_param_t queue_param;
-                       queue_entry_t *qentry;
+                       queue_t qentry;
                        char name[ODP_QUEUE_NAME_LEN];
                        int pktio_id = pktio_to_id(pktio);
 
@@ -1399,15 +1398,14 @@ int odp_pktout_queue_config(odp_pktio_t pktio,
                                return -1;
                        }
 
-                       qentry = queue_to_qentry(queue);
-                       qentry->s.pktout.index  = i;
-                       qentry->s.pktout.pktio  = pktio;
+                       qentry = queue_fn->from_ext(queue);
+                       queue_fn->set_pktout(qentry, pktio, i);
 
                        /* Override default enqueue / dequeue functions */
-                       qentry->s.enqueue       = pktout_enqueue;
-                       qentry->s.dequeue       = pktout_dequeue;
-                       qentry->s.enqueue_multi = pktout_enq_multi;
-                       qentry->s.dequeue_multi = pktout_deq_multi;
+                       queue_fn->set_enq_fn(qentry, pktout_enqueue);
+                       queue_fn->set_deq_fn(qentry, pktout_dequeue);
+                       queue_fn->set_enq_multi_fn(qentry, pktout_enq_multi);
+                       queue_fn->set_deq_multi_fn(qentry, pktout_deq_multi);
 
                        entry->s.out_queue[i].queue = queue;
                }
diff --git a/platform/linux-generic/odp_queue.c 
b/platform/linux-generic/odp_queue.c
index dd430cd1..bc73728d 100644
--- a/platform/linux-generic/odp_queue.c
+++ b/platform/linux-generic/odp_queue.c
@@ -6,6 +6,7 @@
 
 #include <odp/api/queue.h>
 #include <odp_queue_internal.h>
+#include <odp_queue_if.h>
 #include <odp/api/std_types.h>
 #include <odp/api/align.h>
 #include <odp/api/buffer.h>
@@ -40,6 +41,14 @@ typedef struct queue_table_t {
 
 static queue_table_t *queue_tbl;
 
+static int _queue_enq(queue_t handle, odp_buffer_hdr_t *buf_hdr);
+static odp_buffer_hdr_t *_queue_deq(queue_t handle);
+
+static int _queue_enq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],
+                           int num);
+static int _queue_deq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],
+                           int num);
+
 static inline odp_queue_t queue_from_id(uint32_t queue_id)
 {
        return _odp_cast_scalar(odp_queue_t, queue_id + 1);
@@ -89,10 +98,10 @@ static int queue_init(queue_entry_t *queue, const char 
*name,
        }
        queue->s.type = queue->s.param.type;
 
-       queue->s.enqueue = queue_enq;
-       queue->s.dequeue = queue_deq;
-       queue->s.enqueue_multi = queue_enq_multi;
-       queue->s.dequeue_multi = queue_deq_multi;
+       queue->s.enqueue = _queue_enq;
+       queue->s.dequeue = _queue_deq;
+       queue->s.enqueue_multi = _queue_enq_multi;
+       queue->s.dequeue_multi = _queue_deq_multi;
 
        queue->s.pktin = PKTIN_INVALID;
        queue->s.pktout = PKTOUT_INVALID;
@@ -104,7 +113,7 @@ static int queue_init(queue_entry_t *queue, const char 
*name,
 }
 
 
-int odp_queue_init_global(void)
+static int queue_init_global(void)
 {
        uint32_t i;
        odp_shm_t shm;
@@ -141,7 +150,17 @@ int odp_queue_init_global(void)
        return 0;
 }
 
-int odp_queue_term_global(void)
+static int queue_init_local(void)
+{
+       return 0;
+}
+
+static int queue_term_local(void)
+{
+       return 0;
+}
+
+static int queue_term_global(void)
 {
        int ret = 0;
        int rc = 0;
@@ -167,7 +186,7 @@ int odp_queue_term_global(void)
        return rc;
 }
 
-int odp_queue_capability(odp_queue_capability_t *capa)
+static int queue_capability(odp_queue_capability_t *capa)
 {
        memset(capa, 0, sizeof(odp_queue_capability_t));
 
@@ -182,51 +201,37 @@ int odp_queue_capability(odp_queue_capability_t *capa)
        return 0;
 }
 
-odp_queue_type_t odp_queue_type(odp_queue_t handle)
+static odp_queue_type_t queue_type(odp_queue_t handle)
 {
-       queue_entry_t *queue;
-
-       queue = queue_to_qentry(handle);
-
-       return queue->s.type;
+       return qentry_from_int(queue_fn->from_ext(handle))->s.type;
 }
 
-odp_schedule_sync_t odp_queue_sched_type(odp_queue_t handle)
+static odp_schedule_sync_t queue_sched_type(odp_queue_t handle)
 {
-       queue_entry_t *queue;
-
-       queue = queue_to_qentry(handle);
-
-       return queue->s.param.sched.sync;
+       return qentry_from_int(queue_fn->from_ext(handle))->s.param.sched.sync;
 }
 
-odp_schedule_prio_t odp_queue_sched_prio(odp_queue_t handle)
+static odp_schedule_prio_t queue_sched_prio(odp_queue_t handle)
 {
-       queue_entry_t *queue;
-
-       queue = queue_to_qentry(handle);
-
-       return queue->s.param.sched.prio;
+       return qentry_from_int(queue_fn->from_ext(handle))->s.param.sched.prio;
 }
 
-odp_schedule_group_t odp_queue_sched_group(odp_queue_t handle)
+static odp_schedule_group_t queue_sched_group(odp_queue_t handle)
 {
-       queue_entry_t *queue;
-
-       queue = queue_to_qentry(handle);
-
-       return queue->s.param.sched.group;
+       return qentry_from_int(queue_fn->from_ext(handle))
+                              ->s.param.sched.group;
 }
 
-int odp_queue_lock_count(odp_queue_t handle)
+static int queue_lock_count(odp_queue_t handle)
 {
-       queue_entry_t *queue = queue_to_qentry(handle);
+       queue_entry_t *queue = qentry_from_int(queue_fn->from_ext(handle));
 
        return queue->s.param.sched.sync == ODP_SCHED_SYNC_ORDERED ?
                (int)queue->s.param.sched.lock_count : -1;
 }
 
-odp_queue_t odp_queue_create(const char *name, const odp_queue_param_t *param)
+static odp_queue_t queue_create(const char *name,
+                               const odp_queue_param_t *param)
 {
        uint32_t i;
        queue_entry_t *queue;
@@ -291,10 +296,10 @@ void sched_cb_queue_destroy_finalize(uint32_t queue_index)
        UNLOCK(&queue->s.lock);
 }
 
-int odp_queue_destroy(odp_queue_t handle)
+static int queue_destroy(odp_queue_t handle)
 {
        queue_entry_t *queue;
-       queue = queue_to_qentry(handle);
+       queue = qentry_from_int(queue_fn->from_ext(handle));
 
        if (handle == ODP_QUEUE_INVALID)
                return -1;
@@ -343,25 +348,21 @@ int odp_queue_destroy(odp_queue_t handle)
        return 0;
 }
 
-int odp_queue_context_set(odp_queue_t handle, void *context,
-                         uint32_t len ODP_UNUSED)
+static int queue_context_set(odp_queue_t handle, void *context,
+                            uint32_t len ODP_UNUSED)
 {
-       queue_entry_t *queue;
-       queue = queue_to_qentry(handle);
        odp_mb_full();
-       queue->s.param.context = context;
+       qentry_from_int(queue_fn->from_ext(handle))->s.param.context = context;
        odp_mb_full();
        return 0;
 }
 
-void *odp_queue_context(odp_queue_t handle)
+static void *queue_context(odp_queue_t handle)
 {
-       queue_entry_t *queue;
-       queue = queue_to_qentry(handle);
-       return queue->s.param.context;
+       return qentry_from_int(queue_fn->from_ext(handle))->s.param.context;
 }
 
-odp_queue_t odp_queue_lookup(const char *name)
+static odp_queue_t queue_lookup(const char *name)
 {
        uint32_t i;
 
@@ -384,15 +385,16 @@ odp_queue_t odp_queue_lookup(const char *name)
        return ODP_QUEUE_INVALID;
 }
 
-static inline int enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[],
+static inline int enq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],
                            int num)
 {
        int sched = 0;
        int i, ret;
+       queue_entry_t *queue;
        odp_buffer_hdr_t *hdr, *tail, *next_hdr;
 
-       if (sched_fn->ord_enq_multi(queue->s.index, (void **)buf_hdr, num,
-                       &ret))
+       queue = qentry_from_int(handle);
+       if (sched_fn->ord_enq_multi(handle, (void **)buf_hdr, num, &ret))
                return ret;
 
        /* Optimize the common case of single enqueue */
@@ -460,16 +462,17 @@ static inline int enq_multi(queue_entry_t *queue, 
odp_buffer_hdr_t *buf_hdr[],
        return num; /* All events enqueued */
 }
 
-int queue_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num)
+static int _queue_enq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],
+                           int num)
 {
-       return enq_multi(queue, buf_hdr, num);
+       return enq_multi(handle, buf_hdr, num);
 }
 
-int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr)
+static int _queue_enq(queue_t handle, odp_buffer_hdr_t *buf_hdr)
 {
        int ret;
 
-       ret = enq_multi(queue, &buf_hdr, 1);
+       ret = enq_multi(handle, &buf_hdr, 1);
 
        if (ret == 1)
                return 0;
@@ -477,7 +480,7 @@ int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t 
*buf_hdr)
                return -1;
 }
 
-int odp_queue_enq_multi(odp_queue_t handle, const odp_event_t ev[], int num)
+static int queue_enq_multi(odp_queue_t handle, const odp_event_t ev[], int num)
 {
        odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX];
        queue_entry_t *queue;
@@ -486,33 +489,35 @@ int odp_queue_enq_multi(odp_queue_t handle, const 
odp_event_t ev[], int num)
        if (num > QUEUE_MULTI_MAX)
                num = QUEUE_MULTI_MAX;
 
-       queue = queue_to_qentry(handle);
+       queue = qentry_from_int(queue_fn->from_ext(handle));
 
        for (i = 0; i < num; i++)
                buf_hdr[i] = buf_hdl_to_hdr(odp_buffer_from_event(ev[i]));
 
-       return num == 0 ? 0 : queue->s.enqueue_multi(queue, buf_hdr,
-                                                    num);
+       return num == 0 ? 0 : queue->s.enqueue_multi(qentry_to_int(queue),
+                                                    buf_hdr, num);
 }
 
-int odp_queue_enq(odp_queue_t handle, odp_event_t ev)
+static int queue_enq(odp_queue_t handle, odp_event_t ev)
 {
        odp_buffer_hdr_t *buf_hdr;
        queue_entry_t *queue;
 
-       queue   = queue_to_qentry(handle);
+       queue   = qentry_from_int(queue_fn->from_ext(handle));
        buf_hdr = buf_hdl_to_hdr(odp_buffer_from_event(ev));
 
-       return queue->s.enqueue(queue, buf_hdr);
+       return queue->s.enqueue(qentry_to_int(queue), buf_hdr);
 }
 
-static inline int deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[],
+static inline int deq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],
                            int num)
 {
        odp_buffer_hdr_t *hdr, *next;
        int i, j;
+       queue_entry_t *queue;
        int updated = 0;
 
+       queue = qentry_from_int(handle);
        LOCK(&queue->s.lock);
        if (odp_unlikely(queue->s.status < QUEUE_STATUS_READY)) {
                /* Bad queue, or queue has been destroyed.
@@ -578,17 +583,18 @@ static inline int deq_multi(queue_entry_t *queue, 
odp_buffer_hdr_t *buf_hdr[],
        return i;
 }
 
-int queue_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num)
+static int _queue_deq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],
+                           int num)
 {
-       return deq_multi(queue, buf_hdr, num);
+       return deq_multi(handle, buf_hdr, num);
 }
 
-odp_buffer_hdr_t *queue_deq(queue_entry_t *queue)
+static odp_buffer_hdr_t *_queue_deq(queue_t handle)
 {
        odp_buffer_hdr_t *buf_hdr = NULL;
        int ret;
 
-       ret = deq_multi(queue, &buf_hdr, 1);
+       ret = deq_multi(handle, &buf_hdr, 1);
 
        if (ret == 1)
                return buf_hdr;
@@ -596,7 +602,7 @@ odp_buffer_hdr_t *queue_deq(queue_entry_t *queue)
                return NULL;
 }
 
-int odp_queue_deq_multi(odp_queue_t handle, odp_event_t events[], int num)
+static int queue_deq_multi(odp_queue_t handle, odp_event_t events[], int num)
 {
        queue_entry_t *queue;
        odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX];
@@ -605,9 +611,9 @@ int odp_queue_deq_multi(odp_queue_t handle, odp_event_t 
events[], int num)
        if (num > QUEUE_MULTI_MAX)
                num = QUEUE_MULTI_MAX;
 
-       queue = queue_to_qentry(handle);
+       queue = qentry_from_int(queue_fn->from_ext(handle));
 
-       ret = queue->s.dequeue_multi(queue, buf_hdr, num);
+       ret = queue->s.dequeue_multi(qentry_to_int(queue), buf_hdr, num);
 
        for (i = 0; i < ret; i++)
                events[i] = odp_buffer_to_event(buf_hdr[i]->handle.handle);
@@ -616,13 +622,13 @@ int odp_queue_deq_multi(odp_queue_t handle, odp_event_t 
events[], int num)
 }
 
 
-odp_event_t odp_queue_deq(odp_queue_t handle)
+static odp_event_t queue_deq(odp_queue_t handle)
 {
        queue_entry_t *queue;
        odp_buffer_hdr_t *buf_hdr;
 
-       queue   = queue_to_qentry(handle);
-       buf_hdr = queue->s.dequeue(queue);
+       queue   = qentry_from_int(queue_fn->from_ext(handle));
+       buf_hdr = queue->s.dequeue(qentry_to_int(queue));
 
        if (buf_hdr)
                return odp_buffer_to_event(buf_hdr->handle.handle);
@@ -640,7 +646,7 @@ void queue_unlock(queue_entry_t *queue)
        UNLOCK(&queue->s.lock);
 }
 
-void odp_queue_param_init(odp_queue_param_t *params)
+static void queue_param_init(odp_queue_param_t *params)
 {
        memset(params, 0, sizeof(odp_queue_param_t));
        params->type = ODP_QUEUE_TYPE_PLAIN;
@@ -651,7 +657,7 @@ void odp_queue_param_init(odp_queue_param_t *params)
        params->sched.group = ODP_SCHED_GROUP_ALL;
 }
 
-int odp_queue_info(odp_queue_t handle, odp_queue_info_t *info)
+static int queue_info(odp_queue_t handle, odp_queue_info_t *info)
 {
        uint32_t queue_id;
        queue_entry_t *queue;
@@ -730,7 +736,7 @@ int sched_cb_queue_deq_multi(uint32_t queue_index, 
odp_event_t ev[], int num)
        queue_entry_t *qe = get_qentry(queue_index);
        odp_buffer_hdr_t *buf_hdr[num];
 
-       ret = deq_multi(qe, buf_hdr, num);
+       ret = deq_multi(qentry_to_int(qe), buf_hdr, num);
 
        if (ret > 0)
                for (i = 0; i < ret; i++)
@@ -765,7 +771,112 @@ int sched_cb_queue_empty(uint32_t queue_index)
        return ret;
 }
 
-uint64_t odp_queue_to_u64(odp_queue_t hdl)
+static uint64_t queue_to_u64(odp_queue_t hdl)
 {
        return _odp_pri(hdl);
 }
+
+static odp_pktout_queue_t queue_get_pktout(queue_t handle)
+{
+       return qentry_from_int(handle)->s.pktout;
+}
+
+static void queue_set_pktout(queue_t handle, odp_pktio_t pktio, int index)
+{
+       qentry_from_int(handle)->s.pktout.pktio = pktio;
+       qentry_from_int(handle)->s.pktout.index = index;
+}
+
+static odp_pktin_queue_t queue_get_pktin(queue_t handle)
+{
+       return qentry_from_int(handle)->s.pktin;
+}
+
+static void queue_set_pktin(queue_t handle, odp_pktio_t pktio, int index)
+{
+       qentry_from_int(handle)->s.pktin.pktio = pktio;
+       qentry_from_int(handle)->s.pktin.index = index;
+}
+
+static void queue_set_enq_func(queue_t handle, queue_enq_fn_t func)
+{
+       qentry_from_int(handle)->s.enqueue = func;
+}
+
+static void queue_set_enq_multi_func(queue_t handle, queue_enq_multi_fn_t func)
+{
+       qentry_from_int(handle)->s.enqueue_multi = func;
+}
+
+static void queue_set_deq_func(queue_t handle, queue_deq_fn_t func)
+{
+       qentry_from_int(handle)->s.dequeue = func;
+}
+
+static void queue_set_deq_multi_func(queue_t handle, queue_deq_multi_fn_t func)
+{
+       qentry_from_int(handle)->s.dequeue_multi = func;
+}
+
+static void queue_set_type(queue_t handle, odp_queue_type_t type)
+{
+       qentry_from_int(handle)->s.type = type;
+}
+
+static queue_t queue_from_ext(odp_queue_t handle)
+{
+       uint32_t queue_id;
+
+       queue_id = queue_to_id(handle);
+       return qentry_to_int(get_qentry(queue_id));
+}
+
+static odp_queue_t queue_to_ext(queue_t handle)
+{
+       return qentry_from_int(handle)->s.handle;
+}
+
+/* API functions */
+queue_api_t queue_default_api = {
+       .queue_create = queue_create,
+       .queue_destroy = queue_destroy,
+       .queue_lookup = queue_lookup,
+       .queue_capability = queue_capability,
+       .queue_context_set = queue_context_set,
+       .queue_context = queue_context,
+       .queue_enq = queue_enq,
+       .queue_enq_multi = queue_enq_multi,
+       .queue_deq = queue_deq,
+       .queue_deq_multi = queue_deq_multi,
+       .queue_type = queue_type,
+       .queue_sched_type = queue_sched_type,
+       .queue_sched_prio = queue_sched_prio,
+       .queue_sched_group = queue_sched_group,
+       .queue_lock_count = queue_lock_count,
+       .queue_to_u64 = queue_to_u64,
+       .queue_param_init = queue_param_init,
+       .queue_info = queue_info
+};
+
+/* Functions towards internal components */
+queue_fn_t queue_default_fn = {
+       .init_global = queue_init_global,
+       .term_global = queue_term_global,
+       .init_local = queue_init_local,
+       .term_local = queue_term_local,
+       .from_ext = queue_from_ext,
+       .to_ext = queue_to_ext,
+       .enq = _queue_enq,
+       .enq_multi = _queue_enq_multi,
+       .deq = _queue_deq,
+       .deq_multi = _queue_deq_multi,
+       .get_pktout = queue_get_pktout,
+       .set_pktout = queue_set_pktout,
+       .get_pktin = queue_get_pktin,
+       .set_pktin = queue_set_pktin,
+       .set_enq_fn = queue_set_enq_func,
+       .set_enq_multi_fn = queue_set_enq_multi_func,
+       .set_deq_fn = queue_set_deq_func,
+       .set_deq_multi_fn = queue_set_deq_multi_func,
+       .set_type = queue_set_type
+};
diff --git a/platform/linux-generic/odp_queue_if.c 
b/platform/linux-generic/odp_queue_if.c
new file mode 100644
index 00000000..5a4f7194
--- /dev/null
+++ b/platform/linux-generic/odp_queue_if.c
@@ -0,0 +1,103 @@
+/* Copyright (c) 2016, ARM Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#include <odp_queue_if.h>
+
+extern const queue_api_t queue_default_api;
+extern const queue_fn_t queue_default_fn;
+
+const queue_api_t *queue_api = &queue_default_api;
+const queue_fn_t *queue_fn = &queue_default_fn;
+
+odp_queue_t odp_queue_create(const char *name, const odp_queue_param_t *param)
+{
+       return queue_api->queue_create(name, param);
+}
+
+int odp_queue_destroy(odp_queue_t queue)
+{
+       return queue_api->queue_destroy(queue);
+}
+
+odp_queue_t odp_queue_lookup(const char *name)
+{
+       return queue_api->queue_lookup(name);
+}
+
+int odp_queue_capability(odp_queue_capability_t *capa)
+{
+       return queue_api->queue_capability(capa);
+}
+
+int odp_queue_context_set(odp_queue_t queue, void *context, uint32_t len)
+{
+       return queue_api->queue_context_set(queue, context, len);
+}
+
+void *odp_queue_context(odp_queue_t queue)
+{
+       return queue_api->queue_context(queue);
+}
+
+int odp_queue_enq(odp_queue_t queue, odp_event_t ev)
+{
+       return queue_api->queue_enq(queue, ev);
+}
+
+int odp_queue_enq_multi(odp_queue_t queue, const odp_event_t events[], int num)
+{
+       return queue_api->queue_enq_multi(queue, events, num);
+}
+
+odp_event_t odp_queue_deq(odp_queue_t queue)
+{
+       return queue_api->queue_deq(queue);
+}
+
+int odp_queue_deq_multi(odp_queue_t queue, odp_event_t events[], int num)
+{
+       return queue_api->queue_deq_multi(queue, events, num);
+}
+
+odp_queue_type_t odp_queue_type(odp_queue_t queue)
+{
+       return queue_api->queue_type(queue);
+}
+
+odp_schedule_sync_t odp_queue_sched_type(odp_queue_t queue)
+{
+       return queue_api->queue_sched_type(queue);
+}
+
+odp_schedule_prio_t odp_queue_sched_prio(odp_queue_t queue)
+{
+       return queue_api->queue_sched_prio(queue);
+}
+
+odp_schedule_group_t odp_queue_sched_group(odp_queue_t queue)
+{
+       return queue_api->queue_sched_group(queue);
+}
+
+int odp_queue_lock_count(odp_queue_t queue)
+{
+       return queue_api->queue_lock_count(queue);
+}
+
+uint64_t odp_queue_to_u64(odp_queue_t hdl)
+{
+       return queue_api->queue_to_u64(hdl);
+}
+
+void odp_queue_param_init(odp_queue_param_t *param)
+{
+       return queue_api->queue_param_init(param);
+}
+
+int odp_queue_info(odp_queue_t queue, odp_queue_info_t *info)
+{
+       return queue_api->queue_info(queue, info);
+}
diff --git a/platform/linux-generic/odp_schedule.c 
b/platform/linux-generic/odp_schedule.c
index c4567d81..011d4dc4 100644
--- a/platform/linux-generic/odp_schedule.c
+++ b/platform/linux-generic/odp_schedule.c
@@ -646,7 +646,7 @@ static inline void ordered_stash_release(void)
                buf_hdr = sched_local.ordered.stash[i].buf_hdr;
                num = sched_local.ordered.stash[i].num;
 
-               queue_enq_multi(queue, buf_hdr, num);
+               queue_fn->enq_multi(qentry_to_int(queue), buf_hdr, num);
        }
        sched_local.ordered.stash_num = 0;
 }
@@ -712,12 +712,12 @@ static inline int copy_events(odp_event_t out_ev[], 
unsigned int max)
        return i;
 }
 
-static int schedule_ord_enq_multi(uint32_t queue_index, void *buf_hdr[],
+static int schedule_ord_enq_multi(queue_t handle, void *buf_hdr[],
                                  int num, int *ret)
 {
        int i;
        uint32_t stash_num = sched_local.ordered.stash_num;
-       queue_entry_t *dst_queue = get_qentry(queue_index);
+       queue_entry_t *dst_queue = qentry_from_int(handle);
        queue_entry_t *src_queue = sched_local.ordered.src_queue;
 
        if (!sched_local.ordered.src_queue || sched_local.ordered.in_order)
diff --git a/platform/linux-generic/odp_schedule_iquery.c 
b/platform/linux-generic/odp_schedule_iquery.c
index 75470aff..bdf1a460 100644
--- a/platform/linux-generic/odp_schedule_iquery.c
+++ b/platform/linux-generic/odp_schedule_iquery.c
@@ -1108,7 +1108,7 @@ static inline void ordered_stash_release(void)
                buf_hdr = thread_local.ordered.stash[i].buf_hdr;
                num = thread_local.ordered.stash[i].num;
 
-               queue_enq_multi(queue, buf_hdr, num);
+               queue_fn->enq_multi(qentry_to_int(queue), buf_hdr, num);
        }
        thread_local.ordered.stash_num = 0;
 }
@@ -1159,12 +1159,12 @@ static inline void schedule_release_context(void)
                schedule_release_atomic();
 }
 
-static int schedule_ord_enq_multi(uint32_t queue_index, void *buf_hdr[],
+static int schedule_ord_enq_multi(queue_t handle, void *buf_hdr[],
                                  int num, int *ret)
 {
        int i;
        uint32_t stash_num = thread_local.ordered.stash_num;
-       queue_entry_t *dst_queue = get_qentry(queue_index);
+       queue_entry_t *dst_queue = qentry_from_int(handle);
        queue_entry_t *src_queue = thread_local.ordered.src_queue;
 
        if (!thread_local.ordered.src_queue || thread_local.ordered.in_order)
diff --git a/platform/linux-generic/odp_schedule_sp.c 
b/platform/linux-generic/odp_schedule_sp.c
index 0fd4d87d..91d70e3a 100644
--- a/platform/linux-generic/odp_schedule_sp.c
+++ b/platform/linux-generic/odp_schedule_sp.c
@@ -414,10 +414,10 @@ static int unsched_queue(uint32_t qi ODP_UNUSED)
        return 0;
 }
 
-static int ord_enq_multi(uint32_t queue_index, void *buf_hdr[], int num,
+static int ord_enq_multi(queue_t handle, void *buf_hdr[], int num,
                         int *ret)
 {
-       (void)queue_index;
+       (void)handle;
        (void)buf_hdr;
        (void)num;
        (void)ret;
diff --git a/platform/linux-generic/odp_traffic_mngr.c 
b/platform/linux-generic/odp_traffic_mngr.c
index a93b3ba9..8b5f3187 100644
--- a/platform/linux-generic/odp_traffic_mngr.c
+++ b/platform/linux-generic/odp_traffic_mngr.c
@@ -102,7 +102,7 @@ static odp_bool_t tm_demote_pkt_desc(tm_system_t *tm_system,
                                     tm_shaper_obj_t *timer_shaper,
                                     pkt_desc_t *demoted_pkt_desc);
 
-static int queue_tm_reenq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr)
+static int queue_tm_reenq(queue_t queue, odp_buffer_hdr_t *buf_hdr)
 {
        odp_tm_queue_t tm_queue = MAKE_ODP_TM_QUEUE((uint8_t *)queue -
                                                    offsetof(tm_queue_obj_t,
@@ -112,7 +112,7 @@ static int queue_tm_reenq(queue_entry_t *queue, 
odp_buffer_hdr_t *buf_hdr)
        return odp_tm_enq(tm_queue, pkt);
 }
 
-static int queue_tm_reenq_multi(queue_entry_t *queue ODP_UNUSED,
+static int queue_tm_reenq_multi(queue_t queue ODP_UNUSED,
                                odp_buffer_hdr_t *buf[] ODP_UNUSED,
                                int num ODP_UNUSED)
 {
@@ -3882,6 +3882,7 @@ odp_tm_queue_t odp_tm_queue_create(odp_tm_t odp_tm,
        tm_queue_obj_t *tm_queue_obj;
        tm_wred_node_t *tm_wred_node;
        odp_tm_queue_t odp_tm_queue;
+       odp_queue_t queue;
        odp_tm_wred_t wred_profile;
        tm_system_t *tm_system;
        uint32_t color;
@@ -3918,9 +3919,17 @@ odp_tm_queue_t odp_tm_queue_create(odp_tm_t odp_tm,
        tm_queue_obj->pkt = ODP_PACKET_INVALID;
        odp_ticketlock_init(&tm_wred_node->tm_wred_node_lock);
 
-       tm_queue_obj->tm_qentry.s.type = QUEUE_TYPE_TM;
-       tm_queue_obj->tm_qentry.s.enqueue = queue_tm_reenq;
-       tm_queue_obj->tm_qentry.s.enqueue_multi = queue_tm_reenq_multi;
+       queue = odp_queue_create(NULL, NULL);
+       if (queue == ODP_QUEUE_INVALID) {
+               free(tm_wred_node);
+               free(tm_queue_obj);
+               return ODP_TM_INVALID;
+       }
+       tm_queue_obj->tm_qentry = queue_fn->from_ext(queue);
+       queue_fn->set_type(tm_queue_obj->tm_qentry, QUEUE_TYPE_TM);
+       queue_fn->set_enq_fn(tm_queue_obj->tm_qentry, queue_tm_reenq);
+       queue_fn->set_enq_multi_fn(tm_queue_obj->tm_qentry,
+                                  queue_tm_reenq_multi);
 
        tm_system->queue_num_tbl[tm_queue_obj->queue_num - 1] = tm_queue_obj;
        odp_ticketlock_lock(&tm_system->tm_system_lock);
@@ -3992,6 +4001,8 @@ int odp_tm_queue_destroy(odp_tm_queue_t tm_queue)
        odp_ticketlock_lock(&tm_system->tm_system_lock);
        tm_system->queue_num_tbl[tm_queue_obj->queue_num - 1] = NULL;
 
+       odp_queue_destroy(queue_fn->to_ext(tm_queue_obj->tm_qentry));
+
        /* First delete any associated tm_wred_node and then the tm_queue_obj
         * itself */
        free(tm_queue_obj->tm_wred_node);
diff --git a/platform/linux-generic/pktio/loop.c 
b/platform/linux-generic/pktio/loop.c
index e9ad22ba..c95a44be 100644
--- a/platform/linux-generic/pktio/loop.c
+++ b/platform/linux-generic/pktio/loop.c
@@ -11,6 +11,7 @@
 #include <odp_classification_internal.h>
 #include <odp_debug_internal.h>
 #include <odp/api/hints.h>
+#include <odp_queue_if.h>
 
 #include <protocols/eth.h>
 #include <protocols/ip.h>
@@ -55,7 +56,7 @@ static int loopback_recv(pktio_entry_t *pktio_entry, int 
index ODP_UNUSED,
 {
        int nbr, i;
        odp_buffer_hdr_t *hdr_tbl[QUEUE_MULTI_MAX];
-       queue_entry_t *qentry;
+       queue_t queue;
        odp_packet_hdr_t *pkt_hdr;
        odp_packet_hdr_t parsed_hdr;
        odp_packet_t pkt;
@@ -69,8 +70,8 @@ static int loopback_recv(pktio_entry_t *pktio_entry, int 
index ODP_UNUSED,
 
        odp_ticketlock_lock(&pktio_entry->s.rxl);
 
-       qentry = queue_to_qentry(pktio_entry->s.pkt_loop.loopq);
-       nbr = queue_deq_multi(qentry, hdr_tbl, len);
+       queue = queue_fn->from_ext(pktio_entry->s.pkt_loop.loopq);
+       nbr = queue_fn->deq_multi(queue, hdr_tbl, len);
 
        if (pktio_entry->s.config.pktin.bit.ts_all ||
            pktio_entry->s.config.pktin.bit.ts_ptp) {
@@ -154,7 +155,7 @@ static int loopback_send(pktio_entry_t *pktio_entry, int 
index ODP_UNUSED,
                         const odp_packet_t pkt_tbl[], int len)
 {
        odp_buffer_hdr_t *hdr_tbl[QUEUE_MULTI_MAX];
-       queue_entry_t *qentry;
+       queue_t queue;
        int i;
        int ret;
        uint32_t bytes = 0;
@@ -169,8 +170,8 @@ static int loopback_send(pktio_entry_t *pktio_entry, int 
index ODP_UNUSED,
 
        odp_ticketlock_lock(&pktio_entry->s.txl);
 
-       qentry = queue_to_qentry(pktio_entry->s.pkt_loop.loopq);
-       ret = queue_enq_multi(qentry, hdr_tbl, len);
+       queue = queue_fn->from_ext(pktio_entry->s.pkt_loop.loopq);
+       ret = queue_fn->enq_multi(queue, hdr_tbl, len);
 
        if (ret > 0) {
                pktio_entry->s.stats.out_ucast_pkts += ret;

Reply via email to