1 /******************************************
2 * File: net_test_router.c
3 * Purpose: net_test_router application
4 **************************************************************
5 * FILE: net_test_router.c
6 *
7 * DESCRIPTION: netapi user space transport
8 * library net_test_router application
9 *
10 * REVISION HISTORY: rev 0.0.1
11 *
12 * Copyright (c) Texas Instruments Incorporated 2013
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 <stdio.h>
45 #include <stdlib.h>
46 #include <unistd.h>
47 #include <string.h>
48 #include <signal.h>
49 #include <pthread.h>
51 #include "net_test.h"
52 #include "trie.h"
53 #include "string.h"
55 #include <sys/resource.h>
57 #include <ti/drv/sa/salld.h>
58 #include <ti/drv/pa/pa.h>
60 #include "net_test_util.h"
62 extern int QUIT;
64 /* Global definitions */
65 #ifdef MULTI_THREAD
66 cpu_set_t cpu_set;
67 #endif
69 netTestConfig_t netTestCfg;
70 static netTestConfigFile_t config_file;
72 char input_file_name[] = "net_test_config.txt";
74 nwal_RetValue nwalRetVal;
75 Pktlib_HeapHandle ourHeap;
76 Pktlib_HeapHandle specialSmall;
77 Pktlib_HeapHandle specialLarge;
79 PKTIO_HANDLE_T *netcp_rx_chan;
80 PKTIO_HANDLE_T *netcp_rx_chan2;
81 PKTIO_HANDLE_T *netcp_tx_chan;
82 PKTIO_HANDLE_T *netcp_sb_tx_chan;
83 PKTIO_HANDLE_T *netcp_sb_rx_chan;
84 PKTIO_CFG_T our_chan_cfg={PKTIO_RX_TX, PKTIO_LOCAL, PKTIO_Q_ANY, 8};
85 PKTIO_CFG_T netcp_rx_cfg={PKTIO_RX, PKTIO_NA, PKTIO_NA, 8};
86 PKTIO_CFG_T netcp_rx_cfg2={PKTIO_RX, (PKTIO_GLOBAL|PKTIO_PKT), PKTIO_Q_ANY, 8};
87 PKTIO_CFG_T netcp_tx_cfg={PKTIO_TX, PKTIO_NA, PKTIO_NA, 8};
88 PKTIO_CFG_T netcp_sb_rx_cfg={PKTIO_RX, PKTIO_NA, PKTIO_NA, 8};
89 PKTIO_CFG_T netcp_sb_tx_cfg={PKTIO_TX, PKTIO_NA, PKTIO_NA, 8};
91 NETCP_CFG_EXCEPTION_PKT_T expPkt_appid;
92 static hplib_spinLock_T stats_lock;
94 Trie * P_trie;
95 Trie *p_trie_sa_rx;
96 Trie *p_trie_sa_tx;
99 #include "router.c"
100 extern Trie * our_router;
101 extern OUR_ROUTE_T routes[];
103 unsigned int ip[MAX_ROUTES]={BE(0x0a0100c8),BE(0x0a00000a),BE(0x0a02000a),BE(0xc0a8010a),BE(0x9eda6719)};
105 void recv_cb_router(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
106 PKTIO_METADATA_T meta[], int n_pkts,
107 uint64_t ts );
110 extern STATS_T stats[TUNE_NETAPI_NUM_CORES];
111 extern paSysStats_t netcp_stats;
113 /*******************************************
114 *************NETAPI OBJECTS***************
115 *****************************************/
116 static NETAPI_CFG_T our_netapi_default_cfg=
117 {
118 TUNE_NETAPI_PERM_MEM_SZ,
119 128, //start of packet offset for hw to place data on rx for default flow
120 TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
121 TUNE_NETAPI_NUM_GLOBAL_DESC, //total we will use
122 TUNE_NETAPI_DEFAULT_NUM_BUFFERS, //#descriptors+buffers in default heap
123 64, //#descriptors w/o buffers in default heap
124 TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128, //size of buffers in default heap
125 128 , //tail room
126 256 //extra room
127 };
131 void house(NETAPI_SCHED_HANDLE_T *s);
132 NETAPI_T netapi_handle;
133 NETAPI_SCHED_HANDLE_T * our_sched;
134 #ifdef MULTI_THREAD
135 NETAPI_SCHED_HANDLE_T * scheduler[TUNE_NETAPI_NUM_CORES];
136 #endif
137 NETAPI_SCHED_CONFIG_T our_sched_cfg={
138 NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 5000000 //every 5000000 poll loops
139 };
142 NETCP_CFG_IP_T ip_rule0;
143 NETCP_CFG_IP_T ip_rule1;
145 PKTIO_CONTROL_T zap_channel_control={PKTIO_CLEAR, NULL};
147 /* security objects. (for loopback mode) */
148 netTestSA_t sa_info[MAX_SEC_INDEX];
151 NETCP_CFG_IPSEC_POLICY_T rx_policy[MAX_SEC_INDEX];
156 /*************************END NETAPI OBJECTS***********************/
158 void update_header(HEAD_T * p_head, int len)
159 {
160 unsigned char *p = (unsigned char *) &p_head->udp[1];
161 len -= (20+14);
162 /* update ip checksum */
163 /* update udp checksum */
164 /* update length */
165 *p= (len&0xff00)>>8;
166 *(p+1) = len&0xff;
167 }
169 #ifdef MULTI_THREAD
170 NETAPI_T worker_nh[TUNE_NETAPI_NUM_CORES];
171 void slow_path_thread(int coreid)
172 {
173 int err;
174 PKTIO_HANDLE_T *rx_chan;
175 PKTIO_HANDLE_T *tx_chan;
176 PKTIO_HANDLE_T *sb_tx_chan;
177 PKTIO_HANDLE_T *sb_rx_chan;
182 CPU_ZERO( &cpu_set);
183 #ifdef CORTEX_A15
184 CPU_SET( coreid, &cpu_set);
185 hplib_utilSetupCore(coreid, &cpu_set);
186 #else
187 CPU_SET( 0, &cpu_set);
188 hplib_utilSetupCore(coreid+1, &cpu_set);
189 #endif
190 worker_nh[coreid]=netapi_init(NETAPI_CORE_MASTER,NULL);
192 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) worker_nh[coreid];
194 /* open netcp default tx, rx queues */
195 tx_chan = pktio_open(worker_nh[coreid], NETCP_TX, NULL, &netcp_tx_cfg, &err);
197 rx_chan = pktio_open(worker_nh[coreid], NETCP_RX, (PKTIO_CB) recv_cb_router, &netcp_rx_cfg, &err);
201 netapi_setCookie(worker_nh[coreid],(void*)coreid);
203 scheduler[coreid] =netapi_schedOpen(worker_nh[coreid],&our_sched_cfg, &err);
204 if (!scheduler[coreid])
205 {
206 Debug_printf("sched create failed for core%d\n",coreid);
207 exit(1);
208 }
209 scheduler[coreid]->config.yield = FALSE;
210 scheduler[coreid]->config.pollGarbageQ = TRUE;
211 scheduler[coreid]->config.pollCtrlQ = TRUE;
212 /*********************************************/
213 /**************Entry point into scheduler ****/
214 /*********************************************/
215 netapi_schedRun(scheduler[coreid], &err);
216 Debug_printf(">net_test: core %d worker thread done\n",coreid);
218 pktio_close(tx_chan, &err);
219 pktio_close(rx_chan, &err);
220 netapi_shutdown(worker_nh[coreid]);
221 }
223 void fast_path_thread(int coreid)
224 {
225 int err;
226 PKTIO_HANDLE_T *rx_chan;
227 PKTIO_HANDLE_T *tx_chan;
228 PKTIO_HANDLE_T *sb_tx_chan;
229 PKTIO_HANDLE_T *sb_rx_chan;
231 #ifdef CORTEX_A15
232 CPU_SET( coreid, &cpu_set);
233 hplib_utilSetupCore(coreid, &cpu_set);
234 #else
235 CPU_SET( 0, &cpu_set);
236 hplib_utilSetupCore(coreid + 1, &cpu_set);
237 #endif
238 worker_nh[coreid]=netapi_init(NETAPI_CORE_MASTER,NULL);
240 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) worker_nh[coreid];
242 /* open netcp default tx, rx queues */
243 tx_chan = pktio_open(worker_nh[coreid], NETCP_TX, NULL, &netcp_tx_cfg, &err);
246 rx_chan = pktio_open(worker_nh[coreid], NETCP_RX, (PKTIO_CB) recv_cb_router, &netcp_rx_cfg, &err);
247 netapi_setCookie(worker_nh[coreid],(void*)coreid);
249 scheduler[coreid] =netapi_schedOpen(worker_nh[coreid],&our_sched_cfg, &err);
250 if (!scheduler[coreid])
251 {
252 Debug_printf("sched create failed for core%d\n",coreid);
253 exit(1);
254 }
256 /*********************************************/
257 /**************Entry point into scheduler ****/
258 /*********************************************/
259 scheduler[coreid]->config.yield = FALSE;
260 scheduler[coreid]->config.pollGarbageQ = FALSE;
261 scheduler[coreid]->config.pollCtrlQ = FALSE;
262 //sleep(100000);
263 netapi_schedRun(scheduler[coreid], &err);
264 Debug_printf(">net_test: core %d worker thread done\n",coreid);
265 pktio_close(tx_chan, &err);
266 pktio_close(rx_chan, &err);
267 netapi_shutdown(worker_nh[coreid]);
268 \r}
270 #endif
272 /***************************************
273 ********** test driver*****************
274 ***************************************/
275 int main(int argc, char **argv)
276 {
277 int err,i;
278 Pktlib_HeapCfg heapCfg;
279 rlim_t oss,ss = 1024*1024;
280 struct rlimit rl;
281 int32_t errCode;
282 Pktlib_HeapIfTable* pPktifTable;
283 /* Local Per Process default resourcese maintained at NWAL */
284 nwalLocCxtInfo_t nwalLocCxt;
286 FILE * fpr = NULL;
289 err= getrlimit(RLIMIT_STACK,&rl);
290 if (!err) Debug_printf(" stack limit = %d\n",rl.rlim_cur); else Debug_printf("getrlimit failed\n");
292 /* install signal handler for ^c */
293 signal(SIGINT,mysig);
295 fpr = fopen(input_file_name, "r");
296 if (fpr == NULL)
297 {
298 Debug_printf("Error in opening %s input file\n", input_file_name);
299 exit(1);
300 }
301 else
302 {
303 memset(&config_file, 0, sizeof(netTestConfigFile_t));
304 memset(&netTestCfg, 0, sizeof(netTestConfig_t));
305 parse_config_file(fpr,&config_file);
306 }
308 memset(&sa_info, 0, sizeof(sa_info));
310 #ifdef MULTI_THREAD
311 /* assign main net_test thread to run on core 0 */
312 CPU_ZERO( &cpu_set);
313 CPU_SET( 0, &cpu_set);
314 hplib_utilSetupCore(0, &cpu_set);
315 #endif
316 /* create netapi */
317 netapi_handle = netapi_init(NETAPI_SYS_MASTER, &our_netapi_default_cfg);
319 netcp_cfgExceptions(netapi_handle, NETCP_CFG_ALL_EXCEPTIONS, NETCP_CFG_ACTION_DISCARD, (NETCP_CFG_ROUTE_HANDLE_T) NULL);
320 expPkt_appid = netcp_cfgExceptions(netapi_handle, 7, NETCP_CFG_ACTION_TO_SW, (NETCP_CFG_ROUTE_HANDLE_T) NULL);
322 /* open the main heap */
323 ourHeap = Pktlib_findHeapByName("netapi");
324 if (!ourHeap)
325 {
326 Debug_printf("Pktlib_findHeapByName() fail\n");
327 exit(1);
328 }
330 /* create two secondary heaps */
331 /* Initialize the heap configuration. */
332 memset ((void *)&heapCfg, 0, sizeof(Pktlib_HeapCfg));
334 pPktifTable = netapi_getPktlibIfTable();
335 /* Populate the heap configuration */
336 heapCfg.name = "netapi-small";
337 heapCfg.memRegion = NETAPI_GLOBAL_REGION;
338 heapCfg.sharedHeap = 1;
339 heapCfg.useStarvationQueue = 0;
340 heapCfg.dataBufferSize = 512;
341 heapCfg.numPkts = 64;
342 heapCfg.numZeroBufferPackets= 0;
343 heapCfg.heapInterfaceTable.data_malloc = pPktifTable->data_malloc;
344 heapCfg.heapInterfaceTable.data_free = pPktifTable->data_free;
345 heapCfg.dataBufferPktThreshold = 0;
346 heapCfg.zeroBufferPktThreshold = 0;
348 specialSmall = Pktlib_createHeap(&heapCfg, &errCode);
349 heapCfg.name = "netapi-big";
350 heapCfg.dataBufferSize = 1600;
351 specialLarge = Pktlib_createHeap(&heapCfg, &errCode);
352 //register these heaps so poll routine will include their garbage queues.
353 netapi_registerHeap(netapi_handle, specialSmall);
354 netapi_registerHeap(netapi_handle, specialLarge);
356 /* open netcp default tx, rx queues */
357 netcp_tx_chan= pktio_open(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg, &err);
358 if (!netcp_tx_chan)
359 {
360 Debug_printf("pktio open TX failed err=%d\n",err);
361 exit(1);
362 }
363 netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb_router, &netcp_rx_cfg, &err);
364 if (!netcp_rx_chan)
365 {
366 Debug_printf("pktio open RX failed err=%d\n",err);
367 exit(1);
368 }
370 Debug_printf("net_test> %d bytes left in our CMA area\n", netapi_getBufMemRemainder());
371 /* create scheduler instance */
372 our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err);
373 if (!our_sched) {Debug_printf("sched create failed\n"); exit(1);}
376 /*create net_test MAC interfaces, attach IP to created MAC interfaces */
377 create_interfaces(&ip_rule0, &ip_rule1);
379 p_trie_sa_rx = trie_new();
380 p_trie_sa_tx = trie_new();
381 if (!p_trie_sa_rx || !p_trie_sa_tx)
382 {Debug_printf("trie alloc for SA failed\n"); exit(1);}
384 /* Create RX SA's, RX Policy and TX SA's */
385 create_sec_associations(netcp_sb_rx_chan, netcp_sb_tx_chan,netcp_tx_chan);
388 #ifdef MULTI_THREAD
389 {
390 char c;
391 /* create and set affinity of slow path and fast path threads to
392 * specific CPU cores as specified in the net_test_config.txt file */
393 create_sp_fp_threads();
396 //this thread of execution (main) now just waits on user input
397 for(;;)
398 {
399 printf(">");
400 c=getchar();
401 if (c=='q') {QUIT=1;break;}
402 else if (c=='s') our_stats_cb(netapi_handle, &netcp_stats);
403 else if (c=='h') Debug_printf("'q' to quit, 's' for stats, 'h' for help\n");
404 }
406 }
407 #else
408 /*********************************************/
409 /**************Entry point into scheduler ****/
410 /*********************************************/
411 netapi_schedRun(our_sched, &err);
412 #endif
414 /* done */
415 our_stats_cb(netapi_handle, NULL);
419 /*************************************************
420 ************CLEAN UP****************************
421 ************************************************/
424 delete_sec_associations();
425 delete_interfaces( &ip_rule0, &ip_rule1);
427 //close pktio channels we opened
428 pktio_close(netcp_tx_chan ,&err);
429 pktio_close(netcp_rx_chan ,&err);
430 netapi_shutdown(netapi_handle);
431 }
433 static inline void send_it(Ti_Pkt *tip, int len, ROUTE_SEC_T * p_sec, int out_port)
434 {
435 unsigned long st1;
436 unsigned long st2;
437 int err=0;
438 PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
439 nwalTxPktInfo_t meta_tx2={0};
440 st1=hplib_mUtilGetPmuCCNT();
441 #ifdef MULTI_THREAD
442 int coreid=Osal_nwalGetProcId(); //who we are(thread local)
443 //int coreid = our_core;
444 #else
445 int coreid=0;
446 #endif
447 if (len<60)
448 {
449 unsigned int templen;
450 char * p_pkt;
451 len=60;
452 Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
453 Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
454 stats[coreid].tx_min+=1;
455 }
456 Pktlib_setPacketLen(tip,len);
457 meta_tx2.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID );
458 meta_tx2.startOffset = 0;
459 meta_tx2.ipOffBytes = 14;
460 meta_tx2.ploadLen = len ;
461 meta_tx2.enetPort=out_port;
462 if(p_sec)
463 {
464 meta_tx2.txFlag1 |= NWAL_TX_FLAG1_DO_IPSEC_ESP_CRYPTO ;
465 meta2.sa_handle=p_sec->tx_inflow_mode_handle; //this tells netapi that inflow crypto needs to be applied
466 meta_tx2.saOffBytes=14+20;
467 meta_tx2.saPayloadLen=len-14-20; //don't include tag, mac and outer header
468 stats[coreid].sec_tx+=1;
469 }
470 meta2.u.tx_meta=&meta_tx2;
471 pktio_send(netcp_tx_chan,tip,&meta2,&err);
472 stats[coreid].tx +=1;
473 st2=hplib_mUtilGetPmuCCNT();
474 stats[coreid].send_cycles += (unsigned long long) (st2-st1);
475 }
476 void recv_cb_router(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
477 PKTIO_METADATA_T meta[], int n_pkts,
478 uint64_t ts )
479 {
480 int i;
481 int len;
482 int p;
483 Ti_Pkt * tip;
484 unsigned int templen;
485 char * p_pkt;
486 HEAD_T temp_head;
487 unsigned int appid;
488 IP_HEAD_T th;
489 ROUTE_SEC_T *sec_data=NULL;
490 unsigned long t1;
491 unsigned long t2;
492 unsigned long long ct1;
493 unsigned long long ct2;
494 unsigned short ip_pl;
495 unsigned long long n_c_ops;
496 int ifno;
497 int out_port;
498 #ifdef MULTI_THREAD
499 int coreid=Osal_nwalGetProcId(); //who we are(thread local)
500 //int coreid = our_core;
501 #else
502 int coreid=0;
503 #endif
504 t1=hplib_mUtilGetPmuCCNT();
505 ct1 =Osal_cache_op_measure(&n_c_ops);
506 for(i=0;i<n_pkts;i++)
507 {
508 ifno = ((unsigned int)meta[i].u.rx_meta->appId)&0xff;
509 if(coreid<TUNE_NETAPI_NUM_CORES) stats[coreid].rx+=1;
510 if (ifno < TUNE_NETAPI_MAX_NUM_MAC) stats[coreid].if_rx[ifno]+=1;
511 tip = p_recv[i];
512 Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
513 len = Pktlib_getPacketLen(tip)-4;//real length, subtract mac trailer
514 stats[coreid].rx+=1;
515 appid = ((unsigned int)meta[i].u.rx_meta->appId)&0xff000000;
516 switch(appid)
517 {
518 case(NETAPI_NETCP_MATCH_IPSEC):
519 case(NETAPI_NETCP_MATCH_IPSEC_POLICY):
520 {
521 int tailen=12+2;
522 memcpy(&temp_head,&p_pkt[14],sizeof(HEAD_T));
523 if (!check_header(&temp_head,&meta[i])) {
524 stats[coreid].n_bad+=1;
525 Pktlib_freePacket(tip);
526 continue;
527 }
528 tailen+=p_pkt[len-12-2]; //padding length (12)should come from sec_ptr
529 p_pkt = &p_pkt[8+16+20]; //16= iv len, should come from sec_ptr
530 len -= (8+16+20+tailen); //16= iv len should come from sec ptr
532 //now check inner headder.
533 memcpy(&th,&p_pkt[14],20);
534 if (!check_header(&temp_head,&meta[i])) {
535 stats[coreid].n_bad+=1;
536 Pktlib_freePacket(tip);
537 continue;
538 }
539 Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
540 Pktlib_setPacketLen(tip,len);
542 if (route_pkt(our_router, tip, &th, p_pkt, &len,&sec_data,&out_port)<0)
543 {
544 stats[coreid].n_bad+=1;
545 Pktlib_freePacket(tip);
546 }
547 else
548 {
549 send_it(tip,len,sec_data,out_port);
550 }
551 break;
552 }
553 case(NETAPI_NETCP_MATCH_GENERIC_MAC):
554 if((p_pkt[12]!=0x8)||(p_pkt[13]!=0x00))
555 {
556 stats[coreid].n_new+=1;
557 Pktlib_freePacket(tip);
558 continue;
559 }
560 if (!check_header(&temp_head,&meta[i]))
561 {
562 stats[coreid].n_bad+=1;
563 Pktlib_freePacket(tip);
564 continue;
565 }
566 memcpy(&th,&p_pkt[14],20);
567 ip_pl= (((unsigned char *)&th.w1)[2]<<8) | ((unsigned char *)&th.w1)[3];
568 if ((ip_pl+14)<60)
569 {
570 len-= (60-(ip_pl+14));
571 stats[coreid].rx_min+=1;
572 }
573 Pktlib_setPacketLen(tip,len);
574 if (route_pkt(our_router, tip, &th, p_pkt, &len,&sec_data,&out_port)<0)
575 {
576 stats[coreid].n_bad+=1;
577 Pktlib_freePacket(tip);
578 }
579 else
580 {
581 send_it(tip,len,sec_data,out_port);
582 }
583 break;
584 case(NETAPI_NETCP_MATCH_GENERIC_IP):
585 Pktlib_freePacket(tip);
586 stats[coreid].n_new=1;
587 break;
588 default:
589 stats[coreid].n_new+=1;
590 Pktlib_freePacket(tip);
591 break;
592 }
593 }
594 t2=hplib_mUtilGetPmuCCNT();
595 ct2 =Osal_cache_op_measure(&n_c_ops);
596 stats[coreid].app_cycles += (unsigned long long) (t2-t1);
597 stats[coreid].tx_cache_cycles += (unsigned long long) (ct2-ct1);
598 return;
599 }
601 /* STUB functions required for compilation */
602 void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
603 PKTIO_METADATA_T meta[], int n_pkts,
604 uint64_t ts )
605 {
606 }
608 void recv_sb_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
609 PKTIO_METADATA_T meta[], int n_pkts,
610 uint64_t ts )
611 {
612 }