author | David Lide <a0216552@gtudci01.(none)> | |
Wed, 25 Jan 2012 21:13:19 +0000 (16:13 -0500) | ||
committer | David Lide <a0216552@gtudci01.(none)> | |
Wed, 25 Jan 2012 21:13:19 +0000 (16:13 -0500) |
40 files changed:
diff --git a/ti/runtime/netapi/OLD/qmsim.c b/ti/runtime/netapi/OLD/qmsim.c
--- /dev/null
@@ -0,0 +1,72 @@
+#include <stdlib.h>
+#include "qmsim.h"
+
+/*-------------------Simulator part ---------------*/
+
+void dumpq(Q* q)
+{
+ printf("QDUMP: %d %d %d %d\n",q->size, q->ne, q->head,q->tail);
+}
+void qsim_close(Q * q)
+{
+ if (!q) return;
+ if (q->q) free(q->q);
+ free(q);
+ printf("QSIM: freeing queue\n");
+}
+
+Q * qsim_create(nelem)
+{
+void *p;
+Q * q;
+if (!nelem) return NULL;
+q = (Q*) calloc(1,sizeof(Q));
+if (!q) return NULL;
+
+p = (void **) calloc(nelem,sizeof(void *));
+if (!p) { free(q); return NULL; }
+
+q->size=nelem;
+q->q = p ;
+ printf("QSIM CREATE .. "); dumpq(q);
+return q;
+}
+
+int qsim_push(Q *q, void *p)
+{
+ if (!q) return -1;
+ if (q->ne >= q->size) return-1;
+ q->q[q->tail] = p;
+ q->tail +=1;
+ q->ne+=1;
+ if (q->tail >= q->size) q->tail = 0;
+ //dumpq(q);
+ return 1;
+}
+void * qsim_pop(Q *q )
+{
+ void * val;
+ if (!q) return NULL;
+ if (q->ne ==0) return NULL;
+ val = q->q[q->head];
+ q->head+=1;
+ if(q->head>= q->size) q->head=0;
+ q->ne -=1;
+ //dumpq(q);
+ return val;
+}
+
+//#define TEST_QSIM
+#ifdef TEST_QSIM
+main()
+{
+ Q * q;
+ int i;
+ q= qsim_create(10);
+ for(i=1;i<11;i++) qsim_push(q, (void *) i);
+
+ for(;i<16;i++) { void * val; val = qsim_pop(q); printf("%d\n", (int) val);}
+ for(;i<21;i++) qsim_push(q, (void *) i);
+ for(;i<31;i++) { void * val; val = qsim_pop(q); printf("%d\n", (int) val);}
+}
+#endif
diff --git a/ti/runtime/netapi/OLD/qmsim.h b/ti/runtime/netapi/OLD/qmsim.h
--- /dev/null
@@ -0,0 +1,27 @@
+/****************************
+ * qmsim.h: qmss lld, hw simulator
+*****************************/
+#ifndef __QMSIM__H
+#define __QMSIM__H
+
+
+#ifndef NULL
+#define NULL (void*) 0
+#endif
+
+typedef struct Q_t
+{
+ int size;
+ int head;
+ int tail;
+ int ne;
+ void ** q;
+} Q;
+
+/*-----------------------*/
+/*--------simulator------*/
+Q * qsim_create(int nelem);
+int qsim_push(Q *, void *p);
+void * qsim_pop(Q * );
+void qsim_close(Q * );
+#endif
diff --git a/ti/runtime/netapi/OLD/shmtest.c b/ti/runtime/netapi/OLD/shmtest.c
--- /dev/null
@@ -0,0 +1,78 @@
+#include <stdlib.h>
+#include <sys/shm.h>
+#include <errno.h>
+
+ char * p= NULL;
+main(int argc, char * argv[])
+{
+int fd;
+int op=0;
+int name = 0xfeed;
+int err;
+if (argc<3) {printf("shmtest (c[reate]| d[delete]| o[open]) key\n"); exit(1);}
+
+
+switch (argv[1][0])
+{
+case 'D':
+case 'd':
+ op =2; //delete
+ break;
+case 'c':
+case 'C':
+ op =0; //create
+ break;
+case 'o':
+case 'O':
+ op =1; //open
+ break;
+default:
+printf(" unknown op code %c. Need d, o, or c\n", argv[1][0]);
+exit(1);
+break;
+}
+
+name = atoi(argv[2]); printf("key = %d op=%d\n", name,op);
+switch (op)
+{
+case(1): /* open */
+default:
+ fd = shmget( (key_t) name, 100000, 0666 );
+ if (fd <0) {
+ perror(" shget open failed\n");
+ exit( 1);
+ }
+ break;
+
+case(0): /* create */
+ fd = shmget(name, 100000, IPC_CREAT | 0666 );
+ if (fd<0) {perror(" shget create failed , exiting "); exit(1);}
+ break;
+
+case(2):
+ fd = shmget( (key_t) name, 100000, 0666 );
+ if (fd <0) {
+ perror(" delete: shget open failed\n");
+ exit( 1);
+ }
+ err=shmctl(fd, IPC_RMID, 0);
+ if(err<0) {perror("ctl failed: ");}
+ exit( 0); //all we do
+ break;
+}
+
+/* map into us */
+p = shmat(fd, 0, 0);
+if (p == -1) {
+perror("shmat failed\n"); exit(1);
+}
+ else {printf("mapped to %x\n",p);}
+
+if (op==1) { printf("got something: %s\n", p);}
+else if(op==0)
+{
+sprintf(p,"created some shared memory, key=%d...\n",name);
+printf("creating shm ok: %s",p);
+}
+
+}
diff --git a/ti/runtime/netapi/OLD/synchtest.c b/ti/runtime/netapi/OLD/synchtest.c
--- /dev/null
@@ -0,0 +1,10 @@
+int spot=0;
+main()
+{
+int val;
+int i;
+for(i=0;i<10;i++) {
+val=__sync_fetch_and_add_4(&spot, 1);
+printf(" val = %d %d\n",val,spot);
+}
+}
diff --git a/ti/runtime/netapi/OLD/synchtest2.c b/ti/runtime/netapi/OLD/synchtest2.c
--- /dev/null
@@ -0,0 +1,87 @@
+#include <stdio.h>\r
+#include <pthread.h>\r
+#include <unistd.h>\r
+#include <stdlib.h>\r
+#include <sched.h>\r
+#include <linux/unistd.h>\r
+#include <sys/syscall.h>\r
+#include <errno.h>\r
+\r
+#define INC_TO 1000000 // one million...\r
+\r
+int global_int = 0;\r
+\r
+pid_t gettid( void )\r
+{\r
+ return syscall( __NR_gettid );\r
+}\r
+\r
+void *thread_routine( void *arg )\r
+{\r
+ int i;\r
+ int proc_num = (int)(long)arg;\r
+ cpu_set_t set;\r
+\r
+ CPU_ZERO( &set );\r
+ CPU_SET( proc_num, &set );\r
+\r
+ if (sched_setaffinity( gettid(), sizeof( cpu_set_t ), &set ))\r
+ {\r
+ perror( "sched_setaffinity" );\r
+ return NULL;\r
+ }\r
+\r
+ for (i = 0; i < INC_TO; i++)\r
+ {\r
+// global_int++;\r
+ __sync_fetch_and_add( &global_int, 1 );\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+int main()\r
+{\r
+ int procs = 0;\r
+ int i;\r
+ pthread_t *thrs;\r
+\r
+ // Getting number of CPUs\r
+ procs = (int)sysconf( _SC_NPROCESSORS_ONLN );\r
+ if (procs < 0)\r
+ {\r
+ perror( "sysconf" );\r
+ return -1;\r
+ }\r
+\r
+ thrs = malloc( sizeof( pthread_t ) * procs );\r
+ if (thrs == NULL)\r
+ {\r
+ perror( "malloc" );\r
+ return -1;\r
+ }\r
+\r
+ printf( "Starting %d threads...\n", procs );\r
+\r
+ for (i = 0; i < procs; i++)\r
+ {\r
+ if (pthread_create( &thrs[i], NULL, thread_routine,\r
+ (void *)(long)i ))\r
+ {\r
+ perror( "pthread_create" );\r
+ procs = i;\r
+ break;\r
+ }\r
+ }\r
+\r
+ for (i = 0; i < procs; i++)\r
+ pthread_join( thrs[i], NULL );\r
+\r
+ free( thrs );\r
+\r
+ printf( "After doing all the math, global_int value is: %d\n",\r
+ global_int );\r
+ printf( "Expected value is: %d\n", INC_TO * procs );\r
+\r
+ return 0;\r
+}
\ No newline at end of file
diff --git a/ti/runtime/netapi/build/Makefile b/ti/runtime/netapi/build/Makefile
--- /dev/null
@@ -0,0 +1,42 @@
+# INCLUDE Directories
+QMSS_INC_DIR = $(PDK_INSTALL_PATH)/ti/drv/qmss
+CPPI_INC_DIR = $(PDK_INSTALL_PATH)/ti/drv/cppi
+
+INCDIR := $(PDK_INSTALL_PATH); $(QMSS_INC_DIR); $(CPPI_INC_DIR)
+
+# Libraries
+QMSS_LIB = $(PDK_INSTALL_PATH)/ti/drv/qmss/lib/ti.drv.qmss.aearmv7
+CPPI_LIB = $(PDK_INSTALL_PATH)/ti/drv/cppi/lib/ti.drv.cppi.aearmv7
+PA_LIB = $(PDK_INSTALL_PATH)/ti/drv/pa/lib/ti.drv.pa.aearmv7
+NWAL_LIB = $(PDK_INSTALL_PATH)/ti/drv/nwal/lib/ti.drv.nwal.aearmv7
+
+#NETAPI dirs
+NETAPI_SRC_DIR = ../src
+NETAPI_INC_DIR = ../
+NETAPI_LIB_DIR = ../lib
+
+API_OBJS= $(NETAPI_SRC_DIR)/netapi.o $(NETAPI_SRC_DIR)/pktio.o $(NETAPI_SRC_DIR)/netcp_cfg.o $(NETAPI_SRC_DIR)/netapi_sched.o $(NETAPI_SRC_DIR)/netapi_vm.o $(NETAPI_SRC_DIR)/netapi_init.o $(NETAPI_SRC_DIR)/osal.o $(NETAPI_SRC_DIR)/tim64.o $(NETAPI_SRC_DIR)/timlist.o $(NETAPI_SRC_DIR)/netapi_timer.o
+
+CROSS=arm-none-linux-gnueabi-gcc
+CROSS_PATH=/opt/CodeSourcery/Sourcery_G++_Lite/bin
+CC=$(CROSS_PATH)/$(CROSS)
+AR=$(CROSS_PATH)/arm-none-linux-gnueabi-ar
+CFLAGS= -g -I$(NETAPI_INC_DIR) -I. -I $(NETAPI_SRC_DIR) -I$(PDK_INSTALL_PATH) -I$(NWAL_INSTALL_PATH) -I$(QMSS_INC_DIR) -I$(CPPI_INC_DIR) -D__ARMv7 -D_VIRTUAL_ADDR_SUPPORT -D__LINUX_USER_SPACE -D_LITTLE_ENDIAN=1 -DMAKEFILE_BUILD -pthread -D _GNU_SOURCE
+
+all: api
+
+clean:
+ rm -f $(NETAPI_SRC_DIR)/*.o
+ rm -f *.a
+
+
+%.o: %.c
+ $(CC) -c $(CFLAGS) $< -o $@
+
+api: $(NETAPI_LIB_DIR)/api_lib.a
+
+$(NETAPI_LIB_DIR)/api_lib.a: $(API_OBJS)
+ rm -f $(NETAPI_LIB_DIR)/api_lib.a
+ $(AR) rcv $(NETAPI_LIB_DIR)/api_lib.a $(API_OBJS)
+
+
diff --git a/ti/runtime/netapi/lib/api_lib.a b/ti/runtime/netapi/lib/api_lib.a
new file mode 100644 (file)
index 0000000..2c7ca40
Binary files /dev/null and b/ti/runtime/netapi/lib/api_lib.a differ
index 0000000..2c7ca40
Binary files /dev/null and b/ti/runtime/netapi/lib/api_lib.a differ
diff --git a/ti/runtime/netapi/netapi.h b/ti/runtime/netapi/netapi.h
--- /dev/null
@@ -0,0 +1,225 @@
+/**************************************************************
+ * FILE PURPOSE : -----------NETAPI-------------
+ * user space access to transport resources on SOC
+ **************************************************************
+ * FILE: netapi.h
+ *
+ * DESCRIPTION: netapi main header file for user space transport
+ * library
+ *
+ * REVISION HISTORY: rev 0.0.1
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*****************************************************************************/
+
+/** @mainpage Network API
+ *
+ * @section intro Introduction
+ *
+ * The network API provides a user space interface to TI SOC transport
+ * Resources. The library includes:
+ * - general startup and setup for user space operations
+ * - memory heap and packet buffer management
+ * - pktio either to/from network or internal queues
+ * - timers for network stacks
+ * - netcp (network co-processor) configuration and control
+ * - utilities including user space synchronization primitivies
+ * - sample scheduling event loop
+ *
+ * NETAPI allows user space transport to configure control the NETCP:
+ * - Classification of packets based on L2: MAC header fields
+ * - Classification of packets based on L3: IP header fields
+ * - Routing of packets to host based on L4 UDP or L5 GTPU ID
+ * - Unidirectional IPSec SA creation and deletion
+ * - Unidirectional IPSec Security Policy creation and deletion
+ *
+ * \par
+ * NOTE:
+ * (C) Copyright 2010-2011 Texas Instruments, Inc.
+ * \par
+ */
+
+/* Define NETAPI as a master group in Doxygen format and add all NETAPI
+ definitions to this group. */
+/** @defgroup netapi USERSPACE TRANSPORT NETAPI
+ * @{
+ */
+/** @} */
+
+
+#ifndef __NETAPI__H
+#define __NETAPI__H
+#include <stdint.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+
+/**
+ * @defgroup netapi_structures NETAPI data structures
+ */
+/** @ingroup netapi */
+
+/** @defgroup netapi_api_functions NETAPI API's
+ * @ingroup netapi
+ */
+
+/** @ingroup netapi_structures */
+/**
+ * @def NETAPI_T
+ * netapi handle: one per thread
+ * used in most NETAPI calls
+ */
+typedef void * NETAPI_T;
+
+
+#define NETAPI_SYS_MASTER 2 //master for system
+#define NETAPI_CORE_MASTER 1 //master for core
+#define NETAPI_NO_MASTE 0 //data only
+
+
+#include "netapi_err.h"
+#include "netapi_tune.h"
+#include "ti/runtime/pktlib/pktlib_osal.h"
+#include "ti/runtime/pktlib/pktlib.h"
+#include "pktio.h"
+#include "ti/drv/pa/pa.h"
+#include "netcp_cfg.h"
+#include "netapi_sched.h"
+#include "src/netapi_vm.h"
+#include "src/netapi_util.h"
+#include "netsync.h"
+#include "ti/drv/nwal/nwal.h"
+#include "netapi_timer.h"
+#include "src/netapi_loc.h"
+
+/************************************************
+ **********BUILD TIME CONTROLS *****************
+ ***********************************************/
+/* see netapi_tune.h */
+
+
+/*************************************
+ **************NETAPI****************
+ ************************************/
+
+/** @ingroup netapi_api_functions */
+
+/*
+* @brief API instantiates the NETAPI and allocated global resources and is pre-requisite
+ *
+ * @details Allocates global resources valid per system level common across all ARM cores
+ * or per thread based on "master" argument.
+ * Intializes the following substems:
+ * - pktio
+ * - pktlib
+ * - qmss
+ * - cppi
+ * - nwal
+ * @param[in] master mode: NETAPI_SYS_MASTER or NETAPI_NO_MASTER
+ * @retval @ref NETAPI_T: handle to the instance or NULL on error
+ * @pre none
+ */
+NETAPI_T netapi_init(int master);
+
+
+/** @ingroup netapi_api_functions */
+/*
+* @brief API shutdowns a previously intialized NETAPI instance
+ *
+ * @details de-llocates global resources valid per system level common across all ARM cores
+ * or per thread based on "master" argument passed in at init time.
+ * @param[in] @ref NETAPI_T: handle to the instance
+ * @retval none
+ * @pre @ref netapi_init
+ */
+void netapi_shutdown(NETAPI_T p);
+
+/** @ingroup netapi_api_functions */
+/*
+* @brief API returns a @ref Pktlib_HeapIfTable to use when creating pktlib heaps
+ *
+ * @details Application will need a heapIfTable in order to create its own heaps. This
+ * function returns a table that can be used. The memory used for these heaps is
+ * special (alignment, must be contguous, must have a physical2virtual mapping that
+ * is known by NETAPI. Thus it must be completely managed by NETAPI.
+ * @param[in] none
+ * @retval @ref Pktlib_HeapIfTable pointer
+ * @pre @ref netapi_init
+ */
+Pktlib_HeapIfTable *netapi_getPktlibIfTable(void) ;
+
+/* utilities to see how much mem/descriptor space is remaining */
+int netapi_getBufmemRemainder(void);
+int netapi_getDescRemainder(void);
+
+/* utility to get default flow */
+static inline NETCP_CFG_FLOW_HANDLE_T netapi_getDefaultFlow(NETAPI_T p) {
+NETAPI_HANDLE_T *pp = (NETAPI_HANDLE_T *) p;
+return pp->def_flow;
+}
+
+/* utility to get default route */
+static inline NETCP_CFG_ROUTE_HANDLE_T netapi_getDefaultRoute(NETAPI_T p) {
+NETAPI_HANDLE_T *pp = (NETAPI_HANDLE_T *) p;
+return pp->def_route;}
+
+/* utility to set/get a cookie in the netapi handle */
+static inline void * netapi_getCookie(NETAPI_T p)
+{
+NETAPI_HANDLE_T *pp = (NETAPI_HANDLE_T *) p;
+return pp->cookie;
+}
+static inline void netapi_setCookie(NETAPI_T p, void * cookie)
+{
+NETAPI_HANDLE_T *pp = (NETAPI_HANDLE_T *) p;
+pp->cookie= cookie;
+}
+
+
+/** @ingroup netapi_api_functions */
+/*
+* @brief API is used to poll for NETCP configuration response messages.
+ *
+ * @details Application, if controlling the scheduler, will need to call this
+ * function periodically to check for NETCP configuration responses (eg
+ * statistics requests).
+ * @param[in] @ref NETAPI_T handle to NETAPI instance
+ * @retval none
+ * @pre @ref netapi_init
+ */
+void netapi_netcpPoll(NETAPI_T p);
+
+//heap registration for polling purposes
+int netapi_registerHeap(NETAPI_T p, Pktlib_HeapHandle h);
+int netapi_unregisterHeap(NETAPI_T p, Pktlib_HeapHandle h);
+void netapi_poll_heapGarbage(NETAPI_T p);
+
+#endif
diff --git a/ti/runtime/netapi/netapi_err.h b/ti/runtime/netapi/netapi_err.h
--- /dev/null
@@ -0,0 +1,96 @@
+/*******************************
+ * file: netapi_err.h
+ * purpose: netapi error codes
+ **************************************************************
+ * FILE: netapi.h
+ *
+ * DESCRIPTION: netapi Error Definitions for user space transport
+ * library
+ *
+ * REVISION HISTORY: rev 0.0.1
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ ******************************/
+
+#ifndef __NETAPI_ERR__
+#define __NETAPI_ERR__
+/**
+ * @defgroup NETAPI_RetValue NETAPI Return Codes
+ */
+/** @ingroup NETAPI_RetValue */
+
+/**
+ * @def NETAPI_ERR_OK
+ * No error
+ */
+#define NETAPI_ERR_OK 0
+/**
+ * @def NETAPI_ERR_NOMEM
+ * out of memory error
+ */
+#define NETAPI_ERR_NOMEM -1
+/**
+ * @def NETAPI_ERR_BAD_INPUT
+ * arguments or configuraiton is invalid
+ */
+#define NETAPI_ERR_BAD_INPUT -2
+/**
+ * @def NETAPI_ERR_QLLD
+ * QUEUE MANAGER Reports an error
+ */
+#define NETAPI_ERR_QLLD -3
+/**
+ * @def NETAPI_ERR_NOTFOUND
+ * the resource cannot be located
+ */
+#define NETAPI_ERR_NOTFOUND -4
+/**
+ * @def NETAPI_ERR_BUSY
+ * Temporarily out of resources or resource leak
+ */
+#define NETAPI_ERR_BUSY -5
+/**
+ * @def NETAPI_ERR_NWAL_ERR0
+ * NWAL subsytem reports error
+ */
+#define NETAPI_ERR_NWAL_ERR0 -6
+/**
+ * @def NETAPI_ERR_ALREADY_CANCELLED
+ * timer has already been cancelled
+ */
+#define NETAPI_ERR_ALREADY_CANCELLED -100
+/**
+ * @def NETAPI_ERR_NWAL_TX_ERR
+ * error trying to send to NWAL.
+ */
+#define NETAPI_ERR_NWAL_TX_ERR -65536
+#endif
diff --git a/ti/runtime/netapi/netapi_sched.h b/ti/runtime/netapi/netapi_sched.h
--- /dev/null
@@ -0,0 +1,135 @@
+/***********************************
+ * File: netapi_sched.h
+ * Purpose: netapi scheduler module
+ **************************************************************
+ * FILE: netapi_sched.h
+ *
+ * DESCRIPTION: netapi sample event scheduler header file for
+ * user space transport library
+ *
+ * REVISION HISTORY: rev 0.0.1
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ ***********************************/
+#ifndef __NETAPI_SCHED__
+#define __NETAPI_SCHED__
+#include "netapi.h"
+
+/****************************
+ **********CONTEXT**********
+ ****************************/
+struct NETAPI_SCHED_HANDLE_Tag;
+
+typedef void (*NETAPI_SCHED_CB)(struct NETAPI_SCHED_HANDLE_Tag *h);
+
+
+typedef struct NETAPI_SCHED_CONFIG_Tag
+{
+int valid_flags; //which is being configured
+#define NETAPI_SCHED_DURATION 0x1
+#define NETAPI_SCHED_POWER 0x2
+#define NETAPI_SCHED_FINE 0x4 //future
+#define NETAPI_SCHED_CBV 0x8 //callback
+
+/*----duration------*/
+uint64_t duration; //0=forever or #tics to run for
+#define NETAPI_SCHED_FOREVER 0L
+
+/*-----house callback-----*/
+NETAPI_SCHED_CB house_cb;
+
+uint32_t interval; // how many poll loop intervals after which to call the house keeping function
+
+
+/*------power control-------*/
+int power_control; //0= always on, >0 = duty cycle
+#define NETAPI_SCHED_POWER_ALWAYS_OFF 0 //drop to idle
+#define NETAPI_SCHED_POWER_ALWAYS_ON 100 //always runs, no drop to idle
+
+int idle_time; //in ticks
+
+/*-----fine control-----*/
+//future..
+
+} NETAPI_SCHED_CONFIG_T;
+
+
+/* the schedule context */
+typedef struct NETAPI_SCHED_HANDLE_Tag
+{
+ volatile int state; //0= shutdown, 1= shutting down, 2=active
+#define NETAPI_SCHED_STATE_SHUT 0
+#define NETAPI_SCHED_STATE_SHUTTING 1
+#define NETAPI_SCHED_STATE_ACTIVE 2
+ void * back; //pointer back to netapi handle
+ NETAPI_SCHED_CONFIG_T config;
+ uint64_t start; /* start time */
+ volatile int shutdown_reason;
+ volatile uint64_t shutdown_time;
+
+} NETAPI_SCHED_HANDLE_T;
+
+/* how to shut down */
+typedef struct NETAPI_SCHED_SHUTDOWN_Tag
+{
+int shutdown_type;
+#define NETAPI_SCHED_SHUTDOWN_NOW 0
+#define NETAPI_SCHED_SHUTDOWN_TO 1
+#define NETAPI_SCHED_SHUTDOWN_NEXT_IDLE 2
+int timeout; //ticks from now to close
+
+} NETAPI_SCHED_SHUTDOWN_T;
+
+/****************************
+ **************API **********
+ ****************************/
+
+/* open a scheduling contex */
+NETAPI_SCHED_HANDLE_T * netapi_schedOpen(NETAPI_T n, NETAPI_SCHED_CONFIG_T * p_config, int *p_err);
+
+/* re-configure a scheduling context */
+int netapi_schedControl(NETAPI_SCHED_HANDLE_T *s, NETAPI_SCHED_CONFIG_T *p_config, int *p_err);
+
+/* return codes for wait_for_events() */
+#define NETAPI_SCHED_RETURN_ERR 0 //unknown, err
+#define NETAPI_SCHED_RETURN_TO 1 // returned after timeout
+#define NETAPI_SCHED_RETURN_SHUTDOWN 2 //returned after shutdown
+
+/* main entry point. caller gives up control to scheduler */
+int netapi_schedWaitForEvents(NETAPI_SCHED_HANDLE_T *s, int * p_err);
+
+/* shutdown scheduler context */
+int netapi_schedShutdown(NETAPI_SCHED_HANDLE_T * s, NETAPI_SCHED_SHUTDOWN_T * p_close, int *p_err);
+
+static NETAPI_T netapi_schedGetNetapiHandle(NETAPI_SCHED_HANDLE_T *s)
+ { return (NETAPI_T)s->back;}
+#endif
diff --git a/ti/runtime/netapi/netapi_timer.h b/ti/runtime/netapi/netapi_timer.h
--- /dev/null
@@ -0,0 +1,145 @@
+/************************************************
+ *FILE: netapi_timer.h
+ *Purpose: netapi timer related functions
+ **************************************************************
+ * FILE: netapi_timer.h
+ *
+ * DESCRIPTION: netapi timer library header file for user space transport
+ * library
+ *
+ * REVISION HISTORY: rev 0.0.1
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ ***********************************************/
+#ifndef __NETAPI_TIMER__H
+#define __NETAPI_TIMER__H
+#include "netapi.h"
+
+extern volatile unsigned long * t64_virt_addr;
+extern unsigned int cpu_cycles_sec;
+
+//return clock ticks per second
+unsigned long t64_ticks_sec(void);
+#define netapi_getTicksPerSec t64_ticks_sec
+
+//return 64 bit timestamp
+static inline unsigned long long netapi_getTimestamp(void)
+{
+ volatile unsigned long long t1;
+ volatile unsigned long long t2;
+ unsigned long long val;
+ t1 = t64_virt_addr[0x10/4]; //lo
+ t2 = t64_virt_addr[0x14/4]; //hi
+ val = ((unsigned long long) t2) <<32 | t1;
+ return val;
+}
+
+/******************************************************/
+/*******************TIMER API***************************/
+/******************************************************/
+typedef void * NETAPI_TIMER_GROUP_HANDLE_T;
+typedef void * NETAPI_TIMER_T;
+typedef void * NETAPI_TIMER_LIST_T;
+typedef int NETAPI_TIMER_FILTER_T;
+#define NETAPI_TIMER_NA (void*) NULL
+#define NETAPI_TIMER_FILTER_GLOBAL 0x1
+#define NETAPI_TIMER_FILTER_LOCAL 0x2
+#define NETAPI_TIMER_FILTER_E2F 0x4
+#define NETAPI_TIMER_FILTER_E2C 0x8
+#define NETAPI_TIMER_FITLER_ALL 0xf
+
+//iterator on TIMER_LIST_T
+NETAPI_TIMER_T netapi_TimerGetFirst( NETAPI_TIMER_LIST_T list);
+NETAPI_TIMER_T netapi_TimerGetNext( NETAPI_TIMER_LIST_T list,NETAPI_TIMER_T prev);
+void * netapi_TimerGetCookie(NETAPI_TIMER_T timer);
+unsigned long long netapi_TimerGetTs(NETAPI_TIMER_T timer); //debug
+
+//timer callback
+typedef void (*NETAPI_TIMER_CB_T) (
+ NETAPI_TIMER_GROUP_HANDLE_T th,
+ int n_fired, //# timers fired
+ NETAPI_TIMER_LIST_T fired_list,
+ uint64_t currentTime);
+
+//create a timer group
+NETAPI_TIMER_GROUP_HANDLE_T netapi_TimerGroupCreate(
+ NETAPI_T netHandle, //netapi instance
+ char * name, //name of the timer block
+ NETAPI_TIMER_CB_T cb, //the callback function
+ int local, //1 if timers local to thread
+ int exp2cancel,//1 if expect to cancel
+ int timerTicksPerGroupTick, //resolution for this timer block, in timer ticks
+ int maxTimers, //max # of timer objects for this group
+ int *pErr);
+
+//open a [global] timer group
+NETAPI_TIMER_GROUP_HANDLE_T netapi_TimerGroupOpen(
+ NETAPI_T netHandle,
+ NETAPI_TIMER_CB_T cb,
+ int *pErr);
+
+//start an individual timer
+NETAPI_TIMER_T netapi_TimerGroupStartiTimer(
+ NETAPI_TIMER_GROUP_HANDLE_T th,
+ void * cookie,
+ uint64_t offs2fire, //offset in timerGroup ticks (eg msc)
+ int * pErr);
+
+//Cancel a timer
+void netapi_TimerGroupCancel(
+ NETAPI_TIMER_GROUP_HANDLE_T th,
+ NETAPI_TIMER_T timerId,
+ int *pErr);
+
+//close an opened timer group
+void netapi_TimerGroupClose(
+ NETAPI_TIMER_GROUP_HANDLE_T th,
+ int *pErr);
+
+//close an opened timer group
+void netapi_TimerGroupDelete(
+ NETAPI_TIMER_GROUP_HANDLE_T th,
+ int *pErr);
+
+//extract netapi handle from timer group handle
+NETAPI_T netap_TimerGroupGetNH( NETAPI_TIMER_GROUP_HANDLE_T th);
+
+//poll a specific timer group
+int netapi_TimerGroupPoll(NETAPI_TIMER_GROUP_HANDLE_T th, int maxTimers);
+
+//poll all timers
+int netapi_TimerGroupPollAll(NETAPI_T nh, NETAPI_TIMER_FILTER_T f, int maxTimers);
+
+/*****************END API*********************************/
+
+
+#endif
diff --git a/ti/runtime/netapi/netapi_tune.h b/ti/runtime/netapi/netapi_tune.h
--- /dev/null
@@ -0,0 +1,156 @@
+/**************************************************************
+ * FILE: netapi_tune.h
+ * Purpose: hold tunable parameters (build time)
+ **************************************************************
+ * FILE: netapi_tune.h.h
+ *
+ * DESCRIPTION: Tuneable (compile time) parameters for user space transport
+ * library
+ *
+ * REVISION HISTORY: rev 0.0.1
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ ****************************************************/
+#ifndef __NETAPI_TUNE__H
+#define __NETAPI_TUNE__H
+
+
+/**
+ * @defgroup NETAPI_TUNE NETAPI tunable parameters
+ */
+/** @ingroup NETAPI_TUNE */
+
+/**
+* @def NETAPI_ENABLE_SECURITY
+* (0) define this to enable securtiy. Note: libraries being use need to be built with SA enabled also!
+*/
+//#define NETAPI_ENABLE_SECURITY
+
+/**
+ * @def TUNE_NETAPI_NUM_CORES
+ * (0) How many cores (theads)
+ */
+#define TUNE_NETAPI_NUM_CORES 1
+
+/**
+ * @def TUNE_NETAPI_PERM_MEM_SZ
+ * (1) how much contiguous memory to grab. This is used for
+ * descriptors and buffers. Can't be bigger than MSMC (internal SOC memory area)
+ */
+#define TUNE_NETAPI_PERM_MEM_SZ (2*1024*1024)
+
+/**
+ * @def TUNE_NETAPI_MAX_PKTIO
+ * (2) how many GLOBAL pkt io channels
+ */
+#define TUNE_NETAPI_MAX_PKTIO 16
+
+//(2a) default TX channel name
+//(2b) default RX channel name
+
+
+/**
+ * @def TUNE_NETAPI_DEFAULT_BUFFER_SIZE
+ * (3) size of netapi default pktlib heap buffers
+ */
+#define TUNE_NETAPI_DEFAULT_BUFFER_SIZE 1600
+
+//(3a) default pkt heap name
+
+/**
+ * @def TUNE_NETAPI_DEFAULT_NUM_BUFFERS
+ *(4) number of netapi default pktlib heap buffers (and assoc descriptors)
+ */
+#define TUNE_NETAPI_DEFAULT_NUM_BUFFERS 200
+
+/*
+ * @def TUNE_NETAPI_DEFAULT_NUM_SOLO_DESCRIPTORS
+ * (5) number of netapi default pkt lib heap solo descriptors
+ */
+#define TUNE_NETAPI_DEFAULT_NUM_SOLO_DESCRIPTORS 100
+
+/**
+ * @def NETAPI_INCLUDE_SCHED
+ * (6) define this to include the scheduler component
+ */
+#define NETAPI_INCLUDE_SCHED
+
+//(7) # of QM descriptors (total)
+#define TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM 1024 /* 16384 is abs max */
+
+//(8) Region info
+#define TUNE_NETAPI_NUM_LOCAL_DESC 64
+
+/* at least as big as DEFAULT_NUM_SOLO+DEFAULT_NUM_BUFFERS but also a power of 2*/
+#define TUNE_NETAPI_NUM_GLOBAL_DESC 512
+#define TUNE_NETAPI_DESC_SIZE 128 //don't change!!
+
+//(9) Define to 1 for DEBUG MODE [where NETCP just loops pkts that tx back to rx]
+#define TUNE_NETAPI_NWAL_ENABLE_PASS_LOOPBACK 0 /*1*/
+
+
+//(10) NWAL (internal) config. Should not have to change
+#define TUNE_NETAPI_CONFIG_MAX_PA_TO_SA_DESC 16
+#define TUNE_NETAPI_CONFIG_MAX_SA_TO_PA_DESC 16
+#define TUNE_NETAPI_CONFIG_MAX_GLOB_DESC (TEST_CONFIG_MAX_PA_TO_SA_DESC + TEST_CONFIG_MAX_SA_TO_PA_DESC)
+#if 0
+#define TEST_CONFIG_GLOB_DESC_SIZE 128 /* todo:could be smaller */
+#define TEST_CONFIG_GLOB_BUF_SIZE 1500 /* MTU Size */
+#endif
+#define TUNE_NETAPI_MAX_NUM_MAC 2
+#define TUNE_NETAPI_MAX_NUM_IP 2
+#define TUNE_NETAPI_MAX_NUM_PORTS_PER_CORE 4 //udp/tcp ports -> for lUT2 )
+#define TUNE_NETAPI_MAX_NUM_PORTS (TUNE_NETAPI_MAX_NUM_PORTS_PER_CORE * (TUNE_NETAPI_NUM_CORES))
+
+#ifdef NETAPI_ENABLE_SECURITY
+#define TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS 2
+#else
+#define TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS 0
+#endif
+#define TUNE_NETAPI_MAX_NUM_L2_L3_HDRS 2
+#define TUNE_NETAPI_MAX_NUM_TRANS (TUNE_NETAPI_MAX_NUM_MAC + TUNE_NETAPI_MAX_NUM_IP + TUNE_NETAPI_MAX_NUM_PORTS + TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS)
+
+//(11) PA control buffer pool (internal)
+#define TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE 384
+#define TUNE_NETAPI_CONFIG_NUM_CTL_BUF 16
+
+//(12) PKTIO RECV BURST SIZE
+#define TUNE_NETAPI_MAX_BURST_RCV 32 //max #ok pkts to recv in one poll
+
+//(13) netcp interfaces
+#define TUNE_NETAPI_MAX_IP_PER_INTERFACE 2 //2 ip's per interface
+#define TUNE_NETAPI_MAX_INTERFACES 2 //2 interfaces
+
+//(14) timers
+#define TUNE_NETAPI_NUM_TIMER_CELLS 128 //# of hash bins in a timer group
+#define TUNE_NETAPI_NUM_GLOBAL_TIMERS 4 //# global timer blocks
+#endif
diff --git a/ti/runtime/netapi/netcp_cfg.h b/ti/runtime/netapi/netcp_cfg.h
--- /dev/null
@@ -0,0 +1,232 @@
+/***************************************************
+ * File: netcp_cfg.h
+ * Purpose: netcp config API
+ **************************************************************
+ * FILE: netcp_cfg.h
+ *
+ * DESCRIPTION: netapi NETCP configuration API header file
+ * for user space transport library
+ *
+ * REVISION HISTORY: rev 0.0.1
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ ***************************************************/
+
+#ifndef __NETCP_CFG__H
+#define __NETCP_CFG__H
+
+#include "netapi.h"
+#include "ti/drv/pa/pa.h"
+#include "ti/runtime/pktlib/pktlib.h"
+
+#define CONFIG_MAX_L2_HANDLES 10
+#define CONFIG_MAX_L3_HANDLES 20
+#define CONFIG_MAX_L4_HANDLES 40
+
+//NETCP FLOW
+typedef struct NETCP_CFG_FLOW_Tag
+{
+ int flowid;
+} NETCP_CFG_FLOW_T;
+typedef void * NETCP_CFG_FLOW_HANDLE_T;
+
+
+//NETCP ROUTE
+typedef struct NETCP_CFG_ROUTE_Tag
+{
+ NETCP_CFG_FLOW_HANDLE_T p_flow;
+ PKTIO_HANDLE_T * p_dest_q;
+ int nextAction;
+} NETCP_CFG_ROUTE_T;
+typedef void * NETCP_CFG_ROUTE_HANDLE_T;
+
+/*--------------flow management--------*/
+NETCP_CFG_FLOW_HANDLE_T netcp_cfgAddFlow(NETAPI_T ,
+ int n,
+ Pktlib_HeapHandle handles[],
+ int * err );
+void netcp_cfgDelFlow(NETAPI_T , NETCP_CFG_FLOW_HANDLE_T , int * err);
+
+/*------------Routes------------------*/
+NETCP_CFG_ROUTE_HANDLE_T netcp_cfgAddRoute(NETAPI_T ,int nh,
+ Pktlib_HeapHandle heaps[],
+ int *err );
+void netcp_cfgDelRoute(NETAPI_T , NETCP_CFG_ROUTE_HANDLE_T, int *err );
+
+/*-----------Actions----------*/
+#define NETCP_CFG_ACTION_DISCARD 0
+#define NETCP_CFG_ACTION_CONTINUE 1 //pass packet on to next classifier
+#define NETCP_CFG_ACTION_TO_SW 2
+
+/*------------L2----------------------*/
+typedef void * NETCP_CFG_MACIF_T;
+typedef void * NETCP_CFG_VLAN_T;
+typedef void * NETCP_CFG_IP_T;
+
+/* del mac i/f */
+void netcp_cfgDelMac(NETAPI_T h,int iface_no, int *err);
+void netcp_cfgDelIp(NETAPI_T h, int iface_no, nwal_IpType ipType,
+ nwalIpAddr_t * ip_addr,
+ nwalIpOpt_t * ip_qualifiers, int *err);
+
+
+/*****************************************************************
+ * Create a MAC interface
+ ****************************************************************/
+/*
+* @brief API Creates a MAC interface
+ *
+ * @details This api is used to create a MAC interface.
+ * Once it is created, the MAC interface can be used to receive packets. The API
+ * adds a rule to the NETCP 1st level lookup tables to route all packets with destination
+ * MAC matching supplied argument and not matching any other lookup entry (see @ref netcp_cfgAddIp) to
+ * the supplied route, @ref NETCP_CFG_ROUTE_T, (or default route).
+ * Packets arriving that match this rule are identified in meta data with Appid= NETAPI_NETCP_MATCH_GENERIC_MAC
+ * Note: The internal SOC switch must be "taught" that this mac
+ * address is present by transmitting a packet with destination mac = this interface mac address.
+ * @param[in] @ref NETAPI_T: NETAPI instance
+ * @param[in] char *: pointer to 6 byte MAC address for interface
+ * @param[in] int : interface number (0,1,..)
+ * @param[in] int : switch port (0 don't care, 1 switch port 1, 1 switch port 2) [only 0 supported]
+ * @param[in] @ref NETCP_CFG_ROUTE_HANDLE_T : [future] handle of a created route or NULL to use internal default route
+ * @oaram[in] @ref NETCP_CFG_VLAN_T : [future[ vlan configuration . Set to NULL
+ * @param[in] int : [future] interface state (0=down, 1= up)
+ * @param[out] int * err: pointer to error return
+ * @retval @ref NETCP_CFG_MACIF_T : returned handle for interface.
+ * @pre @ref netapi_init
+ */
+NETCP_CFG_MACIF_T netcp_cfgCreateMacInterface(
+ NETAPI_T h, //
+ uint8_t *p_mac, //mac address associated with interface
+ int iface_no, //0,1, ..
+ int switch_port,//0=don't care, 1=switch port 1, 2=switch port 2 , ..
+ NETCP_CFG_ROUTE_HANDLE_T route, //NULL to use default
+ NETCP_CFG_VLAN_T vlan, //future
+ int state, //0=down, 1=up //FUTURE
+ int * err
+ );
+
+/*****************************************************************
+ * Add IP address/qualifier to MAC interface
+ ****************************************************************/
+/*
+* @brief API attaches an IP adderess and qualifier to a MAC interface
+ *
+ * @details This api is used to add an IP address to a MAC interface along
+ * with optional IP qualifier. A route, @ref NETCP_CFG_ROUTE_HANDLE_T,or NULL for default
+ * may be specified to indicate where to send packets matching the MAC interface MAC address, the
+ * supplied IP address and any qualifier. This API adds a rule to the NETCP level 1 lookup tables
+ * Packets arriving that match this rule are identified in meta data with Appid= NETAPI_NETCP_MATCH_GENERIC_IP
+ * Note: An IP address must be attached to enable NETCP Recevie Checksum offload feature
+ * @param[in] @ref NETAPI_T: NETAPI instance
+ * @param[in] int : interface number (0,1,..)
+ * @param[in] @ref nwal_IpType : type of IP address (V4 for V6)
+ * @oaram[in] @ref nwalIpAddr_t : ip_address
+ * @param[in] @ref nwalIpOpt_t : ip_qualifiers (all 0 for no qualifiers). This can be used to apply special handling for
+ * diffserv category for example
+ * @param[in] @ref NETCP_CFG_ROUTE_HANDLE_T : [future] handle of a created route or NULL to use internal default route
+ * @param[out] int * err: pointer to error return
+ * @retval @ref NETCP_CFG_IP_T : returned handle for attched rule.
+ * @pre @ref netapi_init , @ref netcp_cfgAddMac
+ */
+NETCP_CFG_IP_T netcp_AddIp(
+ NETAPI_T h,
+ int iface_no,
+ nwal_IpType ipType,
+ nwalIpAddr_t * ip_addr,
+ nwalIpOpt_t * ip_qualifiers,
+ NETCP_CFG_ROUTE_HANDLE_T route, //NULL for default
+ int * err
+ );
+
+/*------------------classification [FUTURE]-------------------*/
+typedef void *NETCP_CFG_CLASS_T;
+
+//add classifier
+typedef struct NETCP_CFG_CLASSIFIER_Tag
+{
+ //tbd a classisfier
+
+} NETCP_CFG_CLASSIFIER_T;
+
+NETCP_CFG_CLASS_T netcp_cfgAddClass(NETAPI_T h,
+ NETCP_CFG_CLASSIFIER_T *p_class,
+ NETCP_CFG_ROUTE_HANDLE_T p_route,
+ int action, int * err);
+//del classifier
+void netcp_cfgDelClass(NETAPI_T h,
+ NETCP_CFG_CLASS_T p_class,
+ int *err);
+
+
+
+/***************************************************************************
+********************************STATS**************************************
+**************************************************************************/
+
+//stats CB
+typedef void (*NETCP_CFG_STATS_CB)( NETAPI_T h, paSysStats_t* pPaStats);
+
+
+//stats request
+/*
+ * @brief API request statistics from NETCP
+ *
+ * @details This api is used to request a statistics from NETCP. This will generate a stats request
+ * command to NETCP. Sometime later, the statistics result will arrive and will be passed to
+ * the caller via the asynchronus callback @ref NETCP_CFG_STATS_CB that is registered in this call.
+ * Note: to receive the stats callback, the @ref netapi_netcpPoll funcition must be called
+ * @param[in] @ref NETAPI_T: NETAPI instance
+ * @param[in] @ref NETCP_CFG_STATS_CB : the function to call with the resulting statistics block
+ * @param[in] int : clear the stats in NETCP after the report (0=no, 1=yes)
+ * @param[out] int * err: pointer to error return
+ * @retval none
+ * @pre @ref netapi_init
+ */
+void netcp_cfgReqStats(NETAPI_T h, //NEAPI instance
+ NETCP_CFG_STATS_CB c, //stats report callback function
+ int doClear, //0: don't clear, 1 clear
+ int *err);
+
+/******************************************************************/
+/***********************APP ids for rx meta data********************/
+/******************************************************************/
+
+// NWAL "AP ids"
+#define NETAPI_NETCP_MATCH_GENERIC_MAC 0x10000000 //lower byte==interface
+#define NETAPI_NETCP_MATCH_GENERIC_IP 0x20000000 //lower byte==interface
+#define NETAPI_NETCP_MATCH_CLASS 0x80000000 //or' in classifier #
+
+
+
+#endif
+
diff --git a/ti/runtime/netapi/netsync.h b/ti/runtime/netapi/netsync.h
--- /dev/null
@@ -0,0 +1,288 @@
+/*********************************************
+ * File: netsync.h
+ * Purpose: NETAPI Synchronization primitives
+ **************************************************************
+ * FILE: netsync.h
+ *
+ * DESCRIPTION: netapi synch utilities header file for user space transport
+ * library
+ *
+ * REVISION HISTORY: rev 0.0.1
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ **********************************************/
+#ifndef NETAPI_SYNC_H
+#define NETAPI_SYNCH_H
+
+/*--------------------------*/
+/*----------spinlock--------*/
+/*--------------------------*/
+
+typedef int NETAPI_SPINLOCK_T;
+
+#define NETAPI_SPINLOCK_LOCKVAL 1
+#define NETAPI_SPINLOCK_UNLOCKVAL 0 //never change!!
+#define NETAPI_SPINLOCK_UNLOCKED_INITIALIZER (NETAPI_SPINLOCK_UNLOCKVAL)
+
+/* init a lock */
+static inline void netapi_spinlock_init (NETAPI_SPINLOCK_T * val) {*val=NETAPI_SPINLOCK_UNLOCKVAL;}
+
+/* lock a spinlock */
+static inline void netapi_spinlock_lock(NETAPI_SPINLOCK_T * val)
+{
+while(__sync_lock_test_and_set(val, NETAPI_SPINLOCK_LOCKVAL))
+ {
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ }
+}
+
+/* try to get lock 1 time. Return 1 if ok, 0 if un-successful */
+static inline int netapi_spinlock_try_lock( NETAPI_SPINLOCK_T* val)
+{
+ int i=0;
+ if (__sync_lock_test_and_set(val, NETAPI_SPINLOCK_LOCKVAL)) return 0;
+ return 1;
+}
+
+
+/* unlock a spinlock. */
+static inline void netapi_spinlock_unlock(NETAPI_SPINLOCK_T * val)
+{
+ __sync_lock_release(val);
+}
+
+/* poll a lock, return 0 if unlocked, NETAPI_SPINLOCK_LOCKVAL if locked */
+static inline int netapi_spinlock_is_locked(NETAPI_SPINLOCK_T * val)
+{
+ return *val;
+}
+
+/*--------------------------*/
+/*----------rwlock--------*/
+/*--------------------------*/
+
+/* a rw lock strucuture */
+typedef struct RWLOCK_Tag
+{
+ NETAPI_SPINLOCK_T lock_outer; //lock this structure. very short duration lock
+ NETAPI_SPINLOCK_T lock_w; //real write lock
+ unsigned long n_readers; /* # readers active */
+} NETAPI_RWLOCK_T;
+
+//initialize a rw lock
+static inline void netapi_rwlock_init(NETAPI_RWLOCK_T * p_lock)
+{
+ netapi_spinlock_init(&p_lock->lock_outer);
+ netapi_spinlock_init(&p_lock->lock_w);
+ p_lock->n_readers=0;
+}
+
+// lock a write lock.
+static inline void netapi_rwlock_write_lock(NETAPI_RWLOCK_T * p_lock)
+{
+ int ret;
+ while(1)
+ {
+ netapi_spinlock_lock(&p_lock->lock_outer); //get outer lock - now nothing can change
+ // check for 0 readers
+ if(p_lock->n_readers)
+ {
+ netapi_spinlock_unlock(&p_lock->lock_outer); //give up outer & spin
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ continue;
+ }
+
+ //ok, no readers. see if we can get writer lock
+ ret=netapi_spinlock_try_lock(&p_lock->lock_w); //try get writer lock 1 time
+ if(!ret)
+ {
+ netapi_spinlock_unlock(&p_lock->lock_outer); //give up outer & spin
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ continue; /* try again */
+ }
+ netapi_spinlock_unlock(&p_lock->lock_outer); //got write lock=> no other writer, no readers! Keep the writelock but unlock the outer.
+ return;
+ }
+}
+
+//unlock a writer part of rwlock */
+static inline void netapi_rwlock_write_unlock(NETAPI_RWLOCK_T * p_lock)
+{
+ netapi_spinlock_unlock(&p_lock->lock_w);
+}
+
+//grab a read lock
+//=> can be other readers, but no writer
+static inline void netapi_rwlock_read_lock(NETAPI_RWLOCK_T * p_lock)
+{
+int ret;
+
+while(1)
+{
+ /*1st grab outer lock. once we have it, nothing can change */
+ netapi_spinlock_lock(&p_lock->lock_outer);
+
+ /* see if there is a writer */
+ ret= netapi_spinlock_is_locked(&p_lock->lock_w);
+
+ //there is a writer
+ if (ret)
+ {
+ netapi_spinlock_unlock(&p_lock->lock_outer); //give up outer and spin
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ continue;
+ }
+
+ /* there is no writer so we can read!*/
+ p_lock->n_readers+=1;
+
+ /* mb ? */
+ __sync_synchronize(); //make sure every core sees that n_readers has changed
+
+ /* now give back the outer lock */
+ netapi_spinlock_unlock(&p_lock->lock_outer);
+ return;
+}
+}
+
+//rw_lock reader unlock
+static inline void netapi_rwlock_read_unlock(NETAPI_RWLOCK_T * p_lock)
+{
+ //grab outer
+ netapi_spinlock_lock(&p_lock->lock_outer);
+
+ //decrement # of readers. Make sure all cores see update
+ p_lock->n_readers--;
+ __sync_synchronize();
+ //TBD: need to check for <0?
+
+ /* give up the outer */
+ netapi_spinlock_unlock(&p_lock->lock_outer);
+}
+
+/*--------------------------*/
+/*----------atomic32--------*/
+/*--------------------------*/
+typedef struct NETAPI_ATOMIC32_tag
+{
+ long val;
+} NETAPI_ATOMIC32_T;
+
+#define NETAPI_ATOMIC_INIT32(x) {x}
+static inline int netapi_atomic_read32(NETAPI_ATOMIC32_T *p) {return p->val;}
+
+static inline void netapi_atomic_set32(NETAPI_ATOMIC32_T *p, int val)
+{__sync_fetch_and_add(&p->val,0); } //todo crude, why not p->val=val?
+
+static inline void netapi_atomic_add32(NETAPI_ATOMIC32_T *p, int val)
+{__sync_fetch_and_add(&p->val,val);}
+
+static inline void netapi_atomic_sub32(NETAPI_ATOMIC32_T *p, int val)
+{__sync_fetch_and_sub(&p->val,val);}
+
+#define NETAPI_atomic_inc32(p) netapi_atomic_add32(p,1);
+#define NETAPI_atomic_dec32(p) netapi_atomic_sub32(p,1);
+
+static inline int netapi_atomic_add_return32(NETAPI_ATOMIC32_T *p, int val)
+{return __sync_add_and_fetch(&p->val,val);}
+
+static inline int netapi_atomic_sub_return32(NETAPI_ATOMIC32_T *p, int val)
+{return __sync_sub_and_fetch(&p->val,val);}
+
+static inline int netapi_atomic_inc_and_test32(NETAPI_ATOMIC32_T *p)
+{return __sync_add_and_fetch(&p->val,1);}
+
+static inline int netapi_atomic_dec_and_test32(NETAPI_ATOMIC32_T *p)
+{return !__sync_sub_and_fetch(&p->val,1);}
+
+static inline int netapi_atomic_test_and_set32(NETAPI_ATOMIC32_T *p)
+{return (! _sync_lock_test_and_set(p, 1));}
+
+#define netapi_atomic_clear32(p) netapi_atomic_set32(p,0);
+
+/*--------------------------*/
+/*----------atomic64--------*/
+/*--------------------------*/
+typedef struct NETAPI_ATOMIC64_Tag
+{
+ NETAPI_SPINLOCK_T lock;
+ long long val;
+} NETAPI_ATOMIC64_T;
+
+#define NETAPI_ATOMIC_INIT64(x) {NETAPI_SPINLOCK_UNLOCKED_INITIALIZER,x}
+
+static inline long long netapi_atomic_read64(NETAPI_ATOMIC64_T *p)
+{
+long long latch_val;
+netapi_spinlock_lock(&p->lock); //acquire lock
+latch_val = p->val;
+netapi_spinlock_unlock(&p->lock); //free lock
+return latch_val;
+}
+
+static inline void netapi_atomic_set64(NETAPI_ATOMIC64_T *p,long long val)
+{
+netapi_spinlock_lock(&p->lock); //acquire lock
+p->val = val;
+//__sync_synchronize(); //todo: may not need as unlock will do this also probably
+netapi_spinlock_unlock(&p->lock); //free lock
+}
+
+static inline void netapi_atomic_add64(NETAPI_ATOMIC64_T *p, long long val)
+{
+netapi_spinlock_lock(&p->lock); //acquire lock
+p->val += val;
+//__sync_synchronize(); //todo: may not need as unlock will do this also probably
+netapi_spinlock_unlock(&p->lock); //free lock
+}
+
+/*******************************************************
+ ****************memory barrier************************
+******************************************************/
+static inline void netapi_mb(){__sync_synchronize();}
+static inline void netapi_rmb(){__sync_synchronize();}
+static inline void netapi_wmb(){__sync_synchronize();}
+
+
+#endif
diff --git a/ti/runtime/netapi/pktio.h b/ti/runtime/netapi/pktio.h
--- /dev/null
@@ -0,0 +1,294 @@
+/*********************************
+ *FILE: pktio.h
+ *PURPOSE: pktio library header
+ **************************************************************
+ * FILE: pktio.h
+ *
+ * DESCRIPTION: pktio module main header file for user space transport
+ * library
+ *
+ * REVISION HISTORY: rev 0.0.1
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ ********************************/
+#ifndef __PKTIO__H
+#define __PKTIO__H
+#include "netapi.h"
+#include "ti/runtime/pktlib/pktlib.h"
+#include "ti/drv/nwal/nwal.h"
+#include "netapi_err.h"
+
+/*--------------------defines-----------------------*/
+#define PKTIO_NOMEM NETAPI_ERR_NOMEM
+#define NETCP_TX "NETCP_TX"
+#define NETCP_RX "NETCP_RX"
+#define PKTIO_MAX_NAME 19
+
+/*--------------------data structures----------------*/
+typedef struct PKTIO_METADATA_Tag
+{
+ int flags1;
+#define PKTIO_META_RX 0x01
+#define PKTIO_META_TX 0x02
+
+ union
+ {
+ nwalRxPktInfo_t * rx_meta;
+ nwalTxPktInfo_t * tx_meta;
+ } u;
+} PKTIO_METADATA_T;
+
+/* the callback function */
+struct PKTIO_HANDLE_tag;
+
+#define PKTIO_MAX_RECV (TUNE_NETAPI_MAX_BURST_RCV)
+typedef void (*PKTIO_CB)(struct PKTIO_HANDLE_tag * channel, Ti_Pkt* p_recv[],
+ PKTIO_METADATA_T p_meta[], int n_pkts,
+ uint64_t ts );
+
+/** channel configuration */
+#define PKTIO_NA 0
+typedef struct PKTIO_CFG_Tag
+{
+#define PKTIO_R 0x1
+#define PKTIO_W 0x2
+#define PKTIO_RW (PKTIO_R | PKTIO_W)
+int flags1;
+
+#define PKTIO_LOCAL 0x2
+#define PKTIO_GLOBAL 0x1
+#define PKTIO_PKT 0x4 //define this if this q is for NETCP RX
+int flags2;
+
+//for create
+#define PKTIO_Q_ANY -1
+int qnum;
+
+//for poll
+int max_n;
+}PKTIO_CFG_T;
+
+struct NETAPI_tag;
+
+/* a pktio channel .. */
+
+typedef struct PKTIO_HANDLE_Tag
+{
+#define PKTIO_INUSE 0xfeedfeed
+ int inuse;
+ int use_nwal; /* true if this is managed by nwal */
+#define PKTIO_4_IPC 0
+#define PKTIO_4_ADJ_RX 1
+#define PKTIO_DEF_RX 2
+ struct NETAPI_tag * back; /* back handle */
+ void * nwalInstanceHandle; /* save here for conveninece */
+ PKTIO_CB cb; /* callback for channel */
+ PKTIO_CFG_T cfg; /* configuration */
+ Qmss_QueueHnd q; /* the associated queue handle */
+ Qmss_Queue qInfo; /* and its qm#/q# */
+ int max_n; /* max # of pkts to read in one poll */
+ void * cookie; /* app specific */
+ char name[PKTIO_MAX_NAME+1];
+} PKTIO_HANDLE_T;
+
+
+
+typedef struct PKTIO_CONTROL_Tag
+{
+#define CLEAR 0x1 //clear out the channel
+#define DIVERT 0x2 //divert, (to dest channel)
+ int op;
+ PKTIO_HANDLE_T *dest;
+} PKTIO_CONTROL_T;
+
+
+//polling control
+typedef struct PKTIO_POLL_Tag
+{
+/* future */
+} PKTIO_POLL_T;
+
+/*---------------------------------------------------*/
+/*-------------------------API-----------------------*/
+/*---------------------------------------------------*/
+
+/*
+* @brief API creates a NETAPI channel
+ *
+ * @details This assigns global resources to a NETAPI pktio channel.
+ * Once created, the channel can be used to send and/or receive
+ * a TI @ref Ti_Pkt. This can be used for communication with the
+ * the Network co-processor (NETCP) or for internal inter-processor
+ * communication. The channel is saved under the assigned name
+ * and can be opened by other netapi threads instances.
+ * @param[in] @ref NETAPI_T: handle to the instance
+ * @param[in] char * name: a pointer to the char string name for channel
+ * @param[in] @ref PKTIO_CB : callback to be issued on packet receive
+ * @param[in] @ref PKTIO_CFG_T: pointer to channel configuration
+ * @param[out] int * err: pointer to error return
+ * @retval @ref PKTIO_HANDLE_T: handle to the pktio instance or NULL on error
+ * @pre @ref netapi_init
+ */
+PKTIO_HANDLE_T * pktio_create(NETAPI_T netapi_handle, /* netapi instance */
+ char * name, /* name of the channel */
+ PKTIO_CB cb, /* receive callback */
+ PKTIO_CFG_T * p_cfg, /* ptr to config*/
+ int * err);
+
+/*
+* @brief API opens an existing NETAPI channel
+ *
+ * @details This opens an NETAPI pktio channel for use. The channel
+ * must have already been created via @ref pktio_create or may have
+ * been created internally during the netapi intialization.
+ * Once opened, the channel can be used to send and/or receive
+ * a TI @ref Ti_Pkt. This can be used for communication with the
+ * the Network co-processor (NETCP) or for internal inter-processor
+ * communication.
+ *
+ * @param[in] @ref NETAPI_T: handle to the instance
+ * @param[in] char * name: a pointer to the char string name for channel
+ * @param[in] @ref PKTIO_CB : callback to be issued on packet receive
+ * @param[in] @ref PKTIO_CFG_T: pointer to channel configuration
+ * @param[out] int * err: pointer to error return
+ * @retval @ref PKTIO_HANDLE_T: handle to the pktio instance or NULL on error
+ * @pre @ref netapi_init , @ref pktio_create
+ */
+PKTIO_HANDLE_T * pktio_open(NETAPI_T netapi_handle, /* netapi instance */
+ char *name, /* name of channel to open */
+ PKTIO_CB cb, /* receive callback */
+ PKTIO_CFG_T *p_cfg, /* channel configuration */
+ int * err);
+
+/* future: control the channel */
+void pktio_control(PKTIO_HANDLE_T * channel, //handle from open or create
+ PKTIO_CB cb, //change the callback
+ PKTIO_CFG_T * p_cfg,//optional
+ PKTIO_CONTROL_T *p_control,//optional
+ int *err);
+
+/* future: close or delete a pktio channel */
+void pktio_close(PKTIO_HANDLE_T * channel, int * err);
+void pktio_delete(PKTIO_HANDLE_T * channel, int * err);
+
+/*
+* @brief API sends data to a pktio channel
+ *
+ * @details This sends a @ref Ti_Pkt and associated meta data,
+ * @ref PKTIO_METADATA_T to a channel. The channel
+ * must have already been created via @ref pktio_create or opened
+ * via @ref pktio_open. It may have
+ * been created internally during the netapi intialization.
+ * @param[in] @ref PKTIO_HANDLE_T: handle to the channel
+ * @param[in] @ref Ti_Pkt*: pointer to the packet to send
+ * @param[in] @ref PKTIO_METADATA_T: pointer to meta data associated with packet
+ * @param[out] int * err: pointer to error return
+ * @retval int npkts: 1 if packet sent, 0 if error
+ * @pre @ref netapi_init, @ref pktio_create, @ref pktio_open
+ */
+int pktio_send(PKTIO_HANDLE_T * channel, /* the channel */
+ Ti_Pkt *pkt, /* pointer to packet */
+ PKTIO_METADATA_T *m, /* pointer to meta data */
+ int * err);
+
+/*
+* @brief API sends data to a pktio channel
+ *
+ * @details This sends an array of @ref Ti_Pkt and associated meta data,
+ * @ref PKTIO_METADATA_T to a channel. The channel
+ * must have already been created via @ref pktio_create or opened
+ * via @ref pktio_open. It may have
+ * been created internally during the netapi intialization.
+ * @param[in] @ref PKTIO_HANDLE_T: handle to the channel
+ * @param[in] @ref Ti_Pkt*: pointer to the packet to send
+ * @param[in] @ref PKTIO_METADATA_T: pointer to meta data associated with packet
+ * @oaran[in[ int np: the number of packets in list to send
+ * @param[out] int * err: pointer to error return
+ * @retval int npkts: number of packets sent, 0 if error
+ * @pre @ref netapi_init, @ref pktio_create, @ref pktio_open
+ */
+int pktio_sendMulti(PKTIO_HANDLE_T *channel, /* the channel handle */
+ Ti_Pkt * pkt[], /* array of packets to send */
+ PKTIO_METADATA_T * m[], /* meta data array */
+ int np, /* number of packets to send */
+ int * err);
+
+/***********************************/
+/************* polling **************/
+/***********************************/
+
+/*
+* @brief API polls a pkto channel for received packets
+ *
+ * @details This api polls a pktio channel. Any pending data in the channel is
+ * passed to the @ref PKTIO_CB registered when the channel was
+ * created or opened. The channel must
+ * have already been created via @ref pktio_create or opened
+ * via @ref pktio_open. It may have
+ * been created internally during the netapi intialization.
+ * @param[in] @ref PKTIO_HANDLE_T: handle to the channel
+ * @param[in] @ref PKTIO_POLL_T *: pointer to pktio poll configuration
+ * @param[out] int * err: pointer to error return
+ * @retval int npkts: number of packets received by poll
+ * @pre @ref netapi_init, @ref pktio_create, @ref pktio_open
+ */
+int pktio_poll(PKTIO_HANDLE_T * handle, //handle to pktio
+ PKTIO_POLL_T * p_poll_cfg, //polling configuration
+ int * err);
+
+/*
+* @brief API polls all pkto channels associarted with @ref NETAPI_T instance
+ * for received packets
+ *
+ * @details This api polls all pktio channels attached to an instance.
+ * Any pending data in these channels are
+ * passed to the @ref PKTIO_CB registered when the channel was
+ * created or opened. The channels must
+ * have already been created via @ref pktio_create or opened
+ * via @ref pktio_open. They may have
+ * been created internally during the netapi intialization.
+ * @param[in] @ref NETAPI_T: handle of the NETAPI instance
+ * @param[in] @ref PKTIO_POLL_T *: pointer to pktio poll configuration
+ * @param[out] int * err: pointer to error return
+ * @retval int npkts: number of packets received by poll
+ * @pre @ref netapi_init, @ref pktio_create, @ref pktio_open
+ */
+int pktio_pollAll(NETAPI_T handle, PKTIO_POLL_T * p_poll_cfg, int *err);
+
+/*----------------- utilities------------------ */
+/* update max_n for poll */
+#define pktio_set_max_n(handle,max_n) (handle)->max_n=max_n;
+#define pktio_get_netapi_handle(handle) (handle)->back
+#define pktio_set_cookie(handle, cookie) (handle)->cookie = cookie
+#define pktio_get_cookie(handle) (handle)->cookie
+
+#endif
diff --git a/ti/runtime/netapi/src/netapi.c b/ti/runtime/netapi/src/netapi.c
--- /dev/null
@@ -0,0 +1,385 @@
+/*******************************
+ * FILE: netapi.c
+ * Purpose: implementation of netapi startup/shutdown
+ **************************************************************
+ * FILE: netapi.c
+ *
+ * DESCRIPTION: netapi main source file for user space transport
+ * library
+ *
+ * REVISION HISTORY: rev 0.0.1
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ * *****************************/
+#include "netapi.h"
+
+typedef struct PRESET_Tag
+{
+#define KMAXQ 10
+ int kqinuse[KMAXQ];
+ //more..
+} PRESET_T;
+
+/*------------internal prototypes---------------*/
+static uint8_t* netapiSharedMemoryMalloc(uint32_t size);
+static void netapiSharedMemoryFree(uint8_t* ptr);
+static int system_init(NETAPI_HANDLE_T *);
+static void get_presets(PRESET_T * p_preset);
+static void zapQ(int queueNum);
+static void netapi_cleanup_at_start(void);
+
+
+/*------------globals-----------------*/
+#define NUM_HOST_DESC (TUNE_NETAPI_NUM_LOCAL_DESC)
+#define SIZE_LOCAL_DESC (TUNE_NETAPI_DESC_SIZE)
+#define NUM_SHARED_DESC (TUNE_NETAPI_NUM_GLOBAL_DESC)
+#define SIZE_SHARED_DESC (TUNE_NETAPI_DESC_SIZE)
+
+#define CONFIG_BUFSIZE_PA_INST 256
+#define CONFIG_BUFSIZE_L2_TABLE 1000
+#define CONFIG_BUFSIZE_L3_TABLE 4000
+
+static Pktlib_HeapIfTable netapi_pktlib_ifTable;
+static NETAPI_GLOBAL_T netapi_global;
+NETAPI_GLOBAL_T * netapi_get_global(){ return &netapi_global;}
+
+/* utility API for NETAPI user to get pktlib if table to use if he creates his own heap */
+Pktlib_HeapIfTable *netapi_getPktlibIfTable(void) {return &netapi_pktlib_ifTable;}
+
+
+/*-------------------------------------
+ * initialize NETAPI instance
+ *-------------------------------------*/
+NETAPI_T netapi_init(int master)
+{
+ int i;
+ int err;
+ NETAPI_HANDLE_T * p = (NETAPI_HANDLE_T *) calloc(1,sizeof(NETAPI_HANDLE_T));
+ if (!p) return NULL;
+ p->master = master;
+
+ /* create space for our local pktios */
+ for(i=0;i<NETAPI_MAX_PKTIO; i++)
+ {
+ p->pktios[i] = calloc(1,sizeof(PKTIO_HANDLE_T));
+ if (!p->pktios[i]) return NULL;
+ }
+
+#ifdef NETAPI_INCLUDE_SCHED
+ /* create space for scheduler */
+ p->p_sched = calloc(1,sizeof(NETAPI_SCHED_HANDLE_T));
+#endif
+
+
+ /* global stuff (if master) */
+ if (master==NETAPI_SYS_MASTER)
+ {
+ for(i=0;i<NETAPI_MAX_PKTIO;i++)
+ {
+ netapi_global.pktios[i].qn.qNum=-1;
+ netapi_global.pktios[i].name[0]='\0';
+ }
+ }
+ //this goes to shared memory eventually
+ p->global = (void *) &netapi_global;
+
+
+ /* system init */
+ if(master==NETAPI_SYS_MASTER)
+ {
+ err = system_init(p);
+ if (err<0)
+ {
+ //todo: cleanup
+ return NULL;
+ }
+ /* create pktio channels for tx,rx */
+ }
+ else
+ {
+ /*todo init for non-system cores/threads */
+ /* qm_start, */
+ /* attach to heaps */
+ /* nwal_start */
+ }
+
+ return (NETAPI_T) p;
+}
+
+/*-------------------------------
+ * Shut down netapi instance
+ *-------------------------------*/
+void netapi_shutdown(NETAPI_T h)
+{
+ NETAPI_HANDLE_T * p = (NETAPI_HANDLE_T *) h;
+ if (!p) return;
+
+ printf(">netapi: shutdown not fully implemented\n");
+ if (p->master)
+ {
+ /* close heap */
+ /* close queues */
+ netapi_cleanup_at_start();
+ /* close pa */
+ }
+ free(p);
+ return;
+}
+
+//exception crash
+void netapi_err_teardown() { netapi_cleanup_at_start(); exit(-99); }
+
+/*-------------------utilities-------------------*/
+static uint8_t* netapiSharedMemoryMalloc(uint32_t size)
+{
+return (uint8_t *)netapi_VM_memAlloc(size, 128);
+}
+
+static void netapiSharedMemoryFree(uint8_t* ptr)
+{
+ /* Do Nothing. */
+ printf("!!netapi>> Unexpected. need to provide a free () for some reason!! \n");
+ return;
+}
+
+// initialization
+static int system_init(NETAPI_HANDLE_T * handle)
+{
+ int32_t result;
+ Pktlib_HeapHandle sharedHeapHandle;
+ Pktlib_HeapHandle controlHeapHandle;
+
+ /* initialize all the memory we are going to use
+ - chunk for buffers, descriptors
+ - memory mapped peripherals we use, such as QMSS, PA, etc */
+ result= netapi_VM_memory_setup();
+ if (result) printf("NETAPI: system init - memory set up OK\n");
+ else {printf("NETAPI: system init - memory set up failed\n"); return -1;}
+
+ //get timer running
+ netapi_init_timer();
+
+ /* Initialize Queue Manager Sub System */
+ result = netapi_init_qm ();
+ if (result != 1)
+ {
+ return -1;
+ }
+
+ /* Start the QMSS. */
+ if (netapi_start_qm() != 1)
+ {
+ return -1;
+ }
+
+ //clean our old junk in 1st bunch of queues that will be allocated to us
+ netapi_cleanup_at_start();
+
+ /* Initialize the global descriptor memory region. */
+ result= netapi_qm_setup_mem_region(
+ NUM_SHARED_DESC,
+ SIZE_SHARED_DESC,
+ netapi_VM_QMemGlobalDescRam,
+ NETAPI_GLOBAL_REGION);
+ if(result <0) {printf("can't setup shared region\n"); return -1;}
+
+#if 0 //todo setup 2nd region
+/* Initialize the local memory region configuration. */
+ result= netapi_qm_setup_mem_region(
+ NUM_HOST_DESC,
+ SIZE_LOCAL_DESC,
+ netapi_VM_QMemLocalDescRam,
+ NETAPI_LOCAL_REGION);
+ if(result <0) {printf("can't setup local region\n"); return -1;}
+#endif
+ /* Initialize CPPI CPDMA */
+ result = netapi_init_cppi ();
+ if (result != 1)
+ {
+ printf ("Error initializing CPPI SubSystem error code : %d\n",result);
+ return -1;
+ }
+
+ /* CPPI and Queue Manager are initialized. */
+ printf ("Debug: Queue Manager and CPPI are initialized.\n");
+
+ /* create main pkt heap */
+ /* Initialize the Shared Heaps. */
+ Pktlib_sharedHeapInit();
+
+ /* Populate the heap interface table. */
+ netapi_pktlib_ifTable.data_malloc = netapiSharedMemoryMalloc;
+ netapi_pktlib_ifTable.data_free = netapiSharedMemoryFree;
+
+ /* Create Shared Heap with specified configuration. */
+#define SHARED_MAX_DATA_SIZE (TUNE_NETAPI_DEFAULT_BUFFER_SIZE)
+ sharedHeapHandle = Pktlib_createHeap("netapi", Qmss_MemRegion_MEMORY_REGION0,
+ 1,
+ SHARED_MAX_DATA_SIZE,
+ TUNE_NETAPI_DEFAULT_NUM_BUFFERS,
+ TUNE_NETAPI_DEFAULT_NUM_SOLO_DESCRIPTORS,
+ &netapi_pktlib_ifTable);
+ //todo -> cleanup on failure
+ if (!sharedHeapHandle) { printf("netapi -> 'netapi' heap create failed\n"); return -1;}
+ handle->netcp_heap= sharedHeapHandle;
+
+ controlHeapHandle = Pktlib_createHeap("netapi_control", Qmss_MemRegion_MEMORY_REGION0,
+ 1,
+ TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE,
+ TUNE_NETAPI_CONFIG_NUM_CTL_BUF,
+ 0,
+ &netapi_pktlib_ifTable);
+ //todo -> cleanup on failure
+ if (!controlHeapHandle) { printf("netapi -> 'netapicontrol' heap create failed\n"); return -1;}
+ handle->netcp_control_heap= controlHeapHandle;
+
+
+ /* now NWAL */
+ result = netapi_init_nwal(
+ Qmss_MemRegion_MEMORY_REGION0,
+ &netapi_pktlib_ifTable,
+ &netapi_global.nwal_context);
+ if (result<0) {printf("netapi -> init_nwal() failed\n"); return -1; }
+
+ /* start NWAL */
+ result = netapi_start_nwal(sharedHeapHandle,
+ controlHeapHandle,
+ &handle->nwal_local,
+ &netapi_global.nwal_context);
+ if (result<0) {printf("netapi -> start_nwal() failed\n"); return -1; }
+ //** success **
+
+
+ return 0;
+
+}
+
+
+/*---------------
+ * get presets()
+ *---------------*/
+static void get_presets(PRESET_T * p_preset)
+{
+ /* read from kernel or overall config area */
+ /* for now hard code what kernel did */
+}
+
+
+/*************************************************************
+ ******************MISC INTERNAL******************************
+**************************************************************/
+/* poll the garbage queues of all registered heaps */
+void netapi_pollHeapGarbage(NETAPI_T h)
+{
+ NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
+ Pktlib_garbageCollection(n->netcp_heap);
+ /* todo: register heaps of app */
+}
+
+/* todo */
+int netapi_registerHeap(NETAPI_T p, Pktlib_HeapHandle h){ return 0;}
+int netapi_unregisterHeap(NETAPI_T p, Pktlib_HeapHandle h) { return 0;}
+
+/* poll NETCP control queue for responses */
+void netapi_netcpPoll(NETAPI_T p)
+{
+ NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) p;
+ nwal_pollCtl( ((NETAPI_GLOBAL_T *) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
+}
+
+/****************************************************************
+ *****************Cleanup Functions******************************
+*****************************************************************/
+
+//clean up function for linux user space
+static void zapQ(int queueNum)
+{
+char * descPtr;
+int i;
+for (i=0;;i+=1 )
+ {
+ /* Pop descriptor from source queue */
+ if ((descPtr = (char *)Qmss_queuePop (queueNum)) == NULL)
+ {
+ break;
+ }
+ else {/*printf("netapi qzap in play\n");*/}
+ }
+ if(i) printf(">netapi qzap in play. %d descriptors cleaned\n",i);
+}
+
+//defensive: clean out stuff hanging around
+//
+// open a bunch of free queues and zap them
+#define NQUEUES2CLEAR 15
+static Qmss_QueueHnd tempQH[NQUEUES2CLEAR];
+static void netapi_cleanup_at_start(void)
+{
+int i;
+uint8_t isAllocated;
+
+for(i=0;i<NQUEUES2CLEAR;i++)
+{
+ tempQH[i] = Qmss_queueOpen(Qmss_QueueType_GENERAL_PURPOSE_QUEUE,
+ QMSS_PARAM_NOT_SPECIFIED, &isAllocated);
+ zapQ(tempQH[i]);
+}
+
+for(i=0;i<NQUEUES2CLEAR;i++)
+{
+ Qmss_queueClose(tempQH[i]);
+}
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ti/runtime/netapi/src/netapi_init.c b/ti/runtime/netapi/src/netapi_init.c
--- /dev/null
@@ -0,0 +1,652 @@
+/************************************************
+* FILE: netapi_init.c
+* Global, local initialization of NETAPI
+ *
+ * DESCRIPTION: Functions to initialize framework resources for running NETAPI
+ *
+ * REVISION HISTORY:
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***********************************************/
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <ti/drv/nwal/nwal.h>
+#include "netapi.h"
+#include "netapi_vm.h"
+#include "netapi_loc.h"
+#include "ti/drv/nwal/nwal.h"
+
+/* CSL RL includes */
+#include <ti/csl/cslr_device.h>
+#include <ti/csl/cslr_qm_config.h>
+#include <ti/csl/cslr_qm_descriptor_region_config.h>
+#include <ti/csl/cslr_qm_queue_management.h>
+#include <ti/csl/cslr_qm_queue_status_config.h>
+#include <ti/csl/cslr_qm_intd.h>
+#include <ti/csl/cslr_pdsp.h>
+#include <ti/csl/csl_qm_queue.h>
+#include <ti/csl/cslr_cppidma_global_config.h>
+#include <ti/csl/cslr_cppidma_rx_channel_config.h>
+#include <ti/csl/cslr_cppidma_rx_flow_config.h>
+#include <ti/csl/cslr_cppidma_tx_channel_config.h>
+#include <ti/csl/cslr_cppidma_tx_scheduler_config.h>
+#include <ti/csl/csl_cppi.h>
+#include <ti/csl/csl_pscAux.h>
+#include <ti/csl/csl_semAux.h>
+#include <ti/csl/csl_cacheAux.h>
+#include <ti/csl/csl_xmcAux.h>
+#include <ti/csl/csl_cpsw_3gfAux.h>
+#include <ti/csl/csl_cpsw.h>
+#include <ti/csl/csl_cpsgmiiAux.h>
+#include <ti/drv/qmss/qmss_qm.h>
+//pull in device config for qmss, cppi
+#include <ti/drv/qmss/device/qmss_device.c>
+#include <ti/drv/cppi/device/cppi_device.c>
+
+/* TODO: */
+#define DNUM 0
+#define CACHE_LINESZ 64
+
+#define System_printf printf
+#define ALIGN(x) __attribute__((aligned (x)))
+
+/*****************************************************************************
+ * Global Resources shared by all Cores
+ *****************************************************************************/
+uint8_t *QMemGlobDescRam = 0;
+uint8_t *cppiMemPaSaLinkBuf = 0;
+uint8_t *cppiMemSaPaLinkBuf = 0;
+
+/*****************************************************************************
+ * Local Resource allocated at each Core
+ *****************************************************************************/
+/* Descriptors in global shared */
+uint8_t *QMemLocDescRam = NULL;
+uint8_t *cppiMemRxPktLinkBuf = NULL;
+uint8_t *cppiMemTxPktLinkBuf = NULL;
+uint8_t *cppiMemRxCtlLinkBuf = NULL;
+uint8_t *cppiMemTxCtlLinkBuf = NULL;
+
+
+//****************************************************
+// initialize CPSW (switch) [per SOC]
+//***************************************************
+int netapi_init_cpsw(void)
+{
+ CSL_CPSW_3GF_ALE_PORTCONTROL alePortControlCfg;
+
+ CSL_CPSW_3GF_clearAleTable();
+
+ alePortControlCfg.dropUntaggedEnable = 0;
+ alePortControlCfg.vidIngressCheckEnable = 0;
+
+ alePortControlCfg.mcastLimit = 0;
+ alePortControlCfg.bcastLimit = 0;
+
+ /* Disable learning mode for Port 0 */
+ alePortControlCfg.noLearnModeEnable = 1;
+ alePortControlCfg.portState = ALE_PORTSTATE_FORWARD;
+ CSL_CPSW_3GF_setAlePortControlReg (0, &alePortControlCfg);
+
+ /* Enable learning mode for Port 1 */
+ alePortControlCfg.noLearnModeEnable = 0;
+ alePortControlCfg.portState = ALE_PORTSTATE_FORWARD;
+ CSL_CPSW_3GF_setAlePortControlReg (1, &alePortControlCfg);
+
+ /* Enable learning mode for Port 2 */
+ alePortControlCfg.noLearnModeEnable = 0;
+ alePortControlCfg.portState = ALE_PORTSTATE_FORWARD;
+ CSL_CPSW_3GF_setAlePortControlReg (2, &alePortControlCfg);
+
+ return 1;
+}
+
+//****************************************************
+// initialize QM (per SOC)
+//***************************************************
+int netapi_init_qm(void)
+{
+ Qmss_InitCfg qmssInitConfig;
+ int32_t result;
+ Qmss_GlobalConfigParams nwalTest_qmssGblCfgParams;
+
+ memset (&qmssInitConfig, 0, sizeof (Qmss_InitCfg));
+
+ /* Use Internal Linking RAM for optimal performance */
+ qmssInitConfig.linkingRAM0Base = 0;
+ qmssInitConfig.linkingRAM0Size = 0;
+ qmssInitConfig.linkingRAM1Base = 0;
+ qmssInitConfig.maxDescNum = TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM;
+ qmssInitConfig.qmssHwStatus =QMSS_HW_INIT_COMPLETE; //bypass some of the hw init
+ nwalTest_qmssGblCfgParams = qmssGblCfgParams[0];
+
+ nwalTest_qmssGblCfgParams.qmConfigReg = (void *)((uint8_t *)netapi_VM_qmssCfgVaddr +
+ (CSL_QM_SS_CFG_CONFIG_STARVATION_COUNTER_REGS - CSL_QM_SS_CFG_QUE_PEEK_REGS));
+ nwalTest_qmssGblCfgParams.qmDescReg = (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ ((uint32_t)CSL_QM_SS_CFG_DESCRIPTION_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS);
+ nwalTest_qmssGblCfgParams.qmQueMgmtReg = (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ ((uint32_t)CSL_QM_SS_CFG_QM_QUEUE_DEQUEUE_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS);
+ nwalTest_qmssGblCfgParams.qmQueMgmtProxyReg = (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ ((uint32_t)CSL_QM_SS_CFG_PROXY_QUEUE_DEQUEUE_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS);
+ nwalTest_qmssGblCfgParams.qmQueStatReg = (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ ((uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS);
+ nwalTest_qmssGblCfgParams.qmQueIntdReg = (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ ((uint32_t)CSL_QM_SS_CFG_INTD_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS);
+ nwalTest_qmssGblCfgParams.qmPdspCmdReg[0] = (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ ((uint32_t)CSL_QM_SS_CFG_SCRACH_RAM1_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS);
+ nwalTest_qmssGblCfgParams.qmPdspCmdReg[1] = (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ ((uint32_t)CSL_QM_SS_CFG_SCRACH_RAM2_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS);
+ nwalTest_qmssGblCfgParams.qmPdspCtrlReg[0] = (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ ((uint32_t)CSL_QM_SS_CFG_ADSP1_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS);
+ nwalTest_qmssGblCfgParams.qmPdspCtrlReg[1] = (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ ((uint32_t)CSL_QM_SS_CFG_ADSP2_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS);
+ nwalTest_qmssGblCfgParams.qmPdspIRamReg[0] = (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ ((uint32_t)CSL_QM_SS_CFG_APDSP1_RAM_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS);
+ nwalTest_qmssGblCfgParams.qmPdspIRamReg[1] = (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ ((uint32_t)CSL_QM_SS_CFG_APDSP2_RAM_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS);
+ nwalTest_qmssGblCfgParams.qmStatusRAM = (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ ((uint32_t)CSL_QM_SS_CFG_QM_STATUS_RAM_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS);
+ nwalTest_qmssGblCfgParams.qmLinkingRAMReg = (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ ((uint32_t)CSL_QM_SS_CFG_LINKING_RAM_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS);
+ nwalTest_qmssGblCfgParams.qmMcDMAReg = (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ ((uint32_t)CSL_QM_SS_CFG_MCDMA_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS);
+ nwalTest_qmssGblCfgParams.qmTimer16Reg[0] = (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ ((uint32_t)CSL_QM_SS_CFG_TIMER1_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS);
+ nwalTest_qmssGblCfgParams.qmTimer16Reg[1] = (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ ((uint32_t)CSL_QM_SS_CFG_TIMER2_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS);
+ nwalTest_qmssGblCfgParams.qmQueMgmtDataReg = (void *)((uint32_t)netapi_VM_qmssDataVaddr);
+ nwalTest_qmssGblCfgParams.qmQueMgmtProxyDataReg =
+ (void *)((uint32_t)netapi_VM_qmssDataVaddr + ((uint32_t)(0x44040000) - (uint32_t)(0x44020000)));
+
+ result = Qmss_init (&qmssInitConfig, &nwalTest_qmssGblCfgParams);
+ if (result != QMSS_SOK) {
+ System_printf ("function init_qm: qmss_Init failed with error code %d\n", result);
+ return (nwal_FALSE);
+ }
+
+ return 1;
+}
+
+//****************************************************
+// Set up QM memory region (per SOC)
+//***************************************************
+int netapi_qm_setup_mem_region(
+ uint32_t numDesc,
+ uint32_t descSize,
+ uint32_t* pDescMemBase,
+ Qmss_MemRegion memRegion)
+{
+ Qmss_MemRegInfo memInfo;
+ Int32 result;
+ Int n;
+ static int netapi_qm_region_index=0;
+
+ memset(&memInfo,0,sizeof(Qmss_MemRegInfo));
+ memInfo.descBase = pDescMemBase;
+ memInfo.descSize = descSize;
+ memInfo.descNum = numDesc;
+ memInfo.manageDescFlag = Qmss_ManageDesc_MANAGE_DESCRIPTOR;
+ memInfo.memRegion = memRegion==NETAPI_GLOBAL_REGION ? Qmss_MemRegion_MEMORY_REGION0 : Qmss_MemRegion_MEMORY_REGION1;
+
+ if(memRegion == NETAPI_GLOBAL_REGION)
+ {
+ memInfo.startIndex = 0;
+ netapi_qm_region_index += numDesc;
+ }else if(memRegion ==NETAPI_LOCAL_REGION)
+ {
+ /* Global shared memory for all descriptors to all cores */
+ memInfo.startIndex = netapi_qm_region_index;
+ }
+ else
+ {
+ return -1 ;
+ }
+
+ result = Qmss_insertMemoryRegion (&memInfo);
+ if (result < QMSS_SOK)
+ {
+ printf ("function setup_qm_region: Qmss_insertMemoryRegion returned error code %d\n", result);
+ return (-1);
+ }
+
+ return 1;
+
+}
+
+//****************************************************
+// Start QM (per thread)
+//***************************************************
+int netapi_start_qm(void)
+{
+ int32_t result;
+ result = Qmss_start();
+ if (result != QMSS_SOK)
+ {
+ System_printf ("start_qm: Qmss_start failed with error code %d\n", result);
+ return (-1);
+ }
+ return 1;
+}
+
+//*************************************************
+//initilaize CPPI (once per soc)
+//*************************************************
+int netapi_init_cppi(void)
+{
+ int32_t result, i;
+ Cppi_GlobalConfigParams nwalTest_cppiGblCfgParams[CPPI_MAX_CPDMA];
+
+ for (i=0; i<CPPI_MAX_CPDMA; i++)
+ nwalTest_cppiGblCfgParams[i] = cppiGblCfgParams[i];
+
+ /* SRIO CPDMA regs */
+ nwalTest_cppiGblCfgParams[Cppi_CpDma_SRIO_CPDMA].gblCfgRegs =
+ (void *)((uint32_t)netapi_VM_srioCfgVaddr +
+ (((uint32_t)CSL_SRIO_CONFIG_CPPI_DMA_GLOBAL_CFG_REGS) - (uint32_t)CSL_SRIO_CONFIG_REGS));
+ nwalTest_cppiGblCfgParams[Cppi_CpDma_SRIO_CPDMA].txChRegs =
+ (void *)((uint32_t)netapi_VM_srioCfgVaddr +
+ (((uint32_t)CSL_SRIO_CONFIG_CPPI_DMA_TX_CFG_REGS) - (uint32_t)CSL_SRIO_CONFIG_REGS));
+
+ nwalTest_cppiGblCfgParams[Cppi_CpDma_SRIO_CPDMA].rxChRegs =
+ (void *)((uint32_t)netapi_VM_srioCfgVaddr +
+ (((uint32_t)CSL_SRIO_CONFIG_CPPI_DMA_RX_CFG_REGS) - (uint32_t)CSL_SRIO_CONFIG_REGS));
+ nwalTest_cppiGblCfgParams[Cppi_CpDma_SRIO_CPDMA].txSchedRegs =
+ (void *)((uint32_t)netapi_VM_srioCfgVaddr +
+ (((uint32_t)CSL_SRIO_CONFIG_CPPI_DMA_TX_SCHEDULER_CFG_REGS) - (uint32_t)CSL_SRIO_CONFIG_REGS));
+ nwalTest_cppiGblCfgParams[Cppi_CpDma_SRIO_CPDMA].rxFlowRegs =
+ (void *)((uint32_t)netapi_VM_srioCfgVaddr +
+ (((uint32_t)CSL_SRIO_CONFIG_CPPI_DMA_RX_FLOW_CFG_REGS) - (uint32_t)CSL_SRIO_CONFIG_REGS));
+
+ /* PASS CPDMA regs */
+ nwalTest_cppiGblCfgParams[Cppi_CpDma_PASS_CPDMA].gblCfgRegs =
+ (void *)((uint32_t)netapi_VM_passCfgVaddr +
+ (((uint32_t)CSL_PA_SS_CFG_CPPI_DMA_GLOBAL_CFG_REGS) - (uint32_t)CSL_PA_SS_CFG_REGS));
+ nwalTest_cppiGblCfgParams[Cppi_CpDma_PASS_CPDMA].txChRegs =
+ (void *)((uint32_t)netapi_VM_passCfgVaddr +
+ (((uint32_t)CSL_PA_SS_CFG_CPPI_DMA_TX_CFG_REGS) - (uint32_t)CSL_PA_SS_CFG_REGS));
+ nwalTest_cppiGblCfgParams[Cppi_CpDma_PASS_CPDMA].rxChRegs =
+ (void *)((uint32_t)netapi_VM_passCfgVaddr +
+ (((uint32_t)CSL_PA_SS_CFG_CPPI_DMA_RX_CFG_REGS) - (uint32_t)CSL_PA_SS_CFG_REGS));
+ nwalTest_cppiGblCfgParams[Cppi_CpDma_PASS_CPDMA].txSchedRegs =
+ (void *)((uint32_t)netapi_VM_passCfgVaddr +
+ (((uint32_t)CSL_PA_SS_CFG_CPPI_DMA_TX_SCHEDULER_CFG_REGS) - (uint32_t)CSL_PA_SS_CFG_REGS));
+ nwalTest_cppiGblCfgParams[Cppi_CpDma_PASS_CPDMA].rxFlowRegs =
+ (void *)((uint32_t)netapi_VM_passCfgVaddr +
+ (((uint32_t)CSL_PA_SS_CFG_CPPI_DMA_RX_FLOW_CFG_REGS) - (uint32_t)CSL_PA_SS_CFG_REGS));
+ /* QMSS CPDMA regs */
+ nwalTest_cppiGblCfgParams[Cppi_CpDma_QMSS_CPDMA].gblCfgRegs =
+ (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ (((uint32_t)CSL_QM_SS_CFG_CPPI_DMA_GLOBAL_CFG_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS));
+ nwalTest_cppiGblCfgParams[Cppi_CpDma_QMSS_CPDMA].txChRegs =
+ (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ (((uint32_t)CSL_QM_SS_CFG_CPPI_DMA_TX_CFG_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS));
+ nwalTest_cppiGblCfgParams[Cppi_CpDma_QMSS_CPDMA].rxChRegs =
+ (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ (((uint32_t)CSL_QM_SS_CFG_CPPI_DMA_RX_CFG_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS));
+ nwalTest_cppiGblCfgParams[Cppi_CpDma_QMSS_CPDMA].txSchedRegs =
+ (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ (((uint32_t)CSL_QM_SS_CFG_CPPI_DMA_TX_SCHEDULER_CFG_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS));
+ nwalTest_cppiGblCfgParams[Cppi_CpDma_QMSS_CPDMA].rxFlowRegs =
+ (void *)((uint32_t)netapi_VM_qmssCfgVaddr +
+ (((uint32_t)CSL_QM_SS_CFG_CPPI_DMA_RX_FLOW_CFG_REGS) - (uint32_t)CSL_QM_SS_CFG_QUE_PEEK_REGS));
+
+ result = Cppi_init (nwalTest_cppiGblCfgParams);
+ if (result != CPPI_SOK)
+ {
+ printf ("function cppi_init: Cppi_init failed with error code %d\n", result);
+ return (-1);
+ }
+ return 1;
+}
+
+//*************************************************
+//initialize NWAL (one per soc)
+//*************************************************
+/*** NWAL Memory Buffer Configuration ***/
+#define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_HANDLE 3400
+uint8_t nwalInstMem[NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_HANDLE]ALIGN(CACHE_LINESZ);
+
+#define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_MAC 128
+#define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_IPSEC_HANDLE_PER_CHAN 256
+#define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_IP 128
+#define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_PORT 128
+#define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_L2L3_HDR 128
+#define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_LOC_CONTEXT 384
+#define NWAL_CHAN_HANDLE_SIZE ((NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_MAC * TUNE_NETAPI_MAX_NUM_MAC) + \
+ (NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_IPSEC_HANDLE_PER_CHAN * TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS) + \
+ (NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_IP * TUNE_NETAPI_MAX_NUM_IP) + \
+ (NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_PORT * TUNE_NETAPI_MAX_NUM_PORTS)+ \
+ (NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_LOC_CONTEXT * TUNE_NETAPI_NUM_CORES) + \
+ (NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_L2L3_HDR * TUNE_NETAPI_MAX_NUM_L2_L3_HDRS))
+
+uint8_t nwalHandleMem[NWAL_CHAN_HANDLE_SIZE]ALIGN(CACHE_LINESZ);
+
+/* todo: Check if below size information can be made available from pa interface file */
+#define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF0 128
+/* PA instance */
+/* Memory used for the PA Instance. Needs to be assigned global uncached memory for chip */
+uint8_t paBuf0[NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF0]ALIGN(CACHE_LINESZ);
+
+/* Memory used for PA handles */
+#define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1 128
+uint8_t paBuf1[NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1]ALIGN(CACHE_LINESZ);
+
+#define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2 256
+uint8_t paBuf2[NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2]ALIGN(CACHE_LINESZ);
+
+/* Memory used for SA LLD global Handle */
+#define NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE 384
+uint8_t salldHandle[NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE]ALIGN(CACHE_LINESZ);
+
+/* Memory used for SA LLD global Handle */
+#define NETAPI_NWAL_CONFIG_BUFSIZE_SA_CONTEXT_PER_CHAN 384
+uint8_t saContext[NETAPI_NWAL_CONFIG_BUFSIZE_SA_CONTEXT_PER_CHAN * TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS]ALIGN(CACHE_LINESZ);
+
+/* Memory used by SA LLD per Channel */
+#define NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE_PER_CHAN 512
+uint8_t salldChanHandle[NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE_PER_CHAN * TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS]ALIGN(CACHE_LINESZ);
+
+
+/*******************************************
+ * Initialize the nwal subsystem for NETAPI use
+ ***********************************************/
+int netapi_init_nwal(
+ int region2use,
+ Pktlib_HeapIfTable * p_table,
+ NETAPI_NWAL_GLOBAL_CONTEXT_T * p_nwal_context )
+{
+ nwalSizeInfo_t nwalSizeInfo;
+ nwalMemBuf_t nwalMemBuf[nwal_N_BUFS];
+ nwal_RetValue nwalRetVal;
+ nwalGlobCfg_t nwalGlobCfg;
+ uint8_t count;
+ int sizes[nwal_N_BUFS];
+ int aligns[nwal_N_BUFS];
+ void* bases[nwal_N_BUFS];
+
+ memset(p_nwal_context,0,sizeof( NETAPI_NWAL_GLOBAL_CONTEXT_T) );
+ memset(&nwalGlobCfg,0,sizeof(nwalGlobCfg_t ) );
+
+
+ /* Initialize Buffer Pool for NetCP PA to SA packets */
+ nwalGlobCfg.pa2SaBufPool.numBufPools = 1;
+ nwalGlobCfg.pa2SaBufPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE;
+ nwalGlobCfg.pa2SaBufPool.bufPool[0].bufSize = TUNE_NETAPI_DEFAULT_BUFFER_SIZE;
+ nwalGlobCfg.pa2SaBufPool.bufPool[0].heapHandle =
+ Pktlib_createHeap("nwal PA2SA",
+ region2use,
+ 0,
+ TUNE_NETAPI_DEFAULT_BUFFER_SIZE,
+ TUNE_NETAPI_CONFIG_MAX_PA_TO_SA_DESC,
+ 0,
+ p_table);
+ if(nwalGlobCfg.pa2SaBufPool.bufPool[0].heapHandle == NULL)
+ {
+ printf ("Pktlib_createHeap:Heap Creation Failed for PA to SA Buffer Pool \n");
+ netapi_err_teardown();
+ return -1;
+ }
+
+ /* Initialize Buffer Pool for NetCP SA to PA packets */
+ nwalGlobCfg.sa2PaBufPool.numBufPools = 1;
+ nwalGlobCfg.sa2PaBufPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE;
+ nwalGlobCfg.sa2PaBufPool.bufPool[0].bufSize = TUNE_NETAPI_DEFAULT_BUFFER_SIZE;
+
+ nwalGlobCfg.sa2PaBufPool.bufPool[0].heapHandle =
+ Pktlib_createHeap("nwal SA2PA",
+ region2use,
+ 0,
+ TUNE_NETAPI_DEFAULT_BUFFER_SIZE,
+ TUNE_NETAPI_CONFIG_MAX_SA_TO_PA_DESC,
+ 0,
+ p_table);
+ if(nwalGlobCfg.sa2PaBufPool.bufPool[0].heapHandle == NULL)
+ {
+ printf ("Pktlib_createHeap:Heap Creation Failed for SA to PA Buffer Pool \n");
+ netapi_err_teardown();
+ return -1;
+ }
+
+ nwalGlobCfg.hopLimit = 5;/* Default TTL / Hop Limit */
+ nwalGlobCfg.lpbackPass = TUNE_NETAPI_NWAL_ENABLE_PASS_LOOPBACK;
+ nwalGlobCfg.paFwActive = nwal_TRUE;
+ nwalGlobCfg.saFwActive = nwal_TRUE;
+
+ /* Pick Default Physical Address */
+ nwalGlobCfg.paVirtBaseAddr = (uint32_t) netapi_VM_passCfgVaddr;
+ nwalGlobCfg.saVirtBaseAddr = (uint32_t) netapi_VM_passCfgVaddr +
+ ((uint32_t)CSL_PA_SS_CFG_CP_ACE_CFG_REGS - (uint32_t)CSL_PA_SS_CFG_REGS) ;
+ nwalGlobCfg.rxDefPktQ = QMSS_PARAM_NOT_SPECIFIED;
+
+ /* Get the Buffer Requirement from NWAL */
+ memset(&nwalMemBuf,0,sizeof(nwalMemBuf));
+ memset(&nwalSizeInfo,0,sizeof(nwalSizeInfo));
+ nwalSizeInfo.nMaxMacAddress = TUNE_NETAPI_MAX_NUM_MAC;
+ nwalSizeInfo.nMaxIpAddress = TUNE_NETAPI_MAX_NUM_IP;
+ nwalSizeInfo.nMaxL4Ports = TUNE_NETAPI_MAX_NUM_PORTS;
+ nwalSizeInfo.nMaxIpSecChannels = TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS;
+ nwalSizeInfo.nMaxL2L3Hdr = TUNE_NETAPI_MAX_NUM_L2_L3_HDRS;
+ nwalSizeInfo.nProc = TUNE_NETAPI_NUM_CORES;
+ for(count=0;count < nwal_N_BUFS;count++)
+ {
+ nwalMemBuf[count].cacheLineSize = CACHE_LINESZ;
+ }
+ nwalRetVal = nwal_getBufferReq(&nwalSizeInfo,
+ sizes,
+ aligns);
+ if(nwalRetVal != nwal_OK)
+ {
+ printf ("init_nwal: nwal_getBufferReq Failed %d\n", nwalRetVal);
+ return nwal_FALSE;
+ }
+
+/* Check for memory size requirement and update the base */
+ count = 0;
+ bases[nwal_BUF_INDEX_INST] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)nwalInstMem);
+ if(NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_HANDLE < sizes[nwal_BUF_INDEX_INST])
+ {
+ /* Resize Memory */
+ while(1);
+ }
+ count++;
+
+ bases[nwal_BUF_INDEX_INT_HANDLES] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)nwalHandleMem);
+ if(NWAL_CHAN_HANDLE_SIZE < sizes[nwal_BUF_INDEX_INT_HANDLES])
+ {
+ /* Resize Memory */
+ while(1);
+ }
+ count++;
+ bases[nwal_BUF_INDEX_PA_LLD_BUF0] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)paBuf0);
+ if((NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF0) < sizes[nwal_BUF_INDEX_PA_LLD_BUF0])
+ {
+ /* Resize Memory */
+ while(1);
+ }
+ count++;
+
+ bases[nwal_BUF_INDEX_PA_LLD_BUF1] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)paBuf1);
+ if((NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1) < sizes[nwal_BUF_INDEX_PA_LLD_BUF1])
+ {
+ /* Resize Memory */
+ while(1);
+ }
+ count++;
+
+ bases[nwal_BUF_INDEX_PA_LLD_BUF2] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)paBuf2);
+ if((NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2) < sizes[nwal_BUF_INDEX_PA_LLD_BUF2])
+ {
+ /* Resize Memory */
+ while(1);
+ }
+ count++;
+#ifdef NETAPI_ENABLE_SECURITY
+ bases[nwal_BUF_INDEX_SA_LLD_HANDLE] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)salldHandle);
+ if((NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE) < sizes[nwal_BUF_INDEX_SA_LLD_HANDLE])
+ {
+ /* Resize Memory */
+ while(1);
+ }
+ count++;
+
+ bases[nwal_BUF_INDEX_SA_CONTEXT] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)saContext);
+ if((NETAPI_NWAL_CONFIG_BUFSIZE_SA_CONTEXT_PER_CHAN * TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS) <
+ sizes[nwal_BUF_INDEX_SA_CONTEXT])
+ {
+ /* Resize Memory */
+ while(1);
+ }
+ count++;
+
+ bases[nwal_BUF_INDEX_SA_LLD_CHAN_HANDLE] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)salldChanHandle);
+ if((NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE_PER_CHAN * TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS) <
+ sizes[nwal_BUF_INDEX_SA_LLD_CHAN_HANDLE])
+ {
+ /* Resize Memory */
+ while(1);
+ }
+ count++;
+#else
+ bases[nwal_BUF_INDEX_SA_LLD_HANDLE] = 0;
+ bases[nwal_BUF_INDEX_SA_CONTEXT] = 0;
+ bases[nwal_BUF_INDEX_SA_LLD_CHAN_HANDLE] = 0;
+ count = count+3;
+#endif
+ if(count != nwal_N_BUFS)
+ {
+ while(1);
+ }
+
+ /* Initialize NWAL module */
+ nwalRetVal = nwal_create(&nwalGlobCfg,
+ &nwalSizeInfo,
+ sizes,
+ bases,
+ &p_nwal_context->nwalInstHandle);
+ if(nwalRetVal != nwal_OK)
+ {
+ printf ("init_nwal: nwal_create Failed %d\n",nwalRetVal);
+ while(1);
+ }
+
+ printf("init_nwal: Global and Local Network initialization Successful \n");
+ return 1;
+}
+
+//*************************************************
+//* Local (per thread/core) nwal initialization0
+//**************************************************
+int netapi_start_nwal(Pktlib_HeapHandle pkt_heap,
+ Pktlib_HeapHandle cmd_heap,
+ NETAPI_NWAL_LOCAL_CONTEXT_T *p,
+ NETAPI_NWAL_GLOBAL_CONTEXT_T * p_nwal_glob_context )
+{
+ nwalLocCfg_t nwalLocCfg;
+ int count;
+ nwal_RetValue nwalRetVal;
+
+ memset(&nwalLocCfg,0,sizeof(nwalLocCfg));
+
+ /* Common Initialization for all cores */
+ while(count < TUNE_NETAPI_MAX_NUM_TRANS)
+ {
+ p_nwal_glob_context->transInfos[count].transId = count;
+ count++;
+ }
+
+ /* Call back registration for the core */
+ nwalLocCfg.pRxPktCallBack = netapi_NWALRxPktCallback;
+ nwalLocCfg.pCmdCallBack = netapi_NWALCmdCallBack;
+ nwalLocCfg.pPaStatsCallBack = netapi_NWALCmdPaStatsReply;
+
+ /* Initialize Buffer Pool for Control packets from NetCP to Host */
+ nwalLocCfg.rxCtlPool.numBufPools = 1;
+ nwalLocCfg.rxCtlPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE;
+ nwalLocCfg.rxCtlPool.bufPool[0].bufSize = TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE;
+ nwalLocCfg.rxCtlPool.bufPool[0].heapHandle = cmd_heap;
+
+ /* Initialize Buffer Pool for Control packets from Host to NetCP */
+ nwalLocCfg.txCtlPool.numBufPools = 1;
+ nwalLocCfg.txCtlPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE;
+ nwalLocCfg.txCtlPool.bufPool[0].bufSize = TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE;
+ nwalLocCfg.txCtlPool.bufPool[0].heapHandle = cmd_heap;
+
+/* Initialize Buffer Pool for Packets from NetCP to Host */
+ nwalLocCfg.rxPktPool.numBufPools = 1;
+ nwalLocCfg.rxPktPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE;
+ nwalLocCfg.rxPktPool.bufPool[0].bufSize = TUNE_NETAPI_DEFAULT_BUFFER_SIZE;
+ nwalLocCfg.rxPktPool.bufPool[0].heapHandle = pkt_heap;
+
+/* Initialize Buffer Pool for Packets from Host to NetCP */
+ nwalLocCfg.txPktPool.numBufPools = 1;
+ nwalLocCfg.txPktPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE;
+ nwalLocCfg.txPktPool.bufPool[0].bufSize = TUNE_NETAPI_DEFAULT_BUFFER_SIZE;
+ nwalLocCfg.txPktPool.bufPool[0].heapHandle = pkt_heap;
+
+ memcpy(&p->nwalLocCfg,&nwalLocCfg,sizeof(nwalLocCfg_t));
+ while(1)
+ {
+ nwalRetVal = nwal_start(p_nwal_glob_context->nwalInstHandle,&nwalLocCfg);
+ if(nwalRetVal == nwal_ERR_INVALID_STATE)
+ {
+ continue;
+ }
+ break;
+ }
+
+ if(nwalRetVal != nwal_OK)
+ {
+ printf ("nwal_start:Failed ->err %d !!!\n", nwalRetVal);
+ return -1;
+ }
+ p->state = NETAPI_NW_CXT_LOC_ACTIVE;
+ return 1;
+
+
+}
+//***************************************************
+// intialize timer
+//***************************************************
+int netapi_init_timer(void)
+{
+ return t64_start();
+}
+
+
diff --git a/ti/runtime/netapi/src/netapi_loc.h b/ti/runtime/netapi/src/netapi_loc.h
--- /dev/null
@@ -0,0 +1,306 @@
+/*****************************************
+ * file: netapi_loc.h
+ * purpose: internal netapi stuff
+ ****************************************/
+
+#ifndef __NETAPI_LOC__H
+#define __NETAPI_LOC__H
+/***************************************
+* INTERNAL HANDLE STRUCTURE DEFINITION
+****************************************/
+
+/***********************************************
+ * GLOBAL AREA
+ * short term: this is global to process
+ * (multi-process not supported)
+ * long term: this structure gets put in shared memory
+ ***********************************************/
+
+/* list of global pktio channels that have been created
+ (NETCP_TX, RX are intrinsic so won't be here) */
+typedef struct PKTIO_ENTRY_tag
+{
+ char name[PKTIO_MAX_NAME+1];
+ Qmss_Queue qn; // -1 => slot is free
+} PKTIO_ENTRY_T;
+
+/* to hold an IP on an interface */
+typedef struct NETCP_INTERFACE_IP_Tag
+{
+ int in_use;
+ void * nwal_handle;
+ nwal_IpType ip_type;
+ nwalIpAddr_t ip_addr;
+ nwalIpOpt_t ip_qualifiers;
+} NETCP_INTERFACE_IP_T;
+
+/* to hold a netcp 'interface' */
+typedef struct NETCP_INTERFACE_Tag
+{
+ int in_use; /* 1 for valid */
+ int state; /* 0=down, 1=up, future.. */
+ void * nwal_handle; //handle associated with this interface
+ unsigned char mac[6]; // mac address
+ unsigned int vlan; //future
+ NETCP_INTERFACE_IP_T ips[TUNE_NETAPI_MAX_IP_PER_INTERFACE];
+} NETCP_INTERFACE_T;
+
+/*to keep track of netcp config transactions */
+typedef struct {
+ nwal_Bool_t inUse;
+ uint16_t transType;
+#define NETAPI_NWAL_HANDLE_TRANS_NONE 0
+#define NETAPI_NWAL_HANDLE_TRANS_MAC 1
+#define NETAPI_NWAL_HANDLE_TRANS_IP 2
+#define NETAPI_NWAL_HANDLE_TRANS_PORT 3
+#define NETAPI_NWAL_HANDLE_TRANS_SEC_ASSOC 4
+#define NETAPI_NWAL_HANDLE_TRANS_SEC_POLICY 5
+#define NETAPI_NWAL_HANDLE_STAT_REQUEST 6
+
+ uint16_t state;
+#define NETAPI_NWAL_HANDLE_STATE_IDLE 0
+#define NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING 1
+#define NETAPI_NWAL_HANDLE_STATE_OPEN 2
+#define NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING 3
+ nwal_Handle handle;
+ uint64_t transId;
+ NETAPI_T netapi_handle; //the thread making the transaction
+} NetapiNwalTransInfo_t;
+
+/* nwal global context */
+typedef struct
+{
+ int state;
+#define NETAPI_NW_CXT_GLOB_INACTIVE 0x0
+#define NETAPI__CXT_GLOB_ACTIVE 0x1
+#define NETAPI_NW_CXT_GLOB_RES_ALLOC_COMPLETE 0x3
+
+ nwal_Handle nwalInstHandle;
+ paSysStats_t paStats;
+ int numCmdPass;
+ int numCmdFail;
+ int numBogusTransIds;
+ NetapiNwalTransInfo_t transInfos[TUNE_NETAPI_MAX_NUM_TRANS];
+ NETCP_INTERFACE_T interfaces[TUNE_NETAPI_MAX_INTERFACES];
+
+} NETAPI_NWAL_GLOBAL_CONTEXT_T;
+
+/* NWAL Local context (per core/thread) */
+typedef struct
+{
+ //void * nwalLocInstance;
+#define NETAPI_NW_CXT_LOC_INACTIVE 0x0
+#define NETAPI_NW_CXT_LOC_ACTIVE 0x2
+ int state;
+
+ int numPendingCfg;
+ NETCP_CFG_STATS_CB stats_cb;
+
+/* stats */
+ int numL2PktsRecvd;
+ int numL3PktsRecvd;
+ int numL4PktsRecvd;
+ int numL4PktsSent;
+ int TxErrDrop;
+
+ /* local config */
+ nwalLocCfg_t nwalLocCfg;
+} NETAPI_NWAL_LOCAL_CONTEXT_T;
+
+/* the global */
+typedef struct NETAPI_GLOBAL_tag
+{
+#define NETAPI_MAX_PKTIO (TUNE_NETAPI_MAX_PKTIO)
+PKTIO_ENTRY_T pktios[NETAPI_MAX_PKTIO];
+
+/* pktlib heap */
+
+/* global timers */
+
+/* nwal context */
+NETAPI_NWAL_GLOBAL_CONTEXT_T nwal_context;
+
+} NETAPI_GLOBAL_T;
+
+
+/************************************
+ * this is a per thread structure.
+ * It contains stuff local to thread
+ * and pointer to global stuff
+ * that is shared over all threads,
+ **************************************/
+typedef struct NETAPI_HANDLE_Tag
+{
+ int master; //master type
+
+void * global; /* pointer to the global area */
+
+/* heap handle */
+Pktlib_HeapHandle netcp_heap;
+Pktlib_HeapHandle netcp_control_heap;
+
+/* pktios defined */
+int n_pktios; /* #of pktios that are active for this instance */
+void* pktios[NETAPI_MAX_PKTIO]; /* the list of pktios */
+
+/* scheduler stuff. unallocated if NETAPI_INCLUDE_SCHED not set */
+void * p_sched;
+
+/* nwal local context */
+NETAPI_NWAL_LOCAL_CONTEXT_T nwal_local;
+
+/* security stuff */
+
+/* timer stuff */
+
+
+/* default flow*/
+NETCP_CFG_FLOW_HANDLE_T def_flow; //uses our heap above
+
+/* default route */
+NETCP_CFG_ROUTE_HANDLE_T def_route; //uses our rx channel above
+
+/* thread cookie */
+void * cookie; /*set by calling thread */
+
+} NETAPI_HANDLE_T;
+
+
+//internal initialization routines */
+int netapi_init_qm(void);
+int netapi_init_cppi(void);
+int netapi_init_cpsw(void);
+int netapi_start_qm(void);
+int netapi_init_nwal(
+ int region2use,
+ Pktlib_HeapIfTable * p_table,
+ NETAPI_NWAL_GLOBAL_CONTEXT_T * p_nwal_context );
+int netapi_start_nwal(Pktlib_HeapHandle pkt_heap,
+ Pktlib_HeapHandle cmd_heap,
+ NETAPI_NWAL_LOCAL_CONTEXT_T *p ,
+ NETAPI_NWAL_GLOBAL_CONTEXT_T * p_nwal_glob_context );
+
+int netapi_init_timer(void);
+int netapi_qm_setup_mem_region(
+ unsigned int numDesc,
+ unsigned int descSize,
+ unsigned int* pDescMemBase,
+ int memRegion);
+//for above
+#define NETAPI_GLOBAL_REGION 0
+#define NETAPI_LOCAL_REGION 1
+
+
+//nwal callbacks
+void netapi_NWALRxPktCallback (uint32_t appCookie,
+ uint8_t numPkts,
+ nwalRxPktInfo_t* pPktInfo,
+ uint64_t timestamp,
+ nwal_Bool_t* pFreePkt);
+
+void netapi_NWALCmdCallBack (nwal_AppId appHandle,
+ uint16_t trans_id,
+ nwal_RetValue ret);
+
+void netapi_NWALCmdPaStatsReply (nwal_AppId appHandle,
+ nwal_TransID_t trans_id,
+ paSysStats_t *stats);
+
+//***********************************
+//internal utilities
+//*************************************
+
+//return the list of pktios for this instance
+static inline void * netapi_get_pktio_list(NETAPI_T p)
+{
+NETAPI_HANDLE_T *pp = (NETAPI_HANDLE_T *) p;
+return &pp->pktios[0];
+}
+
+//get scheduler block handle
+static inline void * netapi_get_scheduler(NETAPI_T p)
+{
+NETAPI_HANDLE_T *pp = (NETAPI_HANDLE_T *) p;
+return pp->p_sched;
+}
+
+/* return pointer to global area */
+NETAPI_GLOBAL_T * netapi_get_global(void);
+
+//add a pktio name (and queue) to global list
+static inline int netapi_add_global_pktio(NETAPI_T p, char *name, Qmss_Queue * qn)
+{
+NETAPI_HANDLE_T *pp = (NETAPI_HANDLE_T *) p;
+PKTIO_ENTRY_T *pe;
+int i;
+//find a free slot
+pe = &((NETAPI_GLOBAL_T *)(pp->global))->pktios[0];
+
+for(i=0;i<NETAPI_MAX_PKTIO; i++,pe++)
+ {
+ if (pe->qn.qNum == -1)
+ {
+ pe->qn.qNum=qn->qNum;
+ pe->qn.qMgr=qn->qMgr;
+ strncpy(pe->name, name, PKTIO_MAX_NAME);
+ return 1;
+ }
+ pe+=1;
+ }
+ return 0; //no room
+}
+
+//delete a pktio name (and queue) to global list
+static inline int netapi_del_global_pktio(NETAPI_T p, char *name)
+{
+NETAPI_HANDLE_T *pp = (NETAPI_HANDLE_T *) p;
+PKTIO_ENTRY_T *pe;
+int i;
+//find slot
+pe = &((NETAPI_GLOBAL_T *)(pp->global))->pktios[0];
+
+for(i=0;i<NETAPI_MAX_PKTIO; i++,pe++)
+ {
+ if (pe->qn.qNum == -1) continue;
+ if (!strncmp(name, pe->name, PKTIO_MAX_NAME))
+ {
+ pe->qn.qNum=-1;
+ pe->name[0]='\0';
+ return 1;
+ }
+ pe+=1;
+ }
+ return 0; //no room
+}
+
+
+/* get list of global pktios that have been created */
+static inline Qmss_Queue* netapi_find_global_pktio(NETAPI_T p, char *name)
+{
+NETAPI_HANDLE_T *pp = (NETAPI_HANDLE_T *) p;
+PKTIO_ENTRY_T *pe;
+int i;
+//find slot
+pe = &((NETAPI_GLOBAL_T *)(pp->global))->pktios[0];
+
+for(i=0;i<NETAPI_MAX_PKTIO; i++,pe++)
+ {
+ if (pe->qn.qNum == -1) continue;
+ if (!strncmp(name, pe->name, PKTIO_MAX_NAME))
+ {
+ return &pe->qn;
+ }
+ pe +=1;
+ }
+ return NULL; //not found
+}
+
+/* return the nwal global instance handle */
+static inline nwal_Handle netapi_return_nwal_instance_handle(NETAPI_T p)
+{
+
+NETAPI_HANDLE_T *pp = (NETAPI_HANDLE_T *) p;
+return ((NETAPI_GLOBAL_T *)(pp->global))->nwal_context.nwalInstHandle;
+}
+
+#endif
diff --git a/ti/runtime/netapi/src/netapi_sched.c b/ti/runtime/netapi/src/netapi_sched.c
--- /dev/null
@@ -0,0 +1,140 @@
+/****************************************
+ * File: netapi_sched.c
+ * Purpose: netapi scheduling module
+ * NOTE: This sample right now.
+ **************************************************************
+ * FILE: netapi_sched.c
+ *
+ * DESCRIPTION: netapi sample scheduler source file for user space transport
+ * library
+ *
+ * REVISION HISTORY: rev 0.0.1
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ ****************************************/
+
+#include "netapi.h"
+#include "netapi_sched.h"
+
+
+/****************************************/
+/************API************************/
+/**************************************/
+
+/* open a scheduling contex */
+NETAPI_SCHED_HANDLE_T * netapi_schedOpen(NETAPI_T n, NETAPI_SCHED_CONFIG_T * p_config, int *p_err)
+{
+ *p_err=0;
+ NETAPI_SCHED_HANDLE_T * ph = (NETAPI_SCHED_HANDLE_T *) netapi_get_scheduler(n);
+ if(!ph) {*p_err= NETAPI_ERR_NOMEM; return NULL;}
+ if(!p_config) {*p_err= NETAPI_ERR_BAD_INPUT; return NULL;}
+ memcpy(&ph->config,p_config,sizeof(NETAPI_SCHED_CONFIG_T));
+ ph->start = netapi_getTimestamp();
+ ph->back = (void *) n;
+ if (ph->config.valid_flags & NETAPI_SCHED_DURATION)
+ {
+ if (ph->config.duration == NETAPI_SCHED_FOREVER)
+ {
+ ph->shutdown_time=(uint64_t) -1;
+ }
+ else
+ {
+ ph->shutdown_time = ph->start + ph->config.duration;
+ }
+ }
+ else ph->shutdown_time = (uint64_t) -1;
+ ph->state =NETAPI_SCHED_STATE_ACTIVE;
+ return(ph);
+
+}
+
+/* re-configure a scheduling context */
+int netapi_schedControl(NETAPI_SCHED_HANDLE_T *s, NETAPI_SCHED_CONFIG_T *p_config, int *p_err)
+{
+ /* not implemented */
+
+ return 0;
+}
+
+
+/* main entry point. caller gives up control to scheduler */
+int netapi_schedWaitForEvents(NETAPI_SCHED_HANDLE_T *s, int *p_err)
+{
+ int err;
+ *p_err=0;
+ unsigned long long t = netapi_getTimestamp();
+ int next_house;
+
+ next_house = s->config.interval;
+ printf(">entering scheduling loop @%llx until %llx . interval=%x, (1st house=%lx)\n", t, s->shutdown_time,
+ s->config.interval, next_house);
+ /* loop for duration or until shutdown */
+ for(;t< s->shutdown_time;)
+ {
+ t = netapi_getTimestamp();
+ next_house -=1;
+ //poll all pktio channels we have open in RX mode
+ pktio_pollAll((NETAPI_T) s->back, NULL, &err);
+
+ //poll pktlib garbage collections for registered heaps..
+ netapi_pollHeapGarbage((NETAPI_T) s->back);
+
+ //todo timers (local and global)
+ netapi_TimerGroupPollAll((NETAPI_T) s->back, NETAPI_TIMER_FITLER_ALL, 100000);
+
+ //poll NETCP/PA control channels
+ netapi_netcpPoll((NETAPI_T) s->back);
+
+ //see if time to do a house keeping callback
+ if ((s->config.valid_flags & NETAPI_SCHED_CBV) && s->config.house_cb)
+ if (next_house<=0)
+ {
+ s->config.house_cb(s);
+ next_house = s->config.interval;
+ }
+ //see if we were closed and/or its time to close
+ if (s->state!= NETAPI_SCHED_STATE_ACTIVE)
+ { s->state=NETAPI_SCHED_STATE_SHUT; break;}
+ }
+ return 1;
+}
+
+/* shutdown scheduler context */
+int netapi_schedShutdown(NETAPI_SCHED_HANDLE_T * s, NETAPI_SCHED_SHUTDOWN_T * p_close, int * p_err)
+{
+ *p_err=0;
+ s->state=NETAPI_SCHED_STATE_SHUTTING; //say we are closing
+
+ return 1;
+}
+
+
diff --git a/ti/runtime/netapi/src/netapi_timer.c b/ti/runtime/netapi/src/netapi_timer.c
--- /dev/null
@@ -0,0 +1,238 @@
+/*******************************
+ * FILE: netapi_timer.c
+ * Purpose: implementation of user space timers
+ **************************************************************
+ * FILE: netapi.c
+ *
+ * DESCRIPTION: user space timers main source file for user space transport
+ * library
+ *
+ * REVISION HISTORY: rev 0.0.1
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ***************************************************************/
+#include "netapi.h"
+#include "netapi_timer.h"
+#include "timer_loc.h"
+
+
+/*******************************************************************
+ * hash function: returns cell to place timer object in
+ *
+ ******************************************************************/
+/* static */ int our_hash(
+ unsigned long long ct,
+ int n_cells,
+ unsigned int cell_width)
+{
+int c;
+ //simple hash function
+ c= (ct/cell_width) % n_cells;
+ return c;
+
+}
+
+//iterator on TIMER_LIST_T
+NETAPI_TIMER_T netapi_TimerGetFirst( NETAPI_TIMER_LIST_T list)
+{ return (NETAPI_TIMER_T) ((TIM_LIST_T *)list)->head; }
+
+NETAPI_TIMER_T netapi_TimerGetNext( NETAPI_TIMER_LIST_T list,NETAPI_TIMER_T prev)
+{return prev ? (NETAPI_TIMER_T) ((TIM_T*) prev)->next:NULL ;}
+
+//return cookie associated with timer object
+void * netapi_TimerGetCookie(NETAPI_TIMER_T timer)
+{ return ((TIM_T*) timer)->cookie; }
+
+//return timeer value associated with timer object
+unsigned long long netapi_TimerGetTs(NETAPI_TIMER_T timer)
+{ return ((TIM_T*) timer)->t; }
+
+#if 0
+//timer callback
+typedef void (*NETAPI_TIMER_CB_T) (
+ NETAPI_TIMER_GROUP_HANDLE_T th,
+ int n_fired, //# timers fired
+ NETAPI_TIMER_LIST_T fired_list,
+ uint64_t currentTime);
+#endif
+
+static TIMER_GROUP_T temp_g; //temp. todo: put inot netHandle
+
+//create a timer group
+NETAPI_TIMER_GROUP_HANDLE_T netapi_TimerGroupCreate(
+ NETAPI_T netHandle,
+ char * name,
+ NETAPI_TIMER_CB_T cb,
+ int local, //1 if timers local to thread
+ int exp2cancel,//1 if expect to cancel
+ int cell_width,
+ int maxTimers,
+ int *pErr)
+{
+ int ret= tim_group_create(&temp_g, TUNE_NETAPI_NUM_TIMER_CELLS, maxTimers);
+ if (!ret) {*pErr = NETAPI_ERR_NOMEM; return NULL;}
+ *pErr=0;
+ temp_g.cb = cb;
+ temp_g.local = local;
+ temp_g.exp2cancel= exp2cancel;
+ temp_g.cell_width=cell_width;
+ temp_g.h = netHandle;
+ temp_g.last_polled=(netapi_getTimestamp()/cell_width) * cell_width + (cell_width-1);
+ printf(">timer group %s created. width = %d (ticks)\n", name, cell_width);
+ return (NETAPI_TIMER_GROUP_HANDLE_T) &temp_g;
+}
+
+//open a [global] timer group
+NETAPI_TIMER_GROUP_HANDLE_T netapi_TimerGroupOpen(
+ NETAPI_T netHandle,
+ NETAPI_TIMER_CB_T cb,
+ int *pErr)
+{
+printf(">timer group open not implemented \n");
+
+}
+
+//start an individual timer
+NETAPI_TIMER_T netapi_TimerGroupStartTimer(
+ NETAPI_TIMER_GROUP_HANDLE_T th,
+ void * cookie,
+ uint64_t offs2fire, //offset in group ticks
+ int * pErr)
+{
+TIM_T * timer_obj;
+unsigned long long ct= netapi_getTimestamp() + offs2fire* ((TIMER_GROUP_T*) th)->cell_width;
+int cell;
+*pErr=0;
+
+//find cell where to insert
+cell = our_hash(ct,((TIMER_GROUP_T*) th)->n_cells , ((TIMER_GROUP_T*) th)->cell_width);
+
+//get object and insert into this cell
+timer_obj =tim_set(
+ &((TIMER_GROUP_T*) th)->cells[cell],
+ &((TIMER_GROUP_T*) th)->free ,
+ ct,
+ cookie,
+ pErr);
+if (!timer_obj) {return NULL;}
+printf(">timer: setting timer %x for %lld ticks -> hased to cell %d\n",cookie, ct,cell);
+return (NETAPI_TIMER_T) timer_obj;
+}
+
+//Cancel a timer
+void netapi_TimerGroupCancel(
+ NETAPI_TIMER_GROUP_HANDLE_T th,
+ NETAPI_TIMER_T timerId,
+ int *pErr)
+{
+ tim_cancel((TIM_T *) timerId, pErr);
+}
+
+//close an opened timer group
+void netapi_TimerGroupClose(
+ NETAPI_TIMER_GROUP_HANDLE_T th,
+ int *pErr){}
+
+//delete atimer group
+void netapi_TimerGroupDelete(
+ NETAPI_TIMER_GROUP_HANDLE_T th,
+ int *pErr) {printf(">timer group delete not implemented\n");}
+
+//extract netapi handle from timer group handle
+NETAPI_T netap_TimerGroupGetNH( NETAPI_TIMER_GROUP_HANDLE_T th) { return ((TIMER_GROUP_T*) th)->h; }
+
+
+//-----for timer debuggingi-------
+struct
+{
+//last poll stats
+int n_tot;
+int c_seen;
+
+int max_c_seen;
+int max_n_tot;
+
+} timer_poll_stats;
+void dump_poll_stats(void)
+{
+ printf("debug timer poll> n_tot=%d c_seen=%d mnt=%d mcs=%d\n",
+ timer_poll_stats.n_tot, timer_poll_stats.c_seen,
+ timer_poll_stats.max_n_tot, timer_poll_stats.max_c_seen);
+}
+//-------end timer debugging----
+
+//poll a specific timer group
+int netapi_TimerGroupPoll(NETAPI_TIMER_GROUP_HANDLE_T th, int maxTimers)
+{
+unsigned long long ct= netapi_getTimestamp();
+unsigned long long i;
+int cell;
+TIM_LIST_T res;
+int n;
+int n_tot=0;
+int c_seen=0;
+
+ for(i=((TIMER_GROUP_T*) th)->last_polled; (i<= ct) && (n_tot<maxTimers); )
+ {
+ cell = our_hash(i,((TIMER_GROUP_T*) th)->n_cells , ((TIMER_GROUP_T*) th)->cell_width);
+ tim_return_fired_list(&((TIMER_GROUP_T*) th)->cells[cell],
+ &res,
+ &((TIMER_GROUP_T*) th)->free,
+ i,
+ &n);
+ if (n)
+ {
+ ((TIMER_GROUP_T*) th)->cb(th, n, (NETAPI_TIMER_LIST_T) &res, ct);
+ tim_return_free(&((TIMER_GROUP_T*) th)->free,&res,n);
+ n_tot+=n;
+ }
+ i += ((TIMER_GROUP_T*) th)->cell_width;
+ c_seen+=1;
+ }
+ ((TIMER_GROUP_T*) th)->last_polled = i;
+ timer_poll_stats.n_tot = n_tot;
+ timer_poll_stats.c_seen = c_seen;
+ if (n_tot > timer_poll_stats.max_n_tot) timer_poll_stats.max_n_tot = n_tot;
+ if (c_seen > timer_poll_stats.max_c_seen) timer_poll_stats.max_c_seen = c_seen;
+ return n_tot;
+}
+
+//poll all timers
+int netapi_TimerGroupPollAll(NETAPI_T nh, NETAPI_TIMER_FILTER_T f, int maxTimers)
+{
+ //todo: use filters and poll global, local lists in nh
+ netapi_TimerGroupPoll(&temp_g, maxTimers);
+ return 0;
+}
+
+
diff --git a/ti/runtime/netapi/src/netapi_util.h b/ti/runtime/netapi/src/netapi_util.h
--- /dev/null
@@ -0,0 +1,55 @@
+/******************************************************
+ * File: netapi_util.h
+ * Purpose: misc utilites
+ **************************************************************
+ * FILE: netapi_util.h
+ *
+ * DESCRIPTION: netapi utility header file for user space transport
+ * library
+ *
+ * REVISION HISTORY: rev 0.0.1
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ *****************************************************/
+#ifndef __NETAPI_UTIL__H
+#define __NETAPI_UTIL__H
+/* timing */
+static inline unsigned long netapi_timing_start(void)
+{
+ volatile int vval;
+ //read clock
+ asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(vval));
+ return vval;
+}
+#define netapi_timing_stop netapi_timing_start
+
+#endif
diff --git a/ti/runtime/netapi/src/netapi_vm.c b/ti/runtime/netapi/src/netapi_vm.c
--- /dev/null
@@ -0,0 +1,296 @@
+
+/******************************************************************************
+ * FILE netapi_vm.c
+ * PURPOSE: Memory allocator for NETAPI and related utilities
+ * -- using MSMC for descriptors/buffers (current), use CMA (future)
+ ******************************************************************************
+ * FILE NAME: netapi_vm.c
+ *
+ * DESCRIPTION: Memory allocator for netapi
+ * This is only a permanent memory allocator.
+ *
+ * REVISION HISTORY:
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <ti/drv/nwal/nwal.h>
+#include "netapi_vm.h"
+
+
+
+/***********************RAW MEMORY ALLOCATION & TRANSLATION*************************/
+/* Macro to align x to y */
+#define align(x,y) ((x + y) & (~y))
+
+uint8_t *netapi_VM_mem_start_phy = (uint8_t*)0;
+uint8_t *netapi_VM_mem_start = (uint8_t*)0;
+
+static uint8_t *netapi_VM_mem_end = (uint8_t*)0;
+static uint8_t *netapi_VM_mem_alloc_ptr = (uint8_t*)0;
+static uint32_t netapi_VM_mem_size = 0;
+
+
+
+/* File descriptor for /dev/mem */
+static int dev_mem_fd;
+
+nwal_Bool_t netapi_VM_memAllocInit
+(
+ uint8_t *addr, /* Physical address */
+ uint32_t size /* Size of block */
+)
+{
+ void *map_base;
+
+ if((dev_mem_fd = open("/dev/mem", (O_RDWR | O_SYNC))) == -1)
+ {
+ printf("netapi_VM_memAllocInit: Failed to open \"dev/mem\" err=%s\n",
+ strerror(errno));
+ return nwal_FALSE;
+ }
+
+ map_base = netapi_VM_memMap ((void *)addr, size);
+
+ if (!map_base)
+ {
+ printf("netapi_VM_memAllocInit: Failed to mmap addr (0x%x)", addr);
+ return nwal_FALSE;
+ }
+
+ printf("netapi_VM_memAllocInit: Phy Addr %x Memory (%d bytes) mapped at address %p.\n", addr,size, map_base);
+
+ netapi_VM_mem_alloc_ptr = netapi_VM_mem_start = map_base;
+ netapi_VM_mem_size = size;
+ netapi_VM_mem_end = netapi_VM_mem_start + netapi_VM_mem_size;
+ netapi_VM_mem_start_phy = addr;
+ return nwal_TRUE;
+}
+
+void* netapi_VM_memAlloc
+(
+ uint32_t size,
+ uint32_t align
+)
+{
+ uint32_t key;
+ uint8_t *alloc_ptr;
+ void *p_block =NULL;
+
+ Osal_stubCsEnter();
+ alloc_ptr = (uint8_t*)align((uint32_t)netapi_VM_mem_alloc_ptr, align);
+ if ((alloc_ptr + size) < netapi_VM_mem_end)
+ {
+ p_block =(void *)alloc_ptr;
+ netapi_VM_mem_alloc_ptr = alloc_ptr + size;
+ Osal_stubCsExit(key);
+ memset (p_block, 0, size);
+ }
+ else
+ {
+ Osal_stubCsExit(key);
+ }
+ return p_block;
+}\r
+uint32_t xtraLogs=0;
+/* Api to map the give physical address to virtual memory space */
+void *netapi_VM_memMap
+(
+ void *addr, /* Physical address */
+ uint32_t size /* Size of block */
+)
+{
+ void *map_base,*virt_addr,*tmpAddr;
+ uint32_t page_sz;
+ long retval;\r
+ uint32_t mask = (size-1);\r
+ uint32_t offset;
+
+ retval = sysconf(_SC_PAGE_SIZE);
+ if (retval == -1)
+ {
+ printf("netapi_VM_memMap: Failed to get page size err=%s\n",
+ strerror(errno));
+ return (void *)0;
+ }
+
+ page_sz = (uint32_t)retval;
+
+ if (size%page_sz)
+ {
+ printf("netapi_VM_memMap: error: block size not aligned to page size\n");
+ return (void *)0;
+ }
+
+ if ((uint32_t)addr%page_sz)
+ {
+ printf("netapi_VM_memMap: error: addr not aligned to page size\n");
+ return (void *)0;
+ }
+
+ map_base = mmap(0, size, (PROT_READ|PROT_WRITE), MAP_SHARED, dev_mem_fd, (off_t)addr & ~mask);
+ if(map_base == (void *) -1)
+ {
+ printf("netapi_VM_memMap: Failed to mmap \"dev/mem\" err=%s\n",
+ strerror(errno));
+ return (void *)0;
+ }
+ virt_addr = map_base + ((off_t)addr & mask);
+ if(xtraLogs)
+ {
+ printf("netapi_VM_memMap:Memory mapped Begin Address 0x%x Read Value: 0x%x.\n", virt_addr,*((unsigned long *)virt_addr));
+ // offset = size/(sizeof(unsigned long));
+ // tmpAddr = (unsigned long *)virt_addr + offset-1;
+ tmpAddr = (uint8_t *)virt_addr + 0x6800c;
+ printf("netapi_VM_memMap:Memory mapped End Address 0x%x Read Value: 0x%x.\n", (unsigned long *)tmpAddr ,*((unsigned long *)tmpAddr));
+ *((unsigned long *)tmpAddr) = 0x1234;
+ printf("netapi_VM_memMap:Memory mapped End Address 0x%x Write Value: 0x%x.\n", (unsigned long *)tmpAddr ,*((unsigned long *)tmpAddr));
+
+ }
+ return(virt_addr);
+}
+
+/***************************************************************/
+/*************** Memory Initilaization**************************/
+/***************************************************************/
+/* for now use msmc */
+/* Total Permanent memory required in NWAL test
+ * for Packet buffers & descriptor buffers
+ */
+#define NETAPI_PERM_MEM_SZ (TUNE_NETAPI_PERM_MEM_SZ)
+
+/* Physical address map & size for various subsystems */
+#define QMSS_CFG_BASE_ADDR CSL_QM_SS_CFG_QUE_PEEK_REGS
+#define QMSS_CFG_BLK_SZ (1*1024*1024)
+#define QMSS_DATA_BASE_ADDR 0x44020000
+#define QMSS_DATA_BLK_SZ (0x60000)
+#define SRIO_CFG_BASE_ADDR CSL_SRIO_CONFIG_REGS
+#define SRIO_CFG_BLK_SZ (132*1024)
+#define PASS_CFG_BASE_ADDR CSL_PA_SS_CFG_REGS
+#define PASS_CFG_BLK_SZ (1*1024*1024)
+
+#define MSMC_SRAM_BASE_ADDR CSL_MSMC_SRAM_REGS
+
+/* Global variables to hold virtual address of various subsystems */
+void *netapi_VM_qmssCfgVaddr;
+void *netapi_VM_qmssDataVaddr;
+void *netapi_VM_srioCfgVaddr;
+void *netapi_VM_passCfgVaddr;
+
+/* also for our descriptor area */
+unsigned char *netapi_VM_QMemLocalDescRam=NULL;
+unsigned char *netapi_VM_QMemGlobalDescRam=NULL;
+
+
+/*************************************************
+ * setup VM memory
+ ************************************************/
+int netapi_VM_memory_setup(void)
+{
+ /* (1) big chunck of memory out of MSMC -> todo, get from CMA */
+ if (netapi_VM_memAllocInit((uint8_t*)MSMC_SRAM_BASE_ADDR,
+ NETAPI_PERM_MEM_SZ) == nwal_FALSE) {
+ printf("ERROR: \"Top Level Test\" netapi_memAllocInit failed\n");
+ return (-1);
+ }
+
+
+ /* (2) Create virtual memory maps for peripherals */
+ /* (2a) QMSS CFG Regs */
+ netapi_VM_qmssCfgVaddr = netapi_VM_memMap((void*)QMSS_CFG_BASE_ADDR,
+ QMSS_CFG_BLK_SZ);
+ if (!netapi_VM_qmssCfgVaddr)
+ {
+ printf("ERROR: Failed to map QMSS CFG registers\n");
+ return (-1);
+ }
+ printf("main:QMSS_CFG_BASE_ADDR:0x%x Memory mapped at address %p.\n",(void*)QMSS_CFG_BASE_ADDR, netapi_VM_qmssCfgVaddr);
+
+ /* (2b) QMSS DATA Regs */
+ netapi_VM_qmssDataVaddr = netapi_VM_memMap((void*)QMSS_DATA_BASE_ADDR,
+ QMSS_DATA_BLK_SZ);
+ if (!netapi_VM_qmssDataVaddr)
+ {
+ printf("ERROR: Failed to map QMSS DATA registers\n");
+ return (-1);
+ }
+ printf("main:QMSS_DATA_BASE_ADDR:0x%x Memory mapped at address %p.\n",(void*)QMSS_DATA_BASE_ADDR, netapi_VM_qmssDataVaddr);
+
+ /* (2c) SRIO CFG Regs */
+ netapi_VM_srioCfgVaddr = netapi_VM_memMap((void*)SRIO_CFG_BASE_ADDR,
+ SRIO_CFG_BLK_SZ);
+ if (!netapi_VM_srioCfgVaddr)
+ {
+ printf("ERROR: Failed to map SRIO CFG registers\n");
+ return (-1);
+ }
+ printf("main:SRIO_CFG_BASE_ADDR:0x%x Memory mapped at address %p.\n",(void*)SRIO_CFG_BASE_ADDR, netapi_VM_srioCfgVaddr);
+
+ /* (2d) PASS CFG Regs */
+ netapi_VM_passCfgVaddr = netapi_VM_memMap((void*)PASS_CFG_BASE_ADDR,
+ PASS_CFG_BLK_SZ);
+ if (!netapi_VM_passCfgVaddr)
+ {
+ printf("ERROR: Failed to map PASS CFG registers\n");
+ return (-1);
+ }
+ printf("main:PASS_CFG_BASE_ADDR:0x%x Memory mapped at address %p.\n",(void*)PASS_CFG_BASE_ADDR, netapi_VM_passCfgVaddr);
+
+ /* (2e) SA ?? */
+ /*to do */
+
+ /* (2f) Timer */
+ t64_memmap(dev_mem_fd);
+
+ /* (3) Allocate 2 QM regions from continguous chunk above */
+ netapi_VM_QMemGlobalDescRam = (void *)netapi_VM_memAlloc((TUNE_NETAPI_NUM_GLOBAL_DESC *
+ TUNE_NETAPI_DESC_SIZE),
+ 128);
+ netapi_VM_QMemLocalDescRam = (void *)netapi_VM_memAlloc((TUNE_NETAPI_NUM_LOCAL_DESC *
+ TUNE_NETAPI_DESC_SIZE),
+ 128);
+ printf("local desc region=%x global desc region=%x\n", netapi_VM_QMemLocalDescRam,netapi_VM_QMemGlobalDescRam);
+
+ return 1;
+
+}
+
diff --git a/ti/runtime/netapi/src/netapi_vm.h b/ti/runtime/netapi/src/netapi_vm.h
--- /dev/null
@@ -0,0 +1,53 @@
+/************************************************
+ * FILE: netapi_vm.h
+ * PURPOSE: netapi [virtual] memory management
+ ************************************************/
+#ifndef __NETAPI_VM_H__
+#define __NETAPI_VM_H__
+#include "netapi_tune.h"
+#include "ti/drv/nwal/nwal.h"
+
+/* Function to initialize memory allocator */
+nwal_Bool_t netapi_VM_memAllocInit
+(
+ uint8_t *addr, /* Physical address */
+ uint32_t size /* Size of block */
+);
+
+/* Function to allocate memory */
+void* netapi_VM_memAlloc
+(
+ uint32_t size, /* Size of block needed */
+ uint32_t align /* Alignment of the block needed */
+);
+
+
+/* Function to map the give physical address to virtual memory space */
+void *netapi_VM_memMap
+(
+ void *addr, /* Physical address */
+ uint32_t size /* Size of block */
+);
+
+//todo: put in netapi global region somewhere
+
+/* Global variables to hold virtual address of various hw subsystems */
+extern void *netapi_VM_qmssCfgVaddr;
+extern void *netapi_VM_qmssDataVaddr;
+extern void *netapi_VM_srioCfgVaddr;
+extern void *netapi_VM_passCfgVaddr;
+
+/* Physical address of the [only] memory pool */
+extern uint8_t *netapi_VM_mem_start_phy;
+
+/* virtual address of the [only] memory pool */
+extern uint8_t *netapi_VM_mem_start;
+
+//qm regions: netapi defines two regions, 0,1
+extern unsigned char *netapi_VM_QMemLocalDescRam;
+extern unsigned char *netapi_VM_QMemGlobalDescRam;
+#define NETAPI_GLOBAL_REGION 0
+#define NETAPI_LOCAL_REGION 1
+
+#endif
+
diff --git a/ti/runtime/netapi/src/netcp_cfg.c b/ti/runtime/netapi/src/netcp_cfg.c
--- /dev/null
@@ -0,0 +1,536 @@
+/**********************************************************
+ * file: netcp_cfg.c
+ * purpose: netcp configurations routines
+ **************************************************************
+ * FILE: netcp_cfg.c
+ *
+ * DESCRIPTION: netcp configuration main source file for user space transport
+ * library
+ *
+ * REVISION HISTORY: rev 0.0.1
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ ******************************************************/
+
+#include "netapi.h"
+#include "netcp_cfg.h"
+#include "netapi_loc.h"
+
+/******************************************************************
+ ********************Utility*************************************
+*******************************************************************/
+
+
+//get a free transaction id
+static NetapiNwalTransInfo_t * netapi_GetFreeTransInfo(NETAPI_GLOBAL_T *p_global, nwal_TransID_t *pTransId)
+{
+ uint16_t count=0;
+
+ count=0;
+ while(count < TUNE_NETAPI_MAX_NUM_TRANS)
+ {
+ if((p_global->nwal_context.transInfos[count].inUse) != nwal_TRUE)
+ {
+ p_global->nwal_context.transInfos[count].inUse = nwal_TRUE;
+ *pTransId = count;
+ return(&p_global->nwal_context.transInfos[count]);
+ }
+ count++;
+ }
+
+ /* trouble. need to wait for one to free up*/
+ /* to do: handle this by forcing a poll of cntrl queue*/
+ printf("netapi>> trying to get free transaction slot but all full!!\n");
+ return NULL;
+
+}
+//internal: insert an IP address into iface
+void netcp_cfgp_insert_ip(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ nwal_IpType ipType,
+ nwalIpAddr_t *ip_addr,
+ nwalIpOpt_t *ip_qualifiers,
+ int iface_no,
+ void * handle)
+{
+int i;
+for(i=0;i<TUNE_NETAPI_MAX_IP_PER_INTERFACE;i++)
+{
+ if (!p->interfaces[iface_no].ips[i].in_use)
+ {
+ p->interfaces[iface_no].ips[i].in_use=1;
+ memcpy(&p->interfaces[iface_no].ips[i].ip_addr, ip_addr, sizeof(nwalIpAddr_t));
+ if(ip_qualifiers)
+ memcpy(&p->interfaces[iface_no].ips[i].ip_qualifiers, ip_qualifiers, sizeof(nwalIpOpt_t));
+ else
+ memset(&p->interfaces[iface_no].ips[i].ip_qualifiers, 0, sizeof(nwalIpOpt_t));
+ p->interfaces[iface_no].ips[i].ip_type = ipType;
+ p->interfaces[iface_no].ips[i].nwal_handle = handle;
+ return;
+ }
+}
+printf("netcp_cfg> add ip: no room in table\n");
+
+}
+
+
+//internal: instert interface info into global context
+void netcp_cfgp_insert_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, unsigned char * p_mac,
+ int iface_no, int state, NETCP_CFG_VLAN_T vlan, void * handle)
+{
+ if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES))
+ {
+ memset(&p->interfaces[iface_no],0,sizeof(NETCP_INTERFACE_T));
+ p->interfaces[iface_no].in_use = 1;
+ memcpy(&p->interfaces[iface_no].mac[0], p_mac,6);
+ p->interfaces[iface_no].state = state;
+ //todo p->interfaces[iface_no].vlan = vlan;
+ p->interfaces[iface_no].nwal_handle = handle; //save handle assoicated with this rule
+ }
+ else printf("netcp_cfg> insert interface # out of range %d\n",iface_no);
+
+}
+//internal: clear inteface entry
+void netcp_cfgp_delete_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no)
+{
+ if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES))
+ {
+ p->interfaces[iface_no].in_use = 0;
+ }
+ else printf("netcp_cfg> delete interface # out of range %d\n",iface_no);
+
+}
+
+
+//internal:
+
+/***********************************************************************************/
+/****************************************API****************************************/
+/***********************************************************************************/
+
+
+/*****************************************************************
+ * Queury Stats
+ ****************************************************************/
+void netcp_cfgReqStats(NETAPI_T h, NETCP_CFG_STATS_CB cb, int doClear, int *err)
+{
+nwal_RetValue ret;
+NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
+NetapiNwalTransInfo_t *pTransInfo;
+nwal_TransID_t transId;
+if ((!n) || (!cb)) {*err = NETAPI_ERR_BAD_INPUT; return ;}
+*err =0;
+
+pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &transId);
+if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return ;}
+pTransInfo->transType = NETAPI_NWAL_HANDLE_STAT_REQUEST;
+pTransInfo->netapi_handle = h;
+n->nwal_local.stats_cb = cb;
+ret = nwal_getPAStats( ((NETAPI_GLOBAL_T *) n->global)->nwal_context.nwalInstHandle,
+ transId,
+ NULL,
+ doClear);
+if(ret != nwal_OK)
+{
+ pTransInfo->inUse = nwal_FALSE;
+ *err = NETAPI_ERR_BUSY; //no resources??
+ printf("reqStats-> failed, err=%d\n",ret);
+}
+
+}
+/*****************************************************************
+ * CREATE A MAC INTERFACE
+ ****************************************************************/
+NETCP_CFG_MACIF_T netcp_cfgCreateMacInterface(
+ NETAPI_T h,
+ uint8_t *p_mac,
+ int iface_no,
+ int switch_port,
+ NETCP_CFG_ROUTE_HANDLE_T route,
+ NETCP_CFG_VLAN_T vlan, //future
+ int state, //0=down, 1=up //ignored
+ int * err
+ )
+{
+NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
+nwalMacParam_t MacInfo= {
+ 0, /* validParams */
+ 0, /* ifNum */
+ 0, /* vlanId */
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Local mac */
+ NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE, /* Continue parsing to next route for match */
+ NWAL_NEXT_ROUTE_FAIL_ACTION_HOST, /* For next route fail action by default is route to host */
+ CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */
+ QMSS_PARAM_NOT_SPECIFIED /* Use default queue configured to NWAL if packet is routed to host */
+};
+
+nwal_RetValue retValue;
+NetapiNwalTransInfo_t *pTransInfo;
+nwal_TransID_t trans_id;
+
+ if ((!n) || (!p_mac)) {*err = NETAPI_ERR_BAD_INPUT; return NULL;}
+ *err =0;
+
+ pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
+ if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return NULL;}
+ pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;
+ pTransInfo->netapi_handle = h;
+
+ /* set up MacInfo */
+ memcpy(&MacInfo.macAddr,p_mac,6);
+ /* todo: vlan */
+ MacInfo.ifNum = switch_port; /* todo: check for 0/1 relative*/
+
+#if 0 //todo
+ if (route != NULL)
+ {
+ MacInfo.appRxPktFlowId = ((NETCP_CFG_FLOW_T *)(route.flow))->flowid;
+ MacInfo.appRxPktQueue = PKTIO_GET_Q(route->p_dest_q);
+ //handle action ??
+ }
+#endif
+ pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
+ retValue = nwal_setMacIface( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
+ trans_id,
+ (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no),
+ &MacInfo,
+ &pTransInfo->handle);
+ if(retValue != nwal_OK)
+ {
+ *err = NETAPI_ERR_NWAL_ERR0;
+ printf ("ERROR: nwal_setMacIface returned Error Code %d\n",
+ retValue);
+ pTransInfo->inUse = nwal_FALSE;
+ return NULL;
+ }
+ //pTransInfo->inUse = nwal_FALSE;
+ printf ("MAC Open sent with trans_id: %d\n",trans_id);
+
+ //wait here until its done since scheduler isn't running yet most likely..
+ // todo: make this handled by scheduler poll later ??
+ if(trans_id != NWAL_TRANSID_SPIN_WAIT)
+ {
+ n->nwal_local.numPendingCfg++;
+ while ((volatile) n->nwal_local.numPendingCfg)
+ {
+ // if response is there, then this poll squirts out in the CTl poll callback,
+ // which handles the rest (including decrmenting #pending!!
+ nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
+ }
+ }
+ printf ("MAC i/f added\n");
+ netcp_cfgp_insert_mac(&netapi_get_global()->nwal_context,
+ p_mac, iface_no, state,vlan,
+ (void *) pTransInfo->handle);
+ pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
+ pTransInfo->inUse = nwal_FALSE;
+ return NULL;
+}
+
+
+/*****************************************************************/
+/***************Delete a mac interface****************************/
+/*****************************************************************/
+void netcp_cfgDelMac(NETAPI_T h,int iface_no, int *err)
+{
+
+ *err =0;
+
+ netcp_cfgp_delete_mac(&netapi_get_global()->nwal_context, iface_no);
+ printf("netcp_cfg> del mac not fully implemented \n");
+ return;
+}
+
+
+/*****************************************************************/
+/***************Add IP to MAC interface****************************/
+/*****************************************************************/
+NETCP_CFG_IP_T netcp_addIp(
+ NETAPI_T h,
+ int iface_no,
+ nwal_IpType ipType,
+ nwalIpAddr_t * ip_addr,
+ nwalIpOpt_t * ip_qualifiers,
+ NETCP_CFG_ROUTE_HANDLE_T route, //NULL for default
+ int * err
+ )
+{
+NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
+void * n_handle;
+nwalIpParam_t nwalIpParam= {
+ pa_IPV4, /* IP Type */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Dest IP */
+ { 0x0,0,0,0},/* IP Options */
+ NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE, /* Continue parsing to next route for match */
+ NWAL_NEXT_ROUTE_FAIL_ACTION_HOST, /* For next route fail action by default is route to host */
+ CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */
+ QMSS_PARAM_NOT_SPECIFIED /* Use default queue configured to NWAL if packet is routed to host */
+};
+nwal_RetValue retValue;
+NetapiNwalTransInfo_t *pTransInfo;
+nwal_TransID_t trans_id;
+
+
+ //verify that iface has been configurred
+ if ((iface_no<0) || (iface_no>= TUNE_NETAPI_MAX_INTERFACES)) {*err = NETAPI_ERR_BAD_INPUT; return NULL;}
+
+ if(netapi_get_global()->nwal_context.interfaces[iface_no].in_use)
+ {
+ n_handle = netapi_get_global()->nwal_context.interfaces[iface_no].nwal_handle;
+ }
+ else
+ {
+ *err = NETAPI_ERR_BAD_INPUT;
+ return NULL;
+ }
+
+ //get a transaction object for config action
+ pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
+ if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return NULL;}
+ pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;
+ pTransInfo->netapi_handle = h;
+
+ //build nwalIpParam
+ memcpy(&nwalIpParam.locIpAddr,ip_addr, sizeof(nwalIpAddr_t));
+ nwalIpParam.ipType=ipType;
+ if(route)
+ {
+ //todo: support app defined routes
+ }
+ else{} //use nwal defaults
+ if (ip_qualifiers)
+ memcpy(&nwalIpParam.ipOpt,ip_qualifiers, sizeof(nwalIpOpt_t));
+ else
+ memset(&nwalIpParam.ipOpt,0, sizeof(nwalIpOpt_t));
+
+ //perform config action
+ pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
+ retValue = nwal_setIPAddr( netapi_get_global()->nwal_context.nwalInstHandle,
+ trans_id,
+ (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_IP | iface_no),
+ n_handle,
+ &nwalIpParam,
+ &pTransInfo->handle);
+
+ if(retValue != nwal_OK)
+ {
+ *err = NETAPI_ERR_NWAL_ERR0;
+ printf ("ERROR: nwal_setMacIface returned Error Code %d\n",
+ retValue);
+ pTransInfo->inUse = nwal_FALSE;
+ return NULL;
+ }
+ //pTransInfo->inUse = nwal_FALSE;
+ printf ("MAC Open sent with trans_id: %d\n",trans_id);
+
+ //wait here until its done since scheduler isn't running yet most likely..
+ // todo: make this handled by scheduler poll later ??
+ if(trans_id != NWAL_TRANSID_SPIN_WAIT)
+ {
+ n->nwal_local.numPendingCfg++;
+ while ((volatile) n->nwal_local.numPendingCfg)
+ {
+ // if response is there, then this poll squirts out in the CTl poll callback,
+ // which handles the rest (including decrmenting #pending!!
+ nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
+ }
+ }
+ printf ("IP added\n");
+ netcp_cfgp_insert_ip(&netapi_get_global()->nwal_context, ipType,
+ ip_addr, ip_qualifiers, iface_no,
+ pTransInfo->handle);
+ pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
+ pTransInfo->inUse = nwal_FALSE;
+ return NULL;
+
+}
+
+
+
+/*************************************************************************/
+/*********************************INTERNAL*******************************/
+/************************************************************************/
+
+/***************************************************************
+ ********************METCP CMD Reply Callback******************
+ ***************************************************************/
+void netapi_NWALCmdCallBack (nwal_AppId appHandle,
+ uint16_t trans_id,
+ nwal_RetValue ret)
+{
+ NetapiNwalTransInfo_t * p_trans;
+ NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;
+
+ if(trans_id == NWAL_TRANSID_SPIN_WAIT)
+ {
+ printf("ERROR: callback found SPIN_WAIT transaction id. SO CANT FIND OUT WHO WE ARE]n");
+ netapi_get_global()->nwal_context.numBogusTransIds++;
+ return;
+ }
+
+ p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];
+ p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;
+
+ if(ret != nwal_OK)
+ {
+ printf ("ERROR: NWALCmdCallBack returned Error Code %d\n",
+ ret);
+ //todo: atomic inc
+ netapi_get_global()->nwal_context.numCmdFail++;
+ }
+ else
+ {
+ //todo: atomic inc
+ netapi_get_global()->nwal_context.numCmdPass++;
+ switch(p_trans->transType)
+ {
+ case NETAPI_NWAL_HANDLE_TRANS_MAC:
+ {
+ if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
+ {
+ p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
+ }
+ else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
+ {
+ p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
+ }
+ break;
+ }
+ case NETAPI_NWAL_HANDLE_TRANS_IP:
+ {
+ if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
+ {
+ p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
+ }
+ else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
+ {
+ p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
+ }
+ break;
+ }
+#if 0
+ case TEST_NWAL_HANDLE_TRANS_PORT:
+ {
+ if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)
+ {
+ testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;
+ }
+ else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)
+ {
+ testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;
+ }
+ break;
+ }
+ case TEST_NWAL_HANDLE_TRANS_SEC_ASSOC:
+ {
+ if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)
+ {
+ testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;
+ }
+ else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)
+ {
+ System_printf ("Set Security Assoc Close ACK received for trans_id: %d\n",
+ testNwLocContext.transInfos[trans_id].transType,trans_id);
+ nwal_SystemFlush();
+ testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;
+ }
+ break;
+ }
+case TEST_NWAL_HANDLE_TRANS_SEC_POLICY:
+ {
+ if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)
+ {
+ testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;
+ }
+ else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)
+ {
+ System_printf ("Set Security Policy Close ACK received for trans_id: %d\n",
+ testNwLocContext.transInfos[trans_id].transType,trans_id);
+ nwal_SystemFlush();
+ testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;
+ }
+ break;
+ }
+#endif
+ default:
+ {
+ printf ("ERROR: Invalid transaction type %d for trans_id: %d\n",
+ p_trans->transType,trans_id);
+ break;
+ }
+ }
+ }
+
+ p_local->numPendingCfg--;
+
+ if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_IDLE)
+ {
+ p_trans->inUse = nwal_FALSE;
+ }
+
+}
+
+
+/*******************************************************/
+/**************stats reply callback**********************/
+/*******************************************************/
+void netapi_NWALCmdPaStatsReply (nwal_AppId appHandle,
+ nwal_TransID_t trans_id,
+ paSysStats_t *stats)
+{
+ NetapiNwalTransInfo_t * p_trans;
+ NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;
+
+ printf("stats reply for transid %d\n", trans_id);
+ if(trans_id == NWAL_TRANSID_SPIN_WAIT)
+ {
+ printf("ERROR: callback found SPIN_WAIT transaction id. SO CANT FIND OUT WHO WE ARE]n");
+ netapi_get_global()->nwal_context.numBogusTransIds++;
+ return;
+ }
+
+ p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];
+ p_trans->inUse = nwal_FALSE;
+ p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;
+
+ //save a local copy of some stuff*/
+ p_local->numL2PktsRecvd=stats->classify1.nPackets;
+ p_local->numL3PktsRecvd=stats->classify1.nIpv4Packets;
+#if 0
+ p_local->numL4PktsRecvd=stats->;
+ p_local->numL4PktsSent=stats->;
+ p_local->TxErrDrop=stats->;
+#endif
+ //callout result to application !!
+ if (p_local->stats_cb) (*p_local->stats_cb)(p_trans->netapi_handle,stats);
+
+}
+
diff --git a/ti/runtime/netapi/src/osal.c b/ti/runtime/netapi/src/osal.c
--- /dev/null
@@ -0,0 +1,570 @@
+/******************************************************************************
+ * FILE PURPOSE: Functions to OSAL related routines for running NWAL, PA, QMSS,etc
+ ******************************************************************************
+ * FILE NAME: osal.c
+ *
+ * DESCRIPTION: Functions to initialize framework resources for running NWAL
+ *
+ * REVISION HISTORY:
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* CSL RL includes */
+#include <ti/csl/cslr_device.h>
+#include <ti/csl/csl_pscAux.h>
+#include <ti/csl/csl_semAux.h>
+#include <ti/csl/csl_cacheAux.h>
+#include <ti/csl/csl_xmcAux.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "netapi_vm.h"
+#include "netapi_timer.h"
+#define System_printf printf
+
+uint32_t Osal_qmss_MallocCounter =0;
+uint32_t Osal_qmss_FreeCounter =0;
+uint32_t Osal_cppi_MallocCounter =0;
+uint32_t Osal_cppi_FreeCounter =0;
+
+
+
+/* TODO: */
+#define DNUM 0
+
+#if 0
+uint32_t globalCritkey;
+
+/* Lock to be used for critical section */
+pthread_mutex_t mutex_lock;
+
+void nwalTest_osalInit()
+{
+ pthread_mutex_init(&mutex_lock, NULL);
+ return;
+}
+
+void nwalTest_osalshutdown()
+{
+ pthread_mutex_destroy(&mutex_lock);
+ return;
+}
+
+static inline void nwalTest_osalEnterCS()
+{
+#if 0
+ pthread_mutex_lock(&mutex_lock);
+#endif
+ return;
+}
+
+static inline void nwalTest_osalLeaveCS()
+{
+
+#if 0
+ pthread_mutex_unlock(&mutex_lock);
+#endif
+ return;
+}
+
+#endif
+
+/*****************************************************************************
+ * FUNCTION PURPOSE: Cache Invalidation Routine
+ *****************************************************************************
+ * DESCRIPTION: Cache Invalidation Routine
+ *****************************************************************************/
+void Osal_invalidateCache (void *blockPtr, uint32_t size)
+{
+ /* Stub Function. TBD: Would need to handle when cache is enabled for ARM */
+ return;
+}
+
+/*****************************************************************************
+ * FUNCTION PURPOSE: Cache Writeback Routine
+ *****************************************************************************
+ * DESCRIPTION: Cache Invalidation Routine
+ *****************************************************************************/
+void Osal_writeBackCache (void *blockPtr, uint32_t size)
+{
+ /* Stub Function. TBD: Would need to handle when cache is enabled for ARM */
+ return;
+}
+
+
+void * Osal_qmssMtCsEnter()
+{
+ /* Stub Function. TBD: Would need to handle when for multi proc access
+ * To be handled once infrastructure is available from Kernel
+ */
+ return NULL;
+}
+
+
+void Osal_qmssMtCsExit(void *key)
+{
+ /* Stub Function. TBD: Would need to handle when for multi proc access
+ * To be handled once infrastructure is available from Kernel
+ */
+ return;
+}
+
+void Osal_nwalCsEnter(uint32_t *key)
+{
+ /* Stub Function. TBD: Would need to handle when for multi proc access
+ * To be handled once infrastructure is available from Kernel
+ */
+ return;
+}
+
+void Osal_nwalCsExit(uint32_t key)
+{
+ /* Stub Function. TBD: Would need to handle when for multi proc access
+ * To be handled once infrastructure is available from Kernel
+ */
+ return;
+}
+
+
+void Osal_qmssLog ( String fmt, ... )
+{
+}
+
+
+void Osal_cppiCsEnter (uint32_t *key)
+{
+
+ /* Stub Function. TBD: Would need to handle when for multi proc access
+ * To be handled once infrastructure is available from Kernel
+ */
+ return;
+}
+
+void Osal_cppiCsExit (uint32_t key)
+{
+
+ /* Stub Function. TBD: Would need to handle when for multi proc access
+ * To be handled once infrastructure is available from Kernel
+ */
+ return;
+}
+
+void Osal_cppiLog ( String fmt, ... )
+{
+}
+
+void Osal_paBeginMemAccess (Ptr addr, uint32_t size)
+{
+ /* Stub Function. TBD: Would need to handle when for multi proc access
+ * To be handled once infrastructure is available from Kernel
+ */
+
+}
+
+void Osal_paEndMemAccess (Ptr addr, uint32_t size)
+{
+ /* Stub Function. TBD: Would need to handle when for multi proc access
+ * To be handled once infrastructure is available from Kernel
+ */
+}
+
+void* Osal_qmssCsEnter ()
+{
+
+ /* Stub Function. TBD: Would need to handle when for multi proc access
+ * To be handled once infrastructure is available from Kernel
+ */
+ return(NULL);
+}
+
+void Osal_qmssCsExit (void * key)
+{
+ /* Stub Function. TBD: Would need to handle when for multi proc access
+ * To be handled once infrastructure is available from Kernel
+ */
+ return;
+}
+
+Ptr Osal_qmssMalloc (uint32_t num_bytes)
+{
+ Ptr ret;
+
+ Osal_qmss_MallocCounter++;
+ ret = malloc (num_bytes);
+ if(ret==NULL)
+ {
+ System_printf("\nERROR! QMSS Malloc failed!\n");
+ }
+
+ return ret;
+}
+
+void Osal_qmssFree (Ptr ptr, uint32_t size)
+{
+ /* Increment the free counter. */
+ Osal_qmss_FreeCounter++;
+ free(ptr);
+}
+
+Ptr Osal_cppiMalloc (uint32_t num_bytes)
+{
+ Ptr ret;
+
+ Osal_cppi_MallocCounter++;
+ num_bytes += (CACHE_L2_LINESIZE-1);
+ ret = malloc (num_bytes);
+
+ if(ret==NULL)
+ {
+ System_printf("\nERROR! CPPI Malloc failed!\n");
+ }
+
+ return ret;
+}
+
+void Osal_cppiFree (Ptr ptr, uint32_t size)
+{
+ /* Increment the free counter. */
+ Osal_cppi_FreeCounter++;
+ free(ptr);
+}
+
+void Osal_qmssBeginMemAccess (void *blockPtr, uint32_t size)
+{
+ Osal_invalidateCache(blockPtr,size);
+ return;
+}
+
+void Osal_qmssEndMemAccess (void *blockPtr, uint32_t size)
+{
+ Osal_writeBackCache(blockPtr,size);
+ return;
+}
+
+void Osal_cppiBeginMemAccess (void *blockPtr, uint32_t size)
+{
+ Osal_invalidateCache(blockPtr,size);
+ return;
+}
+
+void Osal_cppiEndMemAccess (void *blockPtr, uint32_t size)
+{
+ Osal_writeBackCache(blockPtr,size);
+ return;
+}
+
+void Osal_nwalInvalidateCache (void *blockPtr, uint32_t size)
+{
+ Osal_invalidateCache(blockPtr,size);
+ return;
+}
+
+void Osal_nwalWriteBackCache (void *blockPtr, uint32_t size)
+{
+ Osal_writeBackCache(blockPtr,size);
+ return;
+}
+
+uint32_t Osal_nwalGetCacheLineSize (void )
+{
+ /* By default assumes L2 cache line is enabled. If not return CACHE_L1D_LINESIZE */
+ return (CACHE_L2_LINESIZE);
+}
+
+/********************************************************************
+ * FUNCTION PURPOSE: Convert local address to global
+ ********************************************************************
+ * DESCRIPTION: Returns global address
+ ********************************************************************/
+
+unsigned int Osal_nwalLocToGlobAddr(unsigned int x)
+{
+ return x;
+}
+
+uint16_t Osal_nwalGetProcId (void )
+{
+ return DNUM;
+}
+uint64_t Osal_nwalGetTimeStamp(void)
+{
+ /* Stub function to return timestamp
+ */
+ return netapi_getTimestamp();
+}
+#ifdef NWAL_ENABLE_SA
+void Osal_saCsEnter (uint32_t *key)
+{
+ /* Stub Function. TBD: Would need to handle when for multi proc access
+ * To be handled once infrastructure is available from Kernel
+ */
+ ((CSL_semAcquireDirect (SA_HW_SEM)) == 0);
+ return;
+}
+
+void Osal_saCsExit (uint32_t key)
+{
+ /* Stub Function. TBD: Would need to handle when for multi proc access
+ * To be handled once infrastructure is available from Kernel
+ */
+ return;
+}
+
+
+void Osal_saMtCsEnter (uint32_t *key)
+{
+ /* Stub Function. TBD: Would need to handle when for multi proc access
+ * To be handled once infrastructure is available from Kernel
+ */
+ return;
+}
+
+void Osal_saMtCsExit (uint32_t key)
+{
+ /* Stub Function. TBD: Would need to handle when for multi proc access
+ * To be handled once infrastructure is available from Kernel
+ */
+ return;
+}
+
+void Osal_saBeginMemAccess (void *blockPtr, uint32_t size)
+{
+ Osal_invalidateCache(blockPtr,size);
+ return;
+}
+
+void Osal_saEndMemAccess (void *blockPtr, uint32_t size)
+{
+ Osal_writeBackCache(blockPtr,size);
+ return;
+}
+
+
+
+void Osal_saBeginScAccess (void* addr, uint32_t size)
+{
+ Osal_invalidateCache(addr,size);
+
+}
+
+void Osal_saEndScAccess (void* addr, uint32_t size)
+{
+ Osal_writeBackCache(addr,size);
+
+}
+
+#endif
+
+void Osal_pktLibBeginMemAccess(void* ptr, uint32_t size)
+{
+ Osal_invalidateCache(ptr,size);
+}
+
+
+void Osal_pktLibEndMemAccess(void* ptr, uint32_t size)
+{
+ Osal_writeBackCache(ptr,size);
+}
+
+
+void Osal_pktLibBeginPktAccess(Pktlib_HeapHandle heapHandle, Ti_Pkt* ptrPkt, uint32_t size)
+{
+ /* TODO: We should use the 'heapHandle' and compare it with what we got from the
+ * 'create/find' HEAP API & depending upon the comparison take appropriate action.
+ * Just for testing we are always invalidating the cache here. */
+
+ Osal_invalidateCache(ptrPkt,size);
+}
+
+
+void Osal_pktLibEndPktAccess(Pktlib_HeapHandle heapHandle, Ti_Pkt* ptrPkt, uint32_t size)
+{
+ /* TODO: We should use the 'heapHandle' and compare it with what we got from the
+ * 'create/find' HEAP API & depending upon the comparison take appropriate action.
+ * Just for testing we are always writing back the cache here. */
+
+ /* Writeback the contents of the cache. */
+ Osal_writeBackCache(ptrPkt,size);
+}
+
+
+void* Osal_pktLibEnterCriticalSection(Pktlib_HeapHandle heapHandle)
+{
+ /* TODO: We should use the 'heapHandle' and compare it with what we got from the
+ * 'create/find' HEAP API & depending upon the comparison take appropriate action.
+ * Implementations here could range from a MULTI-THREAD protection if the packets in
+ * the heap are being accessed across multiple threads or MULTI-CORE if the packets
+ * are being accessed across multiple cores and features: split and clone are used.
+ * For NWAL layer no protection required.
+ *
+ * For testing we are not doing any of this so we are simply setting it to NOOP */
+ return NULL;
+}
+
+
+void Osal_pktLibExitCriticalSection(Pktlib_HeapHandle heapHandle, void* csHandle)
+{
+ /* TODO: We should use the 'heapHandle' and compare it with what we got from the
+ * 'create/find' HEAP API & depending upon the comparison take appropriate action.
+ * Implementations here could range from a MULTI-THREAD protection if the packets in
+ * the heap are being accessed across multiple threads or MULTI-CORE if the packets
+ * are being accessed across multiple cores and features: split and clone are used.
+ * For NWAL layer no protection required..
+ *
+ * For testing we are not doing any of this so we are simply setting it to NOOP */
+ return;
+}
+
+void* Osal_qmssVirtToPhy (void *ptr)
+{
+ return (void *)(netapi_VM_mem_start_phy + ((uint8_t*)ptr - netapi_VM_mem_start));
+}
+
+void* Osal_qmssPhyToVirt (void *ptr)
+{
+ if (!ptr) return (void *) 0;
+ //todo, see if out of range of mem_start_phy and size!! (like mmu would do)
+ return (void *)(netapi_VM_mem_start + ((uint8_t*)ptr - netapi_VM_mem_start_phy));
+}
+
+/******************************************************************************
+* Function to traverse a CPPI descriptor and convert all address references
+* from virtual to physical.
+******************************************************************************/
+void* Osal_qmssConvertDescVirtToPhy(void *descAddr)
+{
+ if (!descAddr) return (void *)0;
+
+ if (Cppi_getDescType((Cppi_Desc *)QMSS_DESC_PTR(descAddr)) == Cppi_DescType_HOST)
+ {
+ Cppi_HostDesc *nextBDPtr = (Cppi_HostDesc *)QMSS_DESC_PTR(descAddr);
+ Cppi_HostDesc *prevBDPtr = 0;
+ while (nextBDPtr)
+ {
+ void *buffPtr;
+ if (nextBDPtr->buffPtr)
+ {
+ buffPtr = (void *)nextBDPtr->buffPtr;
+ nextBDPtr->buffPtr = (uint32_t)Osal_qmssVirtToPhy((void *)(nextBDPtr->buffPtr));
+ if (!(nextBDPtr->buffPtr)) return (void *)0;
+ }
+
+ if (nextBDPtr->origBuffPtr)
+ {
+ nextBDPtr->origBuffPtr = (uint32_t)Osal_qmssVirtToPhy((void *)(nextBDPtr->origBuffPtr));
+ if (!(nextBDPtr->origBuffPtr)) return (void *)0;
+ }
+
+ prevBDPtr = nextBDPtr;
+ nextBDPtr = (Cppi_HostDesc *)QMSS_DESC_PTR((nextBDPtr->nextBDPtr));
+ if (prevBDPtr->nextBDPtr)
+ {
+ prevBDPtr->nextBDPtr = (uint32_t)Osal_qmssVirtToPhy((void *)(prevBDPtr->nextBDPtr));
+ if (!(prevBDPtr->nextBDPtr)) return (void *)0;
+ }
+
+ Qmss_osalEndMemAccess(buffPtr, prevBDPtr->buffLen);
+ Qmss_osalEndMemAccess(prevBDPtr, sizeof(Cppi_HostDesc));
+ }
+ descAddr = Osal_qmssVirtToPhy(descAddr);
+ if (!descAddr) return (void *)0;
+ }
+ else if (Cppi_getDescType((Cppi_Desc *)QMSS_DESC_PTR(descAddr)) == Cppi_DescType_MONOLITHIC)
+ {
+ descAddr = Osal_qmssVirtToPhy(descAddr);
+ if (!descAddr) return (void *)0;
+ }
+ return descAddr;
+
+}
+
+
+/******************************************************************************
+* Function to traverse a CPPI descriptor and convert all address references
+* from physical to virtual.
+******************************************************************************/
+void* Osal_qmssConvertDescPhyToVirt(void *descAddr)
+{
+ if (!descAddr) return (void *)0;
+ descAddr = Osal_qmssPhyToVirt(descAddr);
+
+ if (Cppi_getDescType((Cppi_Desc *)QMSS_DESC_PTR(descAddr)) == Cppi_DescType_HOST)
+ {
+ Cppi_HostDesc *nextBDPtr = (Cppi_HostDesc *)QMSS_DESC_PTR(descAddr);
+ while (nextBDPtr)
+ {
+ Qmss_osalBeginMemAccess(nextBDPtr, sizeof(Cppi_HostDesc));
+ if (nextBDPtr->buffPtr)
+ {
+ nextBDPtr->buffPtr = (uint32_t)Osal_qmssPhyToVirt((void *)(nextBDPtr->buffPtr));
+ if (!(nextBDPtr->buffPtr)) return (void *)0;
+ }
+
+ if (nextBDPtr->origBuffPtr)
+ {
+ nextBDPtr->origBuffPtr = (uint32_t)Osal_qmssPhyToVirt((void *)(nextBDPtr->origBuffPtr));
+ if (!(nextBDPtr->origBuffPtr)) return (void *)0;
+ }
+
+ if (nextBDPtr->nextBDPtr)
+ {
+ nextBDPtr->nextBDPtr = (uint32_t)Osal_qmssPhyToVirt((void *)(nextBDPtr->nextBDPtr));
+ if (!(nextBDPtr->nextBDPtr)) return (void *)0;
+ }
+
+ Qmss_osalBeginMemAccess((void *)(nextBDPtr->buffPtr), nextBDPtr->buffLen);
+ nextBDPtr = (void *)QMSS_DESC_PTR((nextBDPtr->nextBDPtr));
+ }
+ }
+ else if (Cppi_getDescType((Cppi_Desc *)QMSS_DESC_PTR(descAddr)) == Cppi_DescType_MONOLITHIC)
+ {
+ descAddr = Osal_qmssPhyToVirt(descAddr);
+ if (!descAddr) return (void *)0;
+ }
+ return descAddr;
+}
+
+void* Osal_stubCsEnter (void)
+{
+
+
+}
+void Osal_stubCsExit (void *CsHandle)
+{
+ /* Release Semaphore using handle */
+
+
+ return;
+}
+
diff --git a/ti/runtime/netapi/src/pktio.c b/ti/runtime/netapi/src/pktio.c
--- /dev/null
@@ -0,0 +1,408 @@
+/*********************************
+ * FILE: pktio.c
+ * PURPOSE: pktio library for NETAPI
+ **************************************************************
+ * FILE: pktio.c
+ *
+ * DESCRIPTION: pktio source file for user space transport
+ * library
+ *
+ * REVISION HISTORY: rev 0.0.1
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ ********************************/
+#include "netapi.h"
+
+/*--------------------Utilites-----------------*/
+static PKTIO_HANDLE_T * pktiop_get_free_channel_slot(NETAPI_T n)
+{
+ PKTIO_HANDLE_T * pp = (PKTIO_HANDLE_T*) netapi_get_pktio_list(n);
+ int i;
+ for(i=0;i<NETAPI_MAX_PKTIO;i++)
+ {
+ if (pp->inuse != PKTIO_INUSE)
+ {
+ return pp;
+ }
+ pp+=1;
+ }
+ return NULL;
+}
+
+/*-----------------------MAIN API----------------------*/
+/* create a channel */
+PKTIO_HANDLE_T * pktio_create(NETAPI_T n, char * name,
+ PKTIO_CB cb, PKTIO_CFG_T * p_cfg, int * err)
+{
+int r = 0;
+PKTIO_HANDLE_T *p;
+uint8_t isAllocated;
+
+*err=0;
+
+if ((!p_cfg)||(!name)) {*err=NETAPI_ERR_BAD_INPUT; return NULL;}
+
+/* get a free channel handle */
+p=pktiop_get_free_channel_slot(n);
+if (!p) {*err = PKTIO_NOMEM; return (p); }
+
+p->inuse= PKTIO_INUSE;
+p->back = n;
+p->cb = cb;
+p->max_n = p_cfg->max_n;
+memcpy((char *)&p->cfg, (char*) p_cfg, sizeof(PKTIO_CFG_T));
+
+ /* create a general queue (for now). TODO: allow qnum to be passed in */
+ p->q = Qmss_queueOpen(Qmss_QueueType_GENERAL_PURPOSE_QUEUE,
+ QMSS_PARAM_NOT_SPECIFIED, &isAllocated);
+ if (p->q == (Qmss_QueueHnd) NULL)
+ {
+ printf("pktio_create: queueOpen failed\n");
+ p->inuse=0;
+ *err= NETAPI_ERR_QLLD; ///queue lld error
+ return NULL;
+ }
+ p->qInfo = Qmss_getQueueNumber(p->q);
+ if (p->cfg.flags2 & PKTIO_PKT)
+ {
+ p->use_nwal =1;
+ p->nwalInstanceHandle = netapi_return_nwal_instance_handle(n);
+ }
+ else p->use_nwal=0;
+
+ /* save name */
+ strncpy(p->name,name,
+ strlen(name)<PKTIO_MAX_NAME ?
+ strlen(name):PKTIO_MAX_NAME);
+
+ /* add name, qnum to global name list */
+ if ((strcmp(name,NETCP_RX)) && (strcmp(name,NETCP_TX)) &&
+ (p_cfg->flags1 & PKTIO_GLOBAL) )
+ {
+ //todo: make sure this succeeds..
+ netapi_add_global_pktio(n, name, &p->qInfo);
+ }
+ ((NETAPI_HANDLE_T *)n )->n_pktios+=1;
+ return p;
+}
+
+
+/***********************************************************/
+/************** open an existing channel. *****************/
+/***********************************************************/
+PKTIO_HANDLE_T * pktio_open(NETAPI_T n, char *name,
+ PKTIO_CB cb, PKTIO_CFG_T * p_cfg, int * err)
+{
+int r=0;
+PKTIO_HANDLE_T *p, *p2;
+uint8_t isAllocated;
+*err=0;
+Qmss_Queue *p_qnum;
+
+if ((!p_cfg)||(!name)) {*err=NETAPI_ERR_BAD_INPUT; return NULL;}
+
+/* get a free channel handle */
+p=pktiop_get_free_channel_slot(n);
+if (!p) {*err = PKTIO_NOMEM; return (p); }
+((NETAPI_HANDLE_T *)n)->n_pktios+=1;
+
+p->inuse= PKTIO_INUSE;
+p->back = n;
+p->cb = cb;
+p->max_n = p_cfg->max_n;
+memcpy((char *)&p->cfg, (char*) p_cfg, sizeof(PKTIO_CFG_T));
+
+/* special handling of NETCP_RX, NETCP_TX */
+if( (!strcmp(name, NETCP_RX)) || (!strcmp(name,NETCP_TX)) )
+{
+ /* these have already been opened internally, so don't search in global list */
+ p->use_nwal = 2;
+ p->q = 0;
+ p->nwalInstanceHandle = netapi_return_nwal_instance_handle(n);
+}
+else
+{
+ /* find queue in global list */
+ p_qnum = netapi_find_global_pktio(n, name);
+ if (!p_qnum )
+ {
+ printf("pktio_open: can't find %s\n",name);
+ p->inuse=0;
+ *err= NETAPI_ERR_NOTFOUND; ///queue lld error
+ return NULL;
+ }
+
+ /* open a general queue (for now). use qnum that was just found */
+ p->q = Qmss_queueOpen(Qmss_QueueType_GENERAL_PURPOSE_QUEUE,
+ p_qnum->qNum , &isAllocated);
+ if (p->q == (Qmss_QueueHnd) NULL)
+ {
+ printf("pktio_create: queueOpen failed\n");
+ p->inuse=0;
+ *err= NETAPI_ERR_QLLD; ///queue lld error
+ return NULL;
+ }
+ p->qInfo = Qmss_getQueueNumber(p->q);
+ if (p_cfg->flags2 & PKTIO_PKT)
+ {
+ p->use_nwal =1;
+ p->nwalInstanceHandle = netapi_return_nwal_instance_handle(n);
+ }
+ else p->use_nwal=0;
+}
+
+ /* save name */
+ strncpy(p->name,name,
+ strlen(name)<PKTIO_MAX_NAME ?
+ strlen(name):PKTIO_MAX_NAME);
+
+
+
+return p;
+}
+
+/***********************************************************/
+/************** control the channel ****************/
+/***********************************************************/
+void pktio_control(PKTIO_HANDLE_T * p,
+ PKTIO_CB cb,
+ PKTIO_CFG_T * p_cfg,
+ PKTIO_CONTROL_T * p_control,
+ int *err)
+{
+ if (!p) { *err=1; return;}
+ if (cb)
+ {
+ p->cb = cb;
+ }
+ if (p_control)
+ {
+ }
+ if (p_cfg)
+ {
+ p->max_n = p_cfg->max_n;
+ memcpy((char *)&p->cfg, (char*) p_cfg, sizeof(PKTIO_CFG_T));
+ }
+ *err=0;
+ return;
+}
+
+/***********************************************************/
+/*****************close ***************************/
+/***********************************************************/
+void pktio_close(PKTIO_HANDLE_T * p, int * err)
+{
+ if(!p) { *err=1; return;}
+ *err=0;
+ //Qmss_queueClose(p->q);
+ p->q=-1;
+ p->inuse=0;
+ ((NETAPI_HANDLE_T *)p->back)->n_pktios-=1;
+ return;
+}
+
+/***********************************************************/
+/*****************Delete***************************/
+/***********************************************************/
+void pktio_delete(PKTIO_HANDLE_T * p, int * err)
+{
+ if(!p) { *err=1; return;}
+ *err=0;
+ /* todo remove from name list */
+ if(p->use_nwal !=2)
+ {
+ Qmss_queueClose(p->q);
+ }
+ p->q=-1;
+ p->inuse=0;
+ ((NETAPI_HANDLE_T *)p->back)->n_pktios-=1;
+ return ;
+}
+
+
+/***********************************************************/
+/*****************send *************************/
+/***********************************************************/
+int pktio_send(PKTIO_HANDLE_T * p, Ti_Pkt *pkt, PKTIO_METADATA_T *m, int * err)
+{
+ nwalTxPktInfo_t * pPktInfo=m->u.tx_meta;
+ nwal_RetValue res;
+ *err=0;
+ if(! (p->cfg.flags1&PKTIO_W)) return 0;
+ if (p->use_nwal)
+ {
+ pPktInfo->pPkt = pkt;
+ //todo metadata
+ res=nwal_send(p->nwalInstanceHandle, nwal_HANDLE_INVALID,pPktInfo);
+ if (res != nwal_OK) *err = NETAPI_ERR_NWAL_TX_ERR -res;
+ }
+ else
+ {
+ /* process meta data */
+ Qmss_queuePushDesc (p->q, (void*)pkt);
+ }
+ return 1;
+}
+
+/***********************************************************/
+/*******************send multiple**************************/
+/***********************************************************/
+int pktio_sendMulti(PKTIO_HANDLE_T * p, Ti_Pkt * pkt[], PKTIO_METADATA_T * m[], int np, int* err)
+{
+ int r=0;
+ *err=0;
+ if(! p->cfg.flags1&PKTIO_W) return 0;
+ if (p->use_nwal)
+ {
+ for(r=0;r<np;r++)
+ {
+ nwalTxPktInfo_t *pPktInfo= m[r]->u.tx_meta;
+ nwal_RetValue res;
+ pPktInfo->pPkt = pkt[r];
+ res=nwal_send(p->nwalInstanceHandle,nwal_HANDLE_INVALID,pPktInfo);
+ if (res != nwal_OK) *err = NETAPI_ERR_NWAL_TX_ERR -res;
+ }
+ }
+ else
+ {
+ for(r=0;r<np;r++)
+ {
+ /* process meta data */
+ Qmss_queuePushDesc(p->q, (void*) pkt[r]);
+ }
+ }
+ return r;
+}
+
+/***********************************************************/
+/******************* polling **********************/
+/***********************************************************/
+
+/* poll a particular channel */
+int pktio_poll(PKTIO_HANDLE_T * p, PKTIO_POLL_T * p_poll_cfg, int * err)
+{
+int r=0;
+int n;
+Ti_Pkt * temp;
+Ti_Pkt * pkt_list[PKTIO_MAX_RECV];
+PKTIO_METADATA_T meta_s[PKTIO_MAX_RECV];
+uint64_t ts= netapi_getTimestamp(); //get_ts
+
+ if(! p->cfg.flags1&PKTIO_R) return 0;
+
+ /** poll the netcp default RX queue we squirt out below */
+ if (p->use_nwal==2)
+ {
+ /* Poll for common L2/L3 packets */
+ nwal_pollPkt(p->nwalInstanceHandle,
+ nwal_POLL_DEFAULT_GLOB_PKT_Q,
+ (uint32_t) p,
+ p->max_n,
+ QMSS_PARAM_NOT_SPECIFIED,
+ (void*) NULL);
+ }
+ /** poll a netcp RX queue. we squirt out below */
+ else if (p->use_nwal==1)
+ {
+ /* Poll an additional NETCP RX queue */
+ nwal_pollPkt(p->nwalInstanceHandle,
+ nwal_POLL_APP_MANAGED_PKT_Q,
+ (uint32_t) p,
+ p->max_n,
+ p->q,
+ (void *) NULL);
+ }
+ /* poll an IPC queue */
+ else
+ {
+ *err=0;
+ n= (p->max_n< PKTIO_MAX_RECV) ? p->max_n : PKTIO_MAX_RECV;
+ for(r=0;r<n;r++)
+ {
+ temp=(Cppi_HostDesc*)QMSS_DESC_PTR(Qmss_queuePop(p->q));
+ if(!temp) break;
+ /* process meta data */
+ pkt_list[r]= temp;
+ meta_s[r].flags1=0x1;
+ }
+ if (r) p->cb(p, pkt_list, &meta_s[0], r, ts);
+ }
+ return r;
+}
+
+/***********************************************************/
+/** poll all channels attached to this handle */
+/***********************************************************/
+int pktio_pollAll(NETAPI_T handle, PKTIO_POLL_T * p_poll_cfg, int *err)
+{
+int i=0;
+int r=0;
+int err2;
+int cnt=0;
+PKTIO_HANDLE_T *pp =( PKTIO_HANDLE_T *) netapi_get_pktio_list(handle);
+
+*err=0;
+for(i=0;i<NETAPI_MAX_PKTIO && cnt < ((NETAPI_HANDLE_T *)handle)->n_pktios;i++,pp+=1)
+{
+ if (pp->inuse != PKTIO_INUSE) continue;
+ if(!(pp->cfg.flags1&PKTIO_R)) continue;
+ r+=pktio_poll(pp, p_poll_cfg, &err2); cnt+=1;
+ if (err2) { *err = err2; break;}
+}
+return r;
+
+}
+
+/***** this is the callback we registered with NWAL for pkt reception *****/
+/* appcookie -> pktio handle */
+void netapi_NWALRxPktCallback (uint32_t appCookie,
+ uint8_t numPkts,
+ nwalRxPktInfo_t* pPktInfo,
+ uint64_t timestamp,
+ nwal_Bool_t* pFreePkt)
+{
+PKTIO_HANDLE_T * p = (PKTIO_HANDLE_T *) appCookie;
+int r=0;
+int n;
+Ti_Pkt * pkt_list[PKTIO_MAX_RECV];
+PKTIO_METADATA_T meta_s[PKTIO_MAX_RECV];
+ for(r=0;r<numPkts;r++)
+ {
+ pkt_list[r] = pPktInfo[r].pPkt;
+ meta_s[r].flags1 = PKTIO_META_RX;
+ meta_s[r].u.rx_meta = &pPktInfo[r];
+ }
+ if (r) p->cb(p, pkt_list, &meta_s[0], r, timestamp);
+
+}
+
+
diff --git a/ti/runtime/netapi/src/tim64.c b/ti/runtime/netapi/src/tim64.c
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * tim64.c : enable use of timer64 from user space
+ * (using 64 bit mode)
+ * TIMER 6
+ **************************************************************
+ * FILE: tim64.c
+ *
+ * DESCRIPTION: tim64 peripheral driver for user space transport
+ * library
+ *
+ * REVISION HISTORY: rev 0.0.1
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <termios.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include "netapi_timer.h"
+
+/* timing */
+static inline unsigned long timing_start(void)
+{
+ volatile int vval;
+ //read clock
+ asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(vval));
+ return vval;
+}
+static inline unsigned long timing_stop(void)
+{
+ volatile int vval2;
+ //read clock
+ asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(vval2));
+ return vval2;
+}
+
+
+
+#define MAP_SIZE 4096UL
+#define MAP_MASK (MAP_SIZE - 1)
+//this is for timer 6
+#define T64BASE_6 (void *)0x02260000
+volatile unsigned long * t64_virt_addr;
+static unsigned long tv_lo;
+static unsigned long tv_hi;
+
+//read
+static unsigned long long read_t64(void)
+{
+ volatile unsigned long long t1;
+ volatile unsigned long long t2;
+ unsigned long long val;
+ t1 = t64_virt_addr[0x10/4]; //lo
+ t2 = t64_virt_addr[0x14/4]; //hi
+
+ val = ((unsigned long long) t2) <<32 | t1;
+ return val;
+
+}
+
+//claibrate
+static unsigned int t64_cpu_cycle_per_tick=0;
+unsigned int cpu_cycles_sec=983040000;
+unsigned long t64_ticks_sec(void)
+{
+ if (t64_cpu_cycle_per_tick)
+ return ( cpu_cycles_sec/t64_cpu_cycle_per_tick); //ticks per/sec
+ else return 166666666;
+
+}
+static int t64_calibrate(int n)
+{
+volatile unsigned long t1;
+volatile unsigned long t2;
+volatile unsigned long long t164;
+volatile unsigned long long t264;
+int i;
+volatile int s;
+t1=timing_start();
+t164=read_t64();
+
+sleep(1);
+#if 0
+for(i=0;i<n;i++)
+{
+ s+=t164*20; s=s*(2+i);
+}
+#endif
+t264=read_t64();
+t2=timing_stop();
+t64_cpu_cycle_per_tick = (unsigned long) ((t2-t1)/(t264-t164));
+printf("calib - n=%d t2-t1=%lu t264-t164=%llu ccpt=%ld tps=%ld\n",
+ n, t2-t1, t264-t164, t64_cpu_cycle_per_tick, t64_ticks_sec());
+
+}
+
+
+/*********************************
+ * memory map t64 into user space
+ * input: pass in fd for /dev/mem
+ **********************************/
+int t64_memmap(int fd)
+{
+ off_t t64_base= (off_t) T64BASE_6;
+ void * map_base;
+ int op;
+ volatile unsigned long t1;
+ volatile unsigned long t2;
+ unsigned long long blah;
+
+
+ /* Map one page */
+ map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, t64_base & ~MAP_MASK);
+ if(map_base == (void *) -1) exit(-99);
+ printf("tim64>mapbase=Memory mapped at address %p.\n", map_base);
+ fflush(stdout);
+
+ t64_virt_addr = (long *) map_base + (t64_base & MAP_MASK);
+ printf("tim64>t64_virt_addr: Memory mapped at address %p.\n", t64_virt_addr);
+ fflush(stdout);
+ return 1;
+}
+
+
+ /*********************************
+ * start the timer64
+ ***********************************/
+int t64_start(void)
+{
+ t64_virt_addr[0x24/4]= 0x00;
+ t64_virt_addr[0x10/4]= 0x00;
+ t64_virt_addr[0x14/4]= 0x00;
+ t64_virt_addr[0x18/4]= 0xffffffff;
+ t64_virt_addr[0x1c/4]= 0xffffffff;
+ t64_virt_addr[0x20/4]= 0x80;
+ t64_virt_addr[0x24/4]= 0x03; //go
+ t64_calibrate(100000);
+ return 1;
+}
+
+
+#ifdef TEST_DRIVER
+int main(int argc, char **argv) {
+ int fd;
+ off_t t64_base= (off_t) T64BASE_6;
+ void * map_base;
+ int op;
+volatile unsigned long t1;
+volatile unsigned long t2;
+unsigned long long blah;
+
+ if(argc < 2) {
+ fprintf(stderr, "Usage: tim64 start|stop|read \n"
+ );
+ exit(1);
+ }
+ if (!strcmp(argv[1],"start")) op=0;
+ else if (!strcmp(argv[1],"stop")) op =1;
+ else if (!strcmp(argv[1],"read")) op =2;
+ else { fprintf(stderr, "Usage: tim64 start|stop|read \n"
+ );
+ exit(1);
+ }
+
+
+ if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) exit(-99);
+ printf("/dev/mem opened.\n");
+ fflush(stdout);
+
+ /* Map one page */
+ map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, t64_base & ~MAP_MASK);
+ if(map_base == (void *) -1) exit(-99);
+ printf("mapbase=Memory mapped at address %p.\n", map_base);
+ fflush(stdout);
+
+ t64_virt_addr = (long *) map_base + (t64_base & MAP_MASK);
+ printf("t64_virt_ddr: Memory mapped at address %p.\n", t64_virt_addr);
+ fflush(stdout);
+
+ switch(op)
+ {
+ case(0):
+ default:
+ //start
+ t64_virt_addr[0x24/4]= 0x00;
+ t64_virt_addr[0x10/4]= 0x00;
+ t64_virt_addr[0x14/4]= 0x00;
+ t64_virt_addr[0x18/4]= 0xffffffff;
+ t64_virt_addr[0x1c/4]= 0xffffffff;
+ t64_virt_addr[0x20/4]= 0x80;
+ t64_virt_addr[0x24/4]= 0x03; //go
+ t64_calibrate(100000);
+ break;
+ case(1):
+ //stop
+ t64_virt_addr[0x24/4]= 0x00;
+ break;
+ case(2):
+ //read
+ tv_lo= t64_virt_addr[0x10/4];
+ tv_hi= t64_virt_addr[0x14/4];
+t1=timing_start();
+blah = read_t64();
+t2=timing_stop();
+
+ printf("t64 = %x%x %llx (read_t64 takes %d ticks)\n",tv_hi,tv_lo,blah, t2-t1);
+ break;
+ }
+ if(munmap(map_base, MAP_SIZE) == -1) exit(-99);
+ close(fd);
+ return 0;
+}
+#endif
diff --git a/ti/runtime/netapi/src/timer_loc.h b/ti/runtime/netapi/src/timer_loc.h
--- /dev/null
@@ -0,0 +1,79 @@
+/********************************************************
+ * File: timer_loc.h
+ * Purpose: local definitions for timer module
+ ******************************************************/
+
+#ifndef __TIMER_LOC__H
+#define __TIMER_LOC__H
+
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+
+/**********************************
+ * A timer object
+ * active timrs have non zero cookie
+ **********************************/
+struct TIM_tag;
+typedef struct TIM_tag
+{
+struct TIM_tag * next;
+void * cookie;
+unsigned long long t;
+} TIM_T;
+
+//a list of timers
+typedef struct TIM_LIST_tAG
+{
+ TIM_T * head;
+ TIM_T * tail;
+} TIM_LIST_T;
+
+
+typedef struct TIMER_GROUP_Tag
+{
+ NETAPI_T h; //back pointer
+ int n_cells; //#of cells (hash entries
+ int n_timers; //# of timer objects
+ int cell_width; //size of each cell (mask)
+ TIM_LIST_T free; //free list of timer objects
+ TIM_LIST_T * cells;//active timers
+ unsigned long long last_polled;
+ NETAPI_TIMER_CB_T cb;
+ int local;
+ int exp2cancel;
+} TIMER_GROUP_T;
+
+/**********************INTERNAL API*******************/
+//create a timer group
+int tim_group_create(TIMER_GROUP_T *g, int n_cells, int n_timers);
+
+//return a list of timer objects to free list
+void tim_return_free(TIM_LIST_T *ftl, TIM_LIST_T *p, int n);
+
+//get a free timer oblject
+TIM_T * tim_get_free(TIM_LIST_T *ftl, void *cookie, unsigned long long t);
+
+//return a list of timers that have fired
+void tim_return_fired_list(TIM_LIST_T *tl, TIM_LIST_T * pr, TIM_LIST_T * ftl, unsigned long long t, int * p_nf);
+
+
+//cancel a timer
+void tim_cancel(TIM_T * p, int *pErr);
+
+//insert an active timer into hash cell
+TIM_T *tim_set(TIM_LIST_T *tl, TIM_LIST_T *free_tl, unsigned long long t, void *cookie, int *pErr);
+
+/********************************************************/
+/********************internal control of hw*************/
+/******************************************************/
+//memmap t64 registers. fd is open(/dev/mem)
+int t64_memmap(int fd);
+
+//start the timer
+int t64_start(void);
+
+
+#endif
diff --git a/ti/runtime/netapi/src/timlist.c b/ti/runtime/netapi/src/timlist.c
--- /dev/null
@@ -0,0 +1,346 @@
+/******************************************
+ * FILE:timlist.c
+ * Purpose: timer low level primitives
+ ***********************************************
+* FILE:timlist.c
+ *
+ * DESCRIPTION: netapi timer library source file for user space transport
+ * library
+ *
+ * REVISION HISTORY: rev 0.0.1
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ ***************************************/
+#include "netapi_timer.h"
+#include "timer_loc.h"
+#include "netapi_err.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+
+//create a timer group
+int tim_group_create(TIMER_GROUP_T *g, int n_cells, int n_timers)
+{
+char * mem= (char *) malloc(n_timers * sizeof (TIM_T));
+if (!mem) return -1;
+g->n_cells = n_cells;
+tim_build_free(&g->free, mem, sizeof(TIM_T) * n_timers);
+g->cells=(TIM_LIST_T *) malloc(n_cells * sizeof(TIM_LIST_T));
+if (!g->cells) {free(mem); return -1;}
+g->n_timers=n_timers;
+g->last_polled=0;
+return 1;
+}
+
+//return as single timer to end of free list, zero cookie, etc
+void tim_return_single_free(TIM_LIST_T *ftl, TIM_T *p)
+{
+TIM_T * pt;
+int i;
+pt = ftl->tail;
+if (!pt)
+{
+ftl->head=p;
+ftl->tail=p;
+}
+else
+{
+pt->next=p;
+ftl->tail = p;
+}
+ p->t=0LL;
+ p->cookie=NULL;
+ p->next=NULL;
+}
+
+
+//return a list of N timers to end of [free] list. zero cookie, etc
+void tim_return_free(TIM_LIST_T *ftl, TIM_LIST_T *p, int n)
+{
+TIM_T * pt;
+int i;
+pt = ftl->tail;
+if (!pt)
+{
+ftl->head=p->head;
+ftl->tail=p->tail;
+}
+else
+{
+pt->next=p->head;
+ftl->tail = p->tail;
+}
+
+pt= p->head;
+for(i=0;i<n;i++)
+{
+ pt->t=0LL;
+ pt->cookie=NULL;
+ pt= pt->next;
+}
+ftl->tail->next=NULL;
+}
+
+//get a [free] entry from front of a list
+TIM_T * tim_get_free(TIM_LIST_T *tl, void *cookie, unsigned long long t)
+{
+TIM_T *p = tl->head;
+if (p)
+{
+ tl->head=p->next;
+ p->next=NULL;
+ p->cookie = cookie;
+ p->t = t;
+ if (!tl->head) tl->tail=NULL;
+}
+return p;
+}
+
+//build a timer list from chunk of memory
+int tim_build_free(TIM_LIST_T *tl, char *p_mem, int mem_size)
+{
+TIM_T * p = (TIM_T*) p_mem;
+TIM_T * p_old = (TIM_T*) p_mem;
+int i=0;
+tl->head = p;
+while(mem_size)
+{
+ p_old = p;
+ p->cookie=NULL;
+ p->t = 0LL;
+ mem_size -= sizeof(TIM_T);
+ p+=1;
+ i+=1;
+ p_old->next=p;
+}
+p_old->next = NULL;
+tl->tail = p_old;
+return i;
+}
+
+//return a list of timers that have fired
+void tim_return_fired_list(TIM_LIST_T *tl, TIM_LIST_T * pr, TIM_LIST_T * ftl, unsigned long long t, int * p_nf)
+{
+int i=0;
+int got_start=0;
+int found_end=0;
+TIM_T * p_last, *p, *temp_p_next;
+TIM_LIST_T p_free={NULL,NULL};
+pr->head=pr->tail=NULL;
+if (! tl->head) { *p_nf=0; return ;}
+
+p = tl->head;
+p_last= NULL;
+
+for(i=0;p;)
+{
+ if(p->t <= t)
+ {
+ if(!got_start)
+ {
+ if(p->cookie)
+ {
+ //start results chain
+ got_start=1;
+ pr->head=pr->tail = p;
+ i+=1;
+ p_last=p;
+ p=p->next;
+ continue;
+ }
+ else //skip over cancelled timer..
+ {
+ //skip & free
+ if (p_last){
+ p_last->next=p->next;
+ }
+ else {
+ tl->head = p->next;
+ }
+ temp_p_next=p->next;
+ tim_return_single_free(ftl,p);
+ p=temp_p_next;
+ /*keep p_last the same! */
+ continue;
+ }
+ }
+ else
+ {
+ if(!p->cookie)
+ {
+ //skip & free
+ if (p_last){
+ p_last->next=p->next;
+ }
+ else {
+ tl->head = p->next;
+ }
+ temp_p_next=p->next;
+ tim_return_single_free(ftl,p);
+ p=temp_p_next;
+ /*keep p_last the same! */
+ continue;
+ }
+ else { //valid entry for list.
+ p_last=p;
+ p=p->next;
+ i+=1;
+ continue;
+ }
+ }
+ }
+ else /* p->t > t */
+ {
+ if(got_start)
+ {
+ found_end =1; //found end of chain to return. All is good
+ pr->tail = p_last;
+ p_last->next=NULL;
+ tl->head=p;
+ }
+ // done
+ break;
+ }
+}
+
+*p_nf=i;
+if ((got_start) && (!found_end))
+{
+ //cleared the list
+ printf("clearingthelist\n");
+ tl->head = tl->tail=NULL;
+}
+return;
+}
+
+//cancel a timer
+void tim_cancel(TIM_T * p, int *pErr)
+{
+ *pErr =0;
+ if (!p) {*pErr = NETAPI_ERR_BAD_INPUT; return; }
+ if (!p->cookie) {*pErr= NETAPI_ERR_ALREADY_CANCELLED; return;}
+ p->cookie = NULL;
+ return;
+}
+
+//set a timer
+TIM_T *tim_set(TIM_LIST_T *tl, TIM_LIST_T *free_tl, unsigned long long t, void *cookie, int *pErr)
+{
+TIM_T *pt = tl->head;
+TIM_T *p = tim_get_free(free_tl, cookie, t);
+TIM_T *pt_last= NULL;
+int i;
+*pErr=0;
+if (!p ) { *pErr=NETAPI_ERR_NOMEM; return NULL;}
+
+if (!pt) //first one
+{
+ tl->head = p;
+ tl->tail =p;
+ return p;
+}
+
+//see if we can place at front of list
+if (pt->t >=t)
+{
+ tl->head=p;
+ p->next=pt;
+ return p;
+}
+
+ //timer has hashed into this chain. find out where
+for(;pt;)
+{
+ if (pt->t >= t)
+ {
+ if (pt_last) {
+ pt_last->next = p;
+ p->next=pt;
+ return p;
+ }
+ else
+ {
+ tl->head=p;
+ p->next=pt;
+ return p;
+ }
+ }
+ else {pt_last=pt;pt=pt->next;}
+}
+//last one
+pt_last->next=p;
+p->next=NULL;
+tl->tail=p;
+return p;
+}
+
+//#define TEST_DRIVER
+#ifdef TEST_DRIVER
+TIM_LIST_T the_base={NULL,NULL};
+TIM_LIST_T cell_base={NULL,NULL};
+char *mem;
+TIM_T * timers[10];
+TIM_LIST_T res;
+main()
+{
+ int err;
+ mem= malloc(100*sizeof(TIM_T));
+ TIM_T *p;
+ int n;
+ int i;
+
+ tim_build_free(&the_base, mem , 100*sizeof(TIM_T));
+
+ timers[0]=tim_set(&cell_base, &the_base, 100LL, (void *) 1, &err);
+ timers[1]=tim_set(&cell_base, &the_base, 101LL, (void *) 2, &err);
+ timers[2]=tim_set(&cell_base, &the_base, 105LL, (void *) 3, &err);
+ timers[3]=tim_set(&cell_base, &the_base, 95LL, (void *) 4, &err);
+ timers[4]=tim_set(&cell_base, &the_base, 95LL, (void *) 5, &err);
+ timers[5]=tim_set(&cell_base, &the_base, 95LL, (void *) 6, &err);
+ timers[6]=tim_set(&cell_base, &the_base, 104LL, (void *) 7, &err);
+ timers[7]=tim_set(&cell_base, &the_base, 104LL, (void *) 8, &err);
+ timers[8]=tim_set(&cell_base, &the_base, 104LL, (void *) 9, &err);
+
+ tim_cancel(timers[6], &err);
+
+for(i=90;i<106;i++)
+ {
+tim_return_fired_list(&cell_base, &res, &the_base, (unsigned long long) i, &n);
+ printf("at %d got %d\n", i, n);
+ if (n) tim_return_free(&the_base,&res,n);
+ }
+
+
+}
+#endif
diff --git a/ti/runtime/netapi/test/build/Makefile b/ti/runtime/netapi/test/build/Makefile
--- /dev/null
@@ -0,0 +1,55 @@
+TRIE_OBJS=../trie.o
+NT_OBJS= ../net_test.o ../stubs.o
+# INCLUDE Directories
+QMSS_INC_DIR = $(PDK_INSTALL_PATH)/ti/drv/qmss
+CPPI_INC_DIR = $(PDK_INSTALL_PATH)/ti/drv/cppi
+NETAPI_INC_DIR = ../../
+
+#NETAPI LIB Build directory
+NETAPI_BUILD_DIR = ../../build
+
+# Support Libraries used by NETAPI
+QMSS_LIB = $(PDK_INSTALL_PATH)/ti/drv/qmss/lib/ti.drv.qmss.aearmv7
+CPPI_LIB = $(PDK_INSTALL_PATH)/ti/drv/cppi/lib/ti.drv.cppi.aearmv7
+PA_LIB = $(PDK_INSTALL_PATH)/ti/drv/pa/lib/ti.drv.pa.aearmv7
+PKTLIB_LIB = $(PDK_INSTALL_PATH)/ti/runtime/pktlib/lib/ti.runtime.pktlib.aearmv7
+NWAL_LIB = $(PDK_INSTALL_PATH)/ti/drv/nwal/lib/ti.drv.nwal.aearmv7
+
+#where netapi lib resides after being built
+NETAPI_LIB_DIR= ../../lib
+
+CROSS=arm-none-linux-gnueabi-gcc
+CROSS_PATH=/opt/CodeSourcery/Sourcery_G++_Lite/bin
+CC=$(CROSS_PATH)/$(CROSS)
+AR=$(CROSS_PATH)/arm-none-linux-gnueabi-ar
+CFLAGS= -g -I../ -I. -I$(NETAPI_INC_DIR) -I$(NETAPI_INC_DIR)/src -I$(PDK_INSTALL_PATH) -I$(QMSS_INC_DIR) -I$(CPPI_INC_DIR) -D__ARMv7 -D_VIRTUAL_ADDR_SUPPORT -D__LINUX_USER_SPACE -D_LITTLE_ENDIAN=1 -DMAKEFILE_BUILD -pthread -D _GNU_SOURCE
+
+
+all: net_test synchtest synchtest2
+
+api_clean:
+ rm -rf $(NETAPI_LIB_DIR)/*.a
+ rm -rf ../../src/*.o
+
+clean:
+ rm -f ../*.o
+ rm -f ../*.a
+ rm -f net_test synchtest synchtest2
+
+
+%.o: %.c
+ $(CC) -c $(CFLAGS) $< -o $@
+
+$(NETAPI_LIB_DIR)/api_lib.a:
+ make -C $(NETAPI_BUILD_DIR)
+
+net_test: $(NT_OBJS) $(TRIE_OBJS) $(NETAPI_LIB_DIR)/api_lib.a
+ $(CC) $(LDFLAGS) $(NT_OBJS) $(TRIE_OBJS) $(NETAPI_LIB_DIR)/api_lib.a $(PKTLIB_LIB) $(QMSS_LIB) $(CPPI_LIB) $(NWAL_LIB) $(PA_LIB) -o net_test
+
+
+synchtest: ../synchtest.o
+ $(CC) $(LDFLAGS) ../synchtest.o -o synchtest
+
+synchtest2: ../synchtest2.o
+ $(CC) $(LDFLAGS) ../synchtest2.o -o synchtest2 -lpthread
+
diff --git a/ti/runtime/netapi/test/net_test.c b/ti/runtime/netapi/test/net_test.c
--- /dev/null
@@ -0,0 +1,838 @@
+/******************************************
+ * File: net_test.c
+ * Purpose: test app for netapi
+ **************************************************************
+ * FILE: net_test.c
+ *
+ * DESCRIPTION: netapi user space transport
+ * library test application
+ *
+ * REVISION HISTORY: rev 0.0.1
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ *****************************************/
+
+#include "stdlib.h"
+#include "stdio.h"
+
+#include "trie.h"
+#include "string.h"
+#include "netapi.h"
+#include "pktio.h"
+#include <sys/resource.h>
+
+/*************debug********************/
+void dump_descr(unsigned long *p, int n)
+{
+ printf("--------dump of descriptor %d %x\n", n, (int) p);
+ printf("> %x %x %x %x %x %x %x %x\n",p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]);
+ printf("> %x %x %x %x %x %x %x %x\n",p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15]);
+ printf("-----------------------------\n");
+}
+/*****************************************/
+
+
+//************for multi pkt burst xfer test in loopback mode
+#define TX_BURST 4
+int pktloopback=TUNE_NETAPI_NWAL_ENABLE_PASS_LOOPBACK;
+
+//this device: 10.0.0.100, mac 0x,01,02,03,04,05 and .. 0x6
+
+//test packet, setup for loopback (so dest is ourself)
+static uint8_t testPkt[] = {
+
+ /* MAC header */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x00, 0xe0, 0xa6, 0x66, 0x57, 0x04,
+ 0x08, 0x00,
+
+ /* IP header */
+ 0x45, 0x00,
+ 0x00, 0x6c, /* Length (including this header) */
+ 0x00, 0x00, 0x00, 0x00, 0x05, 0x11,
+ 0x00, 0x00, /* Header checksum */
+ 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x64,
+
+ /* UDP header */
+ 0x12, 0x34, 0x05, 0x55,
+ 0x00, 0x58, /* Length, including this header */
+ 0x00, 0x00, /* Header checksum */
+
+ /* Payload */
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41,
+ 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
+ 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+ 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61,
+ 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
+ 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+ 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81
+
+};
+
+#define TEST_PAYLOAD_LEN 80
+
+#define TEST_PKT_IP_OFFSET_BYTES 14
+#define TEST_PKT_UDP_OFFSET_BYTES 34
+#define TEST_PKT_PLOAD_OFFSET_BYTES 42
+#define TEST_PKT_UDP_HDR_LEN 8
+/* Offsets to length fields */
+#define TEST_PKT_OFFSET_IP_LEN 16
+#define TEST_PKT_OFFSET_UDP_LEN 38
+
+#define TEST_PKT_LEN 122
+
+/* The pseudo header checksum of the packet except for the 16 bit length */
+#define TEST_PKT_PSEUDO_HDR_CHKSUM_SANS_LEN 0x0FFC
+
+
+
+#if 1
+//#include "arpa/inet.h"
+long htonl(long x)
+{
+ long temp = (x&0xff000000)>>24 | (x&0xff0000)>>8 | (x&0xff00)<<8 | (x&0xff)<<24 ;
+ return temp;
+}
+
+/********************************************************************
+ * FUNCTION PURPOSE: Ones complement addition utility
+ ********************************************************************
+ ********************************************************************/
+uint16_t test_utilOnesComplementAdd (uint16_t v1, uint16_t v2)
+{
+ uint32_t result;
+
+ result = (uint32_t)v1 + (uint32_t)v2;
+ result = (result >> 16) + (result & 0xffff);
+ result = (result >> 16) + (result & 0xffff);
+
+ return ((uint16_t)result);
+}
+
+/********************************************************************
+ * FUNCTION PURPOSE: Ones complement checksum utility
+ ********************************************************************
+ ********************************************************************/
+ uint16_t test_utilOnesCompChkSum (uint8_t *p, uint32_t nwords)
+{
+ uint16_t chksum = 0;
+ uint16_t v;
+ uint32_t i;
+ uint32_t j;
+
+ for (i = j = 0; i < nwords; i++, j+=2) {
+ v = (p[j] << 8) | p[j+1];
+ chksum = test_utilOnesComplementAdd (chksum, v);
+ }
+ return (chksum);
+} /* utilOnesCompChkSum */
+
+/**************************************************************************************
+ * FUNCTION PURPOSE: Compute ipv4 psudo checksum
+ **************************************************************************************
+ * DESCRIPTION: Compute ipv4 psudo checksum
+ **************************************************************************************/
+uint16_t test_utilGetIpv4PsudoChkSum (uint8_t *data, uint16_t payloadLen)
+{
+ uint16_t psudo_chksum;
+
+ psudo_chksum = test_utilOnesCompChkSum (&data[12], 4);
+ psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, (uint16_t) data[9]);
+ psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, payloadLen);
+
+ return (psudo_chksum);
+
+} /* utilGetIpv4PsudoChkSum */
+
+
+
+#endif
+typedef struct stats_t
+{
+ long itx; //initially generated
+ long rx;
+ long tx;
+ long n_bad;
+ long n_new;
+} STATS_T;
+
+typedef struct head_t
+{
+ long ip[5];
+ long udp[2];
+} HEAD_T;
+
+typedef struct key_t
+{
+ long src_ip;
+ long dst_ip;
+ short src_port;
+ short dst_port;
+} KEY_T;
+
+unsigned char mac0[]={0x00,0x01,0x02,0x03,0x04,0x05}; //interface 0
+unsigned char mac1[]={0x00,0x01,0x02,0x03,0x04,0x06}; //interface 1
+nwalIpAddr_t OurIp0={ 10, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+#if 1 //goes with real tx (to laptop)
+unsigned char real_mac_header[]={0xd4,0xbe,0xd9,0x00,0xd3,0x7e,
+ 0x00,0x01,0x02,0x03,0x04,0x05,
+ 0x08,0x00};
+unsigned char real_ip_addr[]={0xa,0x00,0x00,0x64,0xa,0x0,0x0,0xa};
+#endif
+
+#if 0 //goes with loopback
+unsigned char mac_header[]={0x00,0x01,0x02,0x03,0x04,0x05,
+ 0x00,0x11,0x22,0x33,0x44,0x55,
+ 0x08,0x00};
+#endif
+#define NE 65536
+HEAD_T *nat;
+
+#define NP 5000
+int n_pkt = NP;
+STATS_T stats;
+
+Trie * P_trie;
+HEAD_T pkts[NP];
+#define PERSLOW 10 //% of pkts that will not be fastpath'd
+int perslow= PERSLOW;
+
+/*******************************************
+ *************NETAPI OBJECTS***************
+ *****************************************/
+Pktlib_HeapHandle OurHeap;
+PKTIO_HANDLE_T *our_chan;
+PKTIO_HANDLE_T *netcp_rx_chan;
+PKTIO_HANDLE_T *netcp_tx_chan;
+PKTIO_CFG_T our_chan_cfg={PKTIO_RW, PKTIO_LOCAL, PKTIO_Q_ANY, 8};
+PKTIO_CFG_T netcp_rx_cfg={PKTIO_R, PKTIO_NA, PKTIO_NA, 8};
+PKTIO_CFG_T netcp_tx_cfg={PKTIO_W, PKTIO_NA, PKTIO_NA, 8};
+
+void house(NETAPI_SCHED_HANDLE_T *s);
+NETAPI_T netapi_handle;
+NETAPI_SCHED_HANDLE_T * our_sched;
+NETAPI_SCHED_CONFIG_T our_sched_cfg={
+ NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 50 //every 50 poll loops
+};
+void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats);
+NETAPI_TIMER_GROUP_HANDLE_T ourTimerBlock;
+NETAPI_TIMER_T t1;
+NETAPI_TIMER_T t2;
+NETAPI_TIMER_T t3;
+
+void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
+ int n_fired, //# timers fired
+ NETAPI_TIMER_LIST_T fired_list,
+ uint64_t currentTime);
+
+/*************************END NETAPI OBJECTS***********************/
+
+#define START_SRC_IP 0x0a00000a
+#define DST_IP 0xc0a80001
+#define NEW_START_SRC_IP 0x9eda000a
+#define DST_PORT 0x555
+#define START_SRC_PORT 0x1234
+#define NEW_START_SRC_PORT 100
+void update_header(HEAD_T * p_head, int len)
+{
+ unsigned char *p = (unsigned char *) &p_head->udp[1];
+ len -= (20+14);
+ /* update ip checksum */
+ /* update udp checksum */
+ /* update length */
+ *p= (len&0xff00)>>8;
+ *(p+1) = len&0xff;
+}
+
+void gen_pkts(int np)
+{
+int i;
+int ip = START_SRC_IP &0xff;
+int port= START_SRC_PORT;
+HEAD_T temp={{0x25000200,0xdead0000,0x80110000,START_SRC_IP,DST_IP},
+ {START_SRC_PORT<<16|DST_PORT,0x01ec<<16|0x0000}};
+/* endian convert header */
+temp.ip[0]=htonl(temp.ip[0]);
+temp.ip[1]=htonl(temp.ip[1]);
+temp.ip[2]=htonl(temp.ip[2]);
+temp.ip[3]=htonl(temp.ip[3]);
+temp.ip[4]=htonl(temp.ip[4]);
+temp.udp[0]=htonl(temp.udp[0]);
+temp.udp[1]=htonl(temp.udp[1]);
+
+for(i=0;(i<np) && (i<NP);i++)
+ {
+ memcpy(&pkts[i],&temp,sizeof(temp));
+ update_header(&pkts[i],512); /* update checksums etc */
+ /* change template for new pkt */
+ ip+=1;
+ if(ip>254) {(ip=START_SRC_IP&0xff); port+=1; }
+ temp.ip[3] = htonl((START_SRC_IP&0xffffff00)| ip);
+ temp.udp[0] = htonl( (temp.udp[0]&0xffff0000)| port);
+ temp.udp[1] = htonl(temp.udp[1]);
+
+ }
+ n_pkt=np;
+}
+void build_table(Trie * p_trie)
+{
+int i;
+int sip=NEW_START_SRC_IP&0xff;
+int sport=NEW_START_SRC_PORT;
+HEAD_T temp;
+KEY_T key;
+int skip;
+int nskip=0;
+for(i=0;(i<n_pkt) && (i<NE);i++)
+{
+ skip = rand()%100;
+ if (skip<perslow) {nskip++;continue;}
+ memcpy(&temp,&pkts[i],sizeof(temp));
+ temp.ip[3]=htonl(((NEW_START_SRC_IP)&(0xffffff00))|(sip));
+ temp.udp[0] = htonl((temp.udp[0]&0xffff)| (sport<<16));
+ memcpy(&nat[i], &temp, sizeof(temp));
+
+ //insert entry
+ key.src_ip = pkts[i].ip[3];
+ key.dst_ip = pkts[i].ip[4];
+ key.src_port= (pkts[i].udp[0]&0xffff0000)>>16;
+ key.dst_port= (pkts[i].udp[0]&0x0000ffff);
+ trie_insert(p_trie,(char *)&key,sizeof(key), (void *) &nat[i]);
+ /* update */
+ sport+= 1;
+ if (sport > 60000) { sport = NEW_START_SRC_PORT; sip+=1; }
+}
+ //printf("build tab: %d %d\n", n_pkt , nskip);
+}
+
+//===========stub transmitter==================
+void send_pkt(Ti_Pkt *pkt, int len)
+{
+Pktlib_freePacket((Ti_Pkt*)pkt);
+ return;
+}
+
+
+void slow_path(Ti_Pkt *pkt, int len)
+{
+
+ {Ti_Pkt * k= Pktlib_getNextPacket(pkt); if(k != 0) {printf(" slowpath, nexpkt != NULL");}}
+Pktlib_freePacket((Ti_Pkt*)pkt);
+ return;
+}
+/* check header */
+int check_header(HEAD_T * p_head)
+{
+ /* check version */
+ /* ip check sum */
+ /* udp check sum */
+ return 1;
+}
+
+#define PKT_LEN 1400
+void test_alloc_free(int n)
+{
+int i;
+Ti_Pkt * b;
+
+for(i=0;i<n;i++)
+{
+ b=Pktlib_allocPacket(OurHeap,PKT_LEN);
+ Pktlib_freePacket(b);
+}
+}
+/*-----------test driver: gen an input pkt------- */
+//char buffer[sizeof(HEAD_T)+PKT_LEN];
+Ti_Pkt * get_pkt(int n, unsigned int *p_len)
+{
+ int ind;
+ long long temp;
+ Ti_Pkt * b;
+ char * buffer;
+ unsigned int len;
+
+ if (pktloopback==0)
+ {
+ if (n>=4) return NULL; //just gen pkts to warm swtich, so that it knows
+ //our mac is valid
+ }
+ b=Pktlib_allocPacket(OurHeap,PKT_LEN);
+ if (!b)
+ {printf("net_test: get_pkt() heap empty!! %d pkts gen'd %d \n", n); return NULL;};
+
+ //debug
+ //printf("pkt= %x %x\n", b, Pktlib_getNextPacket(b));
+
+#if 0
+/*temp patch - should move inside nwal **/
+{
+Cppi_Desc * pHdrDesc = Pktlib_getDescFromPacket(b);
+
+/* Initialize the PS for no control info. */
+Cppi_setPSLen (Cppi_DescType_HOST, (Cppi_Desc *)pHdrDesc, 0);
+}
+#endif
+
+ //debug - way to validate descriptor
+ {Ti_Pkt* k= Pktlib_getNextPacket(b);
+ if(k != 0) {printf(" genpkt, nexpkt != NULL");}}
+
+
+ //get pointer to buffer area of packet
+ Pktlib_getDataBuffer(b,(uint8_t**)&buffer,&len);
+
+#if 0
+if (pktloopback==0)
+{
+ temp = (long long) rand();
+ temp *= PKT_LEN;
+ temp /= RAND_MAX;
+ temp +=2;
+ *p_len = (int) temp;
+ *p_len = *p_len &0xfffffffe;
+ temp = (long long) rand();
+ temp *= n_pkt;
+ temp /= RAND_MAX;
+ ind = (int) temp;
+ update_header(&pkts[ind],*p_len);
+ //printf("get pkt:%d %d ind=%d len=%d\n",RAND_MAX, rand(),ind, *p_len);
+ memcpy(&buffer[0], &mac_header[0],14);
+ memcpy(&buffer[14],(char*)&pkts[ind],sizeof(HEAD_T));
+}
+else
+#endif
+
+ //copy test packet into buffer
+{
+ memcpy(&buffer[0], &testPkt[0],TEST_PKT_LEN);
+ *p_len = TEST_PKT_LEN;
+}
+ return b;
+}
+
+
+/******************************************************/
+/******************PKT RECEIVE HANDLER *************************/
+/******************************************************/
+void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
+ PKTIO_METADATA_T meta[], int n_pkts,
+ uint64_t ts )
+{
+int i;
+int len;
+int p;
+HEAD_T * p_res;
+Ti_Pkt * tip;
+unsigned int templen;
+int err;
+KEY_T key;
+char * p_pkt;
+HEAD_T * p_head;
+HEAD_T temp_head;
+
+ p_head=&temp_head;
+
+ //debug
+#if 0
+ if (n_pkts != TX_BURST) {
+ printf("recv_cb, txsofar=%d rxsofar=%d np = %d, NOT %d\n",
+ stats.itx, stats.rx, n_pkts,TX_BURST);
+ our_stats_cb(netapi_handle,NULL);
+ }
+#endif
+ //test_alloc_free(7);
+ //printf("recv start\n");
+
+ /* loop over received pkts */
+ for(i=0;i<n_pkts;i++)
+ {
+ tip = p_recv[i];
+ Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
+ len = Pktlib_getPacketLen(tip);//real length
+
+ //debug: validate descriptor */
+ if(Pktlib_getNextPacket(tip) != 0) {printf(" rcv_cb, nexpkt != NULL");}
+ //debug printf("recv pkt, len=%d %d\n", len, templen);
+ stats.rx+=1;
+
+#ifdef DEBUG_DESC
+ if (stats.rx<16){printf(">rx dmp.."); dump_descr((long *) tip, stats.rx);}
+ else if (stats.rx>99) {printf(">rx dmp.."); dump_descr((long *) tip,stats.rx);}
+#endif
+
+
+ /* check header */
+ memcpy(p_head,&p_pkt[14],sizeof(HEAD_T));
+ if (!check_header(p_head)) {
+ stats.n_bad+=1;Pktlib_freePacket(tip); continue;
+ }
+
+ /* lookup flow */
+ key.src_ip = p_head->ip[3];
+ key.dst_ip = p_head->ip[4];
+ key.src_port= (p_head->udp[0]&0xffff0000)>>16;
+ key.dst_port= (p_head->udp[0]&0x0000ffff);
+ p_res= (HEAD_T *) trie_lookup(P_trie, (char *) &key, sizeof(key));
+ if (!p_res) { stats.n_new+=1; slow_path(tip, len); continue;}
+
+ /* copy header */
+ memcpy((char *) p_head, (char *) p_res, sizeof(HEAD_T));
+
+ /* update checksums */
+ //update_header(p_head,len);
+ memcpy(&p_pkt[14],p_head,sizeof(HEAD_T));
+ /* update_mac(&p_pkt[0]); */
+
+ /* send pkt */
+ send_pkt(tip,len);
+ stats.tx+=1;
+ }
+ //printf("recv done\n");
+}
+
+//timer callback
+void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
+ int n_fired, //# timers fired
+ NETAPI_TIMER_LIST_T fired_list,
+ uint64_t currentTime)
+{
+int i;
+NETAPI_TIMER_T tx;
+int cookie;
+int err;
+unsigned long long et;
+printf("TIMER CALLBACK @ %lld %d timers\n", currentTime, n_fired);
+tx = netapi_TimerGetFirst(fired_list);
+for(i=0;i<n_fired;i++)
+{
+ cookie = (int) netapi_TimerGetCookie(tx);
+ et = netapi_TimerGetTs(tx); //debug
+ printf(" timer %d - cookie = %d expected ts=%lld (delta=%lld)\n", i, cookie, et, currentTime-et);
+ if (cookie ==1)
+ t1 = netapi_TimerGroupStartTimer(
+ th,
+ (void *) 1,
+ 100LL, //every second
+ &err);
+ else if (cookie ==2)
+ t1 = netapi_TimerGroupStartTimer(
+ th,
+ (void *) 2,
+ 200LL, //every second
+ &err);
+ else
+ t3 = netapi_TimerGroupStartTimer(
+ th,
+ (void *) 3,
+ 300LL, //every second
+ &err);
+
+
+ tx = netapi_TimerGetNext(fired_list,tx);
+}
+}
+
+
+static int np2process = NP;
+/******************************************************
+ * stats callback
+ *******************************************************/
+void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats)
+{
+uint32_t numFreeDataPackets;
+uint32_t numZeroBufferPackets;
+uint32_t numPacketsinGarbage;
+
+printf("stats @ %lld\n", netapi_getTimestamp());
+if(pPaStats)
+{
+ printf("C1 number of packets: %d\n", pPaStats->classify1.nPackets);
+ printf("C1 number IPv4 packets: %d\n", pPaStats->classify1.nIpv4Packets);
+ printf("C1 number llc/snap fail: %d\n", pPaStats->classify1.nLlcSnapFail);
+ printf("C1 number table matched: %d\n", pPaStats->classify1.nTableMatch);
+ printf("C1 number failed table matched: %d\n", pPaStats->classify1.nNoTableMatch);
+ printf ("C1 number of parse fail: %d\n",pPaStats->classify1.nParseFail);
+ printf("C1 number of command failures: %d\n", pPaStats->classify1.nCommandFail);
+ printf("C1 number invalid reply dests: %d\n", pPaStats->classify1.nInvalidComReplyDest);
+ printf ("C1 number of silent discard: %d\n",pPaStats->classify1.nSilentDiscard);
+ printf("C1 number of invalid control: %d\n", pPaStats->classify1.nInvalidControl);
+ printf ("C1 number of invalid states: %d\n",pPaStats->classify1.nInvalidState);
+ printf ("C1 number of system fails: %d\n\n",pPaStats->classify1.nSystemFail);
+}
+Pktlib_getHeapStats(OurHeap, &numFreeDataPackets,
+ &numZeroBufferPackets, &numPacketsinGarbage);
+printf("heap stats> #free=%d #zb=%d #garbage=%d\n", numFreeDataPackets,
+ numZeroBufferPackets, numPacketsinGarbage);
+//debug
+dump_poll_stats();
+
+
+}
+
+//******************************************************
+//use scheduling housekeeping callback to generate pkts
+//******************************************************
+void house(NETAPI_SCHED_HANDLE_T * s)
+{
+Ti_Pkt * tip;
+unsigned int len;
+nwalTxPktInfo_t meta_tx={0};
+PKTIO_METADATA_T meta = {PKTIO_META_TX,0};
+int err;
+static int house_pkts_gened=0;
+int p;
+unsigned char * pIpHdr,* pData;
+
+for(p=0;p<TX_BURST;p++) {
+//reguest stats
+if ((house_pkts_gened>0) && (! (house_pkts_gened%400)) )
+{
+ printf("net_test> request stats at n=%d \n",house_pkts_gened);
+ netcp_cfgReqStats(netapi_handle, our_stats_cb, 0,&err);
+ if (err!=0) {printf("stats req failed\n");}
+}
+
+
+ if (house_pkts_gened >= np2process+ 100)
+ {
+ //shutdown
+ netapi_schedShutdown(s,NULL,&err);
+ continue;
+ }
+
+ else if (house_pkts_gened >= np2process) { house_pkts_gened+=1; continue;}
+
+
+/* manufacture a pkt to transmit */
+ tip = get_pkt(house_pkts_gened, &len);
+ if(!tip) { house_pkts_gened +=1; continue; }
+
+ /* set the pkt length */
+ Pktlib_setPacketLen(tip, len);
+
+ /* set up meta data */
+ meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM | NWAL_TX_FLAG1_DO_UDP_CHKSUM);
+ meta_tx.startOffset = 0;
+ meta_tx.pktLen = len;
+ meta_tx.ipOffBytes = TEST_PKT_IP_OFFSET_BYTES;
+ meta_tx.l4OffBytes = TEST_PKT_UDP_OFFSET_BYTES;
+ meta_tx.l4HdrLen = TEST_PKT_UDP_HDR_LEN;
+ meta_tx.ploadOffBytes = TEST_PKT_PLOAD_OFFSET_BYTES;
+ meta_tx.ploadLen = TEST_PAYLOAD_LEN;
+
+ Pktlib_getDataBuffer(tip,&pData,&len);
+ pIpHdr = pData + meta_tx.ipOffBytes;
+ meta_tx.pseudoHdrChecksum =
+ test_utilGetIpv4PsudoChkSum(pIpHdr,(TEST_PAYLOAD_LEN+TEST_PKT_UDP_HDR_LEN));
+
+ /* post it to netcp tx channel*/
+ meta.u.tx_meta=&meta_tx;
+#ifdef DEBUG_DESC
+ if (house_pkts_gened<16) dump_descr((long *) tip, house_pkts_gened);
+ else if (house_pkts_gened>99) dump_descr((long *) tip,house_pkts_gened);
+#endif
+ pktio_send(netcp_tx_chan,tip,&meta,&err);
+ if (err == 0) stats.itx +=1;
+
+ house_pkts_gened +=1;
+ }
+}
+
+
+/***************************************
+ ********** test driver*****************
+ ***************************************/
+int main(int argc, char **argv)
+{
+int err;
+rlim_t oss,ss = 1024*1024;
+struct rlimit rl;
+
+err= getrlimit(RLIMIT_STACK,&rl);
+if (!err) printf(" stack limit = %d\n",rl.rlim_cur); else printf("getrlimit failed\n");
+#if 0
+rl.rlim_cur = ss;
+err=setrlimit(RLIMIT_STACK,&rl);
+if (!err) printf("set stack to %d\n",rl.rlim_cur); else printf("setrlimit failed\n");
+#endif
+
+if (argc>=2) np2process = atoi(argv[1]);
+if (np2process<0) np2process = NP; /* default */
+if (argc==3) perslow = atoi(argv[2]);
+if ((perslow<0)||(perslow>100)) perslow=PERSLOW;//default
+if (argc>3) {printf("net_test <no of pkts to process> <percent slow path>\n"); exit(1);}
+
+
+//real mode, so update our test packet mac header and ip header
+if (pktloopback==0)
+{
+memcpy(&testPkt,&real_mac_header[0],14); //overwrite test pkt mac address
+memcpy(&testPkt[26],&real_ip_addr[0],8);//overrite test pkt ip addresses
+}
+
+/*******************************************/
+/*************NETAPI STARTUP****************/
+/*******************************************/
+
+/* create netapi */
+netapi_handle = netapi_init(NETAPI_SYS_MASTER);
+
+/* open the main heap */
+OurHeap = Pktlib_findHeapByName("netapi");
+if (!OurHeap) {printf("findheapbyname fail\n"); exit(1);}
+
+/* create a pktio channel */
+our_chan=pktio_create(netapi_handle,"our1stq",recv_cb, &our_chan_cfg,&err);
+if (!our_chan) {printf("pktio create failed err=%d\n",err); exit(1);}
+
+/* open netcp default tx, rx queues */
+netcp_tx_chan= pktio_open(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg, &err);
+if (!netcp_tx_chan) {printf("pktio open TX failed err=%d\n",err); exit(1);}
+netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, recv_cb, &netcp_rx_cfg, &err);
+if (!netcp_rx_chan) {printf("pktio open RX failed err=%d\n",err); exit(1);}
+
+
+/* create scheduler instance */
+our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err);
+if (!our_sched) {printf("sched create failed\n"); exit(1);}
+
+/* add mac intefaces */
+netcp_cfgCreateMacInterface(
+ netapi_handle,
+ &mac0[0],
+ 0,0,
+ (NETCP_CFG_ROUTE_HANDLE_T) NULL,
+ (NETCP_CFG_VLAN_T ) NULL , //future
+ 1,
+ &err);
+if (err) {printf("addmac0 failed %d\n",err); exit(1); }
+
+//attach an IP to this interface
+netcp_addIp(
+ netapi_handle,
+ 0,
+ nwal_IPV4,
+ &OurIp0,
+ NULL, //all IP
+ (NETCP_CFG_ROUTE_HANDLE_T) NULL,
+ &err
+ );
+if (err) {printf("addip0 failed %d\n",err); exit(1); }
+#if 1
+//create a 2nd mac instance
+netcp_cfgCreateMacInterface(
+ netapi_handle,
+ &mac1[0],
+ 1,1,
+ (NETCP_CFG_ROUTE_HANDLE_T) NULL,
+ (NETCP_CFG_VLAN_T ) NULL , //future
+ 1,
+ &err);
+if (err) {printf("addmac1 failed %d\n",err); exit(1); }
+#endif
+
+ ourTimerBlock = netapi_TimerGroupCreate(
+ netapi_handle,
+ "our1sttimer",
+ our_timer_cb,
+ 0, //1 if timers local to thread
+ 0, //1 if expect to cancel
+ netapi_getTicksPerSec()/100, /* 10 msc resolution for these timers */
+ 100,
+ &err);
+if (err) {printf("timergroupcreate failed %d\n",err); exit(1);}
+
+//start a couple of timers
+t1 = netapi_TimerGroupStartTimer(
+ ourTimerBlock,
+ (void *) 1,
+ 100LL, //every second
+ &err);
+if (err) {printf("timerstart failed %d\n");}
+t2 = netapi_TimerGroupStartTimer(
+ ourTimerBlock,
+ (void *) 2,
+ 200LL, //every 1.1second
+ &err);
+if (err) {printf("timerstart failed %d\n");}
+t3 = netapi_TimerGroupStartTimer(
+ ourTimerBlock,
+ (void *) 3,
+ 300LL, //every 3 seconds
+ &err);
+if (err) {printf("timerstart failed %d\n");}
+
+
+/*********************************************/
+/*****************end NETAPI STARTUP**********/
+/*********************************************/
+
+
+/********************************************
+* Basic pkt loopback test
+*********************************************/
+
+
+/* create TRIE */
+P_trie = trie_new();
+if (!P_trie) {printf("trie alloc failed\n"); exit(1);}
+
+nat = (HEAD_T *) malloc(NE * sizeof(HEAD_T));
+if (!nat) {printf("malloc of nat table failed\n"); exit(1);}
+
+gen_pkts(np2process<NP ? np2process:NP);
+
+/* build table */
+build_table(P_trie);
+
+
+/* processing loop: get pkt, check it, look up in table, copy new header,
+ send packet */
+srand((unsigned) np2process);
+
+
+/*********************************************/
+/**************Entry point into scheduler ****/
+/*********************************************/
+netapi_schedWaitForEvents(our_sched, &err);
+
+/* done */
+printf("done: itx=%d rx=%d tx=%d bad=%d slow=%d\n",stats.itx, stats.rx, stats.tx, stats.n_bad, stats.n_new);
+our_stats_cb(netapi_handle, NULL);
+
+netapi_shutdown(netapi_handle);
+
+}
diff --git a/ti/runtime/netapi/test/qmsim.c b/ti/runtime/netapi/test/qmsim.c
--- /dev/null
@@ -0,0 +1,72 @@
+#include <stdlib.h>
+#include "qmsim.h"
+
+/*-------------------Simulator part ---------------*/
+
+void dumpq(Q* q)
+{
+ printf("QDUMP: %d %d %d %d\n",q->size, q->ne, q->head,q->tail);
+}
+void qsim_close(Q * q)
+{
+ if (!q) return;
+ if (q->q) free(q->q);
+ free(q);
+ printf("QSIM: freeing queue\n");
+}
+
+Q * qsim_create(nelem)
+{
+void *p;
+Q * q;
+if (!nelem) return NULL;
+q = (Q*) calloc(1,sizeof(Q));
+if (!q) return NULL;
+
+p = (void **) calloc(nelem,sizeof(void *));
+if (!p) { free(q); return NULL; }
+
+q->size=nelem;
+q->q = p ;
+ printf("QSIM CREATE .. "); dumpq(q);
+return q;
+}
+
+int qsim_push(Q *q, void *p)
+{
+ if (!q) return -1;
+ if (q->ne >= q->size) return-1;
+ q->q[q->tail] = p;
+ q->tail +=1;
+ q->ne+=1;
+ if (q->tail >= q->size) q->tail = 0;
+ //dumpq(q);
+ return 1;
+}
+void * qsim_pop(Q *q )
+{
+ void * val;
+ if (!q) return NULL;
+ if (q->ne ==0) return NULL;
+ val = q->q[q->head];
+ q->head+=1;
+ if(q->head>= q->size) q->head=0;
+ q->ne -=1;
+ //dumpq(q);
+ return val;
+}
+
+//#define TEST_QSIM
+#ifdef TEST_QSIM
+main()
+{
+ Q * q;
+ int i;
+ q= qsim_create(10);
+ for(i=1;i<11;i++) qsim_push(q, (void *) i);
+
+ for(;i<16;i++) { void * val; val = qsim_pop(q); printf("%d\n", (int) val);}
+ for(;i<21;i++) qsim_push(q, (void *) i);
+ for(;i<31;i++) { void * val; val = qsim_pop(q); printf("%d\n", (int) val);}
+}
+#endif
diff --git a/ti/runtime/netapi/test/qmsim.h b/ti/runtime/netapi/test/qmsim.h
--- /dev/null
@@ -0,0 +1,27 @@
+/****************************
+ * qmsim.h: qmss lld, hw simulator
+*****************************/
+#ifndef __QMSIM__H
+#define __QMSIM__H
+
+
+#ifndef NULL
+#define NULL (void*) 0
+#endif
+
+typedef struct Q_t
+{
+ int size;
+ int head;
+ int tail;
+ int ne;
+ void ** q;
+} Q;
+
+/*-----------------------*/
+/*--------simulator------*/
+Q * qsim_create(int nelem);
+int qsim_push(Q *, void *p);
+void * qsim_pop(Q * );
+void qsim_close(Q * );
+#endif
diff --git a/ti/runtime/netapi/test/stubs.c b/ti/runtime/netapi/test/stubs.c
--- /dev/null
@@ -0,0 +1 @@
+/* stubs .. */
diff --git a/ti/runtime/netapi/test/synchtest.c b/ti/runtime/netapi/test/synchtest.c
--- /dev/null
@@ -0,0 +1,116 @@
+/********************************
+ * file: synchtest.c
+ * sync primitives unit test
+ ******************************/
+#include "netsync.h"
+#include "netapi_util.h"
+
+#if 0
+/* timing */
+static inline unsigned long timing_start(void)
+{
+ volatile int vval;
+ //read clock
+ asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(vval));
+ return vval;
+}
+static inline unsigned long timing_stop(void)
+{
+ volatile int vval2;
+ //read clock
+ asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(vval2));
+ return vval2;
+}
+#endif
+#define timing_start netapi_timing_start
+#define timing_stop netapi_timing_stop
+
+int spot=0;
+
+NETAPI_RWLOCK_T temp;
+
+void test1()
+{
+int v1, v2;
+netapi_rwlock_init(&temp);
+v1 = timing_start();
+netapi_rwlock_write_lock(&temp);
+v2 = timing_stop();
+printf("rwlock write locked, cycles= %d \n", v2-v1);
+}
+
+void test2()
+{
+int v1, v2;
+
+v1 = timing_start();
+netapi_rwlock_write_unlock(&temp);
+v2 = timing_stop();
+printf("rwlock write unlocked, cycles= %d \n",v2-v1);
+}
+void test3()
+{
+int v1,v2;
+v1 = timing_start();
+netapi_rwlock_read_lock(&temp);
+v2 = timing_stop();
+printf("rwlock read locked, cycles= %d \n", v2-v1);
+}
+void test4()
+{
+int v1,v2;
+v1 = timing_start();
+netapi_rwlock_read_unlock(&temp);
+v2 = timing_stop();
+printf("rwlock read_unlocked, cycles= %d\n", v2-v1);
+}
+
+main()
+{
+NETAPI_SPINLOCK_T val;
+int i;
+unsigned long v1,v2;
+int val2;
+for(i=0;i<10;i++) {
+val=__sync_fetch_and_add(&spot, 1);
+printf(" val = %d %d\n",val,spot);
+
+//now we try the synch_lock_and_test
+netapi_spinlock_init(&val);
+v1 = timing_start();
+netapi_spinlock_lock(&val);
+v2 = timing_stop();
+printf("locked, val= %d cycles=%d\n",val,v2-v1);
+
+//try the lock
+v1 = timing_start();
+val2=netapi_spinlock_try_lock(&val);
+v2 = timing_stop();
+printf("try lock has returns %d, cycles=%d\n", val2, v2-v1);
+
+//poll the lock
+v1 = timing_start();
+val2=netapi_spinlock_is_locked(&val);
+v2 = timing_stop();
+printf("is_locked has returns %d, cycles=%d\n", val2, v2-v1);
+
+
+//unlock
+v1 = timing_start();
+netapi_spinlock_unlock(&val);
+v2 = timing_stop();
+printf("unlocked, val= %d cycles=%d\n", val,v2-v1);
+
+/*-------now try rwlock--------*/
+test1();
+test2();
+test3();
+test3();
+test4();
+test4();
+
+}
+}
+
+
+
diff --git a/ti/runtime/netapi/test/synchtest2.c b/ti/runtime/netapi/test/synchtest2.c
--- /dev/null
@@ -0,0 +1,110 @@
+#include <stdio.h>\r
+#include <pthread.h>\r
+#include <unistd.h>\r
+#include <stdlib.h>\r
+#include <sched.h>\r
+#include <linux/unistd.h>\r
+#include <sys/syscall.h>\r
+#include <errno.h>\r
+\r
+#include "netsync.h"\r
+#include "netapi_util.h"\r
+//#define INC_TO 1000000 // one million.\r
+#define INC_TO 10000 // one million...\r
+\r
+NETAPI_ATOMIC64_T global_int=NETAPI_ATOMIC_INIT64(0LL) ;\r
+__thread blah=0;\r
+int blah2=0;\r
+pid_t gettid( void )\r
+{\r
+ return syscall( __NR_gettid );\r
+}\r
+\r
+void *thread_routine( void *arg )\r
+{\r
+ int i;\r
+ int proc_num = (int)(long)arg;\r
+ cpu_set_t set;\r
+ int v1, v2,v3;\r
+\r
+#if 0\r
+ CPU_ZERO( &set );\r
+ CPU_SET( proc_num, &set );\r
+\r
+ if (sched_setaffinity( gettid(), sizeof( cpu_set_t ), &set ))\r
+ {\r
+ perror( "sched_setaffinity" );\r
+ return NULL;\r
+ }\r
+#endif\r
+\r
+ for (i = 0; i < INC_TO; i++)\r
+ {\r
+// global_int++;\r
+ //__sync_fetch_and_add( &global_int, 1 );\r
+ \r
+ v1 = netapi_timing_start(); \r
+ netapi_atomic_add64(&global_int,1LL);\r
+ v1= netapi_timing_stop() - v1;\r
+ sched_yield();\r
+ v2 = netapi_timing_start(); \r
+ blah+=1; \r
+ v2= netapi_timing_stop() - v2;\r
+ \r
+ v3 = netapi_timing_start(); \r
+ blah2+=1; \r
+ v3= netapi_timing_stop() - v3;\r
+ if(i<10) { printf("thread %d -> a64 costs %d, tls costs %d simple++ costs %d\n", proc_num,v1,v2,v3);}\r
+ sched_yield();\r
+ }\r
+ printf("thead %d -> blah=%d\n",proc_num, blah);\r
+ return NULL;\r
+}\r
+\r
+int main()\r
+{\r
+ int procs = 0;\r
+ int i;\r
+ pthread_t *thrs;\r
+ printf("at start up\n");\r
+\r
+ // Getting number of CPUs\r
+ procs = (int)sysconf( _SC_NPROCESSORS_ONLN );\r
+ if (procs < 0)\r
+ {\r
+ perror( "sysconf" );\r
+ return -1;\r
+ }\r
+ printf(" num cpus = %d\n",procs);\r
+ if (procs==1) {procs+=1; printf("adding 2nd 'core' \n");}\r
+ thrs = malloc( sizeof( pthread_t ) * procs );\r
+ if (thrs == NULL)\r
+ {\r
+ perror( "malloc" );\r
+ return -1;\r
+ }\r
+\r
+ printf( "Starting %d threads...\n", procs );\r
+\r
+ for (i = 0; i < procs; i++)\r
+ {\r
+ if (pthread_create( &thrs[i], NULL, thread_routine,\r
+ (void *)(long)i ))\r
+ {\r
+ perror( "pthread_create" );\r
+ procs = i;\r
+ break;\r
+ }\r
+ }\r
+\r
+ for (i = 0; i < procs; i++)\r
+ pthread_join( thrs[i], NULL );\r
+\r
+ free( thrs );\r
+\r
+ printf( "After doing all the math, global_int value is: %lld bare global_int is %d\n",\r
+ global_int.val, blah2 );\r
+ printf( "Expected value is: %d\n", INC_TO * procs );\r
+\r
+ return 0;\r
+}\r
diff --git a/ti/runtime/netapi/test/trie.c b/ti/runtime/netapi/test/trie.c
--- /dev/null
@@ -0,0 +1,324 @@
+/*\r
+\r
+Copyright (c) 2005, Simon Howard\r
+All rights reserved.\r
+\r
+Redistribution and use in source and binary forms, with or without \r
+modification, are permitted provided that the following conditions \r
+are met:\r
+\r
+ * Redistributions of source code must retain the above copyright \r
+ notice, this list of conditions and the following disclaimer.\r
+ * Redistributions in binary form must reproduce the above copyright \r
+ notice, this list of conditions and the following disclaimer in \r
+ the documentation and/or other materials provided with the \r
+ distribution.\r
+ * Neither the name of the C Algorithms project nor the names of its \r
+ contributors may be used to endorse or promote products derived \r
+ from this software without specific prior written permission.\r
+\r
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS \r
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \r
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER \r
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT \r
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN \r
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+POSSIBILITY OF SUCH DAMAGE.\r
+\r
+*/\r
+\r
+/* Trie: fast mapping of strings to values */\r
+\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+#include "trie.h"\r
+\r
+typedef struct _TrieNode TrieNode;\r
+\r
+struct _TrieNode {\r
+ void *data;\r
+ unsigned int use_count;\r
+ TrieNode *next[256];\r
+};\r
+\r
+struct _Trie {\r
+ TrieNode *root_node;\r
+};\r
+\r
+static void trie_free_node(TrieNode *node)\r
+{\r
+ int i;\r
+\r
+ if (node == NULL)\r
+ return;\r
+ \r
+ /* First, free all subnodes */\r
+\r
+ for (i=0; i<256; ++i) {\r
+ trie_free_node(node->next[i]);\r
+ }\r
+\r
+ /* Free this node */\r
+\r
+ free(node);\r
+}\r
+\r
+Trie *trie_new(void)\r
+{\r
+ Trie *new_trie;\r
+\r
+ new_trie = (Trie *) malloc(sizeof(Trie));\r
+ new_trie->root_node = NULL;\r
+\r
+ return new_trie;\r
+}\r
+\r
+void trie_free(Trie *trie)\r
+{\r
+ /* Free the subnode, and all others by implication */\r
+\r
+ trie_free_node(trie->root_node);\r
+\r
+ /* Free the trie */\r
+\r
+ free(trie);\r
+}\r
+\r
+void trie_insert(Trie *trie, char *key, int keylen, void *value)\r
+{\r
+ TrieNode **rover;\r
+ TrieNode *node;\r
+ unsigned char *p;\r
+ unsigned char c;\r
+ int k;\r
+\r
+ /* Cannot insert NULL values */\r
+\r
+ if (value == NULL) {\r
+ return;\r
+ }\r
+\r
+ /* Search down the trie until we reach the end of string,\r
+ * creating nodes as necessary */\r
+\r
+ rover = &trie->root_node;\r
+ p = (unsigned char *) key;\r
+\r
+ for (k=0;;) {\r
+\r
+ node = *rover;\r
+\r
+ if (node == NULL) {\r
+ \r
+ /* Node does not exist, so create it */\r
+\r
+ node = (TrieNode *) malloc(sizeof(TrieNode));\r
+ memset(node, 0, sizeof(TrieNode));\r
+\r
+ /* Link in to the trie */\r
+\r
+ *rover = node;\r
+ }\r
+\r
+ /* One more use of this node */\r
+\r
+ ++node->use_count;\r
+\r
+ /* Current character */\r
+\r
+ c = *p;\r
+\r
+ /* Reached the end of string? If so, we're finished. */\r
+\r
+ if (k>=keylen) {\r
+\r
+ /* Set the data at the node we have reached */\r
+\r
+ node->data = value;\r
+\r
+ break;\r
+ }\r
+\r
+ /* Advance to the next node in the chain */\r
+\r
+ rover = &node->next[c];\r
+ ++p; \r
+ k+=1;\r
+ }\r
+}\r
+\r
+void trie_remove(Trie *trie, char *key, int keylen)\r
+{\r
+ TrieNode *node;\r
+ TrieNode *next;\r
+ TrieNode **last_next_ptr;\r
+ unsigned char *p;\r
+ unsigned char c;\r
+ int k=0;\r
+ \r
+ /* First, search down to the ending node so that the data can\r
+ * be removed. */\r
+\r
+ /* Search down the trie until the end of string is reached */\r
+\r
+ node = trie->root_node;\r
+\r
+ for (p=(unsigned char *) key, k=0; k<keylen; ++p, k+=1) {\r
+\r
+ if (node == NULL) {\r
+ /* Not found in the tree. Return. */\r
+\r
+ return;\r
+ }\r
+\r
+ /* Jump to the next node */\r
+\r
+ c = *p;\r
+ node = node->next[c];\r
+ }\r
+\r
+ /* Remove the data at this node */\r
+\r
+ node->data = NULL;\r
+\r
+ /* Now traverse the tree again as before, decrementing the use\r
+ * count of each node. Free back nodes as necessary. */\r
+\r
+ node = trie->root_node;\r
+ last_next_ptr = &trie->root_node;\r
+ p = key;\r
+\r
+ for (k=0;;k++) {\r
+\r
+ /* Find the next node */\r
+ \r
+ c = *p;\r
+ next = node->next[c];\r
+\r
+ /* Free this node if necessary */\r
+\r
+ --node->use_count;\r
+\r
+ if (node->use_count <= 0) {\r
+ free(node);\r
+\r
+ /* Set the "next" pointer on the previous node to NULL,\r
+ * to unlink the free'd node from the tree. This only\r
+ * needs to be done once in a remove. After the first\r
+ * unlink, all further nodes are also going to be\r
+ * free'd. */\r
+\r
+ if (last_next_ptr != NULL) {\r
+ *last_next_ptr = NULL;\r
+ last_next_ptr = NULL;\r
+ }\r
+ }\r
+ \r
+ /* Go to the next character or finish */\r
+\r
+ if (k>=keylen) {\r
+ break;\r
+ } else {\r
+ ++p;\r
+ }\r
+\r
+ /* If necessary, save the location of the "next" pointer\r
+ * so that it may be set to NULL on the next iteration if\r
+ * the next node visited is freed. */\r
+\r
+ if (last_next_ptr != NULL) {\r
+ last_next_ptr = &node->next[c];\r
+ }\r
+ \r
+ /* Jump to the next node */\r
+\r
+ node = next;\r
+ }\r
+}\r
+\r
+void *trie_lookup(Trie *trie, char *key, int keylen)\r
+{\r
+ TrieNode *node;\r
+ unsigned char *p;\r
+ unsigned char c;\r
+ int k=0;\r
+\r
+ /* Search down the trie until the end of string is found */\r
+ \r
+ node = trie->root_node;\r
+ p = (unsigned char *) key;\r
+\r
+ while (k<keylen ) {\r
+ if (node == NULL) {\r
+ /* Not found - reached end of branch */\r
+\r
+ return NULL;\r
+ }\r
+\r
+ /* Advance to the next node in the chain, next character */\r
+\r
+ c = *p;\r
+ node = node->next[c];\r
+ ++p;\r
+ k+=1;\r
+ }\r
+ /* bug! */\r
+ \r
+ return (node ? node->data : NULL);\r
+\r
+}\r
+\r
+int trie_num_entries(Trie *trie)\r
+{\r
+ /* To find the number of entries, simply look at the use count\r
+ * of the root node. */\r
+\r
+ if (trie->root_node == NULL) {\r
+ return 0;\r
+ } else {\r
+ return trie->root_node->use_count;\r
+ }\r
+}\r
+\r
+//#define TEST\r
+#ifdef TEST\r
+main()\r
+{\r
+Trie * p_trie;\r
+char * p_res;\r
+p_trie = trie_new();\r
+if (!p_trie) {printf("trie alloc failed\n"); exit(1);}\r
+\r
+trie_insert(p_trie,"key1","this is key 1");\r
+trie_insert(p_trie,"key12","this is key 2");\r
+trie_insert(p_trie,"key3","this is key 3");\r
+trie_insert(p_trie,"key4","this is key 4");\r
+\r
+p_res= trie_lookup(p_trie,"key1");\r
+printf("lookup %s = %s\n", "key1", p_res ? p_res : "not found");\r
+\r
+p_res= trie_lookup(p_trie,"key12");\r
+printf("lookup %s = %s\n", "key2", p_res ? p_res : "not found");\r
+\r
+p_res= trie_lookup(p_trie,"key3");\r
+printf("lookup %s = %s\n", "key3", p_res ? p_res : "not found");\r
+\r
+p_res= trie_lookup(p_trie,"key4");\r
+printf("lookup %s = %s\n", "key4", p_res ? p_res : "not found");\r
+\r
+p_res= trie_lookup(p_trie,"key5");\r
+printf("lookup %s = %s\n", "key5", p_res ? p_res : "not found");\r
+\r
+p_res= trie_lookup(p_trie,"k5");\r
+printf("lookup %s = %s\n", "k5", p_res ? p_res : "not found");\r
+\r
+trie_free(p_trie);\r
+\r
+}\r
+#endif\r
diff --git a/ti/runtime/netapi/test/trie.h b/ti/runtime/netapi/test/trie.h
--- /dev/null
@@ -0,0 +1,123 @@
+/*\r
+\r
+Copyright (c) 2005, Simon Howard\r
+All rights reserved.\r
+\r
+Redistribution and use in source and binary forms, with or without \r
+modification, are permitted provided that the following conditions \r
+are met:\r
+\r
+ * Redistributions of source code must retain the above copyright \r
+ notice, this list of conditions and the following disclaimer.\r
+ * Redistributions in binary form must reproduce the above copyright \r
+ notice, this list of conditions and the following disclaimer in \r
+ the documentation and/or other materials provided with the \r
+ distribution.\r
+ * Neither the name of the C Algorithms project nor the names of its \r
+ contributors may be used to endorse or promote products derived \r
+ from this software without specific prior written permission.\r
+\r
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS \r
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \r
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER \r
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT \r
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN \r
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+POSSIBILITY OF SUCH DAMAGE.\r
+\r
+*/\r
+\r
+/**\r
+ * @file trie.h\r
+ *\r
+ * @brief Fast string lookups\r
+ *\r
+ * A trie is a data structure which provides fast mappings from strings\r
+ * to values.\r
+ *\r
+ * To create a new trie, use @ref trie_new. To destroy a trie,\r
+ * use @ref trie_free.\r
+ *\r
+ * To insert a value into a trie, use @ref trie_insert. To remove a value\r
+ * from a trie, use @ref trie_remove. \r
+ *\r
+ * To look up a value from its key, use @ref trie_lookup.\r
+ *\r
+ * To find the number of entries in a trie, use @ref trie_num_entries.\r
+ */\r
+\r
+#ifndef ALGORITHM_TRIE_H\r
+#define ALGORITHM_TRIE_H\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+typedef struct _Trie Trie;\r
+\r
+/**\r
+ * Create a new trie.\r
+ *\r
+ * @return Pointer to a new trie structure.\r
+ */\r
+\r
+Trie *trie_new(void);\r
+\r
+/** \r
+ * Destroy a trie.\r
+ *\r
+ * @param trie The trie to destroy.\r
+ */\r
+\r
+void trie_free(Trie *trie);\r
+\r
+/**\r
+ * Insert a new key-value pair into a trie.\r
+ *\r
+ * @param trie The trie.\r
+ * @param key The key to access the new value.\r
+ * @param value The value.\r
+ */\r
+\r
+void trie_insert(Trie *trie, char *key, int keylen, void *value);\r
+\r
+/**\r
+ * Look up a value from its key in a trie.\r
+ *\r
+ * @param trie The trie.\r
+ * @param key The key.\r
+ * @return The value associated with the key, or NULL if\r
+ * not found in the trie.\r
+ */\r
+\r
+void *trie_lookup(Trie *trie, char *key, int keylen);\r
+\r
+/**\r
+ * Remove an entry from a trie.\r
+ *\r
+ * @param trie The trie.\r
+ * @param key The key of the entry to remove.\r
+ */\r
+\r
+void trie_remove(Trie *trie, char *key, int keylen);\r
+\r
+/** \r
+ * Find the number of entries in a trie.\r
+ *\r
+ * @param trie The trie.\r
+ * @return Count of the number of entries in the trie.\r
+ */\r
+\r
+int trie_num_entries(Trie *trie);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* #ifndef ALGORITHM_TRIE_H */\r
+\r
diff --git a/ti/runtime/netapi/tools/davinci_clocks b/ti/runtime/netapi/tools/davinci_clocks
--- /dev/null
@@ -0,0 +1,56 @@
+ref_clk users=39 122880000 Hz
+ main_pll users=38 pll 983040000 Hz
+ main_div_chip_clk1 users= 3 pll 983040000 Hz
+ emif4f users= 1 psc 983040000 Hz
+ crypto users= 0 psc 983040000 Hz
+ monza_rst_ctrl users= 1 psc 983040000 Hz
+ rac users= 0 psc 983040000 Hz
+ gem0 users= 0 psc 983040000 Hz
+ gem1 users= 0 psc 983040000 Hz
+ gem2 users= 0 psc 983040000 Hz
+ gem3 users= 0 psc 983040000 Hz
+ rsax2_1 users= 0 psc 983040000 Hz
+ rsax2_0 users= 0 psc 983040000 Hz
+ main_div_gem_trace_clk users= 1 pll 245760000 Hz
+ main_div_chip_clk2 users= 1 pll 491520000 Hz
+ vusr users= 0 psc 491520000 Hz
+ pciex users= 0 psc 491520000 Hz
+ msmcsram users= 0 psc 491520000 Hz
+ tcp3d users= 0 psc 491520000 Hz
+ tcp3d_b users= 0 psc 491520000 Hz
+ main_div_chip_clk3 users= 3 pll 327680000 Hz
+ vcp2_a users= 0 psc 327680000 Hz
+ debugss_trc users= 0 psc 327680000 Hz
+ tetb_trc users= 0 psc 327680000 Hz
+ pktproc users= 1 psc 327680000 Hz
+ cpgmac users= 1 psc 327680000 Hz
+ bcp users= 0 psc 327680000 Hz
+ tac users= 0 psc 327680000 Hz
+ fftc users= 0 psc 327680000 Hz
+ aif2 users= 0 psc 327680000 Hz
+ vcp2_b users= 0 psc 327680000 Hz
+ vcp2_c users= 0 psc 327680000 Hz
+ vcp2_d users= 0 psc 327680000 Hz
+ main_div_stm_clk users= 1 pll 163840000 Hz
+ main_div_emif_ptv_clk users= 1 pll 15360000 Hz
+ main_div_chip_clk6 users=20 pll 163840000 Hz
+ modrst0 users=19 163840000 Hz
+ timer0 users= 2 163840000 Hz
+ timer1 users= 2 163840000 Hz
+ uart0 users= 2 163840000 Hz
+ uart1 users= 2 163840000 Hz
+ aemif users= 2 163840000 Hz
+ usim users= 1 163840000 Hz
+ i2c users= 2 163840000 Hz
+ spi users= 2 163840000 Hz
+ gpio users= 2 163840000 Hz
+ key_mgr users= 1 163840000 Hz
+ main_div_slowsys_clk users= 1 pll 15360000 Hz
+ main_div_chip_smreflex_clk users= 2 pll 81920000 Hz
+ src3_pwr users= 1 psc 81920000 Hz
+ main_div_chip_clk3_srio users= 1 pll 327680000 Hz
+ srio users= 0 psc 327680000 Hz
+ main_div_psc_clk6 users= 1 pll 163840000 Hz
+ main_div_chip_dftclk4 users= 1 pll 245760000 Hz
+ main_div_chip_dftclk8 users= 1 pll 122880000 Hz
+
diff --git a/ti/runtime/netapi/tools/parse_clocks.awk b/ti/runtime/netapi/tools/parse_clocks.awk
--- /dev/null
@@ -0,0 +1,3 @@
+BEGIN {}
+/main_div_chip_clk1/ {print $5;}
+END{}