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