added del_ip, del_mac functions
authorDavid Lide <a0216552@gtudci01.(none)>
Mon, 6 Feb 2012 15:23:34 +0000 (10:23 -0500)
committerDavid Lide <a0216552@gtudci01.(none)>
Mon, 6 Feb 2012 15:23:34 +0000 (10:23 -0500)
ti/runtime/netapi/netcp_cfg.h
ti/runtime/netapi/src/netcp_cfg.c
ti/runtime/netapi/test/net_test.c

index 780768a70b4d973d8d59cc5ddff53a766e2befd3..d4be186259cddd38084a176b56cfe8de448c07a2 100644 (file)
-/***************************************************
- * File: netcp_cfg.h 
- * Purpose: netcp config API
- **************************************************************
- *@file netcp_cfg.h
- * 
- * @brief 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"
-
-//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
-
-/******************************************************************/
-/***********************APP ids for rx meta data********************/
-/******************************************************************/
-// NWAL "AP ids" for PA Rules that are added
-#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 #, lower byte==interface
-
-
-/*---------MAC APPID------------------*/
-typedef uint32_t NETCP_CFG_MACIF_T;
-
-/*------------L2----------------------*/
-typedef void * NETCP_CFG_VLAN_T;
-
-/*---------------IP APPID-------------------*/
-typedef uint32_t 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 AppID for interface (this is returned in meta data for
- *                 received packets matching this rule an no others)
- *  @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 AppID for attached rule. This is returned in RX meta data for
- *              packets matching this rule and no other.
- *  @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**************************************
-**************************************************************************/
-
-/*
- *  @brief  This is the callback function that is used to return statistics from NETCP 
- *
- *  @details The application provides a callback function that NETAPI  uses to report statistics.
-*    The request for stats is generated from the @ref netcp_cfgReqStats API.
- *   Note: to receive ths stats callback, the @ref netapi_netcpPoll funcition must be called
- *  @param[in]  @ref NETAPI_T: NETAPI instance
- *  @param[in]  @ref paSysStats_t * : the PA (NETCP packet accelerator subsystem) statistics block 
- *  @retval     none 
- *  @pre       @ref netapi_init , @ref netapi_cfgReqStats, @ref netapi_netcpPoll
- */
-//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);
-
-#endif
-
+/***************************************************\r
+ * File: netcp_cfg.h \r
+ * Purpose: netcp config API\r
+ **************************************************************\r
+ *@file netcp_cfg.h\r
+ * \r
+ * @brief DESCRIPTION:  netapi NETCP configuration API header  file \r
+ *          for user space transport library\r
+ * \r
+ * REVISION HISTORY:  rev 0.0.1 \r
+ *\r
+ *  Copyright (c) Texas Instruments Incorporated 2010-2011\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
+ *\r
+ *    Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the \r
+ *    documentation and/or other materials provided with the   \r
+ *    distribution.\r
+ *\r
+ *    Neither the name of Texas Instruments Incorporated nor the names of\r
+ *    its 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 FOR\r
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+ ***************************************************/\r
+\r
+#ifndef __NETCP_CFG__H\r
+#define __NETCP_CFG__H\r
+\r
+#include "netapi.h"\r
+#include "ti/drv/pa/pa.h"\r
+#include "ti/runtime/pktlib/pktlib.h"\r
+\r
+//NETCP FLOW\r
+typedef struct NETCP_CFG_FLOW_Tag\r
+{\r
+       int flowid;\r
+} NETCP_CFG_FLOW_T;\r
+typedef void *  NETCP_CFG_FLOW_HANDLE_T;\r
+\r
+\r
+//NETCP ROUTE\r
+typedef struct NETCP_CFG_ROUTE_Tag\r
+{\r
+   NETCP_CFG_FLOW_HANDLE_T p_flow;\r
+   PKTIO_HANDLE_T * p_dest_q;\r
+   int nextAction;\r
+} NETCP_CFG_ROUTE_T;\r
+typedef void * NETCP_CFG_ROUTE_HANDLE_T;\r
+\r
+/*--------------flow management--------*/\r
+NETCP_CFG_FLOW_HANDLE_T netcp_cfgAddFlow(NETAPI_T ,\r
+                                            int n, \r
+                                            Pktlib_HeapHandle handles[],\r
+                                            int * err );\r
+void netcp_cfgDelFlow(NETAPI_T , NETCP_CFG_FLOW_HANDLE_T , int * err);\r
+\r
+/*------------Routes------------------*/\r
+NETCP_CFG_ROUTE_HANDLE_T netcp_cfgAddRoute(NETAPI_T ,int nh, \r
+                                               Pktlib_HeapHandle heaps[],\r
+                                               int *err );\r
+void netcp_cfgDelRoute(NETAPI_T , NETCP_CFG_ROUTE_HANDLE_T, int *err );\r
+\r
+/*-----------Actions----------*/\r
+#define NETCP_CFG_ACTION_DISCARD 0\r
+#define NETCP_CFG_ACTION_CONTINUE 1  //pass packet on to next classifier\r
+#define NETCP_CFG_ACTION_TO_SW    2\r
+\r
+/******************************************************************/\r
+/***********************APP ids for rx meta data********************/\r
+/******************************************************************/\r
+// NWAL "AP ids" for PA Rules that are added\r
+#define NETAPI_NETCP_MATCH_GENERIC_MAC   0x10000000  //lower byte==interface\r
+#define NETAPI_NETCP_MATCH_GENERIC_IP    0x20000000  //lower byte==interface\r
+#define NETAPI_NETCP_MATCH_CLASS         0x80000000  //or' in classifier #, lower byte==interface\r
+\r
+\r
+/*---------MAC APPID------------------*/\r
+typedef uint32_t NETCP_CFG_MACIF_T;\r
+\r
+/*------------L2----------------------*/\r
+typedef void * NETCP_CFG_VLAN_T;\r
+\r
+/*---------------IP APPID-------------------*/\r
+typedef uint32_t NETCP_CFG_IP_T;\r
+\r
+/* del mac i/f */\r
+void netcp_cfgDelMac(NETAPI_T h,int iface_no,  int *err);\r
+void netcp_cfgDelIp(NETAPI_T h, int iface_no,  nwal_IpType ipType,\r
+                  nwalIpAddr_t  * ip_addr,\r
+                  nwalIpOpt_t * ip_qualifiers, \r
+                  NETCP_CFG_IP_T, \r
+                  int *err);\r
\r
+\r
+/*****************************************************************\r
+ * Create a  MAC interface \r
+ ****************************************************************/\r
+/*\r
+*  @brief  API Creates a MAC interface  \r
+ *\r
+ *  @details This api is used to create a MAC interface.\r
+ *      Once it is created, the MAC interface can be used to receive packets. The API\r
+ *      adds a rule to the NETCP 1st level lookup tables to route all packets with destination\r
+ *      MAC matching supplied argument and not matching any other lookup entry (see @ref netcp_cfgAddIp) to\r
+ *      the supplied route, @ref NETCP_CFG_ROUTE_T, (or default route).\r
+ *      Packets arriving that match this rule are identified in meta data with Appid=  NETAPI_NETCP_MATCH_GENERIC_MAC\r
+ *  Note: The internal SOC switch must be "taught" that this mac\r
+ *      address is present by transmitting a packet with destination mac = this interface mac address.\r
+ *  @param[in]  @ref NETAPI_T: NETAPI instance \r
+ *  @param[in]  char *: pointer to 6 byte MAC address for interface\r
+ *  @param[in]  int : interface number (0,1,..) \r
+ *  @param[in]  int : switch port (0 don't care, 1 switch port 1, 1 switch port 2) [only 0 supported] \r
+ *  @param[in]  @ref NETCP_CFG_ROUTE_HANDLE_T : [future] handle of a created route or NULL to use internal default route \r
+ *  @oaram[in]  @ref NETCP_CFG_VLAN_T : [future[ vlan configuration . Set to NULL\r
+ *  @param[in]  int : [future] interface state (0=down, 1= up)\r
+ *  @param[out] int * err:  pointer to error return\r
+ *  @retval     @ref NETCP_CFG_MACIF_T : returned AppID for interface (this is returned in meta data for\r
+ *                 received packets matching this rule an no others)\r
+ *  @pre       @ref netapi_init \r
+ */\r
+NETCP_CFG_MACIF_T  netcp_cfgCreateMacInterface(\r
+                  NETAPI_T  h,     //\r
+                  uint8_t *p_mac, //mac address associated with interface\r
+                 int iface_no, //0,1, ..\r
+                  int switch_port,//0=don't care, 1=switch port 1, 2=switch port 2 , ..\r
+                  NETCP_CFG_ROUTE_HANDLE_T  route, //NULL to use default\r
+                  NETCP_CFG_VLAN_T  vlan,  //future\r
+                  int state,  //0=down, 1=up  //FUTURE\r
+                  int * err\r
+                  );\r
+\r
+/*****************************************************************\r
+ * Add IP address/qualifier to MAC interface \r
+ ****************************************************************/\r
+/*\r
+*  @brief  API attaches an IP adderess and qualifier to a MAC interface \r
+ *\r
+ *  @details This api is used to add an IP address to a MAC interface along\r
+ *           with optional IP qualifier. A route, @ref NETCP_CFG_ROUTE_HANDLE_T,or NULL for default \r
+ *            may be specified to indicate where to send packets matching the MAC interface MAC address, the\r
+ *            supplied IP address and any qualifier.  This API adds a rule to the NETCP level 1 lookup tables\r
+ *            Packets arriving that match this rule are identified in meta data with Appid=  NETAPI_NETCP_MATCH_GENERIC_IP\r
+ * Note: An IP address must be attached to enable NETCP Recevie Checksum offload feature\r
+ *  @param[in]  @ref NETAPI_T: NETAPI instance\r
+ *  @param[in]  int : interface number (0,1,..)\r
+ *  @param[in]  @ref nwal_IpType : type of IP address (V4 for V6) \r
+ *  @oaram[in]  @ref nwalIpAddr_t : ip_address\r
+ *  @param[in]  @ref nwalIpOpt_t : ip_qualifiers (all 0 for no qualifiers). This can be used to apply special handling for\r
+ *                  diffserv category for example\r
+ *  @param[in]  @ref NETCP_CFG_ROUTE_HANDLE_T : [future] handle of a created route or NULL to use internal default route \r
+ *  @param[out] int * err:  pointer to error return\r
+ *  @retval     @ref NETCP_CFG_IP_T : returned AppID for attached rule. This is returned in RX meta data for\r
+ *              packets matching this rule and no other.\r
+ *  @pre       @ref netapi_init , @ref netcp_cfgAddMac \r
+ */\r
+NETCP_CFG_IP_T  netcp_cfgAddIp(\r
+                  NETAPI_T  h,\r
+                  int  iface_no,\r
+                  nwal_IpType ipType,\r
+                  nwalIpAddr_t  * ip_addr,\r
+                  nwalIpOpt_t * ip_qualifiers,\r
+                  NETCP_CFG_ROUTE_HANDLE_T  route,  //NULL for default\r
+                  int * err\r
+                  );\r
+#define netcp_addIp netcp_cfgAddIp //oops\r
+\r
+/*------------------classification [FUTURE]-------------------*/\r
+typedef void *NETCP_CFG_CLASS_T;\r
+\r
+//add classifier\r
+typedef struct NETCP_CFG_CLASSIFIER_Tag\r
+{\r
+  //tbd a classisfier\r
+\r
+} NETCP_CFG_CLASSIFIER_T;\r
+\r
+NETCP_CFG_CLASS_T netcp_cfgAddClass(NETAPI_T h,\r
+                                      NETCP_CFG_CLASSIFIER_T *p_class,\r
+                                      NETCP_CFG_ROUTE_HANDLE_T p_route,\r
+                                      int action, int * err);\r
+//del classifier\r
+void netcp_cfgDelClass(NETAPI_T h,\r
+                         NETCP_CFG_CLASS_T p_class,\r
+                         int *err);\r
+\r
+\r
+\r
+/***************************************************************************\r
+********************************STATS**************************************\r
+**************************************************************************/\r
+\r
+/*\r
+ *  @brief  This is the callback function that is used to return statistics from NETCP \r
+ *\r
+ *  @details The application provides a callback function that NETAPI  uses to report statistics.\r
+*    The request for stats is generated from the @ref netcp_cfgReqStats API.\r
+ *   Note: to receive ths stats callback, the @ref netapi_netcpPoll funcition must be called\r
+ *  @param[in]  @ref NETAPI_T: NETAPI instance\r
+ *  @param[in]  @ref paSysStats_t * : the PA (NETCP packet accelerator subsystem) statistics block \r
+ *  @retval     none \r
+ *  @pre       @ref netapi_init , @ref netapi_cfgReqStats, @ref netapi_netcpPoll\r
+ */\r
+//stats CB\r
+typedef void (*NETCP_CFG_STATS_CB)( NETAPI_T h, paSysStats_t* pPaStats);\r
+\r
+\r
+//stats request\r
+/*\r
+ *  @brief  API request statistics from NETCP \r
+ *\r
+ *  @details This api is used to request a statistics from NETCP.  This will generate a stats request\r
+ *           command to NETCP. Sometime later, the statistics result will arrive and will be passed to \r
+ *           the caller via the asynchronus callback @ref NETCP_CFG_STATS_CB that is registered in this call.\r
+ *       Note: to receive the stats callback, the @ref netapi_netcpPoll funcition must be called\r
+ *  @param[in]  @ref NETAPI_T: NETAPI instance\r
+ *  @param[in]  @ref NETCP_CFG_STATS_CB : the function to call with the resulting statistics block\r
+ *  @param[in]  int :  clear the stats in NETCP after the report (0=no, 1=yes)                                          \r
+ *  @param[out] int * err:  pointer to error return\r
+ *  @retval     none \r
+ *  @pre       @ref netapi_init \r
+ */\r
+void netcp_cfgReqStats(NETAPI_T  h,  //NEAPI instance\r
+                       NETCP_CFG_STATS_CB c, //stats report callback function\r
+                       int doClear,   //0: don't clear, 1 clear\r
+                       int *err);\r
+\r
+#endif\r
+\r
index eb971fa1568db72310f2a7e6bf2bc4abbaeb07e1..abc5ebb27a86d8776676a471db87e1560c002dc3 100644 (file)
-/**********************************************************
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#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(">netcp_cfg: 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("> netcp_cfg 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 -1;}
-    *err =0;
-
-    pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
-    if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1;}
-    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 (">netcp cfg - ERROR: nwal_setMacIface returned Error Code %d\n",
-                    retValue);
-        pTransInfo->inUse = nwal_FALSE;
-        return -1;
-    }
-    //pTransInfo->inUse = nwal_FALSE;
-
-    //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 (">netcp cfg: 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  (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no);
-}
-
-
-/*****************************************************************/
-/***************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 -1;}
-
-     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 -1;
-     }
-
-     //get a transaction object for config action
-    pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
-    if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1;}
-    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 (">netcp cfg: nwal_setIP returned Error Code %d\n",
-                    retValue);
-        pTransInfo->inUse = nwal_FALSE;
-        return -1;
-    }
-    //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 (">netcp cfg: 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  (NETAPI_NETCP_MATCH_GENERIC_IP | iface_no);
-}
-
-
-
-/*************************************************************************/
-/*********************************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)
-    {
-        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 (">netcp cfg : 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 ("netcp cfg> 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;
-  
-    if(trans_id == NWAL_TRANSID_SPIN_WAIT)
-    {
-        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);
-    
-} 
-
+/**********************************************************\r
+ * file: netcp_cfg.c\r
+ * purpose: netcp configurations routines\r
+ **************************************************************\r
+ * FILE: netcp_cfg.c\r
+ * \r
+ * DESCRIPTION:  netcp configuration main source file for user space transport\r
+ *               library\r
+ * \r
+ * REVISION HISTORY:  rev 0.0.1 \r
+ *\r
+ *  Copyright (c) Texas Instruments Incorporated 2010-2011\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
+ *\r
+ *    Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the \r
+ *    documentation and/or other materials provided with the   \r
+ *    distribution.\r
+ *\r
+ *    Neither the name of Texas Instruments Incorporated nor the names of\r
+ *    its 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 FOR\r
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+ ******************************************************/\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <unistd.h>\r
+#include <string.h>\r
+#include "netapi.h"\r
+#include "netcp_cfg.h"\r
+#include "netapi_loc.h"\r
+\r
+/******************************************************************\r
+ ********************Utility*************************************\r
+*******************************************************************/\r
+\r
+\r
+//get a free transaction id\r
+static NetapiNwalTransInfo_t *  netapi_GetFreeTransInfo(NETAPI_GLOBAL_T *p_global, nwal_TransID_t *pTransId)\r
+{\r
+         uint16_t    count=0;\r
+\r
+       count=0;\r
+        while(count < TUNE_NETAPI_MAX_NUM_TRANS)\r
+        {\r
+            if((p_global->nwal_context.transInfos[count].inUse) != nwal_TRUE)\r
+            {\r
+                p_global->nwal_context.transInfos[count].inUse = nwal_TRUE;\r
+                *pTransId = count;\r
+                return(&p_global->nwal_context.transInfos[count]);\r
+            }\r
+            count++;\r
+        }\r
+         \r
+        /* trouble.  need to wait for one to free up*/\r
+        /* to do: handle this by forcing a poll of cntrl queue*/\r
+        printf(">netcp_cfg: trying to get free transaction slot but all full!!\n");\r
+        return NULL;\r
+\r
+}\r
+\r
+//internal: find a free slot for IP rule in interface\r
+static int netcp_cfgp_find_ip_slot(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
+                          int iface_no)\r
+{\r
+   int i;\r
+   if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
+   {\r
+        return -1;\r
+   }\r
+   if (!p->interfaces[iface_no].in_use) return -1;\r
+\r
+   //find a free entry\r
+   for(i=0;i<TUNE_NETAPI_MAX_IP_PER_INTERFACE;i++)\r
+   {\r
+       if (!p->interfaces[iface_no].ips[i].in_use)\r
+       {\r
+           p->interfaces[iface_no].ips[i].in_use = 2; //pending\r
+           return i;\r
+       }\r
+   }\r
+   return -1;\r
+}\r
+\r
+//internal:  insert an IP address into iface\r
+static void netcp_cfgp_insert_ip(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, \r
+                          nwal_IpType ipType,\r
+                          nwalIpAddr_t *ip_addr, \r
+                          nwalIpOpt_t *ip_qualifiers, \r
+                          int iface_no,\r
+                          int ip_slot,  //we 'reserved it already'\r
+                          void * handle)\r
+{\r
+        p->interfaces[iface_no].ips[ip_slot].in_use=1;\r
+        memcpy(&p->interfaces[iface_no].ips[ip_slot].ip_addr, ip_addr, sizeof(nwalIpAddr_t));\r
+        if(ip_qualifiers)\r
+        memcpy(&p->interfaces[iface_no].ips[ip_slot].ip_qualifiers, ip_qualifiers, sizeof(nwalIpOpt_t));\r
+        else\r
+        memset(&p->interfaces[iface_no].ips[ip_slot].ip_qualifiers, 0, sizeof(nwalIpOpt_t));\r
+        p->interfaces[iface_no].ips[ip_slot].ip_type = ipType;\r
+        p->interfaces[iface_no].ips[ip_slot].nwal_handle = handle;\r
+        return;\r
+}\r
+\r
+\r
+//internal: instert interface info into global context\r
+static void netcp_cfgp_insert_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, unsigned char * p_mac, \r
+                           int iface_no, int state, NETCP_CFG_VLAN_T vlan, void * handle)\r
+{\r
+   if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES))\r
+   {\r
+        memset(&p->interfaces[iface_no],0,sizeof(NETCP_INTERFACE_T));\r
+       p->interfaces[iface_no].in_use = 1;\r
+       memcpy(&p->interfaces[iface_no].mac[0], p_mac,6);\r
+        p->interfaces[iface_no].state = state;\r
+       //todo p->interfaces[iface_no].vlan = vlan;\r
+       p->interfaces[iface_no].nwal_handle = handle; //save handle assoicated with this rule\r
+   }\r
+   else printf(">netcp_cfg insert interface # out of range %d\n",iface_no);\r
+\r
+}\r
+//internal: clear inteface entry\r
+static void netcp_cfgp_delete_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no)  \r
+{\r
+   if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES))\r
+   {\r
+        p->interfaces[iface_no].in_use = 0;\r
+   }\r
+}\r
+//internal: free IP slot associated with ip address \r
+static void netcp_cfgp_delete_ip(\r
+         NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
+         int iface_no,\r
+         int ip_slot )\r
+{\r
+   if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
+   {\r
+        return ;\r
+   }\r
+   if (!p->interfaces[iface_no].in_use) return ;\r
+   if ((ip_slot <0)||(ip_slot>TUNE_NETAPI_MAX_IP_PER_INTERFACE)) return ;\r
+   p->interfaces[iface_no].ips[ip_slot].in_use=0;\r
+   return;\r
+}\r
+\r
+\r
+//internal: get IP handle associated with ip address \r
+static void *netcp_cfgp_get_ip_handle(\r
+         NETAPI_NWAL_GLOBAL_CONTEXT_T *p, \r
+         int iface_no,\r
+         int ip_slot )\r
+{\r
+   if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
+   {\r
+       return NULL;\r
+   }\r
+   if (!p->interfaces[iface_no].in_use) return NULL;\r
+   if ((ip_slot <0)||(ip_slot>=TUNE_NETAPI_MAX_IP_PER_INTERFACE)) return NULL;\r
+   if (!p->interfaces[iface_no].ips[ip_slot].in_use) return NULL;\r
+   return (void *) p->interfaces[iface_no].ips[ip_slot].nwal_handle;\r
+}\r
+\r
+//internal: get handle associated with interface\r
+static void* netcp_cfgp_get_mac_handle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no)\r
+{\r
+   if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
+   {\r
+       return NULL;\r
+   }\r
+   else if ( p->interfaces[iface_no].in_use)\r
+   {\r
+     return (void *) p->interfaces[iface_no].nwal_handle;\r
+   }\r
+   //no valid entry in slot\r
+   return NULL;\r
+}\r
+\r
+\r
+/***********************************************************************************/\r
+/****************************************API****************************************/\r
+/***********************************************************************************/\r
+\r
+\r
+/*****************************************************************\r
+ *  Queury Stats\r
+ ****************************************************************/\r
+void netcp_cfgReqStats(NETAPI_T  h, NETCP_CFG_STATS_CB cb, int doClear, int *err) \r
+{\r
+nwal_RetValue ret;\r
+NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
+NetapiNwalTransInfo_t *pTransInfo;\r
+nwal_TransID_t     transId;\r
+if ((!n) || (!cb)) {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
+*err =0;\r
+\r
+pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &transId);\r
+if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}\r
+pTransInfo->transType = NETAPI_NWAL_HANDLE_STAT_REQUEST;\r
+pTransInfo->netapi_handle = h;\r
+n->nwal_local.stats_cb = cb;\r
+ret = nwal_getPAStats( ((NETAPI_GLOBAL_T *) n->global)->nwal_context.nwalInstHandle,\r
+                          transId,\r
+                          NULL,\r
+                          doClear);\r
+if(ret !=  nwal_OK)\r
+{\r
+   pTransInfo->inUse = nwal_FALSE;\r
+   *err = NETAPI_ERR_BUSY;  //no resources??\r
+   printf("> netcp_cfg reqStats failed, err=%d\n",ret);\r
+}\r
+\r
+}\r
+/*****************************************************************\r
+ *  CREATE A MAC INTERFACE\r
+ ****************************************************************/\r
+NETCP_CFG_MACIF_T  netcp_cfgCreateMacInterface(\r
+                  NETAPI_T  h,\r
+                  uint8_t *p_mac,\r
+                 int  iface_no, \r
+                  int switch_port, \r
+                  NETCP_CFG_ROUTE_HANDLE_T  route,\r
+                  NETCP_CFG_VLAN_T  vlan,  //future\r
+                  int state,  //0=down, 1=up  //ignored\r
+                  int * err\r
+                  )\r
+{\r
+NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
+nwalMacParam_t   MacInfo= {\r
+    0,      /* validParams */\r
+    0,      /* ifNum */\r
+    0,      /* vlanId      */\r
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },      /* Local mac */\r
+    NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */\r
+    NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */\r
+    CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */\r
+    QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */\r
+};\r
+\r
+nwal_RetValue       retValue;\r
+NetapiNwalTransInfo_t *pTransInfo;\r
+nwal_TransID_t     trans_id;\r
+\r
+    if ((!n) || (!p_mac)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}\r
+    *err =0;\r
+\r
+    pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
+    if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1;}\r
+    pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;\r
+    pTransInfo->netapi_handle = h; \r
+\r
+    /* set up MacInfo */\r
+    memcpy(&MacInfo.macAddr,p_mac,6); \r
+    /* todo: vlan */\r
+    MacInfo.ifNum = switch_port;  /* todo: check for 0/1 relative*/\r
+\r
+#if 0  //todo\r
+    if (route != NULL)\r
+    {\r
+        MacInfo.appRxPktFlowId = ((NETCP_CFG_FLOW_T *)(route.flow))->flowid;\r
+        MacInfo.appRxPktQueue = PKTIO_GET_Q(route->p_dest_q);\r
+        //handle action ??\r
+    }\r
+#endif\r
+    pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;\r
+    retValue = nwal_setMacIface( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
+                                  trans_id,\r
+                                  (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no),\r
+                                  &MacInfo,\r
+                                  &pTransInfo->handle);\r
+    if(retValue !=  nwal_OK)\r
+    {\r
+       *err = NETAPI_ERR_NWAL_ERR0;\r
+        printf (">netcp cfg - ERROR: nwal_setMacIface returned Error Code %d\n",\r
+                    retValue);\r
+        pTransInfo->inUse = nwal_FALSE;\r
+        return -1;\r
+    }\r
+    //pTransInfo->inUse = nwal_FALSE;\r
+\r
+    //wait here until its done since scheduler isn't running yet most likely..\r
+    // todo:  make this handled by scheduler poll later ??\r
+    if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
+    {\r
+        n->nwal_local.numPendingCfg++;\r
+        while ((volatile) n->nwal_local.numPendingCfg)\r
+        {\r
+           // if response is there, then this poll squirts out in the CTl poll callback, \r
+            // which handles the rest (including decrmenting #pending!!\r
+            nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
+        }\r
+    }\r
+    printf (">netcp cfg: MAC i/f %d added\n", iface_no);\r
+    netcp_cfgp_insert_mac(&netapi_get_global()->nwal_context, \r
+                          p_mac, iface_no, state,vlan,\r
+                          (void *) pTransInfo->handle);\r
+    pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
+    pTransInfo->inUse = nwal_FALSE;\r
+    return  (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no);\r
+}\r
+\r
+\r
+/*****************************************************************/\r
+/***************Delete a mac interface****************************/\r
+/*****************************************************************/\r
+void netcp_cfgDelMac(NETAPI_T h,int iface_no,  int *err)\r
+{\r
+    nwal_RetValue ret;\r
+    NetapiNwalTransInfo_t *pTransInfo;\r
+    nwal_TransID_t     trans_id;\r
+    NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
+    void * ifHandle;\r
+\r
+    //get the nwal handle assoicated with this iface\r
+    ifHandle = netcp_cfgp_get_mac_handle(&netapi_get_global()->nwal_context, iface_no );\r
+    if(!ifHandle) \r
+            {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
+    *err =0;\r
+    \r
+    //get a transaction id\r
+    pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
+    if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}\r
+    pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;\r
+    pTransInfo->netapi_handle = h;\r
+    //issue request\r
+    ret = nwal_delMacIface(\r
+                ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
+                trans_id,\r
+                ifHandle);\r
+    if(ret !=  nwal_OK)\r
+    {\r
+        *err = NETAPI_ERR_NWAL_ERR0;\r
+        printf (">netcp cfg - ERROR: nwal_delMacIface returned Error Code %d\n",\r
+                    ret);\r
+        pTransInfo->inUse = nwal_FALSE;\r
+        return ;\r
+    }\r
+    //wait here until its done since scheduler isn't running yet most likely..\r
+    // todo:  make this handled by scheduler poll later ??\r
+    if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
+    {\r
+        n->nwal_local.numPendingCfg++;\r
+        while ((volatile) n->nwal_local.numPendingCfg)\r
+        {\r
+            // if response is there, then this poll squirts out in the CTl poll callback, \r
+            // which handles the rest (including decrmenting #pending!!\r
+            nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
+        }\r
+    }\r
+    printf (">netcp cfg: MAC i/f %d deleted\n",iface_no);\r
+    pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
+    pTransInfo->inUse = nwal_FALSE;\r
+    //zap the entry\r
+    netcp_cfgp_delete_mac(&netapi_get_global()->nwal_context,  iface_no);\r
+    return ;\r
+}\r
+\r
+\r
+/*****************************************************************/\r
+/***************Add IP to MAC interface****************************/\r
+/*****************************************************************/\r
+NETCP_CFG_IP_T  netcp_cfgAddIp(\r
+                  NETAPI_T  h,\r
+                  int  iface_no,\r
+                  nwal_IpType ipType,\r
+                 nwalIpAddr_t  * ip_addr,\r
+                 nwalIpOpt_t * ip_qualifiers,\r
+                  NETCP_CFG_ROUTE_HANDLE_T  route,  //NULL for default\r
+                  int * err\r
+                  )\r
+{\r
+NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
+void * n_handle;\r
+nwalIpParam_t    nwalIpParam= {\r
+    pa_IPV4,      /* IP Type */\r
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Dest IP */\r
+    { 0x0,0,0,0},/* IP Options */\r
+    NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */\r
+    NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */\r
+    CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */\r
+    QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */\r
+};\r
+nwal_RetValue       retValue;\r
+NetapiNwalTransInfo_t *pTransInfo;\r
+nwal_TransID_t     trans_id;\r
+int ip_slot=-1;\r
+NETCP_CFG_IP_T ip_rule_id;\r
+\r
+     //verify that iface has been configurred \r
+     if ((iface_no<0) || (iface_no>= TUNE_NETAPI_MAX_INTERFACES)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}\r
+\r
+     if(netapi_get_global()->nwal_context.interfaces[iface_no].in_use)\r
+     {\r
+       n_handle =  netapi_get_global()->nwal_context.interfaces[iface_no].nwal_handle;\r
+     }\r
+     else\r
+     {\r
+       *err = NETAPI_ERR_BAD_INPUT;\r
+       return -1;\r
+     }\r
+     //find free slot for IP & reserve\r
+     ip_slot= netcp_cfgp_find_ip_slot(&netapi_get_global()->nwal_context, \r
+                                   iface_no);\r
+     if (ip_slot <0) \r
+     {\r
+       *err= NETAPI_ERR_NOMEM;  //no room \r
+     }\r
+\r
+     //get a transaction object for config action\r
+    pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
+    if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1;}\r
+    pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;\r
+    pTransInfo->netapi_handle = h;\r
+\r
+     //build nwalIpParam\r
+     memcpy(&nwalIpParam.locIpAddr,ip_addr, sizeof(nwalIpAddr_t));\r
+     nwalIpParam.ipType=ipType;\r
+     if(route)\r
+     {\r
+          //todo: support app defined routes\r
+     } \r
+     else{} //use nwal defaults\r
+     if (ip_qualifiers)\r
+       memcpy(&nwalIpParam.ipOpt,ip_qualifiers, sizeof(nwalIpOpt_t)); \r
+     else\r
+        memset(&nwalIpParam.ipOpt,0, sizeof(nwalIpOpt_t));\r
+\r
+     //build the rule id that will be returned when a packet matches \r
+     ip_rule_id = NETAPI_NETCP_MATCH_GENERIC_IP | iface_no | ((ip_slot&&0xff)<<8);\r
+     //perform config action\r
+     pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;\r
+     retValue = nwal_setIPAddr(   netapi_get_global()->nwal_context.nwalInstHandle,\r
+                                  trans_id,\r
+                                  (nwal_AppId) (ip_rule_id),\r
+                                  n_handle,\r
+                                  &nwalIpParam,\r
+                                  &pTransInfo->handle);\r
+\r
+    if(retValue !=  nwal_OK)\r
+    {\r
+        *err = NETAPI_ERR_NWAL_ERR0;\r
+        printf (">netcp cfg: nwal_setIP returned Error Code %d\n",\r
+                    retValue);\r
+        pTransInfo->inUse = nwal_FALSE;\r
+        //zap the entry\r
+        netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context,\r
+                         iface_no,\r
+                         ip_slot);\r
+\r
+        return -1;\r
+    }\r
+    //wait here until its done since scheduler isn't running yet most likely..\r
+    // todo:  make this handled by scheduler poll later ??\r
+    if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
+    {\r
+        n->nwal_local.numPendingCfg++;\r
+        while ((volatile) n->nwal_local.numPendingCfg)\r
+        {\r
+            // if response is there, then this poll squirts out in the CTl poll callback, \r
+            // which handles the rest (including decrmenting #pending!!\r
+            nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
+        }\r
+    }\r
+    printf (">netcp cfg: IP added to interface %d (slot%d)\n", iface_no, ip_slot);\r
+    netcp_cfgp_insert_ip(&netapi_get_global()->nwal_context, ipType, \r
+                          ip_addr, ip_qualifiers, iface_no, ip_slot,\r
+                          pTransInfo->handle);\r
+    pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
+    pTransInfo->inUse = nwal_FALSE;\r
+    return  (ip_rule_id);\r
+}\r
+\r
+/*****************************************************************/\r
+/***************Delete an attached IP*****************************/\r
+/*****************************************************************/\r
+void netcp_cfgDelIp(NETAPI_T h, int iface_no,  nwal_IpType ipType,\r
+                  nwalIpAddr_t  * ip_addr,\r
+                  nwalIpOpt_t * ip_qualifiers, \r
+                  NETCP_CFG_IP_T  ip_rule_id,\r
+                  int *err)\r
+{\r
+    nwal_RetValue ret;\r
+    NetapiNwalTransInfo_t *pTransInfo;\r
+    nwal_TransID_t     trans_id;\r
+    NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
+    void * ifHandle;\r
+    int ip_slot = (ip_rule_id>>8)&0xff;\r
+\r
+    //get the nwal handle assoicated with this ip   \r
+    ifHandle = netcp_cfgp_get_ip_handle(\r
+         &netapi_get_global()->nwal_context, iface_no,\r
+         ip_slot );\r
+    if(!ifHandle)\r
+            {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
+    *err =0;\r
+\r
+    //get a transaction id\r
+    pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
+  if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}\r
+    pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;\r
+    pTransInfo->netapi_handle = h;\r
+    //issue request\r
+    ret = nwal_delIPAddr(\r
+                ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
+                trans_id,\r
+                ifHandle);\r
+    if(ret !=  nwal_OK)\r
+    {\r
+        *err = NETAPI_ERR_NWAL_ERR0;\r
+        printf (">netcp cfg - ERROR: nwal_delMacIface returned Error Code %d\n",\r
+                    ret);\r
+        pTransInfo->inUse = nwal_FALSE;\r
+        return ;\r
+    }\r
+    //wait here until its done since scheduler isn't running yet most likely..\r
+    // todo:  make this handled by scheduler poll later ??\r
+    if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
+    {\r
+       n->nwal_local.numPendingCfg++;\r
+        while ((volatile) n->nwal_local.numPendingCfg)\r
+        {\r
+            // if response is there, then this poll squirts out in the CTl poll callback, \r
+            // which handles the rest (including decrmenting #pending!!\r
+            nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
+        }\r
+    }\r
+    printf (">netcp cfg: IP i/f deleted\n");\r
+    pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
+    pTransInfo->inUse = nwal_FALSE;\r
+    //zap the entry\r
+    netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context,  \r
+                         iface_no,\r
+                         ip_slot);\r
+    return ;\r
+}\r
+\r
+\r
+/*************************************************************************/\r
+/*********************************INTERNAL*******************************/\r
+/************************************************************************/\r
+\r
+/***************************************************************\r
+ ********************METCP CMD Reply Callback******************\r
+ ***************************************************************/\r
+void netapi_NWALCmdCallBack (nwal_AppId        appHandle,\r
+                          uint16_t            trans_id,\r
+                          nwal_RetValue     ret)\r
+{\r
+    NetapiNwalTransInfo_t * p_trans;\r
+    NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;\r
+\r
+    if(trans_id == NWAL_TRANSID_SPIN_WAIT)\r
+    {\r
+        netapi_get_global()->nwal_context.numBogusTransIds++;\r
+        return;\r
+    }\r
+\r
+    p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];\r
+    p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;\r
+\r
+    if(ret != nwal_OK)\r
+    {\r
+        printf (">netcp cfg : NWALCmdCallBack returned Error Code %d\n",\r
+                    ret);\r
+       //todo: atomic inc\r
+        netapi_get_global()->nwal_context.numCmdFail++;\r
+    }\r
+    else\r
+    {\r
+       //todo: atomic inc\r
+        netapi_get_global()->nwal_context.numCmdPass++;\r
+        switch(p_trans->transType)\r
+        {\r
+            case NETAPI_NWAL_HANDLE_TRANS_MAC:\r
+            {\r
+                if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
+                {\r
+                    p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
+                }\r
+                else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
+                {\r
+                    p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
+                }\r
+                break;\r
+            }\r
+            case NETAPI_NWAL_HANDLE_TRANS_IP:\r
+            {\r
+                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
+                {\r
+                    p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
+                }\r
+                else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
+                {\r
+                    p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
+                }\r
+                break;\r
+            }\r
+#if 0\r
+            case TEST_NWAL_HANDLE_TRANS_PORT:\r
+            {\r
+                if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)\r
+                {\r
+                    testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;\r
+                }\r
+                else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
+                {\r
+                    testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;\r
+                }\r
+                break;\r
+            }\r
+            case TEST_NWAL_HANDLE_TRANS_SEC_ASSOC:\r
+            {\r
+                if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)\r
+                {\r
+                    testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;\r
+                }\r
+                else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
+                {\r
+                    System_printf ("Set Security Assoc  Close ACK received for trans_id: %d\n",\r
+                                testNwLocContext.transInfos[trans_id].transType,trans_id);\r
+                    nwal_SystemFlush();\r
+                    testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;\r
+                }\r
+                break;\r
+            }\r
+case TEST_NWAL_HANDLE_TRANS_SEC_POLICY:\r
+            {\r
+                if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)\r
+                {\r
+                    testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;\r
+                }\r
+                else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
+                {\r
+                    System_printf ("Set Security Policy  Close ACK received for trans_id: %d\n",\r
+                                testNwLocContext.transInfos[trans_id].transType,trans_id);\r
+                    nwal_SystemFlush();\r
+                    testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;\r
+                }\r
+                break;\r
+            }\r
+#endif\r
+            default:\r
+            {\r
+                printf ("netcp cfg> Invalid transaction type %d for trans_id: %d\n",\r
+                    p_trans->transType,trans_id);\r
+                break;\r
+            }\r
+        }\r
+    }\r
+\r
+    p_local->numPendingCfg--;\r
+\r
+    if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_IDLE)\r
+    {\r
+        p_trans->inUse = nwal_FALSE;\r
+    }\r
+\r
+}\r
+\r
+\r
+/*******************************************************/\r
+/**************stats reply callback**********************/\r
+/*******************************************************/\r
+void netapi_NWALCmdPaStatsReply (nwal_AppId        appHandle,\r
+                              nwal_TransID_t    trans_id,\r
+                              paSysStats_t      *stats)\r
+{\r
+    NetapiNwalTransInfo_t * p_trans;\r
+    NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;\r
+  \r
+    if(trans_id == NWAL_TRANSID_SPIN_WAIT)\r
+    {\r
+        netapi_get_global()->nwal_context.numBogusTransIds++;\r
+        return;\r
+    }\r
+\r
+    p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];\r
+    p_trans->inUse = nwal_FALSE;\r
+    p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;\r
+\r
+    //save a local copy  of some stuff*/\r
+    p_local->numL2PktsRecvd=stats->classify1.nPackets;\r
+    p_local->numL3PktsRecvd=stats->classify1.nIpv4Packets;\r
+#if 0\r
+    p_local->numL4PktsRecvd=stats->;\r
+    p_local->numL4PktsSent=stats->;\r
+    p_local->TxErrDrop=stats->;\r
+#endif\r
+    //callout result to application !!\r
+    if (p_local->stats_cb) (*p_local->stats_cb)(p_trans->netapi_handle,stats);\r
+    \r
+} \r
+\r
index 11d9c5dd14772060bef1e31fc012b22c81894427..fd0f55df2c8728cfe34fce78385c179011a99ca0 100755 (executable)
-/******************************************
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.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 };
-nwalIpAddr_t OurIp1={ 10, 0, 1, 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;
-}
-
-#if 0
-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}};
-HEAD_T temp;
-memcpy(&temp,&testPkt[0],sizeof(HEAD_T));
-
-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;
-}
-#endif
-
-void build_table(Trie * p_trie)
-{
-int i;
-int sport=NEW_START_SRC_PORT; 
-HEAD_T temp,temp2;
-KEY_T key;
-
-memcpy(&temp,&testPkt[14],sizeof(temp));
-
- //insert entry into trie
-key.src_ip = temp.ip[3];
-key.dst_ip = temp.ip[4];
-key.src_port= (temp.udp[0]&0xffff0000)>>16;
-key.dst_port= (temp.udp[0]&0x0000ffff);
-trie_insert(p_trie,(char *)&key,sizeof(key), (void *) &nat[0]); //asociate with nat entry 0
-
-//build nat table
-for(i=0;i<100;i++)
-{
-   memcpy(&temp2,&testPkt[14],sizeof(temp));
-   temp2.udp[0] = (temp2.udp[0] & 0xffff0000) |  sport;
-   memcpy(&nat[i], &temp2, sizeof(temp2));
-   sport+= 1;
-}
-}
-
-//===========stub transmitter==================
-void send_pkt(Ti_Pkt *pkt, int len)
-{
-//just free pkt.  Don't send
-Pktlib_freePacket((Ti_Pkt*)pkt);
-       return;
-}
-
-//==========stub slow path============
-void slow_path(Ti_Pkt *pkt, int len)
-{
-// debug: check descriptor for validity by verifying that desciptor link field is null as expected\n");
-         {Ti_Pkt * k= Pktlib_getNextPacket(pkt); if(k != 0) {printf(" slowpath, nexpkt != NULL");}}
-//just free pkt
-Pktlib_freePacket((Ti_Pkt*)pkt);
-       return;
-}
-/* check header */
-struct LastPktInfo
-{
-int iface;
-int ipcsum;
-int l4csum;
-} ;
-static struct LastPktInfo lpInfo;
-
-int check_header(HEAD_T * p_head, PKTIO_METADATA_T * p_meta)
-{
-if (NWAL_RX_FLAG1_META_DATA_VALID & p_meta->u.rx_meta->rxFlag1)
-{
-lpInfo.iface = ((unsigned int)p_meta->u.rx_meta->appId) &0xff; //last byte is interface num
-lpInfo.ipcsum =(p_meta->u.rx_meta->rxFlag1 & NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_MASK )== NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_ACK ? 1 : 0;
-lpInfo.l4csum = (p_meta->u.rx_meta->rxFlag1 & NWAL_RX_FLAG1_L4_CHKSUM_VERIFY_MASK )== ((NWAL_RX_FLAG1_L4_CHKSUM_VERIFY_ACK) << NWAL_RX_FLAG1_L4_CHKSUM_VERIFY_SHIFT) ? 1 : 0; 
-}
- 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 - 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,&meta[i])) { 
-               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));
-
-       memcpy(&p_pkt[14],p_head,sizeof(HEAD_T));
-        /* update_mac(&p_pkt[0]);  */
-
-       /* 'simulate' 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,  //timer group tics
-        &err);
-  else if (cookie ==2)
-      t2 = netapi_TimerGroupStartTimer(
-        th,
-        (void *) 2,
-        200LL,  //timer group ticks
-        &err);
-  else
-  {
-    t3 = netapi_TimerGroupStartTimer(
-        th,
-        (void *) 3,
-        300LL,  //timer group ticks
-        &err);
-    //cancel 1 and restart 1
-   netapi_TimerGroupCancel(th,t1,&err);
-   t1 = netapi_TimerGroupStartTimer(
-        th,
-        (void *) 1,
-        100LL,  //timer group ticks
-        &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",pPaStats->classify1.nSystemFail);
-       printf ("C2 number parse failed  :      %d\n",pPaStats->classify2.nParseFail);
-       printf ("C2 number Invld Header  :      %d\n",pPaStats->classify2.nInvldHdr);
-       printf ("C2 number udp           :      %d\n",pPaStats->classify2.nUdp);
-       printf ("C2 number tcp           :      %d\n",pPaStats->classify2.nTcp);
-       printf ("C2 number cmd fail      :      %d\n",pPaStats->classify2.nCommandFail);
-       printf ("C2 number silent drop   :      %d\n",pPaStats->classify2.nSilentDiscard);
-       printf ("C2 number invalid cntrl :      %d\n\n",pPaStats->classify2.nInvalidControl);
-}
-Pktlib_getHeapStats(OurHeap, &numFreeDataPackets,
-                             &numZeroBufferPackets, &numPacketsinGarbage);
-printf("heap stats>  #free=%d #zb=%d #garbage=%d\n", numFreeDataPackets,
-                                numZeroBufferPackets, numPacketsinGarbage);
-//debug = dump timer polling stats
-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",(PKTIO_CB) 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, (PKTIO_CB) 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); }
-
-//attach an IP to this interface
-netcp_addIp(
-                  netapi_handle,
-                  1,
-                  nwal_IPV4,
-                  &OurIp1,
-                  NULL,  //all IP
-                  (NETCP_CFG_ROUTE_HANDLE_T) NULL,
-                  &err
-                  );
-if (err) {printf("addip1 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()/1000,  /* 1 msc resolution for these timers */
-        netapi_getTicksPerSec()/5000, /* would like .5 msc tolerence */
-        10,  //small # of timers to test garbage collection
-        &err);
-if (err) {printf("timergroupcreate failed %d\n",err); exit(1);}
-
-//start a couple of timers 
-t1 = netapi_TimerGroupStartTimer(
-        ourTimerBlock,
-        (void *) 1,
-        100LL,  //timer group ticks
-        &err);
-if (err) {printf("timerstart failed %d\n");}
-t2 = netapi_TimerGroupStartTimer(
-        ourTimerBlock,
-        (void *) 2,
-        200LL,  //timer group ticks
-        &err);
-if (err) {printf("timerstart failed %d\n");}
-t3 = netapi_TimerGroupStartTimer(
-        ourTimerBlock,
-        (void *) 3,
-        300LL,  //timer group ticks
-        &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);
-n_pkt= np2process;
-
-/* 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);
-
-}
+/******************************************\r
+ * File: net_test.c\r
+ * Purpose: test app for netapi\r
+ **************************************************************\r
+ * FILE:  net_test.c\r
+ * \r
+ * DESCRIPTION:  netapi user space transport\r
+ *               library  test application\r
+ * \r
+ * REVISION HISTORY:  rev 0.0.1 \r
+ *\r
+ *  Copyright (c) Texas Instruments Incorporated 2010-2011\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
+ *\r
+ *    Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the \r
+ *    documentation and/or other materials provided with the   \r
+ *    distribution.\r
+ *\r
+ *    Neither the name of Texas Instruments Incorporated nor the names of\r
+ *    its 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 FOR\r
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+ *****************************************/\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <unistd.h>\r
+#include <string.h>\r
+\r
+\r
+#include "trie.h"\r
+#include "string.h"\r
+#include "netapi.h"\r
+#include "pktio.h"\r
+#include <sys/resource.h>\r
+\r
+/*************debug********************/\r
+void dump_descr(unsigned long *p, int n)\r
+{\r
+   printf("--------dump of descriptor %d %x\n", n, (int) p);\r
+   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]);\r
+   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]);\r
+   printf("-----------------------------\n");\r
+}\r
+/*****************************************/\r
+\r
+\r
+//************for multi pkt burst  xfer test in loopback mode\r
+#define TX_BURST 4\r
+int pktloopback=TUNE_NETAPI_NWAL_ENABLE_PASS_LOOPBACK;\r
+\r
+//this device: 10.0.0.100, mac 0x,01,02,03,04,05  and .. 0x6\r
+\r
+//test packet, setup for loopback (so dest is ourself)\r
+static uint8_t testPkt[] = {\r
+\r
+  /* MAC header */\r
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05,\r
+  0x00, 0xe0, 0xa6, 0x66, 0x57, 0x04,\r
+  0x08, 0x00,\r
+\r
+  /* IP header */\r
+  0x45, 0x00,\r
+  0x00, 0x6c,  /* Length (including this header) */\r
+  0x00, 0x00, 0x00, 0x00, 0x05, 0x11,\r
+  0x00, 0x00,  /* Header checksum */\r
+  0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x64,\r
+\r
+  /* UDP header */\r
+  0x12, 0x34, 0x05, 0x55,\r
+  0x00, 0x58,  /* Length, including this header */\r
+  0x00, 0x00,  /* Header checksum */\r
+\r
+ /* Payload */\r
+  0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,\r
+  0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41,\r
+  0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,\r
+  0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,\r
+  0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,\r
+  0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61,\r
+  0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,\r
+  0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,\r
+  0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,\r
+  0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81\r
+\r
+};\r
+\r
+#define TEST_PAYLOAD_LEN            80\r
+\r
+#define TEST_PKT_IP_OFFSET_BYTES        14\r
+#define TEST_PKT_UDP_OFFSET_BYTES       34\r
+#define TEST_PKT_PLOAD_OFFSET_BYTES     42\r
+#define TEST_PKT_UDP_HDR_LEN            8\r
+/* Offsets to length fields */\r
+#define TEST_PKT_OFFSET_IP_LEN      16\r
+#define TEST_PKT_OFFSET_UDP_LEN     38\r
+\r
+#define TEST_PKT_LEN                122\r
+\r
+/* The pseudo header checksum of the packet except for the 16 bit length */\r
+#define TEST_PKT_PSEUDO_HDR_CHKSUM_SANS_LEN  0x0FFC\r
+\r
+\r
+\r
+#if 1\r
+//#include "arpa/inet.h"\r
+long htonl(long x)\r
+{\r
+       long temp = (x&0xff000000)>>24 | (x&0xff0000)>>8 | (x&0xff00)<<8 |  (x&0xff)<<24 ;\r
+       return temp;\r
+}\r
+\r
+/********************************************************************\r
+ *  FUNCTION PURPOSE: Ones complement addition utility\r
+ ********************************************************************\r
+ ********************************************************************/\r
+uint16_t test_utilOnesComplementAdd (uint16_t v1, uint16_t v2)\r
+{\r
+  uint32_t result;\r
+\r
+  result = (uint32_t)v1 + (uint32_t)v2;\r
+  result = (result >> 16) + (result & 0xffff);\r
+  result = (result >> 16) + (result & 0xffff);\r
+\r
+  return ((uint16_t)result);\r
+}\r
+\r
+/********************************************************************\r
+ *  FUNCTION PURPOSE: Ones complement checksum utility\r
+ ********************************************************************\r
+ ********************************************************************/\r
+ uint16_t test_utilOnesCompChkSum (uint8_t *p, uint32_t nwords)\r
+{\r
+  uint16_t chksum = 0;\r
+  uint16_t v;\r
+  uint32_t i;\r
+  uint32_t j;\r
+\r
+  for (i = j = 0; i < nwords; i++, j+=2)  {\r
+    v = (p[j] << 8) | p[j+1];\r
+    chksum = test_utilOnesComplementAdd (chksum, v);\r
+  }\r
+  return (chksum);\r
+} /* utilOnesCompChkSum */\r
+\r
+/**************************************************************************************\r
+ * FUNCTION PURPOSE: Compute ipv4 psudo checksum\r
+ **************************************************************************************\r
+ * DESCRIPTION: Compute ipv4 psudo checksum\r
+ **************************************************************************************/\r
+uint16_t test_utilGetIpv4PsudoChkSum (uint8_t *data, uint16_t payloadLen)\r
+{\r
+  uint16_t psudo_chksum;\r
+\r
+  psudo_chksum = test_utilOnesCompChkSum (&data[12], 4);\r
+  psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, (uint16_t) data[9]);\r
+  psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, payloadLen);\r
+\r
+  return (psudo_chksum);\r
+\r
+} /* utilGetIpv4PsudoChkSum */\r
+\r
+\r
+\r
+#endif\r
+typedef struct stats_t\r
+{\r
+        long itx;  //initially generated\r
+       long rx;\r
+       long tx;\r
+       long n_bad;\r
+       long n_new;\r
+} STATS_T;\r
+\r
+typedef struct head_t\r
+{\r
+       long ip[5];\r
+       long udp[2];\r
+} HEAD_T;\r
+\r
+typedef struct key_t\r
+{\r
+  long src_ip;\r
+  long dst_ip;\r
+  short src_port;\r
+  short dst_port;\r
+} KEY_T;\r
+\r
+unsigned char mac0[]={0x00,0x01,0x02,0x03,0x04,0x05}; //interface 0\r
+unsigned char mac1[]={0x00,0x01,0x02,0x03,0x04,0x06}; //interface 1\r
+nwalIpAddr_t OurIp0={ 10, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };\r
+nwalIpAddr_t OurIp1={ 10, 0, 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };\r
+\r
+#if 1  //goes with real tx (to laptop) \r
+unsigned char real_mac_header[]={0xd4,0xbe,0xd9,0x00,0xd3,0x7e,\r
+                      0x00,0x01,0x02,0x03,0x04,0x05,\r
+                      0x08,0x00};\r
+unsigned char real_ip_addr[]={0xa,0x00,0x00,0x64,0xa,0x0,0x0,0xa};\r
+#endif\r
+\r
+#if 0  //goes with loopback\r
+unsigned char mac_header[]={0x00,0x01,0x02,0x03,0x04,0x05, \r
+                      0x00,0x11,0x22,0x33,0x44,0x55,\r
+                      0x08,0x00};\r
+#endif\r
+#define NE 65536 \r
+HEAD_T *nat;\r
+\r
+#define NP 5000\r
+int n_pkt = NP;\r
+STATS_T stats;\r
+\r
+Trie * P_trie;\r
+HEAD_T pkts[NP];\r
+#define PERSLOW  10  //% of pkts that will not be fastpath'd \r
+int perslow= PERSLOW;\r
+\r
+/*******************************************\r
+ *************NETAPI OBJECTS***************\r
+ *****************************************/\r
+Pktlib_HeapHandle OurHeap;\r
+PKTIO_HANDLE_T *our_chan;\r
+PKTIO_HANDLE_T *netcp_rx_chan;\r
+PKTIO_HANDLE_T *netcp_tx_chan;\r
+PKTIO_CFG_T our_chan_cfg={PKTIO_RW, PKTIO_LOCAL, PKTIO_Q_ANY, 8};\r
+PKTIO_CFG_T netcp_rx_cfg={PKTIO_R, PKTIO_NA, PKTIO_NA, 8};\r
+PKTIO_CFG_T netcp_tx_cfg={PKTIO_W, PKTIO_NA, PKTIO_NA, 8};\r
+\r
+void house(NETAPI_SCHED_HANDLE_T *s);\r
+NETAPI_T netapi_handle;\r
+NETAPI_SCHED_HANDLE_T * our_sched;\r
+NETAPI_SCHED_CONFIG_T our_sched_cfg={\r
+  NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 50  //every 50 poll loops\r
+};\r
+void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats);\r
+NETAPI_TIMER_GROUP_HANDLE_T ourTimerBlock; \r
+NETAPI_TIMER_T t1;\r
+NETAPI_TIMER_T t2;\r
+NETAPI_TIMER_T t3;\r
+\r
+void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,\r
+        int n_fired,     //# timers fired\r
+        NETAPI_TIMER_LIST_T fired_list,\r
+        uint64_t currentTime);\r
+\r
+NETCP_CFG_IP_T ip_rule0;\r
+NETCP_CFG_IP_T ip_rule1;\r
+/*************************END NETAPI OBJECTS***********************/\r
+\r
+#define START_SRC_IP 0x0a00000a\r
+#define DST_IP       0xc0a80001\r
+#define NEW_START_SRC_IP 0x9eda000a\r
+#define DST_PORT 0x555 \r
+#define START_SRC_PORT 0x1234\r
+#define NEW_START_SRC_PORT 100\r
+void update_header(HEAD_T * p_head, int len)\r
+{\r
+   unsigned char *p = (unsigned char *) &p_head->udp[1];\r
+   len -= (20+14);\r
+   /* update ip checksum */\r
+   /* update udp checksum */\r
+   /* update length */\r
+   *p= (len&0xff00)>>8;\r
+   *(p+1) = len&0xff;\r
+}\r
+\r
+#if 0\r
+void gen_pkts(int np)\r
+{\r
+int i;\r
+int ip = START_SRC_IP &0xff;\r
+int port= START_SRC_PORT;\r
+//HEAD_T temp={{0x25000200,0xdead0000,0x80110000,START_SRC_IP,DST_IP},\r
+//             {START_SRC_PORT<<16|DST_PORT,0x01ec<<16|0x0000}};\r
+HEAD_T temp;\r
+memcpy(&temp,&testPkt[0],sizeof(HEAD_T));\r
+\r
+for(i=0;(i<np) && (i<NP);i++)\r
+  {\r
+       memcpy(&pkts[i],&temp,sizeof(temp));\r
+       update_header(&pkts[i],512);      /* update checksums etc */\r
+       /* change template for new pkt */\r
+       ip+=1;\r
+       if(ip>254) {(ip=START_SRC_IP&0xff); port+=1; }\r
+       temp.ip[3] = htonl((START_SRC_IP&0xffffff00)| ip);\r
+       temp.udp[0] = htonl( (temp.udp[0]&0xffff0000)| port);\r
+       temp.udp[1] = htonl(temp.udp[1]);\r
+     \r
+  }\r
+  n_pkt=np;\r
+}\r
+#endif\r
+\r
+void build_table(Trie * p_trie)\r
+{\r
+int i;\r
+int sport=NEW_START_SRC_PORT; \r
+HEAD_T temp,temp2;\r
+KEY_T key;\r
+\r
+memcpy(&temp,&testPkt[14],sizeof(temp));\r
+\r
+ //insert entry into trie\r
+key.src_ip = temp.ip[3];\r
+key.dst_ip = temp.ip[4];\r
+key.src_port= (temp.udp[0]&0xffff0000)>>16;\r
+key.dst_port= (temp.udp[0]&0x0000ffff);\r
+trie_insert(p_trie,(char *)&key,sizeof(key), (void *) &nat[0]); //asociate with nat entry 0\r
+\r
+//build nat table\r
+for(i=0;i<100;i++)\r
+{\r
+   memcpy(&temp2,&testPkt[14],sizeof(temp));\r
+   temp2.udp[0] = (temp2.udp[0] & 0xffff0000) |  sport;\r
+   memcpy(&nat[i], &temp2, sizeof(temp2));\r
+   sport+= 1;\r
+}\r
+}\r
+\r
+//===========stub transmitter==================\r
+void send_pkt(Ti_Pkt *pkt, int len)\r
+{\r
+//just free pkt.  Don't send\r
+Pktlib_freePacket((Ti_Pkt*)pkt);\r
+       return;\r
+}\r
+\r
+//==========stub slow path============\r
+void slow_path(Ti_Pkt *pkt, int len)\r
+{\r
+// debug: check descriptor for validity by verifying that desciptor link field is null as expected\n");\r
+         {Ti_Pkt * k= Pktlib_getNextPacket(pkt); if(k != 0) {printf(" slowpath, nexpkt != NULL");}}\r
+//just free pkt\r
+Pktlib_freePacket((Ti_Pkt*)pkt);\r
+       return;\r
+}\r
+/* check header */\r
+struct LastPktInfo\r
+{\r
+int iface;\r
+int ipcsum;\r
+int l4csum;\r
+} ;\r
+static struct LastPktInfo lpInfo;\r
+\r
+int check_header(HEAD_T * p_head, PKTIO_METADATA_T * p_meta)\r
+{\r
+if (NWAL_RX_FLAG1_META_DATA_VALID & p_meta->u.rx_meta->rxFlag1)\r
+{\r
+lpInfo.iface = ((unsigned int)p_meta->u.rx_meta->appId) &0xff; //last byte is interface num\r
+lpInfo.ipcsum =(p_meta->u.rx_meta->rxFlag1 & NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_MASK )== NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_ACK ? 1 : 0;\r
+lpInfo.l4csum = (p_meta->u.rx_meta->rxFlag1 & NWAL_RX_FLAG1_L4_CHKSUM_VERIFY_MASK )== ((NWAL_RX_FLAG1_L4_CHKSUM_VERIFY_ACK) << NWAL_RX_FLAG1_L4_CHKSUM_VERIFY_SHIFT) ? 1 : 0; \r
+}\r
+ return 1;\r
+}\r
+\r
+#define PKT_LEN 1400\r
+void test_alloc_free(int n)\r
+{\r
+int i;\r
+Ti_Pkt * b;\r
+\r
+for(i=0;i<n;i++)\r
+{\r
+  b=Pktlib_allocPacket(OurHeap,PKT_LEN);\r
+  Pktlib_freePacket(b);\r
+}\r
+}\r
+/*-----------test driver: gen an input pkt------- */\r
+//char buffer[sizeof(HEAD_T)+PKT_LEN];\r
+Ti_Pkt * get_pkt(int n, unsigned int *p_len)\r
+{\r
+   int ind;\r
+   long long temp;\r
+   Ti_Pkt * b;\r
+   char * buffer;\r
+   unsigned int len;\r
+\r
+  if (pktloopback==0)\r
+  {\r
+       if (n>=4) return NULL;   //just gen pkts to warm swtich, so that it knows\r
+                                //our mac is valid\r
+  }  \r
+  b=Pktlib_allocPacket(OurHeap,PKT_LEN);\r
+  if (!b) \r
+    {printf("net_test: get_pkt() heap empty!! %d pkts gen'd %d \n", n); return NULL;};\r
+\r
+    //debug - way to validate descriptor\r
+    {Ti_Pkt* k= Pktlib_getNextPacket(b); \r
+         if(k != 0) {printf(" genpkt, nexpkt != NULL");}}\r
+\r
+\r
+   //get pointer to buffer area of packet\r
+   Pktlib_getDataBuffer(b,(uint8_t**)&buffer,&len);\r
+\r
+#if 0 \r
+if (pktloopback==0)\r
+{\r
+   temp = (long long) rand();\r
+   temp *= PKT_LEN;\r
+   temp /= RAND_MAX;\r
+   temp +=2;\r
+   *p_len = (int) temp; \r
+   *p_len = *p_len &0xfffffffe;\r
+   temp = (long long) rand();\r
+   temp *= n_pkt;\r
+   temp /= RAND_MAX;\r
+   ind = (int) temp;\r
+   update_header(&pkts[ind],*p_len);\r
+   //printf("get pkt:%d %d ind=%d len=%d\n",RAND_MAX, rand(),ind, *p_len);\r
+    memcpy(&buffer[0], &mac_header[0],14);\r
+    memcpy(&buffer[14],(char*)&pkts[ind],sizeof(HEAD_T)); \r
+}\r
+else\r
+#endif\r
+\r
+   //copy test packet into buffer\r
+{\r
+    memcpy(&buffer[0], &testPkt[0],TEST_PKT_LEN);\r
+    *p_len = TEST_PKT_LEN;\r
+}\r
+    return b; \r
+}\r
+\r
+\r
+/******************************************************/\r
+/******************PKT RECEIVE HANDLER *************************/\r
+/******************************************************/\r
+void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],\r
+                         PKTIO_METADATA_T meta[], int n_pkts,\r
+                         uint64_t ts )\r
+{\r
+int i;\r
+int len;\r
+int p;\r
+HEAD_T * p_res;\r
+Ti_Pkt * tip;\r
+unsigned int templen;\r
+int err;\r
+KEY_T key;\r
+char * p_pkt;\r
+HEAD_T * p_head;\r
+HEAD_T temp_head;\r
+\r
+    p_head=&temp_head;\r
+\r
+    //debug\r
+#if 0\r
+    if (n_pkts != TX_BURST) {\r
+      printf("recv_cb, txsofar=%d rxsofar=%d  np = %d, NOT %d\n", \r
+             stats.itx, stats.rx, n_pkts,TX_BURST);\r
+      our_stats_cb(netapi_handle,NULL);\r
+    }\r
+#endif\r
+    //test_alloc_free(7);\r
+    //printf("recv start\n");\r
+\r
+   /* loop over received pkts */\r
+   for(i=0;i<n_pkts;i++)\r
+   {\r
+       tip = p_recv[i];\r
+       Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen\r
+       len = Pktlib_getPacketLen(tip);//real length\r
+\r
+         //debug: validate descriptor */\r
+         if(Pktlib_getNextPacket(tip) != 0) {printf(" rcv_cb, nexpkt != NULL");}\r
+        //debug printf("recv pkt, len=%d %d\n", len, templen);\r
+       stats.rx+=1;\r
+\r
+#ifdef DEBUG_DESC\r
+   if (stats.rx<16){printf(">rx dmp.."); dump_descr((long *) tip, stats.rx);}\r
+   else if (stats.rx>99) {printf(">rx dmp.."); dump_descr((long *) tip,stats.rx);}\r
+#endif\r
+\r
+\r
+       /* check header */\r
+       memcpy(p_head,&p_pkt[14],sizeof(HEAD_T));\r
+       if (!check_header(p_head,&meta[i])) { \r
+               stats.n_bad+=1;Pktlib_freePacket(tip); continue;\r
+       }\r
+\r
+       /* lookup flow */\r
+       key.src_ip = p_head->ip[3];\r
+       key.dst_ip = p_head->ip[4];\r
+       key.src_port= (p_head->udp[0]&0xffff0000)>>16;\r
+       key.dst_port= (p_head->udp[0]&0x0000ffff);\r
+       p_res= (HEAD_T *) trie_lookup(P_trie, (char *) &key, sizeof(key));\r
+       if (!p_res) { stats.n_new+=1;  slow_path(tip, len); continue;}\r
+\r
+       /* copy header */\r
+       memcpy((char *) p_head, (char *) p_res, sizeof(HEAD_T));\r
+\r
+       memcpy(&p_pkt[14],p_head,sizeof(HEAD_T));\r
+        /* update_mac(&p_pkt[0]);  */\r
+\r
+       /* 'simulate' send pkt */\r
+       send_pkt(tip,len);\r
+       stats.tx+=1;\r
+    }\r
+    //printf("recv done\n");\r
+}\r
+\r
+//timer callback \r
+void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,\r
+        int n_fired,     //# timers fired\r
+        NETAPI_TIMER_LIST_T fired_list,\r
+        uint64_t currentTime)\r
+{\r
+int i;\r
+NETAPI_TIMER_T tx;\r
+int cookie;\r
+int err;\r
+unsigned long long et;\r
+printf("TIMER CALLBACK @ %lld %d timers\n", currentTime, n_fired);\r
+tx = netapi_TimerGetFirst(fired_list);\r
+for(i=0;i<n_fired;i++)\r
+{\r
+  cookie = (int) netapi_TimerGetCookie(tx);\r
+  et =  netapi_TimerGetTs(tx); //debug\r
+  printf("   timer %d - cookie = %d expected ts=%lld (delta=%lld)\n", i, cookie, et, currentTime-et);\r
+  if (cookie ==1)\r
+     t1 = netapi_TimerGroupStartTimer(\r
+        th,\r
+        (void *) 1,\r
+        100LL,  //timer group tics\r
+        &err);\r
+  else if (cookie ==2)\r
+      t2 = netapi_TimerGroupStartTimer(\r
+        th,\r
+        (void *) 2,\r
+        200LL,  //timer group ticks\r
+        &err);\r
+  else\r
+  {\r
+    t3 = netapi_TimerGroupStartTimer(\r
+        th,\r
+        (void *) 3,\r
+        300LL,  //timer group ticks\r
+        &err);\r
+    //cancel 1 and restart 1\r
+   netapi_TimerGroupCancel(th,t1,&err);\r
+   t1 = netapi_TimerGroupStartTimer(\r
+        th,\r
+        (void *) 1,\r
+        100LL,  //timer group ticks\r
+        &err);\r
+ }\r
+  tx = netapi_TimerGetNext(fired_list,tx); \r
+}\r
+}\r
+\r
+\r
+static int np2process = NP;\r
+/******************************************************\r
+ * stats callback\r
+ *******************************************************/\r
+void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats)\r
+{\r
+uint32_t numFreeDataPackets;\r
+uint32_t numZeroBufferPackets;\r
+uint32_t numPacketsinGarbage;\r
+\r
+printf("stats @ %lld\n", netapi_getTimestamp());\r
+if(pPaStats)\r
+{\r
+       printf("C1 number of packets:           %d\n", pPaStats->classify1.nPackets);\r
+       printf("C1 number IPv4 packets:         %d\n", pPaStats->classify1.nIpv4Packets);\r
+       //printf("C1 number llc/snap fail:        %d\n", pPaStats->classify1.nLlcSnapFail);\r
+       printf("C1 number table matched:        %d\n", pPaStats->classify1.nTableMatch);\r
+       printf("C1 number failed table matched: %d\n", pPaStats->classify1.nNoTableMatch);\r
+       printf ("C1 number of parse fail:        %d\n",pPaStats->classify1.nParseFail);\r
+       printf("C1 number of command failures:  %d\n", pPaStats->classify1.nCommandFail);\r
+       printf("C1 number invalid reply dests:  %d\n", pPaStats->classify1.nInvalidComReplyDest);\r
+       printf ("C1 number of silent discard:    %d\n",pPaStats->classify1.nSilentDiscard);\r
+       printf("C1 number of invalid control:   %d\n", pPaStats->classify1.nInvalidControl);\r
+       printf ("C1 number of invalid states:    %d\n",pPaStats->classify1.nInvalidState);\r
+       printf ("C1 number of system fails:      %d\n",pPaStats->classify1.nSystemFail);\r
+       printf ("C2 number parse failed  :      %d\n",pPaStats->classify2.nParseFail);\r
+       printf ("C2 number Invld Header  :      %d\n",pPaStats->classify2.nInvldHdr);\r
+       printf ("C2 number udp           :      %d\n",pPaStats->classify2.nUdp);\r
+       printf ("C2 number tcp           :      %d\n",pPaStats->classify2.nTcp);\r
+       printf ("C2 number cmd fail      :      %d\n",pPaStats->classify2.nCommandFail);\r
+       printf ("C2 number silent drop   :      %d\n",pPaStats->classify2.nSilentDiscard);\r
+       printf ("C2 number invalid cntrl :      %d\n\n",pPaStats->classify2.nInvalidControl);\r
+}\r
+Pktlib_getHeapStats(OurHeap, &numFreeDataPackets,\r
+                             &numZeroBufferPackets, &numPacketsinGarbage);\r
+printf("heap stats>  #free=%d #zb=%d #garbage=%d\n", numFreeDataPackets,\r
+                                numZeroBufferPackets, numPacketsinGarbage);\r
+//debug = dump timer polling stats\r
+dump_poll_stats();\r
+\r
+\r
+}\r
+\r
+//******************************************************\r
+//use scheduling housekeeping callback to generate pkts\r
+//******************************************************\r
+void house(NETAPI_SCHED_HANDLE_T * s)\r
+{\r
+Ti_Pkt * tip;\r
+unsigned int len;\r
+nwalTxPktInfo_t meta_tx={0};\r
+PKTIO_METADATA_T meta = {PKTIO_META_TX,0};\r
+int err;\r
+static int house_pkts_gened=0;\r
+int p;\r
+unsigned char * pIpHdr,* pData;\r
+\r
+for(p=0;p<TX_BURST;p++) {  \r
+//reguest stats \r
+if ((house_pkts_gened>0) && (! (house_pkts_gened%400)) )\r
+{\r
+   printf("net_test> request stats at n=%d \n",house_pkts_gened);\r
+   netcp_cfgReqStats(netapi_handle, our_stats_cb, 0,&err); \r
+   if (err!=0) {printf("stats req failed\n");}\r
+}\r
+\r
+\r
+  if (house_pkts_gened >= np2process+ 100)\r
+  {\r
+     //shutdown\r
+     netapi_schedShutdown(s,NULL,&err);\r
+     continue;\r
+  }\r
+\r
+  else if (house_pkts_gened >= np2process) { house_pkts_gened+=1;  continue;}\r
+  \r
+\r
+/* manufacture a pkt to transmit */\r
+   tip = get_pkt(house_pkts_gened, &len);\r
+   if(!tip) { house_pkts_gened +=1; continue; }\r
+\r
+   /* set the pkt length */\r
+   Pktlib_setPacketLen(tip, len);\r
+\r
+   /* set up meta data */\r
+    meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM | NWAL_TX_FLAG1_DO_UDP_CHKSUM);\r
+    meta_tx.startOffset = 0;\r
+    meta_tx.pktLen = len;\r
+    meta_tx.ipOffBytes = TEST_PKT_IP_OFFSET_BYTES;\r
+    meta_tx.l4OffBytes = TEST_PKT_UDP_OFFSET_BYTES;\r
+    meta_tx.l4HdrLen = TEST_PKT_UDP_HDR_LEN;\r
+    meta_tx.ploadOffBytes = TEST_PKT_PLOAD_OFFSET_BYTES;\r
+    meta_tx.ploadLen = TEST_PAYLOAD_LEN;\r
+\r
+    Pktlib_getDataBuffer(tip,&pData,&len);\r
+    pIpHdr = pData + meta_tx.ipOffBytes;\r
+    meta_tx.pseudoHdrChecksum =\r
+        test_utilGetIpv4PsudoChkSum(pIpHdr,(TEST_PAYLOAD_LEN+TEST_PKT_UDP_HDR_LEN));\r
+\r
+   /* post it to netcp tx channel*/\r
+   meta.u.tx_meta=&meta_tx;\r
+#ifdef DEBUG_DESC\r
+   if (house_pkts_gened<16) dump_descr((long *) tip, house_pkts_gened);\r
+   else if (house_pkts_gened>99) dump_descr((long *) tip,house_pkts_gened);\r
+#endif\r
+   pktio_send(netcp_tx_chan,tip,&meta,&err);\r
+   if (err == 0) stats.itx +=1;\r
+\r
+   house_pkts_gened +=1;\r
+ }\r
+}\r
+\r
+\r
+/***************************************\r
+ ********** test driver*****************\r
+ ***************************************/\r
+int main(int argc, char **argv)\r
+{\r
+int err;\r
+rlim_t oss,ss = 1024*1024;\r
+struct rlimit rl;\r
+\r
+err= getrlimit(RLIMIT_STACK,&rl);\r
+if (!err) printf(" stack limit = %d\n",rl.rlim_cur); else printf("getrlimit failed\n");\r
+#if 0\r
+rl.rlim_cur = ss;\r
+err=setrlimit(RLIMIT_STACK,&rl);\r
+if (!err) printf("set stack to %d\n",rl.rlim_cur); else printf("setrlimit failed\n");\r
+#endif\r
+\r
+if (argc>=2)  np2process = atoi(argv[1]);\r
+if (np2process<0) np2process = NP; /* default */\r
+if (argc==3)  perslow = atoi(argv[2]);\r
+if ((perslow<0)||(perslow>100)) perslow=PERSLOW;//default\r
+if (argc>3) {printf("net_test  <no of pkts to process> <percent slow path>\n"); exit(1);}\r
+\r
+\r
+//real mode, so update our test packet mac header and ip header\r
+if (pktloopback==0)\r
+{\r
+memcpy(&testPkt,&real_mac_header[0],14); //overwrite test pkt mac address\r
+memcpy(&testPkt[26],&real_ip_addr[0],8);//overrite test pkt ip addresses\r
+}\r
+\r
+/*******************************************/\r
+/*************NETAPI STARTUP****************/\r
+/*******************************************/\r
+\r
+/* create netapi */\r
+netapi_handle = netapi_init(NETAPI_SYS_MASTER);\r
+\r
+/* open the main heap */\r
+OurHeap = Pktlib_findHeapByName("netapi");\r
+if (!OurHeap) {printf("findheapbyname fail\n"); exit(1);}\r
+\r
+/* create a pktio channel */\r
+our_chan=pktio_create(netapi_handle,"our1stq",(PKTIO_CB) recv_cb, &our_chan_cfg,&err);\r
+if (!our_chan) {printf("pktio create failed err=%d\n",err); exit(1);}\r
+\r
+/* open netcp default tx, rx queues */\r
+netcp_tx_chan= pktio_open(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg,  &err);\r
+if (!netcp_tx_chan) {printf("pktio open TX failed err=%d\n",err); exit(1);}\r
+netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb, &netcp_rx_cfg,  &err);\r
+if (!netcp_rx_chan) {printf("pktio open RX failed err=%d\n",err); exit(1);}\r
+\r
+\r
+/* create scheduler instance */\r
+our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err);\r
+if (!our_sched) {printf("sched create failed\n"); exit(1);}\r
+\r
+/* add mac intefaces */\r
+netcp_cfgCreateMacInterface(\r
+                  netapi_handle,\r
+                  &mac0[0],\r
+                  0,0,\r
+                  (NETCP_CFG_ROUTE_HANDLE_T)  NULL,\r
+                  (NETCP_CFG_VLAN_T ) NULL ,  //future\r
+                  1, \r
+                  &err);\r
+if (err) {printf("addmac0 failed %d\n",err); exit(1); } \r
+\r
+//attach an IP to this interface\r
+ip_rule0=netcp_addIp(\r
+                  netapi_handle,\r
+                  0,\r
+                  nwal_IPV4,\r
+                  &OurIp0,\r
+                  NULL,  //all IP\r
+                  (NETCP_CFG_ROUTE_HANDLE_T) NULL,\r
+                  &err\r
+                  );\r
+if (err) {printf("addip0 failed %d\n",err); exit(1); } \r
+#if 1\r
+//create a 2nd mac instance\r
+netcp_cfgCreateMacInterface(\r
+                  netapi_handle,\r
+                  &mac1[0],\r
+                  1,1,\r
+                  (NETCP_CFG_ROUTE_HANDLE_T)  NULL,\r
+                  (NETCP_CFG_VLAN_T ) NULL ,  //future\r
+                  1,\r
+                  &err);\r
+if (err) {printf("addmac1 failed %d\n",err); exit(1); }\r
+\r
+//attach an IP to this interface\r
+ip_rule1=netcp_addIp(\r
+                  netapi_handle,\r
+                  1,\r
+                  nwal_IPV4,\r
+                  &OurIp1,\r
+                  NULL,  //all IP\r
+                  (NETCP_CFG_ROUTE_HANDLE_T) NULL,\r
+                  &err\r
+                  );\r
+if (err) {printf("addip1 failed %d\n",err); exit(1); }\r
+\r
+#endif\r
+\r
+ ourTimerBlock = netapi_TimerGroupCreate(\r
+        netapi_handle,\r
+        "our1sttimer",\r
+        our_timer_cb,\r
+        0,    //1 if timers local to thread\r
+        0,    //1 if expect to cancel\r
+        netapi_getTicksPerSec()/1000,  /* 1 msc resolution for these timers */\r
+        netapi_getTicksPerSec()/5000, /* would like .5 msc tolerence */\r
+        10,  //small # of timers to test garbage collection\r
+        &err);\r
+if (err) {printf("timergroupcreate failed %d\n",err); exit(1);}\r
+\r
+//start a couple of timers \r
+t1 = netapi_TimerGroupStartTimer(\r
+        ourTimerBlock,\r
+        (void *) 1,\r
+        100LL,  //timer group ticks\r
+        &err);\r
+if (err) {printf("timerstart failed %d\n");}\r
+t2 = netapi_TimerGroupStartTimer(\r
+        ourTimerBlock,\r
+        (void *) 2,\r
+        200LL,  //timer group ticks\r
+        &err);\r
+if (err) {printf("timerstart failed %d\n");}\r
+t3 = netapi_TimerGroupStartTimer(\r
+        ourTimerBlock,\r
+        (void *) 3,\r
+        300LL,  //timer group ticks\r
+        &err);\r
+if (err) {printf("timerstart failed %d\n");}\r
+\r
+\r
+/*********************************************/\r
+/*****************end NETAPI STARTUP**********/\r
+/*********************************************/\r
+\r
+\r
+/********************************************\r
+* Basic pkt loopback test\r
+*********************************************/\r
+\r
+\r
+/* create TRIE */\r
+P_trie = trie_new();\r
+if (!P_trie) {printf("trie alloc failed\n"); exit(1);}\r
+\r
+nat = (HEAD_T *) malloc(NE * sizeof(HEAD_T));\r
+if (!nat) {printf("malloc of nat table failed\n"); exit(1);}\r
+\r
+//gen_pkts(np2process<NP ? np2process:NP);\r
+n_pkt= np2process;\r
+\r
+/* build table */\r
+build_table(P_trie);\r
+\r
+\r
+/* processing loop: get pkt, check it, look up in table, copy new header,\r
+   send packet */\r
+srand((unsigned) np2process);\r
+\r
+\r
+/*********************************************/\r
+/**************Entry point into scheduler ****/\r
+/*********************************************/\r
+netapi_schedWaitForEvents(our_sched, &err);\r
+\r
+/* done */\r
+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);\r
+our_stats_cb(netapi_handle, NULL);\r
+\r
+netcp_cfgDelIp(netapi_handle, 0, 0, NULL, NULL, ip_rule0, &err);\r
+netcp_cfgDelIp(netapi_handle, 1, 0, NULL, NULL, ip_rule1, &err);\r
+netcp_cfgDelMac(netapi_handle,0,&err);\r
+netcp_cfgDelMac(netapi_handle,1,&err);\r
+\r
+netapi_shutdown(netapi_handle);\r
+\r
+}\r