d828a5635bdc5d68b3e07c0486b9360c3322cb64
[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 800 
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);
143 #if 1
144 //#include "arpa/inet.h"
145 long htonl(long x)
147         long temp = (x&0xff000000)>>24 | (x&0xff0000)>>8 | (x&0xff00)<<8 |  (x&0xff)<<24 ;
148         return temp;
151 /********************************************************************
152  *  FUNCTION PURPOSE: Ones complement addition utility
153  ********************************************************************
154  ********************************************************************/
155 uint16_t test_utilOnesComplementAdd (uint16_t v1, uint16_t v2)
157   uint32_t result;
159   result = (uint32_t)v1 + (uint32_t)v2;
160   result = (result >> 16) + (result & 0xffff);
161   result = (result >> 16) + (result & 0xffff);
163   return ((uint16_t)result);
166 /********************************************************************
167  *  FUNCTION PURPOSE: Ones complement checksum utility
168  ********************************************************************
169  ********************************************************************/
170  uint16_t test_utilOnesCompChkSum (uint8_t *p, uint32_t nwords)
172   uint16_t chksum = 0;
173   uint16_t v;
174   uint32_t i;
175   uint32_t j;
177   for (i = j = 0; i < nwords; i++, j+=2)  {
178     v = (p[j] << 8) | p[j+1];
179     chksum = test_utilOnesComplementAdd (chksum, v);
180   }
181   return (chksum);
182 } /* utilOnesCompChkSum */
184 /**************************************************************************************
185  * FUNCTION PURPOSE: Compute ipv4 psudo checksum
186  **************************************************************************************
187  * DESCRIPTION: Compute ipv4 psudo checksum
188  **************************************************************************************/
189 uint16_t test_utilGetIpv4PsudoChkSum (uint8_t *data, uint16_t payloadLen)
191   uint16_t psudo_chksum;
193   psudo_chksum = test_utilOnesCompChkSum (&data[12], 4);
194   psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, (uint16_t) data[9]);
195   psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, payloadLen);
197   return (psudo_chksum);
199 } /* utilGetIpv4PsudoChkSum */
203 #endif
204 typedef struct stats_t
206         long itx;  //initially generated
207         long itx2;
208         long rx;
209         long tx;
210         long n_bad;
211         long n_new;
212         long n_class0_rx;   //count of pkts classified 
213         long n_class1_rx;   //count of pkts classified 
214         long n_class2_rx;   //count of pkts classified 
215         long n_t1;
216         long n_t2;
217         long n_t3;
218         long sec_tx;
219         long sec_rx;
220         long sb_tx;
221         long sb_rx;
222         long secp_rx;
223         long n_auth_ok;
224 } STATS_T;
226 typedef struct head_t
228         long ip[5];
229         long udp[2];
230 } HEAD_T;
232 typedef struct key_t
234   long src_ip;
235   long dst_ip;
236   short src_port;
237   short dst_port;
238 } KEY_T;
240 unsigned char mac0[]={0x00,0x01,0x02,0x03,0x04,0x05}; //interface 0
241 unsigned char mac1[]={0x00,0x01,0x02,0x03,0x04,0x06}; //interface 1
242 nwalIpAddr_t OurIp0={ 10, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
243 nwalIpAddr_t OurIp1={ 10, 0, 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
244 nwalIpAddr_t OurIp2={ 10, 0, 2, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
245 nwalIpAddr_t OurIp4IPSEC={ 192,168 , 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
246 nwalIpAddr_t TheirIp4IPSEC={ 192,168 , 1, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
249 #if 1  //goes with real tx (to laptop) 
250 unsigned char real_mac_header[]={0xd4,0xbe,0xd9,0x00,0xd3,0x7e,
251                       0x00,0x01,0x02,0x03,0x04,0x05,
252                       0x08,0x00};
253 unsigned char real_ip_addr[]={0xa,0x00,0x00,0x64,0xa,0x0,0x0,0xa};
254 #endif
256 #if 0  //goes with loopback
257 unsigned char mac_header[]={0x00,0x01,0x02,0x03,0x04,0x05, 
258                       0x00,0x11,0x22,0x33,0x44,0x55,
259                       0x08,0x00};
260 #endif
261 #define NE 65536 
262 HEAD_T *nat;
264 #define NP 5000
265 int n_pkt = NP;
266 STATS_T stats;
268 Trie * P_trie;
269 HEAD_T pkts[NP];
270 #define PERSLOW  10  //% of pkts that will not be fastpath'd 
271 int perslow= PERSLOW;
273 /*******************************************
274  *************NETAPI OBJECTS***************
275  *****************************************/
276 static NETAPI_CFG_T our_netapi_default_cfg=
278 TUNE_NETAPI_PERM_MEM_SZ,
279 128,  //start of packet offset for hw to place data on rx for default flow
280 TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
281 TUNE_NETAPI_NUM_GLOBAL_DESC,        //total we will use
282 TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap
283 64, //#descriptors w/o buffers in default heap
284 TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128,  //size of buffers in default heap
285 128   ,  //tail room
286 256      //extra room 
287 };
289 Pktlib_HeapHandle OurHeap;
290 Pktlib_HeapHandle specialSmall;
291 Pktlib_HeapHandle specialLarge;
293 PKTIO_HANDLE_T *our_chan;
294 PKTIO_HANDLE_T *netcp_rx_chan;
295 PKTIO_HANDLE_T *netcp_rx_chan2;
296 PKTIO_HANDLE_T *netcp_tx_chan;
297 PKTIO_HANDLE_T *netcp_sb_tx_chan;
298 PKTIO_HANDLE_T *netcp_sb_rx_chan;
299 PKTIO_CFG_T our_chan_cfg={PKTIO_RW, PKTIO_LOCAL, PKTIO_Q_ANY, 8};
300 PKTIO_CFG_T netcp_rx_cfg={PKTIO_R, PKTIO_NA, PKTIO_NA, 8};
301 PKTIO_CFG_T netcp_rx_cfg2={PKTIO_R, (PKTIO_GLOBAL|PKTIO_PKT), PKTIO_Q_ANY, 8};
302 PKTIO_CFG_T netcp_tx_cfg={PKTIO_W, PKTIO_NA, PKTIO_NA, 8};
303 PKTIO_CFG_T netcp_sb_rx_cfg={PKTIO_R, PKTIO_NA, PKTIO_NA, 8};
304 PKTIO_CFG_T netcp_sb_tx_cfg={PKTIO_W, PKTIO_NA, PKTIO_NA, 8};
306 void house(NETAPI_SCHED_HANDLE_T *s);
307 NETAPI_T netapi_handle;
308 NETAPI_SCHED_HANDLE_T * our_sched;
309 NETAPI_SCHED_CONFIG_T our_sched_cfg={
310   NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 50000  //every 5000 poll loops
311 };
312 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats);
313 NETAPI_TIMER_GROUP_HANDLE_T ourTimerBlock; 
314 NETAPI_TIMER_T t1;
315 NETAPI_TIMER_T t2;
316 NETAPI_TIMER_T t3;
318 void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
319         int n_fired,     //# timers fired
320         NETAPI_TIMER_LIST_T fired_list,
321         uint64_t currentTime);
323 NETCP_CFG_IP_T ip_rule0;
324 NETCP_CFG_IP_T ip_rule1;
325 NETCP_CFG_CLASS_T class_0;
326 NETCP_CFG_CLASS_T class_1;
327 NETCP_CFG_CLASS_T class_2;
328 NETCP_CFG_FLOW_HANDLE_T specialFlow;
330 NETCP_CFG_CLASSIFIER_T class_0_cfg=
332    NETCP_CFG_CLASS_TYPE_L4,
333    {
334         {0,0, NWAL_APP_PLOAD_PROTO_UDP, {2500}}
335    }
336 };
338 NETCP_CFG_CLASSIFIER_T class_1_cfg=
340    NETCP_CFG_CLASS_TYPE_L4,
341    {
342         {0,0, NWAL_APP_PLOAD_PROTO_UDP, {2502}}
343    }
344 };
346 NETCP_CFG_ROUTE_T  class2_route=
348 NULL, NULL  //* to be filled in
349 };
350 NETCP_CFG_CLASSIFIER_T class_2_cfg=  
352    NETCP_CFG_CLASS_TYPE_L3_L4,
353    {
354         {0,  4 ,0/*fill in below*/ , NULL, NULL,          //L2/L3
355            NWAL_APP_PLOAD_PROTO_UDP, {2504}}   //L4
356    }
357 };
359 PKTIO_CONTROL_T zap_channel_control={PKTIO_CLEAR, NULL};
361 /* security objects. (for loopback mode) */
362 NETCP_CFG_SA_T rx_tunnel;
363 NETCP_CFG_SA_T tx_tunnel;
364 NETCP_CFG_IPSEC_POLICY_T rx_policy;
365 void * rx_data_mode_handle;
366 void * tx_data_mode_handle;
367 void * rx_inflow_mode_handle;
368 void * tx_inflow_mode_handle;
369 /* rx */
370 NETAPI_SEC_SA_INFO_T rx_sa=
372         NWAL_SA_DIR_INBOUND,
373         0x44444444,  //spi
374         nwal_IpSecProtoESP, //ESP mode
375         nwal_SA_MODE_TUNNEL,  //tunnel mode
376         nwal_IPV4, //v4
377         { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (them) -> set below */
378         { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (us)-> set below*/
379         64,/* replayWindow */
380         NWAL_SA_AALG_HMAC_SHA1,
381         NWAL_SA_EALG_AES_CBC,
382         0,0  //na
383 };
385 /*tx */
386 NETAPI_SEC_SA_INFO_T tx_sa=
388        NWAL_SA_DIR_OUTBOUND,
389         0x44444444,  //spi
390         nwal_IpSecProtoESP, //ESP mode
391         nwal_SA_MODE_TUNNEL,  //tunnel mode
392         nwal_IPV4, //v4
393         { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (us) -> set below */
394         { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (them) -> set below*/
395         64, /* NA replayWindow */
396         NWAL_SA_AALG_HMAC_SHA1,
397         NWAL_SA_EALG_AES_CBC,
398         0,0  //seq no
399 };
401 //since we are doing loopback, the rx key params = tx key params
402 static nwalSecKeyParams_t ourTXKeyParams =
404     16, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_DES_CBC and 0 bytes Salt*/
405     20, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_MD5 */
406     NULL, //set below
407     NULL, //set below
408 };
410 static nwalSecKeyParams_t ourRXKeyParams ={
411     16, /* encKeySize: 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_DES_CBC and 0 bytes Salt*/
412     20, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_MD5 */
413     NULL, //set below
414     NULL, //set below
415 };
417 //keys
418 static uint8_t ourAuthKey[36] =
419         {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
420          0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
421          0x20, 0x21, 0x22, 0x23 };
422 static uint8_t ourEncrKey[36] =
423         {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
424          0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
425          0x30, 0x31, 0x32, 0x33 };
428 /*************************END NETAPI OBJECTS***********************/
430 #define START_SRC_IP 0x0a00000a
431 #define DST_IP       0xc0a80001
432 #define NEW_START_SRC_IP 0x9eda000a
433 #define DST_PORT 0x555 
434 #define START_SRC_PORT 0x1234
435 #define NEW_START_SRC_PORT 100
436 void update_header(HEAD_T * p_head, int len)
438    unsigned char *p = (unsigned char *) &p_head->udp[1];
439    len -= (20+14);
440    /* update ip checksum */
441    /* update udp checksum */
442    /* update length */
443    *p= (len&0xff00)>>8;
444    *(p+1) = len&0xff;
447 #if 0
448 void gen_pkts(int np)
450 int i;
451 int ip = START_SRC_IP &0xff;
452 int port= START_SRC_PORT;
453 //HEAD_T temp={{0x25000200,0xdead0000,0x80110000,START_SRC_IP,DST_IP},
454 //             {START_SRC_PORT<<16|DST_PORT,0x01ec<<16|0x0000}};
455 HEAD_T temp;
456 memcpy(&temp,&testPkt[0],sizeof(HEAD_T));
458 for(i=0;(i<np) && (i<NP);i++)
459   {
460        memcpy(&pkts[i],&temp,sizeof(temp));
461        update_header(&pkts[i],512);      /* update checksums etc */
462        /* change template for new pkt */
463        ip+=1;
464        if(ip>254) {(ip=START_SRC_IP&0xff); port+=1; }
465        temp.ip[3] = htonl((START_SRC_IP&0xffffff00)| ip);
466        temp.udp[0] = htonl( (temp.udp[0]&0xffff0000)| port);
467        temp.udp[1] = htonl(temp.udp[1]);
468      
469   }
470   n_pkt=np;
472 #endif
474 void build_table(Trie * p_trie)
476 int i;
477 int sport=NEW_START_SRC_PORT; 
478 HEAD_T temp,temp2;
479 KEY_T key;
481 memcpy(&temp,&testPkt[14],sizeof(temp));
483  //insert entry into trie
484 key.src_ip = temp.ip[3];
485 key.dst_ip = temp.ip[4];
486 key.src_port= (temp.udp[0]&0xffff0000)>>16;
487 key.dst_port= (temp.udp[0]&0x0000ffff);
488 trie_insert(p_trie,(char *)&key,sizeof(key), (void *) &nat[0]); //asociate with nat entry 0
490 //build nat table
491 for(i=0;i<100;i++)
493    memcpy(&temp2,&testPkt[14],sizeof(temp));
494    temp2.udp[0] = (temp2.udp[0] & 0xffff0000) |  sport;
495    memcpy(&nat[i], &temp2, sizeof(temp2));
496    sport+= 1;
500 //===========stub transmitter==================
501 void send_pkt(Ti_Pkt *pkt, int len)
503 //just free pkt.  Don't send
504 Pktlib_freePacket((Ti_Pkt*)pkt);
505         return;
508 //==========stub slow path============
509 void slow_path(Ti_Pkt *pkt, int len)
511 // debug: check descriptor for validity by verifying that desciptor link field is null as expected\n");
512          {Ti_Pkt * k= Pktlib_getNextPacket(pkt); if(k != 0) {printf(" slowpath, nexpkt != NULL");}}
513 //just free pkt
514 Pktlib_freePacket((Ti_Pkt*)pkt);
515         return;
517 /* check header */
518 struct LastPktInfo
520 int iface;
521 int ipcsum;
522 int l4csum;
523 } ;
524 static struct LastPktInfo lpInfo;
526 int check_header(HEAD_T * p_head, PKTIO_METADATA_T * p_meta)
528 if (NWAL_RX_FLAG1_META_DATA_VALID & p_meta->u.rx_meta->rxFlag1)
530 lpInfo.iface = ((unsigned int)p_meta->u.rx_meta->appId) &0xff; //last byte is interface num
531 lpInfo.ipcsum =(p_meta->u.rx_meta->rxFlag1 & NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_MASK )== NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_ACK ? 1 : 0;
532 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; 
533 if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_IPSEC)
535    stats.sec_rx++;
537 if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_IPSEC_POLICY)
539    stats.secp_rx++;
542 if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_CLASS)
544   int c= ((unsigned int)p_meta->u.rx_meta->appId >>8)&0xffff;
545   if (c==0)  stats.n_class0_rx +=1;
546   else if (c==1) stats.n_class1_rx +=1;
547   else if (c==2) stats.n_class2_rx +=1;
548   else printf("**NET_TEST RX -unknown class: %x\n",  p_meta->u.rx_meta->appId);
552  return 1;
555 #define PKT_LEN 1400
556 void test_alloc_free(int n)
558 int i;
559 Ti_Pkt * b;
561 for(i=0;i<n;i++)
563   b=Pktlib_allocPacket(OurHeap,PKT_LEN);
564   Pktlib_freePacket(b);
568 //measurement test points
569 unsigned int vv1;
570 unsigned int vv2;
571 unsigned int vv3;
572 unsigned int vv4;
573 unsigned int vv5;
574 unsigned int vv6;
575 //these are updated by pktio.
576 unsigned int vv7p;
577 unsigned int vv8p;
578 unsigned int vv9p;
579 unsigned int vv10p;
580 unsigned int vv11p;
581 unsigned int vv12p;
583 unsigned int vv11;
585 unsigned int vv13p;  //rcv path
586 unsigned int vv14p;
587 unsigned int vv15p;
589 extern unsigned int nwal_prof1,nwal_prof2,nwal_prof3,nwal_prof4,nwal_prof5,nwal_prof6;
591 //#define REASSEMBLE_BENCH
592 #ifdef REASSEMBLE_BENCH
593 #include <ti/drv/pa/example/reassemLib/reassemLib.h>
594 /*--------------reassembly benchmark--------------------------------*/
595 void our_reassemble_bench(int nfrags)
597 paIPReassemblyConfig_t Config={5,128,10000 };
598 int i,j;
599 int len;
600 Ti_Pkt tip;
601 char *buffer;
602 unsigned long v1;
603 unsigned long v2;
604 unsigned long sum1=0;
605 unsigned long sum2=0;
606 paEx_reassemLibInit(&Config);
607 for(j=0;j<200/nfrags;j++)
609   for(i=0;i<nfrags;i++)
610   {
611     short temp;
612     tip=Pktlib_allocPacket(OurHeap,PKT_LEN);
613     Pktlib_getDataBuffer(tip,(uint8_t**)&buffer,&len);
614     memcpy(&buffer[0],&testPkt[14],20); //IP header
615     if (i < (nfrags-1)) buffer[6] = 0x20;
616     temp = i*40; 
617     buffer[6]|= (temp&0x1f00)>>8;
618     buffer[7]= (temp&0xff);
619     temp = 20+40*8; 
620     buffer[2]= (temp&0xff00)>>8;
621     buffer[3]= (temp&0xff);
622     Pktlib_setPacketLen(tip, temp);
623     v1= netapi_timing_stop();
624     paEx_reassemLibProc(tip, 0xffff);
625     v2= netapi_timing_stop();
626     sum1+= v2-v1;
627   }
628   sum2 += v2-v1;
630 printf("reasssembly test:  %d trials, %d frags/pkt  %d cycles/frag %d cycles/last frag\n",j,nfrags, sum1/(j*nfrags), sum2/(j));
632 #endif
634 /*--------------basic pktio send/recv benchmark----------------------*/
635 unsigned int timings[10];
636 void our_pktio_bench(int ntrials)
638 int i;
639 #define NBATCH 8
640 Ti_Pkt tip;
641 unsigned char * pData;
642 int len;
643 int n;
644 int err;
645 int sum =0;
647    Osal_cache_op_measure_reset();
648    for(i=0;i<10;i++) timings[i]=0;
649    printf("calibration loop .. ");
650    for(i=0;i<1000;i++)
651    {
652    vv1= netapi_timing_stop();
653    vv2= netapi_timing_stop();
654    sum+=(vv2-vv1);
655    }
656    printf(" accuracy = +- %d cycles\n", sum/1000);
657    sleep(1);
658   
659 PKTIO_METADATA_T meta[10]={0};
660 //send single, recv single
661 for(i=0;i<ntrials;i++)
663    vv1= netapi_timing_stop();
664    tip=Pktlib_allocPacket(OurHeap,PKT_LEN);
665    vv2= netapi_timing_stop();
666    Pktlib_getDataBuffer(tip,&pData,&len);
667    vv3= netapi_timing_stop();
668    pktio_send(our_chan,tip,&meta[0],&err);
669    vv4= netapi_timing_stop();
670    n=pktio_poll(our_chan,NULL , &err);
671    vv5=   netapi_timing_stop();
672    timings[0]+=(vv6-vv4);
673    timings[1]+=(vv5-vv4);
674    timings[2]+=(vv7p-vv4);
675    timings[3]+=(vv4-vv3);
676    timings[4]+=(vv8p-vv3); 
677    timings[5]+=(vv3-vv1);
678    timings[6]+=(vv9p-vv8p);
679    timings[7]+=(vv10p-vv7p);
680    timings[8]+=(vv11-vv6);
682    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,
683            timings[1]/ntrials, timings[2]/ntrials,timings[3]/ntrials, timings[4]/ntrials,timings[5]/ntrials,
684            timings[6]/ntrials,timings[7]/ntrials, timings[8]/ntrials );
685    printf("raw qpop = %d  raw qpush = %d pa2va = %d  ", pktio_get_qop_time(), 
686                                                         pktio_get_qpush_time(),
687                                                         pktio_get_pa2va_time());
689    unsigned int ccycles;
690    int n_c_ops;
691    ccycles =Osal_cache_op_measure(&n_c_ops);
692    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);
696 /*-----------test driver: gen an input pkt------- */
697 //char buffer[sizeof(HEAD_T)+PKT_LEN];
698 Ti_Pkt * get_pkt(int n, unsigned int *p_len)
700    int ind;
701    long long temp;
702    Ti_Pkt * b;
703    char * buffer;
704    unsigned int len;
706   if (pktloopback==0)
707   {
708         if (n>=TX_BURST) return NULL;   //just gen pkts to warm swtich, so that it knows
709                                 //our mac is valid
710   }  
711   b=Pktlib_allocPacket(OurHeap,PKT_LEN);
712   if (!b) 
713     {printf("net_test: get_pkt() heap empty!! %d pkts gen'd %d \n", n); return NULL;};
715     //debug - way to validate descriptor
716     {Ti_Pkt* k= Pktlib_getNextPacket(b); 
717          if(k != 0) {printf(" genpkt, nexpkt != NULL");}}
720    //get pointer to buffer area of packet
721    Pktlib_getDataBuffer(b,(uint8_t**)&buffer,&len);
722    if (!buffer) 
723     {printf("net_test: get_pkt() heap returned empty buffer %d \n", n); return NULL;};
725 #if 0 
726 if (pktloopback==0)
728    temp = (long long) rand();
729    temp *= PKT_LEN;
730    temp /= RAND_MAX;
731    temp +=2;
732    *p_len = (int) temp; 
733    *p_len = *p_len &0xfffffffe;
734    temp = (long long) rand();
735    temp *= n_pkt;
736    temp /= RAND_MAX;
737    ind = (int) temp;
738    update_header(&pkts[ind],*p_len);
739    //printf("get pkt:%d %d ind=%d len=%d\n",RAND_MAX, rand(),ind, *p_len);
740     memcpy(&buffer[0], &mac_header[0],14);
741     memcpy(&buffer[14],(char*)&pkts[ind],sizeof(HEAD_T)); 
743 else
744 #endif
746    //copy test packet into buffer
748     memcpy(&buffer[0], &testPkt[0],TEST_PKT_LEN);
749     *p_len = TEST_PKT_LEN;
751     return b; 
755 /*--------------------------------------------------------------
756  *----------utility to flip a packet and send 
757  *--------------------back to source----------------------------
758  *                   flag=1 => ipsec
759  *--------------------------------------------------------------*/
760 void flip_and_send_pkt(Ti_Pkt *tip,  unsigned char * p_pkt, int len, int flag)
762 unsigned char mac_temp[6];
763 unsigned char ip_temp[4];
764 unsigned char new_dest_port[2]={0x75,0x30};  // 30000
765 uint16_t blah; 
766 //mac
767 memcpy(&mac_temp,&p_pkt[0],6);
768 memcpy(&p_pkt[0],&p_pkt[6],6);
769 memcpy(&p_pkt[6],&mac_temp,6);
770 //memcpy(&p_pkt[0],real_mac_header,6); //for testing to wireshark pc
772 //ip  (outer in case of ipsec)
773 memcpy(&ip_temp, &p_pkt[14+12],4);
774 memcpy(&p_pkt[14+12],&p_pkt[14+12+4],4);
775 memcpy(&p_pkt[14+12+4],&ip_temp,4);
777 //outer checksum to 0
778 if (!flag) memset(&p_pkt[14+10],0,2);
780 //inner ip &udp for ipsec
781 if (flag) 
783     //just drop non-udp packet
784     if (p_pkt[14+20+8+16+9]!=0x11)
785     {
786         stats.n_new+=1;Pktlib_freePacket(tip); return;
787     }
789 //spi
790 //memset(&p_pkt[14+20],0x88,4); 
791 //inner ip
792 memcpy(&ip_temp, &p_pkt[14+20+8+16+12],4);
793 memcpy(&p_pkt[14+20+8+16+12],&p_pkt[14+20+8+16+12+4],4);
794 memcpy(&p_pkt[14+20+8+16+12+4],&ip_temp,4);
796 //udp
797 memcpy(&p_pkt[14+20+8+16+20+2],&new_dest_port[0],2);
798 memset(&p_pkt[14+20+8+16+20+6],0,2); //checksum
800 #ifdef IPSEC_MODE_TX_SIDEBAND
802 //inner ip checksum : leave alone
803 #if 0
804 blah=test_utilOnesCompChkSum (&p_pkt[14+20+8+16], 10);
805 p_pkt[14+20+8+16+10]= (blah&0xff00)>>8;
806 p_pkt[14+20+8+16+11]= blah&0xff;
807 #endif
809 //tbd udp checksum (leave at 0)
811 //outer ip, set to 0 (we will compute on way out
812 memset(&p_pkt[14+10],0,2);
814 #else //inflow, don't touch outer , clear inner 
815 memset(&p_pkt[14+20+8+16+10],0,2); //inner checksum, we will compute on way out
816 //outer ip checksum : leave alone
817 #if 0
818 blah = test_utilOnesCompChkSum (&p_pkt[14], 10);
819 p_pkt[14+10]= (blah&0xff00)>>8;
820 p_pkt[14+11]= blah&0xff;
821 #endif
822 #endif
824 else
826 memset(&p_pkt[14+20+6],0,2);//0 udp checksum (we will compute on way out
827 memcpy(&p_pkt[14+20+2],&new_dest_port[0],2);
830 //IPSEC case, 
831 if (flag)
833 #ifdef IPSEC_MODE_TX_SIDEBAND
834  //send to crypto for encryption
835 //12 byte auth tag
836         {
837            PKTIO_METADATA_T meta = {PKTIO_META_SB_TX,{0},0};
838            int err;
839            nwalDmTxPayloadInfo_t meta_tx={0};
840            meta.sa_handle=tx_data_mode_handle;  //use TX SA context
841            meta_tx.ploadLen = len;
842            meta_tx.encOffset = 14+20+8+16 ;
843            meta_tx.authOffset =14+20 ;
844            meta_tx.encSize=len - 14- 20-8-16-12;
845            meta_tx.authSize= len -14-20-12;
846            meta_tx.encIvSize=16;
847            meta_tx.pEncIV= &p_pkt[14+20+8];  //just use same IV..
848            meta_tx.authIvSize=0;
849            meta_tx.pAuthIV=NULL;
850            meta_tx.aadSize=0;
851            meta_tx.pAad=NULL;
852            /* post it to netcp sb tx channel*/
853            meta.u.tx_sb_meta=&meta_tx;
854            pktio_send(netcp_sb_tx_chan,tip,&meta,&err);
855        }
857 #else
858  {
859   //inflow tx
860   //send pkt directly, asking for IP and UDP checksum offloads AND IPSEC to be applied
861            PKTIO_METADATA_T meta = {PKTIO_META_TX,{0},0};
862            int err;
863            nwalTxPktInfo_t meta_tx={0};
864            meta.sa_handle=tx_inflow_mode_handle; //this tells netapi that inflow crypto needs to be applied
865            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 );
866            meta_tx.saOffBytes=14+20;  
867            meta_tx.saPayloadLen=len-14-20;   //don't include tag, mac and outer header
868            meta_tx.startOffset = 0;
869            meta_tx.ipOffBytes = 14+20+8+16;   //to inner header
870            meta_tx.l4OffBytes = 14+20+8+16+20; //to L4 
871            meta_tx.l4HdrLen = 8;
872            meta_tx.ploadLen = (unsigned) ((p_pkt[14+20+8+16+20+4]<<8)|p_pkt[14+20+8+16+20+4+1]) -8 ;
873            meta_tx.pseudoHdrChecksum =
874              test_utilGetIpv4PsudoChkSum(&p_pkt[14+20+8+16],8+ meta_tx.ploadLen);
876            /* post it to netcp tx channel*/
877            meta.u.tx_meta=&meta_tx;
878            pktio_send(netcp_tx_chan,tip,&meta,&err);
879            stats.tx +=1;
880            stats.sec_tx +=1;
881      }
882 #endif
886 else  //non ipsec send pkt directly, asking for IP and UDP checksum ofload
888            PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
889            int err;
890            nwalTxPktInfo_t meta_tx2={0};
891            meta2.sa_handle=nwal_HANDLE_INVALID;
892            meta_tx2.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM|NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID );
893            meta_tx2.startOffset = 0;
894            meta_tx2.ipOffBytes = 14;
895            meta_tx2.l4OffBytes = 14+20;
896            meta_tx2.l4HdrLen = 8;
897            meta_tx2.ploadLen = (unsigned) ((p_pkt[14+20+4]<<8)|p_pkt[14+20+4+1]) -8 ;
898            meta_tx2.pseudoHdrChecksum =
899              test_utilGetIpv4PsudoChkSum(&p_pkt[14],8+ meta_tx2.ploadLen);
901            /* post it to netcp tx channel*/
902            meta2.u.tx_meta=&meta_tx2;
903            pktio_send(netcp_tx_chan,tip,&meta2,&err);
904            stats.tx +=1;
911 /***************************************
912  benchmark receive handler
913 ****************************************/
914 void recv_cb_bench(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
915                          PKTIO_METADATA_T meta[], int n_pkts,
916                          uint64_t ts )
918    int i;
919    vv6=   netapi_timing_stop();
920    for (i=0;i<n_pkts; i++) 
921    {
922      Pktlib_freePacket(p_recv[i]);
923    }
924    vv11 = netapi_timing_stop();
927 /****************************************************************************************/
928 /******************SB Accelerator Callback PKT RECEIVE HANDLER *************************/
929 /******************  Handles Decrypt and Encrypt operation callbacks ******************/
930 /******************************************************************************************/
931 void recv_sb_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
932                          PKTIO_METADATA_T meta[], int n_pkts,
933                          uint64_t ts )
935 int i;
936 int len;
937 int p;
938 HEAD_T * p_res;
939 Ti_Pkt * tip;
940 unsigned int templen;
941 int err;
942 KEY_T key;
943 char * p_pkt;
944 HEAD_T * p_head;
945 HEAD_T temp_head;
946 int tag_cmp=0;
947 unsigned int hash[3];
949  /* loop over received pkts */
950    for(i=0;i<n_pkts;i++)
951    {
952         tip = p_recv[i];
953         Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
954         len = Pktlib_getPacketLen(tip);//real length
956         //is this a decrypt (rx_tunnel) complete
957         if (meta[i].u.rx_sb_meta->appId == rx_tunnel)
958         {
959            stats.sb_rx+=1;
960            //copy hash out of meta data (for some reason it needs endian conversion)
961            hash[0]= htonl( meta[i].u.rx_sb_meta->pAuthTag[0]);
962            hash[1]= htonl( meta[i].u.rx_sb_meta->pAuthTag[1]);
963            hash[2]= htonl( meta[i].u.rx_sb_meta->pAuthTag[2]);
965            if(stats.sb_rx<=16)
966            {
967              char *tp = (char *) &hash[0];
968              dump_header((long*)p_pkt, stats.sb_rx, meta[i].u.rx_sb_meta->appId,0);
969              printf("tag in pkt=%x %x %x %x %x %x %x %x %x %x %x %x\n",
970                       p_pkt[len-12],p_pkt[len-11],p_pkt[len-10],p_pkt[len-9], p_pkt[len-8],
971                       p_pkt[len-7],p_pkt[len-6],
972                       p_pkt[len-5],p_pkt[len-4],p_pkt[len-3],p_pkt[len-2],p_pkt[len-1]);
973              printf("tag from SA=%x %x %x %x %x %x %x %x %x %x %x %x\n",
974                        tp[0],tp[1],tp[2],tp[3],tp[4],tp[5],
975                        tp[6],tp[7],tp[8],tp[9],tp[10],tp[11]);
976            }
977            //check tag 
978            tag_cmp = memcmp(&p_pkt[len-12],(char*) &hash[0],12); //todo, really use meta->authTagLen
979            stats.n_auth_ok += !(tag_cmp);
980            flip_and_send_pkt(tip, p_pkt, len,1);  //flip packet to echo back and send
981         }
982         //this is an encrypt (tx tunnel) complete
983         else if(meta[i].u.rx_sb_meta->appId== tx_tunnel )
984         {
985            hash[0]= htonl( meta[i].u.rx_sb_meta->pAuthTag[0]);
986            hash[1]= htonl( meta[i].u.rx_sb_meta->pAuthTag[1]);
987            hash[2]= htonl( meta[i].u.rx_sb_meta->pAuthTag[2]);
988            stats.sb_tx+=1;
989            if(stats.sb_tx<=16)
990            {
991              char *tp1 = (char *) &hash[0];
992              dump_header((long*)p_pkt, stats.sb_tx, meta[i].u.rx_sb_meta->appId,0);
993              printf("tag in original rx pkt=%x %x %x %x %x %x %x %x %x %x %x %x\n",
994                       p_pkt[len-12],p_pkt[len-11],p_pkt[len-10],p_pkt[len-9], p_pkt[len-8],
995                       p_pkt[len-7],p_pkt[len-6],
996                       p_pkt[len-5],p_pkt[len-4],p_pkt[len-3],p_pkt[len-2],p_pkt[len-1]);
998              printf("tag from SA=%x %x %x %x %x %x %x %x %x %x %x %x\n",
999                        tp1[0],tp1[1],tp1[2],tp1[3],tp1[4],tp1[5],
1000                        tp1[6],tp1[7],tp1[8],tp1[9],tp1[10],tp1[11]);
1001            }
1002            //put the computed tag in the packet
1003            memcpy(&p_pkt[len-12],(char*)&hash[0],12); //todo, really use meta->authTagLen
1004            {
1005            PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
1006            nwalTxPktInfo_t meta_tx={0};
1007            // now send directly 
1008            meta2.sa_handle=nwal_HANDLE_INVALID;
1009            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
1010            meta_tx.startOffset = 0;
1011            meta_tx.ipOffBytes = 14;
1012            //not used
1013            meta_tx.l4OffBytes = 0;
1014            meta_tx.l4HdrLen = 0;
1015            meta_tx.ploadLen = 0;
1017            /* post it to netcp tx channel*/
1018            meta2.u.tx_meta=&meta_tx;
1019            pktio_send(netcp_tx_chan,tip,&meta2,&err);
1020            stats.tx +=1;
1021            }
1022         }
1023         else printf("netapi recv_sb_cb: unknown appiD %x \n",meta[i].u.rx_sb_meta->appId );
1024     }
1027 /******************************************************/
1028 /******************PKT RECEIVE HANDLER *************************/
1029 /******************************************************/
1030 void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
1031                          PKTIO_METADATA_T meta[], int n_pkts,
1032                          uint64_t ts )
1034 int i;
1035 int len;
1036 int p;
1037 HEAD_T * p_res;
1038 Ti_Pkt * tip;
1039 unsigned int templen;
1040 int err;
1041 KEY_T key;
1042 char * p_pkt;
1043 HEAD_T * p_head;
1044 HEAD_T temp_head;
1046     p_head=&temp_head;
1048     //debug
1049 #if 0
1050     if (n_pkts != TX_BURST) {
1051       printf("recv_cb, txsofar=%d rxsofar=%d  np = %d, NOT %d\n", 
1052              stats.itx, stats.rx, n_pkts,TX_BURST);
1053       our_stats_cb(netapi_handle,NULL);
1054     }
1055 #endif
1056     //test_alloc_free(7);
1057     //printf("recv start\n");
1059    /* loop over received pkts */
1060    for(i=0;i<n_pkts;i++)
1061    {
1062         tip = p_recv[i];
1063         Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
1064         len = Pktlib_getPacketLen(tip)-4;//real length, subtract mac trailer
1066          //debug: validate descriptor */
1067          if(Pktlib_getNextPacket(tip) != 0) {printf(" rcv_cb, nexpkt != NULL");}
1068         //debug printf("recv pkt, len=%d %d\n", len, templen);
1069         stats.rx+=1;
1071 #ifdef DEBUG_DESC
1072    if (stats.rx<16){printf(">rx dmp.."); dump_descr((long *) tip, stats.rx);}
1073    else if (stats.rx>99) {printf(">rx dmp.."); dump_descr((long *) tip,stats.rx);}
1074 #endif
1075     if(stats.rx<=16)
1076     {
1077         dump_header((long*)p_pkt, stats.rx, meta[i].u.rx_meta->appId,meta[i].u.rx_meta->rxFlag1);
1078     }
1079         /* check header */
1080         memcpy(p_head,&p_pkt[14],sizeof(HEAD_T));
1082         if ((p_head->ip[2]&0x0000ff00)==0x00003200)
1083         {
1084              if (!check_header(p_head,&meta[i])) {
1085                 stats.n_bad+=1;Pktlib_freePacket(tip); continue;
1086              }
1087  
1088              //process IP SEC PACKET
1089 #ifdef IPSEC_MODE_RX_SIDEBAND
1090         {
1091            //ship to crypto for decrypt!!
1092            //12 byte auth tag
1093            PKTIO_METADATA_T meta2 = {PKTIO_META_SB_TX,{0},0};
1094            nwalDmTxPayloadInfo_t meta_tx={0};
1095            meta2.sa_handle=rx_data_mode_handle;
1096            meta_tx.ploadLen = len;
1097            meta_tx.encOffset = 14+20+8+16 ;
1098            meta_tx.authOffset =14+20 ;
1099            meta_tx.encSize=len - 14- 20-8-16-12;
1100            meta_tx.authSize= len -14-20-12;
1101            meta_tx.encIvSize=16;
1102            meta_tx.pEncIV= &p_pkt[14+20+8];
1103            meta_tx.authIvSize=0;
1104            meta_tx.pAuthIV=NULL;
1105            meta_tx.aadSize=0;
1106            meta_tx.pAad=NULL;
1107            /* post it to netcp sb tx channel*/
1108            meta2.u.tx_sb_meta=&meta_tx;
1109            pktio_send(netcp_sb_tx_chan,tip,&meta2,&err);
1110            continue;
1111         }
1112 #else 
1113         //inflow mode.  flip and send
1114         flip_and_send_pkt(tip,p_pkt,len,1);
1115 #endif
1116     }
1117     else if ((p_head->ip[2]&0x0000ff00)!=0x00001100)
1118     {
1119                 stats.n_new+=1;Pktlib_freePacket(tip); continue;
1120     }
1121     else  //non ipsec
1122     {
1123         if (!check_header(p_head,&meta[i])) { 
1124                 stats.n_bad+=1;Pktlib_freePacket(tip); continue;
1125         }
1127 #if 0
1128         /* lookup flow */
1129         key.src_ip = p_head->ip[3];
1130         key.dst_ip = p_head->ip[4];
1131         key.src_port= (p_head->udp[0]&0xffff0000)>>16;
1132         key.dst_port= (p_head->udp[0]&0x0000ffff);
1133         p_res= (HEAD_T *) trie_lookup(P_trie, (char *) &key, sizeof(key));
1134         if (!p_res) { stats.n_new+=1;  slow_path(tip, len); continue;}
1136         /* copy header */
1137         memcpy((char *) p_head, (char *) p_res, sizeof(HEAD_T));
1139         memcpy(&p_pkt[14],p_head,sizeof(HEAD_T));
1140         /* update_mac(&p_pkt[0]);  */
1142         /* 'simulate' send pkt */
1143         send_pkt(tip,len);
1144 #endif
1145         //just flip and send
1146         flip_and_send_pkt(tip,p_pkt,len,0);
1147     }
1148   }
1149     //printf("recv done\n");
1152 //timer callback 
1153 void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
1154         int n_fired,     //# timers fired
1155         NETAPI_TIMER_LIST_T fired_list,
1156         uint64_t currentTime)
1158 int i;
1159 NETAPI_TIMER_T tx;
1160 int cookie;
1161 int err;
1162 unsigned long long et;
1163 //DEBUGprintf("TIMER CALLBACK @ %lld %d timers\n", currentTime, n_fired);
1164 tx = netapi_TimerGetFirst(fired_list);
1165 for(i=0;i<n_fired;i++)
1167   cookie = (int) netapi_TimerGetCookie(tx);
1168   et =  netapi_TimerGetTs(tx); //debug
1169   //DEBUGprintf("   timer %d - cookie = %d expected ts=%lld (delta=%lld)\n", i, cookie, et, currentTime-et);
1170   if (cookie ==1)
1171   {  
1172      stats.n_t1+=1;
1173      t1 = netapi_TimerGroupStartTimer(
1174         th,
1175         (void *) 1,
1176         100LL,  //timer group tics
1177         &err);
1178   }
1179   else if (cookie ==2)
1180   {
1181       stats.n_t2+=1;
1182       t2 = netapi_TimerGroupStartTimer(
1183         th,
1184         (void *) 2,
1185         200LL,  //timer group ticks
1186         &err);
1187   }
1188   else
1189   {
1190     stats.n_t3+=1;
1191     t3 = netapi_TimerGroupStartTimer(
1192         th,
1193         (void *) 3,
1194         300LL,  //timer group ticks
1195         &err);
1196     //cancel 1 and restart 1
1197    netapi_TimerGroupCancel(th,t1,&err);
1198    t1 = netapi_TimerGroupStartTimer(
1199         th,
1200         (void *) 1,
1201         100LL,  //timer group ticks
1202         &err);
1203  }
1204   tx = netapi_TimerGetNext(fired_list,tx); 
1209 static int np2process = NP;
1210 /******************************************************
1211  * stats callback
1212  *******************************************************/
1213 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats)
1215 uint32_t numFreeDataPackets;
1216 uint32_t            numZeroBufferPackets;
1217 uint32_t            numPacketsinGarbage;
1218 Pktlib_HeapStats    pktLibHeapStats;
1220 printf(">*****stats @ %lld\n", netapi_getTimestamp());
1221 //printf("netcp_tx_handle check %x\n", netcp_tx_chan->back);
1222 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, 
1223          stats.n_class0_rx, stats.n_class1_rx, 
1224          stats.n_class2_rx, stats.sec_rx, stats.secp_rx, stats.sb_rx, stats.sb_tx, stats.n_auth_ok,
1225          stats.n_t1, stats.n_t2,stats.n_t3);
1227 if(pPaStats)
1229        printf("C1 number of packets:           %d\n", pPaStats->classify1.nPackets);
1230        printf("C1 number IPv4 packets:         %d\n", pPaStats->classify1.nIpv4Packets);
1231        //printf("C1 number llc/snap fail:        %d\n", pPaStats->classify1.nLlcSnapFail);
1232        printf("C1 number table matched:        %d\n", pPaStats->classify1.nTableMatch);
1233        printf("C1 number failed table matched: %d\n", pPaStats->classify1.nNoTableMatch);
1234        printf ("C1 number of parse fail:        %d\n",pPaStats->classify1.nParseFail);
1235        printf("C1 number of command failures:  %d\n", pPaStats->classify1.nCommandFail);
1236        printf("C1 number invalid reply dests:  %d\n", pPaStats->classify1.nInvalidComReplyDest);
1237        printf ("C1 number of silent discard:    %d\n",pPaStats->classify1.nSilentDiscard);
1238        printf("C1 number of invalid control:   %d\n", pPaStats->classify1.nInvalidControl);
1239        printf ("C1 number of invalid states:    %d\n",pPaStats->classify1.nInvalidState);
1240        printf ("C1 number of system fails:      %d\n",pPaStats->classify1.nSystemFail);
1241        printf ("C2 number parse failed  :      %d\n",pPaStats->classify2.nParseFail);
1242        printf ("C2 number Invld Header  :      %d\n",pPaStats->classify2.nInvldHdr);
1243        printf ("C2 number udp           :      %d\n",pPaStats->classify2.nUdp);
1244        printf ("C2 number tcp           :      %d\n",pPaStats->classify2.nTcp);
1245        printf ("C2 number cmd fail      :      %d\n",pPaStats->classify2.nCommandFail);
1246        printf ("C2 number silent drop   :      %d\n",pPaStats->classify2.nSilentDiscard);
1247        printf ("C2 number invalid cntrl :      %d\n\n",pPaStats->classify2.nInvalidControl);
1249 Pktlib_getHeapStats(OurHeap, &pktLibHeapStats);
1250 printf("main heap stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
1251                                 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
1252 printf("               >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n", 
1253                         pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
1254                         pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
1256 Pktlib_getHeapStats(specialSmall, &pktLibHeapStats);
1257 printf("specialSmall 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);
1264 Pktlib_getHeapStats(specialLarge, &pktLibHeapStats);
1265 printf("specialLarge heap stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
1266                                 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
1267 printf("                       >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n", 
1268                                 pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
1269                                 pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
1272 //debug = dump timer polling stats
1273 dump_poll_stats();
1278 //******************************************************
1279 //use scheduling housekeeping callback to generate pkts
1280 //******************************************************
1281 void house(NETAPI_SCHED_HANDLE_T * s)
1283 Ti_Pkt * tip;
1284 unsigned int len;
1285 nwalTxPktInfo_t meta_tx;
1286 PKTIO_METADATA_T meta = {PKTIO_META_TX,{0},0};
1287 int err;
1288 static int house_pkts_gened=0;
1289 int p;
1290 unsigned char * pIpHdr,* pData;
1291 unsigned int vv1,vv2,vv3;
1292 unsigned int sum_vv1=0;
1293 unsigned int sum_vv2=0;
1294 unsigned int sum_vv3=0;
1295 unsigned int sum_vv4=0;
1296 unsigned int sum_vv5=0;
1298 unsigned int nwal_flow_vv1,nwal_flow_vv2;
1299 unsigned int nwal_sum_vv1=0;
1300 unsigned int nwal_sum_vv2=0;
1301 unsigned int nwal_sum_vv3=0;
1302 unsigned int nwal_sum_vv4=0;
1303 unsigned int nwal_sum_vv5=0;
1304 unsigned int nwal_sum_vv6=0;
1306 unsigned int nwal_sum_flow_vv1=0;
1307 unsigned int nwal_sum_flow_vv2=0;
1308 static int first =0;
1309 Cppi_HostDesc*      pPktDesc;
1311 Osal_cache_op_measure_reset();
1312 memset(&meta_tx,0,sizeof(meta_tx));
1313 for(p=0;p<TX_BURST;p++) {  
1314 //reguest stats 
1315 if ((house_pkts_gened>0) && (! (house_pkts_gened%1000)) )
1317    printf("net_test> request stats at n=%d \n",house_pkts_gened);
1318    //netcp_cfgReqStats(netapi_handle, our_stats_cb, 0,&err); 
1319    if (err!=0) {printf("stats req failed\n");}
1323   if (house_pkts_gened >= np2process+ 100)
1324   {
1325      //shutdown
1326      netapi_schedShutdown(s,NULL,&err);
1327      continue;
1328   }
1330   else if (house_pkts_gened >= np2process) { house_pkts_gened+=1;  continue;}
1331   
1333 /* manufacture a pkt to transmit */
1334    tip = get_pkt(house_pkts_gened, &len);
1335    if(!tip) { house_pkts_gened +=1; continue; }
1338    /* set the pkt length */
1339    vv1 = netapi_timing_start();
1340    Pktlib_setPacketLen(tip, len);
1342    /* set up meta data */
1343     meta.sa_handle=nwal_HANDLE_INVALID;
1344     meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM | NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID);
1345     meta_tx.startOffset = 0;
1346     //GONE in V2 meta_tx.pktLen = len;
1347     meta_tx.ipOffBytes = TEST_PKT_IP_OFFSET_BYTES;
1348     meta_tx.l4OffBytes = TEST_PKT_UDP_OFFSET_BYTES;
1349     meta_tx.l4HdrLen = TEST_PKT_UDP_HDR_LEN;
1350     //GONE in V2 meta_tx.ploadOffBytes = TEST_PKT_PLOAD_OFFSET_BYTES;
1351     meta_tx.ploadLen = TEST_PAYLOAD_LEN;
1353     Pktlib_getDataBuffer(tip,&pData,&len);
1354     pIpHdr = pData + meta_tx.ipOffBytes;
1355     meta_tx.pseudoHdrChecksum =
1356         test_utilGetIpv4PsudoChkSum(pIpHdr,(TEST_PAYLOAD_LEN+TEST_PKT_UDP_HDR_LEN));
1358    /* post it to netcp tx channel*/
1359    meta.u.tx_meta=&meta_tx;
1360 #ifdef DEBUG_DESC
1361    if (house_pkts_gened<16) dump_descr((long *) tip, house_pkts_gened);
1362    else if (house_pkts_gened>99) dump_descr((long *) tip,house_pkts_gened);
1363 #endif
1365    if(!first)
1366    {
1367        first++;
1368        nwal_flow_vv1= netapi_timing_stop();
1369        if(nwal_initPSCmdInfo(PKTIO_GET_NWAL_INSTANCE(netcp_tx_chan),
1370                              &meta_tx,
1371                              &flowPSCmdInfo) != nwal_OK)
1372        {
1373            printf("nwal_initPSCmdInfo() ERROR \n");
1374        }
1375        nwal_flow_vv2= netapi_timing_stop();
1376        nwal_sum_flow_vv1 += (nwal_flow_vv1-vv1); 
1377        nwal_sum_flow_vv2 += (nwal_flow_vv2-nwal_flow_vv1); 
1378    }
1379        
1380    vv2= netapi_timing_stop();
1381    nwal_mCmdSetL4CkSumPort(  tip,
1382                              &flowPSCmdInfo,
1383                              TEST_PKT_UDP_OFFSET_BYTES,
1384                              (TEST_PKT_UDP_HDR_LEN + TEST_PAYLOAD_LEN),
1385                              meta_tx.pseudoHdrChecksum,
1386                              meta_tx.enetPort);
1388    pPktDesc = Pktlib_getDescFromPacket(tip);
1389    /* Send the packet out to transmit Q*/
1390    Qmss_queuePushDescSize (flowPSCmdInfo.txQueue, 
1391                         pPktDesc, 
1392                         NWAL_DESC_SIZE);
1393    vv3= netapi_timing_stop();
1394    
1396    sum_vv1 += (vv2-vv1);
1397    if(!house_pkts_gened)
1398    {
1399        /* first packet. Take out the PS command label creation cost */
1400        sum_vv1 = sum_vv1 - nwal_sum_flow_vv2;
1401    }
1403    sum_vv3 += (vv3-vv2);
1405    // printf("pktio send. full=%d metadata=%d pktio_send=%d\n", vv3-vv1,  vv2-vv1,  vv3-vv2);
1406    
1408    stats.itx +=1;
1409    house_pkts_gened +=1;
1410  }
1412    unsigned int ccycles;
1413    int n_c_ops;
1414    ccycles =Osal_cache_op_measure(&n_c_ops);
1415    if (sum_vv1) 
1416    {
1417       printf("BURST NWAL Fast send %d pkts.  metadata=%d Cmd Label Creation Cost=%d  nwal Fast Send Cost= %d n_c_ops=%d cache_op_time=%d (pp-> %d)\n", 
1418               stats.itx, sum_vv1/stats.itx,  nwal_sum_flow_vv2, sum_vv3/stats.itx, 
1419               n_c_ops, ccycles, n_c_ops? (ccycles/(n_c_ops/2)) : 0);
1421       printf("NWAL Profile Cycles: Prof1= %d,Prof2=%d,Prof3=%d,Prof4=%d,Prof5=%d ,Prof6=%d \n",
1422               nwal_sum_vv1/stats.itx,nwal_sum_vv2/stats.itx,nwal_sum_vv3/stats.itx,
1423               nwal_sum_vv4/stats.itx,nwal_sum_vv5/stats.itx,nwal_sum_vv6/stats.itx);
1424     
1426       if(stats.itx2)
1427       {
1428           printf("nwal_flowSend Profile Cycles: Prof1= %d,Prof2=%d \n",
1429               nwal_sum_flow_vv1/stats.itx2,nwal_sum_flow_vv2/stats.itx2);
1430       }
1432    }
1437 /***************************************
1438  ********** test driver*****************
1439  ***************************************/
1440 int main(int argc, char **argv)
1442 int err;
1443 rlim_t oss,ss = 1024*1024;
1444 struct rlimit rl;
1445    
1446 Pktlib_HeapCfg      heapCfg;
1447 int32_t             errCode;
1448 Pktlib_HeapIfTable*  pPktifTable;
1450 err= getrlimit(RLIMIT_STACK,&rl);
1451 if (!err) printf(" stack limit = %d\n",rl.rlim_cur); else printf("getrlimit failed\n");
1452 #if 0
1453 rl.rlim_cur = ss;
1454 err=setrlimit(RLIMIT_STACK,&rl);
1455 if (!err) printf("set stack to %d\n",rl.rlim_cur); else printf("setrlimit failed\n");
1456 #endif
1458 if (argc>=2)  np2process = atoi(argv[1]);
1459 if (np2process<0) np2process = NP; /* default */
1460 if (argc==3)  perslow = atoi(argv[2]);
1461 if ((perslow<0)||(perslow>100)) perslow=PERSLOW;//default
1462 if (argc>3) {printf("net_test  <no of pkts to process> <percent slow path>\n"); exit(1);}
1465 //real mode, so update our test packet mac header and ip header
1466 if (pktloopback==0)
1468 memcpy(&testPkt,&real_mac_header[0],14); //overwrite test pkt mac address
1469 memcpy(&testPkt[26],&real_ip_addr[0],8);//overrite test pkt ip addresses
1472 /*******************************************/
1473 /*************NETAPI STARTUP****************/
1474 /*******************************************/
1476 /* create netapi */
1477 netapi_handle = netapi_init(NETAPI_SYS_MASTER, &our_netapi_default_cfg);
1479 /* open the main heap */
1480 OurHeap = Pktlib_findHeapByName("netapi");
1481 if (!OurHeap) {printf("findheapbyname fail\n"); exit(1);}
1483 /* create two secondary heaps */
1484 /* Initialize the heap configuration. */
1485 memset ((void *)&heapCfg, 0, sizeof(Pktlib_HeapCfg));
1487 pPktifTable = netapi_getPktlibIfTable();
1488 /* Populate the heap configuration */
1489 heapCfg.name                = "netapi-small";
1490 heapCfg.memRegion           = NETAPI_GLOBAL_REGION;
1491 heapCfg.sharedHeap          = 1;
1492 heapCfg.useStarvationQueue  = 0;
1493 heapCfg.dataBufferSize      = 512;
1494 heapCfg.numPkts             = 64;
1495 heapCfg.numZeroBufferPackets= 0;
1496 heapCfg.heapInterfaceTable.data_malloc  = pPktifTable->data_malloc;
1497 heapCfg.heapInterfaceTable.data_free    = pPktifTable->data_free;
1498 heapCfg.dataBufferPktThreshold   = 0;
1499 heapCfg.zeroBufferPktThreshold   = 0;
1501 specialSmall = Pktlib_createHeap(&heapCfg, &errCode);
1502 heapCfg.name                = "netapi-big";
1503 heapCfg.dataBufferSize      = 1600;
1504 specialLarge = Pktlib_createHeap(&heapCfg, &errCode);
1505 //register these heaps so poll routine will include their garbage queues.
1506 netapi_registerHeap(netapi_handle, specialSmall);
1507 netapi_registerHeap(netapi_handle, specialLarge);
1509 #ifdef REASSEMBLE_BENCH
1510 our_reassemble_bench(2);
1511 exit(1);
1512 #endif
1514 /* create a pktio channel */
1515 our_chan=pktio_create(netapi_handle,"our1stq",(PKTIO_CB) recv_cb_bench, &our_chan_cfg,&err);
1516 if (!our_chan) {printf("pktio create failed err=%d\n",err); exit(1);}
1518 /* open netcp default tx, rx queues */
1519 netcp_tx_chan= pktio_open(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg,  &err);
1520 if (!netcp_tx_chan) {printf("pktio open TX failed err=%d\n",err); exit(1);}
1521 netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb, &netcp_rx_cfg,  &err);
1522 if (!netcp_rx_chan) {printf("pktio open RX failed err=%d\n",err); exit(1);}
1524 /* create a pktio channel for specially classified pkts */
1525 netcp_rx_chan2= pktio_create(netapi_handle, "classq", (PKTIO_CB) recv_cb, &netcp_rx_cfg2,  &err);
1526 if (!netcp_rx_chan2) {printf("pktio create RX2 failed err=%d\n",err); exit(1);}
1528 /* open netcp default tx, rx queues for sideband crypto */
1529 netcp_sb_tx_chan= pktio_open(netapi_handle, NETCP_SB_TX, NULL, &netcp_sb_tx_cfg,  &err);
1530 if (!netcp_sb_tx_chan) {printf("pktio open SB TX failed err=%d\n",err); exit(1);}
1531 netcp_sb_rx_chan= pktio_open(netapi_handle, NETCP_SB_RX, (PKTIO_CB) recv_sb_cb, &netcp_sb_rx_cfg,  &err);
1532 if (!netcp_sb_rx_chan) {printf("pktio open SB RX failed err=%d\n",err); exit(1);}
1534 printf("net_test> %d bytes left in our CMA area\n", netapi_getBufMemRemainder());
1535 /* create scheduler instance */
1536 our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err);
1537 if (!our_sched) {printf("sched create failed\n"); exit(1);}
1539 /********************************************
1540 * Basic pkt loopback test
1541 *********************************************/
1542 printf("...running pure push/pop benchmark\n");
1543 our_pktio_bench(1000);
1544 our_pktio_bench(1000);
1545 our_pktio_bench(1000);
1546 our_pktio_bench(1000);
1547 our_pktio_bench(1000);
1548 /*********************************************/
1553 /* add mac intefaces */
1554 netcp_cfgCreateMacInterface(
1555                   netapi_handle,
1556                   &mac0[0],
1557                   0,0,
1558                   (NETCP_CFG_ROUTE_HANDLE_T)  NULL,
1559                   (NETCP_CFG_VLAN_T ) NULL ,  //future
1560                   1, 
1561                   &err);
1562 if (err) {printf("addmac0 failed %d\n",err); exit(1); } 
1564 //attach an IP to this interface
1565 ip_rule0=netcp_addIp(
1566                   netapi_handle,
1567                   0,
1568                   nwal_IPV4,
1569                   &OurIp0,
1570                   NULL,  //all IP
1571                   (NETCP_CFG_ROUTE_HANDLE_T) NULL,
1572                   &err
1573                   );
1574 if (err) {printf("addip0 failed %d\n",err); exit(1); } 
1576 //create a 2nd mac instance
1577 netcp_cfgCreateMacInterface(
1578                   netapi_handle,
1579                   &mac1[0],
1580                   1,1,
1581                   (NETCP_CFG_ROUTE_HANDLE_T)  NULL,
1582                   (NETCP_CFG_VLAN_T ) NULL ,  //future
1583                   1,
1584                   &err);
1585 if (err) {printf("addmac1 failed %d\n",err); exit(1); }
1587 //attach an IP to this interface
1588 ip_rule1=netcp_addIp(
1589                   netapi_handle,
1590                   1,
1591                   nwal_IPV4,
1592                   &OurIp1,
1593                   NULL,  //all IP
1594                   (NETCP_CFG_ROUTE_HANDLE_T) NULL,
1595                   &err
1596                   );
1597 if (err) {printf("addip1 failed %d\n",err); exit(1); }
1599 //attach 2 classifiers to iface 0, ip0
1600 class_0_cfg.u.c_l4.ip = ip_rule0;
1601 class_0 =  netcp_cfgAddClass(netapi_handle,
1602                              &class_0_cfg,
1603                              NULL,
1604                              NETCP_CFG_ACTION_TO_SW,
1605                              &err);
1606 if (err) {printf("addclass0 failed %d\n",err); exit(1);}
1608 class_1_cfg.u.c_l4.ip = ip_rule0;
1609 class_1 =  netcp_cfgAddClass(netapi_handle,
1610                              &class_1_cfg,
1611                              NULL,
1612                              NETCP_CFG_ACTION_TO_SW,
1613                              &err);
1614 if (err) {printf("addclass1 failed %d\n",err); exit(1);}
1617 //3rd classifier has a different IP and route
1618 class_2_cfg.u.c_l3_l4.ip_addr = &OurIp2;
1620 //create specialFlow for this classifier
1622 Pktlib_HeapHandle heaps[2];
1623 int sizes[2];
1624 heaps[0]= specialSmall;
1625 heaps[1]= specialLarge;
1626 #define SPECIAL_SOP_OFF 128
1627 sizes[0]=512-SPECIAL_SOP_OFF;
1628 sizes[1]=1600-SPECIAL_SOP_OFF;
1629 specialFlow = netcp_cfgAddFlow( netapi_handle,
1630                                 2,
1631                                 heaps,
1632                                 sizes,
1633                                 SPECIAL_SOP_OFF,  //offset to start rx is 128 
1634                                 &err);
1635 if (err) {printf("add flow failed\n", err); exit(1);}
1637 #if 0
1638 //special route for this classifier:  different flow + destination q
1639 class2_route.p_dest_q = netcp_rx_chan2;
1640 class2_route.p_flow = specialFlow;
1641 class_2 = netcp_cfgAddClass(netapi_handle,
1642                             &class_2_cfg,
1643                             (void*) &class2_route,
1644                             NETCP_CFG_ACTION_TO_SW,
1645                             &err);
1646 if (err) {printf("addclass2 failed %d\n",err); exit(1);}
1647 #endif
1649 //security stuff 
1650 ourRXKeyParams.pEncKey = &ourEncrKey[0];
1651 ourRXKeyParams.pAuthKey = &ourAuthKey[0];
1652 memcpy(&rx_sa.src, &TheirIp4IPSEC,4);
1653 memcpy(&rx_sa.dst, &OurIp4IPSEC,4);
1655 #if 1
1656 rx_tunnel = netapi_secAddSA( netapi_handle,
1657                  0, //iface #0 
1658                 &rx_sa,
1659                 &ourRXKeyParams,
1660 #ifdef IPSEC_MODE_RX_SIDEBAND
1661                 NETAPI_SEC_SA_SIDEBAND,
1662 #else
1663                 NETAPI_SEC_SA_INFLOW,  //USE inflow mode
1664 #endif
1665                 NULL,  //use default route 
1666                 &rx_data_mode_handle,
1667                 &rx_inflow_mode_handle,
1668                 &err);
1669 if (err) {printf("addRxSa failed %d\n",err); exit(1);}
1671 #ifdef IPSEC_MODE_RX_INFLOW
1672 //assume inner and outer ip is the same
1673 rx_policy= netapi_secAddRxPolicy( netapi_handle,
1674                          rx_tunnel,  //link to tunnel above
1675                          4,         //ipv4
1676                          &TheirIp4IPSEC, //src -> them
1677                          &OurIp4IPSEC,  //dst -> us
1678                          NULL,  // no qualifiers
1679                          NULL,  //default route
1680                          &err);
1681 if (err) {printf("addSaPolicy failed %d\n",err); exit(1);}
1682 #else 
1683 rx_policy = 0;
1684 #endif
1685 #endif
1687 //tx SA
1688 //security stuff 
1689 ourTXKeyParams.pEncKey = &ourEncrKey[0];
1690 ourTXKeyParams.pAuthKey = &ourAuthKey[0];
1691 memcpy(&tx_sa.src, &OurIp4IPSEC,4);
1692 memcpy(&tx_sa.dst, &TheirIp4IPSEC,4);
1693 tx_tunnel = netapi_secAddSA( netapi_handle,
1694                  0, //iface #0 
1695                 &tx_sa,
1696                 &ourTXKeyParams,
1697 #ifdef IPSEC_MODE_TX_SIDEBAND
1698                 NETAPI_SEC_SA_SIDEBAND,
1699 #else
1700                 NETAPI_SEC_SA_INFLOW,  //USE inflow mode
1701 #endif
1702                 NULL,  //use default route 
1703                 &tx_data_mode_handle,
1704                 &tx_inflow_mode_handle,
1705                 &err);
1706 if (err) {printf("addTxSa failed %d\n",err); exit(1);}
1709 #ifdef TEST_TIMERS
1710 //timers
1711 ourTimerBlock = netapi_TimerGroupCreate(
1712         netapi_handle,
1713         "our1sttimer",
1714         our_timer_cb,
1715         0,    //1 if timers local to thread
1716         0,    //1 if expect to cancel
1717         netapi_getTicksPerSec()/1000,  /* 1 msc resolution for these timers */
1718         netapi_getTicksPerSec()/5000, /* would like .5 msc tolerence */
1719         10,  //small # of timers to test garbage collection
1720         &err);
1721 if (err) {printf("timergroupcreate failed %d\n",err); exit(1);}
1723 //start a couple of timers 
1724 t1 = netapi_TimerGroupStartTimer(
1725         ourTimerBlock,
1726         (void *) 1,
1727         100LL,  //timer group ticks
1728         &err);
1729 if (err) {printf("timerstart failed %d\n");}
1730 t2 = netapi_TimerGroupStartTimer(
1731         ourTimerBlock,
1732         (void *) 2,
1733         200LL,  //timer group ticks
1734         &err);
1735 if (err) {printf("timerstart failed %d\n");}
1736 t3 = netapi_TimerGroupStartTimer(
1737         ourTimerBlock,
1738         (void *) 3,
1739         300LL,  //timer group ticks
1740         &err);
1741 if (err) {printf("timerstart failed %d\n");}
1742 #endif
1743 //netcp_cfgReqStats(netapi_handle, our_stats_cb, 1,&err);
1744 if (err!=0) {printf("stats req failed\n");}
1746 /*********************************************/
1747 /*****************end NETAPI STARTUP**********/
1748 /*********************************************/
1751 /********************************************
1752 * Basic pkt loopback test
1753 *********************************************/
1754 printf("...runnining pure push/pop benchmark\n");
1755 our_pktio_bench(100);
1758 /**************unused stuff******************/
1759 /* create TRIE */
1760 P_trie = trie_new();
1761 if (!P_trie) {printf("trie alloc failed\n"); exit(1);}
1763 nat = (HEAD_T *) malloc(NE * sizeof(HEAD_T));
1764 if (!nat) {printf("malloc of nat table failed\n"); exit(1);}
1766 //gen_pkts(np2process<NP ? np2process:NP);
1767 n_pkt= np2process;
1769 /* build table */
1770 build_table(P_trie);
1773 /* processing loop: get pkt, check it, look up in table, copy new header,
1774    send packet */
1775 srand((unsigned) np2process);
1778 /*********************************************/
1779 /**************Entry point into scheduler ****/
1780 /*********************************************/
1781 netapi_schedWaitForEvents(our_sched, &err);
1783 /* done */
1784 our_stats_cb(netapi_handle, NULL);
1787 #define DO_FAST_POLL
1788 #ifdef DO_FAST_POLL
1789 example_fast_poll(netcp_rx_chan);
1790 #endif
1792 /*************************************************
1793  ************CLEAN UP****************************
1794  ************************************************/
1796 //delete Classifiers
1797 netcp_cfgDelClass(netapi_handle, class_0, &err); 
1798 netcp_cfgDelClass(netapi_handle, class_1, &err); 
1799 //netcp_cfgDelClass(netapi_handle, class_2, &err); 
1801 //delete flow 
1802 netcp_cfgDelFlow(netapi_handle, specialFlow, &err);
1804 #if 1
1805 //delete policy
1806 if (rx_policy)
1807         netapi_secDelRxPolicy(netapi_handle, rx_policy, &err);
1809 //delete tunnels
1810 netapi_secDelSA(netapi_handle, 0, rx_tunnel, &err);
1811 netapi_secDelSA(netapi_handle, 0, tx_tunnel, &err);
1812 #endif
1814 //delete IPs and MAC Interfacess
1815 netcp_cfgDelIp(netapi_handle, 0, 0, NULL, NULL, ip_rule0, &err);
1816 netcp_cfgDelIp(netapi_handle, 1, 0, NULL, NULL, ip_rule1, &err);
1817 netcp_cfgDelMac(netapi_handle,0,&err);
1818 netcp_cfgDelMac(netapi_handle,1,&err);
1821 //close pktio channels we opened
1822 pktio_close(netcp_tx_chan ,&err);
1823 pktio_close(netcp_rx_chan ,&err);
1824 pktio_close(netcp_sb_tx_chan ,&err);
1825 pktio_close(netcp_sb_rx_chan ,&err);
1827 //clear pktio channel we created
1828 pktio_control(our_chan, (PKTIO_CB) NULL, (PKTIO_CFG_T *) NULL, &zap_channel_control, &err);
1829 pktio_control(netcp_rx_chan2, (PKTIO_CB) NULL, (PKTIO_CFG_T *) NULL, &zap_channel_control, &err);
1831 //delete pktio channels we created
1832 pktio_delete(our_chan, &err);
1833 pktio_delete(netcp_rx_chan2,&err);
1835 netapi_shutdown(netapi_handle);
1839 //EXAMPLE FAST POLL
1840 /* PLD */
1841 void netapi_pld(void * x)
1842 {   
1843            asm volatile("pld [r0]");
1845 #include "ti/drv/nwal/nwal_util.h"
1847 #define M 1008
1848 static int l3_off[M], l4_off[M], L3_chk_ok[M], L4_chk_ok[M], appid[M], len[M] ;
1849 static unsigned char * buf[M];
1850 #define N2POLL 8 //batch size
1851 void example_fast_poll( PKTIO_HANDLE_T * p_pktio)
1853 int j=0;
1854 int jj=0;
1855 int i,k,l=0,ltot=0;
1856 int n= N2POLL; //max # of pkts to poll
1857 Ti_Pkt * pHd[N2POLL];
1858 Ti_Pkt * tempVA;
1859 pasahoLongInfo_t* pinfo;
1860 unsigned long t1;
1861 unsigned long t2;
1862 unsigned long t11;
1863 unsigned long t12;
1864 unsigned long np;
1865 unsigned long sumt=0;
1866 unsigned long sumf=0;
1867 unsigned long sump=0;
1868 unsigned long totlen=0;
1869 int max_batch=0;
1871 //this should  be done once and saved
1872 Qmss_QueueHnd rxQ= PKTIO_GET_DEFAULT_NETCP_Q(p_pktio);
1873 Qmss_QueueHnd freeQ;
1874 //loop forever
1875 for(;;)
1877     t1= netapi_timing_stop();
1878     pHd[0] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (rxQ));
1879     if (!pHd[0]) continue;
1880     //got pkt
1881     for(i=1;(i<n) && (pHd[i-1]);i++)
1882     {
1883         //convert previous descriptor PA -> VA
1884         tempVA  =  Osal_qmssPhyToVirt(pHd[i-1]); 
1886         //try and preload desriptor
1887          __builtin_prefetch(tempVA);
1888         //netapi_pld(tempVA);
1890         //read next descriptor from queue 
1891         pHd[i] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (rxQ));
1892 #if 1   
1893         /* extract some meta data */
1894         Cppi_getData (Cppi_DescType_HOST, (Cppi_Desc*)tempVA, &buf[jj], &len[jj]);
1895         pinfo =  PKTIO_GET_PROTO_INFO(tempVA);
1896         l3_off[jj]= PKTIO_GET_L3_OFFSET(pinfo);
1897         l4_off[jj]= PKTIO_GET_L4_OFFSET(pinfo);
1898         appid[jj]= PKTIO_GET_APPID(tempVA);
1899 //#define VERIFY_SOP
1900 #ifdef VERIFY_SOP
1901   if (sump < 200)  printf("..sop off=%d\n", (int) buf[jj]-
1902            (int)  ((Cppi_HostDesc *) tempVA)->origBuffPtr) ;
1903 #endif
1904 #endif
1905         jj+=1;
1906     }
1907     //finish last pkt in burst
1908     if(pHd[i-1])
1909     {
1910         //convert previous descriptor PA -> VA
1911         tempVA  =  Osal_qmssPhyToVirt(pHd[i-1]); 
1913         /* extract some meta data */
1914 #if 1
1915         pinfo =  PKTIO_GET_PROTO_INFO(tempVA);
1916         l3_off[jj]= PKTIO_GET_L3_OFFSET(pinfo);
1917         l4_off[jj]= PKTIO_GET_L4_OFFSET(pinfo);
1918         appid[jj]= PKTIO_GET_APPID(tempVA);
1919 #endif
1920         //get ptr (Physical address) and length of associate buffer
1921         Cppi_getData (Cppi_DescType_HOST, (Cppi_Desc*)tempVA, &buf[jj], &len[jj]);
1922         jj+=1;
1923     }
1924     t2= netapi_timing_stop();
1925     j+=(pHd[i-1]? i: (i-1)) ;
1926     if (jj>(M-n)) jj=0;
1927     l+=1;  //n batches
1928     ltot+=1;
1929     if(pHd[i-1])
1930     {
1931       if (i>max_batch) max_batch= i;
1932     }
1933     else
1934     {
1935       if( (i-1) >max_batch) max_batch = i-1;
1936     }
1938     //cleanup
1939     //printf("cleanup %d\n",i);
1940     for(k=0;k<i;k++)
1941     {
1942         //cleanup.  need to covert all of desriptor to VA so that i can use freePacket() 
1943         //alternative would be to just do cache ops plus descriptor raw push to pktlib
1944         // heap free queue
1945         if(pHd[k])
1946         {
1948         //tempVA=Qmss_osalConvertDescPhyToVirt(pHd[k]);
1949         tempVA  =  Osal_qmssPhyToVirt(pHd[k]);
1950         freeQ=Qmss_getQueueHandle(Cppi_getReturnQueue (Cppi_DescType_HOST, tempVA));
1951         netapi_utilCacheWbInv(tempVA,128);
1952         //would need to wbInv buffer also in practice. Also need to walk
1953         // descriptor chain 
1954         t11= netapi_timing_stop();
1955        // Pktlib_freePacket(tempVA);
1956         PKTIO_QMSS_QUEUE_PUSH_DESC_SIZE_RAW (freeQ,
1957                                              (void *) pHd[k],
1958                                              128);
1960         t12= netapi_timing_stop();
1961         sumf += (t12-t11);       
1962         }
1963     }
1964     sumt += (t2-t1);
1965     sump +=(pHd[i-1]? i: (i-1));
1966     //printf("end cleanup %d %d %d\n",sumt,sumf,sump );
1967     if (sump > 10000) {
1968        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", 
1969                   j,ltot, appid[j%M], 
1970                   l3_off[j%M],l4_off[j%M],  
1971                   len[j%M],buf[j%M],
1972                    sumt/sump,  (sump*1000)/l, max_batch,
1973                    sumf/sump);
1974        sumt=sump=sumf=0;
1975        l=0;
1976     }