Signed-off-by: Taras Kondratiuk <taras.kondrat...@linaro.org>
Signed-off-by: Taras Kondratiuk <ta...@ti.com>
---
 platform/linux-keystone2/Makefile.am               |   3 +-
 platform/linux-keystone2/include/odp/packet_io.h   | 111 +---
 .../include/odp/plat/packet_io_types.h             |  42 ++
 platform/linux-keystone2/include/odp/queue.h       |   3 +
 .../include/odp_packet_io_internal.h               |  29 +-
 .../linux-keystone2/include/odp_packet_io_queue.h  |   8 +-
 .../linux-keystone2/include/odp_queue_internal.h   |   1 +
 platform/linux-keystone2/odp_init.c                |   4 +-
 platform/linux-keystone2/odp_packet_io.c           | 681 +++++++++++++--------
 platform/linux-keystone2/odp_queue.c               |   2 -
 10 files changed, 500 insertions(+), 384 deletions(-)
 create mode 100644 platform/linux-keystone2/include/odp/plat/packet_io_types.h

diff --git a/platform/linux-keystone2/Makefile.am 
b/platform/linux-keystone2/Makefile.am
index f3d8471..38be9b6 100644
--- a/platform/linux-keystone2/Makefile.am
+++ b/platform/linux-keystone2/Makefile.am
@@ -64,6 +64,7 @@ odpplatinclude_HEADERS = \
                  $(srcdir)/include/odp/plat/event_types.h \
                  $(srcdir)/include/odp/plat/mcsdk_tune.h \
                  $(srcdir)/include/odp/plat/osal.h \
+                 $(srcdir)/include/odp/plat/packet_io_types.h \
                  $(srcdir)/include/odp/plat/packet_types.h \
                  $(srcdir)/include/odp/plat/pool_types.h \
                  $(srcdir)/include/odp/plat/queue_types.h \
@@ -75,7 +76,6 @@ odpplatinclude_HEADERS = \
                  
$(linux_generic_srcdir)/include/odp/plat/classification_types.h \
                  $(linux_generic_srcdir)/include/odp/plat/cpumask_types.h \
                  $(linux_generic_srcdir)/include/odp/plat/crypto_types.h \
-                 $(linux_generic_srcdir)/include/odp/plat/packet_io_types.h \
                  $(linux_generic_srcdir)/include/odp/plat/schedule_types.h \
                  
$(linux_generic_srcdir)/include/odp/plat/shared_memory_types.h \
                  $(linux_generic_srcdir)/include/odp/plat/strong_types.h \
@@ -137,6 +137,7 @@ __LIB__libodp_la_SOURCES = \
                           odp_buffer.c \
                           odp_packet.c \
                           odp_queue.c \
+                          odp_packet_io.c \
                           mcsdk/mcsdk_init.c \
                           mcsdk/mcsdk_navig.c \
                           mcsdk/mcsdk_rmclient.c \
diff --git a/platform/linux-keystone2/include/odp/packet_io.h 
b/platform/linux-keystone2/include/odp/packet_io.h
index 3faace9..a085781 100644
--- a/platform/linux-keystone2/include/odp/packet_io.h
+++ b/platform/linux-keystone2/include/odp/packet_io.h
@@ -19,112 +19,13 @@
 extern "C" {
 #endif
 
-#include <odp_std_types.h>
-#include <odp_buffer_pool.h>
-#include <odp_packet.h>
-#include <odp_queue.h>
+#include <odp/plat/pool_types.h>
+#include <odp/plat/packet_types.h>
+#include <odp/plat/queue_types.h>
+#include <odp/plat/classification_types.h>
+#include <odp/plat/packet_io_types.h>
 
-/** ODP packet IO handle */
-typedef uint32_t odp_pktio_t;
-
-/** Invalid packet IO handle */
-#define ODP_PKTIO_INVALID ((odp_pktio_t)-1)
-
-/**
- * Open an ODP packet IO instance
- *
- * @param dev    Packet IO device
- * @param pool   Pool to use for packet IO
- *
- * @return ODP packet IO handle or ODP_PKTIO_INVALID on error
- */
-odp_pktio_t odp_pktio_open(const char *dev, odp_buffer_pool_t pool);
-
-/**
- * Close an ODP packet IO instance
- *
- * @param id  ODP packet IO handle
- *
- * @return 0 on success or -1 on error
- */
-int odp_pktio_close(odp_pktio_t id);
-
-/**
- * Receive packets
- *
- * @param id          ODP packet IO handle
- * @param pkt_table[] Storage for received packets (filled by function)
- * @param len         Length of pkt_table[], i.e. max number of pkts to receive
- *
- * @return Number of packets received or -1 on error
- */
-int odp_pktio_recv(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len);
-
-/**
- * Send packets
- *
- * @param id           ODP packet IO handle
- * @param pkt_table[]  Array of packets to send
- * @param len          length of pkt_table[]
- *
- * @return Number of packets sent or -1 on error
- */
-int odp_pktio_send(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len);
-
-/**
- * Set the default input queue to be associated with a pktio handle
- *
- * @param id   ODP packet IO handle
- * @param queue default input queue set
- * @return  0 on success or -1 on error
- */
-int odp_pktio_inq_setdef(odp_pktio_t id, odp_queue_t queue);
-
-/**
- * Get default input queue associated with a pktio handle
- *
- * @param id  ODP packet IO handle
- *
- * @return Default input queue set or ODP_QUEUE_INVALID on error
- */
-odp_queue_t odp_pktio_inq_getdef(odp_pktio_t id);
-
-/**
- * Remove default input queue (if set)
- *
- * @param id  ODP packet IO handle
- *
- * @return 0 on success or -1 on error
- */
-int odp_pktio_inq_remdef(odp_pktio_t id);
-
-/**
- * Query default output queue
- *
- * @param id ODP packet IO handle
- *
- * @return Default out queue or ODP_QUEUE_INVALID on error
- */
-odp_queue_t odp_pktio_outq_getdef(odp_pktio_t id);
-
-/**
- * Store packet input handle into packet
- *
- * @param pkt  ODP packet buffer handle
- * @param id   ODP packet IO handle
- *
- * @return
- */
-void odp_pktio_set_input(odp_packet_t pkt, odp_pktio_t id);
-
-/**
- * Get stored packet input handle from packet
- *
- * @param pkt  ODP packet buffer handle
- *
- * @return Packet IO handle
- */
-odp_pktio_t odp_pktio_get_input(odp_packet_t pkt);
+#include <odp/api/packet_io.h>
 
 #ifdef __cplusplus
 }
diff --git a/platform/linux-keystone2/include/odp/plat/packet_io_types.h 
b/platform/linux-keystone2/include/odp/plat/packet_io_types.h
new file mode 100644
index 0000000..d038536
--- /dev/null
+++ b/platform/linux-keystone2/include/odp/plat/packet_io_types.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2014, Linaro Limited
+ * Copyright (c) 2014, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP Packet IO types
+ */
+
+#ifndef ODP_PLAT_PACKET_IO_TYPES_H_
+#define ODP_PLAT_PACKET_IO_TYPES_H_
+
+#include <odp/std_types.h>
+#include <odp/plat/strong_types.h>
+
+/** @addtogroup odp_packet_io ODP PACKET IO
+ *  Operations on a packet.
+ *  @{
+ */
+
+#define ODP_PKTIO_NAME_LEN  32
+
+typedef odp_handle_t odp_pktio_t;
+
+#define ODP_PKTIO_INVALID ((odp_pktio_t)NULL)
+
+/** Get printable format of odp_pktio_t */
+static inline uint64_t odp_pktio_to_u64(odp_pktio_t hdl)
+{
+       return _odp_pri(hdl);
+}
+
+/**
+ * @}
+ */
+
+#endif
diff --git a/platform/linux-keystone2/include/odp/queue.h 
b/platform/linux-keystone2/include/odp/queue.h
index 89a703a..36eaf55 100644
--- a/platform/linux-keystone2/include/odp/queue.h
+++ b/platform/linux-keystone2/include/odp/queue.h
@@ -28,6 +28,7 @@ extern "C" {
 #include <odp/ticketlock.h>
 #include <odp/align.h>
 #include <odp/plat/queue_types.h>
+#include <odp/packet_io.h>
 #include <odp/plat/debug.h>
 
 /**
@@ -47,6 +48,8 @@ typedef struct queue_entry_s {
        odp_ticketlock_t  lock;
        odp_queue_t       handle;
 
+       odp_pktio_t       pktin;
+       struct pktio_entry_s    *pktout_entry;
        odp_buffer_t      sched_buf;
        struct {
                odp_schedule_prio_t  prio;
diff --git a/platform/linux-keystone2/include/odp_packet_io_internal.h 
b/platform/linux-keystone2/include/odp_packet_io_internal.h
index 28bbeb8..5b8f2b0 100644
--- a/platform/linux-keystone2/include/odp_packet_io_internal.h
+++ b/platform/linux-keystone2/include/odp_packet_io_internal.h
@@ -15,33 +15,6 @@
 #ifndef ODP_PACKET_IO_INTERNAL_H_
 #define ODP_PACKET_IO_INTERNAL_H_
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <odp_spinlock.h>
-#include <odp_align.h>
-#include <ti/drv/nwal/nwal.h>
-#include <ti/drv/nwal/nwal_util.h>
-
-struct pktio_entry {
-       odp_spinlock_t lock;             /**< entry spinlock */
-       int taken;                       /**< is entry taken(1) or free(0) */
-       odp_queue_t inq_default;         /**< default input queue, if set */
-       odp_queue_t outq_default;        /**< default out queue */
-       odp_buffer_pool_t in_pool;       /**< pool for incoming packets */
-       odp_pktio_t id;                  /**< pktio handle */
-       nwalTxPSCmdInfo_t tx_ps_cmdinfo; /**< saved Command Label */
-       int port;                        /**< netcp port number */
-};
-
-typedef union {
-       struct pktio_entry s;
-       uint8_t pad[ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(struct pktio_entry))];
-} pktio_entry_t;
-
-#ifdef __cplusplus
-}
-#endif
+#include <odp/plat/packet_io.h>
 
 #endif
diff --git a/platform/linux-keystone2/include/odp_packet_io_queue.h 
b/platform/linux-keystone2/include/odp_packet_io_queue.h
index 4d3a79d..df7e949 100644
--- a/platform/linux-keystone2/include/odp_packet_io_queue.h
+++ b/platform/linux-keystone2/include/odp_packet_io_queue.h
@@ -22,10 +22,10 @@ extern "C" {
 #include <odp_queue_internal.h>
 #include <odp_buffer_internal.h>
 
-odp_buffer_t pktin_dequeue(queue_entry_t *queue);
-int pktin_deq_multi(queue_entry_t *queue, odp_buffer_t buf[], int num);
-int pktout_enqueue(queue_entry_t *queue, odp_buffer_t buf);
-int pktout_enq_multi(queue_entry_t *queue, odp_buffer_t buf[], int num);
+odp_event_t pktin_dequeue(queue_entry_t *queue);
+int pktin_deq_multi(queue_entry_t *queue, odp_event_t ev[], int num);
+int pktout_enqueue(queue_entry_t *queue, odp_event_t ev);
+int pktout_enq_multi(queue_entry_t *queue, const odp_event_t ev[], int num);
 
 #ifdef __cplusplus
 }
diff --git a/platform/linux-keystone2/include/odp_queue_internal.h 
b/platform/linux-keystone2/include/odp_queue_internal.h
index 38a59d4..befbcce 100644
--- a/platform/linux-keystone2/include/odp_queue_internal.h
+++ b/platform/linux-keystone2/include/odp_queue_internal.h
@@ -20,6 +20,7 @@ extern "C" {
 #endif
 
 #include <odp/queue.h>
+#include <odp/packet_io.h>
 #include <odp/align.h>
 
 
diff --git a/platform/linux-keystone2/odp_init.c 
b/platform/linux-keystone2/odp_init.c
index d6ac135..6d78324 100644
--- a/platform/linux-keystone2/odp_init.c
+++ b/platform/linux-keystone2/odp_init.c
@@ -59,12 +59,12 @@ int odp_init_global(odp_init_t *params ODP_UNUSED,
                odp_pr_err("ODP schedule init failed.\n");
                return -1;
        }
-
+#endif
        if (odp_pktio_init_global()) {
                odp_pr_err("ODP packet io init failed.\n");
                return -1;
        }
-
+#if 0
        if (odp_crypto_init_global()) {
                odp_pr_err("ODP crypto init failed.\n");
                return -1;
diff --git a/platform/linux-keystone2/odp_packet_io.c 
b/platform/linux-keystone2/odp_packet_io.c
index 4241a3b..65c6b14 100644
--- a/platform/linux-keystone2/odp_packet_io.c
+++ b/platform/linux-keystone2/odp_packet_io.c
@@ -6,236 +6,297 @@
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
-#include <odp_packet_io.h>
-#include <odp_packet_io_internal.h>
+#include <odp/packet_io.h>
 #include <odp_packet_io_queue.h>
-#include <odp_packet.h>
+#include <odp/packet.h>
 #include <odp_packet_internal.h>
 #include <odp_internal.h>
-#include <odp_spinlock.h>
-#include <odp_shared_memory.h>
-#include <odp_hints.h>
-#include <odp_config.h>
+#include <odp/spinlock.h>
+#include <odp/shared_memory.h>
+#include <odp/hints.h>
+#include <odp/config.h>
 #include <odp_queue_internal.h>
 #include <odp_schedule_internal.h>
-#include <odp_debug.h>
-#include <odp_buffer_pool_internal.h>
-#include <odp_sync.h>
+#include <odp/debug.h>
+#include <odp_pool_internal.h>
+#include <odp/sync.h>
+#include <odp/plat/shared_resource.h>
 
 #include <string.h>
+#include <linux/if_ether.h>
 
-#define DUMMY_PKTIO
+#include <odp_align_internal.h>
+#include <ti/drv/nwal/nwal.h>
+#include <ti/drv/nwal/nwal_util.h>
 
-typedef struct {
-       pktio_entry_t entries[ODP_CONFIG_PKTIO_ENTRIES];
-} pktio_table_t;
-
-static pktio_table_t *pktio_tbl;
+/*
+ * Internal structures and accessor functions
+ */
 
-#define MAX_PORT_INDEX 4
-static int port_index(const char *interface)
+typedef uint8_t pktio_id_t;
+
+typedef struct if_mac {
+#define MAX_MAC_LEN    8
+       uint8_t mac[MAX_MAC_LEN];
+       uint8_t mac_len;
+} _odp_if_mac_t;
+
+typedef struct pktio_entry_s {
+       odp_queue_t inq_default ODP_ALIGNED_CACHE; /**< default input queue */
+       odp_queue_t outq_default;        /**< default out queue */
+       odp_pool_t in_pool;              /**< pool for incoming packets */
+       nwalTxPSCmdInfo_t tx_ps_cmdinfo; /**< saved Command Label */
+       nwal_Handle mac_handle;          /**< NWAL MAC entry */
+       nwal_enetPort_t port;            /**< netcp port number */
+       odp_shr_head_t entry_head;       /**< odp_shr head */
+       char name[ODP_PKTIO_NAME_LEN];
+       _odp_if_mac_t mac;
+
+       union {
+               uint32_t all;
+               struct {
+                       uint32_t promisc_mode:1;
+                       uint32_t inq_created:1;
+               };
+       } flags;
+} pktio_entry_t;
+
+static odp_shr_table_t pktio_tbl;
+
+static pktio_entry_t *_odp_pktio_entry(odp_pktio_t pktio)
 {
-       int ret, port;
-
-       ret = sscanf(interface, "eth%d", &port);
-       if (1 != ret)
-               return -1;
-       port++;
-       if (port > MAX_PORT_INDEX)
-               return -1;
-       return port;
+       ODP_ASSERT(pktio != ODP_PKTIO_INVALID, "Wrong pktio handle");
+       ODP_ASSERT(ODP_ALIGNED_CHECK(pktio, ODP_ALIGNOF(pktio_entry_t)),
+                  "Wrong packet IO handle alignment");
+       return (pktio_entry_t *)(void *)pktio;
 }
 
-static pktio_entry_t *get_entry(odp_pktio_t id)
+static odp_pktio_t _odp_pktio_from_entry(pktio_entry_t *entry)
 {
-       if (odp_unlikely(id == ODP_PKTIO_INVALID ||
-                        id > ODP_CONFIG_PKTIO_ENTRIES))
-               return NULL;
-
-       return &pktio_tbl->entries[id];
+       return (odp_pktio_t)entry;
 }
 
-int odp_pktio_init_global(void)
+static pktio_id_t _odp_pktio_id(odp_pktio_t pktio)
 {
-       pktio_entry_t *pktio_entry;
-       int id;
-       odp_shm_t shm;
-
-       shm = odp_shm_reserve("odp_pktio_entries",
-                             sizeof(pktio_table_t),
-                             sizeof(pktio_entry_t), 0);
-
-       pktio_tbl = odp_shm_addr(shm);
+       ODP_ASSERT(pktio != ODP_PKTIO_INVALID, "Wrong pktio handle");
+       return odp_shr_id(_odp_pktio_entry(pktio));
+}
 
-       if (pktio_tbl == NULL)
-               return -1;
 
-       memset(pktio_tbl, 0, sizeof(pktio_table_t));
+static ODP_UNUSED pktio_entry_t *pktio_id_to_entry(pktio_id_t pktio_id)
+{
+       return odp_shr_from_id(pktio_tbl, pktio_id, pktio_entry_t);
+}
 
-       for (id = 1; id <= ODP_CONFIG_PKTIO_ENTRIES; ++id) {
-               pktio_entry = get_entry(id);
+/*
+ * Interface helper functions
+ */
 
-               odp_spinlock_init(&pktio_entry->s.lock);
-       }
-       return 0;
+#define MAX_PORT_INDEX 4
+static _odp_if_mac_t enetport_mac(nwal_enetPort_t id)
+{
+       _odp_if_mac_t mac = {.mac = {0x11, 0x22, 0x33, 0x44, 0x01, 0x00},
+                            .mac_len = ETH_ALEN};
+       mac.mac[mac.mac_len - 1] = id;
+       return mac;
 }
 
-static int is_free(pktio_entry_t *entry)
+static _odp_if_mac_t loopback_mac(uint8_t tag)
 {
-       return (entry->s.taken == 0);
+       _odp_if_mac_t mac = {.mac = {0x11, 0x22, 0x33, 0x44, 0x02, 0x00},
+                            .mac_len = ETH_ALEN};
+       mac.mac[mac.mac_len - 1] = tag;
+       return mac;
 }
 
-static void set_free(pktio_entry_t *entry)
+static bool is_loopback(const char *interface)
 {
-       entry->s.taken = 0;
+       char loopback_dev[] = "loop";
+
+       return strncmp(interface, loopback_dev, sizeof(loopback_dev) - 1) ?
+               false : true;
 }
 
-static void set_taken(pktio_entry_t *entry)
+static nwal_enetPort_t enetport_id(const char *interface)
 {
-       entry->s.taken = 1;
+       int ret, port;
+
+       ret = sscanf(interface, "eth%d", &port);
+       if (1 != ret)
+               return NWAL_ENET_PORT_UNKNOWN;
+       port++;
+       if (port > MAX_PORT_INDEX)
+               return NWAL_ENET_PORT_UNKNOWN;
+       return port;
 }
 
-static void lock_entry(pktio_entry_t *entry)
+int odp_pktio_init_global(void)
 {
-       odp_spinlock_lock(&entry->s.lock);
+       pktio_tbl = odp_shr_table_create("odp_pktio_entries",
+                                        pktio_entry_t,
+                                        ODP_CONFIG_PKTIO_ENTRIES);
+       if (pktio_tbl == ODP_SHR_TABLE_INVALID)
+               return -1;
+
+       return 0;
 }
 
-static void unlock_entry(pktio_entry_t *entry)
+static pktio_entry_t *lookup_pktio_entry(const char *name)
 {
-       odp_spinlock_unlock(&entry->s.lock);
+       pktio_entry_t *entry;
+
+       odp_shr_table_for_each_allocated_entry(pktio_tbl, entry) {
+               odp_shr_lock(entry);
+               if (strcmp(name, entry->name) == 0) {
+                       /* found it */
+                       odp_shr_unlock(entry);
+                       return entry;
+               }
+               odp_shr_unlock(entry);
+       }
+       return NULL;
 }
 
-static int free_pktio_entry(odp_pktio_t id)
+static pktio_entry_t *alloc_pktio_entry(const char *name)
 {
-       pktio_entry_t *entry = get_entry(id);
+       pktio_entry_t *entry;
 
-       if (entry == NULL)
-               return -1;
+       odp_shr_table_lock(pktio_tbl);
+       /* Device name should be unique */
+       if (lookup_pktio_entry(name)) {
+               odp_shr_table_unlock(pktio_tbl);
+               __odp_errno = EEXIST;
+               return NULL;
+       }
 
-       set_free(entry);
+       entry = odp_shr_alloc_nolock(pktio_tbl, typeof(*entry));
+       if (!entry) {
+               odp_shr_table_unlock(pktio_tbl);
+               return NULL;
+       }
 
-       return 0;
+       strncpy(entry->name, name, ODP_PKTIO_NAME_LEN - 1);
+       entry->name[ODP_PKTIO_NAME_LEN - 1] = 0;
+       odp_shr_table_unlock(pktio_tbl);
+       return entry;
+}
+
+static void free_pktio_entry(pktio_entry_t *entry)
+{
+       odp_shr_free(pktio_tbl, entry);
 }
 
-static nwalTxPktInfo_t tx_pkt_info = {
-               .pPkt = NULL,
-               .txFlag1 = NWAL_TX_FLAG1_META_DATA_VALID,
-               .lpbackPass = 0,
-               .enetPort = 0,
-               .mtuSize = 0,
-               .startOffset = 0,
-               .saOffBytes = 0,
-               .saPayloadLen = 0,
-               .saAhIcvOffBytes = 0,
-               .saAhMacSize = 0,
-               .etherLenOffBytes = 0,
-               .ipOffBytes = 0,
-               .l4OffBytes = 0,
-               .l4HdrLen = 0,
-               .pseudoHdrChecksum = 0,
-               .ploadLen = 0,
-};
-
-odp_pktio_t odp_pktio_open(const char *dev, odp_buffer_pool_t pool)
-{
-       odp_pktio_t id;
-       pktio_entry_t *pktio_entry;
+odp_pktio_t odp_pktio_open(const char *dev, odp_pool_t pool)
+{
+       odp_pktio_t pktio;
+       pktio_entry_t *entry;
        char name[ODP_QUEUE_NAME_LEN];
        queue_entry_t *queue_entry;
-       odp_queue_t qid = ODP_QUEUE_INVALID;
+       odp_queue_t queue;
        nwal_RetValue ret_nwal;
-       int port;
+       nwal_enetPort_t port;
+       bool loopback;
+
+       nwalTxPktInfo_t tx_pkt_info = {
+                       .pPkt = NULL,
+                       .txFlag1 = NWAL_TX_FLAG1_META_DATA_VALID,
+                       .lpbackPass = nwal_FALSE,
+                       .enetPort = NWAL_ENET_PORT_UNKNOWN,
+                       .mtuSize = 0,
+                       .startOffset = 0,
+                       .saOffBytes = 0,
+                       .saPayloadLen = 0,
+                       .saAhIcvOffBytes = 0,
+                       .saAhMacSize = 0,
+                       .etherLenOffBytes = 0,
+                       .ipOffBytes = 0,
+                       .l4OffBytes = 0,
+                       .l4HdrLen = 0,
+                       .pseudoHdrChecksum = 0,
+                       .ploadLen = 0,
+       };
 
        odp_pr_dbg("Allocating HW pktio\n");
 
-       /* Create a default output queue for each pktio resource */
-       port = port_index(dev);
-       if (port < 0) {
-               odp_pr_err("Wrong pktio name: %s\n", dev);
-               return ODP_PKTIO_INVALID;
-       }
-
-       /**
-        * Until classification API is in place there is no criteria to
-        * differentiate pktio except a port number. So map port directly
-        * to pktio entry.
-        */
-       id = port;
-
-       pktio_entry = get_entry(id);
-       lock_entry(pktio_entry);
-       if (!is_free(pktio_entry)) {
-               /* Entry already initialized */
-               odp_pr_dbg("PktIO %d is already initialized\n", id);
-               goto unlock;
+       loopback = is_loopback(dev);
+       if (loopback) {
+               tx_pkt_info.lpbackPass = nwal_TRUE;
+               tx_pkt_info.enetPort = NWAL_ENET_PORT_UNKNOWN;
+               port = NWAL_ENET_PORT_UNKNOWN;
+       } else {
+               port = enetport_id(dev);
+               if (port == NWAL_ENET_PORT_UNKNOWN) {
+                       odp_pr_err("Wrong pktio name: %s\n", dev);
+                       return ODP_PKTIO_INVALID;
+               }
        }
 
-       set_taken(pktio_entry);
-       pktio_entry->s.inq_default = ODP_QUEUE_INVALID;
-       pktio_entry->s.outq_default = ODP_QUEUE_INVALID;
-       pktio_entry->s.port = port;
-
-       snprintf(name, sizeof(name), "%i-pktio_outq_default", (int)id);
-       name[ODP_QUEUE_NAME_LEN-1] = '\0';
-
-       qid = odp_queue_create(name, ODP_QUEUE_TYPE_PKTOUT, NULL);
-       odp_pr_dbg("Created queue %u\n", (uint32_t)qid);
-       if (qid == ODP_QUEUE_INVALID) {
-               free_pktio_entry(id);
-               id = ODP_PKTIO_INVALID;
+       entry = alloc_pktio_entry(dev);
+       if (!entry)
+               return ODP_PKTIO_INVALID;
+       pktio = _odp_pktio_from_entry(entry);
+       entry->inq_default = ODP_QUEUE_INVALID;
+       entry->outq_default = ODP_QUEUE_INVALID;
+       entry->port = port;
+       entry->mac = (loopback) ? loopback_mac(_odp_pktio_id(pktio)) :
+                                 enetport_mac(port);
+
+       snprintf(name, sizeof(name), "%s-pktio_outq_default", dev);
+       name[ODP_QUEUE_NAME_LEN - 1] = '\0';
+
+       queue = odp_queue_create(name, ODP_QUEUE_TYPE_PKTOUT, NULL);
+       odp_pr_dbg("Created queue %u\n", (uint32_t)queue);
+       if (queue == ODP_QUEUE_INVALID) {
                odp_pr_err("Couldn't create queue: %s\n", name);
-               goto unlock;
+               goto free_entry;
        }
 
        ret_nwal = nwal_initPSCmdInfo(odp_global->nwal.handle,
                        &tx_pkt_info,
-                       &pktio_entry->s.tx_ps_cmdinfo);
-
+                       &entry->tx_ps_cmdinfo);
        if (ret_nwal != nwal_OK) {
                odp_pr_err("Couldn't create PSCmdInfo\n");
-               goto unlock;
+               goto queue_destroy;
        }
 
-       pktio_entry->s.in_pool = pool;
-       pktio_entry->s.outq_default = qid;
-       pktio_entry->s.id = id;
+       entry->in_pool = pool;
+       entry->outq_default = queue;
 
-       queue_entry = queue_to_qentry(qid);
-       queue_entry->s.pktout_entry = pktio_entry;
-unlock:
-       unlock_entry(pktio_entry);
-       return id;
+       queue_entry = _odp_queue_to_qentry(queue);
+       queue_entry->pktout_entry = entry;
+       return pktio;
+
+queue_destroy:
+       odp_queue_destroy(queue);
+free_entry:
+       free_pktio_entry(entry);
+       return ODP_PKTIO_INVALID;
 }
 
-int odp_pktio_close(odp_pktio_t id)
+int odp_pktio_close(odp_pktio_t pktio)
 {
-       pktio_entry_t *entry;
+       pktio_entry_t *entry = _odp_pktio_entry(pktio);
+       int ret;
 
-       entry = get_entry(id);
-       if (entry == NULL)
+       /* At this point pktio should not be used anymore. So no locking */
+       ret = odp_pktio_inq_remdef(pktio);
+       if (ret)
                return -1;
 
-       /* Only one entry per port exists, so no need to delete it */
+       if (entry->outq_default != ODP_QUEUE_INVALID) {
+               if (odp_queue_destroy(entry->outq_default))
+                       return -1;
+               entry->outq_default = ODP_QUEUE_INVALID;
+       }
+       /** @todo: close default in queue and remove MAC rules */
+       free_pktio_entry(entry);
 
        return 0;
 }
 
-void odp_pktio_set_input(odp_packet_t pkt, odp_pktio_t pktio)
-{
-       odp_packet_hdr(pkt)->input = pktio;
-}
-
-odp_pktio_t odp_pktio_get_input(odp_packet_t pkt)
-{
-       return odp_packet_hdr(pkt)->input;
-}
-
-static int pktio_inq_setdef_locked(odp_pktio_t id, odp_queue_t queue)
+static int pktio_update_mac_entry(pktio_entry_t *entry)
 {
        nwal_RetValue nwal_ret;
-       nwal_Handle handle;
-       pktio_entry_t *pktio_entry = get_entry(id);
-       queue_entry_t *queue_entry = queue_to_qentry(queue);
        nwalMacParam_t mac_info = {
                        .validParams = NWAL_SET_MAC_VALID_PARAM_IFNUM,
                        .ifNum = 0,
@@ -249,22 +310,37 @@ static int pktio_inq_setdef_locked(odp_pktio_t id, 
odp_queue_t queue)
                        .routeType = 0,
        };
 
-       ODP_ASSERT(pktio_entry && queue_entry, "Not valid entries");
-       ODP_ASSERT(queue_entry->s.type == ODP_QUEUE_TYPE_PKTIN,
-                  "Not PKTIN queue");
+       ODP_ASSERT(entry->inq_default != ODP_QUEUE_INVALID,
+                  "In queue is not set");
 
-       pktio_entry->s.inq_default = queue;
-       odp_sync_stores();
-       mac_info.appRxPktQueue = _odp_queue_to_qmss_queue(queue);
-       /** @todo: Specify flow corresponding to the pool */
-       mac_info.appRxPktFlowId = QMSS_PARAM_NOT_SPECIFIED;
-       mac_info.ifNum = pktio_entry->s.port;
+       if (entry->mac_handle != nwal_HANDLE_INVALID) {
+               nwal_ret = nwal_delMacIface(odp_global->nwal.handle,
+                               NWAL_TRANSID_SPIN_WAIT,
+                               entry->mac_handle);
+               entry->mac_handle = nwal_HANDLE_INVALID;
+               ODP_ASSERT(nwal_ret == nwal_OK,
+                          "nwal_setMacIface returned Error Code: %d\n",
+                          nwal_ret);
+       }
+
+       mac_info.ifNum = entry->port;
+       mac_info.appRxPktQueue = _odp_queue_to_qmss_queue(entry->inq_default);
+       mac_info.appRxPktFlowId = _odp_pool_cppi_flow_id(entry->in_pool);
+       if (mac_info.appRxPktFlowId < 0) {
+               odp_pr_err("couldn't get pool flow id\n");
+               return -1;
+       }
+       if (!entry->flags.promisc_mode) {
+               ODP_ASSERT(entry->mac.mac_len == sizeof(mac_info.macAddr),
+                          "Wrong MAC address length");
+               memcpy(&mac_info.macAddr, entry->mac.mac, entry->mac.mac_len);
+       }
 
        nwal_ret = nwal_setMacIface(odp_global->nwal.handle,
                        NWAL_TRANSID_SPIN_WAIT,
                        (nwal_AppId) (0x12345678),
                        &mac_info,
-                       &handle);
+                       &entry->mac_handle);
        if (nwal_ret != nwal_OK) {
                odp_pr_err("nwal_setMacIface returned Error Code %d\n",
                           nwal_ret);
@@ -272,31 +348,48 @@ static int pktio_inq_setdef_locked(odp_pktio_t id, 
odp_queue_t queue)
        }
 
        odp_pr_info("MAC i/f added\n");
+       return 0;
+}
+
+static int pktio_inq_setdef_locked(odp_pktio_t pktio, odp_queue_t queue)
+{
+       pktio_entry_t *pktio_entry = _odp_pktio_entry(pktio);
+       queue_entry_t *queue_entry = _odp_queue_to_qentry(queue);
+       int ret;
+
+       ODP_ASSERT(pktio_entry && queue_entry, "Not valid entries");
+       ODP_ASSERT(queue_entry->type == ODP_QUEUE_TYPE_PKTIN,
+                  "Not PKTIN queue");
+
+       pktio_entry->inq_default = queue;
+       ret = pktio_update_mac_entry(pktio_entry);
+       if (ret)
+               return ret;
 
        queue_lock(queue_entry);
-       queue_entry->s.pktin = id;
-       queue_entry->s.status = QUEUE_STATUS_SCHED;
+       queue_entry->pktin = pktio;
+       queue_entry->status = QUEUE_STATUS_SCHED;
        queue_unlock(queue_entry);
 
-       odp_schedule_queue(queue, queue_entry->s.param.sched.prio);
+       odp_schedule_queue(queue, queue_entry->sched.prio);
 
        return 0;
 }
 
-static int pktio_inq_create_setdef(odp_pktio_t id)
+static int pktio_inq_create_setdef(odp_pktio_t pktio)
 {
        char name[ODP_QUEUE_NAME_LEN];
        odp_queue_param_t qparam;
        odp_queue_t inq_def;
-       pktio_entry_t *pktio_entry = get_entry(id);
+       pktio_entry_t *entry = _odp_pktio_entry(pktio);
        int ret = 0;
 
-       ODP_ASSERT(pktio_entry, "Not valid entry");
-       lock_entry(pktio_entry);
-       if (pktio_entry->s.inq_default != ODP_QUEUE_INVALID) {
+       ODP_ASSERT(entry, "Not valid entry");
+       odp_shr_lock(entry);
+       if (entry->inq_default != ODP_QUEUE_INVALID) {
                ret = 0;
                odp_pr_dbg("default input queue is already set: %u\n",
-                          pktio_entry->s.inq_default);
+                          entry->inq_default);
                goto unlock;
        }
 
@@ -304,7 +397,7 @@ static int pktio_inq_create_setdef(odp_pktio_t id)
        qparam.sched.prio  = ODP_SCHED_PRIO_DEFAULT;
        qparam.sched.sync  = ODP_SCHED_SYNC_NONE;
        qparam.sched.group = ODP_SCHED_GROUP_DEFAULT;
-       snprintf(name, sizeof(name), "%i-pktio_inq_default", (int)id);
+       snprintf(name, sizeof(name), "%s-pktio_inq_default", entry->name);
        name[ODP_QUEUE_NAME_LEN-1] = '\0';
        inq_def = odp_queue_create(name, ODP_QUEUE_TYPE_PKTIN, &qparam);
        if (inq_def == ODP_QUEUE_INVALID) {
@@ -312,163 +405,267 @@ static int pktio_inq_create_setdef(odp_pktio_t id)
                ret = -1;
                goto unlock;
        }
+       entry->flags.inq_created = 1;
 
-       if (pktio_inq_setdef_locked(id, inq_def)) {
+       if (pktio_inq_setdef_locked(pktio, inq_def)) {
                odp_pr_err("default input-Q setup\n");
                ret = -1;
                goto unlock;
        }
 unlock:
-       unlock_entry(pktio_entry);
+       odp_shr_unlock(entry);
        return ret;
 }
 
-int odp_pktio_recv(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len)
+int odp_pktio_recv(odp_pktio_t pktio, odp_packet_t pkt_table[], int len)
 {
-       pktio_entry_t *pktio_entry = get_entry(id);
-       unsigned pkts = 0;
-       odp_buffer_t buf;
+       pktio_entry_t *entry = _odp_pktio_entry(pktio);
+       int pkts = 0;
+       odp_event_t event;
 
-       ODP_ASSERT(pktio_entry, "Not valid entry");
+       ODP_ASSERT(entry, "Not valid entry");
 
-       if (pktio_entry->s.inq_default == ODP_QUEUE_INVALID) {
+       if (entry->inq_default == ODP_QUEUE_INVALID) {
                /**
                 * Create a default input queue.
                 * @todo: It is a kind of WA for current ODP API usage.
                 * It should be revised.
                 */
-               if (pktio_inq_create_setdef(id))
+               if (pktio_inq_create_setdef(pktio))
                        return -1;
        }
 
        for (pkts = 0; pkts < len; pkts++) {
-               buf = odp_queue_deq(pktio_entry->s.inq_default);
-               if (!odp_buffer_is_valid(buf))
+               event = odp_queue_deq(entry->inq_default);
+               if (event == ODP_EVENT_INVALID)
                        break;
 
-               pkt_table[pkts] = odp_packet_from_buffer(buf);
+               pkt_table[pkts] = odp_packet_from_event(event);
        }
        return pkts;
 }
 
-static inline void pktio_buffer_send(pktio_entry_t *pktio, odp_buffer_t buf)
+static inline void pktio_event_send(pktio_entry_t *pktio, odp_event_t event)
 {
-       nwal_mCmdSetPort(_odp_buf_to_ti_pkt(buf),
-                        &(pktio->s.tx_ps_cmdinfo),
-                        pktio->s.port);
+       Cppi_HostDesc *desc = _odp_ev_to_cppi_desc(event);
+       nwal_mCmdSetPort(Pktlib_getPacketFromDesc(desc),
+                        &(pktio->tx_ps_cmdinfo),
+                        pktio->port);
 
-       Qmss_queuePushDescSize(pktio->s.tx_ps_cmdinfo.txQueue,
-                              _odp_buf_to_cppi_desc(buf),
+       Qmss_queuePushDescSize(pktio->tx_ps_cmdinfo.txQueue,
+                              desc,
                               NWAL_DESC_SIZE);
 }
 
-int odp_pktio_send(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len)
+int odp_pktio_send(odp_pktio_t pktio, odp_packet_t pkt_table[], int len)
 {
-       pktio_entry_t *pktio_entry = get_entry(id);
-       unsigned pkts;
+       pktio_entry_t *entry = _odp_pktio_entry(pktio);
+       int pkts;
 
-       if (pktio_entry == NULL)
+       if (entry == NULL)
                return -1;
 
        for (pkts = 0; pkts < len; pkts++) {
-               pktio_buffer_send(pktio_entry,
-                                 odp_packet_to_buffer(pkt_table[pkts]));
+               pktio_event_send(entry,
+                                odp_packet_to_event(pkt_table[pkts]));
        }
        return pkts;
 }
 
-int odp_pktio_inq_setdef(odp_pktio_t id, odp_queue_t queue)
+int odp_pktio_inq_setdef(odp_pktio_t pktio, odp_queue_t queue)
 {
-       pktio_entry_t *pktio_entry = get_entry(id);
+       pktio_entry_t *entry = _odp_pktio_entry(pktio);
        int ret = 0;
 
-       ODP_ASSERT(pktio_entry, "Not valid entry");
+       ODP_ASSERT(entry, "Not valid entry");
 
-       lock_entry(pktio_entry);
-       if (pktio_entry->s.inq_default == ODP_QUEUE_INVALID) {
-               ret = pktio_inq_setdef_locked(id, queue);
+       odp_shr_lock(entry);
+       if (entry->inq_default == ODP_QUEUE_INVALID) {
+               ret = pktio_inq_setdef_locked(pktio, queue);
        } else {
                 /* Default queue can be assigned only once */
                odp_pr_err("pktio %u: default input queue %s is already set\n",
-                          id,
-                          odp_queue_name(pktio_entry->s.inq_default));
+                          pktio,
+                          odp_queue_name(entry->inq_default));
                ret = -1;
        }
-       unlock_entry(pktio_entry);
+       odp_shr_unlock(entry);
        return ret;
 }
 
-int odp_pktio_inq_remdef(odp_pktio_t id)
+int odp_pktio_inq_remdef(odp_pktio_t pktio)
 {
-       return odp_pktio_inq_setdef(id, ODP_QUEUE_INVALID);
+       pktio_entry_t *pktio_entry = _odp_pktio_entry(pktio);
+       queue_entry_t *queue_entry;
+       nwal_RetValue nwal_ret;
+
+       if (pktio_entry->inq_default == ODP_QUEUE_INVALID)
+               return 0;
+
+       odp_shr_lock(pktio_entry);
+
+       nwal_ret = nwal_delMacIface(odp_global->nwal.handle,
+                       NWAL_TRANSID_SPIN_WAIT,
+                       pktio_entry->mac_handle);
+       pktio_entry->mac_handle = nwal_HANDLE_INVALID;
+       ODP_ASSERT(nwal_ret == nwal_OK,
+                  "nwal_setMacIface returned Error Code: %d\n", nwal_ret);
+
+       if (pktio_entry->flags.inq_created) {
+               /* destroy queue*/
+               if (odp_queue_destroy(pktio_entry->inq_default)) {
+                       odp_shr_unlock(pktio_entry);
+                       return -1;
+               }
+       } else {
+               /* Detach pktio from a queue */
+               queue_entry = _odp_queue_to_qentry(pktio_entry->inq_default);
+               queue_lock(queue_entry);
+               queue_entry->pktin = ODP_PKTIO_INVALID;
+               queue_unlock(queue_entry);
+       }
+
+       pktio_entry->inq_default = ODP_QUEUE_INVALID;
+       odp_shr_unlock(pktio_entry);
+       return 0;
 }
 
-odp_queue_t odp_pktio_inq_getdef(odp_pktio_t id)
+odp_queue_t odp_pktio_inq_getdef(odp_pktio_t pktio)
 {
-       pktio_entry_t *pktio_entry = get_entry(id);
+       pktio_entry_t *entry = _odp_pktio_entry(pktio);
 
-       if (pktio_entry == NULL)
+       if (entry == NULL)
                return ODP_QUEUE_INVALID;
 
-       return pktio_entry->s.inq_default;
+       return entry->inq_default;
 }
 
-odp_queue_t odp_pktio_outq_getdef(odp_pktio_t id)
+odp_queue_t odp_pktio_outq_getdef(odp_pktio_t pktio)
 {
-       pktio_entry_t *pktio_entry = get_entry(id);
+       pktio_entry_t *entry = _odp_pktio_entry(pktio);
 
-       if (pktio_entry == NULL)
+       if (entry == NULL)
                return ODP_QUEUE_INVALID;
 
-       return pktio_entry->s.outq_default;
+       return entry->outq_default;
 }
 
-int pktout_enqueue(queue_entry_t *queue, odp_buffer_t buf)
+int pktout_enqueue(queue_entry_t *qentry, odp_event_t ev)
 {
-       pktio_entry_t *pktio = queue->s.pktout_entry;
+       pktio_entry_t *pktio_entry = qentry->pktout_entry;
        odp_pr_vdbg("sending packet\n");
-       odp_pr_vdbg_packet(odp_packet_from_buffer(buf));
-       pktio_buffer_send(pktio, buf);
+       odp_pr_vdbg_packet(odp_packet_from_event(ev));
+       pktio_event_send(pktio_entry, ev);
        return 0;
 }
 
-int pktout_enq_multi(queue_entry_t *queue, odp_buffer_t buf[], int num)
+int pktout_enq_multi(queue_entry_t *qentry, const odp_event_t ev[], int num)
 {
        int i;
-       pktio_entry_t *pktio = queue->s.pktout_entry;
+       pktio_entry_t *pktio_entry = qentry->pktout_entry;
        for (i = 0; i < num; i++)
-               pktio_buffer_send(pktio, buf[i]);
-       return 0;
+               pktio_event_send(pktio_entry, ev[i]);
+       return num;
 }
 
-static inline void update_in_packet(odp_buffer_t buf,
+#define SW_PARSING
+
+static inline void update_in_packet(odp_event_t ev,
                                    odp_pktio_t pktin)
 {
-       if (!odp_buffer_is_valid(buf))
+       if (ev == ODP_EVENT_INVALID)
                return;
 
-       odp_packet_t pkt = odp_packet_from_buffer(buf);
-       struct odp_pkthdr *pkt_hdr = odp_packet_hdr(pkt);
-       size_t len = odp_packet_get_len(pkt);
-       pkt_hdr->input = pktin;
-       odp_packet_parse(pkt, len, 0);
+       odp_packet_t pkt = odp_packet_from_event(ev);
+       struct odp_pkthdr *hdr = _odp_pkt_hdr(pkt);
+       hdr->input = pktin;
+       ODP_DBG("Received packet ---------\n");
+#ifdef SW_PARSING
+       _odp_packet_parse(pkt);
+#else
+       pasahoLongInfo_t *pasa_info =
+                       nwal_mGetProtoInfo(_odp_buf_to_ti_pkt(buf));
+       ODP_ASSERT(pasa_info, "Invalid info from NetCP");
+       hdr->l2_offset = 0;
+       hdr->l3_offset = PASAHO_LINFO_READ_L3_OFFSET(pasa_info);
+       hdr->l4_offset = PASAHO_LINFO_READ_L4_OFFSET(pasa_info);
+#endif
+       odp_packet_print(pkt);
 }
 
-odp_buffer_t pktin_dequeue(queue_entry_t *queue)
+odp_event_t pktin_dequeue(queue_entry_t *qentry)
 {
-       odp_buffer_t buf;
-       buf = queue_deq(queue);
+       odp_event_t event;
+       event = queue_deq(qentry);
 
-       update_in_packet(buf, queue->s.pktin);
-       return buf;
+       update_in_packet(event, qentry->pktin);
+       return event;
 }
 
-int pktin_deq_multi(queue_entry_t *queue, odp_buffer_t buf[], int num)
+int pktin_deq_multi(queue_entry_t *qentry, odp_event_t ev[], int num)
 {
        int i;
-       num = queue_deq_multi(queue, buf, num);
+       num = queue_deq_multi(qentry, ev, num);
 
        for (i = 0; i < num; i++)
-               update_in_packet(buf[i], queue->s.pktin);
+               update_in_packet(ev[i], qentry->pktin);
        return num;
 }
+
+ssize_t odp_pktio_mac_addr(odp_pktio_t pktio, void *mac_addr, ssize_t 
addr_size)
+{
+       pktio_entry_t *entry = _odp_pktio_entry(pktio);
+       ssize_t size;
+
+       /* MAC address is set only once on pktio open. So no locking. */
+       size = entry->mac.mac_len;
+       if (addr_size < size)
+               return -1;
+
+       memcpy(mac_addr, entry->mac.mac, size);
+
+       return size;
+}
+
+odp_pktio_t odp_pktio_lookup(const char *dev)
+{
+       pktio_entry_t *entry = lookup_pktio_entry(dev);
+       if (!entry)
+               return ODP_PKTIO_INVALID;
+
+       return _odp_pktio_from_entry(entry);
+}
+
+int odp_pktio_mtu(odp_pktio_t pktio)
+{
+       (void)pktio;
+       ODP_UNIMPLEMENTED();
+       return -1;
+}
+
+
+int odp_pktio_promisc_mode_set(odp_pktio_t pktio, odp_bool_t enable)
+{
+       pktio_entry_t *entry = _odp_pktio_entry(pktio);
+       int ret = 0;
+       odp_shr_lock(entry);
+
+       if (!enable == !entry->flags.promisc_mode) {
+               odp_shr_unlock(entry);
+               return 0;
+       }
+
+       entry->flags.promisc_mode = enable;
+       /* If default queue is already set, then MAC entry should be updated */
+       if (entry->inq_default != ODP_QUEUE_INVALID)
+               ret = pktio_update_mac_entry(entry);
+
+       odp_shr_unlock(entry);
+       return ret;
+}
+
+int odp_pktio_promisc_mode(odp_pktio_t pktio)
+{
+       pktio_entry_t *entry = _odp_pktio_entry(pktio);
+       return entry->flags.promisc_mode;
+}
diff --git a/platform/linux-keystone2/odp_queue.c 
b/platform/linux-keystone2/odp_queue.c
index f59a884..2ecc973 100644
--- a/platform/linux-keystone2/odp_queue.c
+++ b/platform/linux-keystone2/odp_queue.c
@@ -65,7 +65,6 @@ static int queue_init(queue_entry_t *qentry, const char *name,
        }
 
        switch (type) {
-#if 0
        case ODP_QUEUE_TYPE_PKTIN:
                qentry->enqueue = NULL;
                qentry->dequeue = pktin_dequeue;
@@ -78,7 +77,6 @@ static int queue_init(queue_entry_t *qentry, const char *name,
                qentry->enqueue_multi = pktout_enq_multi;
                qentry->dequeue_multi = NULL;
                break;
-#endif
        default:
                qentry->enqueue = queue_enq;
                qentry->dequeue = queue_deq;
-- 
1.9.1


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

Reply via email to