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 pktio_lock = hplib_spinLock_UNLOCKED_INITIALIZER;
57 /* Utilites*/
58 static PKTIO_HANDLE_T * pktiop_get_free_channel_slot(NETAPI_T n)
59 {
60 PKTIO_HANDLE_T ** pp = (PKTIO_HANDLE_T **) netapi_get_pktio_list(n);
61 int i;
62 hplib_mSpinLockLock(&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(&pktio_lock);
69 return pp[i];
70 }
71 }
72 hplib_mSpinLockUnlock(&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 netapi_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 netapip_netcpCfgGetSaInflowInfo(&netapi_get_global()->nwal_context, tunnel_id, &swInfo0, &swInfo1);
103 if (netapip_netcpCfgGetSaInflowInfo(&netapi_get_global()->nwal_context, tunnel_id, &swInfo0, &swInfo1))
104 {
105 nwal_mCmdSetL4CkSumCrypPort(pkt,
106 &p->tx_psCmdInfo,
107 pTxPktInfo->l4OffBytes,
108 pTxPktInfo->ploadLen + pTxPktInfo->l4HdrLen,
109 pTxPktInfo->pseudoHdrChecksum,
110 pTxPktInfo->saOffBytes,
111 pTxPktInfo->saPayloadLen,
112 swInfo0,
113 swInfo1,
114 0);
116 netapi_Log("netapi_pktioSendL4CkSumCryptPort: swinfo0 0x%x, swinfo1: 0x%x\n",swInfo0,swInfo1);
117 pPloadDesc = Pktlib_getDescFromPacket(pkt);
118 pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
119 Qmss_queuePushDescSizeRaw(p->tx_psCmdInfo.txQueue,
120 pPloadDesc,
121 NWAL_DESC_SIZE);
122 }
123 return 1;
124 }
126 /********************************************************************
127 * FUNCTION PURPOSE: Send packet via low level NWAL API's
128 * with updates for ESP Crypto and outgoing EMAC port
129 * to NetCP command.
130 ********************************************************************
131 * DESCRIPTION: Send packet via low level NWAL API's
132 * with updates for ESP Crypto and outgoing EMAC port
133 * to NetCP command.
134 ********************************************************************/
135 static int netapi_pktioSendCryptPort(struct PKTIO_HANDLE_tag * pp,
136 Ti_Pkt *pkt,
137 PKTIO_METADATA_T *m,
138 int * err)
139 {
140 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
141 nwalTxPktInfo_t *pTxPktInfo = m->u.tx_meta;
142 Cppi_HostDesc* pPloadDesc;
143 uint32_t swInfo0, swInfo1;
145 NETCP_CFG_SA_T tunnel_id = (NETCP_CFG_SA_T) m->sa_handle;
147 netapip_netcpCfgGetSaInflowInfo(&netapi_get_global()->nwal_context, tunnel_id, &swInfo0, &swInfo1);
149 if (netapip_netcpCfgGetSaInflowInfo(&netapi_get_global()->nwal_context, tunnel_id, &swInfo0, &swInfo1))
150 {
151 nwal_mCmdSetCrypPort(pkt,
152 &p->tx_psCmdInfo,
153 pTxPktInfo->saOffBytes,
154 pTxPktInfo->saPayloadLen,
155 swInfo0,
156 swInfo1,
157 0);
158 netapi_Log("netapi_pktioSendCryptPort: swinfo0 0x%x, swinfo1: 0x%x\n",swInfo0,swInfo1);
159 pPloadDesc = Pktlib_getDescFromPacket(pkt);
160 pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
161 Qmss_queuePushDescSizeRaw(p->tx_psCmdInfo.txQueue,
162 pPloadDesc,
163 NWAL_DESC_SIZE);
164 }
165 return 1;
166 }
168 /********************************************************************
169 * FUNCTION PURPOSE: Send packet via low level NWAL API's
170 * with updates for L4 checksum,AH Crypto and outgoing EMAC port
171 * to NetCP command.
172 *******************************************************************
173 * DESCRIPTION: Send packet via low level NWAL API's
174 * with updates for L4 checksum,AH Crypto and outgoing EMAC port
175 * to NetCP command.
176 ********************************************************************/
177 static int netapi_pktioSendL4CkSumAHCryptPort(struct PKTIO_HANDLE_tag * pp,
178 Ti_Pkt *pkt,
179 PKTIO_METADATA_T *m,
180 int * err)
181 {
182 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
183 nwalTxPktInfo_t *pTxPktInfo = m->u.tx_meta;
184 Cppi_HostDesc* pPloadDesc;
185 uint32_t swInfo0, swInfo1;
187 NETCP_CFG_SA_T tunnel_id = (NETCP_CFG_SA_T) m->sa_handle;
189 if (netapip_netcpCfgGetSaInflowInfo(&netapi_get_global()->nwal_context, tunnel_id, &swInfo0, &swInfo1))
190 {
191 nwal_mCmdSetL4CkSumAHCrypPort(pkt,
192 &p->tx_psCmdInfo,
193 pTxPktInfo->l4OffBytes,
194 pTxPktInfo->ploadLen + pTxPktInfo->l4HdrLen,
195 pTxPktInfo->pseudoHdrChecksum,
196 pTxPktInfo->saOffBytes,
197 pTxPktInfo->saPayloadLen,
198 swInfo0,
199 swInfo1,
200 pTxPktInfo->saAhIcvOffBytes,
201 pTxPktInfo->saAhMacSize,
202 pTxPktInfo->enetPort);
204 netapi_Log("netapi_pktioSendL4CkSumAHCryptPort: swinfo0 0x%x, swinfo1: 0x%x\n",swInfo0,swInfo1);
205 pPloadDesc = Pktlib_getDescFromPacket(pkt);
206 pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
207 Qmss_queuePushDescSizeRaw(p->tx_psCmdInfo.txQueue,
208 pPloadDesc,
209 NWAL_DESC_SIZE);
210 }
211 return 1;
212 }
214 /********************************************************************
215 * FUNCTION PURPOSE: Send packet via low level NWAL API's
216 * with updates for AH Crypto and outgoing EMAC port
217 * to NetCP command.
218 ********************************************************************
219 * DESCRIPTION: Send packet via low level NWAL API's
220 * with updates for AH Crypto and outgoing EMAC port
221 * to NetCP command.
222 ********************************************************************/
223 static int netapi_pktioSendAHCryptPort(struct PKTIO_HANDLE_tag * pp,
224 Ti_Pkt *pkt,
225 PKTIO_METADATA_T *m,
226 int * err)
227 {
228 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
229 nwalTxPktInfo_t *pTxPktInfo = m->u.tx_meta;
230 Cppi_HostDesc* pPloadDesc;
231 uint32_t swInfo0, swInfo1;
233 NETCP_CFG_SA_T tunnel_id = (NETCP_CFG_SA_T) m->sa_handle;
235 if (netapip_netcpCfgGetSaInflowInfo(&netapi_get_global()->nwal_context, tunnel_id, &swInfo0, &swInfo1))
236 {
237 nwal_mCmdSetAHCrypPort(pkt,
238 &p->tx_psCmdInfo,
239 pTxPktInfo->saOffBytes,
240 pTxPktInfo->saPayloadLen,
241 swInfo0,
242 swInfo1,
243 pTxPktInfo->saAhIcvOffBytes,
244 pTxPktInfo->saAhMacSize,
245 pTxPktInfo->enetPort);
247 pPloadDesc = Pktlib_getDescFromPacket(pkt);
248 pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
249 Qmss_queuePushDescSizeRaw(p->tx_psCmdInfo.txQueue,
250 pPloadDesc,
251 NWAL_DESC_SIZE);
252 }
253 return 1;
254 }
258 /********************************************************************
259 * FUNCTION PURPOSE: Send packet via low level NWAL API's
260 * with updates for L4 checksum and outgoing EMAC port
261 * to NetCP command.
262 *******************************************************************
263 * DESCRIPTION: Send packet via low level NWAL API's
264 * with updates for L4 checksum and outgoing EMAC port
265 * to NetCP command.
266 ********************************************************************/
267 static int netapi_pktioSendL4CkSumPort(struct PKTIO_HANDLE_tag * pp,
268 Ti_Pkt *pkt,
269 PKTIO_METADATA_T *m,
270 int * err)
271 {
273 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
274 nwalTxPktInfo_t *pTxPktInfo = m->u.tx_meta;
275 Cppi_HostDesc* pPloadDesc;
276 netapi_Log("netapi_pktioSendL4CkSumPort: non-ipsec packet sent with L4 chksum\n");
277 netapi_Log("netapi_pktioSendL4CkSumPort: l4offbytes: %d, l4HdrLen: %d, enetPort %d\n",
278 pTxPktInfo->l4OffBytes,
279 pTxPktInfo->l4HdrLen,
280 pTxPktInfo->enetPort);
281 nwal_mCmdSetL4CkSumPort(pkt,
282 &p->tx_psCmdInfo,
283 pTxPktInfo->l4OffBytes,
284 pTxPktInfo->l4HdrLen + pTxPktInfo->ploadLen,
285 pTxPktInfo->pseudoHdrChecksum,
286 pTxPktInfo->enetPort);
288 pPloadDesc = Pktlib_getDescFromPacket(pkt);
289 pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
290 Qmss_queuePushDescSizeRaw(p->tx_psCmdInfo.txQueue,
291 pPloadDesc,
292 NWAL_DESC_SIZE);
293 }
296 /********************************************************************
297 * FUNCTION PURPOSE: Send packet via low level NWAL API's
298 * with updates for outgoing EMAC port to NetCP command.
299 ********************************************************************
300 * DESCRIPTION: Send packet via low level NWAL API's
301 * with updates for outgoing EMAC port to NetCP command.
302 ********************************************************************/
303 static int netapi_pktioSendPort(struct PKTIO_HANDLE_tag * pp,
304 Ti_Pkt *pkt,
305 PKTIO_METADATA_T *m,
306 int * err)
307 {
308 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
309 nwalTxPktInfo_t *pTxPktInfo = m->u.tx_meta;
310 Cppi_HostDesc* pPloadDesc;
311 nwal_mCmdSetPort(pkt,
312 &p->tx_psCmdInfo,
313 pTxPktInfo->enetPort);
314 pPloadDesc = Pktlib_getDescFromPacket(pkt);
315 pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
316 Qmss_queuePushDescSizeRaw(p->tx_psCmdInfo.txQueue,
317 pPloadDesc,
318 NWAL_DESC_SIZE);
319 return 1;
320 }
322 /********************************************************************
323 * FUNCTION PURPOSE: Send packet via IPC queue
324 ********************************************************************
325 * DESCRIPTION: Send packet via IPC queue
326 ********************************************************************/
327 static int netapi_pktioSendIpc(struct PKTIO_HANDLE_tag * pp,
328 Ti_Pkt *pkt,
329 PKTIO_METADATA_T *m,
330 int * err)
331 {
332 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
333 err=0;
334 Qmss_queuePushDesc (p->q, (void*)pkt);
335 return 1;
336 }
337 /********************************************************************
338 * FUNCTION PURPOSE: Send packet to NETCP via NWAL
339 ********************************************************************
340 * DESCRIPTION: Send packet to NETCP via NWAL
341 ********************************************************************/
342 static int netapi_pktioSendNwal(struct PKTIO_HANDLE_tag * pp,
343 Ti_Pkt *pkt,
344 PKTIO_METADATA_T *m,
345 int * err)
346 {
347 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
348 nwalTxPktInfo_t * pPktInfo=m->u.tx_meta;
349 nwal_RetValue res;
350 *err=0;
351 pPktInfo->pPkt = pkt;
352 res=nwal_send(p->nwalInstanceHandle, m->sa_handle,pPktInfo);
353 if (res != nwal_OK)
354 {
355 *err = NETAPI_ERR_NWAL_TX_ERR -res;
356 }
357 return 1;
358 }
360 /********************************************************************
361 * FUNCTION PURPOSE: Send packet to SA via NWAL
362 ********************************************************************
363 * DESCRIPTION: Send packet to NETCP via NWAL for side band data mode
364 * channel via NWAL
365 ********************************************************************/
366 static int netapi_pktioSendSb(struct PKTIO_HANDLE_tag * pp,
367 Ti_Pkt *pkt,
368 PKTIO_METADATA_T *m,
369 int * err)
370 {
371 nwal_RetValue nwalRetVal;
372 nwalTxDmPSCmdInfo_t *dmPSCmdInfo;
373 nwalLocCxtInfo_t nwalLocCxt;
374 Cppi_HostDesc* pPloadDesc;
375 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
376 Qmss_QueueHnd rxQ;
377 nwalDmTxPayloadInfo_t *pPktInfoSB = m->u.tx_sb_meta;
379 NETCP_CFG_SA_T tunnel_id = (NETCP_CFG_SA_T) m->sa_handle;
381 dmPSCmdInfo = netapip_netcpCfgGetSaSBInfo(&netapi_get_global()->nwal_context, tunnel_id);
382 if (dmPSCmdInfo)
383 {
384 nwalRetVal = nwal_getDmRxQueue(pktio_mGetNwalInstance(p), &rxQ);
385 if(nwalRetVal == nwal_OK)
386 {
387 dmPSCmdInfo->rxSbSaQ = rxQ;
388 }
389 nwal_mCmdDMUpdate(pkt,
390 dmPSCmdInfo,
391 pPktInfoSB->appCtxId,
392 pPktInfoSB->encOffset,
393 pPktInfoSB->encSize,
394 pPktInfoSB->pEncIV,
395 pPktInfoSB->authOffset,
396 pPktInfoSB->authSize,
397 pPktInfoSB->pAuthIV,
398 pPktInfoSB->aadSize,
399 pPktInfoSB->pAad);
400 pPloadDesc = Pktlib_getDescFromPacket(pkt);
401 pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
402 Qmss_queuePushDescSizeRaw(dmPSCmdInfo->txQueue,
403 pPloadDesc,
404 NWAL_DESC_SIZE);
405 }
406 }
408 /********************************************************************
409 * FUNCTION PURPOSE: Stub function for send, do nothing.
410 ********************************************************************
411 * DESCRIPTION: Stub function for send, do nothing.
412 ********************************************************************/
413 static int netapi_pktioSendDummy(struct PKTIO_HANDLE_tag * p,
414 Ti_Pkt *pkt,
415 PKTIO_METADATA_T *m,
416 int * err)
417 {
418 *err = NETAPI_ERR_BAD_INPUT;
419 return -1;
420 }
422 /********************************************************************
423 * FUNCTION PURPOSE: Stub function for poll, do nothing.
424 ********************************************************************
425 * DESCRIPTION: Stub function for send, do nothing.
426 ********************************************************************/
427 static int netapi_pktioPollDummy(struct PKTIO_HANDLE_tag * p,
428 PKTIO_POLL_T * p_poll_cfg,
429 int * err)
430 {
431 *err= NETAPI_ERR_BAD_INPUT;
432 return 0;
433 }
435 /********************************************************************
436 * FUNCTION PURPOSE: Poll IPC queue
437 ********************************************************************
438 * DESCRIPTION: Poll IPC queue
439 ********************************************************************/
440 static int netapi_pktioPollIpc(struct PKTIO_HANDLE_tag * pp,
441 PKTIO_POLL_T * p_poll_cfg,
442 int * err)
443 {
444 Ti_Pkt * pkt_list[PKTIO_MAX_RECV];
445 PKTIO_METADATA_T meta_s[PKTIO_MAX_RECV];
446 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
447 int r=0;
448 int n;
449 Ti_Pkt * temp;
450 *err=0;
451 n= (p->max_n< PKTIO_MAX_RECV) ? p->max_n : PKTIO_MAX_RECV;
452 for(r=0;r<n;r++)
453 {
455 temp=(Ti_Pkt*)(Cppi_HostDesc*)QMSS_DESC_PTR(Qmss_queuePop(p->q));
457 if(!temp) break;
458 /* process meta data */
459 pkt_list[r]= temp;
460 meta_s[r].flags1=0x1;
461 }
462 if (r)
463 {
464 p->cb((struct PKTIO_HANDLE_tag *)p, pkt_list, &meta_s[0], r, 0LL);
465 }
466 return r;
467 }
469 /********************************************************************
470 * FUNCTION PURPOSE: Poll nwal data queues for pkts from netcp
471 ********************************************************************
472 * DESCRIPTION: Poll nwal data queues for pkts from netcp
473 ********************************************************************/
474 static int netapi_pktioPollNwal(struct PKTIO_HANDLE_tag * pp,
475 PKTIO_POLL_T * p_poll_cfg,
476 int * err)
477 {
478 int r=0;
479 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
480 *err=0;
481 /* Poll for common L2/L3 packets and L4 class pkts (todo-> only do L4 if classifiers are
482 set. optimizaion maybe? */
483 r=nwal_pollPkt(p->nwalInstanceHandle,
484 p->poll_flags,
485 (uint32_t) p,
486 p->max_n,
487 QMSS_PARAM_NOT_SPECIFIED,
488 (void*) NULL);
489 return r;
490 }
491 /********************************************************************
492 * FUNCTION PURPOSE: Poll nwal sideband queues for pkts from SA
493 ********************************************************************
494 * DESCRIPTION: Poll nwal sideband queues for pkts from SA
495 ********************************************************************/
496 static int netapi_pktioPollSb(struct PKTIO_HANDLE_tag * pp,
497 PKTIO_POLL_T * p_poll_cfg,
498 int * err)
499 {
500 int r=0;
501 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
502 *err=0;
503 r=nwal_pollDm(p->nwalInstanceHandle,
504 nwal_POLL_DM_DEF_SB_SA_Q,
505 (uint32_t) p,
506 p->max_n,
507 QMSS_PARAM_NOT_SPECIFIED,
508 (void *) NULL);
509 return r;
510 }
512 /********************************************************************
513 * FUNCTION PURPOSE: Poll application provided NETCP RX queue
514 ********************************************************************
515 * DESCRIPTION: Poll application provided NETCP RX queue
516 ********************************************************************/
517 static int netapi_pktioPollNwalAdj(struct PKTIO_HANDLE_tag * pp,
518 PKTIO_POLL_T * p_poll_cfg,
519 int * err)
520 {
521 int r=0;
522 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
523 *err=0;
524 /* Poll for common L2/L3 packets and L4 class pkts (todo-> only do L4 if classifiers are
525 set. optimizaion maybe? */
526 r=nwal_pollPkt(p->nwalInstanceHandle,
527 nwal_POLL_APP_MANAGED_PKT_Q,
528 (uint32_t) p,
529 p->max_n,
530 p->q,
531 (void *) NULL);
532 return r;
533 }
535 /*************************************************************************
536 * FUNCTION PURPOSE: Poll application defined sideband queues for packets
537 * from SA
538 ************************************************************************
539 * DESCRIPTION: Poll application defined sideband queues for packets
540 * from SA
541 *************************************************************************/
542 static int netapi_pktioPollSbAdj(struct PKTIO_HANDLE_tag * pp,
543 PKTIO_POLL_T * p_poll_cfg,
544 int * err)
545 {
546 int r=0;
547 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
548 *err=0;
549 r=nwal_pollDm(p->nwalInstanceHandle,
550 nwal_POLL_DM_APP_MANAGED_Q,
551 (uint32_t) p,
552 p->max_n,
553 p->q,
554 (void *) NULL);
555 return r;
556 }
558 /*-----------------------MAIN API----------------------*/
559 /********************************************************************
560 * FUNCTION PURPOSE: API creates a NETAPI PKTIO channel
561 ********************************************************************
562 * DESCRIPTION: API creates a NETAPI PKTIO channel
563 ********************************************************************/
564 PKTIO_HANDLE_T * netapi_pktioCreate(NETAPI_T n,
565 char * name,
566 PKTIO_CB cb,
567 PKTIO_CFG_T * p_cfg,
568 int * err)
569 {
570 int r = 0;
571 PKTIO_HANDLE_T *p;
572 uint8_t isAllocated;
574 *err=0;
576 if ((!p_cfg)||(!name)) {*err=NETAPI_ERR_BAD_INPUT; return NULL;}
577 if ((p_cfg->flags2 & PKTIO_PKT) &&(p_cfg->flags1& PKTIO_TX)) { *err=NETAPI_ERR_BAD_INPUT; return NULL;};
578 if ((p_cfg->flags2 & PKTIO_SB) &&(p_cfg->flags1& PKTIO_TX)) { *err=NETAPI_ERR_BAD_INPUT; return NULL;};
580 /* get a free channel handle */
581 p=pktiop_get_free_channel_slot(n);
583 if (!p) {*err = NETAPI_ERR_NOMEM; return (p); }
585 p->back = n;
586 p->cb = cb;
587 p->max_n = p_cfg->max_n;
588 p->_poll=netapi_pktioPollDummy;
589 p->_send=netapi_pktioSendDummy;
590 memcpy((char *)&p->cfg, (char*) p_cfg, sizeof(PKTIO_CFG_T));
592 /* create a general queue (for now). todo: allow qnum to be passed in */
593 p->q = Qmss_queueOpen(Qmss_QueueType_GENERAL_PURPOSE_QUEUE,
594 QMSS_PARAM_NOT_SPECIFIED, &isAllocated);
595 if (p->q == (Qmss_QueueHnd) NULL)
596 {
597 netapi_Log("netapi_pktioCreate: queueOpen failed\n");
598 p->inuse=0;
599 *err= NETAPI_ERR_QLLD; ///queue lld error
600 return NULL;
601 }
602 p->qInfo = Qmss_getQueueNumber(p->q);
603 if (p_cfg->flags2 & PKTIO_PKT)
604 {
605 p->use_nwal = PKTIO_4_ADJ_NWAL;
606 p->_poll=netapi_pktioPollNwalAdj;
607 p->nwalInstanceHandle = netapip_returnNwalInstanceHandle(n);
608 }
609 else if (p_cfg->flags2 & PKTIO_SB)
610 {
611 p->use_nwal = PKTIO_4_ADJ_SB;
612 p->_poll=netapi_pktioPollSbAdj;
613 p->nwalInstanceHandle = netapip_returnNwalInstanceHandle(n);
614 }
615 else
616 {
617 p->use_nwal=0;
618 if (p_cfg->flags1& PKTIO_TX) p->_send=netapi_pktioSendIpc;
619 if (p_cfg->flags1& PKTIO_RX) p->_poll=netapi_pktioPollIpc;
620 }
622 /* save name */
623 strncpy(p->name,name,
624 strlen(name)<PKTIO_MAX_NAME ?
625 strlen(name):PKTIO_MAX_NAME);
627 /* add name, qnum to global name list */
628 if ((strcmp(name,NETCP_RX)) && (strcmp(name,NETCP_TX)) &&
629 (strcmp(name,NETCP_SB_RX)) &&
630 (strcmp(name,NETCP_SB_TX)) &&
631 (p_cfg->flags1 & PKTIO_GLOBAL) )
632 {
633 //todo: make sure this succeeds..
634 hplib_mSpinLockLock(&pktio_lock);
635 r=netapi_add_global_pktio(n, name, &p->qInfo);
636 hplib_mSpinLockUnlock(&pktio_lock);
637 }
639 ((NETAPI_HANDLE_T *)n )->n_pktios+=1;
640 return p;
641 }
643 /********************************************************************
644 * FUNCTION PURPOSE: API opens an existing NETAPI PKTIO channel
645 ********************************************************************
646 * DESCRIPTION: API opens an existing NETAPI PKTIO channel
647 ********************************************************************/
648 PKTIO_HANDLE_T * netapi_pktioOpen(NETAPI_T n,
649 char *name,
650 PKTIO_CB cb,
651 PKTIO_CFG_T * p_cfg,
652 int * err)
653 {
654 int r=0;
655 PKTIO_HANDLE_T *p, *p2;
656 uint8_t isAllocated;
657 *err=0;
658 Qmss_Queue *p_qnum;
660 if ((!p_cfg)||(!name)) {*err=NETAPI_ERR_BAD_INPUT; return NULL;}
662 /* get a free channel handle */
664 p=pktiop_get_free_channel_slot(n);
666 if (!p) {*err = NETAPI_ERR_NOMEM; return (p); }
667 ((NETAPI_HANDLE_T *)n)->n_pktios+=1;
669 p->inuse= PKTIO_INUSE;
670 p->back = n;
671 p->cb = cb;
672 p->max_n = p_cfg->max_n;
673 p->_poll=netapi_pktioPollDummy;
674 p->_send=netapi_pktioSendDummy;
675 memcpy((char *)&p->cfg, (char*) p_cfg, sizeof(PKTIO_CFG_T));
677 /* special handling of NETCP_RX, NETCP_TX */
678 if( (!strcmp(name, NETCP_RX)) || (!strcmp(name,NETCP_TX)) )
679 {
680 /* these have already been opened internally, so don't search in global list */
681 p->use_nwal = PKTIO_DEF_NWAL;
682 p->q = 0;
683 p->nwalInstanceHandle = netapip_returnNwalInstanceHandle(n);
684 if (!strcmp(name,NETCP_RX))
685 {
686 p->_poll=netapi_pktioPollNwal;
687 p->poll_flags= nwal_POLL_DEFAULT_GLOB_PKT_Q|
688 nwal_POLL_DEFAULT_PER_PROC_PKT_Q;
689 }
690 if (!strcmp(name,NETCP_TX))
691 {
692 p->_send=netapi_pktioSendNwal;
693 }
694 }
695 else if( (!strcmp(name, NETCP_SB_RX)) || (!strcmp(name,NETCP_SB_TX)) )
696 {
697 /* these have already been opened internally, so don't search in global list */
698 p->use_nwal = PKTIO_DEF_SB;
699 p->q = 0;
700 p->nwalInstanceHandle = netapip_returnNwalInstanceHandle(n);
701 if (!strcmp(name,NETCP_SB_RX)) p->_poll=netapi_pktioPollSb;
702 if (!strcmp(name,NETCP_SB_TX)) p->_send=netapi_pktioSendSb;
703 }
704 else
705 {
706 hplib_mSpinLockLock(&pktio_lock);
707 /* find queue in global list */
708 p_qnum = netapi_find_global_pktio(n, name);
710 hplib_mSpinLockUnlock(&pktio_lock);
711 if (!p_qnum )
712 {
713 netapi_Log("netapi_pktioOpen: can't find %s\n",name);
714 p->inuse=0;
715 *err= NETAPI_ERR_NOTFOUND; ///queue lld error
716 return NULL;
717 }
719 /* open a general queue (for now). use qnum that was just found */
720 p->q = Qmss_queueOpen(Qmss_QueueType_GENERAL_PURPOSE_QUEUE,
721 p_qnum->qNum , &isAllocated);
722 if (p->q == (Qmss_QueueHnd) NULL)
723 {
724 netapi_Log("netapi_pktioCreate: queueOpen failed\n");
725 p->inuse=0;
726 *err= NETAPI_ERR_QLLD; ///queue lld error
727 return NULL;
728 }
729 p->qInfo = Qmss_getQueueNumber(p->q);
730 netapi_Log("netapi_pktioOpen: queueMgr %d, queueNum; %d\n", p->qInfo.qMgr, p->qInfo.qNum);
731 if (p_cfg->flags2 & PKTIO_PKT)
732 {
733 p->use_nwal = PKTIO_4_ADJ_NWAL; //additonal RX q for nwal
734 p->_poll = netapi_pktioPollNwalAdj;
735 p->nwalInstanceHandle = netapip_returnNwalInstanceHandle(n);
736 netapi_Log("netapi_pktioOpen: nwalInstanceHandle 0x%x\n", p->nwalInstanceHandle);
737 }
738 else if (p_cfg->flags2 & PKTIO_SB)
739 {
740 p->use_nwal = PKTIO_4_ADJ_SB; //additional RX q for sideband with NWAL
741 p->_poll = netapi_pktioPollSbAdj;
742 p->nwalInstanceHandle = netapip_returnNwalInstanceHandle(n);
743 }
744 else
745 {
746 p->use_nwal=0; //not handled by nwal
747 if (p_cfg->flags1& PKTIO_TX) p->_send=netapi_pktioSendIpc;
748 if (p_cfg->flags1& PKTIO_RX) p->_poll=netapi_pktioPollIpc;
749 }
750 }
752 /* save name */
753 strncpy(p->name,name,
754 strlen(name)<PKTIO_MAX_NAME ?
755 strlen(name):PKTIO_MAX_NAME);
757 netapi_Log("netapi_pktioOpen: returning with sucess for name %s\n", p->name);
758 return p;
759 }
761 /********************************************************************
762 * FUNCTION PURPOSE: API controls an existing NETAPI PKTIO channel
763 ********************************************************************
764 * DESCRIPTION: API controls an existing NETAPI PKTIO channel
765 ********************************************************************/
766 void netapi_pktioControl(PKTIO_HANDLE_T * p,
767 PKTIO_CB cb,
768 PKTIO_CFG_T * p_cfg,
769 PKTIO_CONTROL_T * p_control,
770 int *err)
771 {
772 nwal_RetValue nwalRetVal;
773 if (!p)
774 {
775 *err= NETAPI_ERR_BAD_INPUT;
776 return;
777 }
778 if (cb)
779 {
780 p->cb = cb;
781 }
782 if (p_control)
783 {
784 /* todo: check for validity, eg don't allow clear of NETCP TX queues */
785 /* todo: implement divert */
786 switch(p_control->op)
787 {
788 //clear the queue
789 case(PKTIO_SET_POLL_FLAGS):
790 p->poll_flags=p_control->poll_flags;
791 break;
792 case(PKTIO_CLEAR):
793 netapip_zapQ(p->q);
794 break;
795 case (PKTIO_UPDATE_FAST_PATH):
796 if (p_cfg)
797 {
798 nwalRetVal = nwal_initPSCmdInfo(p->nwalInstanceHandle,
799 p_cfg->fast_path_cfg.txPktInfo,
800 &p->tx_psCmdInfo);
801 if (nwalRetVal == nwal_OK)
802 {
803 switch (p_cfg->fast_path_cfg.fp_send_option)
804 {
805 case (PKTIO_FP_ESP_L4CKSUM_PORT):
806 p->_send = netapi_pktioSendL4CkSumCryptPort;
807 break;
808 case (PKTIO_FP_AH_L4CKSUM_PORT):
809 p->_send = netapi_pktioSendL4CkSumAHCryptPort;
810 break;
811 case (PKTIO_FP_ESP_PORT):
812 p->_send = netapi_pktioSendCryptPort;
813 break;
814 case (PKTIO_FP_AH_PORT):
815 p->_send = netapi_pktioSendAHCryptPort;
816 break;
817 case (PKTIO_FP_NO_CRYPTO_NO_CKSUM_PORT):
818 p->_send = netapi_pktioSendPort;
819 break;
820 case (PKTIO_FP_L4CKSUM_PORT):
821 p->_send = netapi_pktioSendL4CkSumPort;
822 break;
823 default:
824 break;
825 }
826 }
827 else
828 {
829 *err = NETAPI_ERR_BAD_INPUT;
830 }
831 }
832 else
833 {
834 *err = NETAPI_ERR_BAD_INPUT;
835 }
836 break;
837 case (PKTIO_UPDATE_MAX_PKTS_PER_POLL):
838 if (p_cfg)
839 {
840 p->max_n = p_cfg->max_n;
841 }
842 else
843 {
844 *err = NETAPI_ERR_BAD_INPUT;
845 }
846 break;
847 case(PKTIO_DIVERT):
848 default:
849 netapi_Log("netapi_pktioControl: pktio_control op %d not implemented\n",p_control->op);
850 *err= NETAPI_ERR_NOT_IMPLEMENTED;
851 break;
852 }
853 }
855 *err = NETAPI_ERR_OK;
856 return;
857 }
858 /********************************************************************
859 * FUNCTION PURPOSE: API closes a NETAPI PKTIO channel
860 ********************************************************************
861 * DESCRIPTION: API closes a NETAPI PKTIO channel
862 ********************************************************************/
863 void netapi_pktioClose(PKTIO_HANDLE_T * p,
864 int * err)
865 {
866 if(!p) { *err=1; return;}
867 *err=0;
868 if (p->q) Qmss_queueClose(p->q); //LLD keeps reference count
869 p->q=-1;
870 p->inuse=0;
871 ((NETAPI_HANDLE_T *)p->back)->n_pktios-=1;
872 return;
873 }
875 /********************************************************************
876 * FUNCTION PURPOSE: API deletes a NETAPI PKTIO channel
877 ********************************************************************
878 * DESCRIPTION: API deletes a NETAPI PKTIO channel
879 ********************************************************************/
880 void netapi_pktioDelete(PKTIO_HANDLE_T * p,
881 int * err)
882 {
883 if(!p) { *err=1; return;}
884 *err=0;
885 /* remove from name list */
886 hplib_mSpinLockLock(&pktio_lock);
887 netapi_del_global_pktio((NETAPI_HANDLE_T *)p->back, p->name);
888 hplib_mSpinLockUnlock(&pktio_lock);
889 if((p->use_nwal != PKTIO_DEF_NWAL) && (p->use_nwal != PKTIO_DEF_SB))
890 {
891 netapip_zapQ(p->q); //since we are deleting, zap the queue
892 Qmss_queueClose(p->q);
893 }
894 p->q=-1;
895 p->inuse=0;
896 ((NETAPI_HANDLE_T *)p->back)->n_pktios-=1;
897 return ;
898 }
900 /********************************************************************
901 * FUNCTION PURPOSE: API sends multiple packets to a NETAPI PKTIO channel
902 ********************************************************************
903 * DESCRIPTION: API sends multiple packets to a NETAPI PKTIO channel
904 ********************************************************************/
905 int netapi_pktioSendMulti(PKTIO_HANDLE_T * p,
906 Ti_Pkt * pkt[],
907 PKTIO_METADATA_T * m[],
908 int np,
909 int* err)
910 {
911 int r=0;
912 for(r=0;r<np;r++)
913 {
914 p->_send((struct PKTIO_HANDLE_tag *)p, (Ti_Pkt *)pkt, (PKTIO_METADATA_T *)m, err);
915 }
916 return r;
917 }
919 /********************************************************************
920 * FUNCTION PURPOSE: API polls all NETAPI PKTIO channels associated with NETAPI_T
921 * instance for received packets
922 ********************************************************************
923 * DESCRIPTION: API polls all NETAPI PKTIO channels associated with NETAPI_T
924 * instance for received packets
925 ********************************************************************/
926 int netapi_pktioPollAll(NETAPI_T handle,
927 PKTIO_POLL_T * p_poll_cfg,
928 int *err)
929 {
930 int i=0;
931 int r=0;
932 int err2;
933 int cnt=0;
934 PKTIO_HANDLE_T **pp =( PKTIO_HANDLE_T **) netapi_get_pktio_list(handle);
936 *err=0;
937 for(i=0;i<NETAPI_MAX_PKTIO && cnt < ((NETAPI_HANDLE_T *)handle)->n_pktios;i++)
938 {
939 if (pp[i]->inuse != PKTIO_INUSE) continue;
940 if(!(pp[i]->cfg.flags1&PKTIO_RX)) continue;
941 r+=pktio_poll(pp[i], p_poll_cfg, &err2); cnt+=1;
942 if (err2) { *err = err2; break;}
943 }
944 return r;
946 }
949 /**********************************************************************
950 * FUNCTION PURPOSE: Callback that gets registered with NWAL for packet reception
951 **********************************************************************
952 * DESCRIPTION: Callback that gets registered with NWAL for packet reception
953 * appCookie is the pktio handle
954 **********************************************************************/
955 void netapi_NWALRxPktCallback(uint32_t appCookie,
956 uint16_t numPkts,
957 nwalRxPktInfo_t* pPktInfo,
958 uint64_t timestamp,
959 nwal_Bool_t* pFreePkt)
960 {
961 PKTIO_HANDLE_T * p = (PKTIO_HANDLE_T *) appCookie;
962 int r=0;
963 int n;
964 Ti_Pkt * pkt_list[PKTIO_MAX_RECV];
965 PKTIO_METADATA_T meta_s[PKTIO_MAX_RECV];
967 for(r=0;r<numPkts;r++)
968 {
969 pkt_list[r] = pPktInfo[r].pPkt;
970 meta_s[r].flags1 = PKTIO_META_RX;
971 meta_s[r].u.rx_meta = &pPktInfo[r];
972 }
973 if (r)
974 {
975 p->cb((struct PKTIO_HANDLE_tag *)p, pkt_list, &meta_s[0], r, timestamp);
976 }
977 }
980 /**********************************************************************
981 * FUNCTION PURPOSE: Callback that gets registered with NWAL for crypto reception
982 **********************************************************************
983 * DESCRIPTION: Callback that gets registered with NWAL for crypto reception,
984 * appCookie is the pktio handle
985 **********************************************************************/
986 void netapi_NWALSBPktCallback(uint32_t appCookie,
987 uint16_t numPkts,
988 nwalDmRxPayloadInfo_t* pDmRxPktInfo,
989 nwal_Bool_t* pFreePkt)
990 {
991 PKTIO_HANDLE_T * p = (PKTIO_HANDLE_T *) appCookie;
992 int r=0;
993 int n;
994 Ti_Pkt * pkt_list[PKTIO_MAX_RECV];
995 PKTIO_METADATA_T meta_s[PKTIO_MAX_RECV];
996 for(r=0;r<numPkts;r++)
997 {
998 pkt_list[r] = pDmRxPktInfo[r].pPkt;
999 meta_s[r].flags1 = PKTIO_META_SB_RX;
1000 meta_s[r].u.rx_sb_meta = &pDmRxPktInfo[r];
1001 }
1002 if (r)
1003 {
1004 p->cb((struct PKTIO_HANDLE_tag *)p, pkt_list, &meta_s[0], r, 0LL);
1005 }
1006 }