fb583e5064754bab584b685c7484135b538826a5
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;
245 }
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)
255 {
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;
310 }
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)
322 {
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 }
334 }
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)
346 {
347 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) p;
348 nwal_pollCtl( ((NETAPI_GLOBAL_T *) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
349 }