This is the initial commit.
[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 "netapi.h"
45 typedef struct PRESET_Tag
46 {
47 #define KMAXQ 10
48         int kqinuse[KMAXQ];
49         //more..
50 } PRESET_T;
52 /*------------internal prototypes---------------*/
53 static uint8_t* netapiSharedMemoryMalloc(uint32_t size);
54 static void netapiSharedMemoryFree(uint8_t* ptr);
55 static int system_init(NETAPI_HANDLE_T *);
56 static void get_presets(PRESET_T * p_preset);
57 static void zapQ(int queueNum);
58 static void netapi_cleanup_at_start(void);
61 /*------------globals-----------------*/
62 #define NUM_HOST_DESC  (TUNE_NETAPI_NUM_LOCAL_DESC)
63 #define SIZE_LOCAL_DESC  (TUNE_NETAPI_DESC_SIZE) 
64 #define NUM_SHARED_DESC  (TUNE_NETAPI_NUM_GLOBAL_DESC) 
65 #define SIZE_SHARED_DESC (TUNE_NETAPI_DESC_SIZE)
67 #define CONFIG_BUFSIZE_PA_INST      256
68 #define CONFIG_BUFSIZE_L2_TABLE     1000
69 #define CONFIG_BUFSIZE_L3_TABLE     4000
71 static Pktlib_HeapIfTable  netapi_pktlib_ifTable;
72 static NETAPI_GLOBAL_T netapi_global;
73 NETAPI_GLOBAL_T * netapi_get_global(){ return &netapi_global;}
75 /* utility API for NETAPI user to get pktlib if table to use if he creates his own heap */
76 Pktlib_HeapIfTable *netapi_getPktlibIfTable(void) {return &netapi_pktlib_ifTable;}
79 /*-------------------------------------
80  *  initialize NETAPI instance 
81  *-------------------------------------*/
82 NETAPI_T netapi_init(int master)
83 {
84  int i;
85  int err;
86  NETAPI_HANDLE_T * p = (NETAPI_HANDLE_T *) calloc(1,sizeof(NETAPI_HANDLE_T));
87  if (!p) return NULL;
88  p->master = master;
90  /* create space for our local pktios */
91  for(i=0;i<NETAPI_MAX_PKTIO; i++)
92  {
93    p->pktios[i] = calloc(1,sizeof(PKTIO_HANDLE_T));
94   if (!p->pktios[i]) return NULL;
95  }
97 #ifdef NETAPI_INCLUDE_SCHED
98  /* create space for scheduler */
99  p->p_sched = calloc(1,sizeof(NETAPI_SCHED_HANDLE_T));
100 #endif 
103  /* global stuff (if master) */
104  if (master==NETAPI_SYS_MASTER)
105  {
106    for(i=0;i<NETAPI_MAX_PKTIO;i++) 
107    { 
108         netapi_global.pktios[i].qn.qNum=-1;
109         netapi_global.pktios[i].name[0]='\0';
110    }
111  }   
112  //this goes to shared memory eventually
113  p->global = (void *) &netapi_global;
116    /* system init */
117    if(master==NETAPI_SYS_MASTER)
118    {
119       err = system_init(p);
120       if (err<0) 
121       {
122         //todo: cleanup
123         return NULL;
124       }
125       /* create pktio channels for tx,rx */
126    }
127    else
128    {
129        /*todo init for non-system cores/threads */
130        /* qm_start, */
131        /* attach to heaps */
132        /* nwal_start */
133    }
134   
135    return (NETAPI_T) p;
138 /*-------------------------------
139  * Shut down netapi instance
140  *-------------------------------*/
141 void netapi_shutdown(NETAPI_T h)
143         NETAPI_HANDLE_T * p = (NETAPI_HANDLE_T *) h;
144         if (!p) return;
146         printf(">netapi:  shutdown not fully implemented\n");
147         if (p->master)
148         {
149         /* close heap */
150         /* close queues */
151         netapi_cleanup_at_start();
152         /* close pa */
153         } 
154         free(p);
155         return;
158 //exception crash
159 void netapi_err_teardown() { netapi_cleanup_at_start(); exit(-99); }
161 /*-------------------utilities-------------------*/
162 static uint8_t* netapiSharedMemoryMalloc(uint32_t size)
164 return  (uint8_t *)netapi_VM_memAlloc(size, 128); 
167 static void netapiSharedMemoryFree(uint8_t* ptr)
169     /* Do Nothing. */
170     printf("!!netapi>> Unexpected.  need to provide a free () for some reason!! \n");
171     return;
174 // initialization
175 static int system_init(NETAPI_HANDLE_T * handle) 
177     int32_t             result;
178     Pktlib_HeapHandle   sharedHeapHandle;
179     Pktlib_HeapHandle   controlHeapHandle;
181     /* initialize all the memory we are going to use
182        - chunk for buffers, descriptors
183        - memory mapped peripherals we use, such as QMSS, PA, etc */
184     result= netapi_VM_memory_setup();
185     if (result) printf("NETAPI: system init - memory set  up OK\n");
186     else {printf("NETAPI: system init - memory set up failed\n"); return -1;}
188     //get timer running
189     netapi_init_timer();
191     /* Initialize Queue Manager Sub System */
192     result = netapi_init_qm (); 
193     if (result != 1)
194     {
195         return -1;
196     }
198     /* Start the QMSS. */
199     if (netapi_start_qm() != 1)
200     {
201         return -1;
202     }
204     //clean our old junk in 1st bunch of queues that will be allocated to us
205     netapi_cleanup_at_start();
207     /* Initialize the global descriptor memory region. */
208     result= netapi_qm_setup_mem_region( 
209                       NUM_SHARED_DESC,
210                       SIZE_SHARED_DESC,
211                       netapi_VM_QMemGlobalDescRam,
212                       NETAPI_GLOBAL_REGION);
213     if(result <0) {printf("can't setup shared region\n"); return -1;}
215 #if 0 //todo setup 2nd region
216 /* Initialize the local memory region configuration. */
217     result= netapi_qm_setup_mem_region( 
218                       NUM_HOST_DESC,
219                       SIZE_LOCAL_DESC,
220                       netapi_VM_QMemLocalDescRam,
221                       NETAPI_LOCAL_REGION);
222     if(result <0) {printf("can't setup local region\n"); return -1;}
223 #endif
224     /* Initialize CPPI CPDMA */
225     result = netapi_init_cppi ();
226     if (result != 1)
227     {
228         printf ("Error initializing CPPI SubSystem error code : %d\n",result);
229         return -1;
230     }
232     /* CPPI and Queue Manager are initialized. */
233     printf ("Debug: Queue Manager and CPPI are initialized.\n");
235     /* create main pkt heap */
236     /* Initialize the Shared Heaps. */
237     Pktlib_sharedHeapInit();
239     /* Populate the heap interface table. */
240     netapi_pktlib_ifTable.data_malloc             = netapiSharedMemoryMalloc;
241     netapi_pktlib_ifTable.data_free               = netapiSharedMemoryFree;
243     /* Create Shared Heap with specified configuration. */
244 #define SHARED_MAX_DATA_SIZE      (TUNE_NETAPI_DEFAULT_BUFFER_SIZE) 
245    sharedHeapHandle = Pktlib_createHeap("netapi", Qmss_MemRegion_MEMORY_REGION0,
246                                                 1,
247                                                 SHARED_MAX_DATA_SIZE,
248                                                 TUNE_NETAPI_DEFAULT_NUM_BUFFERS,
249                                                 TUNE_NETAPI_DEFAULT_NUM_SOLO_DESCRIPTORS,
250                                                 &netapi_pktlib_ifTable);
251    //todo -> cleanup on failure
252    if (!sharedHeapHandle) { printf("netapi -> 'netapi' heap create failed\n"); return -1;}
253    handle->netcp_heap= sharedHeapHandle;
255   controlHeapHandle = Pktlib_createHeap("netapi_control", Qmss_MemRegion_MEMORY_REGION0,
256                                                1,
257                                                TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE,
258                                                TUNE_NETAPI_CONFIG_NUM_CTL_BUF,
259                                                0,
260                                                &netapi_pktlib_ifTable);
261    //todo -> cleanup on failure
262    if (!controlHeapHandle) { printf("netapi -> 'netapicontrol' heap create failed\n"); return -1;}
263    handle->netcp_control_heap= controlHeapHandle;
266     /* now NWAL */
267     result = netapi_init_nwal(
268                               Qmss_MemRegion_MEMORY_REGION0,
269                               &netapi_pktlib_ifTable, 
270                               &netapi_global.nwal_context);
271     if (result<0) {printf("netapi -> init_nwal() failed\n"); return -1; }
273     /* start NWAL */
274     result = netapi_start_nwal(sharedHeapHandle, 
275                                controlHeapHandle,
276                                &handle->nwal_local,
277                                &netapi_global.nwal_context);
278     if (result<0) {printf("netapi -> start_nwal() failed\n"); return -1; }
279     //** success **
282     return 0;
287 /*---------------
288  * get presets()
289  *---------------*/
290 static void get_presets(PRESET_T * p_preset)
292  /* read from kernel or overall config area */
293  /* for now hard code what kernel did */
297 /*************************************************************
298  ******************MISC INTERNAL******************************
299 **************************************************************/
300 /* poll the garbage queues of all registered heaps */
301 void netapi_pollHeapGarbage(NETAPI_T h)
303         NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
304         Pktlib_garbageCollection(n->netcp_heap);
305         /* todo: register heaps of app */
308 /* todo */
309 int netapi_registerHeap(NETAPI_T p,  Pktlib_HeapHandle h){ return 0;}
310 int netapi_unregisterHeap(NETAPI_T p,  Pktlib_HeapHandle h) { return 0;}
312 /* poll NETCP control queue for responses */
313 void netapi_netcpPoll(NETAPI_T  p)
315         NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) p;
316         nwal_pollCtl( ((NETAPI_GLOBAL_T *) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
319 /****************************************************************
320  *****************Cleanup Functions******************************
321 *****************************************************************/
323 //clean up function for linux user space
324 static void zapQ(int queueNum)
326 char * descPtr;
327 int i;
328 for (i=0;;i+=1 )
329         {
330                 /* Pop descriptor from source queue */
331                 if ((descPtr = (char *)Qmss_queuePop (queueNum)) == NULL)
332                 {
333                         break;
334                 }
335                 else {/*printf("netapi qzap in play\n");*/}
336         }
337         if(i) printf(">netapi qzap in play. %d descriptors cleaned\n",i);
340 //defensive: clean out stuff hanging around
341 //
342 //  open a bunch of free queues and zap them
343 #define NQUEUES2CLEAR 15
344 static Qmss_QueueHnd tempQH[NQUEUES2CLEAR];
345 static void netapi_cleanup_at_start(void)
347 int i;
348 uint8_t         isAllocated;
350 for(i=0;i<NQUEUES2CLEAR;i++) 
352         tempQH[i] = Qmss_queueOpen(Qmss_QueueType_GENERAL_PURPOSE_QUEUE,
353                                                   QMSS_PARAM_NOT_SPECIFIED, &isAllocated);
354         zapQ(tempQH[i]);
357 for(i=0;i<NQUEUES2CLEAR;i++)
359         Qmss_queueClose(tempQH[i]);