* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *****************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
#include "netapi.h"
typedef struct PRESET_Tag
static void netapiSharedMemoryFree(uint8_t* ptr);
static int system_init(NETAPI_HANDLE_T *);
static void get_presets(PRESET_T * p_preset);
-static void zapQ(int queueNum);
static void netapi_cleanup_at_start(void);
/*------------globals-----------------*/
#define NUM_HOST_DESC (TUNE_NETAPI_NUM_LOCAL_DESC)
#define SIZE_LOCAL_DESC (TUNE_NETAPI_DESC_SIZE)
-#define NUM_SHARED_DESC (TUNE_NETAPI_NUM_GLOBAL_DESC)
#define SIZE_SHARED_DESC (TUNE_NETAPI_DESC_SIZE)
#define CONFIG_BUFSIZE_PA_INST 256
#define CONFIG_BUFSIZE_L2_TABLE 1000
#define CONFIG_BUFSIZE_L3_TABLE 4000
+static NETAPI_CFG_T netapi_default_cfg=
+{
+TUNE_NETAPI_PERM_MEM_SZ,
+0, //start of packet offset for hw to place data on rx for default flow
+TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
+TUNE_NETAPI_NUM_GLOBAL_DESC, //total we will use
+TUNE_NETAPI_DEFAULT_NUM_BUFFERS, //#descriptors+buffers in default heap
+TUNE_NETAPI_DEFAULT_NUM_SOLO_DESCRIPTORS, //#descriptors w/o buffers in default heap
+TUNE_NETAPI_DEFAULT_BUFFER_SIZE, //size of buffers in default heap
+0,0
+
+};
+
static Pktlib_HeapIfTable netapi_pktlib_ifTable;
static NETAPI_GLOBAL_T netapi_global;
NETAPI_GLOBAL_T * netapi_get_global(){ return &netapi_global;}
/* utility API for NETAPI user to get pktlib if table to use if he creates his own heap */
Pktlib_HeapIfTable *netapi_getPktlibIfTable(void) {return &netapi_pktlib_ifTable;}
-
+//zap a queue
+void netapi_zapQ(int queueNum);
/*-------------------------------------
* initialize NETAPI instance
*-------------------------------------*/
-NETAPI_T netapi_init(int master)
+NETAPI_T netapi_init(int master, NETAPI_CFG_T * p_cfg)
{
int i;
int err;
/* global stuff (if master) */
if (master==NETAPI_SYS_MASTER)
{
+ if (p_cfg) memcpy(&netapi_global.cfg,p_cfg, sizeof(NETAPI_CFG_T));
+ else memcpy(&netapi_global.cfg,&netapi_default_cfg, sizeof(NETAPI_CFG_T));
for(i=0;i<NETAPI_MAX_PKTIO;i++)
{
netapi_global.pktios[i].qn.qNum=-1;
*-------------------------------*/
void netapi_shutdown(NETAPI_T h)
{
+ int i;
NETAPI_HANDLE_T * p = (NETAPI_HANDLE_T *) h;
if (!p) return;
- printf(">netapi: shutdown not fully implemented\n");
+ printf(">netapi: WARNING shutdown may not be fully implemented\n");
if (p->master)
{
- /* close heap */
- /* close queues */
- netapi_cleanup_at_start();
- /* close pa */
+ /* close nwal */
+ nwal_delete(netapi_global.nwal_context.nwalInstHandle);
+
+ /* close heaps */
+ netapi_closeHeap(h, p->netcp_heap);
+ netapi_closeHeap(h, p->netcp_control_heap);
+ netapi_closeHeap(h, netapi_get_global()->nwal_context.pa2sa_heap);
+ netapi_closeHeap(h, netapi_get_global()->nwal_context.sa2pa_heap);
+
+ //loop over registered heaps
+ for(i=0;i<TUNE_NETAPI_MAX_HEAPS;i++)
+ {
+ if (p->createdHeaps[i]) {netapi_closeHeap(h,p->createdHeaps[i]);p->createdHeaps[i]=NULL;}
+ }
+ netapi_cleanup_at_start(); //clear 1st 50 not-specified queues..
+ netapi_VM_memory_teardown();
}
free(p);
return;
/*-------------------utilities-------------------*/
static uint8_t* netapiSharedMemoryMalloc(uint32_t size)
{
-return (uint8_t *)netapi_VM_memAlloc(size, 128);
+return (uint8_t *)netapi_VM_memAlloc(size +netapi_global.cfg.def_heap_extra_size , 128);
}
static void netapiSharedMemoryFree(uint8_t* ptr)
{
int32_t result;
Pktlib_HeapHandle sharedHeapHandle;
- Pktlib_HeapHandle controlHeapHandle;
+ Pktlib_HeapHandle controlHeapHandle;
+ Pktlib_HeapCfg heapCfg;
+ int32_t errCode;
/* initialize all the memory we are going to use
- chunk for buffers, descriptors
netapi_init_timer();
/* Initialize Queue Manager Sub System */
- result = netapi_init_qm ();
+ result = netapi_init_qm (netapi_global.cfg.def_max_descriptors);
if (result != 1)
{
return -1;
/* Initialize the global descriptor memory region. */
result= netapi_qm_setup_mem_region(
- NUM_SHARED_DESC,
+ netapi_global.cfg.def_tot_descriptors_for_us,
SIZE_SHARED_DESC,
- netapi_VM_QMemGlobalDescRam,
+ (unsigned int *) netapi_VM_QMemGlobalDescRam,
NETAPI_GLOBAL_REGION);
if(result <0) {printf(">netapi; can't setup QM shared region\n"); return -1;}
if(result <0) {printf("can't setup local region\n"); return -1;}
#endif
/* Initialize CPPI CPDMA */
+
result = netapi_init_cppi ();
if (result != 1)
{
netapi_pktlib_ifTable.data_malloc = netapiSharedMemoryMalloc;
netapi_pktlib_ifTable.data_free = netapiSharedMemoryFree;
+ /* Initialize the heap configuration. */
+ memset ((void *)&heapCfg, 0, sizeof(Pktlib_HeapCfg));
+ /* Populate the heap configuration */
+ heapCfg.name = "netapi";
+ heapCfg.memRegion = NETAPI_GLOBAL_REGION;
+ heapCfg.sharedHeap = 1;
+ heapCfg.useStarvationQueue = 0;
+ heapCfg.dataBufferSize = netapi_global.cfg.def_heap_buf_size;
+ heapCfg.numPkts = netapi_global.cfg.def_heap_n_descriptors;
+ heapCfg.numZeroBufferPackets= 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. */
-#define SHARED_MAX_DATA_SIZE (TUNE_NETAPI_DEFAULT_BUFFER_SIZE)
- sharedHeapHandle = Pktlib_createHeap("netapi", Qmss_MemRegion_MEMORY_REGION0,
- 1,
- SHARED_MAX_DATA_SIZE,
- TUNE_NETAPI_DEFAULT_NUM_BUFFERS,
- TUNE_NETAPI_DEFAULT_NUM_SOLO_DESCRIPTORS,
- &netapi_pktlib_ifTable);
- //todo -> cleanup on failure
- if (!sharedHeapHandle) { printf(">'netapi' heap create failed\n"); return -1;}
- handle->netcp_heap= sharedHeapHandle;
-
- controlHeapHandle = Pktlib_createHeap("netapi_control", Qmss_MemRegion_MEMORY_REGION0,
- 1,
- TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE,
- TUNE_NETAPI_CONFIG_NUM_CTL_BUF,
- 0,
- &netapi_pktlib_ifTable);
+ sharedHeapHandle = Pktlib_createHeap(&heapCfg, &errCode);
+ //todo -> cleanup on failure
+ if (!sharedHeapHandle) { printf(">'netapi' heap create failed, Error Code: %d\n",errCode); return -1;}
+ handle->netcp_heap= sharedHeapHandle;
+
+
+ /* Update for Control */
+ heapCfg.name = "netapi_control";
+ heapCfg.sharedHeap = 1;
+ heapCfg.dataBufferSize = TUNE_NETAPI_CONFIG_MAX_CTL_RXTX_BUF_SIZE;
+ heapCfg.numPkts = TUNE_NETAPI_CONFIG_NUM_CTL_BUF;
+ heapCfg.numZeroBufferPackets= 0;
+
+ controlHeapHandle = Pktlib_createHeap(&heapCfg, &errCode);;
//todo -> cleanup on failure
- if (!controlHeapHandle) { printf(">netapi -'netapicontrol' heap create failed\n"); return -1;}
+ if (!controlHeapHandle) { printf(">netapi -'netapicontrol' heap create failed, Error Code: %d\n",errCode); return -1;}
handle->netcp_control_heap= controlHeapHandle;
/* now NWAL */
result = netapi_init_nwal(
- Qmss_MemRegion_MEMORY_REGION0,
+ NETAPI_GLOBAL_REGION,
&netapi_pktlib_ifTable,
- &netapi_global.nwal_context);
+ &netapi_global.nwal_context,
+ &netapi_global.cfg);
if (result<0) {printf(">netapi init_nwal() failed\n"); return -1; }
/* start NWAL */
result = netapi_start_nwal(sharedHeapHandle,
controlHeapHandle,
&handle->nwal_local,
+ &netapi_global.cfg,
&netapi_global.nwal_context);
if (result<0) {printf(">netapi start_nwal() failed\n"); return -1; }
//** success **
/* poll the garbage queues of all registered heaps */
void netapi_pollHeapGarbage(NETAPI_T h)
{
+int i;
NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
Pktlib_garbageCollection(n->netcp_heap);
- /* todo: register heaps of app */
+ //no need to do garbage collection on other internal heaps
+ for(i=0;i<TUNE_NETAPI_MAX_HEAPS;i++)
+ {
+ if (n->createdHeaps[i]) Pktlib_garbageCollection(n->createdHeaps[i]);
+ }
}
-/* todo */
-int netapi_registerHeap(NETAPI_T p, Pktlib_HeapHandle h){ return 0;}
-int netapi_unregisterHeap(NETAPI_T p, Pktlib_HeapHandle h) { return 0;}
-
/* poll NETCP control queue for responses */
void netapi_netcpPoll(NETAPI_T p)
{
*****************************************************************/
//clean up function for linux user space
-static void zapQ(int queueNum)
+void netapi_zapQ(int queueNum)
{
char * descPtr;
int i;
+if (!queueNum) return;
for (i=0;;i+=1 )
{
/* Pop descriptor from source queue */
}
else {/*printf("netapi qzap in play\n");*/}
}
- if(i) printf(">netapi: @recovery - %d descriptors cleaned\n",i);
+ if(i) printf(">netapi: @recovery - %d descriptors cleaned from qn %d\n",i, queueNum);
}
//defensive: clean out stuff hanging around
{
tempQH[i] = Qmss_queueOpen(Qmss_QueueType_GENERAL_PURPOSE_QUEUE,
QMSS_PARAM_NOT_SPECIFIED, &isAllocated);
- zapQ(tempQH[i]);
+ netapi_zapQ(tempQH[i]);
}
for(i=0;i<NQUEUES2CLEAR;i++)
}
-
+/********************************
+ * clean up a pktlib heap
+ ***********************************/
+int netapi_closeHeap(NETAPI_T h, Pktlib_HeapHandle p)
+{
+Qmss_QueueHnd q;
+Pktlib_garbageCollection(p);
+q = Pktlib_getZeroHeapQueue(p);
+netapi_zapQ(q);
+q= Pktlib_getInternalHeapQueue(p);
+netapi_zapQ(q);
+}