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>
74 extern NETAPI_SHM_T* pnetapiShm;
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_PROC_GLOBAL_T netapi_proc_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 ("netapip_qmSetupMemRegion: Qmss_insertMemoryRegion returned error code %d\n", result);
157 return (-1);
158 }
160 return 1;
161 }
163 /********************************************************************
164 * FUNCTION PURPOSE: Internal NETAPI function to start QM
165 ********************************************************************
166 * DESCRIPTION: Internal NETAPI function to start QM
167 * once per thread/core
168 ********************************************************************/
169 int netapip_startQm(void)
170 {
171 int32_t result;
172 result = Qmss_start();
173 if (result != QMSS_SOK)
174 {
175 netapi_Log ("netapip_startQm: Qmss_start failed with error code %d\n", result);
176 return (-1);
177 }
178 return 1;
179 }
182 /*** NWAL Memory Buffer Configuration ***/
183 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_HANDLE 3400
184 uint8_t nwalInstMem[NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_HANDLE]ALIGN(CACHE_LINESZ);
186 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_MAC 256
187 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_IPSEC_HANDLE_PER_CHAN 256
188 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_IP 128
189 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_PORT 128
190 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_L2L3_HDR 128
191 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_LOC_CONTEXT 384
192 #define NWAL_CHAN_HANDLE_SIZE ((NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_MAC * TUNE_NETAPI_MAX_NUM_MAC) + \
193 (NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_IPSEC_HANDLE_PER_CHAN * TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS*2) + \
194 (NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_IP * TUNE_NETAPI_MAX_NUM_IP) + \
195 (NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_PORT * TUNE_NETAPI_MAX_NUM_PORTS)+ \
196 (NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_LOC_CONTEXT * TUNE_NETAPI_NUM_CORES) + \
197 (NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_L2L3_HDR * TUNE_NETAPI_MAX_NUM_L2_L3_HDRS))
199 uint8_t nwalHandleMem[NWAL_CHAN_HANDLE_SIZE]ALIGN(CACHE_LINESZ);
202 typedef struct NETAPI_PA_SHM_Tag
203 {
204 /* todo: Check if below size information can be made available from pa interface file */
205 #define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF0 256
206 /* PA instance */
207 /* Memory used for the PA Instance. Needs to be assigned global uncached memory for chip */
208 uint8_t paBuf0[NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF0]ALIGN(CACHE_LINESZ);
210 /* Memory used for PA handles */
211 #define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1 128 * TUNE_NETAPI_MAX_NUM_MAC
212 uint8_t paBuf1[NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1]ALIGN(CACHE_LINESZ);
214 #define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2 13824
217 uint8_t paBuf2[NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2]ALIGN(CACHE_LINESZ);
218 } NETAPI_PA_SHM_T;
221 typedef struct NETAPI_SA_SHM_Tag
222 {
223 /* Memory used for SA LLD global Handle */
224 #define NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE 512
225 uint8_t salldHandle[NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE]ALIGN(CACHE_LINESZ);
227 /* Memory used by SA LLD per Channel */
228 #define NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE_PER_CHAN 512
229 uint8_t salldChanHandle[NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE_PER_CHAN * TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS*2]ALIGN(CACHE_LINESZ);
230 } NETAPI_SA_SHM_T;
232 /********************************************************************
233 * FUNCTION PURPOSE: NETAPI internal function to gracefully cleanup when startup
234 * issue occurs.
235 ********************************************************************
236 * DESCRIPTION: NETAPI internal function to gracefully cleanup when startup
237 * issue occurs.
238 ********************************************************************/
239 void netapipErrTeardown() { netapip_cleanupAtStart(); exit(-99); }
241 /********************************************************************
242 * FUNCTION PURPOSE: Internal NETAPI function to initialize NWAL subsystem
243 ********************************************************************
244 * DESCRIPTION: Internal NETAPI function to initialize NWAL subsytem
245 ********************************************************************/
246 int netapip_initNwal(
247 int region2use,
248 Pktlib_HeapIfTable * p_table,
249 NETAPI_NWAL_GLOBAL_CONTEXT_T * p_nwal_context,
250 NETAPI_CFG_T*p_cfg,
251 nwalGlobalDeviceConfigParams_t *p_nwal_device_cfg)
252 {
253 nwalSizeInfo_t nwalSizeInfo;
254 nwal_RetValue nwalRetVal;
255 nwalGlobCfg_t nwalGlobCfg;
256 uint8_t count;
257 int sizes[nwal_N_BUFS];
258 int aligns[nwal_N_BUFS];
259 void* bases[nwal_N_BUFS];
260 Pktlib_HeapCfg heapCfg;
261 int32_t errCode;
262 void* pBase = NULL;
263 NETAPI_PA_SHM_T* paEntry = NULL;
264 NETAPI_SA_SHM_T* saEntry = NULL;
266 memset(p_nwal_context,0,sizeof( NETAPI_NWAL_GLOBAL_CONTEXT_T) );
267 memset(&nwalGlobCfg,0,sizeof(nwalGlobCfg_t ) );
269 if(p_nwal_device_cfg)
270 nwalGlobCfg.pDeviceCfg = p_nwal_device_cfg;
272 pBase = hplib_shmOpen();
273 if (pBase)
274 {
275 if(hplib_shmAddEntry(pBase, sizeof(NETAPI_PA_SHM_T), PA_ENTRY) == hplib_OK)
276 {
277 paEntry = (NETAPI_PA_SHM_T*)hplib_shmGetEntry(pBase,PA_ENTRY);
278 nwalGlobCfg.instPoolBaseAddr = (void *)paEntry;
279 }
280 else
281 {
282 netapi_Log("netapip_initNwal: Unable to Add shared memory segment for PASS\n");
283 return -1;
284 }
285 if(hplib_shmAddEntry(pBase, sizeof(NETAPI_SA_SHM_T), SA_ENTRY) == hplib_OK)
286 {
287 saEntry = (NETAPI_SA_SHM_T*)hplib_shmGetEntry(pBase,SA_ENTRY);
288 nwalGlobCfg.instPoolSaBaseAddr = (void*) saEntry;
289 }
290 else
291 {
292 netapi_Log("netapip_initNwal: Unable to Add shared memory segment for SASS\n");
293 return -1;
294 }
296 }
297 /* Initialize Buffer Pool for NetCP PA to SA packets */
298 nwalGlobCfg.pa2SaBufPool.numBufPools = 1;
299 nwalGlobCfg.pa2SaBufPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE;
300 nwalGlobCfg.pa2SaBufPool.bufPool[0].bufSize = p_cfg->def_heap_buf_size;
302 /* Initialize the heap configuration. */
303 memset ((void *)&heapCfg, 0, sizeof(Pktlib_HeapCfg));
304 /* Populate the heap configuration */
305 heapCfg.name = "nwal PA2SA";
306 heapCfg.memRegion = region2use;
307 heapCfg.sharedHeap = 0;
308 heapCfg.useStarvationQueue = 0;
309 heapCfg.dataBufferSize = p_cfg->def_heap_buf_size;
310 heapCfg.numPkts = TUNE_NETAPI_CONFIG_MAX_PA_TO_SA_DESC;
311 heapCfg.numZeroBufferPackets= 0;
312 heapCfg.heapInterfaceTable.data_malloc = p_table->data_malloc;
313 heapCfg.heapInterfaceTable.data_free = p_table->data_free;
314 heapCfg.dataBufferPktThreshold = 0;
315 heapCfg.zeroBufferPktThreshold = 0;
318 nwalGlobCfg.pa2SaBufPool.bufPool[0].heapHandle = p_nwal_context->pa2sa_heap=
319 Pktlib_createHeap(&heapCfg, &errCode);
320 if(nwalGlobCfg.pa2SaBufPool.bufPool[0].heapHandle == NULL)
321 {
322 netapi_Log ("netapip_initNwal: Pktlib_createHeap:Heap Creation Failed for PA to SA Buffer Pool, Error Code: %d\n",
323 errCode);
324 netapipErrTeardown();
325 return -1;
326 }
328 /* Initialize Buffer Pool for NetCP SA to PA packets */
329 nwalGlobCfg.sa2PaBufPool.numBufPools = 1;
330 nwalGlobCfg.sa2PaBufPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE;
331 nwalGlobCfg.sa2PaBufPool.bufPool[0].bufSize = p_cfg->def_heap_buf_size;
333 /* Populate the heap configuration */
334 heapCfg.name = "nwal SA2PA";
335 heapCfg.numPkts = TUNE_NETAPI_CONFIG_MAX_SA_TO_PA_DESC;
337 nwalGlobCfg.sa2PaBufPool.bufPool[0].heapHandle = p_nwal_context->sa2pa_heap=
338 Pktlib_createHeap(&heapCfg, &errCode);
339 if(nwalGlobCfg.sa2PaBufPool.bufPool[0].heapHandle == NULL)
340 {
341 netapi_Log ("netapip_initNwal: Pktlib_createHeap:Heap Creation Failed for SA to PA Buffer Pool, Error Code: %d\n",
342 errCode);
343 netapipErrTeardown();
344 return -1;
345 }
347 nwalGlobCfg.hopLimit = 5;/* Default TTL / Hop Limit */
348 nwalGlobCfg.paPowerOn = nwal_TRUE;
349 nwalGlobCfg.saPowerOn = nwal_TRUE;
350 nwalGlobCfg.paFwActive = nwal_TRUE;
351 nwalGlobCfg.saFwActive = nwal_FALSE;
353 /* Pick Default Physical Address */
354 nwalGlobCfg.paVirtBaseAddr = (uint32_t) netapi_VM_VirtAddr->passCfgVaddr;
355 nwalGlobCfg.saVirtBaseAddr = (uint32_t) netapi_VM_VirtAddr->passCfgVaddr +
356 ((uint32_t)CSL_PA_SS_CFG_CP_ACE_CFG_REGS - (uint32_t)CSL_PA_SS_CFG_REGS) ;
357 nwalGlobCfg.rxDefPktQ = QMSS_PARAM_NOT_SPECIFIED;
359 /* Get the Buffer Requirement from NWAL */
360 memset(&nwalSizeInfo,0,sizeof(nwalSizeInfo));
361 nwalSizeInfo.nMaxMacAddress = TUNE_NETAPI_MAX_NUM_MAC;
362 nwalSizeInfo.nMaxIpAddress = TUNE_NETAPI_MAX_NUM_IP;
363 nwalSizeInfo.nMaxL4Ports = TUNE_NETAPI_MAX_NUM_PORTS;
364 nwalSizeInfo.nMaxIpSecChannels = TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS;//we allocate 2 per channel
365 nwalSizeInfo.nMaxDmSecChannels = TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS;//we allocate 2 per channel
366 nwalSizeInfo.nMaxL2L3Hdr = TUNE_NETAPI_MAX_NUM_L2_L3_HDRS;
367 nwalSizeInfo.nProc = TUNE_NETAPI_NUM_CORES;
368 nwalRetVal = nwal_getBufferReq(&nwalSizeInfo,
369 sizes,
370 aligns);
371 if(nwalRetVal != nwal_OK)
372 {
373 netapi_Log ("netapip_initNwal: nwal_getBufferReq Failed %d\n", nwalRetVal);
374 return nwal_FALSE;
375 }
377 /* Check for memory size requirement and update the base */
378 count = 0;
379 bases[nwal_BUF_INDEX_INST] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)nwalInstMem);
380 if(NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_HANDLE < sizes[nwal_BUF_INDEX_INST])
381 {
382 /* Resize Memory */
383 while(1);
384 }
385 count++;
387 bases[nwal_BUF_INDEX_INT_HANDLES] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)nwalHandleMem);
388 if(NWAL_CHAN_HANDLE_SIZE < sizes[nwal_BUF_INDEX_INT_HANDLES])
389 {
390 /* Resize Memory */
391 while(1);
392 }
393 count++;
394 bases[nwal_BUF_INDEX_PA_LLD_BUF0] =
395 (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)paEntry->paBuf0);
396 if((NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF0) < sizes[nwal_BUF_INDEX_PA_LLD_BUF0])
397 {
398 /* Resize Memory */
399 while(1);
400 }
401 count++;
403 bases[nwal_BUF_INDEX_PA_LLD_BUF1] =
404 (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)paEntry->paBuf1);
405 if((NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1) < sizes[nwal_BUF_INDEX_PA_LLD_BUF1])
406 {
407 /* Resize Memory */
408 while(1);
409 }
410 count++;
412 bases[nwal_BUF_INDEX_PA_LLD_BUF2] =
413 (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)paEntry->paBuf2);
414 if((NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2) < sizes[nwal_BUF_INDEX_PA_LLD_BUF2])
415 {
416 /* Resize Memory */
417 while(1);
418 }
419 count++;
420 #ifdef NETAPI_ENABLE_SECURITY
421 bases[nwal_BUF_INDEX_SA_LLD_HANDLE] =
422 (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)saEntry->salldHandle);
423 if((NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE) < sizes[nwal_BUF_INDEX_SA_LLD_HANDLE])
424 {
425 /* Resize Memory */
426 while(1);
427 }
428 count++;
430 bases[nwal_BUF_INDEX_SA_CONTEXT] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)netapi_VM_SaContextVaddr);
431 /* also save this here for easy access to sa_start */
432 nwalGlobCfg.scPoolBaseAddr = bases[nwal_BUF_INDEX_SA_CONTEXT];
433 count++;
435 bases[nwal_BUF_INDEX_SA_LLD_CHAN_HANDLE] =
436 (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)saEntry->salldChanHandle);
437 if((NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE_PER_CHAN * TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS*2) <
438 sizes[nwal_BUF_INDEX_SA_LLD_CHAN_HANDLE])
439 {
440 /* Resize Memory */
441 while(1);
442 }
443 count++;
444 #else
445 bases[nwal_BUF_INDEX_SA_LLD_HANDLE] = 0;
446 bases[nwal_BUF_INDEX_SA_CONTEXT] = 0;
447 bases[nwal_BUF_INDEX_SA_LLD_CHAN_HANDLE] = 0;
448 count = count+3;
449 #endif
450 if(count != nwal_N_BUFS)
451 {
452 while(1);
453 }
455 /* Initialize NWAL module */
456 nwalRetVal = nwal_create(&nwalGlobCfg,
457 &nwalSizeInfo,
458 sizes,
459 bases,
460 &p_nwal_context->nwalInstHandle);
461 if(nwalRetVal != nwal_OK)
462 {
463 netapi_Log ("netapip_initNwal: nwal_create Failed %d\n",nwalRetVal);
464 while(1);
465 }
467 netapi_Log("netapip_initNwal- Global and Local Network initialization Successful \n");
468 return 1;
469 }
471 /********************************************************************
472 * FUNCTION PURPOSE: Internal NETAPI function to start NWAL
473 ********************************************************************
474 * DESCRIPTION: Internal NETAPI function to start NWAL, per thread/core
475 ********************************************************************/
476 int netapip_startNwal(Pktlib_HeapHandle pkt_heap,
477 Pktlib_HeapHandle cmd_rx_heap,
478 Pktlib_HeapHandle cmd_tx_heap,
479 NETAPI_NWAL_LOCAL_CONTEXT_T *p,
480 NETAPI_CFG_T *p_cfg,
481 NETAPI_NWAL_GLOBAL_CONTEXT_T * p_nwal_glob_context )
482 {
483 nwalLocCfg_t nwalLocCfg;
484 int count=0;
485 static int first_time = 0;
486 nwal_RetValue nwalRetVal;
488 memset(&nwalLocCfg,0,sizeof(nwalLocCfg));
490 /* Update the Start of Packet Offset for the default flows created
491 * by NWAL
492 */
493 nwalLocCfg.rxSopPktOffset = p_cfg->def_flow_pkt_rx_offset;
494 nwalLocCfg.rxPktTailRoomSz = p_cfg->def_heap_tailroom_size;
496 /* Call back registration for the core */
497 nwalLocCfg.pRxPktCallBack = netapip_pktioNWALRxPktCallback;
498 nwalLocCfg.pCmdCallBack = netapip_netcpCfgNWALCmdCallBack;
499 nwalLocCfg.pPaStatsCallBack = netapip_netcpCfgNWALCmdPaStatsReply;
501 nwalLocCfg.pRxDmCallBack= netapip_pktioNWALSBPktCallback; //sideband mode callback
503 /* Initialize Buffer Pool for Control packets from NetCP to Host */
504 nwalLocCfg.rxCtlPool.numBufPools = 1;
505 nwalLocCfg.rxCtlPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE;
506 nwalLocCfg.rxCtlPool.bufPool[0].bufSize = TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE;
507 nwalLocCfg.rxCtlPool.bufPool[0].heapHandle = cmd_rx_heap;
509 /* Initialize Buffer Pool for Control packets from Host to NetCP */
510 nwalLocCfg.txCtlPool.numBufPools = 1;
511 nwalLocCfg.txCtlPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE;
512 nwalLocCfg.txCtlPool.bufPool[0].bufSize = TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE;
513 nwalLocCfg.txCtlPool.bufPool[0].heapHandle = cmd_tx_heap;
515 /* Initialize Buffer Pool for Packets from NetCP to Host */
516 nwalLocCfg.rxPktPool.numBufPools = 1;
517 nwalLocCfg.rxPktPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE;
518 nwalLocCfg.rxPktPool.bufPool[0].bufSize = p_cfg->def_heap_buf_size;
519 nwalLocCfg.rxPktPool.bufPool[0].heapHandle = pkt_heap;
521 /* Initialize Buffer Pool for Packets from Host to NetCP */
522 nwalLocCfg.txPktPool.numBufPools = 1;
523 nwalLocCfg.txPktPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE;
524 nwalLocCfg.txPktPool.bufPool[0].bufSize = p_cfg->def_heap_buf_size;
525 nwalLocCfg.txPktPool.bufPool[0].heapHandle = pkt_heap;
527 memcpy(&p->nwalLocCfg,&nwalLocCfg,sizeof(nwalLocCfg_t));
528 while(1)
529 {
530 nwalRetVal = nwal_start(p_nwal_glob_context->nwalInstHandle,&nwalLocCfg);
531 if(nwalRetVal == nwal_ERR_INVALID_STATE)
532 {
533 continue;
534 }
535 break;
536 }
538 if(nwalRetVal != nwal_OK)
539 {
540 netapi_Log (">nwal_start:Failed ->err %d !!!\n", nwalRetVal);
541 return -1;
542 }
543 p->state = NETAPI_NW_CXT_LOC_ACTIVE;
544 return 1;
547 }
548 /***********************************************************************
549 * FUNCTION PURPOSE: Internal NETAPI function to initialize the 64 bit timer.
550 ***********************************************************************
551 * DESCRIPTION: Internal NETAPI function to initialize the 64 bit timer. for tci6614 ONLY
552 **********************************************************************/
553 int netapip_initTimer(void)
554 {
555 #ifdef CORTEX_A8
556 return t64_start();
557 #endif
558 }
563 /***************************************************************************
564 * FUNCTION PURPOSE: NETAPI internal function for virtual memory allocation.
565 ***************************************************************************
566 * DESCRIPTION: NETAPI internal function for virtual memory allocation.
567 **************************************************************************/
569 static uint8_t* netapip_sharedMemoryMalloc(uint32_t size)
570 {
571 return (uint8_t *)hplib_vmMemAlloc(size +pnetapiShm->netapi_global.cfg.def_heap_extra_size , 128, 0);
572 }
574 /********************************************************************
575 * FUNCTION PURPOSE: NETAPI internal function for virtual memory free.
576 ********************************************************************
577 * DESCRIPTION: NETAPI internal function for virtual memory free.
578 ********************************************************************/
579 static void netapip_sharedMemoryFree(uint8_t* ptr, uint32_t size)
580 {
581 /* Do Nothing. */
582 netapi_Log("netapi Unexpected. need to provide a free () for some reason!! \n");
583 return;
584 }
586 //defensive: clean out stuff hanging around
587 //
588 // open a bunch of free queues and zap them
589 #define NQUEUES2CLEAR 35
590 static Qmss_QueueHnd tempQH[NQUEUES2CLEAR];
591 void netapip_cleanupAtStart(void)
592 {
593 int i;
594 uint8_t isAllocated;
596 for(i=0;i<NQUEUES2CLEAR;i++)
597 {
598 tempQH[i] = Qmss_queueOpen(Qmss_QueueType_GENERAL_PURPOSE_QUEUE,
599 QMSS_PARAM_NOT_SPECIFIED, &isAllocated);
600 netapip_zapQ(tempQH[i]);
601 }
603 for(i=0;i<NQUEUES2CLEAR;i++)
604 {
605 Qmss_queueClose(tempQH[i]);
606 }
607 }
611 /********************************************************************
612 * FUNCTION PURPOSE: NETAPI internal function system initialization
613 ********************************************************************
614 * DESCRIPTION: NETAPI internal function system initialization
615 ********************************************************************/
616 int netapip_systemInit(NETAPI_HANDLE_T * handle,
617 hplib_globalDeviceConfigParams_t *p_hplib_device_cfg,
618 NETCP_CFG_GLOB_DEVICE_PARAMS_T *p_netapi_device_cfg,
619 nwalGlobalDeviceConfigParams_t *p_nwal_device_cfg,
620 Bool global_master_process)
621 {
622 int32_t result;
623 Pktlib_HeapHandle sharedHeapHandle;
624 Pktlib_HeapHandle controlRxHeapHandle,controlTxHeapHandle;
625 Pktlib_HeapCfg heapCfg;
626 int32_t errCode;
627 int count=0;
629 #ifdef NETAPI_USE_DDR
630 /* Init attributes for DDR */
631 netapi_VM_MempoolAttr[0].attr = HPLIB_ATTR_KM_CACHED0;
632 netapi_VM_MempoolAttr[0].phys_addr = 0;
633 netapi_VM_MempoolAttr[0].size = 0;
635 /* Init attributes for un-cached MSMC */
636 netapi_VM_MempoolAttr[1].attr = HPLIB_ATTR_UN_CACHED;
637 netapi_VM_MempoolAttr[1].phys_addr = CSL_MSMC_SRAM_REGS;
638 netapi_VM_MempoolAttr[1].size = TUNE_NETAPI_PERM_MEM_SZ;
639 #else
640 netapi_VM_MempoolAttr[1].attr = HPLIB_ATTR_KM_CACHED0;
641 netapi_VM_MempoolAttr[1].phys_addr = 0;
642 netapi_VM_MempoolAttr[1].size = 0;
644 /* Init attributes for un-cached MSMC */
645 netapi_VM_MempoolAttr[0].attr = HPLIB_ATTR_UN_CACHED;
646 netapi_VM_MempoolAttr[0].phys_addr = CSL_MSMC_SRAM_REGS;
647 netapi_VM_MempoolAttr[0].size = TUNE_NETAPI_PERM_MEM_SZ;
648 #endif
649 /* initialize all the memory we are going to use
650 - chunk for buffers, descriptors
651 - memory mapped peripherals we use, such as QMSS, PA, etc */
652 result = hplib_vmInit(&netapi_VM_VirtAddr[0],
653 2,
654 &netapi_VM_MempoolAttr[0],
655 p_hplib_device_cfg);
657 if (global_master_process == TRUE)
658 {
659 hplib_initMallocArea(0);
660 hplib_initMallocArea(1);
661 }
662 else
663 {
664 if (hplib_checkMallocArea(0) != hplib_OK)
665 return -1;
666 if (hplib_checkMallocArea(1) != hplib_OK)
667 return -1;
668 }
670 if (result == hplib_OK) netapi_Log("netapip_systemInit: - memory set up OK\n");
671 else {netapi_Log("netapip_systemInit: - memory set up failed\n"); return -1;}
673 if(global_master_process == FALSE)
674 {
675 //------------------------------------------------
676 //partial initialization. For process, not for SOC
677 //------------------------------------------------
679 /* Start the QMSS. */
680 if (netapip_startQm() != 1)
681 {
682 netapi_Log("netapip_systemInit: returned from netapip_startQm with failure\n");
683 return -1;
684 }
686 //open shared heap handle but create new controlRx & Tx heaps for this
687 //process
688 netapi_pktlib_ifTable.data_malloc = netapip_sharedMemoryMalloc;
689 netapi_pktlib_ifTable.data_free = netapip_sharedMemoryFree;
690 sharedHeapHandle = Pktlib_findHeapByName("netapi");
691 if (!sharedHeapHandle) { netapi_Log(">'netapi' heap create failed, Error Code: %d\n",errCode); return -1;}
692 handle->netcp_heap= sharedHeapHandle;
694 /* Update for Control */
695 heapCfg.name = "netapi_control_rx";/*todo:add random#*/
696 heapCfg.sharedHeap = 1;
697 heapCfg.dataBufferSize = TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE;
698 heapCfg.numPkts = TUNE_NETAPI_CONFIG_NUM_CTL_RX_BUF;
699 heapCfg.numZeroBufferPackets= 0;
700 controlRxHeapHandle = Pktlib_createHeap(&heapCfg, &errCode);
701 if (!controlRxHeapHandle) { netapi_Log("netapi -'netapi_control_rx' heap create failed, Error Code: %d\n",errCode); return -1;}
702 handle->netcp_control_rx_heap= controlRxHeapHandle;
703 heapCfg.name = "netapi_control_tx";
704 heapCfg.numPkts = TUNE_NETAPI_CONFIG_NUM_CTL_TX_BUF;
705 controlTxHeapHandle = Pktlib_createHeap(&heapCfg, &errCode);
706 if (!controlTxHeapHandle) { netapi_Log("netapi -'netapi_control_tx' heap create failed, Error Code: %d\n",errCode); return -1;}
707 handle->netcp_control_tx_heap= controlTxHeapHandle;
709 /* Common Initialization for all threads in process */
710 while(count < TUNE_NETAPI_MAX_NUM_TRANS)
711 {
712 netapi_proc_global.nwal_context.transInfos[count].transId = count;
713 count++;
714 }
715 result = netapip_startNwal(sharedHeapHandle,
716 controlRxHeapHandle,
717 controlTxHeapHandle,
718 &handle->nwal_local,
719 &pnetapiShm->netapi_global.cfg,
720 &pnetapiShm->netapi_global.nwal_context);
721 if (result<0) {netapi_Log("netapi start_nwal() failed\n"); return -1; }
722 netapi_Log("netapip_systemInit: returned from netapip_startNwal\n");
723 }
725 #ifdef NETAPI_ENABLE_SECURITY
726 #define SEC_CONTEXT_SZ 384 //not tunable
727 /* allocate 2x number of tunnels since we need one for inflow and one for data mode */
728 netapi_VM_SaContextVaddr = hplib_vmMemAlloc((TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS*2 *
729 SEC_CONTEXT_SZ), 128, 0);
730 if (!netapi_VM_SaContextVaddr)
731 {
732 netapi_Log("netapip_systemInit: Failed to map SA context memory region\n");
733 return (-1);
734 }
735 netapi_Log("netapip_systemInit: SA Memory mapped/allocated at address %p.\n", netapi_VM_SaContextVaddr);
737 #else
738 netapi_VM_SaContextVaddr= (char *) NULL;
739 #endif
741 /* TODO: the QM regions is application specific and needs to be moved
742 since number of regions created is appliction specific, put this in netapip_systemInit */
743 /* (3) Allocate 2 QM regions from continguous chunk above */
744 netapi_VM_QMemGlobalDescRam =
745 (void *)hplib_vmMemAlloc((TUNE_NETAPI_NUM_GLOBAL_DESC *
746 TUNE_NETAPI_DESC_SIZE),
747 128, 0);
749 netapi_VM_QMemLocalDescRam =
750 (void *)hplib_vmMemAlloc((TUNE_NETAPI_NUM_LOCAL_DESC *
751 TUNE_NETAPI_DESC_SIZE),
752 128, 0);
753 netapi_Log("netapip_systemInit: desc region=%x global desc region=%x\n", netapi_VM_QMemLocalDescRam, netapi_VM_QMemGlobalDescRam);
755 //get timer running
756 #ifdef CORTEX_A8
757 netapip_initTimer();
758 netapi_Log("netapip_systemInit: returned from netapip_initTimer\n");
759 #endif
761 /* Initialize Queue Manager Sub System */
762 result = netapip_initQm (pnetapiShm->netapi_global.cfg.def_max_descriptors,
763 p_netapi_device_cfg);
765 if (result != 1)
766 {
767 netapi_Log("netapip_systemInit: returned from netapip_initQm with failure\n");
768 return -1;
769 }
771 /* Start the QMSS. */
772 if (netapip_startQm() != 1)
773 {
774 netapi_Log("netapip_systemInit: returned from netapip_startQm with failure\n");
775 return -1;
776 }
779 //clean our old junk in 1st bunch of queues that will be allocated to us
780 netapip_cleanupAtStart();
781 netapi_Log("netapip_systemInit: returned from netapip_cleanupAtStart\n");
782 /* Initialize the global descriptor memory region. */
783 result= netapip_qmSetupMemRegion(
784 pnetapiShm->netapi_global.cfg.def_tot_descriptors_for_us,
785 TUNE_NETAPI_DESC_SIZE,
786 (unsigned int *) netapi_VM_QMemGlobalDescRam,
787 TUNE_NETAPI_QM_GLOBAL_REGION);
788 if(result <0) {netapi_Log("netapip_systemInit: can't setup QM shared region\n"); return -1;}
790 netapi_Log("netapip_systemInit: returned from netapip_qmSetupMemRegion\n");
791 /* Initialize CPPI CPDMA */
793 result = netapip_initCppi (p_netapi_device_cfg);
794 netapi_Log("netapip_systemInit: returned from netapip_initCppi\n");
795 if (result != 1)
796 {
797 netapi_Log ("netapi: Error initializing CPPI SubSystem error code : %d\n",result);
798 return -1;
799 }
801 /* CPPI and Queue Manager are initialized. */
802 netapi_Log ("netapi: Queue Manager and CPPI are initialized.\n");
804 /* create main pkt heap */
805 /* Initialize the Shared Heaps. */
806 Pktlib_sharedHeapInit();
807 netapi_Log("netapip_systemInit: returned from Pktlib_sharedHeapInit\n");
808 /* Populate the heap interface table. */
809 netapi_pktlib_ifTable.data_malloc = netapip_sharedMemoryMalloc;
810 netapi_pktlib_ifTable.data_free = netapip_sharedMemoryFree;
812 /* Initialize the heap configuration. */
813 memset ((void *)&heapCfg, 0, sizeof(Pktlib_HeapCfg));
814 /* Populate the heap configuration */
815 heapCfg.name = "netapi";
816 heapCfg.memRegion = TUNE_NETAPI_QM_GLOBAL_REGION;
817 heapCfg.sharedHeap = 1;
818 heapCfg.useStarvationQueue = 0;
819 heapCfg.dataBufferSize = pnetapiShm->netapi_global.cfg.def_heap_buf_size;
820 heapCfg.numPkts = pnetapiShm->netapi_global.cfg.def_heap_n_descriptors;
821 heapCfg.numZeroBufferPackets= pnetapiShm->netapi_global.cfg.def_heap_n_zdescriptors;
822 heapCfg.heapInterfaceTable.data_malloc = netapi_pktlib_ifTable.data_malloc;
823 heapCfg.heapInterfaceTable.data_free = netapi_pktlib_ifTable.data_free;
824 heapCfg.dataBufferPktThreshold = 0;
825 heapCfg.zeroBufferPktThreshold = 0;
827 /* Create Shared Heap with specified configuration. */
828 sharedHeapHandle = Pktlib_createHeap(&heapCfg, &errCode);
829 netapi_Log("netapip_systemInit: returned from Pktlib_createHeap1\n");
830 //todo -> cleanup on failure
831 if (!sharedHeapHandle) { netapi_Log(">'netapi' heap create failed, Error Code: %d\n",errCode); return -1;}
832 handle->netcp_heap= sharedHeapHandle;
834 /* Update for Control */
835 heapCfg.name = "netapi_control_rx";
836 heapCfg.sharedHeap = 1;
837 heapCfg.dataBufferSize = TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE;
838 heapCfg.numPkts = TUNE_NETAPI_CONFIG_NUM_CTL_RX_BUF;
839 heapCfg.numZeroBufferPackets= 0;
841 controlRxHeapHandle = Pktlib_createHeap(&heapCfg, &errCode);
842 netapi_Log("netapip_systemInit: returned from Pktlib_createHeap2\n");
843 //todo -> cleanup on failure
844 if (!controlRxHeapHandle) { netapi_Log("netapi -'netapi_control_rx' heap create failed, Error Code: %d\n",errCode); return -1;}
845 handle->netcp_control_rx_heap= controlRxHeapHandle;
848 heapCfg.name = "netapi_control_tx";
849 heapCfg.numPkts = TUNE_NETAPI_CONFIG_NUM_CTL_TX_BUF;
851 controlTxHeapHandle = Pktlib_createHeap(&heapCfg, &errCode);
852 netapi_Log("netapip_systemInit: returned from Pktlib_createHeap3\n");
853 //todo -> cleanup on failure
854 if (!controlTxHeapHandle) { netapi_Log("netapi -'netapi_control_tx' heap create failed, Error Code: %d\n",errCode); return -1;}
855 handle->netcp_control_tx_heap= controlTxHeapHandle;
857 /* now NWAL */
858 result = netapip_initNwal(TUNE_NETAPI_QM_GLOBAL_REGION,
859 &netapi_pktlib_ifTable,
860 &pnetapiShm->netapi_global.nwal_context,
861 &pnetapiShm->netapi_global.cfg,
862 p_nwal_device_cfg);
863 if (result<0) {netapi_Log("netapi init_nwal() failed\n"); return -1; }
864 netapi_Log("netapip_systemInit: returned from netapip_initNwal\n");
865 /* start NWAL */
868 /* Common Initialization for all cores */
869 while(count < TUNE_NETAPI_MAX_NUM_TRANS)
870 {
871 netapi_proc_global.nwal_context.transInfos[count].transId = count;
872 count++;
873 }
874 result = netapip_startNwal(sharedHeapHandle,
875 controlRxHeapHandle,
876 controlTxHeapHandle,
877 &handle->nwal_local,
878 &pnetapiShm->netapi_global.cfg,
879 &pnetapiShm->netapi_global.nwal_context);
880 if (result<0) {netapi_Log("netapi start_nwal() failed\n"); return -1; }
881 netapi_Log("netapip_systemInit: returned from netapip_startNwal\n");
882 return 0;
883 }
886 /****************************************************************************
887 * FUNCTION PURPOSE: NETAPI internal function which performs clean for linux user space
888 ****************************************************************************
889 * DESCRIPTION: NETAPI internal function which performs clean for linux user space
890 ***************************************************************************/
891 void netapip_zapQ(int queueNum)
892 {
893 char * descPtr;
894 int i;
895 if (!queueNum)
896 {
897 return;
898 }
899 for (i=0;;i+=1 )
900 {
901 /* Pop descriptor from source queue */
902 if ((descPtr = (char *)pktio_mQmssQueuePopRaw(queueNum)) == NULL)
903 {
904 break;
905 }
906 }
907 if(i)
908 {
909 netapi_Log("netapip_zapQ: @recovery - %d descriptors cleaned from qn %d\n",i, queueNum);
910 }
911 }
914 /****************************************************************************
915 * FUNCTION PURPOSE: NETAPI internal function to display internal heap stats.
916 ****************************************************************************
917 * DESCRIPTION: NETAPI internal function to display internal heap stats.
918 ***************************************************************************/
919 void netapi_dump_internal_heap_stats(void)
920 {
921 Pktlib_HeapStats pktLibHeapStats;
922 Pktlib_getHeapStats(netapi_get_global()->nwal_context.pa2sa_heap,&pktLibHeapStats);
923 printf("PA2SA(ingress) stats> #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
924 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
925 printf(" > #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n",
926 pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
927 pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
928 #if 0
929 Pktlib_getHeapStats(netapi_get_global()->nwal_context.pa2saTX_heap,&pktLibHeapStats);
930 netapi_Log("PA2SA(egress) stats> #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
931 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
932 netapi_Log(" > #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n",
933 pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
934 pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
935 #endif
936 Pktlib_getHeapStats(netapi_get_global()->nwal_context.sa2pa_heap,&pktLibHeapStats);
937 printf("SA2PA stats> #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
938 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
939 printf(" > #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n",
940 pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
941 pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
943 }