changes for ifdma mode. some fixes to previous merge
[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     else
121     {
122           *err=NETAPI_ERR_BAD_INPUT;
123           return -1;
124     }
126     return 1;
129 /********************************************************************
130  * FUNCTION PURPOSE: Send packet via low level NWAL API's
131  * with updates for ESP Crypto and outgoing EMAC port 
132  * to NetCP command.
133  ********************************************************************
134  * DESCRIPTION: Send packet via low level NWAL API's
135  * with updates for ESP Crypto and outgoing EMAC port 
136  * to NetCP command.
137  ********************************************************************/
138 static int netapip_pktioSendCryptPort(struct PKTIO_HANDLE_tag * pp,
139                                      Ti_Pkt *pkt,
140                                      PKTIO_METADATA_T *m,
141                                      int * err)
143     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
144     nwalTxPktInfo_t *pTxPktInfo = m->u.tx_meta;
145     Cppi_HostDesc*          pPloadDesc;
146     uint32_t swInfo0, swInfo1;
148     NETCP_CFG_SA_T tunnel_id = (NETCP_CFG_SA_T) m->sa_handle;
150     if (netapip_netcpCfgGetSaInflowInfo(&netapi_get_global()->nwal_context, tunnel_id, &swInfo0, &swInfo1))
151     {
152         nwal_mCmdSetCrypPort(pkt,
153                              &p->tx_psCmdInfo,
154                               pTxPktInfo->saOffBytes, 
155                               pTxPktInfo->saPayloadLen, 
156                               swInfo0, 
157                               swInfo1,
158                               0);
160         pPloadDesc = Pktlib_getDescFromPacket(pkt);
161         pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
162         Qmss_queuePushDescSizeRaw(p->tx_psCmdInfo.txQueue,
163                                   pPloadDesc,
164                                   NWAL_DESC_SIZE);
165     }
166     else
167     {
168           *err=NETAPI_ERR_BAD_INPUT;
169           return -1;
170     }
172     return 1;
175 /********************************************************************
176  * FUNCTION PURPOSE: Send packet via low level NWAL API's
177  * with updates for L4 checksum,AH Crypto and outgoing EMAC port 
178  * to NetCP command.
179  *******************************************************************
180  * DESCRIPTION: Send packet via low level NWAL API's
181  * with updates for L4 checksum,AH Crypto and outgoing EMAC port 
182  * to NetCP command.
183  ********************************************************************/
184 static int netapip_pktioSendL4CkSumAHCryptPort(struct PKTIO_HANDLE_tag * pp,
185                                               Ti_Pkt *pkt,
186                                               PKTIO_METADATA_T *m,
187                                               int * err)
189     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
190     nwalTxPktInfo_t *pTxPktInfo = m->u.tx_meta;
191     Cppi_HostDesc*          pPloadDesc;
192     uint32_t swInfo0, swInfo1;
194     NETCP_CFG_SA_T tunnel_id = (NETCP_CFG_SA_T) m->sa_handle;
196     if (netapip_netcpCfgGetSaInflowInfo(&netapi_get_global()->nwal_context, tunnel_id, &swInfo0, &swInfo1))
197     {
198         nwal_mCmdSetL4CkSumAHCrypPort(pkt,
199                                 &p->tx_psCmdInfo,
200                                 pTxPktInfo->l4OffBytes, 
201                                 pTxPktInfo->ploadLen + pTxPktInfo->l4HdrLen, 
202                                 pTxPktInfo->pseudoHdrChecksum, 
203                                 pTxPktInfo->saOffBytes, 
204                                 pTxPktInfo->saPayloadLen, 
205                                 swInfo0, 
206                                 swInfo1,
207                                 pTxPktInfo->saAhIcvOffBytes,
208                                 pTxPktInfo->saAhMacSize,
209                                 pTxPktInfo->enetPort);
211         pPloadDesc = Pktlib_getDescFromPacket(pkt);
212         pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
213         Qmss_queuePushDescSizeRaw(p->tx_psCmdInfo.txQueue,
214                                   pPloadDesc,
215                                   NWAL_DESC_SIZE);
216     }
217     else
218     {
219           *err=NETAPI_ERR_BAD_INPUT;
220           return -1;
221     }
223     return 1;
226 /********************************************************************
227  * FUNCTION PURPOSE: Send packet via low level NWAL API's
228  * with updates for AH Crypto and outgoing EMAC port 
229  * to NetCP command.
230  ********************************************************************
231  * DESCRIPTION: Send packet via low level NWAL API's
232  * with updates for AH Crypto and outgoing EMAC port 
233  * to NetCP command.
234  ********************************************************************/
235 static int netapip_pktioSendAHCryptPort(struct PKTIO_HANDLE_tag * pp,
236                                        Ti_Pkt *pkt,
237                                        PKTIO_METADATA_T *m,
238                                        int * err)
240     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
241     nwalTxPktInfo_t *pTxPktInfo = m->u.tx_meta;
242     Cppi_HostDesc*          pPloadDesc;
243     uint32_t swInfo0, swInfo1;
245     NETCP_CFG_SA_T tunnel_id = (NETCP_CFG_SA_T) m->sa_handle;
247     if (netapip_netcpCfgGetSaInflowInfo(&netapi_get_global()->nwal_context, tunnel_id, &swInfo0, &swInfo1))
248     {
249         nwal_mCmdSetAHCrypPort(pkt,
250                                 &p->tx_psCmdInfo,
251                                 pTxPktInfo->saOffBytes, 
252                                 pTxPktInfo->saPayloadLen, 
253                                 swInfo0, 
254                                 swInfo1,
255                                 pTxPktInfo->saAhIcvOffBytes,
256                                 pTxPktInfo->saAhMacSize,
257                                 pTxPktInfo->enetPort);
258         
259         pPloadDesc = Pktlib_getDescFromPacket(pkt);
260         pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
261         Qmss_queuePushDescSizeRaw(p->tx_psCmdInfo.txQueue,
262                                   pPloadDesc,
263                                   NWAL_DESC_SIZE);
264     }
265     else
266     {
267        *err= NETAPI_ERR_BAD_INPUT;
268        return -1;
269     }
270     return 1;
275 /********************************************************************
276  * FUNCTION PURPOSE: Send packet via low level NWAL API's
277  * with updates for L4 checksum and outgoing EMAC port 
278  * to NetCP command.
279  *******************************************************************
280  * DESCRIPTION: Send packet via low level NWAL API's
281  * with updates for L4 checksum and outgoing EMAC port 
282  * to NetCP command.
283  ********************************************************************/
284 static int netapip_pktioSendL4CkSumPort(struct PKTIO_HANDLE_tag * pp,
285                                       Ti_Pkt *pkt,
286                                       PKTIO_METADATA_T *m,
287                                       int * err)
290     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
291     nwalTxPktInfo_t *pTxPktInfo = m->u.tx_meta;
292     Cppi_HostDesc*          pPloadDesc;
293     nwal_mCmdSetL4CkSumPort(pkt,
294                             &p->tx_psCmdInfo,
295                             pTxPktInfo->l4OffBytes,
296                             pTxPktInfo->l4HdrLen + pTxPktInfo->ploadLen,
297                             pTxPktInfo->pseudoHdrChecksum,
298                             pTxPktInfo->enetPort);
300     pPloadDesc = Pktlib_getDescFromPacket(pkt);
301     pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
302     Qmss_queuePushDescSizeRaw(p->tx_psCmdInfo.txQueue,
303                                   pPloadDesc,
304                                   NWAL_DESC_SIZE);
308 /********************************************************************
309  * FUNCTION PURPOSE: Send packet via low level NWAL API's
310  * with updates for outgoing EMAC port to NetCP command.
311  ********************************************************************
312  * DESCRIPTION: Send packet via low level NWAL API's
313  * with updates for outgoing EMAC port to NetCP command.
314  ********************************************************************/
315 static int netapip_pktioSendPort(struct PKTIO_HANDLE_tag * pp,
316                                 Ti_Pkt *pkt, 
317                                 PKTIO_METADATA_T *m, 
318                                 int * err)
320     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
321     nwalTxPktInfo_t *pTxPktInfo = m->u.tx_meta;
322     Cppi_HostDesc*          pPloadDesc;
323     nwal_mCmdSetPort(pkt,
324                                 &p->tx_psCmdInfo,
325                                  pTxPktInfo->enetPort);
326     pPloadDesc = Pktlib_getDescFromPacket(pkt);
327     pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
328     Qmss_queuePushDescSizeRaw(p->tx_psCmdInfo.txQueue,
329                                   pPloadDesc,
330                                   NWAL_DESC_SIZE);
331     return 1;
334 /********************************************************************
335  * FUNCTION PURPOSE: Send packet via IPC queue
336  ********************************************************************
337  * DESCRIPTION: Send packet via IPC queue
338  ********************************************************************/
339 static int netapip_pktioSendIpc(struct PKTIO_HANDLE_tag * pp,
340                                Ti_Pkt *pkt,
341                                PKTIO_METADATA_T *m,
342                                int * err)
344     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
345     err=0;
346     Qmss_queuePushDesc (p->q, (void*)pkt);
347     return 1;
349 /********************************************************************
350  * FUNCTION PURPOSE: Send packet to NETCP via NWAL
351  ********************************************************************
352  * DESCRIPTION: Send packet to NETCP via NWAL
353  ********************************************************************/
354 static int netapip_pktioSendNwal(struct PKTIO_HANDLE_tag * pp,
355                                 Ti_Pkt *pkt,
356                                 PKTIO_METADATA_T *m,
357                                 int * err)
359     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
360     nwalTxPktInfo_t * pPktInfo=m->u.tx_meta;
361     nwal_RetValue res;
362     *err=0;
363     pPktInfo->pPkt = pkt;
364     res=nwal_send(p->nwalInstanceHandle, m->sa_handle,pPktInfo);
365     if (res != nwal_OK)
366     {
367         *err = NETAPI_ERR_NWAL_TX_ERR -res;
368         return -1;
369     }
370     return 1;
373 /********************************************************************
374  * FUNCTION PURPOSE: Send packet to SA via NWAL
375  ********************************************************************
376  * DESCRIPTION: Send packet to NETCP via NWAL for side band data mode 
377  * channel via NWAL
378  ********************************************************************/
379 static int netapip_pktioSendSb(struct PKTIO_HANDLE_tag * pp,
380                               Ti_Pkt *pkt, 
381                               PKTIO_METADATA_T *m, 
382                               int * err)
384     nwal_RetValue nwalRetVal;
385     nwalTxDmPSCmdInfo_t     *dmPSCmdInfo;
386     nwalLocCxtInfo_t    nwalLocCxt;
387     Cppi_HostDesc*          pPloadDesc;
388     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
389     Qmss_QueueHnd rxQ;
390     nwalDmTxPayloadInfo_t *pPktInfoSB =  m->u.tx_sb_meta;
392     NETCP_CFG_SA_T tunnel_id = (NETCP_CFG_SA_T) m->sa_handle;
394     dmPSCmdInfo = netapip_netcpCfgGetSaSBInfo(&netapi_get_global()->nwal_context, tunnel_id);
395     if (dmPSCmdInfo)
396     {
397         nwalRetVal = nwal_getDmRxQueue(pktio_mGetNwalInstance(p), &rxQ);
398         if(nwalRetVal == nwal_OK)
399         {
400             dmPSCmdInfo->rxSbSaQ = rxQ;
401         }
402         else 
403         {
404           *err=NETAPI_ERR_BAD_INPUT;
405           return -1;
406         }
407         nwal_mCmdDMUpdate(pkt,
408             dmPSCmdInfo,
409             pPktInfoSB->appCtxId,
410             pPktInfoSB->encOffset,
411             pPktInfoSB->encSize,
412             pPktInfoSB->pEncIV,
413             pPktInfoSB->authOffset,
414             pPktInfoSB->authSize,
415             pPktInfoSB->pAuthIV,
416             pPktInfoSB->aadSize,
417             pPktInfoSB->pAad);
418         pPloadDesc = Pktlib_getDescFromPacket(pkt);
419         pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
420         Qmss_queuePushDescSizeRaw(dmPSCmdInfo->txQueue,
421                                              pPloadDesc,
422                                              NWAL_DESC_SIZE); 
423     }
424     else
425     {
426           *err=NETAPI_ERR_BAD_INPUT;
427           return -1;
428     }
429     return 1;
432 /********************************************************************
433  * FUNCTION PURPOSE: Send packet via infrastructure DMA channel
434  ********************************************************************
435  * DESCRIPTION: Send packet via infrastructure DMA channel
436  ********************************************************************/
437 static int netapip_pktioSendIfdma(struct PKTIO_HANDLE_tag * pp,
438                                  Ti_Pkt *pkt, 
439                                  PKTIO_METADATA_T *m, 
440                                  int * err)
442         Cppi_DescTag            tag={0};
443         Cppi_HostDesc*          pPloadDesc;
444         PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
445         *err=0;
446         tag.srcTagLo = m->u.tx_ifdma_dest;
447         Cppi_setTag (Cppi_DescType_HOST, (Cppi_Desc *)pkt, &tag);
448         pPloadDesc = Pktlib_getDescFromPacket(pkt);
449         pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
450         Qmss_queuePushDescSizeRaw(p->q,
451                                   pPloadDesc,
452                                   NWAL_DESC_SIZE);
453         return 1;
458 /********************************************************************
459  * FUNCTION PURPOSE: Stub function for send, do nothing.
460  ********************************************************************
461  * DESCRIPTION: Stub function for send, do nothing.
462  ********************************************************************/
463 static int netapip_pktioSendDummy(struct PKTIO_HANDLE_tag * p,
464                                  Ti_Pkt *pkt, 
465                                  PKTIO_METADATA_T *m, 
466                                  int * err)
468     *err =  NETAPI_ERR_BAD_INPUT;
469     return -1;
472 /********************************************************************
473  * FUNCTION PURPOSE: Stub function for poll, do nothing.
474  ********************************************************************
475  * DESCRIPTION: Stub function for send, do nothing.
476  ********************************************************************/
477 static int netapip_pktioPollDummy(struct PKTIO_HANDLE_tag * p, 
478                                  PKTIO_POLL_T * p_poll_cfg,
479                                  int * err)
481     *err= NETAPI_ERR_BAD_INPUT;
482     return 0;
485 /********************************************************************
486  * FUNCTION PURPOSE: Poll IPC queue
487  ********************************************************************
488  * DESCRIPTION: Poll IPC queue
489  ********************************************************************/
490 static int netapip_pktioPollIpc(struct PKTIO_HANDLE_tag * pp, 
491                                PKTIO_POLL_T * p_poll_cfg,  
492                                int * err)
494     Ti_Pkt * pkt_list[PKTIO_MAX_RECV];
495     PKTIO_METADATA_T meta_s[PKTIO_MAX_RECV];
496     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
497     int r=0;
498     int n;
499     Ti_Pkt * temp;
500     *err=0;
501     n= (p->max_n< PKTIO_MAX_RECV) ? p->max_n : PKTIO_MAX_RECV;
502     for(r=0;r<n;r++)
503     {
505         temp=(Ti_Pkt*)(Cppi_HostDesc*)QMSS_DESC_PTR(Qmss_queuePop(p->q));
507         if(!temp) break;
508         /* process meta data */
509         pkt_list[r]= temp;
510         meta_s[r].flags1=0x1;
511     }
512     if (r)
513     {
514         p->cb((struct PKTIO_HANDLE_tag *)p, pkt_list, &meta_s[0], r, 0LL);
515     }
516     return r;
519 /********************************************************************
520  * FUNCTION PURPOSE: Poll nwal data queues for pkts from netcp
521  ********************************************************************
522  * DESCRIPTION: Poll nwal data queues for pkts from netcp
523  ********************************************************************/
524 static int netapip_pktioPollNwal(struct PKTIO_HANDLE_tag * pp, 
525                                 PKTIO_POLL_T * p_poll_cfg,  
526                                 int * err)
528     int r=0;
529     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
530     *err=0;
531     /* Poll for common L2/L3 packets and L4 class pkts (todo-> only do L4 if classifiers are
532         set.  optimizaion maybe? */
533     r=nwal_pollPkt(p->nwalInstanceHandle,
534                    p->poll_flags,
535                    (uint32_t) p,
536                    p->max_n,
537                    QMSS_PARAM_NOT_SPECIFIED,
538                    (void*) NULL);
539     return r;
541 /********************************************************************
542  * FUNCTION PURPOSE: Poll nwal sideband queues for pkts from SA
543  ********************************************************************
544  * DESCRIPTION: Poll nwal sideband queues for pkts from SA
545  ********************************************************************/
546 static int  netapip_pktioPollSb(struct PKTIO_HANDLE_tag * pp, 
547                                PKTIO_POLL_T * p_poll_cfg,  
548                                int * err)
550     int r=0;
551     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
552     *err=0;
553     r=nwal_pollDm(p->nwalInstanceHandle,
554                     nwal_POLL_DM_DEF_SB_SA_Q,
555                      (uint32_t) p,
556                      p->max_n,
557                      QMSS_PARAM_NOT_SPECIFIED,
558              (void *) NULL);
559     return r;
562 /********************************************************************
563  * FUNCTION PURPOSE: Poll application provided NETCP RX queue
564  ********************************************************************
565  * DESCRIPTION: Poll application provided NETCP RX queue
566  ********************************************************************/
567 static int netapip_pktioPollNwalAdj(struct PKTIO_HANDLE_tag * pp, 
568                                    PKTIO_POLL_T * p_poll_cfg,  
569                                    int * err)
571     int r=0;
572     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
573     *err=0;
574     /* Poll for common L2/L3 packets and L4 class pkts (todo-> only do L4 if classifiers are
575          set. optimizaion maybe? */
576     r=nwal_pollPkt(p->nwalInstanceHandle,
577                      nwal_POLL_APP_MANAGED_PKT_Q,
578                      (uint32_t) p,
579                      p->max_n,
580                      p->q,
581                      (void *)  NULL);
582     return r;
585 /*************************************************************************
586  * FUNCTION PURPOSE: Poll application defined sideband queues for packets
587  *                   from SA
588  ************************************************************************
589  * DESCRIPTION: Poll application defined sideband queues for packets
590  *                   from SA
591  *************************************************************************/
592 static int  netapip_pktioPollSbAdj(struct PKTIO_HANDLE_tag * pp, 
593                                   PKTIO_POLL_T * p_poll_cfg,  
594                                   int * err)
596     int r=0;
597     PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
598     *err=0;
599     r=nwal_pollDm(p->nwalInstanceHandle,
600                      nwal_POLL_DM_APP_MANAGED_Q,
601                      (uint32_t) p,
602                      p->max_n,
603                      p->q,
604                      (void *)  NULL);
605     return r;
608 /*-----------------------MAIN API----------------------*/
609 /********************************************************************
610  * FUNCTION PURPOSE:  API creates a NETAPI PKTIO channel 
611  ********************************************************************
612  * DESCRIPTION:  API creates a NETAPI PKTIO channel 
613  ********************************************************************/
614 PKTIO_HANDLE_T * netapi_pktioCreate(NETAPI_T n,
615                                     char * name,
616                                     PKTIO_CB cb, 
617                                     PKTIO_CFG_T * p_cfg, 
618                                     int * err)
620     int r = 0;
621     PKTIO_HANDLE_T *p;
622     uint8_t         isAllocated;
624     *err=0;
625     int q= QMSS_PARAM_NOT_SPECIFIED;
626     int qtype=Qmss_QueueType_GENERAL_PURPOSE_QUEUE;
628     if ((!p_cfg)||(!name)) {*err=NETAPI_ERR_BAD_INPUT; return NULL;}
629     if ((p_cfg->flags2 & PKTIO_PKT) &&(p_cfg->flags1& PKTIO_TX)) { *err=NETAPI_ERR_BAD_INPUT; return NULL;};
630     if ((p_cfg->flags2 & PKTIO_SB) &&(p_cfg->flags1& PKTIO_TX)) { *err=NETAPI_ERR_BAD_INPUT; return NULL;};
632     /* get a free channel handle */
633     p=netapip_pktioGetFreeChannelSlot(n);
635     if (!p) {*err = NETAPI_ERR_NOMEM; return (p); }
637     p->back = n;
638     p->cb = cb;
639     p->max_n = p_cfg->max_n;
640     p->_poll=netapip_pktioPollDummy;
641     p->_send=netapip_pktioSendDummy;
642     memcpy((char *)&p->cfg, (char*) p_cfg, sizeof(PKTIO_CFG_T));
645     /* special case for infrastructure dma channels */
646     if (p_cfg->flags2 & PKTIO_IFDMA)
647     {
648         if (p_cfg->qnum!=PKTIO_Q_ANY)
649         {
650             q= p_cfg->qnum;
651         }
652         qtype=Qmss_QueueType_INFRASTRUCTURE_QUEUE;
653     }
656     /* create a  general queue */
657      p->q  = Qmss_queueOpen(qtype,
658                                 q, 
659                                 &isAllocated);
660     if (p->q == (Qmss_QueueHnd) NULL)
661     {
662         netapi_Log("netapi_pktioCreate:  queueOpen failed\n");
663         p->inuse=0;
664         *err= NETAPI_ERR_QLLD;  ///queue lld error
665         return NULL;
666     }
667     p->qInfo = Qmss_getQueueNumber(p->q);
668     if (p_cfg->flags2 & PKTIO_PKT)
669     {
670         p->use_nwal = PKTIO_4_ADJ_NWAL;
671         p->_poll=netapip_pktioPollNwalAdj;
672         p->nwalInstanceHandle = netapip_returnNwalInstanceHandle(n);
673     }
674     else if (p_cfg->flags2 & PKTIO_SB)
675     {
676         p->use_nwal = PKTIO_4_ADJ_SB;
677         p->_poll=netapip_pktioPollSbAdj;
678         p->nwalInstanceHandle = netapip_returnNwalInstanceHandle(n);
679     }
680    else if (p_cfg->flags2 & PKTIO_IFDMA)
681    {
682         p->use_nwal = 0;
683         p->_send = netapip_pktioSendIfdma;
684         p->cfg.flags1=PKTIO_TX;
685         r= netapip_pktioCreateIFDMA(p); //we create the IF DMA channel here
686         if (r<0) 
687         {
688             //trouble -> couldn't set up DMA 
689             //close queue and return failure
690             if (p->q)
691             {
692                 Qmss_queueClose(p->q);
693             }
694             p->inuse=0;
695             *err= NETAPI_ERR_QLLD;  ///queue lld error TODO: fix error code 
696             return NULL;
697         }
698    }
699     else
700     {
701         p->use_nwal=0;
702         if (p_cfg->flags1& PKTIO_TX) p->_send=netapip_pktioSendIpc;
703         if (p_cfg->flags1& PKTIO_RX) p->_poll=netapip_pktioPollIpc;
704     }
706     /* save name */ 
707     strncpy(p->name,name,
708        strlen(name)<PKTIO_MAX_NAME ?
709                strlen(name):PKTIO_MAX_NAME);   
711     /* add name, qnum to global name list */
712     if ((strcmp(name,NETCP_RX)) &&
713         (strcmp(name,NETCP_TX)) &&
714         (strcmp(name,NETCP_SB_RX)) &&
715         (strcmp(name,NETCP_SB_TX)) &&
716         (p_cfg->flags1 & PKTIO_GLOBAL))
717     {
718          //todo: make sure this succeeds..
719         hplib_mSpinLockLock(&netapi_pktio_lock);
720         r=netapip_addGlobalPktio(n, name, &p->qInfo);
721         hplib_mSpinLockUnlock(&netapi_pktio_lock);
722     }
724   ((NETAPI_HANDLE_T *)n )->n_pktios+=1;
725    return p;
728 /********************************************************************
729  * FUNCTION PURPOSE:  API opens an existing  NETAPI PKTIO channel
730  ********************************************************************
731  * DESCRIPTION:  API opens an existing  NETAPI PKTIO channel
732  ********************************************************************/
733 PKTIO_HANDLE_T * netapi_pktioOpen(NETAPI_T  n, 
734                                   char *name,
735                                   PKTIO_CB cb,  
736                                   PKTIO_CFG_T * p_cfg, 
737                                   int * err)
739     int r=0;
740     PKTIO_HANDLE_T *p, *p2;
741     uint8_t         isAllocated;
742     *err=0;
743     Qmss_Queue *p_qnum;
744     int qtype=Qmss_QueueType_GENERAL_PURPOSE_QUEUE;
747     if ((!p_cfg)||(!name)) {*err=NETAPI_ERR_BAD_INPUT; return NULL;}
749     /* get a free channel handle */
751     p=netapip_pktioGetFreeChannelSlot(n);
753     if (!p) {*err = NETAPI_ERR_NOMEM; return (p); }
754     ((NETAPI_HANDLE_T *)n)->n_pktios+=1;
756     p->inuse= PKTIO_INUSE;
757     p->back = n;
758     p->cb = cb;
759     p->max_n = p_cfg->max_n;
760     p->_poll=netapip_pktioPollDummy;
761     p->_send=netapip_pktioSendDummy;
762     memcpy((char *)&p->cfg, (char*) p_cfg, sizeof(PKTIO_CFG_T));
764     /* special handling of NETCP_RX, NETCP_TX */
765     if( (!strcmp(name, NETCP_RX)) || (!strcmp(name,NETCP_TX)) )
766     {
767        /* these have already been opened internally, so don't search in global list */
768         p->use_nwal = PKTIO_DEF_NWAL;
769         p->q = 0;  
770         p->nwalInstanceHandle = netapip_returnNwalInstanceHandle(n);
771         if (!strcmp(name,NETCP_RX))
772         {
773             p->_poll=netapip_pktioPollNwal; 
774             p->poll_flags= nwal_POLL_DEFAULT_GLOB_PKT_Q|
775                                     nwal_POLL_DEFAULT_PER_PROC_PKT_Q;
776         }
777         if (!strcmp(name,NETCP_TX))
778         {
779             p->_send=netapip_pktioSendNwal;
780         }
781     }
782     else if( (!strcmp(name, NETCP_SB_RX)) || (!strcmp(name,NETCP_SB_TX)) )
783     {
784        /* these have already been opened internally, so don't search in global list */
785         p->use_nwal =  PKTIO_DEF_SB;
786         p->q = 0;
787         p->nwalInstanceHandle = netapip_returnNwalInstanceHandle(n);
788         if (!strcmp(name,NETCP_SB_RX)) p->_poll=netapip_pktioPollSb;
789         if (!strcmp(name,NETCP_SB_TX)) p->_send=netapip_pktioSendSb;
790     }
791     else
792     {
793         hplib_mSpinLockLock(&netapi_pktio_lock); 
794         /* Find queue in global list 
795            Note names like "QUEUE:%d" or IFDMA:%d cause general purpose or
796            IFDMA queues of that number to be opened */
797         if (p_cfg->flags2 & PKTIO_IFDMA)
798         {
799             qtype= Qmss_QueueType_INFRASTRUCTURE_QUEUE;
800         }
802         hplib_mSpinLockUnlock(&netapi_pktio_lock);
803         p_qnum = netapip_findGlobalPktio(n, name);
805         if (!p_qnum ) 
806         {
807             netapi_Log("netapi_pktioOpen: can't find %s\n",name);
808             p->inuse=0;
809             *err= NETAPI_ERR_NOTFOUND;  ///queue lld error
810             return NULL;
811       }
813      /* open a general queue (for now). use qnum that was just found */
814          p->q  = Qmss_queueOpen(qtype,
815                            p_qnum->qNum , &isAllocated);
816         if (p->q == (Qmss_QueueHnd) NULL)
817         {
818             netapi_Log("netapi_pktioCreate:  queueOpen failed\n");
819             p->inuse=0;
820             *err= NETAPI_ERR_QLLD;  ///queue lld error
821             return NULL;
822         }
823         p->qInfo = Qmss_getQueueNumber(p->q);
824         netapi_Log("netapi_pktioOpen: queueMgr %d,  queueNum; %d\n", p->qInfo.qMgr, p->qInfo.qNum);
825         if (p_cfg->flags2 & PKTIO_PKT)
826         {
827            p->use_nwal = PKTIO_4_ADJ_NWAL;  //additonal RX q for nwal
828            p->_poll = netapip_pktioPollNwalAdj;
829            p->nwalInstanceHandle = netapip_returnNwalInstanceHandle(n); 
830            netapi_Log("netapi_pktioOpen: nwalInstanceHandle 0x%x\n", p->nwalInstanceHandle);
831         } 
832         else if (p_cfg->flags2 & PKTIO_SB)
833         {
834            p->use_nwal = PKTIO_4_ADJ_SB;  //additional RX q for sideband with NWAL
835            p->_poll = netapip_pktioPollSbAdj;
836            p->nwalInstanceHandle = netapip_returnNwalInstanceHandle(n);
837         }
838         else if (p_cfg->flags2 & PKTIO_IFDMA)
839         {
840             p->_send= netapip_pktioSendIfdma;
841             p->use_nwal = 0;
842         }
843         else
844         {
845            p->use_nwal=0; //not handled by nwal
846             if (p_cfg->flags1& PKTIO_TX) p->_send=netapip_pktioSendIpc;
847             if (p_cfg->flags1& PKTIO_RX) p->_poll=netapip_pktioPollIpc;
848         }
849     }
851         /* save name */
852         strncpy(p->name,name,
853            strlen(name)<PKTIO_MAX_NAME ?
854                    strlen(name):PKTIO_MAX_NAME);
856         netapi_Log("netapi_pktioOpen: returning with sucess for name %s\n", p->name);
857     return p;
860 /********************************************************************
861  * FUNCTION PURPOSE:  API controls an existing NETAPI PKTIO channel
862  ********************************************************************
863  * DESCRIPTION:  API controls an existing NETAPI PKTIO channel
864  ********************************************************************/
865 void netapi_pktioControl(PKTIO_HANDLE_T * p,
866                          PKTIO_CB cb,
867                          PKTIO_CFG_T * p_cfg,
868                          PKTIO_CONTROL_T * p_control,
869                          int *err)
871     nwal_RetValue       nwalRetVal;
872     if (!p)
873     {
874         *err= NETAPI_ERR_BAD_INPUT; 
875         return;
876     }
877     if (cb) 
878     {
879         p->cb = cb;
880     }
881     if (p_control)
882     {
883         /* todo: check for validity, eg don't allow clear of NETCP TX queues */
884         /* todo: implement divert */
885         switch(p_control->op)
886         {
887             //clear the queue
888             case(PKTIO_SET_POLL_FLAGS):
889                 p->poll_flags=p_control->poll_flags;
890                 break;
891             case(PKTIO_CLEAR):
892                 netapip_zapQ(p->q);
893                 break;
894             case (PKTIO_UPDATE_FAST_PATH):
895                 if (p_cfg)
896                 {
897                     nwalRetVal = nwal_initPSCmdInfo(p->nwalInstanceHandle, 
898                                                             p_cfg->fast_path_cfg.txPktInfo,
899                                                             &p->tx_psCmdInfo);
900                     if (nwalRetVal == nwal_OK)
901                     {
902                         switch (p_cfg->fast_path_cfg.fp_send_option)
903                         {
904                             case (PKTIO_FP_ESP_L4CKSUM_PORT):
905                                 p->_send = netapip_pktioSendL4CkSumCryptPort;
906                                 break;
907                             case (PKTIO_FP_AH_L4CKSUM_PORT):
908                                 p->_send = netapip_pktioSendL4CkSumAHCryptPort;
909                                 break;
910                             case (PKTIO_FP_ESP_PORT):
911                                 p->_send = netapip_pktioSendCryptPort;
912                                 break;
913                             case (PKTIO_FP_AH_PORT):
914                                 p->_send = netapip_pktioSendAHCryptPort;
915                                 break;
916                             case (PKTIO_FP_NO_CRYPTO_NO_CKSUM_PORT):
917                                 p->_send = netapip_pktioSendPort;
918                                 break;
919                             case (PKTIO_FP_L4CKSUM_PORT):
920                                 p->_send = netapip_pktioSendL4CkSumPort;
921                                 break;
922                             default:
923                                 break;
924                         }
925                     }
926                     else
927                     {
928                         *err = NETAPI_ERR_BAD_INPUT;
929                     }
930                 }
931                 else
932                 {
933                     *err = NETAPI_ERR_BAD_INPUT;
934                 }
935                 break;
936             case (PKTIO_UPDATE_MAX_PKTS_PER_POLL):
937                 if (p_cfg)
938                 {
939                     p->max_n = p_cfg->max_n;
940                 }
941                 else
942                 {
943                     *err = NETAPI_ERR_BAD_INPUT;
944                 }
945                 break;
946             case(PKTIO_DIVERT):
947             default:
948                 netapi_Log("netapi_pktioControl: pktio_control op %d not implemented\n",p_control->op);
949                 *err= NETAPI_ERR_NOT_IMPLEMENTED;
950                 break;
951         }
952     }
954     *err = NETAPI_ERR_OK;
955     return;
957 /********************************************************************
958  * FUNCTION PURPOSE:  API closes a NETAPI PKTIO channel
959  ********************************************************************
960  * DESCRIPTION:  API closes a NETAPI PKTIO channel
961  ********************************************************************/
962 void netapi_pktioClose(PKTIO_HANDLE_T * p, 
963                        int * err)
965     if(!p)
966     {
967         *err=1;
968         return;
969     }
970     *err=0;
971     if (p->q)
972     {
973         Qmss_queueClose(p->q);
974     }
975     p->q=-1;
976     p->inuse=0;
977     ((NETAPI_HANDLE_T *)p->back)->n_pktios-=1;
978     return;
981 /********************************************************************
982  * FUNCTION PURPOSE:  API deletes a NETAPI PKTIO channel
983  ********************************************************************
984  * DESCRIPTION:  API deletes a NETAPI PKTIO channel
985  ********************************************************************/
986 void netapi_pktioDelete(PKTIO_HANDLE_T * p, 
987                         int * err)
989     if(!p)
990     {
991         *err=1;
992         return;
993     }
994     *err=0;
995         /* remove from name list */
996     hplib_mSpinLockLock(&netapi_pktio_lock);
997         netapi_del_global_pktio((NETAPI_HANDLE_T *)p->back, p->name);
998     hplib_mSpinLockUnlock(&netapi_pktio_lock);
999         if((p->use_nwal != PKTIO_DEF_NWAL) && (p->use_nwal != PKTIO_DEF_SB)) 
1000     {
1001                 netapip_zapQ(p->q);   //since we are deleting, zap the queue 
1002             Qmss_queueClose(p->q);
1003     }
1004     p->q=-1;
1005     p->inuse=0;
1006     ((NETAPI_HANDLE_T *)p->back)->n_pktios-=1;
1007     return ;
1010 /********************************************************************
1011  * FUNCTION PURPOSE:  API sends multiple packets to a NETAPI PKTIO channel
1012  ********************************************************************
1013  * DESCRIPTION:  API sends multiple packets to a NETAPI PKTIO channel
1014  ********************************************************************/
1015 int netapi_pktioSendMulti(PKTIO_HANDLE_T * p, 
1016                           Ti_Pkt * pkt[], 
1017                           PKTIO_METADATA_T * m[], 
1018                           int np, 
1019                           int* err)
1021     int r=0;
1022     for(r=0;r<np;r++)
1023     {
1024         p->_send((struct PKTIO_HANDLE_tag *)p, (Ti_Pkt *)pkt, (PKTIO_METADATA_T *)m, err);
1025     }
1026     return r;
1029 /********************************************************************
1030  * FUNCTION PURPOSE:  API polls all NETAPI PKTIO channels associated with NETAPI_T
1031  * instance for received packets
1032  ********************************************************************
1033  * DESCRIPTION:  API polls all NETAPI PKTIO channels associated with NETAPI_T
1034  * instance for received packets
1035  ********************************************************************/
1036 int netapi_pktioPollAll(NETAPI_T  handle, 
1037                         PKTIO_POLL_T * p_poll_cfg, 
1038                         int *err)
1040     int i=0;
1041     int r=0;
1042     int err2;
1043     int cnt=0;
1044     PKTIO_HANDLE_T **pp =( PKTIO_HANDLE_T **)  netapi_get_pktio_list(handle);
1045     
1046     *err=0;
1047     for(i=0;i<NETAPI_MAX_PKTIO && cnt < ((NETAPI_HANDLE_T *)handle)->n_pktios;i++)
1048     {
1049         if (pp[i]->inuse != PKTIO_INUSE) continue;
1050         if(!(pp[i]->cfg.flags1&PKTIO_RX)) continue;
1051         r+=pktio_poll(pp[i],  p_poll_cfg,  &err2); cnt+=1;
1052         if (err2) { *err = err2; break;}
1053     }
1054     return r;
1058 /********************************************************************
1059  * FUNCTION PURPOSE:  Internal function to delete a PKTIO infrastructure DMA channel
1060  ********************************************************************
1061  * DESCRIPTION:  Internal function to delete a PKTIO infrastructure DMA channel
1062  ********************************************************************/
1063 int netapip_pktioDeleteIFDMA(PKTIO_HANDLE_T *p)
1065         Cppi_channelDisable (p->txChHnd);
1066         Cppi_channelDisable (p->rxChHnd);
1067         Cppi_channelClose(p->txChHnd);
1068         Cppi_channelClose(p->rxChHnd);
1069         Cppi_close(p->cppiHnd);
1070         return 1;
1073 /********************************************************************
1074  * FUNCTION PURPOSE:  Internal function to create a PKTIO infrastructure DMA channel
1075  ********************************************************************
1076  * DESCRIPTION:  Internal function to create a PKTIO infrastructure DMA channel
1077  *               for infrastructure DMQ queue
1078  ********************************************************************/
1079 int netapip_pktioCreateIFDMA(PKTIO_HANDLE_T * p )
1081    int dmaChan =  p->qInfo.qNum - QMSS_INFRASTRUCTURE_QUEUE_BASE;
1082    unsigned char           isAllocated;
1083    Cppi_TxChInitCfg        txChCfg;
1084    Cppi_RxChInitCfg        rxChCfg;
1085    Cppi_CpDmaInitCfg       cpdmaCfg;
1087     /* Set up QMSS CPDMA configuration */
1088     memset ((void *) &cpdmaCfg, 0, sizeof (Cppi_CpDmaInitCfg));
1089     cpdmaCfg.dmaNum = Cppi_CpDma_QMSS_CPDMA;
1091     /* Open QMSS CPDMA */
1092     p->cppiHnd = (Cppi_Handle) Cppi_open (&cpdmaCfg);
1093     if (p->cppiHnd == NULL)
1094     {
1095         return -1;
1096     }
1098  /* Set up Tx Channel parameters */
1099     memset ((void *) &txChCfg, 0, sizeof (Cppi_TxChInitCfg));
1100     txChCfg.channelNum = dmaChan;
1101     txChCfg.priority = 0;
1102     txChCfg.filterEPIB = 0;
1103     txChCfg.filterPS = 0;
1104     txChCfg.aifMonoMode = 0;
1105     txChCfg.txEnable = Cppi_ChState_CHANNEL_DISABLE;
1107     /* Open Tx Channel */
1108     p->txChHnd = (Cppi_ChHnd) Cppi_txChannelOpen (p->cppiHnd, &txChCfg, &isAllocated);
1109     if (p->txChHnd == NULL)
1110     {
1111         Cppi_close(p->cppiHnd);
1112         return -1;
1113     }
1115      /* Set up Rx Channel parameters */
1116     memset ((void *) &rxChCfg, 0, sizeof (Cppi_RxChInitCfg));
1117     rxChCfg.channelNum = dmaChan;
1118     rxChCfg.rxEnable = Cppi_ChState_CHANNEL_DISABLE;
1120     /* Open Rx Channel */
1121     p->rxChHnd = (Cppi_ChHnd) Cppi_rxChannelOpen (p->cppiHnd, &rxChCfg, &isAllocated);
1122     if (p->rxChHnd == NULL)
1123     {
1124         Cppi_channelClose(p->txChHnd);
1125         Cppi_close(p->cppiHnd);
1126         return -1;
1127     }
1128     if (Cppi_channelEnable (p->txChHnd) != CPPI_SOK)
1129     {
1130         Cppi_channelClose(p->txChHnd);
1131         Cppi_channelClose(p->rxChHnd);
1132         Cppi_close(p->cppiHnd);
1133         return -1;
1134     }
1136     /* Enable receive channel */
1137     if (Cppi_channelEnable (p->rxChHnd) != CPPI_SOK)
1138     {
1139         Cppi_channelDisable (p->txChHnd);
1140         Cppi_channelClose(p->txChHnd);
1141         Cppi_channelClose(p->rxChHnd);
1142         Cppi_close(p->cppiHnd);
1143         return -1;
1144     }
1145     return 1;
1148 /**********************************************************************
1149  * FUNCTION PURPOSE:  Internal Callback that gets registered with NWAL for packet reception
1150  **********************************************************************
1151  * DESCRIPTION:  Callback that gets registered with NWAL for packet reception
1152  * appCookie is the pktio handle 
1153  **********************************************************************/
1154 void netapip_pktioNWALRxPktCallback(uint32_t            appCookie,
1155                               uint16_t             numPkts,
1156                               nwalRxPktInfo_t*    pPktInfo,
1157                               uint64_t            timestamp,
1158                               nwal_Bool_t*        pFreePkt)
1160     PKTIO_HANDLE_T * p = (PKTIO_HANDLE_T *) appCookie;
1161     int r=0;
1162     int n;
1163     Ti_Pkt * pkt_list[PKTIO_MAX_RECV];
1164     PKTIO_METADATA_T meta_s[PKTIO_MAX_RECV];
1166     for(r=0;r<numPkts;r++)
1167     {
1168         pkt_list[r] = pPktInfo[r].pPkt;
1169         meta_s[r].flags1 = PKTIO_META_RX;
1170         meta_s[r].u.rx_meta = &pPktInfo[r];
1171     }
1172     if (r)
1173     {
1174         p->cb((struct PKTIO_HANDLE_tag *)p, pkt_list, &meta_s[0], r, timestamp);
1175     }
1179 /**********************************************************************
1180  * FUNCTION PURPOSE:  Internal Callback that gets registered with NWAL for crypto reception
1181  **********************************************************************
1182  * DESCRIPTION:  Callback that gets registered with NWAL for crypto reception,
1183  * appCookie is the pktio handle 
1184  **********************************************************************/
1185 void netapip_pktioNWALSBPktCallback(uint32_t            appCookie,
1186                               uint16_t             numPkts,
1187                               nwalDmRxPayloadInfo_t*  pDmRxPktInfo,
1188                               nwal_Bool_t*        pFreePkt)
1190     PKTIO_HANDLE_T * p = (PKTIO_HANDLE_T *) appCookie;
1191     int r=0;
1192     int n;
1193     Ti_Pkt * pkt_list[PKTIO_MAX_RECV];
1194     PKTIO_METADATA_T meta_s[PKTIO_MAX_RECV];
1195     for(r=0;r<numPkts;r++)
1196     {
1197         pkt_list[r] = pDmRxPktInfo[r].pPkt;
1198         meta_s[r].flags1 =  PKTIO_META_SB_RX;
1199         meta_s[r].u.rx_sb_meta = &pDmRxPktInfo[r];
1200     }
1201     if (r)
1202     {
1203         p->cb((struct PKTIO_HANDLE_tag *)p, pkt_list, &meta_s[0], r, 0LL);
1204     }