]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/netapi.git/blob - ti/runtime/netapi/src/netapi.c
b9fcc578a4004254e56f46fbf049daa8a531ed8b
[keystone-rtos/netapi.git] / ti / runtime / netapi / src / netapi.c
1 /*******************************
2  * FILE: netapi.c
3  * Purpose:  implementation of netapi startup/shutdown
4  **************************************************************
5  * FILE: netapi.c
6  * 
7  * DESCRIPTION:  netapi main source file for user space transport
8  *               library
9  * 
10  * REVISION HISTORY:  rev 0.0.1 
11  *
12  *  Copyright (c) Texas Instruments Incorporated 2010-2011
13  * 
14  *  Redistribution and use in source and binary forms, with or without 
15  *  modification, are permitted provided that the following conditions 
16  *  are met:
17  *
18  *    Redistributions of source code must retain the above copyright 
19  *    notice, this list of conditions and the following disclaimer.
20  *
21  *    Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in the 
23  *    documentation and/or other materials provided with the   
24  *    distribution.
25  *
26  *    Neither the name of Texas Instruments Incorporated nor the names of
27  *    its contributors may be used to endorse or promote products derived
28  *    from this software without specific prior written permission.
29  *
30  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
31  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
32  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
34  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
35  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
36  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
39  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
40  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42  * *****************************/
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <unistd.h>
46 #include <string.h>
47 #include "netapi.h"
49 typedef struct PRESET_Tag
50 {
51 #define KMAXQ 10
52         int kqinuse[KMAXQ];
53         //more..
54 } PRESET_T;
56 /*------------internal prototypes---------------*/
57 static uint8_t* netapiSharedMemoryMalloc(uint32_t size);
58 static void netapiSharedMemoryFree(uint8_t* ptr, uint32_t size);
59 static int system_init(NETAPI_HANDLE_T *);
60 static void get_presets(PRESET_T * p_preset);
61 static void netapi_cleanup_at_start(void);
64 /*------------globals-----------------*/
65 #define NUM_HOST_DESC  (TUNE_NETAPI_NUM_LOCAL_DESC)
66 #define SIZE_LOCAL_DESC  (TUNE_NETAPI_DESC_SIZE) 
67 #define SIZE_SHARED_DESC (TUNE_NETAPI_DESC_SIZE)
69 #define CONFIG_BUFSIZE_PA_INST      256
70 #define CONFIG_BUFSIZE_L2_TABLE     1000
71 #define CONFIG_BUFSIZE_L3_TABLE     4000
73 static NETAPI_CFG_T netapi_default_cfg=
74 {
75 TUNE_NETAPI_PERM_MEM_SZ,
76 0,  //start of packet offset for hw to place data on rx for default flow
77 TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
78 TUNE_NETAPI_NUM_GLOBAL_DESC,        //total we will use
79 TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap
80 TUNE_NETAPI_DEFAULT_NUM_SOLO_DESCRIPTORS, //#descriptors w/o buffers in default heap
81 TUNE_NETAPI_DEFAULT_BUFFER_SIZE,   //size of buffers in default heap
82 0,0
83 };
85 /* Global variablesto hold virtual address of various subsystems */
86 hplib_virtualAddrInfo_T netapi_VM_VirtAddr[HPLIB_MAX_MEM_POOLS];
87 /* Global variables which needs to be populated with memory pool attributes
88     which is passed to HPLIB for memory pool initialization*/
89 hplib_memPoolAttr_T netapi_VM_MempoolAttr[HPLIB_MAX_MEM_POOLS];
90 unsigned char *netapi_VM_QMemLocalDescRam;
91 unsigned char *netapi_VM_QMemGlobalDescRam;
92 unsigned char *netapi_VM_SaContextVaddr;
94 static Pktlib_HeapIfTable  netapi_pktlib_ifTable;
95 static NETAPI_GLOBAL_T netapi_global;
96 NETAPI_GLOBAL_T * netapi_get_global(){ return &netapi_global;}
98 /* utility API for NETAPI user to get pktlib if table to use if he creates his own heap */
99 Pktlib_HeapIfTable *netapi_getPktlibIfTable(void) {return &netapi_pktlib_ifTable;}
101 //zap a queue
102 void netapi_zapQ(int queueNum);
103 /*-------------------------------------
104  *  initialize NETAPI instance 
105  *-------------------------------------*/
106 NETAPI_T netapi_init(int master, NETAPI_CFG_T * p_cfg)
108  int i;
109  int err;
110  NETAPI_HANDLE_T * p = (NETAPI_HANDLE_T *) calloc(1,sizeof(NETAPI_HANDLE_T));
111  NETAPI_HANDLE_T * p_master;
112  if (!p) return NULL;
113  p->master = master;
115  /* create space for our local pktios */
116  for(i=0;i<NETAPI_MAX_PKTIO; i++)
117  {
118    p->pktios[i] = calloc(1,sizeof(PKTIO_HANDLE_T));
119   if (!p->pktios[i]) return NULL;
120  }
122 #ifdef NETAPI_INCLUDE_SCHED
123  /* create space for scheduler */
124  p->p_sched = calloc(1,sizeof(NETAPI_SCHED_HANDLE_T));
125 #endif 
128  /* global stuff (if master) */
129  if (master==NETAPI_SYS_MASTER)
130  {
131    if (p_cfg) memcpy(&netapi_global.cfg,p_cfg, sizeof(NETAPI_CFG_T));
132    else      memcpy(&netapi_global.cfg,&netapi_default_cfg, sizeof(NETAPI_CFG_T));
133    for(i=0;i<NETAPI_MAX_PKTIO;i++) 
134    { 
135         netapi_global.pktios[i].qn.qNum=-1;
136         netapi_global.pktios[i].name[0]='\0';
137    }
138  }   
139  //this goes to shared memory eventually
140  p->global = (void *) &netapi_global;
142  //dalmt: save master's handle back in global; else for slave retrieve p_master
143  if (master==NETAPI_SYS_MASTER)
144  {
145     netapi_global.p_master = p;
146  }
147  else
148  {
149     p_master=(NETAPI_HANDLE_T *)netapi_global.p_master;
150  }
152    /* system init */
153    if(master==NETAPI_SYS_MASTER)
154    {
155       err = system_init(p);
156       if (err<0) 
157       {
158         //todo: cleanup
159         return NULL;
160       }
161       /* create pktio channels for tx,rx */
162    }
163    else if (master==NETAPI_NO_MASTER)
164    {
165    //dalmt ->simple trial.  Just copy master's packetio list for now
166         p->n_pktios = p_master->n_pktios;
167         memcpy(&p->pktios[0],&p_master->pktios[0],NETAPI_MAX_PKTIO*sizeof(PKTIO_HANDLE_T));
168         p->nwal_local=p_master->nwal_local;
169    }
170    else
171    {
172        /*todo init for non-system cores/threads */
173        /* qm_start, */
174        /* attach to heaps */
175        /* nwal_start */
176    }
177   
178    return (NETAPI_T) p;
181 /*-------------------------------
182  * Shut down netapi instance
183  *-------------------------------*/
184 void netapi_shutdown(NETAPI_T h)
186         int i;
187         NETAPI_HANDLE_T * p = (NETAPI_HANDLE_T *) h;
188         if (!p) return;
190         printf(">netapi: WARNING shutdown may not be fully implemented\n");
191         if (p->master)
192         {
193            /* close nwal */
194            nwal_delete(netapi_global.nwal_context.nwalInstHandle);
196            /* close heaps */
197            netapi_closeHeap(h, p->netcp_heap);
198            netapi_closeHeap(h, p->netcp_control_rx_heap);
199            netapi_closeHeap(h, p->netcp_control_tx_heap);
200            netapi_closeHeap(h, netapi_get_global()->nwal_context.pa2sa_heap); 
201            netapi_closeHeap(h, netapi_get_global()->nwal_context.sa2pa_heap); 
202  
203            //loop over registered heaps
204            for(i=0;i<TUNE_NETAPI_MAX_HEAPS;i++)
205            {
206                 if (p->createdHeaps[i])  {netapi_closeHeap(h,p->createdHeaps[i]);p->createdHeaps[i]=NULL;}
207            }
208            netapi_cleanup_at_start();  //clear 1st 50 not-specified queues..
209            hplib_vmTeardown();
210         } 
211         free(p);
212         return;
215 //exception crash
216 void netapi_err_teardown() { netapi_cleanup_at_start(); exit(-99); }
218 /*-------------------utilities-------------------*/
219 static uint8_t* netapiSharedMemoryMalloc(uint32_t size)
221 return  (uint8_t *)hplib_vmMemAlloc(size +netapi_global.cfg.def_heap_extra_size , 128, 0); 
224 static void netapiSharedMemoryFree(uint8_t* ptr, uint32_t size)
226     /* Do Nothing. */
227     printf(">netapi Unexpected.  need to provide a free () for some reason!! \n");
228     return;
231 // initialization
232 static int system_init(NETAPI_HANDLE_T * handle) 
234     int32_t             result;
235     Pktlib_HeapHandle   sharedHeapHandle;
236     Pktlib_HeapHandle   controlRxHeapHandle,controlTxHeapHandle;    
237     Pktlib_HeapCfg      heapCfg;
238     int32_t             errCode;
239 #ifdef NETAPI_USE_DDR
240     /* Init attributes for DDR */
241     netapi_VM_MempoolAttr[0].attr = HPLIB_ATTR_KM_CACHED0;
242     netapi_VM_MempoolAttr[0].phys_addr = 0;
243     netapi_VM_MempoolAttr[0].size = 0;
245        /* Init attributes for un-cached MSMC */
246     netapi_VM_MempoolAttr[1].attr = HPLIB_ATTR_UN_CACHED;
247     netapi_VM_MempoolAttr[1].phys_addr = CSL_MSMC_SRAM_REGS;
248     netapi_VM_MempoolAttr[1].size = TUNE_NETAPI_PERM_MEM_SZ;
249 #else
250     netapi_VM_MempoolAttr[1].attr = HPLIB_ATTR_KM_CACHED0;
251     netapi_VM_MempoolAttr[1].phys_addr = 0;
252     netapi_VM_MempoolAttr[1].size = 0;
254        /* Init attributes for un-cached MSMC */
255     netapi_VM_MempoolAttr[0].attr = HPLIB_ATTR_UN_CACHED;
256     netapi_VM_MempoolAttr[0].phys_addr = CSL_MSMC_SRAM_REGS;
257     netapi_VM_MempoolAttr[0].size = TUNE_NETAPI_PERM_MEM_SZ;
258 #endif
259     /* initialize all the memory we are going to use
260        - chunk for buffers, descriptors
261        - memory mapped peripherals we use, such as QMSS, PA, etc */
262     result = hplib_vmInit(&netapi_VM_VirtAddr[0], 2, &netapi_VM_MempoolAttr[0]);
263     /* TODO: at this point, we need to create the QM regions which need to moved out of the above 
264     netapi_VM_memory_setup() call, also need to move out the SA context stuff */
265         
266     if (result == hplib_OK) printf(">netapi: system init - memory set  up OK\n");
267     else {printf(">netap: system init - memory set up failed\n"); return -1;}
270 #ifdef NETAPI_ENABLE_SECURITY
271 #define SEC_CONTEXT_SZ 384  //not tunable
272 /* allocate 2x number of tunnels since we need one for inflow and one for data mode */
273     netapi_VM_SaContextVaddr = hplib_vmMemAlloc((TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS*2 *
274                                         SEC_CONTEXT_SZ), 128, 0);
275    if (!netapi_VM_SaContextVaddr)
276     {
277         printf(">netapi ERROR: Failed to map SA context memory region\n");
278         return (-1);
279     }
280     printf(">hplib VM_SaContext: Memory mapped/allocated at address %p.\n", netapi_VM_SaContextVaddr);
281 //    *netapi_VM_SaContextVaddr = 'x';
282 //    printf(" system Init: value being read  %c\n", netapi_VM_SaContextVaddr);
283 //    *netapi_VM_SaContextVaddr = 0;
285 #else
286    netapi_VM_SaContextVaddr= (char *) NULL;
287 #endif
289 /* TODO: the QM regions is application specific and needs to be moved since number of regions created is appliction specific, put this in system_init */
290     /* (3) Allocate 2 QM regions from continguous chunk above */
291     netapi_VM_QMemGlobalDescRam = 
292                                                             (void *)hplib_vmMemAlloc((TUNE_NETAPI_NUM_GLOBAL_DESC *
293                                                                                                         TUNE_NETAPI_DESC_SIZE),
294                                                                                                         128, 0);
296     netapi_VM_QMemLocalDescRam =
297                                                             (void *)hplib_vmMemAlloc((TUNE_NETAPI_NUM_LOCAL_DESC *
298                                                                                                         TUNE_NETAPI_DESC_SIZE),
299                                                                                                         128, 0);
300     printf("netapi local desc region=%x global desc region=%x\n", netapi_VM_QMemLocalDescRam, netapi_VM_QMemGlobalDescRam);
302     //get timer running
303 #ifdef CORTEX_A8
304     netapi_init_timer();
305 #endif
306      printf("system_init: returned from netapi_init_timer\n");
308     /* Initialize Queue Manager Sub System */
309     result = netapi_init_qm (netapi_global.cfg.def_max_descriptors); 
310     
311     if (result != 1)
312     {
313          printf("system_init: returned from netapi_init_qm with failure\n");
314         return -1;
315     }
317     /* Start the QMSS. */
318     if (netapi_start_qm() != 1)
319     {
320       printf("system_init: returned from netapi_start_qm with failure\n");
321         return -1;
322     }
323     
325     //clean our old junk in 1st bunch of queues that will be allocated to us
326     netapi_cleanup_at_start();
327  printf("system_init: returned from netapi_cleanup_at_start\n");
328     /* Initialize the global descriptor memory region. */
329     result= netapi_qm_setup_mem_region( 
330                       netapi_global.cfg.def_tot_descriptors_for_us,
331                       SIZE_SHARED_DESC,
332                       (unsigned int *) netapi_VM_QMemGlobalDescRam,
333                       NETAPI_GLOBAL_REGION);
334     if(result <0) {printf(">netapi; can't setup QM shared region\n"); return -1;}
336 printf(">system_init: returned from netapi_qm_setup_mem_region\n");
337 #if 0 //todo setup 2nd region
338 /* Initialize the local memory region configuration. */
339     result= netapi_qm_setup_mem_region( 
340                       NUM_HOST_DESC,
341                       SIZE_LOCAL_DESC,
342                       netapi_VM_QMemLocalDescRam,
343                       NETAPI_LOCAL_REGION);
344     if(result <0) {printf("can't setup local region\n"); return -1;}
345 #endif
346     /* Initialize CPPI CPDMA */
348     result = netapi_init_cppi ();
349     printf(">system_init: returned from netapi_init_cppi\n");
350     if (result != 1)
351     {
352         printf (">netapi: Error initializing CPPI SubSystem error code : %d\n",result);
353         return -1;
354     }
356     /* CPPI and Queue Manager are initialized. */
357     printf (">netapi: Queue Manager and CPPI are initialized.\n");
359     /* create main pkt heap */
360     /* Initialize the Shared Heaps. */
361     Pktlib_sharedHeapInit();
362     printf(">system_init: returned from Pktlib_sharedHeapInit\n");
363     /* Populate the heap interface table. */
364     netapi_pktlib_ifTable.data_malloc             = netapiSharedMemoryMalloc;
365     netapi_pktlib_ifTable.data_free               = netapiSharedMemoryFree;
367     /* Initialize the heap configuration. */
368     memset ((void *)&heapCfg, 0, sizeof(Pktlib_HeapCfg));
369     /* Populate the heap configuration */
370     heapCfg.name                = "netapi";
371     heapCfg.memRegion           = NETAPI_GLOBAL_REGION;
372     heapCfg.sharedHeap          = 1;
373     heapCfg.useStarvationQueue  = 0;
374     heapCfg.dataBufferSize      = netapi_global.cfg.def_heap_buf_size;
375     heapCfg.numPkts             = netapi_global.cfg.def_heap_n_descriptors;
376     heapCfg.numZeroBufferPackets= netapi_global.cfg.def_heap_n_zdescriptors;
377     heapCfg.heapInterfaceTable.data_malloc  = netapi_pktlib_ifTable.data_malloc;
378     heapCfg.heapInterfaceTable.data_free    = netapi_pktlib_ifTable.data_free;
379     heapCfg.dataBufferPktThreshold   = 0;
380     heapCfg.zeroBufferPktThreshold   = 0;
382     /* Create Shared Heap with specified configuration. */
383     sharedHeapHandle = Pktlib_createHeap(&heapCfg, &errCode);
384      printf(">system_init: returned from Pktlib_createHeap1\n");
385     //todo -> cleanup on failure
386     if (!sharedHeapHandle) { printf(">'netapi' heap create failed, Error Code: %d\n",errCode); return -1;}
387     handle->netcp_heap= sharedHeapHandle;
390     /* Update for Control */
391     heapCfg.name                = "netapi_control_rx";
392     heapCfg.sharedHeap          = 1;
393     heapCfg.dataBufferSize      = TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE;
394     heapCfg.numPkts             = TUNE_NETAPI_CONFIG_NUM_CTL_RX_BUF;
395     heapCfg.numZeroBufferPackets= 0;
397     controlRxHeapHandle = Pktlib_createHeap(&heapCfg, &errCode);
398      printf(">system_init: returned from Pktlib_createHeap2\n");
399    //todo -> cleanup on failure
400    if (!controlRxHeapHandle) { printf(">netapi -'netapi_control_rx' heap create failed, Error Code: %d\n",errCode); return -1;}
401    handle->netcp_control_rx_heap= controlRxHeapHandle;
403    
404    heapCfg.name                = "netapi_control_tx";
405    heapCfg.numPkts             = TUNE_NETAPI_CONFIG_NUM_CTL_TX_BUF;
407    controlTxHeapHandle = Pktlib_createHeap(&heapCfg, &errCode);
408     printf(">system_init: returned from Pktlib_createHeap3\n");
409    //todo -> cleanup on failure
410    if (!controlTxHeapHandle) { printf(">netapi -'netapi_control_tx' heap create failed, Error Code: %d\n",errCode); return -1;}
411    handle->netcp_control_tx_heap= controlTxHeapHandle;
413     /* now NWAL */
414     result = netapi_init_nwal(
415                               NETAPI_GLOBAL_REGION,
416                               &netapi_pktlib_ifTable, 
417                               &netapi_global.nwal_context,
418                               &netapi_global.cfg);
419     if (result<0) {printf(">netapi  init_nwal() failed\n"); return -1; }
420  printf("system_init: returned from netapi_init_nwal\n");
421     /* start NWAL */
422     result = netapi_start_nwal(sharedHeapHandle, 
423                                controlRxHeapHandle,
424                                controlTxHeapHandle,
425                                &handle->nwal_local,
426                                &netapi_global.cfg,
427                                &netapi_global.nwal_context);
428     if (result<0) {printf("netapi start_nwal() failed\n"); return -1; }
429     printf("system_init: returned from netapi_start_nwal\n");
430     //** success **
433     return 0;
438 /*---------------
439  * get presets()
440  *---------------*/
441 static void get_presets(PRESET_T * p_preset)
443  /* read from kernel or overall config area */
444  /* for now hard code what kernel did */
448 /*************************************************************
449  ******************MISC INTERNAL******************************
450 **************************************************************/
451 /* poll the garbage queues of all registered heaps */
452 void netapi_pollHeapGarbage(NETAPI_T h)
454 int i;
455         NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
456         Pktlib_garbageCollection(n->netcp_heap);
457         //no need to do garbage collection on other internal heaps
458         for(i=0;i<TUNE_NETAPI_MAX_HEAPS;i++)
459         {
460                 if (n->createdHeaps[i]) Pktlib_garbageCollection(n->createdHeaps[i]);
461         }
464 /* poll NETCP control queue for responses */
465 void netapi_netcpPoll(NETAPI_T  p)
467         NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) p;
468         nwal_pollCtl( ((NETAPI_GLOBAL_T *) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
471 /****************************************************************
472  *****************Cleanup Functions******************************
473 *****************************************************************/
475 //clean up function for linux user space
476 void netapi_zapQ(int queueNum)
478 char * descPtr;
479 int i;
480 if (!queueNum) return;
481 for (i=0;;i+=1 )
482         {
483                 /* Pop descriptor from source queue */
484                 if ((descPtr = (char *)PKTIO_QMSS_QUEUE_POP_RAW  (queueNum)) == NULL)
485                 {
486                         break;
487                 }
488                 else {/*printf("netapi qzap in play\n");*/}
489         }
490         if(i) printf(">netapi: @recovery -  %d descriptors cleaned from qn %d\n",i, queueNum);
493 //defensive: clean out stuff hanging around
494 //
495 //  open a bunch of free queues and zap them
496 #define NQUEUES2CLEAR 35
497 static Qmss_QueueHnd tempQH[NQUEUES2CLEAR];
498 static void netapi_cleanup_at_start(void)
500 int i;
501 uint8_t         isAllocated;
503 for(i=0;i<NQUEUES2CLEAR;i++) 
505         tempQH[i] = Qmss_queueOpen(Qmss_QueueType_GENERAL_PURPOSE_QUEUE,
506                                                   QMSS_PARAM_NOT_SPECIFIED, &isAllocated);
507         netapi_zapQ(tempQH[i]);
510 for(i=0;i<NQUEUES2CLEAR;i++)
512         Qmss_queueClose(tempQH[i]);
517 /********************************
518  *  clean up a  pktlib heap
519  ***********************************/
520 int netapi_closeHeap(NETAPI_T h, Pktlib_HeapHandle p)
522 Qmss_QueueHnd q;
523 Pktlib_garbageCollection(p);  
524 q = Pktlib_getZeroHeapQueue(p);
525 netapi_zapQ(q);
526 q= Pktlib_getInternalHeapQueue(p);
527 netapi_zapQ(q);
534 netapi_getBufMemRemainder(void)
536     hplib_vmGetMemPoolRemainder(0);
541 void netapi_dump_internal_heap_stats(void)
543 Pktlib_HeapStats    pktLibHeapStats;
544 Pktlib_getHeapStats(netapi_get_global()->nwal_context.pa2sa_heap,&pktLibHeapStats);
545 printf("PA2SA(ingress) stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
546                                 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
547 printf("               >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n",
548                         pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
549                         pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
550 #if 0
551 Pktlib_getHeapStats(netapi_get_global()->nwal_context.pa2saTX_heap,&pktLibHeapStats);
552 printf("PA2SA(egress) stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
553                                 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
554 printf("               >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n",
555                         pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
556                         pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
557 #endif
558 Pktlib_getHeapStats(netapi_get_global()->nwal_context.sa2pa_heap,&pktLibHeapStats);
559 printf("SA2PA stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
560                                 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
561 printf("               >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n",
562                         pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
563                         pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);