summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 8b0f060)
raw | patch | inline | side by side (parent: 8b0f060)
author | David Lide <a0216552@gtudci01.(none)> | |
Mon, 13 Feb 2012 16:10:28 +0000 (11:10 -0500) | ||
committer | David Lide <a0216552@gtudci01.(none)> | |
Mon, 13 Feb 2012 16:10:28 +0000 (11:10 -0500) |
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)
);\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)
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
}\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
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
}\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)
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
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
\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
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
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
\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
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
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
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
);\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
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