]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/netapi.git/blob - ti/runtime/netapi/test/net_test.c
Makefile-> change name of netapi lib
[keystone-rtos/netapi.git] / ti / runtime / netapi / test / net_test.c
1 /******************************************
2  * File: net_test.c
3  * Purpose: test app for netapi
4  **************************************************************
5  * FILE:  net_test.c
6  * 
7  * DESCRIPTION:  netapi user space transport
8  *               library  test application
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 "stdlib.h"
45 #include "stdio.h"
47 #include "trie.h"
48 #include "string.h"
49 #include "netapi.h"
50 #include "pktio.h"
51 #include <sys/resource.h>
53 /*************debug********************/
54 void dump_descr(unsigned long *p, int n)
55 {
56    printf("--------dump of descriptor %d %x\n", n, (int) p);
57    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]);
58    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]);
59    printf("-----------------------------\n");
60 }
61 /*****************************************/
64 //************for multi pkt burst  xfer test in loopback mode
65 #define TX_BURST 4
66 int pktloopback=TUNE_NETAPI_NWAL_ENABLE_PASS_LOOPBACK;
68 //this device: 10.0.0.100, mac 0x,01,02,03,04,05  and .. 0x6
70 //test packet, setup for loopback (so dest is ourself)
71 static uint8_t testPkt[] = {
73   /* MAC header */
74   0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
75   0x00, 0xe0, 0xa6, 0x66, 0x57, 0x04,
76   0x08, 0x00,
78   /* IP header */
79   0x45, 0x00,
80   0x00, 0x6c,  /* Length (including this header) */
81   0x00, 0x00, 0x00, 0x00, 0x05, 0x11,
82   0x00, 0x00,  /* Header checksum */
83   0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x64,
85   /* UDP header */
86   0x12, 0x34, 0x05, 0x55,
87   0x00, 0x58,  /* Length, including this header */
88   0x00, 0x00,  /* Header checksum */
90  /* Payload */
91   0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
92   0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41,
93   0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
94   0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
95   0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
96   0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61,
97   0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
98   0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
99   0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
100   0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81
102 };
104 #define TEST_PAYLOAD_LEN            80
106 #define TEST_PKT_IP_OFFSET_BYTES        14
107 #define TEST_PKT_UDP_OFFSET_BYTES       34
108 #define TEST_PKT_PLOAD_OFFSET_BYTES     42
109 #define TEST_PKT_UDP_HDR_LEN            8
110 /* Offsets to length fields */
111 #define TEST_PKT_OFFSET_IP_LEN      16
112 #define TEST_PKT_OFFSET_UDP_LEN     38
114 #define TEST_PKT_LEN                122
116 /* The pseudo header checksum of the packet except for the 16 bit length */
117 #define TEST_PKT_PSEUDO_HDR_CHKSUM_SANS_LEN  0x0FFC
121 #if 1
122 //#include "arpa/inet.h"
123 long htonl(long x)
125         long temp = (x&0xff000000)>>24 | (x&0xff0000)>>8 | (x&0xff00)<<8 |  (x&0xff)<<24 ;
126         return temp;
129 /********************************************************************
130  *  FUNCTION PURPOSE: Ones complement addition utility
131  ********************************************************************
132  ********************************************************************/
133 uint16_t test_utilOnesComplementAdd (uint16_t v1, uint16_t v2)
135   uint32_t result;
137   result = (uint32_t)v1 + (uint32_t)v2;
138   result = (result >> 16) + (result & 0xffff);
139   result = (result >> 16) + (result & 0xffff);
141   return ((uint16_t)result);
144 /********************************************************************
145  *  FUNCTION PURPOSE: Ones complement checksum utility
146  ********************************************************************
147  ********************************************************************/
148  uint16_t test_utilOnesCompChkSum (uint8_t *p, uint32_t nwords)
150   uint16_t chksum = 0;
151   uint16_t v;
152   uint32_t i;
153   uint32_t j;
155   for (i = j = 0; i < nwords; i++, j+=2)  {
156     v = (p[j] << 8) | p[j+1];
157     chksum = test_utilOnesComplementAdd (chksum, v);
158   }
159   return (chksum);
160 } /* utilOnesCompChkSum */
162 /**************************************************************************************
163  * FUNCTION PURPOSE: Compute ipv4 psudo checksum
164  **************************************************************************************
165  * DESCRIPTION: Compute ipv4 psudo checksum
166  **************************************************************************************/
167 uint16_t test_utilGetIpv4PsudoChkSum (uint8_t *data, uint16_t payloadLen)
169   uint16_t psudo_chksum;
171   psudo_chksum = test_utilOnesCompChkSum (&data[12], 4);
172   psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, (uint16_t) data[9]);
173   psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, payloadLen);
175   return (psudo_chksum);
177 } /* utilGetIpv4PsudoChkSum */
181 #endif
182 typedef struct stats_t
184         long itx;  //initially generated
185         long rx;
186         long tx;
187         long n_bad;
188         long n_new;
189 } STATS_T;
191 typedef struct head_t
193         long ip[5];
194         long udp[2];
195 } HEAD_T;
197 typedef struct key_t
199   long src_ip;
200   long dst_ip;
201   short src_port;
202   short dst_port;
203 } KEY_T;
205 unsigned char mac0[]={0x00,0x01,0x02,0x03,0x04,0x05}; //interface 0
206 unsigned char mac1[]={0x00,0x01,0x02,0x03,0x04,0x06}; //interface 1
207 nwalIpAddr_t OurIp0={ 10, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
209 #if 1  //goes with real tx (to laptop) 
210 unsigned char real_mac_header[]={0xd4,0xbe,0xd9,0x00,0xd3,0x7e,
211                       0x00,0x01,0x02,0x03,0x04,0x05,
212                       0x08,0x00};
213 unsigned char real_ip_addr[]={0xa,0x00,0x00,0x64,0xa,0x0,0x0,0xa};
214 #endif
216 #if 0  //goes with loopback
217 unsigned char mac_header[]={0x00,0x01,0x02,0x03,0x04,0x05, 
218                       0x00,0x11,0x22,0x33,0x44,0x55,
219                       0x08,0x00};
220 #endif
221 #define NE 65536 
222 HEAD_T *nat;
224 #define NP 5000
225 int n_pkt = NP;
226 STATS_T stats;
228 Trie * P_trie;
229 HEAD_T pkts[NP];
230 #define PERSLOW  10  //% of pkts that will not be fastpath'd 
231 int perslow= PERSLOW;
233 /*******************************************
234  *************NETAPI OBJECTS***************
235  *****************************************/
236 Pktlib_HeapHandle OurHeap;
237 PKTIO_HANDLE_T *our_chan;
238 PKTIO_HANDLE_T *netcp_rx_chan;
239 PKTIO_HANDLE_T *netcp_tx_chan;
240 PKTIO_CFG_T our_chan_cfg={PKTIO_RW, PKTIO_LOCAL, PKTIO_Q_ANY, 8};
241 PKTIO_CFG_T netcp_rx_cfg={PKTIO_R, PKTIO_NA, PKTIO_NA, 8};
242 PKTIO_CFG_T netcp_tx_cfg={PKTIO_W, PKTIO_NA, PKTIO_NA, 8};
244 void house(NETAPI_SCHED_HANDLE_T *s);
245 NETAPI_T netapi_handle;
246 NETAPI_SCHED_HANDLE_T * our_sched;
247 NETAPI_SCHED_CONFIG_T our_sched_cfg={
248   NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 50  //every 50 poll loops
249 };
250 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats);
251 NETAPI_TIMER_GROUP_HANDLE_T ourTimerBlock; 
252 NETAPI_TIMER_T t1;
253 NETAPI_TIMER_T t2;
254 NETAPI_TIMER_T t3;
256 void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
257         int n_fired,     //# timers fired
258         NETAPI_TIMER_LIST_T fired_list,
259         uint64_t currentTime);
261 /*************************END NETAPI OBJECTS***********************/
263 #define START_SRC_IP 0x0a00000a
264 #define DST_IP       0xc0a80001
265 #define NEW_START_SRC_IP 0x9eda000a
266 #define DST_PORT 0x555 
267 #define START_SRC_PORT 0x1234
268 #define NEW_START_SRC_PORT 100
269 void update_header(HEAD_T * p_head, int len)
271    unsigned char *p = (unsigned char *) &p_head->udp[1];
272    len -= (20+14);
273    /* update ip checksum */
274    /* update udp checksum */
275    /* update length */
276    *p= (len&0xff00)>>8;
277    *(p+1) = len&0xff;
280 void gen_pkts(int np)
282 int i;
283 int ip = START_SRC_IP &0xff;
284 int port= START_SRC_PORT;
285 HEAD_T temp={{0x25000200,0xdead0000,0x80110000,START_SRC_IP,DST_IP},
286              {START_SRC_PORT<<16|DST_PORT,0x01ec<<16|0x0000}};
287 /* endian convert header */
288 temp.ip[0]=htonl(temp.ip[0]);
289 temp.ip[1]=htonl(temp.ip[1]);
290 temp.ip[2]=htonl(temp.ip[2]);
291 temp.ip[3]=htonl(temp.ip[3]);
292 temp.ip[4]=htonl(temp.ip[4]);
293 temp.udp[0]=htonl(temp.udp[0]);
294 temp.udp[1]=htonl(temp.udp[1]);
296 for(i=0;(i<np) && (i<NP);i++)
297   {
298        memcpy(&pkts[i],&temp,sizeof(temp));
299        update_header(&pkts[i],512);      /* update checksums etc */
300        /* change template for new pkt */
301        ip+=1;
302        if(ip>254) {(ip=START_SRC_IP&0xff); port+=1; }
303        temp.ip[3] = htonl((START_SRC_IP&0xffffff00)| ip);
304        temp.udp[0] = htonl( (temp.udp[0]&0xffff0000)| port);
305        temp.udp[1] = htonl(temp.udp[1]);
306      
307   }
308   n_pkt=np;
310 void build_table(Trie * p_trie)
312 int i;
313 int sip=NEW_START_SRC_IP&0xff;
314 int sport=NEW_START_SRC_PORT; 
315 HEAD_T temp;
316 KEY_T key;
317 int skip;
318 int nskip=0;
319 for(i=0;(i<n_pkt) && (i<NE);i++)
321    skip = rand()%100;
322    if (skip<perslow) {nskip++;continue;}
323    memcpy(&temp,&pkts[i],sizeof(temp));
324    temp.ip[3]=htonl(((NEW_START_SRC_IP)&(0xffffff00))|(sip));
325    temp.udp[0] = htonl((temp.udp[0]&0xffff)| (sport<<16));
326    memcpy(&nat[i], &temp, sizeof(temp));
328    //insert entry
329    key.src_ip = pkts[i].ip[3];
330    key.dst_ip = pkts[i].ip[4];
331    key.src_port= (pkts[i].udp[0]&0xffff0000)>>16;
332    key.dst_port= (pkts[i].udp[0]&0x0000ffff);
333    trie_insert(p_trie,(char *)&key,sizeof(key), (void *) &nat[i]);
334    /* update */
335   sport+= 1;
336   if (sport > 60000) { sport = NEW_START_SRC_PORT; sip+=1; }
338  //printf("build tab: %d %d\n", n_pkt , nskip);
341 //===========stub transmitter==================
342 void send_pkt(Ti_Pkt *pkt, int len)
344 Pktlib_freePacket((Ti_Pkt*)pkt);
345         return;
349 void slow_path(Ti_Pkt *pkt, int len)
352          {Ti_Pkt * k= Pktlib_getNextPacket(pkt); if(k != 0) {printf(" slowpath, nexpkt != NULL");}}
353 Pktlib_freePacket((Ti_Pkt*)pkt);
354         return;
356 /* check header */
357 int check_header(HEAD_T * p_head)
359  /* check version */
360  /* ip check sum */
361  /* udp check sum */
362  return 1;
365 #define PKT_LEN 1400
366 void test_alloc_free(int n)
368 int i;
369 Ti_Pkt * b;
371 for(i=0;i<n;i++)
373   b=Pktlib_allocPacket(OurHeap,PKT_LEN);
374   Pktlib_freePacket(b);
377 /*-----------test driver: gen an input pkt------- */
378 //char buffer[sizeof(HEAD_T)+PKT_LEN];
379 Ti_Pkt * get_pkt(int n, unsigned int *p_len)
381    int ind;
382    long long temp;
383    Ti_Pkt * b;
384    char * buffer;
385    unsigned int len;
387   if (pktloopback==0)
388   {
389         if (n>=4) return NULL;   //just gen pkts to warm swtich, so that it knows
390                                 //our mac is valid
391   }  
392   b=Pktlib_allocPacket(OurHeap,PKT_LEN);
393   if (!b) 
394     {printf("net_test: get_pkt() heap empty!! %d pkts gen'd %d \n", n); return NULL;};
396    //debug
397    //printf("pkt= %x %x\n", b, Pktlib_getNextPacket(b));
399 #if 0
400 /*temp patch - should move inside nwal **/
402 Cppi_Desc * pHdrDesc = Pktlib_getDescFromPacket(b);
404 /* Initialize the PS for no control info.  */
405 Cppi_setPSLen (Cppi_DescType_HOST, (Cppi_Desc *)pHdrDesc, 0);
407 #endif
409     //debug - way to validate descriptor
410     {Ti_Pkt* k= Pktlib_getNextPacket(b); 
411          if(k != 0) {printf(" genpkt, nexpkt != NULL");}}
414    //get pointer to buffer area of packet
415    Pktlib_getDataBuffer(b,(uint8_t**)&buffer,&len);
417 #if 0 
418 if (pktloopback==0)
420    temp = (long long) rand();
421    temp *= PKT_LEN;
422    temp /= RAND_MAX;
423    temp +=2;
424    *p_len = (int) temp; 
425    *p_len = *p_len &0xfffffffe;
426    temp = (long long) rand();
427    temp *= n_pkt;
428    temp /= RAND_MAX;
429    ind = (int) temp;
430    update_header(&pkts[ind],*p_len);
431    //printf("get pkt:%d %d ind=%d len=%d\n",RAND_MAX, rand(),ind, *p_len);
432     memcpy(&buffer[0], &mac_header[0],14);
433     memcpy(&buffer[14],(char*)&pkts[ind],sizeof(HEAD_T)); 
435 else
436 #endif
438    //copy test packet into buffer
440     memcpy(&buffer[0], &testPkt[0],TEST_PKT_LEN);
441     *p_len = TEST_PKT_LEN;
443     return b; 
447 /******************************************************/
448 /******************PKT RECEIVE HANDLER *************************/
449 /******************************************************/
450 void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
451                          PKTIO_METADATA_T meta[], int n_pkts,
452                          uint64_t ts )
454 int i;
455 int len;
456 int p;
457 HEAD_T * p_res;
458 Ti_Pkt * tip;
459 unsigned int templen;
460 int err;
461 KEY_T key;
462 char * p_pkt;
463 HEAD_T * p_head;
464 HEAD_T temp_head;
466     p_head=&temp_head;
468     //debug
469 #if 0
470     if (n_pkts != TX_BURST) {
471       printf("recv_cb, txsofar=%d rxsofar=%d  np = %d, NOT %d\n", 
472              stats.itx, stats.rx, n_pkts,TX_BURST);
473       our_stats_cb(netapi_handle,NULL);
474     }
475 #endif
476     //test_alloc_free(7);
477     //printf("recv start\n");
479    /* loop over received pkts */
480    for(i=0;i<n_pkts;i++)
481    {
482         tip = p_recv[i];
483         Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
484         len = Pktlib_getPacketLen(tip);//real length
486          //debug: validate descriptor */
487          if(Pktlib_getNextPacket(tip) != 0) {printf(" rcv_cb, nexpkt != NULL");}
488         //debug printf("recv pkt, len=%d %d\n", len, templen);
489         stats.rx+=1;
491 #ifdef DEBUG_DESC
492    if (stats.rx<16){printf(">rx dmp.."); dump_descr((long *) tip, stats.rx);}
493    else if (stats.rx>99) {printf(">rx dmp.."); dump_descr((long *) tip,stats.rx);}
494 #endif
497         /* check header */
498         memcpy(p_head,&p_pkt[14],sizeof(HEAD_T));
499         if (!check_header(p_head)) { 
500                 stats.n_bad+=1;Pktlib_freePacket(tip); continue;
501         }
503         /* lookup flow */
504         key.src_ip = p_head->ip[3];
505         key.dst_ip = p_head->ip[4];
506         key.src_port= (p_head->udp[0]&0xffff0000)>>16;
507         key.dst_port= (p_head->udp[0]&0x0000ffff);
508         p_res= (HEAD_T *) trie_lookup(P_trie, (char *) &key, sizeof(key));
509         if (!p_res) { stats.n_new+=1;  slow_path(tip, len); continue;}
511         /* copy header */
512         memcpy((char *) p_head, (char *) p_res, sizeof(HEAD_T));
514         /* update checksums */
515         //update_header(p_head,len);
516         memcpy(&p_pkt[14],p_head,sizeof(HEAD_T));
517         /* update_mac(&p_pkt[0]);  */
519         /* send pkt */
520         send_pkt(tip,len);
521         stats.tx+=1;
522     }
523     //printf("recv done\n");
526 //timer callback 
527 void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
528         int n_fired,     //# timers fired
529         NETAPI_TIMER_LIST_T fired_list,
530         uint64_t currentTime)
532 int i;
533 NETAPI_TIMER_T tx;
534 int cookie;
535 int err;
536 unsigned long long et;
537 printf("TIMER CALLBACK @ %lld %d timers\n", currentTime, n_fired);
538 tx = netapi_TimerGetFirst(fired_list);
539 for(i=0;i<n_fired;i++)
541   cookie = (int) netapi_TimerGetCookie(tx);
542   et =  netapi_TimerGetTs(tx); //debug
543   printf("   timer %d - cookie = %d expected ts=%lld (delta=%lld)\n", i, cookie, et, currentTime-et);
544   if (cookie ==1)
545      t1 = netapi_TimerGroupStartTimer(
546         th,
547         (void *) 1,
548         100LL,  //every  second
549         &err);
550   else if (cookie ==2)
551       t1 = netapi_TimerGroupStartTimer(
552         th,
553         (void *) 2,
554         200LL,  //every  second
555         &err);
556   else
557   {
558     t3 = netapi_TimerGroupStartTimer(
559         th,
560         (void *) 3,
561         300LL,  //every  second
562         &err);
563     //cancel 1 and restart 1
564    netapi_TimerGroupCancel(th,t1,&err);
565    t1 = netapi_TimerGroupStartTimer(
566         th,
567         (void *) 1,
568         100LL,  //every  second
569         &err);
572  }
575   tx = netapi_TimerGetNext(fired_list,tx); 
580 static int np2process = NP;
581 /******************************************************
582  * stats callback
583  *******************************************************/
584 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats)
586 uint32_t numFreeDataPackets;
587 uint32_t numZeroBufferPackets;
588 uint32_t numPacketsinGarbage;
590 printf("stats @ %lld\n", netapi_getTimestamp());
591 if(pPaStats)
593        printf("C1 number of packets:           %d\n", pPaStats->classify1.nPackets);
594        printf("C1 number IPv4 packets:         %d\n", pPaStats->classify1.nIpv4Packets);
595        printf("C1 number llc/snap fail:        %d\n", pPaStats->classify1.nLlcSnapFail);
596        printf("C1 number table matched:        %d\n", pPaStats->classify1.nTableMatch);
597        printf("C1 number failed table matched: %d\n", pPaStats->classify1.nNoTableMatch);
598        printf ("C1 number of parse fail:        %d\n",pPaStats->classify1.nParseFail);
599        printf("C1 number of command failures:  %d\n", pPaStats->classify1.nCommandFail);
600        printf("C1 number invalid reply dests:  %d\n", pPaStats->classify1.nInvalidComReplyDest);
601        printf ("C1 number of silent discard:    %d\n",pPaStats->classify1.nSilentDiscard);
602        printf("C1 number of invalid control:   %d\n", pPaStats->classify1.nInvalidControl);
603        printf ("C1 number of invalid states:    %d\n",pPaStats->classify1.nInvalidState);
604        printf ("C1 number of system fails:      %d\n\n",pPaStats->classify1.nSystemFail);
606 Pktlib_getHeapStats(OurHeap, &numFreeDataPackets,
607                              &numZeroBufferPackets, &numPacketsinGarbage);
608 printf("heap stats>  #free=%d #zb=%d #garbage=%d\n", numFreeDataPackets,
609                                 numZeroBufferPackets, numPacketsinGarbage);
610 //debug
611 dump_poll_stats();
616 //******************************************************
617 //use scheduling housekeeping callback to generate pkts
618 //******************************************************
619 void house(NETAPI_SCHED_HANDLE_T * s)
621 Ti_Pkt * tip;
622 unsigned int len;
623 nwalTxPktInfo_t meta_tx={0};
624 PKTIO_METADATA_T meta = {PKTIO_META_TX,0};
625 int err;
626 static int house_pkts_gened=0;
627 int p;
628 unsigned char * pIpHdr,* pData;
630 for(p=0;p<TX_BURST;p++) {  
631 //reguest stats 
632 if ((house_pkts_gened>0) && (! (house_pkts_gened%400)) )
634    printf("net_test> request stats at n=%d \n",house_pkts_gened);
635    netcp_cfgReqStats(netapi_handle, our_stats_cb, 0,&err); 
636    if (err!=0) {printf("stats req failed\n");}
640   if (house_pkts_gened >= np2process+ 100)
641   {
642      //shutdown
643      netapi_schedShutdown(s,NULL,&err);
644      continue;
645   }
647   else if (house_pkts_gened >= np2process) { house_pkts_gened+=1;  continue;}
648   
650 /* manufacture a pkt to transmit */
651    tip = get_pkt(house_pkts_gened, &len);
652    if(!tip) { house_pkts_gened +=1; continue; }
654    /* set the pkt length */
655    Pktlib_setPacketLen(tip, len);
657    /* set up meta data */
658     meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM | NWAL_TX_FLAG1_DO_UDP_CHKSUM);
659     meta_tx.startOffset = 0;
660     meta_tx.pktLen = len;
661     meta_tx.ipOffBytes = TEST_PKT_IP_OFFSET_BYTES;
662     meta_tx.l4OffBytes = TEST_PKT_UDP_OFFSET_BYTES;
663     meta_tx.l4HdrLen = TEST_PKT_UDP_HDR_LEN;
664     meta_tx.ploadOffBytes = TEST_PKT_PLOAD_OFFSET_BYTES;
665     meta_tx.ploadLen = TEST_PAYLOAD_LEN;
667     Pktlib_getDataBuffer(tip,&pData,&len);
668     pIpHdr = pData + meta_tx.ipOffBytes;
669     meta_tx.pseudoHdrChecksum =
670         test_utilGetIpv4PsudoChkSum(pIpHdr,(TEST_PAYLOAD_LEN+TEST_PKT_UDP_HDR_LEN));
672    /* post it to netcp tx channel*/
673    meta.u.tx_meta=&meta_tx;
674 #ifdef DEBUG_DESC
675    if (house_pkts_gened<16) dump_descr((long *) tip, house_pkts_gened);
676    else if (house_pkts_gened>99) dump_descr((long *) tip,house_pkts_gened);
677 #endif
678    pktio_send(netcp_tx_chan,tip,&meta,&err);
679    if (err == 0) stats.itx +=1;
681    house_pkts_gened +=1;
682  }
686 /***************************************
687  ********** test driver*****************
688  ***************************************/
689 int main(int argc, char **argv)
691 int err;
692 rlim_t oss,ss = 1024*1024;
693 struct rlimit rl;
695 err= getrlimit(RLIMIT_STACK,&rl);
696 if (!err) printf(" stack limit = %d\n",rl.rlim_cur); else printf("getrlimit failed\n");
697 #if 0
698 rl.rlim_cur = ss;
699 err=setrlimit(RLIMIT_STACK,&rl);
700 if (!err) printf("set stack to %d\n",rl.rlim_cur); else printf("setrlimit failed\n");
701 #endif
703 if (argc>=2)  np2process = atoi(argv[1]);
704 if (np2process<0) np2process = NP; /* default */
705 if (argc==3)  perslow = atoi(argv[2]);
706 if ((perslow<0)||(perslow>100)) perslow=PERSLOW;//default
707 if (argc>3) {printf("net_test  <no of pkts to process> <percent slow path>\n"); exit(1);}
710 //real mode, so update our test packet mac header and ip header
711 if (pktloopback==0)
713 memcpy(&testPkt,&real_mac_header[0],14); //overwrite test pkt mac address
714 memcpy(&testPkt[26],&real_ip_addr[0],8);//overrite test pkt ip addresses
717 /*******************************************/
718 /*************NETAPI STARTUP****************/
719 /*******************************************/
721 /* create netapi */
722 netapi_handle = netapi_init(NETAPI_SYS_MASTER);
724 /* open the main heap */
725 OurHeap = Pktlib_findHeapByName("netapi");
726 if (!OurHeap) {printf("findheapbyname fail\n"); exit(1);}
728 /* create a pktio channel */
729 our_chan=pktio_create(netapi_handle,"our1stq",recv_cb, &our_chan_cfg,&err);
730 if (!our_chan) {printf("pktio create failed err=%d\n",err); exit(1);}
732 /* open netcp default tx, rx queues */
733 netcp_tx_chan= pktio_open(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg,  &err);
734 if (!netcp_tx_chan) {printf("pktio open TX failed err=%d\n",err); exit(1);}
735 netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, recv_cb, &netcp_rx_cfg,  &err);
736 if (!netcp_rx_chan) {printf("pktio open RX failed err=%d\n",err); exit(1);}
739 /* create scheduler instance */
740 our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err);
741 if (!our_sched) {printf("sched create failed\n"); exit(1);}
743 /* add mac intefaces */
744 netcp_cfgCreateMacInterface(
745                   netapi_handle,
746                   &mac0[0],
747                   0,0,
748                   (NETCP_CFG_ROUTE_HANDLE_T)  NULL,
749                   (NETCP_CFG_VLAN_T ) NULL ,  //future
750                   1, 
751                   &err);
752 if (err) {printf("addmac0 failed %d\n",err); exit(1); } 
754 //attach an IP to this interface
755 netcp_addIp(
756                   netapi_handle,
757                   0,
758                   nwal_IPV4,
759                   &OurIp0,
760                   NULL,  //all IP
761                   (NETCP_CFG_ROUTE_HANDLE_T) NULL,
762                   &err
763                   );
764 if (err) {printf("addip0 failed %d\n",err); exit(1); } 
765 #if 1
766 //create a 2nd mac instance
767 netcp_cfgCreateMacInterface(
768                   netapi_handle,
769                   &mac1[0],
770                   1,1,
771                   (NETCP_CFG_ROUTE_HANDLE_T)  NULL,
772                   (NETCP_CFG_VLAN_T ) NULL ,  //future
773                   1,
774                   &err);
775 if (err) {printf("addmac1 failed %d\n",err); exit(1); }
776 #endif
778  ourTimerBlock = netapi_TimerGroupCreate(
779         netapi_handle,
780         "our1sttimer",
781         our_timer_cb,
782         0,    //1 if timers local to thread
783         0,    //1 if expect to cancel
784         netapi_getTicksPerSec()/100,  /* 10 msc resolution for these timers */
785         netapi_getTicksPerSec()/1000, /* would like 1msc tolerence */
786         100,
787         &err);
788 if (err) {printf("timergroupcreate failed %d\n",err); exit(1);}
790 //start a couple of timers 
791 t1 = netapi_TimerGroupStartTimer(
792         ourTimerBlock,
793         (void *) 1,
794         100LL,  //every  second
795         &err);
796 if (err) {printf("timerstart failed %d\n");}
797 t2 = netapi_TimerGroupStartTimer(
798         ourTimerBlock,
799         (void *) 2,
800         200LL,  //every 1.1second
801         &err);
802 if (err) {printf("timerstart failed %d\n");}
803 t3 = netapi_TimerGroupStartTimer(
804         ourTimerBlock,
805         (void *) 3,
806         300LL,  //every 3 seconds
807         &err);
808 if (err) {printf("timerstart failed %d\n");}
811 /*********************************************/
812 /*****************end NETAPI STARTUP**********/
813 /*********************************************/
816 /********************************************
817 * Basic pkt loopback test
818 *********************************************/
821 /* create TRIE */
822 P_trie = trie_new();
823 if (!P_trie) {printf("trie alloc failed\n"); exit(1);}
825 nat = (HEAD_T *) malloc(NE * sizeof(HEAD_T));
826 if (!nat) {printf("malloc of nat table failed\n"); exit(1);}
828 gen_pkts(np2process<NP ? np2process:NP);
830 /* build table */
831 build_table(P_trie);
834 /* processing loop: get pkt, check it, look up in table, copy new header,
835    send packet */
836 srand((unsigned) np2process);
839 /*********************************************/
840 /**************Entry point into scheduler ****/
841 /*********************************************/
842 netapi_schedWaitForEvents(our_sched, &err);
844 /* done */
845 printf("done: itx=%d rx=%d tx=%d bad=%d slow=%d\n",stats.itx, stats.rx, stats.tx, stats.n_bad, stats.n_new);
846 our_stats_cb(netapi_handle, NULL);
848 netapi_shutdown(netapi_handle);