b074eb7ff98facf18d73febf677dd02d120acf1d
[keystone-rtos/netapi.git] / ti / runtime / netapi / demo / src / netapi_dpi_demo.c
1 /******************************************\r
2  * File: nt_bench.c   \r
3  * Purpose:  benchmarks for NT.\r
4  **************************************************************\r
5  * FILE:  nt_bench.c\r
6  * \r
7  * DESCRIPTION:  netapi user space transport\r
8  *               library  test application : benchmarks\r
9  * \r
10  * REVISION HISTORY:  rev 0.0.1 \r
11  *\r
12  *  Copyright (c) Texas Instruments Incorporated 2010-2011\r
13  * \r
14  *  Redistribution and use in source and binary forms, with or without \r
15  *  modification, are permitted provided that the following conditions \r
16  *  are met:\r
17  *\r
18  *    Redistributions of source code must retain the above copyright \r
19  *    notice, this list of conditions and the following disclaimer.\r
20  *\r
21  *    Redistributions in binary form must reproduce the above copyright\r
22  *    notice, this list of conditions and the following disclaimer in the \r
23  *    documentation and/or other materials provided with the   \r
24  *    distribution.\r
25  *\r
26  *    Neither the name of Texas Instruments Incorporated nor the names of\r
27  *    its contributors may be used to endorse or promote products derived\r
28  *    from this software without specific prior written permission.\r
29  *\r
30  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
31  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
32  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
33  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
34  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
35  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
36  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
37  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
38  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
39  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
40  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
41 \r
42  *****************************************/\r
43 \r
44 #include <stdio.h>\r
45 #include <stdlib.h>\r
46 #include <unistd.h>\r
47 #include <string.h>\r
48 #include <signal.h>\r
49 #include <pthread.h>\r
50 #include <sched.h>\r
51 \r
52 //#include "trie.h"\r
53 #include <ti/runtime/netapi/netapi.h>\r
54 #include <ti/runtime/hplib/hplib.h>\r
55 #include "ti/runtime/netapi/pktio.h"\r
56 #include "netapi_dpi_demo.h"\r
57 #include "navl_wrapper.h"\r
58 //#include "ti/runtime/netapi/test/net_test.h"\r
59 #include <ti/drv/sa/salld.h>\r
60 \r
61 #include <ti/drv/qmss/device/k2e/src/qmss_device.c>\r
62 #include <ti/drv/cppi/device/k2e/src/cppi_device.c>\r
63 \r
64 extern Rm_ServiceHandle   *rmClientServiceHandle;\r
65 \r
66 \r
67 #define netapi_timing_start hplib_mUtilGetPmuCCNT\r
68 \r
69 \r
70 extern NETCP_CFG_EXCEPTION_PKT_T expPkt_appid;\r
71 \r
72 STATS_T stats;\r
73 paSysStats_t netcp_stats;\r
74 struct dpi_stats dpis;\r
75 \r
76 #define VDPI\r
77 #ifdef VDPI\r
78 static int DPI=0;  //1 to enable\r
79 static int DUMP_DPI_CONN=0;\r
80 #endif\r
81 \r
82 static int scnt=0;\r
83 volatile static int QUIT=0;\r
84 static int XMIT=0;\r
85 static int CAP=0;\r
86 volatile int RESET=0; //to reset stats\r
87 static int NTH=1;\r
88 volatile static int PKTGEN=0;\r
89 int pkt_len=64;\r
90 \r
91 \r
92 \r
93 NETCP_CFG_MACIF_T mac[NUM_PROCS];\r
94 NETCP_CFG_MACIF_T mac0;\r
95 NETCP_CFG_MACIF_T mac1;\r
96 \r
97 hplib_spinLock_T dpi_demo_thread_lock;\r
98 \r
99 \r
100 static char usage[] = "usage: %s -s \n";\r
101 \r
102 \r
103 \r
104 \r
105 //int procs =2; \r
106 \r
107 #define HPLIB_THREADID 0  // for main: HPLIB THREAD INSTANCE\r
108 //__thread int our_core;\r
109 static unsigned char dummy_mac[]={0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x01,0x02,0x03,0x04,0x05,0x08,0x00};\r
110 \r
111 void house(NETAPI_SCHED_HANDLE_T *s);\r
112 void our_stats_cb_mt(NETAPI_T h, paSysStats_t* pPaStats);\r
113 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats);\r
114 \r
115 //sig handler\r
116 void netTest_utilMySig(int x)\r
117 {\r
118   QUIT=1;\r
119   scnt+=1;\r
120   printf(">net_test_dpi: recv'd signal %d cnt=%d\n",x,scnt);\r
121   if (scnt > 10) {printf(">dpi-demo: WARNING EXITING WITH PROPER SHUTDOWN LUTS LEFT ACTIVE\n");exit(1);}\r
122 \r
123 }\r
124 \r
125 \r
126 void recv_cb_bridge(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],\r
127                          PKTIO_METADATA_T meta[], int n_pkts,\r
128                          uint64_t ts );\r
129 \r
130 \r
131 /*************debug********************/\r
132 void netTest_utilDumpDescr(unsigned long *p, int n)\r
133 {\r
134    printf("--------dump of descriptor %d %x\n", n, (int) p);\r
135    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]);\r
136    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]);\r
137    printf("-----------------------------\n");\r
138 }\r
139 void netTest_utilDumpHeader(unsigned long *p, int n, int a, int r)\r
140 {\r
141    printf("--------dump of header %d %x appID=%x flag1=%x\n", n, (int) p,a,r);\r
142    printf("> %0x %0x %0x %0x %0x %0x %0x %0x\n",\r
143           ntohl(p[0]),ntohl(p[1]),ntohl(p[2]),ntohl(p[3]),\r
144           ntohl(p[4]),ntohl(p[5]),ntohl(p[6]),ntohl(p[7]) );\r
145 #if 0\r
146    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]);\r
147    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]);\r
148    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]);\r
149 #endif\r
150    printf("-----------------------------\n");\r
151 }\r
152 /*****************************************/\r
153 \r
154 void house(NETAPI_SCHED_HANDLE_T * s)\r
155 {\r
156     int err;\r
157     NETAPI_SCHED_SHUTDOWN_T sched_shutdown;\r
158     int coreid;  //who we are\r
159     NETAPI_T nh= netapi_schedGetHandle(s);\r
160     coreid=(int) netapi_getCookie(nh);\r
161     \r
162     if (QUIT)\r
163     {\r
164         sched_shutdown.shutdown_type = NETAPI_SCHED_SHUTDOWN_NOW;\r
165         netapi_schedClose(s,&sched_shutdown,&err); \r
166         return;\r
167     }\r
168 \r
169 \r
170 #ifdef VDPI\r
171     if (DUMP_DPI_CONN )\r
172         navl_dump_conn_info();\r
173 #endif\r
174 \r
175 \r
176     /* only slow path threads get netcp stats, this needs to be set in cookie\r
177        during slow path thread creation*/\r
178     if (coreid & SP_THREAD_MASK)\r
179     {\r
180         netapi_netcpCfgReqStats(nh, our_stats_cb_mt, 0,&err);\r
181     }\r
182 \r
183 }\r
184 \r
185 unsigned long long CALIB=0;\r
186 unsigned long long calibrate_idle(void)\r
187 {\r
188     volatile unsigned long long  at1;\r
189     volatile unsigned long long  at2;\r
190     volatile unsigned long pt1;\r
191     volatile unsigned long pt2;\r
192     unsigned long long calib;\r
193     at1 = hplib_mUtilGetTimestamp();\r
194     pt1=netapi_timing_start();\r
195     for(;;)\r
196     {\r
197        pt2=netapi_timing_start()   ;\r
198        if ((pt2-pt1) >= 100000) break;\r
199     }\r
200     at2 = hplib_mUtilGetTimestamp();\r
201     \r
202     calib = ((unsigned long long) (pt2-pt1))/(at2-at1);\r
203     printf("calibrate:   arm time=%lld  -> arm cycles=%d calib=%lld\n", at2-at1, pt2-pt1, calib);\r
204     \r
205     return calib;\r
206 }\r
207 \r
208 /*******************************************\r
209  *************NETAPI OBJECTS***************\r
210  *****************************************/\r
211 static NETAPI_CFG_T our_netapi_default_cfg=\r
212 {\r
213 TUNE_NETAPI_PERM_MEM_SZ,\r
214 128,  //start of packet offset for hw to place data on rx for default flow\r
215 TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system\r
216 TUNE_NETAPI_NUM_GLOBAL_DESC,        //total we will use\r
217 TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap\r
218 64, //#descriptors w/o buffers in default heap\r
219 TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128,  //size of buffers in default heap\r
220 128,       //tail room\r
221 256,      //extra room\r
222 0,\r
223 NULL\r
224 };\r
225 \r
226 Pktlib_HeapHandle OurHeap;     //default heap, used by producer\r
227 PKTIO_HANDLE_T * netcp_rx_chan;\r
228 PKTIO_HANDLE_T * netcp_rx_chan2;\r
229 PKTIO_HANDLE_T * netcp_tx_chan;\r
230 \r
231 PKTIO_CFG_T our_chan_cfg={PKTIO_RX_TX, PKTIO_LOCAL, PKTIO_Q_ANY, 8};\r
232 PKTIO_CFG_T netcp_rx_cfg={PKTIO_RX, PKTIO_NA, PKTIO_NA, 8};\r
233 PKTIO_CFG_T netcp_rx_cfg2={PKTIO_RX, (PKTIO_GLOBAL|PKTIO_PKT), PKTIO_Q_ANY, 8};\r
234 PKTIO_CFG_T netcp_tx_cfg={PKTIO_TX, PKTIO_NA, PKTIO_NA, 8};\r
235 NETAPI_T netapi_handle;\r
236 NETAPI_SCHED_HANDLE_T * our_sched;\r
237 NETAPI_SCHED_HANDLE_T * scheduler[TUNE_NETAPI_NUM_CORES];\r
238 NETAPI_SCHED_CONFIG_T our_sched_cfg={\r
239   NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 5000000  //every 5000000 poll loops\r
240 };\r
241 \r
242 NETCP_CFG_IP_T ip_rule0;\r
243 NETCP_CFG_IP_T ip_rule1;\r
244 \r
245 \r
246 PKTIO_CFG_T direct_to_cpsw_cfg={PKTIO_TX, PKTIO_GLOBAL, 648, 8};\r
247 PKTIO_HANDLE_T * cpsw_tx_chan;\r
248 \r
249 PKTIO_CONTROL_T zap_channel_control={PKTIO_CLEAR, NULL};\r
250 PKTIO_CONTROL_T poll_cannel_control={PKTIO_SET_POLL_FLAGS, NULL, nwal_POLL_DEFAULT_GLOB_PKT_Q};\r
251 \r
252 //template for fast path\r
253 nwalTxPktInfo_t txPktInfoNoCrypto =\r
254 {\r
255     NULL,                                                                                               /* p_pkt */\r
256     NWAL_TX_FLAG1_META_DATA_VALID,      /* txFlags */\r
257     0,                                                                                                  /* lpbackPass */\r
258     0,                                                                                                  /* enetport */\r
259     0,                                                                                                  /* msuSize */\r
260     0,                                                                                                   /* startOffset */\r
261     0,                                                    /* saOffBytes */\r
262     0,                                                                                                  /* saPayLoadLen */\r
263     0               ,                                                                                    /* saAhIcvOffBytes */\r
264     0,                                                                                                 /* saAhMacSize */\r
265     0,                                              /* etherLenOffBytes */\r
266     MAC_HEADER_LEN,         /* ipOffBytes */\r
267     MAC_HEADER_LEN + IP_HEADER_LEN,                                        /* l4OffBytes */\r
268     UDP_HEADER_LEN,                                                             /* l4HdrLen */\r
269     0,                                                                         /* pseudoHdrChecksum */\r
270     0                                                                                                   /* pLoadLen */\r
271 };\r
272 \r
273 \r
274 NETCP_CFG_ROUTE_T  test_route=\r
275 {\r
276 0,\r
277 NULL,\r
278 NULL,\r
279 0//* to be filled in\r
280 };\r
281 \r
282 NETCP_CFG_FLOW_HANDLE_T kernelFlow22;\r
283 NETCP_CFG_FLOW_HANDLE_T kernelFlow23;\r
284 \r
285 /*************************END NETAPI OBJECTS***********************/\r
286 \r
287 static unsigned char all_mac[]={0,0,0,0,0,0};\r
288 nwalIpAddr_t all_ip={0,0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };\r
289 \r
290 \r
291 static unsigned char all_dest[]={0xff,0xff,0xff,0xff,0xff,0xff};\r
292 \r
293 \r
294 \r
295 \r
296 static unsigned long last_header[32/sizeof(unsigned long)];\r
297 static unsigned long last_desc[64/sizeof(unsigned long)];\r
298 \r
299 //stats\r
300 #define MAX_CORE 4\r
301 int pkt_rx[MAX_CORE]; \r
302 int pkt_tx[MAX_CORE]; \r
303 unsigned long long pkt_rx_cycles[MAX_CORE]={0L};\r
304 unsigned long long pkt_tx_cycles[MAX_CORE]={0L};\r
305 unsigned long long pkt_cb_cycles[MAX_CORE]={0L};\r
306 unsigned long long idle_cycles[MAX_CORE]={0L};\r
307 volatile unsigned long long start_time[MAX_CORE];\r
308 unsigned long long end_time[MAX_CORE];\r
309 unsigned long long pkt_stall[MAX_CORE]={0L};\r
310 //*********************************\r
311 // packet generator\r
312 //*********************************\r
313 void gen_pkts(int np, int out_port);\r
314 \r
315 /******************************************************\r
316  * stats callback\r
317  *******************************************************/\r
318 void our_stats_cb_mt(NETAPI_T h, paSysStats_t* pPaStats)\r
319 {\r
320   stats.n_stats_cb +=1;\r
321   if(pPaStats) memcpy(&netcp_stats,pPaStats, sizeof(paSysStats_t));\r
322 }\r
323 \r
324 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats)\r
325 {\r
326     uint32_t numFreeDataPackets;\r
327     uint32_t            numZeroBufferPackets;\r
328     uint32_t            numPacketsinGarbage;\r
329     Pktlib_HeapStats    pktLibHeapStats;\r
330     int i,j;\r
331     unsigned long long bcpp;\r
332     unsigned long long bcpp_noc;\r
333     unsigned long long bcpp_app;\r
334     unsigned long long bcpp_tx;\r
335     unsigned long long npL;\r
336     unsigned long long cyclesL;\r
337     unsigned long long ccyclesL; //cache cycles\r
338     unsigned long long tmp_npL[TUNE_NETAPI_NUM_CORES];\r
339     unsigned long long tmp_cyclesL[TUNE_NETAPI_NUM_CORES];\r
340     unsigned long long tmp_ccyclesL[TUNE_NETAPI_NUM_CORES]; //cache cycles\r
341     NETAPI_SA_STATS_T netapi_sa_stats;\r
342 \r
343     printf(">*****stats @ %lld (#cbs%d) \n", hplib_mUtilGetTimestamp(),stats.n_stats_cb);\r
344     //printf("netcp_tx_handle check %x\n", netcp_tx_chan->back);\r
345     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",\r
346              stats.itx, stats.rx, stats.tx, stats.n_bad, stats.n_new, \r
347              stats.n_class0_rx, stats.n_class1_rx, \r
348              stats.n_class2_rx, stats.sec_rx, stats.secp_rx, stats.sb_rx, stats.sb_tx, stats.n_auth_ok,\r
349              stats.sec_tx, stats.rx_min, stats.tx_min, stats.ip);\r
350     printf(">if rx stats:  %d %d %d\n",stats.if_rx[0],stats.if_rx[1],stats.if_rx[2]);\r
351 \r
352 \r
353     printf(">core rx stats:  %d %d %d\n",stats.core_rx[1],stats.core_rx[2],stats.core_rx[3]);\r
354 \r
355 \r
356     /* need to maintain number of fast path threads in some global context */\r
357     for (j= 1;j < NUM_PROCS;j++)\r
358     {\r
359         tmp_npL[j]=0LL; tmp_cyclesL[j]=0LL; tmp_ccyclesL[j]=0LL;\r
360         netapi_schedGetStats(scheduler[j],&tmp_npL[j],&tmp_cyclesL[j],&tmp_ccyclesL[j]);\r
361         npL += tmp_npL[j];\r
362         cyclesL += tmp_cyclesL[j];\r
363         ccyclesL += tmp_ccyclesL[j];\r
364     }\r
365 \r
366     if (npL && stats.rx)\r
367     {\r
368         bcpp = cyclesL/npL; \r
369         bcpp_noc = (cyclesL-ccyclesL)/npL; \r
370         bcpp_app = (stats.app_cycles-stats.tx_cache_cycles)/stats.rx;\r
371     }\r
372     else {bcpp = bcpp_noc=bcpp_app=0L;}\r
373     if (stats.tx)\r
374     {\r
375         bcpp_tx = (stats.send_cycles-stats.tx_cache_cycles)/stats.tx;\r
376     }\r
377     else\r
378     {\r
379         bcpp_tx = 0L;\r
380     }\r
381     printf(">         ++ busy cycles pp=%lld (%lld wo cache ops) (app+tx= %lld) (tx= %lld) ++\n",\r
382          bcpp,bcpp_noc,bcpp_app, bcpp_tx);\r
383 \r
384 \r
385 #ifdef VDPI\r
386     navl_return_stats(\r
387     &dpis.n_ops,\r
388     &dpis.n_class,\r
389     &dpis.min_time,\r
390     &dpis.max_time,\r
391     &dpis.tot,\r
392     &dpis.m_op,\r
393     &dpis.m_bytes,\r
394     &dpis.n_err,\r
395     &dpis.f_op,\r
396     &dpis.m_cycles,\r
397     &dpis.f_cycles);\r
398 \r
399     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",\r
400     dpis.n_ops,\r
401     dpis.n_class,\r
402     dpis.min_time,\r
403     dpis.max_time,\r
404     dpis.n_ops? dpis.tot/dpis.n_ops : 0,\r
405     dpis.m_op,\r
406     dpis.m_bytes,\r
407     dpis.n_err,\r
408     dpis.f_op, dpis.m_cycles, dpis.f_cycles);\r
409     navl_results(1);\r
410     navl_results(2);\r
411 #endif\r
412     if(pPaStats)\r
413     {\r
414         printf("C1 number of packets:           %d\n", pPaStats->classify1.nPackets);\r
415         printf("C1 number IPv4 packets:         %d\n", pPaStats->classify1.nIpv4Packets);\r
416         printf("C1 number IPv6 packets:        %d\n", pPaStats->classify1.nIpv6Packets);\r
417         printf("C1 number Custom packets:        %d\n", pPaStats->classify1.nCustomPackets);\r
418         printf("C1 number SRIO packets:        %d\n", pPaStats->classify1.nSrioPackets);\r
419         printf("C1 number LLC/SNAP Fail packets:        %d\n", pPaStats->classify1.nLlcSnapFail);\r
420         printf("C1 number table matched:        %d\n", pPaStats->classify1.nTableMatch);\r
421         printf("C1 number failed table matched: %d\n", pPaStats->classify1.nNoTableMatch);\r
422         printf("C1 number IP Fragmented packets: %d\n", pPaStats->classify1.nIpFrag);\r
423         printf("C1 number IP Depth Overflow: %d\n", pPaStats->classify1.nIpDepthOverflow);\r
424         printf("C1 number VLAN Depth Overflow: %d\n", pPaStats->classify1.nVlanDepthOverflow);\r
425         printf("C1 number GRE Depth Overflow: %d\n", pPaStats->classify1.nGreDepthOverflow);\r
426         printf("C1 number MPLS Packets: %d\n", pPaStats->classify1.nMplsPackets);\r
427         printf ("C1 number of parse fail:        %d\n",pPaStats->classify1.nParseFail);\r
428         printf("C1 number of Invalid IPv6 Opt:  %d\n", pPaStats->classify1.nInvalidIPv6Opt);\r
429         printf("C1 number of TX IP Fragments:  %d\n", pPaStats->classify1.nTxIpFrag);\r
430         printf ("C1 number of silent discard:    %d\n",pPaStats->classify1.nSilentDiscard);\r
431         printf("C1 number of invalid control:   %d\n", pPaStats->classify1.nInvalidControl);\r
432         printf ("C1 number of invalid states:    %d\n",pPaStats->classify1.nInvalidState);\r
433         printf ("C1 number of system fails:      %d\n",pPaStats->classify1.nSystemFail);\r
434         printf ("C2 number Packets  :           %d\n",pPaStats->classify2.nPackets);\r
435         printf ("C2 number udp           :      %d\n",pPaStats->classify2.nUdp);\r
436         printf ("C2 number tcp           :      %d\n",pPaStats->classify2.nTcp);\r
437         printf ("C2 number Custom       :      %d\n",pPaStats->classify2.nCustom);\r
438         printf ("C2 number silent drop   :      %d\n",pPaStats->classify2.nSilentDiscard);\r
439         printf ("C2 number invalid cntrl :      %d\n\n",pPaStats->classify2.nInvalidControl);\r
440         printf ("C2 number Modify Stats Cmd Fail :      %d\n\n",pPaStats->modify.nCommandFail);\r
441     }\r
442     Pktlib_getHeapStats(OurHeap, &pktLibHeapStats);\r
443 \r
444     printf("main heap stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,\r
445                                 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);\r
446     printf("               >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n", \r
447                         pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,\r
448                         pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);\r
449 }\r
450 \r
451 NETAPI_T worker_nh[MAX_NUM_CORES];\r
452 \r
453 void slow_path_thread(uint32_t index)\r
454 {\r
455     int err, i;;\r
456     uint32_t thread_num;\r
457     cpu_set_t cpu_set;\r
458 \r
459     /* index being passed in is the core we want to run the thread on */\r
460     thread_num = index;\r
461     printf("slow_path_thread, mypid: %d, core_id %d\n", gettid(), thread_num);\r
462 \r
463     CPU_ZERO( &cpu_set);\r
464     for (i = 0; i < 1;i++)\r
465     {\r
466         CPU_SET( i, &cpu_set);\r
467     }\r
468     hplib_utilSetupThread(thread_num, &cpu_set, hplib_spinLock_Type_LOL);\r
469     worker_nh[thread_num] = netapi_init(NETAPI_CORE_MASTER,NULL);\r
470 \r
471     if (worker_nh[thread_num] == NULL)\r
472     {\r
473         printf("slow_path_thread: netapi_init failure, exiting\n");\r
474         exit(1);\r
475     }\r
476     netapi_setCookie(worker_nh[thread_num],(void*)(thread_num | SP_THREAD_MASK));\r
477 \r
478     scheduler[thread_num] =netapi_schedOpen(worker_nh[thread_num],&our_sched_cfg, &err);\r
479     if (!scheduler[thread_num]) \r
480     {\r
481         printf("sched create failed for core%d\n",thread_num);\r
482         goto ERR_slow_path_thread;\r
483     }\r
484     scheduler[thread_num]->config.yield = TRUE;\r
485     scheduler[thread_num]->config.pollGarbageQ = TRUE;\r
486     scheduler[thread_num]->config.pollCtrlQ = TRUE;\r
487     printf("Slow Path thread: %d setup complete, running on ARM CORE: %d\n",\r
488     index,index);\r
489 \r
490 \r
491     netapi_schedRun(scheduler[thread_num], &err);\r
492 \r
493 ERR_slow_path_thread:\r
494     printf("slow_path_thread: calling netapi_shutdown\n");\r
495     netapi_shutdown(worker_nh[thread_num]);\r
496 }\r
497 \r
498 \r
499 void fast_path_thread(uint32_t index)\r
500 {\r
501     int err, i;\r
502     PKTIO_HANDLE_T *rx_chan;\r
503     PKTIO_HANDLE_T *sb_rx_chan;\r
504     uint32_t thread_num;\r
505     int navlHandle;\r
506 \r
507 \r
508     cpu_set_t cpu_set;\r
509 \r
510     CPU_ZERO( &cpu_set);\r
511     thread_num = index;\r
512     printf("fast_path_thread: core %d\n", index);\r
513 \r
514 \r
515     CPU_SET( thread_num, &cpu_set);\r
516     hplib_utilSetupThread(thread_num, &cpu_set, hplib_spinLock_Type_LOL);\r
517 \r
518 \r
519     hplib_mSpinLockLock(&dpi_demo_thread_lock);\r
520     worker_nh[thread_num]=netapi_init(NETAPI_CORE_MASTER,NULL);\r
521     \r
522     if (worker_nh[thread_num] == NULL)\r
523     {\r
524         printf("fast_path_thread: netapi_init failure, exiting\n");\r
525         hplib_mSpinLockUnlock(&dpi_demo_thread_lock);\r
526         exit(1);\r
527     }\r
528     else\r
529     {\r
530 #ifdef VDPI\r
531             navlHandle = navl_per_thread_init(thread_num);\r
532 #endif\r
533     }\r
534     hplib_mSpinLockUnlock(&dpi_demo_thread_lock);\r
535 \r
536 \r
537     if (worker_nh[thread_num] == NULL)\r
538     {\r
539         printf("fast_path_thread: netapi_init failure, exiting\n");\r
540         exit(1);\r
541     }\r
542     \r
543     /* open netcp default RX channels*/\r
544     rx_chan = netapi_pktioOpen(worker_nh[thread_num], NETCP_RX, (PKTIO_CB) recv_cb_bridge, &netcp_rx_cfg,  &err);\r
545 \r
546 \r
547     netapi_setCookie(worker_nh[thread_num],(void*)thread_num);\r
548     \r
549     scheduler[thread_num] =netapi_schedOpen(worker_nh[thread_num],\r
550                                             &our_sched_cfg,\r
551                                             &err);\r
552     if (!scheduler[thread_num]) \r
553         {\r
554         printf("sched create failed for core%d\n",thread_num);\r
555         goto ERR_fast_path_thread;\r
556         //exit(1);\r
557     }\r
558 \r
559  \r
560     scheduler[thread_num]->config.yield = FALSE;\r
561     scheduler[thread_num]->config.pollGarbageQ = FALSE;\r
562     scheduler[thread_num]->config.pollCtrlQ = FALSE;\r
563    /* Entry point to scheduler */\r
564 \r
565 \r
566     printf("Fast Path thread: %d setup complete, running on ARM CORE: %d\n",\r
567     index,index);\r
568     netapi_schedRun(scheduler[thread_num], &err);\r
569 \r
570 ERR_fast_path_thread:\r
571 #ifdef VDPI\r
572         navl_fini(navlHandle);\r
573 #endif\r
574     netapi_pktioClose(rx_chan, &err);\r
575 \r
576     printf("fast_path_thread: calling netapi_shutdown\n");\r
577     netapi_shutdown(worker_nh[thread_num]);\r
578 }\r
579 \r
580 \r
581 //******************************\r
582 //  main program\r
583 //*****************************\r
584 int main(int argc, char **argv)\r
585 {\r
586     int err,i;\r
587     int j;\r
588     int32_t             errCode;\r
589     Pktlib_HeapIfTable*  pPktifTable;\r
590     Pktlib_HeapCfg heapCfg;\r
591     long t1, t2 ;\r
592     cpu_set_t cpu_set;\r
593     int c;\r
594     int statsQueryRequest = 0;\r
595 \r
596 #if 0\r
597     if (initRm())\r
598     {\r
599         printf("main: initRm() returned error\n");\r
600         exit(1);\r
601     }\r
602 #endif\r
603 \r
604 \r
605 #if 1\r
606 \r
607     if (argc == 2)\r
608     {\r
609         printf("main: argument %s\n", argv[1]);\r
610         if(!(strcmp(argv[1], "stats")))\r
611         {\r
612             statsQueryRequest =1;\r
613             printf("querying for stats\n");\r
614         }\r
615     }\r
616     printf("statsQueryReqeust: %d\n", statsQueryRequest);\r
617 \r
618 \r
619 #endif\r
620 \r
621 #if 1\r
622     if (statsQueryRequest)\r
623     {\r
624         navl_wrapper_cfg_info_t *pNavlCfg;\r
625         navl_wrapper_pkt_stat_t *pStats1;\r
626         navl_wrapper_pkt_stat_t *pStats2;\r
627         void* pTemp;\r
628         \r
629         void* pShmBase = hplib_shmOpen();\r
630         if (pShmBase)\r
631         {\r
632             pTemp = hplib_shmGetEntry(pShmBase, APP_ENTRY_1);\r
633             pNavlCfg =  (navl_wrapper_cfg_info_t*)pTemp;\r
634 \r
635             pStats1 = pTemp + sizeof(navl_wrapper_cfg_info_t);\r
636 \r
637         \r
638             pStats2 = pTemp + sizeof(navl_wrapper_cfg_info_t) +\r
639                     (sizeof(navl_wrapper_pkt_stat_t)*pNavlCfg->num_protocols);\r
640 \r
641             printf("main: pStats1: 0x%x pStats2: 0x%x\n", pStats1, pStats2);\r
642         }\r
643         sleep(10);\r
644         exit(1);\r
645     }\r
646 #endif\r
647     printf("***net_test_dpi.. worker threads running on %d cores\n",NUM_FP_PROCS);\r
648 \r
649     signal(SIGINT,netTest_utilMySig);\r
650 \r
651     CPU_ZERO( &cpu_set);\r
652     CPU_SET( 0, &cpu_set);\r
653     hplib_utilSetupThread(HPLIB_THREADID, &cpu_set, hplib_spinLock_Type_LOL);\r
654 \r
655     /* create netapi */\r
656     our_netapi_default_cfg.rmHandle = rmClientServiceHandle;\r
657     netapi_handle = netapi_init(NETAPI_SYS_MASTER,\r
658                                 &our_netapi_default_cfg);\r
659     if (netapi_handle == NULL)\r
660     {\r
661         printf("main: netapi_init failure, exiting\n");\r
662         exit(1);\r
663     }\r
664     netapi_netcpCfgExceptions(netapi_handle,\r
665                               NETCP_CFG_ALL_EXCEPTIONS,\r
666                               NETCP_CFG_ACTION_DISCARD,\r
667                               (NETCP_CFG_ROUTE_HANDLE_T)NULL);\r
668 \r
669     /* open the main heap */\r
670     OurHeap = Pktlib_findHeapByName("netapi");\r
671     if (!OurHeap)\r
672     {\r
673         printf("findheapbyname fail\n");\r
674         exit(1);\r
675     }\r
676 \r
677     //if we want to relay network packets, we create a handle to the \r
678     //default netcp receive queue here\r
679     netcp_rx_chan= netapi_pktioOpen(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb_bridge, &netcp_rx_cfg,  &err);\r
680     if (!netcp_rx_chan)\r
681     {\r
682         printf("pktio open RX failed err=%d\n",err);\r
683         exit(1);\r
684     }\r
685 \r
686     netcp_tx_chan= netapi_pktioOpen(netapi_handle, NETCP_TX, (PKTIO_CB) NULL, &netcp_tx_cfg,  &err);\r
687     if (!netcp_tx_chan)\r
688     {\r
689         printf("pktio open TX failed err=%d\n",err);\r
690         exit(1);\r
691     }\r
692     else  //install a fast path template into the NETCP TX channel\r
693     {\r
694         PKTIO_CONTROL_T control2;\r
695         control2.op = PKTIO_UPDATE_FAST_PATH;\r
696         PKTIO_CFG_T cfg2;\r
697         memset(&cfg2, 0, sizeof(PKTIO_CFG_T));\r
698         cfg2.fast_path_cfg.fp_send_option = PKTIO_FP_NO_CRYPTO_NO_CKSUM_PORT;\r
699         cfg2.fast_path_cfg.txPktInfo= &txPktInfoNoCrypto;\r
700         netapi_pktioControl(netcp_tx_chan, NULL, &cfg2, &control2, &err);\r
701    }\r
702 \r
703 #ifdef VDPI\r
704     navl_setup();\r
705 #endif\r
706     /*********************************************/\r
707     /*****************end NETAPI STARTUP**********/\r
708     /*********************************************/\r
709 \r
710     //now creaate a simple netcp rule\r
711     //to get a lot of packets\r
712     mac0 = netapi_netcpCfgCreateMacInterface(\r
713                       netapi_handle,\r
714                       &all_mac[0],\r
715                       NULL,\r
716                       0,\r
717                       1,\r
718                       (NETCP_CFG_ROUTE_HANDLE_T)  NULL,\r
719                       (NETCP_CFG_VLAN_T ) NULL ,  //future\r
720                       0x0800,\r
721                       1,\r
722                       &err);\r
723     if (err) {printf("addmac0 failed %d\n",err); exit(1); }\r
724     else printf("addmac0 sucess\n");\r
725 \r
726     mac1 = netapi_netcpCfgCreateMacInterface(\r
727                       netapi_handle,\r
728                       &all_mac[0],\r
729                       NULL,\r
730                       1,\r
731                       2,\r
732                       (NETCP_CFG_ROUTE_HANDLE_T)  NULL,\r
733                       (NETCP_CFG_VLAN_T ) NULL ,  //future\r
734                       0x0800,\r
735                       1,\r
736                       &err);\r
737     if (err) {printf("addmac1 failed %d\n",err); exit(1); }\r
738     else printf("addmac1 sucess\n");\r
739 \r
740 #if 0\r
741     ip_rule0=netapi_netcpCfgAddIp(\r
742                       netapi_handle,\r
743                       0,\r
744                       nwal_IPV4,\r
745                       &all_ip,\r
746                       NULL,  //all IP\r
747                       NULL,\r
748                       (NETCP_CFG_ROUTE_HANDLE_T) NULL,\r
749                       (void*)NULL,\r
750                       &err\r
751         );\r
752 \r
753 \r
754     ip_rule1=netapi_netcpCfgAddIp(\r
755                       netapi_handle,\r
756                       1,\r
757                       nwal_IPV4,\r
758                       &all_ip,\r
759                       NULL,  //all IP\r
760                       NULL,\r
761                       (NETCP_CFG_ROUTE_HANDLE_T) NULL,\r
762                       (void*)NULL,\r
763                       &err\r
764         );\r
765 #endif\r
766     if (err) {printf("addip0 failed %d\n",err); exit(1); }\r
767 \r
768 \r
769 \r
770 \r
771     //calibrate idle\r
772     CALIB = calibrate_idle();\r
773 \r
774     //**************************************\r
775     //Create a slow path thread\r
776     //***************************************\r
777     {\r
778     pthread_t *thrs;\r
779     int p;\r
780     char c;\r
781     thrs = malloc( sizeof( pthread_t ) * NUM_PROCS );\r
782     if (thrs == NULL)\r
783     {\r
784         perror( "malloc" );\r
785         return -1;\r
786     }\r
787     printf( "dpi-demo: Starting slow_path_thread on core 0\n");\r
788 \r
789     if (pthread_create( &thrs[0], NULL, (void*)slow_path_thread,\r
790                       (void *)0 ))  //start at core 0\r
791     {\r
792         perror( "pthread_create" );\r
793         exit(1);\r
794     }\r
795 \r
796 \r
797     for (j= 1;j < NUM_PROCS;j++)\r
798     {\r
799         printf( "dpi-demo: Starting fast_path_thread on core 1\n");\r
800         if (pthread_create( &thrs[j], NULL, (void*)fast_path_thread,\r
801                       (void *)j ))  //start at core 1\r
802         {\r
803             perror( "pthread_create" );\r
804             exit(1);\r
805         }\r
806 \r
807     }\r
808     //this thread of execution (main) now just waits on user input\r
809     for(;;)\r
810     {\r
811         printf(">");\r
812         c=getchar();\r
813         if (c=='C')\r
814         {\r
815             CAP=!CAP; \r
816             printf("CAPTURE= %d\n", CAP);\r
817         }\r
818         else if (c=='q') {QUIT=1;break;}\r
819         else if (c=='s')\r
820             our_stats_cb(netapi_handle, &netcp_stats);\r
821 #ifdef VDPI\r
822            else if (c=='c') \r
823             {navl_clear_stats();printf("> Clearing DPI stats\n");}\r
824            else if (c=='v') navl_set_verbose();\r
825            else if (c=='p') \r
826              {DUMP_DPI_CONN = !DUMP_DPI_CONN;printf(">  **DPI CONN DUMP is %s ** \n", DUMP_DPI_CONN ?"enabled":"disabled");}\r
827            else if (c=='d') \r
828              {DPI = !DPI;printf(">  **DPI is %s ** \n", DPI?"enabled":"disabled");}\r
829 #endif\r
830         else if (c=='!') {system("sh");}\r
831 #if 0\r
832         else if (c=='t') {XMIT=!XMIT; printf("XMIT= %d\n", XMIT); }\r
833         else if (c=='p') {PKTGEN=!PKTGEN; printf("PKTGEN= %d @%d bytes\n",PKTGEN,pkt_len);}\r
834         else if (c=='S') {pkt_len+=64; if (pkt_len>1500) pkt_len=64; printf("pkt_len=%d\n",pkt_len);}\r
835         else if (c=='1')\r
836         {\r
837             RESET=1;\r
838         }\r
839         else if (c=='2')\r
840         {\r
841             RESET=(NUM_PROCS>=2) ?2:1;\r
842         }\r
843         else if (c=='3')\r
844         {\r
845             RESET=(NUM_PROCS>=3) ?3: 1;\r
846         }\r
847 #endif\r
848         else if ((c=='h')||(c=='?'))\r
849         {\r
850             printf("> 'q' to quit,  's' for stats,'d' to dump capture\n,> 'h' for help\n ");\r
851         }\r
852 #if 1\r
853         else if (c=='r')\r
854         {\r
855             netTest_utilDumpHeader(&last_header[0], 0,0,0);\r
856             netTest_utilDumpDescr(&last_desc[0], 0);\r
857         }\r
858         else if (c=='b')\r
859         {\r
860            int cc;\r
861             unsigned long long et= hplib_mUtilGetTimestamp();\r
862             for(cc=1;cc<NUM_PROCS+1;cc++)\r
863            printf(">NT_BENCH STATS core%d:    %d received   %d xmitted,  \n %lld idle cycles,  %lld duration ticks  idle=%lld\n pkt rate =%lld stall=%lld\n",\r
864                        cc,\r
865                        pkt_rx[cc],pkt_tx[cc],\r
866                        idle_cycles[cc],\r
867                        (et-start_time[cc]),\r
868                        (et>start_time[cc]) ? (idle_cycles[cc]*100)/(CALIB*(et-start_time[cc])): 0LL,\r
869                        (et>start_time[cc]) ? pkt_rx[cc]/(6LL*(et-start_time[cc])/1180000000LL): 0LL,\r
870                        pkt_stall[cc]\r
871                     );\r
872             }\r
873 #endif\r
874     }\r
875 \r
876 #ifdef VDPI\r
877             navl_done();\r
878 #endif\r
879 \r
880         //wait for completion \r
881         printf("main task now pending on thread completion\n");\r
882         for (i = 0; i < NUM_PROCS; i++)\r
883                 pthread_join( thrs[i], NULL );\r
884 \r
885         free( thrs );\r
886     \r
887     }\r
888 \r
889     /*************************************************\r
890      ************CLEAN UP****************************\r
891      ************************************************/\r
892     //get rid of rule, in the case that we are relaying packets\r
893     //also close our netcp rx channel\r
894     netapi_netcpCfgDelMac(netapi_handle,0,&err);\r
895     netapi_netcpCfgDelMac(netapi_handle,1,&err);\r
896     \r
897     netapi_pktioClose(netcp_rx_chan,&err);\r
898     netapi_pktioClose(netcp_tx_chan,&err);\r
899 \r
900 \r
901     //done\r
902     netapi_shutdown(netapi_handle);\r
903 \r
904 \r
905     //!finished!\r
906 }\r
907 #if 1\r
908 static inline void send_it(Ti_Pkt *tip, int len, int out_port)\r
909 {\r
910   int err=0;\r
911   PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};\r
912   nwalTxPktInfo_t meta_tx2={0};\r
913   int coreid=Osal_nwalGetProcId();\r
914   if (len<60)\r
915   {\r
916      unsigned int templen;\r
917      char * p_pkt;\r
918      len=60;\r
919      Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen\r
920      Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);\r
921   }\r
922   Pktlib_setPacketLen(tip,len);\r
923   meta_tx2.txFlag1 = NWAL_TX_FLAG1_META_DATA_VALID;\r
924   meta_tx2.ploadLen = len ;\r
925   meta_tx2.enetPort=out_port;\r
926   meta2.u.tx_meta=&meta_tx2;\r
927   stats.tx+=1;\r
928   if(coreid<MAX_NUM_CORES)\r
929     pkt_tx[coreid]+=1;\r
930   netapi_pktioSend(netcp_tx_chan,tip,&meta2,&err);\r
931 }\r
932 #endif\r
933 void recv_cb_bridge(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],\r
934                          PKTIO_METADATA_T meta[], int n_pkts,\r
935                          uint64_t ts )\r
936 {\r
937 int i;\r
938 int len;\r
939 int p;\r
940 Ti_Pkt * tip;\r
941 unsigned int appid;\r
942 unsigned int templen;\r
943 char * p_pkt;\r
944 unsigned long t1;\r
945 unsigned long t2;\r
946 unsigned long long ct1;\r
947 unsigned long long ct2;\r
948 unsigned short ip_pl;\r
949 unsigned long long n_c_ops;\r
950 int ifno;\r
951 int out_port;\r
952 \r
953 int coreid=Osal_nwalGetProcId();\r
954 \r
955 \r
956 pasahoLongInfo_t* protoInfo;\r
957 \r
958 t1=netapi_timing_start();\r
959 ct1 =Osal_cache_op_measure(&n_c_ops);\r
960 for(i=0;i<n_pkts;i++)\r
961 {\r
962         \r
963         tip = p_recv[i];\r
964         appid = ((unsigned int)meta[i].u.rx_meta->appId)&0xff000000;\r
965         if (appid == NETAPI_NETCP_MATCH_GENERIC_IP) \r
966         {\r
967            stats.ip+=1;\r
968         }\r
969 \r
970         protoInfo=nwal_mGetProtoInfo(tip);\r
971         ifno = nwal_mGetRxEmacPort( protoInfo);\r
972         if (ifno ==1) out_port=2; else out_port=1;\r
973         if(coreid<MAX_NUM_CORES) stats.core_rx[coreid]+=1;\r
974         if (ifno < MAX_NUM_INTERFACES) stats.if_rx[ifno]+=1;\r
975         Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen\r
976         if (CAP==coreid)\r
977         {\r
978             memcpy((unsigned char *)&last_header[0],p_pkt,32);\r
979             memcpy((unsigned char*)&last_desc[0],tip,64);\r
980         }\r
981         len = Pktlib_getPacketLen(tip)-4;//real length, subtract mac trailer\r
982         stats.rx+=1;\r
983         //printf("recv_cb_bridge: appId: 0x%x, out_port: %d\n", appid, out_port);\r
984         if (appid == NETAPI_NETCP_MATCH_GENERIC_MAC)\r
985         {\r
986 #ifdef VDPI\r
987             {\r
988                 if (DPI)\r
989                     navl_process_pkt(p_pkt, len);\r
990             }\r
991 #endif\r
992         }\r
993 \r
994     \r
995  //printf("recv_cb_bridge: coreId: %d, outPort %d\n", coreid, out_port);\r
996         //Pktlib_freePacket(tip);\r
997         send_it(tip,len+4,out_port);\r
998 }\r
999 t2=netapi_timing_start();\r
1000 ct2 =Osal_cache_op_measure(&n_c_ops);\r
1001 stats.app_cycles +=  (unsigned long long) (t2-t1);\r
1002 stats.tx_cache_cycles += (unsigned long long) (ct2-ct1);\r
1003 return;\r
1004 }\r
1005 \r
1006 #define NTOPOP 150\r
1007 volatile Ti_Pkt * pHd[NTOPOP];\r
1008 \r
1009 #define PKTGEN_PKT_LEN pkt_len\r
1010 #define MAXP 4   //max ports \r
1011 void gen_pkts(int np, int out_port)\r
1012 {\r
1013     int i;\r
1014     int p=0;\r
1015     unsigned long * pI ;\r
1016     Ti_Pkt * tip;\r
1017     int len;\r
1018     unsigned char * pData;\r
1019     int cstall=0;\r
1020     int coreid = Osal_nwalGetProcId();\r
1021     for(i=0;i<np;)\r
1022     {\r
1023         //set out output port\r
1024         if (out_port)\r
1025         {\r
1026             p=out_port;\r
1027         }\r
1028         else //flip flop\r
1029         {\r
1030             p+=1;\r
1031             if(p>MAXP) p=1;\r
1032         }\r
1033         //get a packet\r
1034         tip=Pktlib_allocPacket(OurHeap,PKTGEN_PKT_LEN);\r
1035         pI = (unsigned long *) tip;\r
1036         if (!tip)\r
1037         {\r
1038             pkt_stall[coreid]+=1;\r
1039             cstall+=1;\r
1040             if (cstall >= 100000) \r
1041             {\r
1042                 printf("worker core %d, max stall hit,, exiting.\n",coreid); \r
1043                 return;\r
1044             }\r
1045             continue;\r
1046         }\r
1047         cstall=0;\r
1048         Pktlib_getDataBuffer(tip,&pData,&len);\r
1049         memcpy(pData,&dummy_mac,14);\r
1050         Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, pData,PKTGEN_PKT_LEN);\r
1051         Pktlib_setPacketLen(tip,PKTGEN_PKT_LEN);\r
1052         pI[1]=0x80000000;\r
1053         //pI[2] &= 0xfff0ffff ;move to pktio send function\r
1054 \r
1055         //capture packet just in case\r
1056         if (CAP==coreid)\r
1057         {\r
1058             unsigned int templen;\r
1059             char * p_pkt;\r
1060             Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen\r
1061             memcpy((unsigned char *)&last_header[0],p_pkt,32);\r
1062             memcpy((unsigned char*)&last_desc[0],tip,64);\r
1063         }\r
1064 \r
1065         //send  packet\r
1066         send_it(tip, PKTGEN_PKT_LEN, p);\r
1067         pkt_tx[coreid]+=1;\r
1068         i+=1;\r
1069    }\r
1070 \r
1071     return;\r
1072 }\r