index fe785af69fd0ce3f094b7858ad2b09186cd67fa5..a9947a69be26949ac1c91eee8fcb2875223446e7 100755 (executable)
-/*******************************\r
- * FILE: netapi.c\r
- * Purpose: implementation of netapi startup/shutdown\r
- **************************************************************\r
- * FILE: netapi.c\r
- * \r
- * DESCRIPTION: netapi main source file for user space transport\r
- * library\r
- * \r
- * REVISION HISTORY: rev 0.0.1 \r
- *\r
- * Copyright (c) Texas Instruments Incorporated 2010-2011\r
- * \r
- * Redistribution and use in source and binary forms, with or without \r
- * modification, are permitted provided that the following conditions \r
- * are met:\r
- *\r
- * Redistributions of source code must retain the above copyright \r
- * notice, this list of conditions and the following disclaimer.\r
- *\r
- * Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the \r
- * documentation and/or other materials provided with the \r
- * distribution.\r
- *\r
- * Neither the name of Texas Instruments Incorporated nor the names of\r
- * its contributors may be used to endorse or promote products derived\r
- * from this software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-\r
- * *****************************/\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <unistd.h>\r
-#include <string.h>\r
-#include "netapi.h"\r
-\r
-typedef struct PRESET_Tag\r
-{\r
-#define KMAXQ 10\r
- int kqinuse[KMAXQ];\r
- //more..\r
-} PRESET_T;\r
-\r
-/*------------internal prototypes---------------*/\r
-static uint8_t* netapiSharedMemoryMalloc(uint32_t size);\r
-static void netapiSharedMemoryFree(uint8_t* ptr);\r
-static int system_init(NETAPI_HANDLE_T *);\r
-static void get_presets(PRESET_T * p_preset);\r
-static void netapi_cleanup_at_start(void);\r
-\r
-\r
-/*------------globals-----------------*/\r
-#define NUM_HOST_DESC (TUNE_NETAPI_NUM_LOCAL_DESC)\r
-#define SIZE_LOCAL_DESC (TUNE_NETAPI_DESC_SIZE) \r
-#define SIZE_SHARED_DESC (TUNE_NETAPI_DESC_SIZE)\r
-\r
-#define CONFIG_BUFSIZE_PA_INST 256\r
-#define CONFIG_BUFSIZE_L2_TABLE 1000\r
-#define CONFIG_BUFSIZE_L3_TABLE 4000\r
-\r
-static NETAPI_CFG_T netapi_default_cfg=\r
-{\r
-TUNE_NETAPI_PERM_MEM_SZ,\r
-0, //start of packet offset for hw to place data on rx for default flow\r
-TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system\r
-TUNE_NETAPI_NUM_GLOBAL_DESC, //total we will use\r
-TUNE_NETAPI_DEFAULT_NUM_BUFFERS, //#descriptors+buffers in default heap\r
-TUNE_NETAPI_DEFAULT_NUM_SOLO_DESCRIPTORS, //#descriptors w/o buffers in default heap\r
-TUNE_NETAPI_DEFAULT_BUFFER_SIZE //size of buffers in default heap\r
-\r
-};\r
-\r
-static Pktlib_HeapIfTable netapi_pktlib_ifTable;\r
-static NETAPI_GLOBAL_T netapi_global;\r
-NETAPI_GLOBAL_T * netapi_get_global(){ return &netapi_global;}\r
-\r
-/* utility API for NETAPI user to get pktlib if table to use if he creates his own heap */\r
-Pktlib_HeapIfTable *netapi_getPktlibIfTable(void) {return &netapi_pktlib_ifTable;}\r
-\r
-//zap a queue\r
-void netapi_zapQ(int queueNum);\r
-/*-------------------------------------\r
- * initialize NETAPI instance \r
- *-------------------------------------*/\r
-NETAPI_T netapi_init(int master, NETAPI_CFG_T * p_cfg)\r
-{\r
- int i;\r
- int err;\r
- NETAPI_HANDLE_T * p = (NETAPI_HANDLE_T *) calloc(1,sizeof(NETAPI_HANDLE_T));\r
- if (!p) return NULL;\r
- p->master = master;\r
-\r
- /* create space for our local pktios */\r
- for(i=0;i<NETAPI_MAX_PKTIO; i++)\r
- {\r
- p->pktios[i] = calloc(1,sizeof(PKTIO_HANDLE_T));\r
- if (!p->pktios[i]) return NULL;\r
- }\r
-\r
-#ifdef NETAPI_INCLUDE_SCHED\r
- /* create space for scheduler */\r
- p->p_sched = calloc(1,sizeof(NETAPI_SCHED_HANDLE_T));\r
-#endif \r
-\r
-\r
- /* global stuff (if master) */\r
- if (master==NETAPI_SYS_MASTER)\r
- {\r
- if (p_cfg) memcpy(&netapi_global.cfg,p_cfg, sizeof(NETAPI_CFG_T));\r
- else memcpy(&netapi_global.cfg,&netapi_default_cfg, sizeof(NETAPI_CFG_T));\r
- for(i=0;i<NETAPI_MAX_PKTIO;i++) \r
- { \r
- netapi_global.pktios[i].qn.qNum=-1;\r
- netapi_global.pktios[i].name[0]='\0';\r
- }\r
- } \r
- //this goes to shared memory eventually\r
- p->global = (void *) &netapi_global;\r
-\r
-\r
- /* system init */\r
- if(master==NETAPI_SYS_MASTER)\r
- {\r
- err = system_init(p);\r
- if (err<0) \r
- {\r
- //todo: cleanup\r
- return NULL;\r
- }\r
- /* create pktio channels for tx,rx */\r
- }\r
- else\r
- {\r
- /*todo init for non-system cores/threads */\r
- /* qm_start, */\r
- /* attach to heaps */\r
- /* nwal_start */\r
- }\r
- \r
- return (NETAPI_T) p;\r
-}\r
-\r
-/*-------------------------------\r
- * Shut down netapi instance\r
- *-------------------------------*/\r
-void netapi_shutdown(NETAPI_T h)\r
-{\r
- int i;\r
- NETAPI_HANDLE_T * p = (NETAPI_HANDLE_T *) h;\r
- if (!p) return;\r
-\r
- printf(">netapi: WARNING shutdown may not be fully implemented\n");\r
- if (p->master)\r
- {\r
- /* close nwal */\r
- nwal_delete(netapi_global.nwal_context.nwalInstHandle);\r
-\r
- /* close heaps */\r
- netapi_closeHeap(h, p->netcp_heap);\r
- netapi_closeHeap(h, p->netcp_control_heap);\r
- netapi_closeHeap(h, netapi_get_global()->nwal_context.pa2sa_heap); \r
- netapi_closeHeap(h, netapi_get_global()->nwal_context.sa2pa_heap); \r
- \r
- //loop over registered heaps\r
- for(i=0;i<TUNE_NETAPI_MAX_HEAPS;i++)\r
- {\r
- if (p->createdHeaps[i]) {netapi_closeHeap(h,p->createdHeaps[i]);p->createdHeaps[i]=NULL;}\r
- }\r
- netapi_cleanup_at_start(); //clear 1st 50 not-specified queues..\r
- netapi_VM_memory_teardown();\r
- } \r
- free(p);\r
- return;\r
-}\r
-\r
-//exception crash\r
-void netapi_err_teardown() { netapi_cleanup_at_start(); exit(-99); }\r
-\r
-/*-------------------utilities-------------------*/\r
-static uint8_t* netapiSharedMemoryMalloc(uint32_t size)\r
-{\r
-return (uint8_t *)netapi_VM_memAlloc(size, 128); \r
-}\r
-\r
-static void netapiSharedMemoryFree(uint8_t* ptr)\r
-{\r
- /* Do Nothing. */\r
- printf(">netapi Unexpected. need to provide a free () for some reason!! \n");\r
- return;\r
-}\r
-\r
-// initialization\r
-static int system_init(NETAPI_HANDLE_T * handle) \r
-{\r
- int32_t result;\r
- Pktlib_HeapHandle sharedHeapHandle;\r
- Pktlib_HeapHandle controlHeapHandle;\r
-\r
- /* initialize all the memory we are going to use\r
- - chunk for buffers, descriptors\r
- - memory mapped peripherals we use, such as QMSS, PA, etc */\r
- result= netapi_VM_memory_setup();\r
- if (result) printf(">netapi: system init - memory set up OK\n");\r
- else {printf(">netap: system init - memory set up failed\n"); return -1;}\r
-\r
- //get timer running\r
- netapi_init_timer();\r
-\r
- /* Initialize Queue Manager Sub System */\r
- result = netapi_init_qm (netapi_global.cfg.def_max_descriptors); \r
- if (result != 1)\r
- {\r
- return -1;\r
- }\r
-\r
- /* Start the QMSS. */\r
- if (netapi_start_qm() != 1)\r
- {\r
- return -1;\r
- }\r
-\r
- //clean our old junk in 1st bunch of queues that will be allocated to us\r
- netapi_cleanup_at_start();\r
-\r
- /* Initialize the global descriptor memory region. */\r
- result= netapi_qm_setup_mem_region( \r
- netapi_global.cfg.def_tot_descriptors_for_us,\r
- SIZE_SHARED_DESC,\r
- (unsigned int *) netapi_VM_QMemGlobalDescRam,\r
- NETAPI_GLOBAL_REGION);\r
- if(result <0) {printf(">netapi; can't setup QM shared region\n"); return -1;}\r
-\r
-#if 0 //todo setup 2nd region\r
-/* Initialize the local memory region configuration. */\r
- result= netapi_qm_setup_mem_region( \r
- NUM_HOST_DESC,\r
- SIZE_LOCAL_DESC,\r
- netapi_VM_QMemLocalDescRam,\r
- NETAPI_LOCAL_REGION);\r
- if(result <0) {printf("can't setup local region\n"); return -1;}\r
-#endif\r
- /* Initialize CPPI CPDMA */\r
-\r
- result = netapi_init_cppi ();\r
- if (result != 1)\r
- {\r
- printf (">netapi: Error initializing CPPI SubSystem error code : %d\n",result);\r
- return -1;\r
- }\r
-\r
- /* CPPI and Queue Manager are initialized. */\r
- printf (">netapi: Queue Manager and CPPI are initialized.\n");\r
-\r
- /* create main pkt heap */\r
- /* Initialize the Shared Heaps. */\r
- Pktlib_sharedHeapInit();\r
-\r
- /* Populate the heap interface table. */\r
- netapi_pktlib_ifTable.data_malloc = netapiSharedMemoryMalloc;\r
- netapi_pktlib_ifTable.data_free = netapiSharedMemoryFree;\r
-\r
- /* Create Shared Heap with specified configuration. */\r
- sharedHeapHandle = Pktlib_createHeap("netapi", NETAPI_GLOBAL_REGION, //was 0\r
- 1,\r
- netapi_global.cfg.def_heap_buf_size,\r
- netapi_global.cfg.def_heap_n_descriptors,\r
- netapi_global.cfg.def_heap_n_zdescriptors,\r
- &netapi_pktlib_ifTable);\r
- //todo -> cleanup on failure\r
- if (!sharedHeapHandle) { printf(">'netapi' heap create failed\n"); return -1;}\r
- handle->netcp_heap= sharedHeapHandle;\r
-\r
- controlHeapHandle = Pktlib_createHeap("netapi_control", NETAPI_GLOBAL_REGION,\r
- 1,\r
- TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE,\r
- TUNE_NETAPI_CONFIG_NUM_CTL_BUF,\r
- 0,\r
- &netapi_pktlib_ifTable);\r
- //todo -> cleanup on failure\r
- if (!controlHeapHandle) { printf(">netapi -'netapicontrol' heap create failed\n"); return -1;}\r
- handle->netcp_control_heap= controlHeapHandle;\r
-\r
-\r
- /* now NWAL */\r
- result = netapi_init_nwal(\r
- NETAPI_GLOBAL_REGION,\r
- &netapi_pktlib_ifTable, \r
- &netapi_global.nwal_context,\r
- &netapi_global.cfg);\r
- if (result<0) {printf(">netapi init_nwal() failed\n"); return -1; }\r
-\r
- /* start NWAL */\r
- result = netapi_start_nwal(sharedHeapHandle, \r
- controlHeapHandle,\r
- &handle->nwal_local,\r
- &netapi_global.nwal_context);\r
- if (result<0) {printf(">netapi start_nwal() failed\n"); return -1; }\r
- //** success **\r
-\r
-\r
- return 0;\r
-\r
-}\r
-\r
-\r
-/*---------------\r
- * get presets()\r
- *---------------*/\r
-static void get_presets(PRESET_T * p_preset)\r
-{\r
- /* read from kernel or overall config area */\r
- /* for now hard code what kernel did */\r
-}\r
-\r
-\r
-/*************************************************************\r
- ******************MISC INTERNAL******************************\r
-**************************************************************/\r
-/* poll the garbage queues of all registered heaps */\r
-void netapi_pollHeapGarbage(NETAPI_T h)\r
-{\r
-int i;\r
- NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
- Pktlib_garbageCollection(n->netcp_heap);\r
- //no need to do garbage collection on other internal heaps\r
- for(i=0;i<TUNE_NETAPI_MAX_HEAPS;i++)\r
- {\r
- if (n->createdHeaps[i]) Pktlib_garbageCollection(n->createdHeaps[i]);\r
- }\r
-}\r
-\r
-/* poll NETCP control queue for responses */\r
-void netapi_netcpPoll(NETAPI_T p)\r
-{\r
- NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) p;\r
- nwal_pollCtl( ((NETAPI_GLOBAL_T *) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
-}\r
-\r
-/****************************************************************\r
- *****************Cleanup Functions******************************\r
-*****************************************************************/\r
-\r
-//clean up function for linux user space\r
-void netapi_zapQ(int queueNum)\r
-{\r
-char * descPtr;\r
-int i;\r
-if (!queueNum) return;\r
-for (i=0;;i+=1 )\r
- {\r
- /* Pop descriptor from source queue */\r
- if ((descPtr = (char *)Qmss_queuePop (queueNum)) == NULL)\r
- {\r
- break;\r
- }\r
- else {/*printf("netapi qzap in play\n");*/}\r
- }\r
- if(i) printf(">netapi: @recovery - %d descriptors cleaned from qn %d\n",i, queueNum);\r
-}\r
-\r
-//defensive: clean out stuff hanging around\r
-//\r
-// open a bunch of free queues and zap them\r
-#define NQUEUES2CLEAR 15\r
-static Qmss_QueueHnd tempQH[NQUEUES2CLEAR];\r
-static void netapi_cleanup_at_start(void)\r
-{\r
-int i;\r
-uint8_t isAllocated;\r
-\r
-for(i=0;i<NQUEUES2CLEAR;i++) \r
-{\r
- tempQH[i] = Qmss_queueOpen(Qmss_QueueType_GENERAL_PURPOSE_QUEUE,\r
- QMSS_PARAM_NOT_SPECIFIED, &isAllocated);\r
- netapi_zapQ(tempQH[i]);\r
-}\r
-\r
-for(i=0;i<NQUEUES2CLEAR;i++)\r
-{\r
- Qmss_queueClose(tempQH[i]);\r
-}\r
-\r
-}\r
-\r
-/********************************\r
- * clean up a pktlib heap\r
- ***********************************/\r
-int netapi_closeHeap(NETAPI_T h, Pktlib_HeapHandle p)\r
-{\r
-Qmss_QueueHnd q;\r
-Pktlib_garbageCollection(p); \r
-q = Pktlib_getZeroHeapQueue(p);\r
-netapi_zapQ(q);\r
-q= Pktlib_getInternalHeapQueue(p);\r
-netapi_zapQ(q);\r
-}\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
+/*******************************
+ * FILE: netapi.c
+ * Purpose: implementation of netapi startup/shutdown
+ **************************************************************
+ * FILE: netapi.c
+ *
+ * DESCRIPTION: netapi main source file for user space transport
+ * library
+ *
+ * REVISION HISTORY: rev 0.0.1
+ *
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ * *****************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include "netapi.h"
+
+typedef struct PRESET_Tag
+{
+#define KMAXQ 10
+ int kqinuse[KMAXQ];
+ //more..
+} PRESET_T;
+
+/*------------internal prototypes---------------*/
+static uint8_t* netapiSharedMemoryMalloc(uint32_t size);
+static void netapiSharedMemoryFree(uint8_t* ptr);
+static int system_init(NETAPI_HANDLE_T *);
+static void get_presets(PRESET_T * p_preset);
+static void netapi_cleanup_at_start(void);
+
+
+/*------------globals-----------------*/
+#define NUM_HOST_DESC (TUNE_NETAPI_NUM_LOCAL_DESC)
+#define SIZE_LOCAL_DESC (TUNE_NETAPI_DESC_SIZE)
+#define SIZE_SHARED_DESC (TUNE_NETAPI_DESC_SIZE)
+
+#define CONFIG_BUFSIZE_PA_INST 256
+#define CONFIG_BUFSIZE_L2_TABLE 1000
+#define CONFIG_BUFSIZE_L3_TABLE 4000
+
+static NETAPI_CFG_T netapi_default_cfg=
+{
+TUNE_NETAPI_PERM_MEM_SZ,
+0, //start of packet offset for hw to place data on rx for default flow
+TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
+TUNE_NETAPI_NUM_GLOBAL_DESC, //total we will use
+TUNE_NETAPI_DEFAULT_NUM_BUFFERS, //#descriptors+buffers in default heap
+TUNE_NETAPI_DEFAULT_NUM_SOLO_DESCRIPTORS, //#descriptors w/o buffers in default heap
+TUNE_NETAPI_DEFAULT_BUFFER_SIZE, //size of buffers in default heap
+0,0
+
+};
+
+static Pktlib_HeapIfTable netapi_pktlib_ifTable;
+static NETAPI_GLOBAL_T netapi_global;
+NETAPI_GLOBAL_T * netapi_get_global(){ return &netapi_global;}
+
+/* utility API for NETAPI user to get pktlib if table to use if he creates his own heap */
+Pktlib_HeapIfTable *netapi_getPktlibIfTable(void) {return &netapi_pktlib_ifTable;}
+
+//zap a queue
+void netapi_zapQ(int queueNum);
+/*-------------------------------------
+ * initialize NETAPI instance
+ *-------------------------------------*/
+NETAPI_T netapi_init(int master, NETAPI_CFG_T * p_cfg)
+{
+ int i;
+ int err;
+ NETAPI_HANDLE_T * p = (NETAPI_HANDLE_T *) calloc(1,sizeof(NETAPI_HANDLE_T));
+ if (!p) return NULL;
+ p->master = master;
+
+ /* create space for our local pktios */
+ for(i=0;i<NETAPI_MAX_PKTIO; i++)
+ {
+ p->pktios[i] = calloc(1,sizeof(PKTIO_HANDLE_T));
+ if (!p->pktios[i]) return NULL;
+ }
+
+#ifdef NETAPI_INCLUDE_SCHED
+ /* create space for scheduler */
+ p->p_sched = calloc(1,sizeof(NETAPI_SCHED_HANDLE_T));
+#endif
+
+
+ /* global stuff (if master) */
+ if (master==NETAPI_SYS_MASTER)
+ {
+ if (p_cfg) memcpy(&netapi_global.cfg,p_cfg, sizeof(NETAPI_CFG_T));
+ else memcpy(&netapi_global.cfg,&netapi_default_cfg, sizeof(NETAPI_CFG_T));
+ for(i=0;i<NETAPI_MAX_PKTIO;i++)
+ {
+ netapi_global.pktios[i].qn.qNum=-1;
+ netapi_global.pktios[i].name[0]='\0';
+ }
+ }
+ //this goes to shared memory eventually
+ p->global = (void *) &netapi_global;
+
+
+ /* system init */
+ if(master==NETAPI_SYS_MASTER)
+ {
+ err = system_init(p);
+ if (err<0)
+ {
+ //todo: cleanup
+ return NULL;
+ }
+ /* create pktio channels for tx,rx */
+ }
+ else
+ {
+ /*todo init for non-system cores/threads */
+ /* qm_start, */
+ /* attach to heaps */
+ /* nwal_start */
+ }
+
+ return (NETAPI_T) p;
+}
+
+/*-------------------------------
+ * Shut down netapi instance
+ *-------------------------------*/
+void netapi_shutdown(NETAPI_T h)
+{
+ int i;
+ NETAPI_HANDLE_T * p = (NETAPI_HANDLE_T *) h;
+ if (!p) return;
+
+ printf(">netapi: WARNING shutdown may not be fully implemented\n");
+ if (p->master)
+ {
+ /* close nwal */
+ nwal_delete(netapi_global.nwal_context.nwalInstHandle);
+
+ /* close heaps */
+ netapi_closeHeap(h, p->netcp_heap);
+ netapi_closeHeap(h, p->netcp_control_heap);
+ netapi_closeHeap(h, netapi_get_global()->nwal_context.pa2sa_heap);
+ netapi_closeHeap(h, netapi_get_global()->nwal_context.sa2pa_heap);
+
+ //loop over registered heaps
+ for(i=0;i<TUNE_NETAPI_MAX_HEAPS;i++)
+ {
+ if (p->createdHeaps[i]) {netapi_closeHeap(h,p->createdHeaps[i]);p->createdHeaps[i]=NULL;}
+ }
+ netapi_cleanup_at_start(); //clear 1st 50 not-specified queues..
+ netapi_VM_memory_teardown();
+ }
+ free(p);
+ return;
+}
+
+//exception crash
+void netapi_err_teardown() { netapi_cleanup_at_start(); exit(-99); }
+
+/*-------------------utilities-------------------*/
+static uint8_t* netapiSharedMemoryMalloc(uint32_t size)
+{
+return (uint8_t *)netapi_VM_memAlloc(size +netapi_global.cfg.def_heap_extra_size , 128);
+}
+
+static void netapiSharedMemoryFree(uint8_t* ptr)
+{
+ /* Do Nothing. */
+ printf(">netapi Unexpected. need to provide a free () for some reason!! \n");
+ return;
+}
+
+// initialization
+static int system_init(NETAPI_HANDLE_T * handle)
+{
+ int32_t result;
+ Pktlib_HeapHandle sharedHeapHandle;
+ Pktlib_HeapHandle controlHeapHandle;
+ Pktlib_HeapCfg heapCfg;
+ int32_t errCode;
+
+ /* initialize all the memory we are going to use
+ - chunk for buffers, descriptors
+ - memory mapped peripherals we use, such as QMSS, PA, etc */
+ result= netapi_VM_memory_setup();
+ if (result) printf(">netapi: system init - memory set up OK\n");
+ else {printf(">netap: system init - memory set up failed\n"); return -1;}
+
+ //get timer running
+ netapi_init_timer();
+
+ /* Initialize Queue Manager Sub System */
+ result = netapi_init_qm (netapi_global.cfg.def_max_descriptors);
+ if (result != 1)
+ {
+ return -1;
+ }
+
+ /* Start the QMSS. */
+ if (netapi_start_qm() != 1)
+ {
+ return -1;
+ }
+
+ //clean our old junk in 1st bunch of queues that will be allocated to us
+ netapi_cleanup_at_start();
+
+ /* Initialize the global descriptor memory region. */
+ result= netapi_qm_setup_mem_region(
+ netapi_global.cfg.def_tot_descriptors_for_us,
+ SIZE_SHARED_DESC,
+ (unsigned int *) netapi_VM_QMemGlobalDescRam,
+ NETAPI_GLOBAL_REGION);
+ if(result <0) {printf(">netapi; can't setup QM shared region\n"); return -1;}
+
+#if 0 //todo setup 2nd region
+/* Initialize the local memory region configuration. */
+ result= netapi_qm_setup_mem_region(
+ NUM_HOST_DESC,
+ SIZE_LOCAL_DESC,
+ netapi_VM_QMemLocalDescRam,
+ NETAPI_LOCAL_REGION);
+ if(result <0) {printf("can't setup local region\n"); return -1;}
+#endif
+ /* Initialize CPPI CPDMA */
+
+ result = netapi_init_cppi ();
+ if (result != 1)
+ {
+ printf (">netapi: Error initializing CPPI SubSystem error code : %d\n",result);
+ return -1;
+ }
+
+ /* CPPI and Queue Manager are initialized. */
+ printf (">netapi: Queue Manager and CPPI are initialized.\n");
+
+ /* create main pkt heap */
+ /* Initialize the Shared Heaps. */
+ Pktlib_sharedHeapInit();
+
+ /* Populate the heap interface table. */
+ netapi_pktlib_ifTable.data_malloc = netapiSharedMemoryMalloc;
+ netapi_pktlib_ifTable.data_free = netapiSharedMemoryFree;
+
+ /* Initialize the heap configuration. */
+ memset ((void *)&heapCfg, 0, sizeof(Pktlib_HeapCfg));
+ /* Populate the heap configuration */
+ heapCfg.name = "netapi";
+ heapCfg.memRegion = NETAPI_GLOBAL_REGION;
+ heapCfg.sharedHeap = 1;
+ heapCfg.useStarvationQueue = 0;
+ heapCfg.dataBufferSize = netapi_global.cfg.def_heap_buf_size;
+ heapCfg.numPkts = netapi_global.cfg.def_heap_n_descriptors;
+ heapCfg.numZeroBufferPackets= netapi_global.cfg.def_heap_n_zdescriptors;
+ heapCfg.heapInterfaceTable.data_malloc = netapi_pktlib_ifTable.data_malloc;
+ heapCfg.heapInterfaceTable.data_free = netapi_pktlib_ifTable.data_free;
+ heapCfg.dataBufferPktThreshold = 0;
+ heapCfg.zeroBufferPktThreshold = 0;
+
+ /* Create Shared Heap with specified configuration. */
+ sharedHeapHandle = Pktlib_createHeap(&heapCfg, &errCode);
+ //todo -> cleanup on failure
+ if (!sharedHeapHandle) { printf(">'netapi' heap create failed, Error Code: %d\n",errCode); return -1;}
+ handle->netcp_heap= sharedHeapHandle;
+
+
+ /* Update for Control */
+ heapCfg.name = "netapi_control";
+ heapCfg.sharedHeap = 1;
+ heapCfg.dataBufferSize = TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE;
+ heapCfg.numPkts = TUNE_NETAPI_CONFIG_NUM_CTL_BUF;
+ heapCfg.numZeroBufferPackets= 0;
+
+ controlHeapHandle = Pktlib_createHeap(&heapCfg, &errCode);;
+ //todo -> cleanup on failure
+ if (!controlHeapHandle) { printf(">netapi -'netapicontrol' heap create failed, Error Code: %d\n",errCode); return -1;}
+ handle->netcp_control_heap= controlHeapHandle;
+
+
+ /* now NWAL */
+ result = netapi_init_nwal(
+ NETAPI_GLOBAL_REGION,
+ &netapi_pktlib_ifTable,
+ &netapi_global.nwal_context,
+ &netapi_global.cfg);
+ if (result<0) {printf(">netapi init_nwal() failed\n"); return -1; }
+
+ /* start NWAL */
+ result = netapi_start_nwal(sharedHeapHandle,
+ controlHeapHandle,
+ &handle->nwal_local,
+ &netapi_global.cfg,
+ &netapi_global.nwal_context);
+ if (result<0) {printf(">netapi start_nwal() failed\n"); return -1; }
+ //** success **
+
+
+ return 0;
+
+}
+
+
+/*---------------
+ * get presets()
+ *---------------*/
+static void get_presets(PRESET_T * p_preset)
+{
+ /* read from kernel or overall config area */
+ /* for now hard code what kernel did */
+}
+
+
+/*************************************************************
+ ******************MISC INTERNAL******************************
+**************************************************************/
+/* poll the garbage queues of all registered heaps */
+void netapi_pollHeapGarbage(NETAPI_T h)
+{
+int i;
+ NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
+ Pktlib_garbageCollection(n->netcp_heap);
+ //no need to do garbage collection on other internal heaps
+ for(i=0;i<TUNE_NETAPI_MAX_HEAPS;i++)
+ {
+ if (n->createdHeaps[i]) Pktlib_garbageCollection(n->createdHeaps[i]);
+ }
+}
+
+/* poll NETCP control queue for responses */
+void netapi_netcpPoll(NETAPI_T p)
+{
+ NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) p;
+ nwal_pollCtl( ((NETAPI_GLOBAL_T *) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
+}
+
+/****************************************************************
+ *****************Cleanup Functions******************************
+*****************************************************************/
+
+//clean up function for linux user space
+void netapi_zapQ(int queueNum)
+{
+char * descPtr;
+int i;
+if (!queueNum) return;
+for (i=0;;i+=1 )
+ {
+ /* Pop descriptor from source queue */
+ if ((descPtr = (char *)Qmss_queuePop (queueNum)) == NULL)
+ {
+ break;
+ }
+ else {/*printf("netapi qzap in play\n");*/}
+ }
+ if(i) printf(">netapi: @recovery - %d descriptors cleaned from qn %d\n",i, queueNum);
+}
+
+//defensive: clean out stuff hanging around
+//
+// open a bunch of free queues and zap them
+#define NQUEUES2CLEAR 15
+static Qmss_QueueHnd tempQH[NQUEUES2CLEAR];
+static void netapi_cleanup_at_start(void)
+{
+int i;
+uint8_t isAllocated;
+
+for(i=0;i<NQUEUES2CLEAR;i++)
+{
+ tempQH[i] = Qmss_queueOpen(Qmss_QueueType_GENERAL_PURPOSE_QUEUE,
+ QMSS_PARAM_NOT_SPECIFIED, &isAllocated);
+ netapi_zapQ(tempQH[i]);
+}
+
+for(i=0;i<NQUEUES2CLEAR;i++)
+{
+ Qmss_queueClose(tempQH[i]);
+}
+
+}
+
+/********************************
+ * clean up a pktlib heap
+ ***********************************/
+int netapi_closeHeap(NETAPI_T h, Pktlib_HeapHandle p)
+{
+Qmss_QueueHnd q;
+Pktlib_garbageCollection(p);
+q = Pktlib_getZeroHeapQueue(p);
+netapi_zapQ(q);
+q= Pktlib_getInternalHeapQueue(p);
+netapi_zapQ(q);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+