fb583e5064754bab584b685c7484135b538826a5
[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     if (master == NETAPI_SYS_MASTER)
101     {
102         pBase = hplib_shmCreate(HPLIB_SHM_SIZE);
104         //pshmBase = (hplib_shmInfo_T*)hplib_shmOpen();
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 0
114         pBase = hplib_shmOpen();
115         if(pBase == NULL)
116         {
117             printf("netapi_init: shared memory handle is NULL\n");
118             return NULL;
119         }
120 #endif
121         if (hplib_shmAddEntry(pBase, sizeof(NETAPI_SHM_T), NETAPI_ENTRY) !=
122             hplib_OK)
123         {
124             printf("netapi_init: hplib_shmAddEntry failed for NETAPI_ENTRY\n");
125             return NULL;
126         }
127         else
128         {
129             printf("netapi_init: hplib_shmAddEntry sucess for NETAPI_ENTRY\n");
130         }
131     }
133     /* create space for our local pktios */
134     for(i=0;i<TUNE_NETAPI_MAX_PKTIO; i++)
135     {
136         p->pktios[i] = calloc(1,sizeof(PKTIO_HANDLE_T));
137         if (!p->pktios[i])
138         {
139             return NULL;
140         }
141     }
143 #ifdef NETAPI_INCLUDE_SCHED
144     /* create space for scheduler */
145     p->p_sched = calloc(1,sizeof(NETAPI_SCHED_HANDLE_T));
146     if (!p->p_sched)
147     {
148         goto ERR_netapi_init;
149     }
150 #endif
152     /* Global init for SYS_MATER */
153     if (master==NETAPI_SYS_MASTER)
154     {
155         pnetapiShm = (NETAPI_SHM_T*)hplib_shmGetEntry(pBase, NETAPI_ENTRY);
156         pnetapiShm = (NETAPI_SHM_T*)hplib_shmGetEntry(pBase, NETAPI_ENTRY);
157         pnetapiShm->netapi_pktio_lock= hplib_spinLock_UNLOCKED_INITIALIZER;
158         pnetapiShm->netapi_netcp_cfg_lock = hplib_spinLock_UNLOCKED_INITIALIZER;
159         pnetapiShm->netapi_util_lock = hplib_spinLock_UNLOCKED_INITIALIZER;
160         if (p_cfg)
161         {
162             memcpy(&netapi_global.cfg,p_cfg, sizeof(NETAPI_CFG_T));
163         }
164         else
165         {
166             memcpy(&netapi_global.cfg,&netapi_default_cfg, sizeof(NETAPI_CFG_T));
167         }
168         for(i=0;i<TUNE_NETAPI_MAX_PKTIO;i++) 
169         {
170             netapi_global.pktios[i].qn.qNum=-1;
171             netapi_global.pktios[i].name[0]='\0';
172         }
173     }
174     //this goes to shared memory eventually
175     p->global = (void *) &netapi_global;
177     //save master's handle back in global; else for slave retrieve p_master
178     if (master==NETAPI_SYS_MASTER)
179     {
180         netapi_global.p_master = p;
181     }
182     else
183     {
184         /* get system master reqquired for core and no master */
185         p_master=(NETAPI_HANDLE_T *)netapi_global.p_master;
186     }
188     /* system init */
189     if(master==NETAPI_SYS_MASTER)
190     {
191         err = netapip_systemInit(p);
192         netapi_netcpCfgExceptions(p, NETCP_CFG_ALL_EXCEPTIONS, NETCP_CFG_ACTION_TO_SW, (NETCP_CFG_ROUTE_HANDLE_T) NULL);
193         if (err<0) 
194         {
195             goto ERR_netapi_init;
196         }
197     /* create pktio channels for tx,rx */
198     }
199     else if (master==NETAPI_NO_MASTER)
200     {
201         /*Just copy master's packetio list for now */
202         p->n_pktios = p_master->n_pktios;
203         memcpy(&p->pktios[0],&p_master->pktios[0],TUNE_NETAPI_MAX_PKTIO*sizeof(PKTIO_HANDLE_T));
204         p->nwal_local=p_master->nwal_local;
205     }
206     /* this is the NETAPI_CORE_MASTER case */
207      else if (master==NETAPI_CORE_MASTER)
208     {
210         /* Start the QMSS. */
211         if (netapip_startQm() != 1)
212         {
213             goto ERR_netapi_init;
214         }
215         netapip_startNwal(p_master->netcp_heap, 
216                                        p_master->netcp_control_rx_heap,
217                                        p_master->netcp_control_tx_heap, 
218                                        &p->nwal_local,
219                                        &netapi_global.cfg,
220                                        &netapi_global.nwal_context);
221     }
222     else
223     {
224         netapi_Log("netapi_init: no master specified\n");
225         goto ERR_netapi_init;
226     }
228     return (NETAPI_T) p;
230 ERR_netapi_init:
231     for(i=0;i<TUNE_NETAPI_MAX_PKTIO; i++)
232     {
233         if (p->pktios[i])
234         {
235             free(p->pktios[i]);
236         }
237     }
238 #ifdef NETAPI_INCLUDE_SCHED
239     if (p->p_sched)
240     {
241         free(p->p_sched);
242     }
243 #endif
244     return NULL;
247 /********************************************************************
248 * FUNCTION PURPOSE:  API de-allocates all global resources allocated as part 
249 *                                   of ref netapi_init
250  ********************************************************************
251  * DESCRIPTION:   API de-allocates all global resources allocated as part 
252 *                                   of ref netapi_init
253  ********************************************************************/
254 void netapi_shutdown(NETAPI_T h)
256     int i;
257     hplib_shmInfo_T* pshmBase;
258     NETAPI_HANDLE_T * p = (NETAPI_HANDLE_T *) h;
259     if (!p) return;
260     void * map_base;
261     hplib_VirtMemPoolheader_T *poolHdr;
263     netapi_Log("netapi: WARNING shutdown may not be fully implemented\n");
264     if (p->master ==NETAPI_SYS_MASTER)
265     {
266         /* close nwal */
267         nwal_delete(netapi_global.nwal_context.nwalInstHandle);
269         /* close heaps */
270         netapi_closeHeap(h, p->netcp_heap);
271         netapi_closeHeap(h, p->netcp_control_rx_heap);
272         netapi_closeHeap(h, p->netcp_control_tx_heap);
273         netapi_closeHeap(h, netapi_get_global()->nwal_context.pa2sa_heap); 
274         netapi_closeHeap(h, netapi_get_global()->nwal_context.sa2pa_heap); 
276         /* Un-configure rules for execption packet handling */
277         netapi_netcpCfgExceptions(p,
278                               NETCP_CFG_ALL_EXCEPTIONS,
279                               NETCP_CFG_ACTION_DISCARD,
280                               (NETCP_CFG_ROUTE_HANDLE_T) NULL);
281         //loop over registered heaps
282         for(i=0;i<TUNE_NETAPI_MAX_HEAPS;i++)
283         {
284             if (p->createdHeaps[i])  {netapi_closeHeap(h,p->createdHeaps[i]);p->createdHeaps[i]=NULL;}
285         }
286         netapip_cleanupAtStart();  //clear 1st 50 not-specified queues
288 #if 0
289         hplib_mod_fd = hplib_utilModOpen();
290         if (hplib_mod_fd == -1)
291         {
292             netapi_Log("netapi_shutdown:: failed to open /dev/netapi: '%s'\n",
293                        strerror(errno));
294             return;
295         }
296 #endif
297         map_base = (void *) hplib_utilGetVaOfBufferArea(HPLIBMOD_MMAP_DMA_MEM_OFFSET, 0);
298         if (map_base)
299         {
300             poolHdr = (hplib_VirtMemPoolheader_T*)map_base;
301             poolHdr->ref_count = 0;
302             poolHdr->virtMemAllocOffset = 0;
303         }
304         hplib_vmTeardown();
305         printf("netapi_shutdown: calling hplib_shmDelete\n");
306         hplib_shmDelete();
307     }
308     free(p);
309     return;
312 /***********************************************************************
313 * FUNCTION PURPOSE:  API is used to poll for NETCP configuration response messages.
314 ************************************************************************
315 * DESCRIPTION:  This API is used to poll the netapi internal heaps and any 
316  *              application-created heaps that have been registered with 
317  *              the netapi instance. The poll function checks the garbage collection 
318  *              queue associated with the heap and returns descriptors and buffers 
319  *              when appropriate to the main free queue.
320 ***********************************************************************/
321 void netapi_pollHeapGarbage(NETAPI_T h)
323     int i;
324     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
325     Pktlib_garbageCollection(n->netcp_heap);
326     //no need to do garbage collection on other internal heaps
327     for(i=0;i<TUNE_NETAPI_MAX_HEAPS;i++)
328     {
329         if (n->createdHeaps[i])
330         {
331             Pktlib_garbageCollection(n->createdHeaps[i]);
332         }
333     }
336 /****************************************************************************
337 * FUNCTION PURPOSE:  API is used to poll for NETCP configuration response messages.
338 ****************************************************************************
339 * DESCRIPTION:  This API is used to poll the netapi internal heaps and any 
340  *              application-created heaps    that have been registered with the 
341  *              netapi instance. The poll function checks the garbage collection 
342  *              queue associated with the heap and returns descriptors and buffers
343  *              when appropriate to the main free queue.
344 ***************************************************************************/
345 void netapi_netcpPoll(NETAPI_T  p)
347     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) p;
348     nwal_pollCtl( ((NETAPI_GLOBAL_T *) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);