added 1st attempt at classifier stuff
authorDavid Lide <a0216552@gtudci01.(none)>
Mon, 13 Feb 2012 16:10:28 +0000 (11:10 -0500)
committerDavid Lide <a0216552@gtudci01.(none)>
Mon, 13 Feb 2012 16:10:28 +0000 (11:10 -0500)
ti/runtime/netapi/netapi_sched.h
ti/runtime/netapi/netapi_timer.h
ti/runtime/netapi/netapi_tune.h
ti/runtime/netapi/netcp_cfg.h
ti/runtime/netapi/netsync.h
ti/runtime/netapi/src/netapi_vm.c
ti/runtime/netapi/src/netcp_cfg.c
ti/runtime/netapi/test/net_test.c

index 660309b09c7733cc771601b6535ecdde1b111508..485488ffe076bd3dfd3e9ce3f497057862ccf399 100644 (file)
-/***********************************
- * File: netapi_sched.h
- * Purpose:  netapi scheduler module
- **************************************************************
- * FILE: netapi_sched.h
- * 
- * DESCRIPTION:  netapi sample event scheduler  header file for 
- *         user space transport library
- * 
- * REVISION HISTORY:  rev 0.0.1 
- *
- *  Copyright (c) Texas Instruments Incorporated 2010-2011
- * 
- *  Redistribution and use in source and binary forms, with or without 
- *  modification, are permitted provided that the following conditions 
- *  are met:
- *
- *    Redistributions of source code must retain the above copyright 
- *    notice, this list of conditions and the following disclaimer.
- *
- *    Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the 
- *    documentation and/or other materials provided with the   
- *    distribution.
- *
- *    Neither the name of Texas Instruments Incorporated nor the names of
- *    its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- ***********************************/
-#ifndef __NETAPI_SCHED__
-#define __NETAPI_SCHED__
-#include "netapi.h"
-
-/****************************
- **********CONTEXT**********
- ****************************/
-struct  NETAPI_SCHED_HANDLE_Tag;
-
-typedef void (*NETAPI_SCHED_CB)(struct NETAPI_SCHED_HANDLE_Tag *h);
-
-
-typedef struct NETAPI_SCHED_CONFIG_Tag
-{
-int valid_flags;  //which is being configured
-#define NETAPI_SCHED_DURATION 0x1
-#define NETAPI_SCHED_POWER 0x2
-#define NETAPI_SCHED_FINE  0x4 //future
-#define NETAPI_SCHED_CBV  0x8 //callback
-
-/*----duration------*/
-uint64_t duration;  //0=forever  or #tics to run for 
-#define NETAPI_SCHED_FOREVER 0L
-
-/*-----house callback-----*/
-NETAPI_SCHED_CB house_cb;
-
-uint32_t interval;  // how many poll loop intervals after which to call the house keeping function 
-
-
-/*------power control-------*/
-int power_control;  //0= always on, >0 = duty cycle 
-#define NETAPI_SCHED_POWER_ALWAYS_OFF 0  //drop to idle
-#define NETAPI_SCHED_POWER_ALWAYS_ON 100 //always runs, no drop to idle
-
-int idle_time;   //in ticks
-
-/*-----fine control-----*/
-//future..
-
-} NETAPI_SCHED_CONFIG_T;
-
-
-/* the schedule context */
-typedef struct NETAPI_SCHED_HANDLE_Tag
-{
- volatile int state;   //0= shutdown, 1= shutting down, 2=active
-#define NETAPI_SCHED_STATE_SHUT 0
-#define NETAPI_SCHED_STATE_SHUTTING 1
-#define NETAPI_SCHED_STATE_ACTIVE 2
- void * back;  //pointer back to netapi handle
- NETAPI_SCHED_CONFIG_T config;
- uint64_t start;   /* start time */ 
- volatile int shutdown_reason;
- volatile uint64_t shutdown_time;
-
-} NETAPI_SCHED_HANDLE_T;
-
-/* how to shut down */
-typedef struct NETAPI_SCHED_SHUTDOWN_Tag
-{
-int shutdown_type;
-#define NETAPI_SCHED_SHUTDOWN_NOW 0
-#define NETAPI_SCHED_SHUTDOWN_TO  1
-#define NETAPI_SCHED_SHUTDOWN_NEXT_IDLE  2
-int timeout;  //ticks from now to close
-
-} NETAPI_SCHED_SHUTDOWN_T;
-
-/****************************
- **************API **********
- ****************************/
-
-/* open a scheduling contex */
-NETAPI_SCHED_HANDLE_T * netapi_schedOpen(NETAPI_T n, NETAPI_SCHED_CONFIG_T * p_config, int *p_err);
-
-/* re-configure a scheduling context */
-int netapi_schedControl(NETAPI_SCHED_HANDLE_T *s, NETAPI_SCHED_CONFIG_T *p_config, int *p_err);
-
-/* return codes for wait_for_events() */
-#define NETAPI_SCHED_RETURN_ERR 0   //unknown, err
-#define NETAPI_SCHED_RETURN_TO 1    // returned after timeout
-#define NETAPI_SCHED_RETURN_SHUTDOWN 2 //returned after shutdown
-
-/* main entry point.  caller gives up control to scheduler */
-int netapi_schedWaitForEvents(NETAPI_SCHED_HANDLE_T *s, int * p_err);
-
-/* shutdown scheduler context */
-int netapi_schedShutdown(NETAPI_SCHED_HANDLE_T * s, NETAPI_SCHED_SHUTDOWN_T * p_close, int *p_err);
-
-static NETAPI_T netapi_schedGetNetapiHandle(NETAPI_SCHED_HANDLE_T *s)
-  { return (NETAPI_T)s->back;}
-#endif
+/***********************************\r
+ * File: netapi_sched.h\r
+ * Purpose:  netapi scheduler module\r
+ **************************************************************\r
+ * FILE: netapi_sched.h\r
+ * \r
+ * DESCRIPTION:  netapi sample event scheduler  header file for \r
+ *         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
+#ifndef __NETAPI_SCHED__\r
+#define __NETAPI_SCHED__\r
+#include "netapi.h"\r
+\r
+/****************************\r
+ **********CONTEXT**********\r
+ ****************************/\r
+struct  NETAPI_SCHED_HANDLE_Tag;\r
+\r
+typedef void (*NETAPI_SCHED_CB)(struct NETAPI_SCHED_HANDLE_Tag *h);\r
+\r
+\r
+typedef struct NETAPI_SCHED_CONFIG_Tag\r
+{\r
+int valid_flags;  //which is being configured\r
+#define NETAPI_SCHED_DURATION 0x1\r
+#define NETAPI_SCHED_POWER 0x2\r
+#define NETAPI_SCHED_FINE  0x4 //future\r
+#define NETAPI_SCHED_CBV  0x8 //callback\r
+\r
+/*----duration------*/\r
+uint64_t duration;  //0=forever  or #tics to run for \r
+#define NETAPI_SCHED_FOREVER 0L\r
+\r
+/*-----house callback-----*/\r
+NETAPI_SCHED_CB house_cb;\r
+\r
+uint32_t interval;  // how many poll loop intervals after which to call the house keeping function \r
+\r
+\r
+/*------power control-------*/\r
+int power_control;  //0= always on, >0 = duty cycle \r
+#define NETAPI_SCHED_POWER_ALWAYS_OFF 0  //drop to idle\r
+#define NETAPI_SCHED_POWER_ALWAYS_ON 100 //always runs, no drop to idle\r
+\r
+int idle_time;   //in ticks\r
+\r
+/*-----fine control-----*/\r
+//future..\r
+\r
+} NETAPI_SCHED_CONFIG_T;\r
+\r
+\r
+/* the schedule context */\r
+typedef struct NETAPI_SCHED_HANDLE_Tag\r
+{\r
+ volatile int state;   //0= shutdown, 1= shutting down, 2=active\r
+#define NETAPI_SCHED_STATE_SHUT 0\r
+#define NETAPI_SCHED_STATE_SHUTTING 1\r
+#define NETAPI_SCHED_STATE_ACTIVE 2\r
+ void * back;  //pointer back to netapi handle\r
+ NETAPI_SCHED_CONFIG_T config;\r
+ uint64_t start;   /* start time */ \r
+ volatile int shutdown_reason;\r
+ volatile uint64_t shutdown_time;\r
+\r
+} NETAPI_SCHED_HANDLE_T;\r
+\r
+/* how to shut down */\r
+typedef struct NETAPI_SCHED_SHUTDOWN_Tag\r
+{\r
+int shutdown_type;\r
+#define NETAPI_SCHED_SHUTDOWN_NOW 0\r
+#define NETAPI_SCHED_SHUTDOWN_TO  1\r
+#define NETAPI_SCHED_SHUTDOWN_NEXT_IDLE  2\r
+int timeout;  //ticks from now to close\r
+\r
+} NETAPI_SCHED_SHUTDOWN_T;\r
+\r
+/****************************\r
+ **************API **********\r
+ ****************************/\r
+\r
+/* open a scheduling contex */\r
+NETAPI_SCHED_HANDLE_T * netapi_schedOpen(NETAPI_T n, NETAPI_SCHED_CONFIG_T * p_config, int *p_err);\r
+\r
+/* re-configure a scheduling context */\r
+int netapi_schedControl(NETAPI_SCHED_HANDLE_T *s, NETAPI_SCHED_CONFIG_T *p_config, int *p_err);\r
+\r
+/* return codes for wait_for_events() */\r
+#define NETAPI_SCHED_RETURN_ERR 0   //unknown, err\r
+#define NETAPI_SCHED_RETURN_TO 1    // returned after timeout\r
+#define NETAPI_SCHED_RETURN_SHUTDOWN 2 //returned after shutdown\r
+\r
+/* main entry point.  caller gives up control to scheduler */\r
+int netapi_schedWaitForEvents(NETAPI_SCHED_HANDLE_T *s, int * p_err);\r
+\r
+/* shutdown scheduler context */\r
+int netapi_schedShutdown(NETAPI_SCHED_HANDLE_T * s, NETAPI_SCHED_SHUTDOWN_T * p_close, int *p_err);\r
+\r
+static NETAPI_T netapi_schedGetNetapiHandle(NETAPI_SCHED_HANDLE_T *s)\r
+  { return (NETAPI_T)s->back;}\r
+#endif\r
index a59a905b91d695cd08869f090581a522156c2fe9..f8ed7ba32fae42d2a93086040b24605d30fe3137 100644 (file)
-/************************************************
- *FILE: netapi_timer.h
- *Purpose:  netapi timer related functions
- **************************************************************
- * @file  netapi_timer.h
- * 
- * @breif DESCRIPTION:  netapi timer library header file for user space transport
- *               library
- * 
- * REVISION HISTORY:  rev 0.0.1 
- *
- *  Copyright (c) Texas Instruments Incorporated 2010-2011
- * 
- *  Redistribution and use in source and binary forms, with or without 
- *  modification, are permitted provided that the following conditions 
- *  are met:
- *
- *    Redistributions of source code must retain the above copyright 
- *    notice, this list of conditions and the following disclaimer.
- *
- *    Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the 
- *    documentation and/or other materials provided with the   
- *    distribution.
- *
- *    Neither the name of Texas Instruments Incorporated nor the names of
- *    its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- ***********************************************/
-
-/**  @mainpage Netapi Timer Lib 
- *
- *   @section intro  Introduction
- *
- *   The network API provides a user space interface to timers
- *      - a function to read a hw provided 64bit time stamp, @ref netapi_getTimestamp
- *        This returns a tick running at 1/6 cpu frequency
- *      - functions to create or open timer groups: @ref netapi_TimerGroupCreateTimer
- *        and @ref  netapi_TimerGroupOpenTimer.  A timer group
- *        is a group of timers with the same characteristics:
- *        -> local or global
- *        -> timer resolution (msc, 10 msc, etc)
- *        -> expect to fire or expect to cancel
- *        -> the same call back function for fired timers
- *      - functions to close or delete timer groups
- *      - function to start a timer,  @ref netapi_TimerGroupStartTimer
- *      - function to cancel a timer,  @ref netapi_TimerGroupCancelTimer
- *      - function to poll a timer group, or all timer groups registered to a NETAPI 
- *        instance
- *  \par
- *  NOTE:
- *      (C) Copyright 2010-2011 Texas Instruments, Inc.
- *  \par
- */
-
-
-#ifndef __NETAPI_TIMER__H
-#define __NETAPI_TIMER__H
-#include "netapi.h"
-
-extern volatile unsigned long * t64_virt_addr;
-extern unsigned int cpu_cycles_sec;
-
-//return hw timer clock ticks per second
-unsigned long t64_ticks_sec(void);
-#define netapi_getTicksPerSec t64_ticks_sec
-
-
-/**  @ingroup netapi_api_functions */
-
-/*
- *  @brief  API returns a 64bit h/w timestamp 
- *
- *  @details reads a h/w timer (TIMER64 on Appleton SOC) and returns a 64 bit time stamp    
- *           timer runs at @ref t64_ticks_sec.  Nominally this should be 1/6 CPU clk (@ref cpu_cycles_sec)
- *           
- *  @param[in]  none 
- *  @retval     unsigned long long timestamp (64 buts) 
- *  @pre        @ref netapi_init 
- */
-//return 64 bit timestamp from hw timer
-static inline unsigned long long netapi_getTimestamp(void) 
-{
- volatile unsigned long long t1;
- volatile unsigned long long t2;
- unsigned long long val;
- t1 = t64_virt_addr[0x10/4]; //lo
- t2 = t64_virt_addr[0x14/4]; //hi
- val = ((unsigned long long) t2) <<32 | t1;
- return val;
-}
-
-/******************************************************/
-/*******************TIMER API***************************/
-/******************************************************/
-typedef void * NETAPI_TIMER_GROUP_HANDLE_T;     
-typedef void * NETAPI_TIMER_T;
-typedef void * NETAPI_TIMER_LIST_T;
-
-/* timer filter values */
-typedef int NETAPI_TIMER_FILTER_T;
-#define NETAPI_TIMER_NA   (void*) NULL
-#define NETAPI_TIMER_FILTER_GLOBAL 0x1
-#define NETAPI_TIMER_FILTER_LOCAL 0x2
-#define NETAPI_TIMER_FILTER_E2F 0x4
-#define NETAPI_TIMER_FILTER_E2C 0x8
-#define NETAPI_TIMER_FITLER_ALL 0xf
-
-//iterator on TIMER_LIST_T
-NETAPI_TIMER_T netapi_TimerGetFirst( NETAPI_TIMER_LIST_T list);
-NETAPI_TIMER_T netapi_TimerGetNext( NETAPI_TIMER_LIST_T list,NETAPI_TIMER_T prev);
-void * netapi_TimerGetCookie(NETAPI_TIMER_T timer);
-unsigned long long netapi_TimerGetTs(NETAPI_TIMER_T timer); //debug
-
-/*
- *  @brief  API callback for timer expiration 
- *
- *  @details this function, provided by application,  is registered by application 
- *  when timer group is created.  It is called by timer library when a timer or set of timers
- *  expire. The timer list can be walled with iterators: @ref netapi_TimerGetFirst, 
- *  @ref netapi_TimerGetNext.  The timer id or "cookie" can be accessed via @ref netapi_TimerGetCookie
- *  NOTE: callback should check for cookie==NULL since timer could be cancelled as it is being fired
- *  @param[in]   @ref NETAPI_TIMER_GROUP_HANDLE_T : the handle to the timer group
- *  @param[in]   int  : the number of timers that have fired 
- *  @param[in]   @ref NETAPI_TIMER_LIST_T : the list of timers that hace expired 
- *  @param[in]   uint64_t : the current time
- *  @retval     none 
- *  @pre        @ref netapi_init , @ref netapi_TimerGroupCreate, @ref netapi_TimerGroupStartTimer
- */
-//timer callback
-typedef void (*NETAPI_TIMER_CB_T) (
-       NETAPI_TIMER_GROUP_HANDLE_T th,  //timer group
-       int n_fired,     //# timers fired
-       NETAPI_TIMER_LIST_T fired_list,  //the list of fired timers. Access via iterators above
-       uint64_t currentTime);  //current timestamp
-
-/*
-*  @brief  API  for Timer Group Creation 
- *
- *  @details this function is used to create a timer group. A timer group is a block of timers
- *  that share the same characteristics.
- *  @param[in]   @ref NETAPI_T : the handle to the NETAPI Instance 
- *  @param[in]   char * : the name of the timer
- *  @param[in]   @ref NETAPI_TIMER_CB_T :  the callback function
- *  @param[in]   int  : local   (=1 if this timer group is local to this netapi instance, =0 if global)
- *  @param[in]   int  : exp2cancel. (=1 if this timer group is expected to be cancelled, =0 otherwise))
- *  @param[in]   int  : the timer group 'tick'. This is the group timer resolution in hw timestamp units. 
- *                Eg for 10 msc , enter @ref netapi_getTicksPerSec()/100
- *  @param[in]   int  : timerTolerence in hw timestamp ticks.  This is FUTURE.
- *  @param[in]   int  : maxTimers - the max number of timers that can be handled by the group.
- *  @param[in]   int* : pointer to error return
- *  @retval     @ref NETAPI_TIMER_GROUP_HANDLE_T : handle for this timer group 
- *  @pre        @ref netapi_init 
- */
-//create a timer group
-NETAPI_TIMER_GROUP_HANDLE_T netapi_TimerGroupCreate(
-       NETAPI_T  netHandle,  //netapi instance
-       char * name, //name of the timer block
-       NETAPI_TIMER_CB_T cb, //the callback function
-       int local,    //1 if timers local to thread
-       int exp2cancel,//1 if expect to cancel
-       int timerTicksPerGroupTick,  //resolution for this timer block, in hw timer ticks
-        int timerTolerence,          //tolerence for this timer block, in hw timer ticksi [FUTURE]
-       int maxTimers, //max # of timer objects for this group
-       int *pErr);
-
-//open a [global] timer group [FUTURE]
-NETAPI_TIMER_GROUP_HANDLE_T  netapi_TimerGroupOpen(
-       NETAPI_T netHandle,
-        char * name,
-       NETAPI_TIMER_CB_T cb,
-       int *pErr);
-
-/*
-*  @brief  API  for Start a Timer 
- *
- *  @details this function is used to start a timer. When it expires, the @ref NETAPI_TIMER_CB_T
- *           will be called.
- *  @param[in]   @ref NATAPI_TIMER_GROUP_HANDLE_T : the handle to the timer group 
- *  @param[in]   void * :  application provided timer id or cookie. MUST NOT BE NULL!!!
- *  @param[in]   uint64_t  : offset from current time when to fire this timer.  This offset MUST be in
- *                           units of timer group ticks (set at create time).  Eg. For 10 msc timer group,
- *                           offset2fire =1 =>  timer is to fire in 10 msc.
- *  @param[in]   int* : pointer to error return
- *  @retval     @ref NETAPI_TIMER_T : handle for this timer. Used to reference the timer for cancel
- *  @pre        @ref netapi_init , @ref netapi_TimerGroupCreate
- */
-//start an individual timer
-NETAPI_TIMER_T netapi_TimerGroupStartTimer(
-       NETAPI_TIMER_GROUP_HANDLE_T th,  //the group handle
-       void * cookie,       //user id ->  CANNONT BE NULL 
-       uint64_t offs2fire,  //offset in timerGroup ticks (eg msc)
-       int * pErr);         //error return
-
-/*
-*  @brief  API  for Cancel a Timer 
- *
- *  @details this function is used to cancel a timer. When it expires, the @ref NETAPI_TIMER_CB_T
- *           will be called.
- *  @param[in]   @ref NATAPI_TIMER_GROUP_HANDLE_T : the handle to the timer group 
- *  @param[in]   @ref NATAPI_TIMER_T : the handle to the  individual timer to cancel
- *  @param[in]   int* : pointer to error return
- *  @retval    none 
- *  @pre        @ref netapi_TimerGroupStartTimer
- */
-//Cancel a timer
-void  netapi_TimerGroupCancel(
-        NETAPI_TIMER_GROUP_HANDLE_T th,
-       NETAPI_TIMER_T timerId,
-        int *pErr);
-
-//close an opened timer group
-void netapi_TimerGroupClose(
-       NETAPI_TIMER_GROUP_HANDLE_T th,
-        int *pErr);
-
-//close an opened timer group
-void netapi_TimerGroupDelete(
-        NETAPI_TIMER_GROUP_HANDLE_T th,
-        int *pErr);
-
-//extract netapi handle from timer group handle
-NETAPI_T netap_TimerGroupGetNH( NETAPI_TIMER_GROUP_HANDLE_T th);
-
-//poll a specific timer group
-int  netapi_TimerGroupPoll(NETAPI_TIMER_GROUP_HANDLE_T th, int maxTimers);
-
-/*
-*  @brief  API  for Polling all timer groups attached to an instance 
- *
- *  @details this function is used to poll all or a specified subset of the timer groups of an 
- *  instance. A mask can be set to filter which categories of timer groups (local vs global etc)
- *  to poll. The approximate max # of timers to process can also be set.
- *  @param[in]   @ref NATAPI_T : the handle of the netapi instance. 
- *  @param[in]   @ref NATAPI_TIMER_FILTER_T : the bit mask of timer group types to poll 
- *  @param[in]   int : approximate max number of timers to process.  NOTE: this can be used to
- *               coarsely control how many timers to process. In general, all timers that have been 
- *               hashed into the same cell and have expired will be processed regardless of the
- *               maxTmers setting.. [FUTURE]
- *  @retval    none 
- *  @pre        @ref netapi_init, @ref netapi_TimerGroupCreate
- */
-
-//poll all timers
-int  netapi_TimerGroupPollAll(NETAPI_T nh, NETAPI_TIMER_FILTER_T f,  int maxTimers);
-
-/*****************END API*********************************/
-
-
-#endif
+/************************************************\r
+ *FILE: netapi_timer.h\r
+ *Purpose:  netapi timer related functions\r
+ **************************************************************\r
+ * @file  netapi_timer.h\r
+ * \r
+ * @breif DESCRIPTION:  netapi timer library header 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
+\r
+/**  @mainpage Netapi Timer Lib \r
+ *\r
+ *   @section intro  Introduction\r
+ *\r
+ *   The network API provides a user space interface to timers\r
+ *      - a function to read a hw provided 64bit time stamp, @ref netapi_getTimestamp\r
+ *        This returns a tick running at 1/6 cpu frequency\r
+ *      - functions to create or open timer groups: @ref netapi_TimerGroupCreateTimer\r
+ *        and @ref  netapi_TimerGroupOpenTimer.  A timer group\r
+ *        is a group of timers with the same characteristics:\r
+ *        -> local or global\r
+ *        -> timer resolution (msc, 10 msc, etc)\r
+ *        -> expect to fire or expect to cancel\r
+ *        -> the same call back function for fired timers\r
+ *      - functions to close or delete timer groups\r
+ *      - function to start a timer,  @ref netapi_TimerGroupStartTimer\r
+ *      - function to cancel a timer,  @ref netapi_TimerGroupCancelTimer\r
+ *      - function to poll a timer group, or all timer groups registered to a NETAPI \r
+ *        instance\r
+ *  \par\r
+ *  NOTE:\r
+ *      (C) Copyright 2010-2011 Texas Instruments, Inc.\r
+ *  \par\r
+ */\r
+\r
+\r
+#ifndef __NETAPI_TIMER__H\r
+#define __NETAPI_TIMER__H\r
+#include "netapi.h"\r
+\r
+extern volatile unsigned long * t64_virt_addr;\r
+extern unsigned int cpu_cycles_sec;\r
+\r
+//return hw timer clock ticks per second\r
+unsigned long t64_ticks_sec(void);\r
+#define netapi_getTicksPerSec t64_ticks_sec\r
+\r
+\r
+/**  @ingroup netapi_api_functions */\r
+\r
+/*\r
+ *  @brief  API returns a 64bit h/w timestamp \r
+ *\r
+ *  @details reads a h/w timer (TIMER64 on Appleton SOC) and returns a 64 bit time stamp    \r
+ *           timer runs at @ref t64_ticks_sec.  Nominally this should be 1/6 CPU clk (@ref cpu_cycles_sec)\r
+ *           \r
+ *  @param[in]  none \r
+ *  @retval     unsigned long long timestamp (64 buts) \r
+ *  @pre        @ref netapi_init \r
+ */\r
+//return 64 bit timestamp from hw timer\r
+static inline unsigned long long netapi_getTimestamp(void) \r
+{\r
+ volatile unsigned long long t1;\r
+ volatile unsigned long long t2;\r
+ unsigned long long val;\r
+ t1 = t64_virt_addr[0x10/4]; //lo\r
+ t2 = t64_virt_addr[0x14/4]; //hi\r
+ val = ((unsigned long long) t2) <<32 | t1;\r
+ return val;\r
+}\r
+\r
+/******************************************************/\r
+/*******************TIMER API***************************/\r
+/******************************************************/\r
+typedef void * NETAPI_TIMER_GROUP_HANDLE_T;     \r
+typedef void * NETAPI_TIMER_T;\r
+typedef void * NETAPI_TIMER_LIST_T;\r
+\r
+/* timer filter values */\r
+typedef int NETAPI_TIMER_FILTER_T;\r
+#define NETAPI_TIMER_NA   (void*) NULL\r
+#define NETAPI_TIMER_FILTER_GLOBAL 0x1\r
+#define NETAPI_TIMER_FILTER_LOCAL 0x2\r
+#define NETAPI_TIMER_FILTER_E2F 0x4\r
+#define NETAPI_TIMER_FILTER_E2C 0x8\r
+#define NETAPI_TIMER_FITLER_ALL 0xf\r
+\r
+//iterator on TIMER_LIST_T\r
+NETAPI_TIMER_T netapi_TimerGetFirst( NETAPI_TIMER_LIST_T list);\r
+NETAPI_TIMER_T netapi_TimerGetNext( NETAPI_TIMER_LIST_T list,NETAPI_TIMER_T prev);\r
+void * netapi_TimerGetCookie(NETAPI_TIMER_T timer);\r
+unsigned long long netapi_TimerGetTs(NETAPI_TIMER_T timer); //debug\r
+\r
+/*\r
+ *  @brief  API callback for timer expiration \r
+ *\r
+ *  @details this function, provided by application,  is registered by application \r
+ *  when timer group is created.  It is called by timer library when a timer or set of timers\r
+ *  expire. The timer list can be walled with iterators: @ref netapi_TimerGetFirst, \r
+ *  @ref netapi_TimerGetNext.  The timer id or "cookie" can be accessed via @ref netapi_TimerGetCookie\r
+ *  NOTE: callback should check for cookie==NULL since timer could be cancelled as it is being fired\r
+ *  @param[in]   @ref NETAPI_TIMER_GROUP_HANDLE_T : the handle to the timer group\r
+ *  @param[in]   int  : the number of timers that have fired \r
+ *  @param[in]   @ref NETAPI_TIMER_LIST_T : the list of timers that hace expired \r
+ *  @param[in]   uint64_t : the current time\r
+ *  @retval     none \r
+ *  @pre        @ref netapi_init , @ref netapi_TimerGroupCreate, @ref netapi_TimerGroupStartTimer\r
+ */\r
+//timer callback\r
+typedef void (*NETAPI_TIMER_CB_T) (\r
+       NETAPI_TIMER_GROUP_HANDLE_T th,  //timer group\r
+       int n_fired,     //# timers fired\r
+       NETAPI_TIMER_LIST_T fired_list,  //the list of fired timers. Access via iterators above\r
+       uint64_t currentTime);  //current timestamp\r
+\r
+/*\r
+*  @brief  API  for Timer Group Creation \r
+ *\r
+ *  @details this function is used to create a timer group. A timer group is a block of timers\r
+ *  that share the same characteristics.\r
+ *  @param[in]   @ref NETAPI_T : the handle to the NETAPI Instance \r
+ *  @param[in]   char * : the name of the timer\r
+ *  @param[in]   @ref NETAPI_TIMER_CB_T :  the callback function\r
+ *  @param[in]   int  : local   (=1 if this timer group is local to this netapi instance, =0 if global)\r
+ *  @param[in]   int  : exp2cancel. (=1 if this timer group is expected to be cancelled, =0 otherwise))\r
+ *  @param[in]   int  : the timer group 'tick'. This is the group timer resolution in hw timestamp units. \r
+ *                Eg for 10 msc , enter @ref netapi_getTicksPerSec()/100\r
+ *  @param[in]   int  : timerTolerence in hw timestamp ticks.  This is FUTURE.\r
+ *  @param[in]   int  : maxTimers - the max number of timers that can be handled by the group.\r
+ *  @param[in]   int* : pointer to error return\r
+ *  @retval     @ref NETAPI_TIMER_GROUP_HANDLE_T : handle for this timer group \r
+ *  @pre        @ref netapi_init \r
+ */\r
+//create a timer group\r
+NETAPI_TIMER_GROUP_HANDLE_T netapi_TimerGroupCreate(\r
+       NETAPI_T  netHandle,  //netapi instance\r
+       char * name, //name of the timer block\r
+       NETAPI_TIMER_CB_T cb, //the callback function\r
+       int local,    //1 if timers local to thread\r
+       int exp2cancel,//1 if expect to cancel\r
+       int timerTicksPerGroupTick,  //resolution for this timer block, in hw timer ticks\r
+        int timerTolerence,          //tolerence for this timer block, in hw timer ticksi [FUTURE]\r
+       int maxTimers, //max # of timer objects for this group\r
+       int *pErr);\r
+\r
+//open a [global] timer group [FUTURE]\r
+NETAPI_TIMER_GROUP_HANDLE_T  netapi_TimerGroupOpen(\r
+       NETAPI_T netHandle,\r
+        char * name,\r
+       NETAPI_TIMER_CB_T cb,\r
+       int *pErr);\r
+\r
+/*\r
+*  @brief  API  for Start a Timer \r
+ *\r
+ *  @details this function is used to start a timer. When it expires, the @ref NETAPI_TIMER_CB_T\r
+ *           will be called.\r
+ *  @param[in]   @ref NATAPI_TIMER_GROUP_HANDLE_T : the handle to the timer group \r
+ *  @param[in]   void * :  application provided timer id or cookie. MUST NOT BE NULL!!!\r
+ *  @param[in]   uint64_t  : offset from current time when to fire this timer.  This offset MUST be in\r
+ *                           units of timer group ticks (set at create time).  Eg. For 10 msc timer group,\r
+ *                           offset2fire =1 =>  timer is to fire in 10 msc.\r
+ *  @param[in]   int* : pointer to error return\r
+ *  @retval     @ref NETAPI_TIMER_T : handle for this timer. Used to reference the timer for cancel\r
+ *  @pre        @ref netapi_init , @ref netapi_TimerGroupCreate\r
+ */\r
+//start an individual timer\r
+NETAPI_TIMER_T netapi_TimerGroupStartTimer(\r
+       NETAPI_TIMER_GROUP_HANDLE_T th,  //the group handle\r
+       void * cookie,       //user id ->  CANNONT BE NULL \r
+       uint64_t offs2fire,  //offset in timerGroup ticks (eg msc)\r
+       int * pErr);         //error return\r
+\r
+/*\r
+*  @brief  API  for Cancel a Timer \r
+ *\r
+ *  @details this function is used to cancel a timer. When it expires, the @ref NETAPI_TIMER_CB_T\r
+ *           will be called.\r
+ *  @param[in]   @ref NATAPI_TIMER_GROUP_HANDLE_T : the handle to the timer group \r
+ *  @param[in]   @ref NATAPI_TIMER_T : the handle to the  individual timer to cancel\r
+ *  @param[in]   int* : pointer to error return\r
+ *  @retval    none \r
+ *  @pre        @ref netapi_TimerGroupStartTimer\r
+ */\r
+//Cancel a timer\r
+void  netapi_TimerGroupCancel(\r
+        NETAPI_TIMER_GROUP_HANDLE_T th,\r
+       NETAPI_TIMER_T timerId,\r
+        int *pErr);\r
+\r
+//close an opened timer group\r
+void netapi_TimerGroupClose(\r
+       NETAPI_TIMER_GROUP_HANDLE_T th,\r
+        int *pErr);\r
+\r
+//close an opened timer group\r
+void netapi_TimerGroupDelete(\r
+        NETAPI_TIMER_GROUP_HANDLE_T th,\r
+        int *pErr);\r
+\r
+//extract netapi handle from timer group handle\r
+NETAPI_T netap_TimerGroupGetNH( NETAPI_TIMER_GROUP_HANDLE_T th);\r
+\r
+//poll a specific timer group\r
+int  netapi_TimerGroupPoll(NETAPI_TIMER_GROUP_HANDLE_T th, int maxTimers);\r
+\r
+/*\r
+*  @brief  API  for Polling all timer groups attached to an instance \r
+ *\r
+ *  @details this function is used to poll all or a specified subset of the timer groups of an \r
+ *  instance. A mask can be set to filter which categories of timer groups (local vs global etc)\r
+ *  to poll. The approximate max # of timers to process can also be set.\r
+ *  @param[in]   @ref NATAPI_T : the handle of the netapi instance. \r
+ *  @param[in]   @ref NATAPI_TIMER_FILTER_T : the bit mask of timer group types to poll \r
+ *  @param[in]   int : approximate max number of timers to process.  NOTE: this can be used to\r
+ *               coarsely control how many timers to process. In general, all timers that have been \r
+ *               hashed into the same cell and have expired will be processed regardless of the\r
+ *               maxTmers setting.. [FUTURE]\r
+ *  @retval    none \r
+ *  @pre        @ref netapi_init, @ref netapi_TimerGroupCreate\r
+ */\r
+\r
+//poll all timers\r
+int  netapi_TimerGroupPollAll(NETAPI_T nh, NETAPI_TIMER_FILTER_T f,  int maxTimers);\r
+\r
+/*****************END API*********************************/\r
+\r
+\r
+#endif\r
index 79985be599b1d9808652e8a25953cfffc5275e3b..bfd651d16d815ab9075440c75a05d6d7f71356ae 100644 (file)
 \r
 //(15) heaps\r
 #define TUNE_NETAPI_MAX_HEAPS  4   //max # of heaps one instance can create\r
+\r
+//(16) classifiers\r
+#define TUNE_NETAPI_MAX_CLASSIFIERS 16\r
 #endif\r
index d4be186259cddd38084a176b56cfe8de448c07a2..ae07c6d0cc2fab05fe25178d0d31a8eaf051ad86 100644 (file)
@@ -182,23 +182,67 @@ NETCP_CFG_IP_T  netcp_cfgAddIp(
                   );\r
 #define netcp_addIp netcp_cfgAddIp //oops\r
 \r
-/*------------------classification [FUTURE]-------------------*/\r
-typedef void *NETCP_CFG_CLASS_T;\r
+/*------------------classification API-------------------*/\r
 \r
-//add classifier\r
+//handle to installed classifier returned by API.  Pkts matching\r
+//this classifier will have meta data with this tag.  Also used\r
+//to delete classifier\r
+typedef uint32_t NETCP_CFG_CLASS_T;  \r
+\r
+//classifier L4 type  (L2,L3 implied by iface, ip)\r
+typedef struct NETCP_CFG_CLASS_L4_Tag\r
+{\r
+        //which mac interface pkt is from, \r
+        int iface;\r
+        NETCP_CFG_IP_T  ip;\r
+\r
+        //L4  (port)\r
+        nwal_appProtoType_t proto;   //L4 proto  (-1 for don't care)\r
+        nwalAppProto_t   appProto;   //ports or equivalent\r
+\r
+} NETCP_CFG_CLASS_L4_T;\r
+\r
+//classifier L3_L4 type (L2 implied by iface)\r
+typedef struct NETCP_CFG_CLASS_L3_L4_Tag\r
+{\r
+       //which mac interface pkt is from, \r
+       int iface;\r
+#define NETCP_CFG_CLASS_IFACE_ANY   255 //don't care\r
+\r
+        //iP address: IP type, destination addr, qualifiers\r
+        //ip_addr=NULL => don't care\r
+       nwal_IpType ipType;\r
+        nwalIpAddr_t  * ip_addr;\r
+        nwalIpOpt_t * ip_qualifiers;\r
+       \r
+        //L4  (port)\r
+       nwal_appProtoType_t proto;   //L4 proto  (-1 for don't care)\r
+       nwalAppProto_t   appProto;   //ports or equivalent\r
+\r
+} NETCP_CFG_CLASS_L3_L4_T;\r
+\r
+//classifier\r
 typedef struct NETCP_CFG_CLASSIFIER_Tag\r
 {\r
-  //tbd a classisfier\r
+       int classType;\r
+#define NETCP_CFG_CLASS_TYPE_L4  0\r
+#define NETCP_CFG_CLASS_TYPE_L3_L4  1\r
+        union\r
+       {\r
+               NETCP_CFG_CLASS_L3_L4_T  c_l3_l4;\r
+               NETCP_CFG_CLASS_L4_T  c_l4;\r
+       } u;\r
 \r
 } NETCP_CFG_CLASSIFIER_T;\r
 \r
+//Instert a classifier.\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
+//delete classifier\r
 void netcp_cfgDelClass(NETAPI_T h,\r
-                         NETCP_CFG_CLASS_T p_class,\r
+                         NETCP_CFG_CLASS_T classId,\r
                          int *err);\r
 \r
 \r
index 8ab74729a00509ced215ba91b71c5adc488a522f..f316d0656e1eab4407237d2e3f67aeea67077c33 100644 (file)
-/*********************************************
- * File: netsync.h
- * Purpose: NETAPI Synchronization primitives
- **************************************************************
- * FILE: netsync.h
- * 
- * DESCRIPTION:  netapi synch utilities header file for user space transport
- *               library
- * 
- * REVISION HISTORY:  rev 0.0.1 
- *
- *  Copyright (c) Texas Instruments Incorporated 2010-2011
- * 
- *  Redistribution and use in source and binary forms, with or without 
- *  modification, are permitted provided that the following conditions 
- *  are met:
- *
- *    Redistributions of source code must retain the above copyright 
- *    notice, this list of conditions and the following disclaimer.
- *
- *    Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the 
- *    documentation and/or other materials provided with the   
- *    distribution.
- *
- *    Neither the name of Texas Instruments Incorporated nor the names of
- *    its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- **********************************************/
-#ifndef NETAPI_SYNC_H
-#define NETAPI_SYNCH_H
-
-/*--------------------------*/
-/*----------spinlock--------*/
-/*--------------------------*/
-
-typedef int NETAPI_SPINLOCK_T;
-
-#define NETAPI_SPINLOCK_LOCKVAL 1
-#define NETAPI_SPINLOCK_UNLOCKVAL 0 //never change!!
-#define NETAPI_SPINLOCK_UNLOCKED_INITIALIZER (NETAPI_SPINLOCK_UNLOCKVAL)
-
-/* init a lock */
-static inline void netapi_spinlock_init (NETAPI_SPINLOCK_T * val) {*val=NETAPI_SPINLOCK_UNLOCKVAL;}
-
-/* lock a spinlock */
-static inline void netapi_spinlock_lock(NETAPI_SPINLOCK_T * val)
-{
-while(__sync_lock_test_and_set(val, NETAPI_SPINLOCK_LOCKVAL))
-    {
-        asm volatile("nop" ::  );
-        asm volatile("nop" ::  );
-        asm volatile("nop" ::  );
-        asm volatile("nop" ::  );
-    }
-}
-
-/* try to get lock 1 time. Return 1 if ok, 0 if un-successful */
-static inline int netapi_spinlock_try_lock( NETAPI_SPINLOCK_T* val)
-{
-  int i=0;
-  if (__sync_lock_test_and_set(val, NETAPI_SPINLOCK_LOCKVAL))  return 0;
-  return 1;
-}
-
-
-/* unlock a spinlock.   */
-static inline void netapi_spinlock_unlock(NETAPI_SPINLOCK_T * val)
-{
-  __sync_lock_release(val);
-}
-
-/* poll a lock, return 0 if unlocked, NETAPI_SPINLOCK_LOCKVAL if locked */
-static inline int netapi_spinlock_is_locked(NETAPI_SPINLOCK_T * val)
-{
-   return *val;
-}
-
-/*--------------------------*/
-/*----------rwlock--------*/
-/*--------------------------*/
-
-/* a rw lock strucuture */
-typedef struct RWLOCK_Tag
-{
-      NETAPI_SPINLOCK_T lock_outer; //lock this structure. very short duration lock
-      NETAPI_SPINLOCK_T lock_w;     //real write lock
-      unsigned long n_readers; /* # readers active */
-} NETAPI_RWLOCK_T;
-
-//initialize a rw lock 
-static inline void netapi_rwlock_init(NETAPI_RWLOCK_T * p_lock)
-{
-        netapi_spinlock_init(&p_lock->lock_outer);
-       netapi_spinlock_init(&p_lock->lock_w);
-        p_lock->n_readers=0;
-}
-
-// lock a write lock.  
-static inline void netapi_rwlock_write_lock(NETAPI_RWLOCK_T * p_lock)
-{
-  int ret;
-  while(1)
-  {
-        netapi_spinlock_lock(&p_lock->lock_outer); //get outer lock - now nothing can change
-       // check for 0 readers
-        if(p_lock->n_readers)
-        {
-           netapi_spinlock_unlock(&p_lock->lock_outer); //give up outer & spin
-           asm volatile("nop" ::  );
-           asm volatile("nop" ::  );
-           asm volatile("nop" ::  );
-           asm volatile("nop" ::  );
-           continue;
-        }
-
-       //ok, no readers.  see if we can get writer lock
-        ret=netapi_spinlock_try_lock(&p_lock->lock_w); //try get writer lock 1 time
-        if(!ret)      
-        {
-           netapi_spinlock_unlock(&p_lock->lock_outer); //give up outer & spin
-           asm volatile("nop" ::  );
-           asm volatile("nop" ::  );
-           asm volatile("nop" ::  );
-           asm volatile("nop" ::  );
-           continue;  /* try again */
-        }
-        netapi_spinlock_unlock(&p_lock->lock_outer); //got write lock=> no other writer, no readers!  Keep the writelock but unlock the outer.
-        return;
-  }
-}
-
-//unlock a writer part of rwlock */
-static inline void netapi_rwlock_write_unlock(NETAPI_RWLOCK_T * p_lock)
-{
-  netapi_spinlock_unlock(&p_lock->lock_w);
-}
-
-//grab a read lock
-//=> can be other readers, but no writer
-static inline void netapi_rwlock_read_lock(NETAPI_RWLOCK_T * p_lock)
-{
-int ret;
-
-while(1)
-{
-  /*1st grab outer lock. once we have it, nothing can change */
-  netapi_spinlock_lock(&p_lock->lock_outer);
-
-  /* see if there is a writer */
-  ret= netapi_spinlock_is_locked(&p_lock->lock_w);
-
-  //there is a writer
-  if (ret)
-  {
-     netapi_spinlock_unlock(&p_lock->lock_outer);  //give up outer and spin
-     asm volatile("nop" ::  );
-     asm volatile("nop" ::  );
-     asm volatile("nop" ::  );
-     asm volatile("nop" ::  );
-     continue; 
-  }
-
-  /* there is no writer so we can read!*/
-  p_lock->n_readers+=1;
-
-  /* mb ? */
-  __sync_synchronize();  //make sure every core sees that n_readers has changed
-
-  /* now give back the outer lock */
-  netapi_spinlock_unlock(&p_lock->lock_outer);
-  return;
-}
-}
-
-//rw_lock reader unlock
-static inline void netapi_rwlock_read_unlock(NETAPI_RWLOCK_T * p_lock)
-{
-  //grab outer
-  netapi_spinlock_lock(&p_lock->lock_outer);
-
-  //decrement # of readers.  Make sure all cores see update
-  p_lock->n_readers--;
-  __sync_synchronize(); 
-  //TBD: need to check for <0? 
-  
-  /* give up the outer */
-  netapi_spinlock_unlock(&p_lock->lock_outer);
-}
-
-/*--------------------------*/
-/*----------atomic32--------*/
-/*--------------------------*/
-typedef struct NETAPI_ATOMIC32_tag
-{
-       long val;
-} NETAPI_ATOMIC32_T;
-
-#define NETAPI_ATOMIC_INIT32(x) {x}
-static inline int netapi_atomic_read32(NETAPI_ATOMIC32_T *p) {return p->val;}
-
-static inline void netapi_atomic_set32(NETAPI_ATOMIC32_T *p, int val) 
-{__sync_fetch_and_add(&p->val,0); } //todo crude, why not p->val=val?
-
-static inline void netapi_atomic_add32(NETAPI_ATOMIC32_T *p, int val)
-{__sync_fetch_and_add(&p->val,val);}
-
-static inline void netapi_atomic_sub32(NETAPI_ATOMIC32_T *p, int val)
-{__sync_fetch_and_sub(&p->val,val);}
-
-#define NETAPI_atomic_inc32(p) netapi_atomic_add32(p,1);
-#define NETAPI_atomic_dec32(p) netapi_atomic_sub32(p,1);
-
-static inline int netapi_atomic_add_return32(NETAPI_ATOMIC32_T *p, int val)
-{return __sync_add_and_fetch(&p->val,val);}
-
-static inline int netapi_atomic_sub_return32(NETAPI_ATOMIC32_T *p, int val)
-{return __sync_sub_and_fetch(&p->val,val);}
-
-static inline int netapi_atomic_inc_and_test32(NETAPI_ATOMIC32_T *p)
-{return __sync_add_and_fetch(&p->val,1);}
-
-static inline int netapi_atomic_dec_and_test32(NETAPI_ATOMIC32_T *p)
-{return !__sync_sub_and_fetch(&p->val,1);}
-
-static inline int netapi_atomic_test_and_set32(NETAPI_ATOMIC32_T *p)
-{return (! _sync_lock_test_and_set(p, 1));}
-
-#define netapi_atomic_clear32(p) netapi_atomic_set32(p,0);
-
-/*--------------------------*/
-/*----------atomic64--------*/
-/*--------------------------*/
-typedef struct NETAPI_ATOMIC64_Tag
-{
-       NETAPI_SPINLOCK_T lock;
-       long long val;
-} NETAPI_ATOMIC64_T;
-
-#define NETAPI_ATOMIC_INIT64(x) {NETAPI_SPINLOCK_UNLOCKED_INITIALIZER,x}
-
-static inline long long  netapi_atomic_read64(NETAPI_ATOMIC64_T *p)
-{
-long long latch_val;
-netapi_spinlock_lock(&p->lock);  //acquire lock
-latch_val = p->val;
-netapi_spinlock_unlock(&p->lock);  //free lock
-return latch_val;
-}
-
-static inline void netapi_atomic_set64(NETAPI_ATOMIC64_T *p,long long val)
-{
-netapi_spinlock_lock(&p->lock);  //acquire lock
-p->val = val;
-//__sync_synchronize();  //todo: may not need as unlock will do this also probably
-netapi_spinlock_unlock(&p->lock);  //free lock
-}
-
-static inline void netapi_atomic_add64(NETAPI_ATOMIC64_T *p, long long val) 
-{
-netapi_spinlock_lock(&p->lock);  //acquire lock
-p->val += val;
-//__sync_synchronize();  //todo: may not need as unlock will do this also probably
-netapi_spinlock_unlock(&p->lock);  //free lock
-}
-
-/*******************************************************
- ****************memory barrier************************
-******************************************************/
-static inline void netapi_mb(){__sync_synchronize();}
-static inline void netapi_rmb(){__sync_synchronize();}
-static inline void netapi_wmb(){__sync_synchronize();}
-
-
-#endif
+/*********************************************\r
+ * File: netsync.h\r
+ * Purpose: NETAPI Synchronization primitives\r
+ **************************************************************\r
+ * FILE: netsync.h\r
+ * \r
+ * DESCRIPTION:  netapi synch utilities header 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
+#ifndef NETAPI_SYNC_H\r
+#define NETAPI_SYNCH_H\r
+\r
+/*--------------------------*/\r
+/*----------spinlock--------*/\r
+/*--------------------------*/\r
+\r
+typedef int NETAPI_SPINLOCK_T;\r
+\r
+#define NETAPI_SPINLOCK_LOCKVAL 1\r
+#define NETAPI_SPINLOCK_UNLOCKVAL 0 //never change!!\r
+#define NETAPI_SPINLOCK_UNLOCKED_INITIALIZER (NETAPI_SPINLOCK_UNLOCKVAL)\r
+\r
+/* init a lock */\r
+static inline void netapi_spinlock_init (NETAPI_SPINLOCK_T * val) {*val=NETAPI_SPINLOCK_UNLOCKVAL;}\r
+\r
+/* lock a spinlock */\r
+static inline void netapi_spinlock_lock(NETAPI_SPINLOCK_T * val)\r
+{\r
+while(__sync_lock_test_and_set(val, NETAPI_SPINLOCK_LOCKVAL))\r
+    {\r
+        asm volatile("nop" ::  );\r
+        asm volatile("nop" ::  );\r
+        asm volatile("nop" ::  );\r
+        asm volatile("nop" ::  );\r
+    }\r
+}\r
+\r
+/* try to get lock 1 time. Return 1 if ok, 0 if un-successful */\r
+static inline int netapi_spinlock_try_lock( NETAPI_SPINLOCK_T* val)\r
+{\r
+  int i=0;\r
+  if (__sync_lock_test_and_set(val, NETAPI_SPINLOCK_LOCKVAL))  return 0;\r
+  return 1;\r
+}\r
+\r
+\r
+/* unlock a spinlock.   */\r
+static inline void netapi_spinlock_unlock(NETAPI_SPINLOCK_T * val)\r
+{\r
+  __sync_lock_release(val);\r
+}\r
+\r
+/* poll a lock, return 0 if unlocked, NETAPI_SPINLOCK_LOCKVAL if locked */\r
+static inline int netapi_spinlock_is_locked(NETAPI_SPINLOCK_T * val)\r
+{\r
+   return *val;\r
+}\r
+\r
+/*--------------------------*/\r
+/*----------rwlock--------*/\r
+/*--------------------------*/\r
+\r
+/* a rw lock strucuture */\r
+typedef struct RWLOCK_Tag\r
+{\r
+      NETAPI_SPINLOCK_T lock_outer; //lock this structure. very short duration lock\r
+      NETAPI_SPINLOCK_T lock_w;     //real write lock\r
+      unsigned long n_readers; /* # readers active */\r
+} NETAPI_RWLOCK_T;\r
+\r
+//initialize a rw lock \r
+static inline void netapi_rwlock_init(NETAPI_RWLOCK_T * p_lock)\r
+{\r
+        netapi_spinlock_init(&p_lock->lock_outer);\r
+       netapi_spinlock_init(&p_lock->lock_w);\r
+        p_lock->n_readers=0;\r
+}\r
+\r
+// lock a write lock.  \r
+static inline void netapi_rwlock_write_lock(NETAPI_RWLOCK_T * p_lock)\r
+{\r
+  int ret;\r
+  while(1)\r
+  {\r
+        netapi_spinlock_lock(&p_lock->lock_outer); //get outer lock - now nothing can change\r
+       // check for 0 readers\r
+        if(p_lock->n_readers)\r
+        {\r
+           netapi_spinlock_unlock(&p_lock->lock_outer); //give up outer & spin\r
+           asm volatile("nop" ::  );\r
+           asm volatile("nop" ::  );\r
+           asm volatile("nop" ::  );\r
+           asm volatile("nop" ::  );\r
+           continue;\r
+        }\r
+\r
+       //ok, no readers.  see if we can get writer lock\r
+        ret=netapi_spinlock_try_lock(&p_lock->lock_w); //try get writer lock 1 time\r
+        if(!ret)      \r
+        {\r
+           netapi_spinlock_unlock(&p_lock->lock_outer); //give up outer & spin\r
+           asm volatile("nop" ::  );\r
+           asm volatile("nop" ::  );\r
+           asm volatile("nop" ::  );\r
+           asm volatile("nop" ::  );\r
+           continue;  /* try again */\r
+        }\r
+        netapi_spinlock_unlock(&p_lock->lock_outer); //got write lock=> no other writer, no readers!  Keep the writelock but unlock the outer.\r
+        return;\r
+  }\r
+}\r
+\r
+//unlock a writer part of rwlock */\r
+static inline void netapi_rwlock_write_unlock(NETAPI_RWLOCK_T * p_lock)\r
+{\r
+  netapi_spinlock_unlock(&p_lock->lock_w);\r
+}\r
+\r
+//grab a read lock\r
+//=> can be other readers, but no writer\r
+static inline void netapi_rwlock_read_lock(NETAPI_RWLOCK_T * p_lock)\r
+{\r
+int ret;\r
+\r
+while(1)\r
+{\r
+  /*1st grab outer lock. once we have it, nothing can change */\r
+  netapi_spinlock_lock(&p_lock->lock_outer);\r
+\r
+  /* see if there is a writer */\r
+  ret= netapi_spinlock_is_locked(&p_lock->lock_w);\r
+\r
+  //there is a writer\r
+  if (ret)\r
+  {\r
+     netapi_spinlock_unlock(&p_lock->lock_outer);  //give up outer and spin\r
+     asm volatile("nop" ::  );\r
+     asm volatile("nop" ::  );\r
+     asm volatile("nop" ::  );\r
+     asm volatile("nop" ::  );\r
+     continue; \r
+  }\r
+\r
+  /* there is no writer so we can read!*/\r
+  p_lock->n_readers+=1;\r
+\r
+  /* mb ? */\r
+  __sync_synchronize();  //make sure every core sees that n_readers has changed\r
+\r
+  /* now give back the outer lock */\r
+  netapi_spinlock_unlock(&p_lock->lock_outer);\r
+  return;\r
+}\r
+}\r
+\r
+//rw_lock reader unlock\r
+static inline void netapi_rwlock_read_unlock(NETAPI_RWLOCK_T * p_lock)\r
+{\r
+  //grab outer\r
+  netapi_spinlock_lock(&p_lock->lock_outer);\r
+\r
+  //decrement # of readers.  Make sure all cores see update\r
+  p_lock->n_readers--;\r
+  __sync_synchronize(); \r
+  //TBD: need to check for <0? \r
+  \r
+  /* give up the outer */\r
+  netapi_spinlock_unlock(&p_lock->lock_outer);\r
+}\r
+\r
+/*--------------------------*/\r
+/*----------atomic32--------*/\r
+/*--------------------------*/\r
+typedef struct NETAPI_ATOMIC32_tag\r
+{\r
+       long val;\r
+} NETAPI_ATOMIC32_T;\r
+\r
+#define NETAPI_ATOMIC_INIT32(x) {x}\r
+static inline int netapi_atomic_read32(NETAPI_ATOMIC32_T *p) {return p->val;}\r
+\r
+static inline void netapi_atomic_set32(NETAPI_ATOMIC32_T *p, int val) \r
+{__sync_fetch_and_add(&p->val,0); } //todo crude, why not p->val=val?\r
+\r
+static inline void netapi_atomic_add32(NETAPI_ATOMIC32_T *p, int val)\r
+{__sync_fetch_and_add(&p->val,val);}\r
+\r
+static inline void netapi_atomic_sub32(NETAPI_ATOMIC32_T *p, int val)\r
+{__sync_fetch_and_sub(&p->val,val);}\r
+\r
+#define NETAPI_atomic_inc32(p) netapi_atomic_add32(p,1);\r
+#define NETAPI_atomic_dec32(p) netapi_atomic_sub32(p,1);\r
+\r
+static inline int netapi_atomic_add_return32(NETAPI_ATOMIC32_T *p, int val)\r
+{return __sync_add_and_fetch(&p->val,val);}\r
+\r
+static inline int netapi_atomic_sub_return32(NETAPI_ATOMIC32_T *p, int val)\r
+{return __sync_sub_and_fetch(&p->val,val);}\r
+\r
+static inline int netapi_atomic_inc_and_test32(NETAPI_ATOMIC32_T *p)\r
+{return __sync_add_and_fetch(&p->val,1);}\r
+\r
+static inline int netapi_atomic_dec_and_test32(NETAPI_ATOMIC32_T *p)\r
+{return !__sync_sub_and_fetch(&p->val,1);}\r
+\r
+static inline int netapi_atomic_test_and_set32(NETAPI_ATOMIC32_T *p)\r
+{return (! _sync_lock_test_and_set(p, 1));}\r
+\r
+#define netapi_atomic_clear32(p) netapi_atomic_set32(p,0);\r
+\r
+/*--------------------------*/\r
+/*----------atomic64--------*/\r
+/*--------------------------*/\r
+typedef struct NETAPI_ATOMIC64_Tag\r
+{\r
+       NETAPI_SPINLOCK_T lock;\r
+       long long val;\r
+} NETAPI_ATOMIC64_T;\r
+\r
+#define NETAPI_ATOMIC_INIT64(x) {NETAPI_SPINLOCK_UNLOCKED_INITIALIZER,x}\r
+\r
+static inline long long  netapi_atomic_read64(NETAPI_ATOMIC64_T *p)\r
+{\r
+long long latch_val;\r
+netapi_spinlock_lock(&p->lock);  //acquire lock\r
+latch_val = p->val;\r
+netapi_spinlock_unlock(&p->lock);  //free lock\r
+return latch_val;\r
+}\r
+\r
+static inline void netapi_atomic_set64(NETAPI_ATOMIC64_T *p,long long val)\r
+{\r
+netapi_spinlock_lock(&p->lock);  //acquire lock\r
+p->val = val;\r
+//__sync_synchronize();  //todo: may not need as unlock will do this also probably\r
+netapi_spinlock_unlock(&p->lock);  //free lock\r
+}\r
+\r
+static inline void netapi_atomic_add64(NETAPI_ATOMIC64_T *p, long long val) \r
+{\r
+netapi_spinlock_lock(&p->lock);  //acquire lock\r
+p->val += val;\r
+//__sync_synchronize();  //todo: may not need as unlock will do this also probably\r
+netapi_spinlock_unlock(&p->lock);  //free lock\r
+}\r
+\r
+/*******************************************************\r
+ ****************memory barrier************************\r
+******************************************************/\r
+static inline void netapi_mb(){__sync_synchronize();}\r
+static inline void netapi_rmb(){__sync_synchronize();}\r
+static inline void netapi_wmb(){__sync_synchronize();}\r
+\r
+\r
+#endif\r
index b990d48fa08bafa0eec8811d5c88d7625732c9c0..1ff2106712cb4347836e25fec0c507bc8eb483db 100644 (file)
-
-/******************************************************************************
- * FILE  netapi_vm.c
- * PURPOSE:  Memory allocator for NETAPI and related utilities
- *   -- using MSMC for descriptors/buffers (current), use CMA (future) 
- ******************************************************************************
- * FILE NAME:   netapi_vm.c
- *
- * DESCRIPTION: Memory allocator for netapi 
- * This is only a permanent memory allocator.
- *
- * REVISION HISTORY:
- *
- *  Copyright (c) Texas Instruments Incorporated 2010-2011
- * 
- *  Redistribution and use in source and binary forms, with or without 
- *  modification, are permitted provided that the following conditions 
- *  are met:
- *
- *    Redistributions of source code must retain the above copyright 
- *    notice, this list of conditions and the following disclaimer.
- *
- *    Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the 
- *    documentation and/or other materials provided with the   
- *    distribution.
- *
- *    Neither the name of Texas Instruments Incorporated nor the names of
- *    its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include <ti/drv/nwal/nwal.h> 
-#include "netapi_vm.h"
-
-
-
-/***********************RAW MEMORY ALLOCATION & TRANSLATION*************************/
-/* Macro to align x to y */
-#define align(x,y)   ((x + y) & (~y))
-
-uint8_t *netapi_VM_mem_start_phy = (uint8_t*)0;
-uint8_t *netapi_VM_mem_start = (uint8_t*)0;
-
-static uint8_t *netapi_VM_mem_end = (uint8_t*)0;
-static uint8_t *netapi_VM_mem_alloc_ptr = (uint8_t*)0;
-static uint32_t netapi_VM_mem_size = 0;
-
-
-
-/* File descriptor for /dev/mem */ 
-static int dev_mem_fd;
-
-nwal_Bool_t netapi_VM_memAllocInit
-(
-    uint8_t     *addr, /* Physical address */
-    uint32_t    size   /* Size of block */
-)
-{
-    void *map_base; 
-
-    if((dev_mem_fd = open("/dev/mem", (O_RDWR | O_SYNC))) == -1)
-    {
-        printf(">netapi_VM_memAllocInit: Failed to open \"dev/mem\" err=%s\n",
-               strerror(errno));
-        return nwal_FALSE;
-    }
-
-    map_base = netapi_VM_memMap ((void *)addr, size); 
-
-    if (!map_base)
-    {
-        printf(">netapi_VM_memAllocInit: Failed to mmap addr (0x%x)", addr);
-        return nwal_FALSE;
-    }
-
-    printf(">netapi_VM_memAllocInit: Phy Addr %x Memory (%d bytes) mapped at address %p.\n", addr,size,  map_base); 
-
-    netapi_VM_mem_alloc_ptr = netapi_VM_mem_start = map_base;
-    netapi_VM_mem_size = size;
-    netapi_VM_mem_end = netapi_VM_mem_start + netapi_VM_mem_size;
-    netapi_VM_mem_start_phy = addr;
-    return nwal_TRUE;
-}
-
-void* netapi_VM_memAlloc
-(
-    uint32_t    size,
-    uint32_t    align
-)
-{
-    uint32_t key;
-    uint8_t *alloc_ptr;
-    void *p_block =NULL;
-
-    Osal_stubCsEnter();
-    alloc_ptr = (uint8_t*)align((uint32_t)netapi_VM_mem_alloc_ptr, align);
-    if ((alloc_ptr + size) < netapi_VM_mem_end)
-    {
-        p_block =(void *)alloc_ptr;
-        netapi_VM_mem_alloc_ptr = alloc_ptr + size;
-        Osal_stubCsExit(key);
-        memset (p_block, 0, size);
-    }
-    else 
-    {
-        Osal_stubCsExit(key);
-    }
-    return p_block;
+\r
+/******************************************************************************\r
+ * FILE  netapi_vm.c\r
+ * PURPOSE:  Memory allocator for NETAPI and related utilities\r
+ *   -- using MSMC for descriptors/buffers (current), use CMA (future) \r
+ ******************************************************************************\r
+ * FILE NAME:   netapi_vm.c\r
+ *\r
+ * DESCRIPTION: Memory allocator for netapi \r
+ * This is only a permanent memory allocator.\r
+ *\r
+ * REVISION HISTORY:\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 <stdint.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+#include <fcntl.h>\r
+#include <sys/mman.h>\r
+#include <errno.h>\r
+#include <unistd.h>\r
+\r
+#include <ti/drv/nwal/nwal.h> \r
+#include "netapi_vm.h"\r
+\r
+\r
+\r
+/***********************RAW MEMORY ALLOCATION & TRANSLATION*************************/\r
+/* Macro to align x to y */\r
+#define align(x,y)   ((x + y) & (~y))\r
+\r
+uint8_t *netapi_VM_mem_start_phy = (uint8_t*)0;\r
+uint8_t *netapi_VM_mem_start = (uint8_t*)0;\r
+\r
+static uint8_t *netapi_VM_mem_end = (uint8_t*)0;\r
+static uint8_t *netapi_VM_mem_alloc_ptr = (uint8_t*)0;\r
+static uint32_t netapi_VM_mem_size = 0;\r
+\r
+\r
+\r
+/* File descriptor for /dev/mem */ \r
+static int dev_mem_fd;\r
+\r
+nwal_Bool_t netapi_VM_memAllocInit\r
+(\r
+    uint8_t     *addr, /* Physical address */\r
+    uint32_t    size   /* Size of block */\r
+)\r
+{\r
+    void *map_base; \r
+\r
+    if((dev_mem_fd = open("/dev/mem", (O_RDWR | O_SYNC))) == -1)\r
+    {\r
+        printf(">netapi_VM_memAllocInit: Failed to open \"dev/mem\" err=%s\n",\r
+               strerror(errno));\r
+        return nwal_FALSE;\r
+    }\r
+\r
+    map_base = netapi_VM_memMap ((void *)addr, size); \r
+\r
+    if (!map_base)\r
+    {\r
+        printf(">netapi_VM_memAllocInit: Failed to mmap addr (0x%x)", addr);\r
+        return nwal_FALSE;\r
+    }\r
+\r
+    printf(">netapi_VM_memAllocInit: Phy Addr %x Memory (%d bytes) mapped at address %p.\n", addr,size,  map_base); \r
+\r
+    netapi_VM_mem_alloc_ptr = netapi_VM_mem_start = map_base;\r
+    netapi_VM_mem_size = size;\r
+    netapi_VM_mem_end = netapi_VM_mem_start + netapi_VM_mem_size;\r
+    netapi_VM_mem_start_phy = addr;\r
+    return nwal_TRUE;\r
 }\r
-uint32_t    xtraLogs=0;
-/* Api to map the give physical address to virtual memory space */
-void *netapi_VM_memMap
-(
-    void        *addr, /* Physical address */
-    uint32_t    size   /* Size of block */
-)
-{
-    void            *map_base,*virt_addr,*tmpAddr;
-    uint32_t        page_sz;
+\r
+void* netapi_VM_memAlloc\r
+(\r
+    uint32_t    size,\r
+    uint32_t    align\r
+)\r
+{\r
+    uint32_t key;\r
+    uint8_t *alloc_ptr;\r
+    void *p_block =NULL;\r
+\r
+    Osal_stubCsEnter();\r
+    alloc_ptr = (uint8_t*)align((uint32_t)netapi_VM_mem_alloc_ptr, align);\r
+    if ((alloc_ptr + size) < netapi_VM_mem_end)\r
+    {\r
+        p_block =(void *)alloc_ptr;\r
+        netapi_VM_mem_alloc_ptr = alloc_ptr + size;\r
+        Osal_stubCsExit(key);\r
+        memset (p_block, 0, size);\r
+    }\r
+    else \r
+    {\r
+        Osal_stubCsExit(key);\r
+    }\r
+    return p_block;\r
+}\r
+uint32_t    xtraLogs=0;\r
+/* Api to map the give physical address to virtual memory space */\r
+void *netapi_VM_memMap\r
+(\r
+    void        *addr, /* Physical address */\r
+    uint32_t    size   /* Size of block */\r
+)\r
+{\r
+    void            *map_base,*virt_addr,*tmpAddr;\r
+    uint32_t        page_sz;\r
     long            retval;\r
     uint32_t        mask = (size-1);\r
-    uint32_t        offset;
-
-    retval = sysconf(_SC_PAGE_SIZE);
-    if (retval == -1)
-    {
-        printf(">netapi_VM_memMap: Failed to get page size err=%s\n",
-               strerror(errno));
-        return (void *)0;
-    }
-
-    page_sz = (uint32_t)retval;
-
-    if (size%page_sz)
-    {
-        printf(">netapi_VM_memMap: error: block size not aligned to page size\n");
-        return (void *)0;
-    }
-
-    if ((uint32_t)addr%page_sz)
-    {
-        printf(">netapi_VM_memMap: error: addr not aligned to page size\n");
-        return (void *)0;
-    }
-
-    map_base = mmap(0, size, (PROT_READ|PROT_WRITE), MAP_SHARED, dev_mem_fd, (off_t)addr & ~mask);
-    if(map_base == (void *) -1) 
-    {
-        printf(">netapi_VM_memMap: Failed to mmap \"dev/mem\" err=%s\n",
-               strerror(errno));
-        return (void *)0;
-    }
-    virt_addr = map_base + ((off_t)addr & mask);
-    if(xtraLogs)
-    {
-        printf(">netapi_VM_memMap:Memory mapped Begin Address 0x%x Read Value: 0x%x.\n", virt_addr,*((unsigned long *)virt_addr));
- //       offset = size/(sizeof(unsigned long));
-  //      tmpAddr = (unsigned long *)virt_addr + offset-1;
-        tmpAddr = (uint8_t *)virt_addr + 0x6800c;
-        printf("netapi_VM_memMap:Memory mapped End Address 0x%x Read Value: 0x%x.\n", (unsigned long *)tmpAddr ,*((unsigned long *)tmpAddr));
-        *((unsigned long *)tmpAddr) = 0x1234;
-        printf("netapi_VM_memMap:Memory mapped End Address 0x%x Write Value: 0x%x.\n", (unsigned long *)tmpAddr ,*((unsigned long *)tmpAddr));
-        
-    }
-    return(virt_addr);
-}
-
-/***************************************************************/
-/*************** Memory Initilaization**************************/
-/***************************************************************/
-/* for now use msmc */
-/* Total Permanent memory required in NWAL test
- * for Packet buffers & descriptor buffers
- */
-#define NETAPI_PERM_MEM_SZ  (TUNE_NETAPI_PERM_MEM_SZ) 
-
-/* Physical address map & size for various subsystems */
-#define QMSS_CFG_BASE_ADDR  CSL_QM_SS_CFG_QUE_PEEK_REGS
-#define QMSS_CFG_BLK_SZ (1*1024*1024)
-#define QMSS_DATA_BASE_ADDR 0x44020000 
-#define QMSS_DATA_BLK_SZ (0x60000)
-#define SRIO_CFG_BASE_ADDR  CSL_SRIO_CONFIG_REGS
-#define SRIO_CFG_BLK_SZ (132*1024)
-#define PASS_CFG_BASE_ADDR  CSL_PA_SS_CFG_REGS 
-#define PASS_CFG_BLK_SZ (1*1024*1024)
-
-#define MSMC_SRAM_BASE_ADDR CSL_MSMC_SRAM_REGS
-
-/* Global variables to hold virtual address of various subsystems */
-void *netapi_VM_qmssCfgVaddr;
-void *netapi_VM_qmssDataVaddr;
-void *netapi_VM_srioCfgVaddr;
-void *netapi_VM_passCfgVaddr;
-
-/* also for our descriptor area */
-unsigned char *netapi_VM_QMemLocalDescRam=NULL;
-unsigned char *netapi_VM_QMemGlobalDescRam=NULL;
-
-
-/*************************************************
- * setup VM memory
- ************************************************/
-int netapi_VM_memory_setup(void)
-{
-    /* (1) big chunck of memory out of MSMC -> todo, get from CMA */
-    if (netapi_VM_memAllocInit((uint8_t*)MSMC_SRAM_BASE_ADDR,
-                              NETAPI_PERM_MEM_SZ) == nwal_FALSE) {
-        printf(">netapi ERROR: netapi_V_MmemAllocInit failed\n");
-        return (-1);
-    }
-
-
-    /* (2) Create virtual memory maps for peripherals */
-    /* (2a) QMSS CFG Regs */
-    netapi_VM_qmssCfgVaddr = netapi_VM_memMap((void*)QMSS_CFG_BASE_ADDR,
-                                            QMSS_CFG_BLK_SZ);
-    if (!netapi_VM_qmssCfgVaddr)
-    {
-        printf(">netapi ERROR: Failed to map QMSS CFG registers\n");
-        return (-1);
-    }
-    printf("netapi> QMSS_CFG_BASE_ADDR:0x%x Memory mapped at address %p.\n",(void*)QMSS_CFG_BASE_ADDR, netapi_VM_qmssCfgVaddr);
-
-    /* (2b) QMSS DATA Regs */
-    netapi_VM_qmssDataVaddr = netapi_VM_memMap((void*)QMSS_DATA_BASE_ADDR,
-                                            QMSS_DATA_BLK_SZ);
-    if (!netapi_VM_qmssDataVaddr)
-    {
-        printf(">netapi ERROR: Failed to map QMSS DATA registers\n");
-        return (-1);
-    }
-    printf(">netapi QMSS_DATA_BASE_ADDR:0x%x Memory mapped at address %p.\n",(void*)QMSS_DATA_BASE_ADDR, netapi_VM_qmssDataVaddr);
-
-    /* (2c)  SRIO CFG Regs */
-    netapi_VM_srioCfgVaddr = netapi_VM_memMap((void*)SRIO_CFG_BASE_ADDR,
-                                            SRIO_CFG_BLK_SZ);
-    if (!netapi_VM_srioCfgVaddr)
-    {
-        printf(">netapi ERROR: Failed to map SRIO CFG registers\n");
-        return (-1);
-    }
-    printf(">netapi SRIO_CFG_BASE_ADDR:0x%x Memory mapped at address %p.\n",(void*)SRIO_CFG_BASE_ADDR, netapi_VM_srioCfgVaddr);
-
-    /* (2d) PASS CFG Regs */
-    netapi_VM_passCfgVaddr = netapi_VM_memMap((void*)PASS_CFG_BASE_ADDR,
-                                            PASS_CFG_BLK_SZ);
-    if (!netapi_VM_passCfgVaddr)
-    {
-        printf(">netapi ERROR: Failed to map PASS CFG registers\n");
-        return (-1);
-    }
-    printf(">netapi PASS_CFG_BASE_ADDR:0x%x Memory mapped at address %p.\n",(void*)PASS_CFG_BASE_ADDR, netapi_VM_passCfgVaddr);
-
-    /* (2e)  SA ?? */
-     /*to do */
-
-    /* (2f) Timer */
-    t64_memmap(dev_mem_fd);
-
-    /* (3) Allocate 2 QM regions from continguous chunk above */
-    netapi_VM_QMemGlobalDescRam = (void *)netapi_VM_memAlloc((TUNE_NETAPI_NUM_GLOBAL_DESC *
-                                        TUNE_NETAPI_DESC_SIZE),
-                                        128);
-    netapi_VM_QMemLocalDescRam = (void *)netapi_VM_memAlloc((TUNE_NETAPI_NUM_LOCAL_DESC *
-                                        TUNE_NETAPI_DESC_SIZE),
-                                        128);
-    printf(">netapi local desc region=%x global desc region=%x\n", netapi_VM_QMemLocalDescRam,netapi_VM_QMemGlobalDescRam);
-
-       return 1;
-
-}
-
+    uint32_t        offset;\r
+\r
+    retval = sysconf(_SC_PAGE_SIZE);\r
+    if (retval == -1)\r
+    {\r
+        printf(">netapi_VM_memMap: Failed to get page size err=%s\n",\r
+               strerror(errno));\r
+        return (void *)0;\r
+    }\r
+\r
+    page_sz = (uint32_t)retval;\r
+\r
+    if (size%page_sz)\r
+    {\r
+        printf(">netapi_VM_memMap: error: block size not aligned to page size\n");\r
+        return (void *)0;\r
+    }\r
+\r
+    if ((uint32_t)addr%page_sz)\r
+    {\r
+        printf(">netapi_VM_memMap: error: addr not aligned to page size\n");\r
+        return (void *)0;\r
+    }\r
+\r
+    map_base = mmap(0, size, (PROT_READ|PROT_WRITE), MAP_SHARED, dev_mem_fd, (off_t)addr & ~mask);\r
+    if(map_base == (void *) -1) \r
+    {\r
+        printf(">netapi_VM_memMap: Failed to mmap \"dev/mem\" err=%s\n",\r
+               strerror(errno));\r
+        return (void *)0;\r
+    }\r
+    virt_addr = map_base + ((off_t)addr & mask);\r
+    if(xtraLogs)\r
+    {\r
+        printf(">netapi_VM_memMap:Memory mapped Begin Address 0x%x Read Value: 0x%x.\n", virt_addr,*((unsigned long *)virt_addr));\r
+ //       offset = size/(sizeof(unsigned long));\r
+  //      tmpAddr = (unsigned long *)virt_addr + offset-1;\r
+        tmpAddr = (uint8_t *)virt_addr + 0x6800c;\r
+        printf("netapi_VM_memMap:Memory mapped End Address 0x%x Read Value: 0x%x.\n", (unsigned long *)tmpAddr ,*((unsigned long *)tmpAddr));\r
+        *((unsigned long *)tmpAddr) = 0x1234;\r
+        printf("netapi_VM_memMap:Memory mapped End Address 0x%x Write Value: 0x%x.\n", (unsigned long *)tmpAddr ,*((unsigned long *)tmpAddr));\r
+        \r
+    }\r
+    return(virt_addr);\r
+}\r
+\r
+/***************************************************************/\r
+/*************** Memory Initilaization**************************/\r
+/***************************************************************/\r
+/* for now use msmc */\r
+/* Total Permanent memory required in NWAL test\r
+ * for Packet buffers & descriptor buffers\r
+ */\r
+#define NETAPI_PERM_MEM_SZ  (TUNE_NETAPI_PERM_MEM_SZ) \r
+\r
+/* Physical address map & size for various subsystems */\r
+#define QMSS_CFG_BASE_ADDR  CSL_QM_SS_CFG_QUE_PEEK_REGS\r
+#define QMSS_CFG_BLK_SZ (1*1024*1024)\r
+#define QMSS_DATA_BASE_ADDR 0x44020000 \r
+#define QMSS_DATA_BLK_SZ (0x60000)\r
+#define SRIO_CFG_BASE_ADDR  CSL_SRIO_CONFIG_REGS\r
+#define SRIO_CFG_BLK_SZ (132*1024)\r
+#define PASS_CFG_BASE_ADDR  CSL_PA_SS_CFG_REGS \r
+#define PASS_CFG_BLK_SZ (1*1024*1024)\r
+\r
+#define MSMC_SRAM_BASE_ADDR CSL_MSMC_SRAM_REGS\r
+\r
+/* Global variables to hold virtual address of various subsystems */\r
+void *netapi_VM_qmssCfgVaddr;\r
+void *netapi_VM_qmssDataVaddr;\r
+void *netapi_VM_srioCfgVaddr;\r
+void *netapi_VM_passCfgVaddr;\r
+\r
+/* also for our descriptor area */\r
+unsigned char *netapi_VM_QMemLocalDescRam=NULL;\r
+unsigned char *netapi_VM_QMemGlobalDescRam=NULL;\r
+\r
+\r
+/*************************************************\r
+ * setup VM memory\r
+ ************************************************/\r
+int netapi_VM_memory_setup(void)\r
+{\r
+    /* (1) big chunck of memory out of MSMC -> todo, get from CMA */\r
+    if (netapi_VM_memAllocInit((uint8_t*)MSMC_SRAM_BASE_ADDR,\r
+                              NETAPI_PERM_MEM_SZ) == nwal_FALSE) {\r
+        printf(">netapi ERROR: netapi_V_MmemAllocInit failed\n");\r
+        return (-1);\r
+    }\r
+\r
+\r
+    /* (2) Create virtual memory maps for peripherals */\r
+    /* (2a) QMSS CFG Regs */\r
+    netapi_VM_qmssCfgVaddr = netapi_VM_memMap((void*)QMSS_CFG_BASE_ADDR,\r
+                                            QMSS_CFG_BLK_SZ);\r
+    if (!netapi_VM_qmssCfgVaddr)\r
+    {\r
+        printf(">netapi ERROR: Failed to map QMSS CFG registers\n");\r
+        return (-1);\r
+    }\r
+    printf(">netapi QMSS_CFG_BASE_ADDR:0x%x Memory mapped at address %p.\n",(void*)QMSS_CFG_BASE_ADDR, netapi_VM_qmssCfgVaddr);\r
+\r
+    /* (2b) QMSS DATA Regs */\r
+    netapi_VM_qmssDataVaddr = netapi_VM_memMap((void*)QMSS_DATA_BASE_ADDR,\r
+                                            QMSS_DATA_BLK_SZ);\r
+    if (!netapi_VM_qmssDataVaddr)\r
+    {\r
+        printf(">netapi ERROR: Failed to map QMSS DATA registers\n");\r
+        return (-1);\r
+    }\r
+    printf(">netapi QMSS_DATA_BASE_ADDR:0x%x Memory mapped at address %p.\n",(void*)QMSS_DATA_BASE_ADDR, netapi_VM_qmssDataVaddr);\r
+\r
+    /* (2c)  SRIO CFG Regs */\r
+    netapi_VM_srioCfgVaddr = netapi_VM_memMap((void*)SRIO_CFG_BASE_ADDR,\r
+                                            SRIO_CFG_BLK_SZ);\r
+    if (!netapi_VM_srioCfgVaddr)\r
+    {\r
+        printf(">netapi ERROR: Failed to map SRIO CFG registers\n");\r
+        return (-1);\r
+    }\r
+    printf(">netapi SRIO_CFG_BASE_ADDR:0x%x Memory mapped at address %p.\n",(void*)SRIO_CFG_BASE_ADDR, netapi_VM_srioCfgVaddr);\r
+\r
+    /* (2d) PASS CFG Regs */\r
+    netapi_VM_passCfgVaddr = netapi_VM_memMap((void*)PASS_CFG_BASE_ADDR,\r
+                                            PASS_CFG_BLK_SZ);\r
+    if (!netapi_VM_passCfgVaddr)\r
+    {\r
+        printf(">netapi ERROR: Failed to map PASS CFG registers\n");\r
+        return (-1);\r
+    }\r
+    printf(">netapi PASS_CFG_BASE_ADDR:0x%x Memory mapped at address %p.\n",(void*)PASS_CFG_BASE_ADDR, netapi_VM_passCfgVaddr);\r
+\r
+    /* (2e)  SA ?? */\r
+     /*to do */\r
+\r
+    /* (2f) Timer */\r
+    t64_memmap(dev_mem_fd);\r
+\r
+    /* (3) Allocate 2 QM regions from continguous chunk above */\r
+    netapi_VM_QMemGlobalDescRam = (void *)netapi_VM_memAlloc((TUNE_NETAPI_NUM_GLOBAL_DESC *\r
+                                        TUNE_NETAPI_DESC_SIZE),\r
+                                        128);\r
+    netapi_VM_QMemLocalDescRam = (void *)netapi_VM_memAlloc((TUNE_NETAPI_NUM_LOCAL_DESC *\r
+                                        TUNE_NETAPI_DESC_SIZE),\r
+                                        128);\r
+    printf(">netapi local desc region=%x global desc region=%x\n", netapi_VM_QMemLocalDescRam,netapi_VM_QMemGlobalDescRam);\r
+\r
+       return 1;\r
+\r
+}\r
+\r
index abc5ebb27a86d8776676a471db87e1560c002dc3..4dbb1ce9fc0963b7af08454ad5aa7d65fb5a851b 100644 (file)
@@ -100,6 +100,22 @@ static int netcp_cfgp_find_ip_slot(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
    return -1;\r
 }\r
 \r
+//internal: find a free slot for classifier rule\r
+static int netcp_cfgp_find_class_slot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p)\r
+{\r
+   int i;\r
+        //find a free entry\r
+   for(i=0;i<TUNE_NETAPI_MAX_CLASSIFIERS;i++)\r
+   {\r
+       if (!p->classi[i].in_use)\r
+       {\r
+           p->classi[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
@@ -121,7 +137,7 @@ static void netcp_cfgp_insert_ip(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
 }\r
 \r
 \r
-//internal: instert interface info into global context\r
+//internal: insert 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
@@ -193,6 +209,41 @@ static void* netcp_cfgp_get_mac_handle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface
    return NULL;\r
 }\r
 \r
+ //internal: delete a classifer from list \r
+static void netcp_cfgp_delete_class(\r
+         NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
+         int class_slot )\r
+{\r
+   if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS))\r
+   {\r
+        return ;\r
+   }\r
+   p->classi[class_slot].in_use=0;\r
+   return;\r
+}\r
+\r
+//internal:  insert a classifier into list \r
+static void netcp_cfgp_insert_class(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
+                          int class_slot,  //we 'reserved it already'\r
+                          void * L2_handle,\r
+                          void * L3_handle,\r
+                          void * L4_handle)\r
+{\r
+        p->classi[class_slot].in_use=1;\r
+        p->classi[class_slot].nwal_L2_handle = L2_handle;\r
+        p->classi[class_slot].nwal_L3_handle = L3_handle;\r
+        p->classi[class_slot].nwal_L4_handle = L4_handle;\r
+        return;\r
+}\r
+\r
+//internal: return nwal_handle for class\r
+static void *netcp_cfgp_get_class_handle( NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
+                          int class_slot)\r
+{\r
+   if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS)) return NULL;\r
+   if (!p->classi[class_slot].in_use) return NULL;\r
+   return p->classi[class_slot].nwal_L4_handle;\r
+}\r
 \r
 /***********************************************************************************/\r
 /****************************************API****************************************/\r
@@ -551,6 +602,175 @@ void netcp_cfgDelIp(NETAPI_T h, int iface_no,  nwal_IpType ipType,
     return ;\r
 }\r
 \r
+/**\r
+ * @def netcp_cfgAddClass\r
+ * @brief  add a classifier rule into NETCP\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
+{\r
+NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
+void * l3_handle;  //ip handle\r
+nwal_RetValue       retValue;\r
+NetapiNwalTransInfo_t *pTransInfo;\r
+nwal_TransID_t     trans_id;\r
+int class_slot=-1;\r
+int iface;\r
+int ip_slot;\r
+NETCP_CFG_CLASS_T  classHandle;  //returned by us\r
+nwal_appProtoType_t proto;\r
+nwalLocConnCfg_t tempCfg={\r
+0,  //nwal_handle: to be filled in\r
+{0}, // l4 ports: to be filled in\r
+0,  //core id (NA)\r
+0, //action\r
+CPPI_PARAM_NOT_SPECIFIED, //flow id\r
+QMSS_PARAM_NOT_SPECIFIED, //dest queue\r
+};\r
+\r
+if(!p_class) { *err=NETAPI_ERR_BAD_INPUT; return -1;}\r
+switch(p_class->classType)\r
+{\r
+default:\r
+       printf(">netcp_cfg : classifier type %d not supported\n",p_class->classType);\r
+       break;\r
+\r
+case(NETCP_CFG_CLASS_TYPE_L4):\r
+       //assume just type l4 only (L2, L3 defined by iface, l3 id )\r
+        iface = p_class->u.c_l4.iface;\r
+        ip_slot = (p_class->u.c_l4.ip>>8)&0xff;\r
+\r
+         //verify that iface has been configured \r
+        if(!netapi_get_global()->nwal_context.interfaces[iface].in_use)\r
+       {\r
+               *err = NETAPI_ERR_BAD_INPUT;\r
+               return -1;\r
+       }\r
+        //verify that ip has been configured and get its handle\r
+        l3_handle = netcp_cfgp_get_ip_handle(\r
+                          &netapi_get_global()->nwal_context, iface,\r
+                          ip_slot );\r
+        if(!l3_handle)\r
+            {*err = NETAPI_ERR_BAD_INPUT; return -1 ;}\r
+\r
+\r
+        //find free slot for CLASS & reserve\r
+        class_slot= netcp_cfgp_find_class_slot(&netapi_get_global()->nwal_context);\r
+        if(class_slot<0) {*err = NETAPI_ERR_NOMEM; return -1;}\r
+        classHandle = NETAPI_NETCP_MATCH_CLASS | (class_slot<<8) | (iface&0xff);\r
+        //build request from template\r
+        tempCfg.inHandle=l3_handle;\r
+       memcpy(&tempCfg.appProto,&p_class->u.c_l4.appProto,sizeof(nwalAppProto_t));\r
+        tempCfg.matchAction = (action==NETCP_CFG_ACTION_TO_SW)  ? NWAL_MATCH_ACTION_HOST : NWAL_MATCH_ACTION_DISCARD;\r
+       proto = p_class->u.c_l4.proto;\r
+        //todo: flowid and route \r
+        //get a transaction id\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
+        //issue request\r
+        retValue = nwal_addConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
+                            trans_id,\r
+                           (nwal_AppId) classHandle,\r
+                            proto,\r
+                            &tempCfg,\r
+                            NULL,\r
+                            &pTransInfo->handle);\r
+        if(retValue !=  nwal_OK)\r
+        {\r
+            *err = NETAPI_ERR_NWAL_ERR0;\r
+            printf (">netcp cfg - ERROR: nwal_addConn returned Error Code %d\n",\r
+                    retValue);\r
+            pTransInfo->inUse = nwal_FALSE;\r
+            netcp_cfgp_delete_class(&netapi_get_global()->nwal_context, class_slot);\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: L4 Classifer added to interface %d ip %d (slot%d)\n", iface, ip_slot, class_slot);\r
+         netcp_cfgp_insert_class(&netapi_get_global()->nwal_context, \r
+                                   class_slot,\r
+                                 NULL,  //L2 we have\r
+                                 NULL,  //L3 we have\r
+                                  pTransInfo->handle);\r
+         pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
+\r
+        \r
+        return classHandle;\r
+} //end switch\r
+return -1;\r
+}\r
+\r
+//delete classifier\r
+void netcp_cfgDelClass(NETAPI_T h,\r
+                         NETCP_CFG_CLASS_T classId,\r
+                         int *err)\r
+{\r
+NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
+void * class_handle;  //class handle\r
+nwal_RetValue       retValue;\r
+NetapiNwalTransInfo_t *pTransInfo;\r
+nwal_TransID_t     trans_id;\r
+int class_slot=-1;\r
+//int iface;\r
+//int ip_slot;\r
+\r
+       class_slot = (classId>>8)&0xffff;\r
+        class_handle=netcp_cfgp_get_class_handle(\r
+                       &netapi_get_global()->nwal_context,\r
+                       class_slot );\r
+        if(!class_handle)  {*err = NETAPI_ERR_BAD_INPUT; return -1;}\r
+       netcp_cfgp_delete_class(\r
+                        &netapi_get_global()->nwal_context,\r
+                        class_slot );\r
+        //get a transaction id\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
+        //issue request\r
+        retValue = nwal_delConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
+                            trans_id,\r
+                            class_handle);\r
+        if(retValue !=  nwal_OK)\r
+        {\r
+            *err = NETAPI_ERR_NWAL_ERR0;\r
+            printf (">netcp cfg - ERROR: nwal_delConn returned Error Code %d\n",\r
+                    retValue);\r
+            pTransInfo->inUse = nwal_FALSE;\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: Classifer deleted\n");\r
+         pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
+         pTransInfo->inUse = nwal_FALSE;\r
+         return ;\r
+}\r
+\r
 \r
 /*************************************************************************/\r
 /*********************************INTERNAL*******************************/\r
@@ -612,19 +832,19 @@ void netapi_NWALCmdCallBack (nwal_AppId        appHandle,
                 }\r
                 break;\r
             }\r
-#if 0\r
-            case TEST_NWAL_HANDLE_TRANS_PORT:\r
+            case NETAPI_NWAL_HANDLE_TRANS_PORT:\r
             {\r
-                if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)\r
+                if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
                 {\r
-                    testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;\r
+                    p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
                 }\r
-                else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
+                else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
                 {\r
-                    testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;\r
+                    p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
                 }\r
                 break;\r
             }\r
+#if 0\r
             case TEST_NWAL_HANDLE_TRANS_SEC_ASSOC:\r
             {\r
                 if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)\r
index 1e90059a6ea62b2b8f2ddd46c8bb96f1f57db770..2073b432e481eda611fe1df6c7d15366fe5b0a35 100755 (executable)
@@ -189,6 +189,11 @@ typedef struct stats_t
        long tx;\r
        long n_bad;\r
        long n_new;\r
+        long n_class0_rx;   //count of pkts classified \r
+        long n_class1_rx;   //count of pkts classified \r
+        long n_t1;\r
+        long n_t2;\r
+        long n_t3;\r
 } STATS_T;\r
 \r
 typedef struct head_t\r
@@ -249,7 +254,7 @@ void house(NETAPI_SCHED_HANDLE_T *s);
 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
+  NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 500  //every 500 poll loops\r
 };\r
 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats);\r
 NETAPI_TIMER_GROUP_HANDLE_T ourTimerBlock; \r
@@ -264,6 +269,24 @@ void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
 \r
 NETCP_CFG_IP_T ip_rule0;\r
 NETCP_CFG_IP_T ip_rule1;\r
+NETCP_CFG_CLASS_T class_0;\r
+NETCP_CFG_CLASS_T class_1;\r
+\r
+NETCP_CFG_CLASSIFIER_T class_0_cfg=\r
+{\r
+   NETCP_CFG_CLASS_TYPE_L4,\r
+   {\r
+       {0,0, NWAL_APP_PLOAD_PROTO_UDP, {2500}}\r
+   }\r
+};\r
+\r
+NETCP_CFG_CLASSIFIER_T class_1_cfg=\r
+{\r
+   NETCP_CFG_CLASS_TYPE_L4,\r
+   {\r
+        {0,0, NWAL_APP_PLOAD_PROTO_UDP, {2502}}\r
+   }\r
+};\r
 \r
 PKTIO_CONTROL_T zap_channel_control={PKTIO_CLEAR, NULL};\r
 \r
@@ -372,7 +395,15 @@ 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\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
+if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_CLASS)\r
+{\r
+  int c= ((unsigned int)p_meta->u.rx_meta->appId >>8)&0xffff;\r
+  if (c==0) stats.n_class0_rx +=1;\r
+  else if (c==1) stats.n_class1_rx +=1;\r
+  else printf("**NET_TEST RX -unknown class: %x\n",  p_meta->u.rx_meta->appId);\r
+}\r
 }\r
+\r
  return 1;\r
 }\r
 \r
@@ -533,28 +564,34 @@ NETAPI_TIMER_T tx;
 int cookie;\r
 int err;\r
 unsigned long long et;\r
-printf("TIMER CALLBACK @ %lld %d timers\n", currentTime, n_fired);\r
-printf("netcp_tx_handle check (tc) %x\n", netcp_tx_chan->back);\r
+//DEBUGprintf("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
+  //DEBUGprintf("   timer %d - cookie = %d expected ts=%lld (delta=%lld)\n", i, cookie, et, currentTime-et);\r
   if (cookie ==1)\r
+  {  \r
+     stats.n_t1+=1;\r
      t1 = netapi_TimerGroupStartTimer(\r
         th,\r
         (void *) 1,\r
         100LL,  //timer group tics\r
         &err);\r
+  }\r
   else if (cookie ==2)\r
+  {\r
+      stats.n_t2+=1;\r
       t2 = netapi_TimerGroupStartTimer(\r
         th,\r
         (void *) 2,\r
         200LL,  //timer group ticks\r
         &err);\r
+  }\r
   else\r
   {\r
+    stats.n_t3+=1;\r
     t3 = netapi_TimerGroupStartTimer(\r
         th,\r
         (void *) 3,\r
@@ -585,6 +622,8 @@ uint32_t numPacketsinGarbage;
 \r
 printf("stats @ %lld\n", netapi_getTimestamp());\r
 printf("netcp_tx_handle check %x\n", netcp_tx_chan->back);\r
+printf("itx=%d rx=%d tx=%d bad=%d slow=%d rx_class0=%d rx_class1=%d n_t1=%d n_t2=%d n_t3=%d\n",stats.itx, stats.rx, stats.tx, stats.n_bad, stats.n_new,stats.n_class0_rx, stats.n_class1_rx, stats.n_t1, stats.n_t2,stats.n_t3);\r
+\r
 if(pPaStats)\r
 {\r
        printf("C1 number of packets:           %d\n", pPaStats->classify1.nPackets);\r
@@ -630,6 +669,7 @@ int err;
 static int house_pkts_gened=0;\r
 int p;\r
 unsigned char * pIpHdr,* pData;\r
+unsigned int vv1,vv2,vv3;\r
 \r
 for(p=0;p<TX_BURST;p++) {  \r
 //reguest stats \r
@@ -655,7 +695,9 @@ if ((house_pkts_gened>0) && (! (house_pkts_gened%400)) )
    tip = get_pkt(house_pkts_gened, &len);\r
    if(!tip) { house_pkts_gened +=1; continue; }\r
 \r
+\r
    /* set the pkt length */\r
+   vv1 = netapi_timing_start();\r
    Pktlib_setPacketLen(tip, len);\r
 \r
    /* set up meta data */\r
@@ -679,7 +721,10 @@ if ((house_pkts_gened>0) && (! (house_pkts_gened%400)) )
    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
+   vv2= netapi_timing_stop();\r
    pktio_send(netcp_tx_chan,tip,&meta,&err);\r
+   vv3= netapi_timing_stop();\r
+   printf("pktio send. full=%d metadata=%d pktio_send=%d\n", vv3-vv1,  vv2-vv1,  vv3-vv2);\r
    if (err == 0) stats.itx +=1;\r
 \r
    house_pkts_gened +=1;\r
@@ -790,6 +835,24 @@ ip_rule1=netcp_addIp(
                   );\r
 if (err) {printf("addip1 failed %d\n",err); exit(1); }\r
 \r
+//attach 2 classifiers to iface 0, ip0\r
+class_0_cfg.u.c_l4.ip = ip_rule0;\r
+class_0 =  netcp_cfgAddClass(netapi_handle,\r
+                             &class_0_cfg,\r
+                             NULL,\r
+                             NETCP_CFG_ACTION_TO_SW,\r
+                            &err);\r
+if (err) {printf("addclass0 failed %d\n",err); exit(1);}\r
+\r
+class_1_cfg.u.c_l4.ip = ip_rule0;\r
+class_1 =  netcp_cfgAddClass(netapi_handle,\r
+                             &class_1_cfg,\r
+                             NULL,\r
+                             NETCP_CFG_ACTION_TO_SW,\r
+                             &err);\r
+if (err) {printf("addclass1 failed %d\n",err); exit(1);}\r
+\r
+\r
 #endif\r
 \r
  ourTimerBlock = netapi_TimerGroupCreate(\r
@@ -863,6 +926,10 @@ netapi_schedWaitForEvents(our_sched, &err);
 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
+//delete Classifiers\r
+netcp_cfgDelClass(netapi_handle, class_0, &err); \r
+netcp_cfgDelClass(netapi_handle, class_1, &err); \r
+\r
 //delete IPs and MAC Interfacess\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