SDOCM00113322: kernel RX UDP/TCP checksum offload to NETCP breaks user space tranport...
[keystone-rtos/netapi.git] / ti / runtime / netapi / demo / src / transport_dpi_demo.c
1 /******************************************
2  * File: nt_bench.c   
3  * Purpose:  benchmarks for NT.
4  **************************************************************
5  * FILE:  nt_bench.c
6  * 
7  * DESCRIPTION:  netapi user space transport
8  *               library  test application : benchmarks
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 <stdio.h>
45 #include <stdlib.h>
46 #include <unistd.h>
47 #include <string.h>
48 #include <signal.h>
49 #include <pthread.h>
50 #include <sched.h>
52 //#include "trie.h"
53 #include <ti/runtime/netapi/netapi.h>
54 #include <ti/runtime/hplib/hplib.h>
55 #include "ti/runtime/netapi/pktio.h"
56 #include "transport_dpi_demo.h"
57 #include "navl_wrapper.h"
58 //#include "ti/runtime/netapi/test/net_test.h"
59 #include <ti/drv/sa/salld.h>
61 #include <ti/drv/qmss/device/k2e/src/qmss_device.c>
62 #include <ti/drv/cppi/device/k2e/src/cppi_device.c>
64 extern Rm_ServiceHandle   *rmClientServiceHandle;
65 extern NETCP_CFG_EXCEPTION_PKT_T expPkt_appid;
68 #define netapi_timing_start hplib_mUtilGetPmuCCNT
70 navl_wrapper_cfg_info_t *pNavlCfg;
71 navl_wrapper_pkt_stat_t *pStats1;
72 navl_wrapper_pkt_stat_t *pStats2;
73 navl_global_dpi_stats *pGlobDpiStats;
74 navl_wrapper_mem_stats_t *pNavlMemStats;
77 void* pTemp;
80 STATS_T stats;
81 paSysStats_t netcp_stats;
82 //struct dpi_stats dpis;
84 #define VDPI
85 #ifdef VDPI
86 static int DPI=0;  //1 to enable
87 static int DUMP_DPI_CONN=0;
88 #endif
91 void* pShmBase;
92 void *pShmEntry;
96 static int scnt=0;
97 volatile static int QUIT=0;
98 static int XMIT=0;
99 static int CAP=0;
100 volatile int RESET=0; //to reset stats
101 static int NTH=1;
102 volatile static int PKTGEN=0;
103 int pkt_len=64;
107 NETCP_CFG_MACIF_T mac[NUM_PROCS];
108 NETCP_CFG_MACIF_T mac0;
109 NETCP_CFG_MACIF_T mac1;
111 hplib_spinLock_T dpi_demo_thread_lock;
114 static char usage[] = "usage: %s -s \n";
119 //int procs =2; 
121 #define HPLIB_THREADID 0  // for main: HPLIB THREAD INSTANCE
122 //__thread int our_core;
123 static unsigned char dummy_mac[]={0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x01,0x02,0x03,0x04,0x05,0x08,0x00};
125 void house(NETAPI_SCHED_HANDLE_T *s);
126 void our_stats_cb_mt(NETAPI_T h, paSysStats_t* pPaStats);
127 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats);
129 //sig handler
130 void netTest_utilMySig(int x)
132   QUIT=1;
133   scnt+=1;
134   printf(">net_test_dpi: recv'd signal %d cnt=%d\n",x,scnt);
135   if (scnt > 10) {printf(">dpi-demo: WARNING EXITING WITH PROPER SHUTDOWN LUTS LEFT ACTIVE\n");exit(1);}
140 void recv_cb_bridge(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
141                          PKTIO_METADATA_T meta[], int n_pkts,
142                          uint64_t ts );
145 /*************debug********************/
146 void netTest_utilDumpDescr(unsigned long *p, int n)
148    printf("--------dump of descriptor %d %x\n", n, (int) p);
149    printf("> %x %x %x %x %x %x %x %x\n",p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]);
150    printf("> %x %x %x %x %x %x %x %x\n",p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15]);
151    printf("-----------------------------\n");
153 void netTest_utilDumpHeader(unsigned long *p, int n, int a, int r)
155    printf("--------dump of header %d %x appID=%x flag1=%x\n", n, (int) p,a,r);
156    printf("> %0x %0x %0x %0x %0x %0x %0x %0x\n",
157           ntohl(p[0]),ntohl(p[1]),ntohl(p[2]),ntohl(p[3]),
158           ntohl(p[4]),ntohl(p[5]),ntohl(p[6]),ntohl(p[7]) );
159 #if 0
160    printf("> %x %x %x %x %x %x %x %x\n",p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15]);
161    printf("> %x %x %x %x %x %x %x %x\n",p[16],p[17],p[18],p[19],p[20],p[21],p[22],p[23]);
162    printf("> %x %x %x %x %x %x %x %x\n",p[24],p[25],p[26],p[27],p[28],p[29],p[30],p[31]);
163 #endif
164    printf("-----------------------------\n");
166 /*****************************************/
168 void house(NETAPI_SCHED_HANDLE_T * s)
170     int err;
171     NETAPI_SCHED_SHUTDOWN_T sched_shutdown;
172     int coreid;  //who we are
173     NETAPI_T nh= netapi_schedGetHandle(s);
174     coreid=(int) netapi_getCookie(nh);
175     
176     if (QUIT)
177     {
178         sched_shutdown.shutdown_type = NETAPI_SCHED_SHUTDOWN_NOW;
179         netapi_schedClose(s,&sched_shutdown,&err); 
180         return;
181     }
184 #ifdef VDPI
185     if (DUMP_DPI_CONN )
186         navl_dump_conn_info();
187 #endif
190     /* only slow path threads get netcp stats, this needs to be set in cookie
191        during slow path thread creation*/
192     if (coreid & SP_THREAD_MASK)
193     {
194         netapi_netcpCfgReqStats(nh, our_stats_cb_mt, 0,&err);
195     }
199 unsigned long long CALIB=0;
200 unsigned long long calibrate_idle(void)
202     volatile unsigned long long  at1;
203     volatile unsigned long long  at2;
204     volatile unsigned long pt1;
205     volatile unsigned long pt2;
206     unsigned long long calib;
207     at1 = hplib_mUtilGetTimestamp();
208     pt1=netapi_timing_start();
209     for(;;)
210     {
211        pt2=netapi_timing_start()   ;
212        if ((pt2-pt1) >= 100000) break;
213     }
214     at2 = hplib_mUtilGetTimestamp();
215     
216     calib = ((unsigned long long) (pt2-pt1))/(at2-at1);
217     printf("calibrate:   arm time=%lld  -> arm cycles=%d calib=%lld\n", at2-at1, pt2-pt1, calib);
218     
219     return calib;
222 /*******************************************
223  *************NETAPI OBJECTS***************
224  *****************************************/
225 static NETAPI_CFG_T our_netapi_default_cfg=
227 TUNE_NETAPI_PERM_MEM_SZ,
228 128,  //start of packet offset for hw to place data on rx for default flow
229 TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
230 TUNE_NETAPI_NUM_GLOBAL_DESC,        //total we will use
231 TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap
232 64, //#descriptors w/o buffers in default heap
233 TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128,  //size of buffers in default heap
234 128,       //tail room
235 256,      //extra room
236 0,
237 NULL
238 };
240 Pktlib_HeapHandle OurHeap;     //default heap, used by producer
241 PKTIO_HANDLE_T * netcp_rx_chan;
242 PKTIO_HANDLE_T * netcp_rx_chan2;
243 PKTIO_HANDLE_T * netcp_tx_chan;
245 PKTIO_CFG_T our_chan_cfg={PKTIO_RX_TX, PKTIO_LOCAL, PKTIO_Q_ANY, 8};
246 PKTIO_CFG_T netcp_rx_cfg={PKTIO_RX, PKTIO_NA, PKTIO_NA, 8};
247 PKTIO_CFG_T netcp_rx_cfg2={PKTIO_RX, (PKTIO_GLOBAL|PKTIO_PKT), PKTIO_Q_ANY, 8};
248 PKTIO_CFG_T netcp_tx_cfg={PKTIO_TX, PKTIO_NA, PKTIO_NA, 8};
249 NETAPI_T netapi_handle;
250 NETAPI_SCHED_HANDLE_T * our_sched;
251 NETAPI_SCHED_HANDLE_T * scheduler[TUNE_NETAPI_NUM_CORES];
252 NETAPI_SCHED_CONFIG_T our_sched_cfg={
253   NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 5000000  //every 5000000 poll loops
254 };
256 NETCP_CFG_IP_T ip_rule0;
257 NETCP_CFG_IP_T ip_rule1;
260 PKTIO_CFG_T direct_to_cpsw_cfg={PKTIO_TX, PKTIO_GLOBAL, 648, 8};
261 PKTIO_HANDLE_T * cpsw_tx_chan;
263 PKTIO_CONTROL_T zap_channel_control={PKTIO_CLEAR, NULL};
264 PKTIO_CONTROL_T poll_cannel_control={PKTIO_SET_POLL_FLAGS, NULL, nwal_POLL_DEFAULT_GLOB_PKT_Q};
266 //template for fast path
267 nwalTxPktInfo_t txPktInfoNoCrypto =
269     NULL,                                                                                               /* p_pkt */
270     NWAL_TX_FLAG1_META_DATA_VALID,      /* txFlags */
271     0,                                                                                                  /* lpbackPass */
272     0,                                                                                                  /* enetport */
273     0,                                                                                                  /* msuSize */
274     0,                                                                                                   /* startOffset */
275     0,                                                    /* saOffBytes */
276     0,                                                                                                  /* saPayLoadLen */
277     0               ,                                                                                    /* saAhIcvOffBytes */
278     0,                                                                                                 /* saAhMacSize */
279     0,                                              /* etherLenOffBytes */
280     MAC_HEADER_LEN,         /* ipOffBytes */
281     MAC_HEADER_LEN + IP_HEADER_LEN,                                        /* l4OffBytes */
282     UDP_HEADER_LEN,                                                             /* l4HdrLen */
283     0,                                                                         /* pseudoHdrChecksum */
284     0                                                                                                   /* pLoadLen */
285 };
288 NETCP_CFG_ROUTE_T  test_route=
290 0,
291 NULL,
292 NULL,
293 0,
294 0,
295 0,
297 };
299 NETCP_CFG_FLOW_HANDLE_T kernelFlow22;
300 NETCP_CFG_FLOW_HANDLE_T kernelFlow23;
302 /*************************END NETAPI OBJECTS***********************/
304 static unsigned char all_mac[]={0,0,0,0,0,0};
305 nwalIpAddr_t all_ip={0,0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
308 static unsigned char all_dest[]={0xff,0xff,0xff,0xff,0xff,0xff};
313 static unsigned long last_header[32/sizeof(unsigned long)];
314 static unsigned long last_desc[64/sizeof(unsigned long)];
316 //stats
317 #define MAX_CORE 4
318 int pkt_rx[MAX_CORE]; 
319 int pkt_tx[MAX_CORE]; 
320 unsigned long long pkt_rx_cycles[MAX_CORE]={0L};
321 unsigned long long pkt_tx_cycles[MAX_CORE]={0L};
322 unsigned long long pkt_cb_cycles[MAX_CORE]={0L};
323 unsigned long long idle_cycles[MAX_CORE]={0L};
324 volatile unsigned long long start_time[MAX_CORE];
325 unsigned long long end_time[MAX_CORE];
326 unsigned long long pkt_stall[MAX_CORE]={0L};
327 //*********************************
328 // packet generator
329 //*********************************
330 void gen_pkts(int np, int out_port);
332 /******************************************************
333  * stats callback
334  *******************************************************/
335 void our_stats_cb_mt(NETAPI_T h, paSysStats_t* pPaStats)
337   stats.n_stats_cb +=1;
338   if(pPaStats) memcpy(&netcp_stats,pPaStats, sizeof(paSysStats_t));
341 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats)
343     uint32_t numFreeDataPackets;
344     uint32_t            numZeroBufferPackets;
345     uint32_t            numPacketsinGarbage;
346     Pktlib_HeapStats    pktLibHeapStats;
347     int i,j;
348     unsigned long long bcpp;
349     unsigned long long bcpp_noc;
350     unsigned long long bcpp_app;
351     unsigned long long bcpp_tx;
352     unsigned long long npL;
353     unsigned long long cyclesL;
354     unsigned long long ccyclesL; //cache cycles
355     unsigned long long tmp_npL[TUNE_NETAPI_NUM_CORES];
356     unsigned long long tmp_cyclesL[TUNE_NETAPI_NUM_CORES];
357     unsigned long long tmp_ccyclesL[TUNE_NETAPI_NUM_CORES]; //cache cycles
358     NETAPI_SA_STATS_T netapi_sa_stats;
360     printf(">*****stats @ %lld (#cbs%d) \n", hplib_mUtilGetTimestamp(),stats.n_stats_cb);
361     //printf("netcp_tx_handle check %x\n", netcp_tx_chan->back);
362     printf(">itx=%d rx=%d tx=%d bad=%d slow=%d \n>rx_class0=%d rx_class1=%d rx_class2=%d  secRx=%d  secPRX=%d sb_rx=%d sb_tx=%d auth_ok=%d sec_tx=%d  min_rx=%d min_tx=%d ip=%d\n",
363              stats.itx, stats.rx, stats.tx, stats.n_bad, stats.n_new, 
364              stats.n_class0_rx, stats.n_class1_rx, 
365              stats.n_class2_rx, stats.sec_rx, stats.secp_rx, stats.sb_rx, stats.sb_tx, stats.n_auth_ok,
366              stats.sec_tx, stats.rx_min, stats.tx_min, stats.ip);
367     printf(">if rx stats:  %d %d %d\n",stats.if_rx[0],stats.if_rx[1],stats.if_rx[2]);
370     printf(">core rx stats:  %d %d %d\n",stats.core_rx[1],stats.core_rx[2],stats.core_rx[3]);
373     for (j= 1;j < NUM_PROCS;j++)
374     {
375         tmp_npL[j]=0LL; tmp_cyclesL[j]=0LL; tmp_ccyclesL[j]=0LL;
376         netapi_schedGetStats(scheduler[j],&tmp_npL[j],&tmp_cyclesL[j],&tmp_ccyclesL[j]);
377         npL += tmp_npL[j];
378         cyclesL += tmp_cyclesL[j];
379         ccyclesL += tmp_ccyclesL[j];
380     }
382     if (npL && stats.rx)
383     {
384         bcpp = cyclesL/npL; 
385         bcpp_noc = (cyclesL-ccyclesL)/npL; 
386         bcpp_app = (stats.app_cycles-stats.tx_cache_cycles)/stats.rx;
387     }
388     else {bcpp = bcpp_noc=bcpp_app=0L;}
389     if (stats.tx)
390     {
391         bcpp_tx = (stats.send_cycles-stats.tx_cache_cycles)/stats.tx;
392     }
393     else
394     {
395         bcpp_tx = 0L;
396     }
397     printf(">         ++ busy cycles pp=%lld (%lld wo cache ops) (app+tx= %lld) (tx= %lld) ++\n",
398          bcpp,bcpp_noc,bcpp_app, bcpp_tx);
401 #ifdef VDPI
402     navl_return_stats(
403     &pGlobDpiStats->n_ops,
404     &pGlobDpiStats->n_class,
405     &pGlobDpiStats->min_time,
406     &pGlobDpiStats->max_time,
407     &pGlobDpiStats->tot,
408     &pGlobDpiStats->m_op,
409     &pGlobDpiStats->m_bytes,
410     &pGlobDpiStats->n_err,
411     &pGlobDpiStats->f_op,
412     &pGlobDpiStats->m_cycles,
413     &pGlobDpiStats->f_cycles);
415     printf("dpi stats:  nops=%d nclass=%d min cycle=%d max  cycle=%d ave cycle=%lld #mallocs=%d #mbytes=%d n_err=%d fops=%d mCycles=%d fCycles=%d\n",
416     pGlobDpiStats->n_ops,
417     pGlobDpiStats->n_class,
418     pGlobDpiStats->min_time,
419     pGlobDpiStats->max_time,
420     pGlobDpiStats->n_ops? pGlobDpiStats->tot/pGlobDpiStats->n_ops : 0,
421     pGlobDpiStats->m_op,
422     pGlobDpiStats->m_bytes,
423     pGlobDpiStats->n_err,
424     pGlobDpiStats->f_op, pGlobDpiStats->m_cycles, pGlobDpiStats->f_cycles);
425     for(i=0; i< NUM_FP_PROCS;i++)
426     {
427         navl_results(i);
428     }
429 #endif
430     if(pPaStats)
431     {
432         printf("C1 number of packets:           %d\n", pPaStats->classify1.nPackets);
433         printf("C1 number IPv4 packets:         %d\n", pPaStats->classify1.nIpv4Packets);
434         printf("C1 number IPv6 packets:        %d\n", pPaStats->classify1.nIpv6Packets);
435         printf("C1 number Custom packets:        %d\n", pPaStats->classify1.nCustomPackets);
436         printf("C1 number SRIO packets:        %d\n", pPaStats->classify1.nSrioPackets);
437         printf("C1 number LLC/SNAP Fail packets:        %d\n", pPaStats->classify1.nLlcSnapFail);
438         printf("C1 number table matched:        %d\n", pPaStats->classify1.nTableMatch);
439         printf("C1 number failed table matched: %d\n", pPaStats->classify1.nNoTableMatch);
440         printf("C1 number IP Fragmented packets: %d\n", pPaStats->classify1.nIpFrag);
441         printf("C1 number IP Depth Overflow: %d\n", pPaStats->classify1.nIpDepthOverflow);
442         printf("C1 number VLAN Depth Overflow: %d\n", pPaStats->classify1.nVlanDepthOverflow);
443         printf("C1 number GRE Depth Overflow: %d\n", pPaStats->classify1.nGreDepthOverflow);
444         printf("C1 number MPLS Packets: %d\n", pPaStats->classify1.nMplsPackets);
445         printf("C1 number of parse fail:        %d\n",pPaStats->classify1.nParseFail);
446         printf("C1 number of Invalid IPv6 Opt:  %d\n", pPaStats->classify1.nInvalidIPv6Opt);
447         printf("C1 number of TX IP Fragments:  %d\n", pPaStats->classify1.nTxIpFrag);
448         printf("C1 number of silent discard:    %d\n",pPaStats->classify1.nSilentDiscard);
449         printf("C1 number of invalid control:   %d\n", pPaStats->classify1.nInvalidControl);
450         printf("C1 number of invalid states:    %d\n",pPaStats->classify1.nInvalidState);
451         printf("C1 number of system fails:      %d\n",pPaStats->classify1.nSystemFail);
452         printf("C2 number Packets  :           %d\n",pPaStats->classify2.nPackets);
453         printf("C2 number udp           :      %d\n",pPaStats->classify2.nUdp);
454         printf("C2 number tcp           :      %d\n",pPaStats->classify2.nTcp);
455         printf("C2 number Custom       :      %d\n",pPaStats->classify2.nCustom);
456         printf("C2 number silent drop   :      %d\n",pPaStats->classify2.nSilentDiscard);
457         printf("C2 number invalid cntrl :      %d\n\n",pPaStats->classify2.nInvalidControl);
458         printf("C2 number Modify Stats Cmd Fail :      %d\n\n",pPaStats->modify.nCommandFail);
459     }
460     Pktlib_getHeapStats(OurHeap, &pktLibHeapStats);
462     printf("main heap stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
463                                 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
464     printf("               >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n", 
465                         pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
466                         pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
469 NETAPI_T worker_nh[MAX_NUM_CORES];
471 void slow_path_thread(uint32_t index)
473     int err, i;;
474     uint32_t thread_num;
475     cpu_set_t cpu_set;
477     /* index being passed in is the core we want to run the thread on */
478     thread_num = index;
479     printf("slow_path_thread, mypid: %d, core_id %d\n", gettid(), thread_num);
481     CPU_ZERO( &cpu_set);
482     for (i = 0; i < 1;i++)
483     {
484         CPU_SET( i, &cpu_set);
485     }
486     hplib_utilSetupThread(thread_num, &cpu_set, hplib_spinLock_Type_LOL);
487     worker_nh[thread_num] = netapi_init(NETAPI_CORE_MASTER,NULL);
489     if (worker_nh[thread_num] == NULL)
490     {
491         printf("slow_path_thread: netapi_init failure, exiting\n");
492         exit(1);
493     }
494     netapi_setCookie(worker_nh[thread_num],(void*)(thread_num | SP_THREAD_MASK));
496     scheduler[thread_num] =netapi_schedOpen(worker_nh[thread_num],&our_sched_cfg, &err);
497     if (!scheduler[thread_num]) 
498     {
499         printf("sched create failed for core%d\n",thread_num);
500         goto ERR_slow_path_thread;
501     }
502     scheduler[thread_num]->config.yield = TRUE;
503     scheduler[thread_num]->config.pollGarbageQ = TRUE;
504     scheduler[thread_num]->config.pollCtrlQ = TRUE;
505     printf("Slow Path thread: %d setup complete, running on ARM CORE: %d\n",
506     index,index);
509     netapi_schedRun(scheduler[thread_num], &err);
511 ERR_slow_path_thread:
512     printf("slow_path_thread: calling netapi_shutdown\n");
513     netapi_shutdown(worker_nh[thread_num]);
517 void fast_path_thread(uint32_t index)
519     int err, i;
520     PKTIO_HANDLE_T *rx_chan;
521     PKTIO_HANDLE_T *sb_rx_chan;
522     uint32_t thread_num;
523     int navlHandle;
526     cpu_set_t cpu_set;
528     CPU_ZERO( &cpu_set);
529     thread_num = index;
530     printf("fast_path_thread: core %d\n", index);
533     CPU_SET( thread_num, &cpu_set);
534     hplib_utilSetupThread(thread_num, &cpu_set, hplib_spinLock_Type_LOL);
537     hplib_mSpinLockLock(&dpi_demo_thread_lock);
538     worker_nh[thread_num]=netapi_init(NETAPI_CORE_MASTER,NULL);
539     
540     if (worker_nh[thread_num] == NULL)
541     {
542         printf("fast_path_thread: netapi_init failure, exiting\n");
543         hplib_mSpinLockUnlock(&dpi_demo_thread_lock);
544         exit(1);
545     }
546     else
547     {
548 #ifdef VDPI
549             navlHandle = navl_per_thread_init(thread_num);
550 #endif
551     }
552     hplib_mSpinLockUnlock(&dpi_demo_thread_lock);
555     if (worker_nh[thread_num] == NULL)
556     {
557         printf("fast_path_thread: netapi_init failure, exiting\n");
558         exit(1);
559     }
560     
561     /* open netcp default RX channels*/
562     rx_chan = netapi_pktioOpen(worker_nh[thread_num], NETCP_RX, (PKTIO_CB) recv_cb_bridge, &netcp_rx_cfg,  &err);
565     netapi_setCookie(worker_nh[thread_num],(void*)thread_num);
566     
567     scheduler[thread_num] =netapi_schedOpen(worker_nh[thread_num],
568                                             &our_sched_cfg,
569                                             &err);
570     if (!scheduler[thread_num]) 
571         {
572         printf("sched create failed for core%d\n",thread_num);
573         goto ERR_fast_path_thread;
574         //exit(1);
575     }
577  
578     scheduler[thread_num]->config.yield = FALSE;
579     scheduler[thread_num]->config.pollGarbageQ = FALSE;
580     scheduler[thread_num]->config.pollCtrlQ = FALSE;
581    /* Entry point to scheduler */
584     printf("Fast Path thread: %d setup complete, running on ARM CORE: %d\n",
585     index,index);
586     netapi_schedRun(scheduler[thread_num], &err);
588 ERR_fast_path_thread:
589 #ifdef VDPI
590         navl_fini(navlHandle);
591 #endif
592     netapi_pktioClose(rx_chan, &err);
594     printf("fast_path_thread: calling netapi_shutdown\n");
595     netapi_shutdown(worker_nh[thread_num]);
599 /******************************
600 * main program
601 *****************************/
602 int main(int argc, char **argv)
604     int err,i;
605     int j;
606     int32_t             errCode;
607     Pktlib_HeapIfTable*  pPktifTable;
608     Pktlib_HeapCfg heapCfg;
609     long t1, t2 ;
610     cpu_set_t cpu_set;
611     int c;
612     int statsQueryRequest = 0;
613     pthread_t *thrs;
614     int p;
619 #if 1
621     if (argc == 2)
622     {
623         printf("main: argument %s\n", argv[1]);
624         if(!(strcmp(argv[1], "stats")))
625         {
626             statsQueryRequest =1;
627             printf("querying for stats\n");
628         }
629     }
630     printf("statsQueryReqeust: %d\n", statsQueryRequest);
633 #endif
636     if (!statsQueryRequest)
637     {
638         if (initRm())
639         {
640             printf("main: initRm() returned error\n");
641             exit(1);
642         }
644         signal(SIGINT,netTest_utilMySig);
645         CPU_ZERO( &cpu_set);
646         CPU_SET( 0, &cpu_set);
647         hplib_utilSetupThread(HPLIB_THREADID, &cpu_set, hplib_spinLock_Type_LOL);
648     
649         /* create netapi */
650         our_netapi_default_cfg.rmHandle = rmClientServiceHandle;
651         netapi_handle = netapi_init(NETAPI_SYS_MASTER,
652                                     &our_netapi_default_cfg);
653         if (netapi_handle == NULL)
654         {
655             printf("main: netapi_init failure, exiting\n");
656             exit(1);
657         }
658         /* allocate segment for shared memory for packet stats */
659         /* allocate packet statistics */
660         pShmBase = hplib_shmOpen();
661         if (pShmBase)
662         {
663             if (hplib_shmAddEntry(pShmBase,
664                               sizeof(navl_wrapper_pkt_stat_t)
665                              * MAX_PROTOCOLS *NUM_FP_PROCS + sizeof(navl_wrapper_cfg_info_t),
666                              APP_ENTRY_1) != hplib_OK)
667             {
668                 printf("main:  hplib_shmAddEntry failure\n");
669                 return -1;
670             }
671             else
672             {
673                 pShmEntry = hplib_shmGetEntry(pShmBase, APP_ENTRY_1);
674                 pNavlCfg =  (navl_wrapper_cfg_info_t*)pShmEntry;
675                 memset(pNavlCfg,
676                        0,
677                        sizeof(navl_wrapper_pkt_stat_t) * MAX_PROTOCOLS *NUM_FP_PROCS+ sizeof(navl_wrapper_cfg_info_t));
678                 pNavlCfg =  (navl_wrapper_cfg_info_t*)pShmEntry;
679                 pNavlCfg->enable_dpi = 0; /* disable DPI by default */
680             }
681             if (hplib_shmAddEntry(pShmBase, sizeof(navl_global_dpi_stats), APP_ENTRY_2) != hplib_OK)
682             {
683                 printf("main:  hplib_shmAddEntry failure\n");
684                 return -1;
685             }
686             else
687             {
688                 pShmEntry = hplib_shmGetEntry(pShmBase, APP_ENTRY_2);
689                 pGlobDpiStats = (navl_global_dpi_stats*) pShmEntry;
690                 memset(pGlobDpiStats, 0, sizeof(navl_global_dpi_stats));
691                 pGlobDpiStats->min_time=100000000;
692             }
693             if (hplib_shmAddEntry(pShmBase, sizeof(navl_wrapper_stat_t)* (NUM_FP_PROCS *NUM_MEM_CTX * NUM_MEM_OBJ),
694                                   APP_ENTRY_3) != hplib_OK)
695             {
696                 printf("main:  hplib_shmAddEntry failure\n");
697                 return -1;
698             }
699             else
700             {
701                 pShmEntry = hplib_shmGetEntry(pShmBase, APP_ENTRY_3);
702                 pNavlMemStats = (navl_wrapper_mem_stats_t*) pShmEntry;
703                 memset(pNavlMemStats, 0, sizeof(navl_wrapper_mem_stats_t));
704             }
705             
706         }
707         else
708         {
709             printf("main: hplib_shmOpen failure, exiting\n");
710             exit(1);
711         }
712             /* open the main heap */
713         OurHeap = Pktlib_findHeapByName("netapi");
714         if (!OurHeap)
715         {
716             printf("findheapbyname fail\n");
717             exit(1);
718         }
720         //if we want to relay network packets, we create a handle to the 
721         //default netcp receive queue here
722         netcp_rx_chan= netapi_pktioOpen(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb_bridge, &netcp_rx_cfg,  &err);
723         if (!netcp_rx_chan)
724         {
725             printf("pktio open RX failed err=%d\n",err);
726             exit(1);
727         }
729         netcp_tx_chan= netapi_pktioOpen(netapi_handle, NETCP_TX, (PKTIO_CB) NULL, &netcp_tx_cfg,  &err);
730         if (!netcp_tx_chan)
731         {
732             printf("pktio open TX failed err=%d\n",err);
733             exit(1);
734         }
735         else  //install a fast path template into the NETCP TX channel
736         {
737             PKTIO_CONTROL_T control2;
738             control2.op = PKTIO_UPDATE_FAST_PATH;
739             PKTIO_CFG_T cfg2;
740             memset(&cfg2, 0, sizeof(PKTIO_CFG_T));
741             cfg2.fast_path_cfg.fp_send_option = PKTIO_FP_NO_CRYPTO_NO_CKSUM_PORT;
742             cfg2.fast_path_cfg.txPktInfo= &txPktInfoNoCrypto;
743             netapi_pktioControl(netcp_tx_chan, NULL, &cfg2, &control2, &err);
744        }
747         if (navl_setup() < 0)
748         {
749             printf("main: navl_setup failure, exiting\n");
750             exit(1);
751         }
753         /*********************************************/
754         /*****************end NETAPI STARTUP**********/
755         /*********************************************/
757         //now creaate a simple netcp rule
758         //to get a lot of packets
759         mac0 = netapi_netcpCfgCreateMacInterface(
760                       netapi_handle,
761                       &all_mac[0],
762                       NULL,
763                       0,
764                       1,
765                       (NETCP_CFG_ROUTE_HANDLE_T)  NULL,
766                       (NETCP_CFG_VLAN_T ) NULL ,  //future
767                       0x0800,
768                       1,
769                       &err);
770         if (err) {printf("addmac0 failed %d\n",err); exit(1); }
771         else printf("addmac0 sucess\n");
773         mac1 = netapi_netcpCfgCreateMacInterface(
774                       netapi_handle,
775                       &all_mac[0],
776                       NULL,
777                       1,
778                       2,
779                       (NETCP_CFG_ROUTE_HANDLE_T)  NULL,
780                       (NETCP_CFG_VLAN_T ) NULL ,  //future
781                       0x0800,
782                       1,
783                       &err);
784         if (err) {printf("addmac1 failed %d\n",err); exit(1); }
785         else printf("addmac1 sucess\n");
787         //calibrate idle
788         CALIB = calibrate_idle();
790         //**************************************
791         //Create a slow path thread
792         //***************************************
793         thrs = malloc( sizeof( pthread_t ) * NUM_PROCS );
794         if (thrs == NULL)
795         {
796             perror( "malloc" );
797             return -1;
798         }
799         printf( "dpi-demo: Starting slow_path_thread on core 0\n");
801         if (pthread_create( &thrs[0], NULL, (void*)slow_path_thread,
802                           (void *)0 ))  //start at core 0
803         {
804             perror( "pthread_create" );
805             exit(1);
806         }
809         for (j= 1;j < NUM_PROCS;j++)
810         {
811             printf( "dpi-demo: Starting fast_path_thread on core 1\n");
812             if (pthread_create( &thrs[j], NULL, (void*)fast_path_thread,
813                           (void *)j ))  //start at core 1
814             {
815                 perror( "pthread_create" );
816                 exit(1);
817             }
818         }
819     }
820     else
821     {
822         
823         pShmBase = hplib_shmOpen();
824         if (pShmBase)
825         {
826             pTemp = hplib_shmGetEntry(pShmBase, APP_ENTRY_1);
827             pNavlCfg =  (navl_wrapper_cfg_info_t*)pTemp;
829             pStats1 = pTemp + sizeof(navl_wrapper_cfg_info_t);
831         
832             pStats2 = pTemp + sizeof(navl_wrapper_cfg_info_t) +
833                     (sizeof(navl_wrapper_pkt_stat_t)*pNavlCfg->num_protocols);
835             pTemp = hplib_shmGetEntry(pShmBase, APP_ENTRY_2);
836             pGlobDpiStats = (struct dpi_stats*) pTemp;
838             printf("dpi stats:  nops=%d nclass=%d min cycle=%d max cycle=%d ave cycle=%lld #mallocs=%d #mbytes=%d n_err=%d fops=%d mCycles=%d fCycles=%d\n",
839             pGlobDpiStats->n_ops,
840             pGlobDpiStats->n_class,
841             pGlobDpiStats->min_time,
842             pGlobDpiStats->max_time,
843             pGlobDpiStats->n_ops? pGlobDpiStats->tot/pGlobDpiStats->n_ops : 0,
844             pGlobDpiStats->m_op,
845             pGlobDpiStats->m_bytes,
846             pGlobDpiStats->n_err,
847             pGlobDpiStats->f_op, pGlobDpiStats->m_cycles, pGlobDpiStats->f_cycles);
848             for(i=0;i < NUM_FP_PROCS; i++)
849             {
850                 navl_results2(i);
851             }
852             exit(1);
853         }
854     }
857         //this thread of execution (main) now just waits on user input
858         for(;;)
859         {
860             printf(">");
861             c=getchar();
862             if (c=='C')
863             {
864                 CAP=!CAP; 
865                 printf("CAPTURE= %d\n", CAP);
866             }
867             else if (c=='q') {QUIT=1;break;}
868             else if (c=='s')
869                 our_stats_cb(netapi_handle, &netcp_stats);
870     #ifdef VDPI
871                else if (c=='c') 
872                 {navl_clear_stats();printf("> Clearing DPI stats\n");}
873                else if (c=='v') navl_set_verbose();
874                else if (c=='p') 
875                  {DUMP_DPI_CONN = !DUMP_DPI_CONN;printf(">  **DPI CONN DUMP is %s ** \n", DUMP_DPI_CONN ?"enabled":"disabled");}
876                else if (c=='d')
877                  {
878                     pNavlCfg->enable_dpi = !pNavlCfg->enable_dpi;
879                     printf("enable_dpi flag: %d\n", pNavlCfg->enable_dpi);
880                     printf(">  **DPI is %s ** \n", pNavlCfg->enable_dpi?"enabled":"disabled");
881                  }
882     #endif
883             else if (c=='!') {system("sh");}
884     
885             else if ((c=='h')||(c=='?'))
886             {
887                 printf("> 'q' to quit,  's' for stats,'d' to dump capture\n,> 'h' for help\n ");
888             }
889     #if 1
890             else if (c=='r')
891             {
892                 netTest_utilDumpHeader(&last_header[0], 0,0,0);
893                 netTest_utilDumpDescr(&last_desc[0], 0);
894             }
895     #endif
896         }
900 #ifdef VDPI
901             navl_done();
902 #endif
904         //wait for completion 
905         printf("main task now pending on thread completion\n");
906         for (i = 0; i < NUM_PROCS; i++)
907                 pthread_join( thrs[i], NULL );
909         free( thrs );
911         /*************************************************
912         ************CLEAN UP****************************
913         ************************************************/
914         //get rid of rule, in the case that we are relaying packets
915         //also close our netcp rx channel
916         netapi_netcpCfgDelMac(netapi_handle,0,&err);
917         netapi_netcpCfgDelMac(netapi_handle,1,&err);
918     
919         netapi_pktioClose(netcp_rx_chan,&err);
920         netapi_pktioClose(netcp_tx_chan,&err);
923         //done
924         netapi_shutdown(netapi_handle);
928 #if 1
929 static inline void send_it(Ti_Pkt *tip, int len, int out_port)
931   int err=0;
932   PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
933   nwalTxPktInfo_t meta_tx2={0};
934   int coreid=Osal_nwalGetProcId();
935   if (len<60)
936   {
937      unsigned int templen;
938      char * p_pkt;
939      len=60;
940      Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
941      Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
942   }
943   Pktlib_setPacketLen(tip,len);
944   meta_tx2.txFlag1 = NWAL_TX_FLAG1_META_DATA_VALID;
945   meta_tx2.ploadLen = len ;
946   meta_tx2.enetPort=out_port;
947   meta2.u.tx_meta=&meta_tx2;
948   stats.tx+=1;
949   if(coreid<MAX_NUM_CORES)
950     pkt_tx[coreid]+=1;
951   netapi_pktioSend(netcp_tx_chan,tip,&meta2,&err);
953 #endif
954 void recv_cb_bridge(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
955                          PKTIO_METADATA_T meta[], int n_pkts,
956                          uint64_t ts )
958 int i;
959 int len;
960 int p;
961 Ti_Pkt * tip;
962 unsigned int appid;
963 unsigned int templen;
964 char * p_pkt;
965 unsigned long t1;
966 unsigned long t2;
967 unsigned long long ct1;
968 unsigned long long ct2;
969 unsigned short ip_pl;
970 unsigned long long n_c_ops;
971 int ifno;
972 int out_port;
974 int coreid=Osal_nwalGetProcId();
977 pasahoLongInfo_t* protoInfo;
979 t1=netapi_timing_start();
980 ct1 =Osal_cache_op_measure(&n_c_ops);
981 for(i=0;i<n_pkts;i++)
983         
984         tip = p_recv[i];
985         appid = ((unsigned int)meta[i].u.rx_meta->appId)&0xff000000;
986         if (appid == NETAPI_NETCP_MATCH_GENERIC_IP) 
987         {
988            stats.ip+=1;
989         }
991         protoInfo=nwal_mGetProtoInfo(tip);
992         ifno = nwal_mGetRxEmacPort( protoInfo);
993         if (ifno ==1) out_port=2; else out_port=1;
994         if(coreid<MAX_NUM_CORES) stats.core_rx[coreid]+=1;
995         if (ifno < MAX_NUM_INTERFACES) stats.if_rx[ifno]+=1;
996         Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
997         if (CAP==coreid)
998         {
999             memcpy((unsigned char *)&last_header[0],p_pkt,32);
1000             memcpy((unsigned char*)&last_desc[0],tip,64);
1001         }
1002         len = Pktlib_getPacketLen(tip);//real length, subtract mac trailer
1003         stats.rx+=1;
1004         //printf("recv_cb_bridge: appId: 0x%x, out_port: %d\n", appid, out_port);
1005         if (appid == NETAPI_NETCP_MATCH_GENERIC_MAC)
1006         {
1007 #ifdef VDPI
1008             {
1009                 if (pNavlCfg->enable_dpi)
1010                     navl_process_pkt(p_pkt, len);
1011             }
1012 #endif
1013         }
1015     
1016  //printf("recv_cb_bridge: coreId: %d, outPort %d\n", coreid, out_port);
1017         //Pktlib_freePacket(tip);
1018        send_it(tip,len,out_port);
1020 t2=netapi_timing_start();
1021 ct2 =Osal_cache_op_measure(&n_c_ops);
1022 stats.app_cycles +=  (unsigned long long) (t2-t1);
1023 stats.tx_cache_cycles += (unsigned long long) (ct2-ct1);
1024 return;
1027 #define NTOPOP 150
1028 volatile Ti_Pkt * pHd[NTOPOP];
1030 #define PKTGEN_PKT_LEN pkt_len
1031 #define MAXP 4   //max ports 
1032 void gen_pkts(int np, int out_port)
1034     int i;
1035     int p=0;
1036     unsigned long * pI ;
1037     Ti_Pkt * tip;
1038     int len;
1039     unsigned char * pData;
1040     int cstall=0;
1041     int coreid = Osal_nwalGetProcId();
1042     for(i=0;i<np;)
1043     {
1044         //set out output port
1045         if (out_port)
1046         {
1047             p=out_port;
1048         }
1049         else //flip flop
1050         {
1051             p+=1;
1052             if(p>MAXP) p=1;
1053         }
1054         //get a packet
1055         tip=Pktlib_allocPacket(OurHeap,PKTGEN_PKT_LEN);
1056         pI = (unsigned long *) tip;
1057         if (!tip)
1058         {
1059             pkt_stall[coreid]+=1;
1060             cstall+=1;
1061             if (cstall >= 100000) 
1062             {
1063                 printf("worker core %d, max stall hit,, exiting.\n",coreid); 
1064                 return;
1065             }
1066             continue;
1067         }
1068         cstall=0;
1069         Pktlib_getDataBuffer(tip,&pData,&len);
1070         memcpy(pData,&dummy_mac,14);
1071         Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, pData,PKTGEN_PKT_LEN);
1072         Pktlib_setPacketLen(tip,PKTGEN_PKT_LEN);
1073         pI[1]=0x80000000;
1074         //pI[2] &= 0xfff0ffff ;move to pktio send function
1076         //capture packet just in case
1077         if (CAP==coreid)
1078         {
1079             unsigned int templen;
1080             char * p_pkt;
1081             Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
1082             memcpy((unsigned char *)&last_header[0],p_pkt,32);
1083             memcpy((unsigned char*)&last_desc[0],tip,64);
1084         }
1086         //send  packet
1087         send_it(tip, PKTGEN_PKT_LEN, p);
1088         pkt_tx[coreid]+=1;
1089         i+=1;
1090    }
1092     return;