Multi-proc changes
[keystone-rtos/netapi.git] / ti / runtime / netapi / src / netapi.c
1 /***********************************************************************
2  * FILE: netapi.c
3  * Purpose:  Main initialization and shutdown routines of NETAPI 
4  *           user space transport library.
5  ***********************************************************************
6  * FILE: netapi.c
7  * 
8  * DESCRIPTION:  netapi main source file for user space transport
9  *               library
10  * 
11  * REVISION HISTORY:
12  *
13  *  Copyright (c) Texas Instruments Incorporated 2013
14  * 
15  *  Redistribution and use in source and binary forms, with or without 
16  *  modification, are permitted provided that the following conditions 
17  *  are met:
18  *
19  *    Redistributions of source code must retain the above copyright 
20  *    notice, this list of conditions and the following disclaimer.
21  *
22  *    Redistributions in binary form must reproduce the above copyright
23  *    notice, this list of conditions and the following disclaimer in the 
24  *    documentation and/or other materials provided with the   
25  *    distribution.
26  *
27  *    Neither the name of Texas Instruments Incorporated nor the names of
28  *    its contributors may be used to endorse or promote products derived
29  *    from this software without specific prior written permission.
30  *
31  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
32  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
33  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
35  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
36  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
37  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
40  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
41  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43  * *****************************/
45 #include <unistd.h>
46 #include "ti/runtime/netapi/netapi.h"
47 #include "netapi_loc.h"
49 void* pBase;
50 NETAPI_SHM_T* pnetapiShm;
51 static NETAPI_CFG_T netapi_default_cfg=
52 {
53     TUNE_NETAPI_PERM_MEM_SZ,
54     0,  //start of packet offset for hw to place data on rx for default flow
55     TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
56     TUNE_NETAPI_NUM_GLOBAL_DESC,        //total we will use
57     TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap
58     TUNE_NETAPI_DEFAULT_NUM_SOLO_DESCRIPTORS, //#descriptors w/o buffers in default heap
59     TUNE_NETAPI_DEFAULT_BUFFER_SIZE,   //size of buffers in default heap
60     0,0
61 };
63 /* Global variablesto hold virtual address of various subsystems */
64 hplib_virtualAddrInfo_T netapi_VM_VirtAddr[HPLIB_MAX_MEM_POOLS];
66 /* Global variables which needs to be populated with memory pool attributes
67    which is passed to HPLIB for memory pool initialization*/
68 hplib_memPoolAttr_T netapi_VM_MempoolAttr[HPLIB_MAX_MEM_POOLS];
69 unsigned char *netapi_VM_QMemLocalDescRam;
70 unsigned char *netapi_VM_QMemGlobalDescRam;
71 unsigned char *netapi_VM_SaContextVaddr;
73 Pktlib_HeapIfTable  netapi_pktlib_ifTable;
74 NETAPI_GLOBAL_T netapi_global;
75 NETAPI_GLOBAL_T * netapi_get_global(){ return &netapi_global;}
77 /* utility API for NETAPI user to get pktlib if table to use if he creates his own heap */
78 Pktlib_HeapIfTable *netapi_getPktlibIfTable(void) {return &netapi_pktlib_ifTable;}
81 /********************************************************************
82 * FUNCTION PURPOSE:  API instantiates the NETAPI and allocated global resources.
83  ********************************************************************
84  * DESCRIPTION:  API instantiates the NETAPI and allocated global resources.
85  ********************************************************************/
86 NETAPI_T netapi_init(int master, NETAPI_CFG_T * p_cfg)
87 {
88     static int first_time = HPLIB_TRUE;
89     int i;
90     int err;
91     int exception_id = 7;
92     void* pBase = NULL;
94     hplib_shmInfo_T* pshmBase = NULL;
95     NETAPI_HANDLE_T * p = (NETAPI_HANDLE_T *) calloc(1,sizeof(NETAPI_HANDLE_T));
96     NETAPI_HANDLE_T * p_master;
97     if (!p) return NULL;
98     p->master = master;
100     /* The following segment should be done 1 Time per system boot by global master process */
101     if (master == NETAPI_SYS_MASTER)
102     {
103         pBase = hplib_shmCreate(HPLIB_SHM_SIZE);
105         if (pBase == NULL)
106         {
107             printf("netapi_init: hplib_shmCreate failure\n");
108             return NULL;
109         }
110         else
111              printf("netapi_init: hplib_shmCreate sucess\n");
113         if (hplib_shmAddEntry(pBase, sizeof(NETAPI_SHM_T), NETAPI_ENTRY) !=
114             hplib_OK)
115         {
116             netapi_Log("netapi_init: hplib_shmAddEntry failed for NETAPI_ENTRY\n");
117             return NULL;
118         }
119         else
120         {
121             netapi_Log("netapi_init: hplib_shmAddEntry sucess for NETAPI_ENTRY\n");
122         }
123         Osal_create(first_time);
124     }
126     /* create space for our local pktios */
127     for(i=0;i<TUNE_NETAPI_MAX_PKTIO; i++)
128     {
129         p->pktios[i] = calloc(1,sizeof(PKTIO_HANDLE_T));
130         if (!p->pktios[i])
131         {
132             return NULL;
133         }
134     }
136 #ifdef NETAPI_INCLUDE_SCHED
137     /* create space for scheduler */
138     p->p_sched = calloc(1,sizeof(NETAPI_SCHED_HANDLE_T));
139     if (!p->p_sched)
140     {
141         goto ERR_netapi_init;
142     }
143 #endif
145     /* The following segment should be done 1 Time per system boot by global master process */
146     if (master==NETAPI_SYS_MASTER)
147     {
148         pnetapiShm = (NETAPI_SHM_T*)hplib_shmGetEntry(pBase, NETAPI_ENTRY);
149         pnetapiShm = (NETAPI_SHM_T*)hplib_shmGetEntry(pBase, NETAPI_ENTRY);
150         pnetapiShm->netapi_pktio_lock= hplib_spinLock_UNLOCKED_INITIALIZER;
151         pnetapiShm->netapi_netcp_cfg_lock = hplib_spinLock_UNLOCKED_INITIALIZER;
152         pnetapiShm->netapi_util_lock = hplib_spinLock_UNLOCKED_INITIALIZER;
153         if (p_cfg)
154         {
155             memcpy(&netapi_global.cfg,p_cfg, sizeof(NETAPI_CFG_T));
156         }
157         else
158         {
159             memcpy(&netapi_global.cfg,&netapi_default_cfg, sizeof(NETAPI_CFG_T));
160         }
161         for(i=0;i<TUNE_NETAPI_MAX_PKTIO;i++) 
162         {
163             netapi_global.pktios[i].qn.qNum=-1;
164             netapi_global.pktios[i].name[0]='\0';
165         }
166     }
167     //this goes to shared memory eventually
168     p->global = (void *) &netapi_global;
170     /* The following segment should be done 1 Time per system boot by global master process 
171        save master's handle back in global; else for slave retrieve p_master */
172     if (master==NETAPI_SYS_MASTER)
173     {
174         netapi_global.p_master = p;
175     }
176     else
177     {
178         /* get system master reqquired for core and no master */
179         p_master=(NETAPI_HANDLE_T *)netapi_global.p_master;
180     }
182     /* The following segment should be done 1 Time per system boot by global master process */
183     /* system init */
184     if(master==NETAPI_SYS_MASTER)
185     {
186         err = netapip_systemInit(p, TRUE);
187         netapi_netcpCfgExceptions(p, NETCP_CFG_ALL_EXCEPTIONS, NETCP_CFG_ACTION_TO_SW, (NETCP_CFG_ROUTE_HANDLE_T) NULL);
188         if (err<0) 
189         {
190             goto ERR_netapi_init;
191         }
192     /* create pktio channels for tx,rx */
193     }
194     else if (master==NETAPI_NO_MASTER)
195     {
196         /*Just copy master's packetio list for now */
197         p->n_pktios = p_master->n_pktios;
198         memcpy(&p->pktios[0],&p_master->pktios[0],TUNE_NETAPI_MAX_PKTIO*sizeof(PKTIO_HANDLE_T));
199         p->nwal_local=p_master->nwal_local;
200     }
201     /* this is the NETAPI_CORE_MASTER case */
202      else if (master==NETAPI_CORE_MASTER)
203     {
205         /* Start the QMSS. */
206         if (netapip_startQm() != 1)
207         {
208             goto ERR_netapi_init;
209         }
210         netapip_startNwal(p_master->netcp_heap, 
211                                        p_master->netcp_control_rx_heap,
212                                        p_master->netcp_control_tx_heap, 
213                                        &p->nwal_local,
214                                        &netapi_global.cfg,
215                                        &netapi_global.nwal_context);
216     }
217     else
218     {
219         netapi_Log("netapi_init: no master specified\n");
220         goto ERR_netapi_init;
221     }
223     return (NETAPI_T) p;
225 ERR_netapi_init:
226     for(i=0;i<TUNE_NETAPI_MAX_PKTIO; i++)
227     {
228         if (p->pktios[i])
229         {
230             free(p->pktios[i]);
231         }
232     }
233 #ifdef NETAPI_INCLUDE_SCHED
234     if (p->p_sched)
235     {
236         free(p->p_sched);
237     }
238 #endif
239     return NULL;
242 /********************************************************************
243 * FUNCTION PURPOSE:  API de-allocates all global resources allocated as part 
244 *                                   of ref netapi_init
245  ********************************************************************
246  * DESCRIPTION:   API de-allocates all global resources allocated as part 
247 *                                   of ref netapi_init
248  ********************************************************************/
249 void netapi_shutdown(NETAPI_T h)
251     int i;
252     hplib_shmInfo_T* pshmBase;
253     NETAPI_HANDLE_T * p = (NETAPI_HANDLE_T *) h;
254     if (!p) return;
255     void * map_base;
256     hplib_VirtMemPoolheader_T *poolHdr;
258     netapi_Log("netapi: WARNING shutdown may not be fully implemented\n");
259     if (p->master ==NETAPI_SYS_MASTER)
260     {
261         /* close nwal */
262         nwal_delete(netapi_global.nwal_context.nwalInstHandle);
264         /* close heaps */
265         netapi_closeHeap(h, p->netcp_heap);
266         netapi_closeHeap(h, p->netcp_control_rx_heap);
267         netapi_closeHeap(h, p->netcp_control_tx_heap);
268         netapi_closeHeap(h, netapi_get_global()->nwal_context.pa2sa_heap); 
269         netapi_closeHeap(h, netapi_get_global()->nwal_context.sa2pa_heap); 
271         /* Un-configure rules for execption packet handling */
272         netapi_netcpCfgExceptions(p,
273                               NETCP_CFG_ALL_EXCEPTIONS,
274                               NETCP_CFG_ACTION_DISCARD,
275                               (NETCP_CFG_ROUTE_HANDLE_T) NULL);
276         //loop over registered heaps
277         for(i=0;i<TUNE_NETAPI_MAX_HEAPS;i++)
278         {
279             if (p->createdHeaps[i])  {netapi_closeHeap(h,p->createdHeaps[i]);p->createdHeaps[i]=NULL;}
280         }
281         netapip_cleanupAtStart();  //clear 1st 50 not-specified queues
283         map_base = (void *) hplib_utilGetVaOfBufferArea(HPLIBMOD_MMAP_DMA_MEM_OFFSET, 0);
284         if (map_base)
285         {
286             poolHdr = (hplib_VirtMemPoolheader_T*)map_base;
287             poolHdr->ref_count = 0;
288             poolHdr->virtMemAllocOffset = 0;
289         }
290         hplib_vmTeardown();
291         printf("netapi_shutdown: calling hplib_shmDelete\n");
292         hplib_shmDelete();
293     }
294     free(p);
295     return;
298 /***********************************************************************
299 * FUNCTION PURPOSE:  API is used to poll for NETCP configuration response messages.
300 ************************************************************************
301 * DESCRIPTION:  This API is used to poll the netapi internal heaps and any 
302  *              application-created heaps that have been registered with 
303  *              the netapi instance. The poll function checks the garbage collection 
304  *              queue associated with the heap and returns descriptors and buffers 
305  *              when appropriate to the main free queue.
306 ***********************************************************************/
307 void netapi_pollHeapGarbage(NETAPI_T h)
309     int i;
310     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
311     Pktlib_garbageCollection(n->netcp_heap);
312     //no need to do garbage collection on other internal heaps
313     for(i=0;i<TUNE_NETAPI_MAX_HEAPS;i++)
314     {
315         if (n->createdHeaps[i])
316         {
317             Pktlib_garbageCollection(n->createdHeaps[i]);
318         }
319     }
322 /****************************************************************************
323 * FUNCTION PURPOSE:  API is used to poll for NETCP configuration response messages.
324 ****************************************************************************
325 * DESCRIPTION:  This API is used to poll the netapi internal heaps and any 
326  *              application-created heaps    that have been registered with the 
327  *              netapi instance. The poll function checks the garbage collection 
328  *              queue associated with the heap and returns descriptors and buffers
329  *              when appropriate to the main free queue.
330 ***************************************************************************/
331 void netapi_netcpPoll(NETAPI_T  p)
333     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) p;
334     nwal_pollCtl( ((NETAPI_GLOBAL_T *) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);