1 /****************************************************************************
2 * FILE: netapi_init.c
3 * Global, Private initialization and cleanup routines and defines of NETAPI
4 *
5 * DESCRIPTION: Functions to initialize and cleanup framework resources
6 * for running NETAPI
7 *
8 * REVISION HISTORY:
9 *
10 * Copyright (c) Texas Instruments Incorporated 2013
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 *
19 * Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the
22 * distribution.
23 *
24 * Neither the name of Texas Instruments Incorporated nor the names of
25 * its contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 ***************************************************************************/
42 #include "netapi.h"
43 #include "netapi_loc.h"
44 #include <sys/types.h>
45 #include <sys/stat.h>
46 #include <fcntl.h>
47 #include <sys/mman.h>
48 #include <errno.h>
49 #include <unistd.h>
51 #include "ti/drv/nwal/nwal.h"
53 /* CSL RL includes */
54 #include <ti/csl/cslr_device.h>
55 #include <ti/csl/cslr_qm_config.h>
56 #include <ti/csl/cslr_qm_descriptor_region_config.h>
57 #include <ti/csl/cslr_qm_queue_management.h>
58 #include <ti/csl/cslr_qm_queue_status_config.h>
59 #include <ti/csl/cslr_qm_intd.h>
60 #include <ti/csl/cslr_pdsp.h>
61 #include <ti/csl/csl_qm_queue.h>
62 #include <ti/csl/cslr_cppidma_global_config.h>
63 #include <ti/csl/cslr_cppidma_rx_channel_config.h>
64 #include <ti/csl/cslr_cppidma_rx_flow_config.h>
65 #include <ti/csl/cslr_cppidma_tx_channel_config.h>
66 #include <ti/csl/cslr_cppidma_tx_scheduler_config.h>
67 #include <ti/csl/csl_cppi.h>
68 #include <ti/csl/csl_pscAux.h>
69 #include <ti/csl/csl_semAux.h>
70 #include <ti/csl/csl_cacheAux.h>
71 #include <ti/csl/csl_xmcAux.h>
72 #include <ti/drv/qmss/qmss_qm.h>
75 /* Global variablesto hold virtual address of various subsystems */
76 extern hplib_virtualAddrInfo_T netapi_VM_VirtAddr[];
78 /* Global variables which needs to be populated with memory pool attributes
79 which is passed to HPLIB for memory pool initialization*/
80 extern hplib_memPoolAttr_T netapi_VM_MempoolAttr[];
81 extern unsigned char *netapi_VM_QMemLocalDescRam;
82 extern unsigned char *netapi_VM_QMemGlobalDescRam;
83 extern unsigned char *netapi_VM_SaContextVaddr;
85 extern Pktlib_HeapIfTable netapi_pktlib_ifTable;
86 extern NETAPI_GLOBAL_T netapi_global;
89 /* TODO verify: */
90 #define CACHE_LINESZ 64
93 #define ALIGN(x) __attribute__((aligned (x)))
95 /*****************************************************************************
96 * Global Resources shared by all Cores
97 *****************************************************************************/
98 uint8_t *QMemGlobDescRam = 0;
99 uint8_t *cppiMemPaSaLinkBuf = 0;
100 uint8_t *cppiMemSaPaLinkBuf = 0;
102 /*****************************************************************************
103 * Local Resource allocated at each Core
104 *****************************************************************************/
105 /* Descriptors in global shared */
106 uint8_t *QMemLocDescRam = NULL;
107 uint8_t *cppiMemRxPktLinkBuf = NULL;
108 uint8_t *cppiMemTxPktLinkBuf = NULL;
109 uint8_t *cppiMemRxCtlLinkBuf = NULL;
110 uint8_t *cppiMemTxCtlLinkBuf = NULL;
113 /********************************************************************
114 * FUNCTION PURPOSE: Internal NETAPI function to setup the QM memory region
115 ********************************************************************
116 * DESCRIPTION: Internal NETAPI function to setup the QM memory region,
117 * once per SOC
118 ********************************************************************/
119 int netapip_qmSetupMemRegion(
120 uint32_t numDesc,
121 uint32_t descSize,
122 uint32_t* pDescMemBase,
123 Qmss_MemRegion memRegion)
124 {
125 Qmss_MemRegInfo memInfo;
126 Int32 result;
127 Int n;
128 static int netapi_qm_region_index=0;
130 memset(&memInfo,0,sizeof(Qmss_MemRegInfo));
131 memInfo.descBase = pDescMemBase;
132 memInfo.descSize = descSize;
133 memInfo.descNum = numDesc;
134 memInfo.manageDescFlag = Qmss_ManageDesc_MANAGE_DESCRIPTOR;
135 memInfo.memRegion = memRegion;
137 if(memRegion == TUNE_NETAPI_QM_GLOBAL_REGION)
138 {
139 memInfo.startIndex = TUNE_NETAPI_QM_START_INDEX; //was 0
140 netapi_qm_region_index += numDesc;
141 }else if(memRegion ==NETAPI_LOCAL_REGION)
142 {
143 /* 2nd region for descriptors (perhaps private?) */
144 memInfo.startIndex = netapi_qm_region_index;
145 }
146 else
147 {
148 return -1 ;
149 }
151 memset (pDescMemBase, 0, (descSize * numDesc));
153 result = Qmss_insertMemoryRegion (&memInfo);
154 if (result < QMSS_SOK)
155 {
156 netapi_Log (">function setup_qm_region: Qmss_insertMemoryRegion returned error code %d\n", result);
157 return (-1);
158 }
160 return 1;
162 }
164 /********************************************************************
165 * FUNCTION PURPOSE: Internal NETAPI function to start QM
166 ********************************************************************
167 * DESCRIPTION: Internal NETAPI function to start QM
168 * once per thread/core
169 ********************************************************************/
170 int netapip_startQm(void)
171 {
172 int32_t result;
173 result = Qmss_start();
174 if (result != QMSS_SOK)
175 {
176 netapi_Log (">start_qm: Qmss_start failed with error code %d\n", result);
177 return (-1);
178 }
179 return 1;
180 }
183 /*** NWAL Memory Buffer Configuration ***/
184 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_HANDLE 3400
185 uint8_t nwalInstMem[NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_HANDLE]ALIGN(CACHE_LINESZ);
187 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_MAC 128
188 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_IPSEC_HANDLE_PER_CHAN 256
189 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_IP 128
190 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_PORT 128
191 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_L2L3_HDR 128
192 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_LOC_CONTEXT 384
193 #define NWAL_CHAN_HANDLE_SIZE ((NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_MAC * TUNE_NETAPI_MAX_NUM_MAC) + \
194 (NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_IPSEC_HANDLE_PER_CHAN * TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS*2) + \
195 (NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_IP * TUNE_NETAPI_MAX_NUM_IP) + \
196 (NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_PORT * TUNE_NETAPI_MAX_NUM_PORTS)+ \
197 (NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_LOC_CONTEXT * TUNE_NETAPI_NUM_CORES) + \
198 (NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_L2L3_HDR * TUNE_NETAPI_MAX_NUM_L2_L3_HDRS))
200 uint8_t nwalHandleMem[NWAL_CHAN_HANDLE_SIZE]ALIGN(CACHE_LINESZ);
202 /* todo: Check if below size information can be made available from pa interface file */
203 #define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF0 128
204 /* PA instance */
205 /* Memory used for the PA Instance. Needs to be assigned global uncached memory for chip */
206 uint8_t paBuf0[NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF0]ALIGN(CACHE_LINESZ);
208 /* Memory used for PA handles */
209 #define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1 128 * TUNE_NETAPI_MAX_NUM_MAC
210 uint8_t paBuf1[NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1]ALIGN(CACHE_LINESZ);
212 //#define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2 768
213 //#define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2 6144
214 #define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2 12288
217 uint8_t paBuf2[NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2]ALIGN(CACHE_LINESZ);
219 /* Memory used for SA LLD global Handle */
220 #define NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE 384
221 uint8_t salldHandle[NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE]ALIGN(CACHE_LINESZ);
223 #if 0 //need to alloc this since we need phy addr also
224 /* Memory used for SA contet Handle */
225 #define NETAPI_NWAL_CONFIG_BUFSIZE_SA_CONTEXT_PER_CHAN 384
226 uint8_t saContext[NETAPI_NWAL_CONFIG_BUFSIZE_SA_CONTEXT_PER_CHAN * TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS]ALIGN(CACHE_LINESZ);
227 #endif
229 /* Memory used by SA LLD per Channel */
230 #define NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE_PER_CHAN 512
231 uint8_t salldChanHandle[NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE_PER_CHAN * TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS*2]ALIGN(CACHE_LINESZ);
233 /********************************************************************
234 * FUNCTION PURPOSE: Internal NETAPI function to initialize NWAL subsystem
235 ********************************************************************
236 * DESCRIPTION: Internal NETAPI function to initialize NWAL subsytem
237 ********************************************************************/
238 int netapip_initNwal(
239 int region2use,
240 Pktlib_HeapIfTable * p_table,
241 NETAPI_NWAL_GLOBAL_CONTEXT_T * p_nwal_context,
242 NETAPI_CFG_T*p_cfg )
243 {
244 nwalSizeInfo_t nwalSizeInfo;
245 nwal_RetValue nwalRetVal;
246 nwalGlobCfg_t nwalGlobCfg;
247 uint8_t count;
248 int sizes[nwal_N_BUFS];
249 int aligns[nwal_N_BUFS];
250 void* bases[nwal_N_BUFS];
251 Pktlib_HeapCfg heapCfg;
252 int32_t errCode;
254 memset(p_nwal_context,0,sizeof( NETAPI_NWAL_GLOBAL_CONTEXT_T) );
255 memset(&nwalGlobCfg,0,sizeof(nwalGlobCfg_t ) );
258 /* Initialize Buffer Pool for NetCP PA to SA packets */
259 nwalGlobCfg.pa2SaBufPool.numBufPools = 1;
260 nwalGlobCfg.pa2SaBufPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE;
261 nwalGlobCfg.pa2SaBufPool.bufPool[0].bufSize = p_cfg->def_heap_buf_size;
263 /* Initialize the heap configuration. */
264 memset ((void *)&heapCfg, 0, sizeof(Pktlib_HeapCfg));
265 /* Populate the heap configuration */
266 heapCfg.name = "nwal PA2SA";
267 heapCfg.memRegion = region2use;
268 heapCfg.sharedHeap = 0;
269 heapCfg.useStarvationQueue = 0;
270 heapCfg.dataBufferSize = p_cfg->def_heap_buf_size;
271 heapCfg.numPkts = TUNE_NETAPI_CONFIG_MAX_PA_TO_SA_DESC;
272 heapCfg.numZeroBufferPackets= 0;
273 heapCfg.heapInterfaceTable.data_malloc = p_table->data_malloc;
274 heapCfg.heapInterfaceTable.data_free = p_table->data_free;
275 heapCfg.dataBufferPktThreshold = 0;
276 heapCfg.zeroBufferPktThreshold = 0;
279 nwalGlobCfg.pa2SaBufPool.bufPool[0].heapHandle = p_nwal_context->pa2sa_heap=
280 Pktlib_createHeap(&heapCfg, &errCode);
281 if(nwalGlobCfg.pa2SaBufPool.bufPool[0].heapHandle == NULL)
282 {
283 netapi_Log (">Pktlib_createHeap:Heap Creation Failed for PA to SA Buffer Pool , Error Code: %d\n",errCode);
284 netapi_err_teardown();
285 return -1;
286 }
288 /* Initialize Buffer Pool for NetCP SA to PA packets */
289 nwalGlobCfg.sa2PaBufPool.numBufPools = 1;
290 nwalGlobCfg.sa2PaBufPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE;
291 nwalGlobCfg.sa2PaBufPool.bufPool[0].bufSize = p_cfg->def_heap_buf_size;
293 /* Populate the heap configuration */
294 heapCfg.name = "nwal SA2PA";
295 heapCfg.numPkts = TUNE_NETAPI_CONFIG_MAX_SA_TO_PA_DESC;
297 nwalGlobCfg.sa2PaBufPool.bufPool[0].heapHandle = p_nwal_context->sa2pa_heap=
298 Pktlib_createHeap(&heapCfg, &errCode);
299 if(nwalGlobCfg.sa2PaBufPool.bufPool[0].heapHandle == NULL)
300 {
301 netapi_Log (">Pktlib_createHeap:Heap Creation Failed for SA to PA Buffer Pool , Error Code: %d\n",errCode);
302 netapi_err_teardown();
303 return -1;
304 }
306 nwalGlobCfg.hopLimit = 5;/* Default TTL / Hop Limit */
307 nwalGlobCfg.paPowerOn = nwal_TRUE;
308 nwalGlobCfg.saPowerOn = nwal_TRUE;
309 nwalGlobCfg.paFwActive = nwal_TRUE;
310 nwalGlobCfg.saFwActive = nwal_FALSE;
312 /* Pick Default Physical Address */
313 nwalGlobCfg.paVirtBaseAddr = (uint32_t) netapi_VM_VirtAddr->passCfgVaddr;
314 nwalGlobCfg.saVirtBaseAddr = (uint32_t) netapi_VM_VirtAddr->passCfgVaddr +
315 ((uint32_t)CSL_PA_SS_CFG_CP_ACE_CFG_REGS - (uint32_t)CSL_PA_SS_CFG_REGS) ;
316 nwalGlobCfg.rxDefPktQ = QMSS_PARAM_NOT_SPECIFIED;
318 /* Get the Buffer Requirement from NWAL */
319 memset(&nwalSizeInfo,0,sizeof(nwalSizeInfo));
320 nwalSizeInfo.nMaxMacAddress = TUNE_NETAPI_MAX_NUM_MAC;
321 nwalSizeInfo.nMaxIpAddress = TUNE_NETAPI_MAX_NUM_IP;
322 nwalSizeInfo.nMaxL4Ports = TUNE_NETAPI_MAX_NUM_PORTS;
323 nwalSizeInfo.nMaxIpSecChannels = TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS;//we allocate 2 per channel
324 nwalSizeInfo.nMaxDmSecChannels = TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS;//we allocate 2 per channel
325 nwalSizeInfo.nMaxL2L3Hdr = TUNE_NETAPI_MAX_NUM_L2_L3_HDRS;
326 nwalSizeInfo.nProc = TUNE_NETAPI_NUM_CORES;
327 nwalRetVal = nwal_getBufferReq(&nwalSizeInfo,
328 sizes,
329 aligns);
330 if(nwalRetVal != nwal_OK)
331 {
332 netapi_Log ("netapi: init_nwal - nwal_getBufferReq Failed %d\n", nwalRetVal);
333 return nwal_FALSE;
334 }
336 /* Check for memory size requirement and update the base */
337 count = 0;
338 bases[nwal_BUF_INDEX_INST] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)nwalInstMem);
339 if(NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_HANDLE < sizes[nwal_BUF_INDEX_INST])
340 {
341 /* Resize Memory */
342 while(1);
343 }
344 count++;
346 bases[nwal_BUF_INDEX_INT_HANDLES] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)nwalHandleMem);
347 if(NWAL_CHAN_HANDLE_SIZE < sizes[nwal_BUF_INDEX_INT_HANDLES])
348 {
349 netapi_Log("one\n");
350 /* Resize Memory */
351 while(1);
352 }
353 count++;
354 bases[nwal_BUF_INDEX_PA_LLD_BUF0] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)paBuf0);
355 if((NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF0) < sizes[nwal_BUF_INDEX_PA_LLD_BUF0])
356 {
357 /* Resize Memory */
358 netapi_Log("two\n");
359 while(1);
360 }
361 count++;
363 bases[nwal_BUF_INDEX_PA_LLD_BUF1] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)paBuf1);
364 netapi_Log("NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1 %d, size[nwal_BUF_INDEX_PA_LLD_BUF1] %d\n",
365 NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1, sizes[nwal_BUF_INDEX_PA_LLD_BUF1]);
366 if((NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1) < sizes[nwal_BUF_INDEX_PA_LLD_BUF1])
367 {
368 netapi_Log("NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1 %d, size[nwal_BUF_INDEX_PA_LLD_BUF1] %d\n",
369 NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1, sizes[nwal_BUF_INDEX_PA_LLD_BUF1]);
370 /* Resize Memory */
371 while(1);
372 }
373 count++;
375 bases[nwal_BUF_INDEX_PA_LLD_BUF2] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)paBuf2);
376 if((NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2) < sizes[nwal_BUF_INDEX_PA_LLD_BUF2])
377 {
378 netapi_Log("four\n");
379 /* Resize Memory */
380 while(1);
381 }
382 count++;
383 #ifdef NETAPI_ENABLE_SECURITY
384 bases[nwal_BUF_INDEX_SA_LLD_HANDLE] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)salldHandle);
385 if((NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE) < sizes[nwal_BUF_INDEX_SA_LLD_HANDLE])
386 {
387 netapi_Log("five\n");
388 /* Resize Memory */
389 while(1);
390 }
391 count++;
393 bases[nwal_BUF_INDEX_SA_CONTEXT] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)netapi_VM_SaContextVaddr);
394 count++;
396 bases[nwal_BUF_INDEX_SA_LLD_CHAN_HANDLE] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)salldChanHandle);
397 if((NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE_PER_CHAN * TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS*2) <
398 sizes[nwal_BUF_INDEX_SA_LLD_CHAN_HANDLE])
399 {
400 netapi_Log("netapip_initNwal: sizes[nwal_BUF_INDEX_SA_LLD_CHAN_HANDLE] %d\n", sizes[nwal_BUF_INDEX_SA_LLD_CHAN_HANDLE]);
401 /* Resize Memory */
402 while(1);
403 }
404 count++;
405 #else
406 bases[nwal_BUF_INDEX_SA_LLD_HANDLE] = 0;
407 bases[nwal_BUF_INDEX_SA_CONTEXT] = 0;
408 bases[nwal_BUF_INDEX_SA_LLD_CHAN_HANDLE] = 0;
409 count = count+3;
410 #endif
411 if(count != nwal_N_BUFS)
412 {
413 while(1);
414 }
416 /* Initialize NWAL module */
417 nwalRetVal = nwal_create(&nwalGlobCfg,
418 &nwalSizeInfo,
419 sizes,
420 bases,
421 &p_nwal_context->nwalInstHandle);
422 if(nwalRetVal != nwal_OK)
423 {
424 netapi_Log ("netapi: init_nwal- nwal_create Failed %d\n",nwalRetVal);
425 while(1);
426 }
428 netapi_Log("netapi: init_nwal - Global and Local Network initialization Successful \n");
429 return 1;
430 }
432 /********************************************************************
433 * FUNCTION PURPOSE: Internal NETAPI function to start NWAL
434 ********************************************************************
435 * DESCRIPTION: Internal NETAPI function to start NWAL, per thread/core
436 ********************************************************************/
437 int netapip_startNwal(Pktlib_HeapHandle pkt_heap,
438 Pktlib_HeapHandle cmd_rx_heap,
439 Pktlib_HeapHandle cmd_tx_heap,
440 NETAPI_NWAL_LOCAL_CONTEXT_T *p,
441 NETAPI_CFG_T *p_cfg,
442 NETAPI_NWAL_GLOBAL_CONTEXT_T * p_nwal_glob_context )
443 {
444 nwalLocCfg_t nwalLocCfg;
445 int count=0;
446 static int first_time = 0;
447 nwal_RetValue nwalRetVal;
449 memset(&nwalLocCfg,0,sizeof(nwalLocCfg));
451 /* Update the Start of Packet Offset for the default flows created
452 * by NWAL
453 */
454 nwalLocCfg.rxSopPktOffset = p_cfg->def_flow_pkt_rx_offset;
455 nwalLocCfg.rxPktTailRoomSz = p_cfg->def_heap_tailroom_size;
457 /* Call back registration for the core */
458 nwalLocCfg.pRxPktCallBack = netapip_pktioNWALRxPktCallback;
459 nwalLocCfg.pCmdCallBack = netapip_netcpCfgNWALCmdCallBack;
460 nwalLocCfg.pPaStatsCallBack = netapip_netcpCfgNWALCmdPaStatsReply;
462 nwalLocCfg.pRxDmCallBack= netapip_pktioNWALSBPktCallback; //sideband mode callback
464 /* Initialize Buffer Pool for Control packets from NetCP to Host */
465 nwalLocCfg.rxCtlPool.numBufPools = 1;
466 nwalLocCfg.rxCtlPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE;
467 nwalLocCfg.rxCtlPool.bufPool[0].bufSize = TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE;
468 nwalLocCfg.rxCtlPool.bufPool[0].heapHandle = cmd_rx_heap;
470 /* Initialize Buffer Pool for Control packets from Host to NetCP */
471 nwalLocCfg.txCtlPool.numBufPools = 1;
472 nwalLocCfg.txCtlPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE;
473 nwalLocCfg.txCtlPool.bufPool[0].bufSize = TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE;
474 nwalLocCfg.txCtlPool.bufPool[0].heapHandle = cmd_tx_heap;
476 /* Initialize Buffer Pool for Packets from NetCP to Host */
477 nwalLocCfg.rxPktPool.numBufPools = 1;
478 nwalLocCfg.rxPktPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE;
479 nwalLocCfg.rxPktPool.bufPool[0].bufSize = p_cfg->def_heap_buf_size;
480 nwalLocCfg.rxPktPool.bufPool[0].heapHandle = pkt_heap;
482 /* Initialize Buffer Pool for Packets from Host to NetCP */
483 nwalLocCfg.txPktPool.numBufPools = 1;
484 nwalLocCfg.txPktPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE;
485 nwalLocCfg.txPktPool.bufPool[0].bufSize = p_cfg->def_heap_buf_size;
486 nwalLocCfg.txPktPool.bufPool[0].heapHandle = pkt_heap;
488 memcpy(&p->nwalLocCfg,&nwalLocCfg,sizeof(nwalLocCfg_t));
489 while(1)
490 {
491 nwalRetVal = nwal_start(p_nwal_glob_context->nwalInstHandle,&nwalLocCfg);
492 if(nwalRetVal == nwal_ERR_INVALID_STATE)
493 {
494 continue;
495 }
496 break;
497 }
499 if(nwalRetVal != nwal_OK)
500 {
501 netapi_Log (">nwal_start:Failed ->err %d !!!\n", nwalRetVal);
502 return -1;
503 }
504 p->state = NETAPI_NW_CXT_LOC_ACTIVE;
505 return 1;
508 }
509 /***********************************************************************
510 * FUNCTION PURPOSE: Internal NETAPI function to initialize the 64 bit timer.
511 ***********************************************************************
512 * DESCRIPTION: Internal NETAPI function to initialize the 64 bit timer. for tci6614 ONLY
513 **********************************************************************/
514 int netapip_initTimer(void)
515 {
516 #ifdef CORTEX_A8
517 return t64_start();
518 #endif
519 }
521 /********************************************************************
522 * FUNCTION PURPOSE: NETAPI internal function to gracefully cleanup when startup
523 * issue occurs.
524 ********************************************************************
525 * DESCRIPTION: NETAPI internal function to gracefully cleanup when startup
526 * issue occurs.
527 ********************************************************************/
528 void netapi_err_teardown() { netapip_cleanupAtStart(); exit(-99); }
531 /***************************************************************************
532 * FUNCTION PURPOSE: NETAPI internal function for virtual memory allocation.
533 ***************************************************************************
534 * DESCRIPTION: NETAPI internal function for virtual memory allocation.
535 **************************************************************************/
537 static uint8_t* netapip_sharedMemoryMalloc(uint32_t size)
538 {
539 return (uint8_t *)hplib_vmMemAlloc(size +netapi_global.cfg.def_heap_extra_size , 128, 0);
540 }
542 /********************************************************************
543 * FUNCTION PURPOSE: NETAPI internal function for virtual memory free.
544 ********************************************************************
545 * DESCRIPTION: NETAPI internal function for virtual memory free.
546 ********************************************************************/
547 static void netapip_sharedMemoryFree(uint8_t* ptr, uint32_t size)
548 {
549 /* Do Nothing. */
550 netapi_Log("netapi Unexpected. need to provide a free () for some reason!! \n");
551 return;
552 }
554 //defensive: clean out stuff hanging around
555 //
556 // open a bunch of free queues and zap them
557 #define NQUEUES2CLEAR 35
558 static Qmss_QueueHnd tempQH[NQUEUES2CLEAR];
559 void netapip_cleanupAtStart(void)
560 {
561 int i;
562 uint8_t isAllocated;
564 for(i=0;i<NQUEUES2CLEAR;i++)
565 {
566 tempQH[i] = Qmss_queueOpen(Qmss_QueueType_GENERAL_PURPOSE_QUEUE,
567 QMSS_PARAM_NOT_SPECIFIED, &isAllocated);
568 netapip_zapQ(tempQH[i]);
569 }
571 for(i=0;i<NQUEUES2CLEAR;i++)
572 {
573 Qmss_queueClose(tempQH[i]);
574 }
575 }
578 /********************************************************************
579 * FUNCTION PURPOSE: NETAPI internal function system initialization
580 ********************************************************************
581 * DESCRIPTION: NETAPI internal function system initialization
582 ********************************************************************/
583 int netapip_systemInit(NETAPI_HANDLE_T * handle)
584 {
585 int32_t result;
586 Pktlib_HeapHandle sharedHeapHandle;
587 Pktlib_HeapHandle controlRxHeapHandle,controlTxHeapHandle;
588 Pktlib_HeapCfg heapCfg;
589 int32_t errCode;
590 int count=0;
592 #ifdef NETAPI_USE_DDR
593 /* Init attributes for DDR */
594 netapi_VM_MempoolAttr[0].attr = HPLIB_ATTR_KM_CACHED0;
595 netapi_VM_MempoolAttr[0].phys_addr = 0;
596 netapi_VM_MempoolAttr[0].size = 0;
598 /* Init attributes for un-cached MSMC */
599 netapi_VM_MempoolAttr[1].attr = HPLIB_ATTR_UN_CACHED;
600 netapi_VM_MempoolAttr[1].phys_addr = CSL_MSMC_SRAM_REGS;
601 netapi_VM_MempoolAttr[1].size = TUNE_NETAPI_PERM_MEM_SZ;
602 #else
603 netapi_VM_MempoolAttr[1].attr = HPLIB_ATTR_KM_CACHED0;
604 netapi_VM_MempoolAttr[1].phys_addr = 0;
605 netapi_VM_MempoolAttr[1].size = 0;
607 /* Init attributes for un-cached MSMC */
608 netapi_VM_MempoolAttr[0].attr = HPLIB_ATTR_UN_CACHED;
609 netapi_VM_MempoolAttr[0].phys_addr = CSL_MSMC_SRAM_REGS;
610 netapi_VM_MempoolAttr[0].size = TUNE_NETAPI_PERM_MEM_SZ;
611 #endif
612 /* initialize all the memory we are going to use
613 - chunk for buffers, descriptors
614 - memory mapped peripherals we use, such as QMSS, PA, etc */
615 result = hplib_vmInit(&netapi_VM_VirtAddr[0], 2, &netapi_VM_MempoolAttr[0]);
617 /* TODO: at this point, we need to create the QM regions which need to moved out of the above
618 netapi_VM_memory_setup() call, also need to move out the SA context stuff */
620 if (result == hplib_OK) netapi_Log("netapi: system init - memory set up OK\n");
621 else {netapi_Log(">netap: system init - memory set up failed\n"); return -1;}
624 #ifdef NETAPI_ENABLE_SECURITY
625 #define SEC_CONTEXT_SZ 384 //not tunable
626 /* allocate 2x number of tunnels since we need one for inflow and one for data mode */
627 netapi_VM_SaContextVaddr = hplib_vmMemAlloc((TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS*2 *
628 SEC_CONTEXT_SZ), 128, 0);
629 if (!netapi_VM_SaContextVaddr)
630 {
631 netapi_Log("netapi ERROR: Failed to map SA context memory region\n");
632 return (-1);
633 }
634 netapi_Log(">hplib VM_SaContext: Memory mapped/allocated at address %p.\n", netapi_VM_SaContextVaddr);
636 #else
637 netapi_VM_SaContextVaddr= (char *) NULL;
638 #endif
640 /* TODO: the QM regions is application specific and needs to be moved
641 since number of regions created is appliction specific, put this in netapip_systemInit */
642 /* (3) Allocate 2 QM regions from continguous chunk above */
643 netapi_VM_QMemGlobalDescRam =
644 (void *)hplib_vmMemAlloc((TUNE_NETAPI_NUM_GLOBAL_DESC *
645 TUNE_NETAPI_DESC_SIZE),
646 128, 0);
648 netapi_VM_QMemLocalDescRam =
649 (void *)hplib_vmMemAlloc((TUNE_NETAPI_NUM_LOCAL_DESC *
650 TUNE_NETAPI_DESC_SIZE),
651 128, 0);
652 netapi_Log("netapi local desc region=%x global desc region=%x\n", netapi_VM_QMemLocalDescRam, netapi_VM_QMemGlobalDescRam);
654 //get timer running
655 #ifdef CORTEX_A8
656 netapip_initTimer();
657 #endif
658 netapi_Log("netapip_systemInit: returned from netapip_initTimer\n");
660 /* Initialize Queue Manager Sub System */
661 result = netapip_initQm (netapi_global.cfg.def_max_descriptors);
663 if (result != 1)
664 {
665 netapi_Log("netapip_systemInit: returned from netapip_initQm with failure\n");
666 return -1;
667 }
669 /* Start the QMSS. */
670 if (netapip_startQm() != 1)
671 {
672 netapi_Log("netapip_systemInit: returned from netapip_startQm with failure\n");
673 return -1;
674 }
677 //clean our old junk in 1st bunch of queues that will be allocated to us
678 netapip_cleanupAtStart();
679 netapi_Log("netapip_systemInit: returned from netapip_cleanupAtStart\n");
680 /* Initialize the global descriptor memory region. */
681 result= netapip_qmSetupMemRegion(
682 netapi_global.cfg.def_tot_descriptors_for_us,
683 TUNE_NETAPI_DESC_SIZE,
684 (unsigned int *) netapi_VM_QMemGlobalDescRam,
685 TUNE_NETAPI_QM_GLOBAL_REGION);
686 if(result <0) {netapi_Log("netapi; can't setup QM shared region\n"); return -1;}
688 netapi_Log("netapip_systemInit: returned from netapip_qmSetupMemRegion\n");
689 #if 0 //todo setup 2nd region
690 /* Initialize the local memory region configuration. */
691 result= netapip_qmSetupMemRegion(
692 NUM_HOST_DESC,
693 SIZE_LOCAL_DESC,
694 netapi_VM_QMemLocalDescRam,
695 NETAPI_LOCAL_REGION);
696 if(result <0) {netapi_Log("can't setup local region\n"); return -1;}
697 #endif
698 /* Initialize CPPI CPDMA */
700 result = netapip_initCppi ();
701 netapi_Log("netapip_systemInit: returned from netapip_initCppi\n");
702 if (result != 1)
703 {
704 netapi_Log ("netapi: Error initializing CPPI SubSystem error code : %d\n",result);
705 return -1;
706 }
708 /* CPPI and Queue Manager are initialized. */
709 netapi_Log ("netapi: Queue Manager and CPPI are initialized.\n");
711 /* create main pkt heap */
712 /* Initialize the Shared Heaps. */
713 Pktlib_sharedHeapInit();
714 netapi_Log("netapip_systemInit: returned from Pktlib_sharedHeapInit\n");
715 /* Populate the heap interface table. */
716 netapi_pktlib_ifTable.data_malloc = netapip_sharedMemoryMalloc;
717 netapi_pktlib_ifTable.data_free = netapip_sharedMemoryFree;
719 /* Initialize the heap configuration. */
720 memset ((void *)&heapCfg, 0, sizeof(Pktlib_HeapCfg));
721 /* Populate the heap configuration */
722 heapCfg.name = "netapi";
723 heapCfg.memRegion = TUNE_NETAPI_QM_GLOBAL_REGION;
724 heapCfg.sharedHeap = 1;
725 heapCfg.useStarvationQueue = 0;
726 heapCfg.dataBufferSize = netapi_global.cfg.def_heap_buf_size;
727 heapCfg.numPkts = netapi_global.cfg.def_heap_n_descriptors;
728 heapCfg.numZeroBufferPackets= netapi_global.cfg.def_heap_n_zdescriptors;
729 heapCfg.heapInterfaceTable.data_malloc = netapi_pktlib_ifTable.data_malloc;
730 heapCfg.heapInterfaceTable.data_free = netapi_pktlib_ifTable.data_free;
731 heapCfg.dataBufferPktThreshold = 0;
732 heapCfg.zeroBufferPktThreshold = 0;
734 /* Create Shared Heap with specified configuration. */
735 sharedHeapHandle = Pktlib_createHeap(&heapCfg, &errCode);
736 netapi_Log("netapip_systemInit: returned from Pktlib_createHeap1\n");
737 //todo -> cleanup on failure
738 if (!sharedHeapHandle) { netapi_Log(">'netapi' heap create failed, Error Code: %d\n",errCode); return -1;}
739 handle->netcp_heap= sharedHeapHandle;
742 /* Update for Control */
743 heapCfg.name = "netapi_control_rx";
744 heapCfg.sharedHeap = 1;
745 heapCfg.dataBufferSize = TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE;
746 heapCfg.numPkts = TUNE_NETAPI_CONFIG_NUM_CTL_RX_BUF;
747 heapCfg.numZeroBufferPackets= 0;
749 controlRxHeapHandle = Pktlib_createHeap(&heapCfg, &errCode);
750 netapi_Log("netapip_systemInit: returned from Pktlib_createHeap2\n");
751 //todo -> cleanup on failure
752 if (!controlRxHeapHandle) { netapi_Log("netapi -'netapi_control_rx' heap create failed, Error Code: %d\n",errCode); return -1;}
753 handle->netcp_control_rx_heap= controlRxHeapHandle;
756 heapCfg.name = "netapi_control_tx";
757 heapCfg.numPkts = TUNE_NETAPI_CONFIG_NUM_CTL_TX_BUF;
759 controlTxHeapHandle = Pktlib_createHeap(&heapCfg, &errCode);
760 netapi_Log("netapip_systemInit: returned from Pktlib_createHeap3\n");
761 //todo -> cleanup on failure
762 if (!controlTxHeapHandle) { netapi_Log("netapi -'netapi_control_tx' heap create failed, Error Code: %d\n",errCode); return -1;}
763 handle->netcp_control_tx_heap= controlTxHeapHandle;
765 /* now NWAL */
766 result = netapip_initNwal(
767 TUNE_NETAPI_QM_GLOBAL_REGION,
768 &netapi_pktlib_ifTable,
769 &netapi_global.nwal_context,
770 &netapi_global.cfg);
771 if (result<0) {netapi_Log("netapi init_nwal() failed\n"); return -1; }
772 netapi_Log("netapip_systemInit: returned from netapip_initNwal\n");
773 /* start NWAL */
776 /* Common Initialization for all cores */
777 while(count < TUNE_NETAPI_MAX_NUM_TRANS)
778 {
779 netapi_global.nwal_context.transInfos[count].transId = count;
780 count++;
781 }
782 result = netapip_startNwal(sharedHeapHandle,
783 controlRxHeapHandle,
784 controlTxHeapHandle,
785 &handle->nwal_local,
786 &netapi_global.cfg,
787 &netapi_global.nwal_context);
788 if (result<0) {netapi_Log("netapi start_nwal() failed\n"); return -1; }
789 netapi_Log("netapip_systemInit: returned from netapip_startNwal\n");
790 return 0;
791 }
794 /****************************************************************************
795 * FUNCTION PURPOSE: NETAPI internal function which performs clean for linux user space
796 ****************************************************************************
797 * DESCRIPTION: NETAPI internal function which performs clean for linux user space
798 ***************************************************************************/
799 void netapip_zapQ(int queueNum)
800 {
801 char * descPtr;
802 int i;
803 if (!queueNum)
804 {
805 return;
806 }
807 for (i=0;;i+=1 )
808 {
809 /* Pop descriptor from source queue */
810 if ((descPtr = (char *)pktio_mQmssQueuePopRaw(queueNum)) == NULL)
811 {
812 break;
813 }
814 }
815 if(i)
816 {
817 netapi_Log("netapip_zapQ: @recovery - %d descriptors cleaned from qn %d\n",i, queueNum);
818 }
819 }
822 /****************************************************************************
823 * FUNCTION PURPOSE: NETAPI internal function to display internal heap stats.
824 ****************************************************************************
825 * DESCRIPTION: NETAPI internal function to display internal heap stats.
826 ***************************************************************************/
827 void netapi_dump_internal_heap_stats(void)
828 {
829 Pktlib_HeapStats pktLibHeapStats;
830 Pktlib_getHeapStats(netapi_get_global()->nwal_context.pa2sa_heap,&pktLibHeapStats);
831 netapi_Log("PA2SA(ingress) stats> #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
832 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
833 netapi_Log(" > #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n",
834 pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
835 pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
836 #if 0
837 Pktlib_getHeapStats(netapi_get_global()->nwal_context.pa2saTX_heap,&pktLibHeapStats);
838 netapi_Log("PA2SA(egress) stats> #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
839 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
840 netapi_Log(" > #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n",
841 pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
842 pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
843 #endif
844 Pktlib_getHeapStats(netapi_get_global()->nwal_context.sa2pa_heap,&pktLibHeapStats);
845 netapi_Log("SA2PA stats> #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
846 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
847 netapi_Log(" > #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n",
848 pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
849 pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
851 }