/********************************* * FILE: pktio.c * PURPOSE: pktio library for NETAPI ************************************************************** * FILE: pktio.c * * DESCRIPTION: pktio source file for user space transport * library * * REVISION HISTORY: rev 0.0.1 * * Copyright (c) Texas Instruments Incorporated 2010-2011 * * 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 #include #include #include #include "netapi.h" #include "pktio.h" #include "netapi_util.h" static hplib_spinLock_T pktio_lock = hplib_spinLock_UNLOCKED_INITIALIZER; /*--------------------Utilites-----------------*/ static PKTIO_HANDLE_T * pktiop_get_free_channel_slot(NETAPI_T n) { PKTIO_HANDLE_T ** pp = (PKTIO_HANDLE_T **) netapi_get_pktio_list(n); int i; for(i=0;iinuse != PKTIO_INUSE) { pp[i]->inuse = PKTIO_INUSE; return pp[i]; } } return NULL; } /*-----------------------------------------------------*/ /* optimized send/rcv functions */ /*----------------------------------------------------*/ //******************************************** //send pkt via ipc queue //******************************************** static int pktio_send_ipc(struct PKTIO_HANDLE_tag * pp, Ti_Pkt *pkt, PKTIO_METADATA_T *m, int * err) { PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp; *err=0; #ifdef PKTIO_GET_BENCHMARK p->vv8p=netapi_timing_stop(); #endif Qmss_queuePushDesc (p->q, (void*)pkt); #ifdef PKTIO_GET_BENCHMARK p->vv9p=netapi_timing_stop(); #endif return 1; } //******************************************** //send pkt to NETCP via NWAL //******************************************** static int pktio_send_nwal(struct PKTIO_HANDLE_tag * pp, Ti_Pkt *pkt, PKTIO_METADATA_T *m, int * err) { PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp; nwalTxPktInfo_t * pPktInfo=m->u.tx_meta; nwal_RetValue res; *err=0; pPktInfo->pPkt = pkt; #ifdef PKTIO_GET_BENCHMARK p->vv11p=netapi_timing_stop(); #endif res=nwal_send(p->nwalInstanceHandle, m->sa_handle,pPktInfo); #ifdef PKTIO_GET_BENCHMARK p->vv12p=netapi_timing_stop(); #endif if (res != nwal_OK) { *err = NETAPI_ERR_NWAL_TX_ERR -res;} return 1; } //******************************************** //send to SA via SB queue //******************************************** static int pktio_send_sb(struct PKTIO_HANDLE_tag * pp, Ti_Pkt *pkt, PKTIO_METADATA_T *m, int * err) { PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp; nwalDmTxPayloadInfo_t *pPktInfoSB = m->u.tx_sb_meta; nwal_RetValue res; *err=0; pPktInfoSB->pPkt = pkt; res=nwal_sendDM(p->nwalInstanceHandle, m->sa_handle,pPktInfoSB); if (res != nwal_OK) *err = NETAPI_ERR_NWAL_TX_ERR -res; return 1; } //******************************************** //dummy. return err //******************************************** static int pktio_send_dummy(struct PKTIO_HANDLE_tag * p, Ti_Pkt *pkt, PKTIO_METADATA_T *m, int * err) { *err = NETAPI_ERR_BAD_INPUT; return -1; } //******************************************* //dummy poll //******************************************* static int pktio_poll_dummy(struct PKTIO_HANDLE_tag * p, PKTIO_POLL_T * p_poll_cfg, int * err) { *err= NETAPI_ERR_BAD_INPUT; return 0; } //******************************************** //poll IPC queue //******************************************** static int pktio_poll_ipc(struct PKTIO_HANDLE_tag * pp, PKTIO_POLL_T * p_poll_cfg, int * err) { Ti_Pkt * pkt_list[PKTIO_MAX_RECV]; PKTIO_METADATA_T meta_s[PKTIO_MAX_RECV]; PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp; int r=0; int n; Ti_Pkt * temp; *err=0; n= (p->max_n< PKTIO_MAX_RECV) ? p->max_n : PKTIO_MAX_RECV; for(r=0;rvv7p=netapi_timing_stop(); #endif temp=(Ti_Pkt*)(Cppi_HostDesc*)QMSS_DESC_PTR(Qmss_queuePop(p->q)); #ifdef PKTIO_GET_BENCHMARK if (r==0) p->vv10p=netapi_timing_stop(); #endif if(!temp) break; /* process meta data */ pkt_list[r]= temp; meta_s[r].flags1=0x1; } if (r) p->cb((struct PKTIO_HANDLE_tag *)p, pkt_list, &meta_s[0], r, 0LL); return r; } //******************************************** //poll nwal data queues for pkts from netcp //******************************************** static int pktio_poll_nwal(struct PKTIO_HANDLE_tag * pp, PKTIO_POLL_T * p_poll_cfg, int * err) { int r=0; PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp; *err=0; /* Poll for common L2/L3 packets and L4 class pkts (todo-> only do L4 if classifiers are set.. optimizaion maybe? */ #ifdef PKTIO_GET_BENCHMARK p->vv13p=netapi_timing_stop(); #endif r=nwal_pollPkt(p->nwalInstanceHandle, p->poll_flags, (uint32_t) p, p->max_n, QMSS_PARAM_NOT_SPECIFIED, (void*) NULL); return r; } //******************************************** //poll nwal sideband queues for pkts from SA //******************************************** static int pktio_poll_sb(struct PKTIO_HANDLE_tag * pp, PKTIO_POLL_T * p_poll_cfg, int * err) { int r=0; PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp; *err=0; r=nwal_pollDm(p->nwalInstanceHandle, nwal_POLL_DM_DEF_SB_SA_Q, (uint32_t) p, p->max_n, QMSS_PARAM_NOT_SPECIFIED, (void *) NULL); return r; } //******************************************** //poll app-provided netcp rx queue //******************************************** static int pktio_poll_nwal_adj(struct PKTIO_HANDLE_tag * pp, PKTIO_POLL_T * p_poll_cfg, int * err) { int r=0; PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp; *err=0; /* Poll for common L2/L3 packets and L4 class pkts (todo-> only do L4 if classifiers are set.. optimizaion maybe? */ #ifdef PKTIO_GET_BENCHMARK p->vv14p=netapi_timing_stop(); #endif r=nwal_pollPkt(p->nwalInstanceHandle, nwal_POLL_APP_MANAGED_PKT_Q, (uint32_t) p, p->max_n, p->q, (void *) NULL); return r; } //******************************************** //poll app-defined sideband queues for pkts from SA //******************************************** static int pktio_poll_sb_adj(struct PKTIO_HANDLE_tag * pp, PKTIO_POLL_T * p_poll_cfg, int * err) { int r=0; PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp; *err=0; r=nwal_pollDm(p->nwalInstanceHandle, nwal_POLL_DM_APP_MANAGED_Q, (uint32_t) p, p->max_n, p->q, (void *) NULL); return r; } /*-----------------------MAIN API----------------------*/ /* create a channel */ PKTIO_HANDLE_T * pktio_create(NETAPI_T n, char * name, PKTIO_CB cb, PKTIO_CFG_T * p_cfg, int * err) { int r = 0; PKTIO_HANDLE_T *p; uint8_t isAllocated; *err=0; if ((!p_cfg)||(!name)) {*err=NETAPI_ERR_BAD_INPUT; return NULL;} if ((p_cfg->flags2 & PKTIO_PKT) &&(p_cfg->flags1& PKTIO_W)) { *err=NETAPI_ERR_BAD_INPUT; return NULL;}; if ((p_cfg->flags2 & PKTIO_SB) &&(p_cfg->flags1& PKTIO_W)) { *err=NETAPI_ERR_BAD_INPUT; return NULL;}; /* get a free channel handle */ p=pktiop_get_free_channel_slot(n); if (!p) {*err = PKTIO_NOMEM; return (p); } /* p->inuse= PKTIO_INUSE; moved to pktiop_get_free_channel_slot */ p->back = n; p->cb = cb; p->max_n = p_cfg->max_n; p->_poll=pktio_poll_dummy; p->_send=pktio_send_dummy; memcpy((char *)&p->cfg, (char*) p_cfg, sizeof(PKTIO_CFG_T)); /* create a general queue (for now). todo: allow qnum to be passed in */ p->q = Qmss_queueOpen(Qmss_QueueType_GENERAL_PURPOSE_QUEUE, QMSS_PARAM_NOT_SPECIFIED, &isAllocated); if (p->q == (Qmss_QueueHnd) NULL) { printf(">pktio_create: queueOpen failed\n"); p->inuse=0; *err= NETAPI_ERR_QLLD; ///queue lld error return NULL; } p->qInfo = Qmss_getQueueNumber(p->q); if (p_cfg->flags2 & PKTIO_PKT) { p->use_nwal = PKTIO_4_ADJ_NWAL; p->_poll=pktio_poll_nwal_adj; p->nwalInstanceHandle = netapi_return_nwal_instance_handle(n); } else if (p_cfg->flags2 & PKTIO_SB) { p->use_nwal = PKTIO_4_ADJ_SB; p->_poll=pktio_poll_sb_adj; p->nwalInstanceHandle = netapi_return_nwal_instance_handle(n); } else { p->use_nwal=0; if (p_cfg->flags1& PKTIO_W) p->_send=pktio_send_ipc; if (p_cfg->flags1& PKTIO_R) p->_poll=pktio_poll_ipc; } /* save name */ strncpy(p->name,name, strlen(name)flags1 & PKTIO_GLOBAL) ) { //todo: make sure this succeeds.. hplib_mSpinLockLock(&pktio_lock); r=netapi_add_global_pktio(n, name, &p->qInfo); hplib_mSpinLockUnlock(&pktio_lock); } ((NETAPI_HANDLE_T *)n )->n_pktios+=1; return p; } /***********************************************************/ /************** open an existing channel. *****************/ /***********************************************************/ PKTIO_HANDLE_T * pktio_open(NETAPI_T n, char *name, PKTIO_CB cb, PKTIO_CFG_T * p_cfg, int * err) { int r=0; PKTIO_HANDLE_T *p, *p2; uint8_t isAllocated; *err=0; Qmss_Queue *p_qnum; if ((!p_cfg)||(!name)) {*err=NETAPI_ERR_BAD_INPUT; return NULL;} /* get a free channel handle */ p=pktiop_get_free_channel_slot(n); if (!p) {*err = PKTIO_NOMEM; return (p); } ((NETAPI_HANDLE_T *)n)->n_pktios+=1; p->inuse= PKTIO_INUSE; p->back = n; p->cb = cb; p->max_n = p_cfg->max_n; p->_poll=pktio_poll_dummy; p->_send=pktio_send_dummy; memcpy((char *)&p->cfg, (char*) p_cfg, sizeof(PKTIO_CFG_T)); /* special handling of NETCP_RX, NETCP_TX */ if( (!strcmp(name, NETCP_RX)) || (!strcmp(name,NETCP_TX)) ) { printf("pktio_open: trace 1\n"); /* these have already been opened internally, so don't search in global list */ p->use_nwal = PKTIO_DEF_NWAL; p->q = 0; p->nwalInstanceHandle = netapi_return_nwal_instance_handle(n); printf("pktio_open1: nwalInstanceHandle 0x%x\n", p->nwalInstanceHandle); if (!strcmp(name,NETCP_RX)) { p->_poll=pktio_poll_nwal; p->poll_flags= nwal_POLL_DEFAULT_GLOB_PKT_Q| nwal_POLL_DEFAULT_PER_PROC_PKT_Q; } if (!strcmp(name,NETCP_TX)) p->_send=pktio_send_nwal; } else if( (!strcmp(name, NETCP_SB_RX)) || (!strcmp(name,NETCP_SB_TX)) ) { /* these have already been opened internally, so don't search in global list */ p->use_nwal = PKTIO_DEF_SB; p->q = 0; p->nwalInstanceHandle = netapi_return_nwal_instance_handle(n); if (!strcmp(name,NETCP_SB_RX)) p->_poll=pktio_poll_sb; if (!strcmp(name,NETCP_SB_TX)) p->_send=pktio_send_sb; } else { hplib_mSpinLockLock(&pktio_lock); /* find queue in global list */ p_qnum = netapi_find_global_pktio(n, name); printf("pktio_open: trace 2\n"); hplib_mSpinLockUnlock(&pktio_lock); if (!p_qnum ) { printf(">pktio_open: can't find %s\n",name); p->inuse=0; *err= NETAPI_ERR_NOTFOUND; ///queue lld error return NULL; } /* open a general queue (for now). use qnum that was just found */ p->q = Qmss_queueOpen(Qmss_QueueType_GENERAL_PURPOSE_QUEUE, p_qnum->qNum , &isAllocated); if (p->q == (Qmss_QueueHnd) NULL) { printf(">pktio_create: queueOpen failed\n"); p->inuse=0; *err= NETAPI_ERR_QLLD; ///queue lld error return NULL; } p->qInfo = Qmss_getQueueNumber(p->q); printf("pktio_open: queueMgr %d\, queueNum; %d\n", p->qInfo.qMgr, p->qInfo.qNum); if (p_cfg->flags2 & PKTIO_PKT) { p->use_nwal = PKTIO_4_ADJ_NWAL; //additonal RX q for nwal p->_poll = pktio_poll_nwal_adj; p->nwalInstanceHandle = netapi_return_nwal_instance_handle(n); printf("pktio_open: nwalInstanceHandle 0x%x\n", p->nwalInstanceHandle); } else if (p_cfg->flags2 & PKTIO_SB) { p->use_nwal = PKTIO_4_ADJ_SB; //additional RX q for sideband with NWAL p->_poll = pktio_poll_sb_adj; p->nwalInstanceHandle = netapi_return_nwal_instance_handle(n); } else { p->use_nwal=0; //not handled by nwal if (p_cfg->flags1& PKTIO_W) p->_send=pktio_send_ipc; if (p_cfg->flags1& PKTIO_R) p->_poll=pktio_poll_ipc; } } /* save name */ strncpy(p->name,name, strlen(name)name); return p; } /***********************************************************/ /************** control the channel ****************/ /***********************************************************/ void pktio_control(PKTIO_HANDLE_T * p, PKTIO_CB cb, PKTIO_CFG_T * p_cfg, PKTIO_CONTROL_T * p_control, int *err) { if (!p) { *err=1; return;} if (cb) { p->cb = cb; } if (p_control) { /* todo: check for validity, eg don't allow clear of NETCP TX queues */ /* todo: implement divert */ switch(p_control->op) { //clear the queue case(PKTIO_SET_POLL_FLAGS): p->poll_flags=p_control->poll_flags; break; case(PKTIO_CLEAR): netapi_zapQ(p->q); break; case(PKTIO_DIVERT): default: printf(">pktio_control: pktio_control op %d not implemented\n",p_control->op); *err= NETAPI_ERR_NOT_IMPLEMENTED; break; } } //all we configure is max_n. Can't change type of queue, rx/tx, etc if (p_cfg) { p->max_n = p_cfg->max_n; } *err=0; return; } /***********************************************************/ /*****************close ***************************/ /***********************************************************/ void pktio_close(PKTIO_HANDLE_T * p, int * err) { if(!p) { *err=1; return;} *err=0; if (p->q) Qmss_queueClose(p->q); //LLD keeps reference count p->q=-1; p->inuse=0; ((NETAPI_HANDLE_T *)p->back)->n_pktios-=1; return; } /***********************************************************/ /*****************Delete***************************/ /***********************************************************/ void pktio_delete(PKTIO_HANDLE_T * p, int * err) { if(!p) { *err=1; return;} *err=0; /* remove from name list */ hplib_mSpinLockLock(&pktio_lock); netapi_del_global_pktio((NETAPI_HANDLE_T *)p->back, p->name); hplib_mSpinLockUnlock(&pktio_lock); if((p->use_nwal != PKTIO_DEF_NWAL) && (p->use_nwal != PKTIO_DEF_SB)) { netapi_zapQ(p->q); //since we are deleting, zap the queue Qmss_queueClose(p->q); } p->q=-1; p->inuse=0; ((NETAPI_HANDLE_T *)p->back)->n_pktios-=1; return ; } /***********************************************************/ /*****************send *************************/ /***********************************************************/ int pktio_send_genric(PKTIO_HANDLE_T * p, Ti_Pkt *pkt, PKTIO_METADATA_T *m, int * err) { nwalTxPktInfo_t * pPktInfo=m->u.tx_meta; nwal_RetValue res; *err=0; if(! (p->cfg.flags1&PKTIO_W)) return 0; if ((p->use_nwal== PKTIO_DEF_NWAL) ) { pPktInfo->pPkt = pkt; #ifdef PKTIO_GET_BENCHMARK p->vv11p=netapi_timing_stop(); #endif res=nwal_send(p->nwalInstanceHandle, m->sa_handle,pPktInfo); #ifdef PKTIO_GET_BENCHMARK p->vv12p=netapi_timing_stop(); #endif if (res != nwal_OK) { printf("nwal send err= %d (%x)\n", res, res); *err = NETAPI_ERR_NWAL_TX_ERR -res;} } else if ((p->use_nwal== PKTIO_DEF_SB) ) { nwalDmTxPayloadInfo_t *pPktInfoSB = m->u.tx_sb_meta; pPktInfoSB->pPkt = pkt; res=nwal_sendDM(p->nwalInstanceHandle, m->sa_handle,pPktInfoSB); if (res != nwal_OK) *err = NETAPI_ERR_NWAL_TX_ERR -res; } else { /* tod: meta data for non netcp xfers */ /* process meta data */ #ifdef PKTIO_GET_BENCHMARK p->vv8p=netapi_timing_stop(); #endif Qmss_queuePushDesc (p->q, (void*)pkt); #ifdef PKTIO_GET_BENCHMARK p->vv9p=netapi_timing_stop(); #endif } return 1; } /***********************************************************/ /*******************send multiple**************************/ /***********************************************************/ int pktio_sendMulti(PKTIO_HANDLE_T * p, Ti_Pkt * pkt[], PKTIO_METADATA_T * m[], int np, int* err) { nwal_RetValue res; int r=0; *err=0; if(! p->cfg.flags1&PKTIO_W) return 0; if ((p->use_nwal== PKTIO_DEF_NWAL) ) { for(r=0;ru.tx_meta; pPktInfo->pPkt = pkt[r]; res=nwal_send(p->nwalInstanceHandle,m[r]->sa_handle,pPktInfo); if (res != nwal_OK) *err = NETAPI_ERR_NWAL_TX_ERR -res; } } else if ((p->use_nwal== PKTIO_DEF_SB) ) { for(r=0;ru.tx_sb_meta; pPktInfoSB->pPkt = pkt[r]; res=nwal_sendDM(p->nwalInstanceHandle, m[r]->sa_handle,pPktInfoSB); if (res != nwal_OK) *err = NETAPI_ERR_NWAL_TX_ERR -res; } } else { for(r=0;rq, (void*) pkt[r]); } } return r; } /***********************************************************/ /******************* polling **********************/ /***********************************************************/ /* poll a particular channel */ int pktio_poll_generic(PKTIO_HANDLE_T * p, PKTIO_POLL_T * p_poll_cfg, int * err) { int r=0; int n; Ti_Pkt * temp; Ti_Pkt * pkt_list[PKTIO_MAX_RECV]; PKTIO_METADATA_T meta_s[PKTIO_MAX_RECV]; //uint64_t ts= netapi_getTimestamp(); //get_ts uint64_t ts=0LL; if(! p->cfg.flags1&PKTIO_R) return 0; /** poll the netcp default RX queue we squirt out below */ if (p->use_nwal==PKTIO_DEF_NWAL) { /* Poll for common L2/L3 packets and L4 class pkts (todo-> only do L4 if classifiers are set.. optimizaion maybe? */ #ifdef PKTIO_GET_BENCHMARK p->vv13p=netapi_timing_stop(); #endif r=nwal_pollPkt(p->nwalInstanceHandle, p->poll_flags, (uint32_t) p, p->max_n, QMSS_PARAM_NOT_SPECIFIED, (void*) NULL); } /** poll a netcp RX queue. we squirt out below */ else if (p->use_nwal==PKTIO_4_ADJ_NWAL) { /* Poll an additional NETCP RX queue */ #ifdef PKTIO_GET_BENCHMARK p->vv14p=netapi_timing_stop(); #endif r=nwal_pollPkt(p->nwalInstanceHandle, nwal_POLL_APP_MANAGED_PKT_Q, (uint32_t) p, p->max_n, p->q, (void *) NULL); } /** poll the NETCP default SideBand (data mode -dm) return queue **/ else if(p->use_nwal==PKTIO_DEF_SB) { r=nwal_pollDm(p->nwalInstanceHandle, nwal_POLL_DM_DEF_SB_SA_Q, (uint32_t) p, p->max_n, QMSS_PARAM_NOT_SPECIFIED, (void *) NULL); } /** poll an app define SideBand (data mode -dm) return queue **/ else if (p->use_nwal==PKTIO_4_ADJ_SB) { r=nwal_pollDm(p->nwalInstanceHandle, nwal_POLL_DM_APP_MANAGED_Q, (uint32_t) p, p->max_n, p->q, (void *) NULL); } /* poll an IPC queue */ else { *err=0; n= (p->max_n< PKTIO_MAX_RECV) ? p->max_n : PKTIO_MAX_RECV; for(r=0;rvv7p=netapi_timing_stop(); #endif temp=(Ti_Pkt*)(Cppi_HostDesc*)QMSS_DESC_PTR(Qmss_queuePop(p->q)); #ifdef PKTIO_GET_BENCHMARK if (r==0) p->vv10p=netapi_timing_stop(); #endif if(!temp) break; /* process meta data */ pkt_list[r]= temp; meta_s[r].flags1=0x1; } if (r) p->cb((struct PKTIO_HANDLE_tag *)p, pkt_list, &meta_s[0], r, ts); } return r; } /***********************************************************/ /** poll all channels attached to this handle */ /***********************************************************/ int pktio_pollAll(NETAPI_T handle, PKTIO_POLL_T * p_poll_cfg, int *err) { int i=0; int r=0; int err2; int cnt=0; PKTIO_HANDLE_T **pp =( PKTIO_HANDLE_T **) netapi_get_pktio_list(handle); *err=0; for(i=0;in_pktios;i++) { if (pp[i]->inuse != PKTIO_INUSE) continue; if(!(pp[i]->cfg.flags1&PKTIO_R)) continue; r+=pktio_poll(pp[i], p_poll_cfg, &err2); cnt+=1; if (err2) { *err = err2; break;} } return r; } /***** this is the callback we registered with NWAL for pkt reception *****/ /* appcookie -> pktio handle */ void netapi_NWALRxPktCallback (uint32_t appCookie, uint16_t numPkts, nwalRxPktInfo_t* pPktInfo, uint64_t timestamp, nwal_Bool_t* pFreePkt) { PKTIO_HANDLE_T * p = (PKTIO_HANDLE_T *) appCookie; int r=0; int n; Ti_Pkt * pkt_list[PKTIO_MAX_RECV]; PKTIO_METADATA_T meta_s[PKTIO_MAX_RECV]; #ifdef PKTIO_GET_BENCHMARK p->vv15p=netapi_timing_stop(); #endif for(r=0;rcb((struct PKTIO_HANDLE_tag *)p, pkt_list, &meta_s[0], r, timestamp); } /***** this is the callback we registered with NWAL for crypto callbcak *****/ /* appcookie -> pktio handle */ void netapi_NWALSBPktCallback (uint32_t appCookie, uint16_t numPkts, nwalDmRxPayloadInfo_t* pDmRxPktInfo, nwal_Bool_t* pFreePkt) { PKTIO_HANDLE_T * p = (PKTIO_HANDLE_T *) appCookie; int r=0; int n; Ti_Pkt * pkt_list[PKTIO_MAX_RECV]; PKTIO_METADATA_T meta_s[PKTIO_MAX_RECV]; for(r=0;rcb((struct PKTIO_HANDLE_tag *)p, pkt_list, &meta_s[0], r, 0LL); }