]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/netapi.git/blob - ti/runtime/netapi/src/netapi.c
Merge branch 'master' of gtgit01.gt.design.ti.com:git/projects/netapi
[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);
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
83 };
85 static Pktlib_HeapIfTable  netapi_pktlib_ifTable;
86 static NETAPI_GLOBAL_T netapi_global;
87 NETAPI_GLOBAL_T * netapi_get_global(){ return &netapi_global;}
89 /* utility API for NETAPI user to get pktlib if table to use if he creates his own heap */
90 Pktlib_HeapIfTable *netapi_getPktlibIfTable(void) {return &netapi_pktlib_ifTable;}
92 //zap a queue
93 void netapi_zapQ(int queueNum);
94 /*-------------------------------------
95  *  initialize NETAPI instance 
96  *-------------------------------------*/
97 NETAPI_T netapi_init(int master, NETAPI_CFG_T * p_cfg)
98 {
99  int i;
100  int err;
101  NETAPI_HANDLE_T * p = (NETAPI_HANDLE_T *) calloc(1,sizeof(NETAPI_HANDLE_T));
102  if (!p) return NULL;
103  p->master = master;
105  /* create space for our local pktios */
106  for(i=0;i<NETAPI_MAX_PKTIO; i++)
107  {
108    p->pktios[i] = calloc(1,sizeof(PKTIO_HANDLE_T));
109   if (!p->pktios[i]) return NULL;
110  }
112 #ifdef NETAPI_INCLUDE_SCHED
113  /* create space for scheduler */
114  p->p_sched = calloc(1,sizeof(NETAPI_SCHED_HANDLE_T));
115 #endif 
118  /* global stuff (if master) */
119  if (master==NETAPI_SYS_MASTER)
120  {
121    if (p_cfg) memcpy(&netapi_global.cfg,p_cfg, sizeof(NETAPI_CFG_T));
122    else      memcpy(&netapi_global.cfg,&netapi_default_cfg, sizeof(NETAPI_CFG_T));
123    for(i=0;i<NETAPI_MAX_PKTIO;i++) 
124    { 
125         netapi_global.pktios[i].qn.qNum=-1;
126         netapi_global.pktios[i].name[0]='\0';
127    }
128  }   
129  //this goes to shared memory eventually
130  p->global = (void *) &netapi_global;
133    /* system init */
134    if(master==NETAPI_SYS_MASTER)
135    {
136       err = system_init(p);
137       if (err<0) 
138       {
139         //todo: cleanup
140         return NULL;
141       }
142       /* create pktio channels for tx,rx */
143    }
144    else
145    {
146        /*todo init for non-system cores/threads */
147        /* qm_start, */
148        /* attach to heaps */
149        /* nwal_start */
150    }
151   
152    return (NETAPI_T) p;
155 /*-------------------------------
156  * Shut down netapi instance
157  *-------------------------------*/
158 void netapi_shutdown(NETAPI_T h)
160         int i;
161         NETAPI_HANDLE_T * p = (NETAPI_HANDLE_T *) h;
162         if (!p) return;
164         printf(">netapi: WARNING shutdown may not be fully implemented\n");
165         if (p->master)
166         {
167            /* close nwal */
168            nwal_delete(netapi_global.nwal_context.nwalInstHandle);
170            /* close heaps */
171            netapi_closeHeap(h, p->netcp_heap);
172            netapi_closeHeap(h, p->netcp_control_heap);
173            netapi_closeHeap(h, netapi_get_global()->nwal_context.pa2sa_heap); 
174            netapi_closeHeap(h, netapi_get_global()->nwal_context.sa2pa_heap); 
175  
176            //loop over registered heaps
177            for(i=0;i<TUNE_NETAPI_MAX_HEAPS;i++)
178            {
179                 if (p->createdHeaps[i])  {netapi_closeHeap(h,p->createdHeaps[i]);p->createdHeaps[i]=NULL;}
180            }
181            netapi_cleanup_at_start();  //clear 1st 50 not-specified queues..
182            netapi_VM_memory_teardown();
183         } 
184         free(p);
185         return;
188 //exception crash
189 void netapi_err_teardown() { netapi_cleanup_at_start(); exit(-99); }
191 /*-------------------utilities-------------------*/
192 static uint8_t* netapiSharedMemoryMalloc(uint32_t size)
194 return  (uint8_t *)netapi_VM_memAlloc(size, 128); 
197 static void netapiSharedMemoryFree(uint8_t* ptr)
199     /* Do Nothing. */
200     printf(">netapi Unexpected.  need to provide a free () for some reason!! \n");
201     return;
204 // initialization
205 static int system_init(NETAPI_HANDLE_T * handle) 
207     int32_t             result;
208     Pktlib_HeapHandle   sharedHeapHandle;
209     Pktlib_HeapHandle   controlHeapHandle;    
210     Pktlib_HeapCfg      heapCfg;
211     int32_t             errCode;
213     /* initialize all the memory we are going to use
214        - chunk for buffers, descriptors
215        - memory mapped peripherals we use, such as QMSS, PA, etc */
216     result= netapi_VM_memory_setup();
217     if (result) printf(">netapi: system init - memory set  up OK\n");
218     else {printf(">netap: system init - memory set up failed\n"); return -1;}
220     //get timer running
221     netapi_init_timer();
223     /* Initialize Queue Manager Sub System */
224     result = netapi_init_qm (netapi_global.cfg.def_max_descriptors); 
225     if (result != 1)
226     {
227         return -1;
228     }
230     /* Start the QMSS. */
231     if (netapi_start_qm() != 1)
232     {
233         return -1;
234     }
236     //clean our old junk in 1st bunch of queues that will be allocated to us
237     netapi_cleanup_at_start();
239     /* Initialize the global descriptor memory region. */
240     result= netapi_qm_setup_mem_region( 
241                       netapi_global.cfg.def_tot_descriptors_for_us,
242                       SIZE_SHARED_DESC,
243                       (unsigned int *) netapi_VM_QMemGlobalDescRam,
244                       NETAPI_GLOBAL_REGION);
245     if(result <0) {printf(">netapi; can't setup QM shared region\n"); return -1;}
247 #if 0 //todo setup 2nd region
248 /* Initialize the local memory region configuration. */
249     result= netapi_qm_setup_mem_region( 
250                       NUM_HOST_DESC,
251                       SIZE_LOCAL_DESC,
252                       netapi_VM_QMemLocalDescRam,
253                       NETAPI_LOCAL_REGION);
254     if(result <0) {printf("can't setup local region\n"); return -1;}
255 #endif
256     /* Initialize CPPI CPDMA */
258     result = netapi_init_cppi ();
259     if (result != 1)
260     {
261         printf (">netapi: Error initializing CPPI SubSystem error code : %d\n",result);
262         return -1;
263     }
265     /* CPPI and Queue Manager are initialized. */
266     printf (">netapi: Queue Manager and CPPI are initialized.\n");
268     /* create main pkt heap */
269     /* Initialize the Shared Heaps. */
270     Pktlib_sharedHeapInit();
272     /* Populate the heap interface table. */
273     netapi_pktlib_ifTable.data_malloc             = netapiSharedMemoryMalloc;
274     netapi_pktlib_ifTable.data_free               = netapiSharedMemoryFree;
276     /* Initialize the heap configuration. */
277     memset ((void *)&heapCfg, 0, sizeof(Pktlib_HeapCfg));
278     /* Populate the heap configuration */
279     heapCfg.name                = "netapi";
280     heapCfg.memRegion           = NETAPI_GLOBAL_REGION;
281     heapCfg.sharedHeap          = 1;
282     heapCfg.useStarvationQueue  = 0;
283     heapCfg.dataBufferSize      = netapi_global.cfg.def_heap_buf_size;
284     heapCfg.numPkts             = netapi_global.cfg.def_heap_n_descriptors;
285     heapCfg.numZeroBufferPackets= netapi_global.cfg.def_heap_n_zdescriptors;
286     heapCfg.heapInterfaceTable.data_malloc  = netapi_pktlib_ifTable.data_malloc;
287     heapCfg.heapInterfaceTable.data_free    = netapi_pktlib_ifTable.data_free;
288     heapCfg.dataBufferPktThreshold   = 0;
289     heapCfg.zeroBufferPktThreshold   = 0;
291     /* Create Shared Heap with specified configuration. */
292     sharedHeapHandle = Pktlib_createHeap(&heapCfg, &errCode);
293     //todo -> cleanup on failure
294     if (!sharedHeapHandle) { printf(">'netapi' heap create failed, Error Code: %d\n",errCode); return -1;}
295     handle->netcp_heap= sharedHeapHandle;
298     /* Update for Control */
299     heapCfg.name                = "netapi_control";
300     heapCfg.sharedHeap          = 1;
301     heapCfg.dataBufferSize      = TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE;
302     heapCfg.numPkts             = TUNE_NETAPI_CONFIG_NUM_CTL_BUF;
303     heapCfg.numZeroBufferPackets= 0;
305     controlHeapHandle = Pktlib_createHeap(&heapCfg, &errCode);;
306    //todo -> cleanup on failure
307    if (!controlHeapHandle) { printf(">netapi -'netapicontrol' heap create failed, Error Code: %d\n",errCode); return -1;}
308    handle->netcp_control_heap= controlHeapHandle;
311     /* now NWAL */
312     result = netapi_init_nwal(
313                               NETAPI_GLOBAL_REGION,
314                               &netapi_pktlib_ifTable, 
315                               &netapi_global.nwal_context,
316                               &netapi_global.cfg);
317     if (result<0) {printf(">netapi  init_nwal() failed\n"); return -1; }
319     /* start NWAL */
320     result = netapi_start_nwal(sharedHeapHandle, 
321                                controlHeapHandle,
322                                &handle->nwal_local,
323                                &netapi_global.cfg,
324                                &netapi_global.nwal_context);
325     if (result<0) {printf(">netapi start_nwal() failed\n"); return -1; }
326     //** success **
329     return 0;
334 /*---------------
335  * get presets()
336  *---------------*/
337 static void get_presets(PRESET_T * p_preset)
339  /* read from kernel or overall config area */
340  /* for now hard code what kernel did */
344 /*************************************************************
345  ******************MISC INTERNAL******************************
346 **************************************************************/
347 /* poll the garbage queues of all registered heaps */
348 void netapi_pollHeapGarbage(NETAPI_T h)
350 int i;
351         NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
352         Pktlib_garbageCollection(n->netcp_heap);
353         //no need to do garbage collection on other internal heaps
354         for(i=0;i<TUNE_NETAPI_MAX_HEAPS;i++)
355         {
356                 if (n->createdHeaps[i]) Pktlib_garbageCollection(n->createdHeaps[i]);
357         }
360 /* poll NETCP control queue for responses */
361 void netapi_netcpPoll(NETAPI_T  p)
363         NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) p;
364         nwal_pollCtl( ((NETAPI_GLOBAL_T *) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
367 /****************************************************************
368  *****************Cleanup Functions******************************
369 *****************************************************************/
371 //clean up function for linux user space
372 void netapi_zapQ(int queueNum)
374 char * descPtr;
375 int i;
376 if (!queueNum) return;
377 for (i=0;;i+=1 )
378         {
379                 /* Pop descriptor from source queue */
380                 if ((descPtr = (char *)Qmss_queuePop (queueNum)) == NULL)
381                 {
382                         break;
383                 }
384                 else {/*printf("netapi qzap in play\n");*/}
385         }
386         if(i) printf(">netapi: @recovery -  %d descriptors cleaned from qn %d\n",i, queueNum);
389 //defensive: clean out stuff hanging around
390 //
391 //  open a bunch of free queues and zap them
392 #define NQUEUES2CLEAR 15
393 static Qmss_QueueHnd tempQH[NQUEUES2CLEAR];
394 static void netapi_cleanup_at_start(void)
396 int i;
397 uint8_t         isAllocated;
399 for(i=0;i<NQUEUES2CLEAR;i++) 
401         tempQH[i] = Qmss_queueOpen(Qmss_QueueType_GENERAL_PURPOSE_QUEUE,
402                                                   QMSS_PARAM_NOT_SPECIFIED, &isAllocated);
403         netapi_zapQ(tempQH[i]);
406 for(i=0;i<NQUEUES2CLEAR;i++)
408         Qmss_queueClose(tempQH[i]);
413 /********************************
414  *  clean up a  pktlib heap
415  ***********************************/
416 int netapi_closeHeap(NETAPI_T h, Pktlib_HeapHandle p)
418 Qmss_QueueHnd q;
419 Pktlib_garbageCollection(p);  
420 q = Pktlib_getZeroHeapQueue(p);
421 netapi_zapQ(q);
422 q= Pktlib_getInternalHeapQueue(p);
423 netapi_zapQ(q);