]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/netapi.git/blobdiff - ti/runtime/netapi/src/netapi_init.c
Fixed issue with running and gracefully terminating net_test_router application.
[keystone-rtos/netapi.git] / ti / runtime / netapi / src / netapi_init.c
index 4cbcd96823d1145cfa6411cef48786e1fa611f84..ab77fcc0596aa6789d4f704d806ad615b941473d 100755 (executable)
@@ -1,12 +1,13 @@
-/************************************************
+/****************************************************************************
 *  FILE:  netapi_init.c
-*  Global, local initialization of NETAPI
+*  Global, Private initialization and cleanup routines and defines of NETAPI
  *
- * DESCRIPTION: Functions to initialize framework resources for running NETAPI
+ * DESCRIPTION: Functions to initialize and cleanup framework resources 
+ *              for running NETAPI
  *
  * REVISION HISTORY:
  *
- *  Copyright (c) Texas Instruments Incorporated 2010-2011
+ *  Copyright (c) Texas Instruments Incorporated 2013
  * 
  *  Redistribution and use in source and binary forms, with or without 
  *  modification, are permitted provided that the following conditions 
  *  (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 "netapi.h"
+#include "netapi_loc.h"
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -47,9 +48,6 @@
 #include <errno.h>
 #include <unistd.h>
 
-#include <ti/drv/nwal/nwal.h>
-#include "netapi.h"
-#include "netapi_loc.h"
 #include "ti/drv/nwal/nwal.h"
 
 /* CSL RL includes */
 #include <ti/csl/csl_xmcAux.h>
 #include <ti/drv/qmss/qmss_qm.h>
 
+
+/* Global variablesto hold virtual address of various subsystems */
+extern hplib_virtualAddrInfo_T netapi_VM_VirtAddr[];
+
+/* Global variables which needs to be populated with memory pool attributes
+   which is passed to HPLIB for memory pool initialization*/
+extern hplib_memPoolAttr_T netapi_VM_MempoolAttr[];
+extern unsigned char *netapi_VM_QMemLocalDescRam;
+extern unsigned char *netapi_VM_QMemGlobalDescRam;
+extern unsigned char *netapi_VM_SaContextVaddr;
+
+extern Pktlib_HeapIfTable  netapi_pktlib_ifTable;
+extern NETAPI_GLOBAL_T netapi_global;
+
+
 /* TODO verify: */
 #define CACHE_LINESZ    64
 
-#define System_printf   printf
+
 #define ALIGN(x)    __attribute__((aligned (x)))
 
 /*****************************************************************************
@@ -97,72 +110,75 @@ uint8_t *cppiMemRxCtlLinkBuf = NULL;
 uint8_t *cppiMemTxCtlLinkBuf = NULL;
 
 
-//****************************************************
-// Set up  QM memory region (per SOC)
-//***************************************************
-int netapi_qm_setup_mem_region(
+/********************************************************************
+ * FUNCTION PURPOSE:  Internal NETAPI function to setup the QM memory region
+ ********************************************************************
+ * DESCRIPTION:  Internal NETAPI function to setup the QM memory region,
+ *               once per SOC
+ ********************************************************************/
+int netapip_qmSetupMemRegion(
                       uint32_t          numDesc,
                       uint32_t          descSize,
                       uint32_t*         pDescMemBase,
                       Qmss_MemRegion    memRegion)
 {
-  Qmss_MemRegInfo   memInfo;
-  Int32             result;
-  Int               n;
-  static int  netapi_qm_region_index=0;
-
-  memset(&memInfo,0,sizeof(Qmss_MemRegInfo));
-  memInfo.descBase       = pDescMemBase;
-  memInfo.descSize       = descSize;
-  memInfo.descNum        = numDesc;
-  memInfo.manageDescFlag = Qmss_ManageDesc_MANAGE_DESCRIPTOR;
-  memInfo.memRegion      = memRegion;
-
-  if(memRegion == NETAPI_GLOBAL_REGION)
-  {
-      memInfo.startIndex = TUNE_NETAPI_QM_START_INDEX;  //was 0
-      netapi_qm_region_index += numDesc;
-  }else if(memRegion ==NETAPI_LOCAL_REGION)
-  {
-      /* 2nd region for descriptors (perhaps private?) */
-      memInfo.startIndex     = netapi_qm_region_index;
-  }
-  else
-  {
-      return -1 ;
-  }
-
-  memset (pDescMemBase, 0, (descSize * numDesc));
-
-  result = Qmss_insertMemoryRegion (&memInfo);
-  if (result < QMSS_SOK)  
-  {
-    printf (">function setup_qm_region: Qmss_insertMemoryRegion returned error code %d\n", result);
-    return (-1);
-  }
-
-  return 1;
+    Qmss_MemRegInfo   memInfo;
+    Int32             result;
+    Int               n;
+    static int  netapi_qm_region_index=0;
+
+    memset(&memInfo,0,sizeof(Qmss_MemRegInfo));
+    memInfo.descBase       = pDescMemBase;
+    memInfo.descSize       = descSize;
+    memInfo.descNum        = numDesc;
+    memInfo.manageDescFlag = Qmss_ManageDesc_MANAGE_DESCRIPTOR;
+    memInfo.memRegion      = memRegion;
+
+    if(memRegion == TUNE_NETAPI_QM_GLOBAL_REGION)
+    {
+        memInfo.startIndex = TUNE_NETAPI_QM_START_INDEX;  //was 0
+        netapi_qm_region_index += numDesc;
+    }else if(memRegion ==NETAPI_LOCAL_REGION)
+    {
+        /* 2nd region for descriptors (perhaps private?) */
+        memInfo.startIndex     = netapi_qm_region_index;
+    }
+    else
+    {
+        return -1 ;
+    }
+
+    memset (pDescMemBase, 0, (descSize * numDesc));
+
+    result = Qmss_insertMemoryRegion (&memInfo);
+    if (result < QMSS_SOK)  
+    {
+        netapi_Log ("netapip_qmSetupMemRegion: Qmss_insertMemoryRegion returned error code %d\n", result);
+        return (-1);
+    }
 
+    return 1;
 }
 
-//****************************************************
-// Start QM (per thread)
-//***************************************************
-int netapi_start_qm(void)
+/********************************************************************
+ * FUNCTION PURPOSE:  Internal NETAPI function to start QM
+ ********************************************************************
+ * DESCRIPTION:  Internal NETAPI function to start QM
+ *               once per thread/core
+ ********************************************************************/
+int netapip_startQm(void)
 {
      int32_t          result;
      result = Qmss_start();
      if (result != QMSS_SOK)
      {
-         System_printf (">start_qm: Qmss_start failed with error code %d\n", result);
+         netapi_Log ("netapip_startQm: Qmss_start failed with error code %d\n", result);
          return (-1);
      }
      return 1;
 }
 
-//*************************************************
-//initialize NWAL (one per soc) 
-//*************************************************
+
 /*** NWAL Memory Buffer Configuration ***/
 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_HANDLE     3400
 uint8_t nwalInstMem[NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_HANDLE]ALIGN(CACHE_LINESZ);
@@ -189,15 +205,16 @@ uint8_t nwalHandleMem[NWAL_CHAN_HANDLE_SIZE]ALIGN(CACHE_LINESZ);
 uint8_t paBuf0[NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF0]ALIGN(CACHE_LINESZ);
 
 /* Memory used for PA handles */
-#define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1    128
+#define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1    128 * TUNE_NETAPI_MAX_NUM_MAC
 uint8_t paBuf1[NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1]ALIGN(CACHE_LINESZ);
 
-//#define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2   768 
-#define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2   6144
+#define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2   13824
+
+
 uint8_t paBuf2[NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2]ALIGN(CACHE_LINESZ);
 
 /* Memory used for SA LLD global Handle */
-#define NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE    384
+#define NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE    512
 uint8_t salldHandle[NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE]ALIGN(CACHE_LINESZ);
 
 #if 0  //need to alloc this since we need phy addr also 
@@ -211,14 +228,25 @@ uint8_t saContext[NETAPI_NWAL_CONFIG_BUFSIZE_SA_CONTEXT_PER_CHAN * TUNE_NETAPI_M
 uint8_t salldChanHandle[NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE_PER_CHAN * TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS*2]ALIGN(CACHE_LINESZ);
 
 
-/*******************************************
- * Initialize the nwal subsystem for NETAPI use
- ***********************************************/
-int netapi_init_nwal(
-     int region2use,  
-     Pktlib_HeapIfTable * p_table,
-     NETAPI_NWAL_GLOBAL_CONTEXT_T * p_nwal_context, 
-     NETAPI_CFG_T*p_cfg )
+/********************************************************************
+* FUNCTION PURPOSE:  NETAPI internal function to gracefully cleanup when startup
+*                                  issue occurs.
+ ********************************************************************
+ * DESCRIPTION:  NETAPI internal function to gracefully cleanup when startup
+*                                  issue occurs.
+ ********************************************************************/
+void netapipErrTeardown() { netapip_cleanupAtStart(); exit(-99); }
+
+/********************************************************************
+ * FUNCTION PURPOSE:  Internal NETAPI function to initialize NWAL subsystem
+ ********************************************************************
+ * DESCRIPTION:  Internal NETAPI function to initialize NWAL subsytem
+ ********************************************************************/
+int netapip_initNwal(
+    int region2use,
+    Pktlib_HeapIfTable * p_table,
+    NETAPI_NWAL_GLOBAL_CONTEXT_T * p_nwal_context, 
+    NETAPI_CFG_T*p_cfg )
 {
     nwalSizeInfo_t  nwalSizeInfo;
     nwal_RetValue   nwalRetVal;
@@ -259,8 +287,9 @@ int netapi_init_nwal(
                       Pktlib_createHeap(&heapCfg, &errCode);
     if(nwalGlobCfg.pa2SaBufPool.bufPool[0].heapHandle == NULL)
     {
-        printf (">Pktlib_createHeap:Heap Creation Failed for PA to SA Buffer Pool , Error Code: %d\n",errCode); 
-        netapi_err_teardown(); 
+        netapi_Log ("netapip_initNwal: Pktlib_createHeap:Heap Creation Failed for PA to SA Buffer Pool, Error Code: %d\n",
+                    errCode); 
+        netapipErrTeardown();
         return -1;
     }
 
@@ -277,8 +306,9 @@ int netapi_init_nwal(
         Pktlib_createHeap(&heapCfg, &errCode);
     if(nwalGlobCfg.sa2PaBufPool.bufPool[0].heapHandle == NULL)
     {
-        printf (">Pktlib_createHeap:Heap Creation Failed for SA to PA Buffer Pool  , Error Code: %d\n",errCode); 
-        netapi_err_teardown();
+        netapi_Log ("netapip_initNwal: Pktlib_createHeap:Heap Creation Failed for SA to PA Buffer Pool, Error Code: %d\n",
+                     errCode); 
+        netapipErrTeardown();
         return -1;
     }
 
@@ -308,7 +338,7 @@ int netapi_init_nwal(
                                    aligns);
     if(nwalRetVal != nwal_OK)
     {
-        printf (">netapi: init_nwal - nwal_getBufferReq Failed %d\n", nwalRetVal);
+        netapi_Log ("netapip_initNwal: nwal_getBufferReq Failed %d\n", nwalRetVal);
         return nwal_FALSE;
     }
 
@@ -391,18 +421,20 @@ int netapi_init_nwal(
                              &p_nwal_context->nwalInstHandle);
     if(nwalRetVal != nwal_OK)
     {
-        printf (">netapi: init_nwal- nwal_create Failed %d\n",nwalRetVal);
+        netapi_Log ("netapip_initNwal: nwal_create Failed %d\n",nwalRetVal);
         while(1);
     }
 
-    printf(">netapi: init_nwal - Global and Local Network initialization Successful \n");
+    netapi_Log("netapip_initNwal- Global and Local Network initialization Successful \n");
     return 1;
 }
 
-//*************************************************
-//* Local (per thread/core) nwal initialization0
-//**************************************************
-int netapi_start_nwal(Pktlib_HeapHandle pkt_heap,
+/********************************************************************
+ * FUNCTION PURPOSE:  Internal NETAPI function to start  NWAL 
+ ********************************************************************
+ * DESCRIPTION:  Internal NETAPI function to start NWAL, per thread/core
+ ********************************************************************/
+int netapip_startNwal(Pktlib_HeapHandle pkt_heap,
                       Pktlib_HeapHandle cmd_rx_heap,
                       Pktlib_HeapHandle cmd_tx_heap,
                       NETAPI_NWAL_LOCAL_CONTEXT_T *p,
@@ -410,18 +442,12 @@ int netapi_start_nwal(Pktlib_HeapHandle pkt_heap,
                       NETAPI_NWAL_GLOBAL_CONTEXT_T * p_nwal_glob_context  )
 {
     nwalLocCfg_t    nwalLocCfg;
-    int count;
+    int count=0;
+    static int first_time = 0;
     nwal_RetValue       nwalRetVal;
 
     memset(&nwalLocCfg,0,sizeof(nwalLocCfg));
 
-    /* Common Initialization for all cores */
-    while(count < TUNE_NETAPI_MAX_NUM_TRANS)
-    {
-        p_nwal_glob_context->transInfos[count].transId = count;
-        count++;
-    }
-
     /* Update the Start of Packet Offset for the default flows created 
      * by NWAL
      */
@@ -429,10 +455,11 @@ int netapi_start_nwal(Pktlib_HeapHandle pkt_heap,
     nwalLocCfg.rxPktTailRoomSz = p_cfg->def_heap_tailroom_size;
 
  /* Call back registration for the core */
-    nwalLocCfg.pRxPktCallBack = netapi_NWALRxPktCallback;
-    nwalLocCfg.pCmdCallBack = netapi_NWALCmdCallBack;
-    nwalLocCfg.pPaStatsCallBack = netapi_NWALCmdPaStatsReply;
-    nwalLocCfg.pRxDmCallBack=  netapi_NWALSBPktCallback; //sideband mode callback
+    nwalLocCfg.pRxPktCallBack = netapip_pktioNWALRxPktCallback;
+    nwalLocCfg.pCmdCallBack = netapip_netcpCfgNWALCmdCallBack;
+    nwalLocCfg.pPaStatsCallBack = netapip_netcpCfgNWALCmdPaStatsReply;
+
+    nwalLocCfg.pRxDmCallBack=  netapip_pktioNWALSBPktCallback; //sideband mode callback
 
     /* Initialize Buffer Pool for Control packets from NetCP to Host */
     nwalLocCfg.rxCtlPool.numBufPools = 1;
@@ -471,7 +498,7 @@ int netapi_start_nwal(Pktlib_HeapHandle pkt_heap,
 
     if(nwalRetVal != nwal_OK)
     {
-        printf (">nwal_start:Failed ->err %d !!!\n", nwalRetVal);
+        netapi_Log (">nwal_start:Failed ->err %d !!!\n", nwalRetVal);
         return -1;
     }
     p->state = NETAPI_NW_CXT_LOC_ACTIVE;
@@ -479,12 +506,337 @@ int netapi_start_nwal(Pktlib_HeapHandle pkt_heap,
 
 
 }
-//***************************************************
-// intialize timer
-//***************************************************
-int netapi_init_timer(void)
+/***********************************************************************
+ * FUNCTION PURPOSE:  Internal NETAPI function to initialize the 64 bit timer.
+ ***********************************************************************
+ * DESCRIPTION:  Internal NETAPI function to initialize the 64 bit timer. for tci6614 ONLY
+ **********************************************************************/
+int netapip_initTimer(void)
 {
+#ifdef CORTEX_A8
         return t64_start();
+#endif
+}
+
+
+
+
+/***************************************************************************
+* FUNCTION PURPOSE:  NETAPI internal function for virtual memory allocation.
+ ***************************************************************************
+ * DESCRIPTION:  NETAPI internal function for virtual memory allocation.
+ **************************************************************************/
+
+static uint8_t* netapip_sharedMemoryMalloc(uint32_t size)
+{
+return  (uint8_t *)hplib_vmMemAlloc(size +netapi_global.cfg.def_heap_extra_size , 128, 0); 
+}
+
+/********************************************************************
+* FUNCTION PURPOSE:  NETAPI internal function for virtual memory free.
+ ********************************************************************
+ * DESCRIPTION:  NETAPI internal function for virtual memory free.
+ ********************************************************************/
+static void netapip_sharedMemoryFree(uint8_t* ptr, uint32_t size)
+{
+    /* Do Nothing. */
+    netapi_Log("netapi Unexpected.  need to provide a free () for some reason!! \n");
+    return;
+}
+
+//defensive: clean out stuff hanging around
+//
+//  open a bunch of free queues and zap them
+#define NQUEUES2CLEAR 35
+static Qmss_QueueHnd tempQH[NQUEUES2CLEAR];
+void netapip_cleanupAtStart(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);
+        netapip_zapQ(tempQH[i]);
+    }
+
+    for(i=0;i<NQUEUES2CLEAR;i++)
+    {
+        Qmss_queueClose(tempQH[i]);
+    }
+}
+
+
+/********************************************************************
+* FUNCTION PURPOSE:  NETAPI internal function system initialization
+ ********************************************************************
+ * DESCRIPTION:  NETAPI internal function system initialization
+ ********************************************************************/
+int netapip_systemInit(NETAPI_HANDLE_T * handle) 
+{
+    int32_t             result;
+    Pktlib_HeapHandle   sharedHeapHandle;
+    Pktlib_HeapHandle   controlRxHeapHandle,controlTxHeapHandle;    
+    Pktlib_HeapCfg      heapCfg;
+    int32_t             errCode;
+    int count=0;
+
+#ifdef NETAPI_USE_DDR
+    /* Init attributes for DDR */
+    netapi_VM_MempoolAttr[0].attr = HPLIB_ATTR_KM_CACHED0;
+    netapi_VM_MempoolAttr[0].phys_addr = 0;
+    netapi_VM_MempoolAttr[0].size = 0;
+
+       /* Init attributes for un-cached MSMC */
+    netapi_VM_MempoolAttr[1].attr = HPLIB_ATTR_UN_CACHED;
+    netapi_VM_MempoolAttr[1].phys_addr = CSL_MSMC_SRAM_REGS;
+    netapi_VM_MempoolAttr[1].size = TUNE_NETAPI_PERM_MEM_SZ;
+#else
+    netapi_VM_MempoolAttr[1].attr = HPLIB_ATTR_KM_CACHED0;
+    netapi_VM_MempoolAttr[1].phys_addr = 0;
+    netapi_VM_MempoolAttr[1].size = 0;
+
+       /* Init attributes for un-cached MSMC */
+    netapi_VM_MempoolAttr[0].attr = HPLIB_ATTR_UN_CACHED;
+    netapi_VM_MempoolAttr[0].phys_addr = CSL_MSMC_SRAM_REGS;
+    netapi_VM_MempoolAttr[0].size = TUNE_NETAPI_PERM_MEM_SZ;
+#endif
+    /* initialize all the memory we are going to use
+       - chunk for buffers, descriptors
+       - memory mapped peripherals we use, such as QMSS, PA, etc */
+    result = hplib_vmInit(&netapi_VM_VirtAddr[0], 2, &netapi_VM_MempoolAttr[0]);
+
+
+    if (result == hplib_OK) netapi_Log("netapip_systemInit: - memory set  up OK\n");
+    else {netapi_Log("netapip_systemInit: - memory set up failed\n"); return -1;}
+
+
+#ifdef NETAPI_ENABLE_SECURITY
+#define SEC_CONTEXT_SZ 384  //not tunable
+/* allocate 2x number of tunnels since we need one for inflow and one for data mode */
+    netapi_VM_SaContextVaddr = hplib_vmMemAlloc((TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS*2 *
+                                        SEC_CONTEXT_SZ), 128, 0);
+    if (!netapi_VM_SaContextVaddr)
+    {
+        netapi_Log("netapip_systemInit: Failed to map SA context memory region\n");
+        return (-1);
+    }
+    netapi_Log("netapip_systemInit: SA Memory mapped/allocated at address %p.\n", netapi_VM_SaContextVaddr);
+
+#else
+   netapi_VM_SaContextVaddr= (char *) NULL;
+#endif
+
+/*  TODO: the QM regions is application specific and needs to be moved 
+    since number of regions created is appliction specific, put this in netapip_systemInit */
+    /* (3) Allocate 2 QM regions from continguous chunk above */
+    netapi_VM_QMemGlobalDescRam = 
+                                  (void *)hplib_vmMemAlloc((TUNE_NETAPI_NUM_GLOBAL_DESC *
+                                                            TUNE_NETAPI_DESC_SIZE),
+                                                             128, 0);
+
+    netapi_VM_QMemLocalDescRam =
+                                  (void *)hplib_vmMemAlloc((TUNE_NETAPI_NUM_LOCAL_DESC *
+                                                            TUNE_NETAPI_DESC_SIZE),
+                                                            128, 0);
+    netapi_Log("netapip_systemInit: desc region=%x global desc region=%x\n", netapi_VM_QMemLocalDescRam, netapi_VM_QMemGlobalDescRam);
+
+    //get timer running
+#ifdef CORTEX_A8
+    netapip_initTimer();
+    netapi_Log("netapip_systemInit: returned from netapip_initTimer\n");
+#endif
+
+    /* Initialize Queue Manager Sub System */
+    result = netapip_initQm (netapi_global.cfg.def_max_descriptors); 
+    
+    if (result != 1)
+    {
+         netapi_Log("netapip_systemInit: returned from netapip_initQm with failure\n");
+        return -1;
+    }
+
+    /* Start the QMSS. */
+    if (netapip_startQm() != 1)
+    {
+      netapi_Log("netapip_systemInit: returned from netapip_startQm with failure\n");
+        return -1;
+    }
+    
+
+    //clean our old junk in 1st bunch of queues that will be allocated to us
+    netapip_cleanupAtStart();
+ netapi_Log("netapip_systemInit: returned from netapip_cleanupAtStart\n");
+    /* Initialize the global descriptor memory region. */
+    result= netapip_qmSetupMemRegion( 
+                      netapi_global.cfg.def_tot_descriptors_for_us,
+                      TUNE_NETAPI_DESC_SIZE,
+                      (unsigned int *) netapi_VM_QMemGlobalDescRam,
+                      TUNE_NETAPI_QM_GLOBAL_REGION);
+    if(result <0) {netapi_Log("netapip_systemInit: can't setup QM shared region\n"); return -1;}
+
+netapi_Log("netapip_systemInit: returned from netapip_qmSetupMemRegion\n");
+#if 0 //todo setup 2nd region
+/* Initialize the local memory region configuration. */
+    result= netapip_qmSetupMemRegion( 
+                      NUM_HOST_DESC,
+                      SIZE_LOCAL_DESC,
+                      netapi_VM_QMemLocalDescRam,
+                      NETAPI_LOCAL_REGION);
+    if(result <0) {netapi_Log("can't setup local region\n"); return -1;}
+#endif
+    /* Initialize CPPI CPDMA */
+
+    result = netapip_initCppi ();
+    netapi_Log("netapip_systemInit: returned from netapip_initCppi\n");
+    if (result != 1)
+    {
+        netapi_Log ("netapi: Error initializing CPPI SubSystem error code : %d\n",result);
+        return -1;
+    }
+
+    /* CPPI and Queue Manager are initialized. */
+    netapi_Log ("netapi: Queue Manager and CPPI are initialized.\n");
+
+    /* create main pkt heap */
+    /* Initialize the Shared Heaps. */
+    Pktlib_sharedHeapInit();
+    netapi_Log("netapip_systemInit: returned from Pktlib_sharedHeapInit\n");
+    /* Populate the heap interface table. */
+    netapi_pktlib_ifTable.data_malloc             = netapip_sharedMemoryMalloc;
+    netapi_pktlib_ifTable.data_free               = netapip_sharedMemoryFree;
+
+    /* Initialize the heap configuration. */
+    memset ((void *)&heapCfg, 0, sizeof(Pktlib_HeapCfg));
+    /* Populate the heap configuration */
+    heapCfg.name                = "netapi";
+    heapCfg.memRegion           = TUNE_NETAPI_QM_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);
+     netapi_Log("netapip_systemInit: returned from Pktlib_createHeap1\n");
+    //todo -> cleanup on failure
+    if (!sharedHeapHandle) { netapi_Log(">'netapi' heap create failed, Error Code: %d\n",errCode); return -1;}
+    handle->netcp_heap= sharedHeapHandle;
+
+    /* Update for Control */
+    heapCfg.name                = "netapi_control_rx";
+    heapCfg.sharedHeap          = 1;
+    heapCfg.dataBufferSize      = TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE;
+    heapCfg.numPkts             = TUNE_NETAPI_CONFIG_NUM_CTL_RX_BUF;
+    heapCfg.numZeroBufferPackets= 0;
+
+    controlRxHeapHandle = Pktlib_createHeap(&heapCfg, &errCode);
+     netapi_Log("netapip_systemInit: returned from Pktlib_createHeap2\n");
+   //todo -> cleanup on failure
+   if (!controlRxHeapHandle) { netapi_Log("netapi -'netapi_control_rx' heap create failed, Error Code: %d\n",errCode); return -1;}
+   handle->netcp_control_rx_heap= controlRxHeapHandle;
+
+   
+   heapCfg.name                = "netapi_control_tx";
+   heapCfg.numPkts             = TUNE_NETAPI_CONFIG_NUM_CTL_TX_BUF;
+
+   controlTxHeapHandle = Pktlib_createHeap(&heapCfg, &errCode);
+    netapi_Log("netapip_systemInit: returned from Pktlib_createHeap3\n");
+   //todo -> cleanup on failure
+   if (!controlTxHeapHandle) { netapi_Log("netapi -'netapi_control_tx' heap create failed, Error Code: %d\n",errCode); return -1;}
+   handle->netcp_control_tx_heap= controlTxHeapHandle;
+
+    /* now NWAL */
+    result = netapip_initNwal(
+                              TUNE_NETAPI_QM_GLOBAL_REGION,
+                              &netapi_pktlib_ifTable, 
+                              &netapi_global.nwal_context,
+                              &netapi_global.cfg);
+    if (result<0) {netapi_Log("netapi  init_nwal() failed\n"); return -1; }
+ netapi_Log("netapip_systemInit: returned from netapip_initNwal\n");
+    /* start NWAL */
+
+
+    /* Common Initialization for all cores */
+    while(count < TUNE_NETAPI_MAX_NUM_TRANS)
+    {
+        netapi_global.nwal_context.transInfos[count].transId = count;
+        count++;
+    }
+    result = netapip_startNwal(sharedHeapHandle, 
+                               controlRxHeapHandle,
+                               controlTxHeapHandle,
+                               &handle->nwal_local,
+                               &netapi_global.cfg,
+                               &netapi_global.nwal_context);
+    if (result<0) {netapi_Log("netapi start_nwal() failed\n"); return -1; }
+    netapi_Log("netapip_systemInit: returned from netapip_startNwal\n");
+    return 0;
+}
+
+
+/****************************************************************************
+* FUNCTION PURPOSE:  NETAPI internal function which performs clean for linux user space
+ ****************************************************************************
+ * DESCRIPTION:  NETAPI internal function which performs clean for linux user space
+ ***************************************************************************/
+void netapip_zapQ(int queueNum)
+{
+    char * descPtr;
+    int i;
+    if (!queueNum) 
+    {
+        return;
+    }
+    for (i=0;;i+=1 )
+    {
+        /* Pop descriptor from source queue */
+        if ((descPtr = (char *)pktio_mQmssQueuePopRaw(queueNum)) == NULL)
+        {
+            break;
+        }
+    }
+    if(i)
+    {
+        netapi_Log("netapip_zapQ: @recovery -  %d descriptors cleaned from qn %d\n",i, queueNum);
+    }
 }
 
 
+/****************************************************************************
+* FUNCTION PURPOSE:  NETAPI internal function to display internal heap stats.
+ ****************************************************************************
+ * DESCRIPTION:  NETAPI internal function to display internal heap stats.
+ ***************************************************************************/
+void netapi_dump_internal_heap_stats(void)
+{
+    Pktlib_HeapStats    pktLibHeapStats;
+    Pktlib_getHeapStats(netapi_get_global()->nwal_context.pa2sa_heap,&pktLibHeapStats);
+    netapi_Log("PA2SA(ingress) stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
+                                pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
+    netapi_Log("               >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n",
+                        pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
+                        pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
+#if 0
+Pktlib_getHeapStats(netapi_get_global()->nwal_context.pa2saTX_heap,&pktLibHeapStats);
+netapi_Log("PA2SA(egress) stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
+                                pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
+netapi_Log("               >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n",
+                        pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
+                        pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
+#endif
+    Pktlib_getHeapStats(netapi_get_global()->nwal_context.sa2pa_heap,&pktLibHeapStats);
+    netapi_Log("SA2PA stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
+                                pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
+    netapi_Log("               >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n",
+                        pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
+                        pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
+
+}
+