@@ -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 \
@@ -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
}
new file mode 100644
@@ -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
@@ -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;
@@ -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
@@ -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
}
@@ -20,6 +20,7 @@ extern "C" {
#endif
#include <odp/queue.h>
+#include <odp/packet_io.h>
#include <odp/align.h>
@@ -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;
@@ -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;
+}
@@ -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;