]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/netapi.git/blob - ti/runtime/netapi/test/net_test.c
c01a8174ea20ef56ffe687d4f8cdaa521f97d3e3
[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 <stdio.h>
45 #include <stdlib.h>
46 #include <unistd.h>
47 #include <string.h>
50 #include "trie.h"
51 #include "string.h"
52 #include "netapi.h"
53 #include "pktio.h"
54 #include <sys/resource.h>
56 //IPSEC MODE(only choose one rx and one tx)
57 #define IPSEC_MODE_RX_INFLOW
58 #define IPSEC_MODE_TX_INFLOW
59 //#define IPSEC_MODE_RX_SIDEBAND
60 //#define IPSEC_MODE_TX_SIDEBAND
62 //#define TEST_TIMERS
64 /*************debug********************/
65 void dump_descr(unsigned long *p, int n)
66 {
67    printf("--------dump of descriptor %d %x\n", n, (int) p);
68    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]);
69    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]);
70    printf("-----------------------------\n");
71 }
72 void dump_header(unsigned long *p, int n, int a, int r)
73 {
74    printf("--------dump of header %d %x appID=%x flag1=%x\n", n, (int) p,a,r);
75    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]);
76    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]);
77    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]);
78    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]);
79    printf("-----------------------------\n");
80 }
82 /*****************************************/
85 //************for multi pkt burst  xfer test in loopback mode
86 #define TX_BURST 700 
87 int pktloopback=TUNE_NETAPI_NWAL_ENABLE_PASS_LOOPBACK;
88 nwalTxPSCmdInfo_t   flowPSCmdInfo;
90 //this device: 10.0.0.100, mac 0x,01,02,03,04,05  and .. 0x6
92 //test packet, setup for loopback (so dest is ourself)
93 static uint8_t testPkt[] = {
95   /* MAC header */
96   0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
97   0x00, 0xe0, 0xa6, 0x66, 0x57, 0x04,
98   0x08, 0x00,
100   /* IP header */
101   0x45, 0x00,
102   0x00, 0x6c,  /* Length (including this header) */
103   0x00, 0x00, 0x00, 0x00, 0x05, 0x11,
104   0x00, 0x00,  /* Header checksum */
105   0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x64,
107   /* UDP header */
108   0x12, 0x34, 0x05, 0x55,
109   0x00, 0x58,  /* Length, including this header */
110   0x00, 0x00,  /* Header checksum */
112  /* Payload */
113   0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
114   0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41,
115   0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
116   0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
117   0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
118   0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61,
119   0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
120   0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
121   0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
122   0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81
124 };
126 #define TEST_PAYLOAD_LEN            80
128 #define TEST_PKT_IP_OFFSET_BYTES        14
129 #define TEST_PKT_UDP_OFFSET_BYTES       34
130 #define TEST_PKT_PLOAD_OFFSET_BYTES     42
131 #define TEST_PKT_UDP_HDR_LEN            8
132 /* Offsets to length fields */
133 #define TEST_PKT_OFFSET_IP_LEN      16
134 #define TEST_PKT_OFFSET_UDP_LEN     38
136 #define TEST_PKT_LEN                122
138 /* The pseudo header checksum of the packet except for the 16 bit length */
139 #define TEST_PKT_PSEUDO_HDR_CHKSUM_SANS_LEN  0x0FFC
141 void example_fast_poll( PKTIO_HANDLE_T * p_pktio, int max_pkts);
142 void example_fast_pushpop(Pktlib_HeapHandle p_heap, int ntrials);
145 #if 1
146 //#include "arpa/inet.h"
147 long htonl(long x)
149         long temp = (x&0xff000000)>>24 | (x&0xff0000)>>8 | (x&0xff00)<<8 |  (x&0xff)<<24 ;
150         return temp;
153 /********************************************************************
154  *  FUNCTION PURPOSE: Ones complement addition utility
155  ********************************************************************
156  ********************************************************************/
157 uint16_t test_utilOnesComplementAdd (uint16_t v1, uint16_t v2)
159   uint32_t result;
161   result = (uint32_t)v1 + (uint32_t)v2;
162   result = (result >> 16) + (result & 0xffff);
163   result = (result >> 16) + (result & 0xffff);
165   return ((uint16_t)result);
168 /********************************************************************
169  *  FUNCTION PURPOSE: Ones complement checksum utility
170  ********************************************************************
171  ********************************************************************/
172  uint16_t test_utilOnesCompChkSum (uint8_t *p, uint32_t nwords)
174   uint16_t chksum = 0;
175   uint16_t v;
176   uint32_t i;
177   uint32_t j;
179   for (i = j = 0; i < nwords; i++, j+=2)  {
180     v = (p[j] << 8) | p[j+1];
181     chksum = test_utilOnesComplementAdd (chksum, v);
182   }
183   return (chksum);
184 } /* utilOnesCompChkSum */
186 /**************************************************************************************
187  * FUNCTION PURPOSE: Compute ipv4 psudo checksum
188  **************************************************************************************
189  * DESCRIPTION: Compute ipv4 psudo checksum
190  **************************************************************************************/
191 uint16_t test_utilGetIpv4PsudoChkSum (uint8_t *data, uint16_t payloadLen)
193   uint16_t psudo_chksum;
195   psudo_chksum = test_utilOnesCompChkSum (&data[12], 4);
196   psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, (uint16_t) data[9]);
197   psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, payloadLen);
199   return (psudo_chksum);
201 } /* utilGetIpv4PsudoChkSum */
205 #endif
206 typedef struct stats_t
208         long itx;  //initially generated
209         long itx2;
210         long rx;
211         long tx;
212         long n_bad;
213         long n_new;
214         long n_class0_rx;   //count of pkts classified 
215         long n_class1_rx;   //count of pkts classified 
216         long n_class2_rx;   //count of pkts classified 
217         long n_t1;
218         long n_t2;
219         long n_t3;
220         long sec_tx;
221         long sec_rx;
222         long sb_tx;
223         long sb_rx;
224         long secp_rx;
225         long n_auth_ok;
226 } STATS_T;
228 typedef struct head_t
230         long ip[5];
231         long udp[2];
232 } HEAD_T;
234 typedef struct key_t
236   long src_ip;
237   long dst_ip;
238   short src_port;
239   short dst_port;
240 } KEY_T;
242 unsigned char mac0[]={0x00,0x01,0x02,0x03,0x04,0x05}; //interface 0
243 unsigned char mac1[]={0x00,0x01,0x02,0x03,0x04,0x06}; //interface 1
244 nwalIpAddr_t OurIp0={ 10, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
245 nwalIpAddr_t OurIp1={ 10, 0, 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
246 nwalIpAddr_t OurIp2={ 10, 0, 2, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
247 nwalIpAddr_t OurIp4IPSEC={ 192,168 , 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
248 nwalIpAddr_t TheirIp4IPSEC={ 192,168 , 1, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
251 #if 1  //goes with real tx (to laptop) 
252 unsigned char real_mac_header[]={0xd4,0xbe,0xd9,0x00,0xd3,0x7e,
253                       0x00,0x01,0x02,0x03,0x04,0x05,
254                       0x08,0x00};
255 unsigned char real_ip_addr[]={0xa,0x00,0x00,0x64,0xa,0x0,0x0,0xa};
256 #endif
258 #if 0  //goes with loopback
259 unsigned char mac_header[]={0x00,0x01,0x02,0x03,0x04,0x05, 
260                       0x00,0x11,0x22,0x33,0x44,0x55,
261                       0x08,0x00};
262 #endif
263 #define NE 65536 
264 HEAD_T *nat;
266 #define NP 5000
267 int n_pkt = NP;
268 STATS_T stats;
270 Trie * P_trie;
271 HEAD_T pkts[NP];
272 #define PERSLOW  10  //% of pkts that will not be fastpath'd 
273 int perslow= PERSLOW;
275 /*******************************************
276  *************NETAPI OBJECTS***************
277  *****************************************/
278 static NETAPI_CFG_T our_netapi_default_cfg=
280 TUNE_NETAPI_PERM_MEM_SZ,
281 128,  //start of packet offset for hw to place data on rx for default flow
282 TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
283 TUNE_NETAPI_NUM_GLOBAL_DESC,        //total we will use
284 TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap
285 64, //#descriptors w/o buffers in default heap
286 TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128,  //size of buffers in default heap
287 128   ,  //tail room
288 256      //extra room 
289 };
291 Pktlib_HeapHandle OurHeap;
292 Pktlib_HeapHandle specialSmall;
293 Pktlib_HeapHandle specialLarge;
295 PKTIO_HANDLE_T *our_chan;
296 PKTIO_HANDLE_T *netcp_rx_chan;
297 PKTIO_HANDLE_T *netcp_rx_chan2;
298 PKTIO_HANDLE_T *netcp_tx_chan;
299 PKTIO_HANDLE_T *netcp_sb_tx_chan;
300 PKTIO_HANDLE_T *netcp_sb_rx_chan;
301 PKTIO_CFG_T our_chan_cfg={PKTIO_RW, PKTIO_LOCAL, PKTIO_Q_ANY, 8};
302 PKTIO_CFG_T netcp_rx_cfg={PKTIO_R, PKTIO_NA, PKTIO_NA, 8};
303 PKTIO_CFG_T netcp_rx_cfg2={PKTIO_R, (PKTIO_GLOBAL|PKTIO_PKT), PKTIO_Q_ANY, 8};
304 PKTIO_CFG_T netcp_tx_cfg={PKTIO_W, PKTIO_NA, PKTIO_NA, 8};
305 PKTIO_CFG_T netcp_sb_rx_cfg={PKTIO_R, PKTIO_NA, PKTIO_NA, 8};
306 PKTIO_CFG_T netcp_sb_tx_cfg={PKTIO_W, PKTIO_NA, PKTIO_NA, 8};
308 void house(NETAPI_SCHED_HANDLE_T *s);
309 NETAPI_T netapi_handle;
310 NETAPI_SCHED_HANDLE_T * our_sched;
311 NETAPI_SCHED_CONFIG_T our_sched_cfg={
312   NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 50000  //every 5000 poll loops
313 };
314 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats);
315 NETAPI_TIMER_GROUP_HANDLE_T ourTimerBlock; 
316 NETAPI_TIMER_T t1;
317 NETAPI_TIMER_T t2;
318 NETAPI_TIMER_T t3;
320 void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
321         int n_fired,     //# timers fired
322         NETAPI_TIMER_LIST_T fired_list,
323         uint64_t currentTime);
325 NETCP_CFG_IP_T ip_rule0;
326 NETCP_CFG_IP_T ip_rule1;
327 NETCP_CFG_CLASS_T class_0;
328 NETCP_CFG_CLASS_T class_1;
329 NETCP_CFG_CLASS_T class_2;
330 NETCP_CFG_FLOW_HANDLE_T specialFlow;
332 NETCP_CFG_CLASSIFIER_T class_0_cfg=
334    NETCP_CFG_CLASS_TYPE_L4,
335    {
336         {0,0, NWAL_APP_PLOAD_PROTO_UDP, {2500}}
337    }
338 };
340 NETCP_CFG_CLASSIFIER_T class_1_cfg=
342    NETCP_CFG_CLASS_TYPE_L4,
343    {
344         {0,0, NWAL_APP_PLOAD_PROTO_UDP, {2502}}
345    }
346 };
348 NETCP_CFG_ROUTE_T  class2_route=
350 NULL, NULL  //* to be filled in
351 };
352 NETCP_CFG_CLASSIFIER_T class_2_cfg=  
354    NETCP_CFG_CLASS_TYPE_L3_L4,
355    {
356         {0,  4 ,0/*fill in below*/ , NULL, NULL,          //L2/L3
357            NWAL_APP_PLOAD_PROTO_UDP, {2504}}   //L4
358    }
359 };
361 PKTIO_CONTROL_T zap_channel_control={PKTIO_CLEAR, NULL};
363 /* security objects. (for loopback mode) */
364 NETCP_CFG_SA_T rx_tunnel;
365 NETCP_CFG_SA_T tx_tunnel;
366 NETCP_CFG_IPSEC_POLICY_T rx_policy;
367 void * rx_data_mode_handle;
368 void * tx_data_mode_handle;
369 void * rx_inflow_mode_handle;
370 void * tx_inflow_mode_handle;
371 /* rx */
372 NETAPI_SEC_SA_INFO_T rx_sa=
374         NWAL_SA_DIR_INBOUND,
375         0x44444444,  //spi
376         nwal_IpSecProtoESP, //ESP mode
377         nwal_SA_MODE_TUNNEL,  //tunnel mode
378         nwal_IPV4, //v4
379         { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (them) -> set below */
380         { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (us)-> set below*/
381         64,/* replayWindow */
382         NWAL_SA_AALG_HMAC_SHA1,
383         NWAL_SA_EALG_AES_CBC,
384         0,0  //na
385 };
387 /*tx */
388 NETAPI_SEC_SA_INFO_T tx_sa=
390        NWAL_SA_DIR_OUTBOUND,
391         0x44444444,  //spi
392         nwal_IpSecProtoESP, //ESP mode
393         nwal_SA_MODE_TUNNEL,  //tunnel mode
394         nwal_IPV4, //v4
395         { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (us) -> set below */
396         { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (them) -> set below*/
397         64, /* NA replayWindow */
398         NWAL_SA_AALG_HMAC_SHA1,
399         NWAL_SA_EALG_AES_CBC,
400         0,0  //seq no
401 };
403 //since we are doing loopback, the rx key params = tx key params
404 static nwalSecKeyParams_t ourTXKeyParams =
406     16, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_DES_CBC and 0 bytes Salt*/
407     20, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_MD5 */
408     NULL, //set below
409     NULL, //set below
410 };
412 static nwalSecKeyParams_t ourRXKeyParams ={
413     16, /* encKeySize: 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_DES_CBC and 0 bytes Salt*/
414     20, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_MD5 */
415     NULL, //set below
416     NULL, //set below
417 };
419 //keys
420 static uint8_t ourAuthKey[36] =
421         {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
422          0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
423          0x20, 0x21, 0x22, 0x23 };
424 static uint8_t ourEncrKey[36] =
425         {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
426          0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
427          0x30, 0x31, 0x32, 0x33 };
430 /*************************END NETAPI OBJECTS***********************/
432 #define START_SRC_IP 0x0a00000a
433 #define DST_IP       0xc0a80001
434 #define NEW_START_SRC_IP 0x9eda000a
435 #define DST_PORT 0x555 
436 #define START_SRC_PORT 0x1234
437 #define NEW_START_SRC_PORT 100
438 void update_header(HEAD_T * p_head, int len)
440    unsigned char *p = (unsigned char *) &p_head->udp[1];
441    len -= (20+14);
442    /* update ip checksum */
443    /* update udp checksum */
444    /* update length */
445    *p= (len&0xff00)>>8;
446    *(p+1) = len&0xff;
449 #if 0
450 void gen_pkts(int np)
452 int i;
453 int ip = START_SRC_IP &0xff;
454 int port= START_SRC_PORT;
455 //HEAD_T temp={{0x25000200,0xdead0000,0x80110000,START_SRC_IP,DST_IP},
456 //             {START_SRC_PORT<<16|DST_PORT,0x01ec<<16|0x0000}};
457 HEAD_T temp;
458 memcpy(&temp,&testPkt[0],sizeof(HEAD_T));
460 for(i=0;(i<np) && (i<NP);i++)
461   {
462        memcpy(&pkts[i],&temp,sizeof(temp));
463        update_header(&pkts[i],512);      /* update checksums etc */
464        /* change template for new pkt */
465        ip+=1;
466        if(ip>254) {(ip=START_SRC_IP&0xff); port+=1; }
467        temp.ip[3] = htonl((START_SRC_IP&0xffffff00)| ip);
468        temp.udp[0] = htonl( (temp.udp[0]&0xffff0000)| port);
469        temp.udp[1] = htonl(temp.udp[1]);
470      
471   }
472   n_pkt=np;
474 #endif
476 void build_table(Trie * p_trie)
478 int i;
479 int sport=NEW_START_SRC_PORT; 
480 HEAD_T temp,temp2;
481 KEY_T key;
483 memcpy(&temp,&testPkt[14],sizeof(temp));
485  //insert entry into trie
486 key.src_ip = temp.ip[3];
487 key.dst_ip = temp.ip[4];
488 key.src_port= (temp.udp[0]&0xffff0000)>>16;
489 key.dst_port= (temp.udp[0]&0x0000ffff);
490 trie_insert(p_trie,(char *)&key,sizeof(key), (void *) &nat[0]); //asociate with nat entry 0
492 //build nat table
493 for(i=0;i<100;i++)
495    memcpy(&temp2,&testPkt[14],sizeof(temp));
496    temp2.udp[0] = (temp2.udp[0] & 0xffff0000) |  sport;
497    memcpy(&nat[i], &temp2, sizeof(temp2));
498    sport+= 1;
502 //===========stub transmitter==================
503 void send_pkt(Ti_Pkt *pkt, int len)
505 //just free pkt.  Don't send
506 Pktlib_freePacket((Ti_Pkt*)pkt);
507         return;
510 //==========stub slow path============
511 void slow_path(Ti_Pkt *pkt, int len)
513 // debug: check descriptor for validity by verifying that desciptor link field is null as expected\n");
514          {Ti_Pkt * k= Pktlib_getNextPacket(pkt); if(k != 0) {printf(" slowpath, nexpkt != NULL");}}
515 //just free pkt
516 Pktlib_freePacket((Ti_Pkt*)pkt);
517         return;
519 /* check header */
520 struct LastPktInfo
522 int iface;
523 int ipcsum;
524 int l4csum;
525 } ;
526 static struct LastPktInfo lpInfo;
528 int check_header(HEAD_T * p_head, PKTIO_METADATA_T * p_meta)
530 if (NWAL_RX_FLAG1_META_DATA_VALID & p_meta->u.rx_meta->rxFlag1)
532 lpInfo.iface = ((unsigned int)p_meta->u.rx_meta->appId) &0xff; //last byte is interface num
533 lpInfo.ipcsum =(p_meta->u.rx_meta->rxFlag1 & NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_MASK )== NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_ACK ? 1 : 0;
534 lpInfo.l4csum = (p_meta->u.rx_meta->rxFlag1 & NWAL_RX_FLAG1_L4_CHKSUM_VERIFY_MASK )== ((NWAL_RX_FLAG1_L4_CHKSUM_VERIFY_ACK) << NWAL_RX_FLAG1_L4_CHKSUM_VERIFY_SHIFT) ? 1 : 0; 
535 if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_IPSEC)
537    stats.sec_rx++;
539 if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_IPSEC_POLICY)
541    stats.secp_rx++;
544 if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_CLASS)
546   int c= ((unsigned int)p_meta->u.rx_meta->appId >>8)&0xffff;
547   if (c==0)  stats.n_class0_rx +=1;
548   else if (c==1) stats.n_class1_rx +=1;
549   else if (c==2) stats.n_class2_rx +=1;
550   else printf("**NET_TEST RX -unknown class: %x\n",  p_meta->u.rx_meta->appId);
554  return 1;
557 #define PKT_LEN 1400
558 void test_alloc_free(int n)
560 int i;
561 Ti_Pkt * b;
563 for(i=0;i<n;i++)
565   b=Pktlib_allocPacket(OurHeap,PKT_LEN);
566   Pktlib_freePacket(b);
570 //measurement test points
571 unsigned int vv1;
572 unsigned int vv2;
573 unsigned int vv3;
574 unsigned int vv4;
575 unsigned int vv5;
576 unsigned int vv6;
577 //these are updated by pktio.
578 #ifdef PKTIO_GET_BENCHMARK
579 extern unsigned int vv7p;
580 extern unsigned int vv8p;
581 extern unsigned int vv9p;
582 extern unsigned int vv10p;
583 extern unsigned int vv11p;
584 extern unsigned int vv12p;
586 extern unsigned int vv13p;  //rcv path
587 extern unsigned int vv14p;
588 extern unsigned int vv15p;
589 #endif
591 unsigned int vv11;
593 extern unsigned int nwal_prof1,nwal_prof2,nwal_prof3,nwal_prof4,nwal_prof5,nwal_prof6;
595 //#define REASSEMBLE_BENCH
596 #ifdef REASSEMBLE_BENCH
597 #include <ti/drv/pa/example/reassemLib/reassemLib.h>
598 /*--------------reassembly benchmark--------------------------------*/
599 void our_reassemble_bench(int nfrags)
601 paIPReassemblyConfig_t Config={5,128,10000 };
602 int i,j;
603 int len;
604 Ti_Pkt tip;
605 char *buffer;
606 unsigned long v1;
607 unsigned long v2;
608 unsigned long sum1=0;
609 unsigned long sum2=0;
610 paEx_reassemLibInit(&Config);
611 for(j=0;j<200/nfrags;j++)
613   for(i=0;i<nfrags;i++)
614   {
615     short temp;
616     tip=Pktlib_allocPacket(OurHeap,PKT_LEN);
617     Pktlib_getDataBuffer(tip,(uint8_t**)&buffer,&len);
618     memcpy(&buffer[0],&testPkt[14],20); //IP header
619     if (i < (nfrags-1)) buffer[6] = 0x20;
620     temp = i*40; 
621     buffer[6]|= (temp&0x1f00)>>8;
622     buffer[7]= (temp&0xff);
623     temp = 20+40*8; 
624     buffer[2]= (temp&0xff00)>>8;
625     buffer[3]= (temp&0xff);
626     Pktlib_setPacketLen(tip, temp);
627     v1= netapi_timing_stop();
628     paEx_reassemLibProc(tip, 0xffff);
629     v2= netapi_timing_stop();
630     sum1+= v2-v1;
631   }
632   sum2 += v2-v1;
634 printf("reasssembly test:  %d trials, %d frags/pkt  %d cycles/frag %d cycles/last frag\n",j,nfrags, sum1/(j*nfrags), sum2/(j));
636 #endif
638 /*--------------basic pktio send/recv benchmark----------------------*/
639 unsigned int timings[10];
640 void our_pktio_bench(int ntrials)
642 int i;
643 #define NBATCH 8
644 Ti_Pkt tip;
645 unsigned char * pData;
646 int len;
647 int n;
648 int err;
649 int sum =0;
651    Osal_cache_op_measure_reset();
652    for(i=0;i<10;i++) timings[i]=0;
653    printf("calibration loop .. ");
654    for(i=0;i<1000;i++)
655    {
656    vv1= netapi_timing_stop();
657    vv2= netapi_timing_stop();
658    sum+=(vv2-vv1);
659    }
660    printf(" accuracy = +- %d cycles\n", sum/1000);
661    sleep(1);
662   
663 PKTIO_METADATA_T meta[10]={0};
664 //send single, recv single
665 for(i=0;i<ntrials;i++)
667    vv1= netapi_timing_stop();
668    tip=Pktlib_allocPacket(OurHeap,PKT_LEN);
669    vv2= netapi_timing_stop();
670    Pktlib_getDataBuffer(tip,&pData,&len);
671    vv3= netapi_timing_stop();
672    pktio_send(our_chan,tip,&meta[0],&err);
673    vv4= netapi_timing_stop();
674    n=pktio_poll(our_chan,NULL , &err);
675    vv5=   netapi_timing_stop();
676    timings[0]+=(vv6-vv4);
677    timings[1]+=(vv5-vv4);
678    timings[3]+=(vv4-vv3); 
679    timings[5]+=(vv3-vv1);
680    timings[8]+=(vv11-vv6);
682 #ifdef PKTIO_GET_BENCHMARK
683    timings[2]+=(vv7p-vv4);
684    timings[4]+=(vv8p-vv3);
685    timings[6]+=(vv9p-vv8p);
686    timings[7]+=(vv10p-vv7p);
687 #endif
690 #ifdef PKTIO_GET_BENCHMARK
691    printf("pktio bench. rx=%d (wcb%d) (toqm%d) tx=%d (toqm%d) alloc=%d qpush=%d qpop=%d free=%d\n", timings[0]/ntrials,
692            timings[1]/ntrials, timings[2]/ntrials,timings[3]/ntrials, timings[4]/ntrials,timings[5]/ntrials,
693            timings[6]/ntrials,timings[7]/ntrials, timings[8]/ntrials );
694    {
695        unsigned int ccycles;
696        int n_c_ops;
697        ccycles =Osal_cache_op_measure(&n_c_ops);
698        printf("n_c_ops=%d cache_op_time=%d (total) = %d (pp)\n", n_c_ops, ccycles,  n_c_ops? (ccycles/(n_c_ops)) : 0);
699    }
700 #endif
703 /*-----------test driver: gen an input pkt------- */
704 //char buffer[sizeof(HEAD_T)+PKT_LEN];
705 Ti_Pkt * get_pkt(int n, unsigned int *p_len)
707    int ind;
708    long long temp;
709    Ti_Pkt * b;
710    char * buffer;
711    unsigned int len;
713   if (pktloopback==0)
714   {
715         if (n>=TX_BURST) return NULL;   //just gen pkts to warm swtich, so that it knows
716                                 //our mac is valid
717   }  
718   b=Pktlib_allocPacket(OurHeap,PKT_LEN);
719   if (!b) 
720     {printf("net_test: get_pkt() heap empty!! %d pkts gen'd %d \n", n); return NULL;};
722     //debug - way to validate descriptor
723     {Ti_Pkt* k= Pktlib_getNextPacket(b); 
724          if(k != 0) {printf(" genpkt, nexpkt != NULL");}}
727    //get pointer to buffer area of packet
728    Pktlib_getDataBuffer(b,(uint8_t**)&buffer,&len);
729    if (!buffer) 
730     {printf("net_test: get_pkt() heap returned empty buffer %d \n", n); return NULL;};
732 #if 0 
733 if (pktloopback==0)
735    temp = (long long) rand();
736    temp *= PKT_LEN;
737    temp /= RAND_MAX;
738    temp +=2;
739    *p_len = (int) temp; 
740    *p_len = *p_len &0xfffffffe;
741    temp = (long long) rand();
742    temp *= n_pkt;
743    temp /= RAND_MAX;
744    ind = (int) temp;
745    update_header(&pkts[ind],*p_len);
746    //printf("get pkt:%d %d ind=%d len=%d\n",RAND_MAX, rand(),ind, *p_len);
747     memcpy(&buffer[0], &mac_header[0],14);
748     memcpy(&buffer[14],(char*)&pkts[ind],sizeof(HEAD_T)); 
750 else
751 #endif
753    //copy test packet into buffer
755     memcpy(&buffer[0], &testPkt[0],TEST_PKT_LEN);
756     *p_len = TEST_PKT_LEN;
758     return b; 
762 /*--------------------------------------------------------------
763  *----------utility to flip a packet and send 
764  *--------------------back to source----------------------------
765  *                   flag=1 => ipsec
766  *--------------------------------------------------------------*/
767 void flip_and_send_pkt(Ti_Pkt *tip,  unsigned char * p_pkt, int len, int flag)
769 unsigned char mac_temp[6];
770 unsigned char ip_temp[4];
771 unsigned char new_dest_port[2]={0x75,0x30};  // 30000
772 uint16_t blah; 
773 //mac
774 memcpy(&mac_temp,&p_pkt[0],6);
775 memcpy(&p_pkt[0],&p_pkt[6],6);
776 memcpy(&p_pkt[6],&mac_temp,6);
777 //memcpy(&p_pkt[0],real_mac_header,6); //for testing to wireshark pc
779 //ip  (outer in case of ipsec)
780 memcpy(&ip_temp, &p_pkt[14+12],4);
781 memcpy(&p_pkt[14+12],&p_pkt[14+12+4],4);
782 memcpy(&p_pkt[14+12+4],&ip_temp,4);
784 //outer checksum to 0
785 if (!flag) memset(&p_pkt[14+10],0,2);
787 //inner ip &udp for ipsec
788 if (flag) 
790     //just drop non-udp packet
791     if (p_pkt[14+20+8+16+9]!=0x11)
792     {
793         stats.n_new+=1;Pktlib_freePacket(tip); return;
794     }
796 //spi
797 //memset(&p_pkt[14+20],0x88,4); 
798 //inner ip
799 memcpy(&ip_temp, &p_pkt[14+20+8+16+12],4);
800 memcpy(&p_pkt[14+20+8+16+12],&p_pkt[14+20+8+16+12+4],4);
801 memcpy(&p_pkt[14+20+8+16+12+4],&ip_temp,4);
803 //udp
804 memcpy(&p_pkt[14+20+8+16+20+2],&new_dest_port[0],2);
805 memset(&p_pkt[14+20+8+16+20+6],0,2); //checksum
807 #ifdef IPSEC_MODE_TX_SIDEBAND
809 //inner ip checksum : leave alone
810 #if 0
811 blah=test_utilOnesCompChkSum (&p_pkt[14+20+8+16], 10);
812 p_pkt[14+20+8+16+10]= (blah&0xff00)>>8;
813 p_pkt[14+20+8+16+11]= blah&0xff;
814 #endif
816 //tbd udp checksum (leave at 0)
818 //outer ip, set to 0 (we will compute on way out
819 memset(&p_pkt[14+10],0,2);
821 #else //inflow, don't touch outer , clear inner 
822 memset(&p_pkt[14+20+8+16+10],0,2); //inner checksum, we will compute on way out
823 //outer ip checksum : leave alone
824 #if 0
825 blah = test_utilOnesCompChkSum (&p_pkt[14], 10);
826 p_pkt[14+10]= (blah&0xff00)>>8;
827 p_pkt[14+11]= blah&0xff;
828 #endif
829 #endif
831 else
833 memset(&p_pkt[14+20+6],0,2);//0 udp checksum (we will compute on way out
834 memcpy(&p_pkt[14+20+2],&new_dest_port[0],2);
837 //IPSEC case, 
838 if (flag)
840 #ifdef IPSEC_MODE_TX_SIDEBAND
841  //send to crypto for encryption
842 //12 byte auth tag
843         {
844            PKTIO_METADATA_T meta = {PKTIO_META_SB_TX,{0},0};
845            int err;
846            nwalDmTxPayloadInfo_t meta_tx={0};
847            meta.sa_handle=tx_data_mode_handle;  //use TX SA context
848            meta_tx.ploadLen = len;
849            meta_tx.encOffset = 14+20+8+16 ;
850            meta_tx.authOffset =14+20 ;
851            meta_tx.encSize=len - 14- 20-8-16-12;
852            meta_tx.authSize= len -14-20-12;
853            meta_tx.encIvSize=16;
854            meta_tx.pEncIV= &p_pkt[14+20+8];  //just use same IV..
855            meta_tx.authIvSize=0;
856            meta_tx.pAuthIV=NULL;
857            meta_tx.aadSize=0;
858            meta_tx.pAad=NULL;
859            /* post it to netcp sb tx channel*/
860            meta.u.tx_sb_meta=&meta_tx;
861            pktio_send(netcp_sb_tx_chan,tip,&meta,&err);
862        }
864 #else
865  {
866   //inflow tx
867   //send pkt directly, asking for IP and UDP checksum offloads AND IPSEC to be applied
868            PKTIO_METADATA_T meta = {PKTIO_META_TX,{0},0};
869            int err;
870            nwalTxPktInfo_t meta_tx={0};
871            meta.sa_handle=tx_inflow_mode_handle; //this tells netapi that inflow crypto needs to be applied
872            meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM|NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_DO_IPSEC_CRYPTO| NWAL_TX_FLAG1_META_DATA_VALID );
873            meta_tx.saOffBytes=14+20;  
874            meta_tx.saPayloadLen=len-14-20;   //don't include tag, mac and outer header
875            meta_tx.startOffset = 0;
876            meta_tx.ipOffBytes = 14+20+8+16;   //to inner header
877            meta_tx.l4OffBytes = 14+20+8+16+20; //to L4 
878            meta_tx.l4HdrLen = 8;
879            meta_tx.ploadLen = (unsigned) ((p_pkt[14+20+8+16+20+4]<<8)|p_pkt[14+20+8+16+20+4+1]) -8 ;
880            meta_tx.pseudoHdrChecksum =
881              test_utilGetIpv4PsudoChkSum(&p_pkt[14+20+8+16],8+ meta_tx.ploadLen);
883            /* post it to netcp tx channel*/
884            meta.u.tx_meta=&meta_tx;
885            pktio_send(netcp_tx_chan,tip,&meta,&err);
886            stats.tx +=1;
887            stats.sec_tx +=1;
888      }
889 #endif
893 else  //non ipsec send pkt directly, asking for IP and UDP checksum ofload
895            PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
896            int err;
897            nwalTxPktInfo_t meta_tx2={0};
898            meta2.sa_handle=nwal_HANDLE_INVALID;
899            meta_tx2.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM|NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID );
900            meta_tx2.startOffset = 0;
901            meta_tx2.ipOffBytes = 14;
902            meta_tx2.l4OffBytes = 14+20;
903            meta_tx2.l4HdrLen = 8;
904            meta_tx2.ploadLen = (unsigned) ((p_pkt[14+20+4]<<8)|p_pkt[14+20+4+1]) -8 ;
905            meta_tx2.pseudoHdrChecksum =
906              test_utilGetIpv4PsudoChkSum(&p_pkt[14],8+ meta_tx2.ploadLen);
908            /* post it to netcp tx channel*/
909            meta2.u.tx_meta=&meta_tx2;
910            pktio_send(netcp_tx_chan,tip,&meta2,&err);
911            stats.tx +=1;
918 /***************************************
919  benchmark receive handler
920 ****************************************/
921 void recv_cb_bench(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
922                          PKTIO_METADATA_T meta[], int n_pkts,
923                          uint64_t ts )
925    int i;
926    vv6=   netapi_timing_stop();
927    for (i=0;i<n_pkts; i++) 
928    {
929      Pktlib_freePacket(p_recv[i]);
930    }
931    vv11 = netapi_timing_stop();
934 /****************************************************************************************/
935 /******************SB Accelerator Callback PKT RECEIVE HANDLER *************************/
936 /******************  Handles Decrypt and Encrypt operation callbacks ******************/
937 /******************************************************************************************/
938 void recv_sb_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
939                          PKTIO_METADATA_T meta[], int n_pkts,
940                          uint64_t ts )
942 int i;
943 int len;
944 int p;
945 HEAD_T * p_res;
946 Ti_Pkt * tip;
947 unsigned int templen;
948 int err;
949 KEY_T key;
950 char * p_pkt;
951 HEAD_T * p_head;
952 HEAD_T temp_head;
953 int tag_cmp=0;
954 unsigned int hash[3];
956  /* loop over received pkts */
957    for(i=0;i<n_pkts;i++)
958    {
959         tip = p_recv[i];
960         Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
961         len = Pktlib_getPacketLen(tip);//real length
963         //is this a decrypt (rx_tunnel) complete
964         if ((int)meta[i].u.rx_sb_meta->appId == rx_tunnel)
965         {
966            stats.sb_rx+=1;
967            //copy hash out of meta data (for some reason it needs endian conversion)
968            hash[0]= htonl( meta[i].u.rx_sb_meta->pAuthTag[0]);
969            hash[1]= htonl( meta[i].u.rx_sb_meta->pAuthTag[1]);
970            hash[2]= htonl( meta[i].u.rx_sb_meta->pAuthTag[2]);
972            if(stats.sb_rx<=16)
973            {
974              char *tp = (char *) &hash[0];
975              dump_header((long*)p_pkt, stats.sb_rx, (int)meta[i].u.rx_sb_meta->appId,0);
976              printf("tag in pkt=%x %x %x %x %x %x %x %x %x %x %x %x\n",
977                       p_pkt[len-12],p_pkt[len-11],p_pkt[len-10],p_pkt[len-9], p_pkt[len-8],
978                       p_pkt[len-7],p_pkt[len-6],
979                       p_pkt[len-5],p_pkt[len-4],p_pkt[len-3],p_pkt[len-2],p_pkt[len-1]);
980              printf("tag from SA=%x %x %x %x %x %x %x %x %x %x %x %x\n",
981                        tp[0],tp[1],tp[2],tp[3],tp[4],tp[5],
982                        tp[6],tp[7],tp[8],tp[9],tp[10],tp[11]);
983            }
984            //check tag 
985            tag_cmp = memcmp(&p_pkt[len-12],(char*) &hash[0],12); //todo, really use meta->authTagLen
986            stats.n_auth_ok += !(tag_cmp);
987            flip_and_send_pkt(tip, p_pkt, len,1);  //flip packet to echo back and send
988         }
989         //this is an encrypt (tx tunnel) complete
990         else if((int)meta[i].u.rx_sb_meta->appId== tx_tunnel )
991         {
992            hash[0]= htonl( meta[i].u.rx_sb_meta->pAuthTag[0]);
993            hash[1]= htonl( meta[i].u.rx_sb_meta->pAuthTag[1]);
994            hash[2]= htonl( meta[i].u.rx_sb_meta->pAuthTag[2]);
995            stats.sb_tx+=1;
996            if(stats.sb_tx<=16)
997            {
998              char *tp1 = (char *) &hash[0];
999              dump_header((long*)p_pkt, stats.sb_tx, (int)meta[i].u.rx_sb_meta->appId,0);
1000              printf("tag in original rx pkt=%x %x %x %x %x %x %x %x %x %x %x %x\n",
1001                       p_pkt[len-12],p_pkt[len-11],p_pkt[len-10],p_pkt[len-9], p_pkt[len-8],
1002                       p_pkt[len-7],p_pkt[len-6],
1003                       p_pkt[len-5],p_pkt[len-4],p_pkt[len-3],p_pkt[len-2],p_pkt[len-1]);
1005              printf("tag from SA=%x %x %x %x %x %x %x %x %x %x %x %x\n",
1006                        tp1[0],tp1[1],tp1[2],tp1[3],tp1[4],tp1[5],
1007                        tp1[6],tp1[7],tp1[8],tp1[9],tp1[10],tp1[11]);
1008            }
1009            //put the computed tag in the packet
1010            memcpy(&p_pkt[len-12],(char*)&hash[0],12); //todo, really use meta->authTagLen
1011            {
1012            PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
1013            nwalTxPktInfo_t meta_tx={0};
1014            // now send directly 
1015            meta2.sa_handle=nwal_HANDLE_INVALID;
1016            meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID);//only outer IP header checksum. no udp checksum possible since pkt is already encrypted
1017            meta_tx.startOffset = 0;
1018            meta_tx.ipOffBytes = 14;
1019            //not used
1020            meta_tx.l4OffBytes = 0;
1021            meta_tx.l4HdrLen = 0;
1022            meta_tx.ploadLen = 0;
1024            /* post it to netcp tx channel*/
1025            meta2.u.tx_meta=&meta_tx;
1026            pktio_send(netcp_tx_chan,tip,&meta2,&err);
1027            stats.tx +=1;
1028            }
1029         }
1030         else printf("netapi recv_sb_cb: unknown appiD %x \n",meta[i].u.rx_sb_meta->appId );
1031     }
1034 /******************************************************/
1035 /******************PKT RECEIVE HANDLER *************************/
1036 /******************************************************/
1037 void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
1038                          PKTIO_METADATA_T meta[], int n_pkts,
1039                          uint64_t ts )
1041 int i;
1042 int len;
1043 int p;
1044 HEAD_T * p_res;
1045 Ti_Pkt * tip;
1046 unsigned int templen;
1047 int err;
1048 KEY_T key;
1049 char * p_pkt;
1050 HEAD_T * p_head;
1051 HEAD_T temp_head;
1053     p_head=&temp_head;
1055     //debug
1056 #if 0
1057     if (n_pkts != TX_BURST) {
1058       printf("recv_cb, txsofar=%d rxsofar=%d  np = %d, NOT %d\n", 
1059              stats.itx, stats.rx, n_pkts,TX_BURST);
1060       our_stats_cb(netapi_handle,NULL);
1061     }
1062 #endif
1063     //test_alloc_free(7);
1064     //printf("recv start\n");
1066    /* loop over received pkts */
1067    for(i=0;i<n_pkts;i++)
1068    {
1069         tip = p_recv[i];
1070         Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
1071         len = Pktlib_getPacketLen(tip)-4;//real length, subtract mac trailer
1073          //debug: validate descriptor */
1074          if(Pktlib_getNextPacket(tip) != 0) {printf(" rcv_cb, nexpkt != NULL");}
1075         //debug printf("recv pkt, len=%d %d\n", len, templen);
1076         stats.rx+=1;
1078 #ifdef DEBUG_DESC
1079    if (stats.rx<16){printf(">rx dmp.."); dump_descr((long *) tip, stats.rx);}
1080    else if (stats.rx>99) {printf(">rx dmp.."); dump_descr((long *) tip,stats.rx);}
1081 #endif
1082     if(stats.rx<=16)
1083     {
1084         dump_header((long*)p_pkt, stats.rx, (int)meta[i].u.rx_meta->appId,meta[i].u.rx_meta->rxFlag1);
1085     }
1086         /* check header */
1087         memcpy(p_head,&p_pkt[14],sizeof(HEAD_T));
1089         if ((p_head->ip[2]&0x0000ff00)==0x00003200)
1090         {
1091              if (!check_header(p_head,&meta[i])) {
1092                 stats.n_bad+=1;Pktlib_freePacket(tip); continue;
1093              }
1094  
1095              //process IP SEC PACKET
1096 #ifdef IPSEC_MODE_RX_SIDEBAND
1097         {
1098            //ship to crypto for decrypt!!
1099            //12 byte auth tag
1100            PKTIO_METADATA_T meta2 = {PKTIO_META_SB_TX,{0},0};
1101            nwalDmTxPayloadInfo_t meta_tx={0};
1102            meta2.sa_handle=rx_data_mode_handle;
1103            meta_tx.ploadLen = len;
1104            meta_tx.encOffset = 14+20+8+16 ;
1105            meta_tx.authOffset =14+20 ;
1106            meta_tx.encSize=len - 14- 20-8-16-12;
1107            meta_tx.authSize= len -14-20-12;
1108            meta_tx.encIvSize=16;
1109            meta_tx.pEncIV= &p_pkt[14+20+8];
1110            meta_tx.authIvSize=0;
1111            meta_tx.pAuthIV=NULL;
1112            meta_tx.aadSize=0;
1113            meta_tx.pAad=NULL;
1114            /* post it to netcp sb tx channel*/
1115            meta2.u.tx_sb_meta=&meta_tx;
1116            pktio_send(netcp_sb_tx_chan,tip,&meta2,&err);
1117            continue;
1118         }
1119 #else 
1120         //inflow mode.  flip and send
1121         flip_and_send_pkt(tip,p_pkt,len,1);
1122 #endif
1123     }
1124     else if ((p_head->ip[2]&0x0000ff00)!=0x00001100)
1125     {
1126                 stats.n_new+=1;Pktlib_freePacket(tip); continue;
1127     }
1128     else  //non ipsec
1129     {
1130         if (!check_header(p_head,&meta[i])) { 
1131                 stats.n_bad+=1;Pktlib_freePacket(tip); continue;
1132         }
1134 #if 0
1135         /* lookup flow */
1136         key.src_ip = p_head->ip[3];
1137         key.dst_ip = p_head->ip[4];
1138         key.src_port= (p_head->udp[0]&0xffff0000)>>16;
1139         key.dst_port= (p_head->udp[0]&0x0000ffff);
1140         p_res= (HEAD_T *) trie_lookup(P_trie, (char *) &key, sizeof(key));
1141         if (!p_res) { stats.n_new+=1;  slow_path(tip, len); continue;}
1143         /* copy header */
1144         memcpy((char *) p_head, (char *) p_res, sizeof(HEAD_T));
1146         memcpy(&p_pkt[14],p_head,sizeof(HEAD_T));
1147         /* update_mac(&p_pkt[0]);  */
1149         /* 'simulate' send pkt */
1150         send_pkt(tip,len);
1151 #endif
1152         //just flip and send
1153         flip_and_send_pkt(tip,p_pkt,len,0);
1154     }
1155   }
1156     //printf("recv done\n");
1159 //timer callback 
1160 void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
1161         int n_fired,     //# timers fired
1162         NETAPI_TIMER_LIST_T fired_list,
1163         uint64_t currentTime)
1165 int i;
1166 NETAPI_TIMER_T tx;
1167 int cookie;
1168 int err;
1169 unsigned long long et;
1170 //DEBUGprintf("TIMER CALLBACK @ %lld %d timers\n", currentTime, n_fired);
1171 tx = netapi_TimerGetFirst(fired_list);
1172 for(i=0;i<n_fired;i++)
1174   cookie = (int) netapi_TimerGetCookie(tx);
1175   et =  netapi_TimerGetTs(tx); //debug
1176   //DEBUGprintf("   timer %d - cookie = %d expected ts=%lld (delta=%lld)\n", i, cookie, et, currentTime-et);
1177   if (cookie ==1)
1178   {  
1179      stats.n_t1+=1;
1180      t1 = netapi_TimerGroupStartTimer(
1181         th,
1182         (void *) 1,
1183         100LL,  //timer group tics
1184         &err);
1185   }
1186   else if (cookie ==2)
1187   {
1188       stats.n_t2+=1;
1189       t2 = netapi_TimerGroupStartTimer(
1190         th,
1191         (void *) 2,
1192         200LL,  //timer group ticks
1193         &err);
1194   }
1195   else
1196   {
1197     stats.n_t3+=1;
1198     t3 = netapi_TimerGroupStartTimer(
1199         th,
1200         (void *) 3,
1201         300LL,  //timer group ticks
1202         &err);
1203     //cancel 1 and restart 1
1204    netapi_TimerGroupCancel(th,t1,&err);
1205    t1 = netapi_TimerGroupStartTimer(
1206         th,
1207         (void *) 1,
1208         100LL,  //timer group ticks
1209         &err);
1210  }
1211   tx = netapi_TimerGetNext(fired_list,tx); 
1216 static int np2process = NP;
1217 /******************************************************
1218  * stats callback
1219  *******************************************************/
1220 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats)
1222 uint32_t numFreeDataPackets;
1223 uint32_t            numZeroBufferPackets;
1224 uint32_t            numPacketsinGarbage;
1225 Pktlib_HeapStats    pktLibHeapStats;
1227 printf(">*****stats @ %lld\n", netapi_getTimestamp());
1228 //printf("netcp_tx_handle check %x\n", netcp_tx_chan->back);
1229 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\n  n_t1=%d n_t2=%d n_t3=%d\n",stats.itx, stats.rx, stats.tx, stats.n_bad, stats.n_new, 
1230          stats.n_class0_rx, stats.n_class1_rx, 
1231          stats.n_class2_rx, stats.sec_rx, stats.secp_rx, stats.sb_rx, stats.sb_tx, stats.n_auth_ok,
1232          stats.n_t1, stats.n_t2,stats.n_t3);
1234 if(pPaStats)
1236        printf("C1 number of packets:           %d\n", pPaStats->classify1.nPackets);
1237        printf("C1 number IPv4 packets:         %d\n", pPaStats->classify1.nIpv4Packets);
1238        //printf("C1 number llc/snap fail:        %d\n", pPaStats->classify1.nLlcSnapFail);
1239        printf("C1 number table matched:        %d\n", pPaStats->classify1.nTableMatch);
1240        printf("C1 number failed table matched: %d\n", pPaStats->classify1.nNoTableMatch);
1241        printf ("C1 number of parse fail:        %d\n",pPaStats->classify1.nParseFail);
1242        printf("C1 number of command failures:  %d\n", pPaStats->classify1.nCommandFail);
1243        printf("C1 number invalid reply dests:  %d\n", pPaStats->classify1.nInvalidComReplyDest);
1244        printf ("C1 number of silent discard:    %d\n",pPaStats->classify1.nSilentDiscard);
1245        printf("C1 number of invalid control:   %d\n", pPaStats->classify1.nInvalidControl);
1246        printf ("C1 number of invalid states:    %d\n",pPaStats->classify1.nInvalidState);
1247        printf ("C1 number of system fails:      %d\n",pPaStats->classify1.nSystemFail);
1248        printf ("C2 number parse failed  :      %d\n",pPaStats->classify2.nParseFail);
1249        printf ("C2 number Invld Header  :      %d\n",pPaStats->classify2.nInvldHdr);
1250        printf ("C2 number udp           :      %d\n",pPaStats->classify2.nUdp);
1251        printf ("C2 number tcp           :      %d\n",pPaStats->classify2.nTcp);
1252        printf ("C2 number cmd fail      :      %d\n",pPaStats->classify2.nCommandFail);
1253        printf ("C2 number silent drop   :      %d\n",pPaStats->classify2.nSilentDiscard);
1254        printf ("C2 number invalid cntrl :      %d\n\n",pPaStats->classify2.nInvalidControl);
1256 Pktlib_getHeapStats(OurHeap, &pktLibHeapStats);
1257 printf("main heap stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
1258                                 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
1259 printf("               >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n", 
1260                         pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
1261                         pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
1263 Pktlib_getHeapStats(specialSmall, &pktLibHeapStats);
1264 printf("specialSmall heap stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
1265                                 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
1266 printf("                       >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n", 
1267                                 pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
1268                                 pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
1271 Pktlib_getHeapStats(specialLarge, &pktLibHeapStats);
1272 printf("specialLarge heap stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
1273                                 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
1274 printf("                       >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n", 
1275                                 pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
1276                                 pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
1279 //debug = dump timer polling stats
1280 dump_poll_stats();
1285 //******************************************************
1286 //use scheduling housekeeping callback to generate pkts
1287 //******************************************************
1288 void house(NETAPI_SCHED_HANDLE_T * s)
1290 Ti_Pkt * tip;
1291 unsigned int len;
1292 nwalTxPktInfo_t meta_tx;
1293 PKTIO_METADATA_T meta = {PKTIO_META_TX,{0},0};
1294 int err;
1295 static int house_pkts_gened=0;
1296 int p;
1297 unsigned char * pIpHdr,* pData;
1298 unsigned int vv1,vv2,vv3;
1299 unsigned int sum_vv1=0;
1300 unsigned int sum_vv2=0;
1301 unsigned int sum_vv3=0;
1302 unsigned int sum_vv4=0;
1303 unsigned int sum_vv5=0;
1305 unsigned int nwal_flow_vv1,nwal_flow_vv2;
1306 unsigned int nwal_sum_vv1=0;
1307 unsigned int nwal_sum_vv2=0;
1308 unsigned int nwal_sum_vv3=0;
1309 unsigned int nwal_sum_vv4=0;
1310 unsigned int nwal_sum_vv5=0;
1311 unsigned int nwal_sum_vv6=0;
1313 unsigned int nwal_sum_flow_vv1=0;
1314 unsigned int nwal_sum_flow_vv2=0;
1315 unsigned int cache_op_b1;
1316 unsigned int cache_op_b2;
1317 int n_c_ops;
1318 static int first =0;
1319 Cppi_HostDesc*      pPktDesc;
1321 Osal_cache_op_measure_reset();
1322 memset(&meta_tx,0,sizeof(meta_tx));
1323 for(p=0;p<TX_BURST;p++) {  
1324 //reguest stats 
1325 if ((house_pkts_gened>0) && (! (house_pkts_gened%1000)) )
1327    printf("net_test> request stats at n=%d \n",house_pkts_gened);
1328    netcp_cfgReqStats(netapi_handle, our_stats_cb, 0,&err); 
1329    if (err!=0) {printf("stats req failed\n");}
1333   if (house_pkts_gened >= np2process+ 100)
1334   {
1335      //shutdown
1336      netapi_schedShutdown(s,NULL,&err);
1337      continue;
1338   }
1340   else if (house_pkts_gened >= np2process) { house_pkts_gened+=1;  continue;}
1341   
1343 /* manufacture a pkt to transmit */
1344    tip = get_pkt(house_pkts_gened, &len);
1345    if(!tip) { house_pkts_gened +=1; continue; }
1348    /* set the pkt length */
1349    vv1 = netapi_timing_start();
1350    Pktlib_setPacketLen(tip, len);
1352    /* set up meta data */
1353     meta.sa_handle=nwal_HANDLE_INVALID;
1354 //#define BENCH_UDP_SEND
1355 #ifdef BEND_UDP_SEND
1356     meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM | NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID);
1357     meta_tx.startOffset = 0;
1358     //GONE in V2 meta_tx.pktLen = len;
1359     meta_tx.ipOffBytes = TEST_PKT_IP_OFFSET_BYTES;
1360     meta_tx.l4OffBytes = TEST_PKT_UDP_OFFSET_BYTES;
1361     meta_tx.l4HdrLen = TEST_PKT_UDP_HDR_LEN;
1362     //GONE in V2 meta_tx.ploadOffBytes = TEST_PKT_PLOAD_OFFSET_BYTES;
1363     meta_tx.ploadLen = TEST_PAYLOAD_LEN;
1365     Pktlib_getDataBuffer(tip,&pData,&len);
1366     pIpHdr = pData + meta_tx.ipOffBytes;
1367     meta_tx.pseudoHdrChecksum =
1368         test_utilGetIpv4PsudoChkSum(pIpHdr,(TEST_PAYLOAD_LEN+TEST_PKT_UDP_HDR_LEN));
1369 #else
1370     meta_tx.txFlag1 = NWAL_TX_FLAG1_META_DATA_VALID;
1371     meta_tx.startOffset = 0;
1372     meta_tx.ploadLen = TEST_PAYLOAD_LEN;
1373 #endif
1374    /* post it to netcp tx channel*/
1375    meta.u.tx_meta=&meta_tx;
1376 #ifdef DEBUG_DESC
1377    if (house_pkts_gened<16) dump_descr((long *) tip, house_pkts_gened);
1378    else if (house_pkts_gened>99) dump_descr((long *) tip,house_pkts_gened);
1379 #endif
1381    if(!first)
1382    {
1383        first++;
1384        nwal_flow_vv1= netapi_timing_stop();
1385        if(nwal_initPSCmdInfo(PKTIO_GET_NWAL_INSTANCE(netcp_tx_chan),
1386                              &meta_tx,
1387                              &flowPSCmdInfo) != nwal_OK)
1388        {
1389            printf("nwal_initPSCmdInfo() ERROR \n");
1390        }
1391        nwal_flow_vv2= netapi_timing_stop();
1392        nwal_sum_flow_vv1 += (nwal_flow_vv1-vv1); 
1393        nwal_sum_flow_vv2 += (nwal_flow_vv2-nwal_flow_vv1); 
1394    }
1395        
1396    cache_op_b1= Osal_cache_op_measure(&n_c_ops);
1397    vv2= netapi_timing_stop();
1398 #ifdef BEND_UDP_SEND
1399    nwal_mCmdSetL4CkSumPort(  tip,
1400                              &flowPSCmdInfo,
1401                              TEST_PKT_UDP_OFFSET_BYTES,
1402                              (TEST_PKT_UDP_HDR_LEN + TEST_PAYLOAD_LEN),
1403                              meta_tx.pseudoHdrChecksum,
1404                              meta_tx.enetPort);
1405 #else
1406    nwal_mCmdSetPort  (tip,
1407                       &flowPSCmdInfo,  //could be NULL
1408                       0);  //port 0 -> switch decides
1410 #endif
1412    pPktDesc = Pktlib_getDescFromPacket(tip);
1413    /* Send the packet out to transmit Q*/
1414    Qmss_queuePushDescSize (flowPSCmdInfo.txQueue, 
1415                         pPktDesc, 
1416                         NWAL_DESC_SIZE);
1417    vv3= netapi_timing_stop();
1418    cache_op_b2= Osal_cache_op_measure(&n_c_ops);
1420    sum_vv1 += (vv2-vv1);
1421    if(!house_pkts_gened)
1422    {
1423        /* first packet. Take out the PS command label creation cost */
1424        sum_vv1 = sum_vv1 - nwal_sum_flow_vv2;
1425    }
1427    sum_vv3 += (vv3-vv2)-(cache_op_b2-cache_op_b1); //sub out cache op cost
1429    // printf("pktio send. full=%d metadata=%d pktio_send=%d\n", vv3-vv1,  vv2-vv1,  vv3-vv2);
1430    
1432    stats.itx +=1;
1433    house_pkts_gened +=1;
1434  }
1436    unsigned int ccycles;
1437    ccycles =Osal_cache_op_measure(&n_c_ops);
1438    if (sum_vv1) 
1439    {
1440       printf("BURST NWAL Fast send %d pkts.  metadata=%d Cmd Label Creation Cost=%d  nwal Fast Send Cost (less cacheop)= %d n_c_ops=%d cache_op_time=%d (pp-> %d)\n", 
1441               stats.itx, sum_vv1/stats.itx,  nwal_sum_flow_vv2, sum_vv3/stats.itx, 
1442               n_c_ops, ccycles, n_c_ops? (ccycles/(n_c_ops/2)) : 0);
1443 #if 0
1444       printf("NWAL Profile Cycles: Prof1= %d,Prof2=%d,Prof3=%d,Prof4=%d,Prof5=%d ,Prof6=%d \n",
1445               nwal_sum_vv1/stats.itx,nwal_sum_vv2/stats.itx,nwal_sum_vv3/stats.itx,
1446               nwal_sum_vv4/stats.itx,nwal_sum_vv5/stats.itx,nwal_sum_vv6/stats.itx);
1447   
1448 #endif  
1450       if(stats.itx2)
1451       {
1452           printf("nwal_flowSend Profile Cycles: Prof1= %d,Prof2=%d \n",
1453               nwal_sum_flow_vv1/stats.itx2,nwal_sum_flow_vv2/stats.itx2);
1454       }
1456    }
1461 /***************************************
1462  ********** test driver*****************
1463  ***************************************/
1464 int main(int argc, char **argv)
1466 int err;
1467 rlim_t oss,ss = 1024*1024;
1468 struct rlimit rl;
1469    
1470 Pktlib_HeapCfg      heapCfg;
1471 int32_t             errCode;
1472 Pktlib_HeapIfTable*  pPktifTable;
1474 err= getrlimit(RLIMIT_STACK,&rl);
1475 if (!err) printf(" stack limit = %d\n",rl.rlim_cur); else printf("getrlimit failed\n");
1476 #if 0
1477 rl.rlim_cur = ss;
1478 err=setrlimit(RLIMIT_STACK,&rl);
1479 if (!err) printf("set stack to %d\n",rl.rlim_cur); else printf("setrlimit failed\n");
1480 #endif
1482 if (argc>=2)  np2process = atoi(argv[1]);
1483 if (np2process<0) np2process = NP; /* default */
1484 if (argc==3)  perslow = atoi(argv[2]);
1485 if ((perslow<0)||(perslow>100)) perslow=PERSLOW;//default
1486 if (argc>3) {printf("net_test  <no of pkts to process> <percent slow path>\n"); exit(1);}
1489 //real mode, so update our test packet mac header and ip header
1490 if (pktloopback==0)
1492 memcpy(&testPkt,&real_mac_header[0],14); //overwrite test pkt mac address
1493 memcpy(&testPkt[26],&real_ip_addr[0],8);//overrite test pkt ip addresses
1496 /*******************************************/
1497 /*************NETAPI STARTUP****************/
1498 /*******************************************/
1500 /* create netapi */
1501 netapi_handle = netapi_init(NETAPI_SYS_MASTER, &our_netapi_default_cfg);
1503 /* open the main heap */
1504 OurHeap = Pktlib_findHeapByName("netapi");
1505 if (!OurHeap) {printf("findheapbyname fail\n"); exit(1);}
1507 /* create two secondary heaps */
1508 /* Initialize the heap configuration. */
1509 memset ((void *)&heapCfg, 0, sizeof(Pktlib_HeapCfg));
1511 pPktifTable = netapi_getPktlibIfTable();
1512 /* Populate the heap configuration */
1513 heapCfg.name                = "netapi-small";
1514 heapCfg.memRegion           = NETAPI_GLOBAL_REGION;
1515 heapCfg.sharedHeap          = 1;
1516 heapCfg.useStarvationQueue  = 0;
1517 heapCfg.dataBufferSize      = 512;
1518 heapCfg.numPkts             = 64;
1519 heapCfg.numZeroBufferPackets= 0;
1520 heapCfg.heapInterfaceTable.data_malloc  = pPktifTable->data_malloc;
1521 heapCfg.heapInterfaceTable.data_free    = pPktifTable->data_free;
1522 heapCfg.dataBufferPktThreshold   = 0;
1523 heapCfg.zeroBufferPktThreshold   = 0;
1525 specialSmall = Pktlib_createHeap(&heapCfg, &errCode);
1526 heapCfg.name                = "netapi-big";
1527 heapCfg.dataBufferSize      = 1600;
1528 specialLarge = Pktlib_createHeap(&heapCfg, &errCode);
1529 //register these heaps so poll routine will include their garbage queues.
1530 netapi_registerHeap(netapi_handle, specialSmall);
1531 netapi_registerHeap(netapi_handle, specialLarge);
1533 #ifdef REASSEMBLE_BENCH
1534 our_reassemble_bench(2);
1535 exit(1);
1536 #endif
1538 /* create a pktio channel */
1539 our_chan=pktio_create(netapi_handle,"our1stq",(PKTIO_CB) recv_cb_bench, &our_chan_cfg,&err);
1540 if (!our_chan) {printf("pktio create failed err=%d\n",err); exit(1);}
1542 /* open netcp default tx, rx queues */
1543 netcp_tx_chan= pktio_open(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg,  &err);
1544 if (!netcp_tx_chan) {printf("pktio open TX failed err=%d\n",err); exit(1);}
1545 netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb, &netcp_rx_cfg,  &err);
1546 if (!netcp_rx_chan) {printf("pktio open RX failed err=%d\n",err); exit(1);}
1548 /* create a pktio channel for specially classified pkts */
1549 netcp_rx_chan2= pktio_create(netapi_handle, "classq", (PKTIO_CB) recv_cb, &netcp_rx_cfg2,  &err);
1550 if (!netcp_rx_chan2) {printf("pktio create RX2 failed err=%d\n",err); exit(1);}
1552 /* open netcp default tx, rx queues for sideband crypto */
1553 netcp_sb_tx_chan= pktio_open(netapi_handle, NETCP_SB_TX, NULL, &netcp_sb_tx_cfg,  &err);
1554 if (!netcp_sb_tx_chan) {printf("pktio open SB TX failed err=%d\n",err); exit(1);}
1555 netcp_sb_rx_chan= pktio_open(netapi_handle, NETCP_SB_RX, (PKTIO_CB) recv_sb_cb, &netcp_sb_rx_cfg,  &err);
1556 if (!netcp_sb_rx_chan) {printf("pktio open SB RX failed err=%d\n",err); exit(1);}
1558 printf("net_test> %d bytes left in our CMA area\n", netapi_getBufMemRemainder());
1559 /* create scheduler instance */
1560 our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err);
1561 if (!our_sched) {printf("sched create failed\n"); exit(1);}
1563 #if 0
1564 /********************************************
1565 * Basic pkt loopback test
1566 *********************************************/
1567 printf("...running pure push/pop benchmark\n");
1568 our_pktio_bench(1000);
1569 our_pktio_bench(1000);
1570 our_pktio_bench(1000);
1571 our_pktio_bench(1000);
1572 our_pktio_bench(1000);
1573 /*********************************************/
1574 #endif
1579 /* add mac intefaces */
1580 netcp_cfgCreateMacInterface(
1581                   netapi_handle,
1582                   &mac0[0],
1583                   0,0,
1584                   (NETCP_CFG_ROUTE_HANDLE_T)  NULL,
1585                   (NETCP_CFG_VLAN_T ) NULL ,  //future
1586                   1, 
1587                   &err);
1588 if (err) {printf("addmac0 failed %d\n",err); exit(1); } 
1590 //attach an IP to this interface
1591 ip_rule0=netcp_addIp(
1592                   netapi_handle,
1593                   0,
1594                   nwal_IPV4,
1595                   &OurIp0,
1596                   NULL,  //all IP
1597                   (NETCP_CFG_ROUTE_HANDLE_T) NULL,
1598                   &err
1599                   );
1600 if (err) {printf("addip0 failed %d\n",err); exit(1); } 
1602 //create a 2nd mac instance
1603 netcp_cfgCreateMacInterface(
1604                   netapi_handle,
1605                   &mac1[0],
1606                   1,1,
1607                   (NETCP_CFG_ROUTE_HANDLE_T)  NULL,
1608                   (NETCP_CFG_VLAN_T ) NULL ,  //future
1609                   1,
1610                   &err);
1611 if (err) {printf("addmac1 failed %d\n",err); exit(1); }
1613 //attach an IP to this interface
1614 ip_rule1=netcp_addIp(
1615                   netapi_handle,
1616                   1,
1617                   nwal_IPV4,
1618                   &OurIp1,
1619                   NULL,  //all IP
1620                   (NETCP_CFG_ROUTE_HANDLE_T) NULL,
1621                   &err
1622                   );
1623 if (err) {printf("addip1 failed %d\n",err); exit(1); }
1625 //attach 2 classifiers to iface 0, ip0
1626 class_0_cfg.u.c_l4.ip = ip_rule0;
1627 class_0 =  netcp_cfgAddClass(netapi_handle,
1628                              &class_0_cfg,
1629                              NULL,
1630                              NETCP_CFG_ACTION_TO_SW,
1631                              &err);
1632 if (err) {printf("addclass0 failed %d\n",err); exit(1);}
1634 class_1_cfg.u.c_l4.ip = ip_rule0;
1635 class_1 =  netcp_cfgAddClass(netapi_handle,
1636                              &class_1_cfg,
1637                              NULL,
1638                              NETCP_CFG_ACTION_TO_SW,
1639                              &err);
1640 if (err) {printf("addclass1 failed %d\n",err); exit(1);}
1643 //3rd classifier has a different IP and route
1644 class_2_cfg.u.c_l3_l4.ip_addr = &OurIp2;
1646 //create specialFlow for this classifier
1648 Pktlib_HeapHandle heaps[2];
1649 int sizes[2];
1650 heaps[0]= specialSmall;
1651 heaps[1]= specialLarge;
1652 #define SPECIAL_SOP_OFF 128
1653 sizes[0]=512-SPECIAL_SOP_OFF;
1654 sizes[1]=1600-SPECIAL_SOP_OFF;
1655 specialFlow = netcp_cfgAddFlow( netapi_handle,
1656                                 2,
1657                                 heaps,
1658                                 sizes,
1659                                 SPECIAL_SOP_OFF,  //offset to start rx is 128 
1660                                 &err);
1661 if (err) {printf("add flow failed\n", err); exit(1);}
1663 #if 0
1664 //special route for this classifier:  different flow + destination q
1665 class2_route.p_dest_q = netcp_rx_chan2;
1666 class2_route.p_flow = specialFlow;
1667 class_2 = netcp_cfgAddClass(netapi_handle,
1668                             &class_2_cfg,
1669                             (void*) &class2_route,
1670                             NETCP_CFG_ACTION_TO_SW,
1671                             &err);
1672 if (err) {printf("addclass2 failed %d\n",err); exit(1);}
1673 #endif
1675 //security stuff 
1676 ourRXKeyParams.pEncKey = &ourEncrKey[0];
1677 ourRXKeyParams.pAuthKey = &ourAuthKey[0];
1678 memcpy(&rx_sa.src, &TheirIp4IPSEC,4);
1679 memcpy(&rx_sa.dst, &OurIp4IPSEC,4);
1681 #if 1
1682 rx_tunnel = netapi_secAddSA( netapi_handle,
1683                  0, //iface #0 
1684                 &rx_sa,
1685                 &ourRXKeyParams,
1686 #ifdef IPSEC_MODE_RX_SIDEBAND
1687                 NETAPI_SEC_SA_SIDEBAND,
1688 #else
1689                 NETAPI_SEC_SA_INFLOW,  //USE inflow mode
1690 #endif
1691                 NULL,  //use default route 
1692                 &rx_data_mode_handle,
1693                 &rx_inflow_mode_handle,
1694                 &err);
1695 if (err) {printf("addRxSa failed %d\n",err); exit(1);}
1697 #ifdef IPSEC_MODE_RX_INFLOW
1698 //assume inner and outer ip is the same
1699 rx_policy= netapi_secAddRxPolicy( netapi_handle,
1700                          rx_tunnel,  //link to tunnel above
1701                          4,         //ipv4
1702                          &TheirIp4IPSEC, //src -> them
1703                          &OurIp4IPSEC,  //dst -> us
1704                          NULL,  // no qualifiers
1705                          NULL,  //default route
1706                          &err);
1707 if (err) {printf("addSaPolicy failed %d\n",err); exit(1);}
1708 #else 
1709 rx_policy = 0;
1710 #endif
1711 #endif
1713 //tx SA
1714 //security stuff 
1715 ourTXKeyParams.pEncKey = &ourEncrKey[0];
1716 ourTXKeyParams.pAuthKey = &ourAuthKey[0];
1717 memcpy(&tx_sa.src, &OurIp4IPSEC,4);
1718 memcpy(&tx_sa.dst, &TheirIp4IPSEC,4);
1719 tx_tunnel = netapi_secAddSA( netapi_handle,
1720                  0, //iface #0 
1721                 &tx_sa,
1722                 &ourTXKeyParams,
1723 #ifdef IPSEC_MODE_TX_SIDEBAND
1724                 NETAPI_SEC_SA_SIDEBAND,
1725 #else
1726                 NETAPI_SEC_SA_INFLOW,  //USE inflow mode
1727 #endif
1728                 NULL,  //use default route 
1729                 &tx_data_mode_handle,
1730                 &tx_inflow_mode_handle,
1731                 &err);
1732 if (err) {printf("addTxSa failed %d\n",err); exit(1);}
1735 #ifdef TEST_TIMERS
1736 //timers
1737 ourTimerBlock = netapi_TimerGroupCreate(
1738         netapi_handle,
1739         "our1sttimer",
1740         our_timer_cb,
1741         0,    //1 if timers local to thread
1742         0,    //1 if expect to cancel
1743         netapi_getTicksPerSec()/1000,  /* 1 msc resolution for these timers */
1744         netapi_getTicksPerSec()/5000, /* would like .5 msc tolerence */
1745         10,  //small # of timers to test garbage collection
1746         &err);
1747 if (err) {printf("timergroupcreate failed %d\n",err); exit(1);}
1749 //start a couple of timers 
1750 t1 = netapi_TimerGroupStartTimer(
1751         ourTimerBlock,
1752         (void *) 1,
1753         100LL,  //timer group ticks
1754         &err);
1755 if (err) {printf("timerstart failed %d\n");}
1756 t2 = netapi_TimerGroupStartTimer(
1757         ourTimerBlock,
1758         (void *) 2,
1759         200LL,  //timer group ticks
1760         &err);
1761 if (err) {printf("timerstart failed %d\n");}
1762 t3 = netapi_TimerGroupStartTimer(
1763         ourTimerBlock,
1764         (void *) 3,
1765         300LL,  //timer group ticks
1766         &err);
1767 if (err) {printf("timerstart failed %d\n");}
1768 #endif
1769 netcp_cfgReqStats(netapi_handle, our_stats_cb, 1,&err);
1770 if (err!=0) {printf("stats req failed\n");}
1772 /*********************************************/
1773 /*****************end NETAPI STARTUP**********/
1774 /*********************************************/
1777 #if 0
1778 /********************************************
1779 * Basic pkt loopback test
1780 *********************************************/
1781 printf("...runnining pure push/pop benchmark\n");
1782 our_pktio_bench(100);
1783 #endif
1785 /**************unused stuff******************/
1786 /* create TRIE */
1787 P_trie = trie_new();
1788 if (!P_trie) {printf("trie alloc failed\n"); exit(1);}
1790 nat = (HEAD_T *) malloc(NE * sizeof(HEAD_T));
1791 if (!nat) {printf("malloc of nat table failed\n"); exit(1);}
1793 //gen_pkts(np2process<NP ? np2process:NP);
1794 n_pkt= np2process;
1796 /* build table */
1797 build_table(P_trie);
1800 /* processing loop: get pkt, check it, look up in table, copy new header,
1801    send packet */
1802 srand((unsigned) np2process);
1805 /*********************************************/
1806 /**************Entry point into scheduler ****/
1807 /*********************************************/
1808 netapi_schedWaitForEvents(our_sched, &err);
1810 /* done */
1811 our_stats_cb(netapi_handle, NULL);
1814 #define DO_FAST_POLL
1815 #ifdef DO_FAST_POLL
1816 example_fast_pushpop(OurHeap, 500);
1817 example_fast_poll(netcp_rx_chan,100000);
1818 #endif
1820 /*************************************************
1821  ************CLEAN UP****************************
1822  ************************************************/
1824 //delete Classifiers
1825 netcp_cfgDelClass(netapi_handle, class_0, &err); 
1826 netcp_cfgDelClass(netapi_handle, class_1, &err); 
1827 //netcp_cfgDelClass(netapi_handle, class_2, &err); 
1829 //delete flow 
1830 netcp_cfgDelFlow(netapi_handle, specialFlow, &err);
1832 #if 1
1833 //delete policy
1834 if (rx_policy)
1835         netapi_secDelRxPolicy(netapi_handle, rx_policy, &err);
1837 //delete tunnels
1838 netapi_secDelSA(netapi_handle, 0, rx_tunnel, &err);
1839 netapi_secDelSA(netapi_handle, 0, tx_tunnel, &err);
1840 #endif
1842 //delete IPs and MAC Interfacess
1843 netcp_cfgDelIp(netapi_handle, 0, 0, NULL, NULL, ip_rule0, &err);
1844 netcp_cfgDelIp(netapi_handle, 1, 0, NULL, NULL, ip_rule1, &err);
1845 netcp_cfgDelMac(netapi_handle,0,&err);
1846 netcp_cfgDelMac(netapi_handle,1,&err);
1849 //close pktio channels we opened
1850 pktio_close(netcp_tx_chan ,&err);
1851 pktio_close(netcp_rx_chan ,&err);
1852 pktio_close(netcp_sb_tx_chan ,&err);
1853 pktio_close(netcp_sb_rx_chan ,&err);
1855 //clear pktio channel we created
1856 pktio_control(our_chan, (PKTIO_CB) NULL, (PKTIO_CFG_T *) NULL, &zap_channel_control, &err);
1857 pktio_control(netcp_rx_chan2, (PKTIO_CB) NULL, (PKTIO_CFG_T *) NULL, &zap_channel_control, &err);
1859 //delete pktio channels we created
1860 pktio_delete(our_chan, &err);
1861 pktio_delete(netcp_rx_chan2,&err);
1863 netapi_shutdown(netapi_handle);
1867 //EXAMPLE FAST POLL
1868 /* PLD */
1869 void netapi_pld(void * x)
1870 {   
1871            asm volatile("pld [r0]");
1873 #include "ti/drv/nwal/nwal_util.h"
1875 #define M 1008
1876 static int l3_off[M], l4_off[M], L3_chk_ok[M], L4_chk_ok[M], len[M] ;
1877 static nwal_AppId appid[M];
1878 static unsigned char * buf[M];
1879 #define N2POLL 8 //batch size
1880 #define NTOPOP 190
1881 Ti_Pkt * pHd[NTOPOP];
1882 void example_fast_pushpop(Pktlib_HeapHandle h , int n_trials)
1884 int i,j;
1885 unsigned long t1;
1886 unsigned long t2;
1887 unsigned long sumf=0;
1888 unsigned long sumt=0;
1889 unsigned long sump=0;
1890 #define NTOPOP 190
1891 Ti_Pkt * tempVA;
1892 Qmss_QueueHnd freeQ=Pktlib_getInternalHeapQueue(h);
1894 //n_trials of NTOPOP actions
1895 for(i=0;i<n_trials;i++)
1897     //raw pop
1898     t1= netapi_timing_start();
1899     pHd[0] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (freeQ));
1900     for(j=1;j<NTOPOP;j++)
1901     {
1902        tempVA  =  _Osal_qmssPhyToVirt(pHd[j-1]);
1903        netapi_pld(tempVA);
1904         //__builtin_prefetch(tempVA);
1905        pHd[j] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (freeQ));
1906        sumf+= (int) (   ((Cppi_HostDesc *) tempVA)->origBuffPtr -
1907                   ((Cppi_HostDesc *) tempVA)->buffPtr);
1908     }
1909     tempVA  =  _Osal_qmssPhyToVirt(pHd[j-1]);
1910     sumf+= (int) (   ((Cppi_HostDesc *) tempVA)->origBuffPtr -
1911                   ((Cppi_HostDesc *) tempVA)->buffPtr);
1912     t2=netapi_timing_stop();
1913     sumt+= (t2-t1);
1915     //invalidate/wb 
1916     for(j=0;j<NTOPOP;j++)
1917     {
1918         tempVA  =  _Osal_qmssPhyToVirt(pHd[j]);
1919         netapi_utilCacheWbInv(tempVA,128);
1920     }
1922     //raw push 
1923     t1=netapi_timing_start();
1924     for(j=0;j<NTOPOP;j++)
1925     {
1926         PKTIO_QMSS_QUEUE_PUSH_DESC_SIZE_RAW (freeQ,
1927                                              (void *) pHd[j],
1928                                              128);
1929     }
1930     t2=netapi_timing_stop();
1931     sump += (t2-t1);
1933 printf("\nfast poppush: np=%d  pop=%d  push=%d sumf=%d\n", (n_trials*NTOPOP),
1934         sumt/(n_trials*NTOPOP),  sump/(n_trials*NTOPOP), sumf);
1935 sleep(1);
1936 return;
1941 void example_fast_poll( PKTIO_HANDLE_T * p_pktio, int max_pkts)
1943 int j=0;
1944 int jj=0;
1945 int i,k,l=0,ltot=0;
1946 int n= N2POLL; //max # of pkts to poll
1947 Ti_Pkt * tempVA;
1948 pasahoLongInfo_t* pinfo;
1949 unsigned long t1;
1950 unsigned long t2;
1951 unsigned long t11;
1952 unsigned long t12;
1953 unsigned long np;
1954 unsigned long sumt=0;
1955 unsigned long sumf=0;
1956 unsigned long sump=0;
1957 unsigned long totlen=0;
1958 int max_batch=0;
1960 //this should  be done once and saved
1961 Qmss_QueueHnd rxQ= PKTIO_GET_DEFAULT_NETCP_Q(p_pktio);
1962 Qmss_QueueHnd freeQ;
1963 //loop forever
1964 for(;max_pkts>0;)
1966     t1= netapi_timing_stop();
1967     pHd[0] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (rxQ));
1968     if (!pHd[0]) continue;
1969     //got pkt
1970     for(i=1;(i<n) && (pHd[i-1]);i++)
1971     {
1972         //convert previous descriptor PA -> VA
1973         tempVA  =  Osal_qmssPhyToVirt(pHd[i-1]); 
1975         //try and preload desriptor
1976          __builtin_prefetch(tempVA);
1977         //netapi_pld(tempVA);
1979         //read next descriptor from queue 
1980         pHd[i] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (rxQ));
1981 #if 1   
1982         /* extract some meta data */
1983         Cppi_getData (Cppi_DescType_HOST, (Cppi_Desc*)tempVA, &buf[jj], &len[jj]);
1984         pinfo =  nwal_mGetProtoInfo(tempVA);
1985         l3_off[jj]= nwal_mGetL3OffBytes(pinfo);
1986         l4_off[jj]= nwal_mGetL4Offset(pinfo);
1987         if(nwal_mGetAppidFmPkt(tempVA,&appid[jj]) != nwal_TRUE)
1988         {
1989             printf("ERROR!!!! AppID not available in incoming packet \n");
1990         }
1991 //#define VERIFY_SOP
1992 #ifdef VERIFY_SOP
1993   if (sump < 200)  printf("..sop off=%d\n", (int) buf[jj]-
1994            (int)  ((Cppi_HostDesc *) tempVA)->origBuffPtr) ;
1995 #endif
1996 #endif
1997         jj+=1;
1998     }
1999     //finish last pkt in burst
2000     if(pHd[i-1])
2001     {
2002         //convert previous descriptor PA -> VA
2003         tempVA  =  Osal_qmssPhyToVirt(pHd[i-1]); 
2005         /* extract some meta data */
2006 #if 1
2007         pinfo =  nwal_mGetProtoInfo(tempVA);
2008         l3_off[jj]= nwal_mGetL3OffBytes(pinfo);
2009         l4_off[jj]= nwal_mGetL4Offset(pinfo);
2010         if(nwal_mGetAppidFmPkt(tempVA,&appid[jj]) != nwal_TRUE)
2011         {
2012             printf("ERROR!!!! AppID not available in incoming packet \n");
2013         }
2014 #endif
2015         //get ptr (Physical address) and length of associate buffer
2016         Cppi_getData (Cppi_DescType_HOST, (Cppi_Desc*)tempVA, &buf[jj], &len[jj]);
2017         jj+=1;
2018     }
2019     t2= netapi_timing_stop();
2020     j+=(pHd[i-1]? i: (i-1)) ;
2021     if (jj>(M-n)) jj=0;
2022     l+=1;  //n batches
2023     ltot+=1;
2024     if(pHd[i-1])
2025     {
2026       if (i>max_batch) max_batch= i;
2027     }
2028     else
2029     {
2030       if( (i-1) >max_batch) max_batch = i-1;
2031     }
2033     //cleanup
2034     //printf("cleanup %d\n",i);
2035     for(k=0;k<i;k++)
2036     {
2037         //cleanup.  need to covert all of desriptor to VA so that i can use freePacket() 
2038         //alternative would be to just do cache ops plus descriptor raw push to pktlib
2039         // heap free queue
2040         if(pHd[k])
2041         {
2043         //tempVA=Qmss_osalConvertDescPhyToVirt(pHd[k]);
2044         tempVA  =  Osal_qmssPhyToVirt(pHd[k]);
2045         freeQ=Qmss_getQueueHandle(Cppi_getReturnQueue (Cppi_DescType_HOST, (Cppi_Desc *)tempVA));
2046         netapi_utilCacheWbInv(tempVA,128);
2047         //would need to wbInv buffer also in practice. Also need to walk
2048         // descriptor chain 
2049         t11= netapi_timing_stop();
2050        // Pktlib_freePacket(tempVA);
2051         PKTIO_QMSS_QUEUE_PUSH_DESC_SIZE_RAW (freeQ,
2052                                              (void *) pHd[k],
2053                                              128);
2055         t12= netapi_timing_stop();
2056         sumf += (t12-t11);       
2057         }
2058     }
2059     sumt += (t2-t1);
2060     sump +=(pHd[i-1]? i: (i-1));
2061     max_pkts -= (pHd[i-1]? i: (i-1));
2063     //printf("end cleanup %d %d %d\n",sumt,sumf,sump );
2064     if (sump > 10000) {
2065        printf("pkts rx %d batches=%d  appid=%x l3_off=%d l4_off=%d len=%d buf=0x%x rxcycle= %d pkts/batchx1000=%d maxbatch=%d cycles per rawpush = %d\n", 
2066                   j,ltot, appid[j%M], 
2067                   l3_off[j%M],l4_off[j%M],  
2068                   len[j%M],buf[j%M],
2069                    sumt/sump,  (sump*1000)/l, max_batch,
2070                    sumf/sump);
2071        sumt=sump=sumf=0;
2072        l=0;
2073     }