67578d039c6b559c07fbb71367a72a8f5a999d48
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 ********************************/
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <unistd.h>
46 #include <string.h>
47 #include "netapi.h"
49 #ifdef PKTIO_GET_BENCHMARK
50 /* for benchmarking .. need to be defined somewhere */
51 unsigned int vv7p;
52 unsigned int vv8p;
53 unsigned int vv9p;
54 unsigned int vv10p;
55 unsigned int vv11p;
56 unsigned int vv12p;
57 unsigned int vv13p; //rcv path
58 unsigned int vv14p;
59 unsigned int vv15p;
60 #endif
62 /*--------------------Utilites-----------------*/
65 static PKTIO_HANDLE_T * pktiop_get_free_channel_slot(NETAPI_T n)
66 {
67 PKTIO_HANDLE_T ** pp = (PKTIO_HANDLE_T **) netapi_get_pktio_list(n);
68 int i;
69 for(i=0;i<NETAPI_MAX_PKTIO;i++)
70 {
71 if (pp[i]->inuse != PKTIO_INUSE)
72 {
73 return pp[i];
74 }
75 }
76 return NULL;
77 }
80 /*-----------------------------------------------------*/
81 /* optimized send/rcv functions */
82 /*----------------------------------------------------*/
84 //********************************************
85 //send pkt via ipc queue
86 //********************************************
87 static int pktio_send_ipc(struct PKTIO_HANDLE_tag * pp, Ti_Pkt *pkt, PKTIO_METADATA_T *m, int * err)
88 {
89 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
90 *err=0;
91 #ifdef PKTIO_GET_BENCHMARK
92 vv8p=netapi_timing_stop();
93 #endif
94 Qmss_queuePushDesc (p->q, (void*)pkt);
96 #ifdef PKTIO_GET_BENCHMARK
97 vv9p=netapi_timing_stop();
98 #endif
99 return 1;
100 }
101 //********************************************
102 //send pkt to NETCP via NWAL
103 //********************************************
104 static int pktio_send_nwal(struct PKTIO_HANDLE_tag * pp, Ti_Pkt *pkt, PKTIO_METADATA_T *m, int * err)
105 {
106 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
107 nwalTxPktInfo_t * pPktInfo=m->u.tx_meta;
108 nwal_RetValue res;
109 *err=0;
110 pPktInfo->pPkt = pkt;
111 #ifdef PKTIO_GET_BENCHMARK
112 vv11p=netapi_timing_stop();
113 #endif
114 res=nwal_send(p->nwalInstanceHandle, m->sa_handle,pPktInfo);
115 #ifdef PKTIO_GET_BENCHMARK
116 vv12p=netapi_timing_stop();
117 #endif
118 if (res != nwal_OK) { *err = NETAPI_ERR_NWAL_TX_ERR -res;}
119 return 1;
120 }
121 //********************************************
122 //send to SA via SB queue
123 //********************************************
124 static int pktio_send_sb(struct PKTIO_HANDLE_tag * pp, Ti_Pkt *pkt, PKTIO_METADATA_T *m, int * err)
125 {
126 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
127 nwalDmTxPayloadInfo_t *pPktInfoSB = m->u.tx_sb_meta;
128 nwal_RetValue res;
129 *err=0;
130 pPktInfoSB->pPkt = pkt;
131 res=nwal_sendDM(p->nwalInstanceHandle, m->sa_handle,pPktInfoSB);
132 if (res != nwal_OK) *err = NETAPI_ERR_NWAL_TX_ERR -res;
133 return 1;
134 }
135 //********************************************
136 //dummy. return err
137 //********************************************
138 static int pktio_send_dummy(struct PKTIO_HANDLE_tag * p, Ti_Pkt *pkt, PKTIO_METADATA_T *m, int * err)
139 {
140 *err = NETAPI_ERR_BAD_INPUT;
141 return -1;
142 }
143 //*******************************************
144 //dummy poll
145 //*******************************************
146 static int pktio_poll_dummy(struct PKTIO_HANDLE_tag * p, PKTIO_POLL_T * p_poll_cfg, int * err)
147 {
148 *err= NETAPI_ERR_BAD_INPUT;
149 return 0;
150 }
151 //********************************************
152 //poll IPC queue
153 //********************************************
154 static int pktio_poll_ipc(struct PKTIO_HANDLE_tag * pp, PKTIO_POLL_T * p_poll_cfg, int * err)
155 {
156 Ti_Pkt * pkt_list[PKTIO_MAX_RECV];
157 PKTIO_METADATA_T meta_s[PKTIO_MAX_RECV];
158 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
159 int r=0;
160 int n;
161 Ti_Pkt * temp;
162 *err=0;
163 n= (p->max_n< PKTIO_MAX_RECV) ? p->max_n : PKTIO_MAX_RECV;
164 for(r=0;r<n;r++)
165 {
166 #ifdef PKTIO_GET_BENCHMARK
167 if (r==0) vv7p=netapi_timing_stop();
168 #endif
169 temp=(Ti_Pkt*)(Cppi_HostDesc*)QMSS_DESC_PTR(Qmss_queuePop(p->q));
171 #ifdef PKTIO_GET_BENCHMARK
172 if (r==0) vv10p=netapi_timing_stop();
173 #endif
174 if(!temp) break;
175 /* process meta data */
176 pkt_list[r]= temp;
177 meta_s[r].flags1=0x1;
178 }
179 if (r) p->cb((struct PKTIO_HANDLE_tag *)p, pkt_list, &meta_s[0], r, 0LL);
180 return r;
181 }
182 //********************************************
183 //poll nwal data queues for pkts from netcp
184 //********************************************
185 static int pktio_poll_nwal(struct PKTIO_HANDLE_tag * pp, PKTIO_POLL_T * p_poll_cfg, int * err)
186 {
187 int r=0;
188 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
189 *err=0;
190 /* Poll for common L2/L3 packets and L4 class pkts (todo-> only do L4 if classifiers are
191 set.. optimizaion maybe? */
192 #ifdef PKTIO_GET_BENCHMARK
193 vv13p=netapi_timing_stop();
194 #endif
195 r=nwal_pollPkt(p->nwalInstanceHandle,
196 p->poll_flags,
197 (uint32_t) p,
198 p->max_n,
199 QMSS_PARAM_NOT_SPECIFIED,
200 (void*) NULL);
201 return r;
202 }
203 //********************************************
204 //poll nwal sideband queues for pkts from SA
205 //********************************************
206 static int pktio_poll_sb(struct PKTIO_HANDLE_tag * pp, PKTIO_POLL_T * p_poll_cfg, int * err)
207 {
208 int r=0;
209 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
210 *err=0;
211 r=nwal_pollDm(p->nwalInstanceHandle,
212 nwal_POLL_DM_DEF_SB_SA_Q,
213 (uint32_t) p,
214 p->max_n,
215 QMSS_PARAM_NOT_SPECIFIED,
216 (void *) NULL);
217 return r;
218 }
220 //********************************************
221 //poll app-provided netcp rx queue
222 //********************************************
223 static int pktio_poll_nwal_adj(struct PKTIO_HANDLE_tag * pp, PKTIO_POLL_T * p_poll_cfg, int * err)
224 {
225 int r=0;
226 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
227 *err=0;
228 /* Poll for common L2/L3 packets and L4 class pkts (todo-> only do L4 if classifiers are
229 set.. optimizaion maybe? */
230 #ifdef PKTIO_GET_BENCHMARK
231 vv14p=netapi_timing_stop();
232 #endif
233 r=nwal_pollPkt(p->nwalInstanceHandle,
234 nwal_POLL_APP_MANAGED_PKT_Q,
235 (uint32_t) p,
236 p->max_n,
237 p->q,
238 (void *) NULL);
239 return r;
240 }
242 //********************************************
243 //poll app-defined sideband queues for pkts from SA
244 //********************************************
245 static int pktio_poll_sb_adj(struct PKTIO_HANDLE_tag * pp, PKTIO_POLL_T * p_poll_cfg, int * err)
246 {
247 int r=0;
248 PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
249 *err=0;
250 r=nwal_pollDm(p->nwalInstanceHandle,
251 nwal_POLL_DM_APP_MANAGED_Q,
252 (uint32_t) p,
253 p->max_n,
254 p->q,
255 (void *) NULL);
256 return r;
257 }
259 /*-----------------------MAIN API----------------------*/
260 /* create a channel */
261 PKTIO_HANDLE_T * pktio_create(NETAPI_T n, char * name,
262 PKTIO_CB cb, PKTIO_CFG_T * p_cfg, int * err)
263 {
264 int r = 0;
265 PKTIO_HANDLE_T *p;
266 uint8_t isAllocated;
268 *err=0;
270 if ((!p_cfg)||(!name)) {*err=NETAPI_ERR_BAD_INPUT; return NULL;}
271 if ((p_cfg->flags2 & PKTIO_PKT) &&(p_cfg->flags1& PKTIO_W)) { *err=NETAPI_ERR_BAD_INPUT; return NULL;};
272 if ((p_cfg->flags2 & PKTIO_SB) &&(p_cfg->flags1& PKTIO_W)) { *err=NETAPI_ERR_BAD_INPUT; return NULL;};
274 /* get a free channel handle */
275 p=pktiop_get_free_channel_slot(n);
276 if (!p) {*err = PKTIO_NOMEM; return (p); }
278 p->inuse= PKTIO_INUSE;
279 p->back = n;
280 p->cb = cb;
281 p->max_n = p_cfg->max_n;
282 p->_poll=pktio_poll_dummy;
283 p->_send=pktio_send_dummy;
284 memcpy((char *)&p->cfg, (char*) p_cfg, sizeof(PKTIO_CFG_T));
286 /* create a general queue (for now). todo: allow qnum to be passed in */
287 p->q = Qmss_queueOpen(Qmss_QueueType_GENERAL_PURPOSE_QUEUE,
288 QMSS_PARAM_NOT_SPECIFIED, &isAllocated);
289 if (p->q == (Qmss_QueueHnd) NULL)
290 {
291 printf(">pktio_create: queueOpen failed\n");
292 p->inuse=0;
293 *err= NETAPI_ERR_QLLD; ///queue lld error
294 return NULL;
295 }
296 p->qInfo = Qmss_getQueueNumber(p->q);
297 if (p_cfg->flags2 & PKTIO_PKT)
298 {
299 p->use_nwal = PKTIO_4_ADJ_NWAL;
300 p->_poll=pktio_poll_nwal_adj;
301 p->nwalInstanceHandle = netapi_return_nwal_instance_handle(n);
302 }
303 else if (p_cfg->flags2 & PKTIO_SB)
304 {
305 p->use_nwal = PKTIO_4_ADJ_SB;
306 p->_poll=pktio_poll_sb_adj;
307 p->nwalInstanceHandle = netapi_return_nwal_instance_handle(n);
308 }
309 else
310 {
311 p->use_nwal=0;
312 if (p_cfg->flags1& PKTIO_W) p->_send=pktio_send_ipc;
313 if (p_cfg->flags1& PKTIO_R) p->_poll=pktio_poll_ipc;
314 }
316 /* save name */
317 strncpy(p->name,name,
318 strlen(name)<PKTIO_MAX_NAME ?
319 strlen(name):PKTIO_MAX_NAME);
321 /* add name, qnum to global name list */
322 if ((strcmp(name,NETCP_RX)) && (strcmp(name,NETCP_TX)) &&
323 (strcmp(name,NETCP_SB_RX)) &&
324 (strcmp(name,NETCP_SB_TX)) &&
325 (p_cfg->flags1 & PKTIO_GLOBAL) )
326 {
327 //todo: make sure this succeeds..
328 r=netapi_add_global_pktio(n, name, &p->qInfo);
329 }
330 ((NETAPI_HANDLE_T *)n )->n_pktios+=1;
331 return p;
332 }
335 /***********************************************************/
336 /************** open an existing channel. *****************/
337 /***********************************************************/
338 PKTIO_HANDLE_T * pktio_open(NETAPI_T n, char *name,
339 PKTIO_CB cb, PKTIO_CFG_T * p_cfg, int * err)
340 {
341 int r=0;
342 PKTIO_HANDLE_T *p, *p2;
343 uint8_t isAllocated;
344 *err=0;
345 Qmss_Queue *p_qnum;
347 if ((!p_cfg)||(!name)) {*err=NETAPI_ERR_BAD_INPUT; return NULL;}
349 /* get a free channel handle */
350 p=pktiop_get_free_channel_slot(n);
351 if (!p) {*err = PKTIO_NOMEM; return (p); }
352 ((NETAPI_HANDLE_T *)n)->n_pktios+=1;
354 p->inuse= PKTIO_INUSE;
355 p->back = n;
356 p->cb = cb;
357 p->max_n = p_cfg->max_n;
358 p->_poll=pktio_poll_dummy;
359 p->_send=pktio_send_dummy;
360 memcpy((char *)&p->cfg, (char*) p_cfg, sizeof(PKTIO_CFG_T));
362 /* special handling of NETCP_RX, NETCP_TX */
363 if( (!strcmp(name, NETCP_RX)) || (!strcmp(name,NETCP_TX)) )
364 {
365 /* these have already been opened internally, so don't search in global list */
366 p->use_nwal = PKTIO_DEF_NWAL;
367 p->q = 0;
368 p->nwalInstanceHandle = netapi_return_nwal_instance_handle(n);
369 if (!strcmp(name,NETCP_RX))
370 {
371 p->_poll=pktio_poll_nwal;
372 p->poll_flags= nwal_POLL_DEFAULT_GLOB_PKT_Q| nwal_POLL_DEFAULT_PER_PROC_PKT_Q;
373 }
374 if (!strcmp(name,NETCP_TX)) p->_send=pktio_send_nwal;
375 }
376 else if( (!strcmp(name, NETCP_SB_RX)) || (!strcmp(name,NETCP_SB_TX)) )
377 {
378 /* these have already been opened internally, so don't search in global list */
379 p->use_nwal = PKTIO_DEF_SB;
380 p->q = 0;
381 p->nwalInstanceHandle = netapi_return_nwal_instance_handle(n);
382 if (!strcmp(name,NETCP_SB_RX)) p->_poll=pktio_poll_sb;
383 if (!strcmp(name,NETCP_SB_TX)) p->_send=pktio_send_sb;
384 }
385 else
386 {
387 /* find queue in global list */
388 p_qnum = netapi_find_global_pktio(n, name);
389 if (!p_qnum )
390 {
391 printf(">pktio_open: can't find %s\n",name);
392 p->inuse=0;
393 *err= NETAPI_ERR_NOTFOUND; ///queue lld error
394 return NULL;
395 }
397 /* open a general queue (for now). use qnum that was just found */
398 p->q = Qmss_queueOpen(Qmss_QueueType_GENERAL_PURPOSE_QUEUE,
399 p_qnum->qNum , &isAllocated);
400 if (p->q == (Qmss_QueueHnd) NULL)
401 {
402 printf(">pktio_create: queueOpen failed\n");
403 p->inuse=0;
404 *err= NETAPI_ERR_QLLD; ///queue lld error
405 return NULL;
406 }
407 p->qInfo = Qmss_getQueueNumber(p->q);
408 if (p_cfg->flags2 & PKTIO_PKT)
409 {
410 p->use_nwal = PKTIO_4_ADJ_NWAL; //additonal RX q for nwal
411 p->_poll = pktio_poll_nwal_adj;
412 p->nwalInstanceHandle = netapi_return_nwal_instance_handle(n);
413 }
414 else if (p_cfg->flags2 & PKTIO_SB)
415 {
416 p->use_nwal = PKTIO_4_ADJ_SB; //additional RX q for sideband with NWAL
417 p->_poll = pktio_poll_sb_adj;
418 p->nwalInstanceHandle = netapi_return_nwal_instance_handle(n);
419 }
420 else
421 {
422 p->use_nwal=0; //not handled by nwal
423 if (p_cfg->flags1& PKTIO_W) p->_send=pktio_send_ipc;
424 if (p_cfg->flags1& PKTIO_R) p->_poll=pktio_poll_ipc;
425 }
426 }
428 /* save name */
429 strncpy(p->name,name,
430 strlen(name)<PKTIO_MAX_NAME ?
431 strlen(name):PKTIO_MAX_NAME);
435 return p;
436 }
438 /***********************************************************/
439 /************** control the channel ****************/
440 /***********************************************************/
441 void pktio_control(PKTIO_HANDLE_T * p,
442 PKTIO_CB cb,
443 PKTIO_CFG_T * p_cfg,
444 PKTIO_CONTROL_T * p_control,
445 int *err)
446 {
447 if (!p) { *err=1; return;}
448 if (cb)
449 {
450 p->cb = cb;
451 }
452 if (p_control)
453 {
454 /* todo: check for validity, eg don't allow clear of NETCP TX queues */
455 /* todo: implement divert */
456 switch(p_control->op)
457 {
458 //clear the queue
459 case(PKTIO_SET_POLL_FLAGS):
460 p->poll_flags=p_control->poll_flags;
461 break;
462 case(PKTIO_CLEAR):
463 netapi_zapQ(p->q);
464 break;
465 case(PKTIO_DIVERT):
466 default:
467 printf(">pktio_control: pktio_control op %d not implemented\n",p_control->op);
468 *err= NETAPI_ERR_NOT_IMPLEMENTED;
469 break;
470 }
471 }
472 //all we configure is max_n. Can't change type of queue, rx/tx, etc
473 if (p_cfg)
474 {
475 p->max_n = p_cfg->max_n;
476 }
477 *err=0;
478 return;
479 }
481 /***********************************************************/
482 /*****************close ***************************/
483 /***********************************************************/
484 void pktio_close(PKTIO_HANDLE_T * p, int * err)
485 {
486 if(!p) { *err=1; return;}
487 *err=0;
488 if (p->q) Qmss_queueClose(p->q); //LLD keeps reference count
489 p->q=-1;
490 p->inuse=0;
491 ((NETAPI_HANDLE_T *)p->back)->n_pktios-=1;
492 return;
493 }
495 /***********************************************************/
496 /*****************Delete***************************/
497 /***********************************************************/
498 void pktio_delete(PKTIO_HANDLE_T * p, int * err)
499 {
500 if(!p) { *err=1; return;}
501 *err=0;
502 /* remove from name list */
503 netapi_del_global_pktio((NETAPI_HANDLE_T *)p->back, p->name);
504 if((p->use_nwal != PKTIO_DEF_NWAL) && (p->use_nwal != PKTIO_DEF_SB))
505 {
506 netapi_zapQ(p->q); //since we are deleting, zap the queue
507 Qmss_queueClose(p->q);
508 }
509 p->q=-1;
510 p->inuse=0;
511 ((NETAPI_HANDLE_T *)p->back)->n_pktios-=1;
512 return ;
513 }
516 /***********************************************************/
517 /*****************send *************************/
518 /***********************************************************/
519 int pktio_send_genric(PKTIO_HANDLE_T * p, Ti_Pkt *pkt, PKTIO_METADATA_T *m, int * err)
520 {
521 nwalTxPktInfo_t * pPktInfo=m->u.tx_meta;
522 nwal_RetValue res;
523 *err=0;
524 if(! (p->cfg.flags1&PKTIO_W)) return 0;
525 if ((p->use_nwal== PKTIO_DEF_NWAL) )
526 {
527 pPktInfo->pPkt = pkt;
528 #ifdef PKTIO_GET_BENCHMARK
529 vv11p=netapi_timing_stop();
530 #endif
531 res=nwal_send(p->nwalInstanceHandle, m->sa_handle,pPktInfo);
532 #ifdef PKTIO_GET_BENCHMARK
533 vv12p=netapi_timing_stop();
534 #endif
535 if (res != nwal_OK) { printf("nwal send err= %d (%x)\n", res, res); *err = NETAPI_ERR_NWAL_TX_ERR -res;}
536 }
537 else if ((p->use_nwal== PKTIO_DEF_SB) )
538 {
539 nwalDmTxPayloadInfo_t *pPktInfoSB = m->u.tx_sb_meta;
540 pPktInfoSB->pPkt = pkt;
541 res=nwal_sendDM(p->nwalInstanceHandle, m->sa_handle,pPktInfoSB);
542 if (res != nwal_OK) *err = NETAPI_ERR_NWAL_TX_ERR -res;
543 }
544 else
545 {
546 /* tod: meta data for non netcp xfers */
547 /* process meta data */
548 #ifdef PKTIO_GET_BENCHMARK
549 vv8p=netapi_timing_stop();
550 #endif
551 Qmss_queuePushDesc (p->q, (void*)pkt);
553 #ifdef PKTIO_GET_BENCHMARK
554 vv9p=netapi_timing_stop();
555 #endif
556 }
557 return 1;
558 }
560 /***********************************************************/
561 /*******************send multiple**************************/
562 /***********************************************************/
563 int pktio_sendMulti(PKTIO_HANDLE_T * p, Ti_Pkt * pkt[], PKTIO_METADATA_T * m[], int np, int* err)
564 {
565 nwal_RetValue res;
566 int r=0;
567 *err=0;
568 if(! p->cfg.flags1&PKTIO_W) return 0;
569 if ((p->use_nwal== PKTIO_DEF_NWAL) )
570 {
571 for(r=0;r<np;r++)
572 {
573 nwalTxPktInfo_t *pPktInfo= m[r]->u.tx_meta;
574 pPktInfo->pPkt = pkt[r];
575 res=nwal_send(p->nwalInstanceHandle,m[r]->sa_handle,pPktInfo);
576 if (res != nwal_OK) *err = NETAPI_ERR_NWAL_TX_ERR -res;
577 }
578 }
579 else if ((p->use_nwal== PKTIO_DEF_SB) )
580 {
581 for(r=0;r<np;r++)
582 {
583 nwalDmTxPayloadInfo_t *pPktInfoSB =m[r]->u.tx_sb_meta;
584 pPktInfoSB->pPkt = pkt[r];
585 res=nwal_sendDM(p->nwalInstanceHandle, m[r]->sa_handle,pPktInfoSB);
586 if (res != nwal_OK) *err = NETAPI_ERR_NWAL_TX_ERR -res;
587 }
588 }
589 else
590 {
591 for(r=0;r<np;r++)
592 {
593 /* process meta data */
594 Qmss_queuePushDesc(p->q, (void*) pkt[r]);
595 }
596 }
597 return r;
598 }
600 /***********************************************************/
601 /******************* polling **********************/
602 /***********************************************************/
604 /* poll a particular channel */
605 int pktio_poll_generic(PKTIO_HANDLE_T * p, PKTIO_POLL_T * p_poll_cfg, int * err)
606 {
607 int r=0;
608 int n;
609 Ti_Pkt * temp;
610 Ti_Pkt * pkt_list[PKTIO_MAX_RECV];
611 PKTIO_METADATA_T meta_s[PKTIO_MAX_RECV];
612 //uint64_t ts= netapi_getTimestamp(); //get_ts
613 uint64_t ts=0LL;
615 if(! p->cfg.flags1&PKTIO_R) return 0;
617 /** poll the netcp default RX queue we squirt out below */
618 if (p->use_nwal==PKTIO_DEF_NWAL)
619 {
620 /* Poll for common L2/L3 packets and L4 class pkts (todo-> only do L4 if classifiers are
621 set.. optimizaion maybe? */
622 #ifdef PKTIO_GET_BENCHMARK
623 vv13p=netapi_timing_stop();
624 #endif
625 r=nwal_pollPkt(p->nwalInstanceHandle,
626 p->poll_flags,
627 (uint32_t) p,
628 p->max_n,
629 QMSS_PARAM_NOT_SPECIFIED,
630 (void*) NULL);
631 }
632 /** poll a netcp RX queue. we squirt out below */
633 else if (p->use_nwal==PKTIO_4_ADJ_NWAL)
634 {
635 /* Poll an additional NETCP RX queue */
636 #ifdef PKTIO_GET_BENCHMARK
637 vv14p=netapi_timing_stop();
638 #endif
639 r=nwal_pollPkt(p->nwalInstanceHandle,
640 nwal_POLL_APP_MANAGED_PKT_Q,
641 (uint32_t) p,
642 p->max_n,
643 p->q,
644 (void *) NULL);
645 }
646 /** poll the NETCP default SideBand (data mode -dm) return queue **/
647 else if(p->use_nwal==PKTIO_DEF_SB)
648 {
649 r=nwal_pollDm(p->nwalInstanceHandle,
650 nwal_POLL_DM_DEF_SB_SA_Q,
651 (uint32_t) p,
652 p->max_n,
653 QMSS_PARAM_NOT_SPECIFIED,
654 (void *) NULL);
656 }
657 /** poll an app define SideBand (data mode -dm) return queue **/
658 else if (p->use_nwal==PKTIO_4_ADJ_SB)
659 {
660 r=nwal_pollDm(p->nwalInstanceHandle,
661 nwal_POLL_DM_APP_MANAGED_Q,
662 (uint32_t) p,
663 p->max_n,
664 p->q,
665 (void *) NULL);
666 }
668 /* poll an IPC queue */
669 else
670 {
671 *err=0;
672 n= (p->max_n< PKTIO_MAX_RECV) ? p->max_n : PKTIO_MAX_RECV;
673 for(r=0;r<n;r++)
674 {
675 #ifdef PKTIO_GET_BENCHMARK
676 if (r==0) vv7p=netapi_timing_stop();
677 #endif
678 temp=(Ti_Pkt*)(Cppi_HostDesc*)QMSS_DESC_PTR(Qmss_queuePop(p->q));
680 #ifdef PKTIO_GET_BENCHMARK
681 if (r==0) vv10p=netapi_timing_stop();
682 #endif
683 if(!temp) break;
684 /* process meta data */
685 pkt_list[r]= temp;
686 meta_s[r].flags1=0x1;
687 }
688 if (r) p->cb((struct PKTIO_HANDLE_tag *)p, pkt_list, &meta_s[0], r, ts);
689 }
690 return r;
691 }
693 /***********************************************************/
694 /** poll all channels attached to this handle */
695 /***********************************************************/
696 int pktio_pollAll(NETAPI_T handle, PKTIO_POLL_T * p_poll_cfg, int *err)
697 {
698 int i=0;
699 int r=0;
700 int err2;
701 int cnt=0;
702 PKTIO_HANDLE_T **pp =( PKTIO_HANDLE_T **) netapi_get_pktio_list(handle);
704 *err=0;
705 for(i=0;i<NETAPI_MAX_PKTIO && cnt < ((NETAPI_HANDLE_T *)handle)->n_pktios;i++)
706 {
707 if (pp[i]->inuse != PKTIO_INUSE) continue;
708 if(!(pp[i]->cfg.flags1&PKTIO_R)) continue;
709 r+=pktio_poll(pp[i], p_poll_cfg, &err2); cnt+=1;
710 if (err2) { *err = err2; break;}
711 }
712 return r;
714 }
716 /***** this is the callback we registered with NWAL for pkt reception *****/
717 /* appcookie -> pktio handle */
718 void netapi_NWALRxPktCallback (uint32_t appCookie,
719 uint16_t numPkts,
720 nwalRxPktInfo_t* pPktInfo,
721 uint64_t timestamp,
722 nwal_Bool_t* pFreePkt)
723 {
724 PKTIO_HANDLE_T * p = (PKTIO_HANDLE_T *) appCookie;
725 int r=0;
726 int n;
727 Ti_Pkt * pkt_list[PKTIO_MAX_RECV];
728 PKTIO_METADATA_T meta_s[PKTIO_MAX_RECV];
730 #ifdef PKTIO_GET_BENCHMARK
731 vv15p=netapi_timing_stop();
732 #endif
733 for(r=0;r<numPkts;r++)
734 {
735 pkt_list[r] = pPktInfo[r].pPkt;
736 meta_s[r].flags1 = PKTIO_META_RX;
737 meta_s[r].u.rx_meta = &pPktInfo[r];
738 }
739 if (r) p->cb((struct PKTIO_HANDLE_tag *)p, pkt_list, &meta_s[0], r, timestamp);
741 }
743 /***** this is the callback we registered with NWAL for crypto callbcak *****/
744 /* appcookie -> pktio handle */
745 void netapi_NWALSBPktCallback (uint32_t appCookie,
746 uint16_t numPkts,
747 nwalDmRxPayloadInfo_t* pDmRxPktInfo,
748 nwal_Bool_t* pFreePkt)
749 {
750 PKTIO_HANDLE_T * p = (PKTIO_HANDLE_T *) appCookie;
751 int r=0;
752 int n;
753 Ti_Pkt * pkt_list[PKTIO_MAX_RECV];
754 PKTIO_METADATA_T meta_s[PKTIO_MAX_RECV];
755 for(r=0;r<numPkts;r++)
756 {
757 pkt_list[r] = pDmRxPktInfo[r].pPkt;
758 meta_s[r].flags1 = PKTIO_META_SB_RX;
759 meta_s[r].u.rx_sb_meta = &pDmRxPktInfo[r];
760 }
761 if (r) p->cb((struct PKTIO_HANDLE_tag *)p, pkt_list, &meta_s[0], r, 0LL);
763 }