cb938fcb4592784f728f255817289d98cb097dd5
[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//* to be filled in
294 };
296 NETCP_CFG_FLOW_HANDLE_T kernelFlow22;
297 NETCP_CFG_FLOW_HANDLE_T kernelFlow23;
299 /*************************END NETAPI OBJECTS***********************/
301 static unsigned char all_mac[]={0,0,0,0,0,0};
302 nwalIpAddr_t all_ip={0,0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
305 static unsigned char all_dest[]={0xff,0xff,0xff,0xff,0xff,0xff};
310 static unsigned long last_header[32/sizeof(unsigned long)];
311 static unsigned long last_desc[64/sizeof(unsigned long)];
313 //stats
314 #define MAX_CORE 4
315 int pkt_rx[MAX_CORE]; 
316 int pkt_tx[MAX_CORE]; 
317 unsigned long long pkt_rx_cycles[MAX_CORE]={0L};
318 unsigned long long pkt_tx_cycles[MAX_CORE]={0L};
319 unsigned long long pkt_cb_cycles[MAX_CORE]={0L};
320 unsigned long long idle_cycles[MAX_CORE]={0L};
321 volatile unsigned long long start_time[MAX_CORE];
322 unsigned long long end_time[MAX_CORE];
323 unsigned long long pkt_stall[MAX_CORE]={0L};
324 //*********************************
325 // packet generator
326 //*********************************
327 void gen_pkts(int np, int out_port);
329 /******************************************************
330  * stats callback
331  *******************************************************/
332 void our_stats_cb_mt(NETAPI_T h, paSysStats_t* pPaStats)
334   stats.n_stats_cb +=1;
335   if(pPaStats) memcpy(&netcp_stats,pPaStats, sizeof(paSysStats_t));
338 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats)
340     uint32_t numFreeDataPackets;
341     uint32_t            numZeroBufferPackets;
342     uint32_t            numPacketsinGarbage;
343     Pktlib_HeapStats    pktLibHeapStats;
344     int i,j;
345     unsigned long long bcpp;
346     unsigned long long bcpp_noc;
347     unsigned long long bcpp_app;
348     unsigned long long bcpp_tx;
349     unsigned long long npL;
350     unsigned long long cyclesL;
351     unsigned long long ccyclesL; //cache cycles
352     unsigned long long tmp_npL[TUNE_NETAPI_NUM_CORES];
353     unsigned long long tmp_cyclesL[TUNE_NETAPI_NUM_CORES];
354     unsigned long long tmp_ccyclesL[TUNE_NETAPI_NUM_CORES]; //cache cycles
355     NETAPI_SA_STATS_T netapi_sa_stats;
357     printf(">*****stats @ %lld (#cbs%d) \n", hplib_mUtilGetTimestamp(),stats.n_stats_cb);
358     //printf("netcp_tx_handle check %x\n", netcp_tx_chan->back);
359     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",
360              stats.itx, stats.rx, stats.tx, stats.n_bad, stats.n_new, 
361              stats.n_class0_rx, stats.n_class1_rx, 
362              stats.n_class2_rx, stats.sec_rx, stats.secp_rx, stats.sb_rx, stats.sb_tx, stats.n_auth_ok,
363              stats.sec_tx, stats.rx_min, stats.tx_min, stats.ip);
364     printf(">if rx stats:  %d %d %d\n",stats.if_rx[0],stats.if_rx[1],stats.if_rx[2]);
367     printf(">core rx stats:  %d %d %d\n",stats.core_rx[1],stats.core_rx[2],stats.core_rx[3]);
370     for (j= 1;j < NUM_PROCS;j++)
371     {
372         tmp_npL[j]=0LL; tmp_cyclesL[j]=0LL; tmp_ccyclesL[j]=0LL;
373         netapi_schedGetStats(scheduler[j],&tmp_npL[j],&tmp_cyclesL[j],&tmp_ccyclesL[j]);
374         npL += tmp_npL[j];
375         cyclesL += tmp_cyclesL[j];
376         ccyclesL += tmp_ccyclesL[j];
377     }
379     if (npL && stats.rx)
380     {
381         bcpp = cyclesL/npL; 
382         bcpp_noc = (cyclesL-ccyclesL)/npL; 
383         bcpp_app = (stats.app_cycles-stats.tx_cache_cycles)/stats.rx;
384     }
385     else {bcpp = bcpp_noc=bcpp_app=0L;}
386     if (stats.tx)
387     {
388         bcpp_tx = (stats.send_cycles-stats.tx_cache_cycles)/stats.tx;
389     }
390     else
391     {
392         bcpp_tx = 0L;
393     }
394     printf(">         ++ busy cycles pp=%lld (%lld wo cache ops) (app+tx= %lld) (tx= %lld) ++\n",
395          bcpp,bcpp_noc,bcpp_app, bcpp_tx);
398 #ifdef VDPI
399     navl_return_stats(
400     &pGlobDpiStats->n_ops,
401     &pGlobDpiStats->n_class,
402     &pGlobDpiStats->min_time,
403     &pGlobDpiStats->max_time,
404     &pGlobDpiStats->tot,
405     &pGlobDpiStats->m_op,
406     &pGlobDpiStats->m_bytes,
407     &pGlobDpiStats->n_err,
408     &pGlobDpiStats->f_op,
409     &pGlobDpiStats->m_cycles,
410     &pGlobDpiStats->f_cycles);
412     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",
413     pGlobDpiStats->n_ops,
414     pGlobDpiStats->n_class,
415     pGlobDpiStats->min_time,
416     pGlobDpiStats->max_time,
417     pGlobDpiStats->n_ops? pGlobDpiStats->tot/pGlobDpiStats->n_ops : 0,
418     pGlobDpiStats->m_op,
419     pGlobDpiStats->m_bytes,
420     pGlobDpiStats->n_err,
421     pGlobDpiStats->f_op, pGlobDpiStats->m_cycles, pGlobDpiStats->f_cycles);
422     for(i=0; i< NUM_FP_PROCS;i++)
423     {
424         navl_results(i);
425     }
426 #endif
427     if(pPaStats)
428     {
429         printf("C1 number of packets:           %d\n", pPaStats->classify1.nPackets);
430         printf("C1 number IPv4 packets:         %d\n", pPaStats->classify1.nIpv4Packets);
431         printf("C1 number IPv6 packets:        %d\n", pPaStats->classify1.nIpv6Packets);
432         printf("C1 number Custom packets:        %d\n", pPaStats->classify1.nCustomPackets);
433         printf("C1 number SRIO packets:        %d\n", pPaStats->classify1.nSrioPackets);
434         printf("C1 number LLC/SNAP Fail packets:        %d\n", pPaStats->classify1.nLlcSnapFail);
435         printf("C1 number table matched:        %d\n", pPaStats->classify1.nTableMatch);
436         printf("C1 number failed table matched: %d\n", pPaStats->classify1.nNoTableMatch);
437         printf("C1 number IP Fragmented packets: %d\n", pPaStats->classify1.nIpFrag);
438         printf("C1 number IP Depth Overflow: %d\n", pPaStats->classify1.nIpDepthOverflow);
439         printf("C1 number VLAN Depth Overflow: %d\n", pPaStats->classify1.nVlanDepthOverflow);
440         printf("C1 number GRE Depth Overflow: %d\n", pPaStats->classify1.nGreDepthOverflow);
441         printf("C1 number MPLS Packets: %d\n", pPaStats->classify1.nMplsPackets);
442         printf("C1 number of parse fail:        %d\n",pPaStats->classify1.nParseFail);
443         printf("C1 number of Invalid IPv6 Opt:  %d\n", pPaStats->classify1.nInvalidIPv6Opt);
444         printf("C1 number of TX IP Fragments:  %d\n", pPaStats->classify1.nTxIpFrag);
445         printf("C1 number of silent discard:    %d\n",pPaStats->classify1.nSilentDiscard);
446         printf("C1 number of invalid control:   %d\n", pPaStats->classify1.nInvalidControl);
447         printf("C1 number of invalid states:    %d\n",pPaStats->classify1.nInvalidState);
448         printf("C1 number of system fails:      %d\n",pPaStats->classify1.nSystemFail);
449         printf("C2 number Packets  :           %d\n",pPaStats->classify2.nPackets);
450         printf("C2 number udp           :      %d\n",pPaStats->classify2.nUdp);
451         printf("C2 number tcp           :      %d\n",pPaStats->classify2.nTcp);
452         printf("C2 number Custom       :      %d\n",pPaStats->classify2.nCustom);
453         printf("C2 number silent drop   :      %d\n",pPaStats->classify2.nSilentDiscard);
454         printf("C2 number invalid cntrl :      %d\n\n",pPaStats->classify2.nInvalidControl);
455         printf("C2 number Modify Stats Cmd Fail :      %d\n\n",pPaStats->modify.nCommandFail);
456     }
457     Pktlib_getHeapStats(OurHeap, &pktLibHeapStats);
459     printf("main heap stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
460                                 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
461     printf("               >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n", 
462                         pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
463                         pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
466 NETAPI_T worker_nh[MAX_NUM_CORES];
468 void slow_path_thread(uint32_t index)
470     int err, i;;
471     uint32_t thread_num;
472     cpu_set_t cpu_set;
474     /* index being passed in is the core we want to run the thread on */
475     thread_num = index;
476     printf("slow_path_thread, mypid: %d, core_id %d\n", gettid(), thread_num);
478     CPU_ZERO( &cpu_set);
479     for (i = 0; i < 1;i++)
480     {
481         CPU_SET( i, &cpu_set);
482     }
483     hplib_utilSetupThread(thread_num, &cpu_set, hplib_spinLock_Type_LOL);
484     worker_nh[thread_num] = netapi_init(NETAPI_CORE_MASTER,NULL);
486     if (worker_nh[thread_num] == NULL)
487     {
488         printf("slow_path_thread: netapi_init failure, exiting\n");
489         exit(1);
490     }
491     netapi_setCookie(worker_nh[thread_num],(void*)(thread_num | SP_THREAD_MASK));
493     scheduler[thread_num] =netapi_schedOpen(worker_nh[thread_num],&our_sched_cfg, &err);
494     if (!scheduler[thread_num]) 
495     {
496         printf("sched create failed for core%d\n",thread_num);
497         goto ERR_slow_path_thread;
498     }
499     scheduler[thread_num]->config.yield = TRUE;
500     scheduler[thread_num]->config.pollGarbageQ = TRUE;
501     scheduler[thread_num]->config.pollCtrlQ = TRUE;
502     printf("Slow Path thread: %d setup complete, running on ARM CORE: %d\n",
503     index,index);
506     netapi_schedRun(scheduler[thread_num], &err);
508 ERR_slow_path_thread:
509     printf("slow_path_thread: calling netapi_shutdown\n");
510     netapi_shutdown(worker_nh[thread_num]);
514 void fast_path_thread(uint32_t index)
516     int err, i;
517     PKTIO_HANDLE_T *rx_chan;
518     PKTIO_HANDLE_T *sb_rx_chan;
519     uint32_t thread_num;
520     int navlHandle;
523     cpu_set_t cpu_set;
525     CPU_ZERO( &cpu_set);
526     thread_num = index;
527     printf("fast_path_thread: core %d\n", index);
530     CPU_SET( thread_num, &cpu_set);
531     hplib_utilSetupThread(thread_num, &cpu_set, hplib_spinLock_Type_LOL);
534     hplib_mSpinLockLock(&dpi_demo_thread_lock);
535     worker_nh[thread_num]=netapi_init(NETAPI_CORE_MASTER,NULL);
536     
537     if (worker_nh[thread_num] == NULL)
538     {
539         printf("fast_path_thread: netapi_init failure, exiting\n");
540         hplib_mSpinLockUnlock(&dpi_demo_thread_lock);
541         exit(1);
542     }
543     else
544     {
545 #ifdef VDPI
546             navlHandle = navl_per_thread_init(thread_num);
547 #endif
548     }
549     hplib_mSpinLockUnlock(&dpi_demo_thread_lock);
552     if (worker_nh[thread_num] == NULL)
553     {
554         printf("fast_path_thread: netapi_init failure, exiting\n");
555         exit(1);
556     }
557     
558     /* open netcp default RX channels*/
559     rx_chan = netapi_pktioOpen(worker_nh[thread_num], NETCP_RX, (PKTIO_CB) recv_cb_bridge, &netcp_rx_cfg,  &err);
562     netapi_setCookie(worker_nh[thread_num],(void*)thread_num);
563     
564     scheduler[thread_num] =netapi_schedOpen(worker_nh[thread_num],
565                                             &our_sched_cfg,
566                                             &err);
567     if (!scheduler[thread_num]) 
568         {
569         printf("sched create failed for core%d\n",thread_num);
570         goto ERR_fast_path_thread;
571         //exit(1);
572     }
574  
575     scheduler[thread_num]->config.yield = FALSE;
576     scheduler[thread_num]->config.pollGarbageQ = FALSE;
577     scheduler[thread_num]->config.pollCtrlQ = FALSE;
578    /* Entry point to scheduler */
581     printf("Fast Path thread: %d setup complete, running on ARM CORE: %d\n",
582     index,index);
583     netapi_schedRun(scheduler[thread_num], &err);
585 ERR_fast_path_thread:
586 #ifdef VDPI
587         navl_fini(navlHandle);
588 #endif
589     netapi_pktioClose(rx_chan, &err);
591     printf("fast_path_thread: calling netapi_shutdown\n");
592     netapi_shutdown(worker_nh[thread_num]);
596 /******************************
597 * main program
598 *****************************/
599 int main(int argc, char **argv)
601     int err,i;
602     int j;
603     int32_t             errCode;
604     Pktlib_HeapIfTable*  pPktifTable;
605     Pktlib_HeapCfg heapCfg;
606     long t1, t2 ;
607     cpu_set_t cpu_set;
608     int c;
609     int statsQueryRequest = 0;
610     pthread_t *thrs;
611     int p;
616 #if 1
618     if (argc == 2)
619     {
620         printf("main: argument %s\n", argv[1]);
621         if(!(strcmp(argv[1], "stats")))
622         {
623             statsQueryRequest =1;
624             printf("querying for stats\n");
625         }
626     }
627     printf("statsQueryReqeust: %d\n", statsQueryRequest);
630 #endif
633     if (!statsQueryRequest)
634     {
635         if (initRm())
636         {
637             printf("main: initRm() returned error\n");
638             exit(1);
639         }
641         signal(SIGINT,netTest_utilMySig);
642         CPU_ZERO( &cpu_set);
643         CPU_SET( 0, &cpu_set);
644         hplib_utilSetupThread(HPLIB_THREADID, &cpu_set, hplib_spinLock_Type_LOL);
645     
646         /* create netapi */
647         our_netapi_default_cfg.rmHandle = rmClientServiceHandle;
648         netapi_handle = netapi_init(NETAPI_SYS_MASTER,
649                                     &our_netapi_default_cfg);
650         if (netapi_handle == NULL)
651         {
652             printf("main: netapi_init failure, exiting\n");
653             exit(1);
654         }
655         /* allocate segment for shared memory for packet stats */
656         /* allocate packet statistics */
657         pShmBase = hplib_shmOpen();
658         if (pShmBase)
659         {
660             if (hplib_shmAddEntry(pShmBase,
661                               sizeof(navl_wrapper_pkt_stat_t)
662                              * MAX_PROTOCOLS *NUM_FP_PROCS + sizeof(navl_wrapper_cfg_info_t),
663                              APP_ENTRY_1) != hplib_OK)
664             {
665                 printf("main:  hplib_shmAddEntry failure\n");
666                 return -1;
667             }
668             else
669             {
670                 pShmEntry = hplib_shmGetEntry(pShmBase, APP_ENTRY_1);
671                 pNavlCfg =  (navl_wrapper_cfg_info_t*)pShmEntry;
672                 memset(pNavlCfg,
673                        0,
674                        sizeof(navl_wrapper_pkt_stat_t) * MAX_PROTOCOLS *NUM_FP_PROCS+ sizeof(navl_wrapper_cfg_info_t));
675                 pNavlCfg =  (navl_wrapper_cfg_info_t*)pShmEntry;
676                 pNavlCfg->enable_dpi = 0; /* disable DPI by default */
677             }
678             if (hplib_shmAddEntry(pShmBase, sizeof(navl_global_dpi_stats), APP_ENTRY_2) != hplib_OK)
679             {
680                 printf("main:  hplib_shmAddEntry failure\n");
681                 return -1;
682             }
683             else
684             {
685                 pShmEntry = hplib_shmGetEntry(pShmBase, APP_ENTRY_2);
686                 pGlobDpiStats = (navl_global_dpi_stats*) pShmEntry;
687                 memset(pGlobDpiStats, 0, sizeof(navl_global_dpi_stats));
688                 pGlobDpiStats->min_time=100000000;
689             }
690             if (hplib_shmAddEntry(pShmBase, sizeof(navl_wrapper_stat_t)* (NUM_FP_PROCS *NUM_MEM_CTX * NUM_MEM_OBJ),
691                                   APP_ENTRY_3) != hplib_OK)
692             {
693                 printf("main:  hplib_shmAddEntry failure\n");
694                 return -1;
695             }
696             else
697             {
698                 pShmEntry = hplib_shmGetEntry(pShmBase, APP_ENTRY_3);
699                 pNavlMemStats = (navl_wrapper_mem_stats_t*) pShmEntry;
700                 memset(pNavlMemStats, 0, sizeof(navl_wrapper_mem_stats_t));
701             }
702             
703         }
704         else
705         {
706             printf("main: hplib_shmOpen failure, exiting\n");
707             exit(1);
708         }
709             /* open the main heap */
710         OurHeap = Pktlib_findHeapByName("netapi");
711         if (!OurHeap)
712         {
713             printf("findheapbyname fail\n");
714             exit(1);
715         }
717         //if we want to relay network packets, we create a handle to the 
718         //default netcp receive queue here
719         netcp_rx_chan= netapi_pktioOpen(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb_bridge, &netcp_rx_cfg,  &err);
720         if (!netcp_rx_chan)
721         {
722             printf("pktio open RX failed err=%d\n",err);
723             exit(1);
724         }
726         netcp_tx_chan= netapi_pktioOpen(netapi_handle, NETCP_TX, (PKTIO_CB) NULL, &netcp_tx_cfg,  &err);
727         if (!netcp_tx_chan)
728         {
729             printf("pktio open TX failed err=%d\n",err);
730             exit(1);
731         }
732         else  //install a fast path template into the NETCP TX channel
733         {
734             PKTIO_CONTROL_T control2;
735             control2.op = PKTIO_UPDATE_FAST_PATH;
736             PKTIO_CFG_T cfg2;
737             memset(&cfg2, 0, sizeof(PKTIO_CFG_T));
738             cfg2.fast_path_cfg.fp_send_option = PKTIO_FP_NO_CRYPTO_NO_CKSUM_PORT;
739             cfg2.fast_path_cfg.txPktInfo= &txPktInfoNoCrypto;
740             netapi_pktioControl(netcp_tx_chan, NULL, &cfg2, &control2, &err);
741        }
744         if (navl_setup() < 0)
745         {
746             printf("main: navl_setup failure, exiting\n");
747             exit(1);
748         }
750         /*********************************************/
751         /*****************end NETAPI STARTUP**********/
752         /*********************************************/
754         //now creaate a simple netcp rule
755         //to get a lot of packets
756         mac0 = netapi_netcpCfgCreateMacInterface(
757                       netapi_handle,
758                       &all_mac[0],
759                       NULL,
760                       0,
761                       1,
762                       (NETCP_CFG_ROUTE_HANDLE_T)  NULL,
763                       (NETCP_CFG_VLAN_T ) NULL ,  //future
764                       0x0800,
765                       1,
766                       &err);
767         if (err) {printf("addmac0 failed %d\n",err); exit(1); }
768         else printf("addmac0 sucess\n");
770         mac1 = netapi_netcpCfgCreateMacInterface(
771                       netapi_handle,
772                       &all_mac[0],
773                       NULL,
774                       1,
775                       2,
776                       (NETCP_CFG_ROUTE_HANDLE_T)  NULL,
777                       (NETCP_CFG_VLAN_T ) NULL ,  //future
778                       0x0800,
779                       1,
780                       &err);
781         if (err) {printf("addmac1 failed %d\n",err); exit(1); }
782         else printf("addmac1 sucess\n");
784         //calibrate idle
785         CALIB = calibrate_idle();
787         //**************************************
788         //Create a slow path thread
789         //***************************************
790         thrs = malloc( sizeof( pthread_t ) * NUM_PROCS );
791         if (thrs == NULL)
792         {
793             perror( "malloc" );
794             return -1;
795         }
796         printf( "dpi-demo: Starting slow_path_thread on core 0\n");
798         if (pthread_create( &thrs[0], NULL, (void*)slow_path_thread,
799                           (void *)0 ))  //start at core 0
800         {
801             perror( "pthread_create" );
802             exit(1);
803         }
806         for (j= 1;j < NUM_PROCS;j++)
807         {
808             printf( "dpi-demo: Starting fast_path_thread on core 1\n");
809             if (pthread_create( &thrs[j], NULL, (void*)fast_path_thread,
810                           (void *)j ))  //start at core 1
811             {
812                 perror( "pthread_create" );
813                 exit(1);
814             }
815         }
816     }
817     else
818     {
819         
820         pShmBase = hplib_shmOpen();
821         if (pShmBase)
822         {
823             pTemp = hplib_shmGetEntry(pShmBase, APP_ENTRY_1);
824             pNavlCfg =  (navl_wrapper_cfg_info_t*)pTemp;
826             pStats1 = pTemp + sizeof(navl_wrapper_cfg_info_t);
828         
829             pStats2 = pTemp + sizeof(navl_wrapper_cfg_info_t) +
830                     (sizeof(navl_wrapper_pkt_stat_t)*pNavlCfg->num_protocols);
832             pTemp = hplib_shmGetEntry(pShmBase, APP_ENTRY_2);
833             pGlobDpiStats = (struct dpi_stats*) pTemp;
835             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",
836             pGlobDpiStats->n_ops,
837             pGlobDpiStats->n_class,
838             pGlobDpiStats->min_time,
839             pGlobDpiStats->max_time,
840             pGlobDpiStats->n_ops? pGlobDpiStats->tot/pGlobDpiStats->n_ops : 0,
841             pGlobDpiStats->m_op,
842             pGlobDpiStats->m_bytes,
843             pGlobDpiStats->n_err,
844             pGlobDpiStats->f_op, pGlobDpiStats->m_cycles, pGlobDpiStats->f_cycles);
845             for(i=0;i < NUM_FP_PROCS; i++)
846             {
847                 navl_results2(i);
848             }
849             exit(1);
850         }
851     }
854         //this thread of execution (main) now just waits on user input
855         for(;;)
856         {
857             printf(">");
858             c=getchar();
859             if (c=='C')
860             {
861                 CAP=!CAP; 
862                 printf("CAPTURE= %d\n", CAP);
863             }
864             else if (c=='q') {QUIT=1;break;}
865             else if (c=='s')
866                 our_stats_cb(netapi_handle, &netcp_stats);
867     #ifdef VDPI
868                else if (c=='c') 
869                 {navl_clear_stats();printf("> Clearing DPI stats\n");}
870                else if (c=='v') navl_set_verbose();
871                else if (c=='p') 
872                  {DUMP_DPI_CONN = !DUMP_DPI_CONN;printf(">  **DPI CONN DUMP is %s ** \n", DUMP_DPI_CONN ?"enabled":"disabled");}
873                else if (c=='d')
874                  {
875                     pNavlCfg->enable_dpi = !pNavlCfg->enable_dpi;
876                     printf("enable_dpi flag: %d\n", pNavlCfg->enable_dpi);
877                     printf(">  **DPI is %s ** \n", pNavlCfg->enable_dpi?"enabled":"disabled");
878                  }
879     #endif
880             else if (c=='!') {system("sh");}
881     
882             else if ((c=='h')||(c=='?'))
883             {
884                 printf("> 'q' to quit,  's' for stats,'d' to dump capture\n,> 'h' for help\n ");
885             }
886     #if 1
887             else if (c=='r')
888             {
889                 netTest_utilDumpHeader(&last_header[0], 0,0,0);
890                 netTest_utilDumpDescr(&last_desc[0], 0);
891             }
892     #endif
893         }
897 #ifdef VDPI
898             navl_done();
899 #endif
901         //wait for completion 
902         printf("main task now pending on thread completion\n");
903         for (i = 0; i < NUM_PROCS; i++)
904                 pthread_join( thrs[i], NULL );
906         free( thrs );
908         /*************************************************
909         ************CLEAN UP****************************
910         ************************************************/
911         //get rid of rule, in the case that we are relaying packets
912         //also close our netcp rx channel
913         netapi_netcpCfgDelMac(netapi_handle,0,&err);
914         netapi_netcpCfgDelMac(netapi_handle,1,&err);
915     
916         netapi_pktioClose(netcp_rx_chan,&err);
917         netapi_pktioClose(netcp_tx_chan,&err);
920         //done
921         netapi_shutdown(netapi_handle);
925 #if 1
926 static inline void send_it(Ti_Pkt *tip, int len, int out_port)
928   int err=0;
929   PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
930   nwalTxPktInfo_t meta_tx2={0};
931   int coreid=Osal_nwalGetProcId();
932   if (len<60)
933   {
934      unsigned int templen;
935      char * p_pkt;
936      len=60;
937      Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
938      Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
939   }
940   Pktlib_setPacketLen(tip,len);
941   meta_tx2.txFlag1 = NWAL_TX_FLAG1_META_DATA_VALID;
942   meta_tx2.ploadLen = len ;
943   meta_tx2.enetPort=out_port;
944   meta2.u.tx_meta=&meta_tx2;
945   stats.tx+=1;
946   if(coreid<MAX_NUM_CORES)
947     pkt_tx[coreid]+=1;
948   netapi_pktioSend(netcp_tx_chan,tip,&meta2,&err);
950 #endif
951 void recv_cb_bridge(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
952                          PKTIO_METADATA_T meta[], int n_pkts,
953                          uint64_t ts )
955 int i;
956 int len;
957 int p;
958 Ti_Pkt * tip;
959 unsigned int appid;
960 unsigned int templen;
961 char * p_pkt;
962 unsigned long t1;
963 unsigned long t2;
964 unsigned long long ct1;
965 unsigned long long ct2;
966 unsigned short ip_pl;
967 unsigned long long n_c_ops;
968 int ifno;
969 int out_port;
971 int coreid=Osal_nwalGetProcId();
974 pasahoLongInfo_t* protoInfo;
976 t1=netapi_timing_start();
977 ct1 =Osal_cache_op_measure(&n_c_ops);
978 for(i=0;i<n_pkts;i++)
980         
981         tip = p_recv[i];
982         appid = ((unsigned int)meta[i].u.rx_meta->appId)&0xff000000;
983         if (appid == NETAPI_NETCP_MATCH_GENERIC_IP) 
984         {
985            stats.ip+=1;
986         }
988         protoInfo=nwal_mGetProtoInfo(tip);
989         ifno = nwal_mGetRxEmacPort( protoInfo);
990         if (ifno ==1) out_port=2; else out_port=1;
991         if(coreid<MAX_NUM_CORES) stats.core_rx[coreid]+=1;
992         if (ifno < MAX_NUM_INTERFACES) stats.if_rx[ifno]+=1;
993         Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
994         if (CAP==coreid)
995         {
996             memcpy((unsigned char *)&last_header[0],p_pkt,32);
997             memcpy((unsigned char*)&last_desc[0],tip,64);
998         }
999         len = Pktlib_getPacketLen(tip);//real length, subtract mac trailer
1000         stats.rx+=1;
1001         //printf("recv_cb_bridge: appId: 0x%x, out_port: %d\n", appid, out_port);
1002         if (appid == NETAPI_NETCP_MATCH_GENERIC_MAC)
1003         {
1004 #ifdef VDPI
1005             {
1006                 if (pNavlCfg->enable_dpi)
1007                     navl_process_pkt(p_pkt, len);
1008             }
1009 #endif
1010         }
1012     
1013  //printf("recv_cb_bridge: coreId: %d, outPort %d\n", coreid, out_port);
1014         //Pktlib_freePacket(tip);
1015        send_it(tip,len,out_port);
1017 t2=netapi_timing_start();
1018 ct2 =Osal_cache_op_measure(&n_c_ops);
1019 stats.app_cycles +=  (unsigned long long) (t2-t1);
1020 stats.tx_cache_cycles += (unsigned long long) (ct2-ct1);
1021 return;
1024 #define NTOPOP 150
1025 volatile Ti_Pkt * pHd[NTOPOP];
1027 #define PKTGEN_PKT_LEN pkt_len
1028 #define MAXP 4   //max ports 
1029 void gen_pkts(int np, int out_port)
1031     int i;
1032     int p=0;
1033     unsigned long * pI ;
1034     Ti_Pkt * tip;
1035     int len;
1036     unsigned char * pData;
1037     int cstall=0;
1038     int coreid = Osal_nwalGetProcId();
1039     for(i=0;i<np;)
1040     {
1041         //set out output port
1042         if (out_port)
1043         {
1044             p=out_port;
1045         }
1046         else //flip flop
1047         {
1048             p+=1;
1049             if(p>MAXP) p=1;
1050         }
1051         //get a packet
1052         tip=Pktlib_allocPacket(OurHeap,PKTGEN_PKT_LEN);
1053         pI = (unsigned long *) tip;
1054         if (!tip)
1055         {
1056             pkt_stall[coreid]+=1;
1057             cstall+=1;
1058             if (cstall >= 100000) 
1059             {
1060                 printf("worker core %d, max stall hit,, exiting.\n",coreid); 
1061                 return;
1062             }
1063             continue;
1064         }
1065         cstall=0;
1066         Pktlib_getDataBuffer(tip,&pData,&len);
1067         memcpy(pData,&dummy_mac,14);
1068         Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, pData,PKTGEN_PKT_LEN);
1069         Pktlib_setPacketLen(tip,PKTGEN_PKT_LEN);
1070         pI[1]=0x80000000;
1071         //pI[2] &= 0xfff0ffff ;move to pktio send function
1073         //capture packet just in case
1074         if (CAP==coreid)
1075         {
1076             unsigned int templen;
1077             char * p_pkt;
1078             Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
1079             memcpy((unsigned char *)&last_header[0],p_pkt,32);
1080             memcpy((unsigned char*)&last_desc[0],tip,64);
1081         }
1083         //send  packet
1084         send_it(tip, PKTGEN_PKT_LEN, p);
1085         pkt_tx[coreid]+=1;
1086         i+=1;
1087    }
1089     return;