This is the initial commit.
authorDavid Lide <a0216552@gtudci01.(none)>
Wed, 25 Jan 2012 21:13:19 +0000 (16:13 -0500)
committerDavid Lide <a0216552@gtudci01.(none)>
Wed, 25 Jan 2012 21:13:19 +0000 (16:13 -0500)
40 files changed:
ti/runtime/netapi/OLD/qmsim.c [new file with mode: 0644]
ti/runtime/netapi/OLD/qmsim.h [new file with mode: 0644]
ti/runtime/netapi/OLD/shmtest.c [new file with mode: 0644]
ti/runtime/netapi/OLD/synchtest.c [new file with mode: 0644]
ti/runtime/netapi/OLD/synchtest2.c [new file with mode: 0755]
ti/runtime/netapi/build/Makefile [new file with mode: 0644]
ti/runtime/netapi/lib/api_lib.a [new file with mode: 0644]
ti/runtime/netapi/netapi.h [new file with mode: 0644]
ti/runtime/netapi/netapi_err.h [new file with mode: 0644]
ti/runtime/netapi/netapi_sched.h [new file with mode: 0644]
ti/runtime/netapi/netapi_timer.h [new file with mode: 0644]
ti/runtime/netapi/netapi_tune.h [new file with mode: 0644]
ti/runtime/netapi/netcp_cfg.h [new file with mode: 0644]
ti/runtime/netapi/netsync.h [new file with mode: 0644]
ti/runtime/netapi/pktio.h [new file with mode: 0644]
ti/runtime/netapi/src/netapi.c [new file with mode: 0644]
ti/runtime/netapi/src/netapi_init.c [new file with mode: 0644]
ti/runtime/netapi/src/netapi_loc.h [new file with mode: 0644]
ti/runtime/netapi/src/netapi_sched.c [new file with mode: 0644]
ti/runtime/netapi/src/netapi_timer.c [new file with mode: 0644]
ti/runtime/netapi/src/netapi_util.h [new file with mode: 0644]
ti/runtime/netapi/src/netapi_vm.c [new file with mode: 0644]
ti/runtime/netapi/src/netapi_vm.h [new file with mode: 0644]
ti/runtime/netapi/src/netcp_cfg.c [new file with mode: 0644]
ti/runtime/netapi/src/osal.c [new file with mode: 0644]
ti/runtime/netapi/src/pktio.c [new file with mode: 0644]
ti/runtime/netapi/src/tim64.c [new file with mode: 0644]
ti/runtime/netapi/src/timer_loc.h [new file with mode: 0644]
ti/runtime/netapi/src/timlist.c [new file with mode: 0644]
ti/runtime/netapi/test/build/Makefile [new file with mode: 0644]
ti/runtime/netapi/test/net_test.c [new file with mode: 0755]
ti/runtime/netapi/test/qmsim.c [new file with mode: 0644]
ti/runtime/netapi/test/qmsim.h [new file with mode: 0644]
ti/runtime/netapi/test/stubs.c [new file with mode: 0644]
ti/runtime/netapi/test/synchtest.c [new file with mode: 0644]
ti/runtime/netapi/test/synchtest2.c [new file with mode: 0644]
ti/runtime/netapi/test/trie.c [new file with mode: 0755]
ti/runtime/netapi/test/trie.h [new file with mode: 0755]
ti/runtime/netapi/tools/davinci_clocks [new file with mode: 0644]
ti/runtime/netapi/tools/parse_clocks.awk [new file with mode: 0644]

diff --git a/ti/runtime/netapi/OLD/qmsim.c b/ti/runtime/netapi/OLD/qmsim.c
new file mode 100644 (file)
index 0000000..8cb9ac3
--- /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
new file mode 100644 (file)
index 0000000..bb5dc4b
--- /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
new file mode 100644 (file)
index 0000000..b24adbb
--- /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
new file mode 100644 (file)
index 0000000..92b899d
--- /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
new file mode 100755 (executable)
index 0000000..8698919
--- /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
new file mode 100644 (file)
index 0000000..63dd2ec
--- /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
diff --git a/ti/runtime/netapi/netapi.h b/ti/runtime/netapi/netapi.h
new file mode 100644 (file)
index 0000000..a23cbc2
--- /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
new file mode 100644 (file)
index 0000000..3090383
--- /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
new file mode 100644 (file)
index 0000000..660309b
--- /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
new file mode 100644 (file)
index 0000000..a74294c
--- /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
new file mode 100644 (file)
index 0000000..3a67f23
--- /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
new file mode 100644 (file)
index 0000000..c4f1310
--- /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
new file mode 100644 (file)
index 0000000..8ab7472
--- /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
new file mode 100644 (file)
index 0000000..96bba3e
--- /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
new file mode 100644 (file)
index 0000000..bb8d371
--- /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
new file mode 100644 (file)
index 0000000..5ad7343
--- /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
new file mode 100644 (file)
index 0000000..abe023e
--- /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
new file mode 100644 (file)
index 0000000..f08512b
--- /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
new file mode 100644 (file)
index 0000000..2565089
--- /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
new file mode 100644 (file)
index 0000000..ce1aa04
--- /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
new file mode 100644 (file)
index 0000000..9cc66f4
--- /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
new file mode 100644 (file)
index 0000000..98d4c83
--- /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
new file mode 100644 (file)
index 0000000..7805243
--- /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
new file mode 100644 (file)
index 0000000..0fae54d
--- /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
new file mode 100644 (file)
index 0000000..95fe2dc
--- /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
new file mode 100644 (file)
index 0000000..82c801c
--- /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
new file mode 100644 (file)
index 0000000..5bcdbc1
--- /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
new file mode 100644 (file)
index 0000000..dcea6e9
--- /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
new file mode 100644 (file)
index 0000000..b98c38a
--- /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
new file mode 100755 (executable)
index 0000000..188890e
--- /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
new file mode 100644 (file)
index 0000000..8cb9ac3
--- /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
new file mode 100644 (file)
index 0000000..bb5dc4b
--- /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
new file mode 100644 (file)
index 0000000..fda76b8
--- /dev/null
@@ -0,0 +1 @@
+/* stubs .. */
diff --git a/ti/runtime/netapi/test/synchtest.c b/ti/runtime/netapi/test/synchtest.c
new file mode 100644 (file)
index 0000000..baa19f9
--- /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
new file mode 100644 (file)
index 0000000..08dfebb
--- /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
new file mode 100755 (executable)
index 0000000..c4f50b5
--- /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
new file mode 100755 (executable)
index 0000000..5096cec
--- /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
new file mode 100644 (file)
index 0000000..2f7137a
--- /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
new file mode 100644 (file)
index 0000000..dc6a68f
--- /dev/null
@@ -0,0 +1,3 @@
+BEGIN {}
+/main_div_chip_clk1/ {print $5;}
+END{}