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 }
135 return (NETAPI_T) p;
136 }
138 /*-------------------------------
139 * Shut down netapi instance
140 *-------------------------------*/
141 void netapi_shutdown(NETAPI_T h)
142 {
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;
156 }
158 //exception crash
159 void netapi_err_teardown() { netapi_cleanup_at_start(); exit(-99); }
161 /*-------------------utilities-------------------*/
162 static uint8_t* netapiSharedMemoryMalloc(uint32_t size)
163 {
164 return (uint8_t *)netapi_VM_memAlloc(size, 128);
165 }
167 static void netapiSharedMemoryFree(uint8_t* ptr)
168 {
169 /* Do Nothing. */
170 printf(">netapi Unexpected. need to provide a free () for some reason!! \n");
171 return;
172 }
174 // initialization
175 static int system_init(NETAPI_HANDLE_T * handle)
176 {
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(">netap: 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(">netapi; can't setup QM 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 (">netapi: Error initializing CPPI SubSystem error code : %d\n",result);
229 return -1;
230 }
232 /* CPPI and Queue Manager are initialized. */
233 printf (">netapi: 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' 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;
284 }
287 /*---------------
288 * get presets()
289 *---------------*/
290 static void get_presets(PRESET_T * p_preset)
291 {
292 /* read from kernel or overall config area */
293 /* for now hard code what kernel did */
294 }
297 /*************************************************************
298 ******************MISC INTERNAL******************************
299 **************************************************************/
300 /* poll the garbage queues of all registered heaps */
301 void netapi_pollHeapGarbage(NETAPI_T h)
302 {
303 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
304 Pktlib_garbageCollection(n->netcp_heap);
305 /* todo: register heaps of app */
306 }
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)
314 {
315 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) p;
316 nwal_pollCtl( ((NETAPI_GLOBAL_T *) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
317 }
319 /****************************************************************
320 *****************Cleanup Functions******************************
321 *****************************************************************/
323 //clean up function for linux user space
324 static void zapQ(int queueNum)
325 {
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: @recovery - %d descriptors cleaned\n",i);
338 }
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)
346 {
347 int i;
348 uint8_t isAllocated;
350 for(i=0;i<NQUEUES2CLEAR;i++)
351 {
352 tempQH[i] = Qmss_queueOpen(Qmss_QueueType_GENERAL_PURPOSE_QUEUE,
353 QMSS_PARAM_NOT_SPECIFIED, &isAllocated);
354 zapQ(tempQH[i]);
355 }
357 for(i=0;i<NQUEUES2CLEAR;i++)
358 {
359 Qmss_queueClose(tempQH[i]);
360 }
362 }