33d70a1662d7a9fae191c318889e5eb6f78f5b33
[keystone-rtos/netapi.git] / ti / runtime / netapi / src / pktio.c
1 /*********************************
2  * FILE: pktio.c
3  * PURPOSE: pktio library for NETAPI
4  **************************************************************
5  * FILE:  pktio.c
6  * 
7  * DESCRIPTION:  pktio source file for user space transport
8  *               library
9  * 
10  * REVISION HISTORY:  rev 0.0.1 
11  *
12  *  Copyright (c) Texas Instruments Incorporated 2010-2011
13  * 
14  *  Redistribution and use in source and binary forms, with or without 
15  *  modification, are permitted provided that the following conditions 
16  *  are met:
17  *
18  *    Redistributions of source code must retain the above copyright 
19  *    notice, this list of conditions and the following disclaimer.
20  *
21  *    Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in the 
23  *    documentation and/or other materials provided with the   
24  *    distribution.
25  *
26  *    Neither the name of Texas Instruments Incorporated nor the names of
27  *    its contributors may be used to endorse or promote products derived
28  *    from this software without specific prior written permission.
29  *
30  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
31  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
32  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
34  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
35  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
36  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
39  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
40  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42  ********************************/
44 #include <unistd.h>
45 #include "netapi.h"
46 #include "pktio.h"
51 /*This defines the maximum number of packets to receive in one pktio poll */
52 #define PKTIO_MAX_RECV  (TUNE_NETAPI_MAX_BURST_RCV)
54 static hplib_spinLock_T netapi_pktio_lock = hplib_spinLock_UNLOCKED_INITIALIZER;
57 /* Utilites*/
58 static PKTIO_HANDLE_T * netapip_pktioGetFreeChannelSlot(NETAPI_T n)
59 {
60     PKTIO_HANDLE_T ** pp = (PKTIO_HANDLE_T **) netapi_get_pktio_list(n);
61     int i;
62     hplib_mSpinLockLock(&netapi_pktio_lock);
63     for(i=0;i<NETAPI_MAX_PKTIO;i++)
64     {
65         if (pp[i]->inuse != PKTIO_INUSE)
66         {
67             pp[i]->inuse = PKTIO_INUSE;
68             hplib_mSpinLockUnlock(&netapi_pktio_lock);
69             return  pp[i];
70         }
71     }
72     hplib_mSpinLockUnlock(&netapi_pktio_lock);
73     return NULL;
74 }
77 /*Optimized send functions */
80 /********************************************************************
81  * FUNCTION PURPOSE: Send packet via low level NWAL API's
82  * with updates for L4 checksum,ESP Crypto and outgoing EMAC port 
83  * to NetCP command.
84  ********************************************************************
85  * DESCRIPTION: Send packet via low level NWAL API's
86  * with updates for L4 checksum,ESP Crypto and outgoing EMAC port 
87  * to NetCP command.
88  ********************************************************************/
89 static int netapip_pktioSendL4CkSumCryptPort(struct PKTIO_HANDLE_tag * pp,
90                                             Ti_Pkt *pkt,
91                                             PKTIO_METADATA_T *m,
92                                             int * err)
93 {
94     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
95     nwalTxPktInfo_t *pTxPktInfo = m->u.tx_meta;
96     Cppi_HostDesc*          pPloadDesc;
97     uint32_t swInfo0, swInfo1;
99     NETCP_CFG_SA_T tunnel_id = (NETCP_CFG_SA_T) m->sa_handle;
101     if (netapip_netcpCfgGetSaInflowInfo(&netapi_get_global()->nwal_context, tunnel_id, &swInfo0, &swInfo1))
102     {
103         nwal_mCmdSetL4CkSumCrypPort(pkt,
104                                     &p->tx_psCmdInfo,
105                                     pTxPktInfo->l4OffBytes, 
106                                     pTxPktInfo->ploadLen + pTxPktInfo->l4HdrLen, 
107                                     pTxPktInfo->pseudoHdrChecksum, 
108                                     pTxPktInfo->saOffBytes, 
109                                     pTxPktInfo->saPayloadLen, 
110                                     swInfo0, 
111                                     swInfo1,
112                                     0);
114         pPloadDesc = Pktlib_getDescFromPacket(pkt);
115         pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
116         Qmss_queuePushDescSizeRaw(p->tx_psCmdInfo.txQueue,
117                                   pPloadDesc,
118                                   NWAL_DESC_SIZE);
119     }
120     return 1;
123 /********************************************************************
124  * FUNCTION PURPOSE: Send packet via low level NWAL API's
125  * with updates for ESP Crypto and outgoing EMAC port 
126  * to NetCP command.
127  ********************************************************************
128  * DESCRIPTION: Send packet via low level NWAL API's
129  * with updates for ESP Crypto and outgoing EMAC port 
130  * to NetCP command.
131  ********************************************************************/
132 static int netapip_pktioSendCryptPort(struct PKTIO_HANDLE_tag * pp,
133                                      Ti_Pkt *pkt,
134                                      PKTIO_METADATA_T *m,
135                                      int * err)
137     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
138     nwalTxPktInfo_t *pTxPktInfo = m->u.tx_meta;
139     Cppi_HostDesc*          pPloadDesc;
140     uint32_t swInfo0, swInfo1;
142     NETCP_CFG_SA_T tunnel_id = (NETCP_CFG_SA_T) m->sa_handle;
144     if (netapip_netcpCfgGetSaInflowInfo(&netapi_get_global()->nwal_context, tunnel_id, &swInfo0, &swInfo1))
145     {
146         nwal_mCmdSetCrypPort(pkt,
147                              &p->tx_psCmdInfo,
148                               pTxPktInfo->saOffBytes, 
149                               pTxPktInfo->saPayloadLen, 
150                               swInfo0, 
151                               swInfo1,
152                               0);
154         pPloadDesc = Pktlib_getDescFromPacket(pkt);
155         pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
156         Qmss_queuePushDescSizeRaw(p->tx_psCmdInfo.txQueue,
157                                   pPloadDesc,
158                                   NWAL_DESC_SIZE);
159     }
160     return 1;
163 /********************************************************************
164  * FUNCTION PURPOSE: Send packet via low level NWAL API's
165  * with updates for L4 checksum,AH Crypto and outgoing EMAC port 
166  * to NetCP command.
167  *******************************************************************
168  * DESCRIPTION: Send packet via low level NWAL API's
169  * with updates for L4 checksum,AH Crypto and outgoing EMAC port 
170  * to NetCP command.
171  ********************************************************************/
172 static int netapip_pktioSendL4CkSumAHCryptPort(struct PKTIO_HANDLE_tag * pp,
173                                               Ti_Pkt *pkt,
174                                               PKTIO_METADATA_T *m,
175                                               int * err)
177     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
178     nwalTxPktInfo_t *pTxPktInfo = m->u.tx_meta;
179     Cppi_HostDesc*          pPloadDesc;
180     uint32_t swInfo0, swInfo1;
182     NETCP_CFG_SA_T tunnel_id = (NETCP_CFG_SA_T) m->sa_handle;
184     if (netapip_netcpCfgGetSaInflowInfo(&netapi_get_global()->nwal_context, tunnel_id, &swInfo0, &swInfo1))
185     {
186         nwal_mCmdSetL4CkSumAHCrypPort(pkt,
187                                 &p->tx_psCmdInfo,
188                                 pTxPktInfo->l4OffBytes, 
189                                 pTxPktInfo->ploadLen + pTxPktInfo->l4HdrLen, 
190                                 pTxPktInfo->pseudoHdrChecksum, 
191                                 pTxPktInfo->saOffBytes, 
192                                 pTxPktInfo->saPayloadLen, 
193                                 swInfo0, 
194                                 swInfo1,
195                                 pTxPktInfo->saAhIcvOffBytes,
196                                 pTxPktInfo->saAhMacSize,
197                                 pTxPktInfo->enetPort);
199         pPloadDesc = Pktlib_getDescFromPacket(pkt);
200         pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
201         Qmss_queuePushDescSizeRaw(p->tx_psCmdInfo.txQueue,
202                                   pPloadDesc,
203                                   NWAL_DESC_SIZE);
204     }
205     return 1;
208 /********************************************************************
209  * FUNCTION PURPOSE: Send packet via low level NWAL API's
210  * with updates for AH Crypto and outgoing EMAC port 
211  * to NetCP command.
212  ********************************************************************
213  * DESCRIPTION: Send packet via low level NWAL API's
214  * with updates for AH Crypto and outgoing EMAC port 
215  * to NetCP command.
216  ********************************************************************/
217 static int netapip_pktioSendAHCryptPort(struct PKTIO_HANDLE_tag * pp,
218                                        Ti_Pkt *pkt,
219                                        PKTIO_METADATA_T *m,
220                                        int * err)
222     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
223     nwalTxPktInfo_t *pTxPktInfo = m->u.tx_meta;
224     Cppi_HostDesc*          pPloadDesc;
225     uint32_t swInfo0, swInfo1;
227     NETCP_CFG_SA_T tunnel_id = (NETCP_CFG_SA_T) m->sa_handle;
229     if (netapip_netcpCfgGetSaInflowInfo(&netapi_get_global()->nwal_context, tunnel_id, &swInfo0, &swInfo1))
230     {
231         nwal_mCmdSetAHCrypPort(pkt,
232                                 &p->tx_psCmdInfo,
233                                 pTxPktInfo->saOffBytes, 
234                                 pTxPktInfo->saPayloadLen, 
235                                 swInfo0, 
236                                 swInfo1,
237                                 pTxPktInfo->saAhIcvOffBytes,
238                                 pTxPktInfo->saAhMacSize,
239                                 pTxPktInfo->enetPort);
240         
241         pPloadDesc = Pktlib_getDescFromPacket(pkt);
242         pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
243         Qmss_queuePushDescSizeRaw(p->tx_psCmdInfo.txQueue,
244                                   pPloadDesc,
245                                   NWAL_DESC_SIZE);
246     }
247     return 1;
252 /********************************************************************
253  * FUNCTION PURPOSE: Send packet via low level NWAL API's
254  * with updates for L4 checksum and outgoing EMAC port 
255  * to NetCP command.
256  *******************************************************************
257  * DESCRIPTION: Send packet via low level NWAL API's
258  * with updates for L4 checksum and outgoing EMAC port 
259  * to NetCP command.
260  ********************************************************************/
261 static int netapip_pktioSendL4CkSumPort(struct PKTIO_HANDLE_tag * pp,
262                                       Ti_Pkt *pkt,
263                                       PKTIO_METADATA_T *m,
264                                       int * err)
267     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
268     nwalTxPktInfo_t *pTxPktInfo = m->u.tx_meta;
269     Cppi_HostDesc*          pPloadDesc;
270     nwal_mCmdSetL4CkSumPort(pkt,
271                             &p->tx_psCmdInfo,
272                             pTxPktInfo->l4OffBytes,
273                             pTxPktInfo->l4HdrLen + pTxPktInfo->ploadLen,
274                             pTxPktInfo->pseudoHdrChecksum,
275                             pTxPktInfo->enetPort);
277     pPloadDesc = Pktlib_getDescFromPacket(pkt);
278     pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
279     Qmss_queuePushDescSizeRaw(p->tx_psCmdInfo.txQueue,
280                                   pPloadDesc,
281                                   NWAL_DESC_SIZE);
285 /********************************************************************
286  * FUNCTION PURPOSE: Send packet via low level NWAL API's
287  * with updates for outgoing EMAC port to NetCP command.
288  ********************************************************************
289  * DESCRIPTION: Send packet via low level NWAL API's
290  * with updates for outgoing EMAC port to NetCP command.
291  ********************************************************************/
292 static int netapip_pktioSendPort(struct PKTIO_HANDLE_tag * pp,
293                                 Ti_Pkt *pkt, 
294                                 PKTIO_METADATA_T *m, 
295                                 int * err)
297     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
298     nwalTxPktInfo_t *pTxPktInfo = m->u.tx_meta;
299     Cppi_HostDesc*          pPloadDesc;
300     nwal_mCmdSetPort(pkt,
301                                 &p->tx_psCmdInfo,
302                                  pTxPktInfo->enetPort);
303     pPloadDesc = Pktlib_getDescFromPacket(pkt);
304     pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
305     Qmss_queuePushDescSizeRaw(p->tx_psCmdInfo.txQueue,
306                                   pPloadDesc,
307                                   NWAL_DESC_SIZE);
308     return 1;
311 /********************************************************************
312  * FUNCTION PURPOSE: Send packet via IPC queue
313  ********************************************************************
314  * DESCRIPTION: Send packet via IPC queue
315  ********************************************************************/
316 static int netapip_pktioSendIpc(struct PKTIO_HANDLE_tag * pp,
317                                Ti_Pkt *pkt,
318                                PKTIO_METADATA_T *m,
319                                int * err)
321     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
322     err=0;
323     Qmss_queuePushDesc (p->q, (void*)pkt);
324     return 1;
326 /********************************************************************
327  * FUNCTION PURPOSE: Send packet to NETCP via NWAL
328  ********************************************************************
329  * DESCRIPTION: Send packet to NETCP via NWAL
330  ********************************************************************/
331 static int netapip_pktioSendNwal(struct PKTIO_HANDLE_tag * pp,
332                                 Ti_Pkt *pkt,
333                                 PKTIO_METADATA_T *m,
334                                 int * err)
336     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
337     nwalTxPktInfo_t * pPktInfo=m->u.tx_meta;
338     nwal_RetValue res;
339     *err=0;
340     pPktInfo->pPkt = pkt;
341     res=nwal_send(p->nwalInstanceHandle, m->sa_handle,pPktInfo);
342     if (res != nwal_OK)
343     {
344         *err = NETAPI_ERR_NWAL_TX_ERR -res;
345     }
346     return 1;
349 /********************************************************************
350  * FUNCTION PURPOSE: Send packet to SA via NWAL
351  ********************************************************************
352  * DESCRIPTION: Send packet to NETCP via NWAL for side band data mode 
353  * channel via NWAL
354  ********************************************************************/
355 static int netapip_pktioSendSb(struct PKTIO_HANDLE_tag * pp,
356                               Ti_Pkt *pkt, 
357                               PKTIO_METADATA_T *m, 
358                               int * err)
360     nwal_RetValue nwalRetVal;
361     nwalTxDmPSCmdInfo_t     *dmPSCmdInfo;
362     nwalLocCxtInfo_t    nwalLocCxt;
363     Cppi_HostDesc*          pPloadDesc;
364     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
365     Qmss_QueueHnd rxQ;
366     nwalDmTxPayloadInfo_t *pPktInfoSB =  m->u.tx_sb_meta;
368     NETCP_CFG_SA_T tunnel_id = (NETCP_CFG_SA_T) m->sa_handle;
370     dmPSCmdInfo = netapip_netcpCfgGetSaSBInfo(&netapi_get_global()->nwal_context, tunnel_id);
371     if (dmPSCmdInfo)
372     {
373         nwalRetVal = nwal_getDmRxQueue(pktio_mGetNwalInstance(p), &rxQ);
374         if(nwalRetVal == nwal_OK)
375         {
376             dmPSCmdInfo->rxSbSaQ = rxQ;
377         }
378         nwal_mCmdDMUpdate(pkt,
379             dmPSCmdInfo,
380             pPktInfoSB->appCtxId,
381             pPktInfoSB->encOffset,
382             pPktInfoSB->encSize,
383             pPktInfoSB->pEncIV,
384             pPktInfoSB->authOffset,
385             pPktInfoSB->authSize,
386             pPktInfoSB->pAuthIV,
387             pPktInfoSB->aadSize,
388             pPktInfoSB->pAad);
389         pPloadDesc = Pktlib_getDescFromPacket(pkt);
390         pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
391         Qmss_queuePushDescSizeRaw(dmPSCmdInfo->txQueue,
392                                              pPloadDesc,
393                                              NWAL_DESC_SIZE); 
394     }
395     return 1;
398 /********************************************************************
399  * FUNCTION PURPOSE: Send packet via infrastructure DMA channel
400  ********************************************************************
401  * DESCRIPTION: Send packet via infrastructure DMA channel
402  ********************************************************************/
403 static int netapip_pktioSendIfdma(struct PKTIO_HANDLE_tag * pp,
404                                  Ti_Pkt *pkt, 
405                                  PKTIO_METADATA_T *m, 
406                                  int * err)
408         Cppi_DescTag            tag={0};
409         PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
410         *err=0;
411         tag.srcTagLo = m->u.tx_ifdma_dest;
412         Cppi_setTag (Cppi_DescType_HOST, (Cppi_Desc *)pkt, &tag);
413         Qmss_queuePushDesc (p->q, (void*)pkt);
414         return 1;
419 /********************************************************************
420  * FUNCTION PURPOSE: Stub function for send, do nothing.
421  ********************************************************************
422  * DESCRIPTION: Stub function for send, do nothing.
423  ********************************************************************/
424 static int netapip_pktioSendDummy(struct PKTIO_HANDLE_tag * p,
425                                  Ti_Pkt *pkt, 
426                                  PKTIO_METADATA_T *m, 
427                                  int * err)
429     *err =  NETAPI_ERR_BAD_INPUT;
430     return -1;
433 /********************************************************************
434  * FUNCTION PURPOSE: Stub function for poll, do nothing.
435  ********************************************************************
436  * DESCRIPTION: Stub function for send, do nothing.
437  ********************************************************************/
438 static int netapip_pktioPollDummy(struct PKTIO_HANDLE_tag * p, 
439                                  PKTIO_POLL_T * p_poll_cfg,
440                                  int * err)
442     *err= NETAPI_ERR_BAD_INPUT;
443     return 0;
446 /********************************************************************
447  * FUNCTION PURPOSE: Poll IPC queue
448  ********************************************************************
449  * DESCRIPTION: Poll IPC queue
450  ********************************************************************/
451 static int netapip_pktioPollIpc(struct PKTIO_HANDLE_tag * pp, 
452                                PKTIO_POLL_T * p_poll_cfg,  
453                                int * err)
455     Ti_Pkt * pkt_list[PKTIO_MAX_RECV];
456     PKTIO_METADATA_T meta_s[PKTIO_MAX_RECV];
457     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
458     int r=0;
459     int n;
460     Ti_Pkt * temp;
461     *err=0;
462     n= (p->max_n< PKTIO_MAX_RECV) ? p->max_n : PKTIO_MAX_RECV;
463     for(r=0;r<n;r++)
464     {
466         temp=(Ti_Pkt*)(Cppi_HostDesc*)QMSS_DESC_PTR(Qmss_queuePop(p->q));
468         if(!temp) break;
469         /* process meta data */
470         pkt_list[r]= temp;
471         meta_s[r].flags1=0x1;
472     }
473     if (r)
474     {
475         p->cb((struct PKTIO_HANDLE_tag *)p, pkt_list, &meta_s[0], r, 0LL);
476     }
477     return r;
480 /********************************************************************
481  * FUNCTION PURPOSE: Poll nwal data queues for pkts from netcp
482  ********************************************************************
483  * DESCRIPTION: Poll nwal data queues for pkts from netcp
484  ********************************************************************/
485 static int netapip_pktioPollNwal(struct PKTIO_HANDLE_tag * pp, 
486                                 PKTIO_POLL_T * p_poll_cfg,  
487                                 int * err)
489     int r=0;
490     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
491     *err=0;
492     /* Poll for common L2/L3 packets and L4 class pkts (todo-> only do L4 if classifiers are
493         set.  optimizaion maybe? */
494     r=nwal_pollPkt(p->nwalInstanceHandle,
495                    p->poll_flags,
496                    (uint32_t) p,
497                    p->max_n,
498                    QMSS_PARAM_NOT_SPECIFIED,
499                    (void*) NULL);
500     return r;
502 /********************************************************************
503  * FUNCTION PURPOSE: Poll nwal sideband queues for pkts from SA
504  ********************************************************************
505  * DESCRIPTION: Poll nwal sideband queues for pkts from SA
506  ********************************************************************/
507 static int  netapip_pktioPollSb(struct PKTIO_HANDLE_tag * pp, 
508                                PKTIO_POLL_T * p_poll_cfg,  
509                                int * err)
511     int r=0;
512     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
513     *err=0;
514     r=nwal_pollDm(p->nwalInstanceHandle,
515                     nwal_POLL_DM_DEF_SB_SA_Q,
516                      (uint32_t) p,
517                      p->max_n,
518                      QMSS_PARAM_NOT_SPECIFIED,
519              (void *) NULL);
520     return r;
523 /********************************************************************
524  * FUNCTION PURPOSE: Poll application provided NETCP RX queue
525  ********************************************************************
526  * DESCRIPTION: Poll application provided NETCP RX queue
527  ********************************************************************/
528 static int netapip_pktioPollNwalAdj(struct PKTIO_HANDLE_tag * pp, 
529                                    PKTIO_POLL_T * p_poll_cfg,  
530                                    int * err)
532     int r=0;
533     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
534     *err=0;
535     /* Poll for common L2/L3 packets and L4 class pkts (todo-> only do L4 if classifiers are
536          set. optimizaion maybe? */
537     r=nwal_pollPkt(p->nwalInstanceHandle,
538                      nwal_POLL_APP_MANAGED_PKT_Q,
539                      (uint32_t) p,
540                      p->max_n,
541                      p->q,
542                      (void *)  NULL);
543     return r;
546 /*************************************************************************
547  * FUNCTION PURPOSE: Poll application defined sideband queues for packets
548  *                   from SA
549  ************************************************************************
550  * DESCRIPTION: Poll application defined sideband queues for packets
551  *                   from SA
552  *************************************************************************/
553 static int  netapip_pktioPollSbAdj(struct PKTIO_HANDLE_tag * pp, 
554                                   PKTIO_POLL_T * p_poll_cfg,  
555                                   int * err)
557     int r=0;
558     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
559     *err=0;
560     r=nwal_pollDm(p->nwalInstanceHandle,
561                      nwal_POLL_DM_APP_MANAGED_Q,
562                      (uint32_t) p,
563                      p->max_n,
564                      p->q,
565                      (void *)  NULL);
566     return r;
569 /*-----------------------MAIN API----------------------*/
570 /********************************************************************
571  * FUNCTION PURPOSE:  API creates a NETAPI PKTIO channel 
572  ********************************************************************
573  * DESCRIPTION:  API creates a NETAPI PKTIO channel 
574  ********************************************************************/
575 PKTIO_HANDLE_T * netapi_pktioCreate(NETAPI_T n,
576                                     char * name,
577                                     PKTIO_CB cb, 
578                                     PKTIO_CFG_T * p_cfg, 
579                                     int * err)
581     int r = 0;
582     PKTIO_HANDLE_T *p;
583     uint8_t         isAllocated;
585     *err=0;
586     int q= QMSS_PARAM_NOT_SPECIFIED;
587     int qtype=Qmss_QueueType_GENERAL_PURPOSE_QUEUE;
589     if ((!p_cfg)||(!name)) {*err=NETAPI_ERR_BAD_INPUT; return NULL;}
590     if ((p_cfg->flags2 & PKTIO_PKT) &&(p_cfg->flags1& PKTIO_TX)) { *err=NETAPI_ERR_BAD_INPUT; return NULL;};
591     if ((p_cfg->flags2 & PKTIO_SB) &&(p_cfg->flags1& PKTIO_TX)) { *err=NETAPI_ERR_BAD_INPUT; return NULL;};
593     /* get a free channel handle */
594     p=netapip_pktioGetFreeChannelSlot(n);
596     if (!p) {*err = NETAPI_ERR_NOMEM; return (p); }
598     p->back = n;
599     p->cb = cb;
600     p->max_n = p_cfg->max_n;
601     p->_poll=netapip_pktioPollDummy;
602     p->_send=netapip_pktioSendDummy;
603     memcpy((char *)&p->cfg, (char*) p_cfg, sizeof(PKTIO_CFG_T));
606     /* special case for infrastructure dma channels */
607     if (p_cfg->flags2 & PKTIO_IFDMA)
608     {
609         if (p_cfg->qnum!=PKTIO_Q_ANY)
610         {
611             q= p_cfg->qnum;
612         }
613         qtype=Qmss_QueueType_INFRASTRUCTURE_QUEUE;
614     }
617     /* create a  general queue */
618      p->q  = Qmss_queueOpen(Qmss_QueueType_GENERAL_PURPOSE_QUEUE,
619                        QMSS_PARAM_NOT_SPECIFIED, &isAllocated);
620     if (p->q == (Qmss_QueueHnd) NULL)
621     {
622         netapi_Log("netapi_pktioCreate:  queueOpen failed\n");
623         p->inuse=0;
624         *err= NETAPI_ERR_QLLD;  ///queue lld error
625         return NULL;
626     }
627     p->qInfo = Qmss_getQueueNumber(p->q);
628     if (p_cfg->flags2 & PKTIO_PKT)
629     {
630         p->use_nwal = PKTIO_4_ADJ_NWAL;
631         p->_poll=netapip_pktioPollNwalAdj;
632         p->nwalInstanceHandle = netapip_returnNwalInstanceHandle(n);
633     }
634     else if (p_cfg->flags2 & PKTIO_SB)
635     {
636         p->use_nwal = PKTIO_4_ADJ_SB;
637         p->_poll=netapip_pktioPollSbAdj;
638         p->nwalInstanceHandle = netapip_returnNwalInstanceHandle(n);
639     }
640    else if (p_cfg->flags2 & PKTIO_IFDMA)
641    {
642         p->use_nwal = 0;
643         p->_send = netapip_pktioSendIfdma;
644         p->cfg.flags1=PKTIO_TX;
645         r= netapip_pktioCreateIFDMA(p); //we create the IF DMA channel here
646         if (r<0) 
647         {
648             //trouble -> couldn't set up DMA 
649             //close queue and return failure
650             if (p->q)
651             {
652                 Qmss_queueClose(p->q);
653             }
654             p->inuse=0;
655             *err= NETAPI_ERR_QLLD;  ///queue lld error TODO: fix error code 
656             return NULL;
657         }
658    }
659     else
660     {
661         p->use_nwal=0;
662         if (p_cfg->flags1& PKTIO_TX) p->_send=netapip_pktioSendIpc;
663         if (p_cfg->flags1& PKTIO_RX) p->_poll=netapip_pktioPollIpc;
664     }
666     /* save name */ 
667     strncpy(p->name,name,
668        strlen(name)<PKTIO_MAX_NAME ?
669                strlen(name):PKTIO_MAX_NAME);   
671     /* add name, qnum to global name list */
672     if ((strcmp(name,NETCP_RX)) &&
673         (strcmp(name,NETCP_TX)) &&
674         (strcmp(name,NETCP_SB_RX)) &&
675         (strcmp(name,NETCP_SB_TX)) &&
676         (p_cfg->flags1 & PKTIO_GLOBAL))
677     {
678          //todo: make sure this succeeds..
679         hplib_mSpinLockLock(&netapi_pktio_lock);
680         r=netapip_addGlobalPktio(n, name, &p->qInfo);
681         hplib_mSpinLockUnlock(&netapi_pktio_lock);
682     }
684   ((NETAPI_HANDLE_T *)n )->n_pktios+=1;
685    return p;
688 /********************************************************************
689  * FUNCTION PURPOSE:  API opens an existing  NETAPI PKTIO channel
690  ********************************************************************
691  * DESCRIPTION:  API opens an existing  NETAPI PKTIO channel
692  ********************************************************************/
693 PKTIO_HANDLE_T * netapi_pktioOpen(NETAPI_T  n, 
694                                   char *name,
695                                   PKTIO_CB cb,  
696                                   PKTIO_CFG_T * p_cfg, 
697                                   int * err)
699     int r=0;
700     PKTIO_HANDLE_T *p, *p2;
701     uint8_t         isAllocated;
702     *err=0;
703     Qmss_Queue *p_qnum;
704     int qtype=Qmss_QueueType_GENERAL_PURPOSE_QUEUE;
707     if ((!p_cfg)||(!name)) {*err=NETAPI_ERR_BAD_INPUT; return NULL;}
709     /* get a free channel handle */
711     p=netapip_pktioGetFreeChannelSlot(n);
713     if (!p) {*err = NETAPI_ERR_NOMEM; return (p); }
714     ((NETAPI_HANDLE_T *)n)->n_pktios+=1;
716     p->inuse= PKTIO_INUSE;
717     p->back = n;
718     p->cb = cb;
719     p->max_n = p_cfg->max_n;
720     p->_poll=netapip_pktioPollDummy;
721     p->_send=netapip_pktioSendDummy;
722     memcpy((char *)&p->cfg, (char*) p_cfg, sizeof(PKTIO_CFG_T));
724     /* special handling of NETCP_RX, NETCP_TX */
725     if( (!strcmp(name, NETCP_RX)) || (!strcmp(name,NETCP_TX)) )
726     {
727        /* these have already been opened internally, so don't search in global list */
728         p->use_nwal = PKTIO_DEF_NWAL;
729         p->q = 0;  
730         p->nwalInstanceHandle = netapip_returnNwalInstanceHandle(n);
731         if (!strcmp(name,NETCP_RX))
732         {
733             p->_poll=netapip_pktioPollNwal; 
734             p->poll_flags= nwal_POLL_DEFAULT_GLOB_PKT_Q|
735                                     nwal_POLL_DEFAULT_PER_PROC_PKT_Q;
736         }
737         if (!strcmp(name,NETCP_TX))
738         {
739             p->_send=netapip_pktioSendNwal;
740         }
741     }
742     else if( (!strcmp(name, NETCP_SB_RX)) || (!strcmp(name,NETCP_SB_TX)) )
743     {
744        /* these have already been opened internally, so don't search in global list */
745         p->use_nwal =  PKTIO_DEF_SB;
746         p->q = 0;
747         p->nwalInstanceHandle = netapip_returnNwalInstanceHandle(n);
748         if (!strcmp(name,NETCP_SB_RX)) p->_poll=netapip_pktioPollSb;
749         if (!strcmp(name,NETCP_SB_TX)) p->_send=netapip_pktioSendSb;
750     }
751 #if 0
752     else if (!(strncmp(name,"NETCP_IFDMA:",strlen("NETCP_IFDMA:")) ) )
753     {
754         p_qnum = netapip_findGlobalPktio(n, name);
755         if (!p_qnum )
756         {
757             netapi_Log("pktio_open: can't find %s\n",name);
758             p->inuse=0;
759             *err= NETAPI_ERR_NOTFOUND;  ///queue lld error
760             return NULL;
761         }
763         p->q  = Qmss_queueOpen(Qmss_QueueType_INFRASTRUCTURE_QUEUE,
764                            p_qnum->qNum , &isAllocated);
765         if (p->q == (Qmss_QueueHnd) NULL)
766         {
767             netapi_Log("pktio_create:  queueOpen failed\n");
768             p->inuse=0;
769             *err= NETAPI_ERR_QLLD;  ///queue lld error
770             return NULL;
771         }
772         p->qInfo = Qmss_getQueueNumber(p->q);
773         p->_send= pktio_send_ifdma;
774         p->use_nwal = 0;
775     }
776 #endif
777     else
778     {
779         hplib_mSpinLockLock(&netapi_pktio_lock); 
780         /* Find queue in global list 
781            Note names like "QUEUE:%d" or IFDMA:%d cause general purpose or
782            IFDMA queues of that number to be opened */
783         if (p_cfg->flags2 & PKTIO_IFDMA)
784         {
785             qtype= Qmss_QueueType_INFRASTRUCTURE_QUEUE;
786         }
788         hplib_mSpinLockUnlock(&netapi_pktio_lock);
789         p_qnum = netapip_findGlobalPktio(n, name);
791         if (!p_qnum ) 
792         {
793             netapi_Log("netapi_pktioOpen: can't find %s\n",name);
794             p->inuse=0;
795             *err= NETAPI_ERR_NOTFOUND;  ///queue lld error
796             return NULL;
797       }
799      /* open a general queue (for now). use qnum that was just found */
800          p->q  = Qmss_queueOpen(qtype,
801                            p_qnum->qNum , &isAllocated);
802         if (p->q == (Qmss_QueueHnd) NULL)
803         {
804             netapi_Log("netapi_pktioCreate:  queueOpen failed\n");
805             p->inuse=0;
806             *err= NETAPI_ERR_QLLD;  ///queue lld error
807             return NULL;
808         }
809         p->qInfo = Qmss_getQueueNumber(p->q);
810         netapi_Log("netapi_pktioOpen: queueMgr %d,  queueNum; %d\n", p->qInfo.qMgr, p->qInfo.qNum);
811         if (p_cfg->flags2 & PKTIO_PKT)
812         {
813            p->use_nwal = PKTIO_4_ADJ_NWAL;  //additonal RX q for nwal
814            p->_poll = netapip_pktioPollNwalAdj;
815            p->nwalInstanceHandle = netapip_returnNwalInstanceHandle(n); 
816            netapi_Log("netapi_pktioOpen: nwalInstanceHandle 0x%x\n", p->nwalInstanceHandle);
817         } 
818         else if (p_cfg->flags2 & PKTIO_SB)
819         {
820            p->use_nwal = PKTIO_4_ADJ_SB;  //additional RX q for sideband with NWAL
821            p->_poll = netapip_pktioPollSbAdj;
822            p->nwalInstanceHandle = netapip_returnNwalInstanceHandle(n);
823         }
824         else if (p_cfg->flags2 & PKTIO_IFDMA)
825         {
826             p->_send= netapip_pktioSendIfdma;
827             p->use_nwal = 0;
828         }
829         else
830         {
831            p->use_nwal=0; //not handled by nwal
832             if (p_cfg->flags1& PKTIO_TX) p->_send=netapip_pktioSendIpc;
833             if (p_cfg->flags1& PKTIO_RX) p->_poll=netapip_pktioPollIpc;
834         }
835     }
837         /* save name */
838         strncpy(p->name,name,
839            strlen(name)<PKTIO_MAX_NAME ?
840                    strlen(name):PKTIO_MAX_NAME);
842         netapi_Log("netapi_pktioOpen: returning with sucess for name %s\n", p->name);
843     return p;
846 /********************************************************************
847  * FUNCTION PURPOSE:  API controls an existing NETAPI PKTIO channel
848  ********************************************************************
849  * DESCRIPTION:  API controls an existing NETAPI PKTIO channel
850  ********************************************************************/
851 void netapi_pktioControl(PKTIO_HANDLE_T * p,
852                          PKTIO_CB cb,
853                          PKTIO_CFG_T * p_cfg,
854                          PKTIO_CONTROL_T * p_control,
855                          int *err)
857     nwal_RetValue       nwalRetVal;
858     if (!p)
859     {
860         *err= NETAPI_ERR_BAD_INPUT; 
861         return;
862     }
863     if (cb) 
864     {
865         p->cb = cb;
866     }
867     if (p_control)
868     {
869         /* todo: check for validity, eg don't allow clear of NETCP TX queues */
870         /* todo: implement divert */
871         switch(p_control->op)
872         {
873             //clear the queue
874             case(PKTIO_SET_POLL_FLAGS):
875                 p->poll_flags=p_control->poll_flags;
876                 break;
877             case(PKTIO_CLEAR):
878                 netapip_zapQ(p->q);
879                 break;
880             case (PKTIO_UPDATE_FAST_PATH):
881                 if (p_cfg)
882                 {
883                     nwalRetVal = nwal_initPSCmdInfo(p->nwalInstanceHandle, 
884                                                             p_cfg->fast_path_cfg.txPktInfo,
885                                                             &p->tx_psCmdInfo);
886                     if (nwalRetVal == nwal_OK)
887                     {
888                         switch (p_cfg->fast_path_cfg.fp_send_option)
889                         {
890                             case (PKTIO_FP_ESP_L4CKSUM_PORT):
891                                 p->_send = netapip_pktioSendL4CkSumCryptPort;
892                                 break;
893                             case (PKTIO_FP_AH_L4CKSUM_PORT):
894                                 p->_send = netapip_pktioSendL4CkSumAHCryptPort;
895                                 break;
896                             case (PKTIO_FP_ESP_PORT):
897                                 p->_send = netapip_pktioSendCryptPort;
898                                 break;
899                             case (PKTIO_FP_AH_PORT):
900                                 p->_send = netapip_pktioSendAHCryptPort;
901                                 break;
902                             case (PKTIO_FP_NO_CRYPTO_NO_CKSUM_PORT):
903                                 p->_send = netapip_pktioSendPort;
904                                 break;
905                             case (PKTIO_FP_L4CKSUM_PORT):
906                                 p->_send = netapip_pktioSendL4CkSumPort;
907                                 break;
908                             default:
909                                 break;
910                         }
911                     }
912                     else
913                     {
914                         *err = NETAPI_ERR_BAD_INPUT;
915                     }
916                 }
917                 else
918                 {
919                     *err = NETAPI_ERR_BAD_INPUT;
920                 }
921                 break;
922             case (PKTIO_UPDATE_MAX_PKTS_PER_POLL):
923                 if (p_cfg)
924                 {
925                     p->max_n = p_cfg->max_n;
926                 }
927                 else
928                 {
929                     *err = NETAPI_ERR_BAD_INPUT;
930                 }
931                 break;
932             case(PKTIO_DIVERT):
933             default:
934                 netapi_Log("netapi_pktioControl: pktio_control op %d not implemented\n",p_control->op);
935                 *err= NETAPI_ERR_NOT_IMPLEMENTED;
936                 break;
937         }
938     }
940     *err = NETAPI_ERR_OK;
941     return;
943 /********************************************************************
944  * FUNCTION PURPOSE:  API closes a NETAPI PKTIO channel
945  ********************************************************************
946  * DESCRIPTION:  API closes a NETAPI PKTIO channel
947  ********************************************************************/
948 void netapi_pktioClose(PKTIO_HANDLE_T * p, 
949                        int * err)
951     if(!p)
952     {
953         *err=1;
954         return;
955     }
956     *err=0;
957     if (p->q)
958     {
959         Qmss_queueClose(p->q);
960     }
961     p->q=-1;
962     p->inuse=0;
963     ((NETAPI_HANDLE_T *)p->back)->n_pktios-=1;
964     return;
967 /********************************************************************
968  * FUNCTION PURPOSE:  API deletes a NETAPI PKTIO channel
969  ********************************************************************
970  * DESCRIPTION:  API deletes a NETAPI PKTIO channel
971  ********************************************************************/
972 void netapi_pktioDelete(PKTIO_HANDLE_T * p, 
973                         int * err)
975     if(!p)
976     {
977         *err=1;
978         return;
979     }
980     *err=0;
981         /* remove from name list */
982     hplib_mSpinLockLock(&netapi_pktio_lock);
983         netapi_del_global_pktio((NETAPI_HANDLE_T *)p->back, p->name);
984     hplib_mSpinLockUnlock(&netapi_pktio_lock);
985         if((p->use_nwal != PKTIO_DEF_NWAL) && (p->use_nwal != PKTIO_DEF_SB)) 
986     {
987                 netapip_zapQ(p->q);   //since we are deleting, zap the queue 
988             Qmss_queueClose(p->q);
989     }
990     p->q=-1;
991     p->inuse=0;
992     ((NETAPI_HANDLE_T *)p->back)->n_pktios-=1;
993     return ;
996 /********************************************************************
997  * FUNCTION PURPOSE:  API sends multiple packets to a NETAPI PKTIO channel
998  ********************************************************************
999  * DESCRIPTION:  API sends multiple packets to a NETAPI PKTIO channel
1000  ********************************************************************/
1001 int netapi_pktioSendMulti(PKTIO_HANDLE_T * p, 
1002                           Ti_Pkt * pkt[], 
1003                           PKTIO_METADATA_T * m[], 
1004                           int np, 
1005                           int* err)
1007     int r=0;
1008     for(r=0;r<np;r++)
1009     {
1010         p->_send((struct PKTIO_HANDLE_tag *)p, (Ti_Pkt *)pkt, (PKTIO_METADATA_T *)m, err);
1011     }
1012     return r;
1015 /********************************************************************
1016  * FUNCTION PURPOSE:  API polls all NETAPI PKTIO channels associated with NETAPI_T
1017  * instance for received packets
1018  ********************************************************************
1019  * DESCRIPTION:  API polls all NETAPI PKTIO channels associated with NETAPI_T
1020  * instance for received packets
1021  ********************************************************************/
1022 int netapi_pktioPollAll(NETAPI_T  handle, 
1023                         PKTIO_POLL_T * p_poll_cfg, 
1024                         int *err)
1026     int i=0;
1027     int r=0;
1028     int err2;
1029     int cnt=0;
1030     PKTIO_HANDLE_T **pp =( PKTIO_HANDLE_T **)  netapi_get_pktio_list(handle);
1031     
1032     *err=0;
1033     for(i=0;i<NETAPI_MAX_PKTIO && cnt < ((NETAPI_HANDLE_T *)handle)->n_pktios;i++)
1034     {
1035         if (pp[i]->inuse != PKTIO_INUSE) continue;
1036         if(!(pp[i]->cfg.flags1&PKTIO_RX)) continue;
1037         r+=pktio_poll(pp[i],  p_poll_cfg,  &err2); cnt+=1;
1038         if (err2) { *err = err2; break;}
1039     }
1040     return r;
1044 /********************************************************************
1045  * FUNCTION PURPOSE:  Internal function to delete a PKTIO infrastructure DMA channel
1046  ********************************************************************
1047  * DESCRIPTION:  Internal function to delete a PKTIO infrastructure DMA channel
1048  ********************************************************************/
1049 int netapip_pktioDeleteIFDMA(PKTIO_HANDLE_T *p)
1051         Cppi_channelDisable (p->txChHnd);
1052         Cppi_channelDisable (p->rxChHnd);
1053         Cppi_channelClose(p->txChHnd);
1054         Cppi_channelClose(p->rxChHnd);
1055         Cppi_close(p->cppiHnd);
1056         return 1;
1059 /********************************************************************
1060  * FUNCTION PURPOSE:  Internal function to create a PKTIO infrastructure DMA channel
1061  ********************************************************************
1062  * DESCRIPTION:  Internal function to create a PKTIO infrastructure DMA channel
1063  *               for infrastructure DMQ queue
1064  ********************************************************************/
1065 int netapip_pktioCreateIFDMA(PKTIO_HANDLE_T * p )
1067    int dmaChan =  p->qInfo.qNum - QMSS_INFRASTRUCTURE_QUEUE_BASE;
1068    unsigned char           isAllocated;
1069    Cppi_TxChInitCfg        txChCfg;
1070    Cppi_RxChInitCfg        rxChCfg;
1071    Cppi_CpDmaInitCfg       cpdmaCfg;
1073     /* Set up QMSS CPDMA configuration */
1074     memset ((void *) &cpdmaCfg, 0, sizeof (Cppi_CpDmaInitCfg));
1075     cpdmaCfg.dmaNum = Cppi_CpDma_QMSS_CPDMA;
1077     /* Open QMSS CPDMA */
1078     p->cppiHnd = (Cppi_Handle) Cppi_open (&cpdmaCfg);
1079     if (p->cppiHnd == NULL)
1080     {
1081         return -1;
1082     }
1084  /* Set up Tx Channel parameters */
1085     memset ((void *) &txChCfg, 0, sizeof (Cppi_TxChInitCfg));
1086     txChCfg.channelNum = dmaChan;
1087     txChCfg.priority = 0;
1088     txChCfg.filterEPIB = 0;
1089     txChCfg.filterPS = 0;
1090     txChCfg.aifMonoMode = 0;
1091     txChCfg.txEnable = Cppi_ChState_CHANNEL_DISABLE;
1093     /* Open Tx Channel */
1094     p->txChHnd = (Cppi_ChHnd) Cppi_txChannelOpen (p->cppiHnd, &txChCfg, &isAllocated);
1095     if (p->txChHnd == NULL)
1096     {
1097         Cppi_close(p->cppiHnd);
1098         return -1;
1099     }
1101      /* Set up Rx Channel parameters */
1102     memset ((void *) &rxChCfg, 0, sizeof (Cppi_RxChInitCfg));
1103     rxChCfg.channelNum = dmaChan;
1104     rxChCfg.rxEnable = Cppi_ChState_CHANNEL_DISABLE;
1106     /* Open Rx Channel */
1107     p->rxChHnd = (Cppi_ChHnd) Cppi_rxChannelOpen (p->cppiHnd, &rxChCfg, &isAllocated);
1108     if (p->rxChHnd == NULL)
1109     {
1110         Cppi_channelClose(p->txChHnd);
1111         Cppi_close(p->cppiHnd);
1112         return -1;
1113     }
1114     if (Cppi_channelEnable (p->txChHnd) != CPPI_SOK)
1115     {
1116         Cppi_channelClose(p->txChHnd);
1117         Cppi_channelClose(p->rxChHnd);
1118         Cppi_close(p->cppiHnd);
1119         return -1;
1120     }
1122     /* Enable receive channel */
1123     if (Cppi_channelEnable (p->rxChHnd) != CPPI_SOK)
1124     {
1125         Cppi_channelDisable (p->txChHnd);
1126         Cppi_channelClose(p->txChHnd);
1127         Cppi_channelClose(p->rxChHnd);
1128         Cppi_close(p->cppiHnd);
1129         return -1;
1130     }
1131     return 1;
1134 /**********************************************************************
1135  * FUNCTION PURPOSE:  Internal Callback that gets registered with NWAL for packet reception
1136  **********************************************************************
1137  * DESCRIPTION:  Callback that gets registered with NWAL for packet reception
1138  * appCookie is the pktio handle 
1139  **********************************************************************/
1140 void netapip_pktioNWALRxPktCallback(uint32_t            appCookie,
1141                               uint16_t             numPkts,
1142                               nwalRxPktInfo_t*    pPktInfo,
1143                               uint64_t            timestamp,
1144                               nwal_Bool_t*        pFreePkt)
1146     PKTIO_HANDLE_T * p = (PKTIO_HANDLE_T *) appCookie;
1147     int r=0;
1148     int n;
1149     Ti_Pkt * pkt_list[PKTIO_MAX_RECV];
1150     PKTIO_METADATA_T meta_s[PKTIO_MAX_RECV];
1152     for(r=0;r<numPkts;r++)
1153     {
1154         pkt_list[r] = pPktInfo[r].pPkt;
1155         meta_s[r].flags1 = PKTIO_META_RX;
1156         meta_s[r].u.rx_meta = &pPktInfo[r];
1157     }
1158     if (r)
1159     {
1160         p->cb((struct PKTIO_HANDLE_tag *)p, pkt_list, &meta_s[0], r, timestamp);
1161     }
1165 /**********************************************************************
1166  * FUNCTION PURPOSE:  Internal Callback that gets registered with NWAL for crypto reception
1167  **********************************************************************
1168  * DESCRIPTION:  Callback that gets registered with NWAL for crypto reception,
1169  * appCookie is the pktio handle 
1170  **********************************************************************/
1171 void netapip_pktioNWALSBPktCallback(uint32_t            appCookie,
1172                               uint16_t             numPkts,
1173                               nwalDmRxPayloadInfo_t*  pDmRxPktInfo,
1174                               nwal_Bool_t*        pFreePkt)
1176     PKTIO_HANDLE_T * p = (PKTIO_HANDLE_T *) appCookie;
1177     int r=0;
1178     int n;
1179     Ti_Pkt * pkt_list[PKTIO_MAX_RECV];
1180     PKTIO_METADATA_T meta_s[PKTIO_MAX_RECV];
1181     for(r=0;r<numPkts;r++)
1182     {
1183         pkt_list[r] = pDmRxPktInfo[r].pPkt;
1184         meta_s[r].flags1 =  PKTIO_META_SB_RX;
1185         meta_s[r].u.rx_sb_meta = &pDmRxPktInfo[r];
1186     }
1187     if (r)
1188     {
1189         p->cb((struct PKTIO_HANDLE_tag *)p, pkt_list, &meta_s[0], r, 0LL);
1190     }