/**************************************************************************** * FILE: netapi_init.c * Global, Private initialization and cleanup routines and defines of NETAPI * * DESCRIPTION: Functions to initialize and cleanup framework resources * for running NETAPI * * REVISION HISTORY: * * Copyright (c) Texas Instruments Incorporated 2013 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include "netapi.h" #include "netapi_loc.h" #include #include #include #include #include #include #include "ti/drv/nwal/nwal.h" /* CSL RL includes */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* pointer to NWAL local context memory block used by NWAL for local context intance*/ void* pNwalLocCtxMem = NULL; extern void *pRmClientHandle; nwal_Handle gPNwalInstHandle = NULL; extern NETAPI_SHM_T* pnetapiShm; /* Global variablesto hold virtual address of various subsystems */ extern hplib_virtualAddrInfo_T netapi_VM_VirtAddr[]; /* Global variables which needs to be populated with memory pool attributes which is passed to HPLIB for memory pool initialization*/ extern hplib_memPoolAttr_T netapi_VM_MempoolAttr[]; extern unsigned char *netapi_VM_QMemLocalDescRam; extern unsigned char *netapi_VM_QMemGlobalDescRam; extern unsigned char *netapi_VM_SaContextVaddr; extern Pktlib_HeapIfTable netapi_pktlib_ifTable; extern NETAPI_PROC_GLOBAL_T netapi_proc_global; extern NETAPI_HANDLE_T * netapi_proc_master; /* TODO verify: */ #define CACHE_LINESZ 64 #define ALIGN(x) __attribute__((aligned (x))) /***************************************************************************** * Global Resources shared by all Cores *****************************************************************************/ uint8_t *QMemGlobDescRam = 0; uint8_t *cppiMemPaSaLinkBuf = 0; uint8_t *cppiMemSaPaLinkBuf = 0; #if 0 /***************************************************************************** * Local Resource allocated at each Core *****************************************************************************/ /* Descriptors in global shared */ uint8_t *QMemLocDescRam = NULL; uint8_t *cppiMemRxPktLinkBuf = NULL; uint8_t *cppiMemTxPktLinkBuf = NULL; uint8_t *cppiMemRxCtlLinkBuf = NULL; uint8_t *cppiMemTxCtlLinkBuf = NULL; #endif NETCP_CFG_GLOB_DEVICE_PARAMS_T *p_netapi_device_cfg_local; Qmss_MemRegInfo memInfo; /******************************************************************** * FUNCTION PURPOSE: Internal NETAPI function to setup the QM memory region ******************************************************************** * DESCRIPTION: Internal NETAPI function to setup the QM memory region, * once per SOC ********************************************************************/ int netapip_qmSetupMemRegion( uint32_t numDesc, uint32_t descSize, uint32_t* pDescMemBase, int memRegion, int start_index) { //Qmss_MemRegInfo memInfo; int result; memset(&memInfo,0,sizeof(Qmss_MemRegInfo)); memInfo.descBase = pDescMemBase; memInfo.descSize = descSize; memInfo.descNum = numDesc; memInfo.manageDescFlag = Qmss_ManageDesc_MANAGE_DESCRIPTOR; if (pRmClientHandle) { memInfo.memRegion = -1; memInfo.startIndex = QMSS_START_INDEX_NOT_SPECIFIED; } else { memInfo.memRegion = memRegion; memInfo.startIndex = start_index; } memset (pDescMemBase, 0, (descSize * numDesc)); result = Qmss_insertMemoryRegion (&memInfo); if (result < QMSS_SOK) { return (-1); } netapi_proc_master->memRegion = memInfo.memRegion; return 1; } /******************************************************************** * FUNCTION PURPOSE: Internal NETAPI function to start QM ******************************************************************** * DESCRIPTION: Internal NETAPI function to start QM * once per thread/core ********************************************************************/ int netapip_startQm(void* rmClientServiceHandle) { int32_t result; Qmss_StartCfg startCfg; startCfg.rmServiceHandle = rmClientServiceHandle; startCfg.pQmssGblCfgParams = NULL; //result = Qmss_start(); result = Qmss_startCfg(&startCfg); if (result != QMSS_SOK) { return (-1); } return 1; } /*** NWAL Memory Buffer Configuration ***/ #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_HANDLE 3400 //uint8_t nwalInstMem[NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_HANDLE]ALIGN(CACHE_LINESZ); #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_MAC 256 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_IPSEC_HANDLE_PER_CHAN 256 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_IP 128 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_PORT 128 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_L2L3_HDR 128 #define NWAL_CHAN_HANDLE_SIZE ((NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_MAC * TUNE_NETAPI_MAX_NUM_MAC) + \ (NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_IPSEC_HANDLE_PER_CHAN * TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS*2) + \ (NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_IP * TUNE_NETAPI_MAX_NUM_IP) + \ (NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_PORT * TUNE_NETAPI_MAX_NUM_PORTS)+ \ (NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_L2L3_HDR * TUNE_NETAPI_MAX_NUM_L2_L3_HDRS)) typedef struct NETAPI_NWAL_SHM_Tag { uint8_t nwalInstMem[NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_HANDLE]ALIGN(CACHE_LINESZ); uint8_t nwalHandleMem[NWAL_CHAN_HANDLE_SIZE]ALIGN(CACHE_LINESZ); } NETAPI_NWAL_SHM_T; typedef struct NETAPI_PA_SHM_Tag { /* todo: Check if below size information can be made available from pa interface file */ #define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF0 256 /* PA instance */ /* Memory used for the PA Instance. Needs to be assigned global uncached memory for chip */ uint8_t paBuf0[NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF0]ALIGN(CACHE_LINESZ); /* Memory used for PA handles */ #define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1 128 * TUNE_NETAPI_MAX_NUM_MAC uint8_t paBuf1[NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1]ALIGN(CACHE_LINESZ); #define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2 14592 uint8_t paBuf2[NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2]ALIGN(CACHE_LINESZ); } NETAPI_PA_SHM_T; typedef struct NETAPI_SA_SHM_Tag { /* Memory used for SA LLD global Handle */ #define NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE 512 uint8_t salldHandle[NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE]ALIGN(CACHE_LINESZ); /* Memory used by SA LLD per Channel */ #define NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE_PER_CHAN 512 uint8_t salldChanHandle[NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE_PER_CHAN * TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS*2]ALIGN(CACHE_LINESZ); } NETAPI_SA_SHM_T; /******************************************************************** * FUNCTION PURPOSE: NETAPI internal function to gracefully cleanup when startup * issue occurs. ******************************************************************** * DESCRIPTION: NETAPI internal function to gracefully cleanup when startup * issue occurs. ********************************************************************/ void netapipErrTeardown() { netapip_cleanupAtStart(); exit(-99); } /******************************************************************** * FUNCTION PURPOSE: Internal NETAPI function to initialize NWAL subsystem ******************************************************************** * DESCRIPTION: Internal NETAPI function to initialize NWAL subsytem ********************************************************************/ int netapip_initNwal( int region2use, Pktlib_HeapIfTable * p_table, NETAPI_NWAL_GLOBAL_CONTEXT_T * p_nwal_context, NETAPI_CFG_T*p_cfg) { nwalSizeInfo_t nwalSizeInfo; nwal_RetValue nwalRetVal; nwalGlobCfg_t nwalGlobCfg; nwalBaseAddrCfg_t nwalBaseAddrCfg; uint8_t count; int sizes[nwal_N_BUFS]; int aligns[nwal_N_BUFS]; void* bases[nwal_N_BUFS]; Pktlib_HeapCfg heapCfg; int32_t errCode = 0; void* pBase = NULL; NETAPI_PA_SHM_T* paEntry = NULL; NETAPI_SA_SHM_T* saEntry = NULL; NETAPI_NWAL_SHM_T* nwalEntry = NULL; uint32_t localCtxSize = 0; memset(p_nwal_context,0,sizeof( NETAPI_NWAL_GLOBAL_CONTEXT_T) ); memset(&nwalGlobCfg,0,sizeof(nwalGlobCfg_t ) ); memset (&nwalBaseAddrCfg, 0, sizeof(nwalBaseAddrCfg_t)); pBase = hplib_shmOpen(); if (pBase) { if(hplib_shmAddEntry(pBase, sizeof(NETAPI_PA_SHM_T), PA_ENTRY) == hplib_OK) { paEntry = (NETAPI_PA_SHM_T*)hplib_shmGetEntry(pBase,PA_ENTRY); nwalBaseAddrCfg.pInstPoolPaBaseAddr= (void *)paEntry; } else { return -1; } if(hplib_shmAddEntry(pBase, sizeof(NETAPI_SA_SHM_T), SA_ENTRY) == hplib_OK) { saEntry = (NETAPI_SA_SHM_T*)hplib_shmGetEntry(pBase,SA_ENTRY); nwalBaseAddrCfg.pInstPoolSaBaseAddr= (void*) saEntry; } else { return -1; } if(hplib_shmAddEntry(pBase, sizeof(NETAPI_NWAL_SHM_T), NWAL_ENTRY) == hplib_OK) { nwalEntry = (NETAPI_NWAL_SHM_T*)hplib_shmGetEntry(pBase,NWAL_ENTRY); } else { return -1; } } /* Initialize Buffer Pool for NetCP PA to SA packets */ nwalGlobCfg.pa2SaBufPool.numBufPools = 1; nwalGlobCfg.pa2SaBufPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE; nwalGlobCfg.pa2SaBufPool.bufPool[0].bufSize = p_cfg->def_heap_buf_size; /* Initialize the heap configuration. */ memset ((void *)&heapCfg, 0, sizeof(Pktlib_HeapCfg)); /* Populate the heap configuration */ heapCfg.name = "nwal PA2SA"; heapCfg.memRegion = region2use; heapCfg.sharedHeap = 0; heapCfg.useStarvationQueue = 0; heapCfg.dataBufferSize = p_cfg->def_heap_buf_size; heapCfg.numPkts = TUNE_NETAPI_CONFIG_MAX_PA_TO_SA_DESC; heapCfg.numZeroBufferPackets= 0; heapCfg.heapInterfaceTable.data_malloc = p_table->data_malloc; heapCfg.heapInterfaceTable.data_free = p_table->data_free; heapCfg.dataBufferPktThreshold = 0; heapCfg.zeroBufferPktThreshold = 0; nwalGlobCfg.pa2SaBufPool.bufPool[0].heapHandle = p_nwal_context->pa2sa_heap= Pktlib_createHeap(&heapCfg, &errCode); if(nwalGlobCfg.pa2SaBufPool.bufPool[0].heapHandle == NULL) { netapipErrTeardown(); return -1; } /* Initialize Buffer Pool for NetCP SA to PA packets */ nwalGlobCfg.sa2PaBufPool.numBufPools = 1; nwalGlobCfg.sa2PaBufPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE; nwalGlobCfg.sa2PaBufPool.bufPool[0].bufSize = p_cfg->def_heap_buf_size; /* Populate the heap configuration */ heapCfg.name = "nwal SA2PA"; heapCfg.numPkts = TUNE_NETAPI_CONFIG_MAX_SA_TO_PA_DESC; nwalGlobCfg.sa2PaBufPool.bufPool[0].heapHandle = p_nwal_context->sa2pa_heap = Pktlib_createHeap(&heapCfg, &errCode); if(nwalGlobCfg.sa2PaBufPool.bufPool[0].heapHandle == NULL) { netapipErrTeardown(); return -1; } nwalGlobCfg.hopLimit = 5;/* Default TTL / Hop Limit */ nwalGlobCfg.paPowerOn = nwal_TRUE; nwalGlobCfg.saPowerOn = nwal_TRUE; nwalGlobCfg.paFwActive = nwal_TRUE; nwalGlobCfg.saFwActive = nwal_FALSE; /* Update nwal cfg with virtual PA and SA addresses */ nwalBaseAddrCfg.paVirtBaseAddr = (uint32_t) netapi_VM_VirtAddr->passCfgVaddr; nwalBaseAddrCfg.pSaVirtBaseAddr = (uint32_t) netapi_VM_VirtAddr->passCfgVaddr + CSL_NETCP_CFG_SA_CFG_REGS - CSL_NETCP_CFG_REGS; ; nwalGlobCfg.rxDefPktQ = QMSS_PARAM_NOT_SPECIFIED; /* Get the Buffer Requirement from NWAL */ memset(&nwalSizeInfo,0,sizeof(nwalSizeInfo)); nwalSizeInfo.nMaxMacAddress = TUNE_NETAPI_MAX_NUM_MAC; nwalSizeInfo.nMaxIpAddress = TUNE_NETAPI_MAX_NUM_IP; nwalSizeInfo.nMaxL4Ports = TUNE_NETAPI_MAX_NUM_PORTS; nwalSizeInfo.nMaxIpSecChannels = TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS;//we allocate 2 per channel nwalSizeInfo.nMaxDmSecChannels = TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS;//we allocate 2 per channel nwalSizeInfo.nMaxL2L3Hdr = TUNE_NETAPI_MAX_NUM_L2_L3_HDRS; nwalSizeInfo.nProc = TUNE_NETAPI_NUM_CORES; nwalRetVal = nwal_getBufferReq(&nwalSizeInfo, sizes, aligns); if(nwalRetVal != nwal_OK) { return nwal_FALSE; } /* Check for memory size requirement and update the base */ count = 0; //bases[nwal_BUF_INDEX_INST] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)nwalInstMem); bases[nwal_BUF_INDEX_INST] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)nwalEntry->nwalInstMem); if(NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_HANDLE < sizes[nwal_BUF_INDEX_INST]) { /* Resize Memory */ return nwal_FALSE; //while(1); } count++; //bases[nwal_BUF_INDEX_INT_HANDLES] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)nwalHandleMem); bases[nwal_BUF_INDEX_INT_HANDLES] = (uint32_t *) Osal_nwalLocToGlobAddr((uint32_t)nwalEntry->nwalHandleMem); if(NWAL_CHAN_HANDLE_SIZE < sizes[nwal_BUF_INDEX_INT_HANDLES]) { /* Resize Memory */ return nwal_FALSE; //while(1); } count++; bases[nwal_BUF_INDEX_PA_LLD_BUF0] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)paEntry->paBuf0); if((NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF0) < sizes[nwal_BUF_INDEX_PA_LLD_BUF0]) { /* Resize Memory */ return nwal_FALSE; //while(1); } count++; bases[nwal_BUF_INDEX_PA_LLD_BUF1] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)paEntry->paBuf1); if((NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1) < sizes[nwal_BUF_INDEX_PA_LLD_BUF1]) { /* Resize Memory */ return nwal_FALSE; //while(1); } count++; bases[nwal_BUF_INDEX_PA_LLD_BUF2] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)paEntry->paBuf2); if((NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2) < sizes[nwal_BUF_INDEX_PA_LLD_BUF2]) { /* Resize Memory */ return nwal_FALSE; //while(1); } count++; #ifdef NETAPI_ENABLE_SECURITY bases[nwal_BUF_INDEX_SA_LLD_HANDLE] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)saEntry->salldHandle); if((NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE) < sizes[nwal_BUF_INDEX_SA_LLD_HANDLE]) { /* Resize Memory */ return nwal_FALSE; //while(1); } count++; bases[nwal_BUF_INDEX_SA_CONTEXT] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)netapi_VM_SaContextVaddr); /* also save this here for easy access to sa_start */ nwalBaseAddrCfg.pScPoolBaseAddr= bases[nwal_BUF_INDEX_SA_CONTEXT]; count++; bases[nwal_BUF_INDEX_SA_LLD_CHAN_HANDLE] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)saEntry->salldChanHandle); if((NETAPI_NWAL_CONFIG_BUFSIZE_SA_LLD_HANDLE_PER_CHAN * TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS*2) < sizes[nwal_BUF_INDEX_SA_LLD_CHAN_HANDLE]) { /* Resize Memory */ return nwal_FALSE; //while(1); } count++; #else bases[nwal_BUF_INDEX_SA_LLD_HANDLE] = 0; bases[nwal_BUF_INDEX_SA_CONTEXT] = 0; bases[nwal_BUF_INDEX_SA_LLD_CHAN_HANDLE] = 0; count = count+3; #endif /* Initialize NWAL module */ nwal_getLocContextBufferReq(nwalSizeInfo.nProc, &localCtxSize); pNwalLocCtxMem = malloc(localCtxSize); nwal_createProc(bases[nwal_BUF_INDEX_INST], pNwalLocCtxMem, &nwalBaseAddrCfg); nwalGlobCfg.pBaseAddrCfg = &nwalBaseAddrCfg; nwalRetVal = nwal_create(&nwalGlobCfg, &nwalSizeInfo, sizes, bases, &gPNwalInstHandle); if(nwalRetVal != nwal_OK) { return nwal_FALSE; } return 1; } /******************************************************************** * FUNCTION PURPOSE: Internal NETAPI function to start NWAL ******************************************************************** * DESCRIPTION: Internal NETAPI function to start NWAL, per thread/core ********************************************************************/ int netapip_startNwal(Pktlib_HeapHandle pkt_heap, Pktlib_HeapHandle cmd_rx_heap, Pktlib_HeapHandle cmd_tx_heap, NETAPI_NWAL_LOCAL_CONTEXT_T *p, NETAPI_CFG_T *p_cfg, NETAPI_NWAL_GLOBAL_CONTEXT_T * p_nwal_glob_context, int master) { nwalLocCfg_t nwalLocCfg; nwalBaseAddrCfg_t nwalBaseAddrCfg; int count=0; static int first_time = 0; nwal_RetValue nwalRetVal; void* pBase = NULL; NETAPI_NWAL_SHM_T* nwalEntry = NULL; void* pNwalLocCtxMem = NULL; NETAPI_SA_SHM_T* saEntry = NULL; NETAPI_PA_SHM_T* paEntry = NULL; uint32_t baseAddr; void* instPoolSaBaseAddr; void* pScPoolBaseAddr; void* pInstPoolPaBaseAddr; void* paVirtBaseAddr; uint32_t localCtxSize; memset(&nwalLocCfg,0,sizeof(nwalLocCfg)); memset(&nwalBaseAddrCfg, 0, sizeof(nwalBaseAddrCfg_t)); /* Update the Start of Packet Offset for the default flows created * by NWAL */ nwalLocCfg.rxSopPktOffset = p_cfg->def_flow_pkt_rx_offset; nwalLocCfg.rxPktTailRoomSz = p_cfg->def_heap_tailroom_size; /* Call back registration for the core */ nwalLocCfg.pRxPktCallBack = netapip_pktioNWALRxPktCallback; nwalLocCfg.pCmdCallBack = netapip_netcpCfgNWALCmdCallBack; nwalLocCfg.pPaStatsCallBack = netapip_netcpCfgNWALCmdPaStatsReply; nwalLocCfg.pRxDmCallBack= netapip_pktioNWALSBPktCallback; //sideband mode callback /* Initialize Buffer Pool for Control packets from NetCP to Host */ nwalLocCfg.rxCtlPool.numBufPools = 1; nwalLocCfg.rxCtlPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE; nwalLocCfg.rxCtlPool.bufPool[0].bufSize = TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE; nwalLocCfg.rxCtlPool.bufPool[0].heapHandle = cmd_rx_heap; /* Initialize Buffer Pool for Control packets from Host to NetCP */ nwalLocCfg.txCtlPool.numBufPools = 1; nwalLocCfg.txCtlPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE; nwalLocCfg.txCtlPool.bufPool[0].bufSize = TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE; nwalLocCfg.txCtlPool.bufPool[0].heapHandle = cmd_tx_heap; /* Initialize Buffer Pool for L4 Packets from NetCP to Host */ nwalLocCfg.rxPktPool.numBufPools = 1; nwalLocCfg.rxPktPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE; nwalLocCfg.rxPktPool.bufPool[0].bufSize = p_cfg->def_heap_buf_size; nwalLocCfg.rxPktPool.bufPool[0].heapHandle = pkt_heap; /* Initialize Buffer Pool for Packets from Host to NetCP */ nwalLocCfg.txPktPool.numBufPools = 1; nwalLocCfg.txPktPool.bufPool[0].descSize = TUNE_NETAPI_DESC_SIZE; nwalLocCfg.txPktPool.bufPool[0].bufSize = p_cfg->def_heap_buf_size; nwalLocCfg.txPktPool.bufPool[0].heapHandle = pkt_heap; memcpy(&p->nwalLocCfg,&nwalLocCfg,sizeof(nwalLocCfg_t)); while(1) { if(master == NETAPI_PROC_MASTER) { pBase = hplib_shmOpen(); nwalEntry = (NETAPI_NWAL_SHM_T*)hplib_shmGetEntry(pBase,NWAL_ENTRY); baseAddr = (void*) netapi_VM_VirtAddr->passCfgVaddr + CSL_NETCP_CFG_SA_CFG_REGS - CSL_NETCP_CFG_REGS; saEntry = (NETAPI_SA_SHM_T*)hplib_shmGetEntry(pBase,SA_ENTRY); instPoolSaBaseAddr = (void*) saEntry; pScPoolBaseAddr = Osal_nwalLocToGlobAddr((uint32_t)netapi_VM_SaContextVaddr); paVirtBaseAddr = (void*) netapi_VM_VirtAddr->passCfgVaddr; paEntry = (NETAPI_PA_SHM_T*)hplib_shmGetEntry(pBase,PA_ENTRY); pInstPoolPaBaseAddr = (void *)paEntry; nwal_getLocContextBufferReq(TUNE_NETAPI_NUM_CORES, &localCtxSize); pNwalLocCtxMem = malloc(localCtxSize); if (pNwalLocCtxMem == NULL) { return -1; } nwalBaseAddrCfg.pSaVirtBaseAddr = baseAddr; nwalBaseAddrCfg.pInstPoolSaBaseAddr = instPoolSaBaseAddr; nwalBaseAddrCfg.pScPoolBaseAddr = pScPoolBaseAddr; nwalBaseAddrCfg.paVirtBaseAddr = paVirtBaseAddr; nwalBaseAddrCfg.pInstPoolPaBaseAddr = pInstPoolPaBaseAddr; /* this is 1 time per process */ nwal_createProc(nwalEntry, pNwalLocCtxMem, &nwalBaseAddrCfg); } /* this is for every thread including 1st thread of the process */ netapi_proc_master->spinLock.lock(&pnetapiShm->netapi_util_lock); nwalRetVal = nwal_start(gPNwalInstHandle,&nwalLocCfg); netapi_proc_master->spinLock.unlock(&pnetapiShm->netapi_util_lock); if(nwalRetVal == nwal_ERR_INVALID_STATE) { continue; } break; } if(nwalRetVal != nwal_OK) { return -1; } p->state = NETAPI_NW_CXT_LOC_ACTIVE; return 1; } /*********************************************************************** * FUNCTION PURPOSE: Internal NETAPI function to initialize the 64 bit timer. *********************************************************************** * DESCRIPTION: Internal NETAPI function to initialize the 64 bit timer. for tci6614 ONLY **********************************************************************/ int netapip_initTimer(void) { #ifdef CORTEX_A8 return t64_start(); #else return 0; #endif } /*************************************************************************** * FUNCTION PURPOSE: NETAPI internal function for virtual memory allocation. *************************************************************************** * DESCRIPTION: NETAPI internal function for virtual memory allocation. **************************************************************************/ static uint8_t* netapip_sharedMemoryMalloc(uint32_t size) { return (uint8_t *)hplib_vmMemAlloc(size + pnetapiShm->netapi_global.cfg.def_heap_extra_size , 128, 0); } /******************************************************************** * FUNCTION PURPOSE: NETAPI internal function for virtual memory free. ******************************************************************** * DESCRIPTION: NETAPI internal function for virtual memory free. ********************************************************************/ static void netapip_sharedMemoryFree(uint8_t* ptr, uint32_t size) { /* Do Nothing. */ return; } //defensive: clean out stuff hanging around // // open a bunch of free queues and zap them #define NQUEUES2CLEAR 35 static Qmss_QueueHnd tempQH[NQUEUES2CLEAR]; void netapip_cleanupAtStart(void) { int i; uint8_t isAllocated; for(i=0;inetapi_global.cfg.def_max_descriptors, pRmClientHandle); if (result != 1) { return -1; } /* Start the QMSS. */ if (netapip_startQm(pRmClientHandle) != 1) { return -1; } //clean our old junk in 1st bunch of queues that will be allocated to us netapip_cleanupAtStart(); /* Initialize the global descriptor memory region. */ result= netapip_qmSetupMemRegion( pnetapiShm->netapi_global.cfg.def_tot_descriptors_for_us, TUNE_NETAPI_DESC_SIZE, (unsigned int *) netapi_VM_QMemGlobalDescRam, pnetapiShm->netapi_global.cfg.memoryRegion, pnetapiShm->netapi_global.cfg.start_index); if(result <0) { return -1; } /* Initialize CPPI CPDMA */ result = netapip_initCppi(pRmClientHandle); if (result != 1) { return -1; } /* CPPI and Queue Manager are initialized. */ /* create main pkt heap */ /* Initialize the Shared Heaps. */ Pktlib_sharedHeapInit(); /* Populate the heap interface table. */ netapi_pktlib_ifTable.data_malloc = netapip_sharedMemoryMalloc; netapi_pktlib_ifTable.data_free = netapip_sharedMemoryFree; /* Initialize the heap configuration. */ memset ((void *)&heapCfg, 0, sizeof(Pktlib_HeapCfg)); /* Populate the heap configuration */ heapCfg.name = "netapi"; heapCfg.memRegion = memInfo.memRegion; heapCfg.sharedHeap = 1; heapCfg.useStarvationQueue = 0; heapCfg.dataBufferSize = pnetapiShm->netapi_global.cfg.def_heap_buf_size; heapCfg.numPkts = pnetapiShm->netapi_global.cfg.def_heap_n_descriptors; heapCfg.numZeroBufferPackets= pnetapiShm->netapi_global.cfg.def_heap_n_zdescriptors; heapCfg.heapInterfaceTable.data_malloc = netapi_pktlib_ifTable.data_malloc; heapCfg.heapInterfaceTable.data_free = netapi_pktlib_ifTable.data_free; heapCfg.dataBufferPktThreshold = 0; heapCfg.zeroBufferPktThreshold = 0; /* Create Shared Heap with specified configuration. */ sharedHeapHandle = Pktlib_createHeap(&heapCfg, &errCode); if (!sharedHeapHandle) { return -1;} handle->netcp_heap= sharedHeapHandle; /* Update for Control */ heapCfg.name = "netapi_control_rx"; heapCfg.sharedHeap = 1; heapCfg.dataBufferSize = TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE; heapCfg.numPkts = TUNE_NETAPI_CONFIG_NUM_CTL_RX_BUF; heapCfg.numZeroBufferPackets= 0; controlRxHeapHandle = Pktlib_createHeap(&heapCfg, &errCode); //todo -> cleanup on failure if (!controlRxHeapHandle) { return -1;} handle->netcp_control_rx_heap= controlRxHeapHandle; heapCfg.name = "netapi_control_tx"; heapCfg.numPkts = TUNE_NETAPI_CONFIG_NUM_CTL_TX_BUF; controlTxHeapHandle = Pktlib_createHeap(&heapCfg, &errCode); //todo -> cleanup on failure if (!controlTxHeapHandle) { return -1;} handle->netcp_control_tx_heap= controlTxHeapHandle; /* now NWAL */ result = netapip_initNwal(memInfo.memRegion, &netapi_pktlib_ifTable, &pnetapiShm->netapi_global.nwal_context, &pnetapiShm->netapi_global.cfg); if (result<0) { return -1; } /* Common Initialization for all cores */ while(count < TUNE_NETAPI_MAX_NUM_TRANS) { netapi_proc_global.nwal_context.transInfos[count].transId = count; count++; } result = netapip_startNwal(sharedHeapHandle, controlRxHeapHandle, controlTxHeapHandle, &handle->nwal_local, &pnetapiShm->netapi_global.cfg, &pnetapiShm->netapi_global.nwal_context, handle->master); if (result<0) { return -1; } } else { if (hplib_checkMallocArea(0) != hplib_OK) return -1; if (hplib_checkMallocArea(1) != hplib_OK) return -1; #ifdef NETAPI_ENABLE_SECURITY /* allocate 2x number of tunnels since we need one for inflow and one for data mode */ netapi_VM_SaContextVaddr = hplib_vmMemAlloc((TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS*2 * SEC_CONTEXT_SZ), 128, 0); if (!netapi_VM_SaContextVaddr) { return (-1); } #else netapi_VM_SaContextVaddr= (char *) NULL; #endif /* (3) Allocate 2 QM regions from continguous chunk above */ netapi_VM_QMemGlobalDescRam = (void *)hplib_vmMemAlloc((TUNE_NETAPI_NUM_GLOBAL_DESC * TUNE_NETAPI_DESC_SIZE), 128, 0); netapi_VM_QMemLocalDescRam = (void *)hplib_vmMemAlloc((TUNE_NETAPI_NUM_LOCAL_DESC * TUNE_NETAPI_DESC_SIZE), 128, 0); /**************************************************** * partial initialization. For process, not for SOC ***************************************************/ result = netapip_initQm (pnetapiShm->netapi_global.cfg.def_max_descriptors, pRmClientHandle); if (result != 1) { return -1; } /* Start the QMSS. */ if (netapip_startQm(pRmClientHandle) != 1) { return -1; } result= netapip_qmSetupMemRegion( pnetapiShm->netapi_global.cfg.def_tot_descriptors_for_us, TUNE_NETAPI_DESC_SIZE, (unsigned int *) netapi_VM_QMemGlobalDescRam, pnetapiShm->netapi_global.cfg.memoryRegion, pnetapiShm->netapi_global.cfg.start_index); if(result <0) { return -1; } /* Initialize CPPI CPDMA */ result = netapip_initCppi(pRmClientHandle); if (result != 1) { return -1; } /* CPPI and Queue Manager are initialized. */ /* create main pkt heap for this process */ /* Initialize the Shared Heaps. */ Pktlib_sharedHeapInit(); /* Populate the heap interface table. */ netapi_pktlib_ifTable.data_malloc = netapip_sharedMemoryMalloc; netapi_pktlib_ifTable.data_free = netapip_sharedMemoryFree; /* Initialize the heap configuration. */ memset ((void *)&heapCfg, 0, sizeof(Pktlib_HeapCfg)); /* Populate the heap configuration */ heapCfg.name = "netapi"; //heapCfg.memRegion = TUNE_NETAPI_QM_GLOBAL_REGION; heapCfg.memRegion = memInfo.memRegion; heapCfg.sharedHeap = 1; heapCfg.useStarvationQueue = 0; heapCfg.dataBufferSize = pnetapiShm->netapi_global.cfg.def_heap_buf_size; heapCfg.numPkts = pnetapiShm->netapi_global.cfg.def_heap_n_descriptors; heapCfg.numZeroBufferPackets= pnetapiShm->netapi_global.cfg.def_heap_n_zdescriptors; heapCfg.heapInterfaceTable.data_malloc = netapi_pktlib_ifTable.data_malloc; heapCfg.heapInterfaceTable.data_free = netapi_pktlib_ifTable.data_free; heapCfg.dataBufferPktThreshold = 0; heapCfg.zeroBufferPktThreshold = 0; /* Create Shared Heap with specified configuration. */ sharedHeapHandle = Pktlib_createHeap(&heapCfg, &errCode); //todo -> cleanup on failure if (!sharedHeapHandle) { return -1;} handle->netcp_heap= sharedHeapHandle; //open shared heap handle but create new controlRx & Tx heaps for this //process /* Update for Control */ heapCfg.name = "netapi_control_rx";/*todo:add random#*/ heapCfg.sharedHeap = 1; heapCfg.dataBufferSize = TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE; heapCfg.numPkts = TUNE_NETAPI_CONFIG_NUM_CTL_RX_BUF; heapCfg.numZeroBufferPackets= 0; controlRxHeapHandle = Pktlib_createHeap(&heapCfg, &errCode); if (!controlRxHeapHandle) { return -1;} handle->netcp_control_rx_heap= controlRxHeapHandle; heapCfg.name = "netapi_control_tx"; heapCfg.numPkts = TUNE_NETAPI_CONFIG_NUM_CTL_TX_BUF; controlTxHeapHandle = Pktlib_createHeap(&heapCfg, &errCode); if (!controlTxHeapHandle) { return -1;} handle->netcp_control_tx_heap= controlTxHeapHandle; /* Common Initialization for all threads in process */ while(count < TUNE_NETAPI_MAX_NUM_TRANS) { netapi_proc_global.nwal_context.transInfos[count].transId = count; count++; } result = netapip_startNwal(sharedHeapHandle, controlRxHeapHandle, controlTxHeapHandle, &handle->nwal_local, &pnetapiShm->netapi_global.cfg, &pnetapiShm->netapi_global.nwal_context, handle->master); if (result<0) { return -1; } } //get timer running #ifdef CORTEX_A8 netapip_initTimer(); #endif return 0; } /**************************************************************************** * FUNCTION PURPOSE: NETAPI internal function which performs clean for linux user space **************************************************************************** * DESCRIPTION: NETAPI internal function which performs clean for linux user space ***************************************************************************/ void netapip_zapQ(int queueNum) { int i; if (!queueNum) { return; } for (i=0;;i+=1 ) { /* Pop descriptor from source queue */ if (pktio_mQmssQueuePopRaw(queueNum) == NULL) { break; } } } /**************************************************************************** * FUNCTION PURPOSE: NETAPI internal function to display internal heap stats. **************************************************************************** * DESCRIPTION: NETAPI internal function to display internal heap stats. ***************************************************************************/ void netapi_dump_internal_heap_stats(void) { Pktlib_HeapStats pktLibHeapStats; Pktlib_getHeapStats(netapi_get_global()->nwal_context.pa2sa_heap,&pktLibHeapStats); printf("PA2SA(ingress) stats> #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets, pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage); printf(" > #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n", pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter, pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter); Pktlib_getHeapStats(netapi_get_global()->nwal_context.sa2pa_heap,&pktLibHeapStats); printf("SA2PA stats> #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets, pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage); printf(" > #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n", pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter, pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter); }