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